@abp/ng.core 8.1.2 → 8.2.0-rc.1

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.
Files changed (43) hide show
  1. package/esm2022/lib/components/dynamic-layout.component.mjs +20 -11
  2. package/esm2022/lib/core.module.mjs +8 -1
  3. package/esm2022/lib/models/common.mjs +1 -1
  4. package/esm2022/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.mjs +7 -7
  5. package/esm2022/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.mjs +5 -5
  6. package/esm2022/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.mjs +5 -5
  7. package/esm2022/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.mjs +5 -5
  8. package/esm2022/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.mjs +1 -1
  9. package/esm2022/lib/proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models.mjs +1 -1
  10. package/esm2022/lib/proxy/volo/abp/http/modeling/models.mjs +1 -1
  11. package/esm2022/lib/proxy/volo/abp/localization/models.mjs +1 -1
  12. package/esm2022/lib/services/config-state.service.mjs +4 -6
  13. package/esm2022/lib/services/index.mjs +2 -1
  14. package/esm2022/lib/services/local-storage-listener.service.mjs +22 -0
  15. package/esm2022/lib/services/localization.service.mjs +5 -4
  16. package/esm2022/lib/services/routes.service.mjs +70 -31
  17. package/esm2022/lib/tokens/compare-func.token.mjs +11 -11
  18. package/esm2022/lib/utils/initial-utils.mjs +2 -2
  19. package/esm2022/testing/lib/core-testing.module.mjs +4 -3
  20. package/esm2022/testing/lib/pipes/index.mjs +2 -0
  21. package/esm2022/testing/lib/pipes/localization.pipe.mjs +20 -0
  22. package/esm2022/testing/public-api.mjs +2 -1
  23. package/fesm2022/abp-ng.core-testing.mjs +22 -4
  24. package/fesm2022/abp-ng.core-testing.mjs.map +1 -1
  25. package/fesm2022/abp-ng.core.mjs +1709 -1638
  26. package/fesm2022/abp-ng.core.mjs.map +1 -1
  27. package/lib/components/dynamic-layout.component.d.ts +15 -7
  28. package/lib/models/common.d.ts +1 -0
  29. package/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.d.ts +4 -3
  30. package/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.d.ts +3 -2
  31. package/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.d.ts +3 -2
  32. package/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.d.ts +3 -2
  33. package/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.d.ts +1 -0
  34. package/lib/proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models.d.ts +1 -0
  35. package/lib/services/index.d.ts +1 -0
  36. package/lib/services/local-storage-listener.service.d.ts +7 -0
  37. package/lib/services/routes.service.d.ts +5 -2
  38. package/lib/tokens/compare-func.token.d.ts +1 -1
  39. package/package.json +2 -2
  40. package/testing/lib/core-testing.module.d.ts +2 -1
  41. package/testing/lib/pipes/index.d.ts +1 -0
  42. package/testing/lib/pipes/localization.pipe.d.ts +8 -0
  43. package/testing/public-api.d.ts +1 -0
@@ -1,13 +1,13 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ChangeDetectorRef, Component, Input, Injectable, InjectionToken, Inject, Optional, isDevMode, SkipSelf, signal, NgModuleFactory, Injector, Compiler, computed, Directive, EventEmitter, Output, Self, Pipe, NgModule, APP_INITIALIZER, LOCALE_ID, SecurityContext, effect, ElementRef, HostListener, ComponentFactoryResolver, ApplicationRef } from '@angular/core';
3
- import { of, BehaviorSubject, Subject, throwError, combineLatest, from, firstValueFrom, lastValueFrom, Observable, timer, pipe, concat, ReplaySubject, Subscription, map as map$1, fromEvent } from 'rxjs';
2
+ import { inject, ChangeDetectorRef, Component, Input, Injectable, InjectionToken, NgModuleFactory, Injector, Compiler, Inject, signal, computed, Optional, isDevMode, SkipSelf, Directive, EventEmitter, Output, Self, Pipe, NgModule, APP_INITIALIZER, LOCALE_ID, SecurityContext, effect, ElementRef, HostListener, ComponentFactoryResolver, ApplicationRef } from '@angular/core';
3
+ import { of, BehaviorSubject, Subject, throwError, firstValueFrom, lastValueFrom, Observable, timer, pipe, concat, ReplaySubject, map as map$1, Subscription, combineLatest, from, fromEvent } from 'rxjs';
4
4
  import * as i1$1 from '@angular/router';
5
5
  import { PRIMARY_OUTLET, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router, ActivatedRoute, TitleStrategy, RouterModule } from '@angular/router';
6
6
  import * as i1$2 from '@angular/common';
7
7
  import { registerLocaleData, DOCUMENT, DatePipe, DATE_PIPE_DEFAULT_TIMEZONE, CommonModule } from '@angular/common';
8
- import { map, distinctUntilChanged, filter, catchError, switchMap, take, tap, mapTo, takeUntil, delay, retryWhen, shareReplay, debounceTime, finalize } from 'rxjs/operators';
8
+ import { map, distinctUntilChanged, filter, catchError, tap, take, switchMap, mapTo, takeUntil, delay, retryWhen, shareReplay, debounceTime, finalize } from 'rxjs/operators';
9
9
  import * as i1 from '@angular/common/http';
10
- import { HttpContextToken, HttpClient, HttpContext, HttpParams, HttpErrorResponse, HttpClientModule, HttpClientXsrfModule, HttpHeaders } from '@angular/common/http';
10
+ import { HttpClient, HttpContextToken, HttpContext, HttpParams, HttpErrorResponse, HttpClientModule, HttpClientXsrfModule, HttpHeaders } from '@angular/common/http';
11
11
  import compare from 'just-compare';
12
12
  import clone from 'just-clone';
13
13
  import * as i1$3 from '@angular/forms';
@@ -276,31 +276,27 @@ function escapeHtmlChars(value) {
276
276
  : value;
277
277
  }
278
278
 
279
- const IS_EXTERNAL_REQUEST = new HttpContextToken(() => false);
280
-
281
- // source : https://github.com/armanozak/demo-angular-server-specific-interceptors
282
- class ExternalHttpClient extends HttpClient {
283
- request(first, url, options = {}) {
284
- if (typeof first === 'string') {
285
- this.#setPlaceholderContext(options);
286
- return super.request(first, url || '', options);
287
- }
288
- this.#setPlaceholderContext(first);
289
- return super.request(first);
279
+ class ContentProjectionService {
280
+ constructor(injector) {
281
+ this.injector = injector;
290
282
  }
291
- #setPlaceholderContext(optionsOrRequest) {
292
- optionsOrRequest.context ??= new HttpContext();
293
- optionsOrRequest.context.set(IS_EXTERNAL_REQUEST, true);
283
+ projectContent(projectionStrategy, injector = this.injector) {
284
+ return projectionStrategy.injectContent(injector);
294
285
  }
295
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ExternalHttpClient, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
296
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ExternalHttpClient, providedIn: 'root' }); }
286
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ContentProjectionService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
287
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ContentProjectionService, providedIn: 'root' }); }
297
288
  }
298
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ExternalHttpClient, decorators: [{
289
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ContentProjectionService, decorators: [{
299
290
  type: Injectable,
300
- args: [{
301
- providedIn: 'root',
302
- }]
303
- }] });
291
+ args: [{ providedIn: 'root' }]
292
+ }], ctorParameters: () => [{ type: i0.Injector }] });
293
+
294
+ function pushValueTo(array) {
295
+ return (element) => {
296
+ array.push(element);
297
+ return array;
298
+ };
299
+ }
304
300
 
305
301
  function noop() {
306
302
  const fn = function () { };
@@ -337,6 +333,19 @@ function checkHasProp(object, key) {
337
333
  return Object.prototype.hasOwnProperty.call(object, key);
338
334
  }
339
335
 
336
+ function getShortDateFormat(configStateService) {
337
+ const dateTimeFormat = configStateService.getDeep('localization.currentCulture.dateTimeFormat');
338
+ return dateTimeFormat.shortDatePattern;
339
+ }
340
+ function getShortTimeFormat(configStateService) {
341
+ const dateTimeFormat = configStateService.getDeep('localization.currentCulture.dateTimeFormat');
342
+ return dateTimeFormat?.shortTimePattern?.replace('tt', 'a');
343
+ }
344
+ function getShortDateShortTimeFormat(configStateService) {
345
+ const dateTimeFormat = configStateService.getDeep('localization.currentCulture.dateTimeFormat');
346
+ return `${dateTimeFormat.shortDatePattern} ${dateTimeFormat?.shortTimePattern?.replace('tt', 'a')}`;
347
+ }
348
+
340
349
  function deepMerge(target, source) {
341
350
  if (isObjectAndNotArrayNotNode(target) && isObjectAndNotArrayNotNode(source)) {
342
351
  return deepMergeRecursively(target, source);
@@ -476,281 +485,139 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
476
485
  args: [{ providedIn: 'root' }]
477
486
  }] });
478
487
 
479
- class RestService {
480
- constructor(options, http, externalHttp, environment, httpErrorReporter) {
481
- this.options = options;
482
- this.http = http;
483
- this.externalHttp = externalHttp;
484
- this.environment = environment;
485
- this.httpErrorReporter = httpErrorReporter;
486
- }
487
- getApiFromStore(apiName) {
488
- return this.environment.getApiUrl(apiName);
489
- }
490
- handleError(err) {
491
- this.httpErrorReporter.reportError(err);
492
- return throwError(() => err);
493
- }
494
- request(request, config, api) {
495
- config = config || {};
496
- api = api || this.getApiFromStore(config.apiName);
497
- const { method, params, ...options } = request;
498
- const { observe = "body" /* Rest.Observe.Body */, skipHandleError } = config;
499
- const url = this.removeDuplicateSlashes(api + request.url);
500
- const httpClient = this.getHttpClient(config.skipAddingHeader);
501
- return httpClient
502
- .request(method, url, {
503
- observe,
504
- ...(params && {
505
- params: this.getParams(params, config.httpParamEncoder),
506
- }),
507
- ...options,
508
- })
509
- .pipe(catchError(err => (skipHandleError ? throwError(() => err) : this.handleError(err))));
488
+ function getRemoteEnv(injector, environment) {
489
+ const environmentService = injector.get(EnvironmentService);
490
+ const { remoteEnv } = environment;
491
+ const { headers = {}, method = 'GET', url } = remoteEnv || {};
492
+ if (!url)
493
+ return Promise.resolve();
494
+ const http = injector.get(HttpClient);
495
+ const httpErrorReporter = injector.get(HttpErrorReporterService);
496
+ return http
497
+ .request(method, url, { headers })
498
+ .pipe(catchError(err => {
499
+ httpErrorReporter.reportError(err);
500
+ return of(null);
501
+ }), // TODO: Consider get handle function from a provider
502
+ tap(env => environmentService.setState(mergeEnvironments(environment, env || {}, remoteEnv))))
503
+ .toPromise();
504
+ }
505
+ function mergeEnvironments(local, remote, config) {
506
+ switch (config.mergeStrategy) {
507
+ case 'deepmerge':
508
+ return deepMerge(local, remote);
509
+ case 'overwrite':
510
+ case null:
511
+ case undefined:
512
+ return remote;
513
+ default:
514
+ return config.mergeStrategy(local, remote);
510
515
  }
511
- getHttpClient(isExternal) {
512
- return isExternal ? this.externalHttp : this.http;
516
+ }
517
+
518
+ class LazyModuleFactory extends NgModuleFactory {
519
+ get moduleType() {
520
+ return this.moduleWithProviders.ngModule;
513
521
  }
514
- getParams(params, encoder) {
515
- const filteredParams = Object.entries(params).reduce((acc, [key, value]) => {
516
- if (isUndefinedOrEmptyString(value))
517
- return acc;
518
- if (value === null && !this.options.sendNullsAsQueryParam)
519
- return acc;
520
- acc[key] = value;
521
- return acc;
522
- }, {});
523
- return encoder
524
- ? new HttpParams({ encoder, fromObject: filteredParams })
525
- : new HttpParams({ fromObject: filteredParams });
522
+ constructor(moduleWithProviders) {
523
+ super();
524
+ this.moduleWithProviders = moduleWithProviders;
526
525
  }
527
- removeDuplicateSlashes(url) {
528
- return url.replace(/([^:]\/)\/+/g, '$1');
526
+ create(parentInjector) {
527
+ const injector = Injector.create({
528
+ ...(parentInjector && { parent: parentInjector }),
529
+ providers: this.moduleWithProviders.providers,
530
+ });
531
+ const compiler = injector.get(Compiler);
532
+ const factory = compiler.compileModuleSync(this.moduleType);
533
+ return factory.create(injector);
529
534
  }
530
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RestService, deps: [{ token: CORE_OPTIONS }, { token: i1.HttpClient }, { token: ExternalHttpClient }, { token: EnvironmentService }, { token: HttpErrorReporterService }], target: i0.ɵɵFactoryTarget.Injectable }); }
531
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RestService, providedIn: 'root' }); }
532
535
  }
533
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RestService, decorators: [{
534
- type: Injectable,
535
- args: [{
536
- providedIn: 'root',
537
- }]
538
- }], ctorParameters: () => [{ type: undefined, decorators: [{
539
- type: Inject,
540
- args: [CORE_OPTIONS]
541
- }] }, { type: i1.HttpClient }, { type: ExternalHttpClient }, { type: EnvironmentService }, { type: HttpErrorReporterService }] });
536
+ function featuresFactory(configState, featureKeys, mapFn = features => features) {
537
+ return configState.getFeatures$(featureKeys).pipe(filter(Boolean), map(mapFn));
538
+ }
542
539
 
543
- class AbpApplicationConfigurationService {
544
- constructor(restService) {
545
- this.restService = restService;
546
- this.apiName = 'abp';
547
- this.get = (options) => this.restService.request({
548
- method: 'GET',
549
- url: '/api/abp/application-configuration',
550
- params: { includeLocalizationResources: options.includeLocalizationResources },
551
- }, { apiName: this.apiName });
552
- }
553
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationConfigurationService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable }); }
554
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationConfigurationService, providedIn: 'root' }); }
540
+ /** @deprecated the method will change in v8.0 */
541
+ function downloadBlob(blob, filename) {
542
+ const blobUrl = URL.createObjectURL(blob);
543
+ const link = document.createElement('a');
544
+ link.href = blobUrl;
545
+ link.download = filename;
546
+ document.body.appendChild(link);
547
+ link.dispatchEvent(new MouseEvent('click', {
548
+ bubbles: true,
549
+ cancelable: true,
550
+ view: window,
551
+ }));
552
+ document.body.removeChild(link);
555
553
  }
556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationConfigurationService, decorators: [{
557
- type: Injectable,
558
- args: [{
559
- providedIn: 'root',
560
- }]
561
- }], ctorParameters: () => [{ type: RestService }] });
562
554
 
563
- class AbpApplicationLocalizationService {
564
- constructor(restService) {
565
- this.restService = restService;
566
- this.apiName = 'abp';
567
- this.get = (input) => this.restService.request({
568
- method: 'GET',
569
- url: '/api/abp/application-localization',
570
- params: { cultureName: input.cultureName, onlyDynamics: input.onlyDynamics },
571
- }, { apiName: this.apiName });
572
- }
573
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationLocalizationService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable }); }
574
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationLocalizationService, providedIn: 'root' }); }
555
+ function isNumber(value) {
556
+ return value == Number(value);
575
557
  }
576
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationLocalizationService, decorators: [{
577
- type: Injectable,
578
- args: [{
579
- providedIn: 'root',
580
- }]
581
- }], ctorParameters: () => [{ type: RestService }] });
582
558
 
583
- const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken('INCUDE_LOCALIZATION_RESOURCES_TOKEN');
559
+ function mapEnumToOptions(_enum) {
560
+ const options = [];
561
+ for (const member in _enum)
562
+ if (!isNumber(member))
563
+ options.push({
564
+ key: member,
565
+ value: _enum[member],
566
+ });
567
+ return options;
568
+ }
584
569
 
585
- class ConfigStateService {
586
- setState(config) {
587
- this.store.set(config);
588
- }
589
- get createOnUpdateStream() {
590
- return this.store.sliceUpdate;
570
+ function uuid(a) {
571
+ return a
572
+ ? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
573
+ : ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);
574
+ }
575
+ function generateHash(value) {
576
+ let hashed = 0;
577
+ let charCode;
578
+ for (let i = 0; i < value.length; i++) {
579
+ charCode = value.charCodeAt(i);
580
+ hashed = (hashed << 5) - hashed + charCode;
581
+ hashed |= 0;
591
582
  }
592
- constructor(abpConfigService, abpApplicationLocalizationService, includeLocalizationResources) {
593
- this.abpConfigService = abpConfigService;
594
- this.abpApplicationLocalizationService = abpApplicationLocalizationService;
595
- this.includeLocalizationResources = includeLocalizationResources;
596
- this.updateSubject = new Subject();
597
- this.store = new InternalStore({});
598
- this.initUpdateStream();
583
+ return hashed;
584
+ }
585
+ function generatePassword(length = 8) {
586
+ length = Math.min(Math.max(4, length), 128);
587
+ const lowers = 'abcdefghijklmnopqrstuvwxyz';
588
+ const uppers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
589
+ const numbers = '0123456789';
590
+ const specials = '!@#$%&*()_+{}<>?[]./';
591
+ const all = lowers + uppers + numbers + specials;
592
+ const getRandom = (chrSet) => chrSet[Math.floor(Math.random() * chrSet.length)];
593
+ const password = Array({ length });
594
+ password[0] = getRandom(lowers);
595
+ password[1] = getRandom(uppers);
596
+ password[2] = getRandom(numbers);
597
+ password[3] = getRandom(specials);
598
+ for (let i = 4; i < length; i++) {
599
+ password[i] = getRandom(all);
599
600
  }
600
- initUpdateStream() {
601
- this.updateSubject
602
- .pipe(switchMap(() => this.abpConfigService.get({
603
- includeLocalizationResources: !!this.includeLocalizationResources,
604
- })))
605
- .pipe(switchMap(appState => this.getLocalizationAndCombineWithAppState(appState)))
606
- .subscribe(res => this.store.set(res));
607
- }
608
- getLocalizationAndCombineWithAppState(appState) {
609
- if (!appState.localization.currentCulture.cultureName) {
610
- throw new Error('culture name should defined');
611
- }
612
- return this.getlocalizationResource(appState.localization.currentCulture.cultureName).pipe(map(result => ({ ...appState, localization: { ...appState.localization, ...result } })));
613
- }
614
- getlocalizationResource(cultureName) {
615
- return this.abpApplicationLocalizationService.get({
616
- cultureName: cultureName,
617
- onlyDynamics: false,
618
- });
619
- }
620
- refreshAppState() {
621
- this.updateSubject.next();
622
- return this.createOnUpdateStream(state => state).pipe(take(1));
623
- }
624
- refreshLocalization(lang) {
625
- if (this.includeLocalizationResources) {
626
- return this.refreshAppState().pipe(map(() => null));
627
- }
628
- else {
629
- return this.getlocalizationResource(lang)
630
- .pipe(tap(result => this.store.patch({ localization: { ...this.store.state.localization, ...result } })))
631
- .pipe(map(() => null));
632
- }
633
- }
634
- getOne$(key) {
635
- return this.store.sliceState(state => state[key]);
636
- }
637
- getOne(key) {
638
- return this.store.state[key];
639
- }
640
- getAll$() {
641
- return this.store.sliceState(state => state);
642
- }
643
- getAll() {
644
- return this.store.state;
645
- }
646
- getDeep$(keys) {
647
- keys = splitKeys(keys);
648
- return this.store
649
- .sliceState(state => state)
650
- .pipe(map(state => {
651
- return keys.reduce((acc, val) => {
652
- if (acc) {
653
- return acc[val];
654
- }
655
- return undefined;
656
- }, state);
657
- }));
658
- }
659
- getDeep(keys) {
660
- keys = splitKeys(keys);
661
- return keys.reduce((acc, val) => {
662
- if (acc) {
663
- return acc[val];
664
- }
665
- return undefined;
666
- }, this.store.state);
667
- }
668
- getFeature(key) {
669
- return this.store.state.features?.values?.[key];
670
- }
671
- getFeature$(key) {
672
- return this.store.sliceState(state => state.features?.values?.[key]);
673
- }
674
- getFeatures(keys) {
675
- const { features } = this.store.state;
676
- if (!features)
677
- return;
678
- return keys.reduce((acc, key) => ({ ...acc, [key]: features.values[key] }), {});
679
- }
680
- getFeatures$(keys) {
681
- return this.store.sliceState(({ features }) => {
682
- if (!features?.values)
683
- return;
684
- return keys.reduce((acc, key) => ({ ...acc, [key]: features.values[key] }), {});
685
- });
686
- }
687
- getSetting(key) {
688
- return this.store.state.setting?.values?.[key];
689
- }
690
- getSetting$(key) {
691
- return this.store.sliceState(state => state.setting?.values?.[key]);
692
- }
693
- getSettings(keyword) {
694
- const settings = this.store.state.setting?.values || {};
695
- if (!keyword)
696
- return settings;
697
- const keysFound = Object.keys(settings).filter(key => key.indexOf(keyword) > -1);
698
- return keysFound.reduce((acc, key) => {
699
- acc[key] = settings[key];
700
- return acc;
701
- }, {});
702
- }
703
- getSettings$(keyword) {
704
- return this.store
705
- .sliceState(state => state.setting?.values)
706
- .pipe(map((settings = {}) => {
707
- if (!keyword)
708
- return settings;
709
- const keysFound = Object.keys(settings).filter(key => key.indexOf(keyword) > -1);
710
- return keysFound.reduce((acc, key) => {
711
- acc[key] = settings[key];
712
- return acc;
713
- }, {});
714
- }));
715
- }
716
- getGlobalFeatures() {
717
- return this.store.state.globalFeatures;
718
- }
719
- getGlobalFeatures$() {
720
- return this.store.sliceState(state => state.globalFeatures);
721
- }
722
- isGlobalFeatureEnabled(key, globalFeatures) {
723
- const features = globalFeatures.enabledFeatures || [];
724
- return features.some(f => key === f);
725
- }
726
- getGlobalFeatureIsEnabled(key) {
727
- return this.isGlobalFeatureEnabled(key, this.store.state.globalFeatures);
601
+ return password.sort(() => 0.5 - Math.random()).join('');
602
+ }
603
+
604
+ function getPathName(url) {
605
+ const { pathname } = new URL(url, window.location.origin);
606
+ return pathname;
607
+ }
608
+ class WebHttpUrlEncodingCodec {
609
+ encodeKey(k) {
610
+ return encodeURIComponent(k);
728
611
  }
729
- getGlobalFeatureIsEnabled$(key) {
730
- return this.store.sliceState(state => this.isGlobalFeatureEnabled(key, state.globalFeatures));
612
+ encodeValue(v) {
613
+ return encodeURIComponent(v);
731
614
  }
732
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ConfigStateService, deps: [{ token: AbpApplicationConfigurationService }, { token: AbpApplicationLocalizationService }, { token: INCUDE_LOCALIZATION_RESOURCES_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
733
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ConfigStateService, providedIn: 'root' }); }
734
- }
735
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ConfigStateService, decorators: [{
736
- type: Injectable,
737
- args: [{
738
- providedIn: 'root',
739
- }]
740
- }], ctorParameters: () => [{ type: AbpApplicationConfigurationService }, { type: AbpApplicationLocalizationService }, { type: undefined, decorators: [{
741
- type: Optional
742
- }, {
743
- type: Inject,
744
- args: [INCUDE_LOCALIZATION_RESOURCES_TOKEN]
745
- }] }] });
746
- function splitKeys(keys) {
747
- if (typeof keys === 'string') {
748
- keys = keys.split('.');
615
+ decodeKey(k) {
616
+ return decodeURIComponent(k);
749
617
  }
750
- if (!Array.isArray(keys)) {
751
- throw new Error('The argument must be a dot string or an string array.');
618
+ decodeValue(v) {
619
+ return decodeURIComponent(v);
752
620
  }
753
- return keys;
754
621
  }
755
622
 
756
623
  class AbpLocalStorageService {
@@ -854,208 +721,427 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
854
721
  }]
855
722
  }], ctorParameters: () => [{ type: ConfigStateService }, { type: AbpLocalStorageService }] });
