@yuuvis/client-shell 2.0.2 → 2.0.4

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.
@@ -0,0 +1,83 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, Component } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import * as i1 from '@yuuvis/client-core';
5
+ import { UserService, ConfigService, TranslateService, AppCacheService, TranslateModule } from '@yuuvis/client-core';
6
+ import { DOCUMENT, CommonModule } from '@angular/common';
7
+ import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
8
+ import { ShellService } from '@yuuvis/client-shell-core';
9
+ import { map } from 'rxjs';
10
+ import { MatSelectModule } from '@angular/material/select';
11
+ import { MatButtonToggleGroup, MatButtonToggle } from '@angular/material/button-toggle';
12
+
13
+ class SettingsPageComponent {
14
+ constructor() {
15
+ this.userService = inject(UserService);
16
+ this.config = inject(ConfigService);
17
+ this.translate = inject(TranslateService);
18
+ this.shell = inject(ShellService);
19
+ this.document = inject(DOCUMENT);
20
+ this.#appCache = inject(AppCacheService);
21
+ this.#fb = inject(FormBuilder);
22
+ this.clientLocales = signal([]);
23
+ this.clientVersion = signal(undefined);
24
+ this.user = toSignal(this.userService.user$);
25
+ this.appSettingForms$ = this.shell.appSettings$.pipe(map((settings) => settings.map((e) => {
26
+ const x = {};
27
+ const fcn = e.properties.map((p) => ({
28
+ label: this.translate.instant(p.label) || p.label,
29
+ name: p.name,
30
+ type: p.type
31
+ }));
32
+ e.properties.forEach((p) => {
33
+ x[p.name] = [p.value];
34
+ });
35
+ return {
36
+ appID: e.appID,
37
+ label: e.label,
38
+ formControls: fcn,
39
+ form: this.#fb.group(x)
40
+ };
41
+ })));
42
+ }
43
+ #appCache;
44
+ #fb;
45
+ saveAppSettings(appID, form) {
46
+ this.userService
47
+ .saveUserSettings({
48
+ clientAppSettings: {
49
+ [appID]: form.value
50
+ }
51
+ })
52
+ .subscribe({
53
+ next: () => {
54
+ form.markAsPristine();
55
+ },
56
+ error: (err) => {
57
+ console.error('Error saving app settings', err);
58
+ }
59
+ });
60
+ }
61
+ changeClientLocale(iso) {
62
+ this.userService.changeClientLocale(iso);
63
+ }
64
+ toggleDarkMode() {
65
+ const root = document.getElementsByTagName('body')[0];
66
+ root.classList.toggle('dark');
67
+ }
68
+ ngOnInit() {
69
+ this.clientVersion.set(this.document.body.getAttribute('data-version') ?? 'dev');
70
+ this.clientLocales.set(this.config.getClientLocales());
71
+ }
72
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: SettingsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
73
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: SettingsPageComponent, isStandalone: true, selector: "yuv-settings", ngImport: i0, template: "<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <span class=\"subhead\">{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</span>\n</header>\n\n\n<main>@if (user()) {\n <section class=\"user\">\n <!-- <yuv-user-avatar class=\"background\" [user]=\"user()\"></yuv-user-avatar> -->\n <div class=\"user\">\n <div class=\"meta uname\">{{ user()!.username }}</div>\n <h2>{{ user()!.title }}</h2>\n <div class=\"meta uemail\">{{ user()!.email }}</div>\n <div class=\"meta utenant\">{{ 'yuv.shell.settings.tenant' | translate }}: {{ user()!.tenant }}</div>\n </div>\n </section>\n}\n <!-- language -->\n <section yuvOfflineDisabled>\n <div class=\"label\" translate>yuv.shell.settings.language</div>\n <div class=\"value\">\n <mat-button-toggle-group name=\"language\" [value]=\"translate.currentLang\" (valueChange)=\"changeClientLocale($event)\" [attr.aria-label]=\"'yuv.shell.settings.language' | translate\" >\n @for (locale of clientLocales(); track locale.iso) {\n <mat-button-toggle value=\"{{ locale.iso }}\">{{ locale.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </section>\n\n <!-- app settings -->\n <!-- TODO: activate one feature is refined -->\n <!-- @for (c of appSettingForms$ | async; track $index) {\n <section>\n {{ c.label }}\n <form [formGroup]=\"c.form\" (ngSubmit)=\"saveAppSettings(c.appID, c.form)\">\n @for (n of c.formControls; track $index) {\n <label\n >{{ n.label }}\n\n @switch (n.type) {\n @case ('string') {\n <input type=\"text\" [formControlName]=\"n.name\" />\n }\n @case ('number') {\n <input type=\"number\" [formControlName]=\"n.name\" />\n }\n }\n </label>\n }\n <button [ngClass]=\"{ hideen: c.form.untouched }\" [disabled]=\"c.form.invalid\">Save</button>\n </form>\n </section>\n } -->\n</main>\n", styles: [":host{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto 1fr;grid-template-areas:\"header\" \"settings\";height:100%;overflow:hidden;overflow-y:auto}:host header{grid-area:header;padding:var(--ymt-spacing-3xl)}:host header h1{margin:0}:host header subhead{font:var(--ymt-font-subhead);color:var(--ymt-text-color-subtle)}:host main{grid-area:settings;padding:var(--ymt-spacing-m);overflow-y:auto}:host main section{display:flex;flex-flow:column;padding:var(--ymt-spacing-m)}:host main section .label{margin-block-end:1em}:host main section .value{display:inline-block}:host main section.user h2{margin:0 0 1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "directive", type: i1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }] }); }
74
+ }
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: SettingsPageComponent, decorators: [{
76
+ type: Component,
77
+ args: [{ selector: 'yuv-settings', standalone: true, imports: [CommonModule, TranslateModule,
78
+ MatSelectModule,
79
+ ReactiveFormsModule, MatButtonToggleGroup, MatButtonToggle], template: "<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <span class=\"subhead\">{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</span>\n</header>\n\n\n<main>@if (user()) {\n <section class=\"user\">\n <!-- <yuv-user-avatar class=\"background\" [user]=\"user()\"></yuv-user-avatar> -->\n <div class=\"user\">\n <div class=\"meta uname\">{{ user()!.username }}</div>\n <h2>{{ user()!.title }}</h2>\n <div class=\"meta uemail\">{{ user()!.email }}</div>\n <div class=\"meta utenant\">{{ 'yuv.shell.settings.tenant' | translate }}: {{ user()!.tenant }}</div>\n </div>\n </section>\n}\n <!-- language -->\n <section yuvOfflineDisabled>\n <div class=\"label\" translate>yuv.shell.settings.language</div>\n <div class=\"value\">\n <mat-button-toggle-group name=\"language\" [value]=\"translate.currentLang\" (valueChange)=\"changeClientLocale($event)\" [attr.aria-label]=\"'yuv.shell.settings.language' | translate\" >\n @for (locale of clientLocales(); track locale.iso) {\n <mat-button-toggle value=\"{{ locale.iso }}\">{{ locale.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </section>\n\n <!-- app settings -->\n <!-- TODO: activate one feature is refined -->\n <!-- @for (c of appSettingForms$ | async; track $index) {\n <section>\n {{ c.label }}\n <form [formGroup]=\"c.form\" (ngSubmit)=\"saveAppSettings(c.appID, c.form)\">\n @for (n of c.formControls; track $index) {\n <label\n >{{ n.label }}\n\n @switch (n.type) {\n @case ('string') {\n <input type=\"text\" [formControlName]=\"n.name\" />\n }\n @case ('number') {\n <input type=\"number\" [formControlName]=\"n.name\" />\n }\n }\n </label>\n }\n <button [ngClass]=\"{ hideen: c.form.untouched }\" [disabled]=\"c.form.invalid\">Save</button>\n </form>\n </section>\n } -->\n</main>\n", styles: [":host{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto 1fr;grid-template-areas:\"header\" \"settings\";height:100%;overflow:hidden;overflow-y:auto}:host header{grid-area:header;padding:var(--ymt-spacing-3xl)}:host header h1{margin:0}:host header subhead{font:var(--ymt-font-subhead);color:var(--ymt-text-color-subtle)}:host main{grid-area:settings;padding:var(--ymt-spacing-m);overflow-y:auto}:host main section{display:flex;flex-flow:column;padding:var(--ymt-spacing-m)}:host main section .label{margin-block-end:1em}:host main section .value{display:inline-block}:host main section.user h2{margin:0 0 1rem}\n"] }]
80
+ }] });
81
+
82
+ export { SettingsPageComponent };
83
+ //# sourceMappingURL=yuuvis-client-shell-settings.component-BpcH9FZY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yuuvis-client-shell-settings.component-BpcH9FZY.mjs","sources":["../../../../../libs/yuuvis/client-shell/src/lib/pages/settings/settings.component.ts","../../../../../libs/yuuvis/client-shell/src/lib/pages/settings/settings.component.html"],"sourcesContent":["import { Component, inject, OnInit, Signal, signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { AppCacheService, ConfigService, TranslateModule, TranslateService, UserService, YuvConfigLanguages, YuvUser } from '@yuuvis/client-core';\n\nimport { CommonModule, DOCUMENT } from '@angular/common';\nimport { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { ShellAppSettingProperty, ShellAppSettings, ShellService } from '@yuuvis/client-shell-core';\nimport { map, Observable } from 'rxjs';\nimport {MatSelectModule} from '@angular/material/select';\nimport { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle';\n\n@Component({\n selector: 'yuv-settings',\n standalone: true,\n imports: [CommonModule, TranslateModule,\n MatSelectModule,\n ReactiveFormsModule, MatButtonToggleGroup, MatButtonToggle],\n templateUrl: './settings.component.html',\n styleUrls: ['./settings.component.scss']\n})\nexport class SettingsPageComponent implements OnInit {\n private userService = inject(UserService);\n private config = inject(ConfigService);\n public translate = inject(TranslateService);\n private shell = inject(ShellService);\n readonly document = inject(DOCUMENT);\n #appCache = inject(AppCacheService);\n\n #fb = inject(FormBuilder);\n\n clientLocales = signal<YuvConfigLanguages[]>([]);\n clientVersion = signal<string | undefined>(undefined);\n user: Signal<YuvUser | undefined> = toSignal(this.userService.user$);\n appSettingForms$: Observable<\n {\n appID: string;\n label: string;\n formControls: ShellAppSettingProperty[];\n form: FormGroup;\n }[]\n > = this.shell.appSettings$.pipe(\n map((settings: ShellAppSettings[]) =>\n settings.map((e) => {\n const x: any = {};\n const fcn: ShellAppSettingProperty[] = e.properties.map((p) => ({\n label: this.translate.instant(p.label) || p.label,\n name: p.name,\n type: p.type\n }));\n e.properties.forEach((p) => {\n x[p.name] = [p.value];\n });\n return {\n appID: e.appID,\n label: e.label,\n formControls: fcn,\n form: this.#fb.group(x)\n };\n })\n )\n );\n\n saveAppSettings(appID: string, form: FormGroup) {\n this.userService\n .saveUserSettings({\n clientAppSettings: {\n [appID]: form.value\n }\n })\n .subscribe({\n next: () => {\n form.markAsPristine();\n },\n error: (err) => {\n console.error('Error saving app settings', err);\n }\n });\n }\n\n changeClientLocale(iso: string) {\n this.userService.changeClientLocale(iso);\n }\n\n toggleDarkMode() {\n const root = document.getElementsByTagName('body')[0];\n root.classList.toggle('dark'); \n }\n\n ngOnInit(): void {\n this.clientVersion.set(this.document.body.getAttribute('data-version') ?? 'dev');\n this.clientLocales.set(this.config.getClientLocales());\n }\n}\n","<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <span class=\"subhead\">{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</span>\n</header>\n\n\n<main>@if (user()) {\n <section class=\"user\">\n <!-- <yuv-user-avatar class=\"background\" [user]=\"user()\"></yuv-user-avatar> -->\n <div class=\"user\">\n <div class=\"meta uname\">{{ user()!.username }}</div>\n <h2>{{ user()!.title }}</h2>\n <div class=\"meta uemail\">{{ user()!.email }}</div>\n <div class=\"meta utenant\">{{ 'yuv.shell.settings.tenant' | translate }}: {{ user()!.tenant }}</div>\n </div>\n </section>\n}\n <!-- language -->\n <section yuvOfflineDisabled>\n <div class=\"label\" translate>yuv.shell.settings.language</div>\n <div class=\"value\">\n <mat-button-toggle-group name=\"language\" [value]=\"translate.currentLang\" (valueChange)=\"changeClientLocale($event)\" [attr.aria-label]=\"'yuv.shell.settings.language' | translate\" >\n @for (locale of clientLocales(); track locale.iso) {\n <mat-button-toggle value=\"{{ locale.iso }}\">{{ locale.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </section>\n\n <!-- app settings -->\n <!-- TODO: activate one feature is refined -->\n <!-- @for (c of appSettingForms$ | async; track $index) {\n <section>\n {{ c.label }}\n <form [formGroup]=\"c.form\" (ngSubmit)=\"saveAppSettings(c.appID, c.form)\">\n @for (n of c.formControls; track $index) {\n <label\n >{{ n.label }}\n\n @switch (n.type) {\n @case ('string') {\n <input type=\"text\" [formControlName]=\"n.name\" />\n }\n @case ('number') {\n <input type=\"number\" [formControlName]=\"n.name\" />\n }\n }\n </label>\n }\n <button [ngClass]=\"{ hideen: c.form.untouched }\" [disabled]=\"c.form.invalid\">Save</button>\n </form>\n </section>\n } -->\n</main>\n"],"names":[],"mappings":"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"}
@@ -7,10 +7,10 @@ import * as i3 from '@angular/material/button';
7
7
  import { MatButtonModule, MatIconButton } from '@angular/material/button';
