UNPKG

@dbg-riskit/angular-view

Version:

790 lines (779 loc) 61.6 kB
import { NgClass, DatePipe, DecimalPipe } from '@angular/common'; import * as i0 from '@angular/core'; import { input, computed, signal, inject, ElementRef, ChangeDetectionStrategy, Component, Injectable, LOCALE_ID, Pipe, NgZone, Directive, effect, Renderer2, contentChildren } from '@angular/core'; import { MatCard, MatCardContent } from '@angular/material/card'; import { MatProgressSpinner } from '@angular/material/progress-spinner'; import { provideNativeDateAdapter } from '@angular/material/core'; import { DATE_FORMAT, AUTH_PROVIDER, MAIN_LOGO } from '@dbg-riskit/angular-common'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialogContent, MatDialog } from '@angular/material/dialog'; import { first, filter } from 'rxjs/operators'; import { MatButton, MatIconButton } from '@angular/material/button'; import { MatIcon } from '@angular/material/icon'; import { Logger, CONTENT_TYPE } from '@dbg-riskit/common'; import { BehaviorSubject } from 'rxjs'; import { toSignal } from '@angular/core/rxjs-interop'; import { MatSidenav, MatSidenavContainer } from '@angular/material/sidenav'; import { MatToolbar } from '@angular/material/toolbar'; import { Router, ActivatedRoute, RouterLink, NavigationEnd } from '@angular/router'; const RISK_ERROR_SELECTOR = 'risk-error'; const RISK_GOOD_SELECTOR = 'risk-good'; const RISK_INFO_SELECTOR = 'risk-info'; const RISK_MESSAGE_SELECTOR = 'risk-message'; const RISK_WARN_SELECTOR = 'risk-warn'; const RISK_INITIAL_LOAD_SELECTOR = 'risk-initial-load'; const RISK_NO_DATA_SELECTOR = 'risk-no-data'; const RISK_UPDATE_FAILED_SELECTOR = 'risk-update-failed'; const COMPONENT_SELECTOR = RISK_ERROR_SELECTOR + ', ' + RISK_GOOD_SELECTOR + ', ' + RISK_INFO_SELECTOR + ', ' + RISK_MESSAGE_SELECTOR + ', ' + RISK_WARN_SELECTOR + ', ' + RISK_INITIAL_LOAD_SELECTOR + ', ' + RISK_NO_DATA_SELECTOR + ', ' + RISK_UPDATE_FAILED_SELECTOR; class RiskMessageComponent { constructor() { this.message = input(...(ngDevMode ? [undefined, { debugName: "message" }] : [])); this.initialLoad = computed(() => this.tagName() === RISK_INITIAL_LOAD_SELECTOR, ...(ngDevMode ? [{ debugName: "initialLoad" }] : [])); this.noData = computed(() => this.tagName() === RISK_NO_DATA_SELECTOR, ...(ngDevMode ? [{ debugName: "noData" }] : [])); this.updateError = computed(() => this.tagName() === RISK_UPDATE_FAILED_SELECTOR, ...(ngDevMode ? [{ debugName: "updateError" }] : [])); this.color = computed(() => { switch (this.tagName()) { case RISK_INFO_SELECTOR: case RISK_NO_DATA_SELECTOR: return RISK_INFO_SELECTOR; case RISK_WARN_SELECTOR: case RISK_INITIAL_LOAD_SELECTOR: return RISK_WARN_SELECTOR; case RISK_ERROR_SELECTOR: case RISK_UPDATE_FAILED_SELECTOR: return RISK_ERROR_SELECTOR; case RISK_GOOD_SELECTOR: return RISK_GOOD_SELECTOR; default: return null; } }, ...(ngDevMode ? [{ debugName: "color" }] : [])); this.tagName = signal('', ...(ngDevMode ? [{ debugName: "tagName" }] : [])); const elementRef = inject(ElementRef); this.tagName.set(elementRef.nativeElement.tagName.toLowerCase()); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RiskMessageComponent, isStandalone: true, selector: "risk-error, risk-good, risk-info, risk-message, risk-warn, risk-initial-load, risk-no-data, risk-update-failed", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.risk-message": "true", "class.risk-message-error": "color() === \"risk-error\"", "class.risk-message-warn": "color() === \"risk-warn\"", "class.risk-message-good": "color() === \"risk-good\"", "class.risk-message-info": "color() === \"risk-info\"", "class.risk-message-initial-load": "initialLoad()", "class.risk-message-no-data": "noData()", "class.risk-message-update-error": "updateError()" } }, ngImport: i0, template: "<mat-card [ngClass]=\"color()\">\n <mat-card-content>\n @if (initialLoad()) {\n <mat-spinner [diameter]=\"50\"/>\n Loading...\n }\n @if (noData()) {\n No data available.\n }\n @if (updateError()) {\n Failed to update the data: {{ message() }}.\n }\n @if (!initialLoad() && !noData() && !updateError()) {\n {{ message() }}\n }\n <ng-content/>\n </mat-card-content>\n</mat-card>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ":host(.risk-message-initial-load) .mat-mdc-card-content{display:flex;line-height:50px;padding:15px 24px}:host(.risk-message-initial-load) .mat-mdc-card-content .mat-mdc-progress-spinner{margin-right:15px}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskMessageComponent, decorators: [{ type: Component, args: [{ selector: COMPONENT_SELECTOR, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class.risk-message]': 'true', '[class.risk-message-error]': 'color() === "' + RISK_ERROR_SELECTOR + '"', '[class.risk-message-warn]': 'color() === "' + RISK_WARN_SELECTOR + '"', '[class.risk-message-good]': 'color() === "' + RISK_GOOD_SELECTOR + '"', '[class.risk-message-info]': 'color() === "' + RISK_INFO_SELECTOR + '"', '[class.risk-message-initial-load]': 'initialLoad()', '[class.risk-message-no-data]': 'noData()', '[class.risk-message-update-error]': 'updateError()' }, imports: [ MatCard, MatCardContent, MatProgressSpinner, NgClass ], template: "<mat-card [ngClass]=\"color()\">\n <mat-card-content>\n @if (initialLoad()) {\n <mat-spinner [diameter]=\"50\"/>\n Loading...\n }\n @if (noData()) {\n No data available.\n }\n @if (updateError()) {\n Failed to update the data: {{ message() }}.\n }\n @if (!initialLoad() && !noData() && !updateError()) {\n {{ message() }}\n }\n <ng-content/>\n </mat-card-content>\n</mat-card>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ":host(.risk-message-initial-load) .mat-mdc-card-content{display:flex;line-height:50px;padding:15px 24px}:host(.risk-message-initial-load) .mat-mdc-card-content .mat-mdc-progress-spinner{margin-right:15px}\n"] }] }], ctorParameters: () => [], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }] } }); class RiskDateFormatter { constructor() { this.format = inject(DATE_FORMAT); this.datePipe = inject(DatePipe); } transform(value) { return this.datePipe.transform(value, this.format); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskDateFormatter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskDateFormatter }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskDateFormatter, decorators: [{ type: Injectable }] }); function provideDateFormatter(format) { return [ DatePipe, RiskDateFormatter, ...provideNativeDateAdapter(), { provide: DATE_FORMAT, useValue: format } ]; } class RiskFlexComponent { constructor() { this.wrapContent = input(false, ...(ngDevMode ? [{ debugName: "wrapContent" }] : [])); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskFlexComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: RiskFlexComponent, isStandalone: true, selector: "risk-flex", inputs: { wrapContent: { classPropertyName: "wrapContent", publicName: "wrapContent", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.risk-flex": "!wrapContent()", "class.risk-flex-wrap": "wrapContent()" } }, ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ":host{display:flex}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskFlexComponent, decorators: [{ type: Component, args: [{ selector: 'risk-flex', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content />', host: { '[class.risk-flex]': '!wrapContent()', '[class.risk-flex-wrap]': 'wrapContent()' }, styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ":host{display:flex}\n"] }] }], propDecorators: { wrapContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrapContent", required: false }] }] } }); class RiskFlexSpacerComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskFlexSpacerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: RiskFlexSpacerComponent, isStandalone: true, selector: "risk-flex-spacer", host: { properties: { "class.risk-flex-spacer": "true" } }, ngImport: i0, template: '', isInline: true, styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskFlexSpacerComponent, decorators: [{ type: Component, args: [{ selector: 'risk-flex-spacer', changeDetection: ChangeDetectionStrategy.OnPush, template: '', host: { '[class.risk-flex-spacer]': 'true' }, styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n"] }] }] }); class RiskLoaderComponent { constructor() { this.dialogRef = inject(MatDialogRef); this.data = inject(MAT_DIALOG_DATA); } get dialogData() { return this.data; } close() { this.dialogRef.close(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RiskLoaderComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class.risk-loader-dialog": "true" } }, ngImport: i0, template: ` <mat-dialog-content> <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <mat-spinner/> <risk-flex-spacer/> </risk-flex> @if (dialogData.title) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <h3>{{ dialogData.title }}</h3> <risk-flex-spacer/> </risk-flex> } @if (dialogData.cancel != null) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <button mat-button color="warn" (click)="dialogData.cancel()">Cancel</button> <risk-flex-spacer/> </risk-flex> } </mat-dialog-content> `, isInline: true, styles: ["h3{margin-bottom:0}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: RiskFlexComponent, selector: "risk-flex", inputs: ["wrapContent"] }, { kind: "component", type: RiskFlexSpacerComponent, selector: "risk-flex-spacer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLoaderComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, template: ` <mat-dialog-content> <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <mat-spinner/> <risk-flex-spacer/> </risk-flex> @if (dialogData.title) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <h3>{{ dialogData.title }}</h3> <risk-flex-spacer/> </risk-flex> } @if (dialogData.cancel != null) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <button mat-button color="warn" (click)="dialogData.cancel()">Cancel</button> <risk-flex-spacer/> </risk-flex> } </mat-dialog-content> `, host: { '[class.risk-loader-dialog]': 'true' }, imports: [ MatButton, MatDialogContent, MatProgressSpinner, RiskFlexComponent, RiskFlexSpacerComponent ], styles: ["h3{margin-bottom:0}\n"] }] }] }); class RiskMessageDialogComponent { constructor() { this.dialogRef = inject(MatDialogRef); this.dialogData = inject(MAT_DIALOG_DATA); this.customIcon = computed(() => this.dialogData.icon, ...(ngDevMode ? [{ debugName: "customIcon" }] : [])); this.dialogType = computed(() => this.dialogData.dialogType || 'info', ...(ngDevMode ? [{ debugName: "dialogType" }] : [])); this.buttons = computed(() => this.dialogData.buttons || [{ label: 'OK' }], ...(ngDevMode ? [{ debugName: "buttons" }] : [])); this.color = computed(() => { switch (this.dialogType()) { case 'error': case 'warning': return 'warn'; case 'info': case 'question': return 'accent'; case 'success': return 'primary'; } return null; }, ...(ngDevMode ? [{ debugName: "color" }] : [])); this.icon = computed(() => { if (this.customIcon()) { return this.customIcon(); } switch (this.dialogType()) { case 'error': return 'error'; case 'warning': return 'warning'; case 'info': return 'info'; case 'question': return 'help'; case 'success': return 'check'; } return 'info'; }, ...(ngDevMode ? [{ debugName: "icon" }] : [])); } close(button) { this.dialogRef.close(button.value); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskMessageDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RiskMessageDialogComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class.risk-message-dialog": "true" } }, ngImport: i0, template: "<mat-dialog-content>\n <div class=\"risk-message-dialog-message\">\n @if (dialogData.title) {\n <h3>\n <mat-icon [color]=\"color()\">{{ icon() }}</mat-icon>\n <strong>{{ dialogData.title }}</strong>\n </h3>\n }\n <h3>\n @if (!dialogData.title) {\n <mat-icon [color]=\"color()\">{{ icon() }}</mat-icon>\n }\n {{ dialogData.message }}\n </h3>\n @if (dialogData.note) {\n <small>NOTE: {{ dialogData.note }}</small>\n }\n </div>\n @for (button of buttons(); track button) {\n <a\n (click)=\"close(button)\"\n [color]=\"button.primary ? color() : null\"\n mat-button>{{ button.label }}</a>\n }\n</mat-dialog-content>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ".risk-message-dialog-message{padding:10px;margin-bottom:10px}.risk-message-dialog-message h3{margin:0;white-space:pre-line}.risk-message-dialog-message h3 .mat-icon{font-size:40px;float:left;height:40px;width:40px;margin-right:10px;margin-top:-6px}.risk-message-dialog-message small{white-space:pre-line}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskMessageDialogComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class.risk-message-dialog]': 'true' }, imports: [ MatButton, MatDialogContent, MatIcon ], template: "<mat-dialog-content>\n <div class=\"risk-message-dialog-message\">\n @if (dialogData.title) {\n <h3>\n <mat-icon [color]=\"color()\">{{ icon() }}</mat-icon>\n <strong>{{ dialogData.title }}</strong>\n </h3>\n }\n <h3>\n @if (!dialogData.title) {\n <mat-icon [color]=\"color()\">{{ icon() }}</mat-icon>\n }\n {{ dialogData.message }}\n </h3>\n @if (dialogData.note) {\n <small>NOTE: {{ dialogData.note }}</small>\n }\n </div>\n @for (button of buttons(); track button) {\n <a\n (click)=\"close(button)\"\n [color]=\"button.primary ? color() : null\"\n mat-button>{{ button.label }}</a>\n }\n</mat-dialog-content>\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ".risk-message-dialog-message{padding:10px;margin-bottom:10px}.risk-message-dialog-message h3{margin:0;white-space:pre-line}.risk-message-dialog-message h3 .mat-icon{font-size:40px;float:left;height:40px;width:40px;margin-right:10px;margin-top:-6px}.risk-message-dialog-message small{white-space:pre-line}\n"] }] }] }); class RiskPercentPipe { constructor() { this.decimalPipe = new DecimalPipe(inject(LOCALE_ID)); } transform(value, digits) { const transformedNumber = this.decimalPipe.transform(value, digits); if (transformedNumber) { return transformedNumber + '%'; } return undefined; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskPercentPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); } static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: RiskPercentPipe, isStandalone: true, name: "percent" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskPercentPipe, decorators: [{ type: Pipe, args: [{ name: 'percent' }] }] }); class RiskProgressLoaderComponent { constructor() { this.dialogRef = inject(MatDialogRef); this.dialogData = inject(MAT_DIALOG_DATA); this.value = signal(this.dialogData.value ?? 0, ...(ngDevMode ? [{ debugName: "value" }] : [])); this.total = signal(this.dialogData.total, ...(ngDevMode ? [{ debugName: "total" }] : [])); this.mode = computed(() => { const totalVal = this.total(); const valueVal = this.value(); switch (true) { case totalVal == null: case totalVal != null && totalVal <= 0: case valueVal <= 0: case valueVal === totalVal: return 'indeterminate'; default: return 'determinate'; } }, ...(ngDevMode ? [{ debugName: "mode" }] : [])); } setValue(v) { this.dialogData.value = v; this.value.set(v < 0 ? 0 : v); } setTotal(v) { this.dialogData.total = v; this.total.set(v); } get valueFormatter() { return this.dialogData.valueFormatter || { transform: (data) => data }; } close() { this.dialogRef.close(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskProgressLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RiskProgressLoaderComponent, isStandalone: true, selector: "ng-component", host: { properties: { "class.risk-progress-loader-dialog": "true" } }, ngImport: i0, template: ` @let tot = total(); @let val = value(); <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <mat-progress-spinner [mode]="mode()" [value]="(val / (tot || 1)) * 100"/> <risk-flex-spacer/> </risk-flex> @if (dialogData.title) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <h3>{{ dialogData.title }}</h3> <risk-flex-spacer/> </risk-flex> } <risk-flex [wrapContent]="true"> <risk-flex-spacer/> @if (tot != null && tot > 0) { <h5>{{ valueFormatter.transform(val) }} /{{ valueFormatter.transform(tot) }} - {{ val / tot * 100 | percent:'.1-1' }}</h5> } @else { <h5>{{ valueFormatter.transform(val) }}</h5> } <risk-flex-spacer/> </risk-flex> @if (dialogData.cancel != null) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <button mat-button color="warn" (click)="dialogData.cancel()">Cancel</button> <risk-flex-spacer/> </risk-flex> } `, isInline: true, styles: ["h3{margin-bottom:0}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: RiskFlexComponent, selector: "risk-flex", inputs: ["wrapContent"] }, { kind: "component", type: RiskFlexSpacerComponent, selector: "risk-flex-spacer" }, { kind: "pipe", type: RiskPercentPipe, name: "percent" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskProgressLoaderComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, template: ` @let tot = total(); @let val = value(); <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <mat-progress-spinner [mode]="mode()" [value]="(val / (tot || 1)) * 100"/> <risk-flex-spacer/> </risk-flex> @if (dialogData.title) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <h3>{{ dialogData.title }}</h3> <risk-flex-spacer/> </risk-flex> } <risk-flex [wrapContent]="true"> <risk-flex-spacer/> @if (tot != null && tot > 0) { <h5>{{ valueFormatter.transform(val) }} /{{ valueFormatter.transform(tot) }} - {{ val / tot * 100 | percent:'.1-1' }}</h5> } @else { <h5>{{ valueFormatter.transform(val) }}</h5> } <risk-flex-spacer/> </risk-flex> @if (dialogData.cancel != null) { <risk-flex [wrapContent]="true"> <risk-flex-spacer/> <button mat-button color="warn" (click)="dialogData.cancel()">Cancel</button> <risk-flex-spacer/> </risk-flex> } `, host: { '[class.risk-progress-loader-dialog]': 'true' }, imports: [ MatButton, MatProgressSpinner, RiskFlexComponent, RiskFlexSpacerComponent, RiskPercentPipe ], styles: ["h3{margin-bottom:0}\n"] }] }] }); class RiskDialogService { constructor() { this.dialog = inject(MatDialog); } showWarnDialog(message, note) { return this.showMessageDialog({ dialogType: 'warning', message, note }); } showWarnQuestionDialog(destroyCallback, destructiveButtonLabel, message, note) { return this.showMessageDialog({ dialogType: 'warning', message, note, buttons: [ { label: destructiveButtonLabel, value: true, primary: true }, { label: 'Cancel', value: false } ], answerCallback(result) { if (result) { destroyCallback(); } } }); } showErrorDialog(message, note) { return this.showMessageDialog({ dialogType: 'error', message, note }); } showInfoDialog(message, note) { return this.showMessageDialog({ dialogType: 'info', message, note }); } showSuccessDialog(message, note) { return this.showMessageDialog({ dialogType: 'success', message, note }); } showQuestionDialog(buttons, answerCallback, message, note) { return this.showMessageDialog({ dialogType: 'question', message, note, buttons, answerCallback }); } showMessageDialog(config) { return this.showDialog(RiskMessageDialogComponent, { ...config.config, data: { dialogType: config.dialogType, buttons: config.buttons, title: config.title, message: config.message, note: config.note, icon: config.icon } }, config.answerCallback); } /* eslint-enable */ showLoaderDialog(data) { if (typeof data === 'string') { data = { title: data }; } return this.showDialog(RiskLoaderComponent, { disableClose: true, hasBackdrop: true, data }); } /* eslint-enable */ showProgressLoaderDialog(data) { if (typeof data === 'string') { data = { title: data }; } return this.showDialog(RiskProgressLoaderComponent, { disableClose: true, hasBackdrop: true, data }); } /* eslint-enable */ showDialog(dialogClass, configOrCallback, callback) { let config; if (typeof configOrCallback === 'function') { callback = configOrCallback; } else { config = configOrCallback; } const dialogRef = this.dialog.open(dialogClass, config); dialogRef.afterClosed().pipe(first()).subscribe((result) => { if (callback) { callback(result); } }); return dialogRef.componentInstance; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskDialogService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskDialogService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); /** * Class instances emitted [to observers] for each mql notification */ class MediaChange { constructor(mediaQuery = 'all') { this.mediaQuery = mediaQuery; } } /** * MediaMonitor configures listeners to mediaQuery changes and publishes an Observable facade to * convert mediaQuery change callbacks to subscriber notifications. These notifications will be * performed within the ng Zone to trigger change detections and component updates. * * NOTE: both mediaQuery activations and de-activations are announced in notifications */ class MatchMedia { constructor() { this.ngZone = inject(NgZone); this.logger = inject(Logger); this._registry = new Map(); this._source = new BehaviorSubject(new MediaChange()); this._observable$ = this._source.asObservable(); } /** * For the specified mediaQuery? */ isActive(mediaQuery) { if (this._registry.has(mediaQuery)) { const mql = this._registry.get(mediaQuery); return mql.matches; } return false; } /** * External observers can watch for all (or a specific) mql changes. * Typically used by the MediaQueryAdaptor; optionally available to components * who wish to use the MediaMonitor as mediaMonitor$ observable service. * * NOTE: if a mediaQuery is not specified, then ALL mediaQuery activations will * be announced. */ observe(mediaQuery) { this.registerQuery(mediaQuery); return this._observable$.pipe(filter((change) => { return mediaQuery ? (change.mediaQuery === mediaQuery) : true; })); } /** * Based on the BreakPointRegistry provider, register internal listeners for each unique * mediaQuery. Each listener emits specific MediaChange data to observers */ registerQuery(mediaQuery) { const list = normalizeQuery(mediaQuery); if (list.length > 0) { prepareQueryCSS(list, this.logger); list.forEach((query) => { let mql = this._registry.get(query); const onMQLEvent = () => { this.ngZone.run(() => { const change = new MediaChange(query); this._source.next(change); }); }; if (!mql) { mql = this._buildMQL(query); mql.addEventListener('change', onMQLEvent); this._registry.set(query, mql); } if (mql.matches) { onMQLEvent(); // Announce activate range for initial subscribers } }); } } /** * Call window.matchMedia() to build a MediaQueryList; which * supports 0..n listeners for activation/deactivation */ _buildMQL(query) { const canListen = !!window.matchMedia('all').addEventListener; return canListen ? window.matchMedia(query) : { matches: query === 'all' || query === '', media: query, addListener: () => undefined, addEventListener: () => undefined, removeListener: () => undefined, removeEventListener: () => undefined, dispatchEvent: () => false, onchange: () => undefined }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchMedia, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchMedia, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: MatchMedia, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); /** * Private global registry for all dynamically-created, injected style tags * @see prepare(query) */ const ALL_STYLES = {}; /** * For Webkit engines that only trigger the MediaQueryList Listener * when there is at least one CSS selector for the respective media query. * * @param mediaQueries string[] The mediaQueries used to create a faux CSS selector * */ function prepareQueryCSS(mediaQueries, logger) { const list = mediaQueries.filter((it) => !ALL_STYLES[it]); if (list.length > 0) { const query = list.join(', '); try { const style = document.createElement('style'); style.setAttribute('type', CONTENT_TYPE.TEXT_CSS); // Older IEs if (!style.styleSheet) { const cssText = `/* @angular/flex-layout - workaround for possible browser quirk with mediaQuery listeners see http://bit.ly/2sd4HMP */ @media ${query} {.fx-query-test{ }}`; style.appendChild(document.createTextNode(cssText)); } document.getElementsByTagName('head')[0].appendChild(style); // Store in private global registry list.forEach((mq) => ALL_STYLES[mq] = style); } catch (e) { logger.error(e); } } } /** * Always convert to unique list of queries; for iteration in ::registerQuery() */ function normalizeQuery(mediaQuery) { return (typeof mediaQuery === 'undefined') ? [] : (typeof mediaQuery === 'string') ? [mediaQuery] : unique(mediaQuery); } /** * Filter duplicate mediaQueries in the list */ function unique(list) { const seen = {}; return list.filter((item) => { return seen.hasOwnProperty(item) ? false : (seen[item] = true); }); } const SMALL_SCREEN_MEDIA_QUERY = (width) => `screen and (max-width:${width}px)`; class RiskLayoutVerticalDirective { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutVerticalDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: RiskLayoutVerticalDirective, isStandalone: true, selector: "risk-layout-vertical", host: { properties: { "class.risk-layout-vertical": "true" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutVerticalDirective, decorators: [{ type: Directive, args: [{ selector: 'risk-layout-vertical', host: { '[class.risk-layout-vertical]': 'true' } }] }] }); class RiskLayoutVerticalTitleDirective { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutVerticalTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: RiskLayoutVerticalTitleDirective, isStandalone: true, selector: "risk-layout-vertical-title", host: { properties: { "class.risk-layout-vertical-title": "true" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutVerticalTitleDirective, decorators: [{ type: Directive, args: [{ selector: 'risk-layout-vertical-title', host: { '[class.risk-layout-vertical-title]': 'true' } }] }] }); class RiskLayoutVerticalIconDirective { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutVerticalIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: RiskLayoutVerticalIconDirective, isStandalone: true, selector: "risk-layout-vertical-icon", host: { properties: { "class.risk-layout-vertical-icon": "true" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutVerticalIconDirective, decorators: [{ type: Directive, args: [{ selector: 'risk-layout-vertical-icon', host: { '[class.risk-layout-vertical-icon]': 'true' } }] }] }); class RiskLayoutHorizontalDirective { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutHorizontalDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: RiskLayoutHorizontalDirective, isStandalone: true, selector: "risk-layout-horizontal", host: { properties: { "class.mat-toolbar-row": "true", "class.mat-toolbar-single-row": "true", "class.risk-layout-horizontal": "true" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutHorizontalDirective, decorators: [{ type: Directive, args: [{ selector: 'risk-layout-horizontal', host: { '[class.mat-toolbar-row]': 'true', '[class.mat-toolbar-single-row]': 'true', '[class.risk-layout-horizontal]': 'true' } }] }] }); class RiskLayoutFooterDirective { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: RiskLayoutFooterDirective, isStandalone: true, selector: "risk-layout-footer", host: { properties: { "class.risk-layout-footer": "true" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutFooterDirective, decorators: [{ type: Directive, args: [{ selector: 'risk-layout-footer', host: { '[class.risk-layout-footer]': 'true' } }] }] }); class RiskLayoutComponent { constructor() { this.authProvider = inject(AUTH_PROVIDER, { optional: true }); this.mainLogo = inject(MAIN_LOGO); this.matchMedia = inject(MatchMedia); this.smallScreenMenuVisible = input(true, ...(ngDevMode ? [{ debugName: "smallScreenMenuVisible" }] : [])); this.smallScreenWidth = input(600, ...(ngDevMode ? [{ debugName: "smallScreenWidth" }] : [])); this.footerVisible = input(true, ...(ngDevMode ? [{ debugName: "footerVisible" }] : [])); this.toolbarBackgroundColor = input(...(ngDevMode ? [undefined, { debugName: "toolbarBackgroundColor" }] : [])); this.backgroundColor = input(...(ngDevMode ? [undefined, { debugName: "backgroundColor" }] : [])); this.mediaSmall = signal(false, ...(ngDevMode ? [{ debugName: "mediaSmall" }] : [])); this.authStatus = this.authProvider == null ? signal(true) : toSignal(this.authProvider.loggedInStream, { initialValue: false }); effect((onCleanup) => { const query = SMALL_SCREEN_MEDIA_QUERY(this.smallScreenWidth()); const subscription = this.matchMedia.observe(query).subscribe(() => { this.mediaSmall.set(this.matchMedia.isActive(query)); }); onCleanup(() => subscription.unsubscribe()); }); } get logo() { return this.mainLogo; } closeSideNav(sidenav) { if (!this.authStatus()) { sidenav.close(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: RiskLayoutComponent, isStandalone: true, selector: "risk-layout", inputs: { smallScreenMenuVisible: { classPropertyName: "smallScreenMenuVisible", publicName: "smallScreenMenuVisible", isSignal: true, isRequired: false, transformFunction: null }, smallScreenWidth: { classPropertyName: "smallScreenWidth", publicName: "smallScreenWidth", isSignal: true, isRequired: false, transformFunction: null }, footerVisible: { classPropertyName: "footerVisible", publicName: "footerVisible", isSignal: true, isRequired: false, transformFunction: null }, toolbarBackgroundColor: { classPropertyName: "toolbarBackgroundColor", publicName: "toolbarBackgroundColor", isSignal: true, isRequired: false, transformFunction: null }, backgroundColor: { classPropertyName: "backgroundColor", publicName: "backgroundColor", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.risk-layout": "true" } }, ngImport: i0, template: "<mat-toolbar [style.backgroundColor]=\"toolbarBackgroundColor()\"\n class=\"mat-elevation-z2\">\n <div class=\"risk-layout-logo\">\n <img [src]=\"logo\" alt=\"Company logo\">\n </div>\n\n @if (authStatus()) {\n @if (!mediaSmall()) {\n <ng-content select=\"[menu-horizontal], risk-layout-horizontal > *\"/>\n }\n @if (mediaSmall()) {\n <ng-content select=\"[menu-vertical-title], risk-layout-vertical-title > *\"/>\n <risk-flex-spacer/>\n <ng-content select=\"[menu-vertical-icon], risk-layout-vertical-icon > *\"/>\n @if (smallScreenMenuVisible()) {\n <button (click)=\"sidenav.toggle()\"\n mat-icon-button\n type=\"button\"\n >\n <mat-icon>menu</mat-icon>\n </button>\n }\n }\n }\n</mat-toolbar>\n\n<mat-sidenav-container [class.risk-layout-with-footer]=\"footerVisible()\"\n [style.backgroundColor]=\"backgroundColor()\">\n <mat-sidenav #sidenav=\"matSidenav\" (click)=\"closeSideNav(sidenav)\">\n <ng-content select=\"[menu-vertical], risk-layout-vertical > *\"/>\n </mat-sidenav>\n\n <div class=\"risk-layout-content\">\n <ng-content/>\n </div>\n</mat-sidenav-container>\n\n@if (footerVisible()) {\n <div class=\"risk-layout-footer\">\n <ng-content select=\"risk-layout-footer > *\"/>\n </div>\n}\n", styles: [":host{display:block;padding:0;margin:0}:host>*{vertical-align:bottom}\n", ".risk-layout-logo{margin:0 16px;text-align:center;flex:0 0 auto}@media (max-width: 600px){.risk-layout-logo{margin:0 10px 0 0}}.risk-layout-logo img{height:30px;vertical-align:sub}@media (max-width: 600px){.risk-layout-logo img{height:25px}}.mat-toolbar{border-radius:0!important;position:fixed;z-index:100}@media (max-width: 600px){.mat-toolbar{font-size:17px}.mat-toolbar ::ng-deep h1,.mat-toolbar ::ng-deep h2,.mat-toolbar ::ng-deep h3,.mat-toolbar ::ng-deep h4,.mat-toolbar ::ng-deep h5,.mat-toolbar ::ng-deep h6{font-size:17px}}::ng-deep .risk-layout-horizontal{padding:0!important}::ng-deep .risk-layout-vertical,::ng-deep .risk-layout-vertical-title,::ng-deep .risk-layout-vertical-icon,::ng-deep .risk-layout-footer{display:block}.risk-layout-content{padding:0 50px 50px}@media screen and (max-width: 800px){.risk-layout-content{padding:0 10px}}.mat-sidenav-container{padding-top:69px}@media (max-width: 600px){.mat-sidenav-container{padding-top:61px}}.mat-sidenav{padding-top:77px}@media (max-width: 600px){.mat-sidenav{padding-top:69px}}.risk-layout-with-footer{padding-bottom:30px}.risk-layout-footer{position:fixed;right:0;bottom:0;left:0;overflow:hidden;display:flex;padding:0 .5rem;height:30px;line-height:32px;font-size:.7em;z-index:2}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: RiskFlexSpacerComponent, selector: "risk-flex-spacer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RiskLayoutComponent, decorators: [{ type: Component, args: [{ selector: 'risk-layout', changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class.risk-layout]': 'true' }, imports: [ MatIcon, MatIconButton, MatSidenav, MatSidenavContainer, MatToolbar, RiskFlexSpacerComponent ], template: "<mat-toolbar [style.backgroundColor]=\"toolbarBackgroundColor()\"\n class=\"mat-elevation-z2\">\n <div class=\"risk-layout-logo\">\n <img [src]=\"logo\" alt=\"Company logo\">\n </div>\n\n @if (authStatus()) {\n @if (!mediaSmall()) {\n <ng-content select=\"[menu-horizontal], risk-layout-horizontal > *\"/>\n }\n @if (mediaSmall()) {\n <ng-content select=\"[menu-vertical-title], risk-layout-vertical-title > *\"/>\n <risk-flex-spacer/>\n <ng-content select=\"[menu-vertical-icon], risk-layout-vertical-icon > *\"/>\n @if (smallScreenMenuVisible()) {\n <button (click)=\"sidenav.toggle()\"\n