tin-spa 2.6.2 → 2.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/esm2020/lib/classes/Classes.mjs +1 -1
  2. package/esm2020/lib/components/form/form.component.mjs +5 -4
  3. package/esm2020/lib/components/multi-text/multi-text.component.mjs +168 -0
  4. package/esm2020/lib/components/nav-menu/nav-menu.component.mjs +24 -20
  5. package/esm2020/lib/components/page/page.component.mjs +39 -3
  6. package/esm2020/lib/components/table/detailsDialog.component.mjs +15 -7
  7. package/esm2020/lib/components/table/table.component.mjs +4 -1
  8. package/esm2020/lib/components/table-internal/detailsDialog-internal.component.mjs +15 -7
  9. package/esm2020/lib/components/table-internal/table-internal.component.mjs +4 -1
  10. package/esm2020/lib/components/table-lite/detailsDialog-lite.component.mjs +15 -7
  11. package/esm2020/lib/components/table-lite/table-lite.component.mjs +4 -1
  12. package/esm2020/lib/modules/admin/admin-routing.module.mjs +3 -1
  13. package/esm2020/lib/pages/approvals/approvals.component.mjs +3 -2
  14. package/esm2020/lib/pages/approvals-config/approvals-config.component.mjs +2 -3
  15. package/esm2020/lib/pages/login/login.component.mjs +20 -13
  16. package/esm2020/lib/pages/logs/logs.component.mjs +1 -1
  17. package/esm2020/lib/pages/notifications/notifications.component.mjs +95 -6
  18. package/esm2020/lib/pages/tenant-settings/tenant-settings.component.mjs +37 -4
  19. package/esm2020/lib/services/datalib.service.mjs +1 -1
  20. package/esm2020/lib/services/notifications.service.mjs +33 -0
  21. package/esm2020/lib/tin-spa.module.mjs +6 -3
  22. package/esm2020/public-api.mjs +2 -1
  23. package/fesm2015/tin-spa.mjs +446 -62
  24. package/fesm2015/tin-spa.mjs.map +1 -1
  25. package/fesm2020/tin-spa.mjs +440 -56
  26. package/fesm2020/tin-spa.mjs.map +1 -1
  27. package/lib/classes/Classes.d.ts +2 -1
  28. package/lib/components/multi-text/multi-text.component.d.ts +46 -0
  29. package/lib/components/nav-menu/nav-menu.component.d.ts +4 -1
  30. package/lib/components/page/page.component.d.ts +13 -1
  31. package/lib/pages/login/login.component.d.ts +4 -1
  32. package/lib/pages/notifications/notifications.component.d.ts +10 -1
  33. package/lib/pages/tenant-settings/tenant-settings.component.d.ts +2 -0
  34. package/lib/services/notifications.service.d.ts +12 -0
  35. package/lib/tin-spa.module.d.ts +6 -5
  36. package/package.json +1 -1
  37. package/public-api.d.ts +1 -0
@@ -23,8 +23,9 @@ import { HttpHeaders, HttpResponse, HttpClientModule, HTTP_INTERCEPTORS } from '
23
23
  import * as i3$1 from '@angular/cdk/layout';
24
24
  import * as i8$1 from '@angular/material/autocomplete';
25
25
  import { MatAutocompleteModule } from '@angular/material/autocomplete';
26
+ import * as i10$1 from '@angular/material/badge';
26
27
  import { MatBadgeModule } from '@angular/material/badge';
27
- import * as i15 from '@angular/material/card';
28
+ import * as i16 from '@angular/material/card';
28
29
  import { MatCardModule } from '@angular/material/card';
29
30
  import * as i3$2 from '@angular/material/checkbox';
30
31
  import { MatCheckboxModule } from '@angular/material/checkbox';
@@ -36,9 +37,9 @@ import * as i8$2 from '@angular/material/datepicker';
36
37
  import { MatDatepickerModule } from '@angular/material/datepicker';
37
38
  import * as i6 from '@angular/material/input';
38
39
  import { MatInputModule } from '@angular/material/input';
39
- import * as i11$2 from '@angular/material/list';
40
+ import * as i13$1 from '@angular/material/list';
40
41
  import { MatListModule } from '@angular/material/list';
41
- import * as i8$3 from '@angular/material/menu';
42
+ import * as i9 from '@angular/material/menu';
42
43
  import { MatMenuModule } from '@angular/material/menu';
43
44
  import * as i11 from '@angular/material/paginator';
44
45
  import { MatPaginatorModule } from '@angular/material/paginator';
@@ -60,16 +61,16 @@ import * as i7 from '@angular/material/tooltip';
60
61
  import { MatTooltipModule } from '@angular/material/tooltip';
61
62
  import * as i2 from '@angular/forms';
62
63
  import { FormsModule, ReactiveFormsModule, FormControl, Validators, NG_VALUE_ACCESSOR } from '@angular/forms';
63
- import * as i14 from '@angular/material/sidenav';
64
+ import * as i16$1 from '@angular/material/sidenav';
64
65
  import { MatSidenavModule } from '@angular/material/sidenav';
65
- import * as i15$1 from '@angular/material/toolbar';
66
+ import * as i17 from '@angular/material/toolbar';
66
67
  import { MatToolbarModule } from '@angular/material/toolbar';
67
- import * as i16 from '@angular/material/expansion';
68
+ import * as i18 from '@angular/material/expansion';
68
69
  import { MatExpansionModule } from '@angular/material/expansion';
69
70
  import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
70
71
  import * as i6$2 from 'ngx-doc-viewer';
71
72
  import { NgxDocViewerModule } from 'ngx-doc-viewer';
72
- import * as i12 from '@angular/material/divider';
73
+ import * as i14 from '@angular/material/divider';
73
74
 
74
75
  class TinSpaService {
75
76
  constructor() { }
@@ -3307,6 +3308,161 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3307
3308
  type: Input
3308
3309
  }] } });
3309
3310
 