856
723
 
857
- class LocalizationService {
858
- /**
859
- * Returns currently selected language
860
- * Even though this looks like it's redundant to return the same value as `getLanguage()`,
861
- * it's actually not. This could be invoked any time, and the latestLang could be different from the
862
- * sessionState.getLanguage() value.
863
- */
864
- get currentLang() {
865
- return this.latestLang || this.sessionState.getLanguage();
724
+ const APP_INIT_ERROR_HANDLERS = new InjectionToken('APP_INIT_ERROR_HANDLERS');
725
+
726
+ class AbpTenantService {
727
+ constructor(restService) {
728
+ this.restService = restService;
729
+ this.apiName = 'abp';
730
+ this.findTenantById = (id, config) => this.restService.request({
731
+ method: 'GET',
732
+ url: `/api/abp/multi-tenancy/tenants/by-id/${id}`,
733
+ }, { apiName: this.apiName, ...config });
734
+ this.findTenantByName = (name, config) => this.restService.request({
735
+ method: 'GET',
736
+ url: `/api/abp/multi-tenancy/tenants/by-name/${name}`,
737
+ }, { apiName: this.apiName, ...config });
866
738
  }
867
- get currentLang$() {
868
- return this.sessionState.getLanguage$();
739
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpTenantService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable }); }
740
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpTenantService, providedIn: 'root' }); }
741
+ }
742
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpTenantService, decorators: [{
743
+ type: Injectable,
744
+ args: [{
745
+ providedIn: 'root',
746
+ }]
747
+ }], ctorParameters: () => [{ type: RestService }] });
748
+
749
+ const TENANT_KEY = new InjectionToken('TENANT_KEY');
750
+
751
+ const IS_EXTERNAL_REQUEST = new HttpContextToken(() => false);
752
+
753
+ // source : https://github.com/armanozak/demo-angular-server-specific-interceptors
754
+ class ExternalHttpClient extends HttpClient {
755
+ request(first, url, options = {}) {
756
+ if (typeof first === 'string') {
757
+ this.#setPlaceholderContext(options);
758
+ return super.request(first, url || '', options);
759
+ }
760
+ this.#setPlaceholderContext(first);
761
+ return super.request(first);
869
762
  }
870
- get languageChange$() {
871
- return this._languageChange$.asObservable();
763
+ #setPlaceholderContext(optionsOrRequest) {
764
+ optionsOrRequest.context ??= new HttpContext();
765
+ optionsOrRequest.context.set(IS_EXTERNAL_REQUEST, true);
872
766
  }
873
- constructor(sessionState, injector, otherInstance, configState) {
874
- this.sessionState = sessionState;
875
- this.injector = injector;
876
- this.configState = configState;
877
- this.latestLang = this.sessionState.getLanguage();
878
- this._languageChange$ = new Subject();
879
- this.uiLocalizations$ = new BehaviorSubject(new Map());
880
- this.localizations$ = new BehaviorSubject(new Map());
881
- if (otherInstance)
882
- throw new Error('LocalizationService should have only one instance.');
883
- this.listenToSetLanguage();
884
- this.initLocalizationValues();
767
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ExternalHttpClient, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
768
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ExternalHttpClient, providedIn: 'root' }); }
769
+ }
770
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ExternalHttpClient, decorators: [{
771
+ type: Injectable,
772
+ args: [{
773
+ providedIn: 'root',
774
+ }]
775
+ }] });
776
+
777
+ class RestService {
778
+ constructor(options, http, externalHttp, environment, httpErrorReporter) {
779
+ this.options = options;
780
+ this.http = http;
781
+ this.externalHttp = externalHttp;
782
+ this.environment = environment;
783
+ this.httpErrorReporter = httpErrorReporter;
885
784
  }
886
- initLocalizationValues() {
887
- localizations$.subscribe(val => this.addLocalization(val));
888
- const legacyResources$ = this.configState.getDeep$('localization.values');
889
- const remoteLocalizations$ = this.configState.getDeep$('localization.resources');
890
- const currentLanguage$ = this.sessionState.getLanguage$();
891
- const uiLocalizations$ = combineLatest([currentLanguage$, this.uiLocalizations$]).pipe(map(([currentLang, localizations]) => localizations.get(currentLang)));
892
- combineLatest([legacyResources$, remoteLocalizations$, uiLocalizations$])
893
- .pipe(map(([legacy, resource, local]) => {
894
- if (!resource) {
895
- return;
896
- }
897
- const remote = combineLegacyandNewResources(legacy || {}, resource);
898
- if (remote) {
899
- if (!local) {
900
- local = new Map();
901
- }
902
- Object.entries(remote).forEach(entry => {
903
- const resourceName = entry[0];
904
- const remoteTexts = entry[1];
905
- let resource = local?.get(resourceName) || {};
906
- resource = { ...resource, ...remoteTexts };
907
- local?.set(resourceName, resource);
908
- });
909
- }
910
- return local;
911
- }), filter(Boolean))
912
- .subscribe(val => this.localizations$.next(val));
785
+ getApiFromStore(apiName) {
786
+ return this.environment.getApiUrl(apiName);
913
787
  }
914
- addLocalization(localizations) {
915
- if (!localizations)
916
- return;
917
- const localizationMap = this.uiLocalizations$.value;
918
- localizations.forEach(loc => {
919
- const cultureMap = localizationMap.get(loc.culture) || new Map();
920
- loc.resources.forEach(res => {
921
- let resource = cultureMap.get(res.resourceName) || {};
922
- resource = { ...resource, ...res.texts };
923
- cultureMap.set(res.resourceName, resource);
924
- });
925
- localizationMap.set(loc.culture, cultureMap);
926
- });
927
- this.uiLocalizations$.next(localizationMap);
788
+ handleError(err) {
789
+ this.httpErrorReporter.reportError(err);
790
+ return throwError(() => err);
928
791
  }
929
- listenToSetLanguage() {
930
- this.sessionState
931
- .onLanguageChange$()
932
- .pipe(filter(lang => this.configState.getDeep('localization.currentCulture.cultureName') !== lang), switchMap(lang => this.configState.refreshAppState().pipe(map(() => lang))), filter(Boolean), switchMap(lang => from(this.registerLocale(lang).then(() => lang))))
933
- .subscribe(lang => this._languageChange$.next(lang));
792
+ request(request, config, api) {
793
+ config = config || {};
794
+ api = api || this.getApiFromStore(config.apiName);
795
+ const { method, params, ...options } = request;
796
+ const { observe = "body" /* Rest.Observe.Body */, skipHandleError } = config;
797
+ const url = this.removeDuplicateSlashes(api + request.url);
798
+ const httpClient = this.getHttpClient(config.skipAddingHeader);
799
+ return httpClient
800
+ .request(method, url, {
801
+ observe,
802
+ ...(params && {
803
+ params: this.getParams(params, config.httpParamEncoder),
804
+ }),
805
+ ...options,
806
+ })
807
+ .pipe(catchError(err => (skipHandleError ? throwError(() => err) : this.handleError(err))));
934
808
  }
935
- registerLocale(locale) {
936
- const { registerLocaleFn } = this.injector.get(CORE_OPTIONS);
937
- return registerLocaleFn(locale).then(module => {
938
- if (module?.default)
939
- registerLocaleData(module.default);
940
- this.latestLang = locale;
941
- });
809
+ getHttpClient(isExternal) {
810
+ return isExternal ? this.externalHttp : this.http;
942
811
  }
943
- /**
944
- * Returns an observable localized text with the given interpolation parameters in current language.
945
- * @param key Localizaton key to replace with localized text
946
- * @param interpolateParams Values to interpolate
947
- */
948
- get(key, ...interpolateParams) {
949
- return this.configState
950
- .getAll$()
951
- .pipe(map(state => this.getLocalization(state, key, ...interpolateParams)));
812
+ getParams(params, encoder) {
813
+ const filteredParams = Object.entries(params).reduce((acc, [key, value]) => {
814
+ if (isUndefinedOrEmptyString(value))
815
+ return acc;
816
+ if (value === null && !this.options.sendNullsAsQueryParam)
817
+ return acc;
818
+ acc[key] = value;
819
+ return acc;
820
+ }, {});
821
+ return encoder
822
+ ? new HttpParams({ encoder, fromObject: filteredParams })
823
+ : new HttpParams({ fromObject: filteredParams });
952
824
  }
953
- getResource(resourceName) {
954
- return this.localizations$.value.get(resourceName);
825
+ removeDuplicateSlashes(url) {
826
+ return url.replace(/([^:]\/)\/+/g, '$1');
955
827
  }
956
- getResource$(resourceName) {
957
- return this.localizations$.pipe(map(res => res.get(resourceName)));
828
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RestService, deps: [{ token: CORE_OPTIONS }, { token: i1.HttpClient }, { token: ExternalHttpClient }, { token: EnvironmentService }, { token: HttpErrorReporterService }], target: i0.ɵɵFactoryTarget.Injectable }); }
829
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RestService, providedIn: 'root' }); }
830
+ }
831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RestService, decorators: [{
832
+ type: Injectable,
833
+ args: [{
834
+ providedIn: 'root',
835
+ }]
836
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
837
+ type: Inject,
838
+ args: [CORE_OPTIONS]
839
+ }] }, { type: i1.HttpClient }, { type: ExternalHttpClient }, { type: EnvironmentService }, { type: HttpErrorReporterService }] });
840
+
841
+ class MultiTenancyService {
842
+ constructor(restService, sessionState, tenantService, configStateService, tenantKey) {
843
+ this.restService = restService;
844
+ this.sessionState = sessionState;
845
+ this.tenantService = tenantService;
846
+ this.configStateService = configStateService;
847
+ this.tenantKey = tenantKey;
848
+ this.domainTenant = null;
849
+ this.isTenantBoxVisible = true;
850
+ this.apiName = 'abp';
851
+ this.setTenantToState = (tenant) => {
852
+ this.sessionState.setTenant({ id: tenant.tenantId, name: tenant.name, isAvailable: true });
853
+ return this.configStateService.refreshAppState().pipe(map(_ => tenant));
854
+ };
855
+ }
856
+ setTenantByName(tenantName) {
857
+ return this.tenantService
858
+ .findTenantByName(tenantName)
859
+ .pipe(switchMap(this.setTenantToState));
860
+ }
861
+ setTenantById(tenantId) {
862
+ return this.tenantService
863
+ .findTenantById(tenantId)
864
+ .pipe(switchMap(this.setTenantToState));
865
+ }
866
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: MultiTenancyService, deps: [{ token: RestService }, { token: SessionStateService }, { token: AbpTenantService }, { token: ConfigStateService }, { token: TENANT_KEY }], target: i0.ɵɵFactoryTarget.Injectable }); }
867
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: MultiTenancyService, providedIn: 'root' }); }
868
+ }
869
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: MultiTenancyService, decorators: [{
870
+ type: Injectable,
871
+ args: [{ providedIn: 'root' }]
872
+ }], ctorParameters: () => [{ type: RestService }, { type: SessionStateService }, { type: AbpTenantService }, { type: ConfigStateService }, { type: undefined, decorators: [{
873
+ type: Inject,
874
+ args: [TENANT_KEY]
875
+ }] }] });
876
+
877
+ const TENANT_NOT_FOUND_BY_NAME = new InjectionToken('TENANT_NOT_FOUND_BY_NAME');
878
+
879
+ const tenancyPlaceholder = '{0}';
880
+ function getCurrentTenancyName(appBaseUrl) {
881
+ if (appBaseUrl.charAt(appBaseUrl.length - 1) !== '/')
882
+ appBaseUrl += '/';
883
+ const parseTokens = createTokenParser(appBaseUrl);
884
+ const token = tenancyPlaceholder.replace(/[}{]/g, '');
885
+ return parseTokens(window.location.href)[token]?.[0];
886
+ }
887
+ function getCurrentTenancyNameFromUrl(tenantKey) {
888
+ const urlParams = new URLSearchParams(window.location.search);
889
+ return urlParams.get(tenantKey);
890
+ }
891
+ async function parseTenantFromUrl(injector) {
892
+ const environmentService = injector.get(EnvironmentService);
893
+ const multiTenancyService = injector.get(MultiTenancyService);
894
+ const tenantNotFoundHandler = injector.get(TENANT_NOT_FOUND_BY_NAME, null);
895
+ const baseUrl = environmentService.getEnvironment()?.application?.baseUrl || '';
896
+ const tenancyName = getCurrentTenancyName(baseUrl);
897
+ const hideTenantBox = () => {
898
+ multiTenancyService.isTenantBoxVisible = false;
899
+ };
900
+ const setDomainTenant = (tenant) => {
901
+ multiTenancyService.domainTenant = {
902
+ id: tenant.tenantId,
903
+ name: tenant.name,
904
+ isAvailable: true,
905
+ };
906
+ };
907
+ const setEnvironmentWithDomainTenant = (tenant) => {
908
+ hideTenantBox();
909
+ setDomainTenant(tenant);
910
+ };
911
+ if (tenancyName) {
912
+ /**
913
+ * We have to replace tenant name within the urls from environment,
914
+ * because the code below will make a http request to find information about the domain tenant.
915
+ * Before this request takes place, we need to replace placeholders aka "{0}".
916
+ */
917
+ replaceTenantNameWithinEnvironment(injector, tenancyName);
918
+ const tenant$ = multiTenancyService.setTenantByName(tenancyName);
919
+ try {
920
+ const result = await firstValueFrom(tenant$);
921
+ setEnvironmentWithDomainTenant(result);
922
+ return Promise.resolve(result);
923
+ }
924
+ catch (httpError) {
925
+ if (httpError instanceof HttpErrorResponse &&
926
+ httpError.status === 404 &&
927
+ tenantNotFoundHandler) {
928
+ tenantNotFoundHandler(httpError);
929
+ }
930
+ return Promise.reject();
931
+ }
958
932
  }
959
933
  /**
960
- * Returns localized text with the given interpolation parameters in current language.
961
- * @param key Localization key to replace with localized text
962
- * @param interpolateParams Values to intepolate.
934
+ * If there is no tenant, we still have to clean up {0}. from baseUrl to avoid incorrect http requests.
963
935
  */
964
- instant(key, ...interpolateParams) {
965
- return this.getLocalization(this.configState.getAll(), key, ...interpolateParams);
936
+ replaceTenantNameWithinEnvironment(injector, '', tenancyPlaceholder + '.');
937
+ const tenantIdFromQueryParams = getCurrentTenancyNameFromUrl(multiTenancyService.tenantKey);
938
+ if (tenantIdFromQueryParams) {
939
+ const tenantById$ = multiTenancyService.setTenantById(tenantIdFromQueryParams);
940
+ return firstValueFrom(tenantById$);
966
941
  }
967
- localize(resourceName, key, defaultValue) {
968
- return this.configState.getOne$('localization').pipe(map(createLocalizer), map(localize => localize(resourceName, key, defaultValue)));
942
+ return Promise.resolve();
943
+ }
944
+ function replaceTenantNameWithinEnvironment(injector, tenancyName, placeholder = tenancyPlaceholder) {
945
+ const environmentService = injector.get(EnvironmentService);
946
+ const environment = clone(environmentService.getEnvironment());
947
+ if (environment.application.baseUrl) {
948
+ environment.application.baseUrl = environment.application.baseUrl.replace(placeholder, tenancyName);
969
949
  }
970
- localizeSync(resourceName, key, defaultValue) {
971
- const localization = this.configState.getOne('localization');
972
- return createLocalizer(localization)(resourceName, key, defaultValue);
950
+ if (environment.oAuthConfig?.redirectUri) {
951
+ environment.oAuthConfig.redirectUri = environment.oAuthConfig.redirectUri.replace(placeholder, tenancyName);
973
952
  }
974
- localizeWithFallback(resourceNames, keys, defaultValue) {
975
- return this.configState.getOne$('localization').pipe(map(createLocalizerWithFallback), map(localizeWithFallback => localizeWithFallback(resourceNames, keys, defaultValue)));
953
+ if (!environment.oAuthConfig) {
954
+ environment.oAuthConfig = {};
976
955
  }
977
- localizeWithFallbackSync(resourceNames, keys, defaultValue) {
978
- const localization = this.configState.getOne('localization');
979
- return createLocalizerWithFallback(localization)(resourceNames, keys, defaultValue);
956
+ environment.oAuthConfig.issuer = (environment.oAuthConfig.issuer || '').replace(placeholder, tenancyName);
957
+ Object.keys(environment.apis).forEach(api => {
958
+ Object.keys(environment.apis[api]).forEach(key => {
959
+ environment.apis[api][key] = (environment.apis[api][key] || '').replace(placeholder, tenancyName);
960
+ });
961
+ });
962
+ return environmentService.setState(environment);
963
+ }
964
+
965
+ const CHECK_AUTHENTICATION_STATE_FN_KEY = new InjectionToken('CHECK_AUTHENTICATION_STATE_FN_KEY');
966
+
967
+ function getInitialData(injector) {
968
+ const fn = async () => {
969
+ const environmentService = injector.get(EnvironmentService);
970
+ const configState = injector.get(ConfigStateService);
971
+ const options = injector.get(CORE_OPTIONS);
972
+ environmentService.setState(options.environment);
973
+ await getRemoteEnv(injector, options.environment);
974
+ await parseTenantFromUrl(injector);
975
+ const authService = injector.get(AuthService, undefined, { optional: true });
976
+ const checkAuthenticationState = injector.get(CHECK_AUTHENTICATION_STATE_FN_KEY, noop, {
977
+ optional: true,
978
+ });
979
+ if (!options.skipInitAuthService && authService) {
980
+ await authService.init();
981
+ }
982
+ if (options.skipGetAppConfiguration)
983
+ return;
984
+ const result$ = configState.refreshAppState().pipe(tap(() => checkAuthenticationState(injector)), tap(() => {
985
+ const currentTenant = configState.getOne('currentTenant');
986
+ injector.get(SessionStateService).setTenant(currentTenant);
987
+ }), catchError(error => {
988
+ const appInitErrorHandlers = injector.get(APP_INIT_ERROR_HANDLERS, null);
989
+ if (appInitErrorHandlers && appInitErrorHandlers.length) {
990
+ appInitErrorHandlers.forEach(func => func(error));
991
+ }
992
+ return throwError(error);
993
+ }));
994
+ await lastValueFrom(result$);
995
+ };
996
+ return fn;
997
+ }
998
+ function localeInitializer(injector) {
999
+ const fn = () => {
1000
+ const sessionState = injector.get(SessionStateService);
1001
+ const { registerLocaleFn } = injector.get(CORE_OPTIONS);
1002
+ const lang = sessionState.getLanguage() || 'en';
1003
+ return new Promise((resolve, reject) => {
1004
+ registerLocaleFn(lang).then(module => {
1005
+ if (module?.default)
1006
+ registerLocaleData(module.default);
1007
+ return resolve('resolved');
1008
+ }, reject);
1009
+ });
1010
+ };
1011
+ return fn;
1012
+ }
1013
+
1014
+ class CrossOriginStrategy {
1015
+ constructor(crossorigin, integrity) {
1016
+ this.crossorigin = crossorigin;
1017
+ this.integrity = integrity;
980
1018
  }
981
- getLocalization(state, key, ...interpolateParams) {
982
- if (!key)
983
- key = '';
984
- let defaultValue = '';
985
- if (typeof key !== 'string') {
986
- defaultValue = key.defaultValue;
987
- key = key.key;
1019
+ setCrossOrigin(element) {
1020
+ if (this.integrity)
1021
+ element.setAttribute('integrity', this.integrity);
1022
+ if (this.crossorigin) {
1023
+ element.setAttribute('crossorigin', this.crossorigin);
988
1024
  }
989
- const keys = key.split('::');
990
- const warn = (message) => {
991
- if (isDevMode())
992
- console.warn(message);
1025
+ }
1026
+ }
1027
+ class NoCrossOriginStrategy extends CrossOriginStrategy {
1028
+ setCrossOrigin() { }
1029
+ }
1030
+ const CROSS_ORIGIN_STRATEGY = {
1031
+ Anonymous(integrity) {
1032
+ return new CrossOriginStrategy('anonymous', integrity);
1033
+ },
1034
+ UseCredentials(integrity) {
1035
+ return new CrossOriginStrategy('use-credentials', integrity);
1036
+ },
1037
+ None() {
1038
+ return new NoCrossOriginStrategy(null);
1039
+ },
1040
+ };
1041
+
1042
+ class DomStrategy {
1043
+ constructor(target = document.head, position = 'beforeend') {
1044
+ this.target = target;
1045
+ this.position = position;
1046
+ }
1047
+ insertElement(element) {
1048
+ this.target.insertAdjacentElement(this.position, element);
1049
+ }
1050
+ }
1051
+ const DOM_STRATEGY = {
1052
+ AfterElement(element) {
1053
+ return new DomStrategy(element, 'afterend');
1054
+ },
1055
+ AppendToBody() {
1056
+ return new DomStrategy(document.body, 'beforeend');
1057
+ },
1058
+ AppendToHead() {
1059
+ return new DomStrategy(document.head, 'beforeend');
1060
+ },
1061
+ BeforeElement(element) {
1062
+ return new DomStrategy(element, 'beforebegin');
1063
+ },
1064
+ PrependToHead() {
1065
+ return new DomStrategy(document.head, 'afterbegin');
1066
+ },
1067
+ };
1068
+
1069
+ function fromLazyLoad(element, domStrategy = DOM_STRATEGY.AppendToHead(), crossOriginStrategy = CROSS_ORIGIN_STRATEGY.Anonymous()) {
1070
+ crossOriginStrategy.setCrossOrigin(element);
1071
+ domStrategy.insertElement(element);
1072
+ return new Observable((observer) => {
1073
+ element.onload = (event) => {
1074
+ clearCallbacks(element);
1075
+ observer.next(event);
1076
+ observer.complete();
993
1077
  };
994
- if (keys.length < 2) {
995
- warn('The localization source separator (::) not found.');
996
- return defaultValue || key;
997
- }
998
- if (!state.localization)
999
- return defaultValue || keys[1];
1000
- const sourceName = keys[0] || state.localization.defaultResourceName;
1001
- const sourceKey = keys[1];
1002
- if (sourceName === '_') {
1003
- return defaultValue || sourceKey;
1004
- }
1005
- if (!sourceName) {
1006
- warn('Localization source name is not specified and the defaultResourceName was not defined!');
1007
- return defaultValue || sourceKey;
1078
+ const handleError = createErrorHandler(observer, element);
1079
+ element.onerror = handleError;
1080
+ element.onabort = handleError;
1081
+ element.onemptied = handleError;
1082
+ element.onstalled = handleError;
1083
+ element.onsuspend = handleError;
1084
+ return () => {
1085
+ clearCallbacks(element);
1086
+ observer.complete();
1087
+ };
1088
+ });
1089
+ }
1090
+ function createErrorHandler(observer, element) {
1091
+ return function (event) {
1092
+ clearCallbacks(element);
1093
+ element.parentNode?.removeChild(element);
1094
+ observer.error(event);
1095
+ };
1096
+ }
1097
+ function clearCallbacks(element) {
1098
+ element.onload = null;
1099
+ element.onerror = null;
1100
+ element.onabort = null;
1101
+ element.onemptied = null;
1102
+ element.onstalled = null;
1103
+ element.onsuspend = null;
1104
+ }
1105
+
1106
+ class DefaultQueueManager {
1107
+ constructor() {
1108
+ this.queue = [];
1109
+ this.isRunning = false;
1110
+ this.stack = 0;
1111
+ this.interval = 0;
1112
+ this.stackSize = 100;
1113
+ }
1114
+ init(interval, stackSize) {
1115
+ this.interval = interval;
1116
+ this.stackSize = stackSize;
1117
+ }
1118
+ add(fn) {
1119
+ this.queue.push(fn);
1120
+ this.run();
1121
+ }
1122
+ run() {
1123
+ if (this.isRunning)
1124
+ return;
1125
+ this.stack++;
1126
+ this.isRunning = true;
1127
+ const fn = this.queue.shift();
1128
+ if (!fn) {
1129
+ this.isRunning = false;
1130
+ return;
1008
1131
  }
1009
- const source = this.localizations$.value.get(sourceName);
1010
- if (!source) {
1011
- warn('Could not find localization source: ' + sourceName);
1012
- return defaultValue || sourceKey;
1132
+ fn();
1133
+ if (this.stack > this.stackSize) {
1134
+ setTimeout(() => {
1135
+ this.isRunning = false;
1136
+ this.run();
1137
+ this.stack = 0;
1138
+ }, this.interval);
1013
1139
  }
1014
- let localization = source[sourceKey];
1015
- if (typeof localization === 'undefined') {
1016
- return defaultValue || sourceKey;
1140
+ else {
1141
+ this.isRunning = false;
1142
+ this.run();
1017
1143
  }
1018
- interpolateParams = interpolateParams.filter(params => params != null);
1019
- if (localization)
1020
- localization = interpolate(localization, interpolateParams);
1021
- if (typeof localization !== 'string')
1022
- localization = '';
1023
- return localization || defaultValue || key;
1024
- }
1025
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalizationService, deps: [{ token: SessionStateService }, { token: i0.Injector }, { token: LocalizationService, optional: true, skipSelf: true }, { token: ConfigStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1026
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalizationService, providedIn: 'root' }); }
1027
- }
1028
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalizationService, decorators: [{
1029
- type: Injectable,
1030
- args: [{ providedIn: 'root' }]
1031
- }], ctorParameters: () => [{ type: SessionStateService }, { type: i0.Injector }, { type: LocalizationService, decorators: [{
1032
- type: Optional
1033
- }, {
1034
- type: SkipSelf
1035
- }] }, { type: ConfigStateService }] });
1036
- function recursivelyMergeBaseResources(baseResourceName, source) {
1037
- const item = source[baseResourceName];
1038
- if (item.baseResources.length === 0) {
1039
- return item;
1040
1144
  }
1041
- return item.baseResources.reduce((acc, baseResource) => {
1042
- const baseItem = recursivelyMergeBaseResources(baseResource, source);
1043
- const texts = { ...baseItem.texts, ...item.texts };
1044
- return { ...acc, texts };
1045
- }, item);
1046
- }
1047
- function mergeResourcesWithBaseResource(resource) {
1048
- const entities = Object.keys(resource).map(key => {
1049
- const newValue = recursivelyMergeBaseResources(key, resource);
1050
- return [key, newValue];
1051
- });
1052
- return entities.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
1053
- }
1054
- function combineLegacyandNewResources(legacy, resource) {
1055
- const mergedResource = mergeResourcesWithBaseResource(resource);
1056
- return Object.entries(mergedResource).reduce((acc, [key, value]) => {
1057
- return { ...acc, [key]: value.texts };
1058
- }, legacy);
1059
1145
  }
1060
1146
 
1061
1147
  function findRoute(routesService, path) {
@@ -1082,1372 +1168,1343 @@ function reloadRoute(router, ngZone) {
1082
1168
  });
1083
1169
  }
1084
1170
 
1085
- class ReplaceableComponentsService {
1086
- get replaceableComponents$() {
1087
- return this.store.sliceState(state => state);
1088
- }
1089
- get replaceableComponents() {
1090
- return this.store.state;
1091
- }
1092
- get onUpdate$() {
1093
- return this.store.sliceUpdate(state => state);
1171
+ /* eslint-disable @typescript-eslint/ban-types */
1172
+ class BaseTreeNode {
1173
+ constructor(props) {
1174
+ this.children = [];
1175
+ this.isLeaf = true;
1176
+ Object.assign(this, props);
1094
1177
  }
1095
- constructor(ngZone, router) {
1096
- this.ngZone = ngZone;
1097
- this.router = router;
1098
- this.store = new InternalStore([]);
1178
+ static create(props) {
1179
+ return new BaseTreeNode(props);
1099
1180
  }
1100
- add(replaceableComponent, reload) {
1101
- const replaceableComponents = [...this.store.state];
1102
- const index = replaceableComponents.findIndex(component => component.key === replaceableComponent.key);
1103
- if (index > -1) {
1104
- replaceableComponents[index] = replaceableComponent;
1181
+ }
1182
+ function createTreeFromList(list, keySelector, parentKeySelector, valueMapper) {
1183
+ const map = createMapFromList(list, keySelector, valueMapper);
1184
+ const tree = [];
1185
+ list.forEach(row => {
1186
+ const id = keySelector(row);
1187
+ const parentId = parentKeySelector(row);
1188
+ const node = map.get(id);
1189
+ if (!node)
1190
+ return;
1191
+ if (parentId) {
1192
+ const parent = map.get(parentId);
1193
+ if (!parent)
1194
+ return;
1195
+ parent.children.push(node);
1196
+ parent.isLeaf = false;
1197
+ node.parent = parent;
1105
1198
  }
1106
1199
  else {
1107
- replaceableComponents.push(replaceableComponent);
1200
+ tree.push(node);
1108
1201
  }
1109
- this.store.set(replaceableComponents);
1110
- if (reload)
1111
- reloadRoute(this.router, this.ngZone);
1112
- }
1113
- get(replaceableComponentKey) {
1114
- return this.replaceableComponents.find(component => component.key === replaceableComponentKey);
1115
- }
1116
- get$(replaceableComponentKey) {
1117
- return this.replaceableComponents$.pipe(map(components => components.find(component => component.key === replaceableComponentKey)));
1202
+ });
1203
+ return tree;
1204
+ }
1205
+ function createMapFromList(list, keySelector, valueMapper) {
1206
+ const map = new Map();
1207
+ list.forEach(row => map.set(keySelector(row), valueMapper(row)));
1208
+ return map;
1209
+ }
1210
+ function createTreeNodeFilterCreator(key, mapperFn) {
1211
+ return (search) => {
1212
+ const regex = new RegExp('.*' + search + '.*', 'i');
1213
+ return function collectNodes(nodes, matches = []) {
1214
+ for (const node of nodes) {
1215
+ if (regex.test(mapperFn(node[key])))
1216
+ matches.push(node);
1217
+ if (node.children.length)
1218
+ collectNodes(node.children, matches);
1219
+ }
1220
+ return matches;
1221
+ };
1222
+ };
1223
+ }
1224
+ function createGroupMap(list, othersGroupKey) {
1225
+ if (!isArray(list) || !list.some(node => Boolean(node.group)))
1226
+ return undefined;
1227
+ const mapGroup = new Map();
1228
+ for (const node of list) {
1229
+ const group = node?.group || othersGroupKey;
1230
+ if (typeof group !== 'string') {
1231
+ throw new Error(`Invalid group: ${group}`);
1232
+ }
1233
+ const items = mapGroup.get(group) || [];
1234
+ items.push(node);
1235
+ mapGroup.set(group, items);
1118
1236
  }
1119
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ReplaceableComponentsService, deps: [{ token: i0.NgZone }, { token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Injectable }); }
1120
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ReplaceableComponentsService, providedIn: 'root' }); }
1237
+ return mapGroup;
1121
1238
  }
1122
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ReplaceableComponentsService, decorators: [{
1123
- type: Injectable,
1124
- args: [{ providedIn: 'root' }]
1125
- }], ctorParameters: () => [{ type: i0.NgZone }, { type: i1$1.Router }] });
1126
1239
 
1127
- const NavigationEvent = {
1128
- Cancel: NavigationCancel,
1129
- End: NavigationEnd,
1130
- Error: NavigationError,
1131
- Start: NavigationStart,
1132
- };
1133
- class RouterEvents {
1134
- #previousNavigation;
1135
- #currentNavigation;
1240
+ class DomInsertionService {
1136
1241
  constructor() {
1137
- this.router = inject(Router);
1138
- this.#previousNavigation = signal(undefined);
1139
- this.previousNavigation = this.#previousNavigation.asReadonly();
1140
- this.#currentNavigation = signal(undefined);
1141
- this.currentNavigation = this.#currentNavigation.asReadonly();
1142
- this.listenToNavigation();
1143
- }
1144
- listenToNavigation() {
1145
- const routerEvent$ = this.router.events.pipe(filter(e => e instanceof NavigationEvent.End && !e.url.includes('error')));
1146
- routerEvent$.subscribe(event => {
1147
- this.#previousNavigation.set(this.currentNavigation());
1148
- this.#currentNavigation.set(event.url);
1149
- });
1150
- }
1151
- getEvents(...eventTypes) {
1152
- const filterRouterEvents = (event) => eventTypes.some(type => event instanceof type);
1153
- return this.router.events.pipe(filter(filterRouterEvents));
1242
+ this.inserted = new Set();
1154
1243
  }
1155
- getNavigationEvents(...navigationEventKeys) {
1156
- const filterNavigationEvents = (event) => navigationEventKeys.some(key => event instanceof NavigationEvent[key]);
1157
- return this.router.events.pipe(filter(filterNavigationEvents));
1244
+ insertContent(contentStrategy) {
1245
+ const hash = generateHash(contentStrategy.content);
1246
+ if (this.inserted.has(hash))
1247
+ return;
1248
+ const element = contentStrategy.insertElement();
1249
+ this.inserted.add(hash);
1250
+ return element;
1158
1251
  }
1159
- getAllEvents() {
1160
- return this.router.events;
1252
+ removeContent(element) {
1253
+ if (element.textContent) {
1254
+ const hash = generateHash(element.textContent);
1255
+ this.inserted.delete(hash);
1256
+ element.parentNode?.removeChild(element);
1257
+ }
1161
1258
  }
1162
- getAllNavigationEvents() {
1163
- const keys = Object.keys(NavigationEvent);
1164
- return this.getNavigationEvents(...keys);
1259
+ has(content) {
1260
+ const hash = generateHash(content);
1261
+ return this.inserted.has(hash);
1165
1262
  }
1166
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterEvents, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1167
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterEvents, providedIn: 'root' }); }
1263
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DomInsertionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1264
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DomInsertionService, providedIn: 'root' }); }
1168
1265
  }
1169
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterEvents, decorators: [{
1266
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DomInsertionService, decorators: [{
1170
1267
  type: Injectable,
1171
- args: [{ providedIn: 'root' }]
1172
- }], ctorParameters: () => [] });
1173
-
1174
- const APP_INIT_ERROR_HANDLERS = new InjectionToken('APP_INIT_ERROR_HANDLERS');
1175
-
1176
- const COOKIE_LANGUAGE_KEY = new InjectionToken('COOKIE_LANGUAGE_KEY', {
1177
- factory: () => '.AspNetCore.Culture',
1178
- });
1179
-
1180
- const LIST_QUERY_DEBOUNCE_TIME = new InjectionToken('LIST_QUERY_DEBOUNCE_TIME');
1181
-
1182
- const LOADER_DELAY = new InjectionToken('LOADER_DELAY');
1183
-
1184
- const NAVIGATE_TO_MANAGE_PROFILE = new InjectionToken('NAVIGATE_TO_MANAGE_PROFILE');
1185
-
1186
- const QUEUE_MANAGER = new InjectionToken("QUEUE_MANAGER");
1187
-
1188
- const TENANT_KEY = new InjectionToken('TENANT_KEY');
1189
-
1190
- const PIPE_TO_LOGIN_FN_KEY = new InjectionToken('PIPE_TO_LOGIN_FN_KEY');
1191
-
1192
- /**
1193
- * @deprecated The token should not be used anymore.
1194
- */
1195
- const SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY = new InjectionToken('SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY');
1196
-
1197
- const CHECK_AUTHENTICATION_STATE_FN_KEY = new InjectionToken('CHECK_AUTHENTICATION_STATE_FN_KEY');
1198
-
1199
- const OTHERS_GROUP = new InjectionToken('OTHERS_GROUP');
1268
+ args: [{ providedIn: 'root' }]
1269
+ }] });
1200
1270
 
