@elite.framework/ng.core 2.0.20 → 2.0.23
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/abstracts/README.md +3 -0
- package/abstracts/index.d.ts +115 -0
- package/constants/README.md +3 -0
- package/constants/index.d.ts +347 -0
- package/directives/index.d.ts +45 -4
- package/fesm2022/elite.framework-ng.core-abstracts.mjs +196 -0
- package/fesm2022/elite.framework-ng.core-abstracts.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-constants.mjs +365 -0
- package/fesm2022/elite.framework-ng.core-constants.mjs.map +1 -0
- package/fesm2022/elite.framework-ng.core-directives.mjs +205 -4
- package/fesm2022/elite.framework-ng.core-directives.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.core-interceptors.mjs +3 -4
- package/fesm2022/elite.framework-ng.core-interceptors.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.core-models.mjs +80 -1
- package/fesm2022/elite.framework-ng.core-models.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.core-pipes.mjs +62 -4
- package/fesm2022/elite.framework-ng.core-pipes.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.core-providers.mjs +155 -6
- package/fesm2022/elite.framework-ng.core-providers.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.core-services.mjs +1728 -45
- package/fesm2022/elite.framework-ng.core-services.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.core-tokens.mjs +37 -2
- package/fesm2022/elite.framework-ng.core-tokens.mjs.map +1 -1
- package/fesm2022/elite.framework-ng.core-utils.mjs +325 -1
- package/fesm2022/elite.framework-ng.core-utils.mjs.map +1 -1
- package/models/index.d.ts +483 -8
- package/package.json +9 -1
- package/pipes/index.d.ts +22 -4
- package/providers/index.d.ts +18 -3
- package/services/index.d.ts +1185 -20
- package/tokens/index.d.ts +36 -18
- package/utils/index.d.ts +94 -1
|
@@ -1,27 +1,68 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Inject,
|
|
3
|
-
import { throwError, catchError, map, BehaviorSubject } from 'rxjs';
|
|
2
|
+
import { Injectable, inject, Inject, InjectionToken, PLATFORM_ID, Optional, isDevMode, SkipSelf, effect, signal, Injector } from '@angular/core';
|
|
3
|
+
import { throwError, catchError, map as map$1, Subject, BehaviorSubject, combineLatest, from, switchMap as switchMap$1, Subscription, of, timer, firstValueFrom, noop as noop$1, lastValueFrom } from 'rxjs';
|
|
4
4
|
import * as i1 from '@angular/common/http';
|
|
5
|
-
import { HttpParams } from '@angular/common/http';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { HttpParams, HttpClient, HttpErrorResponse } from '@angular/common/http';
|
|
6
|
+
import { CORE_OPTIONS, INCUDE_LOCALIZATION_RESOURCES_TOKEN, localizations$, DISABLE_PROJECT_NAME, OTHERS_GROUP, TENANT_KEY, TENANT_NOT_FOUND_BY_NAME, CHECK_AUTHENTICATION_STATE_FN_KEY, APP_INIT_ERROR_HANDLERS } from '@elite.framework/ng.core/tokens';
|
|
7
|
+
import { InternalStore, isFunction, transformStringToArray, isPlainObject, createLocalizer, createLocalizerWithFallback, interpolate, createTreeFromList, BaseTreeNode, createGroupMap, pushValueTo, noop, getPathName, deepMerge, createTokenParser } from '@elite.framework/ng.core/utils';
|
|
8
|
+
import { map, switchMap, tap, take, filter, mapTo, takeUntil, catchError as catchError$1 } from 'rxjs/operators';
|
|
9
|
+
import { isPlatformBrowser, DOCUMENT, registerLocaleData } from '@angular/common';
|
|
8
10
|
import * as i1$1 from '@ngx-translate/core';
|
|
9
11
|
import Swal from 'sweetalert2';
|
|
10
12
|
import * as i2 from '@angular/router';
|
|
11
|
-
import { RouterStateSnapshot } from '@angular/router';
|
|
12
|
-
import { DEFAULT_REDIRECT_KEY } from '@elite.framework/ng.core/models';
|
|
13
|
-
import
|
|
13
|
+
import { RouterStateSnapshot, TitleStrategy, NavigationStart, NavigationError, NavigationEnd, NavigationCancel, Router, PRIMARY_OUTLET } from '@angular/router';
|
|
14
|
+
import { DEFAULT_REDIRECT_KEY, NavItem, UserMenu } from '@elite.framework/ng.core/models';
|
|
15
|
+
import compare from 'just-compare';
|
|
16
|
+
import { toSignal } from '@angular/core/rxjs-interop';
|
|
17
|
+
import { Title } from '@angular/platform-browser';
|
|
18
|
+
import clone from 'just-clone';
|
|
19
|
+
import { AuthService } from '@elite.framework/ng.core/abstracts';
|
|
20
|
+
|
|
21
|
+
const mapToApiUrl = (key) => (apis) => ((key && apis[key]) || apis.default).url || apis.default.url;
|
|
22
|
+
const mapToIssuer = (issuer) => {
|
|
23
|
+
if (!issuer) {
|
|
24
|
+
return issuer;
|
|
25
|
+
}
|
|
26
|
+
return issuer.endsWith('/') ? issuer : issuer + '/';
|
|
27
|
+
};
|
|
28
|
+
class EnvironmentService {
|
|
29
|
+
store = new InternalStore({});
|
|
30
|
+
get createOnUpdateStream() {
|
|
31
|
+
return this.store.sliceUpdate;
|
|
32
|
+
}
|
|
33
|
+
getEnvironment$() {
|
|
34
|
+
return this.store.sliceState(state => state);
|
|
35
|
+
}
|
|
36
|
+
getEnvironment() {
|
|
37
|
+
return this.store.state;
|
|
38
|
+
}
|
|
39
|
+
getApiUrl(key) {
|
|
40
|
+
return mapToApiUrl(key)(this.store.state?.apis);
|
|
41
|
+
}
|
|
42
|
+
getApiUrl$(key) {
|
|
43
|
+
return this.store.sliceState(state => state.apis).pipe(map(mapToApiUrl(key)));
|
|
44
|
+
}
|
|
45
|
+
setState(environment) {
|
|
46
|
+
this.store.set(environment);
|
|
47
|
+
}
|
|
48
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: EnvironmentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
49
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: EnvironmentService, providedIn: 'root' });
|
|
50
|
+
}
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: EnvironmentService, decorators: [{
|
|
52
|
+
type: Injectable,
|
|
53
|
+
args: [{ providedIn: 'root' }]
|
|
54
|
+
}] });
|
|
14
55
|
|
|
15
56
|
class RestService {
|
|
16
57
|
options;
|
|
17
58
|
http;
|
|
18
|
-
environment = inject(
|
|
59
|
+
environment = inject(EnvironmentService);
|
|
19
60
|
constructor(options, http) {
|
|
20
61
|
this.options = options;
|
|
21
62
|
this.http = http;
|
|
22
63
|
}
|
|
23
64
|
getApiFromStore(apiName) {
|
|
24
|
-
return this.environment.
|
|
65
|
+
return this.environment.getApiUrl(apiName);
|
|
25
66
|
}
|
|
26
67
|
handleError(err) {
|
|
27
68
|
// this.httpErrorReporter.reportError(err);
|
|
@@ -98,7 +139,7 @@ class BaseService {
|
|
|
98
139
|
url: url,
|
|
99
140
|
params: params,
|
|
100
141
|
}, { apiName: this.apiName })
|
|
101
|
-
.pipe(map(response => response));
|
|
142
|
+
.pipe(map$1(response => response));
|
|
102
143
|
};
|
|
103
144
|
get = (id) => this.restService.request({
|
|
104
145
|
method: 'GET',
|
|
@@ -536,32 +577,296 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
|
|
|
536
577
|
args: [{ providedIn: 'root' }]
|
|
537
578
|
}], ctorParameters: () => [{ type: i1$1.TranslateService }] });
|
|
538
579
|
|
|
539
|
-
class
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
580
|
+
class ApplicationLocalizationService {
|
|
581
|
+
restService;
|
|
582
|
+
apiName = 'framework';
|
|
583
|
+
get = (input, config) => this.restService.request({
|
|
584
|
+
method: 'GET',
|
|
585
|
+
url: '/api/asp-net-core/framework-application-localizations/get',
|
|
586
|
+
params: { cultureName: input.cultureName, onlyDynamics: input.onlyDynamics },
|
|
587
|
+
}, { apiName: this.apiName, ...config });
|
|
588
|
+
constructor(restService) {
|
|
589
|
+
this.restService = restService;
|
|
544
590
|
}
|
|
545
|
-
|
|
546
|
-
|
|
591
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ApplicationLocalizationService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
592
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ApplicationLocalizationService, providedIn: 'root' });
|
|
593
|
+
}
|
|
594
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ApplicationLocalizationService, decorators: [{
|
|
595
|
+
type: Injectable,
|
|
596
|
+
args: [{
|
|
597
|
+
providedIn: 'root',
|
|
598
|
+
}]
|
|
599
|
+
}], ctorParameters: () => [{ type: RestService }] });
|
|
600
|
+
|
|
601
|
+
class ApplicationConfigurationService {
|
|
602
|
+
restService;
|
|
603
|
+
// apiName = 'framework';
|
|
604
|
+
apiName = '';
|
|
605
|
+
get = (options, config) => this.restService.request({
|
|
606
|
+
method: 'GET',
|
|
607
|
+
url: '/api/framework/application-configuration',
|
|
608
|
+
params: { includeLocalizationResources: options.includeLocalizationResources },
|
|
609
|
+
}, { apiName: this.apiName, ...config });
|
|
610
|
+
constructor(restService) {
|
|
611
|
+
this.restService = restService;
|
|
547
612
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
613
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ApplicationConfigurationService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
614
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ApplicationConfigurationService, providedIn: 'root' });
|
|
615
|
+
}
|
|
616
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ApplicationConfigurationService, decorators: [{
|
|
617
|
+
type: Injectable,
|
|
618
|
+
args: [{
|
|
619
|
+
providedIn: 'root',
|
|
620
|
+
}]
|
|
621
|
+
}], ctorParameters: () => [{ type: RestService }] });
|
|
622
|
+
|
|
623
|
+
class ConfigStateService {
|
|
624
|
+
abpConfigService;
|
|
625
|
+
applicationLocalizationService;
|
|
626
|
+
includeLocalizationResources;
|
|
627
|
+
updateSubject = new Subject();
|
|
628
|
+
store = new InternalStore({});
|
|
629
|
+
uiCultureFromAuthCodeFlow;
|
|
630
|
+
setState(config) {
|
|
631
|
+
this.store.set(config);
|
|
632
|
+
}
|
|
633
|
+
get createOnUpdateStream() {
|
|
634
|
+
return this.store.sliceUpdate;
|
|
635
|
+
}
|
|
636
|
+
constructor(abpConfigService, applicationLocalizationService, includeLocalizationResources) {
|
|
637
|
+
this.abpConfigService = abpConfigService;
|
|
638
|
+
this.applicationLocalizationService = applicationLocalizationService;
|
|
639
|
+
this.includeLocalizationResources = includeLocalizationResources;
|
|
640
|
+
this.initUpdateStream();
|
|
641
|
+
}
|
|
642
|
+
initUpdateStream() {
|
|
643
|
+
this.updateSubject
|
|
644
|
+
.pipe(switchMap(() => this.abpConfigService.get({
|
|
645
|
+
includeLocalizationResources: !!this.includeLocalizationResources,
|
|
646
|
+
})))
|
|
647
|
+
.pipe(switchMap(appState => this.getLocalizationAndCombineWithAppState(appState)))
|
|
648
|
+
.subscribe(res => this.store.set(res));
|
|
649
|
+
}
|
|
650
|
+
getLocalizationAndCombineWithAppState(appState) {
|
|
651
|
+
// debugger
|
|
652
|
+
if (!appState.localization.currentCulture.cultureName) {
|
|
653
|
+
throw new Error('culture name should defined');
|
|
654
|
+
}
|
|
655
|
+
const cultureName = this.uiCultureFromAuthCodeFlow ?? appState.localization.currentCulture.cultureName;
|
|
656
|
+
return this.getlocalizationResource(cultureName).pipe(map(result => ({ ...appState, localization: { ...appState.localization, ...result } })), tap(() => (this.uiCultureFromAuthCodeFlow = undefined)));
|
|
551
657
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
658
|
+
getlocalizationResource(cultureName) {
|
|
659
|
+
return this.applicationLocalizationService.get({
|
|
660
|
+
cultureName: cultureName,
|
|
661
|
+
onlyDynamics: false,
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
refreshAppState() {
|
|
665
|
+
this.updateSubject.next();
|
|
666
|
+
return this.createOnUpdateStream(state => state).pipe(take(1));
|
|
667
|
+
}
|
|
668
|
+
refreshLocalization(lang) {
|
|
669
|
+
if (this.includeLocalizationResources) {
|
|
670
|
+
return this.refreshAppState().pipe(map(() => null));
|
|
671
|
+
}
|
|
672
|
+
return this.getlocalizationResource(lang)
|
|
673
|
+
.pipe(tap(result => this.store.patch({ localization: { ...this.store.state.localization, ...result } })))
|
|
674
|
+
.pipe(map(() => { return null; }));
|
|
675
|
+
}
|
|
676
|
+
getOne$(key) {
|
|
677
|
+
return this.store.sliceState(state => state[key]);
|
|
678
|
+
}
|
|
679
|
+
getOne(key) {
|
|
680
|
+
return this.store.state[key];
|
|
681
|
+
}
|
|
682
|
+
getAll$() {
|
|
683
|
+
return this.store.sliceState(state => state);
|
|
684
|
+
}
|
|
685
|
+
getAll() {
|
|
686
|
+
return this.store.state;
|
|
687
|
+
}
|
|
688
|
+
getDeep$(keys) {
|
|
689
|
+
keys = splitKeys(keys);
|
|
690
|
+
return this.store
|
|
691
|
+
.sliceState(state => state)
|
|
692
|
+
.pipe(map(state => {
|
|
693
|
+
return keys.reduce((acc, val) => {
|
|
694
|
+
if (acc) {
|
|
695
|
+
return acc[val];
|
|
696
|
+
}
|
|
697
|
+
return undefined;
|
|
698
|
+
}, state);
|
|
699
|
+
}));
|
|
700
|
+
}
|
|
701
|
+
getDeep(keys) {
|
|
702
|
+
keys = splitKeys(keys);
|
|
703
|
+
return keys.reduce((acc, val) => {
|
|
704
|
+
if (acc) {
|
|
705
|
+
return acc[val];
|
|
706
|
+
}
|
|
707
|
+
return undefined;
|
|
708
|
+
}, this.store.state);
|
|
709
|
+
}
|
|
710
|
+
getFeature(key) {
|
|
711
|
+
return this.store.state.features?.values?.[key];
|
|
712
|
+
}
|
|
713
|
+
getFeature$(key) {
|
|
714
|
+
return this.store.sliceState(state => state.features?.values?.[key]);
|
|
715
|
+
}
|
|
716
|
+
getFeatures(keys) {
|
|
717
|
+
const { features } = this.store.state;
|
|
718
|
+
if (!features)
|
|
719
|
+
return null;
|
|
720
|
+
return keys.reduce((acc, key) => ({ ...acc, [key]: features.values[key] }), {});
|
|
721
|
+
}
|
|
722
|
+
getFeatures$(keys) {
|
|
723
|
+
return this.store.sliceState(({ features }) => {
|
|
724
|
+
if (!features?.values)
|
|
725
|
+
return null;
|
|
726
|
+
return keys.reduce((acc, key) => ({ ...acc, [key]: features.values[key] }), {});
|
|
556
727
|
});
|
|
557
728
|
}
|
|
558
|
-
|
|
559
|
-
|
|
729
|
+
isFeatureEnabled(key, features) {
|
|
730
|
+
return features.values[key] === 'true';
|
|
731
|
+
}
|
|
732
|
+
getFeatureIsEnabled(key) {
|
|
733
|
+
return this.isFeatureEnabled(key, this.store.state.features);
|
|
734
|
+
}
|
|
735
|
+
getFeatureIsEnabled$(key) {
|
|
736
|
+
return this.store.sliceState(state => this.isFeatureEnabled(key, state.features));
|
|
737
|
+
}
|
|
738
|
+
getSetting(key) {
|
|
739
|
+
return this.store.state.setting?.values?.[key];
|
|
740
|
+
}
|
|
741
|
+
getSetting$(key) {
|
|
742
|
+
return this.store.sliceState(state => state.setting?.values?.[key]);
|
|
743
|
+
}
|
|
744
|
+
getSettings(keyword) {
|
|
745
|
+
const settings = this.store.state.setting?.values || {};
|
|
746
|
+
if (!keyword)
|
|
747
|
+
return settings;
|
|
748
|
+
const keysFound = Object.keys(settings).filter(key => key.indexOf(keyword) > -1);
|
|
749
|
+
return keysFound.reduce((acc, key) => {
|
|
750
|
+
acc[key] = settings[key];
|
|
751
|
+
return acc;
|
|
752
|
+
}, {});
|
|
753
|
+
}
|
|
754
|
+
getSettings$(keyword) {
|
|
755
|
+
return this.store
|
|
756
|
+
.sliceState(state => state.setting?.values)
|
|
757
|
+
.pipe(map((settings = {}) => {
|
|
758
|
+
if (!keyword)
|
|
759
|
+
return settings;
|
|
760
|
+
const keysFound = Object.keys(settings).filter(key => key.indexOf(keyword) > -1);
|
|
761
|
+
return keysFound.reduce((acc, key) => {
|
|
762
|
+
acc[key] = settings[key];
|
|
763
|
+
return acc;
|
|
764
|
+
}, {});
|
|
765
|
+
}));
|
|
766
|
+
}
|
|
767
|
+
getGlobalFeatures() {
|
|
768
|
+
return this.store.state.globalFeatures;
|
|
769
|
+
}
|
|
770
|
+
getGlobalFeatures$() {
|
|
771
|
+
return this.store.sliceState(state => state.globalFeatures);
|
|
772
|
+
}
|
|
773
|
+
isGlobalFeatureEnabled(key, globalFeatures) {
|
|
774
|
+
const features = globalFeatures.enabledFeatures || [];
|
|
775
|
+
return features.some(f => key === f);
|
|
776
|
+
}
|
|
777
|
+
getGlobalFeatureIsEnabled(key) {
|
|
778
|
+
return this.isGlobalFeatureEnabled(key, this.store.state.globalFeatures);
|
|
779
|
+
}
|
|
780
|
+
getGlobalFeatureIsEnabled$(key) {
|
|
781
|
+
return this.store.sliceState(state => this.isGlobalFeatureEnabled(key, state.globalFeatures));
|
|
782
|
+
}
|
|
783
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ConfigStateService, deps: [{ token: ApplicationConfigurationService }, { token: ApplicationLocalizationService }, { token: INCUDE_LOCALIZATION_RESOURCES_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
784
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ConfigStateService, providedIn: 'root' });
|
|
560
785
|
}
|
|
561
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type:
|
|
786
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ConfigStateService, decorators: [{
|
|
562
787
|
type: Injectable,
|
|
563
|
-
args: [{
|
|
564
|
-
|
|
788
|
+
args: [{
|
|
789
|
+
providedIn: 'root',
|
|
790
|
+
}]
|
|
791
|
+
}], ctorParameters: () => [{ type: ApplicationConfigurationService }, { type: ApplicationLocalizationService }, { type: undefined, decorators: [{
|
|
792
|
+
type: Optional
|
|
793
|
+
}, {
|
|
794
|
+
type: Inject,
|
|
795
|
+
args: [INCUDE_LOCALIZATION_RESOURCES_TOKEN]
|
|
796
|
+
}] }] });
|
|
797
|
+
function splitKeys(keys) {
|
|
798
|
+
if (typeof keys === 'string') {
|
|
799
|
+
keys = keys.split('.');
|
|
800
|
+
}
|
|
801
|
+
if (!Array.isArray(keys)) {
|
|
802
|
+
throw new Error('The argument must be a dot string or an string array.');
|
|
803
|
+
}
|
|
804
|
+
return keys;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
class PermissionCheckerService {
|
|
808
|
+
configState;
|
|
809
|
+
constructor(configState) {
|
|
810
|
+
this.configState = configState;
|
|
811
|
+
}
|
|
812
|
+
isPolicyGranted(key, grantedPolicies) {
|
|
813
|
+
if (!key)
|
|
814
|
+
return true;
|
|
815
|
+
const orRegexp = /\|\|/g;
|
|
816
|
+
const andRegexp = /&&/g;
|
|
817
|
+
// TODO: Allow combination of ANDs & ORs
|
|
818
|
+
if (orRegexp.test(key)) {
|
|
819
|
+
const keys = key.split('||').filter(Boolean);
|
|
820
|
+
if (keys.length < 2)
|
|
821
|
+
return false;
|
|
822
|
+
return keys.some(k => this.getPolicy(k.trim(), grantedPolicies));
|
|
823
|
+
}
|
|
824
|
+
else if (andRegexp.test(key)) {
|
|
825
|
+
const keys = key.split('&&').filter(Boolean);
|
|
826
|
+
if (keys.length < 2)
|
|
827
|
+
return false;
|
|
828
|
+
return keys.every(k => this.getPolicy(k.trim(), grantedPolicies));
|
|
829
|
+
}
|
|
830
|
+
return this.getPolicy(key, grantedPolicies);
|
|
831
|
+
}
|
|
832
|
+
getGrantedPolicy$(key) {
|
|
833
|
+
return this.getStream().pipe(map$1(grantedPolicies => this.isPolicyGranted(key, grantedPolicies)));
|
|
834
|
+
}
|
|
835
|
+
isGrantedAsync(permissionName) {
|
|
836
|
+
if (!permissionName)
|
|
837
|
+
return true;
|
|
838
|
+
return this.getGrantedPolicy$(permissionName);
|
|
839
|
+
}
|
|
840
|
+
isGranted(permissionName) {
|
|
841
|
+
if (!permissionName)
|
|
842
|
+
return true;
|
|
843
|
+
return this.getGrantedPolicy(permissionName);
|
|
844
|
+
}
|
|
845
|
+
getGrantedPolicy(key) {
|
|
846
|
+
const policies = this.getSnapshot();
|
|
847
|
+
return this.isPolicyGranted(key, policies);
|
|
848
|
+
}
|
|
849
|
+
getStream() {
|
|
850
|
+
return this.configState.getAll$().pipe(map$1(this.mapToPolicies));
|
|
851
|
+
}
|
|
852
|
+
getSnapshot() {
|
|
853
|
+
return this.mapToPolicies(this.configState.getAll());
|
|
854
|
+
}
|
|
855
|
+
mapToPolicies(applicationConfiguration) {
|
|
856
|
+
return applicationConfiguration?.auth?.grantedPolicies || {};
|
|
857
|
+
}
|
|
858
|
+
getPolicy(key, grantedPolicies) {
|
|
859
|
+
return grantedPolicies[key] || false;
|
|
860
|
+
}
|
|
861
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: PermissionCheckerService, deps: [{ token: ConfigStateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
862
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: PermissionCheckerService, providedIn: 'root' });
|
|
863
|
+
}
|
|
864
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: PermissionCheckerService, decorators: [{
|
|
865
|
+
type: Injectable,
|
|
866
|
+
args: [{
|
|
867
|
+
providedIn: 'root'
|
|
868
|
+
}]
|
|
869
|
+
}], ctorParameters: () => [{ type: ConfigStateService }] });
|
|
565
870
|
|
|
566
871
|
const ngxPermissionsGuard = (route, state) => {
|
|
567
872
|
const guard = inject(NgxPermissionsGuard);
|
|
@@ -620,7 +925,7 @@ class NgxPermissionsGuard {
|
|
|
620
925
|
// EXCEPT check
|
|
621
926
|
if (permissions.except?.length) {
|
|
622
927
|
for (const perm of permissions.except) {
|
|
623
|
-
if (await this.permissions.
|
|
928
|
+
if (await this.permissions.isGranted(perm)) {
|
|
624
929
|
this.handleRedirect(permissions, perm, route, state);
|
|
625
930
|
return false;
|
|
626
931
|
}
|
|
@@ -671,13 +976,13 @@ class NgxPermissionsGuard {
|
|
|
671
976
|
console.warn('Unknown redirect type', resolvedRedirect);
|
|
672
977
|
}
|
|
673
978
|
}
|
|
674
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: NgxPermissionsGuard, deps: [{ token:
|
|
979
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: NgxPermissionsGuard, deps: [{ token: PermissionCheckerService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
675
980
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: NgxPermissionsGuard, providedIn: 'root' });
|
|
676
981
|
}
|
|
677
982
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: NgxPermissionsGuard, decorators: [{
|
|
678
983
|
type: Injectable,
|
|
679
984
|
args: [{ providedIn: 'root' }]
|
|
680
|
-
}], ctorParameters: () => [{ type:
|
|
985
|
+
}], ctorParameters: () => [{ type: PermissionCheckerService }, { type: i2.Router }] });
|
|
681
986
|
|
|
682
987
|
// logger.interface.ts
|
|
683
988
|
var LogLevel;
|
|
@@ -693,13 +998,13 @@ var LogLevel;
|
|
|
693
998
|
// Remove the separate LoggerConfig interface since we're using EnvironmentConfig
|
|
694
999
|
// and extend EnvironmentConfig to include logger-specific properties
|
|
695
1000
|
class LoggerService {
|
|
696
|
-
environment;
|
|
697
1001
|
level = LogLevel.DEBUG;
|
|
698
1002
|
enableConsole = true;
|
|
699
1003
|
prefix = '[App]';
|
|
700
1004
|
timestamp = true;
|
|
701
|
-
|
|
702
|
-
|
|
1005
|
+
environmentService = inject(EnvironmentService);
|
|
1006
|
+
environment = this.environmentService?.getEnvironment();
|
|
1007
|
+
constructor() {
|
|
703
1008
|
// Use environment configuration if provided
|
|
704
1009
|
if (this.environment) {
|
|
705
1010
|
this.configureFromEnvironment(this.environment);
|
|
@@ -786,7 +1091,7 @@ class LoggerService {
|
|
|
786
1091
|
// this.sendToLogRocket(level, message, args);
|
|
787
1092
|
}
|
|
788
1093
|
// Send to backend if apiUrl is available
|
|
789
|
-
if (this.environment?.
|
|
1094
|
+
if (this.environment?.apis.default.url) {
|
|
790
1095
|
// this.http.post(`${this.environment.apiUrl}/logs`, {
|
|
791
1096
|
// level, message, args, timestamp: new Date()
|
|
792
1097
|
// }).subscribe();
|
|
@@ -797,7 +1102,7 @@ class LoggerService {
|
|
|
797
1102
|
console.error('Failed to send log to external service:', error);
|
|
798
1103
|
}
|
|
799
1104
|
}
|
|
800
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LoggerService, deps: [
|
|
1105
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LoggerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
801
1106
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LoggerService, providedIn: 'root' });
|
|
802
1107
|
}
|
|
803
1108
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LoggerService, decorators: [{
|
|
@@ -805,12 +1110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
|
|
|
805
1110
|
args: [{
|
|
806
1111
|
providedIn: 'root'
|
|
807
1112
|
}]
|
|
808
|
-
}], ctorParameters: () => [
|
|
809
|
-
type: Optional
|
|
810
|
-
}, {
|
|
811
|
-
type: Inject,
|
|
812
|
-
args: [ENVIRONMENT]
|
|
813
|
-
}] }] });
|
|
1113
|
+
}], ctorParameters: () => [] });
|
|
814
1114
|
|
|
815
1115
|
class IdParserService {
|
|
816
1116
|
/**
|
|
@@ -1274,9 +1574,1392 @@ class QueryParser {
|
|
|
1274
1574
|
}
|
|
1275
1575
|
}
|
|
1276
1576
|
|
|
1577
|
+
class SessionStateService {
|
|
1578
|
+
configState;
|
|
1579
|
+
localStorageService;
|
|
1580
|
+
store = new InternalStore({});
|
|
1581
|
+
document = inject(DOCUMENT);
|
|
1582
|
+
updateLocalStorage = () => {
|
|
1583
|
+
this.localStorageService.set('abpSession', JSON.stringify(this.store.state), { expires: new Date(new Date().getTime() + 365 * 86400000), path: '/' });
|
|
1584
|
+
};
|
|
1585
|
+
constructor(configState, localStorageService) {
|
|
1586
|
+
this.configState = configState;
|
|
1587
|
+
this.localStorageService = localStorageService;
|
|
1588
|
+
this.init();
|
|
1589
|
+
this.setInitialLanguage();
|
|
1590
|
+
}
|
|
1591
|
+
init() {
|
|
1592
|
+
const session = this.localStorageService.get('abpSession');
|
|
1593
|
+
if (session) {
|
|
1594
|
+
this.store.set(JSON.parse(session));
|
|
1595
|
+
}
|
|
1596
|
+
this.store.sliceUpdate(state => state).subscribe(this.updateLocalStorage);
|
|
1597
|
+
}
|
|
1598
|
+
setInitialLanguage() {
|
|
1599
|
+
const appLanguage = this.getLanguage();
|
|
1600
|
+
this.configState
|
|
1601
|
+
.getDeep$('localization.currentCulture.cultureName')
|
|
1602
|
+
.pipe(filter(cultureName => !!cultureName), take(1))
|
|
1603
|
+
.subscribe(lang => {
|
|
1604
|
+
if (lang.includes(';')) {
|
|
1605
|
+
lang = lang.split(';')[0];
|
|
1606
|
+
}
|
|
1607
|
+
this.setLanguage(lang);
|
|
1608
|
+
});
|
|
1609
|
+
}
|
|
1610
|
+
onLanguageChange$() {
|
|
1611
|
+
return this.store.sliceUpdate(state => state.language);
|
|
1612
|
+
}
|
|
1613
|
+
onTenantChange$() {
|
|
1614
|
+
return this.store.sliceUpdate(state => state.tenant);
|
|
1615
|
+
}
|
|
1616
|
+
getLanguage() {
|
|
1617
|
+
return this.store.state.language;
|
|
1618
|
+
}
|
|
1619
|
+
getLanguage$() {
|
|
1620
|
+
return this.store.sliceState(state => state.language);
|
|
1621
|
+
}
|
|
1622
|
+
getTenant() {
|
|
1623
|
+
return this.store.state.tenant;
|
|
1624
|
+
}
|
|
1625
|
+
getTenant$() {
|
|
1626
|
+
return this.store.sliceState(state => state.tenant);
|
|
1627
|
+
}
|
|
1628
|
+
setTenant(tenant) {
|
|
1629
|
+
if (compare(tenant, this.store.state.tenant))
|
|
1630
|
+
return;
|
|
1631
|
+
this.store.set({ ...this.store.state, tenant });
|
|
1632
|
+
}
|
|
1633
|
+
setState(session) {
|
|
1634
|
+
if (compare(session, this.store.state))
|
|
1635
|
+
return;
|
|
1636
|
+
this.store.set({ ...this.store.state, ...session });
|
|
1637
|
+
}
|
|
1638
|
+
setLanguage(language) {
|
|
1639
|
+
const currentLanguage = this.store.state.language;
|
|
1640
|
+
if (language !== currentLanguage) {
|
|
1641
|
+
this.store.patch({ language });
|
|
1642
|
+
}
|
|
1643
|
+
const currentAttribute = this.document.documentElement.getAttribute('lang');
|
|
1644
|
+
if (language !== currentAttribute) {
|
|
1645
|
+
this.document.documentElement.setAttribute('lang', language);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
get application() {
|
|
1649
|
+
return this.store.state.application;
|
|
1650
|
+
}
|
|
1651
|
+
get user() {
|
|
1652
|
+
return this.store.state.user;
|
|
1653
|
+
}
|
|
1654
|
+
get userId() {
|
|
1655
|
+
return this.user ? this.user.id : 0;
|
|
1656
|
+
}
|
|
1657
|
+
get tenant() {
|
|
1658
|
+
return this.store.state.tenant;
|
|
1659
|
+
}
|
|
1660
|
+
get branch() {
|
|
1661
|
+
return this.store.state.branch;
|
|
1662
|
+
}
|
|
1663
|
+
/* get branchName(): BranchLoginInfoDto {
|
|
1664
|
+
return this._branch ? this.branch.Name : '';
|
|
1665
|
+
|
|
1666
|
+
} */
|
|
1667
|
+
get tenancyName() {
|
|
1668
|
+
return this.store.state.tenant ? this.tenant?.tenancyName : '';
|
|
1669
|
+
}
|
|
1670
|
+
get branchId() {
|
|
1671
|
+
// return this.branch ? this.branch.id : this.configState.Session?.branchId ? this.configState.Session.branchId:null;
|
|
1672
|
+
return this.branch ? this.branch.id : 0;
|
|
1673
|
+
}
|
|
1674
|
+
get tenantId() {
|
|
1675
|
+
return this.tenant ? this.tenant.id : 0;
|
|
1676
|
+
}
|
|
1677
|
+
getShownLoginName() {
|
|
1678
|
+
const userName = this.store.state.user?.userName ?? '';
|
|
1679
|
+
if (!this.multiTenancySide) {
|
|
1680
|
+
return userName;
|
|
1681
|
+
}
|
|
1682
|
+
return (this.store.state.tenant ? this.store.state.tenant.tenancyName : '.') + '\\' + userName;
|
|
1683
|
+
}
|
|
1684
|
+
changeTenantIfNeeded(tenantId) {
|
|
1685
|
+
if (this.isCurrentTenant(tenantId)) {
|
|
1686
|
+
return false;
|
|
1687
|
+
}
|
|
1688
|
+
// this.configState.SetTenantIdCookie(tenantId);
|
|
1689
|
+
location.reload();
|
|
1690
|
+
return true;
|
|
1691
|
+
}
|
|
1692
|
+
isCurrentTenant(tenantId) {
|
|
1693
|
+
let isTenant = tenantId ?? 0 > 0;
|
|
1694
|
+
if (!isTenant && !this.tenant) { // this is host
|
|
1695
|
+
return true;
|
|
1696
|
+
}
|
|
1697
|
+
if (!tenantId && this.tenant) {
|
|
1698
|
+
return false;
|
|
1699
|
+
}
|
|
1700
|
+
else if (tenantId && (!this.tenant || this.tenant.id !== tenantId)) {
|
|
1701
|
+
return false;
|
|
1702
|
+
}
|
|
1703
|
+
return true;
|
|
1704
|
+
}
|
|
1705
|
+
get impersonatorUser() {
|
|
1706
|
+
return this.store.state.impersonatorUser;
|
|
1707
|
+
}
|
|
1708
|
+
get impersonatorUserId() {
|
|
1709
|
+
return this.impersonatorUser ? this.impersonatorUser.id : 0;
|
|
1710
|
+
}
|
|
1711
|
+
get impersonatorTenant() {
|
|
1712
|
+
return this.store.state.impersonatorTenant;
|
|
1713
|
+
}
|
|
1714
|
+
get impersonatorTenancyName() {
|
|
1715
|
+
return this.impersonatorTenant ? this.impersonatorTenant?.tenancyName ?? '' : '';
|
|
1716
|
+
}
|
|
1717
|
+
get impersonatorTenantId() {
|
|
1718
|
+
return this.impersonatorTenant ? this.impersonatorTenant.id : 0;
|
|
1719
|
+
}
|
|
1720
|
+
get multiTenancySide() {
|
|
1721
|
+
// return this.configState.session?.multiTenancySide;
|
|
1722
|
+
return 0;
|
|
1723
|
+
}
|
|
1724
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SessionStateService, deps: [{ token: ConfigStateService }, { token: SsrCookieService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1725
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SessionStateService, providedIn: 'root' });
|
|
1726
|
+
}
|
|
1727
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SessionStateService, decorators: [{
|
|
1728
|
+
type: Injectable,
|
|
1729
|
+
args: [{
|
|
1730
|
+
providedIn: 'root',
|
|
1731
|
+
}]
|
|
1732
|
+
}], ctorParameters: () => [{ type: ConfigStateService }, { type: SsrCookieService }] });
|
|
1733
|
+
|
|
1734
|
+
class LocalizationService {
|
|
1735
|
+
sessionState;
|
|
1736
|
+
injector;
|
|
1737
|
+
configState;
|
|
1738
|
+
latestLang = 'ar';
|
|
1739
|
+
_languageChange$ = new Subject();
|
|
1740
|
+
uiLocalizations$ = new BehaviorSubject(new Map());
|
|
1741
|
+
localizations$ = new BehaviorSubject(new Map());
|
|
1742
|
+
/**
|
|
1743
|
+
* Returns currently selected language
|
|
1744
|
+
* Even though this looks like it's redundant to return the same value as `getLanguage()`,
|
|
1745
|
+
* it's actually not. This could be invoked any time, and the latestLang could be different from the
|
|
1746
|
+
* sessionState.getLanguage() value.
|
|
1747
|
+
*/
|
|
1748
|
+
get currentLanguage() {
|
|
1749
|
+
return this.latestLang || this.sessionState.getLanguage();
|
|
1750
|
+
}
|
|
1751
|
+
get currentLang() {
|
|
1752
|
+
return this.latestLang || this.sessionState.getLanguage();
|
|
1753
|
+
}
|
|
1754
|
+
get currentLang$() {
|
|
1755
|
+
return this.sessionState.getLanguage$();
|
|
1756
|
+
}
|
|
1757
|
+
get languageChange$() {
|
|
1758
|
+
return this._languageChange$.asObservable();
|
|
1759
|
+
}
|
|
1760
|
+
constructor(sessionState, injector, otherInstance, configState) {
|
|
1761
|
+
this.sessionState = sessionState;
|
|
1762
|
+
this.injector = injector;
|
|
1763
|
+
this.configState = configState;
|
|
1764
|
+
if (otherInstance)
|
|
1765
|
+
throw new Error('LocalizationService should have only one instance.');
|
|
1766
|
+
this.listenToSetLanguage();
|
|
1767
|
+
this.initLocalizationValues();
|
|
1768
|
+
this.latestLang = this.sessionState.getLanguage();
|
|
1769
|
+
}
|
|
1770
|
+
initLocalizationValues() {
|
|
1771
|
+
localizations$.subscribe(val => this.addLocalization(val));
|
|
1772
|
+
const legacyResources$ = this.configState.getDeep$('localization.values');
|
|
1773
|
+
const remoteLocalizations$ = this.configState.getDeep$('localization.resources');
|
|
1774
|
+
const currentLanguage$ = this.sessionState.getLanguage$();
|
|
1775
|
+
const uiLocalizations$ = combineLatest([currentLanguage$, this.uiLocalizations$]).pipe(map(([currentLang, localizations]) => localizations.get(currentLang)));
|
|
1776
|
+
combineLatest([legacyResources$, remoteLocalizations$, uiLocalizations$])
|
|
1777
|
+
.pipe(map(([legacy, resource, local]) => {
|
|
1778
|
+
if (!resource) {
|
|
1779
|
+
return null;
|
|
1780
|
+
}
|
|
1781
|
+
const remote = combineLegacyandNewResources(legacy || {}, resource);
|
|
1782
|
+
if (remote) {
|
|
1783
|
+
if (!local) {
|
|
1784
|
+
local = new Map();
|
|
1785
|
+
}
|
|
1786
|
+
Object.entries(remote).forEach(entry => {
|
|
1787
|
+
const resourceName = entry[0];
|
|
1788
|
+
const remoteTexts = entry[1];
|
|
1789
|
+
let resource = local?.get(resourceName) || {};
|
|
1790
|
+
resource = { ...resource, ...remoteTexts };
|
|
1791
|
+
local?.set(resourceName, resource);
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
return local;
|
|
1795
|
+
}), filter(Boolean))
|
|
1796
|
+
.subscribe(val => this.localizations$.next(val));
|
|
1797
|
+
}
|
|
1798
|
+
addLocalization(localizations) {
|
|
1799
|
+
if (!localizations)
|
|
1800
|
+
return;
|
|
1801
|
+
const localizationMap = this.uiLocalizations$.value;
|
|
1802
|
+
localizations.forEach(loc => {
|
|
1803
|
+
const cultureMap = localizationMap.get(loc.culture) || new Map();
|
|
1804
|
+
loc.resources.forEach(res => {
|
|
1805
|
+
let resource = cultureMap.get(res.resourceName) || {};
|
|
1806
|
+
resource = { ...resource, ...res.texts };
|
|
1807
|
+
cultureMap.set(res.resourceName, resource);
|
|
1808
|
+
});
|
|
1809
|
+
localizationMap.set(loc.culture, cultureMap);
|
|
1810
|
+
});
|
|
1811
|
+
this.uiLocalizations$.next(localizationMap);
|
|
1812
|
+
}
|
|
1813
|
+
listenToSetLanguage() {
|
|
1814
|
+
this.sessionState
|
|
1815
|
+
.onLanguageChange$()
|
|
1816
|
+
.pipe(filter(lang => this.configState.getDeep('localization.currentCulture.cultureName') !== lang), switchMap((lang) => this.configState.refreshLocalization(lang).pipe(map(() => lang))), filter(Boolean), switchMap((lang) => from(this.registerLocale(lang).then(() => lang))))
|
|
1817
|
+
.subscribe((lang) => this._languageChange$.next(lang));
|
|
1818
|
+
}
|
|
1819
|
+
registerLocale(locale) {
|
|
1820
|
+
const { registerLocaleFn } = this.injector.get(CORE_OPTIONS);
|
|
1821
|
+
return registerLocaleFn(locale).then(module => {
|
|
1822
|
+
if (module?.default)
|
|
1823
|
+
registerLocaleData(module.default);
|
|
1824
|
+
this.latestLang = locale;
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
/**
|
|
1828
|
+
* Returns an observable localized text with the given interpolation parameters in current language.
|
|
1829
|
+
* @param key Localizaton key to replace with localized text
|
|
1830
|
+
* @param interpolateParams Values to interpolate
|
|
1831
|
+
*/
|
|
1832
|
+
get(key, ...interpolateParams) {
|
|
1833
|
+
return this.configState
|
|
1834
|
+
.getAll$()
|
|
1835
|
+
.pipe(map(state => this.getLocalization(state, key, ...interpolateParams)));
|
|
1836
|
+
}
|
|
1837
|
+
getResource(resourceName) {
|
|
1838
|
+
return this.localizations$.value.get(resourceName);
|
|
1839
|
+
}
|
|
1840
|
+
getResource$(resourceName) {
|
|
1841
|
+
return this.localizations$.pipe(map(res => res.get(resourceName)));
|
|
1842
|
+
}
|
|
1843
|
+
/**
|
|
1844
|
+
* Returns localized text with the given interpolation parameters in current language.
|
|
1845
|
+
* @param key Localization key to replace with localized text
|
|
1846
|
+
* @param interpolateParams Values to intepolate.
|
|
1847
|
+
*/
|
|
1848
|
+
instant(key, ...interpolateParams) {
|
|
1849
|
+
return this.getLocalization(this.configState.getAll(), key, ...interpolateParams);
|
|
1850
|
+
}
|
|
1851
|
+
localize(resourceName, key, defaultValue) {
|
|
1852
|
+
return this.configState.getOne$('localization').pipe(map(createLocalizer), map((localize) => localize(resourceName, key, defaultValue)));
|
|
1853
|
+
}
|
|
1854
|
+
get defaultResourceName() {
|
|
1855
|
+
return this.configState.getAll().localization ? this.configState.getAll().localization.defaultResourceName : 'FrameworkLocalization';
|
|
1856
|
+
}
|
|
1857
|
+
l(key) {
|
|
1858
|
+
const localization = this.configState.getOne('localization');
|
|
1859
|
+
return createLocalizer(localization)(this.defaultResourceName ?? '', key, key);
|
|
1860
|
+
}
|
|
1861
|
+
localizeSync(resourceName, key, defaultValue) {
|
|
1862
|
+
const localization = this.configState.getOne('localization');
|
|
1863
|
+
return createLocalizer(localization)(resourceName, key, defaultValue);
|
|
1864
|
+
}
|
|
1865
|
+
localizeWithFallback(resourceNames, keys, defaultValue) {
|
|
1866
|
+
return this.configState.getOne$('localization').pipe(map(createLocalizerWithFallback), map((localizeWithFallback) => localizeWithFallback(resourceNames, keys, defaultValue)));
|
|
1867
|
+
}
|
|
1868
|
+
localizeWithFallbackSync(resourceNames, keys, defaultValue) {
|
|
1869
|
+
const localization = this.configState.getOne('localization');
|
|
1870
|
+
return createLocalizerWithFallback(localization)(resourceNames, keys, defaultValue);
|
|
1871
|
+
}
|
|
1872
|
+
getLocalization(state, key, ...interpolateParams) {
|
|
1873
|
+
let defaultValue = '';
|
|
1874
|
+
if (!key) {
|
|
1875
|
+
return defaultValue;
|
|
1876
|
+
}
|
|
1877
|
+
if (typeof key !== 'string') {
|
|
1878
|
+
defaultValue = key.defaultValue;
|
|
1879
|
+
key = key.key;
|
|
1880
|
+
}
|
|
1881
|
+
const keys = key.split('::');
|
|
1882
|
+
const warn = (message) => {
|
|
1883
|
+
if (isDevMode())
|
|
1884
|
+
console.warn(message);
|
|
1885
|
+
};
|
|
1886
|
+
if (keys.length < 2) {
|
|
1887
|
+
warn('The localization source separator (::) not found.');
|
|
1888
|
+
return defaultValue || key;
|
|
1889
|
+
}
|
|
1890
|
+
if (!state.localization)
|
|
1891
|
+
return defaultValue || keys[1];
|
|
1892
|
+
const sourceName = keys[0] || state.localization.defaultResourceName;
|
|
1893
|
+
const sourceKey = keys[1];
|
|
1894
|
+
if (sourceName === '_') {
|
|
1895
|
+
return defaultValue || sourceKey;
|
|
1896
|
+
}
|
|
1897
|
+
if (!sourceName) {
|
|
1898
|
+
warn('Localization source name is not specified and the defaultResourceName was not defined!');
|
|
1899
|
+
return defaultValue || sourceKey;
|
|
1900
|
+
}
|
|
1901
|
+
const source = this.localizations$.value.get(sourceName);
|
|
1902
|
+
if (!source) {
|
|
1903
|
+
warn('Could not find localization source: ' + sourceName);
|
|
1904
|
+
return defaultValue || sourceKey;
|
|
1905
|
+
}
|
|
1906
|
+
let localization = source[sourceKey];
|
|
1907
|
+
if (typeof localization === 'undefined') {
|
|
1908
|
+
return defaultValue || sourceKey;
|
|
1909
|
+
}
|
|
1910
|
+
interpolateParams = interpolateParams.filter(params => params != null);
|
|
1911
|
+
if (localization)
|
|
1912
|
+
localization = interpolate(localization, interpolateParams);
|
|
1913
|
+
if (typeof localization !== 'string')
|
|
1914
|
+
localization = '';
|
|
1915
|
+
return localization || defaultValue || key;
|
|
1916
|
+
}
|
|
1917
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalizationService, deps: [{ token: SessionStateService }, { token: i0.Injector }, { token: LocalizationService, optional: true, skipSelf: true }, { token: ConfigStateService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1918
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalizationService, providedIn: 'root' });
|
|
1919
|
+
}
|
|
1920
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalizationService, decorators: [{
|
|
1921
|
+
type: Injectable,
|
|
1922
|
+
args: [{ providedIn: 'root' }]
|
|
1923
|
+
}], ctorParameters: () => [{ type: SessionStateService }, { type: i0.Injector }, { type: LocalizationService, decorators: [{
|
|
1924
|
+
type: Optional
|
|
1925
|
+
}, {
|
|
1926
|
+
type: SkipSelf
|
|
1927
|
+
}] }, { type: ConfigStateService }] });
|
|
1928
|
+
function recursivelyMergeBaseResources(baseResourceName, source) {
|
|
1929
|
+
const item = source[baseResourceName];
|
|
1930
|
+
if (item.baseResources.length === 0) {
|
|
1931
|
+
return item;
|
|
1932
|
+
}
|
|
1933
|
+
return item.baseResources.reduce((acc, baseResource) => {
|
|
1934
|
+
const baseItem = recursivelyMergeBaseResources(baseResource, source);
|
|
1935
|
+
const texts = { ...baseItem.texts, ...item.texts };
|
|
1936
|
+
return { ...acc, texts };
|
|
1937
|
+
}, item);
|
|
1938
|
+
}
|
|
1939
|
+
function mergeResourcesWithBaseResource(resource) {
|
|
1940
|
+
const entities = Object.keys(resource).map(key => {
|
|
1941
|
+
const newValue = recursivelyMergeBaseResources(key, resource);
|
|
1942
|
+
return [key, newValue];
|
|
1943
|
+
});
|
|
1944
|
+
return entities.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
|
|
1945
|
+
}
|
|
1946
|
+
function combineLegacyandNewResources(legacy, resource) {
|
|
1947
|
+
const mergedResource = mergeResourcesWithBaseResource(resource);
|
|
1948
|
+
return Object.entries(mergedResource).reduce((acc, [key, value]) => {
|
|
1949
|
+
return { ...acc, [key]: value.texts };
|
|
1950
|
+
}, legacy);
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
class LocalStorageListenerService {
|
|
1954
|
+
window = inject(DOCUMENT).defaultView;
|
|
1955
|
+
constructor() {
|
|
1956
|
+
this.window?.addEventListener('storage', event => {
|
|
1957
|
+
if (event.key === 'access_token') {
|
|
1958
|
+
const tokenRemoved = event.newValue === null;
|
|
1959
|
+
const tokenAdded = event.oldValue === null && event.newValue !== null;
|
|
1960
|
+
if (tokenRemoved || tokenAdded) {
|
|
1961
|
+
this.window?.location.assign('/');
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1966
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalStorageListenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1967
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalStorageListenerService, providedIn: 'root' });
|
|
1968
|
+
}
|
|
1969
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalStorageListenerService, decorators: [{
|
|
1970
|
+
type: Injectable,
|
|
1971
|
+
args: [{
|
|
1972
|
+
providedIn: 'root',
|
|
1973
|
+
}]
|
|
1974
|
+
}], ctorParameters: () => [] });
|
|
1975
|
+
|
|
1976
|
+
class LocalStorageService {
|
|
1977
|
+
cookieService;
|
|
1978
|
+
constructor(cookieService) {
|
|
1979
|
+
this.cookieService = cookieService;
|
|
1980
|
+
}
|
|
1981
|
+
getItem(key, callback) {
|
|
1982
|
+
if (!this.cookieService) {
|
|
1983
|
+
return '';
|
|
1984
|
+
}
|
|
1985
|
+
var value = this.cookieService.get(key);
|
|
1986
|
+
if (callback) {
|
|
1987
|
+
callback();
|
|
1988
|
+
}
|
|
1989
|
+
return value;
|
|
1990
|
+
}
|
|
1991
|
+
setItem(key, value, callback) {
|
|
1992
|
+
if (!this.cookieService) {
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
if (value === null) {
|
|
1996
|
+
value = undefined;
|
|
1997
|
+
}
|
|
1998
|
+
this.cookieService.set(key, value, { expires: new Date(new Date().getTime() + 365 * 86400000), path: '/' });
|
|
1999
|
+
// debugger
|
|
2000
|
+
if (callback) {
|
|
2001
|
+
callback();
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
removeItem(key, callback) {
|
|
2005
|
+
if (!this.cookieService) {
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
2008
|
+
this.cookieService.delete(key);
|
|
2009
|
+
if (callback) {
|
|
2010
|
+
callback();
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalStorageService, deps: [{ token: SsrCookieService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2014
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalStorageService, providedIn: 'root' });
|
|
2015
|
+
}
|
|
2016
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: LocalStorageService, decorators: [{
|
|
2017
|
+
type: Injectable,
|
|
2018
|
+
args: [{ providedIn: 'root' }]
|
|
2019
|
+
}], ctorParameters: () => [{ type: SsrCookieService }] });
|
|
2020
|
+
|
|
2021
|
+
class FrameworkTitleStrategy extends TitleStrategy {
|
|
2022
|
+
title = inject(Title);
|
|
2023
|
+
localizationService = inject(LocalizationService);
|
|
2024
|
+
disableProjectName = inject(DISABLE_PROJECT_NAME, { optional: true });
|
|
2025
|
+
routerState;
|
|
2026
|
+
langugageChange = toSignal(this.localizationService.languageChange$);
|
|
2027
|
+
constructor() {
|
|
2028
|
+
super();
|
|
2029
|
+
effect(() => {
|
|
2030
|
+
if (this.langugageChange()) {
|
|
2031
|
+
this.updateTitle(this.routerState);
|
|
2032
|
+
}
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
updateTitle(routerState) {
|
|
2036
|
+
this.routerState = routerState;
|
|
2037
|
+
const title = this.buildTitle(routerState);
|
|
2038
|
+
const projectName = this.localizationService.instant({
|
|
2039
|
+
key: '::AppName',
|
|
2040
|
+
defaultValue: 'MyProjectName',
|
|
2041
|
+
});
|
|
2042
|
+
if (!title) {
|
|
2043
|
+
return this.title.setTitle(projectName);
|
|
2044
|
+
}
|
|
2045
|
+
let localizedText = this.localizationService.instant({ key: title, defaultValue: title });
|
|
2046
|
+
if (!this.disableProjectName) {
|
|
2047
|
+
localizedText += ` | ${projectName}`;
|
|
2048
|
+
}
|
|
2049
|
+
this.title.setTitle(localizedText);
|
|
2050
|
+
}
|
|
2051
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: FrameworkTitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2052
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: FrameworkTitleStrategy, providedIn: 'root' });
|
|
2053
|
+
}
|
|
2054
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: FrameworkTitleStrategy, decorators: [{
|
|
2055
|
+
type: Injectable,
|
|
2056
|
+
args: [{
|
|
2057
|
+
providedIn: 'root',
|
|
2058
|
+
}]
|
|
2059
|
+
}], ctorParameters: () => [] });
|
|
2060
|
+
|
|
2061
|
+
const SORT_COMPARE_FUNC = new InjectionToken('SORT_COMPARE_FUNC');
|
|
2062
|
+
function compareFuncFactory() {
|
|
2063
|
+
const localizationService = inject(LocalizationService);
|
|
2064
|
+
const fn = (a, b) => {
|
|
2065
|
+
const aNumber = a.order;
|
|
2066
|
+
const bNumber = b.order;
|
|
2067
|
+
if (aNumber > bNumber)
|
|
2068
|
+
return 1;
|
|
2069
|
+
if (aNumber < bNumber)
|
|
2070
|
+
return -1;
|
|
2071
|
+
if (a.id > b.id)
|
|
2072
|
+
return 1;
|
|
2073
|
+
if (a.id < b.id)
|
|
2074
|
+
return -1;
|
|
2075
|
+
if (!Number.isInteger(aNumber))
|
|
2076
|
+
return 1;
|
|
2077
|
+
if (!Number.isInteger(bNumber))
|
|
2078
|
+
return -1;
|
|
2079
|
+
const aName = localizationService.instant(a.name);
|
|
2080
|
+
const bName = localizationService.instant(b.name);
|
|
2081
|
+
// const aName = localizationService.localize(a.name,'ERP');
|
|
2082
|
+
// const bName = localizationService.localize(b.name,'ERP');
|
|
2083
|
+
if (aName > bName)
|
|
2084
|
+
return 1;
|
|
2085
|
+
if (aName < bName)
|
|
2086
|
+
return -1;
|
|
2087
|
+
return 0;
|
|
2088
|
+
};
|
|
2089
|
+
return fn;
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
class AbstractTreeService {
|
|
2093
|
+
_flat$ = new BehaviorSubject([]);
|
|
2094
|
+
_tree$ = new BehaviorSubject([]);
|
|
2095
|
+
_visible$ = new BehaviorSubject([]);
|
|
2096
|
+
othersGroup;
|
|
2097
|
+
shouldSingularizeRoutes = true;
|
|
2098
|
+
get flat() {
|
|
2099
|
+
return this._flat$.value;
|
|
2100
|
+
}
|
|
2101
|
+
get flat$() {
|
|
2102
|
+
return this._flat$.asObservable();
|
|
2103
|
+
}
|
|
2104
|
+
get tree() {
|
|
2105
|
+
return this._tree$.value;
|
|
2106
|
+
}
|
|
2107
|
+
get tree$() {
|
|
2108
|
+
return this._tree$.asObservable();
|
|
2109
|
+
}
|
|
2110
|
+
get visible() {
|
|
2111
|
+
return this._visible$.value;
|
|
2112
|
+
}
|
|
2113
|
+
get visible$() {
|
|
2114
|
+
return this._visible$.asObservable();
|
|
2115
|
+
}
|
|
2116
|
+
filterWith(setOrMap) {
|
|
2117
|
+
return this._flat$.value.filter(item => !setOrMap.has(item[this.id]));
|
|
2118
|
+
}
|
|
2119
|
+
findItemsToRemove(set) {
|
|
2120
|
+
return this._flat$.value.reduce((acc, item) => {
|
|
2121
|
+
if (!acc.has(item[this.parentId])) {
|
|
2122
|
+
return acc;
|
|
2123
|
+
}
|
|
2124
|
+
const childSet = new Set([item[this.id]]);
|
|
2125
|
+
const children = this.findItemsToRemove(childSet);
|
|
2126
|
+
return new Set([...acc, ...children]);
|
|
2127
|
+
}, set);
|
|
2128
|
+
}
|
|
2129
|
+
publish(flatItems) {
|
|
2130
|
+
this._flat$.next(flatItems);
|
|
2131
|
+
this._tree$.next(this.createTree(flatItems));
|
|
2132
|
+
this._visible$.next(this.createTree(flatItems.filter(item => !this.hide(item))));
|
|
2133
|
+
return flatItems;
|
|
2134
|
+
}
|
|
2135
|
+
createTree(items) {
|
|
2136
|
+
return createTreeFromList(items, item => item[this.id], item => item[this.parentId], item => BaseTreeNode.create(item));
|
|
2137
|
+
}
|
|
2138
|
+
createGroupedTree(list) {
|
|
2139
|
+
const map = createGroupMap(list, this.othersGroup);
|
|
2140
|
+
if (!map) {
|
|
2141
|
+
return undefined;
|
|
2142
|
+
}
|
|
2143
|
+
return Array.from(map, ([key, items]) => ({ group: key, items }));
|
|
2144
|
+
}
|
|
2145
|
+
add(items) {
|
|
2146
|
+
let flatItems = [];
|
|
2147
|
+
if (!this.shouldSingularizeRoutes) {
|
|
2148
|
+
flatItems = [...this.flat, ...items];
|
|
2149
|
+
}
|
|
2150
|
+
if (this.shouldSingularizeRoutes) {
|
|
2151
|
+
const map = new Map();
|
|
2152
|
+
items.forEach(item => map.set(item[this.id], item));
|
|
2153
|
+
flatItems = this.filterWith(map);
|
|
2154
|
+
map.forEach(pushValueTo(flatItems));
|
|
2155
|
+
}
|
|
2156
|
+
flatItems.sort(this.sort);
|
|
2157
|
+
return this.publish(flatItems);
|
|
2158
|
+
}
|
|
2159
|
+
find(predicate, tree = this.tree) {
|
|
2160
|
+
return tree.reduce((acc, node) => {
|
|
2161
|
+
if (acc) {
|
|
2162
|
+
return acc;
|
|
2163
|
+
}
|
|
2164
|
+
if (predicate(node)) {
|
|
2165
|
+
return node;
|
|
2166
|
+
}
|
|
2167
|
+
return this.find(predicate, node.children);
|
|
2168
|
+
}, null);
|
|
2169
|
+
}
|
|
2170
|
+
patch(identifier, props) {
|
|
2171
|
+
const flatItems = this._flat$.value;
|
|
2172
|
+
const index = flatItems.findIndex(item => item[this.id] === identifier);
|
|
2173
|
+
if (index < 0) {
|
|
2174
|
+
return false;
|
|
2175
|
+
}
|
|
2176
|
+
flatItems[index] = { ...flatItems[index], ...props };
|
|
2177
|
+
flatItems.sort(this.sort);
|
|
2178
|
+
return this.publish(flatItems);
|
|
2179
|
+
}
|
|
2180
|
+
refresh() {
|
|
2181
|
+
return this.add([]);
|
|
2182
|
+
}
|
|
2183
|
+
remove(identifiers) {
|
|
2184
|
+
const set = new Set();
|
|
2185
|
+
identifiers.forEach(id => set.add(id));
|
|
2186
|
+
const setToRemove = this.findItemsToRemove(set);
|
|
2187
|
+
const flatItems = this.filterWith(setToRemove);
|
|
2188
|
+
return this.publish(flatItems);
|
|
2189
|
+
}
|
|
2190
|
+
removeByParam(params) {
|
|
2191
|
+
if (!params) {
|
|
2192
|
+
return null;
|
|
2193
|
+
}
|
|
2194
|
+
const keys = Object.keys(params);
|
|
2195
|
+
if (keys.length === 0) {
|
|
2196
|
+
return null;
|
|
2197
|
+
}
|
|
2198
|
+
const excludedList = this.flat.filter(item => keys.every(key => item[key] === params[key]));
|
|
2199
|
+
if (!excludedList?.length) {
|
|
2200
|
+
return null;
|
|
2201
|
+
}
|
|
2202
|
+
for (const item of excludedList) {
|
|
2203
|
+
this.removeByParam({ [this.parentId]: item[this.id] });
|
|
2204
|
+
}
|
|
2205
|
+
const flatItems = this.flat.filter(item => !excludedList.includes(item));
|
|
2206
|
+
return this.publish(flatItems);
|
|
2207
|
+
}
|
|
2208
|
+
search(params, tree = this.tree) {
|
|
2209
|
+
const searchKeys = Object.keys(params);
|
|
2210
|
+
return tree.reduce((acc, node) => {
|
|
2211
|
+
if (acc) {
|
|
2212
|
+
return acc;
|
|
2213
|
+
}
|
|
2214
|
+
if (searchKeys.every(key => node[key] === params[key])) {
|
|
2215
|
+
return node;
|
|
2216
|
+
}
|
|
2217
|
+
return this.search(params, node.children);
|
|
2218
|
+
}, null);
|
|
2219
|
+
}
|
|
2220
|
+
setSingularizeStatus(singularize = true) {
|
|
2221
|
+
this.shouldSingularizeRoutes = singularize;
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
class AbstractNavTreeService extends AbstractTreeService {
|
|
2225
|
+
injector;
|
|
2226
|
+
subscription;
|
|
2227
|
+
permissionService;
|
|
2228
|
+
compareFunc;
|
|
2229
|
+
id = 'name';
|
|
2230
|
+
parentId = 'parentName';
|
|
2231
|
+
hide = (item) => item.invisible || !this.isGranted(item);
|
|
2232
|
+
sort = (a, b) => {
|
|
2233
|
+
return this.compareFunc(a, b);
|
|
2234
|
+
};
|
|
2235
|
+
constructor(injector) {
|
|
2236
|
+
super();
|
|
2237
|
+
this.injector = injector;
|
|
2238
|
+
// TODO Merge Dynamic Nav Too!
|
|
2239
|
+
const configState = this.injector.get(ConfigStateService);
|
|
2240
|
+
this.subscription = configState
|
|
2241
|
+
.createOnUpdateStream((state) => state)
|
|
2242
|
+
.subscribe(() => this.refresh());
|
|
2243
|
+
this.permissionService = injector.get(PermissionCheckerService);
|
|
2244
|
+
this.othersGroup = injector.get(OTHERS_GROUP);
|
|
2245
|
+
this.compareFunc = injector.get(SORT_COMPARE_FUNC);
|
|
2246
|
+
}
|
|
2247
|
+
isGranted({ requiredPolicy }) {
|
|
2248
|
+
return this.permissionService.getGrantedPolicy(requiredPolicy);
|
|
2249
|
+
}
|
|
2250
|
+
hasChildren(identifier) {
|
|
2251
|
+
const node = this.find(item => item[this.id] === identifier);
|
|
2252
|
+
return Boolean(node?.children?.length);
|
|
2253
|
+
}
|
|
2254
|
+
hasInvisibleChild(identifier) {
|
|
2255
|
+
const node = this.find(item => item[this.id] === identifier);
|
|
2256
|
+
return node?.children?.some(child => child.invisible) || false;
|
|
2257
|
+
}
|
|
2258
|
+
/* istanbul ignore next */
|
|
2259
|
+
ngOnDestroy() {
|
|
2260
|
+
// this.subscription.unsubscribe();
|
|
2261
|
+
}
|
|
2262
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AbstractNavTreeService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2263
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AbstractNavTreeService });
|
|
2264
|
+
}
|
|
2265
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AbstractNavTreeService, decorators: [{
|
|
2266
|
+
type: Injectable
|
|
2267
|
+
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
2268
|
+
class RoutesService extends AbstractNavTreeService {
|
|
2269
|
+
hasPathOrChild(item) {
|
|
2270
|
+
return Boolean(item.path) || this.hasChildren(item.name);
|
|
2271
|
+
}
|
|
2272
|
+
get groupedVisible() {
|
|
2273
|
+
return this.createGroupedTree(this.visible.filter(item => this.hasPathOrChild(item)));
|
|
2274
|
+
}
|
|
2275
|
+
get groupedVisible$() {
|
|
2276
|
+
return this.visible$.pipe(map$1(items => items.filter(item => this.hasPathOrChild(item))), map$1(visible => this.createGroupedTree(visible)));
|
|
2277
|
+
}
|
|
2278
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RoutesService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2279
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RoutesService, providedIn: 'root' });
|
|
2280
|
+
}
|
|
2281
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RoutesService, decorators: [{
|
|
2282
|
+
type: Injectable,
|
|
2283
|
+
args: [{ providedIn: 'root' }]
|
|
2284
|
+
}] });
|
|
2285
|
+
|
|
2286
|
+
class RoutesHandler {
|
|
2287
|
+
routes;
|
|
2288
|
+
router;
|
|
2289
|
+
constructor(routes, router) {
|
|
2290
|
+
this.routes = routes;
|
|
2291
|
+
this.router = router;
|
|
2292
|
+
this.addRoutes();
|
|
2293
|
+
}
|
|
2294
|
+
addRoutes() {
|
|
2295
|
+
this.router?.config?.forEach(({ path = '', data }) => {
|
|
2296
|
+
const routes = data?.routes;
|
|
2297
|
+
if (!routes)
|
|
2298
|
+
return;
|
|
2299
|
+
if (Array.isArray(routes)) {
|
|
2300
|
+
this.routes.add(routes);
|
|
2301
|
+
}
|
|
2302
|
+
else {
|
|
2303
|
+
const routesFlatten = flatRoutes([{ path, ...routes }], { path: '' });
|
|
2304
|
+
this.routes.add(routesFlatten);
|
|
2305
|
+
}
|
|
2306
|
+
});
|
|
2307
|
+
}
|
|
2308
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RoutesHandler, deps: [{ token: RoutesService }, { token: i2.Router, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2309
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RoutesHandler, providedIn: 'root' });
|
|
2310
|
+
}
|
|
2311
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RoutesHandler, decorators: [{
|
|
2312
|
+
type: Injectable,
|
|
2313
|
+
args: [{
|
|
2314
|
+
providedIn: 'root',
|
|
2315
|
+
}]
|
|
2316
|
+
}], ctorParameters: () => [{ type: RoutesService }, { type: i2.Router, decorators: [{
|
|
2317
|
+
type: Optional
|
|
2318
|
+
}] }] });
|
|
2319
|
+
function flatRoutes(routes, parent) {
|
|
2320
|
+
if (!routes)
|
|
2321
|
+
return [];
|
|
2322
|
+
return routes.reduce((acc, route) => {
|
|
2323
|
+
const { children, ...current } = {
|
|
2324
|
+
...route,
|
|
2325
|
+
parentName: parent.name,
|
|
2326
|
+
path: (parent.path + '/' + route.path).replace(/\/\//g, '/'),
|
|
2327
|
+
};
|
|
2328
|
+
acc.push(current, ...flatRoutes(children, current));
|
|
2329
|
+
return acc;
|
|
2330
|
+
}, []);
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
class MultiTenancyService {
|
|
2334
|
+
restService;
|
|
2335
|
+
sessionState;
|
|
2336
|
+
configStateService;
|
|
2337
|
+
tenantKey;
|
|
2338
|
+
get isEnabled() {
|
|
2339
|
+
// return this.framework.multiTenancy.isEnabled;
|
|
2340
|
+
return true;
|
|
2341
|
+
}
|
|
2342
|
+
domainTenant = null;
|
|
2343
|
+
isTenantBoxVisible = true;
|
|
2344
|
+
apiName = 'framework';
|
|
2345
|
+
setTenantToState = (tenant) => {
|
|
2346
|
+
this.sessionState.setTenant({ id: tenant.id, name: tenant.name, /* isAvailable: true */ });
|
|
2347
|
+
return this.configStateService.refreshAppState().pipe(map$1(_ => tenant));
|
|
2348
|
+
};
|
|
2349
|
+
constructor(restService, sessionState, configStateService, tenantKey) {
|
|
2350
|
+
this.restService = restService;
|
|
2351
|
+
this.sessionState = sessionState;
|
|
2352
|
+
this.configStateService = configStateService;
|
|
2353
|
+
this.tenantKey = tenantKey;
|
|
2354
|
+
}
|
|
2355
|
+
setTenantByName(tenantName) {
|
|
2356
|
+
return this
|
|
2357
|
+
.findTenantByName(tenantName)
|
|
2358
|
+
.pipe(switchMap$1(this.setTenantToState));
|
|
2359
|
+
}
|
|
2360
|
+
setTenantById(tenantId) {
|
|
2361
|
+
return this
|
|
2362
|
+
.findTenantById(tenantId)
|
|
2363
|
+
.pipe(switchMap$1(this.setTenantToState));
|
|
2364
|
+
}
|
|
2365
|
+
findTenantById = (id, config) => this.restService.request({
|
|
2366
|
+
method: 'GET',
|
|
2367
|
+
url: `/api/framework/multi-tenancy/tenants/by-id/${id}`,
|
|
2368
|
+
}, { apiName: this.apiName, ...config });
|
|
2369
|
+
findTenantByName = (name, config) => this.restService.request({
|
|
2370
|
+
method: 'GET',
|
|
2371
|
+
url: `/api/framework/multi-tenancy/tenants/by-name/${name}`,
|
|
2372
|
+
}, { apiName: this.apiName, ...config });
|
|
2373
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: MultiTenancyService, deps: [{ token: RestService }, { token: SessionStateService }, { token: ConfigStateService }, { token: TENANT_KEY }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2374
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: MultiTenancyService, providedIn: 'root' });
|
|
2375
|
+
}
|
|
2376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: MultiTenancyService, decorators: [{
|
|
2377
|
+
type: Injectable,
|
|
2378
|
+
args: [{
|
|
2379
|
+
providedIn: 'root'
|
|
2380
|
+
}]
|
|
2381
|
+
}], ctorParameters: () => [{ type: RestService }, { type: SessionStateService }, { type: ConfigStateService }, { type: undefined, decorators: [{
|
|
2382
|
+
type: Inject,
|
|
2383
|
+
args: [TENANT_KEY]
|
|
2384
|
+
}] }] });
|
|
2385
|
+
|
|
2386
|
+
class HttpErrorReporterService {
|
|
2387
|
+
_reporter$ = new Subject();
|
|
2388
|
+
_errors$ = new BehaviorSubject([]);
|
|
2389
|
+
get reporter$() {
|
|
2390
|
+
return this._reporter$.asObservable();
|
|
2391
|
+
}
|
|
2392
|
+
get errors$() {
|
|
2393
|
+
return this._errors$.asObservable();
|
|
2394
|
+
}
|
|
2395
|
+
get errors() {
|
|
2396
|
+
return this._errors$.value;
|
|
2397
|
+
}
|
|
2398
|
+
reportError(error) {
|
|
2399
|
+
this._reporter$.next(error);
|
|
2400
|
+
this._errors$.next([...this.errors, error]);
|
|
2401
|
+
}
|
|
2402
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: HttpErrorReporterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2403
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: HttpErrorReporterService, providedIn: 'root' });
|
|
2404
|
+
}
|
|
2405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: HttpErrorReporterService, decorators: [{
|
|
2406
|
+
type: Injectable,
|
|
2407
|
+
args: [{ providedIn: 'root' }]
|
|
2408
|
+
}] });
|
|
2409
|
+
|
|
2410
|
+
class SubscriptionService {
|
|
2411
|
+
subscription = new Subscription();
|
|
2412
|
+
get isClosed() {
|
|
2413
|
+
return this.subscription.closed;
|
|
2414
|
+
}
|
|
2415
|
+
addOne(source$, nextOrObserver, error) {
|
|
2416
|
+
const subscription = source$.subscribe(nextOrObserver, error);
|
|
2417
|
+
this.subscription.add(subscription);
|
|
2418
|
+
return subscription;
|
|
2419
|
+
}
|
|
2420
|
+
closeAll() {
|
|
2421
|
+
this.subscription.unsubscribe();
|
|
2422
|
+
}
|
|
2423
|
+
closeOne(subscription) {
|
|
2424
|
+
this.removeOne(subscription);
|
|
2425
|
+
if (subscription) {
|
|
2426
|
+
subscription.unsubscribe();
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
ngOnDestroy() {
|
|
2430
|
+
this.subscription.unsubscribe();
|
|
2431
|
+
}
|
|
2432
|
+
removeOne(subscription) {
|
|
2433
|
+
if (!subscription)
|
|
2434
|
+
return;
|
|
2435
|
+
this.subscription.remove(subscription);
|
|
2436
|
+
}
|
|
2437
|
+
reset() {
|
|
2438
|
+
this.subscription.unsubscribe();
|
|
2439
|
+
this.subscription = new Subscription();
|
|
2440
|
+
}
|
|
2441
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SubscriptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2442
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SubscriptionService });
|
|
2443
|
+
}
|
|
2444
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: SubscriptionService, decorators: [{
|
|
2445
|
+
type: Injectable
|
|
2446
|
+
}] });
|
|
2447
|
+
|
|
2448
|
+
const NavigationEvent = {
|
|
2449
|
+
Cancel: NavigationCancel,
|
|
2450
|
+
End: NavigationEnd,
|
|
2451
|
+
Error: NavigationError,
|
|
2452
|
+
Start: NavigationStart,
|
|
2453
|
+
};
|
|
2454
|
+
class RouterEvents {
|
|
2455
|
+
router = inject(Router);
|
|
2456
|
+
#previousNavigation = signal(undefined, ...(ngDevMode ? [{ debugName: "#previousNavigation" }] : []));
|
|
2457
|
+
previousNavigation = this.#previousNavigation.asReadonly();
|
|
2458
|
+
#currentNavigation = signal(undefined, ...(ngDevMode ? [{ debugName: "#currentNavigation" }] : []));
|
|
2459
|
+
currentNavigation = this.#currentNavigation.asReadonly();
|
|
2460
|
+
constructor() {
|
|
2461
|
+
this.listenToNavigation();
|
|
2462
|
+
}
|
|
2463
|
+
listenToNavigation() {
|
|
2464
|
+
const routerEvent$ = this.router.events.pipe(filter(e => e instanceof NavigationEvent.End && !e.url.includes('error')));
|
|
2465
|
+
routerEvent$.subscribe(event => {
|
|
2466
|
+
this.#previousNavigation.set(this.currentNavigation());
|
|
2467
|
+
this.#currentNavigation.set(event.url);
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
getEvents(...eventTypes) {
|
|
2471
|
+
const filterRouterEvents = (event) => eventTypes.some(type => event instanceof type);
|
|
2472
|
+
return this.router.events.pipe(filter(filterRouterEvents));
|
|
2473
|
+
}
|
|
2474
|
+
getNavigationEvents(...navigationEventKeys) {
|
|
2475
|
+
const filterNavigationEvents = (event) => navigationEventKeys.some(key => event instanceof NavigationEvent[key]);
|
|
2476
|
+
return this.router.events.pipe(filter(filterNavigationEvents));
|
|
2477
|
+
}
|
|
2478
|
+
getAllEvents() {
|
|
2479
|
+
return this.router.events;
|
|
2480
|
+
}
|
|
2481
|
+
getAllNavigationEvents() {
|
|
2482
|
+
const keys = Object.keys(NavigationEvent);
|
|
2483
|
+
return this.getNavigationEvents(...keys);
|
|
2484
|
+
}
|
|
2485
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RouterEvents, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2486
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RouterEvents, providedIn: 'root' });
|
|
2487
|
+
}
|
|
2488
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RouterEvents, decorators: [{
|
|
2489
|
+
type: Injectable,
|
|
2490
|
+
args: [{ providedIn: 'root' }]
|
|
2491
|
+
}], ctorParameters: () => [] });
|
|
2492
|
+
|
|
2493
|
+
class RouterWaitService {
|
|
2494
|
+
routerEvents;
|
|
2495
|
+
store = new InternalStore({ loading: false });
|
|
2496
|
+
destroy$ = new Subject();
|
|
2497
|
+
delay;
|
|
2498
|
+
constructor(routerEvents, injector) {
|
|
2499
|
+
this.routerEvents = routerEvents;
|
|
2500
|
+
// this.delay = injector.get(LOADER_DELAY, 500);
|
|
2501
|
+
this.delay = 500;
|
|
2502
|
+
this.updateLoadingStatusOnNavigationEvents();
|
|
2503
|
+
}
|
|
2504
|
+
updateLoadingStatusOnNavigationEvents() {
|
|
2505
|
+
this.routerEvents
|
|
2506
|
+
.getAllNavigationEvents()
|
|
2507
|
+
.pipe(map(event => event instanceof NavigationStart), switchMap(condition => condition
|
|
2508
|
+
? this.delay === 0
|
|
2509
|
+
? of(true)
|
|
2510
|
+
: timer(this.delay || 0).pipe(mapTo(true), takeUntil(this.destroy$))
|
|
2511
|
+
: of(false)), tap(() => this.destroy$.next()))
|
|
2512
|
+
.subscribe(status => {
|
|
2513
|
+
this.setLoading(status);
|
|
2514
|
+
});
|
|
2515
|
+
}
|
|
2516
|
+
getLoading() {
|
|
2517
|
+
return this.store.state.loading;
|
|
2518
|
+
}
|
|
2519
|
+
getLoading$() {
|
|
2520
|
+
return this.store.sliceState(({ loading }) => loading);
|
|
2521
|
+
}
|
|
2522
|
+
updateLoading$() {
|
|
2523
|
+
return this.store.sliceUpdate(({ loading }) => loading);
|
|
2524
|
+
}
|
|
2525
|
+
setLoading(loading) {
|
|
2526
|
+
this.store.patch({ loading });
|
|
2527
|
+
}
|
|
2528
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RouterWaitService, deps: [{ token: RouterEvents }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2529
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RouterWaitService, providedIn: 'root' });
|
|
2530
|
+
}
|
|
2531
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: RouterWaitService, decorators: [{
|
|
2532
|
+
type: Injectable,
|
|
2533
|
+
args: [{
|
|
2534
|
+
providedIn: 'root',
|
|
2535
|
+
}]
|
|
2536
|
+
}], ctorParameters: () => [{ type: RouterEvents }, { type: i0.Injector }] });
|
|
2537
|
+
|
|
2538
|
+
class AbstractMenuService {
|
|
2539
|
+
sortFn;
|
|
2540
|
+
_items$ = new BehaviorSubject([]);
|
|
2541
|
+
get items() {
|
|
2542
|
+
return this._items$.value;
|
|
2543
|
+
}
|
|
2544
|
+
get items$() {
|
|
2545
|
+
return this._items$.asObservable();
|
|
2546
|
+
}
|
|
2547
|
+
constructor() {
|
|
2548
|
+
this.sortFn = inject(SORT_COMPARE_FUNC);
|
|
2549
|
+
}
|
|
2550
|
+
addItems(newItems) {
|
|
2551
|
+
const items = [...this.items];
|
|
2552
|
+
newItems.forEach(item => {
|
|
2553
|
+
const index = items.findIndex(i => i.id === item.id);
|
|
2554
|
+
// const data = new this.baseClass(item);
|
|
2555
|
+
// const data = new this.baseClass(item);
|
|
2556
|
+
if (index > -1) {
|
|
2557
|
+
items[index] = item;
|
|
2558
|
+
return;
|
|
2559
|
+
}
|
|
2560
|
+
items.push(item);
|
|
2561
|
+
});
|
|
2562
|
+
items.sort(this.sortItems);
|
|
2563
|
+
this._items$.next(items);
|
|
2564
|
+
}
|
|
2565
|
+
removeItem(id) {
|
|
2566
|
+
const index = this.items.findIndex(item => item.id === id);
|
|
2567
|
+
if (index < 0)
|
|
2568
|
+
return;
|
|
2569
|
+
const items = [...this.items.slice(0, index), ...this.items.slice(index + 1)];
|
|
2570
|
+
this._items$.next(items);
|
|
2571
|
+
}
|
|
2572
|
+
patchItem(id, item) {
|
|
2573
|
+
const index = this.items.findIndex(i => i.id === id);
|
|
2574
|
+
if (index < 0)
|
|
2575
|
+
return;
|
|
2576
|
+
const items = [...this.items];
|
|
2577
|
+
items[index] = new this.baseClass({ ...items[index], ...item });
|
|
2578
|
+
items.sort(this.sortItems);
|
|
2579
|
+
this._items$.next(items);
|
|
2580
|
+
}
|
|
2581
|
+
sortItems = (a, b) => {
|
|
2582
|
+
return this.sortFn(a, b);
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
|
|
2586
|
+
class NavItemsService extends AbstractMenuService {
|
|
2587
|
+
baseClass = NavItem;
|
|
2588
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: NavItemsService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2589
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: NavItemsService, providedIn: 'root' });
|
|
2590
|
+
}
|
|
2591
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: NavItemsService, decorators: [{
|
|
2592
|
+
type: Injectable,
|
|
2593
|
+
args: [{ providedIn: 'root' }]
|
|
2594
|
+
}] });
|
|
2595
|
+
|
|
2596
|
+
class UserMenuService extends AbstractMenuService {
|
|
2597
|
+
baseClass = UserMenu;
|
|
2598
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: UserMenuService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
2599
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: UserMenuService, providedIn: 'root' });
|
|
2600
|
+
}
|
|
2601
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: UserMenuService, decorators: [{
|
|
2602
|
+
type: Injectable,
|
|
2603
|
+
args: [{ providedIn: 'root' }]
|
|
2604
|
+
}] });
|
|
2605
|
+
|
|
2606
|
+
function findRoute(routesService, path) {
|
|
2607
|
+
const node = routesService.find(route => route.path === path);
|
|
2608
|
+
return node || path === '/'
|
|
2609
|
+
? node
|
|
2610
|
+
: findRoute(routesService, path.split('/').slice(0, -1).join('/') || '/');
|
|
2611
|
+
}
|
|
2612
|
+
function getRoutePath(router, url = router.url) {
|
|
2613
|
+
const emptyGroup = { segments: [] };
|
|
2614
|
+
const primaryGroup = router.parseUrl(url).root.children[PRIMARY_OUTLET];
|
|
2615
|
+
return '/' + (primaryGroup || emptyGroup).segments.map(({ path }) => path).join('/');
|
|
2616
|
+
}
|
|
2617
|
+
function reloadRoute(router, ngZone) {
|
|
2618
|
+
const { shouldReuseRoute } = router.routeReuseStrategy;
|
|
2619
|
+
const setRouteReuse = (reuse) => {
|
|
2620
|
+
router.routeReuseStrategy.shouldReuseRoute = reuse;
|
|
2621
|
+
};
|
|
2622
|
+
setRouteReuse(() => false);
|
|
2623
|
+
router.navigated = false;
|
|
2624
|
+
ngZone.run(async () => {
|
|
2625
|
+
await router.navigateByUrl(router.url).catch(noop);
|
|
2626
|
+
setRouteReuse(shouldReuseRoute);
|
|
2627
|
+
});
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
class ReplaceableComponentsService {
|
|
2631
|
+
ngZone;
|
|
2632
|
+
router;
|
|
2633
|
+
store;
|
|
2634
|
+
get replaceableComponents$() {
|
|
2635
|
+
return this.store.sliceState(state => state);
|
|
2636
|
+
}
|
|
2637
|
+
get replaceableComponents() {
|
|
2638
|
+
return this.store.state;
|
|
2639
|
+
}
|
|
2640
|
+
get onUpdate$() {
|
|
2641
|
+
return this.store.sliceUpdate(state => state);
|
|
2642
|
+
}
|
|
2643
|
+
constructor(ngZone, router) {
|
|
2644
|
+
this.ngZone = ngZone;
|
|
2645
|
+
this.router = router;
|
|
2646
|
+
this.store = new InternalStore([]);
|
|
2647
|
+
}
|
|
2648
|
+
add(replaceableComponent, reload) {
|
|
2649
|
+
const replaceableComponents = [...this.store.state];
|
|
2650
|
+
const index = replaceableComponents.findIndex(component => component.key === replaceableComponent.key);
|
|
2651
|
+
if (index > -1) {
|
|
2652
|
+
replaceableComponents[index] = replaceableComponent;
|
|
2653
|
+
}
|
|
2654
|
+
else {
|
|
2655
|
+
replaceableComponents.push(replaceableComponent);
|
|
2656
|
+
}
|
|
2657
|
+
this.store.set(replaceableComponents);
|
|
2658
|
+
if (reload)
|
|
2659
|
+
reloadRoute(this.router, this.ngZone);
|
|
2660
|
+
}
|
|
2661
|
+
get(replaceableComponentKey) {
|
|
2662
|
+
return this.replaceableComponents.find(component => component.key === replaceableComponentKey);
|
|
2663
|
+
}
|
|
2664
|
+
get$(replaceableComponentKey) {
|
|
2665
|
+
return this.replaceableComponents$.pipe(map(components => components.find(component => component.key === replaceableComponentKey)));
|
|
2666
|
+
}
|
|
2667
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ReplaceableComponentsService, deps: [{ token: i0.NgZone }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2668
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ReplaceableComponentsService, providedIn: 'root' });
|
|
2669
|
+
}
|
|
2670
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: ReplaceableComponentsService, decorators: [{
|
|
2671
|
+
type: Injectable,
|
|
2672
|
+
args: [{ providedIn: 'root' }]
|
|
2673
|
+
}], ctorParameters: () => [{ type: i0.NgZone }, { type: i2.Router }] });
|
|
2674
|
+
|
|
2675
|
+
class HttpWaitService {
|
|
2676
|
+
store = new InternalStore({
|
|
2677
|
+
requests: [],
|
|
2678
|
+
filteredRequests: [],
|
|
2679
|
+
});
|
|
2680
|
+
delay;
|
|
2681
|
+
destroy$ = new Subject();
|
|
2682
|
+
constructor(injector) {
|
|
2683
|
+
this.delay = 500;
|
|
2684
|
+
}
|
|
2685
|
+
getLoading() {
|
|
2686
|
+
return !!this.applyFilter(this.store.state.requests).length;
|
|
2687
|
+
}
|
|
2688
|
+
getLoading$() {
|
|
2689
|
+
return this.store
|
|
2690
|
+
.sliceState(({ requests }) => requests)
|
|
2691
|
+
.pipe(map(requests => !!this.applyFilter(requests).length), switchMap(condition => condition
|
|
2692
|
+
? this.delay === 0
|
|
2693
|
+
? of(true)
|
|
2694
|
+
: timer(this.delay).pipe(mapTo(true), takeUntil(this.destroy$))
|
|
2695
|
+
: of(false)), tap(() => this.destroy$.next()));
|
|
2696
|
+
}
|
|
2697
|
+
updateLoading$() {
|
|
2698
|
+
return this.store.sliceUpdate(({ requests }) => !!this.applyFilter(requests).length);
|
|
2699
|
+
}
|
|
2700
|
+
clearLoading() {
|
|
2701
|
+
this.store.patch({ requests: [] });
|
|
2702
|
+
}
|
|
2703
|
+
addRequest(request) {
|
|
2704
|
+
this.store.patch({ requests: [...this.store.state.requests, request] });
|
|
2705
|
+
}
|
|
2706
|
+
deleteRequest(request) {
|
|
2707
|
+
const requests = this.store.state.requests.filter(r => r !== request);
|
|
2708
|
+
this.store.patch({ requests });
|
|
2709
|
+
}
|
|
2710
|
+
addFilter(request) {
|
|
2711
|
+
const requests = Array.isArray(request) ? request : [request];
|
|
2712
|
+
const filteredRequests = [
|
|
2713
|
+
...this.store.state.filteredRequests.filter(f => !requests.some(r => this.isSameRequest(f, r))),
|
|
2714
|
+
...requests,
|
|
2715
|
+
];
|
|
2716
|
+
this.store.patch({ filteredRequests });
|
|
2717
|
+
}
|
|
2718
|
+
removeFilter(request) {
|
|
2719
|
+
const requests = Array.isArray(request) ? request : [request];
|
|
2720
|
+
const filteredRequests = this.store.state.filteredRequests.filter(f => !requests.some(r => this.isSameRequest(f, r)));
|
|
2721
|
+
this.store.patch({ filteredRequests });
|
|
2722
|
+
}
|
|
2723
|
+
applyFilter(requests) {
|
|
2724
|
+
if (!requests) {
|
|
2725
|
+
return [];
|
|
2726
|
+
}
|
|
2727
|
+
const { filteredRequests } = this.store.state;
|
|
2728
|
+
return requests.filter(({ method, url }) => !filteredRequests.find(filteredRequest => this.isSameRequest(filteredRequest, { method, endpoint: getPathName(url) })));
|
|
2729
|
+
}
|
|
2730
|
+
isSameRequest(filteredRequest, request) {
|
|
2731
|
+
const { method, endpoint } = filteredRequest;
|
|
2732
|
+
return endpoint === request.endpoint && method === request.method;
|
|
2733
|
+
}
|
|
2734
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: HttpWaitService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2735
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: HttpWaitService, providedIn: 'root' });
|
|
2736
|
+
}
|
|
2737
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: HttpWaitService, decorators: [{
|
|
2738
|
+
type: Injectable,
|
|
2739
|
+
args: [{
|
|
2740
|
+
providedIn: 'root',
|
|
2741
|
+
}]
|
|
2742
|
+
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
2743
|
+
|
|
2744
|
+
class WindowService {
|
|
2745
|
+
document = inject(DOCUMENT);
|
|
2746
|
+
window = this.document.defaultView;
|
|
2747
|
+
navigator = this.window?.navigator;
|
|
2748
|
+
copyToClipboard(text) {
|
|
2749
|
+
return this.navigator?.clipboard.writeText(text);
|
|
2750
|
+
}
|
|
2751
|
+
open(url, target, features) {
|
|
2752
|
+
return this.window?.open(url, target, features);
|
|
2753
|
+
}
|
|
2754
|
+
reloadPage() {
|
|
2755
|
+
this.window?.location.reload();
|
|
2756
|
+
}
|
|
2757
|
+
downloadBlob(blob, fileName) {
|
|
2758
|
+
const blobUrl = this.window?.URL.createObjectURL(blob);
|
|
2759
|
+
const a = this.document.createElement('a');
|
|
2760
|
+
a.style.display = 'none';
|
|
2761
|
+
a.href = blobUrl ?? '';
|
|
2762
|
+
a.download = fileName;
|
|
2763
|
+
this.document.body.appendChild(a);
|
|
2764
|
+
a.dispatchEvent(new MouseEvent('click', {
|
|
2765
|
+
bubbles: true,
|
|
2766
|
+
cancelable: true,
|
|
2767
|
+
view: this.window,
|
|
2768
|
+
}));
|
|
2769
|
+
this.window?.URL.revokeObjectURL(blobUrl ?? '');
|
|
2770
|
+
this.document.body.removeChild(a);
|
|
2771
|
+
}
|
|
2772
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: WindowService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2773
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: WindowService, providedIn: 'root' });
|
|
2774
|
+
}
|
|
2775
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: WindowService, decorators: [{
|
|
2776
|
+
type: Injectable,
|
|
2777
|
+
args: [{ providedIn: 'root' }]
|
|
2778
|
+
}] });
|
|
2779
|
+
|
|
2780
|
+
function getRemoteEnv(injector, environment) {
|
|
2781
|
+
const environmentService = injector.get(EnvironmentService);
|
|
2782
|
+
const { remoteEnv } = environment;
|
|
2783
|
+
const { headers = {}, method = 'GET', url } = remoteEnv || {};
|
|
2784
|
+
if (!url)
|
|
2785
|
+
return Promise.resolve();
|
|
2786
|
+
const http = injector.get(HttpClient);
|
|
2787
|
+
const httpErrorReporter = injector.get(HttpErrorReporterService);
|
|
2788
|
+
return http
|
|
2789
|
+
.request(method, url, { headers })
|
|
2790
|
+
.pipe(catchError$1(err => {
|
|
2791
|
+
httpErrorReporter.reportError(err);
|
|
2792
|
+
return of(null);
|
|
2793
|
+
}), // TODO: Consider get handle function from a provider
|
|
2794
|
+
tap(env => environmentService.setState(mergeEnvironments(environment, env || {}, remoteEnv))))
|
|
2795
|
+
.toPromise();
|
|
2796
|
+
}
|
|
2797
|
+
function mergeEnvironments(local, remote, config) {
|
|
2798
|
+
switch (config.mergeStrategy) {
|
|
2799
|
+
case 'deepmerge':
|
|
2800
|
+
return deepMerge(local, remote);
|
|
2801
|
+
case 'overwrite':
|
|
2802
|
+
case null:
|
|
2803
|
+
case undefined:
|
|
2804
|
+
return remote;
|
|
2805
|
+
default:
|
|
2806
|
+
return config.mergeStrategy(local, remote);
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
const tenancyPlaceholder = '{0}';
|
|
2811
|
+
function getCurrentTenancyName(appBaseUrl, injector) {
|
|
2812
|
+
const cookieService = injector.get(SsrCookieService);
|
|
2813
|
+
if (appBaseUrl.charAt(appBaseUrl.length - 1) !== '/')
|
|
2814
|
+
appBaseUrl += '/';
|
|
2815
|
+
const parseTokens = createTokenParser(appBaseUrl);
|
|
2816
|
+
const token = tenancyPlaceholder.replace(/[}{]/g, '');
|
|
2817
|
+
try {
|
|
2818
|
+
return parseTokens(cookieService.url)[token]?.[0];
|
|
2819
|
+
}
|
|
2820
|
+
catch (error) {
|
|
2821
|
+
return '';
|
|
2822
|
+
}
|
|
2823
|
+
// return parseTokens(window.location.href)[token]?.[0];
|
|
2824
|
+
// const pattern = /^http?:\/\/([^.]+)\.localhost\:4200/;
|
|
2825
|
+
// const match = cookieService.url.match(pattern);
|
|
2826
|
+
// if (match && match.length > 1) {
|
|
2827
|
+
// return match[1];
|
|
2828
|
+
// }
|
|
2829
|
+
// return '';
|
|
2830
|
+
}
|
|
2831
|
+
function getCurrentTenancyNameFromUrl(tenantKey) {
|
|
2832
|
+
if (typeof window === 'undefined') {
|
|
2833
|
+
return null; // or fallback like: return '';
|
|
2834
|
+
}
|
|
2835
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
2836
|
+
return urlParams.get(tenantKey);
|
|
2837
|
+
}
|
|
2838
|
+
//
|
|
2839
|
+
async function parseTenantFromUrl(injector) {
|
|
2840
|
+
const environmentService = injector.get(EnvironmentService);
|
|
2841
|
+
const multiTenancyService = injector.get(MultiTenancyService);
|
|
2842
|
+
const tenantNotFoundHandler = injector.get(TENANT_NOT_FOUND_BY_NAME, null);
|
|
2843
|
+
const baseUrl = environmentService.getEnvironment()?.application?.baseUrl || '';
|
|
2844
|
+
const tenancyName = getCurrentTenancyName(baseUrl, injector);
|
|
2845
|
+
const hideTenantBox = () => {
|
|
2846
|
+
multiTenancyService.isTenantBoxVisible = false;
|
|
2847
|
+
};
|
|
2848
|
+
const setDomainTenant = (tenant) => {
|
|
2849
|
+
multiTenancyService.domainTenant = {
|
|
2850
|
+
id: tenant.id,
|
|
2851
|
+
name: tenant.name,
|
|
2852
|
+
isAvailable: true,
|
|
2853
|
+
};
|
|
2854
|
+
};
|
|
2855
|
+
const setEnvironmentWithDomainTenant = (tenant) => {
|
|
2856
|
+
hideTenantBox();
|
|
2857
|
+
setDomainTenant(tenant);
|
|
2858
|
+
};
|
|
2859
|
+
if (tenancyName) {
|
|
2860
|
+
/**
|
|
2861
|
+
* We have to replace tenant name within the urls from environment,
|
|
2862
|
+
* because the code below will make a http request to find information about the domain tenant.
|
|
2863
|
+
* Before this request takes place, we need to replace placeholders aka "{0}".
|
|
2864
|
+
*/
|
|
2865
|
+
replaceTenantNameWithinEnvironment(injector, tenancyName);
|
|
2866
|
+
const tenant$ = multiTenancyService.setTenantByName(tenancyName);
|
|
2867
|
+
try {
|
|
2868
|
+
const result = await firstValueFrom(tenant$);
|
|
2869
|
+
setEnvironmentWithDomainTenant(result);
|
|
2870
|
+
return Promise.resolve(result);
|
|
2871
|
+
}
|
|
2872
|
+
catch (httpError) {
|
|
2873
|
+
if (httpError instanceof HttpErrorResponse &&
|
|
2874
|
+
httpError.status === 404 &&
|
|
2875
|
+
tenantNotFoundHandler) {
|
|
2876
|
+
tenantNotFoundHandler(httpError);
|
|
2877
|
+
}
|
|
2878
|
+
return Promise.reject();
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
/**
|
|
2882
|
+
* If there is no tenant, we still have to clean up {0}. from baseUrl to avoid incorrect http requests.
|
|
2883
|
+
*/
|
|
2884
|
+
replaceTenantNameWithinEnvironment(injector, '', tenancyPlaceholder + '.');
|
|
2885
|
+
const tenantIdFromQueryParams = getCurrentTenancyNameFromUrl(multiTenancyService.tenantKey);
|
|
2886
|
+
if (tenantIdFromQueryParams) {
|
|
2887
|
+
const tenantById$ = multiTenancyService.setTenantById(tenantIdFromQueryParams);
|
|
2888
|
+
return firstValueFrom(tenantById$);
|
|
2889
|
+
}
|
|
2890
|
+
return Promise.resolve();
|
|
2891
|
+
}
|
|
2892
|
+
function replaceTenantNameWithinEnvironment(injector, tenancyName, placeholder = tenancyPlaceholder) {
|
|
2893
|
+
const environmentService = injector.get(EnvironmentService);
|
|
2894
|
+
const environment = clone(environmentService.getEnvironment());
|
|
2895
|
+
if (environment.application.baseUrl) {
|
|
2896
|
+
environment.application.baseUrl = environment.application.baseUrl.replace(placeholder, tenancyName);
|
|
2897
|
+
}
|
|
2898
|
+
if (environment.oAuthConfig?.redirectUri) {
|
|
2899
|
+
environment.oAuthConfig.redirectUri = environment.oAuthConfig.redirectUri.replace(placeholder, tenancyName);
|
|
2900
|
+
}
|
|
2901
|
+
if (!environment.oAuthConfig) {
|
|
2902
|
+
environment.oAuthConfig = {};
|
|
2903
|
+
}
|
|
2904
|
+
environment.oAuthConfig.issuer = (environment.oAuthConfig.issuer || '').replace(placeholder, tenancyName);
|
|
2905
|
+
Object.keys(environment.apis).forEach(api => {
|
|
2906
|
+
Object.keys(environment.apis[api]).forEach(key => {
|
|
2907
|
+
environment.apis[api][key] = (environment.apis[api][key] || '').replace(placeholder, tenancyName);
|
|
2908
|
+
});
|
|
2909
|
+
});
|
|
2910
|
+
return environmentService.setState(environment);
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
async function getInitialData() {
|
|
2914
|
+
const injector = inject(Injector);
|
|
2915
|
+
const environmentService = injector.get(EnvironmentService);
|
|
2916
|
+
const configState = injector.get(ConfigStateService);
|
|
2917
|
+
const options = injector.get(CORE_OPTIONS);
|
|
2918
|
+
environmentService.setState(options.environment);
|
|
2919
|
+
await getRemoteEnv(injector, options.environment);
|
|
2920
|
+
await parseTenantFromUrl(injector);
|
|
2921
|
+
const authService = injector.get(AuthService, undefined, { optional: true });
|
|
2922
|
+
const checkAuthenticationState = injector.get(CHECK_AUTHENTICATION_STATE_FN_KEY, noop$1, {
|
|
2923
|
+
optional: true,
|
|
2924
|
+
});
|
|
2925
|
+
if (!options.skipInitAuthService && authService) {
|
|
2926
|
+
await authService.init();
|
|
2927
|
+
}
|
|
2928
|
+
if (options.skipGetAppConfiguration)
|
|
2929
|
+
return;
|
|
2930
|
+
const result$ = configState.refreshAppState().pipe(tap(() => checkAuthenticationState(injector)), tap(() => {
|
|
2931
|
+
const currentTenant = configState.getOne('currentTenant');
|
|
2932
|
+
injector.get(SessionStateService).setTenant(currentTenant);
|
|
2933
|
+
// const currentSession= configState.getOne('currentT') as Session.State;
|
|
2934
|
+
// injector.get(SessionStateService).setState(currentSession);
|
|
2935
|
+
}), catchError$1(error => {
|
|
2936
|
+
const appInitErrorHandlers = injector.get(APP_INIT_ERROR_HANDLERS, null);
|
|
2937
|
+
if (appInitErrorHandlers && appInitErrorHandlers.length) {
|
|
2938
|
+
appInitErrorHandlers.forEach(func => func(error));
|
|
2939
|
+
}
|
|
2940
|
+
return throwError(() => error);
|
|
2941
|
+
// Don't rethrow to avoid breaking the app
|
|
2942
|
+
// return of(null); // ✅ suppresses the error
|
|
2943
|
+
}));
|
|
2944
|
+
await lastValueFrom(result$);
|
|
2945
|
+
}
|
|
2946
|
+
function localeInitializer() {
|
|
2947
|
+
const injector = inject(Injector);
|
|
2948
|
+
const sessionState = injector.get(SessionStateService);
|
|
2949
|
+
const { registerLocaleFn } = injector.get(CORE_OPTIONS);
|
|
2950
|
+
const lang = sessionState.getLanguage() || 'en';
|
|
2951
|
+
return new Promise((resolve, reject) => {
|
|
2952
|
+
registerLocaleFn(lang).then(module => {
|
|
2953
|
+
if (module?.default)
|
|
2954
|
+
registerLocaleData(module.default);
|
|
2955
|
+
return resolve('resolved');
|
|
2956
|
+
}, reject);
|
|
2957
|
+
});
|
|
2958
|
+
}
|
|
2959
|
+
|
|
1277
2960
|
/**
|
|
1278
2961
|
* Generated bundle index. Do not edit.
|
|
1279
2962
|
*/
|
|
1280
2963
|
|
|
1281
|
-
export { BaseService, GenericService, IdParserService, LogLevel, LoggerService, NgxPermissionsGuard,
|
|
2964
|
+
export { AbstractMenuService, AbstractNavTreeService, AbstractTreeService, ApplicationConfigurationService, ApplicationLocalizationService, BaseService, ConfigStateService, EnvironmentService, FrameworkTitleStrategy, GenericService, HttpErrorReporterService, HttpWaitService, IdParserService, LocalStorageListenerService, LocalStorageService, LocalizationService, LogLevel, LoggerService, MultiTenancyService, NavItemsService, NavigationEvent, NgxPermissionsGuard, PermissionCheckerService, QueryParser, REQUEST, ReplaceableComponentsService, RestService, RouterEvents, RouterWaitService, RoutesHandler, RoutesService, SORT_COMPARE_FUNC, SessionStateService, SsrCookieService, SubscriptionService, SwalService, UserMenuService, WindowService, compareFuncFactory, findRoute, getCurrentTenancyNameFromUrl, getInitialData, getRemoteEnv, getRoutePath, isUndefinedOrEmptyString, localeInitializer, ngxPermissionsGuard, parseTenantFromUrl, reloadRoute };
|
|
1282
2965
|
//# sourceMappingURL=elite.framework-ng.core-services.mjs.map
|