8
8
  import * as i2 from '@angular/material/icon';
9
9
  import { MatIconModule, MatIconRegistry, MatIcon } from '@angular/material/icon';
10
- import * as i2$2 from '@angular/router';
10
+ import * as i2$1 from '@angular/router';
11
11
  import { Router, NavigationEnd, RouterModule } from '@angular/router';
12
12
  import { SwPush } from '@angular/service-worker';
13
- import * as i2$1 from '@yuuvis/client-core';
13
+ import * as i1$1 from '@yuuvis/client-core';
14
14
  import { Utils, LocaleDatePipe, TranslateModule, AuthService, UserService, TranslateService, DeviceService, SafeHtmlPipe, UserRoles, DmsService, SystemType } from '@yuuvis/client-core';
15
15
  import { ShellNotificationsService, ShellService, CommandPaletteService } from '@yuuvis/client-shell-core';
16
16
  import { of, switchMap as switchMap$1, tap as tap$1 } from 'rxjs';
@@ -22,7 +22,7 @@ import * as i4 from '@yuuvis/client-framework/list';
22
22
  import { YuvListModule, ListItemDirective } from '@yuuvis/client-framework/list';
23
23
  import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
24
24
  import { MatListModule } from '@angular/material/list';
25
- import * as i1$1 from '@angular/material/sidenav';
25
+ import * as i1$2 from '@angular/material/sidenav';
26
26
  import { MatSidenavModule } from '@angular/material/sidenav';
27
27
  import { MatToolbarModule } from '@angular/material/toolbar';
28
28
  import * as i3$1 from '@yuuvis/client-framework/metadata-form-defaults';
@@ -114,7 +114,7 @@ class NotificationsPageComponent {
114
114
  });
115
115
  }