1201
- const TENANT_NOT_FOUND_BY_NAME = new InjectionToken('TENANT_NOT_FOUND_BY_NAME');
1271
+ const LOADER_DELAY = new InjectionToken('LOADER_DELAY');
1202
1272
 
1203
- class ContentProjectionService {
1273
+ class HttpWaitService {
1204
1274
  constructor(injector) {
1205
- this.injector = injector;
1275
+ this.store = new InternalStore({
1276
+ requests: [],
1277
+ filteredRequests: [],
1278
+ });
1279
+ this.destroy$ = new Subject();
1280
+ this.delay = injector.get(LOADER_DELAY, 500);
1206
1281
  }
1207
- projectContent(projectionStrategy, injector = this.injector) {
1208
- return projectionStrategy.injectContent(injector);
1282
+ getLoading() {
1283
+ return !!this.applyFilter(this.store.state.requests).length;
1209
1284
  }
1210
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ContentProjectionService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1211
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ContentProjectionService, providedIn: 'root' }); }
1285
+ getLoading$() {
1286
+ return this.store
1287
+ .sliceState(({ requests }) => requests)
1288
+ .pipe(map(requests => !!this.applyFilter(requests).length), switchMap(condition => condition
1289
+ ? this.delay === 0
1290
+ ? of(true)
1291
+ : timer(this.delay).pipe(mapTo(true), takeUntil(this.destroy$))
1292
+ : of(false)), tap(() => this.destroy$.next()));
1293
+ }
1294
+ updateLoading$() {
1295
+ return this.store.sliceUpdate(({ requests }) => !!this.applyFilter(requests).length);
1296
+ }
1297
+ clearLoading() {
1298
+ this.store.patch({ requests: [] });
1299
+ }
1300
+ addRequest(request) {
1301
+ this.store.patch({ requests: [...this.store.state.requests, request] });
1302
+ }
1303
+ deleteRequest(request) {
1304
+ const requests = this.store.state.requests.filter(r => r !== request);
1305
+ this.store.patch({ requests });
1306
+ }
1307
+ addFilter(request) {
1308
+ const requests = Array.isArray(request) ? request : [request];
1309
+ const filteredRequests = [
1310
+ ...this.store.state.filteredRequests.filter(f => !requests.some(r => this.isSameRequest(f, r))),
1311
+ ...requests,
1312
+ ];
1313
+ this.store.patch({ filteredRequests });
1314
+ }
1315
+ removeFilter(request) {
1316
+ const requests = Array.isArray(request) ? request : [request];
1317
+ const filteredRequests = this.store.state.filteredRequests.filter(f => !requests.some(r => this.isSameRequest(f, r)));
1318
+ this.store.patch({ filteredRequests });
1319
+ }
1320
+ applyFilter(requests) {
1321
+ if (!requests) {
1322
+ return [];
1323
+ }
1324
+ const { filteredRequests } = this.store.state;
1325
+ return requests.filter(({ method, url }) => !filteredRequests.find(filteredRequest => this.isSameRequest(filteredRequest, { method, endpoint: getPathName(url) })));
1326
+ }
1327
+ isSameRequest(filteredRequest, request) {
1328
+ const { method, endpoint } = filteredRequest;
1329
+ return endpoint === request.endpoint && method === request.method;
1330
+ }
1331
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: HttpWaitService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1332
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: HttpWaitService, providedIn: 'root' }); }
1212
1333
  }
1213
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ContentProjectionService, decorators: [{
1334
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: HttpWaitService, decorators: [{
1214
1335
  type: Injectable,
1215
- args: [{ providedIn: 'root' }]
1336
+ args: [{
1337
+ providedIn: 'root',
1338
+ }]
1216
1339
  }], ctorParameters: () => [{ type: i0.Injector }] });
1217
1340
 
