@yuuvis/client-framework 2.4.4 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/common/lib/components/busy-overlay/busy-overlay.component.d.ts +10 -0
- package/common/lib/components/busy-overlay/busy-overlay.interface.d.ts +4 -0
- package/common/lib/components/dialog/dialog.component.d.ts +5 -1
- package/common/lib/components/index.d.ts +1 -0
- package/common/lib/directives/busy-overlay.directive.d.ts +51 -13
- package/fesm2022/yuuvis-client-framework-actions.mjs +1 -1
- package/fesm2022/yuuvis-client-framework-actions.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-common.mjs +166 -74
- package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-forms.mjs +27 -13
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-details.mjs +28 -32
- package/fesm2022/yuuvis-client-framework-object-details.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs +2 -2
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs +3 -3
- package/fesm2022/yuuvis-client-framework-object-relationship.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-summary.mjs +1 -1
- package/fesm2022/yuuvis-client-framework-object-summary.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-versions.mjs +1 -1
- package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tile-list.mjs +1 -1
- package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-widget-grid.mjs +2 -2
- package/fesm2022/yuuvis-client-framework-widget-grid.mjs.map +1 -1
- package/forms/lib/elements/catalog/catalog.component.d.ts +4 -1
- package/forms/lib/elements/data-grid/model/data-grid.interface.d.ts +6 -0
- package/object-details/lib/object-details-header/object-details-header.component.d.ts +9 -7
- package/object-details/lib/object-details-shell/object-details-shell.component.d.ts +3 -1
- package/object-details/lib/object-details.component.d.ts +3 -1
- package/object-details/lib/object-metadata/object-metadata.component.d.ts +2 -2
- package/package.json +16 -16
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, ChangeDetectionStrategy, Component, inject, ElementRef, Input, Directive, computed,
|
|
2
|
+
import { input, ChangeDetectionStrategy, Component, inject, ElementRef, Input, Directive, computed, effect, output, signal, EnvironmentInjector, ViewContainerRef, EventEmitter, HostListener, Output, NgZone, contentChildren, HostBinding, forwardRef, NgModule, Injectable } from '@angular/core';
|
|
3
3
|
import { CommonModule, DOCUMENT } from '@angular/common';
|
|
4
4
|
import { MatButtonModule } from '@angular/material/button';
|
|
5
5
|
import * as i2 from '@angular/material/dialog';
|
|
6
6
|
import { MatDialogActions, MatDialogTitle, MatDialogContent, MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
|
|
7
7
|
import * as i1 from '@ngx-translate/core';
|
|
8
8
|
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
9
|
-
import { YmtButtonDirective } from '@yuuvis/material';
|
|
9
|
+
import { YmtButtonDirective, YmtIconButtonDirective } from '@yuuvis/material';
|
|
10
10
|
import { TranslateModule as TranslateModule$1, Utils, RetentionService, LocaleDatePipe } from '@yuuvis/client-core';
|
|
11
11
|
import { MatProgressSpinner } from '@angular/material/progress-spinner';
|
|
12
|
+
import * as i1$1 from '@angular/material/icon';
|
|
13
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
12
14
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
13
15
|
import { Subject, fromEvent, merge, timer, of } from 'rxjs';
|
|
14
16
|
import { debounceTime, tap, filter, switchMap, map, takeUntil } from 'rxjs/operators';
|
|
15
17
|
import { NG_VALUE_ACCESSOR, NgControl, FormControlDirective, FormControlName, NgModel } from '@angular/forms';
|
|
16
18
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
17
|
-
import * as i2$1 from '@angular/material/icon';
|
|
18
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
19
19
|
|
|
20
20
|
class DialogComponent {
|
|
21
21
|
constructor() {
|
|
22
|
+
this.headertitle = input(null);
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated use headertitle instead
|
|
25
|
+
*/
|
|
22
26
|
this.headertitel = input(null);
|
|
23
27
|
}
|
|
24
28
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
25
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: DialogComponent, isStandalone: true, selector: "yuv-dialog", inputs: { headertitel: { classPropertyName: "headertitel", publicName: "headertitel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
26
|
-
@let title = headertitel();
|
|
29
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: DialogComponent, isStandalone: true, selector: "yuv-dialog", inputs: { headertitle: { classPropertyName: "headertitle", publicName: "headertitle", isSignal: true, isRequired: false, transformFunction: null }, headertitel: { classPropertyName: "headertitel", publicName: "headertitel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
30
|
+
@let title = headertitle() ?? headertitel();
|
|
27
31
|
@if (title) {
|
|
28
32
|
<h2 mat-dialog-title>{{ title }}</h2>
|
|
29
33
|
}
|
|
@@ -39,7 +43,7 @@ class DialogComponent {
|
|
|
39
43
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DialogComponent, decorators: [{
|
|
40
44
|
type: Component,
|
|
41
45
|
args: [{ selector: 'yuv-dialog', imports: [TranslateModule, MatDialogActions, MatDialogTitle, MatDialogContent], template: `
|
|
42
|
-
@let title = headertitel();
|
|
46
|
+
@let title = headertitle() ?? headertitel();
|
|
43
47
|
@if (title) {
|
|
44
48
|
<h2 mat-dialog-title>{{ title }}</h2>
|
|
45
49
|
}
|
|
@@ -58,7 +62,7 @@ class ConfirmComponent {
|
|
|
58
62
|
this.dialogData = inject(MAT_DIALOG_DATA);
|
|
59
63
|
}
|
|
60
64
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
61
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ConfirmComponent, isStandalone: true, selector: "yuv-confirm", ngImport: i0, template: "<yuv-dialog [headertitel]=\"dialogData.title || ''\">\n <main>{{ dialogData.message }}</main>\n <footer>\n @if (!dialogData.hideCancelButton) {\n <button ymtButton=\"secondary\" mat-dialog-close type=\"button\">\n {{ dialogData.cancelLabel || ('yuv.confirm.cancel' | translate) }}\n </button>\n }\n <button ymtButton=\"primary\" type=\"button\" [mat-dialog-close]=\"true\">{{ dialogData.confirmLabel || ('yuv.confirm.confirm' | translate) }}</button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{padding:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }] }); }
|
|
65
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ConfirmComponent, isStandalone: true, selector: "yuv-confirm", ngImport: i0, template: "<yuv-dialog [headertitel]=\"dialogData.title || ''\">\n <main>{{ dialogData.message }}</main>\n <footer>\n @if (!dialogData.hideCancelButton) {\n <button ymtButton=\"secondary\" mat-dialog-close type=\"button\">\n {{ dialogData.cancelLabel || ('yuv.confirm.cancel' | translate) }}\n </button>\n }\n <button ymtButton=\"primary\" type=\"button\" [mat-dialog-close]=\"true\">{{ dialogData.confirmLabel || ('yuv.confirm.confirm' | translate) }}</button>\n </footer>\n</yuv-dialog>\n", styles: [":host{display:contents}:host main{padding:var(--ymt-spacing-m)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitle", "headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }] }); }
|
|
62
66
|
}
|
|
63
67
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ConfirmComponent, decorators: [{
|
|
64
68
|
type: Component,
|
|
@@ -138,108 +142,196 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
138
142
|
}]
|
|
139
143
|
}] });
|
|
140
144
|
|
|
145
|
+
class BusyOverlayComponent {
|
|
146
|
+
constructor() {
|
|
147
|
+
this.config = input();
|
|
148
|
+
this.error = input(undefined);
|
|
149
|
+
this.x = effect(() => {
|
|
150
|
+
console.log('BusyOverlayComponent error changed:', this.error());
|
|
151
|
+
});
|
|
152
|
+
this.errorDismiss = output();
|
|
153
|
+
}
|
|
154
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: BusyOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
155
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: BusyOverlayComponent, isStandalone: true, selector: "yuv-busy-overlay", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { errorDismiss: "errorDismiss" }, host: { properties: { "class.error": "!!error()", "class.blured": "!!config()?.blur", "style.--backdrop-background": "config()?.backdropColor || \"var(--ymt-surface-app)\"" } }, ngImport: i0, template: "<div class=\"backdrop\"></div>\n\n@let e = error();\n@if (e) {\n <div class=\"error\">\n <button ymtIconButton icon-button-size=\"small\" (click)=\"errorDismiss.emit()\">\n <mat-icon>close</mat-icon>\n </button>\n <p>{{ e }}</p>\n </div>\n} @else {\n <mat-progress-spinner class=\"ymt-progress-spinner--giant\" [mode]=\"'indeterminate'\"></mat-progress-spinner>\n}\n", styles: [":host{position:absolute;transition:opacity .2s;inset:0;display:grid;place-items:center;z-index:5}:host.blured{backdrop-filter:blur(2px)}:host{--mdc-circular-progress-active-indicator-color: currentColor}:host .error,:host mat-progress-spinner{opacity:0;animation:fadeIn .2s ease-in forwards;animation-delay:.2s}:host .error{display:flex;flex-direction:column;background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);border:var(--ymt-danger);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-corner-xs);max-width:60ch;margin:var(--ymt-spacing-m);overflow-y:auto;align-items:end}:host .error p{margin:var(--ymt-spacing-m)}:host .backdrop{position:absolute;inset:0;background-color:rgb(from var(--backdrop-background) r g b/.5);animation:fadeIn .2s ease-in}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
|
|
156
|
+
}
|
|
157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: BusyOverlayComponent, decorators: [{
|
|
158
|
+
type: Component,
|
|
159
|
+
args: [{ selector: 'yuv-busy-overlay', imports: [CommonModule,
|
|
160
|
+
YmtIconButtonDirective,
|
|
161
|
+
MatIconModule,
|
|
162
|
+
MatProgressSpinner], host: {
|
|
163
|
+
'[class.error]': '!!error()',
|
|
164
|
+
'[class.blured]': '!!config()?.blur',
|
|
165
|
+
'[style.--backdrop-background]': 'config()?.backdropColor || "var(--ymt-surface-app)"'
|
|
166
|
+
}, template: "<div class=\"backdrop\"></div>\n\n@let e = error();\n@if (e) {\n <div class=\"error\">\n <button ymtIconButton icon-button-size=\"small\" (click)=\"errorDismiss.emit()\">\n <mat-icon>close</mat-icon>\n </button>\n <p>{{ e }}</p>\n </div>\n} @else {\n <mat-progress-spinner class=\"ymt-progress-spinner--giant\" [mode]=\"'indeterminate'\"></mat-progress-spinner>\n}\n", styles: [":host{position:absolute;transition:opacity .2s;inset:0;display:grid;place-items:center;z-index:5}:host.blured{backdrop-filter:blur(2px)}:host{--mdc-circular-progress-active-indicator-color: currentColor}:host .error,:host mat-progress-spinner{opacity:0;animation:fadeIn .2s ease-in forwards;animation-delay:.2s}:host .error{display:flex;flex-direction:column;background-color:var(--ymt-danger-container);color:var(--ymt-on-danger-container);border:var(--ymt-danger);padding:var(--ymt-spacing-xs);border-radius:var(--ymt-corner-xs);max-width:60ch;margin:var(--ymt-spacing-m);overflow-y:auto;align-items:end}:host .error p{margin:var(--ymt-spacing-m)}:host .backdrop{position:absolute;inset:0;background-color:rgb(from var(--backdrop-background) r g b/.5);animation:fadeIn .2s ease-in}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}\n"] }]
|
|
167
|
+
}] });
|
|
168
|
+
|
|
141
169
|
/**
|
|
142
170
|
* A directive that will overlay its host component with a translucent background
|
|
143
171
|
* and a loading spinner once the condition resolves with true. This is useful for example to
|
|
144
172
|
* prevent user intercation while component data is loading or some processing is done.
|
|
145
173
|
*
|
|
146
|
-
* It'll also
|
|
147
|
-
* all elements inside (like buttons, inputs etc.)
|
|
174
|
+
* It'll also prevent the overlayed element from beiong interacted with.
|
|
148
175
|
*
|
|
149
|
-
*
|
|
150
|
-
* <div class="
|
|
176
|
+
* ```html
|
|
177
|
+
* <div class="data-panel" [yuvBusyOverlay]="isLoadingData">...</div>
|
|
178
|
+
* ```
|
|
179
|
+
* Setting a `yuvBusyError` will replace the loading spinner by the provided error message.
|
|
180
|
+
* You need to keep the `yuvBusyOverlay` condition true to show the error.
|
|
181
|
+
* The error element rendered has a dismiss/close action that trigger the `yuvBusyErrorDismiss`
|
|
182
|
+
* output event, that you then can use to set the busy condition to false.
|
|
183
|
+
*
|
|
184
|
+
* ```html
|
|
185
|
+
* <div class="result-list"
|
|
186
|
+
* [yuvBusyOverlay]="waitingForServerResponse"
|
|
187
|
+
* (yuvBusyErrorDismiss)="waitingForServerResponse = false"
|
|
188
|
+
* [yuvBusyError]="errorMessage">
|
|
189
|
+
* ...
|
|
190
|
+
* </div>
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* ```ts
|
|
194
|
+
* // in your component code
|
|
195
|
+
* this.waitingForServerResponse = true;
|
|
196
|
+
* fetchData().subscribe({
|
|
197
|
+
* next: (data) => {
|
|
198
|
+
* ...
|
|
199
|
+
* this.waitingForServerResponse = false;
|
|
200
|
+
* }
|
|
201
|
+
* error: (err) => {
|
|
202
|
+
* this.errorMessage = 'Failed to load data from server: ' + err.message;
|
|
203
|
+
* }
|
|
204
|
+
* });
|
|
205
|
+
* ```
|
|
151
206
|
*
|
|
152
207
|
*/
|
|
153
208
|
class BusyOverlayDirective {
|
|
154
209
|
constructor() {
|
|
155
|
-
this
|
|
210
|
+
this.#initialStylePosition = signal('initial');
|
|
211
|
+
this.stylePosition = signal(this.#initialStylePosition());
|
|
156
212
|
this.#elRef = inject(ElementRef);
|
|
157
213
|
this.#environmentInjector = inject(EnvironmentInjector);
|
|
158
|
-
this.#
|
|
159
|
-
|
|
214
|
+
this.#vcRef = inject(ViewContainerRef);
|
|
215
|
+
/**
|
|
216
|
+
* The Boolean expression to evaluate as the condition for showing the busy overlay
|
|
217
|
+
*/
|
|
218
|
+
this.yuvBusyOverlay = input(false);
|
|
219
|
+
this.#yuvBusyOverlayEffect = effect(() => {
|
|
220
|
+
const busy = this.yuvBusyOverlay();
|
|
221
|
+
if (busy === true) {
|
|
222
|
+
this.#addBusyOverlay();
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
this.#removeBusyOverlay();
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
/**
|
|
229
|
+
* Configuration options for the busy overlay. These include
|
|
230
|
+
* e.g. backdrops bacckground color and whether to blur the
|
|
231
|
+
* overlayed content.
|
|
232
|
+
*/
|
|
160
233
|
this.yuvBusyOverlayConfig = input();
|
|
234
|
+
/**
|
|
235
|
+
* Error message to display in the overlay. If set, the loading spinner is replaced by the error message.
|
|
236
|
+
*/
|
|
237
|
+
this.yuvBusyError = input();
|
|
238
|
+
this.#yuvBusyErrorEffect = effect(() => {
|
|
239
|
+
this.#busyOverlayComponentRef?.setInput('error', this.yuvBusyError());
|
|
240
|
+
});
|
|
241
|
+
/**
|
|
242
|
+
* Event emitted when the error message's dismiss action is triggered.
|
|
243
|
+
*/
|
|
244
|
+
this.yuvBusyErrorDismiss = output();
|
|
245
|
+
this.#outputSubscriptions = [];
|
|
161
246
|
}
|
|
247
|
+
#initialStylePosition;
|
|
162
248
|
#elRef;
|
|
163
249
|
#environmentInjector;
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
this.#removeBusyOverlay();
|
|
250
|
+
#vcRef;
|
|
251
|
+
#yuvBusyOverlayEffect;
|
|
252
|
+
#yuvBusyErrorEffect;
|
|
253
|
+
#busyOverlayComponentRef;
|
|
254
|
+
#outputSubscriptions;
|
|
255
|
+
#attachOverlay() {
|
|
256
|
+
if (this.#busyOverlayComponentRef) {
|
|
257
|
+
// Already attached; just refresh inputs/outputs
|
|
258
|
+
this.#applyInputs();
|
|
259
|
+
return;
|
|
175
260
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const componentRef = createComponent(MatProgressSpinner, {
|
|
261
|
+
// Create the component inside the directive’s host
|
|
262
|
+
this.#busyOverlayComponentRef = this.#vcRef.createComponent(BusyOverlayComponent, {
|
|
179
263
|
environmentInjector: this.#environmentInjector
|
|
180
264
|
});
|
|
181
|
-
this.#
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
265
|
+
const node = this.#busyOverlayComponentRef.location.nativeElement;
|
|
266
|
+
this.#elRef.nativeElement.appendChild(node);
|
|
267
|
+
this.#applyInputs();
|
|
268
|
+
this.#bindOutputs();
|
|
269
|
+
this.#busyOverlayComponentRef.changeDetectorRef?.detectChanges?.();
|
|
270
|
+
}
|
|
271
|
+
#detachOverlay() {
|
|
272
|
+
// Unsubscribe outputs first
|
|
273
|
+
this.#outputSubscriptions.forEach((sub) => sub.unsubscribe());
|
|
274
|
+
this.#outputSubscriptions = [];
|
|
275
|
+
// Destroy componentRef and clear container
|
|
276
|
+
if (this.#busyOverlayComponentRef) {
|
|
277
|
+
this.#busyOverlayComponentRef.destroy();
|
|
278
|
+
this.#busyOverlayComponentRef = undefined;
|
|
279
|
+
}
|
|
280
|
+
this.#vcRef.clear();
|
|
281
|
+
}
|
|
282
|
+
#applyInputs() {
|
|
283
|
+
if (!this.#busyOverlayComponentRef)
|
|
284
|
+
return;
|
|
285
|
+
this.#busyOverlayComponentRef.setInput('config', this.yuvBusyOverlayConfig());
|
|
286
|
+
this.#busyOverlayComponentRef.setInput('error', this.yuvBusyError());
|
|
287
|
+
}
|
|
288
|
+
#bindOutputs() {
|
|
289
|
+
if (!this.#busyOverlayComponentRef)
|
|
290
|
+
return;
|
|
291
|
+
// Clean up old subscriptions if re-binding
|
|
292
|
+
this.#outputSubscriptions.forEach((sub) => sub.unsubscribe());
|
|
293
|
+
this.#outputSubscriptions = [];
|
|
294
|
+
const errorDismissOutput = this.#busyOverlayComponentRef.instance.errorDismiss;
|
|
295
|
+
this.#outputSubscriptions.push(errorDismissOutput.subscribe(() => {
|
|
296
|
+
this.yuvBusyErrorDismiss.emit();
|
|
297
|
+
}));
|
|
187
298
|
}
|
|
188
299
|
#addBusyOverlay() {
|
|
189
|
-
this.stylePosition
|
|
190
|
-
|
|
191
|
-
overlay.style.position = 'absolute';
|
|
192
|
-
overlay.style.transition = 'opacity 200ms';
|
|
193
|
-
overlay.style.opacity = '0';
|
|
194
|
-
overlay.style.inset = '0';
|
|
195
|
-
overlay.style.display = 'grid';
|
|
196
|
-
overlay.style.alignItems = 'center';
|
|
197
|
-
overlay.style.justifyContent = 'center';
|
|
198
|
-
overlay.style.zIndex = '5';
|
|
199
|
-
const backdropBackground = this.yuvBusyOverlayConfig()?.backdropColor || 'var(--ymt-surface-app)';
|
|
200
|
-
overlay.style.backgroundColor = `rgb(from ${backdropBackground} r g b / .5)`;
|
|
201
|
-
if (this.yuvBusyOverlayConfig()?.blur) {
|
|
202
|
-
overlay.style.backdropFilter = 'blur(2px)';
|
|
203
|
-
}
|
|
204
|
-
this.#overlayId = `p${Utils.uuid()}`;
|
|
205
|
-
overlay.setAttribute('id', this.#overlayId);
|
|
206
|
-
overlay.append(this.#createSpinner('indeterminate').location.nativeElement);
|
|
207
|
-
const el = this.#elRef.nativeElement;
|
|
208
|
-
el.setAttribute('inert', '');
|
|
209
|
-
el.append(overlay);
|
|
210
|
-
setTimeout(() => {
|
|
211
|
-
overlay.style.opacity = '1';
|
|
212
|
-
});
|
|
300
|
+
this.stylePosition.set('relative');
|
|
301
|
+
this.#attachOverlay();
|
|
213
302
|
}
|
|
214
303
|
#removeBusyOverlay() {
|
|
215
|
-
|
|
304
|
+
if (!this.#busyOverlayComponentRef)
|
|
305
|
+
return;
|
|
306
|
+
const el = this.#busyOverlayComponentRef.location.nativeElement;
|
|
216
307
|
if (el) {
|
|
217
308
|
el.style.opacity = '0';
|
|
218
309
|
setTimeout(() => {
|
|
219
|
-
|
|
310
|
+
this.#detachOverlay();
|
|
311
|
+
this.stylePosition.set(this.#initialStylePosition());
|
|
220
312
|
}, 200);
|
|
221
313
|
}
|
|
222
|
-
this.#elRef.nativeElement.removeAttribute('inert');
|
|
223
|
-
this.#overlayId = null;
|
|
224
314
|
}
|
|
225
315
|
ngOnInit() {
|
|
226
|
-
this.
|
|
316
|
+
this.#initialStylePosition.set(getComputedStyle(this.#elRef.nativeElement).position);
|
|
317
|
+
}
|
|
318
|
+
ngOnDestroy() {
|
|
319
|
+
this.#detachOverlay();
|
|
227
320
|
}
|
|
228
321
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: BusyOverlayDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
229
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.15", type: BusyOverlayDirective, isStandalone: true, selector: "[yuvBusyOverlay]", inputs: { yuvBusyOverlay: { classPropertyName: "yuvBusyOverlay", publicName: "yuvBusyOverlay", isSignal:
|
|
322
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.15", type: BusyOverlayDirective, isStandalone: true, selector: "[yuvBusyOverlay]", inputs: { yuvBusyOverlay: { classPropertyName: "yuvBusyOverlay", publicName: "yuvBusyOverlay", isSignal: true, isRequired: false, transformFunction: null }, yuvBusyOverlayConfig: { classPropertyName: "yuvBusyOverlayConfig", publicName: "yuvBusyOverlayConfig", isSignal: true, isRequired: false, transformFunction: null }, yuvBusyError: { classPropertyName: "yuvBusyError", publicName: "yuvBusyError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { yuvBusyErrorDismiss: "yuvBusyErrorDismiss" }, host: { properties: { "attr.aria-busy": "yuvBusyOverlay() ? \"true\" : \"false\"", "style.position": "stylePosition()" } }, ngImport: i0 }); }
|
|
230
323
|
}
|
|
231
324
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: BusyOverlayDirective, decorators: [{
|
|
232
325
|
type: Directive,
|
|
233
326
|
args: [{
|
|
234
327
|
selector: '[yuvBusyOverlay]',
|
|
235
|
-
standalone: true
|
|
328
|
+
standalone: true,
|
|
329
|
+
host: {
|
|
330
|
+
'[attr.aria-busy]': 'yuvBusyOverlay() ? "true" : "false"',
|
|
331
|
+
'[style.position]': 'stylePosition()'
|
|
332
|
+
}
|
|
236
333
|
}]
|
|
237
|
-
}]
|
|
238
|
-
type: HostBinding,
|
|
239
|
-
args: ['style.position']
|
|
240
|
-
}], yuvBusyOverlay: [{
|
|
241
|
-
type: Input
|
|
242
|
-
}] } });
|
|
334
|
+
}] });
|
|
243
335
|
|
|
244
336
|
/**
|
|
245
337
|
* Fixes the issue of 'click' event beeing triggered on 'doubleclick' by defining new outputs that
|
|
@@ -1231,7 +1323,7 @@ class RetentionBadgeComponent {
|
|
|
1231
1323
|
}
|
|
1232
1324
|
#retention;
|
|
1233
1325
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: RetentionBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1234
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: RetentionBadgeComponent, isStandalone: true, selector: "yuv-retention-badge", inputs: { dmsObject: { classPropertyName: "dmsObject", publicName: "dmsObject", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let rd = retentionData();\n@if (rd.underRetention) {\n <div class=\"badge\">\n <span class=\"badge__icon\">\n <mat-icon class=\"ymt-icon--size-s\">lock_clock</mat-icon>\n </span>\n <span class=\"badge__label\">\n <span class=\"badge__label-truncated\">\n {{\n 'yuv.retention-badge.retain'\n | translate\n : {\n from: rd.start | localeDate: 'shortDate',\n until: rd.end | localeDate: 'shortDate'\n }\n }}\n </span>\n </span>\n </div>\n}\n", styles: [":host{display:contents}:host .badge{font:var(--ymt-font-body-subtle);color:var(--badge-retention-color, var(--ymt-on-surface));display:inline-flex;overflow:hidden;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-s) var(--ymt-spacing-2xs) var(--ymt-spacing-xs);background-color:var(--badge-retention-background, var(--ymt-primary-container));border-radius:var(--ymt-corner-full);gap:var(--ymt-spacing-s)}:host .badge__icon{flex-shrink:0;color:var(--badge-retention-icon-color, var(--ymt-on-primary-container));display:flex;align-items:center;justify-content:center}:host .badge__label{color:var(--badge-retention-color, var(--ymt-on-surface));align-self:stretch;display:flex;align-items:center;justify-content:center;border-top-right-radius:var(--ymt-corner-full);border-bottom-right-radius:var(--ymt-corner-full);overflow:hidden}:host .badge__label-truncated{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "pipe", type: LocaleDatePipe, name: "localeDate" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type:
|
|
1326
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: RetentionBadgeComponent, isStandalone: true, selector: "yuv-retention-badge", inputs: { dmsObject: { classPropertyName: "dmsObject", publicName: "dmsObject", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let rd = retentionData();\n@if (rd.underRetention) {\n <div class=\"badge\">\n <span class=\"badge__icon\">\n <mat-icon class=\"ymt-icon--size-s\">lock_clock</mat-icon>\n </span>\n <span class=\"badge__label\">\n <span class=\"badge__label-truncated\">\n {{\n 'yuv.retention-badge.retain'\n | translate\n : {\n from: rd.start | localeDate: 'shortDate',\n until: rd.end | localeDate: 'shortDate'\n }\n }}\n </span>\n </span>\n </div>\n}\n", styles: [":host{display:contents}:host .badge{font:var(--ymt-font-body-subtle);color:var(--badge-retention-color, var(--ymt-on-surface));display:inline-flex;overflow:hidden;padding:var(--ymt-spacing-2xs) var(--ymt-spacing-s) var(--ymt-spacing-2xs) var(--ymt-spacing-xs);background-color:var(--badge-retention-background, var(--ymt-primary-container));border-radius:var(--ymt-corner-full);gap:var(--ymt-spacing-s)}:host .badge__icon{flex-shrink:0;color:var(--badge-retention-icon-color, var(--ymt-on-primary-container));display:flex;align-items:center;justify-content:center}:host .badge__label{color:var(--badge-retention-color, var(--ymt-on-surface));align-self:stretch;display:flex;align-items:center;justify-content:center;border-top-right-radius:var(--ymt-corner-full);border-bottom-right-radius:var(--ymt-corner-full);overflow:hidden}:host .badge__label-truncated{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "pipe", type: LocaleDatePipe, name: "localeDate" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
|
|
1235
1327
|
}
|
|
1236
1328
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: RetentionBadgeComponent, decorators: [{
|
|
1237
1329
|
type: Component,
|
|
@@ -1260,5 +1352,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
1260
1352
|
* Generated bundle index. Do not edit.
|
|
1261
1353
|
*/
|
|
1262
1354
|
|
|
1263
|
-
export { AbstractMatFormField, AutofocusChildDirective, AutofocusDelayedDirective, BusyOverlayDirective, ClickDoubleDirective, ConfirmComponent, ConfirmService, ContainerSizeDirective, DialogComponent, DialogSize, DragScrollDirective, DragSelectDirective, DragSelectItemDirective, FileDropZoneDirective, FocusWithinDirective, FormTranslateService, LayoutSettingsService, LightDismissDirective, LongPressDirective, NoopValueAccessorDirective, RetentionBadgeComponent, YuvCommonModule, getFirstFocusableChild, getFocusableChildren, injectNgControl };
|
|
1355
|
+
export { AbstractMatFormField, AutofocusChildDirective, AutofocusDelayedDirective, BusyOverlayComponent, BusyOverlayDirective, ClickDoubleDirective, ConfirmComponent, ConfirmService, ContainerSizeDirective, DialogComponent, DialogSize, DragScrollDirective, DragSelectDirective, DragSelectItemDirective, FileDropZoneDirective, FocusWithinDirective, FormTranslateService, LayoutSettingsService, LightDismissDirective, LongPressDirective, NoopValueAccessorDirective, RetentionBadgeComponent, YuvCommonModule, getFirstFocusableChild, getFocusableChildren, injectNgControl };
|
|
1264
1356
|
//# sourceMappingURL=yuuvis-client-framework-common.mjs.map
|