@ui-tool/core
Version:
1,287 lines (1,233 loc) • 182 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, ComponentFactoryResolver, ChangeDetectorRef, ViewContainerRef, Component, ChangeDetectionStrategy, Input, ViewChild, PLATFORM_ID, NgModule, Directive, Inject, InjectFlags, Injector, Pipe, HostBinding, Injectable, Optional, ContentChildren } from '@angular/core';
import { Subscription, of, throwError, ReplaySubject, Subject, from, forkJoin } from 'rxjs';
import { Router, RouterEvent, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, RouterModule } from '@angular/router';
import { switchMap, map, filter, tap, mergeMap, retryWhen, catchError, distinctUntilChanged, debounceTime, delay } from 'rxjs/operators';
import { findLastIndex, merge, cloneDeep } from 'lodash-es';
import * as i1 from '@angular/common';
import { isPlatformBrowser, CommonModule, DOCUMENT } from '@angular/common';
import { v4 } from 'uuid';
import * as i1$1 from '@angular/forms';
import { FormControl, FormControlDirective, NgModel, AbstractControl, NgControl, FormControlName, FormArray, FormGroup } from '@angular/forms';
import { __decorate, __param, __awaiter } from 'tslib';
import * as i1$2 from '@angular/platform-browser';
// Multiple validation summarizer
const COMMON_VALIDATOR_SERVICE = new InjectionToken('COMMON_VALIDATOR_SERVICE');
const COMMON_VALIDATOR_OPTIONS = new InjectionToken('COMMON_VALIDATOR_OPTIONS');
const COMMON_VALIDATOR_OPTIONS_PROVIDER = new InjectionToken('COMMON_VALIDATOR_OPTIONS_PROVIDER');
// Spinner providers.
const SPINNER_SERVICE = new InjectionToken('SPINNER_SERVICE');
const SPINNER_METHOD_INVOKE_CALLBACK = new InjectionToken('SPINNER_METHOD_INVOKE_CALLBACK');
const SPINNER_REQUEST_ID = new InjectionToken('SPINNER_REQUEST_ID');
const SPINNER_HOST = new InjectionToken('SPINNER_HOST');
const DISPLAY_SPINNER_OPTIONS = new InjectionToken('DISPLAY_SPINNER_OPTIONS');
// Banner providers.
const BANNER_SERVICE = new InjectionToken('BANNER_SERVICE');
const BANNER_BUILDER = new InjectionToken('BANNER_BUILDER');
// Smart navigator providers.
const SMART_NAVIGATOR_SERVICE = new InjectionToken('SMART_NAVIGATOR_SERVICE');
const SMART_NAVIGATOR_ROUTES = new InjectionToken('SMART_NAVIGATOR_ROUTES');
const SMART_NAVIGATOR_SCREEN_CODE_RESOLVER = new InjectionToken('SMART_NAVIGATOR_SCREEN_CODE_RESOLVER');
// Dialog providers.
const DIALOG_BUILDER = new InjectionToken('DIALOG_BUILDER');
const DIALOG_SERVICE = new InjectionToken('DIALOG_SERVICE');
// Windows provider.
const WINDOW = new InjectionToken('WINDOW');
// Sentinel providers
const REQUIREMENT_SENTINEL_SERVICE = new InjectionToken('REQUIREMENT_SENTINEL_SERVICE');
const REQUIREMENT_SENTINEL_EXCEPTION_PROCESSOR = new InjectionToken('REQUIREMENT_SENTINEL_EXCEPTION_PROCESSOR');
const REQUIREMENT_HANDLER = new InjectionToken('REQUIREMENT_HANDLER');
const FEATURE_SENTINEL_SERVICE = new InjectionToken('FEATURE_SENTINEL_SERVICE');
const ROLE_SENTINEL_SERVICE = new InjectionToken('ROLE_SENTINEL_SERVICE');
const STACK_SERVICE = new InjectionToken('STACK_SERVICE');
const ASSET_SERVICE = new InjectionToken('ASSET_SERVICE');
// Multiple validation summarizer
const MULTIPLE_VALIDATION_SUMMARIZER_SERVICE = new InjectionToken('MULTIPLE_VALIDATION_SUMMARIZER_SERVICE');
const MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS = new InjectionToken('MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER');
const MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER = new InjectionToken('MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER');
// Validation summarizer providers.
const VALIDATION_SUMMARIZER_SERVICE = new InjectionToken('VALIDATION_SUMMARIZER_PROVIDER');
const VALIDATION_ITEM_TEMPLATE_BUILDERS = new InjectionToken('VALIDATION_ITEM_TEMPLATE_BUILDERS_PROVIDER');
const VALIDATION_SUMMARIZER_OPTIONS_PROVIDER = new InjectionToken('VALIDATION_SUMMARIZER_OPTION_PROVIDER');
// Key-value which is used for mapping validation error with its actual display.
const builtInValidationMessages = {
required: 'MSG_VALIDATION_PROPERTY_REQUIRED',
min: 'MSG_VALIDATION_PROPERTY_MIN',
max: 'MSG_VALIDATION_PROPERTY_MAX',
minlength: 'MSG_VALIDATION_PROPERTY_MIN_LENGTH',
maxlength: 'MSG_VALIDATION_PROPERTY_MAX_LENGTH',
pattern: 'MSG_VALIDATION_PROPERTY_PATTERN',
email: 'MSG_VALIDATION_PROPERTY_EMAIL'
};
class DialogResultConstant {
}
//#region Properties
DialogResultConstant.reject = 'DISMISS';
DialogResultConstant.resolve = 'MANUALLY_CLOSED';
class DialogBuilderExceptionConstant {
}
//#region Properties
DialogBuilderExceptionConstant.invalidDialogSettings = 'INVALID_DIALOG_SETTINGS';
class DialogKindConstant {
}
//#region Properties
DialogKindConstant.confirmation = 'confirmation';
DialogKindConstant.error = 'error';
DialogKindConstant.info = 'info';
DialogKindConstant.warning = 'warning';
class SmartNavigatorExceptions {
}
//#region Properties
SmartNavigatorExceptions.invalidScreenCode = 'INVALID_SCREEN_CODE';
SmartNavigatorExceptions.invalidNavigationRequest = 'INVALID_NAVIGATION_REQUEST';
SmartNavigatorExceptions.screenCodeMappingNotFound = 'SCREEN_CODE_MAPPING_NOT_FOUND';
SmartNavigatorExceptions.urlNotFound = 'SCREEN_URL_NOT_FOUND';
class SpinnerCommands {
}
//#region Properties
SpinnerCommands.display = 'DISPLAY_SPINNER';
SpinnerCommands.close = 'CLOSE_SPINNER';
SpinnerCommands.purge = 'PURGE_SPINNER';
var StackItemEvents;
(function (StackItemEvents) {
StackItemEvents["ITEM__DELETED"] = "ITEM__DELETED";
StackItemEvents["ITEM__PUSHED"] = "ITEM__PUSHED";
})(StackItemEvents || (StackItemEvents = {}));
var Visibilities;
(function (Visibilities) {
Visibilities[Visibilities["hidden"] = 0] = "hidden";
Visibilities[Visibilities["visible"] = 1] = "visible";
})(Visibilities || (Visibilities = {}));
class ConfirmationDialogSettings {
//#endregion
//#region Constructor
constructor(message, title, icon, injector) {
this.kind = DialogKindConstant.confirmation;
this.message = message;
this.title = title || '';
this.icon = icon;
this.injector = injector;
this.backdropClasses = [];
this.buttons = [];
this.centered = true;
this.dialogClasses = [];
this.disableClose = false;
}
}
// tslint:disable-next-line:no-empty-interface
class ErrorDialogSettings {
//#endregion
//#region Constructor
constructor(message, title, icon, injector) {
this.kind = DialogKindConstant.error;
this.message = message;
this.title = title || '';
this.icon = icon;
this.injector = injector;
this.backdropClasses = [];
this.buttons = [];
this.centered = true;
this.dialogClasses = [];
this.disableClose = false;
}
}
// tslint:disable-next-line:no-empty-interface
class InfoDialogSettings {
//#endregion
//#region Constructor
constructor(message, title, icon, injector) {
this.kind = DialogKindConstant.info;
this.message = message;
this.title = title || '';
this.icon = icon;
this.injector = injector;
this.backdropClasses = [];
this.buttons = [];
this.centered = true;
this.dialogClasses = [];
this.disableClose = false;
}
}
class WarningDialogSettings {
//#endregion
//#region Constructor
constructor(message, title, icon, injector) {
this.kind = DialogKindConstant.warning;
this.message = message;
this.title = title || '';
this.icon = icon;
this.injector = injector;
this.backdropClasses = [];
this.buttons = [];
this.centered = true;
this.dialogClasses = [];
this.disableClose = false;
}
}
class BasicDialogButton {
//#endregion
//#region Constructor
constructor(content, clickHandler, classes) {
this.content = content;
this.clickHandler = clickHandler;
this.classes = classes;
}
}
class DialogResult {
//#endregion
//#region Constructor
constructor(action, data) {
this._action = action;
this._data = data;
}
//#endregion
//#region Accessor
// Modal dialog action.
get action() {
return this._action;
}
// Data.
get data() {
return this._data;
}
}
class TemplateDialogButton {
//#endregion
//#region Constructor
constructor(content) {
this.content = content;
}
}
class NavigateToScreenRequest {
//#endregion
//#region Constructor
constructor(code, routeParams, extras) {
this.code = code;
this.routeParams = routeParams;
this.extras = extras;
}
}
class DeleteSpinnerCommand {
//#endregion
//#region Constructor
constructor(containerId, id) {
this.kind = SpinnerCommands.close;
this.containerId = containerId;
this.id = id;
}
}
class DisplaySpinnerCommand {
//#endregion
//#region Constructor
constructor(containerId, id, options) {
this.containerId = containerId;
this.id = id;
this.options = options;
this.kind = SpinnerCommands.display;
}
}
class DisplaySpinnerOptions {
}
class PurgeSpinnerCommand {
//#endregion
//#region Constructor
constructor(containerId) {
this.containerId = containerId;
this.kind = SpinnerCommands.purge;
}
}
class StackItemOptions {
}
class StackItemDeletedEvent {
//#endregion
//#region Constructor
constructor(stackCode, itemIds) {
this.stackCode = stackCode;
this.itemIds = itemIds;
this.kind = StackItemEvents.ITEM__DELETED;
this.stackCode = stackCode;
}
}
class StackItemPushedEvent {
//#endregion
//#region Constructor
constructor(stackCode, id, itemIds) {
this.stackCode = stackCode;
this.id = id;
this.itemIds = itemIds;
this.kind = StackItemEvents.ITEM__PUSHED;
this.stackCode = stackCode;
this.id = id;
}
}
class ValidationItemBuildContext {
//#region Constructor
constructor(containerGroupId, label, validationMessage, control) {
this.containerGroupId = containerGroupId;
this.label = label;
this.validationMessage = validationMessage;
this.control = control;
}
}
class ValidationMessage {
//#endregion
//#region Constructor
constructor(key, content) {
this.key = key;
this.content = content;
this.additionalValue = {};
}
}
class AssetFile {
//#endregion
//#region Properties
constructor(kind) {
this.kind = kind;
}
}
class JsScriptFile extends AssetFile {
//#region Constructor
constructor(link) {
super('js-script');
this.link = link;
}
}
class CssFile extends AssetFile {
//#region Constructor
constructor(href) {
super('css');
this.href = href;
}
}
class AssetLoadResult {
//#endregion
//#region Properties
constructor(kind) {
this.kind = kind;
this.successful = false;
}
}
class HtmlContent {
//#region Constructor
constructor(content) {
this.content = content;
}
}
// Implementations export.
class BannerComponent {
//#endregion
//#region Constructor
constructor(injector) {
this.injector = injector;
this.id = '';
this.queryMode = 'pop';
this.preserveMode = 'navigate-start-clear';
this.container = null;
this._destroyBannerTimer = null;
this._displayingRequest = null;
this._displayRequests = [];
// Service reflection.
this.bannerService = this.injector.get(BANNER_SERVICE);
this.componentFactoryResolver = this.injector.get(ComponentFactoryResolver);
this.router = this.injector.get(Router);
this.windowService = this.injector.get(WINDOW);
this.bannerBuilders = this.injector.get(BANNER_BUILDER);
this.changeDetectorRef = this.injector.get(ChangeDetectorRef);
this._subscription = new Subscription();
}
//#endregion
//#region Methods
ngAfterViewInit() {
const id = this.id;
// Subscription about banner display requested.
const displayBannerSubscription = this.bannerService
.addedRequestEvent
.subscribe(request => {
// Container is invalid.
if (!this.container) {
return;
}
// Add the request into list.
this._displayRequests.push(request);
// No banner has been displayed before.
if (!this._displayingRequest) {
this.bannerService.displayNextBanner(id);
}
});
this._subscription.add(displayBannerSubscription);
// Subscription which raises when next banner display is requested.
const nextBannerDisplayRequestSubscription = this.bannerService
.nextBannerDisplayRequested
.pipe(switchMap(request => {
// Invalid container.
if (request.containerId && request.containerId !== id) {
return of(void (0));
}
if (!request.containerId) {
return of(void (0));
}
// Get the next settings.
const nextRequest = this.queryMode === 'pop' ? this.popRequest(request.containerId)
: this.dequeueRequest(request.containerId);
if (!nextRequest) {
// Clear the host view.
if (this.container) {
this.container.clear();
this._displayingRequest = null;
}
return of(void (0));
}
return this.displayBannerAsync(nextRequest)
.pipe(map(_ => void (0)));
}))
.subscribe(() => {
this.changeDetectorRef.markForCheck();
});
this._subscription.add(nextBannerDisplayRequestSubscription);
// Listen to navigation event.
const navigationEventSubscription = this.router
.events
.pipe(filter(e => e instanceof RouterEvent), filter(e => (e instanceof NavigationCancel) || (e instanceof NavigationEnd) || (e instanceof NavigationError)))
.subscribe(e => {
if (!this.container) {
return;
}
if (((e instanceof NavigationCancel) || (e instanceof NavigationEnd) || (e instanceof NavigationError))
&& this.preserveMode === 'navigate-end-clear') {
this.container.clear();
this.changeDetectorRef.markForCheck();
}
if ((e instanceof NavigationStart)
&& this.preserveMode === 'navigate-start-clear') {
this.container.clear();
this.changeDetectorRef.markForCheck();
}
});
this._subscription.add(navigationEventSubscription);
// Hook delete display banner request.
this.hookDeleteRequestEvent();
}
// Called when component is destroyed.
ngOnDestroy() {
var _a;
(_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
// Clear the previous timeout.
if (this._destroyBannerTimer) {
this.windowService.clearTimeout(this._destroyBannerTimer);
}
}
//#endregion
//#region Internal methods
hookDeleteRequestEvent() {
const deleteRequestSubscription = this.bannerService
.deleteRequestEvent
.subscribe(deleteRequest => {
var _a;
// Container is invalid.
if (!this.container) {
return;
}
let index = 0;
while (index < this._displayRequests.length) {
// Container is invalid.
if (deleteRequest.containerId && deleteRequest.containerId !== this.id) {
index++;
continue;
}
// Request id is invalid.
if (deleteRequest.id && deleteRequest.id !== ((_a = this._displayingRequest) === null || _a === void 0 ? void 0 : _a.id)) {
index++;
continue;
}
this._displayRequests.splice(index, 1);
}
if (!this.ableToDeleteDisplayingRequest(deleteRequest)) {
return;
}
this.container.clear();
this._displayingRequest = null;
this.changeDetectorRef.markForCheck();
});
this._subscription.add(deleteRequestSubscription);
}
// Display banner by handling request.
displayBannerAsync(bannerDisplayRequest) {
// Invalid request.
if (!bannerDisplayRequest) {
return of(void (0));
}
// Request does not belong to the current container.
if (bannerDisplayRequest.containerId && this.id
&& bannerDisplayRequest.containerId !== this.id) {
return of(void (0));
}
const settings = bannerDisplayRequest.settings;
if (!settings) {
return of(void (0));
}
// Clear the previous timeout.
if (this._destroyBannerTimer) {
this.windowService.clearTimeout(this._destroyBannerTimer);
}
let itemIndex = 0;
const builders = this.bannerBuilders;
const isNotAbleToBuildException = 'IS_NOT_ABLE_TO_BE_BUILT';
const noBuilderAvailableException = 'NO_BUILDER_AVAILABLE';
const maxRetriesExceeded = 'MAX_RETRIES_EXCEEDED';
return of(void (0))
.pipe(tap(_ => {
if (!builders) {
throw noBuilderAvailableException;
}
if (itemIndex > builders.length - 1) {
throw maxRetriesExceeded;
}
}), mergeMap(_ => builders[itemIndex].canBuildAsync(bannerDisplayRequest.settings)), mergeMap(ableToBuild => {
if (!ableToBuild) {
return throwError(isNotAbleToBuildException);
}
return builders[itemIndex].buildAsync(bannerDisplayRequest.settings)
.pipe(tap((componentRef) => {
if (!this.container) {
return;
}
// Update the request.
this._displayingRequest = bannerDisplayRequest;
const hookDisposeRequest = componentRef.instance
.disposeRequestingEvent
.subscribe((_) => {
this.bannerService.displayNextBanner(this.id);
});
componentRef.onDestroy(() => {
if (hookDisposeRequest && !hookDisposeRequest.closed) {
hookDisposeRequest.unsubscribe();
}
// Mark no request to be displayed.
this._displayingRequest = null;
});
// Detect changes.
componentRef.changeDetectorRef.detectChanges();
this.container.clear();
this.container.insert(componentRef.hostView);
if (settings.timeout && settings.timeout.duration && settings.timeout.action) {
this._destroyBannerTimer = this.windowService
.setTimeout(() => {
// Do action on timeout.
if (settings && settings.timeout) {
settings.timeout.action();
}
}, settings.timeout.duration);
}
}), map(_ => void (0)));
}), retryWhen(exceptionObservable => {
return exceptionObservable
.pipe(tap(exception => {
if (exception !== isNotAbleToBuildException) {
throw exception;
}
itemIndex++;
}));
}));
//#endregion
}
// Whether displaying request is removable or not.
ableToDeleteDisplayingRequest(deleteRequest) {
var _a;
if (deleteRequest.containerId && deleteRequest.containerId !== this.id) {
return false;
}
if (deleteRequest.id && deleteRequest.id !== ((_a = this._displayingRequest) === null || _a === void 0 ? void 0 : _a.id)) {
return false;
}
return true;
}
// Dequeue request.
dequeueRequest(containerId) {
if (!this._displayRequests || !this._displayRequests.length) {
return null;
}
// Get first match item in the messages list.
const itemIndex = this._displayRequests.findIndex(x => x.containerId === containerId);
if (itemIndex < 0) {
return null;
}
const item = this._displayRequests[itemIndex];
this._displayRequests.splice(itemIndex, 1);
return item;
}
// Pop request.
popRequest(containerId) {
if (!this._displayRequests || !this._displayRequests.length) {
return null;
}
// Find the last index of item.
const lastIndex = findLastIndex(this._displayRequests, x => x.containerId === containerId);
if (lastIndex < 0) {
return null;
}
const item = this._displayRequests[lastIndex];
this._displayRequests.splice(lastIndex, 1);
return item;
}
}
BannerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
BannerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BannerComponent, selector: "cms-banner", inputs: { id: "id", queryMode: ["query-mode", "queryMode"], preserveMode: ["preserve-mode", "preserveMode"] }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<ng-template #container></ng-template>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerComponent, decorators: [{
type: Component,
args: [{ selector: 'cms-banner', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #container></ng-template>\n" }]
}], ctorParameters: function () { return [{ type: i0.Injector }]; }, propDecorators: { id: [{
type: Input
}], queryMode: [{
type: Input,
args: ['query-mode']
}], preserveMode: [{
type: Input,
args: ['preserve-mode']
}], container: [{
type: ViewChild,
args: ['container', { read: ViewContainerRef }]
}] } });
class BannerService {
//#endregion
//#region Constructor
constructor() {
this._bannerDisplayRequestSubject = new ReplaySubject(1);
this._deleteRequestSubject = new ReplaySubject(1);
this._displayNextSubject = new ReplaySubject(1);
this.addedRequestEvent = this._bannerDisplayRequestSubject.asObservable();
this.deleteRequestEvent = this._deleteRequestSubject.asObservable();
this.nextBannerDisplayRequested = this._displayNextSubject.asObservable();
}
//#endregion
//#region Methods
// Display banner using specific settings.
// If container id is defined, only the contain whose id matches will display the banner.
addBanner(settings, containerId) {
const request = {
id: settings.id,
containerId,
settings
};
this._bannerDisplayRequestSubject.next(request);
return request.id;
}
// Find and delete banner by id.
// No id is defined, all banner will be deleted.
deleteBanner(id, containerId) {
const deleteRequest = {
id,
containerId
};
this._deleteRequestSubject.next(deleteRequest);
}
// Get the next banner and display it inside a specific container.
// If no container id is defined, display next banner into every banner.
displayNextBanner(containerId) {
const request = {
containerId
};
this._displayNextSubject.next(request);
}
}
/* Define abstract class for obtaining reference to the global window object. */
class WindowRef {
// tslint:disable-next-line:ban-types
get nativeWindow() {
throw new Error('Not implemented.');
}
}
/* Define class that implements the abstract class and returns the native window object. */
class BrowserWindowRef extends WindowRef {
constructor() {
super();
}
// tslint:disable-next-line:ban-types
get nativeWindow() {
return window;
}
}
/* Create an factory function that returns the native window object. */
// tslint:disable-next-line:ban-types
function windowFactory(browserWindowRef, platformId) {
if (isPlatformBrowser(platformId)) {
return browserWindowRef.nativeWindow;
}
return {};
}
/* Create a injectable provider for the WindowRef token that uses the BrowserWindowRef class. */
const browserWindowProvider = {
provide: WindowRef,
useValue: new BrowserWindowRef()
};
/* Create an injectable provider that uses the windowFactory function for returning the native window object. */
const windowProvider = {
provide: WINDOW,
useFactory: windowFactory,
deps: [WindowRef, PLATFORM_ID]
};
/* Create an array of providers. */
const WINDOW_PROVIDERS = [
browserWindowProvider,
windowProvider
];
// Child validation summarizer providers
// Validation summarizer option.
// tslint:disable-next-line:max-line-length
const VALIDATION_SUMMARIZER_OPTIONS = new InjectionToken('VALIDATION_SUMMARIZER_OPTIONS_PROVIDER');
const NULL_VALIDATION_SUMMARIZER_PROVIDER = new InjectionToken('BLANK_VALIDATION_SUMMARIZER_PROVIDER');
// Common validator
const NULL_COMMON_VALIDATOR_SERVICE = new InjectionToken('NULL_COMMON_VALIDATOR_SERVICE');
// Banner
const NULL_BANNER_SERVICE_PROVIDER = new InjectionToken('NULL_BANNER_SERVICE_PROVIDER');
const NULL_BANNER_CONTENT_BUILDER_SERVICE_PROVIDER = new InjectionToken('NULL_BANNER_CONTENT_BUILDER_SERVICE_PROVIDER');
// Validation pipe
const HAS_ANY_VALIDATOR_SERVICE = new InjectionToken('HAS_ANY_VALIDATOR_SERVICE');
//#region Services
// Build banner service.
function buildBannerService(option) {
return new BannerService();
}
// Build null banner service.
function buildNullBannerProvider() {
return {
provide: NULL_BANNER_SERVICE_PROVIDER,
useValue: {}
};
}
// Build banner provider.
function buildBannerProvider() {
return {
provide: BANNER_SERVICE,
useFactory: buildBannerService
};
}
//#endregion
//#region Content builders
function buildEmptyContentBuilderProvider() {
return {
provide: NULL_BANNER_CONTENT_BUILDER_SERVICE_PROVIDER,
useValue: {}
};
}
//#endregion
class BannerModule {
//#region Methods
static forRoot(options) {
return {
ngModule: BannerModule,
providers: [
// Banner service registration.
(options || {}).serviceProvider || buildBannerProvider(),
// Banner content builder.
(options || {}).contentBuilderProviders || buildEmptyContentBuilderProvider()
]
};
}
static forChild(options) {
return {
ngModule: BannerModule,
providers: [
// Banner service registration.
(options || {}).serviceProvider || buildNullBannerProvider(),
// Banner content builder.
(options || {}).contentBuilderProviders || buildEmptyContentBuilderProvider()
]
};
}
}
BannerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
BannerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerModule, declarations: [BannerComponent], imports: [CommonModule,
RouterModule], exports: [BannerComponent] });
BannerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerModule, providers: [
WINDOW_PROVIDERS,
{
provide: BANNER_SERVICE,
useClass: BannerService
}
], imports: [[
CommonModule,
RouterModule
]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerModule, decorators: [{
type: NgModule,
args: [{
declarations: [
BannerComponent
],
exports: [
BannerComponent
],
imports: [
CommonModule,
RouterModule
],
providers: [
WINDOW_PROVIDERS,
{
provide: BANNER_SERVICE,
useClass: BannerService
}
]
}]
}] });
var RequirementSentinelExceptionCodes;
(function (RequirementSentinelExceptionCodes) {
RequirementSentinelExceptionCodes["NO_REQUIREMENT_HANDLER_AT_ALL"] = "NO_REQUIREMENT_HANDLER_AT_ALL";
RequirementSentinelExceptionCodes["REQUIREMENT_NOT_FOUND_FOR_SPECIFIC_NAME"] = "REQUIREMENT_NOT_FOUND_FOR_SPECIFIC_NAME";
RequirementSentinelExceptionCodes["FAILED_WHILE_HANDLING_EXTERNAL_BUSINESS"] = "FAILED_WHILE_HANDLING_EXTERNAL_BUSINESS";
})(RequirementSentinelExceptionCodes || (RequirementSentinelExceptionCodes = {}));
var RequirementSentinelExceptionTypes;
(function (RequirementSentinelExceptionTypes) {
RequirementSentinelExceptionTypes["INTERNAL"] = "INTERNAL";
RequirementSentinelExceptionTypes["EXTERNAL"] = "EXTERNAL";
})(RequirementSentinelExceptionTypes || (RequirementSentinelExceptionTypes = {}));
class ExternalRequirementSentinelException {
//#endregion
//#region Constructor
constructor(requirementName, code, metadata) {
this.requirementName = requirementName;
this.type = RequirementSentinelExceptionTypes.EXTERNAL;
this.code = code;
this.metadata = metadata;
}
}
class InternalRequirementSentinelException {
//#endregion
//#region Constructor
constructor(requirementName, code, metadata) {
this.requirementName = requirementName;
this.type = RequirementSentinelExceptionTypes.INTERNAL;
this.code = code;
this.metadata = metadata;
}
}
class RequirementSentinelDirective {
//#endregion
//#region Constructor
constructor(_meetRequirementService, _viewContainerRef, _templateRef) {
this._meetRequirementService = _meetRequirementService;
this._viewContainerRef = _viewContainerRef;
this._templateRef = _templateRef;
this.__requirement = undefined;
this.__displayContent$ = new Subject();
this.__subscription = new Subscription();
}
//#endregion
//#region Accessors
set requirement(value) {
this.__requirement = value;
this.__displayContent$.next();
}
set elseTemplate(value) {
this.__elseTemplateRef = value;
this.__displayContent$.next();
}
set context(value) {
this.__context = value;
this.__displayContent$.next();
}
//#endregion
//#region Life cycles
ngOnInit() {
// Display feature subscription.
const displayContentSubscription = this.__displayContent$
.pipe(switchMap(() => {
return this._meetRequirementService
.shouldRequirementMetAsync(this.__requirement || '', this.__context)
.pipe(catchError(_ => of(false)));
}), distinctUntilChanged())
.subscribe(ableToAccessFeature => {
this._viewContainerRef.clear();
if (!ableToAccessFeature) {
if (this.__elseTemplateRef) {
const elseView = this._viewContainerRef.createEmbeddedView(this.__elseTemplateRef);
elseView.markForCheck();
}
return;
}
const embeddedView = this._viewContainerRef.createEmbeddedView(this._templateRef);
embeddedView.markForCheck();
});
this.__subscription.add(displayContentSubscription);
// Hook validation event from service.
const hookValidationEventSubscription = this._meetRequirementService
.hookValidationEventAsync()
.subscribe(() => {
this.__displayContent$.next();
});
this.__subscription.add(hookValidationEventSubscription);
// Do the first requirement check.
this.__displayContent$.next();
}
ngOnDestroy() {
var _a;
(_a = this.__subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
}
}
RequirementSentinelDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RequirementSentinelDirective, deps: [{ token: REQUIREMENT_SENTINEL_SERVICE }, { token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
RequirementSentinelDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: RequirementSentinelDirective, selector: "[meetRequirement]", inputs: { requirement: ["meetRequirement", "requirement"], elseTemplate: ["meetRequirementElse", "elseTemplate"], context: ["meetRequirementContext", "context"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RequirementSentinelDirective, decorators: [{
type: Directive,
args: [{
selector: '[meetRequirement]'
}]
}], ctorParameters: function () {
return [{ type: undefined, decorators: [{
type: Inject,
args: [REQUIREMENT_SENTINEL_SERVICE]
}] }, { type: i0.ViewContainerRef }, { type: i0.TemplateRef }];
}, propDecorators: { requirement: [{
type: Input,
args: ['meetRequirement']
}], elseTemplate: [{
type: Input,
args: ['meetRequirementElse']
}], context: [{
type: Input,
args: ['meetRequirementContext']
}] } });
class RequirementSentinelService {
//#endregion
//#region Constructor
constructor(injector) {
this._requirementHandlers = injector
.get(REQUIREMENT_HANDLER, null, InjectFlags.Optional);
this._exceptionProcessor = injector.get(REQUIREMENT_SENTINEL_EXCEPTION_PROCESSOR, null, InjectFlags.Optional);
this._doValidationEvent = new ReplaySubject(1);
}
//#endregion
//#region Methods
shouldRequirementMetAsync(name, context) {
// No requirement is found.
if (!this._requirementHandlers || !this._requirementHandlers.length) {
return this.__processExceptionAsync(new InternalRequirementSentinelException(name, RequirementSentinelExceptionCodes.NO_REQUIREMENT_HANDLER_AT_ALL));
}
// Find the requirement which has the exact name with the passed one.
const requirementHandler = this._requirementHandlers.find(item => item.name === name);
if (!requirementHandler) {
return this.__processExceptionAsync(new InternalRequirementSentinelException(name, RequirementSentinelExceptionCodes.REQUIREMENT_NOT_FOUND_FOR_SPECIFIC_NAME, {
name
}));
}
return requirementHandler.shouldRequirementMetAsync(context)
.pipe(catchError(exception => {
return this.__processExceptionAsync(new ExternalRequirementSentinelException(name, RequirementSentinelExceptionCodes.FAILED_WHILE_HANDLING_EXTERNAL_BUSINESS, {
exception
}));
}));
}
doValidation() {
this._doValidationEvent.next();
}
hookValidationEventAsync() {
return this._doValidationEvent.asObservable();
}
//#endregion
//#region Internal methods
__processExceptionAsync(exceptionInstance) {
if (!this._exceptionProcessor) {
return of(false);
}
return this._exceptionProcessor.processExceptionAsync(exceptionInstance)
.pipe(map(() => false));
}
}
function buildSentinelDirectiveService(injector) {
return new RequirementSentinelService(injector);
}
class RequirementSentinelModule {
//#region Methods
static forRoot() {
return {
ngModule: RequirementSentinelModule,
providers: [
{
provide: REQUIREMENT_SENTINEL_SERVICE,
useFactory: buildSentinelDirectiveService,
deps: [
Injector
]
}
]
};
}
static forChild({ providers }) {
return {
ngModule: RequirementSentinelModule,
providers: [
...(providers || []),
{
provide: REQUIREMENT_SENTINEL_SERVICE,
useFactory: buildSentinelDirectiveService,
deps: [
Injector
]
}
]
};
}
}
RequirementSentinelModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RequirementSentinelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
RequirementSentinelModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RequirementSentinelModule, declarations: [RequirementSentinelDirective], exports: [RequirementSentinelDirective] });
RequirementSentinelModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RequirementSentinelModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RequirementSentinelModule, decorators: [{
type: NgModule,
args: [{
declarations: [
RequirementSentinelDirective
],
exports: [
RequirementSentinelDirective
]
}]
}] });
class FeatureSentinelDirective {
//#endregion
//#region Constructor
constructor(_requireFeaturePermissionService, _viewContainerRef, _templateRef) {
this._requireFeaturePermissionService = _requireFeaturePermissionService;
this._viewContainerRef = _viewContainerRef;
this._templateRef = _templateRef;
this.__names = [];
this.__displayFeatureContent$ = new ReplaySubject();
this._subscription = new Subscription();
}
//#endregion
//#region Accessors
set name(value) {
if (value instanceof Array) {
this.__names = value;
}
else {
this.__names = [value];
}
this.__displayFeatureContent$.next();
}
set elseTemplate(value) {
this.__elseTemplateRef = value;
this.__displayFeatureContent$.next();
}
//#endregion
//#region Methods
ngOnInit() {
// Display feature subscription.
const displayFeatureContentSubscription = this.__displayFeatureContent$
.pipe(switchMap(() => {
return this._requireFeaturePermissionService
.ableToAccessFeaturesAsync(this.__names)
.pipe(catchError(_ => of(false)));
}), distinctUntilChanged())
.subscribe(ableToAccessFeature => {
this._viewContainerRef.clear();
if (!ableToAccessFeature) {
if (this.__elseTemplateRef) {
const elseView = this._viewContainerRef.createEmbeddedView(this.__elseTemplateRef);
elseView.markForCheck();
}
return;
}
else {
const embeddedView = this._viewContainerRef.createEmbeddedView(this._templateRef);
embeddedView.markForCheck();
}
});
this._subscription.add(displayFeatureContentSubscription);
// Hook validation event from service.
const hookValidationEventSubscription = this._requireFeaturePermissionService
.hookValidationEventAsync()
.subscribe(() => {
this.__displayFeatureContent$.next();
});
this._subscription.add(hookValidationEventSubscription);
this.__displayFeatureContent$.next();
}
ngOnDestroy() {
var _a;
this.__displayFeatureContent$.complete();
(_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
}
}
FeatureSentinelDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FeatureSentinelDirective, deps: [{ token: FEATURE_SENTINEL_SERVICE }, { token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
FeatureSentinelDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: FeatureSentinelDirective, selector: "[hasFeatureAccess]", inputs: { name: ["hasFeatureAccess", "name"], elseTemplate: ["hasFeatureAccessElse", "elseTemplate"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FeatureSentinelDirective, decorators: [{
type: Directive,
args: [{
selector: '[hasFeatureAccess]'
}]
}], ctorParameters: function () {
return [{ type: undefined, decorators: [{
type: Inject,
args: [FEATURE_SENTINEL_SERVICE]
}] }, { type: i0.ViewContainerRef }, { type: i0.TemplateRef }];
}, propDecorators: { name: [{
type: Input,
args: ['hasFeatureAccess']
}], elseTemplate: [{
type: Input,
args: ['hasFeatureAccessElse']
}] } });
class FeatureSentinelModule {
//#region Properties
static forRoot(option) {
return {
ngModule: FeatureSentinelModule,
providers: option.providers || []
};
}
}
FeatureSentinelModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FeatureSentinelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
FeatureSentinelModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FeatureSentinelModule, declarations: [FeatureSentinelDirective], exports: [FeatureSentinelDirective] });
FeatureSentinelModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FeatureSentinelModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: FeatureSentinelModule, decorators: [{
type: NgModule,
args: [{
declarations: [
FeatureSentinelDirective
],
exports: [
FeatureSentinelDirective
]
}]
}] });
class RoleSentinelDirective {
//#endregion
//#region Constructor
constructor(_requireRolePermissionService, _viewContainerRef, _templateRef) {
this._requireRolePermissionService = _requireRolePermissionService;
this._viewContainerRef = _viewContainerRef;
this._templateRef = _templateRef;
this.__names = [];
this.__displayRoleContent$ = new ReplaySubject(1);
this._subscription = new Subscription();
}
//#endregion
//#region Accessors
set name(value) {
if (value instanceof Array) {
this.__names = value;
}
else {
this.__names = [value];
}
this.__displayRoleContent$.next();
}
set elseTemplate(value) {
this.__elseTemplateRef = value;
this.__displayRoleContent$.next();
}
//#endregion
//#region Methods
ngOnInit() {
const displayFeatureContentSubscription = this.__displayRoleContent$
.pipe(switchMap(() => {
return this._requireRolePermissionService
.hasAnyRoleAsync(this.__names)
.pipe(catchError(_ => of(false)));
}), distinctUntilChanged())
.subscribe(ableToAccessFeature => {
this._viewContainerRef.clear();
if (!ableToAccessFeature) {
if (this.__elseTemplateRef) {
const elseView = this._viewContainerRef.createEmbeddedView(this.__elseTemplateRef);
elseView.markForCheck();
}
return;
}
const embeddedView = this._viewContainerRef.createEmbeddedView(this._templateRef);
embeddedView.markForCheck();
});
// Trigger validation.
this.__displayRoleContent$.next();
const hookRoleValidationSubscription = this._requireRolePermissionService
.hookValidationEventAsync()
.subscribe(() => {
this.__displayRoleContent$.next();
});
this._subscription.add(hookRoleValidationSubscription);
this._subscription.add(displayFeatureContentSubscription);
}
ngOnDestroy() {
var _a;
(_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
this.__displayRoleContent$.complete();
}
}
RoleSentinelDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleSentinelDirective, deps: [{ token: ROLE_SENTINEL_SERVICE }, { token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
RoleSentinelDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: RoleSentinelDirective, selector: "[hasRoles]", inputs: { name: ["hasRoles", "name"], elseTemplate: ["hasRolesElse", "elseTemplate"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleSentinelDirective, decorators: [{
type: Directive,
args: [{
selector: '[hasRoles]'
}]
}], ctorParameters: function () {
return [{ type: undefined, decorators: [{
type: Inject,
args: [ROLE_SENTINEL_SERVICE]
}] }, { type: i0.ViewContainerRef }, { type: i0.TemplateRef }];
}, propDecorators: { name: [{
type: Input,
args: ['hasRoles']
}], elseTemplate: [{
type: Input,
args: ['hasRolesElse']
}] } });
class RoleSentinelModule {
//#region Properties
static forRoot(option) {
return {
ngModule: RoleSentinelModule,
providers: option.providers || []
};
}
}
RoleSentinelModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleSentinelModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
RoleSentinelModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleSentinelModule, declarations: [RoleSentinelDirective], exports: [RoleSentinelDirective] });
RoleSentinelModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleSentinelModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: RoleSentinelModule, decorators: [{
type: NgModule,
args: [{
declarations: [
RoleSentinelDirective
],
exports: [
RoleSentinelDirective
]
}]
}] });
class SmartNavigatorService {
//#endregion
//#region Constructor
constructor(injector) {
this.injector = injector;
const codeToUrlMappings = this.injector.get(SMART_NAVIGATOR_ROUTES);
this._router = this.injector.get(Router);
this._screenCodeResolvers = this.injector.get(SMART_NAVIGATOR_SCREEN_CODE_RESOLVER, null, InjectFlags.Optional);
this.__codeToUrlMappings = {};
if (codeToUrlMappings) {
this.__codeToUrlMappings = merge({}, codeToUrlMappings);
}
}
//#endregion
//#endregion
//#region Methods
// Navigate to a screen by using screen code.
navigateToScreenAsync(request) {
if (!request) {
throw new Error(SmartNavigatorExceptions.invalidNavigationRequest);
}
// Get raw url from screen code.
const rawUrl = this.loadRawUrl(request.code);
const compiled = this.__template(rawUrl);
const fullUrl = compiled(request.routeParams);
return from(this._router.navigate([fullUrl], request.extras));
}
// Get raw url.
loadRawUrl(code) {
if (!code || !code.length) {
throw new Error(SmartNavigatorExceptions.invalidScreenCode);
}
let url = this.__codeToUrlMappings[code];
if (url) {
return url;
}
cons