1218
- function pushValueTo(array) {
1219
- return (element) => {
1220
- array.push(element);
1221
- return array;
1222
- };
1223
- }
1224
-
1225
- function getShortDateFormat(configStateService) {
1226
- const dateTimeFormat = configStateService.getDeep('localization.currentCulture.dateTimeFormat');
1227
- return dateTimeFormat.shortDatePattern;
1228
- }
1229
- function getShortTimeFormat(configStateService) {
1230
- const dateTimeFormat = configStateService.getDeep('localization.currentCulture.dateTimeFormat');
1231
- return dateTimeFormat?.shortTimePattern?.replace('tt', 'a');
1232
- }
1233
- function getShortDateShortTimeFormat(configStateService) {
1234
- const dateTimeFormat = configStateService.getDeep('localization.currentCulture.dateTimeFormat');
1235
- return `${dateTimeFormat.shortDatePattern} ${dateTimeFormat?.shortTimePattern?.replace('tt', 'a')}`;
1236
- }
1237
-
1238
- function getRemoteEnv(injector, environment) {
1239
- const environmentService = injector.get(EnvironmentService);
1240
- const { remoteEnv } = environment;
1241
- const { headers = {}, method = 'GET', url } = remoteEnv || {};
1242
- if (!url)
1243
- return Promise.resolve();
1244
- const http = injector.get(HttpClient);
1245
- const httpErrorReporter = injector.get(HttpErrorReporterService);
1246
- return http
1247
- .request(method, url, { headers })
1248
- .pipe(catchError(err => {
1249
- httpErrorReporter.reportError(err);
1250
- return of(null);
1251
- }), // TODO: Consider get handle function from a provider
1252
- tap(env => environmentService.setState(mergeEnvironments(environment, env || {}, remoteEnv))))
1253
- .toPromise();
1254
- }
1255
- function mergeEnvironments(local, remote, config) {
1256
- switch (config.mergeStrategy) {
1257
- case 'deepmerge':
1258
- return deepMerge(local, remote);
1259
- case 'overwrite':
1260
- case null:
1261
- case undefined:
1262
- return remote;
1263
- default:
1264
- return config.mergeStrategy(local, remote);
1341
+ class ResourceWaitService {
1342
+ constructor() {
1343
+ this.store = new InternalStore({ resources: new Set() });
1265
1344
  }
1266
- }
1267
-
1268
- class LazyModuleFactory extends NgModuleFactory {
1269
- get moduleType() {
1270
- return this.moduleWithProviders.ngModule;
1345
+ getLoading() {
1346
+ return !!this.store.state.resources.size;
1271
1347
  }
1272
- constructor(moduleWithProviders) {
1273
- super();
1274
- this.moduleWithProviders = moduleWithProviders;
1348
+ getLoading$() {
1349
+ return this.store.sliceState(({ resources }) => !!resources.size);
1275
1350
  }
1276
- create(parentInjector) {
1277
- const injector = Injector.create({
1278
- ...(parentInjector && { parent: parentInjector }),
1279
- providers: this.moduleWithProviders.providers,
1280
- });
1281
- const compiler = injector.get(Compiler);
1282
- const factory = compiler.compileModuleSync(this.moduleType);
1283
- return factory.create(injector);
1351
+ updateLoading$() {
1352
+ return this.store.sliceUpdate(({ resources }) => !!resources?.size);
1284
1353
  }
1285
- }
1286
- function featuresFactory(configState, featureKeys, mapFn = features => features) {
1287
- return configState.getFeatures$(featureKeys).pipe(filter(Boolean), map(mapFn));
1288
- }
1289
-
1290
- /** @deprecated the method will change in v8.0 */
1291
- function downloadBlob(blob, filename) {
1292
- const blobUrl = URL.createObjectURL(blob);
1293
- const link = document.createElement('a');
1294
- link.href = blobUrl;
1295
- link.download = filename;
1296
- document.body.appendChild(link);
1297
- link.dispatchEvent(new MouseEvent('click', {
1298
- bubbles: true,
1299
- cancelable: true,
1300
- view: window,
1301
- }));
1302
- document.body.removeChild(link);
1303
- }
1304
-
1305
- function isNumber(value) {
1306
- return value == Number(value);
1307
- }
1308
-
1309
- function mapEnumToOptions(_enum) {
1310
- const options = [];
1311
- for (const member in _enum)
1312
- if (!isNumber(member))
1313
- options.push({
1314
- key: member,
1315
- value: _enum[member],
1316
- });
1317
- return options;
1318
- }
1319
-
1320
- function uuid(a) {
1321
- return a
1322
- ? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
1323
- : ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);
1324
- }
1325
- function generateHash(value) {
1326
- let hashed = 0;
1327
- let charCode;
1328
- for (let i = 0; i < value.length; i++) {
1329
- charCode = value.charCodeAt(i);
1330
- hashed = (hashed << 5) - hashed + charCode;
1331
- hashed |= 0;
1354
+ clearLoading() {
1355
+ this.store.patch({ resources: new Set() });
1332
1356
  }
1333
- return hashed;
1334
- }
1335
- function generatePassword(length = 8) {
1336
- length = Math.min(Math.max(4, length), 128);
1337
- const lowers = 'abcdefghijklmnopqrstuvwxyz';
1338
- const uppers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
1339
- const numbers = '0123456789';
1340
- const specials = '!@#$%&*()_+{}<>?[]./';
1341
- const all = lowers + uppers + numbers + specials;
1342
- const getRandom = (chrSet) => chrSet[Math.floor(Math.random() * chrSet.length)];
1343
- const password = Array({ length });
1344
- password[0] = getRandom(lowers);
1345
- password[1] = getRandom(uppers);
1346
- password[2] = getRandom(numbers);
1347
- password[3] = getRandom(specials);
1348
- for (let i = 4; i < length; i++) {
1349
- password[i] = getRandom(all);
1357
+ addResource(resource) {
1358
+ const resources = this.store.state.resources;
1359
+ resources.add(resource);
1360
+ this.store.patch({ resources });
1350
1361
  }
1351
- return password.sort(() => 0.5 - Math.random()).join('');
1362
+ deleteResource(resource) {
1363
+ const resources = this.store.state.resources;
1364
+ resources.delete(resource);
1365
+ this.store.patch({ resources });
1366
+ }
1367
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ResourceWaitService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1368
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ResourceWaitService, providedIn: 'root' }); }
1352
1369
  }
1370
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ResourceWaitService, decorators: [{
1371
+ type: Injectable,
1372
+ args: [{
1373
+ providedIn: 'root',
1374
+ }]
1375
+ }] });
1353
1376
 
1354
- function getPathName(url) {
1355
- const { pathname } = new URL(url, window.location.origin);
1356
- return pathname;
1357
- }
1358
- class WebHttpUrlEncodingCodec {
1359
- encodeKey(k) {
1360
- return encodeURIComponent(k);
1361
- }
1362
- encodeValue(v) {
1363
- return encodeURIComponent(v);
1364
- }
1365
- decodeKey(k) {
1366
- return decodeURIComponent(k);
1377
+ class LazyLoadService {
1378
+ constructor(resourceWaitService) {
1379
+ this.resourceWaitService = resourceWaitService;
1380
+ this.loaded = new Map();
1367
1381
  }
1368
- decodeValue(v) {
1369
- return decodeURIComponent(v);
1382
+ load(strategy, retryTimes, retryDelay) {
1383
+ if (this.loaded.has(strategy.path))
1384
+ return of(new CustomEvent('load'));
1385
+ this.resourceWaitService.addResource(strategy.path);
1386
+ const delayOperator = retryDelay ? pipe(delay(retryDelay)) : pipe();
1387
+ const takeOp = retryTimes ? pipe(take(retryTimes)) : pipe();
1388
+ return strategy.createStream().pipe(retryWhen(error$ => concat(error$.pipe(delayOperator, takeOp), throwError(() => new CustomEvent('error')))), tap(() => {
1389
+ this.loaded.set(strategy.path, strategy.element);
1390
+ this.resourceWaitService.deleteResource(strategy.path);
1391
+ }), delay(100), shareReplay({ bufferSize: 1, refCount: true }));
1370
1392
  }
1371
- }
1372
-
1373
- class AbpTenantService {
1374
- constructor(restService) {
1375
- this.restService = restService;
1376
- this.apiName = 'abp';
1377
- this.findTenantById = (id) => this.restService.request({
1378
- method: 'GET',
1379
- url: `/api/abp/multi-tenancy/tenants/by-id/${id}`,
1380
- }, { apiName: this.apiName });
1381
- this.findTenantByName = (name) => this.restService.request({
1382
- method: 'GET',
1383
- url: `/api/abp/multi-tenancy/tenants/by-name/${name}`,
1384
- }, { apiName: this.apiName });
1393
+ remove(path) {
1394
+ const element = this.loaded.get(path);
1395
+ if (!element)
1396
+ return false;
1397
+ element.parentNode?.removeChild(element);
1398
+ this.loaded.delete(path);
1399
+ return true;
1385
1400
  }
1386
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpTenantService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1387
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpTenantService, providedIn: 'root' }); }
1401
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LazyLoadService, deps: [{ token: ResourceWaitService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1402
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LazyLoadService, providedIn: 'root' }); }
1388
1403
  }
1389
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpTenantService, decorators: [{
1404
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LazyLoadService, decorators: [{
1390
1405
  type: Injectable,
1391
1406
  args: [{
1392
1407
  providedIn: 'root',
1393
1408
  }]
1394
- }], ctorParameters: () => [{ type: RestService }] });
1409
+ }], ctorParameters: () => [{ type: ResourceWaitService }] });
1395
1410
 
