@yuuvis/client-shell 2.0.0-beta.0 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/yuuvis-client-shell-dashboard.component-DWdP5HSx.mjs +14 -0
- package/fesm2022/yuuvis-client-shell-dashboard.component-DWdP5HSx.mjs.map +1 -0
- package/fesm2022/yuuvis-client-shell-settings.component-R-GCMuxK.mjs +84 -0
- package/fesm2022/yuuvis-client-shell-settings.component-R-GCMuxK.mjs.map +1 -0
- package/fesm2022/yuuvis-client-shell-web-share-target.component-BQiQkEd_.mjs +21 -0
- package/fesm2022/yuuvis-client-shell-web-share-target.component-BQiQkEd_.mjs.map +1 -0
- package/fesm2022/yuuvis-client-shell.mjs +144 -143
- package/fesm2022/yuuvis-client-shell.mjs.map +1 -1
- package/lib/actions/manage-flavors/manage-flavors.component.d.ts +1 -0
- package/lib/assets/i18n/de.json +3 -3
- package/lib/assets/i18n/en.json +3 -3
- package/lib/client-shell.component.d.ts +4 -2
- package/lib/components/sidebar-nav/sidebar-nav.component.d.ts +8 -0
- package/lib/pages/dashboard/dashboard.component.d.ts +1 -1
- package/lib/pages/notifications/notifications.component.d.ts +0 -2
- package/lib/pages/settings/settings.component.d.ts +1 -0
- package/package.json +7 -18
- package/esm2022/index.mjs +0 -6
- package/esm2022/lib/actions/manage-flavors/manage-flavors.action.mjs +0 -39
- package/esm2022/lib/actions/manage-flavors/manage-flavors.component.mjs +0 -69
- package/esm2022/lib/client-shell.component.mjs +0 -191
- package/esm2022/lib/components/app-logo/app-logo.component.mjs +0 -18
- package/esm2022/lib/directives/inert.directive.mjs +0 -26
- package/esm2022/lib/lib.routes.mjs +0 -15
- package/esm2022/lib/pages/dashboard/dashboard.component.mjs +0 -11
- package/esm2022/lib/pages/notifications/notifications.component.mjs +0 -82
- package/esm2022/lib/pages/settings/settings.component.mjs +0 -71
- package/esm2022/lib/pages/web-share-target/web-share-target.component.mjs +0 -18
- package/esm2022/widget-dashboard/index.mjs +0 -3
- package/esm2022/widget-dashboard/lib/widget-dashboard.component.mjs +0 -46
- package/esm2022/widget-dashboard/lib/widget-dashboard.config.mjs +0 -3
- package/esm2022/widget-dashboard/lib/widget-dashboard.module.mjs +0 -49
- package/esm2022/widget-dashboard/yuuvis-client-shell-widget-dashboard.mjs +0 -5
- package/esm2022/yuuvis-client-shell.mjs +0 -5
- package/fesm2022/yuuvis-client-shell-widget-dashboard.mjs +0 -98
- package/fesm2022/yuuvis-client-shell-widget-dashboard.mjs.map +0 -1
- package/widget-dashboard/README.md +0 -19
- package/widget-dashboard/index.d.ts +0 -2
- package/widget-dashboard/lib/widget-dashboard.component.d.ts +0 -16
- package/widget-dashboard/lib/widget-dashboard.config.d.ts +0 -7
- package/widget-dashboard/lib/widget-dashboard.module.d.ts +0 -13
|
@@ -1,27 +1,39 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ElementRef, input, effect, Directive, Component, signal,
|
|
2
|
+
import { inject, ElementRef, input, effect, Directive, HostListener, Component, ChangeDetectionStrategy, signal, computed } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
|
-
import {
|
|
4
|
+
import { CommonModule, AsyncPipe } from '@angular/common';
|
|
5
5
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
6
|
+
import * as i3 from '@angular/material/button';
|
|
7
|
+
import { MatButtonModule, MatIconButton } from '@angular/material/button';
|
|
8
|
+
import * as i2 from '@angular/material/icon';
|
|
9
|
+
import { MatIconModule, MatIconRegistry, MatIcon } from '@angular/material/icon';
|
|
6
10
|
import * as i2$2 from '@angular/router';
|
|
7
11
|
import { Router, NavigationEnd, RouterModule } from '@angular/router';
|
|
8
12
|
import { SwPush } from '@angular/service-worker';
|
|
9
|
-
import * as i2 from '@yuuvis/client-core';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import { ICONS, YvcIconModule } from '@yuuvis/components/icon';
|
|
15
|
-
import { map, of, tap as tap$1 } from 'rxjs';
|
|
16
|
-
import { tap, map as map$1, filter, catchError, switchMap } from 'rxjs/operators';
|
|
17
|
-
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
|
|
13
|
+
import * as i2$1 from '@yuuvis/client-core';
|
|
14
|
+
import { Utils, LocaleDatePipe, TranslateModule, AuthService, UserService, TranslateService, DeviceService, SafeHtmlPipe, UserRoles, DmsService, SystemType } from '@yuuvis/client-core';
|
|
15
|
+
import { ShellNotificationsService, ShellService, CommandPaletteService } from '@yuuvis/client-shell-core';
|
|
16
|
+
import { of, switchMap as switchMap$1, tap as tap$1 } from 'rxjs';
|
|
17
|
+
import { map, shareReplay, tap, filter, catchError, switchMap } from 'rxjs/operators';
|
|
18
18
|
import { CdkTrapFocus } from '@angular/cdk/a11y';
|
|
19
|
-
import { LightDismissDirective, BusyOverlayDirective } from '@yuuvis/client-framework/common';
|
|
20
|
-
import { YUV_ICONS } from '@yuuvis/client-framework/icons';
|
|
21
|
-
import
|
|
19
|
+
import { LightDismissDirective, ConfirmService, BusyOverlayDirective, DialogComponent } from '@yuuvis/client-framework/common';
|
|
20
|
+
import { YUV_ICONS, YuvIconComponent } from '@yuuvis/client-framework/icons';
|
|
21
|
+
import * as i4 from '@yuuvis/client-framework/list';
|
|
22
|
+
import { YuvListModule, ListItemDirective } from '@yuuvis/client-framework/list';
|
|
23
|
+
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
|
24
|
+
import { MatListModule } from '@angular/material/list';
|
|
25
|
+
import * as i1$1 from '@angular/material/sidenav';
|
|
26
|
+
import { MatSidenavModule } from '@angular/material/sidenav';
|
|
27
|
+
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
28
|
+
import * as i3$1 from '@yuuvis/client-framework/metadata-form-defaults';
|
|
29
|
+
import { YuvMetadataFormDefaultsModule } from '@yuuvis/client-framework/metadata-form-defaults';
|
|
30
|
+
import { MatProgressBar } from '@angular/material/progress-bar';
|
|
31
|
+
import * as i4$1 from '@angular/material/tooltip';
|
|
32
|
+
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
33
|
+
import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material/dialog';
|
|
22
34
|
import { AbstractContextAction, ACTION_ICON, SelectionRange } from '@yuuvis/client-framework/actions';
|
|
23
|
-
import { YvcOverlayRef, YvcOverlayService } from '@yuuvis/components/overlay';
|
|
24
35
|
import { FlavorChipComponent } from '@yuuvis/client-framework/object-flavor';
|
|
36
|
+
import { YuvButtonDirective } from '@yuuvis/material';
|
|
25
37
|
|
|
26
38
|
class InertDirective {
|
|
27
39
|
constructor() {
|
|
@@ -35,10 +47,10 @@ class InertDirective {
|
|
|
35
47
|
el.removeAttribute('inert');
|
|
36
48
|
});
|
|
37
49
|
}
|
|
38
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
39
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
50
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: InertDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
51
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.1", type: InertDirective, isStandalone: true, selector: "[inert]", inputs: { inert: { classPropertyName: "inert", publicName: "inert", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
40
52
|
}
|
|
41
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
53
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: InertDirective, decorators: [{
|
|
42
54
|
type: Directive,
|
|
43
55
|
args: [{
|
|
44
56
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -47,76 +59,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
47
59
|
}]
|
|
48
60
|
}], ctorParameters: () => [] });
|
|
49
61
|
|
|
50
|
-
class DashboardPageComponent {
|
|
51
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DashboardPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
52
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DashboardPageComponent, selector: "yuv-dashboard", ngImport: i0, template: "yuuvis Momentum\n", styles: [":host{display:grid;align-items:center;justify-content:center;height:100%;overflow:hidden;color:var(--text-color-hint);font-size:var(--font-display)}\n"] }); }
|
|
53
|
-
}
|
|
54
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DashboardPageComponent, decorators: [{
|
|
55
|
-
type: Component,
|
|
56
|
-
args: [{ selector: 'yuv-dashboard', template: "yuuvis Momentum\n", styles: [":host{display:grid;align-items:center;justify-content:center;height:100%;overflow:hidden;color:var(--text-color-hint);font-size:var(--font-display)}\n"] }]
|
|
57
|
-
}] });
|
|
58
|
-
|
|
59
|
-
class SettingsPageComponent {
|
|
60
|
-
constructor() {
|
|
61
|
-
this.userService = inject(UserService);
|
|
62
|
-
this.config = inject(ConfigService);
|
|
63
|
-
this.translate = inject(TranslateService);
|
|
64
|
-
this.shell = inject(ShellService);
|
|
65
|
-
this.document = inject(DOCUMENT);
|
|
66
|
-
this.#fb = inject(FormBuilder);
|
|
67
|
-
this.clientLocales = signal([]);
|
|
68
|
-
this.clientVersion = signal(undefined);
|
|
69
|
-
this.user = toSignal(this.userService.user$);
|
|
70
|
-
this.appSettingForms$ = this.shell.appSettings$.pipe(map((settings) => settings.map((e) => {
|
|
71
|
-
const x = {};
|
|
72
|
-
const fcn = e.properties.map((p) => ({
|
|
73
|
-
label: this.translate.instant(p.label) || p.label,
|
|
74
|
-
name: p.name,
|
|
75
|
-
type: p.type
|
|
76
|
-
}));
|
|
77
|
-
e.properties.forEach((p) => {
|
|
78
|
-
x[p.name] = [p.value];
|
|
79
|
-
});
|
|
80
|
-
return {
|
|
81
|
-
appID: e.appID,
|
|
82
|
-
label: e.label,
|
|
83
|
-
formControls: fcn,
|
|
84
|
-
form: this.#fb.group(x)
|
|
85
|
-
};
|
|
86
|
-
})));
|
|
87
|
-
}
|
|
88
|
-
#fb;
|
|
89
|
-
saveAppSettings(appID, form) {
|
|
90
|
-
this.userService
|
|
91
|
-
.saveUserSettings({
|
|
92
|
-
clientAppSettings: {
|
|
93
|
-
[appID]: form.value
|
|
94
|
-
}
|
|
95
|
-
})
|
|
96
|
-
.subscribe({
|
|
97
|
-
next: () => {
|
|
98
|
-
form.markAsPristine();
|
|
99
|
-
},
|
|
100
|
-
error: (err) => {
|
|
101
|
-
console.error('Error saving app settings', err);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
changeClientLocale(iso) {
|
|
106
|
-
this.userService.changeClientLocale(iso);
|
|
107
|
-
}
|
|
108
|
-
ngOnInit() {
|
|
109
|
-
this.clientVersion.set(this.document.body.getAttribute('data-version') ?? 'dev');
|
|
110
|
-
this.clientLocales.set(this.config.getClientLocales());
|
|
111
|
-
}
|
|
112
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SettingsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
113
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SettingsPageComponent, isStandalone: true, selector: "yuv-settings", ngImport: i0, template: "<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <h4>{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</h4>\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 buttons\">\n @for (locale of clientLocales(); track locale.iso) {\n <button class=\"toggle secondary\" (click)=\"changeClientLocale(locale.iso)\" [ngClass]=\"{ active: translate.currentLang === locale.iso }\">\n {{ locale.label }}\n </button>\n }\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:calc(var(--app-pane-padding) * 2)}:host header h1,:host header h4{margin:0}:host header h1{font-size:var(--font-display);font-weight:400}:host header h4{font-size:var(--font-cation);font-weight:400;font-style:italic;color:var(--text-color-caption)}:host main{grid-area:settings;padding:var(--app-pane-padding);overflow-y:auto}:host main section{display:flex;flex-flow:column;padding:var(--app-pane-padding)}:host main section .label{margin-block-end:1em}:host main section .value{display:flex;flex-flow:row wrap;gap:calc(var(--app-pane-padding) / 4)}:host main section.user h2{margin:0 0 1rem;font-weight:400}:host button.active{background-color:var(--color-accent);color:var(--color-accent-tone);pointer-events:none}:host button.color.clear{padding:2px 8px}:host button.color.accent.active{outline:2px solid #fff;outline-offset:-2px}\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: ReactiveFormsModule }] }); }
|
|
114
|
-
}
|
|
115
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SettingsPageComponent, decorators: [{
|
|
116
|
-
type: Component,
|
|
117
|
-
args: [{ selector: 'yuv-settings', standalone: true, imports: [CommonModule, TranslateModule, ReactiveFormsModule], template: "<header>\n <h1>{{ 'yuv.shell.settings.title' | translate }}</h1>\n <h4>{{ 'yuc.shell.settings.client.version' | translate }}: {{ clientVersion() }}</h4>\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 buttons\">\n @for (locale of clientLocales(); track locale.iso) {\n <button class=\"toggle secondary\" (click)=\"changeClientLocale(locale.iso)\" [ngClass]=\"{ active: translate.currentLang === locale.iso }\">\n {{ locale.label }}\n </button>\n }\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:calc(var(--app-pane-padding) * 2)}:host header h1,:host header h4{margin:0}:host header h1{font-size:var(--font-display);font-weight:400}:host header h4{font-size:var(--font-cation);font-weight:400;font-style:italic;color:var(--text-color-caption)}:host main{grid-area:settings;padding:var(--app-pane-padding);overflow-y:auto}:host main section{display:flex;flex-flow:column;padding:var(--app-pane-padding)}:host main section .label{margin-block-end:1em}:host main section .value{display:flex;flex-flow:row wrap;gap:calc(var(--app-pane-padding) / 4)}:host main section.user h2{margin:0 0 1rem;font-weight:400}:host button.active{background-color:var(--color-accent);color:var(--color-accent-tone);pointer-events:none}:host button.color.clear{padding:2px 8px}:host button.color.accent.active{outline:2px solid #fff;outline-offset:-2px}\n"] }]
|
|
118
|
-
}] });
|
|
119
|
-
|
|
120
62
|
class NotificationsPageComponent {
|
|
121
63
|
constructor() {
|
|
122
64
|
this.router = inject(Router);
|
|
@@ -127,8 +69,6 @@ class NotificationsPageComponent {
|
|
|
127
69
|
this.notifications = toSignal(this.shellNotifications.shellNotifications$);
|
|
128
70
|
this.notificationsIdEffect = effect(() => (this._notificationIDs = (this.notifications() || []).map((n) => n.id)));
|
|
129
71
|
this.icons = {
|
|
130
|
-
close: ICONS.clear,
|
|
131
|
-
trash: YUV_ICONS.trash,
|
|
132
72
|
note: YUV_ICONS.notification
|
|
133
73
|
};
|
|
134
74
|
}
|
|
@@ -173,47 +113,59 @@ class NotificationsPageComponent {
|
|
|
173
113
|
fc[0].focus();
|
|
174
114
|
});
|
|
175
115
|
}
|
|
176
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
177
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
116
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: NotificationsPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
117
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.1", 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" }] }); }
|
|
178
118
|
}
|
|
179
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: NotificationsPageComponent, decorators: [{
|
|
180
120
|
type: Component,
|
|
181
|
-
args: [{ selector: 'yuv-notifications', standalone: true, imports: [
|
|
121
|
+
args: [{ selector: 'yuv-notifications', standalone: true, imports: [
|
|
122
|
+
CommonModule,
|
|
123
|
+
LightDismissDirective,
|
|
124
|
+
MatIconModule,
|
|
125
|
+
MatButtonModule,
|
|
126
|
+
LocaleDatePipe,
|
|
127
|
+
YuvIconComponent,
|
|
128
|
+
CdkTrapFocus,
|
|
129
|
+
YuvListModule,
|
|
130
|
+
TranslateModule
|
|
131
|
+
], 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"] }]
|
|
182
132
|
}], propDecorators: { onKeydown: [{
|
|
183
133
|
type: HostListener,
|
|
184
134
|
args: ['keydown', ['$event']]
|
|
185
135
|
}] } });
|
|
186
136
|
|
|
187
|
-
class WebShareTargetPageComponent {
|
|
188
|
-
constructor() {
|
|
189
|
-
navigator.serviceWorker.onmessage = (e) => {
|
|
190
|
-
const file = e.data.file;
|
|
191
|
-
console.log(file);
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WebShareTargetPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
195
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: WebShareTargetPageComponent, isStandalone: true, selector: "yuv-web-share-target", ngImport: i0, template: "<p>web-share-target works!</p>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
196
|
-
}
|
|
197
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WebShareTargetPageComponent, decorators: [{
|
|
198
|
-
type: Component,
|
|
199
|
-
args: [{ selector: 'yuv-web-share-target', standalone: true, imports: [CommonModule], template: "<p>web-share-target works!</p>\n" }]
|
|
200
|
-
}], ctorParameters: () => [] });
|
|
201
|
-
|
|
202
137
|
const clientShellRoutes = [
|
|
203
|
-
{ path: 'dashboard',
|
|
138
|
+
{ path: 'dashboard', loadComponent: () => import('./yuuvis-client-shell-dashboard.component-DWdP5HSx.mjs').then((comp) => comp.DashboardPageComponent) },
|
|
204
139
|
{ path: 'notifications', component: NotificationsPageComponent, outlet: 'aside' },
|
|
205
|
-
{ path: 'settings',
|
|
206
|
-
{
|
|
140
|
+
{ path: 'settings', loadComponent: () => import('./yuuvis-client-shell-settings.component-R-GCMuxK.mjs').then((comp) => comp.SettingsPageComponent) },
|
|
141
|
+
{
|
|
142
|
+
path: 'web-share-target',
|
|
143
|
+
loadComponent: () => import('./yuuvis-client-shell-web-share-target.component-BQiQkEd_.mjs').then((comp) => comp.WebShareTargetPageComponent)
|
|
144
|
+
},
|
|
207
145
|
// default route
|
|
208
146
|
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
|
209
147
|
// redirecting route
|
|
210
148
|
{ path: '**', redirectTo: '/' }
|
|
211
149
|
];
|
|
212
150
|
|
|
151
|
+
class SidebarNavComponent {
|
|
152
|
+
constructor() {
|
|
153
|
+
this.breakpointObserver = inject(BreakpointObserver);
|
|
154
|
+
this.isHandset$ = this.breakpointObserver.observe(Breakpoints.Handset).pipe(map((result) => result.matches), shareReplay());
|
|
155
|
+
}
|
|
156
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SidebarNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
157
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.1", 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 }); }
|
|
158
|
+
}
|
|
159
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: SidebarNavComponent, decorators: [{
|
|
160
|
+
type: Component,
|
|
161
|
+
args: [{ selector: 'yuv-sidebar-nav', changeDetection: ChangeDetectionStrategy.OnPush, imports: [TranslateModule, MatToolbarModule, MatButtonModule, MatSidenavModule, MatListModule, MatIconModule], 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"] }]
|
|
162
|
+
}] });
|
|
163
|
+
|
|
213
164
|
class ClientShellComponent {
|
|
214
165
|
#shell;
|
|
215
166
|
#device;
|
|
216
167
|
#swPush;
|
|
168
|
+
#matIconRegistryService;
|
|
217
169
|
onFocusChange(event) {
|
|
218
170
|
// console.log('focused: ', document.activeElement);
|
|
219
171
|
}
|
|
@@ -234,6 +186,7 @@ class ClientShellComponent {
|
|
|
234
186
|
this.commandPalette = inject(CommandPaletteService);
|
|
235
187
|
this.#device = inject(DeviceService);
|
|
236
188
|
this.#swPush = inject(SwPush);
|
|
189
|
+
this.#matIconRegistryService = inject(MatIconRegistry);
|
|
237
190
|
this.APP_LOGOUT_EVENT_KEY = 'yuv.app.event.logout';
|
|
238
191
|
this._levels = {
|
|
239
192
|
info: 0,
|
|
@@ -241,10 +194,11 @@ class ClientShellComponent {
|
|
|
241
194
|
warning: 2,
|
|
242
195
|
alert: 3
|
|
243
196
|
};
|
|
197
|
+
this.safeHtmlPipe = inject(SafeHtmlPipe);
|
|
244
198
|
this.showUploadOverlay = false;
|
|
245
199
|
this.busy$ = this.#shell.isBusy$;
|
|
246
200
|
this.showNotifications = signal(false);
|
|
247
|
-
this.newNotifications = toSignal(this.shellNotifications.shellNotifications$.pipe(tap((n) => this.showNotifications.set(n.length > 0)), map
|
|
201
|
+
this.newNotifications = toSignal(this.shellNotifications.shellNotifications$.pipe(tap((n) => this.showNotifications.set(n.length > 0)), map((notifications) => {
|
|
248
202
|
let maxLevel = 'info';
|
|
249
203
|
const count = notifications.filter((n) => !n.seen).length;
|
|
250
204
|
notifications.forEach((n) => (maxLevel = n.level && this._levels[n.level] > this._levels[maxLevel] ? n.level : maxLevel));
|
|
@@ -260,10 +214,24 @@ class ClientShellComponent {
|
|
|
260
214
|
if (cfg) {
|
|
261
215
|
this.#shell.setShellConfig(cfg);
|
|
262
216
|
}
|
|
263
|
-
}, {
|
|
264
|
-
allowSignalWrites: true
|
|
265
217
|
});
|
|
266
|
-
this.
|
|
218
|
+
this.registerIcons = computed(() => {
|
|
219
|
+
const apps = this.apps();
|
|
220
|
+
const config = this.#shell.shellConfig();
|
|
221
|
+
const namespace = config.shellIconNamespace;
|
|
222
|
+
// find svg-icons to register and put them in an array
|
|
223
|
+
const customSvgIconsToRegister = apps
|
|
224
|
+
.filter(({ svgIcon }) => !!svgIcon)
|
|
225
|
+
.map(({ svgIcon, iconName }) => ({ svgIcon, iconName }));
|
|
226
|
+
customSvgIconsToRegister.push(config.appIcon);
|
|
227
|
+
// register svg-icons
|
|
228
|
+
const allRegistered = customSvgIconsToRegister.every((icon) => {
|
|
229
|
+
return namespace && icon && icon.svgIcon && icon.iconName
|
|
230
|
+
? !!this.#matIconRegistryService.addSvgIconLiteralInNamespace(namespace, icon.iconName, this.safeHtmlPipe.transform(icon.svgIcon))
|
|
231
|
+
: false;
|
|
232
|
+
});
|
|
233
|
+
return allRegistered;
|
|
234
|
+
});
|
|
267
235
|
this.translate.onLangChange.subscribe(() => this._setCommands(true));
|
|
268
236
|
// this.router.events.pipe(
|
|
269
237
|
// // filter(e => e instanceof NavigationStart)
|
|
@@ -271,7 +239,7 @@ class ClientShellComponent {
|
|
|
271
239
|
// console.log(e);
|
|
272
240
|
// });
|
|
273
241
|
this.router.events
|
|
274
|
-
.pipe(filter((e) => e instanceof NavigationEnd), map
|
|
242
|
+
.pipe(filter((e) => e instanceof NavigationEnd), map((e) => e))
|
|
275
243
|
.subscribe((e) => this._processRouterNavigationEnd(e));
|
|
276
244
|
this.#device.init();
|
|
277
245
|
this.userService.user$.subscribe((user) => {
|
|
@@ -287,6 +255,9 @@ class ClientShellComponent {
|
|
|
287
255
|
}
|
|
288
256
|
});
|
|
289
257
|
}
|
|
258
|
+
getAppTitle(a) {
|
|
259
|
+
return a.title || '';
|
|
260
|
+
}
|
|
290
261
|
openNotifications() {
|
|
291
262
|
this.router.navigate([{}]);
|
|
292
263
|
}
|
|
@@ -322,7 +293,6 @@ class ClientShellComponent {
|
|
|
322
293
|
}
|
|
323
294
|
requestSubscription() {
|
|
324
295
|
if (!this.#swPush.isEnabled) {
|
|
325
|
-
console.log('Notification is not enabled.');
|
|
326
296
|
return;
|
|
327
297
|
}
|
|
328
298
|
this.#swPush.messages
|
|
@@ -350,7 +320,7 @@ class ClientShellComponent {
|
|
|
350
320
|
// get persisted routes to decide where to redirect the logged in user to
|
|
351
321
|
this.auth
|
|
352
322
|
.getInitialRequestUri()
|
|
353
|
-
.pipe(switchMap((res) => this.auth.resetInitialRequestUri().pipe(map
|
|
323
|
+
.pipe(switchMap((res) => this.auth.resetInitialRequestUri().pipe(map((_) => res))))
|
|
354
324
|
.subscribe((res) => {
|
|
355
325
|
const loginRes = res && !ignoreRoutes.includes(res.uri) ? res : null;
|
|
356
326
|
if (loginRes)
|
|
@@ -371,12 +341,12 @@ class ClientShellComponent {
|
|
|
371
341
|
this._setCommands();
|
|
372
342
|
this.requestSubscription();
|
|
373
343
|
}
|
|
374
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
375
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
344
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: ClientShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
345
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.1", 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"] }] }); }
|
|
376
346
|
}
|
|
377
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
347
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: ClientShellComponent, decorators: [{
|
|
378
348
|
type: Component,
|
|
379
|
-
args: [{ selector: 'yuv-client-shell', standalone: true, imports: [
|
|
349
|
+
args: [{ selector: 'yuv-client-shell', standalone: true, imports: [AsyncPipe, TranslateModule, RouterModule, YuvMetadataFormDefaultsModule, SidebarNavComponent, MatIconButton, MatIcon, MatProgressBar, MatTooltipModule], providers: [SafeHtmlPipe], 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"] }]
|
|
380
350
|
}], ctorParameters: () => [], propDecorators: { onFocusChange: [{
|
|
381
351
|
type: HostListener,
|
|
382
352
|
args: ['document:focusin', ['$event']]
|
|
@@ -390,38 +360,51 @@ class AppLogoComponent {
|
|
|
390
360
|
this.icon = input();
|
|
391
361
|
this.label = input.required();
|
|
392
362
|
}
|
|
393
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
394
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
363
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AppLogoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
364
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.1", type: AppLogoComponent, isStandalone: true, selector: "yuv-app-logo", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<span class=\"label\">{{label()}}</span>\n", styles: [":host{--text-color: var(--ymt-on-brand);--icon-color: var(--text-color);--surface-color: var(--ymt-brand);--band-icon-size: 32px;--icon-background-color: transparent;padding:var(--ymt-spacing-xs) calc(var(--ymt-spacing-m)) var(--ymt-spacing-xs) calc(var(--ymt-spacing-m));font:var(--ymt-font-title-small);line-height:1;background-color:var(--surface-color);color:var(--text-color)}:host .label{line-height:1em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
395
365
|
}
|
|
396
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
366
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: AppLogoComponent, decorators: [{
|
|
397
367
|
type: Component,
|
|
398
|
-
args: [{ selector: 'yuv-app-logo', standalone: true, imports: [CommonModule
|
|
368
|
+
args: [{ selector: 'yuv-app-logo', standalone: true, imports: [CommonModule], template: "<span class=\"label\">{{label()}}</span>\n", styles: [":host{--text-color: var(--ymt-on-brand);--icon-color: var(--text-color);--surface-color: var(--ymt-brand);--band-icon-size: 32px;--icon-background-color: transparent;padding:var(--ymt-spacing-xs) calc(var(--ymt-spacing-m)) var(--ymt-spacing-xs) calc(var(--ymt-spacing-m));font:var(--ymt-font-title-small);line-height:1;background-color:var(--surface-color);color:var(--text-color)}:host .label{line-height:1em}\n"] }]
|
|
399
369
|
}] });
|
|
400
370
|
|
|
401
371
|
class ManageFlavorsComponent {
|
|
402
372
|
constructor() {
|
|
403
|
-
this.#overlayRef = inject(YvcOverlayRef);
|
|
404
373
|
this.#shell = inject(ShellService);
|
|
405
374
|
this.#dmsService = inject(DmsService);
|
|
406
|
-
this
|
|
375
|
+
this.#dialogData = inject(MAT_DIALOG_DATA);
|
|
376
|
+
this.#dialogRef = inject((MatDialogRef));
|
|
377
|
+
this.item = this.#dialogData;
|
|
378
|
+
this.#confirm = inject(ConfirmService);
|
|
379
|
+
this.translate = inject(TranslateService);
|
|
407
380
|
this.busy = signal(false);
|
|
408
381
|
this.appliedFlavors = [];
|
|
409
382
|
this.applicableFlavors = [];
|
|
410
383
|
}
|
|
411
|
-
#overlayRef;
|
|
412
384
|
#shell;
|
|
413
385
|
#dmsService;
|
|
386
|
+
#dialogData;
|
|
387
|
+
#dialogRef;
|
|
388
|
+
#confirm;
|
|
414
389
|
applyFlavor(flavor) {
|
|
415
390
|
this.busy.set(true);
|
|
416
391
|
this.#shell.triggerApplyObjectFlavor(this.item, flavor).subscribe(() => {
|
|
417
|
-
this.#
|
|
392
|
+
this.#dialogRef.close();
|
|
418
393
|
this.busy.set(false);
|
|
419
394
|
});
|
|
420
395
|
}
|
|
421
396
|
removeFlavor(flavor) {
|
|
422
397
|
this.busy.set(true);
|
|
423
|
-
this.#
|
|
424
|
-
|
|
398
|
+
this.#confirm
|
|
399
|
+
.confirm({
|
|
400
|
+
message: this.translate.instant('yuv.object-flavor.flavor.remove.confirm.message', {
|
|
401
|
+
flavor: this.#shell.getFlavorLabel(flavor.id)
|
|
402
|
+
})
|
|
403
|
+
})
|
|
404
|
+
.pipe(switchMap$1((confirmed) => (confirmed ? this.#shell.removeObjectFlavor(this.item, flavor) : of(undefined))))
|
|
405
|
+
.subscribe((res) => {
|
|
406
|
+
if (res !== undefined)
|
|
407
|
+
this.#dialogRef.close();
|
|
425
408
|
this.busy.set(false);
|
|
426
409
|
});
|
|
427
410
|
}
|
|
@@ -442,25 +425,35 @@ class ManageFlavorsComponent {
|
|
|
442
425
|
this.applicableFlavors = res.applicable;
|
|
443
426
|
}
|
|
444
427
|
cancel() {
|
|
445
|
-
|
|
446
|
-
this.#overlayRef.close();
|
|
428
|
+
this.#dialogRef.close();
|
|
447
429
|
}
|
|
448
430
|
ngOnInit() {
|
|
449
431
|
this.#refreshDmsObject();
|
|
450
432
|
}
|
|
451
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
452
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
433
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: ManageFlavorsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
434
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.1", 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: YuvButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive"] }] }); }
|
|
453
435
|
}
|
|
454
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
436
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.1", ngImport: i0, type: ManageFlavorsComponent, decorators: [{
|
|
455
437
|
type: Component,
|
|
456
|
-
args: [{ selector: 'yuv-manage-flavors', standalone: true, imports: [
|
|
438
|
+
args: [{ selector: 'yuv-manage-flavors', standalone: true, imports: [
|
|
439
|
+
CommonModule,
|
|
440
|
+
BusyOverlayDirective,
|
|
441
|
+
MatIconModule,
|
|
442
|
+
MatTooltipModule,
|
|
443
|
+
TranslateModule,
|
|
444
|
+
ListItemDirective,
|
|
445
|
+
FlavorChipComponent,
|
|
446
|
+
DialogComponent,
|
|
447
|
+
MatButtonModule,
|
|
448
|
+
YuvButtonDirective
|
|
449
|
+
], 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"] }]
|
|
457
450
|
}] });
|
|
458
451
|
|
|
459
452
|
class ManageFlavorsAction extends AbstractContextAction {
|
|
460
453
|
constructor() {
|
|
461
454
|
super(...arguments);
|
|
462
455
|
this.#shell = inject(ShellService);
|
|
463
|
-
this.#
|
|
456
|
+
this.#dialog = inject(MatDialog);
|
|
464
457
|
this.translate = inject(TranslateService);
|
|
465
458
|
this.id = 'yuv.base.manage-flavor';
|
|
466
459
|
this.label = this.translate.instant('yuv.shell.action.manage-flavor.label');
|
|
@@ -474,15 +467,23 @@ class ManageFlavorsAction extends AbstractContextAction {
|
|
|
474
467
|
};
|
|
475
468
|
}
|
|
476
469
|
#shell;
|
|
477
|
-
#
|
|
470
|
+
#dialog;
|
|
478
471
|
isExecutable(items) {
|
|
479
472
|
const item = items[0];
|
|
480
|
-
|
|
473
|
+
if (!item)
|
|
474
|
+
return of(false);
|
|
475
|
+
const applicableFlavors = item.isFolder
|
|
476
|
+
? this.#shell.getApplicableFolderFlavors()
|
|
477
|
+
: item.content
|
|
478
|
+
? this.#shell.getApplicableDocumentFlavors(item.content.mimeType)
|
|
479
|
+
: [];
|
|
480
|
+
return of(item && !!item.permissions?.writeIndexData && applicableFlavors.length > 0);
|
|
481
481
|
}
|
|
482
482
|
run(items) {
|
|
483
|
-
this.#
|
|
483
|
+
this.#dialog.open(ManageFlavorsComponent, {
|
|
484
484
|
width: '400px',
|
|
485
485
|
maxWidth: '90vw',
|
|
486
|
+
data: items[0]
|
|
486
487
|
});
|
|
487
488
|
return of(true);
|
|
488
489
|
}
|