File

src/lib/service/backend/backend.service.ts

Description

BackendService encapsulates the communication with the yuuvis® RAD REST endpoints.

As yuuvis® RAD provides different services, this service is also capable of providing the base URIs for those services.

Index

Properties
Methods

Methods

Public del
del(uri: string, base?: string, requestOptions?: HttpOptions)

Wrapped HTTP DELETE method

Parameters :
Name Type Optional Description
uri string no

The target REST URI

base string yes

The Base URI (backend service) to be used

requestOptions HttpOptions yes

Additional request options

Returns : Observable<any>

The return value of the target DELETE endpoint

Public download
download(uri: string, version?: number)
Parameters :
Name Type Optional
uri string no
version number yes
Returns : void
Public downloadContent
downloadContent(dmsObjects: DmsObject[], rendition?: "PDF" | "TIFF" | "TEXT" | "JPEG", fileNameWithVersionNumber?: boolean, recyclebin?: boolean)

Download the content of dms objects.

Parameters :
Name Type Optional
dmsObjects DmsObject[] no
rendition "PDF" | "TIFF" | "TEXT" | "JPEG" yes
fileNameWithVersionNumber boolean yes
recyclebin boolean yes
Returns : void
Public downloadMulti
downloadMulti(uri: string, version?: number, _body?: any)
Parameters :
Name Type Optional
uri string no
version number yes
_body any yes
Returns : void
Public get
get(uri: string, base?: string, requestOptions?: HttpOptions)

Wrapped HTTP GET method

Parameters :
Name Type Optional Description
uri string no

The REST URI to be queried

base string yes

The Base URI (backend service) to be used

requestOptions HttpOptions yes

Additional request options

Returns : Observable<any>

The data retrieved from the given endpoint

Public getAgentBase
getAgentBase()

Gets the base URI for the Agent-Service endpoint

Returns : any

Base URI

Public getBaseWithContext
getBaseWithContext(base: string)
Parameters :
Name Type Optional
base string no
Returns : any
Public getBpmBase
getBpmBase()

Gets the base URI for the BPM-Service endpoint

Returns : any

Base URI

Public getContextBase
getContextBase()

Gets the base URI for the Context-Service endpoint

Returns : any

Base URI

Public getHeaders
getHeaders()

Retrieves the current headers

Returns : HttpHeaders

The HttpHeaders that are currently set up

Public getInboxBase
getInboxBase()

Gets the base URI for the Inbox-Service endpoint

Returns : any

Base URI

Public getSearchBase
getSearchBase()

Gets the base URI for the Search-Service endpoint

Returns : any

Base URI

Public getServiceBase
getServiceBase()

Gets the base URI for the DMS-Service endpoint

Returns : any

Base URI

Public getStatusBase
getStatusBase()

Gets the base URI for the Status-Service endpoint

Returns : any

Base URI

Public post
post(uri: string, data?: , base?: string, requestOptions?: HttpOptions)

Wrapped HTTP POST method

Parameters :
Name Type Optional Description
uri string no

The target REST URI

data yes

Data to be 'posted'

base string yes

The Base URI (backend service) to be used

requestOptions HttpOptions yes

Additional request options

Returns : Observable<any>

The return value of the target POST endpoint

Public postMultiPart
postMultiPart(uri: string, formData: FormData, base?: string, requestOptions?: HttpOptions)

Performs a multipart form data POST request.

Parameters :
Name Type Optional Description
uri string no

The target REST URI

formData FormData no

FormData to be 'posted'

base string yes

The Base URI (backend service) to be used

requestOptions HttpOptions yes

Additional request options

Returns : Observable<any>

The return value of the target POST endpoint

Public put
put(uri: string, data?: any, base?: string, requestOptions?: HttpOptions)

Wrapped HTTP PUT method

Parameters :
Name Type Optional Description
uri string no

The target REST URI

data any yes

Data to be 'posted'

base string yes

The Base URI (backend service) to be used

requestOptions HttpOptions yes

Additional request options

Returns : Observable<any>

The return value of the target PUT endpoint

Public setHeader
setHeader(key: string, value: string)

Add a new header.

Parameters :
Name Type Optional Description
key string no

The headers name

value string no

The value

Returns : void

Properties

Public gridDataFilter
gridDataFilter: MonoTypeOperatorFunction<any>
Type : MonoTypeOperatorFunction<any>
Default value : map((data: any[]) => data?.filter((v: any) => !v.__removed))