3311
+ class MultiTextComponent {
3312
+ constructor(messageService) {
3313
+ this.messageService = messageService;
3314
+ this.display = "";
3315
+ this.value = "";
3316
+ this.valueChange = new EventEmitter();
3317
+ this.readonly = false;
3318
+ this.required = true;
3319
+ this.hint = "";
3320
+ this.strict = false;
3321
+ this.copyContent = false;
3322
+ this.clearContent = false;
3323
+ this.options = [];
3324
+ this.optionDisplay = "name"; // Default to name if not provided
3325
+ this.optionValue = "value"; // Default to value if not provided
3326
+ this.values = [];
3327
+ this.control = new FormControl('');
3328
+ this.errorState = false;
3329
+ this.selectedFromAutocomplete = false;
3330
+ }
3331
+ ngOnInit() {
3332
+ this.values = this.value ? this.value.split(';').filter(val => val.trim() !== '') : [];
3333
+ this.setupAutoComplete();
3334
+ }
3335
+ ngOnChanges() {
3336
+ if (this.options) {
3337
+ this.setupAutoComplete();
3338
+ }
3339
+ }
3340
+ setupAutoComplete() {
3341
+ this.filteredOptions = this.control.valueChanges.pipe(startWith(''), map(value => this.filterOptions(value)));
3342
+ }
3343
+ filterOptions(value) {
3344
+ if (!value || !this.options)
3345
+ return this.options || [];
3346
+ const searchValue = value.toString().toLowerCase();
3347
+ return this.options.filter(option => {
3348
+ const displayValue = option[this.optionDisplay]?.toString().toLowerCase();
3349
+ return displayValue?.includes(searchValue);
3350
+ });
3351
+ }
3352
+ add(event) {
3353
+ // Skip validation if option was selected from autocomplete
3354
+ if (this.selectedFromAutocomplete) {
3355
+ this.selectedFromAutocomplete = false;
3356
+ return;
3357
+ }
3358
+ const input = (event.value || '').trim();
3359
+ if (!input)
3360
+ return;
3361
+ if (this.strict) {
3362
+ const found = this.options.find(opt => {
3363
+ const optionDisplayValue = opt[this.optionDisplay]?.toString().toLowerCase();
3364
+ const optionValue = opt[this.optionValue]?.toString().toLowerCase();
3365
+ const inputLower = input.toLowerCase();
3366
+ return optionDisplayValue === inputLower || optionValue === inputLower;
3367
+ });
3368
+ // if (!found) {
3369
+ // this.errorState = true;
3370
+ // this.hint = 'Value must be selected from the list';
3371
+ // return;
3372
+ // }
3373
+ this.addValue(found[this.optionValue]?.toString());
3374
+ }
3375
+ else {
3376
+ this.addValue(input);
3377
+ }
3378
+ this.resetInput();
3379
+ }
3380
+ addValue(value) {
3381
+ if (!this.values.includes(value)) {
3382
+ this.values.push(value);
3383
+ this.errorState = false;
3384
+ this.updateValue();
3385
+ }
3386
+ }
3387
+ remove(value) {
3388
+ const index = this.values.indexOf(value);
3389
+ if (index >= 0) {
3390
+ this.values.splice(index, 1);
3391
+ this.updateValue();
3392
+ }
3393
+ }
3394
+ optionSelected(event) {
3395
+ const selectedOption = event.option.value;
3396
+ if (selectedOption) {
3397
+ this.selectedFromAutocomplete = true;
3398
+ this.addValue(selectedOption[this.optionValue]?.toString());
3399
+ this.resetInput();
3400
+ }
3401
+ }
3402
+ resetInput() {
3403
+ // Reset form control
3404
+ this.control.setValue('');
3405
+ // Reset input element if available
3406
+ if (this.textInput?.nativeElement) {
3407
+ this.textInput.nativeElement.value = '';
3408
+ }
3409
+ }
3410
+ updateValue() {
3411
+ this.value = this.values.join(';');
3412
+ this.valueChange.emit(this.value);
3413
+ }
3414
+ clear() {
3415
+ this.values = [];
3416
+ this.updateValue();
3417
+ }
3418
+ getDisplayValue(value) {
3419
+ const option = this.options?.find(opt => opt[this.optionValue]?.toString() === value);
3420
+ return option ? option[this.optionDisplay]?.toString() : value;
3421
+ }
3422
+ copyValues() {
3423
+ navigator.clipboard.writeText(this.value).then(() => {
3424
+ this.messageService.toast('Copied');
3425
+ });
3426
+ }
3427
+ }
3428
+ MultiTextComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MultiTextComponent, deps: [{ token: MessageService }], target: i0.ɵɵFactoryTarget.Component });
3429
+ MultiTextComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MultiTextComponent, selector: "spa-multi-text", inputs: { display: "display", value: "value", readonly: "readonly", required: "required", hint: "hint", strict: "strict", suffix: "suffix", infoMessage: "infoMessage", copyContent: "copyContent", clearContent: "clearContent", options: "options", optionDisplay: "optionDisplay", optionValue: "optionValue" }, outputs: { valueChange: "valueChange" }, viewQueries: [{ propertyName: "textInput", first: true, predicate: ["textInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<mat-form-field style=\"width: 100%;\">\n <mat-label>{{display}}</mat-label>\n <mat-chip-list #chipList>\n <mat-chip *ngFor=\"let value of values\" [removable]=\"!readonly\" (removed)=\"remove(value)\">\n {{getDisplayValue(value)}}\n <mat-icon matChipRemove *ngIf=\"!readonly\">cancel</mat-icon>\n </mat-chip>\n <input #textInput autocomplete=\"off\" [placeholder]=\"readonly ? '' : display\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"add($event)\" [formControl]=\"control\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\">\n </mat-chip-list>\n\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"option\">\n {{option[optionDisplay]}}\n </mat-option>\n </mat-autocomplete>\n\n <mat-error *ngIf=\"errorState\">{{hint}}</mat-error>\n <mat-hint *ngIf=\"hint && !errorState\">{{hint}}</mat-hint>\n\n <div matSuffix class=\"suffix-icons\">\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\">\n </spa-suffix>\n </div>\n</mat-form-field>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix]" }, { kind: "component", type: i6$1.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i6$1.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "directive", type: i6$1.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i6$1.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i7$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i8$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { kind: "directive", type: i8$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: SuffixComponent, selector: "spa-suffix", inputs: ["label", "infoMessage", "copyContent", "isHovered", "clearContent", "value"], outputs: ["infoClick", "copyClick", "clearClick", "valueChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
3430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MultiTextComponent, decorators: [{
3431
+ type: Component,
3432
+ args: [{ selector: 'spa-multi-text', template: "<mat-form-field style=\"width: 100%;\">\n <mat-label>{{display}}</mat-label>\n <mat-chip-list #chipList>\n <mat-chip *ngFor=\"let value of values\" [removable]=\"!readonly\" (removed)=\"remove(value)\">\n {{getDisplayValue(value)}}\n <mat-icon matChipRemove *ngIf=\"!readonly\">cancel</mat-icon>\n </mat-chip>\n <input #textInput autocomplete=\"off\" [placeholder]=\"readonly ? '' : display\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"add($event)\" [formControl]=\"control\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\">\n </mat-chip-list>\n\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\n <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"option\">\n {{option[optionDisplay]}}\n </mat-option>\n </mat-autocomplete>\n\n <mat-error *ngIf=\"errorState\">{{hint}}</mat-error>\n <mat-hint *ngIf=\"hint && !errorState\">{{hint}}</mat-hint>\n\n <div matSuffix class=\"suffix-icons\">\n <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\">\n </spa-suffix>\n </div>\n</mat-form-field>\n" }]
3433
+ }], ctorParameters: function () { return [{ type: MessageService }]; }, propDecorators: { textInput: [{
3434
+ type: ViewChild,
3435
+ args: ['textInput']
3436
+ }], display: [{
3437
+ type: Input
3438
+ }], value: [{
3439
+ type: Input
3440
+ }], valueChange: [{
3441
+ type: Output
3442
+ }], readonly: [{
3443
+ type: Input
3444
+ }], required: [{
3445
+ type: Input
3446
+ }], hint: [{
3447
+ type: Input
3448
+ }], strict: [{
3449
+ type: Input
3450
+ }], suffix: [{
3451
+ type: Input
3452
+ }], infoMessage: [{
3453
+ type: Input
3454
+ }], copyContent: [{
3455
+ type: Input
3456
+ }], clearContent: [{
3457
+ type: Input
3458
+ }], options: [{
3459
+ type: Input
3460
+ }], optionDisplay: [{
3461
+ type: Input
3462
+ }], optionValue: [{
3463
+ type: Input
3464
+ }] } });
3465
+
3310
3466
  class CamelToWordsPipe {
3311
3467
  transform(value) {
3312
3468
  return Core.camelToWords(value);
@@ -3492,10 +3648,10 @@ class FormComponent {
3492
3648
  }
3493
3649
  }
3494
3650
  FormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormComponent, deps: [{ token: MessageService }, { token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component });
3495
- FormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: FormComponent, selector: "spa-form", inputs: { files: "files", data: "data", config: "config" }, outputs: { buttonClick: "buttonClick", inputChange: "inputChange" }, queries: [{ propertyName: "dynamicSelectTemplate", first: true, predicate: ["dynamicSelect"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\r\n<div [ngClass]=\"multiColumn ? 'tin-grid' : 'tin-col'\">\r\n\r\n <div [ngClass]=\"field.span || field.type =='section' || field.type =='file' || field.type =='file-view' ? 'span-col' : ''\" *ngFor=\"let field of getVisibleFields()\">\r\n\r\n <ng-container >\r\n\r\n <ng-container [ngSwitch]=\"field.type\" class=\"highlight\">\r\n\r\n <div *ngSwitchCase=\"'section'\" class=\"title\">\r\n <label style=\"font-size: larger;\">{{field.name | camelToWords}}</label>\r\n </div>\r\n\r\n <ng-container *ngSwitchCase=\"'file'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode !='view'\">\r\n <spa-attach message=\"Drag and Drop files here\" [(files)]=\"files\"></spa-attach>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'file-view'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode && config.mode !='create'\">\r\n <spa-viewer [fileAction]=\"field.loadAction\" [path]=\"field.path\" [folderName]=\"data[field.keyField]\" ></spa-viewer>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <label *ngSwitchCase=\"'blank'\"></label>\r\n\r\n <label *ngSwitchCase=\"'string'\" [ngStyle]=\"{'font-size':field.size ?? '14px'}\" >{{data[field.name] ?? field.alias ?? field.name}}</label>\r\n\r\n <spa-label *ngSwitchCase=\"'label'\" [display]=\"field.alias ?? field.name | camelToWords\" [value]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [format]=\"field.format\" ></spa-label>\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [infoMessage]=\"field.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [min]=\"field?.min\" [max]=\"field?.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [min]=\"field.min\" [max]=\"field.max\" [infoMessage]=\"field.infoMessage\" ></spa-datetime>\r\n\r\n <spa-email *ngSwitchCase=\"'email'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-email>\r\n\r\n <spa-text *ngSwitchCase=\"'password'\" [format]=\"'password'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n\r\n <!-- <spa-select *ngSwitchCase=\"'multi-select'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [multiple]=\"true\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" >\r\n </spa-select> -->\r\n\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'composite'\">\r\n <div class=\"composite-field-container\">\r\n <div class=\"composite-field-group\">\r\n <ng-container *ngFor=\"let subfield of getVisibleSubfields(field)\">\r\n <ng-container [ngSwitch]=\"subfield.type\">\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [infoMessage]=\"subfield.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [infoMessage]=\"subfield.infoMessage\" ></spa-datetime>\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n <spa-text *ngSwitchDefault [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [options]=\"subfield.options\" [optionValue]=\"subfield.optionValue ?? 'value'\" [rows]=\"subfield.rows\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <spa-text *ngSwitchDefault [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"span-col-center\" *ngIf=\"config.button\">\r\n <button mat-raised-button color=\"primary\" (click)=\"buttonClicked()\" cdkFocusInitial>{{buttonDisplay}}</button>\r\n </div>\r\n\r\n\r\n</div>\r\n", styles: [".title{margin-top:1em;font-size:larger;font-weight:300}.composite-field-group{display:flex;flex-direction:row;flex-wrap:wrap;gap:12px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: TextComponent, selector: "spa-text", inputs: ["readonly", "hint", "display", "placeholder", "value", "format", "type", "rows", "width", "copyContent", "clearContent", "options", "optionValue", "required", "min", "max", "regex", "suffix", "infoMessage"], outputs: ["valueChange", "leave", "enterPress"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: DateComponent, selector: "spa-date", inputs: ["required", "min", "max", "readonly", "hint", "value", "display", "placeholder", "width", "infoMessage"], outputs: ["valueChange", "infoClick"] }, { kind: "component", type: DatetimeComponent, selector: "spa-datetime", inputs: ["display", "value", "readonly", "width", "min", "max", "infoMessage"], outputs: ["valueChange", "infoClick"] }, { kind: "component", type: LabelComponent, selector: "spa-label", inputs: ["display", "value", "format"] }, { kind: "component", type: MoneyComponent, selector: "spa-money", inputs: ["readonly", "hint", "display", "placeholder", "value", "width", "currency", "required", "min", "max", "infoMessage"], outputs: ["valueChange", "leave", "enterPress", "infoClick"] }, { kind: "component", type: AttachComponent, selector: "spa-attach", inputs: ["message", "files", "enableUpload"], outputs: ["filesChange", "upload"] }, { kind: "component", type: NumberComponent, selector: "spa-number", inputs: ["readonly", "hint", "display", "placeholder", "value", "width", "required", "min", "max", "step", "suffix", "infoMessage"], outputs: ["valueChange", "leave", "enterPress", "infoClick"] }, { kind: "component", type: ViewerComponent, selector: "spa-viewer", inputs: ["fileAction", "path", "folderName", "fileNames", "removable", "display", "title"], outputs: ["remove"] }, { kind: "component", type: EmailComponent, selector: "spa-email", inputs: ["display", "value", "readonly", "required", "hint", "suffix", "infoMessage", "copyContent", "clearContent", "options", "optionValue"], outputs: ["valueChange"] }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] });
3651
+ FormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: FormComponent, selector: "spa-form", inputs: { files: "files", data: "data", config: "config" }, outputs: { buttonClick: "buttonClick", inputChange: "inputChange" }, queries: [{ propertyName: "dynamicSelectTemplate", first: true, predicate: ["dynamicSelect"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "\r\n<div [ngClass]=\"multiColumn ? 'tin-grid' : 'tin-col'\">\r\n\r\n <div [ngClass]=\"field.span || field.type =='section' || field.type =='file' || field.type =='file-view' ? 'span-col' : ''\" *ngFor=\"let field of getVisibleFields()\">\r\n\r\n <ng-container >\r\n\r\n <ng-container [ngSwitch]=\"field.type\" class=\"highlight\">\r\n\r\n <div *ngSwitchCase=\"'section'\" class=\"title\">\r\n <label style=\"font-size: larger;\">{{field.name | camelToWords}}</label>\r\n </div>\r\n\r\n <ng-container *ngSwitchCase=\"'file'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode !='view'\">\r\n <spa-attach message=\"Drag and Drop files here\" [(files)]=\"files\"></spa-attach>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'file-view'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode && config.mode !='create'\">\r\n <spa-viewer [fileAction]=\"field.loadAction\" [path]=\"field.path\" [folderName]=\"data[field.keyField]\" ></spa-viewer>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <label *ngSwitchCase=\"'blank'\"></label>\r\n\r\n <label *ngSwitchCase=\"'string'\" [ngStyle]=\"{'font-size':field.size ?? '14px'}\" >{{data[field.name] ?? field.alias ?? field.name}}</label>\r\n\r\n <spa-label *ngSwitchCase=\"'label'\" [display]=\"field.alias ?? field.name | camelToWords\" [value]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [format]=\"field.format\" ></spa-label>\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [infoMessage]=\"field.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [min]=\"field?.min\" [max]=\"field?.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [min]=\"field.min\" [max]=\"field.max\" [infoMessage]=\"field.infoMessage\" ></spa-datetime>\r\n\r\n <spa-email *ngSwitchCase=\"'email'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-email>\r\n\r\n <spa-text *ngSwitchCase=\"'password'\" [format]=\"'password'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n\r\n <!-- <spa-select *ngSwitchCase=\"'multi-select'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [multiple]=\"true\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" >\r\n </spa-select> -->\r\n\r\n <spa-multi-text *ngSwitchCase=\"'multi-text'\" [strict]=\"field.strict\" [display]=\"field.alias ?? field.name | camelToWords\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-multi-text>\r\n\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'composite'\">\r\n <div class=\"composite-field-container\">\r\n <div class=\"composite-field-group\">\r\n <ng-container *ngFor=\"let subfield of getVisibleSubfields(field)\">\r\n <ng-container [ngSwitch]=\"subfield.type\">\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [infoMessage]=\"subfield.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [infoMessage]=\"subfield.infoMessage\" ></spa-datetime>\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n <spa-text *ngSwitchDefault [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [options]=\"subfield.options\" [optionValue]=\"subfield.optionValue ?? 'value'\" [rows]=\"subfield.rows\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <spa-text *ngSwitchDefault [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"span-col-center\" *ngIf=\"config.button\">\r\n <button mat-raised-button color=\"primary\" (click)=\"buttonClicked()\" cdkFocusInitial>{{buttonDisplay}}</button>\r\n </div>\r\n\r\n\r\n</div>\r\n", styles: [".title{margin-top:1em;font-size:larger;font-weight:300}.composite-field-group{display:flex;flex-direction:row;flex-wrap:wrap;gap:12px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: TextComponent, selector: "spa-text", inputs: ["readonly", "hint", "display", "placeholder", "value", "format", "type", "rows", "width", "copyContent", "clearContent", "options", "optionValue", "required", "min", "max", "regex", "suffix", "infoMessage"], outputs: ["valueChange", "leave", "enterPress"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: DateComponent, selector: "spa-date", inputs: ["required", "min", "max", "readonly", "hint", "value", "display", "placeholder", "width", "infoMessage"], outputs: ["valueChange", "infoClick"] }, { kind: "component", type: DatetimeComponent, selector: "spa-datetime", inputs: ["display", "value", "readonly", "width", "min", "max", "infoMessage"], outputs: ["valueChange", "infoClick"] }, { kind: "component", type: LabelComponent, selector: "spa-label", inputs: ["display", "value", "format"] }, { kind: "component", type: MoneyComponent, selector: "spa-money", inputs: ["readonly", "hint", "display", "placeholder", "value", "width", "currency", "required", "min", "max", "infoMessage"], outputs: ["valueChange", "leave", "enterPress", "infoClick"] }, { kind: "component", type: AttachComponent, selector: "spa-attach", inputs: ["message", "files", "enableUpload"], outputs: ["filesChange", "upload"] }, { kind: "component", type: NumberComponent, selector: "spa-number", inputs: ["readonly", "hint", "display", "placeholder", "value", "width", "required", "min", "max", "step", "suffix", "infoMessage"], outputs: ["valueChange", "leave", "enterPress", "infoClick"] }, { kind: "component", type: ViewerComponent, selector: "spa-viewer", inputs: ["fileAction", "path", "folderName", "fileNames", "removable", "display", "title"], outputs: ["remove"] }, { kind: "component", type: EmailComponent, selector: "spa-email", inputs: ["display", "value", "readonly", "required", "hint", "suffix", "infoMessage", "copyContent", "clearContent", "options", "optionValue"], outputs: ["valueChange"] }, { kind: "component", type: MultiTextComponent, selector: "spa-multi-text", inputs: ["display", "value", "readonly", "required", "hint", "strict", "suffix", "infoMessage", "copyContent", "clearContent", "options", "optionDisplay", "optionValue"], outputs: ["valueChange"] }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] });
3496
3652
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: FormComponent, decorators: [{
3497
3653
  type: Component,
3498
- args: [{ selector: 'spa-form', template: "\r\n<div [ngClass]=\"multiColumn ? 'tin-grid' : 'tin-col'\">\r\n\r\n <div [ngClass]=\"field.span || field.type =='section' || field.type =='file' || field.type =='file-view' ? 'span-col' : ''\" *ngFor=\"let field of getVisibleFields()\">\r\n\r\n <ng-container >\r\n\r\n <ng-container [ngSwitch]=\"field.type\" class=\"highlight\">\r\n\r\n <div *ngSwitchCase=\"'section'\" class=\"title\">\r\n <label style=\"font-size: larger;\">{{field.name | camelToWords}}</label>\r\n </div>\r\n\r\n <ng-container *ngSwitchCase=\"'file'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode !='view'\">\r\n <spa-attach message=\"Drag and Drop files here\" [(files)]=\"files\"></spa-attach>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'file-view'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode && config.mode !='create'\">\r\n <spa-viewer [fileAction]=\"field.loadAction\" [path]=\"field.path\" [folderName]=\"data[field.keyField]\" ></spa-viewer>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <label *ngSwitchCase=\"'blank'\"></label>\r\n\r\n <label *ngSwitchCase=\"'string'\" [ngStyle]=\"{'font-size':field.size ?? '14px'}\" >{{data[field.name] ?? field.alias ?? field.name}}</label>\r\n\r\n <spa-label *ngSwitchCase=\"'label'\" [display]=\"field.alias ?? field.name | camelToWords\" [value]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [format]=\"field.format\" ></spa-label>\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [infoMessage]=\"field.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [min]=\"field?.min\" [max]=\"field?.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [min]=\"field.min\" [max]=\"field.max\" [infoMessage]=\"field.infoMessage\" ></spa-datetime>\r\n\r\n <spa-email *ngSwitchCase=\"'email'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-email>\r\n\r\n <spa-text *ngSwitchCase=\"'password'\" [format]=\"'password'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n\r\n <!-- <spa-select *ngSwitchCase=\"'multi-select'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [multiple]=\"true\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" >\r\n </spa-select> -->\r\n\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'composite'\">\r\n <div class=\"composite-field-container\">\r\n <div class=\"composite-field-group\">\r\n <ng-container *ngFor=\"let subfield of getVisibleSubfields(field)\">\r\n <ng-container [ngSwitch]=\"subfield.type\">\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [infoMessage]=\"subfield.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [infoMessage]=\"subfield.infoMessage\" ></spa-datetime>\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n <spa-text *ngSwitchDefault [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [options]=\"subfield.options\" [optionValue]=\"subfield.optionValue ?? 'value'\" [rows]=\"subfield.rows\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <spa-text *ngSwitchDefault [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"span-col-center\" *ngIf=\"config.button\">\r\n <button mat-raised-button color=\"primary\" (click)=\"buttonClicked()\" cdkFocusInitial>{{buttonDisplay}}</button>\r\n </div>\r\n\r\n\r\n</div>\r\n", styles: [".title{margin-top:1em;font-size:larger;font-weight:300}.composite-field-group{display:flex;flex-direction:row;flex-wrap:wrap;gap:12px}\n"] }]
3654
+ args: [{ selector: 'spa-form', template: "\r\n<div [ngClass]=\"multiColumn ? 'tin-grid' : 'tin-col'\">\r\n\r\n <div [ngClass]=\"field.span || field.type =='section' || field.type =='file' || field.type =='file-view' ? 'span-col' : ''\" *ngFor=\"let field of getVisibleFields()\">\r\n\r\n <ng-container >\r\n\r\n <ng-container [ngSwitch]=\"field.type\" class=\"highlight\">\r\n\r\n <div *ngSwitchCase=\"'section'\" class=\"title\">\r\n <label style=\"font-size: larger;\">{{field.name | camelToWords}}</label>\r\n </div>\r\n\r\n <ng-container *ngSwitchCase=\"'file'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode !='view'\">\r\n <spa-attach message=\"Drag and Drop files here\" [(files)]=\"files\"></spa-attach>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngSwitchCase=\"'file-view'\">\r\n <div class=\"mt-1 mb-2\" *ngIf=\"config.mode && config.mode !='create'\">\r\n <spa-viewer [fileAction]=\"field.loadAction\" [path]=\"field.path\" [folderName]=\"data[field.keyField]\" ></spa-viewer>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <label *ngSwitchCase=\"'blank'\"></label>\r\n\r\n <label *ngSwitchCase=\"'string'\" [ngStyle]=\"{'font-size':field.size ?? '14px'}\" >{{data[field.name] ?? field.alias ?? field.name}}</label>\r\n\r\n <spa-label *ngSwitchCase=\"'label'\" [display]=\"field.alias ?? field.name | camelToWords\" [value]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [format]=\"field.format\" ></spa-label>\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [infoMessage]=\"field.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [min]=\"field?.min\" [max]=\"field?.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [min]=\"field.min\" [max]=\"field.max\" [infoMessage]=\"field.infoMessage\" ></spa-datetime>\r\n\r\n <spa-email *ngSwitchCase=\"'email'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-email>\r\n\r\n <spa-text *ngSwitchCase=\"'password'\" [format]=\"'password'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n\r\n <!-- <spa-select *ngSwitchCase=\"'multi-select'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [multiple]=\"true\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" >\r\n </spa-select> -->\r\n\r\n <spa-multi-text *ngSwitchCase=\"'multi-text'\" [strict]=\"field.strict\" [display]=\"field.alias ?? field.name | camelToWords\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-multi-text>\r\n\r\n\r\n\r\n <ng-container *ngSwitchCase=\"'composite'\">\r\n <div class=\"composite-field-container\">\r\n <div class=\"composite-field-group\">\r\n <ng-container *ngFor=\"let subfield of getVisibleSubfields(field)\">\r\n <ng-container [ngSwitch]=\"subfield.type\">\r\n\r\n <spa-number *ngSwitchCase=\"'number'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\"></spa-number>\r\n\r\n <spa-money *ngSwitchCase=\"'money'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-money>\r\n\r\n <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [infoMessage]=\"subfield.infoMessage\" ></spa-check>\r\n\r\n <spa-date *ngSwitchCase=\"'date'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" ></spa-date>\r\n\r\n <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [infoMessage]=\"subfield.infoMessage\" ></spa-datetime>\r\n\r\n <ng-container *ngSwitchCase=\"'select'\">\r\n <ng-container *ngTemplateOutlet=\"dynamicSelectTemplate; context: {\r\n $implicit: field,\r\n field: field,\r\n data: data,\r\n testReadOnly: testReadOnly.bind(this),\r\n selectChanged: selectChanged.bind(this)\r\n }\">\r\n </ng-container>\r\n </ng-container>\r\n\r\n <spa-text *ngSwitchDefault [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [options]=\"subfield.options\" [optionValue]=\"subfield.optionValue ?? 'value'\" [rows]=\"subfield.rows\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"subfield.required\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n\r\n </ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n\r\n <spa-text *ngSwitchDefault [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionValue]=\"field.optionValue ?? 'value'\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-text>\r\n\r\n </ng-container>\r\n\r\n </ng-container>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"span-col-center\" *ngIf=\"config.button\">\r\n <button mat-raised-button color=\"primary\" (click)=\"buttonClicked()\" cdkFocusInitial>{{buttonDisplay}}</button>\r\n </div>\r\n\r\n\r\n</div>\r\n", styles: [".title{margin-top:1em;font-size:larger;font-weight:300}.composite-field-group{display:flex;flex-direction:row;flex-wrap:wrap;gap:12px}\n"] }]
3499
3655
  }], ctorParameters: function () { return [{ type: MessageService }, { type: DataServiceLib }]; }, propDecorators: { dynamicSelectTemplate: [{
3500
3656
  type: ContentChild,
3501
3657
  args: ['dynamicSelect']
@@ -3698,7 +3854,7 @@ class DetailsDialogLite {
3698
3854
  return;
3699
3855
  }
3700
3856
  if (this.validateForm()) {
3701
- this.executeAction(button, this.details, button.action?.successMessage || "Updated");
3857
+ this.executeAction(button, this.details);
3702
3858
  }
3703
3859
  }
3704
3860
  validateForm() {
@@ -3734,23 +3890,31 @@ class DetailsDialogLite {
3734
3890
  }
3735
3891
  return data;
3736
3892
  }
3737
- executeAction(button, data, defaultSuccessMessage) {
3893
+ executeAction(button, data) {
3738
3894
  const actionData = this.prepareActionData(button, data);
3739
3895
  if (button.confirm) {
3740
3896
  this.messageService.confirm(button.confirm.message).subscribe((result) => {
3741
3897
  if (result === "yes") {
3742
- this.performApiCall(button, actionData, defaultSuccessMessage);
3898
+ this.performApiCall(button, actionData);
3743
3899
  }
3744
3900
  });
3745
3901
  }
3746
3902
  else {
3747
- this.performApiCall(button, actionData, defaultSuccessMessage);
3903
+ this.performApiCall(button, actionData);
3748
3904
  }
3749
3905
  }
3750
- performApiCall(button, data, defaultSuccessMessage) {
3906
+ performApiCall(button, data) {
3751
3907
  this.dataService.CallApi(button.action, data).subscribe((apiResponse) => {
3752
3908
  if (apiResponse.success) {
3753
- this.messageService.toast(button.action?.successMessage || defaultSuccessMessage);
3909
+ if (button.action.successMessage) {
3910
+ this.messageService.toast(button.action.successMessage);
3911
+ }
3912
+ else if (apiResponse.message != "success" && apiResponse.message != "") {
3913
+ this.messageService.toast(apiResponse.message);
3914
+ }
3915
+ else {
3916
+ this.messageService.toast("Updated");
3917
+ }
3754
3918
  this.dialogRef.close({ message: 'success', data: { ...apiResponse, data: this.details } });
3755
3919
  }
3756
3920
  else {
@@ -4124,7 +4288,7 @@ class TilesComponent {
4124
4288
  }
4125
4289
  }
4126
4290
  TilesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TilesComponent, deps: [{ token: DataServiceLib }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component });
4127
- TilesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TilesComponent, selector: "spa-tiles", inputs: { config: "config", lastSearch: "lastSearch", data: "data", reload: "reload" }, outputs: { tileActionSelected: "tileActionSelected", tileClick: "tileClick", tileUnClick: "tileUnClick" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex row align-items-center justify-content-between\">\r\n <ng-container *ngFor=\"let tile of tiles\">\r\n <mat-card class=\"col\" [class.selected-tile]=\"tile.name === selectedTile\" style=\"margin-left: 5px;margin-right: 5px; padding: 10px 16px ; min-width: 150px; margin-top: 5px;\" (click)=\"clicked(tile)\">\r\n\r\n <!-- Number -->\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div style=\"text-align: center;font-size: 30px;\">\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.prefix\" >{{tile.prefix}}</mat-label> &nbsp;\r\n <mat-label style=\"font-weight:bold; text-align: center;\" [ngStyle]=\"{'color':tile.color }\">{{data[tile.name] ?? 0}}</mat-label>&nbsp;\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.suffix\">{{tile.suffix}}</mat-label>\r\n </div>\r\n </div>\r\n\r\n <!-- Info -->\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div class=\"d-flex justify-content-center align-items-center\" style=\"text-align: center;\">\r\n <mat-label style=\"padding-left:5px;padding-right:5px; text-align: center;font-size: 14px;\">{{tile.alias ?? tile.name | camelToWords}}</mat-label>\r\n <mat-icon [matTooltip]=\"tile.info\" matTooltipPosition=\"above\" style=\"font-size: 20px; color:steelblue;\">info</mat-icon>\r\n </div>\r\n </div>\r\n\r\n </mat-card>\r\n </ng-container>\r\n</div>\r\n", styles: [".card{min-width:200px;max-width:200px;display:flex;flex-direction:column;align-items:center;padding:5px 10px}.tiles{gap:1;row-gap:5px}.col{transition:all .3s ease;cursor:pointer}.selected-tile{background-color:#e0e0e0;box-shadow:0 4px 8px #0003;transform:translateY(-2px)}.selected-tile mat-label{font-weight:700}.selected-tile{border:2px solid #3f51b5}.col:hover{background-color:#f5f5f5}.selected-tile:hover{background-color:#e0e0e0}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "component", type: i15.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] });
4291
+ TilesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TilesComponent, selector: "spa-tiles", inputs: { config: "config", lastSearch: "lastSearch", data: "data", reload: "reload" }, outputs: { tileActionSelected: "tileActionSelected", tileClick: "tileClick", tileUnClick: "tileUnClick" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"d-flex row align-items-center justify-content-between\">\r\n <ng-container *ngFor=\"let tile of tiles\">\r\n <mat-card class=\"col\" [class.selected-tile]=\"tile.name === selectedTile\" style=\"margin-left: 5px;margin-right: 5px; padding: 10px 16px ; min-width: 150px; margin-top: 5px;\" (click)=\"clicked(tile)\">\r\n\r\n <!-- Number -->\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div style=\"text-align: center;font-size: 30px;\">\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.prefix\" >{{tile.prefix}}</mat-label> &nbsp;\r\n <mat-label style=\"font-weight:bold; text-align: center;\" [ngStyle]=\"{'color':tile.color }\">{{data[tile.name] ?? 0}}</mat-label>&nbsp;\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.suffix\">{{tile.suffix}}</mat-label>\r\n </div>\r\n </div>\r\n\r\n <!-- Info -->\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div class=\"d-flex justify-content-center align-items-center\" style=\"text-align: center;\">\r\n <mat-label style=\"padding-left:5px;padding-right:5px; text-align: center;font-size: 14px;\">{{tile.alias ?? tile.name | camelToWords}}</mat-label>\r\n <mat-icon [matTooltip]=\"tile.info\" matTooltipPosition=\"above\" style=\"font-size: 20px; color:steelblue;\">info</mat-icon>\r\n </div>\r\n </div>\r\n\r\n </mat-card>\r\n </ng-container>\r\n</div>\r\n", styles: [".card{min-width:200px;max-width:200px;display:flex;flex-direction:column;align-items:center;padding:5px 10px}.tiles{gap:1;row-gap:5px}.col{transition:all .3s ease;cursor:pointer}.selected-tile{background-color:#e0e0e0;box-shadow:0 4px 8px #0003;transform:translateY(-2px)}.selected-tile mat-label{font-weight:700}.selected-tile{border:2px solid #3f51b5}.col:hover{background-color:#f5f5f5}.selected-tile:hover{background-color:#e0e0e0}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "component", type: i16.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "pipe", type: CamelToWordsPipe, name: "camelToWords" }] });
4128
4292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TilesComponent, decorators: [{
4129
4293
  type: Component,
4130
4294
  args: [{ selector: 'spa-tiles', template: "<div class=\"d-flex row align-items-center justify-content-between\">\r\n <ng-container *ngFor=\"let tile of tiles\">\r\n <mat-card class=\"col\" [class.selected-tile]=\"tile.name === selectedTile\" style=\"margin-left: 5px;margin-right: 5px; padding: 10px 16px ; min-width: 150px; margin-top: 5px;\" (click)=\"clicked(tile)\">\r\n\r\n <!-- Number -->\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div style=\"text-align: center;font-size: 30px;\">\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.prefix\" >{{tile.prefix}}</mat-label> &nbsp;\r\n <mat-label style=\"font-weight:bold; text-align: center;\" [ngStyle]=\"{'color':tile.color }\">{{data[tile.name] ?? 0}}</mat-label>&nbsp;\r\n <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.suffix\">{{tile.suffix}}</mat-label>\r\n </div>\r\n </div>\r\n\r\n <!-- Info -->\r\n <div class=\"row d-flex justify-content-center align-items-center\">\r\n <div class=\"d-flex justify-content-center align-items-center\" style=\"text-align: center;\">\r\n <mat-label style=\"padding-left:5px;padding-right:5px; text-align: center;font-size: 14px;\">{{tile.alias ?? tile.name | camelToWords}}</mat-label>\r\n <mat-icon [matTooltip]=\"tile.info\" matTooltipPosition=\"above\" style=\"font-size: 20px; color:steelblue;\">info</mat-icon>\r\n </div>\r\n </div>\r\n\r\n </mat-card>\r\n </ng-container>\r\n</div>\r\n", styles: [".card{min-width:200px;max-width:200px;display:flex;flex-direction:column;align-items:center;padding:5px 10px}.tiles{gap:1;row-gap:5px}.col{transition:all .3s ease;cursor:pointer}.selected-tile{background-color:#e0e0e0;box-shadow:0 4px 8px #0003;transform:translateY(-2px)}.selected-tile mat-label{font-weight:700}.selected-tile{border:2px solid #3f51b5}.col:hover{background-color:#f5f5f5}.selected-tile:hover{background-color:#e0e0e0}\n"] }]
@@ -4696,6 +4860,9 @@ class TableLiteComponent {
4696
4860
  if (b.action.successMessage) {
4697
4861
  this.messageService.toast(b.action.successMessage);
4698
4862
  }
4863
+ else if (apiResponse.message != "success" && apiResponse.message != "") {
4864
+ this.messageService.toast(apiResponse.message);
4865
+ }
4699
4866
  else {
4700
4867
  this.messageService.toast("Updated");
4701
4868
  }
@@ -4909,7 +5076,7 @@ class DetailsDialogInternal {
4909
5076
  return;
4910
5077
  }
4911
5078
  if (this.validateForm()) {
4912
- this.executeAction(button, this.details, button.action?.successMessage || "Updated");
5079
+ this.executeAction(button, this.details);
4913
5080
  }
4914
5081
  }
4915
5082
  validateForm() {
@@ -4945,23 +5112,31 @@ class DetailsDialogInternal {
4945
5112
  }
4946
5113
  return data;
4947
5114
  }
4948
- executeAction(button, data, defaultSuccessMessage) {
5115
+ executeAction(button, data) {
4949
5116
  const actionData = this.prepareActionData(button, data);
4950
5117
  if (button.confirm) {
4951
5118
  this.messageService.confirm(button.confirm.message).subscribe((result) => {
4952
5119
  if (result === "yes") {
4953
- this.performApiCall(button, actionData, defaultSuccessMessage);
5120
+ this.performApiCall(button, actionData);
4954
5121
  }
4955
5122
  });
4956
5123
  }
4957
5124
  else {
4958
- this.performApiCall(button, actionData, defaultSuccessMessage);
5125
+ this.performApiCall(button, actionData);
4959
5126
  }
4960
5127
  }
4961
- performApiCall(button, data, defaultSuccessMessage) {
5128
+ performApiCall(button, data) {
4962
5129
  this.dataService.CallApi(button.action, data).subscribe((apiResponse) => {
4963
5130
  if (apiResponse.success) {
4964
- this.messageService.toast(button.action?.successMessage || defaultSuccessMessage);
5131
+ if (button.action.successMessage) {
5132
+ this.messageService.toast(button.action.successMessage);
5133
+ }
5134
+ else if (apiResponse.message != "success" && apiResponse.message != "") {
5135
+ this.messageService.toast(apiResponse.message);
5136
+ }
5137
+ else {
5138
+ this.messageService.toast("Updated");
5139
+ }
4965
5140
  this.dialogRef.close({ message: 'success', data: { ...apiResponse, data: this.details } });
4966
5141
  }
4967
5142
  else {
@@ -5059,14 +5234,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5059
5234
  type: Input
5060
5235
  }] } });
5061
5236
 
5237
+ class NotificationsService {
5238
+ constructor(dataService) {
5239
+ this.dataService = dataService;
5240
+ this.notificationCount = new BehaviorSubject(0);
5241
+ this.notificationCount$ = this.notificationCount.asObservable();
5242
+ // this.loadNotifications();
5243
+ }
5244
+ loadNotifications() {
5245
+ // Using the dedicated count endpoint for better performance
5246
+ this.dataService.CallApi({ url: 'notifications/count/x' }).subscribe((apiResponse) => {
5247
+ console.log(apiResponse);
5248
+ if (apiResponse.success) {
5249
+ this.notificationCount.next(apiResponse.data);
5250
+ }
5251
+ });
5252
+ }
5253
+ refreshCount() {
5254
+ this.loadNotifications();
5255
+ }
5256
+ }
5257
+ NotificationsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationsService, deps: [{ token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Injectable });
5258
+ NotificationsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationsService, providedIn: 'root' });
5259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationsService, decorators: [{
5260
+ type: Injectable,
5261
+ args: [{
5262
+ providedIn: 'root'
5263
+ }]
5264
+ }], ctorParameters: function () { return [{ type: DataServiceLib }]; } });
5265
+
5062
5266
  class NavMenuComponent {
5063
- constructor(router, authService, storageService, socialService, breakpointObserver, dataService) {
5267
+ constructor(router, authService, storageService, notificationsService, socialService, breakpointObserver, dataService) {
5064
5268
  this.router = router;
5065
5269
  this.authService = authService;
5066
5270
  this.storageService = storageService;
5271
+ this.notificationsService = notificationsService;
5067
5272
  this.socialService = socialService;
5068
5273
  this.breakpointObserver = breakpointObserver;
5069
5274
  this.dataService = dataService;
5275
+ this.notificationCount$ = this.notificationsService.notificationCount$;
5070
5276
  this.isExpanded = false;
5071
5277
  this.nowDate = new Date();
5072
5278
  this.appConfig = new AppConfig();
@@ -5112,12 +5318,12 @@ class NavMenuComponent {
5112
5318
  }
5113
5319
  }
5114
5320
  }
5115
- NavMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavMenuComponent, deps: [{ token: i1$3.Router }, { token: AuthService }, { token: StorageService }, { token: i8.SocialAuthService }, { token: i3$1.BreakpointObserver }, { token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component });
5116
- NavMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NavMenuComponent, selector: "spa-nav-menu", inputs: { appConfig: "appConfig", footer: "footer" }, ngImport: i0, template: "<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top'\">\r\n\r\n <nav class=\"toolbar navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom box-shadow mb-3 \" style=\"padding-right: 10px;\">\r\n\r\n\r\n <div class=\"container-fluid\" style=\"padding-right: 0px;\">\r\n\r\n <img *ngIf=\"appConfig.logo!=''\" [src]=\"appConfig.logo\" style=\"height: 50px; margin-right: 2em\" />\r\n\r\n <div>\r\n <!-- <div style=\"font-size: 20px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n <div *ngIf=\"!dataService.appConfig.multitenant\" style=\"font-size: 22px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"font-size: 20px; ; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-label=\"Toggle navigation\" [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\r\n <span class=\"navbar-toggler-icon\"></span>\r\n </button>\r\n\r\n <div *ngIf=\"myRole\" class=\" navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse stack-top\" style=\"margin-right: 0px;\" [ngClass]=\"{ show: isExpanded, navitems: isExpanded }\" >\r\n\r\n <button mat-icon-button (click)=\"logoff()\" > <mat-icon>logout</mat-icon> </button>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >support_agent</mat-icon> </button>\r\n\r\n <!-- <button mat-icon-button (click)=\"redirectTo('home/admin/tenants')\"> <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button> -->\r\n </div>\r\n\r\n\r\n <button id=\"btnUser\" mat-button [matMenuTriggerFor]=\"profileMenu\" ><mat-icon style=\"font-size: 24px;\">account_circle</mat-icon> &nbsp;{{loggedUserFullName}}</button>\r\n\r\n <mat-menu #profileMenu=\"matMenu\">\r\n <button id=\"btnProfile\" mat-menu-item (click)=\"redirectTo('home/user/profile')\" >Profile</button>\r\n <button id=\"btnLogOff\" mat-menu-item (click)=\"logoff()\">Log Off</button>\r\n </mat-menu>\r\n\r\n <div *ngFor=\"let item of appConfig.capItems\">\r\n\r\n <!-- Menu Item -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && !item.capSubItems && item.showMenu\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items ignored -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && item.ignoreSubsDisplay\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items to display-->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && !item.ignoreSubsDisplay\" mat-button [matMenuTriggerFor]=\"adminMenu\">{{item.display}}</button>\r\n\r\n\r\n <!-- Sub Menu Items -->\r\n <mat-menu #adminMenu=\"matMenu\">\r\n\r\n <div *ngFor=\"let subItem of item.capSubItems\">\r\n\r\n <button *ngIf=\"myRole[subItem.name] && subItem.showMenu\" mat-menu-item (click)=\"redirectTo(subItem.link)\">{{subItem.display}}</button>\r\n\r\n </div>\r\n\r\n </mat-menu>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n </nav>\r\n\r\n</header>\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"dataService.appConfig.navigation == 'top'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<!-- SIDE -->\r\n<mat-toolbar class=\"tin-bg-image-toolbar\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\" style=\"padding: 0px 8px;\">\r\n\r\n <button mat-icon-button (click)=\"toggle()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <img [src]=\"dataService.appConfig.logo\" style=\"height: 50px;\" />\r\n\r\n <div style=\"padding-left: 10px; \">\r\n\r\n <div style=\"font-size: 20px; height: 25px; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <span class=\"toolbar-item-spacer\"></span>\r\n\r\n <!-- buttons -->\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >help</mat-icon> </button>\r\n\r\n </div>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button matTooltip=\"Notifications\"><mat-icon>notifications</mat-icon></button>\r\n\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"userAccountMenu\"><mat-icon>account_circle</mat-icon></button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\"> <mat-icon>logout</mat-icon></button>\r\n\r\n\r\n <!-- my account menu -->\r\n <mat-menu #userAccountMenu [overlapTrigger]=\"false\" yPosition=\"below\">\r\n\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon> <span>Help</span>\r\n </button>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n\r\n </mat-menu>\r\n\r\n</mat-toolbar>\r\n\r\n\r\n\r\n\r\n<mat-sidenav-container class=\"app-container\" [hasBackdrop]=\"smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n\r\n <mat-sidenav #sidenav [mode]=\"smallScreen ? 'over' : 'over'\" [class.mat-elevation-z4]=\"true\" [opened]=\"isExpanded\" class=\"app-sidenav side-color\" style=\"height: 100%;\">\r\n <mat-nav-list >\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\" >\r\n\r\n <!-- Menu item -->\r\n <mat-list-item [routerLink]=\"cap.link\" *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.capSubItems && cap.ignoreSubsDisplay)\" style=\"height: 40px;font-size: 15px;\" (click)=\"toggle()\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon}}</mat-icon>{{cap.display}}\r\n </mat-list-item>\r\n\r\n <!-- Menu With Sub items -->\r\n <mat-expansion-panel class=\"side-color\" [class.mat-elevation-z0]=\"true\" *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay\">\r\n\r\n <mat-expansion-panel-header style=\"height: 40px;padding-left: 15px;\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon != 'navigate_next' ? cap.icon : 'fiber_manual_record' }}</mat-icon>{{cap.display}}\r\n </mat-expansion-panel-header>\r\n\r\n <!-- Sub items -->\r\n <mat-nav-list *ngFor=\"let capSub of cap.capSubItems\">\r\n\r\n <mat-list-item [routerLink]=\"capSub.link\" style=\"height: 30px; font-size: 15px;\" (click)=\"toggle()\" *ngIf=\"myRole[cap.name] && cap.showMenu\">\r\n <mat-icon style=\"margin-right: 5px;\">{{capSub.icon}}</mat-icon>{{capSub.display}}\r\n </mat-list-item>\r\n\r\n </mat-nav-list>\r\n\r\n </mat-expansion-panel>\r\n\r\n </ng-container>\r\n\r\n </mat-nav-list>\r\n </mat-sidenav>\r\n\r\n\r\n\r\n <mat-sidenav-content class=\"container-fluid tin-bg-image\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <hr style=\"margin-top: 0px;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </mat-sidenav-content>\r\n\r\n</mat-sidenav-container>\r\n\r\n\r\n<!-- footer -->\r\n<div class=\"tin-center\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <label style=\"text-align: center; font-size: 12px;\">&copy; {{nowDate | date : 'yyyy'}} {{footer}}</label>\r\n</div>\r\n\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n", styles: ["a.navbar-brand{white-space:normal;text-align:center;word-break:break-all}html{font-size:14px}.box-shadow{box-shadow:0 .25rem .75rem #0000000d}.toolbar{height:60px;display:flex;align-items:center;background-color:#03a;color:#fff}.stack-top{z-index:9;margin:20px}.navitems{background-color:#03a}.toolbar-item-spacer{flex:1 1 auto}.app-container{height:90%;margin:0}.app-sidenav{width:200px}.side-color{background-color:#def0fc}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i8$3.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i8$3.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8$3.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11$2.MatNavList, selector: "mat-nav-list", inputs: ["disableRipple", "disabled"], exportAs: ["matNavList"] }, { kind: "component", type: i11$2.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["disableRipple", "disabled"], exportAs: ["matListItem"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i14.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i14.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i14.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "component", type: i15$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1$3.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i16.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i16.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "component", type: LoaderComponent, selector: "spa-loader", inputs: ["logo"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] });
5321
+ NavMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavMenuComponent, deps: [{ token: i1$3.Router }, { token: AuthService }, { token: StorageService }, { token: NotificationsService }, { token: i8.SocialAuthService }, { token: i3$1.BreakpointObserver }, { token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component });
5322
+ NavMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NavMenuComponent, selector: "spa-nav-menu", inputs: { appConfig: "appConfig", footer: "footer" }, ngImport: i0, template: "<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top'\">\r\n\r\n <nav class=\"toolbar navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom box-shadow mb-3 \" style=\"padding-right: 10px;\">\r\n\r\n\r\n <div class=\"container-fluid\" style=\"padding-right: 0px;\">\r\n\r\n <img *ngIf=\"appConfig.logo!=''\" [src]=\"appConfig.logo\" style=\"height: 50px; margin-right: 2em\" />\r\n\r\n <div>\r\n <!-- <div style=\"font-size: 20px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n <div *ngIf=\"!dataService.appConfig.multitenant\" style=\"font-size: 22px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"font-size: 20px; ; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-label=\"Toggle navigation\" [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\r\n <span class=\"navbar-toggler-icon\"></span>\r\n </button>\r\n\r\n <div *ngIf=\"myRole\" class=\" navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse stack-top\" style=\"margin-right: 0px;\" [ngClass]=\"{ show: isExpanded, navitems: isExpanded }\" >\r\n\r\n <button mat-icon-button (click)=\"logoff()\" > <mat-icon>logout</mat-icon> </button>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >support_agent</mat-icon> </button>\r\n\r\n <!-- <button mat-icon-button (click)=\"redirectTo('home/admin/notifications')\"> <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button> -->\r\n </div>\r\n\r\n\r\n <button id=\"btnUser\" mat-button [matMenuTriggerFor]=\"profileMenu\" ><mat-icon style=\"font-size: 24px;\">account_circle</mat-icon> &nbsp;{{loggedUserFullName}}</button>\r\n\r\n <mat-menu #profileMenu=\"matMenu\">\r\n <button id=\"btnProfile\" mat-menu-item (click)=\"redirectTo('home/user/profile')\" >Profile</button>\r\n <button id=\"btnLogOff\" mat-menu-item (click)=\"logoff()\">Log Off</button>\r\n </mat-menu>\r\n\r\n <div *ngFor=\"let item of appConfig.capItems\">\r\n\r\n <!-- Menu Item -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && !item.capSubItems && item.showMenu\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items ignored -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && item.ignoreSubsDisplay\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items to display-->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && !item.ignoreSubsDisplay\" mat-button [matMenuTriggerFor]=\"adminMenu\">{{item.display}}</button>\r\n\r\n\r\n <!-- Sub Menu Items -->\r\n <mat-menu #adminMenu=\"matMenu\">\r\n\r\n <div *ngFor=\"let subItem of item.capSubItems\">\r\n\r\n <button *ngIf=\"myRole[subItem.name] && subItem.showMenu\" mat-menu-item (click)=\"redirectTo(subItem.link)\">{{subItem.display}}</button>\r\n\r\n </div>\r\n\r\n </mat-menu>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n </nav>\r\n\r\n</header>\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"dataService.appConfig.navigation == 'top'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<!-- SIDE -->\r\n<mat-toolbar class=\"tin-bg-image-toolbar\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\" style=\"padding: 0px 8px;\">\r\n\r\n <button mat-icon-button (click)=\"toggle()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <img [src]=\"dataService.appConfig.logo\" style=\"height: 50px;\" />\r\n\r\n <div style=\"padding-left: 10px; \">\r\n\r\n <div style=\"font-size: 20px; height: 25px; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <span class=\"toolbar-item-spacer\"></span>\r\n\r\n <!-- buttons -->\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <!-- <label style=\"font-size: 14px;\">Hi, {{loggedUserFullName}}</label> -->\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >help</mat-icon> </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/notifications')\" matTooltip=\"Notifications\">\r\n <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\r\n </button>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"userAccountMenu\"><mat-icon>account_circle</mat-icon></button>\r\n <label style=\"font-size: 14px;\">{{loggedUserFullName}}</label>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\"> <mat-icon>logout</mat-icon></button>\r\n\r\n\r\n <!-- my account menu -->\r\n <mat-menu #userAccountMenu [overlapTrigger]=\"false\" yPosition=\"below\">\r\n\r\n\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon> <span>Help</span>\r\n </button>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n\r\n </mat-menu>\r\n\r\n</mat-toolbar>\r\n\r\n\r\n\r\n\r\n<mat-sidenav-container class=\"app-container\" [hasBackdrop]=\"smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n\r\n <mat-sidenav #sidenav [mode]=\"smallScreen ? 'over' : 'over'\" [class.mat-elevation-z4]=\"true\" [opened]=\"isExpanded\" class=\"app-sidenav side-color\" style=\"height: 100%;\">\r\n <mat-nav-list >\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\" >\r\n\r\n <!-- Menu item -->\r\n <mat-list-item [routerLink]=\"cap.link\" *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.capSubItems && cap.ignoreSubsDisplay)\" style=\"height: 40px;font-size: 15px;\" (click)=\"toggle()\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon}}</mat-icon>{{cap.display}}\r\n </mat-list-item>\r\n\r\n <!-- Menu With Sub items -->\r\n <mat-expansion-panel class=\"side-color\" [class.mat-elevation-z0]=\"true\" *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay\">\r\n\r\n <mat-expansion-panel-header style=\"height: 40px;padding-left: 15px;\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon != 'navigate_next' ? cap.icon : 'fiber_manual_record' }}</mat-icon>{{cap.display}}\r\n </mat-expansion-panel-header>\r\n\r\n <!-- Sub items -->\r\n <mat-nav-list *ngFor=\"let capSub of cap.capSubItems\">\r\n\r\n <mat-list-item [routerLink]=\"capSub.link\" style=\"height: 30px; font-size: 15px;\" (click)=\"toggle()\" *ngIf=\"myRole[cap.name] && cap.showMenu\">\r\n <mat-icon style=\"margin-right: 5px;\">{{capSub.icon}}</mat-icon>{{capSub.display}}\r\n </mat-list-item>\r\n\r\n </mat-nav-list>\r\n\r\n </mat-expansion-panel>\r\n\r\n </ng-container>\r\n\r\n </mat-nav-list>\r\n </mat-sidenav>\r\n\r\n\r\n\r\n <mat-sidenav-content class=\"container-fluid tin-bg-image\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <hr style=\"margin-top: 0px;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </mat-sidenav-content>\r\n\r\n</mat-sidenav-container>\r\n\r\n\r\n<!-- footer -->\r\n<div class=\"tin-center\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <label style=\"text-align: center; font-size: 12px;\">&copy; {{nowDate | date : 'yyyy'}} {{footer}}</label>\r\n</div>\r\n\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n", styles: ["a.navbar-brand{white-space:normal;text-align:center;word-break:break-all}html{font-size:14px}.box-shadow{box-shadow:0 .25rem .75rem #0000000d}.toolbar{height:60px;display:flex;align-items:center;background-color:#03a;color:#fff}.stack-top{z-index:9;margin:20px}.navitems{background-color:#03a}.toolbar-item-spacer{flex:1 1 auto}.app-container{height:90%;margin:0}.app-sidenav{width:200px}.side-color{background-color:#def0fc}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i9.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i9.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i9.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i10$1.MatBadge, selector: "[matBadge]", inputs: ["matBadgeDisabled", "matBadgeColor", "matBadgeOverlap", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i13$1.MatNavList, selector: "mat-nav-list", inputs: ["disableRipple", "disabled"], exportAs: ["matNavList"] }, { kind: "component", type: i13$1.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["disableRipple", "disabled"], exportAs: ["matListItem"] }, { kind: "component", type: i14.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: i16$1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i16$1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i16$1.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "component", type: i17.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1$3.RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: ["queryParams", "fragment", "queryParamsHandling", "state", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i18.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["disabled", "expanded", "hideToggle", "togglePosition"], outputs: ["opened", "closed", "expandedChange", "afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i18.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["tabIndex", "expandedHeight", "collapsedHeight"] }, { kind: "component", type: LoaderComponent, selector: "spa-loader", inputs: ["logo"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "date" }] });
5117
5323
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NavMenuComponent, decorators: [{
5118
5324
  type: Component,
5119
- args: [{ selector: 'spa-nav-menu', template: "<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top'\">\r\n\r\n <nav class=\"toolbar navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom box-shadow mb-3 \" style=\"padding-right: 10px;\">\r\n\r\n\r\n <div class=\"container-fluid\" style=\"padding-right: 0px;\">\r\n\r\n <img *ngIf=\"appConfig.logo!=''\" [src]=\"appConfig.logo\" style=\"height: 50px; margin-right: 2em\" />\r\n\r\n <div>\r\n <!-- <div style=\"font-size: 20px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n <div *ngIf=\"!dataService.appConfig.multitenant\" style=\"font-size: 22px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"font-size: 20px; ; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-label=\"Toggle navigation\" [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\r\n <span class=\"navbar-toggler-icon\"></span>\r\n </button>\r\n\r\n <div *ngIf=\"myRole\" class=\" navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse stack-top\" style=\"margin-right: 0px;\" [ngClass]=\"{ show: isExpanded, navitems: isExpanded }\" >\r\n\r\n <button mat-icon-button (click)=\"logoff()\" > <mat-icon>logout</mat-icon> </button>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >support_agent</mat-icon> </button>\r\n\r\n <!-- <button mat-icon-button (click)=\"redirectTo('home/admin/tenants')\"> <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button> -->\r\n </div>\r\n\r\n\r\n <button id=\"btnUser\" mat-button [matMenuTriggerFor]=\"profileMenu\" ><mat-icon style=\"font-size: 24px;\">account_circle</mat-icon> &nbsp;{{loggedUserFullName}}</button>\r\n\r\n <mat-menu #profileMenu=\"matMenu\">\r\n <button id=\"btnProfile\" mat-menu-item (click)=\"redirectTo('home/user/profile')\" >Profile</button>\r\n <button id=\"btnLogOff\" mat-menu-item (click)=\"logoff()\">Log Off</button>\r\n </mat-menu>\r\n\r\n <div *ngFor=\"let item of appConfig.capItems\">\r\n\r\n <!-- Menu Item -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && !item.capSubItems && item.showMenu\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items ignored -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && item.ignoreSubsDisplay\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items to display-->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && !item.ignoreSubsDisplay\" mat-button [matMenuTriggerFor]=\"adminMenu\">{{item.display}}</button>\r\n\r\n\r\n <!-- Sub Menu Items -->\r\n <mat-menu #adminMenu=\"matMenu\">\r\n\r\n <div *ngFor=\"let subItem of item.capSubItems\">\r\n\r\n <button *ngIf=\"myRole[subItem.name] && subItem.showMenu\" mat-menu-item (click)=\"redirectTo(subItem.link)\">{{subItem.display}}</button>\r\n\r\n </div>\r\n\r\n </mat-menu>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n </nav>\r\n\r\n</header>\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"dataService.appConfig.navigation == 'top'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<!-- SIDE -->\r\n<mat-toolbar class=\"tin-bg-image-toolbar\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\" style=\"padding: 0px 8px;\">\r\n\r\n <button mat-icon-button (click)=\"toggle()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <img [src]=\"dataService.appConfig.logo\" style=\"height: 50px;\" />\r\n\r\n <div style=\"padding-left: 10px; \">\r\n\r\n <div style=\"font-size: 20px; height: 25px; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <span class=\"toolbar-item-spacer\"></span>\r\n\r\n <!-- buttons -->\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >help</mat-icon> </button>\r\n\r\n </div>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button matTooltip=\"Notifications\"><mat-icon>notifications</mat-icon></button>\r\n\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"userAccountMenu\"><mat-icon>account_circle</mat-icon></button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\"> <mat-icon>logout</mat-icon></button>\r\n\r\n\r\n <!-- my account menu -->\r\n <mat-menu #userAccountMenu [overlapTrigger]=\"false\" yPosition=\"below\">\r\n\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon> <span>Help</span>\r\n </button>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n\r\n </mat-menu>\r\n\r\n</mat-toolbar>\r\n\r\n\r\n\r\n\r\n<mat-sidenav-container class=\"app-container\" [hasBackdrop]=\"smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n\r\n <mat-sidenav #sidenav [mode]=\"smallScreen ? 'over' : 'over'\" [class.mat-elevation-z4]=\"true\" [opened]=\"isExpanded\" class=\"app-sidenav side-color\" style=\"height: 100%;\">\r\n <mat-nav-list >\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\" >\r\n\r\n <!-- Menu item -->\r\n <mat-list-item [routerLink]=\"cap.link\" *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.capSubItems && cap.ignoreSubsDisplay)\" style=\"height: 40px;font-size: 15px;\" (click)=\"toggle()\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon}}</mat-icon>{{cap.display}}\r\n </mat-list-item>\r\n\r\n <!-- Menu With Sub items -->\r\n <mat-expansion-panel class=\"side-color\" [class.mat-elevation-z0]=\"true\" *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay\">\r\n\r\n <mat-expansion-panel-header style=\"height: 40px;padding-left: 15px;\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon != 'navigate_next' ? cap.icon : 'fiber_manual_record' }}</mat-icon>{{cap.display}}\r\n </mat-expansion-panel-header>\r\n\r\n <!-- Sub items -->\r\n <mat-nav-list *ngFor=\"let capSub of cap.capSubItems\">\r\n\r\n <mat-list-item [routerLink]=\"capSub.link\" style=\"height: 30px; font-size: 15px;\" (click)=\"toggle()\" *ngIf=\"myRole[cap.name] && cap.showMenu\">\r\n <mat-icon style=\"margin-right: 5px;\">{{capSub.icon}}</mat-icon>{{capSub.display}}\r\n </mat-list-item>\r\n\r\n </mat-nav-list>\r\n\r\n </mat-expansion-panel>\r\n\r\n </ng-container>\r\n\r\n </mat-nav-list>\r\n </mat-sidenav>\r\n\r\n\r\n\r\n <mat-sidenav-content class=\"container-fluid tin-bg-image\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <hr style=\"margin-top: 0px;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </mat-sidenav-content>\r\n\r\n</mat-sidenav-container>\r\n\r\n\r\n<!-- footer -->\r\n<div class=\"tin-center\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <label style=\"text-align: center; font-size: 12px;\">&copy; {{nowDate | date : 'yyyy'}} {{footer}}</label>\r\n</div>\r\n\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n", styles: ["a.navbar-brand{white-space:normal;text-align:center;word-break:break-all}html{font-size:14px}.box-shadow{box-shadow:0 .25rem .75rem #0000000d}.toolbar{height:60px;display:flex;align-items:center;background-color:#03a;color:#fff}.stack-top{z-index:9;margin:20px}.navitems{background-color:#03a}.toolbar-item-spacer{flex:1 1 auto}.app-container{height:90%;margin:0}.app-sidenav{width:200px}.side-color{background-color:#def0fc}\n"] }]
5120
- }], ctorParameters: function () { return [{ type: i1$3.Router }, { type: AuthService }, { type: StorageService }, { type: i8.SocialAuthService }, { type: i3$1.BreakpointObserver }, { type: DataServiceLib }]; }, propDecorators: { appConfig: [{
5325
+ args: [{ selector: 'spa-nav-menu', template: "<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top'\">\r\n\r\n <nav class=\"toolbar navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom box-shadow mb-3 \" style=\"padding-right: 10px;\">\r\n\r\n\r\n <div class=\"container-fluid\" style=\"padding-right: 0px;\">\r\n\r\n <img *ngIf=\"appConfig.logo!=''\" [src]=\"appConfig.logo\" style=\"height: 50px; margin-right: 2em\" />\r\n\r\n <div>\r\n <!-- <div style=\"font-size: 20px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px;\">\r\n {{tenantName}}\r\n </div> -->\r\n\r\n <div *ngIf=\"!dataService.appConfig.multitenant\" style=\"font-size: 22px;\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\" style=\"font-size: 20px; ; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-label=\"Toggle navigation\" [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\r\n <span class=\"navbar-toggler-icon\"></span>\r\n </button>\r\n\r\n <div *ngIf=\"myRole\" class=\" navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse stack-top\" style=\"margin-right: 0px;\" [ngClass]=\"{ show: isExpanded, navitems: isExpanded }\" >\r\n\r\n <button mat-icon-button (click)=\"logoff()\" > <mat-icon>logout</mat-icon> </button>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >support_agent</mat-icon> </button>\r\n\r\n <!-- <button mat-icon-button (click)=\"redirectTo('home/admin/notifications')\"> <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button> -->\r\n </div>\r\n\r\n\r\n <button id=\"btnUser\" mat-button [matMenuTriggerFor]=\"profileMenu\" ><mat-icon style=\"font-size: 24px;\">account_circle</mat-icon> &nbsp;{{loggedUserFullName}}</button>\r\n\r\n <mat-menu #profileMenu=\"matMenu\">\r\n <button id=\"btnProfile\" mat-menu-item (click)=\"redirectTo('home/user/profile')\" >Profile</button>\r\n <button id=\"btnLogOff\" mat-menu-item (click)=\"logoff()\">Log Off</button>\r\n </mat-menu>\r\n\r\n <div *ngFor=\"let item of appConfig.capItems\">\r\n\r\n <!-- Menu Item -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && !item.capSubItems && item.showMenu\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items ignored -->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && item.ignoreSubsDisplay\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\r\n\r\n <!-- Menu Item with Sub items to display-->\r\n <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && !item.ignoreSubsDisplay\" mat-button [matMenuTriggerFor]=\"adminMenu\">{{item.display}}</button>\r\n\r\n\r\n <!-- Sub Menu Items -->\r\n <mat-menu #adminMenu=\"matMenu\">\r\n\r\n <div *ngFor=\"let subItem of item.capSubItems\">\r\n\r\n <button *ngIf=\"myRole[subItem.name] && subItem.showMenu\" mat-menu-item (click)=\"redirectTo(subItem.link)\">{{subItem.display}}</button>\r\n\r\n </div>\r\n\r\n </mat-menu>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n\r\n </nav>\r\n\r\n</header>\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"dataService.appConfig.navigation == 'top'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n<!-- SIDE -->\r\n<mat-toolbar class=\"tin-bg-image-toolbar\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\" style=\"padding: 0px 8px;\">\r\n\r\n <button mat-icon-button (click)=\"toggle()\" matTooltip=\"Menu\">\r\n <mat-icon>menu</mat-icon>\r\n </button>\r\n\r\n <img [src]=\"dataService.appConfig.logo\" style=\"height: 50px;\" />\r\n\r\n <div style=\"padding-left: 10px; \">\r\n\r\n <div style=\"font-size: 20px; height: 25px; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\r\n {{appConfig.appName}}\r\n </div>\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\r\n {{tenantName}}\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n\r\n <span class=\"toolbar-item-spacer\"></span>\r\n\r\n <!-- buttons -->\r\n\r\n <div *ngIf=\"dataService.appConfig.multitenant\">\r\n\r\n <!-- <label style=\"font-size: 14px;\">Hi, {{loggedUserFullName}}</label> -->\r\n\r\n <button mat-icon-button (click)=\"redirectTo('home/admin/tenant-settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/bug')\"> <mat-icon >help</mat-icon> </button>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/admin/notifications')\" matTooltip=\"Notifications\">\r\n <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\r\n </button>\r\n\r\n </div>\r\n\r\n\r\n\r\n <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"userAccountMenu\"><mat-icon>account_circle</mat-icon></button>\r\n <label style=\"font-size: 14px;\">{{loggedUserFullName}}</label>\r\n\r\n <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\"> <mat-icon>logout</mat-icon></button>\r\n\r\n\r\n <!-- my account menu -->\r\n <mat-menu #userAccountMenu [overlapTrigger]=\"false\" yPosition=\"below\">\r\n\r\n\r\n <button mat-menu-item routerLink=\"home/user/profile\">\r\n <mat-icon>person</mat-icon><span>Profile</span>\r\n </button>\r\n\r\n <button mat-menu-item routerLink=\"home/admin/bug\" *ngIf=\"dataService.appConfig.multitenant && smallScreen\">\r\n <mat-icon>help</mat-icon> <span>Help</span>\r\n </button>\r\n\r\n <mat-divider></mat-divider>\r\n\r\n <button mat-menu-item (click)=\"logoff()\">\r\n <mat-icon>logout</mat-icon>Logout\r\n </button>\r\n\r\n </mat-menu>\r\n\r\n</mat-toolbar>\r\n\r\n\r\n\r\n\r\n<mat-sidenav-container class=\"app-container\" [hasBackdrop]=\"smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n\r\n <mat-sidenav #sidenav [mode]=\"smallScreen ? 'over' : 'over'\" [class.mat-elevation-z4]=\"true\" [opened]=\"isExpanded\" class=\"app-sidenav side-color\" style=\"height: 100%;\">\r\n <mat-nav-list >\r\n\r\n <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\" >\r\n\r\n <!-- Menu item -->\r\n <mat-list-item [routerLink]=\"cap.link\" *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.capSubItems && cap.ignoreSubsDisplay)\" style=\"height: 40px;font-size: 15px;\" (click)=\"toggle()\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon}}</mat-icon>{{cap.display}}\r\n </mat-list-item>\r\n\r\n <!-- Menu With Sub items -->\r\n <mat-expansion-panel class=\"side-color\" [class.mat-elevation-z0]=\"true\" *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay\">\r\n\r\n <mat-expansion-panel-header style=\"height: 40px;padding-left: 15px;\">\r\n <mat-icon style=\"margin-right: 5px;\">{{cap.icon != 'navigate_next' ? cap.icon : 'fiber_manual_record' }}</mat-icon>{{cap.display}}\r\n </mat-expansion-panel-header>\r\n\r\n <!-- Sub items -->\r\n <mat-nav-list *ngFor=\"let capSub of cap.capSubItems\">\r\n\r\n <mat-list-item [routerLink]=\"capSub.link\" style=\"height: 30px; font-size: 15px;\" (click)=\"toggle()\" *ngIf=\"myRole[cap.name] && cap.showMenu\">\r\n <mat-icon style=\"margin-right: 5px;\">{{capSub.icon}}</mat-icon>{{capSub.display}}\r\n </mat-list-item>\r\n\r\n </mat-nav-list>\r\n\r\n </mat-expansion-panel>\r\n\r\n </ng-container>\r\n\r\n </mat-nav-list>\r\n </mat-sidenav>\r\n\r\n\r\n\r\n <mat-sidenav-content class=\"container-fluid tin-bg-image\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <hr style=\"margin-top: 0px;\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n </mat-sidenav-content>\r\n\r\n</mat-sidenav-container>\r\n\r\n\r\n<!-- footer -->\r\n<div class=\"tin-center\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\r\n <label style=\"text-align: center; font-size: 12px;\">&copy; {{nowDate | date : 'yyyy'}} {{footer}}</label>\r\n</div>\r\n\r\n\r\n<div class=\"container-fluid tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side'\">\r\n <router-outlet></router-outlet>\r\n <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\r\n</div>\r\n", styles: ["a.navbar-brand{white-space:normal;text-align:center;word-break:break-all}html{font-size:14px}.box-shadow{box-shadow:0 .25rem .75rem #0000000d}.toolbar{height:60px;display:flex;align-items:center;background-color:#03a;color:#fff}.stack-top{z-index:9;margin:20px}.navitems{background-color:#03a}.toolbar-item-spacer{flex:1 1 auto}.app-container{height:90%;margin:0}.app-sidenav{width:200px}.side-color{background-color:#def0fc}\n"] }]
5326
+ }], ctorParameters: function () { return [{ type: i1$3.Router }, { type: AuthService }, { type: StorageService }, { type: NotificationsService }, { type: i8.SocialAuthService }, { type: i3$1.BreakpointObserver }, { type: DataServiceLib }]; }, propDecorators: { appConfig: [{
5121
5327
  type: Input
5122
5328
  }], footer: [{
5123
5329
  type: Input
@@ -5525,6 +5731,9 @@ class TableInternalComponent {
5525
5731
  if (b.action.successMessage) {
5526
5732
  this.messageService.toast(b.action.successMessage);
5527
5733
  }
5734
+ else if (apiResponse.message != "success" && apiResponse.message != "") {
5735
+ this.messageService.toast(apiResponse.message);
5736
+ }
5528
5737
  else {
5529
5738
  this.messageService.toast("Updated");
5530
5739
  }
@@ -5738,7 +5947,7 @@ class DetailsDialog {
5738
5947
  return;
5739
5948
  }
5740
5949
  if (this.validateForm()) {
5741
- this.executeAction(button, this.details, button.action?.successMessage || "Updated");
5950
+ this.executeAction(button, this.details);
5742
5951
  }
5743
5952
  }
5744
5953
  validateForm() {
@@ -5774,23 +5983,31 @@ class DetailsDialog {
5774
5983
  }
5775
5984
  return data;
5776
5985
  }
5777
- executeAction(button, data, defaultSuccessMessage) {
5986
+ executeAction(button, data) {
5778
5987
  const actionData = this.prepareActionData(button, data);
5779
5988
  if (button.confirm) {
5780
5989
  this.messageService.confirm(button.confirm.message).subscribe((result) => {
5781
5990
  if (result === "yes") {
5782
- this.performApiCall(button, actionData, defaultSuccessMessage);
5991
+ this.performApiCall(button, actionData);
5783
5992
  }
5784
5993
  });
5785
5994
  }
5786
5995
  else {
5787
- this.performApiCall(button, actionData, defaultSuccessMessage);
5996
+ this.performApiCall(button, actionData);
5788
5997
  }
5789
5998
  }
5790
- performApiCall(button, data, defaultSuccessMessage) {
5999
+ performApiCall(button, data) {
5791
6000
  this.dataService.CallApi(button.action, data).subscribe((apiResponse) => {
5792
6001
  if (apiResponse.success) {
5793
- this.messageService.toast(button.action?.successMessage || defaultSuccessMessage);
6002
+ if (button.action.successMessage) {
6003
+ this.messageService.toast(button.action.successMessage);
6004
+ }
6005
+ else if (apiResponse.message != "success" && apiResponse.message != "") {
6006
+ this.messageService.toast(apiResponse.message);
6007
+ }
6008
+ else {
6009
+ this.messageService.toast("Updated");
6010
+ }
5794
6011
  this.dialogRef.close({ message: 'success', data: { ...apiResponse, data: this.details } });
5795
6012
  }
5796
6013
  else {
@@ -6114,6 +6331,9 @@ class TableComponent {
6114
6331
  if (b.action.successMessage) {
6115
6332
  this.messageService.toast(b.action.successMessage);
6116
6333
  }
6334
+ else if (apiResponse.message != "success" && apiResponse.message != "") {
6335
+ this.messageService.toast(apiResponse.message);
6336
+ }
6117
6337
  else {
6118
6338
  this.messageService.toast("Updated");
6119
6339
  }
@@ -6298,7 +6518,7 @@ class TenantSettingsComponent {
6298
6518
  ],
6299
6519
  buttons: [
6300
6520
  { name: 'create', display: 'Add Member', dialog: true, detailsConfig: this.inviteDialogConfig },
6301
- { name: 'edit', icon: { name: 'security' }, tip: 'Edit Access', dialog: true, action: { url: 'members/dto?action=role', method: 'post' }, disabled: x => x.own },
6521
+ { name: 'edit', icon: { name: 'security' }, tip: 'Edit Access', dialog: true, action: { url: 'members/dto?action=role', method: 'post' }, },
6302
6522
  { name: 'remove', icon: { name: 'close', color: 'red' }, tip: 'Remove Member', confirm: { message: 'Remove Member from this Organisation ?' }, action: { url: 'members/dto?action=remove', method: 'post' }, disabled: x => x.own },
6303
6523
  ],
6304
6524
  loadAction: { url: 'members/all/x' },
@@ -6353,6 +6573,39 @@ class TenantSettingsComponent {
6353
6573
  ],
6354
6574
  loadAction: { url: 'tenants/my_tenants/x' },
6355
6575
  };
6576
+ //Email
6577
+ this.mailerFormConfig = {
6578
+ fields: [
6579
+ { name: 'smtp', type: 'text', required: true, alias: 'SMTP Server' },
6580
+ { name: 'port', type: 'number', required: true, defaultValue: 587 },
6581
+ { name: 'address', type: 'text', required: true, alias: 'Email Address' },
6582
+ { name: 'display', type: 'text', required: true, alias: 'Display Name' },
6583
+ { name: 'password', type: 'password', required: true, span: true },
6584
+ { name: 'enableSsl', type: 'checkbox', alias: 'Enable SSL' },
6585
+ { name: 'isBodyHtml', type: 'checkbox', alias: 'HTML Body' },
6586
+ ]
6587
+ };
6588
+ this.mailerTableConfig = {
6589
+ showFilter: true,
6590
+ elevation: 'low',
6591
+ minColumns: ['smtp', 'address'],
6592
+ flatButtons: true,
6593
+ columns: [
6594
+ { name: 'smtp', type: 'text', alias: 'SMTP Server' },
6595
+ { name: 'port', type: 'number' },
6596
+ { name: 'address', type: 'text', alias: 'Email Address' },
6597
+ { name: 'display', type: 'text', alias: 'Display Name' },
6598
+ { name: 'enableSsl', type: 'checkbox', alias: 'SSL Enabled' },
6599
+ { name: 'isBodyHtml', type: 'checkbox', alias: 'HTML Body' },
6600
+ ],
6601
+ buttons: [
6602
+ { name: 'create', display: 'Configure Email', dialog: true, action: { url: 'mailerconfigs?action=create', method: 'post' } },
6603
+ { name: 'edit', dialog: true, action: { url: 'mailerconfigs?action=edit', method: 'post' } },
6604
+ { name: 'delete', dialog: true, action: { url: 'mailerconfigs?action=delete', method: 'post' } },
6605
+ ],
6606
+ loadAction: { url: 'mailerconfigs/all/x' },
6607
+ formConfig: this.mailerFormConfig
6608
+ };
6356
6609
  }
6357
6610
  ngOnInit() {
6358
6611
  this.authService.myRoleObserv.subscribe(rol => this.myRole = rol);
@@ -6408,10 +6661,10 @@ class TenantSettingsComponent {
6408
6661
  }
6409
6662
  }
6410
6663
  TenantSettingsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TenantSettingsComponent, deps: [{ token: DataServiceLib }, { token: MessageService }, { token: AuthService }, { token: i4.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
6411
- TenantSettingsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TenantSettingsComponent, selector: "spa-tenant-settings", ngImport: i0, template: "<div class=\"container\">\r\n\r\n <div>\r\n\r\n <label class=\"title\" >Organisation Details</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-2 mt-3 tin-grid\" style=\" font-size: 14px;\">\r\n\r\n <div class=\"tin-col mb-3\" style=\"max-width: 500px;\">\r\n <spa-select display=\"Current Organisation\" [options]=\"tenants\" optionDisplay=\"name\" optionValue=\"tenantID\" [(value)]=\"currentTenantID\"\r\n hint=\"You are required to login again after switching organisations.\" style=\"min-width: 300px;margin-bottom: 10px;\"></spa-select>\r\n <button mat-stroked-button color=\"primary\" [disabled]=\"currentTenantID == currTenant.tenantID\" (click)=\"switchTenant()\">Switch</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <ng-container *ngIf=\"ownTenant\" >\r\n <!-- Members -->\r\n <div class=\"mt-3\" >\r\n\r\n <label class=\"title\" >Members</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Invite other users to join your organisation as partners or employees to form a partnership or company.</label>\r\n\r\n <spa-table [config]=\"membersTableConfig\" [reload]=\"tableReload\" ></spa-table>\r\n\r\n </div>\r\n\r\n\r\n<!-- My Organisations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >My Organisations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Organisations that you are a member of.</label>\r\n\r\n <spa-table [config]=\"orgsTableConfig\" [reload]=\"orgsReload\" (actionResponse)=\"updateTenant($event)\"></spa-table>\r\n\r\n </div>\r\n\r\n\r\n <!-- My Invitations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\">My Invitations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Requests for you to join other organisations.</label>\r\n\r\n\r\n <spa-invitations-table></spa-invitations-table>\r\n\r\n </div>\r\n\r\n <!-- Billing -->\r\n <div class=\"mt-3 mb-5\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >Billing and Subscription</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-1 mt-3\" style=\"max-width: 300px; font-size: 14px;\">\r\n <spa-label display=\"Plan\" [value]=\"plan.name\"></spa-label>\r\n <spa-label display=\"Next Payment\" format=\"money\" [value]=\"plan.price\"></spa-label>\r\n <spa-label display=\"Due Date\" format=\"date\" value=\"2024-01-01\"></spa-label>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n\r\n\r\n\r\n</div>\r\n\r\n\r\n", styles: [".title{margin-top:1em;font-size:28px;font-weight:300}.subtitle{font-size:smaller}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: LabelComponent, selector: "spa-label", inputs: ["display", "value", "format"] }, { kind: "component", type: SelectComponent, selector: "spa-select", inputs: ["peekConfig"] }, { kind: "component", type: TableComponent, selector: "spa-table", inputs: ["hideTitle", "data", "tileData", "config", "reload"], outputs: ["dataLoad", "refreshClick", "searchClick", "createClick", "actionClick", "inputChange", "actionResponse"] }, { kind: "component", type: InvitationsTableComponent, selector: "spa-invitations-table" }] });
6664
+ TenantSettingsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TenantSettingsComponent, selector: "spa-tenant-settings", ngImport: i0, template: "<div class=\"container\">\r\n\r\n <div>\r\n\r\n <label class=\"title\" >Organisation Details</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-2 mt-3 tin-grid\" style=\" font-size: 14px;\">\r\n\r\n <div class=\"tin-col mb-3\" style=\"max-width: 500px;\">\r\n <spa-select display=\"Current Organisation\" [options]=\"tenants\" optionDisplay=\"name\" optionValue=\"tenantID\" [(value)]=\"currentTenantID\"\r\n hint=\"You are required to login again after switching organisations.\" style=\"min-width: 300px;margin-bottom: 10px;\"></spa-select>\r\n <button mat-stroked-button color=\"primary\" [disabled]=\"currentTenantID == currTenant.tenantID\" (click)=\"switchTenant()\">Switch</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <ng-container *ngIf=\"ownTenant\" >\r\n <!-- Members -->\r\n <div class=\"mt-3\" >\r\n\r\n <label class=\"title\" >Members</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Invite other users to join your organisation as partners or employees to form a partnership or company.</label>\r\n\r\n <spa-table [config]=\"membersTableConfig\" [reload]=\"tableReload\" ></spa-table>\r\n\r\n </div>\r\n\r\n\r\n<!-- My Organisations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >My Organisations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Organisations that you are a member of.</label>\r\n\r\n <spa-table [config]=\"orgsTableConfig\" [reload]=\"orgsReload\" (actionResponse)=\"updateTenant($event)\"></spa-table>\r\n\r\n </div>\r\n\r\n\r\n <!-- My Invitations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\">My Invitations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Requests for you to join other organisations.</label>\r\n\r\n\r\n <spa-invitations-table></spa-invitations-table>\r\n\r\n </div>\r\n\r\n <!-- Billing -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >Billing and Subscription</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-1 mt-3\" style=\"max-width: 300px; font-size: 14px;\">\r\n <spa-label display=\"Plan\" [value]=\"plan.name\"></spa-label>\r\n <spa-label display=\"Next Payment\" format=\"money\" [value]=\"plan.price\"></spa-label>\r\n <spa-label display=\"Due Date\" format=\"date\" value=\"2024-01-01\"></spa-label>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Email -->\r\n <div class=\"mt-3 mb-5\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\">Email Configuration</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Configure email settings for sending notifications.</label>\r\n\r\n <spa-table [config]=\"mailerTableConfig\"></spa-table>\r\n\r\n </div>\r\n\r\n\r\n </ng-container>\r\n\r\n\r\n\r\n</div>\r\n\r\n\r\n", styles: [".title{margin-top:1em;font-size:28px;font-weight:300}.subtitle{font-size:smaller}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: LabelComponent, selector: "spa-label", inputs: ["display", "value", "format"] }, { kind: "component", type: SelectComponent, selector: "spa-select", inputs: ["peekConfig"] }, { kind: "component", type: TableComponent, selector: "spa-table", inputs: ["hideTitle", "data", "tileData", "config", "reload"], outputs: ["dataLoad", "refreshClick", "searchClick", "createClick", "actionClick", "inputChange", "actionResponse"] }, { kind: "component", type: InvitationsTableComponent, selector: "spa-invitations-table" }] });
6412
6665
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TenantSettingsComponent, decorators: [{
6413
6666
  type: Component,
6414
- args: [{ selector: 'spa-tenant-settings', template: "<div class=\"container\">\r\n\r\n <div>\r\n\r\n <label class=\"title\" >Organisation Details</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-2 mt-3 tin-grid\" style=\" font-size: 14px;\">\r\n\r\n <div class=\"tin-col mb-3\" style=\"max-width: 500px;\">\r\n <spa-select display=\"Current Organisation\" [options]=\"tenants\" optionDisplay=\"name\" optionValue=\"tenantID\" [(value)]=\"currentTenantID\"\r\n hint=\"You are required to login again after switching organisations.\" style=\"min-width: 300px;margin-bottom: 10px;\"></spa-select>\r\n <button mat-stroked-button color=\"primary\" [disabled]=\"currentTenantID == currTenant.tenantID\" (click)=\"switchTenant()\">Switch</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <ng-container *ngIf=\"ownTenant\" >\r\n <!-- Members -->\r\n <div class=\"mt-3\" >\r\n\r\n <label class=\"title\" >Members</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Invite other users to join your organisation as partners or employees to form a partnership or company.</label>\r\n\r\n <spa-table [config]=\"membersTableConfig\" [reload]=\"tableReload\" ></spa-table>\r\n\r\n </div>\r\n\r\n\r\n<!-- My Organisations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >My Organisations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Organisations that you are a member of.</label>\r\n\r\n <spa-table [config]=\"orgsTableConfig\" [reload]=\"orgsReload\" (actionResponse)=\"updateTenant($event)\"></spa-table>\r\n\r\n </div>\r\n\r\n\r\n <!-- My Invitations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\">My Invitations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Requests for you to join other organisations.</label>\r\n\r\n\r\n <spa-invitations-table></spa-invitations-table>\r\n\r\n </div>\r\n\r\n <!-- Billing -->\r\n <div class=\"mt-3 mb-5\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >Billing and Subscription</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-1 mt-3\" style=\"max-width: 300px; font-size: 14px;\">\r\n <spa-label display=\"Plan\" [value]=\"plan.name\"></spa-label>\r\n <spa-label display=\"Next Payment\" format=\"money\" [value]=\"plan.price\"></spa-label>\r\n <spa-label display=\"Due Date\" format=\"date\" value=\"2024-01-01\"></spa-label>\r\n </div>\r\n\r\n </div>\r\n </ng-container>\r\n\r\n\r\n\r\n</div>\r\n\r\n\r\n", styles: [".title{margin-top:1em;font-size:28px;font-weight:300}.subtitle{font-size:smaller}\n"] }]
6667
+ args: [{ selector: 'spa-tenant-settings', template: "<div class=\"container\">\r\n\r\n <div>\r\n\r\n <label class=\"title\" >Organisation Details</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-2 mt-3 tin-grid\" style=\" font-size: 14px;\">\r\n\r\n <div class=\"tin-col mb-3\" style=\"max-width: 500px;\">\r\n <spa-select display=\"Current Organisation\" [options]=\"tenants\" optionDisplay=\"name\" optionValue=\"tenantID\" [(value)]=\"currentTenantID\"\r\n hint=\"You are required to login again after switching organisations.\" style=\"min-width: 300px;margin-bottom: 10px;\"></spa-select>\r\n <button mat-stroked-button color=\"primary\" [disabled]=\"currentTenantID == currTenant.tenantID\" (click)=\"switchTenant()\">Switch</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <ng-container *ngIf=\"ownTenant\" >\r\n <!-- Members -->\r\n <div class=\"mt-3\" >\r\n\r\n <label class=\"title\" >Members</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Invite other users to join your organisation as partners or employees to form a partnership or company.</label>\r\n\r\n <spa-table [config]=\"membersTableConfig\" [reload]=\"tableReload\" ></spa-table>\r\n\r\n </div>\r\n\r\n\r\n<!-- My Organisations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >My Organisations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Organisations that you are a member of.</label>\r\n\r\n <spa-table [config]=\"orgsTableConfig\" [reload]=\"orgsReload\" (actionResponse)=\"updateTenant($event)\"></spa-table>\r\n\r\n </div>\r\n\r\n\r\n <!-- My Invitations -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\">My Invitations</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Requests for you to join other organisations.</label>\r\n\r\n\r\n <spa-invitations-table></spa-invitations-table>\r\n\r\n </div>\r\n\r\n <!-- Billing -->\r\n <div class=\"mt-3\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\" >Billing and Subscription</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n\r\n <div *ngIf=\"currTenant && plan\" class=\"mb-1 mt-3\" style=\"max-width: 300px; font-size: 14px;\">\r\n <spa-label display=\"Plan\" [value]=\"plan.name\"></spa-label>\r\n <spa-label display=\"Next Payment\" format=\"money\" [value]=\"plan.price\"></spa-label>\r\n <spa-label display=\"Due Date\" format=\"date\" value=\"2024-01-01\"></spa-label>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Email -->\r\n <div class=\"mt-3 mb-5\" *ngIf=\"ownTenant\">\r\n\r\n <label class=\"title\">Email Configuration</label>\r\n <hr style=\"margin-top: 0px; margin-bottom: 0px;\">\r\n <label class=\"subtitle text-muted\">Configure email settings for sending notifications.</label>\r\n\r\n <spa-table [config]=\"mailerTableConfig\"></spa-table>\r\n\r\n </div>\r\n\r\n\r\n </ng-container>\r\n\r\n\r\n\r\n</div>\r\n\r\n\r\n", styles: [".title{margin-top:1em;font-size:28px;font-weight:300}.subtitle{font-size:smaller}\n"] }]
6415
6668
  }], ctorParameters: function () { return [{ type: DataServiceLib }, { type: MessageService }, { type: AuthService }, { type: i4.MatDialog }]; } });
6416
6669
 
6417
6670
  class TenantsComponent {
@@ -6882,7 +7135,7 @@ class AccountsComponent {
6882
7135
  }
6883
7136
  }
6884
7137
  AccountsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AccountsComponent, deps: [{ token: i1$3.Router }, { token: DataServiceLib }, { token: MessageService }, { token: AuthService }, { token: i4.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
6885
- AccountsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AccountsComponent, selector: "spa-accounts", ngImport: i0, template: "<h4>Accounts</h4>\r\n<hr>\r\n\r\n<div class=\"tin-row d-flex justify-content-between\" style=\"font-size: 14px;margin-left: 5px;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"open(null)\">Create</button>\r\n <spa-filter [showText]=\"false\" (refreshClick)=\"loadData()\"></spa-filter>\r\n</div>\r\n\r\n<div class=\"row \" style=\"margin-left: 0px;\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" *ngFor=\"let account of accounts\" style=\"max-width: 350px;margin: 5px;\">\r\n\r\n <div class=\"tin-row d-flex justify-content-between\">\r\n <label style=\"font-size: 24px; font-weight: 300;\">{{account.name}}</label>\r\n <button mat-mini-fab color=\"primary\" (click)=\"open(account)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <hr style=\"margin-top: 5px;margin-bottom: 10px;\"/>\r\n\r\n <label *ngIf=\"account.description != ''\" style=\"font-size: small;margin-bottom: 5px;\">{{account.description}}</label>\r\n\r\n <div *ngIf=\"account\" class=\"tin-row\">\r\n <label style=\"margin-right: 5px;font-size: 14px;\">{{account?.currency}}</label>\r\n <label style=\"font-size: 34px;margin-right: 20px;\">{{account?.balance | currency : '' : ''}}</label>\r\n </div>\r\n\r\n <mat-card-actions class=\"d-flex justify-content-between\" >\r\n <button mat-stroked-button color=\"primary\" style=\"margin-right:10px;\" (click)=\"view(account)\">View</button>\r\n <button mat-mini-fab *ngIf=\"account.count == 0\" color=\"warn\" style=\"margin-right:10px\" (click)=\"delete(account)\"><mat-icon>delete</mat-icon></button>\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n</div>\r\n\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i15.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "directive", type: i15.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "component", type: FilterComponent, selector: "spa-filter", inputs: ["flatButtons", "showText", "showButton", "data"], outputs: ["refreshClick"] }, { kind: "pipe", type: i1.CurrencyPipe, name: "currency" }] });
7138
+ AccountsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AccountsComponent, selector: "spa-accounts", ngImport: i0, template: "<h4>Accounts</h4>\r\n<hr>\r\n\r\n<div class=\"tin-row d-flex justify-content-between\" style=\"font-size: 14px;margin-left: 5px;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"open(null)\">Create</button>\r\n <spa-filter [showText]=\"false\" (refreshClick)=\"loadData()\"></spa-filter>\r\n</div>\r\n\r\n<div class=\"row \" style=\"margin-left: 0px;\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" *ngFor=\"let account of accounts\" style=\"max-width: 350px;margin: 5px;\">\r\n\r\n <div class=\"tin-row d-flex justify-content-between\">\r\n <label style=\"font-size: 24px; font-weight: 300;\">{{account.name}}</label>\r\n <button mat-mini-fab color=\"primary\" (click)=\"open(account)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <hr style=\"margin-top: 5px;margin-bottom: 10px;\"/>\r\n\r\n <label *ngIf=\"account.description != ''\" style=\"font-size: small;margin-bottom: 5px;\">{{account.description}}</label>\r\n\r\n <div *ngIf=\"account\" class=\"tin-row\">\r\n <label style=\"margin-right: 5px;font-size: 14px;\">{{account?.currency}}</label>\r\n <label style=\"font-size: 34px;margin-right: 20px;\">{{account?.balance | currency : '' : ''}}</label>\r\n </div>\r\n\r\n <mat-card-actions class=\"d-flex justify-content-between\" >\r\n <button mat-stroked-button color=\"primary\" style=\"margin-right:10px;\" (click)=\"view(account)\">View</button>\r\n <button mat-mini-fab *ngIf=\"account.count == 0\" color=\"warn\" style=\"margin-right:10px\" (click)=\"delete(account)\"><mat-icon>delete</mat-icon></button>\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n</div>\r\n\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i16.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "directive", type: i16.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "component", type: FilterComponent, selector: "spa-filter", inputs: ["flatButtons", "showText", "showButton", "data"], outputs: ["refreshClick"] }, { kind: "pipe", type: i1.CurrencyPipe, name: "currency" }] });
6886
7139
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AccountsComponent, decorators: [{
6887
7140
  type: Component,
6888
7141
  args: [{ selector: 'spa-accounts', template: "<h4>Accounts</h4>\r\n<hr>\r\n\r\n<div class=\"tin-row d-flex justify-content-between\" style=\"font-size: 14px;margin-left: 5px;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"open(null)\">Create</button>\r\n <spa-filter [showText]=\"false\" (refreshClick)=\"loadData()\"></spa-filter>\r\n</div>\r\n\r\n<div class=\"row \" style=\"margin-left: 0px;\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" *ngFor=\"let account of accounts\" style=\"max-width: 350px;margin: 5px;\">\r\n\r\n <div class=\"tin-row d-flex justify-content-between\">\r\n <label style=\"font-size: 24px; font-weight: 300;\">{{account.name}}</label>\r\n <button mat-mini-fab color=\"primary\" (click)=\"open(account)\"><mat-icon>edit</mat-icon></button>\r\n </div>\r\n\r\n <hr style=\"margin-top: 5px;margin-bottom: 10px;\"/>\r\n\r\n <label *ngIf=\"account.description != ''\" style=\"font-size: small;margin-bottom: 5px;\">{{account.description}}</label>\r\n\r\n <div *ngIf=\"account\" class=\"tin-row\">\r\n <label style=\"margin-right: 5px;font-size: 14px;\">{{account?.currency}}</label>\r\n <label style=\"font-size: 34px;margin-right: 20px;\">{{account?.balance | currency : '' : ''}}</label>\r\n </div>\r\n\r\n <mat-card-actions class=\"d-flex justify-content-between\" >\r\n <button mat-stroked-button color=\"primary\" style=\"margin-right:10px;\" (click)=\"view(account)\">View</button>\r\n <button mat-mini-fab *ngIf=\"account.count == 0\" color=\"warn\" style=\"margin-right:10px\" (click)=\"delete(account)\"><mat-icon>delete</mat-icon></button>\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n</div>\r\n\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"] }]
@@ -7297,16 +7550,102 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
7297
7550
  }], ctorParameters: function () { return [{ type: DataServiceLib }, { type: AuthService }]; } });
7298
7551
 
7299
7552
  class NotificationsComponent {
7300
- constructor() { }
7553
+ constructor(dataService, notificationsService) {
7554
+ this.dataService = dataService;
7555
+ this.notificationsService = notificationsService;
7556
+ this.createDialog = {
7557
+ formConfig: {
7558
+ title: 'Send Notification',
7559
+ fixedTitle: true,
7560
+ fields: [
7561
+ { name: 'message', type: 'text', required: true, span: true },
7562
+ {
7563
+ name: 'category', type: 'select', required: true, defaultFirstValue: true,
7564
+ options: [
7565
+ { name: 'System', value: 0 },
7566
+ { name: 'Security', value: 1 },
7567
+ { name: 'Task', value: 2 },
7568
+ { name: 'Approval', value: 3 },
7569
+ { name: 'Other', value: 4 }
7570
+ ]
7571
+ },
7572
+ {
7573
+ name: 'type', type: 'select', required: true, defaultFirstValue: true,
7574
+ options: [
7575
+ { name: 'Info', value: 'info' },
7576
+ { name: 'Warning', value: 'warn' },
7577
+ { name: 'Error', value: 'error' }
7578
+ ]
7579
+ },
7580
+ { name: 'durationHours', type: 'number', required: true, defaultValue: 24, hint: 'How long to keep this notification active' },
7581
+ { name: 'notifyAllUsers', type: 'checkbox', alias: 'Notify All Users', span: true },
7582
+ { name: 'recipients', type: 'multi-text', alias: 'Recipients', span: true, hiddenCondition: x => x.notifyAllUsers },
7583
+ { name: 'roleIDs', type: 'multi-text', strict: true, copyContent: true, alias: 'Role IDs', span: true, hiddenCondition: x => x.notifyAllUsers, infoMessage: 'Loading roles...' },
7584
+ {
7585
+ name: 'channels', type: 'select', alias: 'Notification Channels', span: true, defaultFirstValue: true, required: true,
7586
+ options: [
7587
+ { name: 'UI Only', value: 1 },
7588
+ { name: 'UI + Email', value: 3 },
7589
+ { name: 'UI + Email + SMS', value: 7 },
7590
+ { name: 'All Channels', value: 15 }
7591
+ ]
7592
+ }
7593
+ ]
7594
+ },
7595
+ mode: 'create',
7596
+ buttons: [
7597
+ { name: 'create', display: 'Send', action: { url: 'notifications/notify', method: 'post', successMessage: 'Notification sent successfully' } }
7598
+ ]
7599
+ };
7600
+ this.notificationsTableConfig = {
7601
+ showFilter: true,
7602
+ minColumns: ['message', 'categoryName'],
7603
+ flatButtons: true,
7604
+ columns: [
7605
+ {
7606
+ name: 'type', type: 'icon',
7607
+ icons: [
7608
+ { name: 'info', color: 'steelblue', condition: x => x.type === 'info' },
7609
+ { name: 'warning', color: '#FF9800', condition: x => x.type === 'warn' },
7610
+ { name: 'error', color: '#f44336', condition: x => x.type === 'error' }
7611
+ ]
7612
+ },
7613
+ { name: 'createdDate', type: 'datetime', alias: 'Date' },
7614
+ { name: 'message', type: 'text' },
7615
+ { name: 'categoryName', type: 'text', alias: 'Category' },
7616
+ // { name: 'createdByName', type: 'text', alias: 'From' }
7617
+ ],
7618
+ buttons: [
7619
+ { name: 'create', display: 'Send Notification', dialog: true, detailsConfig: this.createDialog },
7620
+ { name: 'dismiss', icon: { name: 'done' }, color: 'green', action: { url: 'notifications?action=dismiss', method: 'post' }, visible: x => x.canDismiss },
7621
+ { name: 'dismissAll', display: 'Dismiss All', inHeader: true, icon: { name: 'done_all' }, color: 'green', action: { url: 'notifications/dismiss-all', method: 'post' } }
7622
+ ],
7623
+ loadAction: { url: 'notifications/all/x' }
7624
+ };
7625
+ }
7301
7626
  ngOnInit() {
7627
+ this.loadRoles();
7628
+ this.notificationsService.loadNotifications();
7629
+ }
7630
+ loadRoles() {
7631
+ this.dataService.CallApi({ url: 'role/list/x' }, "").subscribe((apiResponse) => {
7632
+ this.createDialog.formConfig.fields.find(x => x.name == 'roleIDs').infoMessage = 'Available Roles:\n' + apiResponse.data.map(r => `${r.roleID} - ${r.roleName}`).join('\n');
7633
+ this.createDialog.formConfig.fields.find(x => x.name == 'roleIDs').options = apiResponse.data;
7634
+ });
7635
+ this.dataService.CallApi({ url: 'user/list/x' }, "").subscribe((apiResponse) => {
7636
+ this.createDialog.formConfig.fields.find(x => x.name == 'recipients').options = apiResponse.data;
7637
+ });
7638
+ }
7639
+ actionClicked(x) {
7640
+ this.notificationsService.loadNotifications();
7302
7641
  }
7303
7642
  }
7304
- NotificationsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7305
- NotificationsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NotificationsComponent, selector: "spa-notifications", ngImport: i0, template: "<p>notifications works!</p>\n", styles: [""] });
7643
+ NotificationsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationsComponent, deps: [{ token: DataServiceLib }, { token: NotificationsService }], target: i0.ɵɵFactoryTarget.Component });
7644
+ NotificationsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NotificationsComponent, selector: "spa-notifications", ngImport: i0, template: "<h4>Notifications</h4>\n<hr>\n\n\n<div class=\"mt-3\" style=\" font-size: 14px;\">\n <spa-table [config]=\"notificationsTableConfig\" (actionResponse)=\"actionClicked($event)\"></spa-table>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: TableComponent, selector: "spa-table", inputs: ["hideTitle", "data", "tileData", "config", "reload"], outputs: ["dataLoad", "refreshClick", "searchClick", "createClick", "actionClick", "inputChange", "actionResponse"] }] });
7306
7645
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NotificationsComponent, decorators: [{
7307
7646
  type: Component,
7308
- args: [{ selector: 'spa-notifications', template: "<p>notifications works!</p>\n" }]
7309
- }], ctorParameters: function () { return []; } });
7647
+ args: [{ selector: 'spa-notifications', template: "<h4>Notifications</h4>\n<hr>\n\n\n<div class=\"mt-3\" style=\" font-size: 14px;\">\n <spa-table [config]=\"notificationsTableConfig\" (actionResponse)=\"actionClicked($event)\"></spa-table>\n</div>\n" }]
7648
+ }], ctorParameters: function () { return [{ type: DataServiceLib }, { type: NotificationsService }]; } });
7310
7649
 
7311
7650
  class PageComponent {
7312
7651
  constructor(dataServiceLib, messageService) {
@@ -7316,6 +7655,12 @@ class PageComponent {
7316
7655
  this.searchModeActivated = new EventEmitter();
7317
7656
  this.searchModeDeactivated = new EventEmitter();
7318
7657
  this.refreshClick = new EventEmitter();
7658
+ this.actionClick = new EventEmitter();
7659
+ this.actionResponse = new EventEmitter();
7660
+ this.inputChange = new EventEmitter();
7661
+ this.createClick = new EventEmitter();
7662
+ this.searchClick = new EventEmitter();
7663
+ this.dataLoad = new EventEmitter();
7319
7664
  this.tableReload = new Subject();
7320
7665
  this.searchMode = false;
7321
7666
  }
@@ -7348,12 +7693,30 @@ class PageComponent {
7348
7693
  refreshClicked() {
7349
7694
  this.refreshClick.emit();
7350
7695
  }
7696
+ actionClicked(x) {
7697
+ this.actionClick.emit(x);
7698
+ }
7699
+ actionResponded(x) {
7700
+ this.actionResponse.emit(x);
7701
+ }
7702
+ inputChanged(x) {
7703
+ this.inputChange.emit(x);
7704
+ }
7705
+ createClicked(x) {
7706
+ this.createClick.emit(x);
7707
+ }
7708
+ searchClicked(x) {
7709
+ this.searchClick.emit(x);
7710
+ }
7711
+ dataLoaded(x) {
7712
+ this.dataLoad.emit(x);
7713
+ }
7351
7714
  }
7352
7715
  PageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PageComponent, deps: [{ token: DataServiceLib }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component });
7353
- PageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PageComponent, selector: "spa-page", inputs: { config: "config" }, outputs: { searchModeActivated: "searchModeActivated", searchModeDeactivated: "searchModeDeactivated", refreshClick: "refreshClick" }, ngImport: i0, template: "<div class=\"row\">\r\n\r\n <div class=\"col\">\r\n <h4>{{config.title ?? 'Untitled'}} </h4>\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" style=\"font-size: 14px;\">\r\n <spa-check *ngIf=\"config.searchTableConfig\" [(value)]=\"searchMode\" display=\"Search Mode\" (valueChange)=\"toggleSearch()\" style=\"margin-right: 10px;\"></spa-check>\r\n </div>\r\n\r\n</div>\r\n\r\n<hr style=\"margin-top: 0px;\" />\r\n\r\n\r\n<div style=\" font-size: 14px;\">\r\n <!-- Normal -->\r\n <spa-table *ngIf=\"!searchMode\" [config]=\"normalTableConfig\" [reload]=\"tableReload\" (refreshClick)=\"refreshClicked()\"></spa-table>\r\n\r\n <!-- Search -->\r\n <spa-table *ngIf=\"searchMode\" [config]=\"searchTableConfig\" [reload]=\"tableReload\" (refreshClick)=\"refreshClicked()\"></spa-table>\r\n</div>\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: TableComponent, selector: "spa-table", inputs: ["hideTitle", "data", "tileData", "config", "reload"], outputs: ["dataLoad", "refreshClick", "searchClick", "createClick", "actionClick", "inputChange", "actionResponse"] }] });
7716
+ PageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PageComponent, selector: "spa-page", inputs: { config: "config" }, outputs: { searchModeActivated: "searchModeActivated", searchModeDeactivated: "searchModeDeactivated", refreshClick: "refreshClick", actionClick: "actionClick", actionResponse: "actionResponse", inputChange: "inputChange", createClick: "createClick", searchClick: "searchClick", dataLoad: "dataLoad" }, ngImport: i0, template: "<div class=\"row\">\r\n\r\n <div class=\"col\">\r\n <h4>{{config.title ?? 'Untitled'}} </h4>\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" style=\"font-size: 14px;\">\r\n <spa-check *ngIf=\"config.searchTableConfig\" [(value)]=\"searchMode\" display=\"Search Mode\" (valueChange)=\"toggleSearch()\" style=\"margin-right: 10px;\"></spa-check>\r\n </div>\r\n\r\n</div>\r\n\r\n<hr style=\"margin-top: 0px;\" />\r\n\r\n\r\n<div style=\" font-size: 14px;\">\r\n <!-- Normal -->\r\n <spa-table *ngIf=\"!searchMode\" [config]=\"normalTableConfig\" [reload]=\"tableReload\"\r\n (refreshClick)=\"refreshClicked()\" (actionClick)=\"actionClicked($event)\" (actionResponse)=\"actionResponded($event)\"\r\n (inputChange)=\"inputChanged($event)\" (createClick)=\"createClicked($event)\" (searchClick)=\"searchClicked($event)\" (dataLoad)=\"dataLoaded($event)\">\r\n </spa-table>\r\n\r\n <!-- Search -->\r\n <spa-table *ngIf=\"searchMode\" [config]=\"searchTableConfig\" [reload]=\"tableReload\"\r\n (refreshClick)=\"refreshClicked()\" (actionClick)=\"actionClicked($event)\" (actionResponse)=\"actionResponded($event)\"\r\n (inputChange)=\"inputChanged($event)\" (createClick)=\"createClicked($event)\" (searchClick)=\"searchClicked($event)\" (dataLoad)=\"dataLoaded($event)\">\r\n </spa-table>\r\n</div>\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CheckComponent, selector: "spa-check", inputs: ["readonly", "display", "value", "infoMessage"], outputs: ["valueChange", "click", "check", "uncheck", "infoClick"] }, { kind: "component", type: TableComponent, selector: "spa-table", inputs: ["hideTitle", "data", "tileData", "config", "reload"], outputs: ["dataLoad", "refreshClick", "searchClick", "createClick", "actionClick", "inputChange", "actionResponse"] }] });
7354
7717
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PageComponent, decorators: [{
7355
7718
  type: Component,
7356
- args: [{ selector: 'spa-page', template: "<div class=\"row\">\r\n\r\n <div class=\"col\">\r\n <h4>{{config.title ?? 'Untitled'}} </h4>\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" style=\"font-size: 14px;\">\r\n <spa-check *ngIf=\"config.searchTableConfig\" [(value)]=\"searchMode\" display=\"Search Mode\" (valueChange)=\"toggleSearch()\" style=\"margin-right: 10px;\"></spa-check>\r\n </div>\r\n\r\n</div>\r\n\r\n<hr style=\"margin-top: 0px;\" />\r\n\r\n\r\n<div style=\" font-size: 14px;\">\r\n <!-- Normal -->\r\n <spa-table *ngIf=\"!searchMode\" [config]=\"normalTableConfig\" [reload]=\"tableReload\" (refreshClick)=\"refreshClicked()\"></spa-table>\r\n\r\n <!-- Search -->\r\n <spa-table *ngIf=\"searchMode\" [config]=\"searchTableConfig\" [reload]=\"tableReload\" (refreshClick)=\"refreshClicked()\"></spa-table>\r\n</div>\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"] }]
7719
+ args: [{ selector: 'spa-page', template: "<div class=\"row\">\r\n\r\n <div class=\"col\">\r\n <h4>{{config.title ?? 'Untitled'}} </h4>\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-end\" style=\"font-size: 14px;\">\r\n <spa-check *ngIf=\"config.searchTableConfig\" [(value)]=\"searchMode\" display=\"Search Mode\" (valueChange)=\"toggleSearch()\" style=\"margin-right: 10px;\"></spa-check>\r\n </div>\r\n\r\n</div>\r\n\r\n<hr style=\"margin-top: 0px;\" />\r\n\r\n\r\n<div style=\" font-size: 14px;\">\r\n <!-- Normal -->\r\n <spa-table *ngIf=\"!searchMode\" [config]=\"normalTableConfig\" [reload]=\"tableReload\"\r\n (refreshClick)=\"refreshClicked()\" (actionClick)=\"actionClicked($event)\" (actionResponse)=\"actionResponded($event)\"\r\n (inputChange)=\"inputChanged($event)\" (createClick)=\"createClicked($event)\" (searchClick)=\"searchClicked($event)\" (dataLoad)=\"dataLoaded($event)\">\r\n </spa-table>\r\n\r\n <!-- Search -->\r\n <spa-table *ngIf=\"searchMode\" [config]=\"searchTableConfig\" [reload]=\"tableReload\"\r\n (refreshClick)=\"refreshClicked()\" (actionClick)=\"actionClicked($event)\" (actionResponse)=\"actionResponded($event)\"\r\n (inputChange)=\"inputChanged($event)\" (createClick)=\"createClicked($event)\" (searchClick)=\"searchClicked($event)\" (dataLoad)=\"dataLoaded($event)\">\r\n </spa-table>\r\n</div>\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}\n"] }]
7357
7720
  }], ctorParameters: function () { return [{ type: DataServiceLib }, { type: MessageService }]; }, propDecorators: { config: [{
7358
7721
  type: Input
7359
7722
  }], searchModeActivated: [{
@@ -7362,6 +7725,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
7362
7725
  type: Output
7363
7726
  }], refreshClick: [{
7364
7727
  type: Output
7728
+ }], actionClick: [{
7729
+ type: Output
7730
+ }], actionResponse: [{
7731
+ type: Output
7732
+ }], inputChange: [{
7733
+ type: Output
7734
+ }], createClick: [{
7735
+ type: Output
7736
+ }], searchClick: [{
7737
+ type: Output
7738
+ }], dataLoad: [{
7739
+ type: Output
7365
7740
  }] } });
7366
7741
 
7367
7742
  class SelectContextDirective {
@@ -7390,6 +7765,7 @@ class ApprovalsComponent {
7390
7765
  this.approvalsTableConfig = {
7391
7766
  showFilter: true,
7392
7767
  minColumns: ['message', 'statusName'],
7768
+ minButtons: ['approve', 'decline'],
7393
7769
  flatButtons: true,
7394
7770
  greyOut: (x) => x.isGreyedOut,
7395
7771
  logResponse: true,
@@ -7437,7 +7813,7 @@ class ApprovalsComponent {
7437
7813
  }
7438
7814
  }
7439
7815
  ApprovalsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ApprovalsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7440
- ApprovalsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ApprovalsComponent, selector: "spa-approvals", ngImport: i0, template: "<spa-page [config]=\"pageConfig\"></spa-page>\n", styles: [""], dependencies: [{ kind: "component", type: PageComponent, selector: "spa-page", inputs: ["config"], outputs: ["searchModeActivated", "searchModeDeactivated", "refreshClick"] }] });
7816
+ ApprovalsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ApprovalsComponent, selector: "spa-approvals", ngImport: i0, template: "<spa-page [config]=\"pageConfig\"></spa-page>\n", styles: [""], dependencies: [{ kind: "component", type: PageComponent, selector: "spa-page", inputs: ["config"], outputs: ["searchModeActivated", "searchModeDeactivated", "refreshClick", "actionClick", "actionResponse", "inputChange", "createClick", "searchClick", "dataLoad"] }] });
7441
7817
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ApprovalsComponent, decorators: [{
7442
7818
  type: Component,
7443
7819
  args: [{ selector: 'spa-approvals', template: "<spa-page [config]=\"pageConfig\"></spa-page>\n" }]
@@ -7448,7 +7824,6 @@ class ApprovalsConfigComponent {
7448
7824
  // Approval Roles
7449
7825
  this.approvalRolesFormConfig = {
7450
7826
  title: 'Approval Role',
7451
- alertMessages: { messages: [] },
7452
7827
  fields: [
7453
7828
  { name: 'roleID', type: 'select', required: true, alias: 'Role', optionDisplay: 'roleName', optionValue: 'roleID', loadAction: { url: 'role/all/x' } }
7454
7829
  ],
@@ -7523,7 +7898,7 @@ class ApprovalsConfigComponent {
7523
7898
  }
7524
7899
  }
7525
7900
  ApprovalsConfigComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ApprovalsConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7526
- ApprovalsConfigComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ApprovalsConfigComponent, selector: "spa-approvals-config", ngImport: i0, template: "<spa-page [config]=\"pageConfig\"></spa-page>\n", styles: [""], dependencies: [{ kind: "component", type: PageComponent, selector: "spa-page", inputs: ["config"], outputs: ["searchModeActivated", "searchModeDeactivated", "refreshClick"] }] });
7901
+ ApprovalsConfigComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ApprovalsConfigComponent, selector: "spa-approvals-config", ngImport: i0, template: "<spa-page [config]=\"pageConfig\"></spa-page>\n", styles: [""], dependencies: [{ kind: "component", type: PageComponent, selector: "spa-page", inputs: ["config"], outputs: ["searchModeActivated", "searchModeDeactivated", "refreshClick", "actionClick", "actionResponse", "inputChange", "createClick", "searchClick", "dataLoad"] }] });
7527
7902
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ApprovalsConfigComponent, decorators: [{
7528
7903
  type: Component,
7529
7904
  args: [{ selector: 'spa-approvals-config', template: "<spa-page [config]=\"pageConfig\"></spa-page>\n" }]
@@ -7540,13 +7915,14 @@ TinSpaModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
7540
7915
  TransactionsComponent, transactDialog, ListDialogComponent, TasksComponent,
7541
7916
  DepartmentsComponent, EmployeesComponent, PositionsComponent, GradesComponent, WelcomeComponent, NotificationsComponent, InvitationsTableComponent,
7542
7917
  TableHeaderComponent, TableRowComponent, TableActionComponent,
7543
- AlertComponent, EmailComponent, PageComponent, SelectCommonComponent, SelectInternalComponent, SuffixComponent, SelectContextDirective, SelectLiteComponent, TableLiteComponent, DetailsDialogLite, ApprovalsComponent, ApprovalsConfigComponent], imports: [SpaMatModule,
7918
+ AlertComponent, EmailComponent, PageComponent, SelectCommonComponent, SelectInternalComponent, SuffixComponent, SelectContextDirective, SelectLiteComponent, TableLiteComponent, DetailsDialogLite, ApprovalsComponent, ApprovalsConfigComponent, MultiTextComponent], imports: [SpaMatModule,
7544
7919
  HttpClientModule,
7545
7920
  CurrencyInputModule,
7546
7921
  NgxDocViewerModule], exports: [TinSpaComponent,
7547
7922
  SpaMatModule,
7548
7923
  AlertComponent,
7549
7924
  TextComponent,
7925
+ MultiTextComponent,
7550
7926
  messageDialog,
7551
7927
  NavMenuComponent,
7552
7928
  LoaderComponent,
@@ -7598,7 +7974,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
7598
7974
  TransactionsComponent, transactDialog, ListDialogComponent, TasksComponent,
7599
7975
  DepartmentsComponent, EmployeesComponent, PositionsComponent, GradesComponent, WelcomeComponent, NotificationsComponent, InvitationsTableComponent,
7600
7976
  TableHeaderComponent, TableRowComponent, TableActionComponent,
7601
- AlertComponent, EmailComponent, PageComponent, SelectCommonComponent, SelectInternalComponent, SuffixComponent, SelectContextDirective, SelectLiteComponent, TableLiteComponent, DetailsDialogLite, ApprovalsComponent, ApprovalsConfigComponent
7977
+ AlertComponent, EmailComponent, PageComponent, SelectCommonComponent, SelectInternalComponent, SuffixComponent, SelectContextDirective, SelectLiteComponent, TableLiteComponent, DetailsDialogLite, ApprovalsComponent, ApprovalsConfigComponent, MultiTextComponent
7602
7978
  ],
7603
7979
  imports: [
7604
7980
  SpaMatModule,
@@ -7611,6 +7987,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
7611
7987
  SpaMatModule,
7612
7988
  AlertComponent,
7613
7989
  TextComponent,
7990
+ MultiTextComponent,
7614
7991
  messageDialog,
7615
7992
  NavMenuComponent,
7616
7993
  LoaderComponent,
@@ -7652,7 +8029,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
7652
8029
  }] });
7653
8030
 
7654
8031
  class LoginComponent {
7655
- constructor(httpService, storageService, router, messageService, dataService, authService, logService, route, socialService) {
8032
+ constructor(httpService, storageService, router, messageService, dataService, authService, logService, route, socialService, notificationsService) {
7656
8033
  this.httpService = httpService;
7657
8034
  this.storageService = storageService;
7658
8035
  this.router = router;
@@ -7662,6 +8039,7 @@ class LoginComponent {
7662
8039
  this.logService = logService;
7663
8040
  this.route = route;
7664
8041
  this.socialService = socialService;
8042
+ this.notificationsService = notificationsService;
7665
8043
  this.style = "default";
7666
8044
  this.email = "";
7667
8045
  this.password = "";
@@ -7751,13 +8129,18 @@ class LoginComponent {
7751
8129
  this.messageService.toast(this.httpService.Error(error));
7752
8130
  });
7753
8131
  }
8132
+ notifications() {
8133
+ if (this.appConfig.multitenant) {
8134
+ this.notificationsService.loadNotifications();
8135
+ }
8136
+ }
7754
8137
  }
7755
- LoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoginComponent, deps: [{ token: HttpService }, { token: StorageService }, { token: i1$3.Router }, { token: MessageService }, { token: DataServiceLib }, { token: AuthService }, { token: LogService }, { token: i1$3.ActivatedRoute }, { token: i8.SocialAuthService }], target: i0.ɵɵFactoryTarget.Component });
7756
- LoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LoginComponent, selector: "spa-login", ngImport: i0, template: "\r\n <div *ngIf=\"style=='old'\" class=\"tin-bg-login login-page\">\r\n\r\n <div *ngIf=\"appConfig.logo!=''\" class=\"d-flex justify-content-center row align-items-center\" style=\"margin-top:3em;margin-bottom:1em\">\r\n\r\n <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px;margin-right:3em;margin-left:3em\" />\r\n <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px;margin-right:3em;margin-left:3em\" />\r\n <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px; margin-right:3em;margin-left:3em\" />\r\n\r\n </div>\r\n\r\n\r\n <div *ngIf=\"appConfig.logo ==''\" style=\"margin-top:2em\">\r\n <!-- Add margin top when there is no logo -->\r\n </div>\r\n\r\n\r\n <div class=\"d-flex justify-content-center row align-items-center\" style=\"margin-top:3em;\">\r\n\r\n <div class=\"d-none d-sm-block\">\r\n </div>\r\n\r\n <div style=\"margin-left:1em\">\r\n\r\n <mat-card class=\"mat-elevation-z3 login-card\" style=\"width:400px; \">\r\n\r\n <mat-card-header>\r\n <mat-card-title>{{appConfig.appName}}</mat-card-title>\r\n </mat-card-header>\r\n\r\n <mat-card-content>\r\n\r\n <div class=\"tin-input mt-2\">\r\n\r\n <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\" ></spa-text>\r\n\r\n <mat-form-field >\r\n <mat-label>Password</mat-label>\r\n <input id=\"txtPassword\" matInput [type]=\"hide ? 'password' : 'text'\" (keyup.enter)=\"login()\" [(ngModel)]=\"user.password\" autocomplete=\"off\" >\r\n <button mat-icon-button matSuffix (click)=\"hide = !hide\" [attr.aria-label]=\"'Hide password'\" [attr.aria-pressed]=\"hide\">\r\n <mat-icon style=\"font-size: 18px;\">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n\r\n </div>\r\n\r\n </mat-card-content>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <div class=\"row \">\r\n\r\n <div class=\"col d-flex justify-content-center\">\r\n <button id=\"btnLogin\" mat-raised-button [disabled]=\"isProcessing\" style=\"width: 100px;\" (click)=\"login()\" color=\"primary\">Login</button>\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-center\" *ngIf=\"appConfig.selfService\">\r\n <button id=\"btnSignup\" mat-stroked-button color=\"primary\" style=\"width: 100px;\" (click)=\"signup()\">Signup</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n <div *ngIf=\"appConfig.selfService\">\r\n <br />\r\n <a mat-button id=\"lnkRecover\" style=\"margin-left: 1em\" (click)=\"recoverAccount()\">Forgot your password ?</a>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div *ngIf=\"style=='default'\" class=\"login-page background tin-bg-login\">\r\n\r\n <div class=\"container\" >\r\n\r\n <div class=\"logo\">\r\n <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px\" />\r\n <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px\" />\r\n <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px\" />\r\n </div>\r\n\r\n <mat-card class=\"mat-elevation-z3 \" style=\"width:400px; \">\r\n\r\n <mat-card-header>\r\n <mat-card-title style=\"font-size: 40px;margin-bottom: 10px; margin-top: 20px; font-weight: 300\">{{appConfig.appName}}</mat-card-title>\r\n </mat-card-header>\r\n\r\n <mat-card-content *ngIf=\"appConfig.localAuth || appConfig.ADAuth\">\r\n\r\n <div class=\"tin-input mt-2\">\r\n\r\n <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\"></spa-text>\r\n\r\n <spa-text id=\"txtPassword\" display=\"Password\" format=\"password\" [(value)]=\"user.password\" (enterPress)=\"login()\"></spa-text>\r\n\r\n </div>\r\n\r\n </mat-card-content>\r\n\r\n\r\n <mat-card-actions style=\"margin-bottom: 10px;\">\r\n\r\n <div class=\"button mt-0\" *ngIf=\"appConfig.localAuth || appConfig.ADAuth\">\r\n <button id=\"btnLogin\" mat-flat-button [disabled]=\"isProcessing\" style=\"width: 350px;\" (click)=\"login()\" color=\"primary\">Login</button>\r\n </div>\r\n\r\n <div class=\"button\" *ngIf=\"(appConfig.localAuth || appConfig.ADAuth) && appConfig.selfService\" >\r\n <button id=\"btnSignup\" mat-stroked-button color=\"primary\" style=\"width: 350px;\" (click)=\"signup()\">Sign up with Email</button>\r\n </div>\r\n\r\n <div class=\"button\" *ngIf=\"appConfig.googleAuth\">\r\n <asl-google-signin-button type='standard' width=\"350px\" size='medium' logo_alignment=\"center\" style=\"text-align: center;\"></asl-google-signin-button>\r\n </div>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n <a *ngIf=\"appConfig.selfService\" mat-button id=\"lnkRecover\" style=\"margin-top: 1em\" (click)=\"recoverAccount()\">Forgot your password ?</a>\r\n\r\n\r\n\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"style=='bs'\">\r\n\r\n <div class=\"container\">\r\n\r\n <div class=\"image\">\r\n <img class=\"mb-4\" src=\"c:\\Tinashe\\Code\\Angular\\Junk\\bs-examples\\assets\\brand\\bootstrap-logo.svg\" alt=\"\" width=\"72\" height=\"57\">\r\n </div>\r\n\r\n <div class=\"details\">\r\n <h1 class=\"h3 mb-3 fw-normal\" >Please sign in</h1>\r\n\r\n <div class=\"form-floating\">\r\n <input class=\"form-control\" id=\"floatingInput\" placeholder=\"name@example.com\" [(ngModel)]=\"user.userName\">\r\n <label for=\"floatingInput\">Username</label>\r\n </div>\r\n\r\n <div class=\"form-floating\">\r\n <input type=\"password\" class=\"form-control\" id=\"floatingPassword\" placeholder=\"Password\" [(ngModel)]=\"user.password\">\r\n <label for=\"floatingPassword\">Password</label>\r\n </div>\r\n\r\n <div class=\"form-check text-start my-3\">\r\n <input class=\"form-check-input\" type=\"checkbox\" value=\"remember-me\" id=\"flexCheckDefault\" >\r\n <label class=\"form-check-label\" for=\"flexCheckDefault\">\r\n Remember me\r\n </label>\r\n </div>\r\n\r\n <button class=\"btn btn-primary w-100 py-2\" (click)=\"login()\">Sign in</button>\r\n\r\n </div>\r\n\r\n <p class=\"mt-5 mb-3 text-body-secondary\">&copy; 2017\u20132023</p>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n", styles: [".login-page{position:absolute;inset:0;overflow:auto}.background{min-height:100%}.container{display:flex;flex-direction:column;align-items:center;height:100vh}.logo{margin-top:3em;margin-bottom:1em}.buttons{display:flex;flex-direction:row;justify-content:space-evenly}.button{display:flex;flex-direction:row;justify-content:center;margin-top:10px}\n"], dependencies: [{ kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i15.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "component", type: i15.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i15.MatCardContent, selector: "mat-card-content, [mat-card-content], [matCardContent]" }, { kind: "directive", type: i15.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: i15.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "component", type: TextComponent, selector: "spa-text", inputs: ["readonly", "hint", "display", "placeholder", "value", "format", "type", "rows", "width", "copyContent", "clearContent", "options", "optionValue", "required", "min", "max", "regex", "suffix", "infoMessage"], outputs: ["valueChange", "leave", "enterPress"] }, { kind: "directive", type: i8.GoogleSigninButtonDirective, selector: "asl-google-signin-button", inputs: ["type", "size", "text", "shape", "theme", "logo_alignment", "width", "locale"] }] });
8138
+ LoginComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoginComponent, deps: [{ token: HttpService }, { token: StorageService }, { token: i1$3.Router }, { token: MessageService }, { token: DataServiceLib }, { token: AuthService }, { token: LogService }, { token: i1$3.ActivatedRoute }, { token: i8.SocialAuthService }, { token: NotificationsService }], target: i0.ɵɵFactoryTarget.Component });
8139
+ LoginComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LoginComponent, selector: "spa-login", ngImport: i0, template: "\r\n <div *ngIf=\"style=='old'\" class=\"tin-bg-login login-page\">\r\n\r\n <div *ngIf=\"appConfig.logo!=''\" class=\"d-flex justify-content-center row align-items-center\" style=\"margin-top:3em;margin-bottom:1em\">\r\n\r\n <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px;margin-right:3em;margin-left:3em\" />\r\n <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px;margin-right:3em;margin-left:3em\" />\r\n <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px; margin-right:3em;margin-left:3em\" />\r\n\r\n </div>\r\n\r\n\r\n <div *ngIf=\"appConfig.logo ==''\" style=\"margin-top:2em\">\r\n <!-- Add margin top when there is no logo -->\r\n </div>\r\n\r\n\r\n <div class=\"d-flex justify-content-center row align-items-center\" style=\"margin-top:3em;\">\r\n\r\n <div class=\"d-none d-sm-block\">\r\n </div>\r\n\r\n <div style=\"margin-left:1em\">\r\n\r\n <mat-card class=\"mat-elevation-z3 login-card\" style=\"width:400px; \">\r\n\r\n <mat-card-header>\r\n <mat-card-title>{{appConfig.appName}}</mat-card-title>\r\n </mat-card-header>\r\n\r\n <mat-card-content>\r\n\r\n <div class=\"tin-input mt-2\">\r\n\r\n <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\" ></spa-text>\r\n\r\n <mat-form-field >\r\n <mat-label>Password</mat-label>\r\n <input id=\"txtPassword\" matInput [type]=\"hide ? 'password' : 'text'\" (keyup.enter)=\"login()\" [(ngModel)]=\"user.password\" autocomplete=\"off\" >\r\n <button mat-icon-button matSuffix (click)=\"hide = !hide\" [attr.aria-label]=\"'Hide password'\" [attr.aria-pressed]=\"hide\">\r\n <mat-icon style=\"font-size: 18px;\">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n\r\n </div>\r\n\r\n </mat-card-content>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <div class=\"row \">\r\n\r\n <div class=\"col d-flex justify-content-center\">\r\n <button id=\"btnLogin\" mat-raised-button [disabled]=\"isProcessing\" style=\"width: 100px;\" (click)=\"login()\" color=\"primary\">Login</button>\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-center\" *ngIf=\"appConfig.selfService\">\r\n <button id=\"btnSignup\" mat-stroked-button color=\"primary\" style=\"width: 100px;\" (click)=\"signup()\">Signup</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n <div *ngIf=\"appConfig.selfService\">\r\n <br />\r\n <a mat-button id=\"lnkRecover\" style=\"margin-left: 1em\" (click)=\"recoverAccount()\">Forgot your password ?</a>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div *ngIf=\"style=='default'\" class=\"login-page background tin-bg-login\">\r\n\r\n <div class=\"container\" >\r\n\r\n <div class=\"logo\">\r\n <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px\" />\r\n <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px\" />\r\n <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px\" />\r\n </div>\r\n\r\n <mat-card class=\"mat-elevation-z3 \" style=\"width:400px; \">\r\n\r\n <mat-card-header>\r\n <mat-card-title style=\"font-size: 40px;margin-bottom: 10px; margin-top: 20px; font-weight: 300\">{{appConfig.appName}}</mat-card-title>\r\n </mat-card-header>\r\n\r\n <mat-card-content *ngIf=\"appConfig.localAuth || appConfig.ADAuth\">\r\n\r\n <div class=\"tin-input mt-2\">\r\n\r\n <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\"></spa-text>\r\n\r\n <spa-text id=\"txtPassword\" display=\"Password\" format=\"password\" [(value)]=\"user.password\" (enterPress)=\"login()\"></spa-text>\r\n\r\n </div>\r\n\r\n </mat-card-content>\r\n\r\n\r\n <mat-card-actions style=\"margin-bottom: 10px;\">\r\n\r\n <div class=\"button mt-0\" *ngIf=\"appConfig.localAuth || appConfig.ADAuth\">\r\n <button id=\"btnLogin\" mat-flat-button [disabled]=\"isProcessing\" style=\"width: 350px;\" (click)=\"login()\" color=\"primary\">Login</button>\r\n </div>\r\n\r\n <div class=\"button\" *ngIf=\"(appConfig.localAuth || appConfig.ADAuth) && appConfig.selfService\" >\r\n <button id=\"btnSignup\" mat-stroked-button color=\"primary\" style=\"width: 350px;\" (click)=\"signup()\">Sign up with Email</button>\r\n </div>\r\n\r\n <div class=\"button\" *ngIf=\"appConfig.googleAuth\">\r\n <asl-google-signin-button type='standard' width=\"350px\" size='medium' logo_alignment=\"center\" style=\"text-align: center;\"></asl-google-signin-button>\r\n </div>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n <a *ngIf=\"appConfig.selfService\" mat-button id=\"lnkRecover\" style=\"margin-top: 1em\" (click)=\"recoverAccount()\">Forgot your password ?</a>\r\n\r\n\r\n\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"style=='bs'\">\r\n\r\n <div class=\"container\">\r\n\r\n <div class=\"image\">\r\n <img class=\"mb-4\" src=\"c:\\Tinashe\\Code\\Angular\\Junk\\bs-examples\\assets\\brand\\bootstrap-logo.svg\" alt=\"\" width=\"72\" height=\"57\">\r\n </div>\r\n\r\n <div class=\"details\">\r\n <h1 class=\"h3 mb-3 fw-normal\" >Please sign in</h1>\r\n\r\n <div class=\"form-floating\">\r\n <input class=\"form-control\" id=\"floatingInput\" placeholder=\"name@example.com\" [(ngModel)]=\"user.userName\">\r\n <label for=\"floatingInput\">Username</label>\r\n </div>\r\n\r\n <div class=\"form-floating\">\r\n <input type=\"password\" class=\"form-control\" id=\"floatingPassword\" placeholder=\"Password\" [(ngModel)]=\"user.password\">\r\n <label for=\"floatingPassword\">Password</label>\r\n </div>\r\n\r\n <div class=\"form-check text-start my-3\">\r\n <input class=\"form-check-input\" type=\"checkbox\" value=\"remember-me\" id=\"flexCheckDefault\" >\r\n <label class=\"form-check-label\" for=\"flexCheckDefault\">\r\n Remember me\r\n </label>\r\n </div>\r\n\r\n <button class=\"btn btn-primary w-100 py-2\" (click)=\"login()\">Sign in</button>\r\n\r\n </div>\r\n\r\n <p class=\"mt-5 mb-3 text-body-secondary\">&copy; 2017\u20132023</p>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n", styles: [".login-page{position:absolute;inset:0;overflow:auto}.background{min-height:100%}.container{display:flex;flex-direction:column;align-items:center;height:100vh}.logo{margin-top:3em;margin-bottom:1em}.buttons{display:flex;flex-direction:row;justify-content:space-evenly}.button{display:flex;flex-direction:row;justify-content:center;margin-top:10px}\n"], dependencies: [{ kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix]" }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i16.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "component", type: i16.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i16.MatCardContent, selector: "mat-card-content, [mat-card-content], [matCardContent]" }, { kind: "directive", type: i16.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: i16.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "component", type: TextComponent, selector: "spa-text", inputs: ["readonly", "hint", "display", "placeholder", "value", "format", "type", "rows", "width", "copyContent", "clearContent", "options", "optionValue", "required", "min", "max", "regex", "suffix", "infoMessage"], outputs: ["valueChange", "leave", "enterPress"] }, { kind: "directive", type: i8.GoogleSigninButtonDirective, selector: "asl-google-signin-button", inputs: ["type", "size", "text", "shape", "theme", "logo_alignment", "width", "locale"] }] });
7757
8140
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoginComponent, decorators: [{
7758
8141
  type: Component,
7759
8142
  args: [{ selector: "spa-login", template: "\r\n <div *ngIf=\"style=='old'\" class=\"tin-bg-login login-page\">\r\n\r\n <div *ngIf=\"appConfig.logo!=''\" class=\"d-flex justify-content-center row align-items-center\" style=\"margin-top:3em;margin-bottom:1em\">\r\n\r\n <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px;margin-right:3em;margin-left:3em\" />\r\n <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px;margin-right:3em;margin-left:3em\" />\r\n <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px; margin-right:3em;margin-left:3em\" />\r\n\r\n </div>\r\n\r\n\r\n <div *ngIf=\"appConfig.logo ==''\" style=\"margin-top:2em\">\r\n <!-- Add margin top when there is no logo -->\r\n </div>\r\n\r\n\r\n <div class=\"d-flex justify-content-center row align-items-center\" style=\"margin-top:3em;\">\r\n\r\n <div class=\"d-none d-sm-block\">\r\n </div>\r\n\r\n <div style=\"margin-left:1em\">\r\n\r\n <mat-card class=\"mat-elevation-z3 login-card\" style=\"width:400px; \">\r\n\r\n <mat-card-header>\r\n <mat-card-title>{{appConfig.appName}}</mat-card-title>\r\n </mat-card-header>\r\n\r\n <mat-card-content>\r\n\r\n <div class=\"tin-input mt-2\">\r\n\r\n <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\" ></spa-text>\r\n\r\n <mat-form-field >\r\n <mat-label>Password</mat-label>\r\n <input id=\"txtPassword\" matInput [type]=\"hide ? 'password' : 'text'\" (keyup.enter)=\"login()\" [(ngModel)]=\"user.password\" autocomplete=\"off\" >\r\n <button mat-icon-button matSuffix (click)=\"hide = !hide\" [attr.aria-label]=\"'Hide password'\" [attr.aria-pressed]=\"hide\">\r\n <mat-icon style=\"font-size: 18px;\">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>\r\n </button>\r\n </mat-form-field>\r\n\r\n </div>\r\n\r\n </mat-card-content>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <div class=\"row \">\r\n\r\n <div class=\"col d-flex justify-content-center\">\r\n <button id=\"btnLogin\" mat-raised-button [disabled]=\"isProcessing\" style=\"width: 100px;\" (click)=\"login()\" color=\"primary\">Login</button>\r\n </div>\r\n\r\n <div class=\"col d-flex justify-content-center\" *ngIf=\"appConfig.selfService\">\r\n <button id=\"btnSignup\" mat-stroked-button color=\"primary\" style=\"width: 100px;\" (click)=\"signup()\">Signup</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n <div *ngIf=\"appConfig.selfService\">\r\n <br />\r\n <a mat-button id=\"lnkRecover\" style=\"margin-left: 1em\" (click)=\"recoverAccount()\">Forgot your password ?</a>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div *ngIf=\"style=='default'\" class=\"login-page background tin-bg-login\">\r\n\r\n <div class=\"container\" >\r\n\r\n <div class=\"logo\">\r\n <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px\" />\r\n <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px\" />\r\n <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px\" />\r\n </div>\r\n\r\n <mat-card class=\"mat-elevation-z3 \" style=\"width:400px; \">\r\n\r\n <mat-card-header>\r\n <mat-card-title style=\"font-size: 40px;margin-bottom: 10px; margin-top: 20px; font-weight: 300\">{{appConfig.appName}}</mat-card-title>\r\n </mat-card-header>\r\n\r\n <mat-card-content *ngIf=\"appConfig.localAuth || appConfig.ADAuth\">\r\n\r\n <div class=\"tin-input mt-2\">\r\n\r\n <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\"></spa-text>\r\n\r\n <spa-text id=\"txtPassword\" display=\"Password\" format=\"password\" [(value)]=\"user.password\" (enterPress)=\"login()\"></spa-text>\r\n\r\n </div>\r\n\r\n </mat-card-content>\r\n\r\n\r\n <mat-card-actions style=\"margin-bottom: 10px;\">\r\n\r\n <div class=\"button mt-0\" *ngIf=\"appConfig.localAuth || appConfig.ADAuth\">\r\n <button id=\"btnLogin\" mat-flat-button [disabled]=\"isProcessing\" style=\"width: 350px;\" (click)=\"login()\" color=\"primary\">Login</button>\r\n </div>\r\n\r\n <div class=\"button\" *ngIf=\"(appConfig.localAuth || appConfig.ADAuth) && appConfig.selfService\" >\r\n <button id=\"btnSignup\" mat-stroked-button color=\"primary\" style=\"width: 350px;\" (click)=\"signup()\">Sign up with Email</button>\r\n </div>\r\n\r\n <div class=\"button\" *ngIf=\"appConfig.googleAuth\">\r\n <asl-google-signin-button type='standard' width=\"350px\" size='medium' logo_alignment=\"center\" style=\"text-align: center;\"></asl-google-signin-button>\r\n </div>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n <a *ngIf=\"appConfig.selfService\" mat-button id=\"lnkRecover\" style=\"margin-top: 1em\" (click)=\"recoverAccount()\">Forgot your password ?</a>\r\n\r\n\r\n\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"style=='bs'\">\r\n\r\n <div class=\"container\">\r\n\r\n <div class=\"image\">\r\n <img class=\"mb-4\" src=\"c:\\Tinashe\\Code\\Angular\\Junk\\bs-examples\\assets\\brand\\bootstrap-logo.svg\" alt=\"\" width=\"72\" height=\"57\">\r\n </div>\r\n\r\n <div class=\"details\">\r\n <h1 class=\"h3 mb-3 fw-normal\" >Please sign in</h1>\r\n\r\n <div class=\"form-floating\">\r\n <input class=\"form-control\" id=\"floatingInput\" placeholder=\"name@example.com\" [(ngModel)]=\"user.userName\">\r\n <label for=\"floatingInput\">Username</label>\r\n </div>\r\n\r\n <div class=\"form-floating\">\r\n <input type=\"password\" class=\"form-control\" id=\"floatingPassword\" placeholder=\"Password\" [(ngModel)]=\"user.password\">\r\n <label for=\"floatingPassword\">Password</label>\r\n </div>\r\n\r\n <div class=\"form-check text-start my-3\">\r\n <input class=\"form-check-input\" type=\"checkbox\" value=\"remember-me\" id=\"flexCheckDefault\" >\r\n <label class=\"form-check-label\" for=\"flexCheckDefault\">\r\n Remember me\r\n </label>\r\n </div>\r\n\r\n <button class=\"btn btn-primary w-100 py-2\" (click)=\"login()\">Sign in</button>\r\n\r\n </div>\r\n\r\n <p class=\"mt-5 mb-3 text-body-secondary\">&copy; 2017\u20132023</p>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n", styles: [".login-page{position:absolute;inset:0;overflow:auto}.background{min-height:100%}.container{display:flex;flex-direction:column;align-items:center;height:100vh}.logo{margin-top:3em;margin-bottom:1em}.buttons{display:flex;flex-direction:row;justify-content:space-evenly}.button{display:flex;flex-direction:row;justify-content:center;margin-top:10px}\n"] }]
7760
- }], ctorParameters: function () { return [{ type: HttpService }, { type: StorageService }, { type: i1$3.Router }, { type: MessageService }, { type: DataServiceLib }, { type: AuthService }, { type: LogService }, { type: i1$3.ActivatedRoute }, { type: i8.SocialAuthService }]; } });
8143
+ }], ctorParameters: function () { return [{ type: HttpService }, { type: StorageService }, { type: i1$3.Router }, { type: MessageService }, { type: DataServiceLib }, { type: AuthService }, { type: LogService }, { type: i1$3.ActivatedRoute }, { type: i8.SocialAuthService }, { type: NotificationsService }]; } });
7761
8144
 
7762
8145
  class SignupComponent {
7763
8146
  constructor(httpService, messageService, dataService, authService) {
@@ -8157,7 +8540,7 @@ class LogsComponent {
8157
8540
  }
8158
8541
  }
8159
8542
  LogsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LogsComponent, deps: [{ token: AuthService }, { token: DataServiceLib }], target: i0.ɵɵFactoryTarget.Component });
8160
- LogsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LogsComponent, selector: "spa-logs", ngImport: i0, template: "\r\n <spa-page [config]=\"logsPageConfig\"></spa-page>\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"], dependencies: [{ kind: "component", type: PageComponent, selector: "spa-page", inputs: ["config"], outputs: ["searchModeActivated", "searchModeDeactivated", "refreshClick"] }] });
8543
+ LogsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LogsComponent, selector: "spa-logs", ngImport: i0, template: "\r\n <spa-page [config]=\"logsPageConfig\"></spa-page>\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"], dependencies: [{ kind: "component", type: PageComponent, selector: "spa-page", inputs: ["config"], outputs: ["searchModeActivated", "searchModeDeactivated", "refreshClick", "actionClick", "actionResponse", "inputChange", "createClick", "searchClick", "dataLoad"] }] });
8161
8544
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LogsComponent, decorators: [{
8162
8545
  type: Component,
8163
8546
  args: [{ selector: 'spa-logs', template: "\r\n <spa-page [config]=\"logsPageConfig\"></spa-page>\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"] }]
@@ -8407,7 +8790,7 @@ class RolesComponent {
8407
8790
  }
8408
8791
  }