1396
- class MultiTenancyService {
1397
- constructor(restService, sessionState, tenantService, configStateService, tenantKey) {
1398
- this.restService = restService;
1399
- this.sessionState = sessionState;
1400
- this.tenantService = tenantService;
1401
- this.configStateService = configStateService;
1402
- this.tenantKey = tenantKey;
1403
- this.domainTenant = null;
1404
- this.isTenantBoxVisible = true;
1405
- this.apiName = 'abp';
1406
- this.setTenantToState = (tenant) => {
1407
- this.sessionState.setTenant({ id: tenant.tenantId, name: tenant.name, isAvailable: true });
1408
- return this.configStateService.refreshAppState().pipe(map(_ => tenant));
1409
- };
1411
+ const LIST_QUERY_DEBOUNCE_TIME = new InjectionToken('LIST_QUERY_DEBOUNCE_TIME');
1412
+
1413
+ class ListService {
1414
+ set filter(value) {
1415
+ this._filter = value;
1416
+ this.get();
1410
1417
  }
1411
- setTenantByName(tenantName) {
1412
- return this.tenantService
1413
- .findTenantByName(tenantName)
1414
- .pipe(switchMap(this.setTenantToState));
1418
+ get filter() {
1419
+ return this._filter;
1415
1420
  }
1416
- setTenantById(tenantId) {
1417
- return this.tenantService
1418
- .findTenantById(tenantId)
1419
- .pipe(switchMap(this.setTenantToState));
1421
+ set maxResultCount(value) {
1422
+ this._maxResultCount = value;
1423
+ this.get();
1420
1424
  }
1421
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: MultiTenancyService, deps: [{ token: RestService }, { token: SessionStateService }, { token: AbpTenantService }, { token: ConfigStateService }, { token: TENANT_KEY }], target: i0.ɵɵFactoryTarget.Injectable }); }
1422
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: MultiTenancyService, providedIn: 'root' }); }
1423
- }
1424
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: MultiTenancyService, decorators: [{
1425
- type: Injectable,
1426
- args: [{ providedIn: 'root' }]
1427
- }], ctorParameters: () => [{ type: RestService }, { type: SessionStateService }, { type: AbpTenantService }, { type: ConfigStateService }, { type: undefined, decorators: [{
1428
- type: Inject,
1429
- args: [TENANT_KEY]
1430
- }] }] });
1431
-
1432
- const tenancyPlaceholder = '{0}';
1433
- function getCurrentTenancyName(appBaseUrl) {
1434
- if (appBaseUrl.charAt(appBaseUrl.length - 1) !== '/')
1435
- appBaseUrl += '/';
1436
- const parseTokens = createTokenParser(appBaseUrl);
1437
- const token = tenancyPlaceholder.replace(/[}{]/g, '');
1438
- return parseTokens(window.location.href)[token]?.[0];
1439
- }
1440
- function getCurrentTenancyNameFromUrl(tenantKey) {
1441
- const urlParams = new URLSearchParams(window.location.search);
1442
- return urlParams.get(tenantKey);
1443
- }
1444
- async function parseTenantFromUrl(injector) {
1445
- const environmentService = injector.get(EnvironmentService);
1446
- const multiTenancyService = injector.get(MultiTenancyService);
1447
- const tenantNotFoundHandler = injector.get(TENANT_NOT_FOUND_BY_NAME, null);
1448
- const baseUrl = environmentService.getEnvironment()?.application?.baseUrl || '';
1449
- const tenancyName = getCurrentTenancyName(baseUrl);
1450
- const hideTenantBox = () => {
1451
- multiTenancyService.isTenantBoxVisible = false;
1452
- };
1453
- const setDomainTenant = (tenant) => {
1454
- multiTenancyService.domainTenant = {
1455
- id: tenant.tenantId,
1456
- name: tenant.name,
1457
- isAvailable: true,
1458
- };
1459
- };
1460
- const setEnvironmentWithDomainTenant = (tenant) => {
1461
- hideTenantBox();
1462
- setDomainTenant(tenant);
1463
- };
1464
- if (tenancyName) {
1465
- /**
1466
- * We have to replace tenant name within the urls from environment,
1467
- * because the code below will make a http request to find information about the domain tenant.
1468
- * Before this request takes place, we need to replace placeholders aka "{0}".
1469
- */
1470
- replaceTenantNameWithinEnvironment(injector, tenancyName);
1471
- const tenant$ = multiTenancyService.setTenantByName(tenancyName);
1472
- try {
1473
- const result = await firstValueFrom(tenant$);
1474
- setEnvironmentWithDomainTenant(result);
1475
- return Promise.resolve(result);
1476
- }
1477
- catch (httpError) {
1478
- if (httpError instanceof HttpErrorResponse &&
1479
- httpError.status === 404 &&
1480
- tenantNotFoundHandler) {
1481
- tenantNotFoundHandler(httpError);
1482
- }
1483
- return Promise.reject();
1484
- }
1425
+ get maxResultCount() {
1426
+ return this._maxResultCount;
1485
1427
  }
1486
- /**
1487
- * If there is no tenant, we still have to clean up {0}. from baseUrl to avoid incorrect http requests.
1488
- */
1489
- replaceTenantNameWithinEnvironment(injector, '', tenancyPlaceholder + '.');
1490
- const tenantIdFromQueryParams = getCurrentTenancyNameFromUrl(multiTenancyService.tenantKey);
1491
- if (tenantIdFromQueryParams) {
1492
- const tenantById$ = multiTenancyService.setTenantById(tenantIdFromQueryParams);
1493
- return firstValueFrom(tenantById$);
1428
+ set page(value) {
1429
+ if (value === this._page)
1430
+ return;
1431
+ this._page = value;
1432
+ this.get();
1494
1433
  }
1495
- return Promise.resolve();
1496
- }
1497
- function replaceTenantNameWithinEnvironment(injector, tenancyName, placeholder = tenancyPlaceholder) {
1498
- const environmentService = injector.get(EnvironmentService);
1499
- const environment = clone(environmentService.getEnvironment());
1500
- if (environment.application.baseUrl) {
1501
- environment.application.baseUrl = environment.application.baseUrl.replace(placeholder, tenancyName);
1434
+ get page() {
1435
+ return this._page;
1502
1436
  }
1503
- if (environment.oAuthConfig?.redirectUri) {
1504
- environment.oAuthConfig.redirectUri = environment.oAuthConfig.redirectUri.replace(placeholder, tenancyName);
1437
+ set totalCount(value) {
1438
+ if (value === this._totalCount)
1439
+ return;
1440
+ this._totalCount = value;
1441
+ this.get();
1505
1442
  }
1506
- if (!environment.oAuthConfig) {
1507
- environment.oAuthConfig = {};
1443
+ get totalCount() {
1444
+ return this._totalCount;
1508
1445
  }
1509
- environment.oAuthConfig.issuer = (environment.oAuthConfig.issuer || '').replace(placeholder, tenancyName);
1510
- Object.keys(environment.apis).forEach(api => {
1511
- Object.keys(environment.apis[api]).forEach(key => {
1512
- environment.apis[api][key] = (environment.apis[api][key] || '').replace(placeholder, tenancyName);
1513
- });
1514
- });
1515
- return environmentService.setState(environment);
1516
- }
1517
-
1518
- function getInitialData(injector) {
1519
- const fn = async () => {
1520
- const environmentService = injector.get(EnvironmentService);
1521
- const configState = injector.get(ConfigStateService);
1522
- const options = injector.get(CORE_OPTIONS);
1523
- environmentService.setState(options.environment);
1524
- await getRemoteEnv(injector, options.environment);
1525
- await parseTenantFromUrl(injector);
1526
- const authService = injector.get(AuthService, undefined, { optional: true });
1527
- const checkAuthenticationState = injector.get(CHECK_AUTHENTICATION_STATE_FN_KEY, noop, {
1528
- optional: true,
1529
- });
1530
- if (authService) {
1531
- await authService.init();
1532
- }
1533
- if (options.skipGetAppConfiguration)
1534
- return;
1535
- const result$ = configState.refreshAppState().pipe(tap(() => checkAuthenticationState(injector)), tap(() => {
1536
- const currentTenant = configState.getOne('currentTenant');
1537
- injector.get(SessionStateService).setTenant(currentTenant);
1538
- }), catchError(error => {
1539
- const appInitErrorHandlers = injector.get(APP_INIT_ERROR_HANDLERS, null);
1540
- if (appInitErrorHandlers && appInitErrorHandlers.length) {
1541
- appInitErrorHandlers.forEach(func => func(error));
1542
- }
1543
- return throwError(error);
1544
- }));
1545
- await lastValueFrom(result$);
1546
- };
1547
- return fn;
1548
- }
1549
- function localeInitializer(injector) {
1550
- const fn = () => {
1551
- const sessionState = injector.get(SessionStateService);
1552
- const { registerLocaleFn } = injector.get(CORE_OPTIONS);
1553
- const lang = sessionState.getLanguage() || 'en';
1554
- return new Promise((resolve, reject) => {
1555
- registerLocaleFn(lang).then(module => {
1556
- if (module?.default)
1557
- registerLocaleData(module.default);
1558
- return resolve('resolved');
1559
- }, reject);
1560
- });
1561
- };
1562
- return fn;
1563
- }
1564
-
1565
- class CrossOriginStrategy {
1566
- constructor(crossorigin, integrity) {
1567
- this.crossorigin = crossorigin;
1568
- this.integrity = integrity;
1446
+ set sortKey(value) {
1447
+ this._sortKey = value;
1448
+ this.get();
1569
1449
  }
1570
- setCrossOrigin(element) {
1571
- if (this.integrity)
1572
- element.setAttribute('integrity', this.integrity);
1573
- if (this.crossorigin) {
1574
- element.setAttribute('crossorigin', this.crossorigin);
1575
- }
1450
+ get sortKey() {
1451
+ return this._sortKey;
1576
1452
  }
1577
- }
1578
- class NoCrossOriginStrategy extends CrossOriginStrategy {
1579
- setCrossOrigin() { }
1580
- }
1581
- const CROSS_ORIGIN_STRATEGY = {
1582
- Anonymous(integrity) {
1583
- return new CrossOriginStrategy('anonymous', integrity);
1584
- },
1585
- UseCredentials(integrity) {
1586
- return new CrossOriginStrategy('use-credentials', integrity);
1587
- },
1588
- None() {
1589
- return new NoCrossOriginStrategy(null);
1590
- },
1591
- };
1592
-
1593
- class DomStrategy {
1594
- constructor(target = document.head, position = 'beforeend') {
1595
- this.target = target;
1596
- this.position = position;
1453
+ set sortOrder(value) {
1454
+ this._sortOrder = value;
1455
+ this.get();
1456
+ }
1457
+ get sortOrder() {
1458
+ return this._sortOrder;
1459
+ }
1460
+ get query$() {
1461
+ return this._query$
1462
+ .asObservable()
1463
+ .pipe(this.delay, shareReplay({ bufferSize: 1, refCount: true }));
1597
1464
  }
1598
- insertElement(element) {
1599
- this.target.insertAdjacentElement(this.position, element);
1465
+ get isLoading$() {
1466
+ return this._isLoading$.asObservable();
1600
1467
  }
1601
- }
1602
- const DOM_STRATEGY = {
1603
- AfterElement(element) {
1604
- return new DomStrategy(element, 'afterend');
1605
- },
1606
- AppendToBody() {
1607
- return new DomStrategy(document.body, 'beforeend');
1608
- },
1609
- AppendToHead() {
1610
- return new DomStrategy(document.head, 'beforeend');
1611
- },
1612
- BeforeElement(element) {
1613
- return new DomStrategy(element, 'beforebegin');
1614
- },
1615
- PrependToHead() {
1616
- return new DomStrategy(document.head, 'afterbegin');
1617
- },
1618
- };
1619
-
1620
- function fromLazyLoad(element, domStrategy = DOM_STRATEGY.AppendToHead(), crossOriginStrategy = CROSS_ORIGIN_STRATEGY.Anonymous()) {
1621
- crossOriginStrategy.setCrossOrigin(element);
1622
- domStrategy.insertElement(element);
1623
- return new Observable((observer) => {
1624
- element.onload = (event) => {
1625
- clearCallbacks(element);
1626
- observer.next(event);
1627
- observer.complete();
1468
+ constructor(injector) {
1469
+ this._filter = '';
1470
+ this._maxResultCount = 10;
1471
+ this._skipCount = 0;
1472
+ this._page = 0;
1473
+ this._totalCount = 0;
1474
+ this._sortKey = '';
1475
+ this._sortOrder = '';
1476
+ this._query$ = new ReplaySubject(1);
1477
+ this._isLoading$ = new BehaviorSubject(false);
1478
+ this.destroy$ = new Subject();
1479
+ this.get = () => {
1480
+ this.resetPageWhenUnchanged();
1481
+ this.next();
1628
1482
  };
1629
- const handleError = createErrorHandler(observer, element);
1630
- element.onerror = handleError;
1631
- element.onabort = handleError;
1632
- element.onemptied = handleError;
1633
- element.onstalled = handleError;
1634
- element.onsuspend = handleError;
1635
- return () => {
1636
- clearCallbacks(element);
1637
- observer.complete();
1483
+ this.getWithoutPageReset = () => {
1484
+ this.next();
1638
1485
  };
1639
- });
1640
- }
1641
- function createErrorHandler(observer, element) {
1642
- return function (event) {
1643
- clearCallbacks(element);
1644
- element.parentNode?.removeChild(element);
1645
- observer.error(event);
1646
- };
1647
- }
1648
- function clearCallbacks(element) {
1649
- element.onload = null;
1650
- element.onerror = null;
1651
- element.onabort = null;
1652
- element.onemptied = null;
1653
- element.onstalled = null;
1654
- element.onsuspend = null;
1655
- }
1656
-
1657
- class DefaultQueueManager {
1658
- constructor() {
1659
- this.queue = [];
1660
- this.isRunning = false;
1661
- this.stack = 0;
1662
- this.interval = 0;
1663
- this.stackSize = 100;
1486
+ const delay = injector.get(LIST_QUERY_DEBOUNCE_TIME, 300);
1487
+ this.delay = delay ? debounceTime(delay) : tap();
1488
+ this.get();
1664
1489
  }
1665
- init(interval, stackSize) {
1666
- this.interval = interval;
1667
- this.stackSize = stackSize;
1490
+ hookToQuery(streamCreatorCallback) {
1491
+ return this.query$.pipe(tap(() => this._isLoading$.next(true)), switchMap(query => streamCreatorCallback(query).pipe(catchError(() => of(null)))), filter(Boolean), tap(() => this._isLoading$.next(false)), shareReplay({ bufferSize: 1, refCount: true }), takeUntil(this.destroy$));
1668
1492
  }
1669
- add(fn) {
1670
- this.queue.push(fn);
1671
- this.run();
1493
+ ngOnDestroy() {
1494
+ this.destroy$.next();
1672
1495
  }
1673
- run() {
1674
- if (this.isRunning)
1675
- return;
1676
- this.stack++;
1677
- this.isRunning = true;
1678
- const fn = this.queue.shift();
1679
- if (!fn) {
1680
- this.isRunning = false;
1496
+ resetPageWhenUnchanged() {
1497
+ const maxPage = Number(Number(this.totalCount / this._maxResultCount).toFixed());
1498
+ const skipCount = this._page * this._maxResultCount;
1499
+ if (skipCount !== this._totalCount) {
1500
+ this._skipCount = skipCount;
1681
1501
  return;
1682
1502
  }
1683
- fn();
1684
- if (this.stack > this.stackSize) {
1685
- setTimeout(() => {
1686
- this.isRunning = false;
1687
- this.run();
1688
- this.stack = 0;
1689
- }, this.interval);
1690
- }
1691
- else {
1692
- this.isRunning = false;
1693
- this.run();
1503
+ if (this.page === maxPage && this.page > 0) {
1504
+ this._skipCount = skipCount - this._maxResultCount;
1505
+ this.page = this.page - 1;
1694
1506
  }
1695
1507
  }
1508
+ next() {
1509
+ this._query$.next({
1510
+ filter: this._filter || undefined,
1511
+ maxResultCount: this._maxResultCount,
1512
+ skipCount: this._page * this._maxResultCount,
1513
+ sorting: this._sortOrder ? `${this._sortKey} ${this._sortOrder}` : undefined,
1514
+ });
1515
+ }
1516
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ListService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1517
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ListService }); }
1696
1518
  }
1519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ListService, decorators: [{
1520
+ type: Injectable
1521
+ }], ctorParameters: () => [{ type: i0.Injector }] });
1697
1522
 
1698
- /* eslint-disable @typescript-eslint/ban-types */
1699
- class BaseTreeNode {
1700
- constructor(props) {
1701
- this.children = [];
1702
- this.isLeaf = true;
1703
- Object.assign(this, props);
1523
+ class PermissionService {
1524
+ constructor(configState) {
1525
+ this.configState = configState;
1704
1526
  }
1705
- static create(props) {
1706
- return new BaseTreeNode(props);
1527
+ getGrantedPolicy$(key) {
1528
+ return this.getStream().pipe(map(grantedPolicies => this.isPolicyGranted(key, grantedPolicies)));
1707
1529
  }
1708
- }
1709
- function createTreeFromList(list, keySelector, parentKeySelector, valueMapper) {
1710
- const map = createMapFromList(list, keySelector, valueMapper);
1711
- const tree = [];
1712
- list.forEach(row => {
1713
- const id = keySelector(row);
1714
- const parentId = parentKeySelector(row);
1715
- const node = map.get(id);
1716
- if (!node)
1717
- return;
1718
- if (parentId) {
1719
- const parent = map.get(parentId);
1720
- if (!parent)
1721
- return;
1722
- parent.children.push(node);
1723
- parent.isLeaf = false;
1724
- node.parent = parent;
1530
+ getGrantedPolicy(key) {
1531
+ const policies = this.getSnapshot();
1532
+ return this.isPolicyGranted(key, policies);
1533
+ }
1534
+ filterItemsByPolicy(items) {
1535
+ const policies = this.getSnapshot();
1536
+ return items.filter(item => !item.requiredPolicy || this.isPolicyGranted(item.requiredPolicy, policies));
1537
+ }
1538
+ filterItemsByPolicy$(items) {
1539
+ return this.getStream().pipe(map(policies => items.filter(item => !item.requiredPolicy || this.isPolicyGranted(item.requiredPolicy, policies))));
1540
+ }
1541
+ isPolicyGranted(key, grantedPolicies) {
1542
+ if (!key)
1543
+ return true;
1544
+ const orRegexp = /\|\|/g;
1545
+ const andRegexp = /&&/g;
1546
+ // TODO: Allow combination of ANDs & ORs
1547
+ if (orRegexp.test(key)) {
1548
+ const keys = key.split('||').filter(Boolean);
1549
+ if (keys.length < 2)
1550
+ return false;
1551
+ return keys.some(k => this.getPolicy(k.trim(), grantedPolicies));
1725
1552
  }
1726
- else {
1727
- tree.push(node);
1553
+ else if (andRegexp.test(key)) {
1554
+ const keys = key.split('&&').filter(Boolean);
1555
+ if (keys.length < 2)
1556
+ return false;
1557
+ return keys.every(k => this.getPolicy(k.trim(), grantedPolicies));
1728
1558
  }
1729
- });
1730
- return tree;
1731
- }
1732
- function createMapFromList(list, keySelector, valueMapper) {
1733
- const map = new Map();
1734
- list.forEach(row => map.set(keySelector(row), valueMapper(row)));
1735
- return map;
1736
- }
1737
- function createTreeNodeFilterCreator(key, mapperFn) {
1738
- return (search) => {
1739
- const regex = new RegExp('.*' + search + '.*', 'i');
1740
- return function collectNodes(nodes, matches = []) {
1741
- for (const node of nodes) {
1742
- if (regex.test(mapperFn(node[key])))
1743
- matches.push(node);
1744
- if (node.children.length)
1745
- collectNodes(node.children, matches);
1746
- }
1747
- return matches;
1748
- };
1749
- };
1559
+ return this.getPolicy(key, grantedPolicies);
1560
+ }
1561
+ getStream() {
1562
+ return this.configState.getAll$().pipe(map(this.mapToPolicies));
1563
+ }
1564
+ getSnapshot() {
1565
+ return this.mapToPolicies(this.configState.getAll());
1566
+ }
1567
+ mapToPolicies(applicationConfiguration) {
1568
+ return applicationConfiguration?.auth?.grantedPolicies || {};
1569
+ }
1570
+ getPolicy(key, grantedPolicies) {
1571
+ return grantedPolicies[key] || false;
1572
+ }
1573
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionService, deps: [{ token: ConfigStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1574
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionService, providedIn: 'root' }); }
1750
1575
  }
1751
- function createGroupMap(list, othersGroupKey) {
1752
- if (!isArray(list) || !list.some(node => Boolean(node.group)))
1753
- return undefined;
1754
- const mapGroup = new Map();
1755
- for (const node of list) {
1756
- const group = node?.group || othersGroupKey;
1757
- if (typeof group !== 'string') {
1758
- throw new Error(`Invalid group: ${group}`);
1576
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionService, decorators: [{
1577
+ type: Injectable,
1578
+ args: [{ providedIn: 'root' }]
1579
+ }], ctorParameters: () => [{ type: ConfigStateService }] });
1580
+
1581
+ class ReplaceableComponentsService {
1582
+ get replaceableComponents$() {
1583
+ return this.store.sliceState(state => state);
1584
+ }
1585
+ get replaceableComponents() {
1586
+ return this.store.state;
1587
+ }
1588
+ get onUpdate$() {
1589
+ return this.store.sliceUpdate(state => state);
1590
+ }
1591
+ constructor(ngZone, router) {
1592
+ this.ngZone = ngZone;
1593
+ this.router = router;
1594
+ this.store = new InternalStore([]);
1595
+ }
1596
+ add(replaceableComponent, reload) {
1597
+ const replaceableComponents = [...this.store.state];
1598
+ const index = replaceableComponents.findIndex(component => component.key === replaceableComponent.key);
1599
+ if (index > -1) {
1600
+ replaceableComponents[index] = replaceableComponent;
1759
1601
  }
1760
- const items = mapGroup.get(group) || [];
1761
- items.push(node);
1762
- mapGroup.set(group, items);
1602
+ else {
1603
+ replaceableComponents.push(replaceableComponent);
1604
+ }
1605
+ this.store.set(replaceableComponents);
1606
+ if (reload)
1607
+ reloadRoute(this.router, this.ngZone);
1763
1608
  }
1764
- return mapGroup;
1609
+ get(replaceableComponentKey) {
1610
+ return this.replaceableComponents.find(component => component.key === replaceableComponentKey);
1611
+ }
1612
+ get$(replaceableComponentKey) {
1613
+ return this.replaceableComponents$.pipe(map(components => components.find(component => component.key === replaceableComponentKey)));
1614
+ }
1615
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ReplaceableComponentsService, deps: [{ token: i0.NgZone }, { token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Injectable }); }
1616
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ReplaceableComponentsService, providedIn: 'root' }); }
1765
1617
  }
1618
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ReplaceableComponentsService, decorators: [{
1619
+ type: Injectable,
1620
+ args: [{ providedIn: 'root' }]
1621
+ }], ctorParameters: () => [{ type: i0.NgZone }, { type: i1$1.Router }] });
1766
1622
 
1767
- class DomInsertionService {
1623
+ const NavigationEvent = {
1624
+ Cancel: NavigationCancel,
1625
+ End: NavigationEnd,
1626
+ Error: NavigationError,
1627
+ Start: NavigationStart,
1628
+ };
1629
+ class RouterEvents {
1630
+ #previousNavigation;
1631
+ #currentNavigation;
1768
1632
  constructor() {
1769
- this.inserted = new Set();
1633
+ this.router = inject(Router);
1634
+ this.#previousNavigation = signal(undefined);
1635
+ this.previousNavigation = this.#previousNavigation.asReadonly();
1636
+ this.#currentNavigation = signal(undefined);
1637
+ this.currentNavigation = this.#currentNavigation.asReadonly();
1638
+ this.listenToNavigation();
1770
1639
  }
1771
- insertContent(contentStrategy) {
1772
- const hash = generateHash(contentStrategy.content);
1773
- if (this.inserted.has(hash))
1774
- return;
1775
- const element = contentStrategy.insertElement();
1776
- this.inserted.add(hash);
1777
- return element;
1640
+ listenToNavigation() {
1641
+ const routerEvent$ = this.router.events.pipe(filter(e => e instanceof NavigationEvent.End && !e.url.includes('error')));
1642
+ routerEvent$.subscribe(event => {
1643
+ this.#previousNavigation.set(this.currentNavigation());
1644
+ this.#currentNavigation.set(event.url);
1645
+ });
1778
1646
  }
1779
- removeContent(element) {
1780
- if (element.textContent) {
1781
- const hash = generateHash(element.textContent);
1782
- this.inserted.delete(hash);
1783
- element.parentNode?.removeChild(element);
1784
- }
1647
+ getEvents(...eventTypes) {
1648
+ const filterRouterEvents = (event) => eventTypes.some(type => event instanceof type);
1649
+ return this.router.events.pipe(filter(filterRouterEvents));
1785
1650
  }
1786
- has(content) {
1787
- const hash = generateHash(content);
1788
- return this.inserted.has(hash);
1651
+ getNavigationEvents(...navigationEventKeys) {
1652
+ const filterNavigationEvents = (event) => navigationEventKeys.some(key => event instanceof NavigationEvent[key]);
1653
+ return this.router.events.pipe(filter(filterNavigationEvents));
1789
1654
  }
1790
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DomInsertionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1791
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DomInsertionService, providedIn: 'root' }); }
1655
+ getAllEvents() {
1656
+ return this.router.events;
1657
+ }
1658
+ getAllNavigationEvents() {
1659
+ const keys = Object.keys(NavigationEvent);
1660
+ return this.getNavigationEvents(...keys);
1661
+ }
1662
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterEvents, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1663
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterEvents, providedIn: 'root' }); }
1792
1664
  }
1793
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DomInsertionService, decorators: [{
1665
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterEvents, decorators: [{
1794
1666
  type: Injectable,
1795
1667
  args: [{ providedIn: 'root' }]
1796
- }] });
1668
+ }], ctorParameters: () => [] });
1797
1669
 
1798
- class HttpWaitService {
1799
- constructor(injector) {
1800
- this.store = new InternalStore({
1801
- requests: [],
1802
- filteredRequests: [],
1803
- });
1670
+ class RouterWaitService {
1671
+ constructor(routerEvents, injector) {
1672
+ this.routerEvents = routerEvents;
1673
+ this.store = new InternalStore({ loading: false });
1804
1674
  this.destroy$ = new Subject();
1805
1675
  this.delay = injector.get(LOADER_DELAY, 500);
1676
+ this.updateLoadingStatusOnNavigationEvents();
1806
1677
  }
1807
- getLoading() {
1808
- return !!this.applyFilter(this.store.state.requests).length;
1809
- }
1810
- getLoading$() {
1811
- return this.store
1812
- .sliceState(({ requests }) => requests)
1813
- .pipe(map(requests => !!this.applyFilter(requests).length), switchMap(condition => condition
1678
+ updateLoadingStatusOnNavigationEvents() {
1679
+ this.routerEvents
1680
+ .getAllNavigationEvents()
1681
+ .pipe(map(event => event instanceof NavigationStart), switchMap(condition => condition
1814
1682
  ? this.delay === 0
1815
1683
  ? of(true)
1816
- : timer(this.delay).pipe(mapTo(true), takeUntil(this.destroy$))
1817
- : of(false)), tap(() => this.destroy$.next()));
1818
- }
1819
- updateLoading$() {
1820
- return this.store.sliceUpdate(({ requests }) => !!this.applyFilter(requests).length);
1821
- }
1822
- clearLoading() {
1823
- this.store.patch({ requests: [] });
1824
- }
1825
- addRequest(request) {
1826
- this.store.patch({ requests: [...this.store.state.requests, request] });
1827
- }
1828
- deleteRequest(request) {
1829
- const requests = this.store.state.requests.filter(r => r !== request);
1830
- this.store.patch({ requests });
1684
+ : timer(this.delay || 0).pipe(mapTo(true), takeUntil(this.destroy$))
1685
+ : of(false)), tap(() => this.destroy$.next()))
1686
+ .subscribe(status => {
1687
+ this.setLoading(status);
1688
+ });
1831
1689
  }
1832
- addFilter(request) {
1833
- const requests = Array.isArray(request) ? request : [request];
1834
- const filteredRequests = [
1835
- ...this.store.state.filteredRequests.filter(f => !requests.some(r => this.isSameRequest(f, r))),
1836
- ...requests,
1837
- ];
1838
- this.store.patch({ filteredRequests });
1690
+ getLoading() {
1691
+ return this.store.state.loading;
1839
1692
  }
1840
- removeFilter(request) {
1841
- const requests = Array.isArray(request) ? request : [request];
1842
- const filteredRequests = this.store.state.filteredRequests.filter(f => !requests.some(r => this.isSameRequest(f, r)));
1843
- this.store.patch({ filteredRequests });
1693
+ getLoading$() {
1694
+ return this.store.sliceState(({ loading }) => loading);
1844
1695
  }
1845
- applyFilter(requests) {
1846
- if (!requests) {
1847
- return [];
1848
- }
1849
- const { filteredRequests } = this.store.state;
1850
- return requests.filter(({ method, url }) => !filteredRequests.find(filteredRequest => this.isSameRequest(filteredRequest, { method, endpoint: getPathName(url) })));
1696
+ updateLoading$() {
1697
+ return this.store.sliceUpdate(({ loading }) => loading);
1851
1698
  }
1852
- isSameRequest(filteredRequest, request) {
1853
- const { method, endpoint } = filteredRequest;
1854
- return endpoint === request.endpoint && method === request.method;
1699
+ setLoading(loading) {
1700
+ this.store.patch({ loading });
1855
1701
  }
1856
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: HttpWaitService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1857
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: HttpWaitService, providedIn: 'root' }); }
1702
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterWaitService, deps: [{ token: RouterEvents }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1703
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterWaitService, providedIn: 'root' }); }
1858
1704
  }
1859
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: HttpWaitService, decorators: [{
1705
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterWaitService, decorators: [{
1860
1706
  type: Injectable,
1861
1707
  args: [{
1862
1708
  providedIn: 'root',
1863
1709
  }]
1864
- }], ctorParameters: () => [{ type: i0.Injector }] });
1710
+ }], ctorParameters: () => [{ type: RouterEvents }, { type: i0.Injector }] });
1865
1711
 
1866
- class ResourceWaitService {
1712
+ const COOKIE_LANGUAGE_KEY = new InjectionToken('COOKIE_LANGUAGE_KEY', {
1713
+ factory: () => '.AspNetCore.Culture',
1714
+ });
1715
+
1716
+ const NAVIGATE_TO_MANAGE_PROFILE = new InjectionToken('NAVIGATE_TO_MANAGE_PROFILE');
1717
+
1718
+ const QUEUE_MANAGER = new InjectionToken("QUEUE_MANAGER");
1719
+
1720
+ const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken('INCUDE_LOCALIZATION_RESOURCES_TOKEN');
1721
+
1722
+ const PIPE_TO_LOGIN_FN_KEY = new InjectionToken('PIPE_TO_LOGIN_FN_KEY');
1723
+
1724
+ /**
1725
+ * @deprecated The token should not be used anymore.
1726
+ */
1727
+ const SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY = new InjectionToken('SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY');
1728
+
1729
+ const OTHERS_GROUP = new InjectionToken('OTHERS_GROUP');
1730
+
1731
+ const SORT_COMPARE_FUNC = new InjectionToken('SORT_COMPARE_FUNC');
1732
+ function compareFuncFactory() {
1733
+ const localizationService = inject(LocalizationService);
1734
+ const fn = (a, b) => {
1735
+ const aNumber = a.order;
1736
+ const bNumber = b.order;
1737
+ if (aNumber > bNumber)
1738
+ return 1;
1739
+ if (aNumber < bNumber)
1740
+ return -1;
1741
+ if (a.id > b.id)
1742
+ return 1;
1743
+ if (a.id < b.id)
1744
+ return -1;
1745
+ if (!Number.isInteger(aNumber))
1746
+ return 1;
1747
+ if (!Number.isInteger(bNumber))
1748
+ return -1;
1749
+ const aName = localizationService.instant(a.name);
1750
+ const bName = localizationService.instant(b.name);
1751
+ if (aName > bName)
1752
+ return 1;
1753
+ if (aName < bName)
1754
+ return -1;
1755
+ return 0;
1756
+ };
1757
+ return fn;
1758
+ }
1759
+
1760
+ // eslint-disable-next-line @typescript-eslint/ban-types
1761
+ class AbstractTreeService {
1867
1762
  constructor() {
1868
- this.store = new InternalStore({ resources: new Set() });
1763
+ this._flat$ = new BehaviorSubject([]);
1764
+ this._tree$ = new BehaviorSubject([]);
1765
+ this._visible$ = new BehaviorSubject([]);
1766
+ this.shouldSingularizeRoutes = true;
1869
1767
  }
1870
- getLoading() {
1871
- return !!this.store.state.resources.size;
1768
+ get flat() {
1769
+ return this._flat$.value;
1872
1770
  }
1873
- getLoading$() {
1874
- return this.store.sliceState(({ resources }) => !!resources.size);
1771
+ get flat$() {
1772
+ return this._flat$.asObservable();
1875
1773
  }
1876
- updateLoading$() {
1877
- return this.store.sliceUpdate(({ resources }) => !!resources?.size);
1774
+ get tree() {
1775
+ return this._tree$.value;
1776
+ }
1777
+ get tree$() {
1778
+ return this._tree$.asObservable();
1779
+ }
1780
+ get visible() {
1781
+ return this._visible$.value;
1782
+ }
1783
+ get visible$() {
1784
+ return this._visible$.asObservable();
1785
+ }
1786
+ filterWith(setOrMap) {
1787
+ return this._flat$.value.filter(item => !setOrMap.has(item[this.id]));
1788
+ }
1789
+ findItemsToRemove(set) {
1790
+ return this._flat$.value.reduce((acc, item) => {
1791
+ if (!acc.has(item[this.parentId])) {
1792
+ return acc;
1793
+ }
1794
+ const childSet = new Set([item[this.id]]);
1795
+ const children = this.findItemsToRemove(childSet);
1796
+ return new Set([...acc, ...children]);
1797
+ }, set);
1878
1798
  }
1879
- clearLoading() {
1880
- this.store.patch({ resources: new Set() });
1799
+ publish(flatItems) {
1800
+ this._flat$.next(flatItems);
1801
+ this._tree$.next(this.createTree(flatItems));
1802
+ this._visible$.next(this.createTree(flatItems.filter(item => !this.hide(item))));
1803
+ return flatItems;
1881
1804
  }
1882
- addResource(resource) {
1883
- const resources = this.store.state.resources;
1884
- resources.add(resource);
1885
- this.store.patch({ resources });
1805
+ createTree(items) {
1806
+ return createTreeFromList(items, item => item[this.id], item => item[this.parentId], item => BaseTreeNode.create(item));
1886
1807
  }
1887
- deleteResource(resource) {
1888
- const resources = this.store.state.resources;
1889
- resources.delete(resource);
1890
- this.store.patch({ resources });
1808
+ createGroupedTree(list) {
1809
+ const map = createGroupMap(list, this.othersGroup);
1810
+ if (!map) {
1811
+ return undefined;
1812
+ }
1813
+ return Array.from(map, ([key, items]) => ({ group: key, items }));
1891
1814
  }
1892
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ResourceWaitService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1893
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ResourceWaitService, providedIn: 'root' }); }
1894
- }
1895
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ResourceWaitService, decorators: [{
1896
- type: Injectable,
1897
- args: [{
1898
- providedIn: 'root',
1899
- }]
1900
- }] });
1901
-
1902
- class LazyLoadService {
1903
- constructor(resourceWaitService) {
1904
- this.resourceWaitService = resourceWaitService;
1905
- this.loaded = new Map();
1815
+ add(items) {
1816
+ let flatItems = [];
1817
+ if (!this.shouldSingularizeRoutes) {
1818
+ flatItems = [...this.flat, ...items];
1819
+ }
1820
+ if (this.shouldSingularizeRoutes) {
1821
+ const map = new Map();
1822
+ items.forEach(item => map.set(item[this.id], item));
1823
+ flatItems = this.filterWith(map);
1824
+ map.forEach(pushValueTo(flatItems));
1825
+ }
1826
+ flatItems.sort(this.sort);
1827
+ return this.publish(flatItems);
1906
1828
  }
1907
- load(strategy, retryTimes, retryDelay) {
1908
- if (this.loaded.has(strategy.path))
1909
- return of(new CustomEvent('load'));
1910
- this.resourceWaitService.addResource(strategy.path);
1911
- const delayOperator = retryDelay ? pipe(delay(retryDelay)) : pipe();
1912
- const takeOp = retryTimes ? pipe(take(retryTimes)) : pipe();
1913
- return strategy.createStream().pipe(retryWhen(error$ => concat(error$.pipe(delayOperator, takeOp), throwError(() => new CustomEvent('error')))), tap(() => {
1914
- this.loaded.set(strategy.path, strategy.element);
1915
- this.resourceWaitService.deleteResource(strategy.path);
1916
- }), delay(100), shareReplay({ bufferSize: 1, refCount: true }));
1829
+ find(predicate, tree = this.tree) {
1830
+ return tree.reduce((acc, node) => {
1831
+ if (acc) {
1832
+ return acc;
1833
+ }
1834
+ if (predicate(node)) {
1835
+ return node;
1836
+ }
1837
+ return this.find(predicate, node.children);
1838
+ }, null);
1917
1839
  }
1918
- remove(path) {
1919
- const element = this.loaded.get(path);
1920
- if (!element)
1840
+ patch(identifier, props) {
1841
+ const flatItems = this._flat$.value;
1842
+ const index = flatItems.findIndex(item => item[this.id] === identifier);
1843
+ if (index < 0) {
1921
1844
  return false;
1922
- element.parentNode?.removeChild(element);
1923
- this.loaded.delete(path);
1924
- return true;
1845
+ }
1846
+ flatItems[index] = { ...flatItems[index], ...props };
1847
+ flatItems.sort(this.sort);
1848
+ return this.publish(flatItems);
1925
1849
  }
1926
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LazyLoadService, deps: [{ token: ResourceWaitService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1927
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LazyLoadService, providedIn: 'root' }); }
1928
- }
1929
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LazyLoadService, decorators: [{
1930
- type: Injectable,
1931
- args: [{
1932
- providedIn: 'root',
1933
- }]
1934
- }], ctorParameters: () => [{ type: ResourceWaitService }] });
1935
-
1936
- class ListService {
1937
- set filter(value) {
1938
- this._filter = value;
1939
- this.get();
1850
+ refresh() {
1851
+ return this.add([]);
1940
1852
  }
1941
- get filter() {
1942
- return this._filter;
1853
+ remove(identifiers) {
1854
+ const set = new Set();
1855
+ identifiers.forEach(id => set.add(id));
1856
+ const setToRemove = this.findItemsToRemove(set);
1857
+ const flatItems = this.filterWith(setToRemove);
1858
+ return this.publish(flatItems);
1943
1859
  }
1944
- set maxResultCount(value) {
1945
- this._maxResultCount = value;
1946
- this.get();
1860
+ removeByParam(params) {
1861
+ if (!params) {
1862
+ return null;
1863
+ }
1864
+ const keys = Object.keys(params);
1865
+ if (keys.length === 0) {
1866
+ return null;
1867
+ }
1868
+ const excludedList = this.flat.filter(item => keys.every(key => item[key] === params[key]));
1869
+ if (!excludedList?.length) {
1870
+ return null;
1871
+ }
1872
+ for (const item of excludedList) {
1873
+ this.removeByParam({ [this.parentId]: item[this.id] });
1874
+ }
1875
+ const flatItems = this.flat.filter(item => !excludedList.includes(item));
1876
+ return this.publish(flatItems);
1947
1877
  }
1948
- get maxResultCount() {
1949
- return this._maxResultCount;
1878
+ search(params, tree = this.tree) {
1879
+ const searchKeys = Object.keys(params);
1880
+ return tree.reduce((acc, node) => {
1881
+ if (acc) {
1882
+ return acc;
1883
+ }
1884
+ if (searchKeys.every(key => node[key] === params[key])) {
1885
+ return node;
1886
+ }
1887
+ return this.search(params, node.children);
1888
+ }, null);
1950
1889
  }
1951
- set page(value) {
1952
- if (value === this._page)
1953
- return;
1954
- this._page = value;
1955
- this.get();
1890
+ setSingularizeStatus(singularize = true) {
1891
+ this.shouldSingularizeRoutes = singularize;
1956
1892
  }
1957
- get page() {
1958
- return this._page;
1893
+ }
1894
+ class AbstractNavTreeService extends AbstractTreeService {
1895
+ constructor(injector) {
1896
+ super();
1897
+ this.injector = injector;
1898
+ this.id = 'name';
1899
+ this.parentId = 'parentName';
1900
+ this.hide = (item) => item.invisible || !this.isGranted(item);
1901
+ this.sort = (a, b) => {
1902
+ return this.compareFunc(a, b);
1903
+ };
1904
+ const configState = this.injector.get(ConfigStateService);
1905
+ this.subscription = configState
1906
+ .createOnUpdateStream(state => state)
1907
+ .subscribe(() => this.refresh());
1908
+ this.permissionService = injector.get(PermissionService);
1909
+ this.othersGroup = injector.get(OTHERS_GROUP);
1910
+ this.compareFunc = injector.get(SORT_COMPARE_FUNC);
1959
1911
  }
1960
- set totalCount(value) {
1961
- if (value === this._totalCount)
1962
- return;
1963
- this._totalCount = value;
1964
- this.get();
1912
+ isGranted({ requiredPolicy }) {
1913
+ return this.permissionService.getGrantedPolicy(requiredPolicy);
1965
1914
  }
1966
- get totalCount() {
1967
- return this._totalCount;
1915
+ hasChildren(identifier) {
1916
+ const node = this.find(item => item[this.id] === identifier);
1917
+ return Boolean(node?.children?.length);
1968
1918
  }
1969
- set sortKey(value) {
1970
- this._sortKey = value;
1971
- this.get();
1919
+ hasInvisibleChild(identifier) {
1920
+ const node = this.find(item => item[this.id] === identifier);
1921
+ return node?.children?.some(child => child.invisible) || false;
1972
1922
  }
1973
- get sortKey() {
1974
- return this._sortKey;
1923
+ /* istanbul ignore next */
1924
+ ngOnDestroy() {
1925
+ this.subscription.unsubscribe();
1975
1926
  }
1976
- set sortOrder(value) {
1977
- this._sortOrder = value;
1978
- this.get();
1927
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbstractNavTreeService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1928
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbstractNavTreeService }); }
1929
+ }
1930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbstractNavTreeService, decorators: [{
1931
+ type: Injectable
1932
+ }], ctorParameters: () => [{ type: i0.Injector }] });
1933
+ class RoutesService extends AbstractNavTreeService {
1934
+ hasPathOrChild(item) {
1935
+ return Boolean(item.path) || this.hasChildren(item.name);
1979
1936
  }
1980
- get sortOrder() {
1981
- return this._sortOrder;
1937
+ get groupedVisible() {
1938
+ return this.createGroupedTree(this.visible.filter(item => this.hasPathOrChild(item)));
1982
1939
  }
1983
- get query$() {
1984
- return this._query$
1985
- .asObservable()
1986
- .pipe(this.delay, shareReplay({ bufferSize: 1, refCount: true }));
1940
+ get groupedVisible$() {
1941
+ return this.visible$.pipe(map$1(items => items.filter(item => this.hasPathOrChild(item))), map$1(visible => this.createGroupedTree(visible)));
1987
1942
  }
1988
- get isLoading$() {
1989
- return this._isLoading$.asObservable();
1943
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RoutesService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
1944
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RoutesService, providedIn: 'root' }); }
1945
+ }
1946
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RoutesService, decorators: [{
1947
+ type: Injectable,
1948
+ args: [{ providedIn: 'root' }]
1949
+ }] });
1950
+
1951
+ class SubscriptionService {
1952
+ constructor() {
1953
+ this.subscription = new Subscription();
1990
1954
  }
1991
- constructor(injector) {
1992
- this._filter = '';
1993
- this._maxResultCount = 10;
1994
- this._skipCount = 0;
1995
- this._page = 0;
1996
- this._totalCount = 0;
1997
- this._sortKey = '';
1998
- this._sortOrder = '';
1999
- this._query$ = new ReplaySubject(1);
2000
- this._isLoading$ = new BehaviorSubject(false);
2001
- this.destroy$ = new Subject();
2002
- this.get = () => {
2003
- this.resetPageWhenUnchanged();
2004
- this.next();
2005
- };
2006
- this.getWithoutPageReset = () => {
2007
- this.next();
2008
- };
2009
- const delay = injector.get(LIST_QUERY_DEBOUNCE_TIME, 300);
2010
- this.delay = delay ? debounceTime(delay) : tap();
2011
- this.get();
1955
+ get isClosed() {
1956
+ return this.subscription.closed;
2012
1957
  }
2013
- hookToQuery(streamCreatorCallback) {
2014
- return this.query$.pipe(tap(() => this._isLoading$.next(true)), switchMap(query => streamCreatorCallback(query).pipe(catchError(() => of(null)))), filter(Boolean), tap(() => this._isLoading$.next(false)), shareReplay({ bufferSize: 1, refCount: true }), takeUntil(this.destroy$));
1958
+ addOne(source$, nextOrObserver, error) {
1959
+ const subscription = source$.subscribe(nextOrObserver, error);
1960
+ this.subscription.add(subscription);
1961
+ return subscription;
1962
+ }
1963
+ closeAll() {
1964
+ this.subscription.unsubscribe();
1965
+ }
1966
+ closeOne(subscription) {
1967
+ this.removeOne(subscription);
1968
+ if (subscription) {
1969
+ subscription.unsubscribe();
1970
+ }
2015
1971
  }
2016
1972
  ngOnDestroy() {
2017
- this.destroy$.next();
1973
+ this.subscription.unsubscribe();
2018
1974
  }
2019
- resetPageWhenUnchanged() {
2020
- const maxPage = Number(Number(this.totalCount / this._maxResultCount).toFixed());
2021
- const skipCount = this._page * this._maxResultCount;
2022
- if (skipCount !== this._totalCount) {
2023
- this._skipCount = skipCount;
1975
+ removeOne(subscription) {
1976
+ if (!subscription)
2024
1977
  return;
2025
- }
2026
- if (this.page === maxPage && this.page > 0) {
2027
- this._skipCount = skipCount - this._maxResultCount;
2028
- this.page = this.page - 1;
2029
- }
1978
+ this.subscription.remove(subscription);
2030
1979
  }
2031
- next() {
2032
- this._query$.next({
2033
- filter: this._filter || undefined,
2034
- maxResultCount: this._maxResultCount,
2035
- skipCount: this._page * this._maxResultCount,
2036
- sorting: this._sortOrder ? `${this._sortKey} ${this._sortOrder}` : undefined,
2037
- });
1980
+ reset() {
1981
+ this.subscription.unsubscribe();
1982
+ this.subscription = new Subscription();
2038
1983
  }
2039
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ListService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
2040
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ListService }); }
1984
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SubscriptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1985
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SubscriptionService }); }
2041
1986
  }
2042
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ListService, decorators: [{
1987
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SubscriptionService, decorators: [{
2043
1988
  type: Injectable
2044
- }], ctorParameters: () => [{ type: i0.Injector }] });
1989
+ }] });
2045
1990
 
2046
- class PermissionService {
2047
- constructor(configState) {
2048
- this.configState = configState;
2049
- }
2050
- getGrantedPolicy$(key) {
2051
- return this.getStream().pipe(map(grantedPolicies => this.isPolicyGranted(key, grantedPolicies)));
2052
- }
2053
- getGrantedPolicy(key) {
2054
- const policies = this.getSnapshot();
2055
- return this.isPolicyGranted(key, policies);
2056
- }
2057
- filterItemsByPolicy(items) {
2058
- const policies = this.getSnapshot();
2059
- return items.filter(item => !item.requiredPolicy || this.isPolicyGranted(item.requiredPolicy, policies));
2060
- }
2061
- filterItemsByPolicy$(items) {
2062
- return this.getStream().pipe(map(policies => items.filter(item => !item.requiredPolicy || this.isPolicyGranted(item.requiredPolicy, policies))));
1991
+ const trackBy = (key) => (_, item) => item[key];
1992
+ const trackByDeep = (
1993
+ // eslint-disable-next-line @typescript-eslint/ban-types
1994
+ ...keys) => (_, item) => keys.reduce((acc, key) => acc[key], item);
1995
+ class TrackByService {
1996
+ constructor() {
1997
+ this.by = trackBy;
1998
+ this.byDeep = trackByDeep;
2063
1999
  }
2064
- isPolicyGranted(key, grantedPolicies) {
2065
- if (!key)
2066
- return true;
2067
- const orRegexp = /\|\|/g;
2068
- const andRegexp = /&&/g;
2069
- // TODO: Allow combination of ANDs & ORs
2070
- if (orRegexp.test(key)) {
2071
- const keys = key.split('||').filter(Boolean);
2072
- if (keys.length < 2)
2073
- return false;
2074
- return keys.some(k => this.getPolicy(k.trim(), grantedPolicies));
2075
- }
2076
- else if (andRegexp.test(key)) {
2077
- const keys = key.split('&&').filter(Boolean);
2078
- if (keys.length < 2)
2079
- return false;
2080
- return keys.every(k => this.getPolicy(k.trim(), grantedPolicies));
2081
- }
2082
- return this.getPolicy(key, grantedPolicies);
2000
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TrackByService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2001
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TrackByService, providedIn: 'root' }); }
2002
+ }
2003
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TrackByService, decorators: [{
2004
+ type: Injectable,
2005
+ args: [{
2006
+ providedIn: 'root',
2007
+ }]
2008
+ }] });
2009
+
2010
+ class AbpWindowService {
2011
+ constructor() {
2012
+ this.document = inject(DOCUMENT);
2013
+ this.window = this.document.defaultView;
2014
+ this.navigator = this.window.navigator;
2083
2015
  }
2084
- getStream() {
2085
- return this.configState.getAll$().pipe(map(this.mapToPolicies));
2016
+ copyToClipboard(text) {
2017
+ return this.navigator.clipboard.writeText(text);
2086
2018
  }
2087
- getSnapshot() {
2088
- return this.mapToPolicies(this.configState.getAll());
2019
+ open(url, target, features) {
2020
+ return this.window.open(url, target, features);
2089
2021
  }
2090
- mapToPolicies(applicationConfiguration) {
2091
- return applicationConfiguration?.auth?.grantedPolicies || {};
2022
+ reloadPage() {
2023
+ this.window.location.reload();
2092
2024
  }
2093
- getPolicy(key, grantedPolicies) {
2094
- return grantedPolicies[key] || false;
2025
+ downloadBlob(blob, fileName) {
2026
+ const blobUrl = this.window.URL.createObjectURL(blob);
2027
+ const a = this.document.createElement('a');
2028
+ a.style.display = 'none';
2029
+ a.href = blobUrl;
2030
+ a.download = fileName;
2031
+ this.document.body.appendChild(a);
2032
+ a.dispatchEvent(new MouseEvent('click', {
2033
+ bubbles: true,
2034
+ cancelable: true,
2035
+ view: this.window,
2036
+ }));
2037
+ this.window.URL.revokeObjectURL(blobUrl);
2038
+ this.document.body.removeChild(a);
2095
2039
  }
2096
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionService, deps: [{ token: ConfigStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2097
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionService, providedIn: 'root' }); }
2040
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpWindowService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2041
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpWindowService, providedIn: 'root' }); }
2098
2042
  }
2099
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: PermissionService, decorators: [{
2043
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpWindowService, decorators: [{
2100
2044
  type: Injectable,
2101
2045
  args: [{ providedIn: 'root' }]
2102
- }], ctorParameters: () => [{ type: ConfigStateService }] });
2046
+ }] });
2103
2047
 
