oip-common 0.6.6 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -0
- package/fesm2022/oip-common.mjs +873 -81
- package/fesm2022/oip-common.mjs.map +1 -1
- package/index.d.ts +319 -5
- package/package.json +1 -1
package/fesm2022/oip-common.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, inject, signal, computed, effect, isDevMode, DestroyRef, ChangeDetectorRef, Component, Input, InjectionToken, PLATFORM_ID, ViewChild, HostBinding, EventEmitter, Output, Renderer2, SecurityContext, ChangeDetectionStrategy, Injector, EnvironmentInjector, ViewContainerRef, makeEnvironmentProviders, importProvidersFrom } from '@angular/core';
|
|
2
|
+
import { Injectable, inject, signal, computed, effect, isDevMode, DestroyRef, ChangeDetectorRef, Component, Input, InjectionToken, PLATFORM_ID, ViewChild, HostBinding, EventEmitter, Output, untracked, Renderer2, SecurityContext, ChangeDetectionStrategy, Injector, EnvironmentInjector, ViewContainerRef, makeEnvironmentProviders, importProvidersFrom } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
4
|
import { Subject, BehaviorSubject, of, tap, shareReplay, ReplaySubject, firstValueFrom, from, filter as filter$1 } from 'rxjs';
|
|
5
5
|
import * as i2$1 from 'primeng/api';
|
|
@@ -8,7 +8,7 @@ import { HttpErrorResponse, HttpClient as HttpClient$1, provideHttpClient, withI
|
|
|
8
8
|
import * as i1$7 from '@ngx-translate/core';
|
|
9
9
|
import { TranslateService, TranslatePipe, TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
|
10
10
|
import * as i1$5 from '@angular/router';
|
|
11
|
-
import { Router, ActivatedRoute, RouterModule,
|
|
11
|
+
import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError, NavigationSkipped, ActivatedRoute, RouterModule, RouterLinkActive, RouterLink } from '@angular/router';
|
|
12
12
|
import { tap as tap$1, catchError, filter, distinctUntilChanged, switchMap, map, take } from 'rxjs/operators';
|
|
13
13
|
import { Title, DomSanitizer } from '@angular/platform-browser';
|
|
14
14
|
import { PrimeNG } from 'primeng/config';
|
|
@@ -26,8 +26,6 @@ import * as i3$3 from 'primeng/styleclass';
|
|
|
26
26
|
import { StyleClassModule } from 'primeng/styleclass';
|
|
27
27
|
import { updatePreset, updateSurfacePalette, $t, definePreset } from '@primeng/themes';
|
|
28
28
|
import Aura from '@primeng/themes/aura';
|
|
29
|
-
import Lara from '@primeng/themes/lara';
|
|
30
|
-
import Nora from '@primeng/themes/nora';
|
|
31
29
|
import * as i3 from 'primeng/selectbutton';
|
|
32
30
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
|
33
31
|
import { Tabs, TabList, Tab } from 'primeng/tabs';
|
|
@@ -41,7 +39,7 @@ import { PaginatorModule } from 'primeng/paginator';
|
|
|
41
39
|
import * as i7 from 'primeng/popover';
|
|
42
40
|
import { Popover, PopoverModule } from 'primeng/popover';
|
|
43
41
|
import * as i4 from 'primeng/progressspinner';
|
|
44
|
-
import { ProgressSpinnerModule } from 'primeng/progressspinner';
|
|
42
|
+
import { ProgressSpinnerModule, ProgressSpinner } from 'primeng/progressspinner';
|
|
45
43
|
import * as i9 from 'primeng/tag';
|
|
46
44
|
import { Tag, TagModule } from 'primeng/tag';
|
|
47
45
|
import * as signalR from '@microsoft/signalr';
|
|
@@ -546,7 +544,7 @@ var msgService$1 = {
|
|
|
546
544
|
secondary: "Secondary"
|
|
547
545
|
};
|
|
548
546
|
var primeng$1 = "";
|
|
549
|
-
var en$
|
|
547
|
+
var en$j = {
|
|
550
548
|
msgService: msgService$1,
|
|
551
549
|
primeng: primeng$1
|
|
552
550
|
};
|
|
@@ -750,7 +748,7 @@ var primeng = {
|
|
|
750
748
|
zoomOut: "Уменьшить"
|
|
751
749
|
}
|
|
752
750
|
};
|
|
753
|
-
var ru$
|
|
751
|
+
var ru$j = {
|
|
754
752
|
msgService: msgService,
|
|
755
753
|
primeng: primeng
|
|
756
754
|
};
|
|
@@ -759,7 +757,7 @@ var ru$h = {
|
|
|
759
757
|
* Global dictionaries shared by all components. They are bundled with the library,
|
|
760
758
|
* so the application never requests `assets/i18n/{lang}.json`.
|
|
761
759
|
*/
|
|
762
|
-
const globalTranslations = { en: en$
|
|
760
|
+
const globalTranslations = { en: en$j, ru: ru$j };
|
|
763
761
|
/**
|
|
764
762
|
* Service for managing translation loading in the application
|
|
765
763
|
*/
|
|
@@ -1378,13 +1376,94 @@ function collectKeyPaths(value, prefix = '', paths = new Set()) {
|
|
|
1378
1376
|
return paths;
|
|
1379
1377
|
}
|
|
1380
1378
|
|
|
1379
|
+
/**
|
|
1380
|
+
* Tracks whether the application is switching between modules.
|
|
1381
|
+
*
|
|
1382
|
+
* Two sources feed the state:
|
|
1383
|
+
* - router navigation, from `NavigationStart` until the navigation ends, is cancelled or fails;
|
|
1384
|
+
* - explicit work registered with {@link begin}/{@link end} or {@link track}, which covers everything
|
|
1385
|
+
* running after `NavigationEnd`: module instance rights, settings and extension loading.
|
|
1386
|
+
*
|
|
1387
|
+
* The UI blocker rendered by the layout observes {@link loading}.
|
|
1388
|
+
*/
|
|
1389
|
+
class ModuleLoadingService {
|
|
1390
|
+
/** Releases a stuck blocker when a caller never balances its `begin()`. */
|
|
1391
|
+
static { this.watchdogTimeoutMs = 30_000; }
|
|
1392
|
+
constructor() {
|
|
1393
|
+
this.router = inject(Router);
|
|
1394
|
+
this.navigating = signal(false, ...(ngDevMode ? [{ debugName: "navigating" }] : []));
|
|
1395
|
+
this.pending = signal(0, ...(ngDevMode ? [{ debugName: "pending" }] : []));
|
|
1396
|
+
/** True while a module transition is in progress. */
|
|
1397
|
+
this.loading = computed(() => this.navigating() || this.pending() > 0, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
1398
|
+
this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {
|
|
1399
|
+
if (event instanceof NavigationStart) {
|
|
1400
|
+
this.navigating.set(true);
|
|
1401
|
+
}
|
|
1402
|
+
else if (event instanceof NavigationEnd ||
|
|
1403
|
+
event instanceof NavigationCancel ||
|
|
1404
|
+
event instanceof NavigationError ||
|
|
1405
|
+
event instanceof NavigationSkipped) {
|
|
1406
|
+
this.navigating.set(false);
|
|
1407
|
+
}
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
/**
|
|
1411
|
+
* Registers one unit of loading work. Every call must be balanced with {@link end},
|
|
1412
|
+
* preferably from a `finally` block. Prefer {@link track} when the work is a promise.
|
|
1413
|
+
*/
|
|
1414
|
+
begin() {
|
|
1415
|
+
this.pending.update((count) => count + 1);
|
|
1416
|
+
this.armWatchdog();
|
|
1417
|
+
}
|
|
1418
|
+
/** Releases one unit of loading work registered with {@link begin}. */
|
|
1419
|
+
end() {
|
|
1420
|
+
this.pending.update((count) => Math.max(0, count - 1));
|
|
1421
|
+
this.armWatchdog();
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Blocks the UI until `work` settles, and keeps the blocker released when it rejects.
|
|
1425
|
+
*
|
|
1426
|
+
* @example
|
|
1427
|
+
* await this.moduleLoading.track(this.reloadModuleInstance());
|
|
1428
|
+
*/
|
|
1429
|
+
async track(work) {
|
|
1430
|
+
this.begin();
|
|
1431
|
+
try {
|
|
1432
|
+
return await work;
|
|
1433
|
+
}
|
|
1434
|
+
finally {
|
|
1435
|
+
this.end();
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
armWatchdog() {
|
|
1439
|
+
if (this.watchdogHandle != null) {
|
|
1440
|
+
clearTimeout(this.watchdogHandle);
|
|
1441
|
+
this.watchdogHandle = undefined;
|
|
1442
|
+
}
|
|
1443
|
+
if (this.pending() === 0) {
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
1446
|
+
this.watchdogHandle = setTimeout(() => {
|
|
1447
|
+
this.watchdogHandle = undefined;
|
|
1448
|
+
console.warn(`[ModuleLoadingService] Loading work did not finish within ${ModuleLoadingService.watchdogTimeoutMs}ms, releasing the UI blocker.`);
|
|
1449
|
+
this.pending.set(0);
|
|
1450
|
+
}, ModuleLoadingService.watchdogTimeoutMs);
|
|
1451
|
+
}
|
|
1452
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModuleLoadingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1453
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModuleLoadingService, providedIn: 'root' }); }
|
|
1454
|
+
}
|
|
1455
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ModuleLoadingService, decorators: [{
|
|
1456
|
+
type: Injectable,
|
|
1457
|
+
args: [{ providedIn: 'root' }]
|
|
1458
|
+
}], ctorParameters: () => [] });
|
|
1459
|
+
|
|
1381
1460
|
var baseComponent$1 = {
|
|
1382
1461
|
content: "Content",
|
|
1383
1462
|
settings: "Settings",
|
|
1384
1463
|
security: "Security",
|
|
1385
1464
|
success: "Saved successfully"
|
|
1386
1465
|
};
|
|
1387
|
-
var en$
|
|
1466
|
+
var en$i = {
|
|
1388
1467
|
baseComponent: baseComponent$1
|
|
1389
1468
|
};
|
|
1390
1469
|
|
|
@@ -1394,7 +1473,7 @@ var baseComponent = {
|
|
|
1394
1473
|
security: "Безопасность",
|
|
1395
1474
|
success: "Сохранено"
|
|
1396
1475
|
};
|
|
1397
|
-
var ru$
|
|
1476
|
+
var ru$i = {
|
|
1398
1477
|
baseComponent: baseComponent
|
|
1399
1478
|
};
|
|
1400
1479
|
|
|
@@ -1471,6 +1550,7 @@ class BaseModuleComponent {
|
|
|
1471
1550
|
this.securitySettings = [];
|
|
1472
1551
|
this.destroyRef = inject(DestroyRef);
|
|
1473
1552
|
this.securityService = inject(SecurityService);
|
|
1553
|
+
this.moduleLoadingService = inject(ModuleLoadingService);
|
|
1474
1554
|
this.httpClient = inject(HttpClient);
|
|
1475
1555
|
/**
|
|
1476
1556
|
* Provide access to app settings
|
|
@@ -1529,7 +1609,7 @@ class BaseModuleComponent {
|
|
|
1529
1609
|
* @type {Subject<TLocalStoreSettings>}
|
|
1530
1610
|
*/
|
|
1531
1611
|
this.localSettingsUpdate = new Subject();
|
|
1532
|
-
this.baseTranslations = provideTranslations({ en: en$
|
|
1612
|
+
this.baseTranslations = provideTranslations({ en: en$i, ru: ru$i });
|
|
1533
1613
|
this.l10nService = inject(L10nService);
|
|
1534
1614
|
this.canRead = false;
|
|
1535
1615
|
this.canEdit = false;
|
|
@@ -1757,7 +1837,8 @@ class BaseModuleComponent {
|
|
|
1757
1837
|
});
|
|
1758
1838
|
}
|
|
1759
1839
|
async reloadModuleInstance() {
|
|
1760
|
-
|
|
1840
|
+
// Blocks the UI for the whole bootstrap: router navigation has already ended by the time it runs.
|
|
1841
|
+
this.moduleInstanceReloadPromise = this.moduleInstanceReloadPromise.then(() => this.moduleLoadingService.track((async () => {
|
|
1761
1842
|
// Rights first: the backend rejects settings and data requests without the read right.
|
|
1762
1843
|
await this.watchSecurityRights();
|
|
1763
1844
|
if (!this.canRead) {
|
|
@@ -1765,7 +1846,7 @@ class BaseModuleComponent {
|
|
|
1765
1846
|
}
|
|
1766
1847
|
await this.getSettings();
|
|
1767
1848
|
await this.onModuleInstanceChange();
|
|
1768
|
-
});
|
|
1849
|
+
})()));
|
|
1769
1850
|
await this.moduleInstanceReloadPromise;
|
|
1770
1851
|
}
|
|
1771
1852
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BaseModuleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
@@ -1829,7 +1910,7 @@ var securityComponent$1 = {
|
|
|
1829
1910
|
savedSecurity: "Security settings saved",
|
|
1830
1911
|
selectRoles: "Select roles"
|
|
1831
1912
|
};
|
|
1832
|
-
var en$
|
|
1913
|
+
var en$h = {
|
|
1833
1914
|
securityComponent: securityComponent$1
|
|
1834
1915
|
};
|
|
1835
1916
|
|
|
@@ -1839,13 +1920,13 @@ var securityComponent = {
|
|
|
1839
1920
|
savedSecurity: "Настройки сохранены",
|
|
1840
1921
|
selectRoles: "Выберите роли"
|
|
1841
1922
|
};
|
|
1842
|
-
var ru$
|
|
1923
|
+
var ru$h = {
|
|
1843
1924
|
securityComponent: securityComponent
|
|
1844
1925
|
};
|
|
1845
1926
|
|
|
1846
1927
|
class SecurityComponent {
|
|
1847
1928
|
constructor() {
|
|
1848
|
-
this.translations = provideTranslations({ en: en$
|
|
1929
|
+
this.translations = provideTranslations({ en: en$h, ru: ru$h });
|
|
1849
1930
|
this.msgService = inject(MsgService);
|
|
1850
1931
|
this.translateService = inject(TranslateService);
|
|
1851
1932
|
this.httpClient = inject(HttpClient);
|
|
@@ -2014,7 +2095,7 @@ const APP_THEME_PRESETS_MERGE_MODE = new InjectionToken('APP_THEME_PRESETS_MERGE
|
|
|
2014
2095
|
factory: () => 'mergeWithDefaults'
|
|
2015
2096
|
});
|
|
2016
2097
|
|
|
2017
|
-
var en$
|
|
2098
|
+
var en$g = {
|
|
2018
2099
|
"app-configurator": {
|
|
2019
2100
|
primary: "Primary",
|
|
2020
2101
|
surface: "Surface",
|
|
@@ -2025,7 +2106,7 @@ var en$e = {
|
|
|
2025
2106
|
}
|
|
2026
2107
|
};
|
|
2027
2108
|
|
|
2028
|
-
var ru$
|
|
2109
|
+
var ru$g = {
|
|
2029
2110
|
"app-configurator": {
|
|
2030
2111
|
primary: "Основной",
|
|
2031
2112
|
surface: "Фон",
|
|
@@ -2036,11 +2117,19 @@ var ru$e = {
|
|
|
2036
2117
|
}
|
|
2037
2118
|
};
|
|
2038
2119
|
|
|
2120
|
+
/**
|
|
2121
|
+
* Aura stays eager: it is the fallback preset and its primitive palette backs the color swatches
|
|
2122
|
+
* shown before any other preset is resolved. Lara and Nora are loaded on demand, which keeps roughly
|
|
2123
|
+
* 300 KB out of the initial bundle for applications that never switch away from the default theme.
|
|
2124
|
+
*/
|
|
2039
2125
|
const DEFAULT_THEME_PRESETS = [
|
|
2040
2126
|
{ id: 'Aura', label: 'Aura', preset: Aura },
|
|
2041
|
-
{ id: 'Lara', label: 'Lara', preset:
|
|
2042
|
-
{ id: 'Nora', label: 'Nora', preset:
|
|
2127
|
+
{ id: 'Lara', label: 'Lara', preset: () => import('@primeng/themes/lara').then((m) => m.default) },
|
|
2128
|
+
{ id: 'Nora', label: 'Nora', preset: () => import('@primeng/themes/nora').then((m) => m.default) }
|
|
2043
2129
|
];
|
|
2130
|
+
function isPresetLoader(preset) {
|
|
2131
|
+
return typeof preset === 'function';
|
|
2132
|
+
}
|
|
2044
2133
|
const PRIMARY_COLORS = [
|
|
2045
2134
|
'emerald',
|
|
2046
2135
|
'green',
|
|
@@ -2061,7 +2150,7 @@ const PRIMARY_COLORS = [
|
|
|
2061
2150
|
];
|
|
2062
2151
|
class AppConfiguratorComponent {
|
|
2063
2152
|
constructor() {
|
|
2064
|
-
this.translations = provideTranslations({ en: en$
|
|
2153
|
+
this.translations = provideTranslations({ en: en$g, ru: ru$g });
|
|
2065
2154
|
this.router = inject(Router);
|
|
2066
2155
|
this.config = inject(PrimeNG);
|
|
2067
2156
|
this.layoutService = inject(LayoutService);
|
|
@@ -2072,6 +2161,14 @@ class AppConfiguratorComponent {
|
|
|
2072
2161
|
this.themePresets = this.getThemePresets();
|
|
2073
2162
|
this.themePresetsMap = new Map(this.themePresets.map((theme) => [theme.id, theme]));
|
|
2074
2163
|
this.defaultThemePreset = this.themePresets[0] ?? DEFAULT_THEME_PRESETS[0];
|
|
2164
|
+
/**
|
|
2165
|
+
* Presets resolved so far, keyed by theme id. Seeded with the eagerly provided ones and filled in
|
|
2166
|
+
* as loaders resolve; it is a signal so the color swatches recompute once a preset arrives.
|
|
2167
|
+
*/
|
|
2168
|
+
this.resolvedPresets = signal(new Map(this.themePresets
|
|
2169
|
+
.filter((theme) => !isPresetLoader(theme.preset))
|
|
2170
|
+
.map((theme) => [theme.id, theme.preset])), ...(ngDevMode ? [{ debugName: "resolvedPresets" }] : []));
|
|
2171
|
+
this.pendingPresets = new Map();
|
|
2075
2172
|
this.fallbackPrimaryColors = (DEFAULT_THEME_PRESETS[0].preset.primitive ?? {});
|
|
2076
2173
|
this.presets = this.themePresets.map((theme) => ({ label: theme.label ?? theme.id, value: theme.id }));
|
|
2077
2174
|
this.showMenuModeButton = signal(!this.router.url.includes('auth'), ...(ngDevMode ? [{ debugName: "showMenuModeButton" }] : []));
|
|
@@ -2235,7 +2332,7 @@ class AppConfiguratorComponent {
|
|
|
2235
2332
|
ngOnInit() {
|
|
2236
2333
|
if (isPlatformBrowser(this.platformId)) {
|
|
2237
2334
|
const presetId = this.ensureValidThemeId(this.layoutService.layoutConfig().preset);
|
|
2238
|
-
this.onPresetChange(presetId);
|
|
2335
|
+
void this.onPresetChange(presetId);
|
|
2239
2336
|
}
|
|
2240
2337
|
}
|
|
2241
2338
|
getPresetExt() {
|
|
@@ -2385,13 +2482,46 @@ class AppConfiguratorComponent {
|
|
|
2385
2482
|
getThemeById(themeId) {
|
|
2386
2483
|
return this.themePresetsMap.get(themeId ?? '') ?? this.defaultThemePreset;
|
|
2387
2484
|
}
|
|
2485
|
+
/**
|
|
2486
|
+
* The preset of a theme, or `undefined` while its loader is still in flight.
|
|
2487
|
+
*/
|
|
2488
|
+
getResolvedPreset(theme) {
|
|
2489
|
+
return isPresetLoader(theme.preset) ? this.resolvedPresets().get(theme.id) : theme.preset;
|
|
2490
|
+
}
|
|
2491
|
+
/**
|
|
2492
|
+
* Resolves a theme preset, running its loader at most once and caching the result.
|
|
2493
|
+
* A failed load falls back to the default preset so the configurator stays usable.
|
|
2494
|
+
*/
|
|
2495
|
+
async loadPreset(theme) {
|
|
2496
|
+
const resolved = this.getResolvedPreset(theme);
|
|
2497
|
+
if (resolved) {
|
|
2498
|
+
return resolved;
|
|
2499
|
+
}
|
|
2500
|
+
const pending = this.pendingPresets.get(theme.id);
|
|
2501
|
+
if (pending) {
|
|
2502
|
+
return pending;
|
|
2503
|
+
}
|
|
2504
|
+
const load = theme.preset()
|
|
2505
|
+
.then((preset) => {
|
|
2506
|
+
this.resolvedPresets.update((presets) => new Map(presets).set(theme.id, preset));
|
|
2507
|
+
return preset;
|
|
2508
|
+
})
|
|
2509
|
+
.catch((error) => {
|
|
2510
|
+
console.error(`[AppConfigurator] Failed to load theme preset "${theme.id}".`, error);
|
|
2511
|
+
return this.getResolvedPreset(this.defaultThemePreset) ?? Aura;
|
|
2512
|
+
})
|
|
2513
|
+
.finally(() => this.pendingPresets.delete(theme.id));
|
|
2514
|
+
this.pendingPresets.set(theme.id, load);
|
|
2515
|
+
return load;
|
|
2516
|
+
}
|
|
2388
2517
|
getPrimaryColorOptions(activeThemePreset) {
|
|
2389
2518
|
if (activeThemePreset.primaryColors) {
|
|
2390
2519
|
return Object.entries(activeThemePreset.primaryColors)
|
|
2391
2520
|
.filter((entry) => Boolean(entry[1]))
|
|
2392
2521
|
.map(([name, palette]) => ({ name, palette }));
|
|
2393
2522
|
}
|
|
2394
|
-
const presetPalette = activeThemePreset
|
|
2523
|
+
const presetPalette = this.getResolvedPreset(activeThemePreset)
|
|
2524
|
+
?.primitive ?? {};
|
|
2395
2525
|
const palettes = [{ name: 'noir', palette: {} }];
|
|
2396
2526
|
PRIMARY_COLORS.forEach((color) => {
|
|
2397
2527
|
palettes.push({
|
|
@@ -2442,9 +2572,10 @@ class AppConfiguratorComponent {
|
|
|
2442
2572
|
updateSurfacePalette(color.palette);
|
|
2443
2573
|
}
|
|
2444
2574
|
}
|
|
2445
|
-
onPresetChange(event) {
|
|
2575
|
+
async onPresetChange(event) {
|
|
2446
2576
|
const nextThemeId = this.ensureValidThemeId(event);
|
|
2447
2577
|
const nextTheme = this.getThemeById(nextThemeId);
|
|
2578
|
+
const preset = await this.loadPreset(nextTheme);
|
|
2448
2579
|
const primaryColors = this.getPrimaryColorOptions(nextTheme);
|
|
2449
2580
|
const surfaceColors = this.getSurfaceColorOptions(nextTheme);
|
|
2450
2581
|
this.layoutService.layoutConfig.update((state) => ({
|
|
@@ -2457,7 +2588,6 @@ class AppConfiguratorComponent {
|
|
|
2457
2588
|
? (surfaceColors[0]?.name ?? state.surface)
|
|
2458
2589
|
: state.surface
|
|
2459
2590
|
}));
|
|
2460
|
-
const preset = nextTheme.preset;
|
|
2461
2591
|
const surfacePalette = this.surfaceColors().find((s) => s.name === this.selectedSurfaceColor())?.palette;
|
|
2462
2592
|
$t().preset(preset).preset(this.getPresetExt()).surfacePalette(surfacePalette).use({ useDefaultOptions: true });
|
|
2463
2593
|
}
|
|
@@ -3028,7 +3158,7 @@ var userNotifications$1 = {
|
|
|
3028
3158
|
markAsRead: "Read",
|
|
3029
3159
|
markedAsRead: "Notification marked as read"
|
|
3030
3160
|
};
|
|
3031
|
-
var en$
|
|
3161
|
+
var en$f = {
|
|
3032
3162
|
userNotifications: userNotifications$1
|
|
3033
3163
|
};
|
|
3034
3164
|
|
|
@@ -3039,13 +3169,13 @@ var userNotifications = {
|
|
|
3039
3169
|
markAsRead: "Прочитано",
|
|
3040
3170
|
markedAsRead: "Оповещение отмечено прочитанным"
|
|
3041
3171
|
};
|
|
3042
|
-
var ru$
|
|
3172
|
+
var ru$f = {
|
|
3043
3173
|
userNotifications: userNotifications
|
|
3044
3174
|
};
|
|
3045
3175
|
|
|
3046
3176
|
class UserNotificationsComponent {
|
|
3047
3177
|
constructor() {
|
|
3048
|
-
this.translations = provideTranslations({ en: en$
|
|
3178
|
+
this.translations = provideTranslations({ en: en$f, ru: ru$f });
|
|
3049
3179
|
this.notifications = [];
|
|
3050
3180
|
this.totalCount = 0;
|
|
3051
3181
|
this.skip = 0;
|
|
@@ -3474,7 +3604,7 @@ var topbar$1 = {
|
|
|
3474
3604
|
profile: "Profile",
|
|
3475
3605
|
applications: "Applications"
|
|
3476
3606
|
};
|
|
3477
|
-
var en$
|
|
3607
|
+
var en$e = {
|
|
3478
3608
|
topbar: topbar$1
|
|
3479
3609
|
};
|
|
3480
3610
|
|
|
@@ -3487,13 +3617,13 @@ var topbar = {
|
|
|
3487
3617
|
profile: "Профиль",
|
|
3488
3618
|
applications: "Приложения"
|
|
3489
3619
|
};
|
|
3490
|
-
var ru$
|
|
3620
|
+
var ru$e = {
|
|
3491
3621
|
topbar: topbar
|
|
3492
3622
|
};
|
|
3493
3623
|
|
|
3494
3624
|
class AppTopbar {
|
|
3495
3625
|
constructor() {
|
|
3496
|
-
this.translations = provideTranslations({ en: en$
|
|
3626
|
+
this.translations = provideTranslations({ en: en$e, ru: ru$e });
|
|
3497
3627
|
this.securityService = inject(SecurityService);
|
|
3498
3628
|
this.topBarService = inject(TopBarService);
|
|
3499
3629
|
this.userService = inject(UserService);
|
|
@@ -3822,6 +3952,18 @@ class MenuApi extends HttpClient {
|
|
|
3822
3952
|
format: "json",
|
|
3823
3953
|
...params,
|
|
3824
3954
|
});
|
|
3955
|
+
this.setStartModule = ({ id, ...query }, params = {}) => this.request({
|
|
3956
|
+
path: `/api/menu/set-start-module/${id}`,
|
|
3957
|
+
method: "POST",
|
|
3958
|
+
secure: true,
|
|
3959
|
+
...params,
|
|
3960
|
+
});
|
|
3961
|
+
this.deleteStartModule = (params = {}) => this.request({
|
|
3962
|
+
path: `/api/menu/delete-start-module`,
|
|
3963
|
+
method: "DELETE",
|
|
3964
|
+
secure: true,
|
|
3965
|
+
...params,
|
|
3966
|
+
});
|
|
3825
3967
|
this.getModuleInstanceRights = (query, params = {}) => this.request({
|
|
3826
3968
|
path: `/api/menu/get-module-instance-rights`,
|
|
3827
3969
|
method: "GET",
|
|
@@ -3941,6 +4083,106 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3941
4083
|
type: Injectable
|
|
3942
4084
|
}] });
|
|
3943
4085
|
|
|
4086
|
+
/**
|
|
4087
|
+
* Resolves the module instance the current user lands on when no explicit route is requested.
|
|
4088
|
+
*
|
|
4089
|
+
* The menu returned by the backend is already filtered by the rights of the current user, so the
|
|
4090
|
+
* first navigable leaf of that menu is always a module the user may open. When the user picked a
|
|
4091
|
+
* start module explicitly it comes back marked with `isStart`, and a module that was deleted or
|
|
4092
|
+
* whose rights were revoked simply disappears from the menu, which falls back to the first leaf.
|
|
4093
|
+
*
|
|
4094
|
+
* The resolved url is cached per user and dropped whenever the authenticated user changes or the
|
|
4095
|
+
* start module is reassigned.
|
|
4096
|
+
*/
|
|
4097
|
+
class StartPageService {
|
|
4098
|
+
constructor() {
|
|
4099
|
+
this.menuApi = inject(MenuApi);
|
|
4100
|
+
this.router = inject(Router);
|
|
4101
|
+
this.securityService = inject(SecurityService);
|
|
4102
|
+
this.request = undefined;
|
|
4103
|
+
this.cachedIdentity = undefined;
|
|
4104
|
+
this.securityService.payload.subscribe((payload) => {
|
|
4105
|
+
// The menu depends on both the user and the roles of the current session.
|
|
4106
|
+
const roles = payload?.realm_access?.roles ?? [];
|
|
4107
|
+
const identity = `${payload?.preferred_username ?? ''}|${[...roles].sort().join(',')}`;
|
|
4108
|
+
if (identity !== this.cachedIdentity) {
|
|
4109
|
+
this.cachedIdentity = identity;
|
|
4110
|
+
this.clearCache();
|
|
4111
|
+
}
|
|
4112
|
+
});
|
|
4113
|
+
}
|
|
4114
|
+
/**
|
|
4115
|
+
* Gets the url of the start module instance.
|
|
4116
|
+
*
|
|
4117
|
+
* @returns The url tree to navigate to, or `null` when the user has no module available.
|
|
4118
|
+
*/
|
|
4119
|
+
resolveStartUrl() {
|
|
4120
|
+
if (this.request) {
|
|
4121
|
+
return this.request;
|
|
4122
|
+
}
|
|
4123
|
+
this.request = this.loadStartUrl().catch((error) => {
|
|
4124
|
+
this.request = undefined;
|
|
4125
|
+
throw error;
|
|
4126
|
+
});
|
|
4127
|
+
return this.request;
|
|
4128
|
+
}
|
|
4129
|
+
/**
|
|
4130
|
+
* Makes the module instance the start page of the current user.
|
|
4131
|
+
*
|
|
4132
|
+
* @param moduleInstanceId Module instance to open by default.
|
|
4133
|
+
*/
|
|
4134
|
+
async setStartModule(moduleInstanceId) {
|
|
4135
|
+
await this.menuApi.setStartModule({ id: moduleInstanceId });
|
|
4136
|
+
this.clearCache();
|
|
4137
|
+
}
|
|
4138
|
+
/**
|
|
4139
|
+
* Clears the start page of the current user, falling back to the first available module.
|
|
4140
|
+
*/
|
|
4141
|
+
async clearStartModule() {
|
|
4142
|
+
await this.menuApi.deleteStartModule();
|
|
4143
|
+
this.clearCache();
|
|
4144
|
+
}
|
|
4145
|
+
/**
|
|
4146
|
+
* Drops the cached url, for example after the menu was changed.
|
|
4147
|
+
*/
|
|
4148
|
+
clearCache() {
|
|
4149
|
+
this.request = undefined;
|
|
4150
|
+
}
|
|
4151
|
+
async loadStartUrl() {
|
|
4152
|
+
const menu = (await this.menuApi.get()) ?? [];
|
|
4153
|
+
const item = this.findStartItem(menu);
|
|
4154
|
+
return item ? this.router.createUrlTree(item.routerLink) : null;
|
|
4155
|
+
}
|
|
4156
|
+
findStartItem(menu) {
|
|
4157
|
+
const leaves = this.collectNavigableLeaves(menu);
|
|
4158
|
+
return leaves.find((item) => item.isStart) ?? leaves[0] ?? null;
|
|
4159
|
+
}
|
|
4160
|
+
collectNavigableLeaves(items) {
|
|
4161
|
+
const result = [];
|
|
4162
|
+
for (const item of [...items].sort((a, b) => (a.order ?? 0) - (b.order ?? 0))) {
|
|
4163
|
+
if (item.separator) {
|
|
4164
|
+
continue;
|
|
4165
|
+
}
|
|
4166
|
+
if (item.items?.length) {
|
|
4167
|
+
// A folder is never a landing page itself, its children are.
|
|
4168
|
+
result.push(...this.collectNavigableLeaves(item.items));
|
|
4169
|
+
continue;
|
|
4170
|
+
}
|
|
4171
|
+
// A module without a real route would resolve back to the empty path and loop.
|
|
4172
|
+
if (item.routerLink?.some((segment) => !!segment && segment !== '/')) {
|
|
4173
|
+
result.push(item);
|
|
4174
|
+
}
|
|
4175
|
+
}
|
|
4176
|
+
return result;
|
|
4177
|
+
}
|
|
4178
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: StartPageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
4179
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: StartPageService, providedIn: 'root' }); }
|
|
4180
|
+
}
|
|
4181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: StartPageService, decorators: [{
|
|
4182
|
+
type: Injectable,
|
|
4183
|
+
args: [{ providedIn: 'root' }]
|
|
4184
|
+
}], ctorParameters: () => [] });
|
|
4185
|
+
|
|
3944
4186
|
class MenuItemComponent {
|
|
3945
4187
|
constructor(cd, router, menuService) {
|
|
3946
4188
|
this.cd = cd;
|
|
@@ -3952,6 +4194,7 @@ class MenuItemComponent {
|
|
|
3952
4194
|
this.msgService = inject(MsgService);
|
|
3953
4195
|
this.menuDataService = inject(MenuApi);
|
|
3954
4196
|
this.securityService = inject(SecurityService);
|
|
4197
|
+
this.startPageService = inject(StartPageService);
|
|
3955
4198
|
this.active = false;
|
|
3956
4199
|
this.subscriptions = [];
|
|
3957
4200
|
this.localization = {};
|
|
@@ -4025,13 +4268,25 @@ class MenuItemComponent {
|
|
|
4025
4268
|
this.menuItemCreateDialogComponent.showDialog();
|
|
4026
4269
|
}
|
|
4027
4270
|
onContextMenu($event, item) {
|
|
4271
|
+
const startModuleItems = this.getStartModuleItems(item);
|
|
4272
|
+
// Choosing a start page is available to every user, the rest of the menu is administrative.
|
|
4028
4273
|
if (!this.securityService.isAdmin()) {
|
|
4274
|
+
if (startModuleItems.length === 0) {
|
|
4275
|
+
return;
|
|
4276
|
+
}
|
|
4277
|
+
$event.stopPropagation();
|
|
4278
|
+
$event.preventDefault();
|
|
4279
|
+
this.menuService.contextMenuItem = item;
|
|
4280
|
+
this.contextMenu.model = startModuleItems;
|
|
4281
|
+
this.contextMenu.show($event);
|
|
4029
4282
|
return;
|
|
4030
4283
|
}
|
|
4031
4284
|
$event.stopPropagation();
|
|
4032
4285
|
$event.preventDefault();
|
|
4033
4286
|
this.menuService.contextMenuItem = item;
|
|
4034
4287
|
this.contextMenu.model = [
|
|
4288
|
+
...startModuleItems,
|
|
4289
|
+
{ separator: true, visible: startModuleItems.length > 0 },
|
|
4035
4290
|
{
|
|
4036
4291
|
label: this.localization.new,
|
|
4037
4292
|
icon: PrimeIcons.PLUS,
|
|
@@ -4072,6 +4327,39 @@ class MenuItemComponent {
|
|
|
4072
4327
|
];
|
|
4073
4328
|
this.contextMenu.show($event);
|
|
4074
4329
|
}
|
|
4330
|
+
/**
|
|
4331
|
+
* Builds the start page entries of the context menu. Only a navigable leaf can be a start page.
|
|
4332
|
+
*/
|
|
4333
|
+
getStartModuleItems(item) {
|
|
4334
|
+
if (!item?.routerLink || item.items?.length) {
|
|
4335
|
+
return [];
|
|
4336
|
+
}
|
|
4337
|
+
return item.isStart
|
|
4338
|
+
? [
|
|
4339
|
+
{
|
|
4340
|
+
label: this.localization.unsetStartModule,
|
|
4341
|
+
icon: PrimeIcons.STAR,
|
|
4342
|
+
command: () => this.clearStartModule()
|
|
4343
|
+
}
|
|
4344
|
+
]
|
|
4345
|
+
: [
|
|
4346
|
+
{
|
|
4347
|
+
label: this.localization.setStartModule,
|
|
4348
|
+
icon: PrimeIcons.STAR_FILL,
|
|
4349
|
+
command: () => this.setStartModule(item)
|
|
4350
|
+
}
|
|
4351
|
+
];
|
|
4352
|
+
}
|
|
4353
|
+
async setStartModule(item) {
|
|
4354
|
+
await this.startPageService.setStartModule(item.moduleInstanceId);
|
|
4355
|
+
this.msgService.success(this.localization.setStartModuleSuccessMessage);
|
|
4356
|
+
await this.menuService.loadMenu();
|
|
4357
|
+
}
|
|
4358
|
+
async clearStartModule() {
|
|
4359
|
+
await this.startPageService.clearStartModule();
|
|
4360
|
+
this.msgService.success(this.localization.unsetStartModuleSuccessMessage);
|
|
4361
|
+
await this.menuService.loadMenu();
|
|
4362
|
+
}
|
|
4075
4363
|
deleteItem(event) {
|
|
4076
4364
|
this.confirmationService.confirm({
|
|
4077
4365
|
header: this.localization.deleteItemConfirmHeader,
|
|
@@ -4431,9 +4719,9 @@ class MenuItemCreateDialogComponent {
|
|
|
4431
4719
|
<input
|
|
4432
4720
|
autocomplete="off"
|
|
4433
4721
|
class="flex-auto"
|
|
4722
|
+
disabled
|
|
4434
4723
|
id="oip-menu-item-create-dialog-parent-input"
|
|
4435
4724
|
pInputText
|
|
4436
|
-
readonly
|
|
4437
4725
|
[ngModel]="menuService.contextMenuItem?.label" />
|
|
4438
4726
|
</div>
|
|
4439
4727
|
}
|
|
@@ -4528,9 +4816,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
4528
4816
|
<input
|
|
4529
4817
|
autocomplete="off"
|
|
4530
4818
|
class="flex-auto"
|
|
4819
|
+
disabled
|
|
4531
4820
|
id="oip-menu-item-create-dialog-parent-input"
|
|
4532
4821
|
pInputText
|
|
4533
|
-
readonly
|
|
4534
4822
|
[ngModel]="menuService.contextMenuItem?.label" />
|
|
4535
4823
|
</div>
|
|
4536
4824
|
}
|
|
@@ -4617,6 +4905,7 @@ class MenuItemEditDialogComponent {
|
|
|
4617
4905
|
this.msgService = inject(MsgService);
|
|
4618
4906
|
this.visibleChange = new EventEmitter();
|
|
4619
4907
|
this.roles = [];
|
|
4908
|
+
this.moduleName = '';
|
|
4620
4909
|
this.iconOptions = Object.values(PrimeIcons)
|
|
4621
4910
|
.filter((icon) => typeof icon === 'string')
|
|
4622
4911
|
.map((icon) => ({
|
|
@@ -4668,7 +4957,9 @@ class MenuItemEditDialogComponent {
|
|
|
4668
4957
|
icon: this.menuService.contextMenuItem?.icon,
|
|
4669
4958
|
viewRoles: this.menuService.contextMenuItem?.securities
|
|
4670
4959
|
};
|
|
4671
|
-
|
|
4960
|
+
const [roles, modules] = await Promise.all([this.securityApi.getRealmRoles(), this.menuService.getModules()]);
|
|
4961
|
+
this.roles = roles;
|
|
4962
|
+
this.moduleName = modules.find((module) => module.key === this.item.moduleId)?.value ?? '';
|
|
4672
4963
|
this.visible = true;
|
|
4673
4964
|
this.visibleChange.emit(this.visible);
|
|
4674
4965
|
}
|
|
@@ -4692,6 +4983,19 @@ class MenuItemEditDialogComponent {
|
|
|
4692
4983
|
[(ngModel)]="item.label" />
|
|
4693
4984
|
</div>
|
|
4694
4985
|
|
|
4986
|
+
<div class="flex items-center gap-4 mb-4">
|
|
4987
|
+
<label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-module">
|
|
4988
|
+
{{ 'menuItemEditDialogComponent.module' | translate }}
|
|
4989
|
+
</label>
|
|
4990
|
+
<input
|
|
4991
|
+
autocomplete="off"
|
|
4992
|
+
class="flex-auto"
|
|
4993
|
+
disabled
|
|
4994
|
+
id="oip-menu-item-edit-dialog-module"
|
|
4995
|
+
pInputText
|
|
4996
|
+
[ngModel]="moduleName" />
|
|
4997
|
+
</div>
|
|
4998
|
+
|
|
4695
4999
|
<div class="flex items-center gap-4 mb-4">
|
|
4696
5000
|
<label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-icon">
|
|
4697
5001
|
{{ 'menuItemEditDialogComponent.icon' | translate }}
|
|
@@ -4778,6 +5082,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
4778
5082
|
[(ngModel)]="item.label" />
|
|
4779
5083
|
</div>
|
|
4780
5084
|
|
|
5085
|
+
<div class="flex items-center gap-4 mb-4">
|
|
5086
|
+
<label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-module">
|
|
5087
|
+
{{ 'menuItemEditDialogComponent.module' | translate }}
|
|
5088
|
+
</label>
|
|
5089
|
+
<input
|
|
5090
|
+
autocomplete="off"
|
|
5091
|
+
class="flex-auto"
|
|
5092
|
+
disabled
|
|
5093
|
+
id="oip-menu-item-edit-dialog-module"
|
|
5094
|
+
pInputText
|
|
5095
|
+
[ngModel]="moduleName" />
|
|
5096
|
+
</div>
|
|
5097
|
+
|
|
4781
5098
|
<div class="flex items-center gap-4 mb-4">
|
|
4782
5099
|
<label class="font-semibold w-1/3" for="oip-menu-item-edit-dialog-icon">
|
|
4783
5100
|
{{ 'menuItemEditDialogComponent.icon' | translate }}
|
|
@@ -4859,7 +5176,11 @@ var menuItemComponent$1 = {
|
|
|
4859
5176
|
deleteItemConfirmRejectButtonPropsLabel: "Cancel",
|
|
4860
5177
|
deleteItemConfirmAcceptButtonPropsLabel: "Delete",
|
|
4861
5178
|
moveUp: "Move up",
|
|
4862
|
-
moveDown: "Move down"
|
|
5179
|
+
moveDown: "Move down",
|
|
5180
|
+
setStartModule: "Set as start page",
|
|
5181
|
+
unsetStartModule: "Clear start page",
|
|
5182
|
+
setStartModuleSuccessMessage: "Start page updated",
|
|
5183
|
+
unsetStartModuleSuccessMessage: "Start page cleared"
|
|
4863
5184
|
};
|
|
4864
5185
|
var menuItemEditDialogComponent$1 = {
|
|
4865
5186
|
header: "Edit menu item",
|
|
@@ -4883,7 +5204,7 @@ var menuItemCreateDialogComponent$1 = {
|
|
|
4883
5204
|
cancel: "Cancel",
|
|
4884
5205
|
save: "Save"
|
|
4885
5206
|
};
|
|
4886
|
-
var en$
|
|
5207
|
+
var en$d = {
|
|
4887
5208
|
menuComponent: menuComponent$1,
|
|
4888
5209
|
menuItemComponent: menuItemComponent$1,
|
|
4889
5210
|
menuItemEditDialogComponent: menuItemEditDialogComponent$1,
|
|
@@ -4904,7 +5225,11 @@ var menuItemComponent = {
|
|
|
4904
5225
|
deleteItemConfirmRejectButtonPropsLabel: "Отмена",
|
|
4905
5226
|
deleteItemConfirmAcceptButtonPropsLabel: "Удалить",
|
|
4906
5227
|
moveUp: "Вверх",
|
|
4907
|
-
moveDown: "Вниз"
|
|
5228
|
+
moveDown: "Вниз",
|
|
5229
|
+
setStartModule: "Сделать стартовой",
|
|
5230
|
+
unsetStartModule: "Убрать стартовую",
|
|
5231
|
+
setStartModuleSuccessMessage: "Стартовая страница обновлена",
|
|
5232
|
+
unsetStartModuleSuccessMessage: "Стартовая страница сброшена"
|
|
4908
5233
|
};
|
|
4909
5234
|
var menuItemEditDialogComponent = {
|
|
4910
5235
|
header: "Редактировать элемент меню",
|
|
@@ -4928,7 +5253,7 @@ var menuItemCreateDialogComponent = {
|
|
|
4928
5253
|
cancel: "Отмена",
|
|
4929
5254
|
save: "Сохранить"
|
|
4930
5255
|
};
|
|
4931
|
-
var ru$
|
|
5256
|
+
var ru$d = {
|
|
4932
5257
|
menuComponent: menuComponent,
|
|
4933
5258
|
menuItemComponent: menuItemComponent,
|
|
4934
5259
|
menuItemEditDialogComponent: menuItemEditDialogComponent,
|
|
@@ -4939,7 +5264,7 @@ class MenuComponent {
|
|
|
4939
5264
|
constructor() {
|
|
4940
5265
|
// Registers the whole menu/l10n/menu.*.json bundle, which also covers
|
|
4941
5266
|
// menuItemComponent, menuItemEditDialogComponent and menuItemCreateDialogComponent.
|
|
4942
|
-
this.translations = provideTranslations({ en: en$
|
|
5267
|
+
this.translations = provideTranslations({ en: en$d, ru: ru$d });
|
|
4943
5268
|
this.menuService = inject(MenuService);
|
|
4944
5269
|
this.securityService = inject(SecurityService);
|
|
4945
5270
|
this.translateService = inject(TranslateService);
|
|
@@ -4954,6 +5279,8 @@ class MenuComponent {
|
|
|
4954
5279
|
if (!this.securityService.isAdmin()) {
|
|
4955
5280
|
return;
|
|
4956
5281
|
}
|
|
5282
|
+
$event.preventDefault();
|
|
5283
|
+
$event.stopPropagation();
|
|
4957
5284
|
this.menuService.contextMenuItem = null;
|
|
4958
5285
|
this.contextMenu.model = [
|
|
4959
5286
|
{
|
|
@@ -4962,6 +5289,7 @@ class MenuComponent {
|
|
|
4962
5289
|
command: (event) => this.newClick(event)
|
|
4963
5290
|
}
|
|
4964
5291
|
];
|
|
5292
|
+
this.contextMenu.show($event);
|
|
4965
5293
|
}
|
|
4966
5294
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4967
5295
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MenuComponent, isStandalone: true, selector: "app-menu", providers: [MenuApi], viewQueries: [{ propertyName: "menuItemCreateDialogComponent", first: true, predicate: MenuItemCreateDialogComponent, descendants: true }, { propertyName: "menuItemEditDialogComponent", first: true, predicate: MenuItemEditDialogComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ContextMenu, descendants: true }], ngImport: i0, template: ` <div #empty class="layout-sidebar" (contextmenu)="onContextMenu($event)">
|
|
@@ -4984,8 +5312,9 @@ class MenuComponent {
|
|
|
4984
5312
|
}
|
|
4985
5313
|
</ul>
|
|
4986
5314
|
</div>
|
|
5315
|
+
<!-- Always rendered: choosing a start page is available to every user, not only to admins. -->
|
|
5316
|
+
<p-contextMenu />
|
|
4987
5317
|
@if (securityService.isAdmin()) {
|
|
4988
|
-
<p-contextMenu [target]="empty" />
|
|
4989
5318
|
<menu-item-create-dialog />
|
|
4990
5319
|
<menu-item-edit-dialog />
|
|
4991
5320
|
}`, isInline: true, dependencies: [{ kind: "component", type: MenuItemComponent, selector: "[app-menuitem]", inputs: ["item", "index", "root", "parentKey", "menuItemCreateDialogComponent", "menuItemEditDialogComponent", "contextMenu"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i1$6.ContextMenu, selector: "p-contextMenu, p-contextmenu, p-context-menu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "autoZIndex", "baseZIndex", "id", "breakpoint", "ariaLabel", "ariaLabelledBy", "pressDelay", "appendTo"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "component", type: MenuItemCreateDialogComponent, selector: "menu-item-create-dialog", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: MenuItemEditDialogComponent, selector: "menu-item-edit-dialog", inputs: ["visible"], outputs: ["visibleChange"] }] }); }
|
|
@@ -5026,8 +5355,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5026
5355
|
}
|
|
5027
5356
|
</ul>
|
|
5028
5357
|
</div>
|
|
5358
|
+
<!-- Always rendered: choosing a start page is available to every user, not only to admins. -->
|
|
5359
|
+
<p-contextMenu />
|
|
5029
5360
|
@if (securityService.isAdmin()) {
|
|
5030
|
-
<p-contextMenu [target]="empty" />
|
|
5031
5361
|
<menu-item-create-dialog />
|
|
5032
5362
|
<menu-item-edit-dialog />
|
|
5033
5363
|
}`
|
|
@@ -5058,6 +5388,147 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5058
5388
|
}]
|
|
5059
5389
|
}], ctorParameters: () => [] });
|
|
5060
5390
|
|
|
5391
|
+
var blockLoader$1 = {
|
|
5392
|
+
loading: "Loading..."
|
|
5393
|
+
};
|
|
5394
|
+
var en$c = {
|
|
5395
|
+
blockLoader: blockLoader$1
|
|
5396
|
+
};
|
|
5397
|
+
|
|
5398
|
+
var blockLoader = {
|
|
5399
|
+
loading: "Загрузка..."
|
|
5400
|
+
};
|
|
5401
|
+
var ru$c = {
|
|
5402
|
+
blockLoader: blockLoader
|
|
5403
|
+
};
|
|
5404
|
+
|
|
5405
|
+
/**
|
|
5406
|
+
* Full screen blocker shown while the application switches between modules.
|
|
5407
|
+
*
|
|
5408
|
+
* Render it as a sibling of `.layout-wrapper`, not inside it: while the blocker is visible the
|
|
5409
|
+
* wrapper is marked `inert`, which would also disable an overlay nested in it.
|
|
5410
|
+
*
|
|
5411
|
+
* The blocker appears only when a transition outlasts {@link showDelayMs} and then stays for at
|
|
5412
|
+
* least {@link minVisibleMs}, so quick navigation does not flash a spinner.
|
|
5413
|
+
*/
|
|
5414
|
+
class BlockLoaderComponent {
|
|
5415
|
+
static { this.showDelayMs = 150; }
|
|
5416
|
+
static { this.minVisibleMs = 300; }
|
|
5417
|
+
constructor() {
|
|
5418
|
+
this.translations = provideTranslations({ en: en$c, ru: ru$c });
|
|
5419
|
+
this.moduleLoadingService = inject(ModuleLoadingService);
|
|
5420
|
+
this.shownAt = 0;
|
|
5421
|
+
this.visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
|
|
5422
|
+
effect(() => {
|
|
5423
|
+
const loading = this.moduleLoadingService.loading();
|
|
5424
|
+
untracked(() => (loading ? this.scheduleShow() : this.scheduleHide()));
|
|
5425
|
+
});
|
|
5426
|
+
effect(() => {
|
|
5427
|
+
this.blockInteraction(this.visible());
|
|
5428
|
+
});
|
|
5429
|
+
}
|
|
5430
|
+
ngOnDestroy() {
|
|
5431
|
+
this.clearTimers();
|
|
5432
|
+
this.blockInteraction(false);
|
|
5433
|
+
}
|
|
5434
|
+
scheduleShow() {
|
|
5435
|
+
this.clearTimer('hide');
|
|
5436
|
+
if (this.visible() || this.showHandle != null) {
|
|
5437
|
+
return;
|
|
5438
|
+
}
|
|
5439
|
+
this.showHandle = setTimeout(() => {
|
|
5440
|
+
this.showHandle = undefined;
|
|
5441
|
+
this.shownAt = Date.now();
|
|
5442
|
+
this.visible.set(true);
|
|
5443
|
+
}, BlockLoaderComponent.showDelayMs);
|
|
5444
|
+
}
|
|
5445
|
+
scheduleHide() {
|
|
5446
|
+
this.clearTimer('show');
|
|
5447
|
+
if (!this.visible() || this.hideHandle != null) {
|
|
5448
|
+
return;
|
|
5449
|
+
}
|
|
5450
|
+
const remaining = BlockLoaderComponent.minVisibleMs - (Date.now() - this.shownAt);
|
|
5451
|
+
if (remaining <= 0) {
|
|
5452
|
+
this.visible.set(false);
|
|
5453
|
+
return;
|
|
5454
|
+
}
|
|
5455
|
+
this.hideHandle = setTimeout(() => {
|
|
5456
|
+
this.hideHandle = undefined;
|
|
5457
|
+
this.visible.set(false);
|
|
5458
|
+
}, remaining);
|
|
5459
|
+
}
|
|
5460
|
+
clearTimer(timer) {
|
|
5461
|
+
const handle = timer === 'show' ? this.showHandle : this.hideHandle;
|
|
5462
|
+
if (handle == null) {
|
|
5463
|
+
return;
|
|
5464
|
+
}
|
|
5465
|
+
clearTimeout(handle);
|
|
5466
|
+
if (timer === 'show') {
|
|
5467
|
+
this.showHandle = undefined;
|
|
5468
|
+
}
|
|
5469
|
+
else {
|
|
5470
|
+
this.hideHandle = undefined;
|
|
5471
|
+
}
|
|
5472
|
+
}
|
|
5473
|
+
clearTimers() {
|
|
5474
|
+
this.clearTimer('show');
|
|
5475
|
+
this.clearTimer('hide');
|
|
5476
|
+
}
|
|
5477
|
+
/**
|
|
5478
|
+
* Takes the application out of the interaction and accessibility trees while the blocker is up,
|
|
5479
|
+
* so pointer, keyboard and screen reader input cannot reach a module that is still loading.
|
|
5480
|
+
*/
|
|
5481
|
+
blockInteraction(blocked) {
|
|
5482
|
+
const wrapper = document.querySelector('.layout-wrapper');
|
|
5483
|
+
if (blocked) {
|
|
5484
|
+
wrapper?.setAttribute('inert', '');
|
|
5485
|
+
// Not the layout's `blocked-scroll` class: the layout drops it whenever it closes the menu.
|
|
5486
|
+
document.body.style.setProperty('overflow', 'hidden');
|
|
5487
|
+
}
|
|
5488
|
+
else {
|
|
5489
|
+
wrapper?.removeAttribute('inert');
|
|
5490
|
+
document.body.style.removeProperty('overflow');
|
|
5491
|
+
}
|
|
5492
|
+
}
|
|
5493
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BlockLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5494
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BlockLoaderComponent, isStandalone: true, selector: "block-loader", ngImport: i0, template: `
|
|
5495
|
+
@if (visible()) {
|
|
5496
|
+
<div
|
|
5497
|
+
class="animate-fadein fixed inset-0 z-[1200] flex flex-col items-center justify-center gap-4 bg-surface-0/70 dark:bg-surface-900/70"
|
|
5498
|
+
role="status"
|
|
5499
|
+
aria-live="polite"
|
|
5500
|
+
aria-busy="true"
|
|
5501
|
+
(pointerdown)="$event.preventDefault()"
|
|
5502
|
+
(contextmenu)="$event.preventDefault()">
|
|
5503
|
+
<p-progress-spinner [style]="{ width: '3rem', height: '3rem' }" animationDuration=".8s" strokeWidth="4" />
|
|
5504
|
+
<span class="text-color font-medium">{{ 'blockLoader.loading' | translate }}</span>
|
|
5505
|
+
</div>
|
|
5506
|
+
}
|
|
5507
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
|
|
5508
|
+
}
|
|
5509
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BlockLoaderComponent, decorators: [{
|
|
5510
|
+
type: Component,
|
|
5511
|
+
args: [{
|
|
5512
|
+
selector: 'block-loader',
|
|
5513
|
+
standalone: true,
|
|
5514
|
+
imports: [ProgressSpinner, TranslatePipe],
|
|
5515
|
+
template: `
|
|
5516
|
+
@if (visible()) {
|
|
5517
|
+
<div
|
|
5518
|
+
class="animate-fadein fixed inset-0 z-[1200] flex flex-col items-center justify-center gap-4 bg-surface-0/70 dark:bg-surface-900/70"
|
|
5519
|
+
role="status"
|
|
5520
|
+
aria-live="polite"
|
|
5521
|
+
aria-busy="true"
|
|
5522
|
+
(pointerdown)="$event.preventDefault()"
|
|
5523
|
+
(contextmenu)="$event.preventDefault()">
|
|
5524
|
+
<p-progress-spinner [style]="{ width: '3rem', height: '3rem' }" animationDuration=".8s" strokeWidth="4" />
|
|
5525
|
+
<span class="text-color font-medium">{{ 'blockLoader.loading' | translate }}</span>
|
|
5526
|
+
</div>
|
|
5527
|
+
}
|
|
5528
|
+
`
|
|
5529
|
+
}]
|
|
5530
|
+
}], ctorParameters: () => [] });
|
|
5531
|
+
|
|
5061
5532
|
class AppLayoutComponent {
|
|
5062
5533
|
constructor() {
|
|
5063
5534
|
this.layoutService = inject(LayoutService);
|
|
@@ -5148,14 +5619,16 @@ class AppLayoutComponent {
|
|
|
5148
5619
|
</div>
|
|
5149
5620
|
<div class="layout-mask animate-fadein"></div>
|
|
5150
5621
|
</div>
|
|
5151
|
-
|
|
5622
|
+
<!-- Outside the wrapper on purpose: the blocker marks the wrapper inert while it is visible. -->
|
|
5623
|
+
<block-loader />
|
|
5624
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AppTopbar, selector: "app-topbar" }, { kind: "component", type: SidebarComponent, selector: "app-sidebar" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$5.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: FooterComponent, selector: "app-footer" }, { kind: "component", type: BlockLoaderComponent, selector: "block-loader" }] }); }
|
|
5152
5625
|
}
|
|
5153
5626
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AppLayoutComponent, decorators: [{
|
|
5154
5627
|
type: Component,
|
|
5155
5628
|
args: [{
|
|
5156
5629
|
selector: 'app-layout',
|
|
5157
5630
|
standalone: true,
|
|
5158
|
-
imports: [CommonModule, AppTopbar, SidebarComponent, RouterModule, FooterComponent],
|
|
5631
|
+
imports: [CommonModule, AppTopbar, SidebarComponent, RouterModule, FooterComponent, BlockLoaderComponent],
|
|
5159
5632
|
template: `
|
|
5160
5633
|
<div class="layout-wrapper" [ngClass]="containerClass">
|
|
5161
5634
|
<app-topbar></app-topbar>
|
|
@@ -5168,6 +5641,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5168
5641
|
</div>
|
|
5169
5642
|
<div class="layout-mask animate-fadein"></div>
|
|
5170
5643
|
</div>
|
|
5644
|
+
<!-- Outside the wrapper on purpose: the blocker marks the wrapper inert while it is visible. -->
|
|
5645
|
+
<block-loader />
|
|
5171
5646
|
`,
|
|
5172
5647
|
providers: [MenuService, MenuApi]
|
|
5173
5648
|
}]
|
|
@@ -5256,7 +5731,7 @@ var notfound$1 = {
|
|
|
5256
5731
|
description: "Requested resource is not available.",
|
|
5257
5732
|
button: "Go to home"
|
|
5258
5733
|
};
|
|
5259
|
-
var en$
|
|
5734
|
+
var en$b = {
|
|
5260
5735
|
notfound: notfound$1
|
|
5261
5736
|
};
|
|
5262
5737
|
|
|
@@ -5266,13 +5741,13 @@ var notfound = {
|
|
|
5266
5741
|
description: "Запрашиваемый ресурс недоступен.",
|
|
5267
5742
|
button: "На главную"
|
|
5268
5743
|
};
|
|
5269
|
-
var ru$
|
|
5744
|
+
var ru$b = {
|
|
5270
5745
|
notfound: notfound
|
|
5271
5746
|
};
|
|
5272
5747
|
|
|
5273
5748
|
class NotfoundComponent {
|
|
5274
5749
|
constructor() {
|
|
5275
|
-
this.translations = provideTranslations({ en: en$
|
|
5750
|
+
this.translations = provideTranslations({ en: en$b, ru: ru$b });
|
|
5276
5751
|
}
|
|
5277
5752
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotfoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5278
5753
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: NotfoundComponent, isStandalone: true, selector: "app-notfound", ngImport: i0, template: ` <app-floating-configurator />
|
|
@@ -5332,7 +5807,7 @@ var unauthorized$1 = {
|
|
|
5332
5807
|
signInToContinue: "Sign in to continue",
|
|
5333
5808
|
signIn: "Sign In"
|
|
5334
5809
|
};
|
|
5335
|
-
var en$
|
|
5810
|
+
var en$a = {
|
|
5336
5811
|
unauthorized: unauthorized$1
|
|
5337
5812
|
};
|
|
5338
5813
|
|
|
@@ -5341,13 +5816,13 @@ var unauthorized = {
|
|
|
5341
5816
|
signInToContinue: "Войдите чтобы продолжить",
|
|
5342
5817
|
signIn: "Войти"
|
|
5343
5818
|
};
|
|
5344
|
-
var ru$
|
|
5819
|
+
var ru$a = {
|
|
5345
5820
|
unauthorized: unauthorized
|
|
5346
5821
|
};
|
|
5347
5822
|
|
|
5348
5823
|
class UnauthorizedComponent {
|
|
5349
5824
|
constructor() {
|
|
5350
|
-
this.translations = provideTranslations({ en: en$
|
|
5825
|
+
this.translations = provideTranslations({ en: en$a, ru: ru$a });
|
|
5351
5826
|
this.securityService = inject(SecurityService);
|
|
5352
5827
|
this.route = inject(ActivatedRoute);
|
|
5353
5828
|
}
|
|
@@ -5437,12 +5912,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5437
5912
|
}]
|
|
5438
5913
|
}] });
|
|
5439
5914
|
|
|
5915
|
+
var unauthorized_component = /*#__PURE__*/Object.freeze({
|
|
5916
|
+
__proto__: null,
|
|
5917
|
+
UnauthorizedComponent: UnauthorizedComponent
|
|
5918
|
+
});
|
|
5919
|
+
|
|
5440
5920
|
var access$1 = {
|
|
5441
5921
|
title: "Access Denied",
|
|
5442
5922
|
message: "You do not have the necessary permissions. Please contact admins.",
|
|
5443
5923
|
button: "Go to Dashboard"
|
|
5444
5924
|
};
|
|
5445
|
-
var en$
|
|
5925
|
+
var en$9 = {
|
|
5446
5926
|
access: access$1
|
|
5447
5927
|
};
|
|
5448
5928
|
|
|
@@ -5451,13 +5931,13 @@ var access = {
|
|
|
5451
5931
|
message: "У вас недостаточно прав. Пожалуйста, обратитесь к администраторам.",
|
|
5452
5932
|
button: "На главную"
|
|
5453
5933
|
};
|
|
5454
|
-
var ru$
|
|
5934
|
+
var ru$9 = {
|
|
5455
5935
|
access: access
|
|
5456
5936
|
};
|
|
5457
5937
|
|
|
5458
5938
|
class AccessComponent {
|
|
5459
5939
|
constructor() {
|
|
5460
|
-
this.translations = provideTranslations({ en: en$
|
|
5940
|
+
this.translations = provideTranslations({ en: en$9, ru: ru$9 });
|
|
5461
5941
|
}
|
|
5462
5942
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AccessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5463
5943
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: AccessComponent, isStandalone: true, selector: "app-access", ngImport: i0, template: `<div
|
|
@@ -5537,7 +6017,7 @@ var error$1 = {
|
|
|
5537
6017
|
message: "Requested resource is not available.",
|
|
5538
6018
|
button: "Go to Dashboard"
|
|
5539
6019
|
};
|
|
5540
|
-
var en$
|
|
6020
|
+
var en$8 = {
|
|
5541
6021
|
error: error$1
|
|
5542
6022
|
};
|
|
5543
6023
|
|
|
@@ -5546,13 +6026,13 @@ var error = {
|
|
|
5546
6026
|
message: "Запрашиваемый ресурс недоступен.",
|
|
5547
6027
|
button: "На главную"
|
|
5548
6028
|
};
|
|
5549
|
-
var ru$
|
|
6029
|
+
var ru$8 = {
|
|
5550
6030
|
error: error
|
|
5551
6031
|
};
|
|
5552
6032
|
|
|
5553
6033
|
class ErrorComponent {
|
|
5554
6034
|
constructor() {
|
|
5555
|
-
this.translations = provideTranslations({ en: en$
|
|
6035
|
+
this.translations = provideTranslations({ en: en$8, ru: ru$8 });
|
|
5556
6036
|
}
|
|
5557
6037
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ErrorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5558
6038
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: ErrorComponent, isStandalone: true, selector: "app-error", ngImport: i0, template: `<div
|
|
@@ -5627,6 +6107,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5627
6107
|
}]
|
|
5628
6108
|
}] });
|
|
5629
6109
|
|
|
6110
|
+
var error_component = /*#__PURE__*/Object.freeze({
|
|
6111
|
+
__proto__: null,
|
|
6112
|
+
ErrorComponent: ErrorComponent
|
|
6113
|
+
});
|
|
6114
|
+
|
|
5630
6115
|
var profileComponent$1 = {
|
|
5631
6116
|
changePhoto: "Upload Photo",
|
|
5632
6117
|
successfullyUploaded: "Uploaded successfully",
|
|
@@ -5639,7 +6124,7 @@ var profileComponent$1 = {
|
|
|
5639
6124
|
photoDeleted: "Photo deleted",
|
|
5640
6125
|
failedToDeletePhoto: "Failed to delete user photo"
|
|
5641
6126
|
};
|
|
5642
|
-
var en$
|
|
6127
|
+
var en$7 = {
|
|
5643
6128
|
profileComponent: profileComponent$1
|
|
5644
6129
|
};
|
|
5645
6130
|
|
|
@@ -5655,13 +6140,13 @@ var profileComponent = {
|
|
|
5655
6140
|
photoDeleted: "Фото удалено",
|
|
5656
6141
|
failedToDeletePhoto: "Не удалось удалить фото пользователя"
|
|
5657
6142
|
};
|
|
5658
|
-
var ru$
|
|
6143
|
+
var ru$7 = {
|
|
5659
6144
|
profileComponent: profileComponent
|
|
5660
6145
|
};
|
|
5661
6146
|
|
|
5662
6147
|
class UserProfileComponent {
|
|
5663
6148
|
constructor() {
|
|
5664
|
-
this.translations = provideTranslations({ en: en$
|
|
6149
|
+
this.translations = provideTranslations({ en: en$7, ru: ru$7 });
|
|
5665
6150
|
this.userService = inject(UserService);
|
|
5666
6151
|
this.msgService = inject(MsgService);
|
|
5667
6152
|
this.translateService = inject(TranslateService);
|
|
@@ -5786,6 +6271,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5786
6271
|
}]
|
|
5787
6272
|
}] });
|
|
5788
6273
|
|
|
6274
|
+
var userProfile_component = /*#__PURE__*/Object.freeze({
|
|
6275
|
+
__proto__: null,
|
|
6276
|
+
UserProfileComponent: UserProfileComponent
|
|
6277
|
+
});
|
|
6278
|
+
|
|
5789
6279
|
var config$1 = {
|
|
5790
6280
|
all: "All",
|
|
5791
6281
|
applicationManagement: "Application management",
|
|
@@ -5802,7 +6292,7 @@ var config$1 = {
|
|
|
5802
6292
|
timeZone: "Time zone",
|
|
5803
6293
|
usePhoto256x256Pixel: "Use photo 256x256 pixel"
|
|
5804
6294
|
};
|
|
5805
|
-
var en$
|
|
6295
|
+
var en$6 = {
|
|
5806
6296
|
config: config$1
|
|
5807
6297
|
};
|
|
5808
6298
|
|
|
@@ -5822,13 +6312,13 @@ var config = {
|
|
|
5822
6312
|
timeZone: "Часовой пояс",
|
|
5823
6313
|
usePhoto256x256Pixel: "Используйте фото 256x256 пикселей"
|
|
5824
6314
|
};
|
|
5825
|
-
var ru$
|
|
6315
|
+
var ru$6 = {
|
|
5826
6316
|
config: config
|
|
5827
6317
|
};
|
|
5828
6318
|
|
|
5829
6319
|
class ConfigComponent {
|
|
5830
6320
|
constructor() {
|
|
5831
|
-
this.translations = provideTranslations({ en: en$
|
|
6321
|
+
this.translations = provideTranslations({ en: en$6, ru: ru$6 });
|
|
5832
6322
|
this.layoutService = inject(LayoutService);
|
|
5833
6323
|
this.l10nService = inject(L10nService);
|
|
5834
6324
|
this.userService = inject(UserService);
|
|
@@ -6092,7 +6582,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6092
6582
|
}]
|
|
6093
6583
|
}], ctorParameters: () => [] });
|
|
6094
6584
|
|
|
6095
|
-
var
|
|
6585
|
+
var config_component = /*#__PURE__*/Object.freeze({
|
|
6586
|
+
__proto__: null,
|
|
6587
|
+
ConfigComponent: ConfigComponent
|
|
6588
|
+
});
|
|
6589
|
+
|
|
6590
|
+
var en$5 = {
|
|
6096
6591
|
"db-migration": {
|
|
6097
6592
|
migrationManager: "Migration manager",
|
|
6098
6593
|
actions: {
|
|
@@ -6112,7 +6607,7 @@ var en$4 = {
|
|
|
6112
6607
|
}
|
|
6113
6608
|
};
|
|
6114
6609
|
|
|
6115
|
-
var ru$
|
|
6610
|
+
var ru$5 = {
|
|
6116
6611
|
"db-migration": {
|
|
6117
6612
|
migrationManager: "Менеджер миграций",
|
|
6118
6613
|
actions: {
|
|
@@ -6135,7 +6630,7 @@ var ru$4 = {
|
|
|
6135
6630
|
class DbMigrationComponent extends BaseModuleComponent {
|
|
6136
6631
|
constructor() {
|
|
6137
6632
|
super(...arguments);
|
|
6138
|
-
this.translations = provideTranslations({ en: en$
|
|
6633
|
+
this.translations = provideTranslations({ en: en$5, ru: ru$5 });
|
|
6139
6634
|
}
|
|
6140
6635
|
async ngOnInit() {
|
|
6141
6636
|
await super.ngOnInit();
|
|
@@ -6339,6 +6834,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6339
6834
|
}]
|
|
6340
6835
|
}] });
|
|
6341
6836
|
|
|
6837
|
+
var dbMigration_component = /*#__PURE__*/Object.freeze({
|
|
6838
|
+
__proto__: null,
|
|
6839
|
+
DbMigrationComponent: DbMigrationComponent
|
|
6840
|
+
});
|
|
6841
|
+
|
|
6342
6842
|
/* eslint-disable */
|
|
6343
6843
|
/* tslint:disable */
|
|
6344
6844
|
// @ts-nocheck
|
|
@@ -6435,7 +6935,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6435
6935
|
type: Injectable
|
|
6436
6936
|
}] });
|
|
6437
6937
|
|
|
6438
|
-
var en$
|
|
6938
|
+
var en$4 = {
|
|
6439
6939
|
"app-modules": {
|
|
6440
6940
|
title: "Modules",
|
|
6441
6941
|
refreshTooltip: "Refresh",
|
|
@@ -6466,7 +6966,7 @@ var en$3 = {
|
|
|
6466
6966
|
}
|
|
6467
6967
|
};
|
|
6468
6968
|
|
|
6469
|
-
var ru$
|
|
6969
|
+
var ru$4 = {
|
|
6470
6970
|
"app-modules": {
|
|
6471
6971
|
title: "Модули",
|
|
6472
6972
|
refreshTooltip: "Обновить",
|
|
@@ -6497,7 +6997,7 @@ var ru$3 = {
|
|
|
6497
6997
|
}
|
|
6498
6998
|
};
|
|
6499
6999
|
|
|
6500
|
-
L10nService.registerTranslations({ en: en$
|
|
7000
|
+
L10nService.registerTranslations({ en: en$4, ru: ru$4 });
|
|
6501
7001
|
class AppModulesComponent {
|
|
6502
7002
|
constructor() {
|
|
6503
7003
|
this.modules = [];
|
|
@@ -6744,6 +7244,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6744
7244
|
}]
|
|
6745
7245
|
}], ctorParameters: () => [] });
|
|
6746
7246
|
|
|
7247
|
+
var appModules_component = /*#__PURE__*/Object.freeze({
|
|
7248
|
+
__proto__: null,
|
|
7249
|
+
AppModulesComponent: AppModulesComponent
|
|
7250
|
+
});
|
|
7251
|
+
|
|
6747
7252
|
var ServiceType;
|
|
6748
7253
|
(function (ServiceType) {
|
|
6749
7254
|
ServiceType["Service"] = "Service";
|
|
@@ -6794,7 +7299,7 @@ var applications$1 = {
|
|
|
6794
7299
|
deleteSuccess: "Application deleted"
|
|
6795
7300
|
}
|
|
6796
7301
|
};
|
|
6797
|
-
var en$
|
|
7302
|
+
var en$3 = {
|
|
6798
7303
|
applications: applications$1
|
|
6799
7304
|
};
|
|
6800
7305
|
|
|
@@ -6842,11 +7347,11 @@ var applications = {
|
|
|
6842
7347
|
deleteSuccess: "Приложение удалено"
|
|
6843
7348
|
}
|
|
6844
7349
|
};
|
|
6845
|
-
var ru$
|
|
7350
|
+
var ru$3 = {
|
|
6846
7351
|
applications: applications
|
|
6847
7352
|
};
|
|
6848
7353
|
|
|
6849
|
-
L10nService.registerTranslations({ en: en$
|
|
7354
|
+
L10nService.registerTranslations({ en: en$3, ru: ru$3 });
|
|
6850
7355
|
class ApplicationsComponent {
|
|
6851
7356
|
get serviceTypeOptions() {
|
|
6852
7357
|
return [
|
|
@@ -7553,6 +8058,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
7553
8058
|
}]
|
|
7554
8059
|
}], ctorParameters: () => [] });
|
|
7555
8060
|
|
|
8061
|
+
var applications_component = /*#__PURE__*/Object.freeze({
|
|
8062
|
+
__proto__: null,
|
|
8063
|
+
ApplicationsComponent: ApplicationsComponent
|
|
8064
|
+
});
|
|
8065
|
+
|
|
7556
8066
|
/* eslint-disable */
|
|
7557
8067
|
/* tslint:disable */
|
|
7558
8068
|
// @ts-nocheck
|
|
@@ -7713,7 +8223,7 @@ var discussionComponent$1 = {
|
|
|
7713
8223
|
addReaction: "Failed to add reaction."
|
|
7714
8224
|
}
|
|
7715
8225
|
};
|
|
7716
|
-
var en$
|
|
8226
|
+
var en$2 = {
|
|
7717
8227
|
discussionComponent: discussionComponent$1
|
|
7718
8228
|
};
|
|
7719
8229
|
|
|
@@ -7757,14 +8267,14 @@ var discussionComponent = {
|
|
|
7757
8267
|
addReaction: "Не удалось добавить реакцию."
|
|
7758
8268
|
}
|
|
7759
8269
|
};
|
|
7760
|
-
var ru$
|
|
8270
|
+
var ru$2 = {
|
|
7761
8271
|
discussionComponent: discussionComponent
|
|
7762
8272
|
};
|
|
7763
8273
|
|
|
7764
8274
|
class DiscussionComponent {
|
|
7765
8275
|
constructor() {
|
|
7766
8276
|
this.msgService = inject(MsgService);
|
|
7767
|
-
this.translations = provideTranslations({ en: en$
|
|
8277
|
+
this.translations = provideTranslations({ en: en$2, ru: ru$2 });
|
|
7768
8278
|
this.discussionApi = inject(DiscussionApi);
|
|
7769
8279
|
this.sanitizer = inject(DomSanitizer);
|
|
7770
8280
|
this.translateService = inject(TranslateService);
|
|
@@ -8819,7 +9329,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8819
9329
|
args: [{ required: true }]
|
|
8820
9330
|
}] } });
|
|
8821
9331
|
|
|
8822
|
-
var
|
|
9332
|
+
var discussion_component = /*#__PURE__*/Object.freeze({
|
|
9333
|
+
__proto__: null,
|
|
9334
|
+
DiscussionComponent: DiscussionComponent
|
|
9335
|
+
});
|
|
9336
|
+
|
|
9337
|
+
var en$1 = {
|
|
8823
9338
|
"iframe-module": {
|
|
8824
9339
|
iframeModule: {
|
|
8825
9340
|
urlPlaceholder: "Site URL",
|
|
@@ -8830,7 +9345,7 @@ var en = {
|
|
|
8830
9345
|
}
|
|
8831
9346
|
};
|
|
8832
9347
|
|
|
8833
|
-
var ru = {
|
|
9348
|
+
var ru$1 = {
|
|
8834
9349
|
"iframe-module": {
|
|
8835
9350
|
iframeModule: {
|
|
8836
9351
|
urlPlaceholder: "URL сайта",
|
|
@@ -8844,7 +9359,7 @@ var ru = {
|
|
|
8844
9359
|
class IframeModuleComponent extends BaseModuleComponent {
|
|
8845
9360
|
constructor() {
|
|
8846
9361
|
super();
|
|
8847
|
-
this.translations = provideTranslations({ en, ru });
|
|
9362
|
+
this.translations = provideTranslations({ en: en$1, ru: ru$1 });
|
|
8848
9363
|
this.renderer = inject(Renderer2);
|
|
8849
9364
|
this.translate = inject(TranslateService);
|
|
8850
9365
|
this.iframeUrl = null;
|
|
@@ -8987,6 +9502,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8987
9502
|
args: ['iframe']
|
|
8988
9503
|
}] } });
|
|
8989
9504
|
|
|
9505
|
+
var iframeModule_component = /*#__PURE__*/Object.freeze({
|
|
9506
|
+
__proto__: null,
|
|
9507
|
+
IframeModuleComponent: IframeModuleComponent
|
|
9508
|
+
});
|
|
9509
|
+
|
|
8990
9510
|
const OIP_EXTENSION_EVENTS = {
|
|
8991
9511
|
contextChange: 'oip:context-change',
|
|
8992
9512
|
titleChange: 'oip:title-change',
|
|
@@ -9094,7 +9614,7 @@ class CustomElementExtensionModuleHostComponent extends BaseModuleComponent {
|
|
|
9094
9614
|
async reloadExtension() {
|
|
9095
9615
|
this.loadError = null;
|
|
9096
9616
|
this.extensionMetadata = undefined;
|
|
9097
|
-
await this.loadExtensionMetadata();
|
|
9617
|
+
await this.moduleLoadingService.track(this.loadExtensionMetadata());
|
|
9098
9618
|
await this.renderExtension();
|
|
9099
9619
|
}
|
|
9100
9620
|
async loadExtensionMetadata() {
|
|
@@ -9110,7 +9630,11 @@ class CustomElementExtensionModuleHostComponent extends BaseModuleComponent {
|
|
|
9110
9630
|
}));
|
|
9111
9631
|
await this.loadExtensionTranslations(this.extensionMetadata);
|
|
9112
9632
|
}
|
|
9113
|
-
|
|
9633
|
+
/** Blocks the UI while the extension is (re)mounted, including the queued render after the view init. */
|
|
9634
|
+
renderExtension() {
|
|
9635
|
+
return this.moduleLoadingService.track(this.renderExtensionInternal());
|
|
9636
|
+
}
|
|
9637
|
+
async renderExtensionInternal() {
|
|
9114
9638
|
if (this.destroyed || !this.container || !this.extensionMetadata || !this.showContent) {
|
|
9115
9639
|
return;
|
|
9116
9640
|
}
|
|
@@ -9358,7 +9882,7 @@ class ExtensionModuleHostComponent extends BaseModuleComponent {
|
|
|
9358
9882
|
async reloadExtension() {
|
|
9359
9883
|
this.loadError = null;
|
|
9360
9884
|
this.extensionMetadata = undefined;
|
|
9361
|
-
await this.loadExtensionMetadata();
|
|
9885
|
+
await this.moduleLoadingService.track(this.loadExtensionMetadata());
|
|
9362
9886
|
await this.renderExtension();
|
|
9363
9887
|
}
|
|
9364
9888
|
async onModuleInstanceChange() {
|
|
@@ -9386,7 +9910,11 @@ class ExtensionModuleHostComponent extends BaseModuleComponent {
|
|
|
9386
9910
|
}));
|
|
9387
9911
|
await this.loadExtensionTranslations(this.extensionMetadata);
|
|
9388
9912
|
}
|
|
9389
|
-
|
|
9913
|
+
/** Blocks the UI while the extension is (re)mounted, including the queued render after the view init. */
|
|
9914
|
+
renderExtension() {
|
|
9915
|
+
return this.moduleLoadingService.track(this.renderExtensionInternal());
|
|
9916
|
+
}
|
|
9917
|
+
async renderExtensionInternal() {
|
|
9390
9918
|
if (this.destroyed || !this.viewContainer) {
|
|
9391
9919
|
return;
|
|
9392
9920
|
}
|
|
@@ -9544,6 +10072,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
9544
10072
|
args: ['extensionContainer', { read: ViewContainerRef }]
|
|
9545
10073
|
}] } });
|
|
9546
10074
|
|
|
10075
|
+
var extensionModuleHost_component = /*#__PURE__*/Object.freeze({
|
|
10076
|
+
__proto__: null,
|
|
10077
|
+
ExtensionModuleHostComponent: ExtensionModuleHostComponent
|
|
10078
|
+
});
|
|
10079
|
+
|
|
10080
|
+
var noModules$1 = {
|
|
10081
|
+
title: "No modules available",
|
|
10082
|
+
description: "There is no module you can open yet. Please contact the administrators to get access."
|
|
10083
|
+
};
|
|
10084
|
+
var en = {
|
|
10085
|
+
noModules: noModules$1
|
|
10086
|
+
};
|
|
10087
|
+
|
|
10088
|
+
var noModules = {
|
|
10089
|
+
title: "Нет доступных модулей",
|
|
10090
|
+
description: "Вам пока не доступен ни один модуль. Обратитесь к администраторам, чтобы получить доступ."
|
|
10091
|
+
};
|
|
10092
|
+
var ru = {
|
|
10093
|
+
noModules: noModules
|
|
10094
|
+
};
|
|
10095
|
+
|
|
10096
|
+
/**
|
|
10097
|
+
* Landing page shown when the user has no module instance to open.
|
|
10098
|
+
*
|
|
10099
|
+
* Rendered inside the shell on purpose: the menu and the top bar stay available, so an
|
|
10100
|
+
* administrator can keep working while a regular user sees why the page is empty.
|
|
10101
|
+
*/
|
|
10102
|
+
class NoModulesComponent {
|
|
10103
|
+
constructor() {
|
|
10104
|
+
this.translations = provideTranslations({ en, ru });
|
|
10105
|
+
}
|
|
10106
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NoModulesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10107
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: NoModulesComponent, isStandalone: true, selector: "app-no-modules", ngImport: i0, template: `<div class="flex flex-col items-center justify-center text-center gap-4 py-20">
|
|
10108
|
+
<i class="pi pi-inbox text-5xl text-surface-400"></i>
|
|
10109
|
+
<h1 class="text-surface-900 dark:text-surface-0 font-bold text-2xl lg:text-3xl m-0">
|
|
10110
|
+
{{ 'noModules.title' | translate }}
|
|
10111
|
+
</h1>
|
|
10112
|
+
<div class="text-surface-600 dark:text-surface-200 max-w-2xl">{{ 'noModules.description' | translate }}</div>
|
|
10113
|
+
</div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$7.TranslatePipe, name: "translate" }] }); }
|
|
10114
|
+
}
|
|
10115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NoModulesComponent, decorators: [{
|
|
10116
|
+
type: Component,
|
|
10117
|
+
args: [{
|
|
10118
|
+
selector: 'app-no-modules',
|
|
10119
|
+
template: `<div class="flex flex-col items-center justify-center text-center gap-4 py-20">
|
|
10120
|
+
<i class="pi pi-inbox text-5xl text-surface-400"></i>
|
|
10121
|
+
<h1 class="text-surface-900 dark:text-surface-0 font-bold text-2xl lg:text-3xl m-0">
|
|
10122
|
+
{{ 'noModules.title' | translate }}
|
|
10123
|
+
</h1>
|
|
10124
|
+
<div class="text-surface-600 dark:text-surface-200 max-w-2xl">{{ 'noModules.description' | translate }}</div>
|
|
10125
|
+
</div>`,
|
|
10126
|
+
imports: [TranslateModule],
|
|
10127
|
+
standalone: true
|
|
10128
|
+
}]
|
|
10129
|
+
}] });
|
|
10130
|
+
|
|
10131
|
+
var noModules_component = /*#__PURE__*/Object.freeze({
|
|
10132
|
+
__proto__: null,
|
|
10133
|
+
NoModulesComponent: NoModulesComponent
|
|
10134
|
+
});
|
|
10135
|
+
|
|
9547
10136
|
/**
|
|
9548
10137
|
* A route guard that ensures the user is authenticated and has a valid access token.
|
|
9549
10138
|
* If the access token is expired, it attempts to refresh the session.
|
|
@@ -9882,11 +10471,214 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
9882
10471
|
type: Injectable
|
|
9883
10472
|
}] });
|
|
9884
10473
|
|
|
10474
|
+
/**
|
|
10475
|
+
* Guard that requires an authenticated session and preserves the requested url as the return url.
|
|
10476
|
+
*
|
|
10477
|
+
* Use it on every application route rendered inside the oip shell instead of repeating the
|
|
10478
|
+
* `inject(AuthGuardService)` lambda.
|
|
10479
|
+
*/
|
|
10480
|
+
const oipAuthGuard = (_, state) => inject(AuthGuardService).canActivate(state.url);
|
|
10481
|
+
/**
|
|
10482
|
+
* Redirects the empty route to the module instance the user lands on by default.
|
|
10483
|
+
*
|
|
10484
|
+
* The order is: the explicit `startRoute` of the host application, then the module the user marked
|
|
10485
|
+
* as their start page, then the first module available to them, and finally the no modules page.
|
|
10486
|
+
*/
|
|
10487
|
+
const oipStartRedirectGuard = async (route) => {
|
|
10488
|
+
const router = inject(Router);
|
|
10489
|
+
const startPageService = inject(StartPageService);
|
|
10490
|
+
const moduleLoading = inject(ModuleLoadingService);
|
|
10491
|
+
const data = (route.data ?? {});
|
|
10492
|
+
const noModules = router.parseUrl(`/${data.noModulesPath ?? 'no-modules'}`);
|
|
10493
|
+
if (data.startRoute) {
|
|
10494
|
+
return router.parseUrl(data.startRoute);
|
|
10495
|
+
}
|
|
10496
|
+
try {
|
|
10497
|
+
// Resolving reads the menu over the network, so keep the blocker up until the target is known.
|
|
10498
|
+
return (await moduleLoading.track(startPageService.resolveStartUrl())) ?? noModules;
|
|
10499
|
+
}
|
|
10500
|
+
catch (error) {
|
|
10501
|
+
console.error('Failed to resolve the start module', error);
|
|
10502
|
+
return noModules;
|
|
10503
|
+
}
|
|
10504
|
+
};
|
|
10505
|
+
/**
|
|
10506
|
+
* Page shown when the user has no module instance to open.
|
|
10507
|
+
*/
|
|
10508
|
+
function oipNoModulesRoute(path = 'no-modules') {
|
|
10509
|
+
return {
|
|
10510
|
+
path,
|
|
10511
|
+
loadComponent: () => Promise.resolve().then(function () { return noModules_component; }).then((m) => m.NoModulesComponent),
|
|
10512
|
+
canActivate: [oipAuthGuard]
|
|
10513
|
+
};
|
|
10514
|
+
}
|
|
10515
|
+
/**
|
|
10516
|
+
* Empty route redirecting to the start module of the current user.
|
|
10517
|
+
*
|
|
10518
|
+
* Registered last among the shell children so a host application can claim the empty path itself.
|
|
10519
|
+
*/
|
|
10520
|
+
function oipStartRoute(path = '', data = {}) {
|
|
10521
|
+
return {
|
|
10522
|
+
path,
|
|
10523
|
+
pathMatch: 'full',
|
|
10524
|
+
canActivate: [oipAuthGuard, oipStartRedirectGuard],
|
|
10525
|
+
children: [],
|
|
10526
|
+
data
|
|
10527
|
+
};
|
|
10528
|
+
}
|
|
10529
|
+
/**
|
|
10530
|
+
* Access denied page. Referenced by {@link AuthGuardService} and {@link moduleAccessGuard} redirects,
|
|
10531
|
+
* so keep it registered unless the host application provides its own `access` route.
|
|
10532
|
+
*/
|
|
10533
|
+
function oipAccessRoute(path = 'access') {
|
|
10534
|
+
return { path, component: AccessComponent };
|
|
10535
|
+
}
|
|
10536
|
+
/** Authentication error page. */
|
|
10537
|
+
function oipErrorRoute(path = 'error') {
|
|
10538
|
+
return {
|
|
10539
|
+
path,
|
|
10540
|
+
loadComponent: () => Promise.resolve().then(function () { return error_component; }).then((m) => m.ErrorComponent)
|
|
10541
|
+
};
|
|
10542
|
+
}
|
|
10543
|
+
/** Current user profile. */
|
|
10544
|
+
function oipProfileRoute(path = 'profile') {
|
|
10545
|
+
return {
|
|
10546
|
+
path,
|
|
10547
|
+
loadComponent: () => Promise.resolve().then(function () { return userProfile_component; }).then((m) => m.UserProfileComponent),
|
|
10548
|
+
canActivate: [oipAuthGuard]
|
|
10549
|
+
};
|
|
10550
|
+
}
|
|
10551
|
+
/** Application configuration. */
|
|
10552
|
+
function oipConfigRoute(path = 'config') {
|
|
10553
|
+
return {
|
|
10554
|
+
path,
|
|
10555
|
+
loadComponent: () => Promise.resolve().then(function () { return config_component; }).then((m) => m.ConfigComponent),
|
|
10556
|
+
canActivate: [oipAuthGuard]
|
|
10557
|
+
};
|
|
10558
|
+
}
|
|
10559
|
+
/** Registered applications, administrators only. */
|
|
10560
|
+
function oipApplicationsRoute(path = 'applications') {
|
|
10561
|
+
return {
|
|
10562
|
+
path,
|
|
10563
|
+
loadComponent: () => Promise.resolve().then(function () { return applications_component; }).then((m) => m.ApplicationsComponent),
|
|
10564
|
+
canActivate: [oipAuthGuard],
|
|
10565
|
+
data: { requireAdmin: true }
|
|
10566
|
+
};
|
|
10567
|
+
}
|
|
10568
|
+
/** Module registry, administrators only. */
|
|
10569
|
+
function oipModulesRoute(path = 'modules') {
|
|
10570
|
+
return {
|
|
10571
|
+
path,
|
|
10572
|
+
loadComponent: () => Promise.resolve().then(function () { return appModules_component; }).then((m) => m.AppModulesComponent),
|
|
10573
|
+
canActivate: [oipAuthGuard],
|
|
10574
|
+
data: { requireAdmin: true }
|
|
10575
|
+
};
|
|
10576
|
+
}
|
|
10577
|
+
/** Discussion module. The path must keep an `:id` segment. */
|
|
10578
|
+
function oipDiscussionRoute(path = 'discussion/:id') {
|
|
10579
|
+
return {
|
|
10580
|
+
path,
|
|
10581
|
+
loadComponent: () => Promise.resolve().then(function () { return discussion_component; }).then((m) => m.DiscussionComponent),
|
|
10582
|
+
canActivate: [oipAuthGuard]
|
|
10583
|
+
};
|
|
10584
|
+
}
|
|
10585
|
+
/** Database migration module. The path must keep an `:id` segment. */
|
|
10586
|
+
function oipDbMigrationRoute(path = 'db-migration/:id') {
|
|
10587
|
+
return {
|
|
10588
|
+
path,
|
|
10589
|
+
loadComponent: () => Promise.resolve().then(function () { return dbMigration_component; }).then((m) => m.DbMigrationComponent),
|
|
10590
|
+
canActivate: [oipAuthGuard]
|
|
10591
|
+
};
|
|
10592
|
+
}
|
|
10593
|
+
/** Iframe module host. The path must keep an `:id` segment. */
|
|
10594
|
+
function oipIframeModuleRoute(path = 'iframe-module/:id') {
|
|
10595
|
+
return {
|
|
10596
|
+
path,
|
|
10597
|
+
loadComponent: () => Promise.resolve().then(function () { return iframeModule_component; }).then((m) => m.IframeModuleComponent),
|
|
10598
|
+
canActivate: [oipAuthGuard]
|
|
10599
|
+
};
|
|
10600
|
+
}
|
|
10601
|
+
/** Extension module host. The path must keep the `:extensionKey` and `:id` segments. */
|
|
10602
|
+
function oipExtensionsRoute(path = 'extensions/:extensionKey/:id') {
|
|
10603
|
+
return {
|
|
10604
|
+
path,
|
|
10605
|
+
loadComponent: () => Promise.resolve().then(function () { return extensionModuleHost_component; }).then((m) => m.ExtensionModuleHostComponent),
|
|
10606
|
+
canActivate: [oipAuthGuard]
|
|
10607
|
+
};
|
|
10608
|
+
}
|
|
10609
|
+
function builtInRoute(toggle, factory, into) {
|
|
10610
|
+
if (toggle === false) {
|
|
10611
|
+
return;
|
|
10612
|
+
}
|
|
10613
|
+
into.push(typeof toggle === 'string' ? factory(toggle) : factory());
|
|
10614
|
+
}
|
|
10615
|
+
/**
|
|
10616
|
+
* Builds the standard oip route tree: an authenticated shell holding the application routes and the
|
|
10617
|
+
* built-in pages, followed by the unauthorized, not found and catch-all routes.
|
|
10618
|
+
*
|
|
10619
|
+
* The returned array is ordered so that the `**` route stays last; concatenating anything after it
|
|
10620
|
+
* makes those routes unreachable.
|
|
10621
|
+
*
|
|
10622
|
+
* @example
|
|
10623
|
+
* export const appRoutes = provideOipRoutes({
|
|
10624
|
+
* children: [
|
|
10625
|
+
* {
|
|
10626
|
+
* path: 'dashboard/:id',
|
|
10627
|
+
* loadComponent: () => import('./dashboard.component').then((m) => m.DashboardComponent),
|
|
10628
|
+
* canActivate: [oipAuthGuard]
|
|
10629
|
+
* }
|
|
10630
|
+
* ],
|
|
10631
|
+
* features: { dbMigration: 'legacy-migration/:id', modules: false },
|
|
10632
|
+
* startRoute: '/dashboard/1'
|
|
10633
|
+
* });
|
|
10634
|
+
*/
|
|
10635
|
+
function provideOipRoutes(options = {}) {
|
|
10636
|
+
const features = options.features ?? {};
|
|
10637
|
+
const children = [...(options.children ?? [])];
|
|
10638
|
+
builtInRoute(features.access, oipAccessRoute, children);
|
|
10639
|
+
builtInRoute(features.error, oipErrorRoute, children);
|
|
10640
|
+
builtInRoute(features.profile, oipProfileRoute, children);
|
|
10641
|
+
builtInRoute(features.config, oipConfigRoute, children);
|
|
10642
|
+
builtInRoute(features.applications, oipApplicationsRoute, children);
|
|
10643
|
+
builtInRoute(features.modules, oipModulesRoute, children);
|
|
10644
|
+
builtInRoute(features.discussion, oipDiscussionRoute, children);
|
|
10645
|
+
builtInRoute(features.dbMigration, oipDbMigrationRoute, children);
|
|
10646
|
+
builtInRoute(features.iframeModule, oipIframeModuleRoute, children);
|
|
10647
|
+
builtInRoute(features.extensions, oipExtensionsRoute, children);
|
|
10648
|
+
builtInRoute(features.noModules, oipNoModulesRoute, children);
|
|
10649
|
+
// Registered last so a host application that declares its own empty path keeps it.
|
|
10650
|
+
if (features.start !== false && !children.some((route) => route.path === '')) {
|
|
10651
|
+
const noModulesPath = typeof features.noModules === 'string' ? features.noModules : 'no-modules';
|
|
10652
|
+
const startPath = typeof features.start === 'string' ? features.start : '';
|
|
10653
|
+
children.push(oipStartRoute(startPath, { startRoute: options.startRoute, noModulesPath }));
|
|
10654
|
+
}
|
|
10655
|
+
const notFoundPath = options.notFoundPath ?? 'notfound';
|
|
10656
|
+
const routes = [
|
|
10657
|
+
{
|
|
10658
|
+
path: '',
|
|
10659
|
+
component: options.layout ?? AppLayoutComponent,
|
|
10660
|
+
canActivate: [oipAuthGuard],
|
|
10661
|
+
canActivateChild: [moduleAccessGuard],
|
|
10662
|
+
children
|
|
10663
|
+
},
|
|
10664
|
+
{
|
|
10665
|
+
path: options.unauthorizedPath ?? 'unauthorized',
|
|
10666
|
+
loadComponent: () => Promise.resolve().then(function () { return unauthorized_component; }).then((m) => m.UnauthorizedComponent)
|
|
10667
|
+
},
|
|
10668
|
+
...(options.rootRoutes ?? []),
|
|
10669
|
+
{ path: notFoundPath, component: NotfoundComponent }
|
|
10670
|
+
];
|
|
10671
|
+
if (options.wildcard !== false) {
|
|
10672
|
+
routes.push({ path: '**', redirectTo: `/${notFoundPath}` });
|
|
10673
|
+
}
|
|
10674
|
+
return routes;
|
|
10675
|
+
}
|
|
10676
|
+
|
|
9885
10677
|
// Components
|
|
9886
10678
|
|
|
9887
10679
|
/**
|
|
9888
10680
|
* Generated bundle index. Do not edit.
|
|
9889
10681
|
*/
|
|
9890
10682
|
|
|
9891
|
-
export { APP_INFO_TOKEN, APP_THEME_PRESETS, APP_THEME_PRESETS_MERGE_MODE, AccessComponent, AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppInfoService, AppLayoutComponent, AppModulesComponent, AppTopbar, AppTopbarApplicationSwitcherComponent, ApplicationRegistryService, ApplicationsApi, ApplicationsComponent, AuthGuardService, BaseModuleComponent, BffSecurityService, ConfigComponent, ContentType, CustomElementExtensionModuleHostComponent, DbMigrationComponent, DiscussionComponent, ErrorComponent, ExtensionLoaderService, ExtensionModuleHostComponent, FolderModuleApi, FooterComponent, HttpClient, IframeModuleApi, IframeModuleComponent, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, ModuleInstanceRightsService, MsgService, NotfoundComponent, NotificationApi, NotificationService, OIP_EXTENSION_EVENTS, SecurityApi, SecurityComponent, SecurityService, SidebarComponent, TableFilterService, TopBarService, UnauthorizedComponent, UserNotificationsComponent, UserProfileApi, UserProfileComponent, UserService, convertToPrimeNgDateFormat, defaultTheme, emitOipContextChange, emitOipError, emitOipNavigate, emitOipNotify, emitOipSettingsChange, emitOipTitleChange, langIntercept, mergeWithDefaults, moduleAccessGuard, provideAppInfo, provideAppThemes, provideLogoComponent, provideOip, provideTranslations, replaceDefaults };
|
|
10683
|
+
export { APP_INFO_TOKEN, APP_THEME_PRESETS, APP_THEME_PRESETS_MERGE_MODE, AccessComponent, AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppInfoService, AppLayoutComponent, AppModulesComponent, AppTopbar, AppTopbarApplicationSwitcherComponent, ApplicationRegistryService, ApplicationsApi, ApplicationsComponent, AuthGuardService, BaseModuleComponent, BffSecurityService, BlockLoaderComponent, ConfigComponent, ContentType, CustomElementExtensionModuleHostComponent, DbMigrationComponent, DiscussionComponent, ErrorComponent, ExtensionLoaderService, ExtensionModuleHostComponent, FolderModuleApi, FooterComponent, HttpClient, IframeModuleApi, IframeModuleComponent, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, ModuleInstanceRightsService, ModuleLoadingService, MsgService, NoModulesComponent, NotfoundComponent, NotificationApi, NotificationService, OIP_EXTENSION_EVENTS, SecurityApi, SecurityComponent, SecurityService, SidebarComponent, StartPageService, TableFilterService, TopBarService, UnauthorizedComponent, UserNotificationsComponent, UserProfileApi, UserProfileComponent, UserService, convertToPrimeNgDateFormat, defaultTheme, emitOipContextChange, emitOipError, emitOipNavigate, emitOipNotify, emitOipSettingsChange, emitOipTitleChange, langIntercept, mergeWithDefaults, moduleAccessGuard, oipAccessRoute, oipApplicationsRoute, oipAuthGuard, oipConfigRoute, oipDbMigrationRoute, oipDiscussionRoute, oipErrorRoute, oipExtensionsRoute, oipIframeModuleRoute, oipModulesRoute, oipNoModulesRoute, oipProfileRoute, oipStartRedirectGuard, oipStartRoute, provideAppInfo, provideAppThemes, provideLogoComponent, provideOip, provideOipRoutes, provideTranslations, replaceDefaults };
|
|
9892
10684
|
//# sourceMappingURL=oip-common.mjs.map
|