UNPKG

@netgrif/components-core

Version:

Netgrif Application engine frontend core Angular library

1,355 lines (1,339 loc) 2.45 MB
import * as i0 from '@angular/core'; import { NgModule, Injectable, Inject, Component, InjectionToken, Optional, Input, Injector, ViewChild, ViewChildren, SkipSelf, EventEmitter, Output, TemplateRef, Type, Pipe, Directive } from '@angular/core'; import * as i2$1 from '@angular/common'; import { CommonModule, registerLocaleData, CurrencyPipe, DecimalPipe, getCurrencySymbol } from '@angular/common'; import { DragDropModule } from '@angular/cdk/drag-drop'; import { A11yModule } from '@angular/cdk/a11y'; import { CdkStepperModule } from '@angular/cdk/stepper'; import { CdkTableModule } from '@angular/cdk/table'; import { CdkTreeModule, NestedTreeControl } from '@angular/cdk/tree'; import { PortalModule, ComponentPortal, TemplatePortal } from '@angular/cdk/portal'; import { ScrollingModule, CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; import * as i1$3 from '@angular/forms'; import { FormsModule, ReactiveFormsModule, FormControl, Validators } from '@angular/forms'; import { FlexModule, FlexLayoutModule } from '@ngbracket/ngx-layout'; import { MatMomentDateModule, MomentDateAdapter } from '@angular/material-moment-adapter'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatBadgeModule } from '@angular/material/badge'; import { MatBottomSheetModule } from '@angular/material/bottom-sheet'; import * as i4 from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatCardModule } from '@angular/material/card'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatChipsModule } from '@angular/material/chips'; import { MatStepperModule } from '@angular/material/stepper'; import { MatDatepickerModule } from '@angular/material/datepicker'; import * as i1$2 from '@angular/material/dialog'; import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { MatDividerModule } from '@angular/material/divider'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatGridListModule } from '@angular/material/grid-list'; import * as i5 from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon'; import * as i4$1 from '@angular/material/input'; import { MatInputModule } from '@angular/material/input'; import { MatListModule } from '@angular/material/list'; import { MatMenuModule } from '@angular/material/menu'; import { MatPaginatorModule } from '@angular/material/paginator'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatProgressSpinnerModule, MatSpinner } from '@angular/material/progress-spinner'; import { MatRadioModule } from '@angular/material/radio'; import * as i2$3 from '@angular/material/core'; import { MatRippleModule, MatOptionModule, DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core'; import { MatSliderModule } from '@angular/material/slider'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatSelectModule } from '@angular/material/select'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import * as i1 from '@angular/material/snack-bar'; import { MatSnackBarModule, MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar'; import { MatSortModule } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { MatTabsModule } from '@angular/material/tabs'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTreeModule, MatTreeNestedDataSource } from '@angular/material/tree'; import * as i5$1 from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field'; import { CovalentMarkdownModule } from '@covalent/markdown'; import en$1 from '@angular/common/locales/en'; import sk$1 from '@angular/common/locales/sk'; import de$1 from '@angular/common/locales/de'; import * as i1$4 from 'rxjs'; import { BehaviorSubject, of, interval, ReplaySubject, throwError, Subject, Observable, forkJoin, combineLatest, timer, from, race } from 'rxjs'; import { map, distinctUntilChanged, catchError, tap, take, filter, debounceTime, startWith, defaultIfEmpty, switchMap, scan, mergeMap, reduce, concatMap, takeUntil } from 'rxjs/operators'; import * as i2 from '@angular/common/http'; import { HttpHeaders, HttpErrorResponse, HttpParams, HttpEventType, HttpClient, HTTP_INTERCEPTORS, HttpClientModule, HttpResponse, HttpHandler } from '@angular/common/http'; import { AngularResizeEventModule } from 'angular-resize-event'; import * as i2$4 from '@angular-material-components/datetime-picker'; import { NgxMatDatetimePickerModule } from '@angular-material-components/datetime-picker'; import { NgxMatMomentModule } from '@angular-material-components/moment-adapter'; import * as i1$1 from '@ngx-translate/core'; import { TranslateModule, TranslateLoader, TranslateService, TranslatePipe, TranslateStore } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import * as i3 from '@ngbracket/ngx-layout/flex'; import * as i2$2 from '@angular/platform-browser'; import moment from 'moment'; import { __decorate, __param } from 'tslib'; import * as Buffer from 'buffer'; import { ENTER, COMMA, SEMICOLON } from '@angular/cdk/keycodes'; import * as i3$1 from '@angular/router'; import { NavigationEnd, Router, ActivatedRoute } from '@angular/router'; import * as i1$5 from '@angular/cdk/overlay'; import { OverlayModule } from '@angular/cdk/overlay'; import { orderBy } from 'natural-orderby'; import * as i4$2 from 'angular2-hotkeys'; import { Hotkey } from 'angular2-hotkeys'; import semver from 'semver'; import 'hammerjs'; import * as i1$6 from '@angular/cdk/layout'; import { Breakpoints } from '@angular/cdk/layout'; import { HttpClientTestingModule } from '@angular/common/http/testing'; // TODO BUG 17.4.2020 - this file should contain very precise information about the intended structure of nae.json BUT this is a .d.ts file. // If we include other interfaces from the lib into this file, schematic compilation fails. Schematics reference this file without problem // but they can't reference files above their sourceRoot declared in their tsconfig file. Since this file is .d.ts it runs without anybody // noticing. However as soon as we include other interfaces from the lib here, schematics will reference them and fail to compile. // We need to find a good solution for this. class MaterialModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: MaterialModule, imports: [CommonModule, FlexLayoutModule], exports: [FlexModule, FlexLayoutModule, A11yModule, CdkStepperModule, CdkTableModule, CdkTreeModule, DragDropModule, MatAutocompleteModule, MatBadgeModule, MatBottomSheetModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatStepperModule, MatDatepickerModule, MatDialogModule, MatDividerModule, MatExpansionModule, MatGridListModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatMomentDateModule, MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule, MatTooltipModule, MatTreeModule, PortalModule, ScrollingModule, MatOptionModule, MatFormFieldModule, FormsModule, ReactiveFormsModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MaterialModule, imports: [CommonModule, FlexLayoutModule, FlexModule, FlexLayoutModule, A11yModule, CdkStepperModule, CdkTableModule, CdkTreeModule, DragDropModule, MatAutocompleteModule, MatBadgeModule, MatBottomSheetModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatStepperModule, MatDatepickerModule, MatDialogModule, MatDividerModule, MatExpansionModule, MatGridListModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatMomentDateModule, MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule, MatTooltipModule, MatTreeModule, PortalModule, ScrollingModule, MatOptionModule, MatFormFieldModule, FormsModule, ReactiveFormsModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MaterialModule, decorators: [{ type: NgModule, args: [{ declarations: [], imports: [ CommonModule, FlexLayoutModule ], exports: [ FlexModule, FlexLayoutModule, A11yModule, CdkStepperModule, CdkTableModule, CdkTreeModule, DragDropModule, MatAutocompleteModule, MatBadgeModule, MatBottomSheetModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatChipsModule, MatStepperModule, MatDatepickerModule, MatDialogModule, MatDividerModule, MatExpansionModule, MatGridListModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatMomentDateModule, MatPaginatorModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSidenavModule, MatSliderModule, MatSlideToggleModule, MatSnackBarModule, MatSortModule, MatTableModule, MatTabsModule, MatToolbarModule, MatTooltipModule, MatTreeModule, PortalModule, ScrollingModule, MatOptionModule, MatFormFieldModule, FormsModule, ReactiveFormsModule, ] }] }] }); class CovalentModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CovalentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: CovalentModule, exports: [CovalentMarkdownModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CovalentModule, imports: [CovalentMarkdownModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CovalentModule, decorators: [{ type: NgModule, args: [{ exports: [ CovalentMarkdownModule ] }] }] }); class CurrencyModule { constructor() { registerLocaleData(en$1); registerLocaleData(sk$1); registerLocaleData(de$1); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CurrencyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: CurrencyModule, imports: [CommonModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CurrencyModule, providers: [CurrencyPipe, DecimalPipe], imports: [CommonModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CurrencyModule, decorators: [{ type: NgModule, args: [{ declarations: [], imports: [ CommonModule ], providers: [CurrencyPipe, DecimalPipe] }] }], ctorParameters: () => [] }); var LogLevel; (function (LogLevel) { LogLevel[LogLevel["ALL"] = 0] = "ALL"; LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG"; LogLevel[LogLevel["INFO"] = 2] = "INFO"; LogLevel[LogLevel["WARN"] = 3] = "WARN"; LogLevel[LogLevel["ERROR"] = 4] = "ERROR"; LogLevel[LogLevel["OFF"] = 6] = "OFF"; })(LogLevel || (LogLevel = {})); class LogEntry { date; level; message; params; config; /** * Log entry class * @param level - Log level of this entry * @param message - message to write to the log * @param params - additional parameters to write into the log * @param config - extra class configuration */ constructor(level, message, params, config) { this.date = new Date(); this.level = level; this.message = message; this.params = params; const defaults = { logWithDate: true, serializeParams: true, includeLogLevel: true }; this.config = { ...defaults, ...config }; } get levelString() { return LogLevel[this.level.toString()]; } /** * Serialization of additional parameters of the entry. * @return Serialized JSON */ serializeParams() { if (!this.config.serializeParams) { return ''; } return JSON.stringify(this.params); } /** * Stringify log entry. According to configuration entry can include time, log level and extra parameters * @return Log string */ toString() { let str = ''; if (this.config.logWithDate) { str += '[' + this.date.toISOString() + '] '; } if (this.config.includeLogLevel) { str += '<' + this.levelString + '> '; } str += this.message; if (this.config.serializeParams && this.params) { if (this.params instanceof Array) { if (this.params.length !== 0) { str += ' , params: ' + this.serializeParams(); } } else { str += ' , params: ' + this.serializeParams(); } } return str; } } class LogPublisher { location; constructor(publisherService) { publisherService .register(this) .subscribe(entry => { if (entry) { this.log(entry); } }); } } class ConsoleLogPublisher extends LogPublisher { constructor(publisherService) { super(publisherService); } clear() { console.clear(); } log(entry) { if (!entry) { return; } switch (entry.level) { case LogLevel.DEBUG: console.debug(entry.toString()); break; case LogLevel.ERROR: console.error(entry.toString()); break; case LogLevel.INFO: console.info(entry.toString()); break; case LogLevel.WARN: console.warn(entry.toString()); break; default: console.log(entry.toString()); } } } class LocalStorageLogPublisher extends LogPublisher { static DEFAULT_KEY = 'application-log'; constructor(publisherService, logKey) { super(publisherService); this.location = !logKey ? LocalStorageLogPublisher.DEFAULT_KEY : logKey; } clear() { localStorage.removeItem(this.location); } log(entry) { if (!entry) { return; } const logString = localStorage.getItem(this.location); let log; if (!logString) { log = []; } else { log = JSON.parse(logString); } log.push(entry); try { localStorage.setItem(this.location, JSON.stringify(log)); } catch (e) { const deleted = log.splice(0, 1)[0]; console.debug('Log entry from ' + deleted.date.toISOString() + ' was deleted from the LocalStorage \'' + this.location + '\''); try { localStorage.setItem(this.location, JSON.stringify(log)); } catch (ex) { console.error(ex); throw new Error(ex.message); } } } } class ConfigurationService { configuration; _configurationResource; _applicationConfiguration; _dataFieldConfiguration; APPLICATION_CONFIG; _config$ = new BehaviorSubject(null); config$ = this._config$.asObservable(); loaded$ = this.config$.pipe(map(cfg => !!cfg), distinctUntilChanged()); constructor(configuration, _configurationResource, _applicationConfiguration) { this.configuration = configuration; this._configurationResource = _configurationResource; this._applicationConfiguration = _applicationConfiguration; this.APPLICATION_CONFIG = _applicationConfiguration; if (!this._applicationConfiguration?.resolve_configuration) { this.initialize(); } } get snapshot() { return this.configuration ? this.createConfigurationCopy() : null; } initialize() { this.resolveEndpointURLs(); this._dataFieldConfiguration = this.getConfigurationSubtree(['services', 'dataFields']); this._config$.next(this.createConfigurationCopy()); } getAsync() { return of(this.get()); } /** * Calls to this method should be avoided as creating a deep copy of the configuration has a large overhead * * @returns a deep copy of the entire configuration object */ get() { return this.createConfigurationCopy(); } /** * Get view configuration from nae.json for view at given config path. * @param viewConfigPath configuration path to the requested view. No leading backslash. * @return requested configuration if it exists. `undefined` otherwise. */ getViewByPath(viewConfigPath) { const viewPathSegments = viewConfigPath.split('/'); const configTreePathSegments = ['views']; for (let i = 0; i < viewPathSegments.length; i++) { if (i > 0) { configTreePathSegments.push('children'); } configTreePathSegments.push(viewPathSegments[i]); } return this.getConfigurationSubtree(configTreePathSegments); } /** * Get view configuration from nae.json for view at given url. * @param url to the requested view. Necessary backslash. * @return requested configuration if it exists. `undefined` otherwise. */ getViewByUrl(url) { const views = this.getViewsCopy(); if (!views) { return undefined; } let map = new Map(); map = this.getChildren(views, map, ''); if (map.get(url) === undefined) { for (const [key, value] of map) { if (key?.includes('/**') && url?.includes(key.split('/**')[0])) return value; } } return map.get(url); } getChildren(views, map, prefix) { Object.keys(views).forEach(view => { if (!!views[view].routing.path) { prefix = prefix.charAt(prefix.length - 1) === '/' ? prefix.length > 1 ? prefix.substring(0, prefix.length - 2) : '' : prefix; const viewPath = views[view].routing.path.charAt(0) === '/' ? views[view].routing.path.length > 1 ? views[view].routing.path.substring(1) : '' : views[view].routing.path; map.set(views[view].routing.match ? prefix + '/' + viewPath + '/**' : prefix + '/' + viewPath, views[view]); } if (views[view].children) { this.getChildren(views[view].children, map, prefix + '/' + views[view].routing.path); } }); return map; } /** * Get all URLs/paths of views with specified layout. * @param layout Search views with this layout * @returns Paths with prefixed '/' of all views with specified layout, empty array otherwise. */ getPathsByView(layout) { const config = this.createConfigurationCopy(); const result = []; if (!config.views) { return result; } Object.values(config.views).forEach(view => { result.push(...this.getView(layout, view).map(path => '/' + path)); }); return result; } getConfigurationSubtreeByPath(path) { return this.getConfigurationSubtree(path.split('.')); } /** * @param pathSegments the keys specifying the path trough the configuration that should be accessed * @returns a deep copy of a specified subsection of the configuration object, or `undefined` if such subsection doesn't exist. * Calling this method with an empty array as argument is equivalent to calling the [get()]{@link ConfigurationService#get} method. */ getConfigurationSubtree(pathSegments) { let root = this.configuration; for (const segment of pathSegments) { if (root[segment] === undefined) { return undefined; } root = root[segment]; } return this.deepCopy(root); } /** * @returns the appropriate template configuration for data fields, or `undefined` if such configuration is not present. */ getDatafieldConfiguration() { if (this._dataFieldConfiguration === undefined) { return undefined; } return { ...this._dataFieldConfiguration }; } /** * Resolves the URL addresses of backend endpoints based on the provided configuration. * * If the URLs begin with either `http://`, or `https://` the provided URL will be used. * * If not, then the URLs are considered to be relative to the location of the frontend application and it's URL will be used * as the base path. `/api` is appended automatically. */ resolveEndpointURLs() { if (this.configuration?.providers?.auth?.address === undefined) { throw new Error(`'provider.auth.address' is a required property and must be present in the configuration!`); } this.configuration.providers.auth.address = this.resolveURL(this.configuration.providers.auth.address); if (this.configuration?.providers?.resources === undefined) { throw new Error(`'provider.resources' is a required property and must be present in the configuration!`); } if (Array.isArray(this.configuration.providers.resources)) { this.configuration.providers.resources.forEach(resource => { if (resource?.address === undefined) { throw new Error(`Resources defined in 'provider.resources' must define an address property!`); } resource.address = this.resolveURL(resource.address); }); } else { if (this.configuration?.providers?.resources?.address === undefined) { throw new Error(`Resources defined in 'provider.resources' must define an address property!`); } this.configuration.providers.resources.address = this.resolveURL(this.configuration.providers.resources.address); } } /** * Resolves a single URL address. * * If the URL begins with either `http://`, or `https://` the provided URL will be used. * * If not, then the URL is considered to be relative to the location of the frontend application and it's URL will be used * as the base path. `/api` is appended automatically. * * @param configURL value from the configuration file * @returns the resolved URL */ resolveURL(configURL) { if (configURL.startsWith('http://') || configURL.startsWith('https://')) { return configURL; } else { return location.origin + '/api' + configURL; } } /** * @returns the services configuration, or `undefined` if such configuration is not present. */ getServicesConfiguration() { const subtree = this.getConfigurationSubtree(['services']); return subtree !== undefined ? this.deepCopy(subtree) : undefined; } /** * @returns the value stored in the [onLogoutRedirect]{@link Services#auth.onLogoutRedirect} attribute if defined. * If not and the deprecated attribute [logoutRedirect]{@link Services#auth.logoutRedirect} is defined then its value is returned. * Otherwise, `undefined` is returned. */ getOnLogoutPath() { return this.configuration?.services?.auth?.onLogoutRedirect ?? this.configuration?.services?.auth?.logoutRedirect; } /** * @returns the value stored in the [toLoginRedirect]{@link Services#auth.toLoginRedirect} attribute if defined. * If not and the deprecated attribute [loginRedirect]{@link Services#auth.loginRedirect} is defined then its value is returned. * Otherwise, `undefined` is returned. */ getToLoginPath() { return this.configuration?.services?.auth?.toLoginRedirect ?? this.configuration?.services?.auth?.loginRedirect; } /** * @returns the value stored in the [onLoginRedirect]{@link Services#auth.onLoginRedirect} attribute if defined. * Otherwise, `undefined` is returned. */ getOnLoginPath() { return this.configuration?.services?.auth?.onLoginRedirect; } getView(searched, view) { const paths = []; if (!!view.layout && view.layout.name === searched) { paths.push(view.routing.path); } if (view.children && Object.keys(view.children).length !== 0) { Object.values(view.children).forEach(child => { paths.push(...this.getView(searched, child).map(path => view.routing.path + '/' + path)); }); } return paths; } /** * @param endpointKey the attribute name of the endpoint address in `nae.json` * @returns the endpoint address or `undefined` if such endpoint is not defined in `nae.json` */ resolveProvidersEndpoint(endpointKey) { const config = this.configuration; if (!config || !config.providers || !config.providers.auth || !config.providers.auth.address || !config.providers.auth.endpoints || !config.providers.auth.endpoints[endpointKey]) { throw new Error('Authentication provider address is not set!'); } return config.providers.auth.address + config.providers.auth.endpoints[endpointKey]; } /** * Loads and initializes application configuration from the backend. * If configuration resolution is disabled in APPLICATION_CONFIG, returns null Observable. * Otherwise fetches public configuration via ConfigurationResourceService. * * @returns Observable<any> that emits null if resolution is disabled, otherwise emits the loaded configuration * @fires initialize() Upon successful configuration load to setup endpoints and data field configurations * @see ApplicationConfiguration * @see NetgrifApplicationEngine */ loadConfiguration() { if (!this.APPLICATION_CONFIG?.resolve_configuration) { return of(void 0); } return this._configurationResource.getPublicApplicationConfiguration(this.APPLICATION_CONFIG).pipe(catchError((err) => { if (err.status === 404) { return of(null); } console.log(err.message); return of(null); }), tap((data) => { if (!data?.properties) { return; } this.configuration = data.properties; this.initialize(); }), take(1), map(() => void 0)); } createConfigurationCopy() { return this.deepCopy(this.configuration); } getViewsCopy() { return this.getConfigurationSubtree(['views']); } deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); } } const PUBLISHERS = { console: ConsoleLogPublisher, localStorage: LocalStorageLogPublisher, backend: null }; class LogPublisherService { // public static instance: LogPublisherService; _log; _publishers; constructor(config) { // LogPublisherService.instance = this; this._log = new BehaviorSubject(null); this._publishers = []; const serviceConfig = config.get().services; if (serviceConfig && serviceConfig.log && serviceConfig.log.publishers) { Object.keys(PUBLISHERS).filter(p => serviceConfig.log.publishers?.includes(p) && PUBLISHERS[p]) .forEach(key => new PUBLISHERS[key](this)); } } ngOnDestroy() { this._log.complete(); } get publishers() { return this._publishers; } register(publisher) { if (!publisher) { return of(null); } this._publishers.push(publisher); return this._log; } publish(entry) { if (!entry) { return; } this._log.next(entry); } clearAll() { this._publishers.forEach(publisher => publisher.clear()); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LogPublisherService, deps: [{ token: ConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LogPublisherService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LogPublisherService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: ConfigurationService }] }); class AbstractLoggerService { publisherService; config; publisher; constructor(publisherService, _config) { this.publisherService = publisherService; this.publisher = publisherService; this.config = { logWithDate: true, serializeParams: true, level: LogLevel.ALL }; const servicesConfig = _config.get().services; if (servicesConfig && servicesConfig.log) { this.config = Object.assign(this.config, servicesConfig.log, { level: this.resolveLevel(servicesConfig.log.level) }); } } get level() { return this.config.level; } shouldLog(level) { return (level >= this.level && level !== LogLevel.OFF) || this.level === LogLevel.ALL; } writeToLog(level, message, params) { if (!this.shouldLog(level)) { return; } const entry = new LogEntry(level, message, params, this.config); this.publisher.publish(entry); } info(message, ...params) { this.writeToLog(LogLevel.INFO, message, params); } debug(message, ...params) { this.writeToLog(LogLevel.DEBUG, message, params); } warn(message, ...params) { this.writeToLog(LogLevel.WARN, message, params); } error(message, ...params) { this.writeToLog(LogLevel.ERROR, message, params); } log(level, message, ...param) { this.writeToLog(level, message, param); } resolveLevel(level) { if (!level) { return LogLevel.OFF; } return LogLevel[level]; } } class LoggerService extends AbstractLoggerService { constructor(publisherService, config) { super(publisherService, config); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LoggerService, deps: [{ token: LogPublisherService }, { token: ConfigurationService }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LoggerService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LoggerService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: LogPublisherService }, { type: ConfigurationService }] }); /* SERVICES */ class CustomDateAdapter extends MomentDateAdapter { getFirstDayOfWeek() { return 1; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDateAdapter, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDateAdapter }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDateAdapter, decorators: [{ type: Injectable }] }); var toolbar$2 = { menu: { lang: "Language", profile: "Profile", logout: "Logout", en: "English", sk: "Slovak", de: "German", open: "Open menu", home: "Home", back: "Back", folders: "Folders", views: "Views" } }; var tasks$2 = { snackbar: { noTasksFound: "No tasks found", failedToLoad: "failed to load", noData: "No data for task", noGroup: "No data group for task", dataSaved: "Data saved successfully", failedSave: "Saving data failed", assignTask: "Assigning task", assignTaskSuccess: "Task assigned successfully", delegateTask: "Delegating task", delegateTaskSuccess: "Task successfully delegated", failed: "failed", cancelTask: "Canceling assignment of task", cancelTaskSuccess: "Task successfully canceled", finishTask: "Finishing task", finishTaskSuccess: "Task successfully finished", invalidData: "Some fields have invalid values", missingRequired: "Some required fields are empty", noCase: "No cases found", caseGetFailed: "Getting cases failed", noLongerExists: "The selected task no longer exists", caseDeleteFailed: "Case could not be deleted", caseDeleteSuccess: "Case successfully deleted", rolesSuccessAssign: "Roles successfully assigned to selected users" }, view: { noTasksSatisfyingThisFilter: "There are no tasks satisfying this filter", collapse: "Collapse", assign: "Assign", reassign: "Reassign", delegate: "Delegate", finish: "Finish", cancel: "Cancel", noData: "This task has no data. Finish to continue.", redirecting: "Redirecting...", closeTab: "Close" }, footer: { defaultText: "NETGRIF, s.r.o. © 2022" } }; var search$2 = { category: { "case": { title: { name: "Case title", placeholder: "Enter case title" }, visualId: { name: "Case visual ID", placeholder: "Enter case visual ID" }, stringId: { name: "Case ID", placeholder: "Enter case ID" }, author: { name: "Case author", placeholder: "Enter author's name or email" }, process: { name: "Case process", placeholder: "Select case process" }, role: { name: "Process role", placeholder: "Select process role" }, task: { name: "Case task", placeholder: "Select case task" }, creationDate: { name: "Case creation date", placeholder: "Select case creation date" }, creationDateTime: { name: "Case creation date and time", placeholder: "Select case creation date and time" }, dataset: { name: "Case data", placeholder: { field: "Select data field", value: "Enter data field value" } } }, task: { assignee: { name: "Task assignee", placeholder: "Select task assignee" }, process: { name: "Task process", placeholder: "Select task process" }, role: { name: "Task process role", placeholder: "Select task process role" }, task: { name: "Task", placeholder: "Select task" } }, select: "Search category", userMe: "ME" }, operator: { name: "Operator", substring: "contains substring", inRange: { from: "from", to: "to" }, equals: "is exactly", notEquals: "is different from", moreThan: "is more than", lessThan: "is less than", lessThanEqual: "is less or equal than", moreThanEqual: "is more or equal than", like: "is like", isNull: "is empty" }, tooltip: { toAdvanced: "Switch to advanced search", toFullText: "Switch to basic search", help: "Help", save: "Save filter", load: "Load filter" }, help: { title: "Advanced search help", text: "Advanced search can be used to create more complex search queries. Start by selecting a search category. Search category determines, what you want your query to look for. Some categories (like searching in case data) require further configuration. Afterwards you have to select a search operator. The operator determines how the query attempts to match your data. Are you looking for numbers from a specific range? Are you looking for an exact match? Finally you have to enter the searched value. You can combine simpler queries into more complicated ones by binding them with an OR or an AND keyword. Queries combined with OR find results that match at least one sub-query. Queries combined with AND find results that match all sub-queries." }, fullText: "Enter searched phrase", and: "and", or: "or" }; var dataField$2 = { validations: { required: "This field is required!", requiredTrue: "Entered value must be true", odd: "Entered number must be odd", even: "Entered number must be even", positive: "Entered number must be positive", negative: "Entered number must be negative", decimal: "Entered number must be decimal", inrange: "Entered number must be in range {{range}}", minLength: "Entered text must be at least {{length}} characters long", maxLength: "Entered text must be at most {{length}} characters long", pattern: "Entered text is in a wrong format", phone: "Entered text must be in telephone number format", email: "Entered text must be in email format", dateRange: "Entered date must be between {{left}} and {{right}}", datePast: "Entered date must be earlier than {{right}}", dateFuture: "Entered date must be later than {{left}}", weekend: "Entered date must be weekend day", workday: "Entered date must be week day", enumeration: "One of the options must be selected", min: "Entered number must be greater than {{length}}", translationRequired: "Translation for languages: <{{translation}}> must be entered", translationOnly: "Only translation for languages: <{{translation}}> is allowed", requiredI18n: "At least one value must be entered", requiredUserList: "At least one value must be entered" }, snackBar: { downloadFail: " failed to download", moreFiles: "You choose more files as you allowed", sameFiles: "You cannot upload two of the same files", fileSize: "Files size exceeded allowed limit", wontUploadSameFile: "The file already exists. If you want to update the file, please renamed it or delete existing file", wontUploadSameFiles: "The selected files have already been uploaded. To update files, delete files that have already been uploaded", fileUploadFailed: "The file failed to upload", fileDeleteFailed: "The file could not be deleted", maxFilesExceeded: "Maximum number of uploadable files exceeded: ", maxFilesSizeExceeded: "The maximum size of uploaded files is exceeded: ", notSelectedUser: "No user has been selected", userAssigned: "User {{userName}} was assigned", userListAssigned: "Selected users {{userNames}} were assigned" }, values: { boolean: { "true": "true", "false": "false" } }, clear: "Clear", save: "Save", noFile: "No file", file: { noFile: "No File", clickToUpload: "Click to upload file", clickToDownload: "Click to download {{fileName}}", clickToOpen: "Click to view file content", clickToDelete: "Click to delete file", notAllowed: "File {{fileName}} can't be uploaded. Its filetype is not allowed." }, i18n: { languageSelect: "Select language", deleteTranslation: "Delete translation", showTranslations: "Show translations", hideTranslations: "Hide translations" }, dynamicEnum: { noData: "No items match your search" }, "enum": { reset: "Reset" }, user: { selectUser: "Select user", deleteUser: "Delete user", save: "Assign", deleteAll: "Empty user list" }, textarea: { insertText: "Insert text here..." } }; var dialog$2 = { close: "Close", submit: "Submit" }; var forms$2 = { email: { enterEmail: "Enter your email" }, login: { length: "The login name must have at least 4 letters", login: "Username", wrongCredentials: "Wrong credentials!", loginButton: "Log in", ssoButton: "Log with SSO", reset: "Reset password", sign: "Sign Up", enterPass: "Enter your password" }, changePassword: { oldPassword: "Enter your old password", enterNewPass: "Enter your new password", repeatNewPass: "Repeat your new password", changePass: "Change password" }, register: { email: "Your email", name: "Name", surname: "Surname", repeatPass: "Repeat your password", register: "Register", notVerified: "It is not possible to verify token!", passwordsMustMatch: "The passwords must match!" }, forgottenPass: { enterNewPass: "Enter your new password", repeatNewPass: "Repeat your new password", recover: "Change password" } }; var headers$2 = { newHeader: "Select new header", date: "Choose a date", dateTime: "Choose a date and time", selectUser: "Choose a user", caseMeta: { mongoID: "Case ID", visualID: "Visual ID", title: "Title", author: "Author", creationDate: "Creation date" }, taskMeta: { "case": "Case", caseID: "Case ID", taskID: "Task ID", priority: "Priority", user: "Assignee", assignDate: "Assign Date" }, workflowMeta: { initials: "Initials", version: "Version", netId: "Process ID", creationDate: "Upload date", title: "Title", author: "Author" }, orderMode: "Ordering mode", searchMode: "Search mode", editMode: "Enable edit mode", overflowMode: "Table mode", columnWidth: "Column width", columnCount: "Number of columns" }; var panel$2 = { "case": { "delete": "Delete" }, workflow: { net: "Net identifier", title: "Title", version: "Version", author: "Author", upload: "Upload date" } }; var profile$2 = { notLogged: "You are not logged in!", general: "General Information", personal: "Personal Information", name: "First name", surname: "Last name", authority: "Authorities", roles: "Roles", groups: "Groups", preference: "Preferences", caseHead: "Case headers", caseFilter: "Case filters", taskHead: "Task headers", taskFilter: "Task filters", workHead: "Workflow headers", workFilter: "Workflow filters" }; var admin$2 = { "user-list": { noUsersWereFound: "There are any user in the system at the moment", listTitle: "Users" }, "ldapGroup-list": { noLdapGroupsWereFound: "No LDAP group was found", listTitle: "LDAP groups", count: "Number of groups" }, "process-list": { newestVersion: "Newest version", listTitle: "Processes", roles: "Roles", noRoles: "There are no roles in the process", noProcessesWereFound: "There are no processes in the system at the moment" }, "user-invite": { newUser: "New User", orgs: "Organizations", selectedOrgs: "Selected Organizations", selectedRoles: "Selected Roles", mail: "Enter Email", noSelectedOrgs: "There is no organisation assigned to this user yet!", noSelectedRoles: "There is no role assigned to this user yet!", noOrgs: "There is no available groups for now!", version: "Version", emailFieldMandatory: "Email field is mandatory", oneOrMoreOrganization: "New user must belong to one or more groups", inviteSent: "Invite sent", inviteFailed: "Invite failed", "invite-user": "INVITE USER" } }; var preferences$2 = { snackbar: { saveSuccess: "User preferences saved successfully", saveFailure: "An error occurred while saving user preferences" } }; var caseTree$2 = { newNodeDefaultName: "New Node", noTaskSelected: "No case is currently selected. Click on a node in the tree to select a case." }; var dashboard$2 = { cases: "cases" }; var workflow$2 = { "delete": "delete", download: "download", dialog: { header: "Are you sure you want to delete the process '{{name}}' with version '{{version}}'?", content: "Doing so will remove all cases created from this process!", typeToConfirm: "Type {{delete}} to confirm" }, snackBar: { deleteCanceled: "Process delete canceled", deleteSuccess: "Process successfully deleted", deleteInProgress: "The process has been marked for deletion, the deletion is now underway", deleteError: "Process could not be deleted", uploadFailed: "Process file could not be uploaded.", uploadSuccess: "Process file uploaded successfully" } }; var legal$2 = { byClicking: "By clicking '{{buttonName}}',", youIndicate: "you are indicating that you have read and acknowledge the", termsOfService: "Terms of Service", and: "and", privacyNotice: "Privacy Notice", sentenceEnd: "" }; var publicView$2 = { resolving: "Public view is loading ...", netNotExist: "The process does not exists", errorCreate: "Error while creating case " }; var dynamicNavigation$2 = { couldNotResolveView: "An error has occurred during the view resolution process. The view could not be displayed", filterNotFound: "This view has no filter", loadMoreItems: "More", ascending: "Ascending", descending: "Descending" }; var impersonation$2 = { user: { successfullyRepresented: "User successfully represented", currentlyAlreadyRepresented: "User is already being represented by someone else", currentlyLogged: "User is currently logged in" }, action: { failed: "Action failed", deactivated: "Representation was successfully deactivated" } }; var session$2 = { expireTitle: "Your Session is about to expire", expireDetail: "Your session is about to expire.\n\nRedirecting to Login page in {{time}} seconds.", exitButton: "Logout", refreshButton: "Stay Connected" }; var paginator$2 = { firstPage: "First page", itemsPage: "Items per page:", lastPage: "Last page", nextPage: "Next page", previousPage: "Previous page", pageOne: "Page 1 of 1", pageAmount: "Page {{page}} of {{amountPages}}" }; var en = { toolbar: toolbar$2, tasks: tasks$2, "side-menu": { "filter-selector": { "choose-filter": "Choose a filter", "search-filter": "Search filters", "case-filters": "Case filters", "task-filters": "Task filters", select: "Select" }, "files-upload": { upload: "Upload files", send: "Send" }, "import-net": { upload: "Upload model", choose: "Choose a process file", done: "Done", search: "Search for process" }, "new-case": { "case": "New Case", choose: "Choose process", caseTitle: "Fill out case title", color: "Choose case color", back: "Back", next: "Next", reset: "Reset", create: "Create", selection: "You must make a selection", errFirst: "Process is required.", errSecond: "Title is required.", errThird: "Color is required.", noNets: "No allowed Nets", createCase: "Successful create new case", defaultCaseName: "with default case name", errorCreate: "Error while creating case ", createCaseError: "A new case was created, but an error occurred while executing actions" },