2104
- class RouterWaitService {
2105
- constructor(routerEvents, injector) {
2106
- this.routerEvents = routerEvents;
2107
- this.store = new InternalStore({ loading: false });
2108
- this.destroy$ = new Subject();
2109
- this.delay = injector.get(LOADER_DELAY, 500);
2110
- this.updateLoadingStatusOnNavigationEvents();
2048
+ class InternetConnectionService {
2049
+ constructor() {
2050
+ this.document = inject(DOCUMENT);
2051
+ this.window = this.document.defaultView;
2052
+ this.navigator = this.window.navigator;
2053
+ this.status$ = new BehaviorSubject(this.navigator.onLine);
2054
+ this.status = signal(this.navigator.onLine);
2055
+ this.networkStatus = computed(() => this.status());
2056
+ this.window.addEventListener('offline', () => this.setStatus(false));
2057
+ this.window.addEventListener('online', () => this.setStatus(true));
2111
2058
  }
2112
- updateLoadingStatusOnNavigationEvents() {
2113
- this.routerEvents
2114
- .getAllNavigationEvents()
2115
- .pipe(map(event => event instanceof NavigationStart), switchMap(condition => condition
2116
- ? this.delay === 0
2117
- ? of(true)
2118
- : timer(this.delay || 0).pipe(mapTo(true), takeUntil(this.destroy$))
2119
- : of(false)), tap(() => this.destroy$.next()))
2120
- .subscribe(status => {
2121
- this.setLoading(status);
2122
- });
2059
+ setStatus(val) {
2060
+ this.status.set(val);
2061
+ this.status$.next(val);
2123
2062
  }
2124
- getLoading() {
2125
- return this.store.state.loading;
2063
+ get networkStatus$() {
2064
+ return this.status$.asObservable();
2126
2065
  }
2127
- getLoading$() {
2128
- return this.store.sliceState(({ loading }) => loading);
2066
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: InternetConnectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2067
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: InternetConnectionService, providedIn: 'root' }); }
2068
+ }
2069
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: InternetConnectionService, decorators: [{
2070
+ type: Injectable,
2071
+ args: [{
2072
+ providedIn: 'root',
2073
+ }]
2074
+ }], ctorParameters: () => [] });
2075
+
2076
+ class LocalStorageListenerService {
2077
+ constructor() {
2078
+ this.window = inject(DOCUMENT).defaultView;
2079
+ this.window.addEventListener('storage', event => {
2080
+ if (event.key === 'access_token' && event.newValue === null) {
2081
+ this.window.location.reload();
2082
+ }
2083
+ });
2129
2084
  }
2130
- updateLoading$() {
2131
- return this.store.sliceUpdate(({ loading }) => loading);
2085
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalStorageListenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2086
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalStorageListenerService, providedIn: 'root' }); }
2087
+ }
2088
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalStorageListenerService, decorators: [{
2089
+ type: Injectable,
2090
+ args: [{
2091
+ providedIn: 'root',
2092
+ }]
2093
+ }], ctorParameters: () => [] });
2094
+
2095
+ class AbpApplicationConfigurationService {
2096
+ constructor(restService) {
2097
+ this.restService = restService;
2098
+ this.apiName = 'abp';
2099
+ this.get = (options, config) => this.restService.request({
2100
+ method: 'GET',
2101
+ url: '/api/abp/application-configuration',
2102
+ params: { includeLocalizationResources: options.includeLocalizationResources },
2103
+ }, { apiName: this.apiName, ...config });
2132
2104
  }
2133
- setLoading(loading) {
2134
- this.store.patch({ loading });
2105
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationConfigurationService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2106
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationConfigurationService, providedIn: 'root' }); }
2107
+ }
2108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationConfigurationService, decorators: [{
2109
+ type: Injectable,
2110
+ args: [{
2111
+ providedIn: 'root',
2112
+ }]
2113
+ }], ctorParameters: () => [{ type: RestService }] });
2114
+
2115
+ class AbpApplicationLocalizationService {
2116
+ constructor(restService) {
2117
+ this.restService = restService;
2118
+ this.apiName = 'abp';
2119
+ this.get = (input, config) => this.restService.request({
2120
+ method: 'GET',
2121
+ url: '/api/abp/application-localization',
2122
+ params: { cultureName: input.cultureName, onlyDynamics: input.onlyDynamics },
2123
+ }, { apiName: this.apiName, ...config });
2135
2124
  }
2136
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterWaitService, deps: [{ token: RouterEvents }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
2137
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterWaitService, providedIn: 'root' }); }
2125
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationLocalizationService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2126
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationLocalizationService, providedIn: 'root' }); }
2138
2127
  }
2139
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RouterWaitService, decorators: [{
2128
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApplicationLocalizationService, decorators: [{
2140
2129
  type: Injectable,
2141
2130
  args: [{
2142
2131
  providedIn: 'root',
2143
2132
  }]
2144
- }], ctorParameters: () => [{ type: RouterEvents }, { type: i0.Injector }] });
2133
+ }], ctorParameters: () => [{ type: RestService }] });
2145
2134
 