116
116
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: NotificationsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
117
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: NotificationsPageComponent, isStandalone: true, selector: "yuv-notifications", host: { listeners: { "keydown": "onKeydown($event)" } }, ngImport: i0, template: "<div class=\"notifications\" (yuvLightDismiss)=\"close()\" cdkTrapFocus>\n <h2>{{ 'yuv.shell.notifications.title' | translate }}</h2>\n\n @if (notifications()?.length) {\n <yuv-list (itemSelect)=\"itemSelected($event)\" (itemFocus)=\"itemFocused($event)\">\n @for (n of notifications(); track n.id) {\n <div class=\"note {{ n.level }}\" [ngClass]=\"{ withRoute: n.targetRoute }\" yuvListItem>\n <div class=\"icon\"><yuv-icon [svg]=\"n.icon || icons.note\"></yuv-icon></div>\n <div class=\"received\">{{ n.timestamp | localeDate }}</div>\n <div class=\"title\">{{ n.title }}</div>\n <div class=\"description\">{{ n.description }}</div>\n <div class=\"meta\"></div>\n\n <div class=\"actions\">\n <button mat-icon-button (click)=\"remove(n.id)\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n }\n </yuv-list>\n\n <div class=\"actions\">\n <button mat-icon-button [hidden]=\"!notifications()?.length\" class=\"icon secondary\" (click)=\"removeAll()\">\n {{ 'yuv.shell.notifications.button.remove.all' | translate }}<mat-icon>delete</mat-icon>\n </button>\n </div>\n } @else {\n <div class=\"empty\">\n <p>{{ 'yuv.shell.notifications.empty' | translate }}</p>\n </div>\n }\n\n <button mat-icon-button class=\"icon close\" (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n", styles: [":host{height:100%;display:flex}:host .notifications{background-color:var(--ymt-surface-panel);border-inline-end:1px solid var(--ymt-outline-variant);height:100%;overflow:hidden;box-sizing:border-box;padding:var(--ymt-spacing-m);display:grid;grid-template-rows:auto auto 1fr;grid-template-columns:1fr auto;grid-template-areas:\"title close\" \"actions actions\" \"list list\";gap:var(--ymt-spacing-m);max-width:30vw;min-width:300px;box-shadow:8px 0 8px #0000001a;animation:dialogAppear .2s ease-in-out}:host .notifications h2{color:var(--ymt-text-color-subtle);grid-area:title;margin:0;padding:0;align-self:center;text-overflow:ellipsis;overflow:hidden}:host .notifications .actions{grid-area:actions;display:flex;justify-content:end;--icon-size: 18px}:host .notifications .actions button{border-radius:.4em}:host .notifications .close{grid-area:close;--icon-size: 18px}:host .notifications yuv-list,:host .notifications .empty{grid-area:list}:host .notifications .empty{display:grid;align-items:center;justify-content:center;color:var(--ymt-text-color-subtle)}:host .notifications .note{--level-color: transparent;display:grid;grid-template-rows:auto auto auto auto;grid-template-columns:auto 1fr auto;grid-template-areas:\"icon received actions\" \"icon title title\" \"icon description description\" \"icon meta meta\";row-gap:var(--ymt-spacing-2xs);column-gap:var(--ymt-spacing-xs);align-items:center;padding:var(--ymt-spacing-xs);padding-inline-start:var(--ymt-spacing-m);margin-block-end:var(--ymt-spacing-xs);background-color:var(--ymt-surface-panel);outline:1px solid var(--ymt-outline-variant);outline-offset:-1px;position:relative;cursor:default}:host .notifications .note.withRoute{cursor:pointer}:host .notifications .note:before{content:\"\";width:4px;position:absolute;left:2px;top:2px;bottom:2px;border-radius:2px;background-color:var(--level-color)}:host .notifications .note.alert{--level-color: var(--ymt-danger)}:host .notifications .note.warning{--level-color: var(--ymt-warning)}:host .notifications .note.success{--level-color: var(--ymt-success)}:host .notifications .note:hover,:host .notifications .note[aria-current=true]{background-color:var(--ymt-focus-background)}:host .notifications .note:hover button,:host .notifications .note[aria-current=true] button{opacity:1}:host .notifications .note .icon{grid-area:icon;color:var(--ymt-text-color-subtle)}:host .notifications .note .title{overflow:hidden;text-overflow:ellipsis;font-weight:700;grid-area:title;color:var(--ymt-text-color)}:host .notifications .note .description{grid-area:description;overflow:hidden;text-overflow:ellipsis}:host .notifications .note .meta{grid-area:meta}:host .notifications .note .received{grid-area:received;color:var(--ymt-text-color-subtle)}:host .notifications .note button{grid-area:actions;padding:0;opacity:0}@keyframes dialogAppear{0%{opacity:0;transform:translate(calc(var(--ymt-spacing-m) * -1))}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: LightDismissDirective, selector: "[yuvLightDismiss]", outputs: ["yuvLightDismiss"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "pipe", type: LocaleDatePipe, name: "localeDate" }, { kind: "component", type: YuvIconComponent, selector: "yuv-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i4.ListComponent, selector: "yuv-list", inputs: ["multiselect", "selfHandleSelection", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: i4.ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }] }); }
117
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: NotificationsPageComponent, isStandalone: true, selector: "yuv-notifications", host: { listeners: { "keydown": "onKeydown($event)" } }, ngImport: i0, template: "<div class=\"notifications\" (yuvLightDismiss)=\"close()\" cdkTrapFocus>\n <h2>{{ 'yuv.shell.notifications.title' | translate }}</h2>\n\n @if (notifications()?.length) {\n <yuv-list (itemSelect)=\"itemSelected($event)\" (itemFocus)=\"itemFocused($event)\">\n @for (n of notifications(); track n.id) {\n <div class=\"note {{ n.level }}\" [ngClass]=\"{ withRoute: n.targetRoute }\" yuvListItem>\n <div class=\"icon\"><yuv-icon [svg]=\"n.icon || icons.note\"></yuv-icon></div>\n <div class=\"received\">{{ n.timestamp | localeDate }}</div>\n <div class=\"title\">{{ n.title }}</div>\n <div class=\"description\">{{ n.description }}</div>\n <div class=\"meta\"></div>\n\n <div class=\"actions\">\n <button mat-icon-button (click)=\"remove(n.id)\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n }\n </yuv-list>\n\n <div class=\"actions\">\n <button mat-icon-button [hidden]=\"!notifications()?.length\" class=\"icon secondary\" (click)=\"removeAll()\">\n {{ 'yuv.shell.notifications.button.remove.all' | translate }}<mat-icon>delete</mat-icon>\n </button>\n </div>\n } @else {\n <div class=\"empty\">\n <p>{{ 'yuv.shell.notifications.empty' | translate }}</p>\n </div>\n }\n\n <button mat-icon-button class=\"icon close\" (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n", styles: [":host{height:100%;display:flex}:host .notifications{background-color:var(--ymt-surface-panel);border-inline-end:1px solid var(--ymt-outline-variant);height:100%;overflow:hidden;box-sizing:border-box;padding:var(--ymt-spacing-m);display:grid;grid-template-rows:auto auto 1fr;grid-template-columns:1fr auto;grid-template-areas:\"title close\" \"actions actions\" \"list list\";gap:var(--ymt-spacing-m);max-width:30vw;min-width:300px;box-shadow:8px 0 8px #0000001a;animation:dialogAppear .2s ease-in-out}:host .notifications h2{color:var(--ymt-text-color-subtle);grid-area:title;margin:0;padding:0;align-self:center;text-overflow:ellipsis;overflow:hidden}:host .notifications .actions{grid-area:actions;display:flex;justify-content:end;--icon-size: 18px}:host .notifications .actions button{border-radius:.4em}:host .notifications .close{grid-area:close;--icon-size: 18px}:host .notifications yuv-list,:host .notifications .empty{grid-area:list}:host .notifications .empty{display:grid;align-items:center;justify-content:center;color:var(--ymt-text-color-subtle)}:host .notifications .note{--level-color: transparent;display:grid;grid-template-rows:auto auto auto auto;grid-template-columns:auto 1fr auto;grid-template-areas:\"icon received actions\" \"icon title title\" \"icon description description\" \"icon meta meta\";row-gap:var(--ymt-spacing-2xs);column-gap:var(--ymt-spacing-xs);align-items:center;padding:var(--ymt-spacing-xs);padding-inline-start:var(--ymt-spacing-m);margin-block-end:var(--ymt-spacing-xs);background-color:var(--ymt-surface-panel);outline:1px solid var(--ymt-outline-variant);outline-offset:-1px;position:relative;cursor:default}:host .notifications .note.withRoute{cursor:pointer}:host .notifications .note:before{content:\"\";width:4px;position:absolute;left:2px;top:2px;bottom:2px;border-radius:2px;background-color:var(--level-color)}:host .notifications .note.alert{--level-color: var(--ymt-danger)}:host .notifications .note.warning{--level-color: var(--ymt-warning)}:host .notifications .note.success{--level-color: var(--ymt-success)}:host .notifications .note:hover,:host .notifications .note[aria-current=true]{background-color:var(--ymt-focus-background)}:host .notifications .note:hover button,:host .notifications .note[aria-current=true] button{opacity:1}:host .notifications .note .icon{grid-area:icon;color:var(--ymt-text-color-subtle)}:host .notifications .note .title{overflow:hidden;text-overflow:ellipsis;font-weight:700;grid-area:title;color:var(--ymt-text-color)}:host .notifications .note .description{grid-area:description;overflow:hidden;text-overflow:ellipsis}:host .notifications .note .meta{grid-area:meta}:host .notifications .note .received{grid-area:received;color:var(--ymt-text-color-subtle)}:host .notifications .note button{grid-area:actions;padding:0;opacity:0}@keyframes dialogAppear{0%{opacity:0;transform:translate(calc(var(--ymt-spacing-m) * -1))}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: LightDismissDirective, selector: "[yuvLightDismiss]", outputs: ["yuvLightDismiss"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "pipe", type: LocaleDatePipe, name: "localeDate" }, { kind: "component", type: YuvIconComponent, selector: "yuv-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i4.ListComponent, selector: "yuv-list", inputs: ["multiselect", "selfHandleSelection", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: i4.ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] }); }
118
118
  }