BackendService

BackendService encapsulates the communication with the yuuvis® RAD REST endpoints.

As yuuvis® RAD provides different backend services, this service is also capable of providing the base URIs for those services.

import {of as observableOf, Observable, MonoTypeOperatorFunction} from 'rxjs';
import {map, tap} from 'rxjs/operators';
import {Inject, Injectable} from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import {Config} from '../config/config.service';
import {DmsObject} from '../../model/dms-object.model';
import * as FileSaver from 'file-saver';
import {Logger} from '../logger/logger';
import {AuthProfile} from '../auth/auth-profile.interface';
import {HttpParams} from '@angular/common/http';
import {finalize, shareReplay} from 'rxjs/operators';
import {CoreConfig} from '../../config/core-config';
import {CORE_CONFIG} from '../../config/core-init.tokens';

/**
 * HttpOptions for http request
 * @param observe: 'body' | 'events' | 'response'
 * @param responseType: 'arraybuffer' | 'blob' | 'json' | 'text'
 */
export interface HttpOptions {
  headers?:
  | HttpHeaders
  | {
    [header: string]: string | string[];
  };
  observe?: any;
  params?:
  | HttpParams
  | {
    [param: string]: string | string[];
  };
  reportProgress?: boolean;
  responseType?: any;
  withCredentials?: boolean;
}


// @ts-ignore
/**
 * `BackendService` encapsulates the communication with the yuuvis<sup>&reg;</sup> RAD REST endpoints.
 *
 * As yuuvis<sup>&reg;</sup> RAD provides different services, this service is also capable of providing the base URIs for those services.
 */
@Injectable({
  providedIn: 'root'
})
export class BackendService {

  public gridDataFilter: MonoTypeOperatorFunction<any> = map((data: any[]) => data?.filter((v: any) => !v.__removed));
  private authProfile: AuthProfile;
  private cache = new Map<string, any>();
  private temp = new Map<string, Observable<any>>();
  private headers = this.setDefaultHeaders();

  /**
   * @ignore
   */
  constructor(private http: HttpClient,
    @Inject(CORE_CONFIG) public coreConfig: CoreConfig,
    private logger: Logger,
    private config: Config) {

    /**
     * default profile is supposed to use NTLM
     * @type {host: string; ntlm: boolean}
     */
    this.authProfile = {
      host: '',
      ntlm: true
    };
  }

  /**
   * @ignore
   */
  public setAuthProfile(profile?: AuthProfile) {
    if (profile) {
      this.headers = this.setDefaultHeaders();
      this.authProfile = profile;
      if (this.authProfile.auth) {
        // this.setHeader('Authorization', this.authProfile.auth);
      }
      this.headers.delete('Authorization');
    }
  }

  /**
   * Add a new header.
   * @param key The headers name
   * @param value The value
   */
  public setHeader(key: string, value: string) {
    if (value && value.length) {
      this.headers = this.headers.set(key, value);
    }
  }

  /**
   * Retrieves the current headers
   * @returns The `HttpHeaders` that are currently set up
   */
  public getHeaders(): HttpHeaders {
    return this.headers;
  }

  /**
   * @ignore
   */
  public getHttpOptions(requestOptions?: HttpOptions): HttpOptions {
    return Object.assign({headers: this.getHeaders(), withCredentials: this.coreConfig.withCredentials}, requestOptions);
  }

  /**
   * Gets the base URI for the DMS-Service endpoint
   * @returns Base URI
   */
  public getServiceBase() {
    return this.config.getUri('serviceBase');
  }

  /**
   * Gets the base URI for the Search-Service endpoint
   * @returns Base URI
   */
  public getSearchBase() {
    return this.config.getUri('searchBase');
  }

  /**
   * Gets the base URI for the Context-Service endpoint
   * @returns Base URI
   */
  public getContextBase() {
    return this.config.getUri('contextBase');
  }

  /**
   * Gets the base URI for the Inbox-Service endpoint
   * @returns Base URI
   */
  public getInboxBase() {
    return this.config.getUri('inboxBase');
  }

  /**
   * Gets the base URI for the BPM-Service endpoint
   * @returns Base URI
   */
  public getBpmBase() {
    return this.config.getUri('bpmBase');
  }

  /**
   * Gets the base URI for the Agent-Service endpoint
   * @returns Base URI
   */
  public getAgentBase() {
    return this.config.getUri('agentBase');
  }