2146
- class SubscriptionService {
2147
- constructor() {
2148
- this.subscription = new Subscription();
2135
+ class ConfigStateService {
2136
+ setState(config) {
2137
+ this.store.set(config);
2149
2138
  }
2150
- get isClosed() {
2151
- return this.subscription.closed;
2139
+ get createOnUpdateStream() {
2140
+ return this.store.sliceUpdate;
2152
2141
  }
2153
- addOne(source$, nextOrObserver, error) {
2154
- const subscription = source$.subscribe(nextOrObserver, error);
2155
- this.subscription.add(subscription);
2156
- return subscription;
2142
+ constructor(abpConfigService, abpApplicationLocalizationService, includeLocalizationResources) {
2143
+ this.abpConfigService = abpConfigService;
2144
+ this.abpApplicationLocalizationService = abpApplicationLocalizationService;
2145
+ this.includeLocalizationResources = includeLocalizationResources;
2146
+ this.updateSubject = new Subject();
2147
+ this.store = new InternalStore({});
2148
+ this.initUpdateStream();
2149
+ }
2150
+ initUpdateStream() {
2151
+ this.updateSubject
2152
+ .pipe(switchMap(() => this.abpConfigService.get({
2153
+ includeLocalizationResources: !!this.includeLocalizationResources,
2154
+ })))
2155
+ .pipe(switchMap(appState => this.getLocalizationAndCombineWithAppState(appState)))
2156
+ .subscribe(res => this.store.set(res));
2157
+ }
2158
+ getLocalizationAndCombineWithAppState(appState) {
2159
+ if (!appState.localization.currentCulture.cultureName) {
2160
+ throw new Error('culture name should defined');
2161
+ }
2162
+ return this.getlocalizationResource(appState.localization.currentCulture.cultureName).pipe(map(result => ({ ...appState, localization: { ...appState.localization, ...result } })));
2163
+ }
2164
+ getlocalizationResource(cultureName) {
2165
+ return this.abpApplicationLocalizationService.get({
2166
+ cultureName: cultureName,
2167
+ onlyDynamics: false,
2168
+ });
2169
+ }
2170
+ refreshAppState() {
2171
+ this.updateSubject.next();
2172
+ return this.createOnUpdateStream(state => state).pipe(take(1));
2173
+ }
2174
+ refreshLocalization(lang) {
2175
+ if (this.includeLocalizationResources) {
2176
+ return this.refreshAppState().pipe(map(() => null));
2177
+ }
2178
+ return this.getlocalizationResource(lang)
2179
+ .pipe(tap(result => this.store.patch({ localization: { ...this.store.state.localization, ...result } })))
2180
+ .pipe(map(() => null));
2181
+ }
2182
+ getOne$(key) {
2183
+ return this.store.sliceState(state => state[key]);
2184
+ }
2185
+ getOne(key) {
2186
+ return this.store.state[key];
2187
+ }
2188
+ getAll$() {
2189
+ return this.store.sliceState(state => state);
2190
+ }
2191
+ getAll() {
2192
+ return this.store.state;
2157
2193
  }
2158
- closeAll() {
2159
- this.subscription.unsubscribe();
2194
+ getDeep$(keys) {
2195
+ keys = splitKeys(keys);
2196
+ return this.store
2197
+ .sliceState(state => state)
2198
+ .pipe(map(state => {
2199
+ return keys.reduce((acc, val) => {
2200
+ if (acc) {
2201
+ return acc[val];
2202
+ }
2203
+ return undefined;
2204
+ }, state);
2205
+ }));
2160
2206
  }
2161
- closeOne(subscription) {
2162
- this.removeOne(subscription);
2163
- if (subscription) {
2164
- subscription.unsubscribe();
2165
- }
2207
+ getDeep(keys) {
2208
+ keys = splitKeys(keys);
2209
+ return keys.reduce((acc, val) => {
2210
+ if (acc) {
2211
+ return acc[val];
2212
+ }
2213
+ return undefined;
2214
+ }, this.store.state);
2166
2215
  }
2167
- ngOnDestroy() {
2168
- this.subscription.unsubscribe();
2216
+ getFeature(key) {
2217
+ return this.store.state.features?.values?.[key];
2169
2218
  }
2170
- removeOne(subscription) {
2171
- if (!subscription)
2219
+ getFeature$(key) {
2220
+ return this.store.sliceState(state => state.features?.values?.[key]);
2221
+ }
2222
+ getFeatures(keys) {
2223
+ const { features } = this.store.state;
2224
+ if (!features)
2172
2225
  return;
2173
- this.subscription.remove(subscription);
2226
+ return keys.reduce((acc, key) => ({ ...acc, [key]: features.values[key] }), {});
2174
2227
  }
2175
- reset() {
2176
- this.subscription.unsubscribe();
2177
- this.subscription = new Subscription();
2228
+ getFeatures$(keys) {
2229
+ return this.store.sliceState(({ features }) => {
2230
+ if (!features?.values)
2231
+ return;
2232
+ return keys.reduce((acc, key) => ({ ...acc, [key]: features.values[key] }), {});
2233
+ });
2178
2234
  }
2179
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SubscriptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2180
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SubscriptionService }); }
2181
- }
2182
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SubscriptionService, decorators: [{
2183
- type: Injectable
2184
- }] });
2185
-
2186
- const trackBy = (key) => (_, item) => item[key];
2187
- const trackByDeep = (
2188
- // eslint-disable-next-line @typescript-eslint/ban-types
2189
- ...keys) => (_, item) => keys.reduce((acc, key) => acc[key], item);
2190
- class TrackByService {
2191
- constructor() {
2192
- this.by = trackBy;
2193
- this.byDeep = trackByDeep;
2235
+ getSetting(key) {
2236
+ return this.store.state.setting?.values?.[key];
2194
2237
  }
2195
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TrackByService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2196
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TrackByService, providedIn: 'root' }); }
2197
- }
2198
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TrackByService, decorators: [{
2199
- type: Injectable,
2200
- args: [{
2201
- providedIn: 'root',
2202
- }]
2203
- }] });
2204
-
2205
- class AbpWindowService {
2206
- constructor() {
2207
- this.document = inject(DOCUMENT);
2208
- this.window = this.document.defaultView;
2209
- this.navigator = this.window.navigator;
2238
+ getSetting$(key) {
2239
+ return this.store.sliceState(state => state.setting?.values?.[key]);
2210
2240
  }
2211
- copyToClipboard(text) {
2212
- return this.navigator.clipboard.writeText(text);
2241
+ getSettings(keyword) {
2242
+ const settings = this.store.state.setting?.values || {};
2243
+ if (!keyword)
2244
+ return settings;
2245
+ const keysFound = Object.keys(settings).filter(key => key.indexOf(keyword) > -1);
2246
+ return keysFound.reduce((acc, key) => {
2247
+ acc[key] = settings[key];
2248
+ return acc;
2249
+ }, {});
2213
2250
  }
2214
- open(url, target, features) {
2215
- return this.window.open(url, target, features);
2251
+ getSettings$(keyword) {
2252
+ return this.store
2253
+ .sliceState(state => state.setting?.values)
2254
+ .pipe(map((settings = {}) => {
2255
+ if (!keyword)
2256
+ return settings;
2257
+ const keysFound = Object.keys(settings).filter(key => key.indexOf(keyword) > -1);
2258
+ return keysFound.reduce((acc, key) => {
2259
+ acc[key] = settings[key];
2260
+ return acc;
2261
+ }, {});
2262
+ }));
2216
2263
  }
2217
- reloadPage() {
2218
- this.window.location.reload();
2264
+ getGlobalFeatures() {
2265
+ return this.store.state.globalFeatures;
2219
2266
  }
2220
- downloadBlob(blob, fileName) {
2221
- const blobUrl = this.window.URL.createObjectURL(blob);
2222
- const a = this.document.createElement('a');
2223
- a.style.display = 'none';
2224
- a.href = blobUrl;
2225
- a.download = fileName;
2226
- this.document.body.appendChild(a);
2227
- a.dispatchEvent(new MouseEvent('click', {
2228
- bubbles: true,
2229
- cancelable: true,
2230
- view: this.window,
2231
- }));
2232
- this.window.URL.revokeObjectURL(blobUrl);
2233
- this.document.body.removeChild(a);
2267
+ getGlobalFeatures$() {
2268
+ return this.store.sliceState(state => state.globalFeatures);
2234
2269
  }
2235
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpWindowService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2236
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpWindowService, providedIn: 'root' }); }
2237
- }
2238
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpWindowService, decorators: [{
2239
- type: Injectable,
2240
- args: [{ providedIn: 'root' }]
2241
- }] });
2242
-
2243
- class InternetConnectionService {
2244
- constructor() {
2245
- this.document = inject(DOCUMENT);
2246
- this.window = this.document.defaultView;
2247
- this.navigator = this.window.navigator;
2248
- this.status$ = new BehaviorSubject(this.navigator.onLine);
2249
- this.status = signal(this.navigator.onLine);
2250
- this.networkStatus = computed(() => this.status());
2251
- this.window.addEventListener('offline', () => this.setStatus(false));
2252
- this.window.addEventListener('online', () => this.setStatus(true));
2270
+ isGlobalFeatureEnabled(key, globalFeatures) {
2271
+ const features = globalFeatures.enabledFeatures || [];
2272
+ return features.some(f => key === f);
2253
2273
  }
2254
- setStatus(val) {
2255
- this.status.set(val);
2256
- this.status$.next(val);
2274
+ getGlobalFeatureIsEnabled(key) {
2275
+ return this.isGlobalFeatureEnabled(key, this.store.state.globalFeatures);
2257
2276
  }
2258
- get networkStatus$() {
2259
- return this.status$.asObservable();
2277
+ getGlobalFeatureIsEnabled$(key) {
2278
+ return this.store.sliceState(state => this.isGlobalFeatureEnabled(key, state.globalFeatures));
2260
2279
  }
2261
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: InternetConnectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2262
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: InternetConnectionService, providedIn: 'root' }); }
2280
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ConfigStateService, deps: [{ token: AbpApplicationConfigurationService }, { token: AbpApplicationLocalizationService }, { token: INCUDE_LOCALIZATION_RESOURCES_TOKEN, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
2281
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ConfigStateService, providedIn: 'root' }); }
2263
2282
  }