119
119
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: NotificationsPageComponent, decorators: [{
120
120
  type: Component,
@@ -137,7 +137,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImpo
137
137
  const clientShellRoutes = [
138
138
  { path: 'dashboard', loadComponent: () => import('./yuuvis-client-shell-dashboard.component-akNayAfe.mjs').then((comp) => comp.DashboardPageComponent) },
139
139
  { path: 'notifications', component: NotificationsPageComponent, outlet: 'aside' },
140
- { path: 'settings', loadComponent: () => import('./yuuvis-client-shell-settings.component-C_TUScRF.mjs').then((comp) => comp.SettingsPageComponent) },
140
+ { path: 'settings', loadComponent: () => import('./yuuvis-client-shell-settings.component-BpcH9FZY.mjs').then((comp) => comp.SettingsPageComponent) },
141
141
  {
142
142
  path: 'web-share-target',
143
143
  loadComponent: () => import('./yuuvis-client-shell-web-share-target.component-gkFyLIOi.mjs').then((comp) => comp.WebShareTargetPageComponent)
@@ -154,7 +154,7 @@ class SidebarNavComponent {
154
154
  this.isHandset$ = this.breakpointObserver.observe(Breakpoints.Handset).pipe(map((result) => result.matches), shareReplay());
155
155
  }
156
156
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: SidebarNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
157
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.12", type: SidebarNavComponent, isStandalone: true, selector: "yuv-sidebar-nav", ngImport: i0, template: "<mat-sidenav-container class=\"sidenav-container\">\n <mat-sidenav class=\"sidenav\"\n attr.role=\"navigation\"\n mode=\"side\"\n opened>\n <div class=\"sidenav-content\">\n <div class=\"app-logo\">\n <ng-content select=\".shell-nav__shell-logo-button\"></ng-content>\n </div>\n <div class=\"nav-list\">\n <ng-content select=\".shell-nav__nav-list\"></ng-content>\n </div>\n <div class=\"actions\">\n <ng-content select=\".shell-nav__actions\"></ng-content>\n </div>\n </div>\n </mat-sidenav>\n <mat-sidenav-content></mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{--mat-sidenav-container-shape: none}:host{--mat-sidenav-container-width: calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host{--mat-sidenav-container-divider-color: var(--ymt-outline-variant)}:host{--mat-sidenav-container-background-color: transparent}:host{--mat-sidenav-content-background-color: transparent}:host{--mat-sidenav-container-text-color: var(--ymt-on-surface)}.sidenav-container{height:100%;width:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}.sidenav-container .sidenav .sidenav-content{height:100%;display:flex;flex-flow:column nowrap;justify-content:flex-start;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .app-logo{height:30px;width:100%;flex:0 0 auto;background-color:var(--ymt-brand);margin-bottom:8px}.sidenav-container .sidenav .sidenav-content .nav-list{flex:1 0 auto;display:flex;flex-flow:column nowrap;align-items:center;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .actions{flex:0 0 auto;display:flex;flex-flow:column nowrap;align-items:center;margin-bottom:8px;gap:var(--ymt-spacing-2xs)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container{width:100%;height:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav{width:100%;border:none;border-top:1px solid var(--ymt-outline-variant)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content{flex-flow:row nowrap;height:calc(calc(24px + var(--ymt-spacing-s) + 1px + 16px) - 1px);margin-block-start:0;overflow-y:hidden}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .app-logo{height:100%;width:auto;aspect-ratio:1/1;margin-bottom:0;margin-right:8px}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .nav-list{flex-flow:row nowrap;height:auto}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .actions{flex-flow:row nowrap;margin-bottom:0;margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$1.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1$1.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1$1.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatIconModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
157
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.12", type: SidebarNavComponent, isStandalone: true, selector: "yuv-sidebar-nav", ngImport: i0, template: "<mat-sidenav-container class=\"sidenav-container\">\n <mat-sidenav class=\"sidenav\"\n attr.role=\"navigation\"\n mode=\"side\"\n opened>\n <div class=\"sidenav-content\">\n <div class=\"app-logo\">\n <ng-content select=\".shell-nav__shell-logo-button\"></ng-content>\n </div>\n <div class=\"nav-list\">\n <ng-content select=\".shell-nav__nav-list\"></ng-content>\n </div>\n <div class=\"actions\">\n <ng-content select=\".shell-nav__actions\"></ng-content>\n </div>\n </div>\n </mat-sidenav>\n <mat-sidenav-content></mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host{--mat-sidenav-container-shape: none}:host{--mat-sidenav-container-width: calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host{--mat-sidenav-container-divider-color: var(--ymt-outline-variant)}:host{--mat-sidenav-container-background-color: transparent}:host{--mat-sidenav-content-background-color: transparent}:host{--mat-sidenav-container-text-color: var(--ymt-on-surface)}.sidenav-container{height:100%;width:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}.sidenav-container .sidenav .sidenav-content{height:100%;display:flex;flex-flow:column nowrap;justify-content:flex-start;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .app-logo{height:30px;width:100%;flex:0 0 auto;background-color:var(--ymt-brand);margin-bottom:8px}.sidenav-container .sidenav .sidenav-content .nav-list{flex:1 0 auto;display:flex;flex-flow:column nowrap;align-items:center;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .actions{flex:0 0 auto;display:flex;flex-flow:column nowrap;align-items:center;margin-bottom:8px;gap:var(--ymt-spacing-2xs)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container{width:100%;height:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav{width:100%;border:none;border-top:1px solid var(--ymt-outline-variant)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content{flex-flow:row nowrap;height:calc(calc(24px + var(--ymt-spacing-s) + 1px + 16px) - 1px);margin-block-start:0;overflow-y:hidden}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .app-logo{height:100%;width:auto;aspect-ratio:1/1;margin-bottom:0;margin-right:8px}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .nav-list{flex-flow:row nowrap;height:auto}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .actions{flex-flow:row nowrap;margin-bottom:0;margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$2.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1$2.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1$2.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatListModule }, { kind: "ngmodule", type: MatIconModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
158
158
  }
159
159
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: SidebarNavComponent, decorators: [{
160
160
  type: Component,
@@ -342,7 +342,7 @@ class ClientShellComponent {
342
342
  this.requestSubscription();
343
343
  }
344
344
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: ClientShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
345
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: ClientShellComponent, isStandalone: true, selector: "yuv-client-shell", inputs: { apps: { classPropertyName: "apps", publicName: "apps", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:focusin": "onFocusChange($event)", "dragover": "onDragOver($event)" } }, providers: [SafeHtmlPipe], ngImport: i0, template: "<yuv-metadata-default-templates></yuv-metadata-default-templates>\n\n<!-- gloabl busy indicator -->\n@if (busy$ | async) {\n <mat-progress-bar\n mode=\"indeterminate\"\n class=\"progress-bar\"\n ></mat-progress-bar>\n}\n\n@let iconsRegistered = registerIcons();\n\n<yuv-sidebar-nav class=\"shell-nav\">\n <button class=\"shell-nav__shell-logo-button\" routerLink=\"/\" routerLinkActive=\"active\" [attr.aria-label]=\"'yuv.shell.logo.aria.label' | translate\">\n @if (iconsRegistered) {\n <mat-icon svgIcon=\"shellIcons:app_logo\"></mat-icon>\n }\n </button>\n <ul class=\"shell-nav__nav-list\">\n @for (a of apps(); track a.path) {\n <li class=\"shell-nav__nav-list-item\">\n <button class=\"shell-nav__nav-list-item-button\" mat-icon-button routerLinkActive=\"active\" [routerLink]=\"a.path\" \n matTooltipPosition=\"after\"\n [matTooltip]=\"getAppTitle(a)\">\n @if (a.svgIcon) {\n @if (iconsRegistered) {\n <mat-icon [svgIcon]=\"'shellIcons:' + a.iconName\"></mat-icon>\n }\n } @else {\n <mat-icon>{{ a.iconName }}</mat-icon>\n }\n <!--@if (getNotifications(a.id)) {\n <div [ngClass]=\"'badge ' + getNotifications(a.id).maxLevel\">{{ getNotifications(a.id).count }}</div>\n }-->\n </button>\n </li>\n }\n </ul>\n <section class=\"shell-nav__actions\">\n @if (showNotifications()) {\n <button\n class=\"shell-nav__actions-button\"\n mat-icon-button\n [routerLink]=\"[{ outlets: { aside: 'notifications' } }]\"\n routerLinkActive=\"active\"\n matTooltipPosition=\"after\"\n [matTooltip]=\"'yuv.shell.notifications.title' | translate\"\n >\n <mat-icon>notifications</mat-icon>\n @if (newNotifications(); as note) {\n <div class=\"badge {{ note.maxLevel }}\">{{ note.count }}</div>\n }\n </button>\n }\n <button\n class=\"shell-nav__actions-button\"\n mat-icon-button\n [routerLink]=\"['/settings']\"\n routerLinkActive=\"active\"\n [matTooltip]=\"'yuv.shell.settings.title' | translate\"\n >\n <mat-icon>settings</mat-icon>\n </button>\n <button class=\"shell-nav__actions-button\" mat-icon-button (click)=\"appLogout()\" [matTooltip]=\"'yuv.shell.cmd.logout' | translate\">\n <mat-icon>power_settings_new</mat-icon>\n </button>\n </section>\n</yuv-sidebar-nav>\n\n<main id=\"main-shell_content\" aria-label=\"main shell content\" [inert]=\"asideOutlet.isActivated\">\n <router-outlet></router-outlet>\n</main>\n\n<!-- outlet for aside modals like notifications -->\n<div class=\"asideOutlet\" [hidden]=\"!asideOutlet.isActivated\">\n <router-outlet name=\"aside\" #asideOutlet=\"outlet\"></router-outlet>\n</div>\n\n<div id=\"fi\" inert></div>\n", styles: [":host{--mat-sidenav-container-shape: none}:host{--mat-sidenav-container-width: calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host{--mat-sidenav-container-divider-color: var(--ymt-outline-variant)}:host{--mat-sidenav-container-background-color: transparent}:host{--mat-sidenav-content-background-color: transparent}:host{--mat-sidenav-container-text-color: var(--ymt-on-surface)}.sidenav-container{height:100%;width:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}.sidenav-container .sidenav .sidenav-content{height:100%;display:flex;flex-flow:column nowrap;justify-content:flex-start;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .app-logo{height:30px;width:100%;flex:0 0 auto;background-color:var(--ymt-brand);margin-bottom:8px}.sidenav-container .sidenav .sidenav-content .nav-list{flex:1 0 auto;display:flex;flex-flow:column nowrap;align-items:center;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .actions{flex:0 0 auto;display:flex;flex-flow:column nowrap;align-items:center;margin-bottom:8px;gap:var(--ymt-spacing-2xs)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container{width:100%;height:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav{width:100%;border:none;border-top:1px solid var(--ymt-outline-variant)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content{flex-flow:row nowrap;height:calc(calc(24px + var(--ymt-spacing-s) + 1px + 16px) - 1px);margin-block-start:0;overflow-y:hidden}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .app-logo{height:100%;width:auto;aspect-ratio:1/1;margin-bottom:0;margin-right:8px}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .nav-list{flex-flow:row nowrap;height:auto}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .actions{flex-flow:row nowrap;margin-bottom:0;margin-right:8px}:host{position:absolute;inset:0;overflow:hidden;display:flex;background-color:var(--ymt-surface-frame)}:host .progress-bar{position:absolute}:host .shell-nav{flex:0 0 auto}:host .shell-nav__nav-list{display:contents;list-style:none}:host .shell-nav__nav-list-item{display:inline-block}:host .shell-nav__shell-logo-button{-webkit-user-select:none;user-select:none;display:block;position:relative;box-sizing:border-box;border:none;outline:none;cursor:pointer;height:100%;width:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);padding:0;padding-block:0;background:none}:host .shell-nav__shell-logo-button mat-icon{width:100%;height:100%}:host .shell-nav__actions{display:contents}:host main{flex:1;color:var(--ymt-text-color)}:host .asideOutlet{position:absolute;inset:0;padding-inline-start:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host-context([data-screen-size=s][data-screen-orientation=portrait]){flex-flow:column-reverse}:host-context([data-screen-size=s][data-screen-orientation=portrait]) main{overflow:hidden}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .asideOutlet{padding-inline-start:0}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2$2.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i2$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2$2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: YuvMetadataFormDefaultsModule }, { kind: "component", type: i3$1.MetadataDefaultTemplatesComponent, selector: "yuv-metadata-default-templates" }, { kind: "component", type: SidebarNavComponent, selector: "yuv-sidebar-nav" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
345
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: ClientShellComponent, isStandalone: true, selector: "yuv-client-shell", inputs: { apps: { classPropertyName: "apps", publicName: "apps", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:focusin": "onFocusChange($event)", "dragover": "onDragOver($event)" } }, providers: [SafeHtmlPipe], ngImport: i0, template: "<yuv-metadata-default-templates></yuv-metadata-default-templates>\n\n<!-- gloabl busy indicator -->\n@if (busy$ | async) {\n <mat-progress-bar\n mode=\"indeterminate\"\n class=\"progress-bar\"\n ></mat-progress-bar>\n}\n\n@let iconsRegistered = registerIcons();\n\n<yuv-sidebar-nav class=\"shell-nav\">\n <button class=\"shell-nav__shell-logo-button\" routerLink=\"/\" routerLinkActive=\"active\" [attr.aria-label]=\"'yuv.shell.logo.aria.label' | translate\">\n @if (iconsRegistered) {\n <mat-icon svgIcon=\"shellIcons:app_logo\"></mat-icon>\n }\n </button>\n <ul class=\"shell-nav__nav-list\">\n @for (a of apps(); track a.path) {\n <li class=\"shell-nav__nav-list-item\">\n <button class=\"shell-nav__nav-list-item-button\" mat-icon-button routerLinkActive=\"active\" [routerLink]=\"a.path\" \n matTooltipPosition=\"after\"\n [matTooltip]=\"getAppTitle(a)\">\n @if (a.svgIcon) {\n @if (iconsRegistered) {\n <mat-icon [svgIcon]=\"'shellIcons:' + a.iconName\"></mat-icon>\n }\n } @else {\n <mat-icon>{{ a.iconName }}</mat-icon>\n }\n <!--@if (getNotifications(a.id)) {\n <div [ngClass]=\"'badge ' + getNotifications(a.id).maxLevel\">{{ getNotifications(a.id).count }}</div>\n }-->\n </button>\n </li>\n }\n </ul>\n <section class=\"shell-nav__actions\">\n @if (showNotifications()) {\n <button\n class=\"shell-nav__actions-button\"\n mat-icon-button\n [routerLink]=\"[{ outlets: { aside: 'notifications' } }]\"\n routerLinkActive=\"active\"\n matTooltipPosition=\"after\"\n [matTooltip]=\"'yuv.shell.notifications.title' | translate\"\n >\n <mat-icon>notifications</mat-icon>\n @if (newNotifications(); as note) {\n <div class=\"badge {{ note.maxLevel }}\">{{ note.count }}</div>\n }\n </button>\n }\n <button\n class=\"shell-nav__actions-button\"\n mat-icon-button\n [routerLink]=\"['/settings']\"\n routerLinkActive=\"active\"\n [matTooltip]=\"'yuv.shell.settings.title' | translate\"\n >\n <mat-icon>settings</mat-icon>\n </button>\n <button class=\"shell-nav__actions-button\" mat-icon-button (click)=\"appLogout()\" [matTooltip]=\"'yuv.shell.cmd.logout' | translate\">\n <mat-icon>power_settings_new</mat-icon>\n </button>\n </section>\n</yuv-sidebar-nav>\n\n<main id=\"main-shell_content\" aria-label=\"main shell content\" [inert]=\"asideOutlet.isActivated\">\n <router-outlet></router-outlet>\n</main>\n\n<!-- outlet for aside modals like notifications -->\n<div class=\"asideOutlet\" [hidden]=\"!asideOutlet.isActivated\">\n <router-outlet name=\"aside\" #asideOutlet=\"outlet\"></router-outlet>\n</div>\n\n<div id=\"fi\" inert></div>\n", styles: [":host{--mat-sidenav-container-shape: none}:host{--mat-sidenav-container-width: calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host{--mat-sidenav-container-divider-color: var(--ymt-outline-variant)}:host{--mat-sidenav-container-background-color: transparent}:host{--mat-sidenav-content-background-color: transparent}:host{--mat-sidenav-container-text-color: var(--ymt-on-surface)}.sidenav-container{height:100%;width:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}.sidenav-container .sidenav .sidenav-content{height:100%;display:flex;flex-flow:column nowrap;justify-content:flex-start;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .app-logo{height:30px;width:100%;flex:0 0 auto;background-color:var(--ymt-brand);margin-bottom:8px}.sidenav-container .sidenav .sidenav-content .nav-list{flex:1 0 auto;display:flex;flex-flow:column nowrap;align-items:center;gap:var(--ymt-spacing-2xs)}.sidenav-container .sidenav .sidenav-content .actions{flex:0 0 auto;display:flex;flex-flow:column nowrap;align-items:center;margin-bottom:8px;gap:var(--ymt-spacing-2xs)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container{width:100%;height:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav{width:100%;border:none;border-top:1px solid var(--ymt-outline-variant)}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content{flex-flow:row nowrap;height:calc(calc(24px + var(--ymt-spacing-s) + 1px + 16px) - 1px);margin-block-start:0;overflow-y:hidden}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .app-logo{height:100%;width:auto;aspect-ratio:1/1;margin-bottom:0;margin-right:8px}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .nav-list{flex-flow:row nowrap;height:auto}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .sidenav-container .sidenav .sidenav-content .actions{flex-flow:row nowrap;margin-bottom:0;margin-right:8px}:host{position:absolute;inset:0;overflow:hidden;display:flex;background-color:var(--ymt-surface-frame)}:host .progress-bar{position:absolute}:host .shell-nav{flex:0 0 auto}:host .shell-nav__nav-list{display:contents;list-style:none}:host .shell-nav__nav-list-item{display:inline-block}:host .shell-nav__shell-logo-button{-webkit-user-select:none;user-select:none;display:block;position:relative;box-sizing:border-box;border:none;outline:none;cursor:pointer;height:100%;width:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);padding:0;padding-block:0;background:none}:host .shell-nav__shell-logo-button mat-icon{width:100%;height:100%}:host .shell-nav__actions{display:contents}:host main{flex:1;color:var(--ymt-text-color)}:host .asideOutlet{position:absolute;inset:0;padding-inline-start:calc(24px + var(--ymt-spacing-s) + 1px + 16px)}:host-context([data-screen-size=s][data-screen-orientation=portrait]){flex-flow:column-reverse}:host-context([data-screen-size=s][data-screen-orientation=portrait]) main{overflow:hidden}:host-context([data-screen-size=s][data-screen-orientation=portrait]) .asideOutlet{padding-inline-start:0}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2$1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i2$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2$1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: YuvMetadataFormDefaultsModule }, { kind: "component", type: i3$1.MetadataDefaultTemplatesComponent, selector: "yuv-metadata-default-templates" }, { kind: "component", type: SidebarNavComponent, selector: "yuv-sidebar-nav" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
346
346
  }
347
347
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: ClientShellComponent, decorators: [{
348
348
  type: Component,
@@ -431,7 +431,7 @@ class ManageFlavorsComponent {
431
431
  this.#refreshDmsObject();
432
432
  }
433
433
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: ManageFlavorsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
434
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: ManageFlavorsComponent, isStandalone: true, selector: "yuv-manage-flavors", ngImport: i0, template: "<yuv-dialog [headertitel]=\"'yuv.shell.action.manage-flavors.title' | translate\">\n <main [yuvBusyOverlay]=\"busy()\">\n <p>{{ 'yuv.shell.action.manage-flavors.text' | translate }}</p>\n @if (appliedFlavors.length) {\n <h3>{{ 'yuv.shell.action.manage-flavors.applied.headline' | translate }}</h3>\n <ul>\n @for (f of appliedFlavors; track $index) {\n <li>\n <yuv-flavor-chip [flavor]=\"f\" yuvListItem></yuv-flavor-chip>\n <button mat-icon-button [matTooltip]=\"'yuv.shell.action.manage-flavors.applicable.button.remove.tooltip' | translate\" (click)=\"removeFlavor(f)\">\n <mat-icon>delete_forever</mat-icon>\n </button>\n </li>\n }\n </ul>\n }\n @if (applicableFlavors.length) {\n <h3>{{ 'yuv.shell.action.manage-flavors.applicable.headline' | translate }}</h3>\n <ul>\n @for (f of applicableFlavors; track $index) {\n <li>\n <yuv-flavor-chip [flavor]=\"f\" yuvListItem></yuv-flavor-chip>\n <button mat-icon-button [matTooltip]=\"'yuv.shell.action.manage-flavors.applied.button.apply.tooltip' | translate\" (click)=\"applyFlavor(f)\">\n <mat-icon>add</mat-icon>\n </button>\n </li>\n }\n </ul>\n }\n </main>\n <footer>\n <button ymtButton=\"secondary\" (click)=\"cancel()\">{{ 'yuv.shell.action.manage-flavors.button.cancel' | translate }}</button>\n </footer>\n</yuv-dialog>\n", styles: [":host main{display:flex;flex-flow:column;padding:var(--ymt-spacing-m);flex:1;overflow-y:auto}:host main yuv-flavor-chip{border-color:transparent;flex:1}:host main ul{padding:0;margin:0;list-style-type:none}:host main li{display:flex;gap:var(--ymt-spacing-xs);align-items:center;border:1px solid var(--ymt-outline-variant);margin-block-end:2px;padding:var(--ymt-spacing-2xs)}:host footer{flex:0 0 auto;margin-block-start:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "component", type: FlavorChipComponent, selector: "yuv-flavor-chip", inputs: ["flavor", "enableRemove", "enableDescription"], outputs: ["flavorRemove"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }] }); }
434
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: ManageFlavorsComponent, isStandalone: true, selector: "yuv-manage-flavors", ngImport: i0, template: "<yuv-dialog [headertitel]=\"'yuv.shell.action.manage-flavors.title' | translate\">\n <main [yuvBusyOverlay]=\"busy()\">\n <p>{{ 'yuv.shell.action.manage-flavors.text' | translate }}</p>\n @if (appliedFlavors.length) {\n <h3>{{ 'yuv.shell.action.manage-flavors.applied.headline' | translate }}</h3>\n <ul>\n @for (f of appliedFlavors; track $index) {\n <li>\n <yuv-flavor-chip [flavor]=\"f\" yuvListItem></yuv-flavor-chip>\n <button mat-icon-button [matTooltip]=\"'yuv.shell.action.manage-flavors.applicable.button.remove.tooltip' | translate\" (click)=\"removeFlavor(f)\">\n <mat-icon>delete_forever</mat-icon>\n </button>\n </li>\n }\n </ul>\n }\n @if (applicableFlavors.length) {\n <h3>{{ 'yuv.shell.action.manage-flavors.applicable.headline' | translate }}</h3>\n <ul>\n @for (f of applicableFlavors; track $index) {\n <li>\n <yuv-flavor-chip [flavor]=\"f\" yuvListItem></yuv-flavor-chip>\n <button mat-icon-button [matTooltip]=\"'yuv.shell.action.manage-flavors.applied.button.apply.tooltip' | translate\" (click)=\"applyFlavor(f)\">\n <mat-icon>add</mat-icon>\n </button>\n </li>\n }\n </ul>\n }\n </main>\n <footer>\n <button ymtButton=\"secondary\" (click)=\"cancel()\">{{ 'yuv.shell.action.manage-flavors.button.cancel' | translate }}</button>\n </footer>\n</yuv-dialog>\n", styles: [":host main{display:flex;flex-flow:column;padding:var(--ymt-spacing-m);flex:1;overflow-y:auto}:host main yuv-flavor-chip{border-color:transparent;flex:1}:host main ul{padding:0;margin:0;list-style-type:none}:host main li{display:flex;gap:var(--ymt-spacing-xs);align-items:center;border:1px solid var(--ymt-outline-variant);margin-block-end:2px;padding:var(--ymt-spacing-2xs)}:host footer{flex:0 0 auto;margin-block-start:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "component", type: FlavorChipComponent, selector: "yuv-flavor-chip", inputs: ["flavor", "enableRemove", "enableDescription"], outputs: ["flavorRemove"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitel"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }] }); }
435
435
  }
436
436
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: ManageFlavorsComponent, decorators: [{
437
437
  type: Component,
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@yuuvis/client-shell",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "author": "OPTIMAL SYSTEMS GmbH <npm@optimal-systems.de>",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {
7
7
  "@angular/common": "^19.2.1",
8
8
  "@angular/core": "^19.2.1",
9
9
  "@angular/service-worker": "^19.2.1",
10
- "@yuuvis/client-core": "2.0.2",
11
- "@yuuvis/client-shell-core": "2.0.2"
10
+ "@yuuvis/client-core": "^2.0.4",
11
+ "@yuuvis/client-shell-core": "^2.0.4"
12
12
  },
13
13
  "dependencies": {
14
- "@yuuvis/client-framework": "2.0.2",
14
+ "@yuuvis/client-framework": "2.0.4",
15
15
  "tslib": "^2.3.0"
16
16
  },
17
17
  "sideEffects": false,
@@ -1,84 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { inject, signal, Component } from '@angular/core';
3
- import { toSignal } from '@angular/core/rxjs-interop';
4
- import * as i2 from '@yuuvis/client-core';
5
- import { UserService, ConfigService, TranslateService, AppCacheService, TranslateModule } from '@yuuvis/client-core';
6
- import * as i1 from '@angular/common';
7
- import { DOCUMENT, CommonModule } from '@angular/common';
8
- import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
9
- import { ShellService } from '@yuuvis/client-shell-core';
10
- import { map } from 'rxjs';
11
- import { MatSelectModule } from '@angular/material/select';
12
- import { MatButtonToggleGroup, MatButtonToggle } from '@angular/material/button-toggle';
13
-
14
- class SettingsPageComponent {
15
- constructor() {
16
- this.userService = inject(UserService);
17
- this.config = inject(ConfigService);
18
- this.translate = inject(TranslateService);
19
- this.shell = inject(ShellService);
20
- this.document = inject(DOCUMENT);
21
- this.#appCache = inject(AppCacheService);
22
- this.#fb = inject(FormBuilder);
23
- this.clientLocales = signal([]);
24
- this.clientVersion = signal(undefined);
25
- this.user = toSignal(this.userService.user$);
26
- this.appSettingForms$ = this.shell.appSettings$.pipe(map((settings) => settings.map((e) => {
27
- const x = {};
28
- const fcn = e.properties.map((p) => ({
29
- label: this.translate.instant(p.label) || p.label,
30
- name: p.name,
31
- type: p.type
32
- }));
33
- e.properties.forEach((p) => {
34
- x[p.name] = [p.value];
35
- });
36
- return {
37
- appID: e.appID,
38
- label: e.label,
39
- formControls: fcn,
40
- form: this.#fb.group(x)
41
- };
42
- })));
43
- }
44
- #appCache;
45
- #fb;
46
- saveAppSettings(appID, form) {
47
- this.userService
48
- .saveUserSettings({
49
- clientAppSettings: {
50
- [appID]: form.value
51
- }
52
- })
53
- .subscribe({
54
- next: () => {
55
- form.markAsPristine();
56
- },
57
- error: (err) => {
58
- console.error('Error saving app settings', err);
59
- }
60
- });
61
- }
62
- changeClientLocale(iso) {
63
- this.userService.changeClientLocale(iso);
64
- }
65
- toggleDarkMode() {
66
- const root = document.getElementsByTagName('body')[0];
67
- root.classList.toggle('dark');
68
- }
69
- ngOnInit() {
70
- this.clientVersion.set(this.document.body.getAttribute('data-version') ?? 'dev');
71
- this.clientLocales.set(this.config.getClientLocales());
72
- }
73
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: SettingsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
74
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.12", type: SettingsPageComponent, isStandalone: true, selector: "yuv-settings", ngImport: i0, template: "<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <span class=\"subhead\">{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</span>\n</header>\n\n\n<main>@if (user()) {\n <section class=\"user\">\n <!-- <yuv-user-avatar class=\"background\" [user]=\"user()\"></yuv-user-avatar> -->\n <div class=\"user\">\n <div class=\"meta uname\">{{ user()!.username }}</div>\n <h2>{{ user()!.title }}</h2>\n <div class=\"meta uemail\">{{ user()!.email }}</div>\n <div class=\"meta utenant\">{{ 'yuv.shell.settings.tenant' | translate }}: {{ user()!.tenant }}</div>\n </div>\n </section>\n}\n <!-- language -->\n <section yuvOfflineDisabled>\n <div class=\"label\" translate>yuv.shell.settings.language</div>\n <div class=\"value\">\n <mat-button-toggle-group name=\"language\" hideSingleSelectionIndicator=\"true\" [attr.aria-label]=\"'yuv.shell.settings.language' | translate\" >\n @for (locale of clientLocales(); track locale.iso) {\n <mat-button-toggle value=\"{{ locale.label }}\" class=\"toggle-button\" (click)=\"changeClientLocale(locale.iso)\" [ngClass]=\"{ active: translate.currentLang === locale.iso }\" [checked]=\"translate.currentLang === locale.iso\">{{ locale.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </section>\n\n <!-- app settings -->\n <!-- TODO: activate one feature is refined -->\n <!-- @for (c of appSettingForms$ | async; track $index) {\n <section>\n {{ c.label }}\n <form [formGroup]=\"c.form\" (ngSubmit)=\"saveAppSettings(c.appID, c.form)\">\n @for (n of c.formControls; track $index) {\n <label\n >{{ n.label }}\n\n @switch (n.type) {\n @case ('string') {\n <input type=\"text\" [formControlName]=\"n.name\" />\n }\n @case ('number') {\n <input type=\"number\" [formControlName]=\"n.name\" />\n }\n }\n </label>\n }\n <button [ngClass]=\"{ hideen: c.form.untouched }\" [disabled]=\"c.form.invalid\">Save</button>\n </form>\n </section>\n } -->\n</main>\n", styles: [":host{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto 1fr;grid-template-areas:\"header\" \"settings\";height:100%;overflow:hidden;overflow-y:auto}:host header{grid-area:header;padding:var(--ymt-spacing-3xl)}:host header h1{margin:0}:host header subhead{font:var(--ymt-font-subhead);color:var(--ymt-text-color-subtle)}:host main{grid-area:settings;padding:var(--ymt-spacing-m);overflow-y:auto}:host main section{display:flex;flex-flow:column;padding:var(--ymt-spacing-m)}:host main section .label{margin-block-end:1em}:host main section .value{display:inline-block}:host main section.user h2{margin:0 0 1rem}:host .toggle-button.active{background-color:var(--ymt-primary);color:var(--ymt-on-primary);pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "directive", type: i2.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }] }); }
75
- }
76
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.12", ngImport: i0, type: SettingsPageComponent, decorators: [{
77
- type: Component,
78
- args: [{ selector: 'yuv-settings', standalone: true, imports: [CommonModule, TranslateModule,
79
- MatSelectModule,
80
- ReactiveFormsModule, MatButtonToggleGroup, MatButtonToggle], template: "<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <span class=\"subhead\">{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</span>\n</header>\n\n\n<main>@if (user()) {\n <section class=\"user\">\n <!-- <yuv-user-avatar class=\"background\" [user]=\"user()\"></yuv-user-avatar> -->\n <div class=\"user\">\n <div class=\"meta uname\">{{ user()!.username }}</div>\n <h2>{{ user()!.title }}</h2>\n <div class=\"meta uemail\">{{ user()!.email }}</div>\n <div class=\"meta utenant\">{{ 'yuv.shell.settings.tenant' | translate }}: {{ user()!.tenant }}</div>\n </div>\n </section>\n}\n <!-- language -->\n <section yuvOfflineDisabled>\n <div class=\"label\" translate>yuv.shell.settings.language</div>\n <div class=\"value\">\n <mat-button-toggle-group name=\"language\" hideSingleSelectionIndicator=\"true\" [attr.aria-label]=\"'yuv.shell.settings.language' | translate\" >\n @for (locale of clientLocales(); track locale.iso) {\n <mat-button-toggle value=\"{{ locale.label }}\" class=\"toggle-button\" (click)=\"changeClientLocale(locale.iso)\" [ngClass]=\"{ active: translate.currentLang === locale.iso }\" [checked]=\"translate.currentLang === locale.iso\">{{ locale.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </section>\n\n <!-- app settings -->\n <!-- TODO: activate one feature is refined -->\n <!-- @for (c of appSettingForms$ | async; track $index) {\n <section>\n {{ c.label }}\n <form [formGroup]=\"c.form\" (ngSubmit)=\"saveAppSettings(c.appID, c.form)\">\n @for (n of c.formControls; track $index) {\n <label\n >{{ n.label }}\n\n @switch (n.type) {\n @case ('string') {\n <input type=\"text\" [formControlName]=\"n.name\" />\n }\n @case ('number') {\n <input type=\"number\" [formControlName]=\"n.name\" />\n }\n }\n </label>\n }\n <button [ngClass]=\"{ hideen: c.form.untouched }\" [disabled]=\"c.form.invalid\">Save</button>\n </form>\n </section>\n } -->\n</main>\n", styles: [":host{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto 1fr;grid-template-areas:\"header\" \"settings\";height:100%;overflow:hidden;overflow-y:auto}:host header{grid-area:header;padding:var(--ymt-spacing-3xl)}:host header h1{margin:0}:host header subhead{font:var(--ymt-font-subhead);color:var(--ymt-text-color-subtle)}:host main{grid-area:settings;padding:var(--ymt-spacing-m);overflow-y:auto}:host main section{display:flex;flex-flow:column;padding:var(--ymt-spacing-m)}:host main section .label{margin-block-end:1em}:host main section .value{display:inline-block}:host main section.user h2{margin:0 0 1rem}:host .toggle-button.active{background-color:var(--ymt-primary);color:var(--ymt-on-primary);pointer-events:none}\n"] }]
81
- }] });
82
-
83
- export { SettingsPageComponent };
84
- //# sourceMappingURL=yuuvis-client-shell-settings.component-C_TUScRF.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"yuuvis-client-shell-settings.component-C_TUScRF.mjs","sources":["../../../../../libs/yuuvis/client-shell/src/lib/pages/settings/settings.component.ts","../../../../../libs/yuuvis/client-shell/src/lib/pages/settings/settings.component.html"],"sourcesContent":["import { Component, inject, OnInit, Signal, signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { AppCacheService, ConfigService, TranslateModule, TranslateService, UserService, YuvConfigLanguages, YuvUser } from '@yuuvis/client-core';\n\nimport { CommonModule, DOCUMENT } from '@angular/common';\nimport { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';\nimport { ShellAppSettingProperty, ShellAppSettings, ShellService } from '@yuuvis/client-shell-core';\nimport { map, Observable } from 'rxjs';\nimport {MatSelectModule} from '@angular/material/select';\nimport { MatButtonToggle, MatButtonToggleGroup } from '@angular/material/button-toggle';\n\n@Component({\n selector: 'yuv-settings',\n standalone: true,\n imports: [CommonModule, TranslateModule,\n MatSelectModule,\n ReactiveFormsModule, MatButtonToggleGroup, MatButtonToggle],\n templateUrl: './settings.component.html',\n styleUrls: ['./settings.component.scss']\n})\nexport class SettingsPageComponent implements OnInit {\n private userService = inject(UserService);\n private config = inject(ConfigService);\n public translate = inject(TranslateService);\n private shell = inject(ShellService);\n readonly document = inject(DOCUMENT);\n #appCache = inject(AppCacheService);\n\n #fb = inject(FormBuilder);\n\n clientLocales = signal<YuvConfigLanguages[]>([]);\n clientVersion = signal<string | undefined>(undefined);\n user: Signal<YuvUser | undefined> = toSignal(this.userService.user$);\n appSettingForms$: Observable<\n {\n appID: string;\n label: string;\n formControls: ShellAppSettingProperty[];\n form: FormGroup;\n }[]\n > = this.shell.appSettings$.pipe(\n map((settings: ShellAppSettings[]) =>\n settings.map((e) => {\n const x: any = {};\n const fcn: ShellAppSettingProperty[] = e.properties.map((p) => ({\n label: this.translate.instant(p.label) || p.label,\n name: p.name,\n type: p.type\n }));\n e.properties.forEach((p) => {\n x[p.name] = [p.value];\n });\n return {\n appID: e.appID,\n label: e.label,\n formControls: fcn,\n form: this.#fb.group(x)\n };\n })\n )\n );\n\n saveAppSettings(appID: string, form: FormGroup) {\n this.userService\n .saveUserSettings({\n clientAppSettings: {\n [appID]: form.value\n }\n })\n .subscribe({\n next: () => {\n form.markAsPristine();\n },\n error: (err) => {\n console.error('Error saving app settings', err);\n }\n });\n }\n\n changeClientLocale(iso: string) {\n this.userService.changeClientLocale(iso);\n }\n\n toggleDarkMode() {\n const root = document.getElementsByTagName('body')[0];\n root.classList.toggle('dark'); \n }\n\n ngOnInit(): void {\n this.clientVersion.set(this.document.body.getAttribute('data-version') ?? 'dev');\n this.clientLocales.set(this.config.getClientLocales());\n }\n}\n","<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <span class=\"subhead\">{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</span>\n</header>\n\n\n<main>@if (user()) {\n <section class=\"user\">\n <!-- <yuv-user-avatar class=\"background\" [user]=\"user()\"></yuv-user-avatar> -->\n <div class=\"user\">\n <div class=\"meta uname\">{{ user()!.username }}</div>\n <h2>{{ user()!.title }}</h2>\n <div class=\"meta uemail\">{{ user()!.email }}</div>\n <div class=\"meta utenant\">{{ 'yuv.shell.settings.tenant' | translate }}: {{ user()!.tenant }}</div>\n </div>\n </section>\n}\n <!-- language -->\n <section yuvOfflineDisabled>\n <div class=\"label\" translate>yuv.shell.settings.language</div>\n <div class=\"value\">\n <mat-button-toggle-group name=\"language\" hideSingleSelectionIndicator=\"true\" [attr.aria-label]=\"'yuv.shell.settings.language' | translate\" >\n @for (locale of clientLocales(); track locale.iso) {\n <mat-button-toggle value=\"{{ locale.label }}\" class=\"toggle-button\" (click)=\"changeClientLocale(locale.iso)\" [ngClass]=\"{ active: translate.currentLang === locale.iso }\" [checked]=\"translate.currentLang === locale.iso\">{{ locale.label }}</mat-button-toggle>\n }\n </mat-button-toggle-group>\n </div>\n </section>\n\n <!-- app settings -->\n <!-- TODO: activate one feature is refined -->\n <!-- @for (c of appSettingForms$ | async; track $index) {\n <section>\n {{ c.label }}\n <form [formGroup]=\"c.form\" (ngSubmit)=\"saveAppSettings(c.appID, c.form)\">\n @for (n of c.formControls; track $index) {\n <label\n >{{ n.label }}\n\n @switch (n.type) {\n @case ('string') {\n <input type=\"text\" [formControlName]=\"n.name\" />\n }\n @case ('number') {\n <input type=\"number\" [formControlName]=\"n.name\" />\n }\n }\n </label>\n }\n <button [ngClass]=\"{ hideen: c.form.untouched }\" [disabled]=\"c.form.invalid\">Save</button>\n </form>\n </section>\n } -->\n</main>\n"],"names":[],"mappings":";;;;;;;;;;;;;MAoBa,qBAAqB,CAAA;AATlC,IAAA,WAAA,GAAA;AAUU,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACjC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;AAC/B,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACnC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;AAC3B,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AACpC,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,eAAe,CAAC;AAEnC,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC;AAEzB,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAuB,EAAE,CAAC;AAChD,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAqB,SAAS,CAAC;QACrD,IAAI,CAAA,IAAA,GAAgC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;QACpE,IAAgB,CAAA,gBAAA,GAOZ,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAC9B,GAAG,CAAC,CAAC,QAA4B,KAC/B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAI;YACjB,MAAM,CAAC,GAAQ,EAAE;AACjB,YAAA,MAAM,GAAG,GAA8B,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM;AAC9D,gBAAA,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK;gBACjD,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,CAAC,CAAC;AACT,aAAA,CAAC,CAAC;YACH,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,KAAI;gBACzB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AACvB,aAAC,CAAC;YACF,OAAO;gBACL,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;AACd,gBAAA,YAAY,EAAE,GAAG;gBACjB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;aACvB;SACF,CAAC,CACH,CACF;AAgCF;AAlEC,IAAA,SAAS;AAET,IAAA,GAAG;IAkCH,eAAe,CAAC,KAAa,EAAE,IAAe,EAAA;AAC5C,QAAA,IAAI,CAAC;AACF,aAAA,gBAAgB,CAAC;AAChB,YAAA,iBAAiB,EAAE;AACjB,gBAAA,CAAC,KAAK,GAAG,IAAI,CAAC;AACf;SACF;AACA,aAAA,SAAS,CAAC;YACT,IAAI,EAAE,MAAK;gBACT,IAAI,CAAC,cAAc,EAAE;aACtB;AACD,YAAA,KAAK,EAAE,CAAC,GAAG,KAAI;AACb,gBAAA,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC;;AAElD,SAAA,CAAC;;AAGN,IAAA,kBAAkB,CAAC,GAAW,EAAA;AAC5B,QAAA,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC;;IAG1C,cAAc,GAAA;QACZ,MAAM,IAAI,GAAG,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACrD,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;;IAG/B,QAAQ,GAAA;AACN,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC;AAChF,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;;+GAtE7C,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,qBAAqB,ECpBlC,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,wpEAsDA,EDxCY,MAAA,EAAA,CAAA,uuBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EAAE,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,EACrC,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,IAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,EACf,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,mBAAmB,EAAE,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,oBAAoB,kTAAE,eAAe,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,eAAA,EAAA,YAAA,EAAA,SAAA,EAAA,UAAA,EAAA,qBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FAIjD,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBATjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,cACZ,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,eAAe;wBACrC,eAAe;AACf,wBAAA,mBAAmB,EAAE,oBAAoB,EAAE,eAAe,CAAC,EAAA,QAAA,EAAA,wpEAAA,EAAA,MAAA,EAAA,CAAA,uuBAAA,CAAA,EAAA;;;;;"}