  /**
   * Gets the base URI for the Status-Service endpoint
   * @returns Base URI
   */
  public getStatusBase() {
    return this.config.getUri('statusBase');
  }

  /**
   * @ignore
   */
  public getIconBase(id: string = '') {
    return this.getBaseWithContext(this.getServiceBase()) + '/ui/icon/' + id;
  }

  /**
   * @ignore
   */
  public getHost() {
    return this.authProfile.host || '';
  }

  public getBaseWithContext(base: string) {
    return base?.startsWith('/') ? this.config.getContextPath() + base : base;
  }

  private getContextPath(base?: string): string {
    return this.getHost() + (this.getBaseWithContext(base || this.getServiceBase()));
  }

  /**
   * Wrapped HTTP GET method
   * @param uri The REST URI to be queried
   * @param base The Base URI (backend service) to be used
   * @param requestOptions Additional request options
   * @returns The data retrieved from the given endpoint
   */
  public get(uri: string, base?: string, requestOptions?: HttpOptions): Observable<any> {
    return this.http.get(this.getContextPath(base) + uri, this.getHttpOptions(requestOptions));
  }

  /**
   * Wrapped HTTP PUT method
   * @param uri The target REST URI
   * @param data Data to be 'posted'
   * @param base The Base URI (backend service) to be used
   * @param requestOptions Additional request options
   * @returns The return value of the target PUT endpoint
   */
  public put(uri: string, data?: any, base?: string, requestOptions?: HttpOptions): Observable<any> {
    return this.http.put(this.getContextPath(base) + uri, data, this.getHttpOptions(requestOptions));
  }

  /**
   * @ignore
   */
  public getJson(uri: string, base?: string): Observable<any> {
    return this.http.get(this.getContextPath(base) + uri, this.getHttpOptions({responseType: 'json'}));
  }

  /**
   * Wrapped HTTP POST method
   * @param uri The target REST URI
   * @param data Data to be 'posted'
   * @param base The Base URI (backend service) to be used
   * @param requestOptions Additional request options
   * @returns The return value of the target POST endpoint
   */
  public post(uri: string, data?, base?: string, requestOptions?: HttpOptions): Observable<any> {
    const baseUri = this.getContextPath(base);
    const payload = data ? JSON.stringify(data) : '';
    return this.http.post(`${baseUri}${uri}`, payload, this.getHttpOptions(requestOptions));
  }

  /**
   * Performs a multipart form data POST request.
   * @param uri The target REST URI
   * @param formData FormData to be 'posted'
   * @param base The Base URI (backend service) to be used
   * @param requestOptions Additional request options
   * @returns The return value of the target POST endpoint
   */
  public postMultiPart(uri: string, formData: FormData, base?: string, requestOptions?: HttpOptions): Observable<any> {
    const baseUri = this.getContextPath(base);
    const headers = this.getHeaders();
    headers.delete('Content-Type');
    const reqOptions = Object.assign({headers: headers, withCredentials: this.coreConfig.withCredentials}, requestOptions);
    return this.http.post(`${baseUri}${uri}`, formData, reqOptions);
  }

  /**
   * Wrapped HTTP DELETE method
   * @param uri The target REST URI
   * @param base The Base URI (backend service) to be used
   * @param requestOptions Additional request options
   * @returns The return value of the target DELETE endpoint
   */
  public del(uri: string, base?: string, requestOptions?: HttpOptions): Observable<any> {
    return this.http.delete(this.getContextPath(base) + uri, this.getHttpOptions(requestOptions));
  }

  /**
   * @ignore
   * Soft update for lists - enables grid to handle all changes
   * to add new - only item should be specified
   * to remove - only id should be specified
   * to update - both params should be specified
   *
   * @param any[] list Original list of items
   * @param id?: string; item?: any data[]
   * @returns any[]
   */
  public update(list: any[], data: {id?: string, item?: any}[]) {
    data.forEach(({id, item}) => {
      if (id) {
        const _item = list.find(l => l.id === id);
        Object.assign(_item, item, item ? {__updated: true} : {__removed: true});
      } else if (item) {
        list.unshift(Object.assign(item, {__added: true}));
      }
    });
    return list;
  }

  /**
   * @ignore
   * Cache for small requests like icons and configs
   *
   * @param string uri
   * @returns Observable<any>
   */
  public getViaCache(uri: string): Observable<any> {
    if (this.cache.has(uri)) {
      return observableOf(this.cache.get(uri));
    } else {
      return this.getViaTempCache(uri, () => this.http.get(uri, {withCredentials: this.coreConfig.withCredentials, responseType: 'text'}).pipe(
        tap(text => this.cache.set(uri, text))));
    }
  }

