@yuuvis/client-framework 3.0.1 → 3.2.0
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.
- package/fesm2022/yuuvis-client-framework-actions.mjs +214 -126
- package/fesm2022/yuuvis-client-framework-actions.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-app-bar.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-app-bar.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-badges.mjs +379 -0
- package/fesm2022/yuuvis-client-framework-badges.mjs.map +1 -0
- package/fesm2022/yuuvis-client-framework-breadcrumb.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-breadcrumb.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-clipboard.mjs +8 -8
- package/fesm2022/yuuvis-client-framework-clipboard.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-datepicker.mjs +31 -31
- package/fesm2022/yuuvis-client-framework-datepicker.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-forms.mjs +745 -657
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-icons.mjs +9 -9
- package/fesm2022/yuuvis-client-framework-icons.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs +10 -9
- package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-metadata-form.mjs +19 -17
- package/fesm2022/yuuvis-client-framework-metadata-form.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-details.mjs +215 -208
- package/fesm2022/yuuvis-client-framework-object-details.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs +18 -18
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-form.mjs +41 -37
- package/fesm2022/yuuvis-client-framework-object-form.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-preview.mjs +9 -9
- package/fesm2022/yuuvis-client-framework-object-preview.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs +29 -29
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-summary.mjs +16 -16
- package/fesm2022/yuuvis-client-framework-object-summary.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-versions.mjs +18 -12
- package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-pagination.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-pagination.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-query-list.mjs +7 -7
- package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-renderer.mjs +40 -40
- package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-sequence-list.mjs +50 -38
- package/fesm2022/yuuvis-client-framework-sequence-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-simple-search.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-simple-search.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-sort.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-sort.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tile-list.mjs +191 -127
- package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-token-search.mjs +7 -7
- package/fesm2022/yuuvis-client-framework-token-search.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tree.mjs +9 -9
- package/fesm2022/yuuvis-client-framework-tree.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-upload-progress.mjs +10 -10
- package/fesm2022/yuuvis-client-framework-upload-progress.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework.mjs +96 -51
- package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
- package/lib/assets/i18n/de.json +12 -1
- package/lib/assets/i18n/en.json +12 -1
- package/package.json +9 -5
- package/types/yuuvis-client-framework-actions.d.ts +91 -52
- package/types/yuuvis-client-framework-badges.d.ts +194 -0
- package/types/yuuvis-client-framework-forms.d.ts +215 -186
- package/types/yuuvis-client-framework-object-details.d.ts +104 -104
- package/types/yuuvis-client-framework-object-versions.d.ts +1 -0
- package/types/yuuvis-client-framework-sequence-list.d.ts +2 -2
- package/types/yuuvis-client-framework-tile-list.d.ts +11 -6
- package/types/yuuvis-client-framework.d.ts +13 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yuuvis-client-framework-upload-progress.mjs","sources":["../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress-overlay/upload-progress-overlay.component.ts","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress-overlay/upload-progress-overlay.component.html","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress.component.ts","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress.component.html","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress.module.ts","../../../../../libs/yuuvis/client-framework/upload-progress/src/yuuvis-client-framework-upload-progress.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, computed, inject, input, output } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\nimport { ProgressStatusItem, TranslateService, UploadResult, UploadService } from '@yuuvis/client-core';\n\n@Component({\n selector: 'yuv-upload-progress-overlay',\n standalone: true,\n imports: [CommonModule, MatButtonModule, MatIconModule, MatProgressSpinner],\n templateUrl: './upload-progress-overlay.component.html',\n styleUrl: './upload-progress-overlay.component.scss'\n})\nexport class UploadProgressOverlayComponent {\n #uploadService = inject(UploadService);\n translate = inject(TranslateService);\n\n items = input<ProgressStatusItem[]>();\n _items = computed(() => {\n const items = this.items() || [];\n items.forEach((item) => {\n if (item.err) {\n item.err.message = this.#getErrorMessage(item.err.code);\n }\n });\n return items;\n });\n itemClick = output<UploadResult>();\n\n remove(id?: string) {\n this.#uploadService.cancelItem(id);\n }\n\n #getErrorMessage(status: number): string {\n switch (status) {\n case 403:\n return this.translate.instant('yuv.upload-progress-overlay.error.403');\n default:\n return this.translate.instant('yuv.upload-progress-overlay.error.default');\n }\n }\n}\n","<ul>\n @for (item of _items(); track item.id) {\n @let progress = item.progress | async;\n <li [ngClass]=\"{ err: !!item.err, done: !!item.result }\" [style.--progress]=\"progress + '%'\">\n <button mat-icon-button class=\"remove\" (click)=\"remove(item.id)\">\n <mat-icon [ngClass]=\"{ err: !!item.err }\">close</mat-icon>\n </button>\n\n @if (!item.result) {\n <div class=\"name\">{{ item.filename }}\n @if(item.err) {\n <span class=\"error\">{{item.err.message}}</span>\n }\n </div>\n <div class=\"progress\">\n @if (progress && progress < 100) {\n <div class=\"percentage\">{{ progress }}</div>\n }\n @else if(item.err) {\n <mat-icon class=\"error\">warning</mat-icon>\n }\n @else {\n <mat-progress-spinner mode=\"indeterminate\" class=\"ymt-progress-spinner--tiny\"></mat-progress-spinner>\n }\n </div>\n } @else {\n <div class=\"result-items\">\n @for (res of item.result; track $index) {\n <div class=\"result-item\">\n <div class=\"name\" (click)=\"itemClick.emit(res)\">\n {{ res.label }}\n </div>\n </div>\n }\n </div>\n <mat-icon class=\"done\">check</mat-icon>\n }\n </li>\n }\n</ul>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { TranslatePipe, UploadResult, UploadService } from '@yuuvis/client-core';\nimport { UploadProgressOverlayComponent } from './upload-progress-overlay/upload-progress-overlay.component';\n\n@Component({\n selector: 'yuv-upload-progress',\n standalone: true,\n imports: [CommonModule, MatButtonModule, MatIconModule, TranslatePipe, UploadProgressOverlayComponent],\n templateUrl: './upload-progress.component.html',\n styleUrl: './upload-progress.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.expanded]': 'expanded'\n }\n})\nexport class UploadProgressComponent {\n //#region Dependencies\n\n #uploadService = inject(UploadService);\n\n //#endregion\n\n //#region Angular stuff\n\n expanded = true;\n resultItemClick = output<UploadResult>();\n\n /**\n * Optional list of scope identifiers this component instance should respond to.\n *\n * When provided, the component will display upload progress only for uploads\n * that were initiated with a matching scope via `UploadService.uploadFile()` or\n * `UploadService.multipartUpload()`. This allows multiple `UploadProgressComponent`\n * instances to coexist in different sections of the UI, each showing only the uploads\n * relevant to its own context.\n *\n * If omitted, the component responds to all uploads regardless of scope.\n *\n * @example\n * ```html\n * <!-- Shows only uploads tagged with scope 'mail-editor' or 'attachments-panel' -->\n * <yuv-upload-progress [scopes]=\"['mail-editor', 'attachments-panel']\" />\n *\n * <!-- Shows all uploads (no scope filter) -->\n * <yuv-upload-progress />\n * ```\n */\n scopes = input<string[]>();\n //#endregion\n\n //#region Properties\n\n completedUp$ = this.#uploadService.uploadStatus$;\n\n #status = toSignal(this.#uploadService.status$);\n\n filteredItems = computed(() => {\n const items = this.#status()?.items ?? [];\n const scopes = this.scopes();\n return scopes?.length ? items.filter((item) => item.scope && scopes.includes(item.scope)) : items;\n });\n\n //#endregion\n\n //#region UI Methods\n\n close(): void {\n this.filteredItems().forEach((item) => this.#uploadService.cancelItem(item.id));\n }\n\n //#endregion\n}\n","@let items = filteredItems();\n@if (items.length) {\n @let completed = completedUp$ | async;\n\n <div class=\"upload-progress\">\n <header>\n <h4>\n @if (!completed) {\n {{ 'yuv.upload-progress.header.uploading' | translate: { count: items.length } }}\n } @else {\n {{ 'yuv.upload-progress.header.uploaded' | translate: { count: items.length } }}\n }\n </h4>\n <button mat-icon-button (click)=\"expanded = !expanded\">\n <mat-icon class=\"toggle\">keyboard_arrow_down</mat-icon>\n </button>\n <button mat-icon-button (click)=\"close()\">\n <mat-icon class=\"toggle\">clear</mat-icon>\n </button>\n </header>\n @if (expanded) {\n <yuv-upload-progress-overlay [items]=\"items\" (itemClick)=\"resultItemClick.emit($event)\" />\n }\n </div>\n}\n","import { NgModule } from \"@angular/core\";\nimport { UploadProgressComponent } from \"./upload-progress.component\";\n\n\nconst cmp = [\n UploadProgressComponent\n]\n\n@NgModule({\n imports: [cmp],\n exports: [cmp]\n })\n export class YuvUploadProgressModule {}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2","i3"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"yuuvis-client-framework-upload-progress.mjs","sources":["../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress-overlay/upload-progress-overlay.component.ts","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress-overlay/upload-progress-overlay.component.html","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress.component.ts","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress.component.html","../../../../../libs/yuuvis/client-framework/upload-progress/src/lib/upload-progress/upload-progress.module.ts","../../../../../libs/yuuvis/client-framework/upload-progress/src/yuuvis-client-framework-upload-progress.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { Component, computed, inject, input, output } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\nimport { ProgressStatusItem, TranslateService, UploadResult, UploadService } from '@yuuvis/client-core';\n\n@Component({\n selector: 'yuv-upload-progress-overlay',\n standalone: true,\n imports: [CommonModule, MatButtonModule, MatIconModule, MatProgressSpinner],\n templateUrl: './upload-progress-overlay.component.html',\n styleUrl: './upload-progress-overlay.component.scss'\n})\nexport class UploadProgressOverlayComponent {\n #uploadService = inject(UploadService);\n translate = inject(TranslateService);\n\n items = input<ProgressStatusItem[]>();\n _items = computed(() => {\n const items = this.items() || [];\n items.forEach((item) => {\n if (item.err) {\n item.err.message = this.#getErrorMessage(item.err.code);\n }\n });\n return items;\n });\n itemClick = output<UploadResult>();\n\n remove(id?: string) {\n this.#uploadService.cancelItem(id);\n }\n\n #getErrorMessage(status: number): string {\n switch (status) {\n case 403:\n return this.translate.instant('yuv.upload-progress-overlay.error.403');\n default:\n return this.translate.instant('yuv.upload-progress-overlay.error.default');\n }\n }\n}\n","<ul>\n @for (item of _items(); track item.id) {\n @let progress = item.progress | async;\n <li [ngClass]=\"{ err: !!item.err, done: !!item.result }\" [style.--progress]=\"progress + '%'\">\n <button mat-icon-button class=\"remove\" (click)=\"remove(item.id)\">\n <mat-icon [ngClass]=\"{ err: !!item.err }\">close</mat-icon>\n </button>\n\n @if (!item.result) {\n <div class=\"name\">{{ item.filename }}\n @if(item.err) {\n <span class=\"error\">{{item.err.message}}</span>\n }\n </div>\n <div class=\"progress\">\n @if (progress && progress < 100) {\n <div class=\"percentage\">{{ progress }}</div>\n }\n @else if(item.err) {\n <mat-icon class=\"error\">warning</mat-icon>\n }\n @else {\n <mat-progress-spinner mode=\"indeterminate\" class=\"ymt-progress-spinner--tiny\"></mat-progress-spinner>\n }\n </div>\n } @else {\n <div class=\"result-items\">\n @for (res of item.result; track $index) {\n <div class=\"result-item\">\n <div class=\"name\" (click)=\"itemClick.emit(res)\">\n {{ res.label }}\n </div>\n </div>\n }\n </div>\n <mat-icon class=\"done\">check</mat-icon>\n }\n </li>\n }\n</ul>\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { TranslatePipe, UploadResult, UploadService } from '@yuuvis/client-core';\nimport { UploadProgressOverlayComponent } from './upload-progress-overlay/upload-progress-overlay.component';\n\n@Component({\n selector: 'yuv-upload-progress',\n standalone: true,\n imports: [CommonModule, MatButtonModule, MatIconModule, TranslatePipe, UploadProgressOverlayComponent],\n templateUrl: './upload-progress.component.html',\n styleUrl: './upload-progress.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.expanded]': 'expanded'\n }\n})\nexport class UploadProgressComponent {\n //#region Dependencies\n\n #uploadService = inject(UploadService);\n\n //#endregion\n\n //#region Angular stuff\n\n expanded = true;\n resultItemClick = output<UploadResult>();\n\n /**\n * Optional list of scope identifiers this component instance should respond to.\n *\n * When provided, the component will display upload progress only for uploads\n * that were initiated with a matching scope via `UploadService.uploadFile()` or\n * `UploadService.multipartUpload()`. This allows multiple `UploadProgressComponent`\n * instances to coexist in different sections of the UI, each showing only the uploads\n * relevant to its own context.\n *\n * If omitted, the component responds to all uploads regardless of scope.\n *\n * @example\n * ```html\n * <!-- Shows only uploads tagged with scope 'mail-editor' or 'attachments-panel' -->\n * <yuv-upload-progress [scopes]=\"['mail-editor', 'attachments-panel']\" />\n *\n * <!-- Shows all uploads (no scope filter) -->\n * <yuv-upload-progress />\n * ```\n */\n scopes = input<string[]>();\n //#endregion\n\n //#region Properties\n\n completedUp$ = this.#uploadService.uploadStatus$;\n\n #status = toSignal(this.#uploadService.status$);\n\n filteredItems = computed(() => {\n const items = this.#status()?.items ?? [];\n const scopes = this.scopes();\n return scopes?.length ? items.filter((item) => item.scope && scopes.includes(item.scope)) : items;\n });\n\n //#endregion\n\n //#region UI Methods\n\n close(): void {\n this.filteredItems().forEach((item) => this.#uploadService.cancelItem(item.id));\n }\n\n //#endregion\n}\n","@let items = filteredItems();\n@if (items.length) {\n @let completed = completedUp$ | async;\n\n <div class=\"upload-progress\">\n <header>\n <h4>\n @if (!completed) {\n {{ 'yuv.upload-progress.header.uploading' | translate: { count: items.length } }}\n } @else {\n {{ 'yuv.upload-progress.header.uploaded' | translate: { count: items.length } }}\n }\n </h4>\n <button mat-icon-button (click)=\"expanded = !expanded\">\n <mat-icon class=\"toggle\">keyboard_arrow_down</mat-icon>\n </button>\n <button mat-icon-button (click)=\"close()\">\n <mat-icon class=\"toggle\">clear</mat-icon>\n </button>\n </header>\n @if (expanded) {\n <yuv-upload-progress-overlay [items]=\"items\" (itemClick)=\"resultItemClick.emit($event)\" />\n }\n </div>\n}\n","import { NgModule } from \"@angular/core\";\nimport { UploadProgressComponent } from \"./upload-progress.component\";\n\n\nconst cmp = [\n UploadProgressComponent\n]\n\n@NgModule({\n imports: [cmp],\n exports: [cmp]\n })\n export class YuvUploadProgressModule {}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i2","i3"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable, signal, ChangeDetectionStrategy, Component, makeEnvironmentProviders, provideAppInitializer, NgZone, NgModule } from '@angular/core';
|
|
2
|
+
import { inject, Injectable, signal, ChangeDetectionStrategy, Component, DestroyRef, makeEnvironmentProviders, provideAppInitializer, NgZone, NgModule } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
3
4
|
import { TranslateService } from '@ngx-translate/core';
|
|
4
|
-
import { AppCacheService, BackendService, UserService } from '@yuuvis/client-core';
|
|
5
|
+
import { AppCacheService, BackendService, UserService, EventService, YuvEventType } from '@yuuvis/client-core';
|
|
5
6
|
import { finalize, timer, switchMap, map, debounceTime } from 'rxjs';
|
|
6
|
-
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
7
7
|
import * as i1 from '@angular/material/button';
|
|
8
8
|
import { MatButtonModule } from '@angular/material/button';
|
|
9
9
|
import { MatSnackBar, MatSnackBarRef, MAT_SNACK_BAR_DATA, MatSnackBarLabel, MatSnackBarActions, MatSnackBarAction } from '@angular/material/snack-bar';
|
|
@@ -509,10 +509,10 @@ class HaloFocusService {
|
|
|
509
509
|
this.#stopTracking();
|
|
510
510
|
}
|
|
511
511
|
};
|
|
512
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
513
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
512
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HaloFocusService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
513
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HaloFocusService, providedIn: 'root' }); }
|
|
514
514
|
}
|
|
515
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
515
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HaloFocusService, decorators: [{
|
|
516
516
|
type: Injectable,
|
|
517
517
|
args: [{
|
|
518
518
|
providedIn: 'root'
|
|
@@ -941,10 +941,10 @@ class HaloUtilityService {
|
|
|
941
941
|
haloElement.style.height = `${height}px`;
|
|
942
942
|
haloElement.style.borderRadius = cs.borderRadius || '8px';
|
|
943
943
|
}
|
|
944
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
945
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
944
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HaloUtilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
945
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HaloUtilityService }); }
|
|
946
946
|
}
|
|
947
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
947
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HaloUtilityService, decorators: [{
|
|
948
948
|
type: Injectable
|
|
949
949
|
}] });
|
|
950
950
|
|
|
@@ -997,10 +997,10 @@ class SnackBarService {
|
|
|
997
997
|
panelClass: ['yuv-snack-bar', 'level-' + options.level]
|
|
998
998
|
});
|
|
999
999
|
}
|
|
1000
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1001
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1000
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SnackBarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1001
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SnackBarService, providedIn: 'root' }); }
|
|
1002
1002
|
}
|
|
1003
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1003
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SnackBarService, decorators: [{
|
|
1004
1004
|
type: Injectable,
|
|
1005
1005
|
args: [{
|
|
1006
1006
|
providedIn: 'root'
|
|
@@ -1026,8 +1026,8 @@ class SnackBarComponent {
|
|
|
1026
1026
|
this.#snackBarRef.dismiss();
|
|
1027
1027
|
}
|
|
1028
1028
|
}
|
|
1029
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1030
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1029
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SnackBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1030
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: SnackBarComponent, isStandalone: true, selector: "yuv-snack-bar-component", host: { properties: { "class.info": "level() === 'info'", "class.success": "level() === 'success'", "class.warning": "level() === 'warning'", "class.danger": "level() === 'danger'" } }, ngImport: i0, template: `
|
|
1031
1031
|
@let a = action();
|
|
1032
1032
|
<span
|
|
1033
1033
|
matSnackBarLabel
|
|
@@ -1046,7 +1046,7 @@ class SnackBarComponent {
|
|
|
1046
1046
|
}
|
|
1047
1047
|
`, isInline: true, styles: [":host{display:flex}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatSnackBarLabel, selector: "[matSnackBarLabel]" }, { kind: "directive", type: MatSnackBarActions, selector: "[matSnackBarActions]" }, { kind: "directive", type: MatSnackBarAction, selector: "[matSnackBarAction]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1048
1048
|
}
|
|
1049
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1049
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SnackBarComponent, decorators: [{
|
|
1050
1050
|
type: Component,
|
|
1051
1051
|
args: [{ selector: 'yuv-snack-bar-component', template: `
|
|
1052
1052
|
@let a = action();
|
|
@@ -1156,6 +1156,8 @@ class SessionService {
|
|
|
1156
1156
|
this.#snackBarService = inject(SnackBarService);
|
|
1157
1157
|
this.#backendService = inject(BackendService);
|
|
1158
1158
|
this.#userService = inject(UserService);
|
|
1159
|
+
this.#eventService = inject(EventService);
|
|
1160
|
+
this.#destroyRef = inject(DestroyRef);
|
|
1159
1161
|
this.translate = inject(TranslateService);
|
|
1160
1162
|
//#endregion
|
|
1161
1163
|
//#region Properties
|
|
@@ -1167,6 +1169,7 @@ class SessionService {
|
|
|
1167
1169
|
this.#trackingWindowActivity = false;
|
|
1168
1170
|
this.#userActivityTrackingInitialized = false;
|
|
1169
1171
|
this.#extendingSessionViaBackend = false;
|
|
1172
|
+
this.#isLoggingOut = false;
|
|
1170
1173
|
this.#sessionChannel = new BroadcastChannel('session_channel');
|
|
1171
1174
|
}
|
|
1172
1175
|
//#region Dependencies
|
|
@@ -1188,12 +1191,15 @@ class SessionService {
|
|
|
1188
1191
|
#snackBarService;
|
|
1189
1192
|
#backendService;
|
|
1190
1193
|
#userService;
|
|
1194
|
+
#eventService;
|
|
1195
|
+
#destroyRef;
|
|
1191
1196
|
//#endregion
|
|
1192
1197
|
//#region Properties
|
|
1193
1198
|
#sessionDuration;
|
|
1194
1199
|
#sessionStorageKey;
|
|
1195
1200
|
#activityWindowBeforeEnd;
|
|
1196
1201
|
#popupBeforeEnd;
|
|
1202
|
+
#activityWindowSchedule$;
|
|
1197
1203
|
#activityWindowStart$;
|
|
1198
1204
|
#activityWindowEnd$;
|
|
1199
1205
|
#logoutTimer$;
|
|
@@ -1202,6 +1208,7 @@ class SessionService {
|
|
|
1202
1208
|
#trackingWindowActivity;
|
|
1203
1209
|
#userActivityTrackingInitialized;
|
|
1204
1210
|
#extendingSessionViaBackend;
|
|
1211
|
+
#isLoggingOut;
|
|
1205
1212
|
#sessionChannel;
|
|
1206
1213
|
#snackReference;
|
|
1207
1214
|
//#endregion
|
|
@@ -1221,6 +1228,7 @@ class SessionService {
|
|
|
1221
1228
|
init(sessionDuration) {
|
|
1222
1229
|
this.startSession(sessionDuration ?? sessionDefaultDuration);
|
|
1223
1230
|
this.listenToChannel();
|
|
1231
|
+
this.listenToGlobalLogout();
|
|
1224
1232
|
this.setupHttpDebounce();
|
|
1225
1233
|
this.setupUserActivityTracking();
|
|
1226
1234
|
}
|
|
@@ -1257,35 +1265,43 @@ class SessionService {
|
|
|
1257
1265
|
* @param skipBackendCall When true, skips the whoami backend call (used when already triggered by HTTP activity)
|
|
1258
1266
|
*/
|
|
1259
1267
|
extendSession(broadcast = true, expiresAt, skipBackendCall = false) {
|
|
1268
|
+
if (this.#isLoggingOut)
|
|
1269
|
+
return;
|
|
1260
1270
|
const newExpiresAt = expiresAt ?? Date.now() + this.#sessionDuration;
|
|
1261
1271
|
this.setExpiresAt(newExpiresAt);
|
|
1262
1272
|
this.resetAllTimers();
|
|
1263
|
-
if (
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
this.#extendingSessionViaBackend = false;
|
|
1272
|
-
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
1273
|
-
}, 600);
|
|
1274
|
-
if (broadcast) {
|
|
1275
|
-
this.#sessionChannel.postMessage({
|
|
1276
|
-
type: ChannelMessage.SessionExtended,
|
|
1277
|
-
expiresAt: newExpiresAt
|
|
1278
|
-
});
|
|
1279
|
-
}
|
|
1280
|
-
}))
|
|
1281
|
-
.subscribe();
|
|
1282
|
-
}
|
|
1283
|
-
else if (broadcast) {
|
|
1284
|
-
this.#sessionChannel.postMessage({
|
|
1285
|
-
type: ChannelMessage.SessionExtended,
|
|
1286
|
-
expiresAt: newExpiresAt
|
|
1287
|
-
});
|
|
1273
|
+
if (skipBackendCall) {
|
|
1274
|
+
if (broadcast) {
|
|
1275
|
+
this.#sessionChannel.postMessage({
|
|
1276
|
+
type: ChannelMessage.SessionExtended,
|
|
1277
|
+
expiresAt: newExpiresAt
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
return;
|
|
1288
1281
|
}
|
|
1282
|
+
// The #extendingSessionViaBackend flag is intentionally NOT checked here:
|
|
1283
|
+
// user-initiated extends (popup click, user activity at window end) must always
|
|
1284
|
+
// touch the backend so its session matches the freshly bumped local expiresAt.
|
|
1285
|
+
// The flag's sole purpose is to filter the HTTP debounce subscriber so the
|
|
1286
|
+
// whoami response itself doesn't trigger a recursive extend.
|
|
1287
|
+
this.#extendingSessionViaBackend = true;
|
|
1288
|
+
this.#backendService
|
|
1289
|
+
.get('/idm/whoami')
|
|
1290
|
+
.pipe(finalize(() => {
|
|
1291
|
+
// Keep flag true longer than debounce time to suppress the debounce
|
|
1292
|
+
// emission caused by the whoami response itself.
|
|
1293
|
+
setTimeout(() => {
|
|
1294
|
+
this.#extendingSessionViaBackend = false;
|
|
1295
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
1296
|
+
}, 600);
|
|
1297
|
+
if (broadcast) {
|
|
1298
|
+
this.#sessionChannel.postMessage({
|
|
1299
|
+
type: ChannelMessage.SessionExtended,
|
|
1300
|
+
expiresAt: newExpiresAt
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
}))
|
|
1304
|
+
.subscribe();
|
|
1289
1305
|
}
|
|
1290
1306
|
//#endregion
|
|
1291
1307
|
//#region Core Logic
|
|
@@ -1302,8 +1318,30 @@ class SessionService {
|
|
|
1302
1318
|
}
|
|
1303
1319
|
};
|
|
1304
1320
|
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Listens to the global LOGOUT event emitted by AuthService.
|
|
1323
|
+
*
|
|
1324
|
+
* Covers logout paths that bypass SessionService.performLogout — e.g.,
|
|
1325
|
+
* 401 caught by AuthInterceptor or any manual `AuthService.logout()` call.
|
|
1326
|
+
* Without this, other tabs would not receive a SessionLogout broadcast and
|
|
1327
|
+
* the HTTP activity subscription would briefly stay alive after auth dies.
|
|
1328
|
+
*
|
|
1329
|
+
* Note: UI buttons that call only `UserService.logout()` (e.g. sidebar-nav)
|
|
1330
|
+
* do not emit this event — for those, the system still converges via the
|
|
1331
|
+
* 401 interceptor or local expiry.
|
|
1332
|
+
*/
|
|
1333
|
+
listenToGlobalLogout() {
|
|
1334
|
+
this.#eventService
|
|
1335
|
+
.on(YuvEventType.LOGOUT)
|
|
1336
|
+
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
1337
|
+
.subscribe(() => this.performLogout(true));
|
|
1338
|
+
}
|
|
1305
1339
|
scheduleActivityWindow() {
|
|
1306
|
-
|
|
1340
|
+
// Capture the outer subscription so clearTimers can cancel a pending
|
|
1341
|
+
// async getExpiresAt() resolution. Without this, two extendSession calls
|
|
1342
|
+
// in quick succession could leak the inner timers of the first call when
|
|
1343
|
+
// its getExpiresAt resolves after the second call's clearTimers has run.
|
|
1344
|
+
this.#activityWindowSchedule$ = this.getExpiresAt().subscribe((expiresAt) => {
|
|
1307
1345
|
const activityWindowStartIn = expiresAt - Date.now() - this.#activityWindowBeforeEnd;
|
|
1308
1346
|
const activityWindowEndIn = expiresAt - Date.now() - this.#popupBeforeEnd;
|
|
1309
1347
|
this.#activityWindowStart$ = timer(Math.max(activityWindowStartIn, 0)).subscribe(() => {
|
|
@@ -1347,7 +1385,11 @@ class SessionService {
|
|
|
1347
1385
|
});
|
|
1348
1386
|
}
|
|
1349
1387
|
performLogout(broadcast = true) {
|
|
1388
|
+
if (this.#isLoggingOut)
|
|
1389
|
+
return;
|
|
1390
|
+
this.#isLoggingOut = true;
|
|
1350
1391
|
this.clearTimers();
|
|
1392
|
+
this.#httpActivitySubscription$?.unsubscribe();
|
|
1351
1393
|
this.#snackReference?.dismiss();
|
|
1352
1394
|
if (broadcast) {
|
|
1353
1395
|
this.#sessionChannel.postMessage({
|
|
@@ -1371,11 +1413,14 @@ class SessionService {
|
|
|
1371
1413
|
setupUserActivityTracking() {
|
|
1372
1414
|
if (this.#userActivityTrackingInitialized)
|
|
1373
1415
|
return;
|
|
1374
|
-
|
|
1416
|
+
const handler = () => {
|
|
1375
1417
|
if (this.#trackingWindowActivity) {
|
|
1376
1418
|
this.#activityDetectedInWindow = true;
|
|
1377
1419
|
}
|
|
1378
|
-
}
|
|
1420
|
+
};
|
|
1421
|
+
const events = ['mousemove', 'keydown', 'click', 'scroll'];
|
|
1422
|
+
events.forEach((event) => window.addEventListener(event, handler, { passive: true }));
|
|
1423
|
+
this.#destroyRef.onDestroy(() => events.forEach((event) => window.removeEventListener(event, handler)));
|
|
1379
1424
|
this.#userActivityTrackingInitialized = true;
|
|
1380
1425
|
}
|
|
1381
1426
|
//#endregion
|
|
@@ -1392,15 +1437,15 @@ class SessionService {
|
|
|
1392
1437
|
this.#appCacheService.setItem(this.#sessionStorageKey, expiresAt).subscribe();
|
|
1393
1438
|
}
|
|
1394
1439
|
clearTimers() {
|
|
1440
|
+
this.#activityWindowSchedule$?.unsubscribe();
|
|
1395
1441
|
this.#activityWindowStart$?.unsubscribe();
|
|
1396
1442
|
this.#activityWindowEnd$?.unsubscribe();
|
|
1397
1443
|
this.#logoutTimer$?.unsubscribe();
|
|
1398
|
-
this.#httpActivitySubscription$?.unsubscribe();
|
|
1399
1444
|
}
|
|
1400
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1401
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1445
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1446
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SessionService, providedIn: 'root' }); }
|
|
1402
1447
|
}
|
|
1403
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1448
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SessionService, decorators: [{
|
|
1404
1449
|
type: Injectable,
|
|
1405
1450
|
args: [{ providedIn: 'root' }]
|
|
1406
1451
|
}] });
|
|
@@ -1526,11 +1571,11 @@ function provideSession(sessionDuration) {
|
|
|
1526
1571
|
}
|
|
1527
1572
|
|
|
1528
1573
|
class YuuvisClientFrameworkModule {
|
|
1529
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1530
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.
|
|
1531
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.
|
|
1574
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: YuuvisClientFrameworkModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1575
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.12", ngImport: i0, type: YuuvisClientFrameworkModule, imports: [CommonModule] }); }
|
|
1576
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: YuuvisClientFrameworkModule, imports: [CommonModule] }); }
|
|
1532
1577
|
}
|
|
1533
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1578
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: YuuvisClientFrameworkModule, decorators: [{
|
|
1534
1579
|
type: NgModule,
|
|
1535
1580
|
args: [{
|
|
1536
1581
|
imports: [CommonModule],
|