2264
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: InternetConnectionService, decorators: [{
2283
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: ConfigStateService, decorators: [{
2265
2284
  type: Injectable,
2266
2285
  args: [{
2267
2286
  providedIn: 'root',
2268
2287
  }]
2269
- }], ctorParameters: () => [] });
2270
-
2271
- const SORT_COMPARE_FUNC = new InjectionToken('SORT_COMPARE_FUNC');
2272
- function compareFuncFactory() {
2273
- const localizationService = inject(LocalizationService);
2274
- const fn = (a, b) => {
2275
- const aName = localizationService.instant(a.name);
2276
- const bName = localizationService.instant(b.name);
2277
- const aNumber = a.order;
2278
- const bNumber = b.order;
2279
- if (!Number.isInteger(aNumber))
2280
- return 1;
2281
- if (!Number.isInteger(bNumber))
2282
- return -1;
2283
- if (aNumber > bNumber)
2284
- return 1;
2285
- if (aNumber < bNumber)
2286
- return -1;
2287
- if (aName > bName)
2288
- return 1;
2289
- if (aName < bName)
2290
- return -1;
2291
- if (a.id > b.id)
2292
- return 1;
2293
- if (a.id < b.id)
2294
- return -1;
2295
- return 0;
2296
- };
2297
- return fn;
2298
- }
2299
-
2300
- // eslint-disable-next-line @typescript-eslint/ban-types
2301
- class AbstractTreeService {
2302
- constructor() {
2303
- this._flat$ = new BehaviorSubject([]);
2304
- this._tree$ = new BehaviorSubject([]);
2305
- this._visible$ = new BehaviorSubject([]);
2306
- }
2307
- get flat() {
2308
- return this._flat$.value;
2309
- }
2310
- get flat$() {
2311
- return this._flat$.asObservable();
2312
- }
2313
- get tree() {
2314
- return this._tree$.value;
2315
- }
2316
- get tree$() {
2317
- return this._tree$.asObservable();
2318
- }
2319
- get visible() {
2320
- return this._visible$.value;
2321
- }
2322
- get visible$() {
2323
- return this._visible$.asObservable();
2324
- }
2325
- createTree(items) {
2326
- return createTreeFromList(items, item => item[this.id], item => item[this.parentId], item => BaseTreeNode.create(item));
2288
+ }], ctorParameters: () => [{ type: AbpApplicationConfigurationService }, { type: AbpApplicationLocalizationService }, { type: undefined, decorators: [{
2289
+ type: Optional
2290
+ }, {
2291
+ type: Inject,
2292
+ args: [INCUDE_LOCALIZATION_RESOURCES_TOKEN]
2293
+ }] }] });
2294
+ function splitKeys(keys) {
2295
+ if (typeof keys === 'string') {
2296
+ keys = keys.split('.');
2327
2297
  }
2328
- createGroupedTree(list) {
2329
- const map = createGroupMap(list, this.othersGroup);
2330
- if (!map) {
2331
- return undefined;
2332
- }
2333
- return Array.from(map, ([key, items]) => ({ group: key, items }));
2298
+ if (!Array.isArray(keys)) {
2299
+ throw new Error('The argument must be a dot string or an string array.');
2334
2300
  }
2335
- filterWith(setOrMap) {
2336
- return this._flat$.value.filter(item => !setOrMap.has(item[this.id]));
2301
+ return keys;
2302
+ }
2303
+
2304
+ class LocalizationService {
2305
+ /**
2306
+ * Returns currently selected language
2307
+ * Even though this looks like it's redundant to return the same value as `getLanguage()`,
2308
+ * it's actually not. This could be invoked any time, and the latestLang could be different from the
2309
+ * sessionState.getLanguage() value.
2310
+ */
2311
+ get currentLang() {
2312
+ return this.latestLang || this.sessionState.getLanguage();
2337
2313
  }
2338
- findItemsToRemove(set) {
2339
- return this._flat$.value.reduce((acc, item) => {
2340
- if (!acc.has(item[this.parentId]))
2341
- return acc;
2342
- const childSet = new Set([item[this.id]]);
2343
- const children = this.findItemsToRemove(childSet);
2344
- return new Set([...acc, ...children]);
2345
- }, set);
2314
+ get currentLang$() {
2315
+ return this.sessionState.getLanguage$();
2346
2316
  }
2347
- publish(flatItems, visibleItems) {
2348
- this._flat$.next(flatItems);
2349
- this._tree$.next(this.createTree(flatItems));
2350
- this._visible$.next(this.createTree(visibleItems));
2351
- return flatItems;
2317
+ get languageChange$() {
2318
+ return this._languageChange$.asObservable();
2352
2319
  }
2353
- add(items) {
2354
- const map = new Map();
2355
- items.forEach(item => map.set(item[this.id], item));
2356
- const flatItems = this.filterWith(map);
2357
- map.forEach(pushValueTo(flatItems));
2358
- flatItems.sort(this.sort);
2359
- const visibleItems = flatItems.filter(item => !this.hide(item));
2360
- return this.publish(flatItems, visibleItems);
2320
+ constructor(sessionState, injector, otherInstance, configState) {
2321
+ this.sessionState = sessionState;
2322
+ this.injector = injector;
2323
+ this.configState = configState;
2324
+ this.latestLang = this.sessionState.getLanguage();
2325
+ this._languageChange$ = new Subject();
2326
+ this.uiLocalizations$ = new BehaviorSubject(new Map());
2327
+ this.localizations$ = new BehaviorSubject(new Map());
2328
+ if (otherInstance)
2329
+ throw new Error('LocalizationService should have only one instance.');
2330
+ this.listenToSetLanguage();
2331
+ this.initLocalizationValues();
2361
2332
  }
2362
- find(predicate, tree = this.tree) {
2363
- return tree.reduce((acc, node) => (acc ? acc : predicate(node) ? node : this.find(predicate, node.children)), null);
2333
+ initLocalizationValues() {
2334
+ localizations$.subscribe(val => this.addLocalization(val));
2335
+ const legacyResources$ = this.configState.getDeep$('localization.values');
2336
+ const remoteLocalizations$ = this.configState.getDeep$('localization.resources');
2337
+ const currentLanguage$ = this.sessionState.getLanguage$();
2338
+ const uiLocalizations$ = combineLatest([currentLanguage$, this.uiLocalizations$]).pipe(map(([currentLang, localizations]) => localizations.get(currentLang)));
2339
+ combineLatest([legacyResources$, remoteLocalizations$, uiLocalizations$])
2340
+ .pipe(map(([legacy, resource, local]) => {
2341
+ if (!resource) {
2342
+ return;
2343
+ }
2344
+ const remote = combineLegacyandNewResources(legacy || {}, resource);
2345
+ if (remote) {
2346
+ if (!local) {
2347
+ local = new Map();
2348
+ }
2349
+ Object.entries(remote).forEach(entry => {
2350
+ const resourceName = entry[0];
2351
+ const remoteTexts = entry[1];
2352
+ let resource = local?.get(resourceName) || {};
2353
+ resource = { ...resource, ...remoteTexts };
2354
+ local?.set(resourceName, resource);
2355
+ });
2356
+ }
2357
+ return local;
2358
+ }), filter(Boolean))
2359
+ .subscribe(val => this.localizations$.next(val));
2364
2360
  }
2365
- patch(identifier, props) {
2366
- const flatItems = this._flat$.value;
2367
- const index = flatItems.findIndex(item => item[this.id] === identifier);
2368
- if (index < 0)
2369
- return false;
2370
- flatItems[index] = { ...flatItems[index], ...props };
2371
- flatItems.sort(this.sort);
2372
- const visibleItems = flatItems.filter(item => !this.hide(item));
2373
- return this.publish(flatItems, visibleItems);
2361
+ addLocalization(localizations) {
2362
+ if (!localizations)
2363
+ return;
2364
+ const localizationMap = this.uiLocalizations$.value;
2365
+ localizations.forEach(loc => {
2366
+ const cultureMap = localizationMap.get(loc.culture) || new Map();
2367
+ loc.resources.forEach(res => {
2368
+ let resource = cultureMap.get(res.resourceName) || {};
2369
+ resource = { ...resource, ...res.texts };
2370
+ cultureMap.set(res.resourceName, resource);
2371
+ });
2372
+ localizationMap.set(loc.culture, cultureMap);
2373
+ });
2374
+ this.uiLocalizations$.next(localizationMap);
2374
2375
  }
2375
- refresh() {
2376
- return this.add([]);
2376
+ listenToSetLanguage() {
2377
+ this.sessionState
2378
+ .onLanguageChange$()
2379
+ .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))))
2380
+ .subscribe(lang => this._languageChange$.next(lang));
2377
2381
  }
2378
- remove(identifiers) {
2379
- const set = new Set();
2380
- identifiers.forEach(id => set.add(id));
2381
- const setToRemove = this.findItemsToRemove(set);
2382
- const flatItems = this.filterWith(setToRemove);
2383
- const visibleItems = flatItems.filter(item => !this.hide(item));
2384
- return this.publish(flatItems, visibleItems);
2382
+ registerLocale(locale) {
2383
+ const { registerLocaleFn } = this.injector.get(CORE_OPTIONS);
2384
+ return registerLocaleFn(locale).then(module => {
2385
+ if (module?.default)
2386
+ registerLocaleData(module.default);
2387
+ this.latestLang = locale;
2388
+ });
2385
2389
  }
2386
- search(params, tree = this.tree) {
2387
- const searchKeys = Object.keys(params);
2388
- return tree.reduce((acc, node) => acc
2389
- ? acc
2390
- : searchKeys.every(key => node[key] === params[key])
2391
- ? node
2392
- : this.search(params, node.children), null);
2390
+ /**
2391
+ * Returns an observable localized text with the given interpolation parameters in current language.
2392
+ * @param key Localizaton key to replace with localized text
2393
+ * @param interpolateParams Values to interpolate
2394
+ */
2395
+ get(key, ...interpolateParams) {
2396
+ return this.configState
2397
+ .getAll$()
2398
+ .pipe(map(state => this.getLocalization(state, key, ...interpolateParams)));
2393
2399
  }
2394
- }
2395
- class AbstractNavTreeService extends AbstractTreeService {
2396
- constructor(injector) {
2397
- super();
2398
- this.injector = injector;
2399
- this.id = 'name';
2400
- this.parentId = 'parentName';
2401
- this.hide = (item) => item.invisible || !this.isGranted(item);
2402
- this.sort = (a, b) => {
2403
- return this.compareFunc(a, b);
2404
- };
2405
- const configState = this.injector.get(ConfigStateService);
2406
- this.subscription = configState
2407
- .createOnUpdateStream(state => state)
2408
- .subscribe(() => this.refresh());
2409
- this.permissionService = injector.get(PermissionService);
2410
- this.othersGroup = injector.get(OTHERS_GROUP);
2411
- this.compareFunc = injector.get(SORT_COMPARE_FUNC);
2400
+ getResource(resourceName) {
2401
+ return this.localizations$.value.get(resourceName);
2412
2402
  }
2413
- isGranted({ requiredPolicy }) {
2414
- return this.permissionService.getGrantedPolicy(requiredPolicy);
2403
+ getResource$(resourceName) {
2404
+ return this.localizations$.pipe(map(res => res.get(resourceName)));
2415
2405
  }
2416
- hasChildren(identifier) {
2417
- const node = this.find(item => item[this.id] === identifier);
2418
- return Boolean(node?.children?.length);
2406
+ /**
2407
+ * Returns localized text with the given interpolation parameters in current language.
2408
+ * @param key Localization key to replace with localized text
2409
+ * @param interpolateParams Values to intepolate.
2410
+ */
2411
+ instant(key, ...interpolateParams) {
2412
+ return this.getLocalization(this.configState.getAll(), key, ...interpolateParams);
2419
2413
  }
2420
- hasInvisibleChild(identifier) {
2421
- const node = this.find(item => item[this.id] === identifier);
2422
- return node?.children?.some(child => child.invisible) || false;
2414
+ localize(resourceName, key, defaultValue) {
2415
+ return this.configState.getOne$('localization').pipe(map(createLocalizer), map(localize => localize(resourceName, key, defaultValue)));
2423
2416
  }
2424
- /* istanbul ignore next */
2425
- ngOnDestroy() {
2426
- this.subscription.unsubscribe();
2417
+ localizeSync(resourceName, key, defaultValue) {
2418
+ const localization = this.configState.getOne('localization');
2419
+ return createLocalizer(localization)(resourceName, key, defaultValue);
2427
2420
  }
2428
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbstractNavTreeService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
2429
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbstractNavTreeService }); }
2430
- }
2431
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbstractNavTreeService, decorators: [{
2432
- type: Injectable
2433
- }], ctorParameters: () => [{ type: i0.Injector }] });
2434
- class RoutesService extends AbstractNavTreeService {
2435
- hasPathOrChild(item) {
2436
- return Boolean(item.path) || this.hasChildren(item.name);
2421
+ localizeWithFallback(resourceNames, keys, defaultValue) {
2422
+ return this.configState.getOne$('localization').pipe(map(createLocalizerWithFallback), map(localizeWithFallback => localizeWithFallback(resourceNames, keys, defaultValue)));
2437
2423
  }
2438
- get groupedVisible() {
2439
- return this.createGroupedTree(this.visible.filter(item => this.hasPathOrChild(item)));
2424
+ localizeWithFallbackSync(resourceNames, keys, defaultValue) {
2425
+ const localization = this.configState.getOne('localization');
2426
+ return createLocalizerWithFallback(localization)(resourceNames, keys, defaultValue);
2440
2427
  }
2441
- get groupedVisible$() {
2442
- return this.visible$.pipe(map$1(items => items.filter(item => this.hasPathOrChild(item))), map$1(visible => this.createGroupedTree(visible)));
2428
+ getLocalization(state, key, ...interpolateParams) {
2429
+ let defaultValue = '';
2430
+ if (!key) {
2431
+ return defaultValue;
2432
+ }
2433
+ if (typeof key !== 'string') {
2434
+ defaultValue = key.defaultValue;
2435
+ key = key.key;
2436
+ }
2437
+ const keys = key.split('::');
2438
+ const warn = (message) => {
2439
+ if (isDevMode())
2440
+ console.warn(message);
2441
+ };
2442
+ if (keys.length < 2) {
2443
+ warn('The localization source separator (::) not found.');
2444
+ return defaultValue || key;
2445
+ }
2446
+ if (!state.localization)
2447
+ return defaultValue || keys[1];
2448
+ const sourceName = keys[0] || state.localization.defaultResourceName;
2449
+ const sourceKey = keys[1];
2450
+ if (sourceName === '_') {
2451
+ return defaultValue || sourceKey;
2452
+ }
2453
+ if (!sourceName) {
2454
+ warn('Localization source name is not specified and the defaultResourceName was not defined!');
2455
+ return defaultValue || sourceKey;
2456
+ }
2457
+ const source = this.localizations$.value.get(sourceName);
2458
+ if (!source) {
2459
+ warn('Could not find localization source: ' + sourceName);
2460
+ return defaultValue || sourceKey;
2461
+ }
2462
+ let localization = source[sourceKey];
2463
+ if (typeof localization === 'undefined') {
2464
+ return defaultValue || sourceKey;
2465
+ }
2466
+ interpolateParams = interpolateParams.filter(params => params != null);
2467
+ if (localization)
2468
+ localization = interpolate(localization, interpolateParams);
2469
+ if (typeof localization !== 'string')
2470
+ localization = '';
2471
+ return localization || defaultValue || key;
2443
2472
  }
2444
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RoutesService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
2445
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RoutesService, providedIn: 'root' }); }
2473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalizationService, deps: [{ token: SessionStateService }, { token: i0.Injector }, { token: LocalizationService, optional: true, skipSelf: true }, { token: ConfigStateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2474
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalizationService, providedIn: 'root' }); }
2446
2475
  }
2447
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: RoutesService, decorators: [{
2476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: LocalizationService, decorators: [{
2448
2477
  type: Injectable,
2449
2478
  args: [{ providedIn: 'root' }]
2450
- }] });
2479
+ }], ctorParameters: () => [{ type: SessionStateService }, { type: i0.Injector }, { type: LocalizationService, decorators: [{
2480
+ type: Optional
2481
+ }, {
2482
+ type: SkipSelf
2483
+ }] }, { type: ConfigStateService }] });
2484
+ function recursivelyMergeBaseResources(baseResourceName, source) {
2485
+ const item = source[baseResourceName];
2486
+ if (item.baseResources.length === 0) {
2487
+ return item;
2488
+ }
2489
+ return item.baseResources.reduce((acc, baseResource) => {
2490
+ const baseItem = recursivelyMergeBaseResources(baseResource, source);
2491
+ const texts = { ...baseItem.texts, ...item.texts };
2492
+ return { ...acc, texts };
2493
+ }, item);
2494
+ }
2495
+ function mergeResourcesWithBaseResource(resource) {
2496
+ const entities = Object.keys(resource).map(key => {
2497
+ const newValue = recursivelyMergeBaseResources(key, resource);
2498
+ return [key, newValue];
2499
+ });
2500
+ return entities.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
2501
+ }
2502
+ function combineLegacyandNewResources(legacy, resource) {
2503
+ const mergedResource = mergeResourcesWithBaseResource(resource);
2504
+ return Object.entries(mergedResource).reduce((acc, [key, value]) => {
2505
+ return { ...acc, [key]: value.texts };
2506
+ }, legacy);
2507
+ }
2451
2508
 
2452
2509
  const DYNAMIC_LAYOUTS_TOKEN = new InjectionToken('DYNAMIC_LAYOUTS');
2453
2510
 
@@ -2462,6 +2519,7 @@ class DynamicLayoutComponent {
2462
2519
  this.replaceableComponents = inject(ReplaceableComponentsService);
2463
2520
  this.subscription = inject(SubscriptionService);
2464
2521
  this.routerEvents = inject(RouterEvents);
2522
+ this.environment = inject(EnvironmentService);
2465
2523
  if (dynamicLayoutComponent) {
2466
2524
  if (isDevMode())
2467
2525
  console.warn('DynamicLayoutComponent must be used only in AppComponent.');
@@ -2474,7 +2532,10 @@ class DynamicLayoutComponent {
2474
2532
  if (this.layout) {
2475
2533
  return;
2476
2534
  }
2477
- this.getLayout();
2535
+ const { oAuthConfig } = this.environment.getEnvironment();
2536
+ if (oAuthConfig.responseType === 'code') {
2537
+ this.getLayout();
2538
+ }
2478
2539
  }
2479
2540
  checkLayoutOnNavigationEnd() {
2480
2541
  const navigationEnd$ = this.routerEvents.getNavigationEvents('End');
@@ -2496,11 +2557,8 @@ class DynamicLayoutComponent {
2496
2557
  }
2497
2558
  }
2498
2559
  getExtractedLayout() {
2499
- const routeData = (this.route.snapshot.data || {});
2560
+ const routeData = this.route.snapshot.data || {};
2500
2561
  let expectedLayout = routeData['layout'];
2501
- if (expectedLayout) {
2502
- return expectedLayout;
2503
- }
2504
2562
  let node = findRoute(this.routes, getRoutePath(this.router));
2505
2563
  node = { parent: node };
2506
2564
  while (node.parent) {
@@ -2515,7 +2573,8 @@ class DynamicLayoutComponent {
2515
2573
  showLayoutNotFoundError(layoutName) {
2516
2574
  let message = `Layout ${layoutName} not found.`;
2517
2575
  if (layoutName === 'account') {
2518
- message = 'Account layout not found. Please check your configuration. If you are using LeptonX, please make sure you have added "AccountLayoutModule.forRoot()" to your app.module configuration.';
2576
+ message =
2577
+ 'Account layout not found. Please check your configuration. If you are using LeptonX, please make sure you have added "AccountLayoutModule.forRoot()" to your app.module configuration.';
2519
2578
  }
2520
2579
  console.warn(message);
2521
2580
  }
@@ -2529,15 +2588,21 @@ class DynamicLayoutComponent {
2529
2588
  return this.replaceableComponents.get(key);
2530
2589
  }
2531
2590
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DynamicLayoutComponent, deps: [{ token: DynamicLayoutComponent, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Component }); }
2532
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: DynamicLayoutComponent, selector: "abp-dynamic-layout", providers: [SubscriptionService], ngImport: i0, template: `
2533
- <ng-container *ngIf="isLayoutVisible" [ngComponentOutlet]="layout"></ng-container> `, isInline: true, dependencies: [{ kind: "directive", type: i1$2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
2591
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.3", type: DynamicLayoutComponent, selector: "abp-dynamic-layout", providers: [SubscriptionService], ngImport: i0, template: `
2592
+ @if (isLayoutVisible) {
2593
+ <ng-container [ngComponentOutlet]="layout"></ng-container>
2594
+ }
2595
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$2.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }] }); }
2534
2596
  }
2535
2597
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: DynamicLayoutComponent, decorators: [{
2536
2598
  type: Component,
2537
2599
  args: [{
2538
2600
  selector: 'abp-dynamic-layout',
2539
2601
  template: `
2540
- <ng-container *ngIf="isLayoutVisible" [ngComponentOutlet]="layout"></ng-container> `,
2602
+ @if (isLayoutVisible) {
2603
+ <ng-container [ngComponentOutlet]="layout"></ng-container>
2604
+ }
2605
+ `,
2541
2606
  providers: [SubscriptionService],
2542
2607
  }]
2543
2608
  }], ctorParameters: () => [{ type: DynamicLayoutComponent, decorators: [{
@@ -3994,6 +4059,12 @@ class CoreModule {
3994
4059
  deps: [LocalizationService],
3995
4060
  useFactory: noop,
3996
4061
  },
4062
+ {
4063
+ provide: APP_INITIALIZER,
4064
+ multi: true,
4065
+ deps: [LocalStorageListenerService],
4066
+ useFactory: noop,
4067
+ },
3997
4068
  {
3998
4069
  provide: APP_INITIALIZER,
3999
4070
  multi: true,
@@ -4342,11 +4413,11 @@ class AbpApiDefinitionService {
4342
4413
  constructor(restService) {
4343
4414
  this.restService = restService;
4344
4415
  this.apiName = 'abp';
4345
- this.getByModel = (model) => this.restService.request({
4416
+ this.getByModel = (model, config) => this.restService.request({
4346
4417
  method: 'GET',
4347
4418
  url: '/api/abp/api-definition',
4348
4419
  params: { includeTypes: model.includeTypes },
4349
- }, { apiName: this.apiName });
4420
+ }, { apiName: this.apiName, ...config });
4350
4421
  }
4351
4422
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApiDefinitionService, deps: [{ token: RestService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4352
4423
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AbpApiDefinitionService, providedIn: 'root' }); }
@@ -4806,5 +4877,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImpor
4806
4877
  * Generated bundle index. Do not edit.
4807
4878
  */
4808
4879
 
4809
- export { APP_INIT_ERROR_HANDLERS, AbpApiDefinitionService, AbpApplicationConfigurationService, AbpApplicationLocalizationService, AbpLocalStorageService, AbpTenantService, AbpValidators, AbpWindowService, AbstractAuthErrorFilter, AbstractNavTreeService, AbstractNgModelComponent, AbstractTreeService, ApiInterceptor, AuditedEntityDto, AuditedEntityWithUserDto, AuthErrorEvent, AuthErrorFilterService, AuthEvent, AuthGuard, AuthInfoEvent, AuthService, AuthSuccessEvent, AutofocusDirective, BaseCoreModule, BaseTreeNode, CHECK_AUTHENTICATION_STATE_FN_KEY, CONTAINER_STRATEGY, CONTENT_SECURITY_STRATEGY, CONTENT_STRATEGY, CONTEXT_STRATEGY, COOKIE_LANGUAGE_KEY, CORE_OPTIONS, CROSS_ORIGIN_STRATEGY, ClearContainerStrategy, ComponentContextStrategy, ComponentProjectionStrategy, ConfigStateService, ContainerStrategy, ContentProjectionService, ContentSecurityStrategy, ContentStrategy, ContextStrategy, CoreModule, CreationAuditedEntityDto, CreationAuditedEntityWithUserDto, CrossOriginStrategy, DEFAULT_DYNAMIC_LAYOUTS, DOM_STRATEGY, DefaultQueueManager, DomInsertionService, DomStrategy, DynamicLayoutComponent, EntityDto, EnvironmentService, ExtensibleAuditedEntityDto, ExtensibleAuditedEntityWithUserDto, ExtensibleCreationAuditedEntityDto, ExtensibleCreationAuditedEntityWithUserDto, ExtensibleEntityDto, ExtensibleFullAuditedEntityDto, ExtensibleFullAuditedEntityWithUserDto, ExtensibleLimitedResultRequestDto, ExtensibleObject, ExtensiblePagedAndSortedResultRequestDto, ExtensiblePagedResultRequestDto, ExternalHttpClient, ForDirective, FormSubmitDirective, FullAuditedEntityDto, FullAuditedEntityWithUserDto, HttpErrorReporterService, HttpWaitService, INCUDE_LOCALIZATION_RESOURCES_TOKEN, INJECTOR_PIPE_DATA_TOKEN, IS_EXTERNAL_REQUEST, InitDirective, InputEventDebounceDirective, InsertIntoContainerStrategy, InternalStore, InternetConnectionService, LIST_QUERY_DEBOUNCE_TIME, LOADER_DELAY, LOADING_STRATEGY, LOCALIZATIONS, LazyLoadService, LazyModuleFactory, LimitedResultRequestDto, ListResultDto, ListService, LoadingStrategy, LocalizationModule, LocalizationPipe, LocalizationService, LooseContentSecurityStrategy, MultiTenancyService, NAVIGATE_TO_MANAGE_PROFILE, NavigationEvent, NoContentSecurityStrategy, NoContextStrategy, NoCrossOriginStrategy, OTHERS_GROUP, index as ObjectExtending, PIPE_TO_LOGIN_FN_KEY, PROJECTION_STRATEGY, PagedAndSortedResultRequestDto, PagedResultDto, PagedResultRequestDto, PermissionDirective, PermissionGuard, PermissionService, ProjectionStrategy, QUEUE_MANAGER, ReplaceableComponentsService, ReplaceableRouteContainerComponent, ReplaceableTemplateDirective, ResourceWaitService, RestService, RootComponentProjectionStrategy, RootCoreModule, RouterEvents, RouterOutletComponent, RouterWaitService, RoutesService, SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY, SORT_COMPARE_FUNC, SafeHtmlPipe, ScriptContentStrategy, ScriptLoadingStrategy, SessionStateService, ShortDatePipe, ShortDateTimePipe, ShortTimePipe, ShowPasswordDirective, SortPipe, StopPropagationDirective, StyleContentStrategy, StyleLoadingStrategy, SubscriptionService, TENANT_KEY, TENANT_NOT_FOUND_BY_NAME, TemplateContextStrategy, TemplateProjectionStrategy, ToInjectorPipe, TrackByService, TrackCapsLockDirective, WebHttpUrlEncodingCodec, authGuard, checkHasProp, compareFuncFactory, coreOptionsFactory, createGroupMap, createLocalizationPipeKeyGenerator, createLocalizer, createLocalizerWithFallback, createMapFromList, createTokenParser, createTreeFromList, createTreeNodeFilterCreator, deepMerge, differentLocales, downloadBlob, escapeHtmlChars, exists, featuresFactory, findRoute, fromLazyLoad, generateHash, generatePassword, getInitialData, getLocaleDirection, getPathName, getRemoteEnv, getRoutePath, getShortDateFormat, getShortDateShortTimeFormat, getShortTimeFormat, interpolate, isArray, isNode, isNullOrEmpty, isNullOrUndefined, isNumber, isObject, isObjectAndNotArray, isObjectAndNotArrayNotNode, isUndefinedOrEmptyString, localeInitializer, localizationContributor, localizations$, mapEnumToOptions, noop, parseTenantFromUrl, permissionGuard, pushValueTo, reloadRoute, trackBy, trackByDeep, uuid, validateCreditCard, validateMinAge, validateRange, validateRequired, validateStringLength, validateUniqueCharacter, validateUrl };
4880
+ export { APP_INIT_ERROR_HANDLERS, AbpApiDefinitionService, AbpApplicationConfigurationService, AbpApplicationLocalizationService, AbpLocalStorageService, AbpTenantService, AbpValidators, AbpWindowService, AbstractAuthErrorFilter, AbstractNavTreeService, AbstractNgModelComponent, AbstractTreeService, ApiInterceptor, AuditedEntityDto, AuditedEntityWithUserDto, AuthErrorEvent, AuthErrorFilterService, AuthEvent, AuthGuard, AuthInfoEvent, AuthService, AuthSuccessEvent, AutofocusDirective, BaseCoreModule, BaseTreeNode, CHECK_AUTHENTICATION_STATE_FN_KEY, CONTAINER_STRATEGY, CONTENT_SECURITY_STRATEGY, CONTENT_STRATEGY, CONTEXT_STRATEGY, COOKIE_LANGUAGE_KEY, CORE_OPTIONS, CROSS_ORIGIN_STRATEGY, ClearContainerStrategy, ComponentContextStrategy, ComponentProjectionStrategy, ConfigStateService, ContainerStrategy, ContentProjectionService, ContentSecurityStrategy, ContentStrategy, ContextStrategy, CoreModule, CreationAuditedEntityDto, CreationAuditedEntityWithUserDto, CrossOriginStrategy, DEFAULT_DYNAMIC_LAYOUTS, DOM_STRATEGY, DefaultQueueManager, DomInsertionService, DomStrategy, DynamicLayoutComponent, EntityDto, EnvironmentService, ExtensibleAuditedEntityDto, ExtensibleAuditedEntityWithUserDto, ExtensibleCreationAuditedEntityDto, ExtensibleCreationAuditedEntityWithUserDto, ExtensibleEntityDto, ExtensibleFullAuditedEntityDto, ExtensibleFullAuditedEntityWithUserDto, ExtensibleLimitedResultRequestDto, ExtensibleObject, ExtensiblePagedAndSortedResultRequestDto, ExtensiblePagedResultRequestDto, ExternalHttpClient, ForDirective, FormSubmitDirective, FullAuditedEntityDto, FullAuditedEntityWithUserDto, HttpErrorReporterService, HttpWaitService, INCUDE_LOCALIZATION_RESOURCES_TOKEN, INJECTOR_PIPE_DATA_TOKEN, IS_EXTERNAL_REQUEST, InitDirective, InputEventDebounceDirective, InsertIntoContainerStrategy, InternalStore, InternetConnectionService, LIST_QUERY_DEBOUNCE_TIME, LOADER_DELAY, LOADING_STRATEGY, LOCALIZATIONS, LazyLoadService, LazyModuleFactory, LimitedResultRequestDto, ListResultDto, ListService, LoadingStrategy, LocalStorageListenerService, LocalizationModule, LocalizationPipe, LocalizationService, LooseContentSecurityStrategy, MultiTenancyService, NAVIGATE_TO_MANAGE_PROFILE, NavigationEvent, NoContentSecurityStrategy, NoContextStrategy, NoCrossOriginStrategy, OTHERS_GROUP, index as ObjectExtending, PIPE_TO_LOGIN_FN_KEY, PROJECTION_STRATEGY, PagedAndSortedResultRequestDto, PagedResultDto, PagedResultRequestDto, PermissionDirective, PermissionGuard, PermissionService, ProjectionStrategy, QUEUE_MANAGER, ReplaceableComponentsService, ReplaceableRouteContainerComponent, ReplaceableTemplateDirective, ResourceWaitService, RestService, RootComponentProjectionStrategy, RootCoreModule, RouterEvents, RouterOutletComponent, RouterWaitService, RoutesService, SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY, SORT_COMPARE_FUNC, SafeHtmlPipe, ScriptContentStrategy, ScriptLoadingStrategy, SessionStateService, ShortDatePipe, ShortDateTimePipe, ShortTimePipe, ShowPasswordDirective, SortPipe, StopPropagationDirective, StyleContentStrategy, StyleLoadingStrategy, SubscriptionService, TENANT_KEY, TENANT_NOT_FOUND_BY_NAME, TemplateContextStrategy, TemplateProjectionStrategy, ToInjectorPipe, TrackByService, TrackCapsLockDirective, WebHttpUrlEncodingCodec, authGuard, checkHasProp, compareFuncFactory, coreOptionsFactory, createGroupMap, createLocalizationPipeKeyGenerator, createLocalizer, createLocalizerWithFallback, createMapFromList, createTokenParser, createTreeFromList, createTreeNodeFilterCreator, deepMerge, differentLocales, downloadBlob, escapeHtmlChars, exists, featuresFactory, findRoute, fromLazyLoad, generateHash, generatePassword, getInitialData, getLocaleDirection, getPathName, getRemoteEnv, getRoutePath, getShortDateFormat, getShortDateShortTimeFormat, getShortTimeFormat, interpolate, isArray, isNode, isNullOrEmpty, isNullOrUndefined, isNumber, isObject, isObjectAndNotArray, isObjectAndNotArrayNotNode, isUndefinedOrEmptyString, localeInitializer, localizationContributor, localizations$, mapEnumToOptions, noop, parseTenantFromUrl, permissionGuard, pushValueTo, reloadRoute, trackBy, trackByDeep, uuid, validateCreditCard, validateMinAge, validateRange, validateRequired, validateStringLength, validateUniqueCharacter, validateUrl };
4810
4881
  //# sourceMappingURL=abp-ng.core.mjs.map