  /**
   * @ignore
   * Temporary Cache for multiple identical requests
   *
   * @param string id
   * @param Function request
   * @returns Observable<any>
   */
  public getViaTempCache(id: string, request?: Function): Observable<any> {
    if (this.temp.has(id)) {
      return this.temp.get(id);
    } else {
      const resp = (request ? request() : this.get(id)).pipe(
        finalize(() => this.temp.delete(id)),
        shareReplay(1)
      );
      this.temp.set(id, resp);
      return resp;
    }
  }

  /**
   * Download the content of dms objects.
   *
   * @param DmsObject[] dmsObjects Array of dms objects to be downloaded
   * @param "PDF" | "TIFF" | "TEXT" | "JPEG" rendition The type of rendition to be downloaded. If not specified, the original content will be downloaded.
   * Possible renditions are `PDF`, `TIFF`, `TEXT`, `JPEG`.
   */
  public downloadContent(dmsObjects: DmsObject[], rendition?: 'PDF' | 'TIFF' | 'TEXT' | 'JPEG', fileNameWithVersionNumber?: boolean, recyclebin?: boolean) {

    const item = dmsObjects[0];
    if (dmsObjects.length === 1) {
      if (item.content) {

        let uri = `/dms/${item.content.id}/content?type=${item.content.type}&asdownload=true&recyclebin=${!!recyclebin}`;
        if (rendition) {
          uri += `&rendition=${rendition}&_intent=DOWNLOAD_${rendition}`;
        } else {
          uri += '&_intent=DOWNLOAD';
        }
        if (item.content.id === item.id) {
          uri += `&version=${item.version}`;
        }
        this.download(uri, fileNameWithVersionNumber ? item.version : null);
      } else {
        this.logger.error('The provided dms object has no content', item);
      }
    }

    if (dmsObjects.length > 1) {
      let uri = '/dms/batch/export';
      if (item.content) {
        const expressions = dmsObjects.map(obj => obj.content.id);
        const data = {
          query: {
            expression: [...expressions]
          },
          options: {
            rendition: ''
          }
        };
        data.options.rendition = rendition ? 'PDF' : null;
        this.downloadMulti(uri, fileNameWithVersionNumber ? item.version : null, data);
      } else {
        this.logger.error('The provided dms object has no content', item);
      }
    }
  }

  public download(uri: string, version?: number) {
    const baseUri = this.getContextPath();
    this.http.get(`${baseUri}${uri}`, {observe: 'response', responseType: 'blob', withCredentials: this.coreConfig.withCredentials})
      .subscribe((res) => {
        FileSaver.saveAs(
          res.body,
          this.getFileNameFromHttpResponse(res, version)
        );
      });
  }

  public downloadMulti(uri: string, version?: number, _body?: any) {
    const baseUri = this.getContextPath();
    this.http.post(`${baseUri}${uri}`, _body, {observe: 'response', responseType: 'blob', withCredentials: this.coreConfig.withCredentials})
      .subscribe((res) => {
        FileSaver.saveAs(
          res.body,
          this.getFileNameFromHttpResponse(res, version)
        );
      });
  }

  private getFileNameFromHttpResponse(res: HttpResponse<any>, version: number) {
    const contentDispositionHeader = res.headers.get('Content-Disposition') || '';
    const encodedFileNameMatchResult = contentDispositionHeader.match('filename\\*=UTF-8\'\'(.*)')
      || contentDispositionHeader.match('filename=\"(.*)\"');
    const encodedFileName = encodedFileNameMatchResult ? encodedFileNameMatchResult[1] : null;
    const filename = encodedFileName ? decodeURIComponent(encodedFileName) : 'unknown';
    const index = !~filename.lastIndexOf('.') ? filename.length : filename.lastIndexOf('.');
    return !version ? filename : `${filename.slice(0, index)}_v${version}${filename.slice(index)}`;
  }


  /**
   * Getter for the HTTP Headers
   *
   * @returns HttpHeaders
   */
  private setDefaultHeaders(): HttpHeaders {
    return new HttpHeaders({
      'Content-Type': 'application/json',
      'X-os-include-links': 'false',
      'X-os-include-actions': 'false',
      'X-os-sync-index': 'true'
    });
  }
}

results matching ""

    No results matching ""