@yuuvis/client-framework 3.4.1 → 3.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/fesm2022/yuuvis-client-framework-datepicker.mjs +2 -2
- package/fesm2022/yuuvis-client-framework-datepicker.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-details.mjs +97 -88
- package/fesm2022/yuuvis-client-framework-object-details.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-preview.mjs +2 -1
- package/fesm2022/yuuvis-client-framework-object-preview.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-renderer.mjs +92 -137
- package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework.mjs +172 -3
- package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
- package/lib/assets/i18n/de.json +7 -0
- package/lib/assets/i18n/en.json +12 -5
- package/package.json +6 -6
- package/types/yuuvis-client-framework-object-details.d.ts +3 -11
- package/types/yuuvis-client-framework-renderer.d.ts +21 -3
- package/types/yuuvis-client-framework.d.ts +121 -2
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable, signal, ChangeDetectionStrategy, Component,
|
|
2
|
+
import { inject, Injectable, ApplicationRef, DestroyRef, signal, ChangeDetectionStrategy, Component, makeEnvironmentProviders, provideAppInitializer, NgZone, NgModule } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
4
|
+
import { SwUpdate } from '@angular/service-worker';
|
|
4
5
|
import { TranslateService } from '@ngx-translate/core';
|
|
6
|
+
import { ConfirmService } from '@yuuvis/client-framework/common';
|
|
7
|
+
import { filter, first, concat, interval, finalize, timer, switchMap, map, debounceTime } from 'rxjs';
|
|
5
8
|
import { AppCacheService, BackendService, UserService, EventService, YuvEventType } from '@yuuvis/client-core';
|
|
6
|
-
import { finalize, timer, switchMap, map, debounceTime } from 'rxjs';
|
|
7
9
|
import * as i1 from '@angular/material/button';
|
|
8
10
|
import { MatButtonModule } from '@angular/material/button';
|
|
9
11
|
import { MatSnackBar, MatSnackBarRef, MAT_SNACK_BAR_DATA, MatSnackBarLabel, MatSnackBarActions, MatSnackBarAction } from '@angular/material/snack-bar';
|
|
@@ -124,6 +126,22 @@ const haloFocusStyles = {
|
|
|
124
126
|
transform: 'translateZ(0)'
|
|
125
127
|
};
|
|
126
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Default interval (in milliseconds) for periodic PWA update checks.
|
|
131
|
+
*
|
|
132
|
+
* After the application stabilizes, {@link PwaUpdateService} polls the service
|
|
133
|
+
* worker for a newer deployed version on this interval. This complements the
|
|
134
|
+
* `VERSION_READY` event, which only fires while the tab is open and the service
|
|
135
|
+
* worker happens to detect a change — long-running sessions would otherwise
|
|
136
|
+
* never learn about a new release.
|
|
137
|
+
*
|
|
138
|
+
* Override via `providePwaUpdate({ checkInterval })`. Set `checkInterval` to `0`
|
|
139
|
+
* to disable polling and rely solely on `VERSION_READY`.
|
|
140
|
+
*
|
|
141
|
+
* @default 6 hours (21600000 milliseconds)
|
|
142
|
+
*/
|
|
143
|
+
const pwaUpdateDefaultCheckInterval = 6 * 60 * 60 * 1000; // 6 hours
|
|
144
|
+
|
|
127
145
|
/**
|
|
128
146
|
* Default session duration (in milliseconds) when no explicit duration is provided.
|
|
129
147
|
*
|
|
@@ -948,6 +966,115 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
948
966
|
type: Injectable
|
|
949
967
|
}] });
|
|
950
968
|
|
|
969
|
+
/**
|
|
970
|
+
* Detects newly deployed versions of the application (PWA) and lets the user
|
|
971
|
+
* decide when to apply them.
|
|
972
|
+
*
|
|
973
|
+
* **Flow (per the Angular `SwUpdate` documentation):**
|
|
974
|
+
* 1. **Check** — listens for the `VERSION_READY` event and, additionally, polls
|
|
975
|
+
* `checkForUpdate()` on an interval once the app is stable. The update is
|
|
976
|
+
* *not* applied automatically.
|
|
977
|
+
* 2. **Ask** — when a new version is ready, prompts the user via the framework
|
|
978
|
+
* {@link ConfirmService} dialog instead of reloading silently.
|
|
979
|
+
* 3. **Apply** — only after the user confirms, calls `activateUpdate()` and then
|
|
980
|
+
* reloads the page so the new version takes effect.
|
|
981
|
+
*
|
|
982
|
+
* The service is a no-op when the service worker is disabled (e.g. dev mode),
|
|
983
|
+
* so it is safe to provide unconditionally.
|
|
984
|
+
*
|
|
985
|
+
* Wire it up via `providePwaUpdate()` in `app.config.ts`. The service worker
|
|
986
|
+
* itself must still be registered separately via `provideServiceWorker(...)`.
|
|
987
|
+
*
|
|
988
|
+
* @see https://angular.dev/ecosystem/service-workers/communications
|
|
989
|
+
*/
|
|
990
|
+
class PwaUpdateService {
|
|
991
|
+
#swUpdate = inject(SwUpdate);
|
|
992
|
+
#confirm = inject(ConfirmService);
|
|
993
|
+
#translate = inject(TranslateService);
|
|
994
|
+
#appRef = inject(ApplicationRef);
|
|
995
|
+
#destroyRef = inject(DestroyRef);
|
|
996
|
+
/** Guards against opening multiple confirm dialogs while one is already open. */
|
|
997
|
+
#prompting = false;
|
|
998
|
+
/**
|
|
999
|
+
* Starts listening for updates. Called automatically by `providePwaUpdate()`.
|
|
1000
|
+
* Does nothing when the service worker is not enabled.
|
|
1001
|
+
*/
|
|
1002
|
+
init(config) {
|
|
1003
|
+
if (!this.#swUpdate.isEnabled) {
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
// 1a. React when the service worker has already downloaded a new version.
|
|
1007
|
+
this.#swUpdate.versionUpdates
|
|
1008
|
+
.pipe(filter((event) => event.type === 'VERSION_READY'), takeUntilDestroyed(this.#destroyRef))
|
|
1009
|
+
.subscribe(() => this.#promptUpdate(config));
|
|
1010
|
+
// 1b. Poll for updates: first once the app is stable, then on an interval.
|
|
1011
|
+
const checkInterval = config?.checkInterval ?? pwaUpdateDefaultCheckInterval;
|
|
1012
|
+
if (checkInterval > 0) {
|
|
1013
|
+
const appStable$ = this.#appRef.isStable.pipe(first((stable) => stable));
|
|
1014
|
+
concat(appStable$, interval(checkInterval))
|
|
1015
|
+
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
1016
|
+
.subscribe(() => void this.checkForUpdate());
|
|
1017
|
+
}
|
|
1018
|
+
// 1c. Offer a reload when the service worker is in a broken, unrecoverable state.
|
|
1019
|
+
this.#swUpdate.unrecoverable
|
|
1020
|
+
.pipe(takeUntilDestroyed(this.#destroyRef))
|
|
1021
|
+
.subscribe(() => this.#promptUpdate(config, true));
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Manually triggers an update check (e.g. from a "check for updates" button).
|
|
1025
|
+
* Resolves to `true` when a new version was found. Network errors are swallowed
|
|
1026
|
+
* and resolve to `false`.
|
|
1027
|
+
*/
|
|
1028
|
+
checkForUpdate() {
|
|
1029
|
+
if (!this.#swUpdate.isEnabled) {
|
|
1030
|
+
return Promise.resolve(false);
|
|
1031
|
+
}
|
|
1032
|
+
return this.#swUpdate.checkForUpdate().catch(() => false);
|
|
1033
|
+
}
|
|
1034
|
+
#promptUpdate(config, unrecoverable = false) {
|
|
1035
|
+
if (this.#prompting) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
this.#prompting = true;
|
|
1039
|
+
const messageKey = unrecoverable
|
|
1040
|
+
? (config?.unrecoverableMessage ?? 'yuv.pwa.update.unrecoverable.message')
|
|
1041
|
+
: (config?.message ?? 'yuv.pwa.update.message');
|
|
1042
|
+
this.#confirm
|
|
1043
|
+
.confirm({
|
|
1044
|
+
title: this.#translate.instant(config?.title ?? 'yuv.pwa.update.title'),
|
|
1045
|
+
message: this.#translate.instant(messageKey),
|
|
1046
|
+
confirmLabel: this.#translate.instant(config?.confirmLabel ?? 'yuv.pwa.update.confirm'),
|
|
1047
|
+
cancelLabel: this.#translate.instant(config?.cancelLabel ?? 'yuv.pwa.update.cancel'),
|
|
1048
|
+
// An unrecoverable worker cannot keep serving the app, so reloading is the only option.
|
|
1049
|
+
hideCancelButton: unrecoverable,
|
|
1050
|
+
level: 'info'
|
|
1051
|
+
})
|
|
1052
|
+
.subscribe((confirmed) => {
|
|
1053
|
+
this.#prompting = false;
|
|
1054
|
+
if (confirmed) {
|
|
1055
|
+
this.#applyUpdate(unrecoverable);
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
#applyUpdate(unrecoverable) {
|
|
1060
|
+
// In an unrecoverable state there is no pending version to activate — just reload.
|
|
1061
|
+
if (unrecoverable) {
|
|
1062
|
+
document.location.reload();
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1065
|
+
void this.#swUpdate
|
|
1066
|
+
.activateUpdate()
|
|
1067
|
+
.catch(() => false)
|
|
1068
|
+
.finally(() => document.location.reload());
|
|
1069
|
+
}
|
|
1070
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: PwaUpdateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1071
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: PwaUpdateService, providedIn: 'root' }); }
|
|
1072
|
+
}
|
|
1073
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: PwaUpdateService, decorators: [{
|
|
1074
|
+
type: Injectable,
|
|
1075
|
+
args: [{ providedIn: 'root' }]
|
|
1076
|
+
}] });
|
|
1077
|
+
|
|
951
1078
|
const SNACK_BAR_DEFAULT_DURATION = 3000;
|
|
952
1079
|
class SnackBarService {
|
|
953
1080
|
#snackBar;
|
|
@@ -1520,6 +1647,48 @@ function provideHaloFocus(config) {
|
|
|
1520
1647
|
]);
|
|
1521
1648
|
}
|
|
1522
1649
|
|
|
1650
|
+
/**
|
|
1651
|
+
* Provides and initializes PWA update detection for the application.
|
|
1652
|
+
*
|
|
1653
|
+
* On startup it boots {@link PwaUpdateService}, which watches for newly deployed
|
|
1654
|
+
* versions of the app and, instead of reloading silently, asks the user to
|
|
1655
|
+
* confirm before activating the update and reloading the page.
|
|
1656
|
+
*
|
|
1657
|
+
* **Detection:** reacts to the service worker `VERSION_READY` event and also
|
|
1658
|
+
* polls `checkForUpdate()` on an interval (default 6 hours) once the app is
|
|
1659
|
+
* stable, so long-running sessions still pick up new releases.
|
|
1660
|
+
*
|
|
1661
|
+
* **Prerequisite:** the service worker must be registered separately via
|
|
1662
|
+
* `provideServiceWorker('ngsw-worker.js', { enabled: !isDevMode() })`. When the
|
|
1663
|
+
* service worker is disabled (e.g. dev mode) this provider is a harmless no-op.
|
|
1664
|
+
*
|
|
1665
|
+
* @param config - Optional configuration (check interval, custom dialog labels/messages).
|
|
1666
|
+
* @returns EnvironmentProviders for the PWA update feature.
|
|
1667
|
+
*
|
|
1668
|
+
* @example
|
|
1669
|
+
* // app.config.ts
|
|
1670
|
+
* export const appConfig: ApplicationConfig = {
|
|
1671
|
+
* providers: [
|
|
1672
|
+
* provideServiceWorker('ngsw-worker.js', { enabled: !isDevMode() }),
|
|
1673
|
+
* providePwaUpdate()
|
|
1674
|
+
* ]
|
|
1675
|
+
* };
|
|
1676
|
+
*
|
|
1677
|
+
* @example
|
|
1678
|
+
* // Custom check interval (1 hour) and labels
|
|
1679
|
+
* providePwaUpdate({
|
|
1680
|
+
* checkInterval: 60 * 60 * 1000,
|
|
1681
|
+
* message: 'A new version is available. Reload now?'
|
|
1682
|
+
* });
|
|
1683
|
+
*/
|
|
1684
|
+
function providePwaUpdate(config) {
|
|
1685
|
+
return makeEnvironmentProviders([
|
|
1686
|
+
provideAppInitializer(() => {
|
|
1687
|
+
inject(PwaUpdateService).init(config);
|
|
1688
|
+
})
|
|
1689
|
+
]);
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1523
1692
|
/**
|
|
1524
1693
|
* Provides and initializes the SessionService at application startup.
|
|
1525
1694
|
*
|
|
@@ -1586,5 +1755,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
1586
1755
|
* Generated bundle index. Do not edit.
|
|
1587
1756
|
*/
|
|
1588
1757
|
|
|
1589
|
-
export { ChannelMessage, HaloFocusService, HaloUtilityService, SessionService, SnackBarComponent, SnackBarService, YuuvisClientFrameworkModule, defaultHaloFocusOffset, haloExcludedElementsInMatFormField, haloFocusNavigationKeys, haloFocusStyles, provideHaloFocus, provideSession, sessionActivityWindowBeforeEnd, sessionDefaultDuration, sessionPopupBeforeEnd };
|
|
1758
|
+
export { ChannelMessage, HaloFocusService, HaloUtilityService, PwaUpdateService, SessionService, SnackBarComponent, SnackBarService, YuuvisClientFrameworkModule, defaultHaloFocusOffset, haloExcludedElementsInMatFormField, haloFocusNavigationKeys, haloFocusStyles, provideHaloFocus, providePwaUpdate, provideSession, pwaUpdateDefaultCheckInterval, sessionActivityWindowBeforeEnd, sessionDefaultDuration, sessionPopupBeforeEnd };
|
|
1590
1759
|
//# sourceMappingURL=yuuvis-client-framework.mjs.map
|