8409
8792
  RolesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RolesComponent, deps: [{ token: HttpService }, { token: i1$3.Router }, { token: AuthService }, { token: DataServiceLib }, { token: i4.MatDialog }, { token: MessageService }], target: i0.ɵɵFactoryTarget.Component });
8410
- RolesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: RolesComponent, selector: "spa-roles", ngImport: i0, template: "<h4> Roles </h4>\r\n<hr />\r\n\r\n<div class=\"container-fluid mb-5\">\r\n\r\n <div class=\"d-flex justify-content-between mb-2\">\r\n\r\n <div >\r\n <button id=\"btnNewRole\" mat-raised-button color=\"primary\" (click)=\"addRole()\">New Role</button>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end\">\r\n <button id=\"btnRefresh\" mat-mini-fab color=\"primary\" (click)=\"refresh()\" matTooltip=\"refresh data\" matTooltipPosition=\"right\"><mat-icon class=\"refreshIcon\">refresh</mat-icon></button>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"row mt-2 mb-1\" *ngFor=\"let role of roles\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" style=\"width:100%\">\r\n\r\n <h4>{{role.roleName}}</h4>\r\n <hr />\r\n\r\n <div class=\"tin-row\" style=\" font-size:12px;\">\r\n\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capItem of appConfig.capItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capItem.name]\">{{capItem.display}}</mat-checkbox>\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubItem of capItem.capSubItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubItem.name]\">{{capSubItem.display}}</mat-checkbox>\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubSubItem of capSubItem.capSubItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubSubItem.name]\">{{capSubSubItem.display}}</mat-checkbox>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <button mat-mini-fab color=\"primary\" (click)=\"updateRole(role)\" style=\"margin-right:10px;\">\r\n <mat-icon>done_all</mat-icon>\r\n </button>\r\n\r\n <button mat-mini-fab color=\"warn\" (click)=\"deleteRole(role)\" style=\"margin-right:10px\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"], dependencies: [{ kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i15.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "directive", type: i15.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
8793
+ RolesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: RolesComponent, selector: "spa-roles", ngImport: i0, template: "<h4> Roles </h4>\r\n<hr />\r\n\r\n<div class=\"container-fluid mb-5\">\r\n\r\n <div class=\"d-flex justify-content-between mb-2\">\r\n\r\n <div >\r\n <button id=\"btnNewRole\" mat-raised-button color=\"primary\" (click)=\"addRole()\">New Role</button>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end\">\r\n <button id=\"btnRefresh\" mat-mini-fab color=\"primary\" (click)=\"refresh()\" matTooltip=\"refresh data\" matTooltipPosition=\"right\"><mat-icon class=\"refreshIcon\">refresh</mat-icon></button>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"row mt-2 mb-1\" *ngFor=\"let role of roles\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" style=\"width:100%\">\r\n\r\n <h4>{{role.roleName}}</h4>\r\n <hr />\r\n\r\n <div class=\"tin-row\" style=\" font-size:12px;\">\r\n\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capItem of appConfig.capItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capItem.name]\">{{capItem.display}}</mat-checkbox>\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubItem of capItem.capSubItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubItem.name]\">{{capSubItem.display}}</mat-checkbox>\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubSubItem of capSubItem.capSubItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubSubItem.name]\">{{capSubSubItem.display}}</mat-checkbox>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <button mat-mini-fab color=\"primary\" (click)=\"updateRole(role)\" style=\"margin-right:10px;\">\r\n <mat-icon>done_all</mat-icon>\r\n </button>\r\n\r\n <button mat-mini-fab color=\"warn\" (click)=\"deleteRole(role)\" style=\"margin-right:10px\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"], dependencies: [{ kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i16.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "directive", type: i16.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
8411
8794
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: RolesComponent, decorators: [{
8412
8795
  type: Component,
8413
8796
  args: [{ selector: "spa-roles", template: "<h4> Roles </h4>\r\n<hr />\r\n\r\n<div class=\"container-fluid mb-5\">\r\n\r\n <div class=\"d-flex justify-content-between mb-2\">\r\n\r\n <div >\r\n <button id=\"btnNewRole\" mat-raised-button color=\"primary\" (click)=\"addRole()\">New Role</button>\r\n </div>\r\n\r\n <div class=\"d-flex justify-content-end\">\r\n <button id=\"btnRefresh\" mat-mini-fab color=\"primary\" (click)=\"refresh()\" matTooltip=\"refresh data\" matTooltipPosition=\"right\"><mat-icon class=\"refreshIcon\">refresh</mat-icon></button>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <div class=\"row mt-2 mb-1\" *ngFor=\"let role of roles\">\r\n\r\n <mat-card class=\"mat-elevation-z8\" style=\"width:100%\">\r\n\r\n <h4>{{role.roleName}}</h4>\r\n <hr />\r\n\r\n <div class=\"tin-row\" style=\" font-size:12px;\">\r\n\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capItem of appConfig.capItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capItem.name]\">{{capItem.display}}</mat-checkbox>\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubItem of capItem.capSubItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubItem.name]\">{{capSubItem.display}}</mat-checkbox>\r\n\r\n <div class=\"tin-row\" *ngFor=\"let capSubSubItem of capSubItem.capSubItems\">\r\n\r\n <mat-checkbox color=\"primary\" style=\"min-width: 100px;\" [(ngModel)]=\"role[capSubSubItem.name]\">{{capSubSubItem.display}}</mat-checkbox>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n <mat-card-actions>\r\n\r\n <button mat-mini-fab color=\"primary\" (click)=\"updateRole(role)\" style=\"margin-right:10px;\">\r\n <mat-icon>done_all</mat-icon>\r\n </button>\r\n\r\n <button mat-mini-fab color=\"warn\" (click)=\"deleteRole(role)\" style=\"margin-right:10px\">\r\n <mat-icon>delete</mat-icon>\r\n </button>\r\n\r\n </mat-card-actions>\r\n\r\n </mat-card>\r\n\r\n </div>\r\n\r\n\r\n</div>\r\n\r\n", styles: [".mat-mini-fab{width:32px;height:32px}.mat-mini-fab mat-icon{font-size:16px;margin-top:-3px}.refreshIcon{font-size:22px!important;margin-top:-7px!important}\n"] }]
@@ -8633,6 +9016,7 @@ const routes$1 = [
8633
9016
  { path: "welcome", component: WelcomeComponent },
8634
9017
  { path: "approvals", component: ApprovalsComponent },
8635
9018
  { path: "approvals-config", component: ApprovalsConfigComponent },
9019
+ { path: "notifications", component: NotificationsComponent },
8636
9020
  ];
8637
9021
  class AdminRoutingModule {
8638
9022
  }
@@ -8714,5 +9098,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
8714
9098
  * Generated bundle index. Do not edit.
8715
9099
  */
8716
9100
 
8717
- export { AccountsComponent, Action, ActionResponse, ActivityComponent, AdminModule, AlertComponent, AlertMessage, AlertMessages, ApiResponse, AppConfig, AttachComponent, AuthService, CapItem, ChangePasswordComponent, CheckComponent, ChipsComponent, Constants, Core, CreateAccountComponent, CustomersComponent, DataServiceLib, DateComponent, DatetimeComponent, DepartmentsComponent, DetailsDialog, DetailsDialogConfig, DetailsDialogProcessor, DetailsSource, DialogService, EmailComponent, EmployeesComponent, ExportService, FilterComponent, FinAccount, FormComponent, FormConfig, GradesComponent, HttpService, IndexModule, InventoryComponent, LabelComponent, ListDialogComponent, ListDialogConfig, LoaderComponent, LoaderService, LogService, LoginComponent, LogsComponent, MessageService, MoneyComponent, NavMenuComponent, NumberComponent, OptionComponent, PageComponent, PageConfig, PositionsComponent, ProfileComponent, RecoverAccountComponent, RolesComponent, SearchComponent, SearchConfig, SelectComponent, SettingsComponent, SignupComponent, SpaAdminModule, SpaIndexModule, SpaMatModule, SpaUserModule, Step, StepConfig, StepsComponent, StorageService, SuppliersComponent, TableComponent, TableConfig, TasksComponent, TextComponent, TileConfig, TilesComponent, TinSpaComponent, TinSpaModule, TinSpaService, Transaction, TransactionsComponent, UserModule, UsersComponent, ViewerComponent, WelcomeComponent, addRoleDialog, dialogOptions, messageDialog, viewerDialog };
9101
+ export { AccountsComponent, Action, ActionResponse, ActivityComponent, AdminModule, AlertComponent, AlertMessage, AlertMessages, ApiResponse, AppConfig, AttachComponent, AuthService, CapItem, ChangePasswordComponent, CheckComponent, ChipsComponent, Constants, Core, CreateAccountComponent, CustomersComponent, DataServiceLib, DateComponent, DatetimeComponent, DepartmentsComponent, DetailsDialog, DetailsDialogConfig, DetailsDialogProcessor, DetailsSource, DialogService, EmailComponent, EmployeesComponent, ExportService, FilterComponent, FinAccount, FormComponent, FormConfig, GradesComponent, HttpService, IndexModule, InventoryComponent, LabelComponent, ListDialogComponent, ListDialogConfig, LoaderComponent, LoaderService, LogService, LoginComponent, LogsComponent, MessageService, MoneyComponent, MultiTextComponent, NavMenuComponent, NumberComponent, OptionComponent, PageComponent, PageConfig, PositionsComponent, ProfileComponent, RecoverAccountComponent, RolesComponent, SearchComponent, SearchConfig, SelectComponent, SettingsComponent, SignupComponent, SpaAdminModule, SpaIndexModule, SpaMatModule, SpaUserModule, Step, StepConfig, StepsComponent, StorageService, SuppliersComponent, TableComponent, TableConfig, TasksComponent, TextComponent, TileConfig, TilesComponent, TinSpaComponent, TinSpaModule, TinSpaService, Transaction, TransactionsComponent, UserModule, UsersComponent, ViewerComponent, WelcomeComponent, addRoleDialog, dialogOptions, messageDialog, viewerDialog };
8718
9102
  //# sourceMappingURL=tin-spa.mjs.map