@tilde-nlp/ngx-common 8.1.39 → 8.1.41
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/tilde-nlp-ngx-common.mjs +152 -197
- package/fesm2022/tilde-nlp-ngx-common.mjs.map +1 -1
- package/index.d.ts +10 -8
- package/package.json +1 -1
- package/static-files/user-config-bridge.html +45 -85
- package/web-components/main.js +24 -24
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, EventEmitter, Component, Input, ViewChild, Output, NgModule, Optional, Inject, Pipe, inject, Directive, HostListener, HostBinding, ViewChildren, input, effect, ElementRef, ContentChild, ContentChildren, InjectionToken, signal, output, computed, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { Injectable, EventEmitter, Component, Input, ViewChild, Output, NgModule, Optional, Inject, Pipe, inject, Directive, HostListener, HostBinding, ViewChildren, input, effect, ElementRef, ContentChild, ContentChildren, InjectionToken, signal, output, computed, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';
|
|
3
3
|
import * as i2 from '@angular/material/icon';
|
|
4
4
|
import { MatIconModule, MatIcon } from '@angular/material/icon';
|
|
5
5
|
import * as i2$1 from '@angular/platform-browser';
|
|
6
6
|
import { Title } from '@angular/platform-browser';
|
|
7
|
-
import { Subject, map, Observable, of, take, BehaviorSubject, tap, forkJoin, takeUntil, finalize, catchError, fromEvent, debounceTime } from 'rxjs';
|
|
7
|
+
import { Subject, map, Observable, of, take, BehaviorSubject, tap, forkJoin, takeUntil, finalize, catchError, fromEvent, debounceTime, ReplaySubject, filter, first } from 'rxjs';
|
|
8
8
|
import * as i1$1 from '@angular/common';
|
|
9
9
|
import { CommonModule, TitleCasePipe, AsyncPipe, DatePipe } from '@angular/common';
|
|
10
10
|
import { FlexLayoutModule } from '@ngbracket/ngx-layout';
|
|
@@ -4416,7 +4416,7 @@ class MultiFunctionalTableComponent {
|
|
|
4416
4416
|
}], tableElementRef: [{
|
|
4417
4417
|
type: ViewChild,
|
|
4418
4418
|
args: [MatTable, { read: ElementRef }]
|
|
4419
|
-
}] }); })();
|
|
4419
|
+
}], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] }); })();
|
|
4420
4420
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MultiFunctionalTableComponent, { className: "MultiFunctionalTableComponent", filePath: "lib/multi-functional-table/multi-functional-table.component.ts", lineNumber: 27 }); })();
|
|
4421
4421
|
|
|
4422
4422
|
class StatusDisplayModule {
|
|
@@ -8519,7 +8519,7 @@ class SubscriptionComponent {
|
|
|
8519
8519
|
CommonModule,
|
|
8520
8520
|
MatButtonModule
|
|
8521
8521
|
], template: "@if(token()){\r\n <!-- narrow type to non null property -->\r\n @let userToken = token()!;\r\n\r\n <h3 class=\"subscription-section-title text-l-semi-bold\">{{ \"SUBSCRIPTION.USER_INFO\" | translate }}</h3>\r\n\r\n <div class=\"subscription-data-row\">\r\n <div class=\"subscription-label\">\r\n <span class=\"label\">{{ \"SUBSCRIPTION.LABEL_NAME\" | translate }}</span>\r\n </div>\r\n\r\n <div class=\"subscription-data\">\r\n <span>{{ userToken.name }}</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"subscription-data-row\">\r\n <div class=\"subscription-label\">\r\n <span class=\"label\">{{ \"SUBSCRIPTION.LABEL_EMAIL\" | translate }}</span>\r\n </div>\r\n\r\n <div class=\"subscription-data\">\r\n <span>{{ userToken.email }}</span>\r\n </div>\r\n </div>\r\n}\r\n\r\n@if(subscription()){\r\n @let currentSubscription = subscription()!;\r\n\r\n <div fxLayout=\"row\" class=\"subscription-data-row\">\r\n <div class=\"subscription-label\">\r\n <span class=\"label\">{{ \"SUBSCRIPTION.LABEL_SUBSCRIPTION_PLAN_ID\" | translate }}</span>\r\n </div>\r\n\r\n <div class=\"subscription-data\">\r\n <ng-container>\r\n <span>\r\n {{ currentSubscription.Label ? currentSubscription.Label : currentSubscription.PlanId }}\r\n\r\n @switch (subscriptionState()) {\r\n @case(subscriptionStates.TRIAL){\r\n <span> ({{ \"SUBSCRIPTION.TRIAL_END_DATE\" | translate: { date: currentSubscription.EndDate | date: \"dd.MM.yyyy.\" } }}) </span>\r\n }\r\n @case (subscriptionStates.ACTIVE) {\r\n @if(currentSubscription.EndDate){\r\n <span> ({{ \"SUBSCRIPTION.END_DATE\" | translate: { date: currentSubscription.EndDate | date: \"dd.MM.yyyy.\" } }}) </span>\r\n }\r\n }\r\n @case (subscriptionStates.ENDED) {\r\n ({{ \"SUBSCRIPTION.END_DATE\" | translate: { date: currentSubscription.EndDate | date: \"dd.MM.yyyy.\" } }})\r\n }\r\n }\r\n </span>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n @if(currentSubscription.EndDate){\r\n <div class=\"subscription-data-row\">\r\n <div class=\"subscription-label\">\r\n <span class=\"label\">{{ \"SUBSCRIPTION.LABEL_SUBSCRIPTION_END_DATE\" | translate }}</span>\r\n </div>\r\n\r\n <div class=\"subscription-data\">\r\n <ng-container>\r\n <span>{{currentSubscription.EndDate | date: \"dd.MM.yyyy\"}}</span>\r\n </ng-container>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if(currentSubscription.Addons?.length){\r\n <div fxLayout=\"row\" class=\"subscription-data-row\">\r\n <div class=\"subscription-label\">\r\n <span class=\"label\">{{ \"SUBSCRIPTION.ADDITIONS_PLUGINS\" | translate }}</span>\r\n </div>\r\n\r\n <div class=\"subscription-data\">\r\n @for (item of currentSubscription.Addons; track $index; let i = $index) {\r\n <span>{{ item.id }}</span>\r\n @if(item.qt>1){\r\n <span> ({{item.qt}})</span>\r\n }\r\n <span> {{ currentSubscription.Addons!.length - 1 > i ? \",\" : \"\" }} </span>\r\n }\r\n </div>\r\n </div>\r\n }\r\n}\r\n\r\n@if(visibleQuotas().length){\r\n <h3 class=\"subscription-section-title text-l-semi-bold\">{{ \"SUBSCRIPTION.LIMITS\" | translate }}</h3>\r\n\r\n @for (currentQuota of visibleQuotas(); track $index) {\r\n <div class=\"subscription-limit-wrapper\">\r\n <mat-progress-bar [value]=\"currentQuota.percentUsed\"></mat-progress-bar>\r\n <div class=\"subscription-limit\">\r\n <span class=\"text-l-semi-bold\">\r\n {{ (\"QUOTA.\" + (currentQuota.quotaType.toString() | uppercase) + (currentQuota.isUnlimited? \"_UNLIMITED\": \"\")) | translate: { used: currentQuota.convertedUsed, limit: currentQuota.convertedLimit, percent: currentQuota.percentUsed} }}\r\n </span>\r\n </div>\r\n </div>\r\n }\r\n}\r\n\r\n<!-- Add some extra info, such as disclaimer etc -->\r\n <ng-content></ng-content>\r\n\r\n<div class=\"subscription-actions-wrapper\">\r\n @if(chargebeeSettings()){\r\n <a mat-flat-button color=\"accent\" class=\"manage-sub-btn button-row-element\" href=\"javascript:void(0)\" data-cb-type=\"portal\" (click)=\"manageClicked()\">\r\n {{ \"SUBSCRIPTION.MANAGE\" | translate }}\r\n </a>\r\n }\r\n @if(contactUsUrl()){\r\n <a mat-stroked-button [attr.href]=\"contactUsUrl()\" target=\"_blank\" color=\"accent\" (click)=\"contactUsClicked()\">{{\"SUBSCRIPTION.CONTACT\" | translate}}</a>\r\n }\r\n</div>\r\n", styles: [":host{display:block}mat-card{margin:1.5rem}.subscription-container:not(.mobile){margin:16px 32px}.subscription-section-title{margin:32px 0 18px}.subscription-data-row{border-bottom:2px solid var(--base-70);margin-bottom:18px;flex-direction:row;display:flex}.subscription-data{color:var(--base-30);word-wrap:break-word;margin-left:.5rem}.subscription-limit-wrapper,.subscription-limit{margin-top:16px}.subscription-actions-wrapper{padding:32px 0 18px;display:flex;flex-direction:row;gap:24px}.subscription-manage-link{text-decoration:none}.subscription-container:not(.mobile,.empty){width:75%}.subscription-label:not(.mobile,.empty){width:35%}.subscription-data:not(.mobile,.empty){width:65%}.untranslated-files-disclaimer{margin-top:16px;margin-bottom:10px;color:var(--base-40)}.no-subscription-message{margin-top:32px;color:var(--base-40)}.contact-sales-btn{text-align:center}.contact-sales-btn:hover{text-decoration:none}\n"] }]
|
|
8522
|
-
}], null,
|
|
8522
|
+
}], null, { token: [{ type: i0.Input, args: [{ isSignal: true, alias: "token", required: true }] }], subscription: [{ type: i0.Input, args: [{ isSignal: true, alias: "subscription", required: true }] }], quota: [{ type: i0.Input, args: [{ isSignal: true, alias: "quota", required: true }] }], visibleQuotaTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleQuotaTypes", required: false }] }], contactUsUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "contactUsUrl", required: false }] }], chargebeeSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "chargebeeSettings", required: false }] }], manageClick: [{ type: i0.Output, args: ["manageClick"] }], contactUsClick: [{ type: i0.Output, args: ["contactUsClick"] }] }); })();
|
|
8523
8523
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SubscriptionComponent, { className: "SubscriptionComponent", filePath: "lib/subscription/subscription.component.ts", lineNumber: 26 }); })();
|
|
8524
8524
|
|
|
8525
8525
|
var AccessibilityFontSizes;
|
|
@@ -9459,22 +9459,14 @@ class CookieConsentComponent {
|
|
|
9459
9459
|
this.destroy.complete();
|
|
9460
9460
|
}
|
|
9461
9461
|
resolveInitialConsentState() {
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
});
|
|
9471
|
-
return;
|
|
9472
|
-
}
|
|
9473
|
-
if (configured) {
|
|
9474
|
-
this.isClosed = true;
|
|
9475
|
-
return;
|
|
9476
|
-
}
|
|
9477
|
-
this.setupTranslations();
|
|
9462
|
+
this.isCookieConsentConfigured()
|
|
9463
|
+
.pipe(tap((isConfigured) => {
|
|
9464
|
+
if (isConfigured) {
|
|
9465
|
+
this.isClosed = true;
|
|
9466
|
+
return;
|
|
9467
|
+
}
|
|
9468
|
+
this.setupTranslations();
|
|
9469
|
+
})).subscribe();
|
|
9478
9470
|
}
|
|
9479
9471
|
injectConsentScript() {
|
|
9480
9472
|
if (!this.script || typeof document === 'undefined') {
|
|
@@ -9501,24 +9493,19 @@ class CookieConsentComponent {
|
|
|
9501
9493
|
return translations[key] ? key : 'en';
|
|
9502
9494
|
}
|
|
9503
9495
|
isCookieConsentConfigured() {
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
return this.applyStoredConsent(snapshot);
|
|
9496
|
+
if (!this.#storage) {
|
|
9497
|
+
return of(false);
|
|
9507
9498
|
}
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
}
|
|
9512
|
-
return this.applyStoredConsent(stored ?? null);
|
|
9499
|
+
return this.#storage?.read().pipe(map((config) => {
|
|
9500
|
+
return this.hasUserHandledConsent(config ?? null);
|
|
9501
|
+
}));
|
|
9513
9502
|
}
|
|
9514
|
-
|
|
9503
|
+
hasUserHandledConsent(config) {
|
|
9515
9504
|
const consent = config?.cookieConsent;
|
|
9516
9505
|
if (!consent?.updatedAt) {
|
|
9517
9506
|
return false;
|
|
9518
9507
|
}
|
|
9519
|
-
|
|
9520
|
-
this.#analytics.cookieConsentGiven(true);
|
|
9521
|
-
}
|
|
9508
|
+
this.#analytics.cookieConsentGiven(true);
|
|
9522
9509
|
return true;
|
|
9523
9510
|
}
|
|
9524
9511
|
persistConsent(accepted) {
|
|
@@ -9531,10 +9518,7 @@ class CookieConsentComponent {
|
|
|
9531
9518
|
accepted,
|
|
9532
9519
|
updatedAt: now,
|
|
9533
9520
|
},
|
|
9534
|
-
});
|
|
9535
|
-
}
|
|
9536
|
-
isPromise(value) {
|
|
9537
|
-
return !!value && typeof value.then === 'function';
|
|
9521
|
+
}).subscribe();
|
|
9538
9522
|
}
|
|
9539
9523
|
static { this.ɵfac = function CookieConsentComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CookieConsentComponent)(); }; }
|
|
9540
9524
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CookieConsentComponent, selectors: [["lib-cookie-consent"]], inputs: { script: "script", privacyPolicyUrl: "privacyPolicyUrl" }, decls: 1, vars: 1, consts: [[1, "cookie-consent-container"], [1, "cookie-consent-content"], [1, "cookie-consent-description", 3, "innerHTML"], [1, "cookie-consent-actions"], ["mat-flat-button", "", 3, "click"], ["mat-stroked-button", "", 3, "click"], [1, "cookie-consent-info"], [1, "cookie-consent-info--privacy", 3, "href"], [1, "cookie-consent-info--details", 3, "click"], [1, "spin"], [1, "cookie-consent--details"]], template: function CookieConsentComponent_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -9598,134 +9582,132 @@ const USER_CONFIG_MESSAGE_UPDATE = 'ngx-user-config:update';
|
|
|
9598
9582
|
const DEFAULT_USER_CONFIG_OPTIONS = {
|
|
9599
9583
|
strategy: UserConfigStrategy.Local,
|
|
9600
9584
|
iframeUrl: DEFAULT_USER_CONFIG_IFRAME_URL,
|
|
9585
|
+
defaultConfig: DEFAULT_USER_CONFIG
|
|
9601
9586
|
};
|
|
9602
9587
|
|
|
9603
|
-
const USER_CONFIG_STORAGE_KEY = 'ngx_common_user_config';
|
|
9604
|
-
|
|
9605
9588
|
const USER_CONFIG_OPTIONS = new InjectionToken('USER_CONFIG_OPTIONS');
|
|
9606
9589
|
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
|
|
9612
|
-
|
|
9613
|
-
|
|
9614
|
-
|
|
9590
|
+
const mergeSection = (defaults, override) => ({
|
|
9591
|
+
...defaults,
|
|
9592
|
+
...(override ?? {}),
|
|
9593
|
+
});
|
|
9594
|
+
const mergeConfigSections = (base, override = {}) => ({
|
|
9595
|
+
accessibility: mergeSection(base.accessibility, override.accessibility),
|
|
9596
|
+
cookieConsent: mergeSection(base.cookieConsent, override.cookieConsent),
|
|
9597
|
+
language: mergeSection(base.language, override.language),
|
|
9598
|
+
metadata: mergeSection(base.metadata, override.metadata),
|
|
9599
|
+
});
|
|
9600
|
+
function createDefaultUserConfig(options) {
|
|
9601
|
+
const override = options.defaultConfig ?? {};
|
|
9602
|
+
return mergeConfigSections(DEFAULT_USER_CONFIG, override);
|
|
9603
|
+
}
|
|
9604
|
+
function mergeUserConfig(current, update, options) {
|
|
9605
|
+
const base = current ?? createDefaultUserConfig(options);
|
|
9606
|
+
const merged = mergeConfigSections(base, update);
|
|
9607
|
+
return {
|
|
9608
|
+
...merged,
|
|
9609
|
+
metadata: {
|
|
9610
|
+
...merged.metadata,
|
|
9611
|
+
updatedAt: new Date().toISOString(),
|
|
9612
|
+
},
|
|
9613
|
+
};
|
|
9614
|
+
}
|
|
9615
|
+
|
|
9616
|
+
class BaseStorageStrategy {
|
|
9617
|
+
constructor(options) {
|
|
9618
|
+
this.options = options;
|
|
9615
9619
|
this.snapshot = signal(null, ...(ngDevMode ? [{ debugName: "snapshot" }] : []));
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
if (!win) {
|
|
9619
|
-
return;
|
|
9620
|
-
}
|
|
9621
|
-
this.#messageHandler = (event) => this.#handleMessage(event);
|
|
9622
|
-
win.addEventListener('message', this.#messageHandler);
|
|
9623
|
-
const cached = this.#readCache();
|
|
9624
|
-
if (cached) {
|
|
9625
|
-
this.snapshot.set(cached);
|
|
9626
|
-
}
|
|
9620
|
+
/** Tracks when the initial data has been fetched from the source */
|
|
9621
|
+
this.isReady$ = new ReplaySubject(1);
|
|
9627
9622
|
}
|
|
9623
|
+
/**
|
|
9624
|
+
* Returns an Observable that waits for the source to be ready,
|
|
9625
|
+
* then emits the current snapshot.
|
|
9626
|
+
*/
|
|
9628
9627
|
read() {
|
|
9629
|
-
return this
|
|
9628
|
+
return this.isReady$.pipe(filter((ready) => ready), first(), map(() => {
|
|
9629
|
+
return this.snapshot();
|
|
9630
|
+
}));
|
|
9630
9631
|
}
|
|
9632
|
+
/**
|
|
9633
|
+
* Waits for readiness, performs a deep merge, updates the local signal,
|
|
9634
|
+
* and triggers the implementation-specific persistence.
|
|
9635
|
+
*/
|
|
9631
9636
|
write(config) {
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9637
|
+
return this.isReady$.pipe(filter((ready) => ready), first(), map(() => {
|
|
9638
|
+
const merged = this.mergeWithBase(config);
|
|
9639
|
+
this.snapshot.set(merged);
|
|
9640
|
+
this.saveToSource(merged);
|
|
9641
|
+
return merged;
|
|
9642
|
+
}));
|
|
9643
|
+
}
|
|
9644
|
+
initialize() {
|
|
9645
|
+
return this.isReady$.pipe(filter((ready) => ready), first(), map(() => null));
|
|
9646
|
+
}
|
|
9647
|
+
mergeWithBase(update) {
|
|
9648
|
+
return mergeUserConfig(this.snapshot(), update, this.options);
|
|
9649
|
+
}
|
|
9650
|
+
createDefaultConfig() {
|
|
9651
|
+
return createDefaultUserConfig(this.options);
|
|
9652
|
+
}
|
|
9653
|
+
static { this.ɵfac = function BaseStorageStrategy_Factory(__ngFactoryType__) { i0.ɵɵinvalidFactory(); }; }
|
|
9654
|
+
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: BaseStorageStrategy, factory: BaseStorageStrategy.ɵfac }); }
|
|
9655
|
+
}
|
|
9656
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(BaseStorageStrategy, [{
|
|
9657
|
+
type: Injectable
|
|
9658
|
+
}], () => [{ type: undefined }], null); })();
|
|
9659
|
+
|
|
9660
|
+
class IframeStorageStrategy extends BaseStorageStrategy {
|
|
9661
|
+
#dom = inject(DOMService);
|
|
9662
|
+
#options = inject(USER_CONFIG_OPTIONS);
|
|
9663
|
+
#iframe;
|
|
9664
|
+
#messageHandler;
|
|
9665
|
+
constructor() {
|
|
9666
|
+
super(inject(USER_CONFIG_OPTIONS));
|
|
9667
|
+
this.#init();
|
|
9668
|
+
}
|
|
9669
|
+
saveToSource(config) {
|
|
9670
|
+
this.#postToBridge({ type: USER_CONFIG_MESSAGE_UPDATE, payload: config });
|
|
9636
9671
|
}
|
|
9637
9672
|
ngOnDestroy() {
|
|
9638
9673
|
if (this.#messageHandler && this.#dom.window) {
|
|
9639
9674
|
this.#dom.window.removeEventListener('message', this.#messageHandler);
|
|
9640
9675
|
}
|
|
9641
9676
|
}
|
|
9642
|
-
#
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
}
|
|
9646
|
-
const win = this.#dom.window;
|
|
9647
|
-
const doc = win?.document;
|
|
9648
|
-
if (!doc) {
|
|
9677
|
+
#init() {
|
|
9678
|
+
const window = this.#dom.window;
|
|
9679
|
+
if (!window) {
|
|
9649
9680
|
return;
|
|
9650
9681
|
}
|
|
9682
|
+
;
|
|
9683
|
+
this.#messageHandler = (event) => this.#handleMessage(event);
|
|
9684
|
+
window.addEventListener('message', this.#messageHandler);
|
|
9685
|
+
const doc = window.document;
|
|
9651
9686
|
const iframe = doc.createElement('iframe');
|
|
9652
9687
|
iframe.style.display = 'none';
|
|
9653
9688
|
iframe.name = USER_CONFIG_IFRAME_NAME;
|
|
9654
9689
|
iframe.src = this.#options?.iframeUrl ?? DEFAULT_USER_CONFIG_IFRAME_URL;
|
|
9655
9690
|
iframe.setAttribute('aria-hidden', 'true');
|
|
9656
|
-
iframe.addEventListener('load', () =>
|
|
9691
|
+
iframe.addEventListener('load', () => {
|
|
9692
|
+
this.#postToBridge({ type: USER_CONFIG_MESSAGE_REQUEST });
|
|
9693
|
+
});
|
|
9657
9694
|
doc.body?.appendChild(iframe);
|
|
9658
9695
|
this.#iframe = iframe;
|
|
9659
9696
|
}
|
|
9660
9697
|
#handleMessage(event) {
|
|
9661
|
-
if (
|
|
9662
|
-
return;
|
|
9663
|
-
}
|
|
9664
|
-
const data = event.data;
|
|
9665
|
-
if (data?.type === USER_CONFIG_MESSAGE_SNAPSHOT && data.payload) {
|
|
9666
|
-
const snapshot = data.payload;
|
|
9667
|
-
this.#writeCache(snapshot);
|
|
9668
|
-
this.snapshot.set(snapshot);
|
|
9669
|
-
}
|
|
9670
|
-
}
|
|
9671
|
-
#postToBridge(message) {
|
|
9672
|
-
if (!this.#iframe?.contentWindow) {
|
|
9698
|
+
if (event.source !== this.#iframe?.contentWindow) {
|
|
9673
9699
|
return;
|
|
9674
9700
|
}
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
#readCache() {
|
|
9678
|
-
const store = this.#dom.localStorage;
|
|
9679
|
-
if (!store) {
|
|
9680
|
-
return null;
|
|
9681
|
-
}
|
|
9682
|
-
return this.#parse(store.getItem(USER_CONFIG_STORAGE_KEY));
|
|
9683
|
-
}
|
|
9684
|
-
#writeCache(config) {
|
|
9685
|
-
const store = this.#dom.localStorage;
|
|
9686
|
-
if (!store) {
|
|
9701
|
+
const messageData = event.data;
|
|
9702
|
+
if (messageData?.type !== USER_CONFIG_MESSAGE_SNAPSHOT) {
|
|
9687
9703
|
return;
|
|
9688
9704
|
}
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
catch {
|
|
9693
|
-
/* noop */
|
|
9694
|
-
}
|
|
9705
|
+
const data = messageData?.payload ?? this.createDefaultConfig();
|
|
9706
|
+
this.snapshot.set(data);
|
|
9707
|
+
this.isReady$.next(true);
|
|
9695
9708
|
}
|
|
9696
|
-
#
|
|
9697
|
-
|
|
9698
|
-
return null;
|
|
9699
|
-
}
|
|
9700
|
-
try {
|
|
9701
|
-
return JSON.parse(raw);
|
|
9702
|
-
}
|
|
9703
|
-
catch {
|
|
9704
|
-
return DEFAULT_USER_CONFIG;
|
|
9705
|
-
}
|
|
9706
|
-
}
|
|
9707
|
-
#mergeWithBase(update) {
|
|
9708
|
-
const base = this.snapshot() ?? this.read() ?? DEFAULT_USER_CONFIG;
|
|
9709
|
-
const mergedMetadata = {
|
|
9710
|
-
...base.metadata,
|
|
9711
|
-
...update.metadata,
|
|
9712
|
-
updatedAt: new Date().toISOString(),
|
|
9713
|
-
};
|
|
9714
|
-
return {
|
|
9715
|
-
accessibility: {
|
|
9716
|
-
...base.accessibility,
|
|
9717
|
-
...update.accessibility,
|
|
9718
|
-
},
|
|
9719
|
-
cookieConsent: {
|
|
9720
|
-
...base.cookieConsent,
|
|
9721
|
-
...update.cookieConsent,
|
|
9722
|
-
},
|
|
9723
|
-
language: {
|
|
9724
|
-
...base.language,
|
|
9725
|
-
...update.language,
|
|
9726
|
-
},
|
|
9727
|
-
metadata: mergedMetadata,
|
|
9728
|
-
};
|
|
9709
|
+
#postToBridge(message) {
|
|
9710
|
+
this.#iframe?.contentWindow?.postMessage(message, USER_CONFIG_IFRAME_TARGET_ORIGIN);
|
|
9729
9711
|
}
|
|
9730
9712
|
static { this.ɵfac = function IframeStorageStrategy_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || IframeStorageStrategy)(); }; }
|
|
9731
9713
|
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: IframeStorageStrategy, factory: IframeStorageStrategy.ɵfac, providedIn: 'root' }); }
|
|
@@ -9735,91 +9717,60 @@ class IframeStorageStrategy {
|
|
|
9735
9717
|
args: [{ providedIn: 'root' }]
|
|
9736
9718
|
}], () => [], null); })();
|
|
9737
9719
|
|
|
9738
|
-
|
|
9739
|
-
|
|
9720
|
+
const USER_CONFIG_STORAGE_KEY = 'ngx_common_user_config';
|
|
9721
|
+
|
|
9722
|
+
class LocalStorageStrategy extends BaseStorageStrategy {
|
|
9723
|
+
#dom = inject(DOMService);
|
|
9740
9724
|
#storageListener;
|
|
9741
9725
|
constructor() {
|
|
9742
|
-
|
|
9743
|
-
this
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9750
|
-
return;
|
|
9726
|
+
super(inject(USER_CONFIG_OPTIONS));
|
|
9727
|
+
this.#init();
|
|
9728
|
+
}
|
|
9729
|
+
saveToSource(config) {
|
|
9730
|
+
const store = this.#dom.localStorage;
|
|
9731
|
+
if (store) {
|
|
9732
|
+
try {
|
|
9733
|
+
store.setItem(USER_CONFIG_STORAGE_KEY, JSON.stringify(config));
|
|
9751
9734
|
}
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
this.snapshot.set(parsed);
|
|
9735
|
+
catch (exception) {
|
|
9736
|
+
console.error('Failed to save user config to localStorage', exception);
|
|
9755
9737
|
}
|
|
9756
|
-
};
|
|
9757
|
-
win.addEventListener('storage', this.#storageListener);
|
|
9758
|
-
const current = this.read();
|
|
9759
|
-
if (current) {
|
|
9760
|
-
this.snapshot.set(current);
|
|
9761
9738
|
}
|
|
9762
9739
|
}
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
return null;
|
|
9740
|
+
ngOnDestroy() {
|
|
9741
|
+
if (this.#storageListener && this.#dom.window) {
|
|
9742
|
+
this.#dom.window.removeEventListener('storage', this.#storageListener);
|
|
9767
9743
|
}
|
|
9768
|
-
return this.#parse(store.getItem(USER_CONFIG_STORAGE_KEY));
|
|
9769
9744
|
}
|
|
9770
|
-
|
|
9745
|
+
#init() {
|
|
9746
|
+
const win = this.#dom.window;
|
|
9771
9747
|
const store = this.#dom.localStorage;
|
|
9772
|
-
if (
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
}
|
|
9780
|
-
catch {
|
|
9781
|
-
/* noop */
|
|
9748
|
+
if (win) {
|
|
9749
|
+
this.#storageListener = (event) => {
|
|
9750
|
+
if (event.key === USER_CONFIG_STORAGE_KEY && event.newValue) {
|
|
9751
|
+
this.snapshot.set(this.#parse(event.newValue));
|
|
9752
|
+
}
|
|
9753
|
+
};
|
|
9754
|
+
win.addEventListener('storage', this.#storageListener);
|
|
9782
9755
|
}
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
this.#dom.window.removeEventListener('storage', this.#storageListener);
|
|
9756
|
+
if (store) {
|
|
9757
|
+
const raw = store.getItem(USER_CONFIG_STORAGE_KEY);
|
|
9758
|
+
this.snapshot.set(this.#parse(raw));
|
|
9787
9759
|
}
|
|
9760
|
+
// LocalStorage is available immediately
|
|
9761
|
+
this.isReady$.next(true);
|
|
9788
9762
|
}
|
|
9789
9763
|
#parse(raw) {
|
|
9790
9764
|
if (!raw) {
|
|
9791
|
-
return
|
|
9765
|
+
return this.createDefaultConfig();
|
|
9792
9766
|
}
|
|
9793
9767
|
try {
|
|
9794
9768
|
return JSON.parse(raw);
|
|
9795
9769
|
}
|
|
9796
9770
|
catch {
|
|
9797
|
-
return
|
|
9771
|
+
return this.createDefaultConfig();
|
|
9798
9772
|
}
|
|
9799
9773
|
}
|
|
9800
|
-
#mergeWithBase(update) {
|
|
9801
|
-
const base = this.snapshot() ?? this.read() ?? DEFAULT_USER_CONFIG;
|
|
9802
|
-
const mergedMetadata = {
|
|
9803
|
-
...base.metadata,
|
|
9804
|
-
...update.metadata,
|
|
9805
|
-
updatedAt: new Date().toISOString(),
|
|
9806
|
-
};
|
|
9807
|
-
return {
|
|
9808
|
-
accessibility: {
|
|
9809
|
-
...base.accessibility,
|
|
9810
|
-
...update.accessibility,
|
|
9811
|
-
},
|
|
9812
|
-
cookieConsent: {
|
|
9813
|
-
...base.cookieConsent,
|
|
9814
|
-
...update.cookieConsent,
|
|
9815
|
-
},
|
|
9816
|
-
language: {
|
|
9817
|
-
...base.language,
|
|
9818
|
-
...update.language,
|
|
9819
|
-
},
|
|
9820
|
-
metadata: mergedMetadata,
|
|
9821
|
-
};
|
|
9822
|
-
}
|
|
9823
9774
|
static { this.ɵfac = function LocalStorageStrategy_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LocalStorageStrategy)(); }; }
|
|
9824
9775
|
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: LocalStorageStrategy, factory: LocalStorageStrategy.ɵfac, providedIn: 'root' }); }
|
|
9825
9776
|
}
|
|
@@ -9862,6 +9813,10 @@ function provideUserConfig(options = {}) {
|
|
|
9862
9813
|
useFactory: userConfigStorageFactory,
|
|
9863
9814
|
deps: [USER_CONFIG_OPTIONS],
|
|
9864
9815
|
},
|
|
9816
|
+
provideAppInitializer(() => {
|
|
9817
|
+
const storage = inject(USER_CONFIG_STORAGE);
|
|
9818
|
+
return storage.initialize();
|
|
9819
|
+
})
|
|
9865
9820
|
]);
|
|
9866
9821
|
}
|
|
9867
9822
|
|