oip-common 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/oip-common.mjs +1141 -71
- package/fesm2022/oip-common.mjs.map +1 -1
- package/index.d.ts +164 -14
- package/package.json +1 -1
- package/templates/http-client.ejs +34 -8
- package/assets/i18n/app-modules.en.json +0 -30
- package/assets/i18n/app-modules.ru.json +0 -30
- package/assets/i18n/applications.en.json +0 -46
- package/assets/i18n/applications.ru.json +0 -46
- package/assets/i18n/config.en.json +0 -18
- package/assets/i18n/config.ru.json +0 -18
- package/assets/i18n/db-migration.en.json +0 -19
- package/assets/i18n/db-migration.ru.json +0 -19
- package/assets/i18n/en.json +0 -138
- package/assets/i18n/iframe-module.en.json +0 -10
- package/assets/i18n/iframe-module.ru.json +0 -10
- package/assets/i18n/notfound.en.json +0 -8
- package/assets/i18n/notfound.ru.json +0 -8
- package/assets/i18n/ru.json +0 -282
package/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { OnDestroy, OnInit, DestroyRef, WritableSignal, OnChanges, SimpleChanges
|
|
|
3
3
|
import * as rxjs from 'rxjs';
|
|
4
4
|
import { Observable, BehaviorSubject, Subscription, Subject } from 'rxjs';
|
|
5
5
|
import { MessageService, ToastMessageOptions, ConfirmationService, MenuItem, FilterMetadata } from 'primeng/api';
|
|
6
|
-
import { ActivatedRoute, QueryParamsHandling, IsActiveMatchOptions, Params,
|
|
7
|
-
import { InterpolationParameters, Translation,
|
|
6
|
+
import { Router, ActivatedRoute, QueryParamsHandling, IsActiveMatchOptions, Params, CanActivateChildFn } from '@angular/router';
|
|
7
|
+
import { TranslationObject, InterpolationParameters, Translation, TranslateService } from '@ngx-translate/core';
|
|
8
8
|
import { ContextMenu } from 'primeng/contextmenu';
|
|
9
9
|
import { PaletteDesignToken, Preset } from '@primeuix/themes/types';
|
|
10
10
|
import { PrimeNG } from 'primeng/config';
|
|
@@ -147,6 +147,10 @@ declare class LayoutService {
|
|
|
147
147
|
static ɵprov: i0.ɵɵInjectableDeclaration<LayoutService>;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Translations of a single namespace grouped by language code, e.g. { en: {...}, ru: {...} }
|
|
152
|
+
*/
|
|
153
|
+
type TranslationsByLang = Record<string, TranslationObject>;
|
|
150
154
|
interface LanguageDto {
|
|
151
155
|
code: string;
|
|
152
156
|
name: string;
|
|
@@ -163,6 +167,20 @@ declare class L10nService {
|
|
|
163
167
|
private readonly primeNg;
|
|
164
168
|
private readonly layoutService;
|
|
165
169
|
availableLanguages: LanguageDto[];
|
|
170
|
+
/**
|
|
171
|
+
* Translations bundled with components, registered at module load time.
|
|
172
|
+
*/
|
|
173
|
+
private static readonly staticTranslations;
|
|
174
|
+
/**
|
|
175
|
+
* Registers translations bundled with a component instead of loading them over HTTP.
|
|
176
|
+
* Namespaces are taken from the root keys of the passed dictionaries.
|
|
177
|
+
* Components derived from <c>BaseModuleComponent</c> don't call it directly - it is enough
|
|
178
|
+
* to declare the static <c>translations</c> field.
|
|
179
|
+
* @param byLang - Translations grouped by language code
|
|
180
|
+
* @param namespace - Explicit namespace, needed when the dictionaries are still empty
|
|
181
|
+
*/
|
|
182
|
+
static registerTranslations(byLang: TranslationsByLang | undefined, namespace?: string): void;
|
|
183
|
+
constructor();
|
|
166
184
|
/**
|
|
167
185
|
* Loads translations for a specific component
|
|
168
186
|
* @param component - Name of the component to load translations for
|
|
@@ -184,6 +202,12 @@ declare class L10nService {
|
|
|
184
202
|
* @param lang - Language code to load translations for
|
|
185
203
|
*/
|
|
186
204
|
private loadTranslations;
|
|
205
|
+
/**
|
|
206
|
+
* Merges a translation dictionary into the dictionary of the given language
|
|
207
|
+
* @param lang - Language code
|
|
208
|
+
* @param translations - Translations to merge
|
|
209
|
+
*/
|
|
210
|
+
private mergeTranslation;
|
|
187
211
|
/**
|
|
188
212
|
* Changes the lang currently used
|
|
189
213
|
*/
|
|
@@ -291,8 +315,14 @@ declare enum ContentType {
|
|
|
291
315
|
declare class HttpClient<SecurityDataType = unknown> {
|
|
292
316
|
protected securityService: SecurityService;
|
|
293
317
|
protected layoutService: LayoutService;
|
|
318
|
+
protected router: Router;
|
|
294
319
|
baseUrl: string;
|
|
295
320
|
private securityWorker?;
|
|
321
|
+
/**
|
|
322
|
+
* Reads the module instance id of the deepest activated route.
|
|
323
|
+
* The backend uses it to check module instance rights on endpoints that do not carry the id in their contract.
|
|
324
|
+
*/
|
|
325
|
+
protected getCurrentModuleInstanceId(): number | undefined;
|
|
296
326
|
private abortControllers;
|
|
297
327
|
private customFetch;
|
|
298
328
|
private baseApiParams;
|
|
@@ -307,6 +337,7 @@ declare class HttpClient<SecurityDataType = unknown> {
|
|
|
307
337
|
protected createAbortSignal: (cancelToken: CancelToken) => AbortSignal | undefined;
|
|
308
338
|
abortRequest: (cancelToken: CancelToken) => void;
|
|
309
339
|
request: <T = any, E = any>({ body, secure, path, type, query, format, baseUrl, cancelToken, ...params }: FullRequestParams) => Promise<T>;
|
|
340
|
+
private authorizeOnUnauthorized;
|
|
310
341
|
private getCsrfRequestParams;
|
|
311
342
|
static ɵfac: i0.ɵɵFactoryDeclaration<HttpClient<any>, never>;
|
|
312
343
|
static ɵprov: i0.ɵɵInjectableDeclaration<HttpClient<any>>;
|
|
@@ -391,6 +422,16 @@ declare abstract class BaseModuleComponent<TBackendStoreSettings, TLocalStoreSet
|
|
|
391
422
|
* @type {string}
|
|
392
423
|
*/
|
|
393
424
|
title: string;
|
|
425
|
+
/**
|
|
426
|
+
* Translations bundled with the component, grouped by language code.
|
|
427
|
+
* Declare it in a derived component to load translations from the component folder
|
|
428
|
+
* instead of `assets/i18n`:
|
|
429
|
+
*
|
|
430
|
+
* ```ts
|
|
431
|
+
* static override readonly translations = { en, ru };
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
static readonly translations: TranslationsByLang | undefined;
|
|
394
435
|
l10nService: L10nService;
|
|
395
436
|
l10n$: Observable<Translation | TranslationObject>;
|
|
396
437
|
canRead: boolean;
|
|
@@ -481,13 +522,13 @@ declare abstract class BaseModuleComponent<TBackendStoreSettings, TLocalStoreSet
|
|
|
481
522
|
/**
|
|
482
523
|
* Starts watching current token roles and maps them to module instance security settings.
|
|
483
524
|
*/
|
|
484
|
-
protected watchSecurityRights(controller?: string, id?: number | undefined): void
|
|
525
|
+
protected watchSecurityRights(controller?: string, id?: number | undefined): Promise<void>;
|
|
485
526
|
private resetRightsState;
|
|
486
527
|
private updateRightsState;
|
|
487
528
|
protected hasSecurityRight(roles: string[], securitySettings: SecurityDto[], code: string): boolean;
|
|
488
529
|
protected getSecurity(controller?: string, id?: number | undefined): Promise<SecurityDto[]>;
|
|
489
530
|
protected saveSecurity(request: PutSecurityDto, controller?: string): Promise<unknown>;
|
|
490
|
-
protected getModuleInstanceSettings<TSettings>(controller?: string
|
|
531
|
+
protected getModuleInstanceSettings<TSettings>(controller?: string): Promise<TSettings>;
|
|
491
532
|
protected saveModuleInstanceSettings<TSettings>(request: {
|
|
492
533
|
id: number;
|
|
493
534
|
settings: TSettings;
|
|
@@ -651,10 +692,7 @@ interface ModuleInstanceDto {
|
|
|
651
692
|
order?: number;
|
|
652
693
|
separator?: boolean;
|
|
653
694
|
}
|
|
654
|
-
interface
|
|
655
|
-
id?: number;
|
|
656
|
-
}
|
|
657
|
-
interface GetModuleInstanceSettingsParams4 {
|
|
695
|
+
interface GetModuleInstanceRightsParams {
|
|
658
696
|
id?: number;
|
|
659
697
|
}
|
|
660
698
|
interface DeleteModuleInstanceParams {
|
|
@@ -749,6 +787,7 @@ declare class MenuService {
|
|
|
749
787
|
|
|
750
788
|
declare class MenuApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
|
|
751
789
|
get: (params?: RequestParams) => Promise<ModuleInstanceDto[]>;
|
|
790
|
+
getModuleInstanceRights: (query: GetModuleInstanceRightsParams, params?: RequestParams) => Promise<string[]>;
|
|
752
791
|
getAdminMenu: (params?: RequestParams) => Promise<ModuleInstanceDto[]>;
|
|
753
792
|
getModules: (params?: RequestParams) => Promise<IntKeyValueDto[]>;
|
|
754
793
|
addModuleInstance: (data: AddModuleInstanceDto, params?: RequestParams) => Promise<void>;
|
|
@@ -795,7 +834,6 @@ declare class MenuItemEditDialogComponent {
|
|
|
795
834
|
private readonly msgService;
|
|
796
835
|
visible: boolean;
|
|
797
836
|
visibleChange: EventEmitter<boolean>;
|
|
798
|
-
modules: any[];
|
|
799
837
|
roles: string[];
|
|
800
838
|
iconOptions: PrimeIconOption[];
|
|
801
839
|
item: EditModuleInstanceDto;
|
|
@@ -875,6 +913,11 @@ declare class UnauthorizedComponent implements OnInit {
|
|
|
875
913
|
static ɵcmp: i0.ɵɵComponentDeclaration<UnauthorizedComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
876
914
|
}
|
|
877
915
|
|
|
916
|
+
declare class AccessComponent {
|
|
917
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AccessComponent, never>;
|
|
918
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AccessComponent, "app-access", never, {}, {}, never, never, true, never>;
|
|
919
|
+
}
|
|
920
|
+
|
|
878
921
|
declare class ErrorComponent {
|
|
879
922
|
static ɵfac: i0.ɵɵFactoryDeclaration<ErrorComponent, never>;
|
|
880
923
|
static ɵcmp: i0.ɵɵComponentDeclaration<ErrorComponent, "app-error", never, {}, {}, never, never, true, never>;
|
|
@@ -954,8 +997,47 @@ interface MigrationDto {
|
|
|
954
997
|
exist: boolean;
|
|
955
998
|
}
|
|
956
999
|
declare class DbMigrationComponent extends BaseModuleComponent<NoSettingsDto, NoSettingsDto> implements OnInit, OnDestroy {
|
|
1000
|
+
static readonly translations: {
|
|
1001
|
+
en: {
|
|
1002
|
+
"db-migration": {
|
|
1003
|
+
migrationManager: string;
|
|
1004
|
+
actions: {
|
|
1005
|
+
refresh: string;
|
|
1006
|
+
cleanFilter: string;
|
|
1007
|
+
applyMigration: string;
|
|
1008
|
+
};
|
|
1009
|
+
columns: {
|
|
1010
|
+
name: string;
|
|
1011
|
+
applied: string;
|
|
1012
|
+
exist: string;
|
|
1013
|
+
pending: string;
|
|
1014
|
+
};
|
|
1015
|
+
messages: {
|
|
1016
|
+
errorRefreshing: string;
|
|
1017
|
+
};
|
|
1018
|
+
};
|
|
1019
|
+
};
|
|
1020
|
+
ru: {
|
|
1021
|
+
"db-migration": {
|
|
1022
|
+
migrationManager: string;
|
|
1023
|
+
actions: {
|
|
1024
|
+
refresh: string;
|
|
1025
|
+
cleanFilter: string;
|
|
1026
|
+
applyMigration: string;
|
|
1027
|
+
};
|
|
1028
|
+
columns: {
|
|
1029
|
+
name: string;
|
|
1030
|
+
applied: string;
|
|
1031
|
+
exist: string;
|
|
1032
|
+
pending: string;
|
|
1033
|
+
};
|
|
1034
|
+
messages: {
|
|
1035
|
+
errorRefreshing: string;
|
|
1036
|
+
};
|
|
1037
|
+
};
|
|
1038
|
+
};
|
|
1039
|
+
};
|
|
957
1040
|
data: MigrationDto[];
|
|
958
|
-
constructor();
|
|
959
1041
|
ngOnInit(): Promise<void>;
|
|
960
1042
|
refreshAction(): Promise<void>;
|
|
961
1043
|
getData(): Promise<MigrationDto[]>;
|
|
@@ -1292,6 +1374,28 @@ declare class DiscussionComponent implements OnChanges, OnDestroy, OnInit {
|
|
|
1292
1374
|
}
|
|
1293
1375
|
|
|
1294
1376
|
declare class IframeModuleComponent extends BaseModuleComponent<IframeModuleSettings, IframeModuleSettings> implements OnInit, OnDestroy {
|
|
1377
|
+
static readonly translations: {
|
|
1378
|
+
en: {
|
|
1379
|
+
"iframe-module": {
|
|
1380
|
+
iframeModule: {
|
|
1381
|
+
urlPlaceholder: string;
|
|
1382
|
+
settingSaveButtonLabel: string;
|
|
1383
|
+
emptyUrlMessage: string;
|
|
1384
|
+
siteLoadingMessage: string;
|
|
1385
|
+
};
|
|
1386
|
+
};
|
|
1387
|
+
};
|
|
1388
|
+
ru: {
|
|
1389
|
+
"iframe-module": {
|
|
1390
|
+
iframeModule: {
|
|
1391
|
+
urlPlaceholder: string;
|
|
1392
|
+
settingSaveButtonLabel: string;
|
|
1393
|
+
emptyUrlMessage: string;
|
|
1394
|
+
siteLoadingMessage: string;
|
|
1395
|
+
};
|
|
1396
|
+
};
|
|
1397
|
+
};
|
|
1398
|
+
};
|
|
1295
1399
|
private iframe?;
|
|
1296
1400
|
private readonly renderer;
|
|
1297
1401
|
private readonly translate;
|
|
@@ -1443,6 +1547,52 @@ declare class AuthGuardService {
|
|
|
1443
1547
|
static ɵprov: i0.ɵɵInjectableDeclaration<AuthGuardService>;
|
|
1444
1548
|
}
|
|
1445
1549
|
|
|
1550
|
+
/**
|
|
1551
|
+
* Route data flag marking a route that only administrators may open.
|
|
1552
|
+
*/
|
|
1553
|
+
interface ModuleAccessRouteData {
|
|
1554
|
+
requireAdmin?: boolean;
|
|
1555
|
+
}
|
|
1556
|
+
/**
|
|
1557
|
+
* Guards module routes against direct navigation without the required rights.
|
|
1558
|
+
*
|
|
1559
|
+
* - Routes flagged with `data: { requireAdmin: true }` require the `admin` role.
|
|
1560
|
+
* - Routes carrying an `:id` segment require the `read` right on that module instance.
|
|
1561
|
+
* - Everything else is left to {@link AuthGuardService}.
|
|
1562
|
+
*
|
|
1563
|
+
* Denied navigation is redirected to the access denied page. This is a UX guard only:
|
|
1564
|
+
* the backend checks the same rights on every module endpoint.
|
|
1565
|
+
*/
|
|
1566
|
+
declare const moduleAccessGuard: CanActivateChildFn;
|
|
1567
|
+
|
|
1568
|
+
/**
|
|
1569
|
+
* Reads the rights the current user has on a module instance.
|
|
1570
|
+
*
|
|
1571
|
+
* Results are cached per instance and dropped whenever the authenticated user changes.
|
|
1572
|
+
*/
|
|
1573
|
+
declare class ModuleInstanceRightsService {
|
|
1574
|
+
static readonly readRight = "read";
|
|
1575
|
+
private readonly menuApi;
|
|
1576
|
+
private readonly securityService;
|
|
1577
|
+
private readonly cache;
|
|
1578
|
+
private cachedIdentity;
|
|
1579
|
+
constructor();
|
|
1580
|
+
/**
|
|
1581
|
+
* Gets the rights of the current user on the given module instance.
|
|
1582
|
+
*/
|
|
1583
|
+
getRights(moduleInstanceId: number): Promise<string[]>;
|
|
1584
|
+
/**
|
|
1585
|
+
* Checks whether the current user has the `read` right on the given module instance.
|
|
1586
|
+
*/
|
|
1587
|
+
canRead(moduleInstanceId: number): Promise<boolean>;
|
|
1588
|
+
/**
|
|
1589
|
+
* Drops every cached result, for example after module security was changed.
|
|
1590
|
+
*/
|
|
1591
|
+
clearCache(): void;
|
|
1592
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ModuleInstanceRightsService, never>;
|
|
1593
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ModuleInstanceRightsService>;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1446
1596
|
declare class NotificationService {
|
|
1447
1597
|
private connection;
|
|
1448
1598
|
private securityService;
|
|
@@ -1590,13 +1740,13 @@ declare function emitOipError(element: HTMLElement, error: unknown): void;
|
|
|
1590
1740
|
declare function emitOipContextChange(element: HTMLElement, context: OipExtensionHostContext): void;
|
|
1591
1741
|
|
|
1592
1742
|
declare class FolderModuleApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
|
|
1593
|
-
getModuleInstanceSettings: (
|
|
1743
|
+
getModuleInstanceSettings: (params?: RequestParams) => Promise<FolderModuleSettings>;
|
|
1594
1744
|
static ɵfac: i0.ɵɵFactoryDeclaration<FolderModuleApi<any>, never>;
|
|
1595
1745
|
static ɵprov: i0.ɵɵInjectableDeclaration<FolderModuleApi<any>>;
|
|
1596
1746
|
}
|
|
1597
1747
|
|
|
1598
1748
|
declare class IframeModuleApi<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
|
|
1599
|
-
getModuleInstanceSettings: (
|
|
1749
|
+
getModuleInstanceSettings: (params?: RequestParams) => Promise<IframeModuleSettings>;
|
|
1600
1750
|
static ɵfac: i0.ɵɵFactoryDeclaration<IframeModuleApi<any>, never>;
|
|
1601
1751
|
static ɵprov: i0.ɵɵInjectableDeclaration<IframeModuleApi<any>>;
|
|
1602
1752
|
}
|
|
@@ -1674,5 +1824,5 @@ declare class CustomElementExtensionModuleHostComponent extends BaseModuleCompon
|
|
|
1674
1824
|
static ɵcmp: i0.ɵɵComponentDeclaration<CustomElementExtensionModuleHostComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
1675
1825
|
}
|
|
1676
1826
|
|
|
1677
|
-
export { APP_THEME_PRESETS, APP_THEME_PRESETS_MERGE_MODE, AppConfiguratorComponent, AppFloatingConfiguratorComponent, 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, MsgService, NotfoundComponent, NotificationApi, NotificationService, OIP_EXTENSION_EVENTS, ProfileComponent, SecurityApi, SecurityComponent, SecurityService, SidebarComponent, TableFilterService, TopBarService, UnauthorizedComponent, UserNotificationsComponent, UserProfileApi, UserService, convertToPrimeNgDateFormat, defaultTheme, emitOipContextChange, emitOipError, emitOipNavigate, emitOipNotify, emitOipSettingsChange, emitOipTitleChange, langIntercept, mergeWithDefaults, provideAppThemes, provideLogoComponent, provideOip, replaceDefaults };
|
|
1678
|
-
export type { AppConfig, AppThemePreset, AppThemePresetMergeMode, AuthCsrfToken, LanguageDto, MenuChangeEvent, NoSettingsDto, OipExtensionHostContext, OipExtensionLoadType, OipExtensionManifest, OipExtensionModuleMetadata, OipExtensionNavigateEvent, OipExtensionNotifyEvent, PutSecurityDto, RequestParams, SecurityDto, TopBarDto };
|
|
1827
|
+
export { APP_THEME_PRESETS, APP_THEME_PRESETS_MERGE_MODE, AccessComponent, AppConfiguratorComponent, AppFloatingConfiguratorComponent, 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, ProfileComponent, SecurityApi, SecurityComponent, SecurityService, SidebarComponent, TableFilterService, TopBarService, UnauthorizedComponent, UserNotificationsComponent, UserProfileApi, UserService, convertToPrimeNgDateFormat, defaultTheme, emitOipContextChange, emitOipError, emitOipNavigate, emitOipNotify, emitOipSettingsChange, emitOipTitleChange, langIntercept, mergeWithDefaults, moduleAccessGuard, provideAppThemes, provideLogoComponent, provideOip, replaceDefaults };
|
|
1828
|
+
export type { AppConfig, AppThemePreset, AppThemePresetMergeMode, AuthCsrfToken, LanguageDto, MenuChangeEvent, ModuleAccessRouteData, NoSettingsDto, OipExtensionHostContext, OipExtensionLoadType, OipExtensionManifest, OipExtensionModuleMetadata, OipExtensionNavigateEvent, OipExtensionNotifyEvent, PutSecurityDto, RequestParams, SecurityDto, TopBarDto };
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ const { apiConfig, generateResponses, config } = it;
|
|
|
8
8
|
import { LayoutService } from "../services/app.layout.service";
|
|
9
9
|
import { SecurityService } from "../services/security.service";
|
|
10
10
|
import { inject, Injectable } from "@angular/core";
|
|
11
|
+
import { ActivatedRoute, Router } from "@angular/router";
|
|
11
12
|
import { firstValueFrom } from "rxjs";
|
|
12
13
|
|
|
13
14
|
export type QueryParamsType = Record<string | number, any>;
|
|
@@ -61,16 +62,41 @@ export enum ContentType {
|
|
|
61
62
|
export class HttpClient<SecurityDataType = unknown> {
|
|
62
63
|
protected securityService = inject(SecurityService);
|
|
63
64
|
protected layoutService = inject(LayoutService);
|
|
65
|
+
protected router = inject(Router);
|
|
64
66
|
public baseUrl: string = "<%~ apiConfig.baseUrl %>";
|
|
65
67
|
private securityWorker?: ApiConfig<SecurityDataType>["securityWorker"] =
|
|
66
|
-
() =>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
() => {
|
|
69
|
+
const moduleInstanceId = this.getCurrentModuleInstanceId();
|
|
70
|
+
return {
|
|
71
|
+
headers: {
|
|
72
|
+
"Accept-language": this.layoutService.language()
|
|
73
|
+
? this.layoutService.language()
|
|
74
|
+
: 'en',
|
|
75
|
+
"X-Timezone": this.layoutService.timeZone(),
|
|
76
|
+
...(moduleInstanceId != null
|
|
77
|
+
? { "X-Module-Instance-Id": String(moduleInstanceId) }
|
|
78
|
+
: {}),
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Reads the module instance id of the deepest activated route.
|
|
85
|
+
* The backend uses it to check module instance rights on endpoints that do not carry the id in their contract.
|
|
86
|
+
*/
|
|
87
|
+
protected getCurrentModuleInstanceId(): number | undefined {
|
|
88
|
+
// May run before the first navigation completes, when route snapshots are not available yet.
|
|
89
|
+
let route: ActivatedRoute | null | undefined = this.router.routerState?.root;
|
|
90
|
+
let id: string | null = null;
|
|
91
|
+
|
|
92
|
+
while (route) {
|
|
93
|
+
id = route.snapshot?.paramMap?.get("id") ?? id;
|
|
94
|
+
route = route.firstChild;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const parsed = id != null ? Number(id) : Number.NaN;
|
|
98
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
99
|
+
}
|
|
74
100
|
|
|
75
101
|
private abortControllers = new Map<CancelToken, AbortController>();
|
|
76
102
|
private customFetch = (...fetchParams: Parameters<typeof fetch>) => fetch(...fetchParams);
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"app-modules": {
|
|
3
|
-
"title": "Modules",
|
|
4
|
-
"refreshTooltip": "Refresh",
|
|
5
|
-
"register": {
|
|
6
|
-
"manifestUrlPlaceholder": "External module manifest URL",
|
|
7
|
-
"button": "Register"
|
|
8
|
-
},
|
|
9
|
-
"table": {
|
|
10
|
-
"moduleId": "Module ID",
|
|
11
|
-
"name": "Name",
|
|
12
|
-
"currentlyLoaded": "Currently Loaded",
|
|
13
|
-
"yes": "Yes",
|
|
14
|
-
"no": "No",
|
|
15
|
-
"deleteTooltip": "Delete"
|
|
16
|
-
},
|
|
17
|
-
"confirm": {
|
|
18
|
-
"header": "Warning",
|
|
19
|
-
"message": "Are you sure you want to delete the module?",
|
|
20
|
-
"cancel": "Cancel",
|
|
21
|
-
"delete": "Delete"
|
|
22
|
-
},
|
|
23
|
-
"messages": {
|
|
24
|
-
"deleteSuccess": "Module deleted",
|
|
25
|
-
"deleteError": "Module delete failed",
|
|
26
|
-
"registerError": "External module registration failed",
|
|
27
|
-
"registerSuccess": "External module registered"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"app-modules": {
|
|
3
|
-
"title": "Модули",
|
|
4
|
-
"refreshTooltip": "Обновить",
|
|
5
|
-
"register": {
|
|
6
|
-
"manifestUrlPlaceholder": "URL манифеста внешнего модуля",
|
|
7
|
-
"button": "Зарегистрировать"
|
|
8
|
-
},
|
|
9
|
-
"table": {
|
|
10
|
-
"moduleId": "ID модуля",
|
|
11
|
-
"name": "Название",
|
|
12
|
-
"currentlyLoaded": "Загружен",
|
|
13
|
-
"yes": "Да",
|
|
14
|
-
"no": "Нет",
|
|
15
|
-
"deleteTooltip": "Удалить"
|
|
16
|
-
},
|
|
17
|
-
"confirm": {
|
|
18
|
-
"header": "Внимание",
|
|
19
|
-
"message": "Вы уверены, что хотите удалить модуль?",
|
|
20
|
-
"cancel": "Отмена",
|
|
21
|
-
"delete": "Удалить"
|
|
22
|
-
},
|
|
23
|
-
"messages": {
|
|
24
|
-
"deleteSuccess": "Модуль удален",
|
|
25
|
-
"deleteError": "Не удалось удалить модуль",
|
|
26
|
-
"registerError": "Не удалось зарегистрировать внешний модуль",
|
|
27
|
-
"registerSuccess": "Внешний модуль зарегистрирован"
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"applications": {
|
|
3
|
-
"title": "Applications",
|
|
4
|
-
"subtitle": "Manage the frontend application registry",
|
|
5
|
-
"searchPlaceholder": "Search applications",
|
|
6
|
-
"search": "Search",
|
|
7
|
-
"clear": "Clear",
|
|
8
|
-
"add": "Add",
|
|
9
|
-
"refreshTooltip": "Refresh",
|
|
10
|
-
"empty": "No applications found",
|
|
11
|
-
"table": {
|
|
12
|
-
"code": "Code",
|
|
13
|
-
"displayName": "Name",
|
|
14
|
-
"baseUrl": "Base URL",
|
|
15
|
-
"internalBaseUrl": "Internal Base URL",
|
|
16
|
-
"icon": "Icon",
|
|
17
|
-
"order": "Order",
|
|
18
|
-
"enabled": "Enabled",
|
|
19
|
-
"serviceType": "Service type",
|
|
20
|
-
"current": "Current",
|
|
21
|
-
"actions": "Actions",
|
|
22
|
-
"yes": "Yes",
|
|
23
|
-
"no": "No",
|
|
24
|
-
"editTooltip": "Edit",
|
|
25
|
-
"deleteTooltip": "Delete",
|
|
26
|
-
"saveTooltip": "Save",
|
|
27
|
-
"cancelTooltip": "Cancel"
|
|
28
|
-
},
|
|
29
|
-
"serviceTypes": {
|
|
30
|
-
"service": "Service",
|
|
31
|
-
"application": "Application"
|
|
32
|
-
},
|
|
33
|
-
"confirm": {
|
|
34
|
-
"header": "Warning",
|
|
35
|
-
"message": "Are you sure you want to delete application {{displayName}}?",
|
|
36
|
-
"cancel": "Cancel",
|
|
37
|
-
"delete": "Delete"
|
|
38
|
-
},
|
|
39
|
-
"messages": {
|
|
40
|
-
"requiredFields": "Fill code, name and Base URL",
|
|
41
|
-
"createSuccess": "Application created",
|
|
42
|
-
"updateSuccess": "Application updated",
|
|
43
|
-
"deleteSuccess": "Application deleted"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"applications": {
|
|
3
|
-
"title": "Приложения",
|
|
4
|
-
"subtitle": "Управление реестром фронтенд-приложений",
|
|
5
|
-
"searchPlaceholder": "Поиск по приложениям",
|
|
6
|
-
"search": "Найти",
|
|
7
|
-
"clear": "Очистить",
|
|
8
|
-
"add": "Добавить",
|
|
9
|
-
"refreshTooltip": "Обновить",
|
|
10
|
-
"empty": "Приложения не найдены",
|
|
11
|
-
"table": {
|
|
12
|
-
"code": "Код",
|
|
13
|
-
"displayName": "Название",
|
|
14
|
-
"baseUrl": "Base URL",
|
|
15
|
-
"internalBaseUrl": "Internal Base URL",
|
|
16
|
-
"icon": "Иконка",
|
|
17
|
-
"order": "Порядок",
|
|
18
|
-
"enabled": "Включено",
|
|
19
|
-
"serviceType": "Тип сервиса",
|
|
20
|
-
"current": "Текущее",
|
|
21
|
-
"actions": "Действия",
|
|
22
|
-
"yes": "Да",
|
|
23
|
-
"no": "Нет",
|
|
24
|
-
"editTooltip": "Редактировать",
|
|
25
|
-
"deleteTooltip": "Удалить",
|
|
26
|
-
"saveTooltip": "Сохранить",
|
|
27
|
-
"cancelTooltip": "Отменить"
|
|
28
|
-
},
|
|
29
|
-
"serviceTypes": {
|
|
30
|
-
"service": "Сервис",
|
|
31
|
-
"application": "Приложение"
|
|
32
|
-
},
|
|
33
|
-
"confirm": {
|
|
34
|
-
"header": "Внимание",
|
|
35
|
-
"message": "Вы уверены, что хотите удалить приложение {{displayName}}?",
|
|
36
|
-
"cancel": "Отмена",
|
|
37
|
-
"delete": "Удалить"
|
|
38
|
-
},
|
|
39
|
-
"messages": {
|
|
40
|
-
"requiredFields": "Заполните код, название и Base URL",
|
|
41
|
-
"createSuccess": "Приложение создано",
|
|
42
|
-
"updateSuccess": "Приложение обновлено",
|
|
43
|
-
"deleteSuccess": "Приложение удалено"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"config": {
|
|
3
|
-
"all": "All",
|
|
4
|
-
"applicationManagement": "Application management",
|
|
5
|
-
"dateFormat": "Date format",
|
|
6
|
-
"dateTimeFormat": "Date and time format:",
|
|
7
|
-
"goTo": "Go to",
|
|
8
|
-
"localization": "Localization",
|
|
9
|
-
"menu": "Menu",
|
|
10
|
-
"moduleManagement": "Module management",
|
|
11
|
-
"photo": "Photo",
|
|
12
|
-
"profile": "Profile",
|
|
13
|
-
"selectLanguage": "Select language",
|
|
14
|
-
"timeFormat": "Time format",
|
|
15
|
-
"timeZone": "Time zone",
|
|
16
|
-
"usePhoto256x256Pixel": "Use photo 256x256 pixel"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"config": {
|
|
3
|
-
"all": "Все",
|
|
4
|
-
"applicationManagement": "Управление приложениями",
|
|
5
|
-
"dateFormat": "Формат даты",
|
|
6
|
-
"dateTimeFormat": "Формат даты и времени:",
|
|
7
|
-
"goTo": "Перейти",
|
|
8
|
-
"localization": "Локализация",
|
|
9
|
-
"menu": "Меню",
|
|
10
|
-
"moduleManagement": "Управление модулями",
|
|
11
|
-
"photo": "Фото",
|
|
12
|
-
"profile": "Профиль",
|
|
13
|
-
"selectLanguage": "Выберите язык",
|
|
14
|
-
"timeFormat": "Формат времени",
|
|
15
|
-
"timeZone": "Часовой пояс",
|
|
16
|
-
"usePhoto256x256Pixel": "Используйте фото 256x256 пикселей"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"db-migration": {
|
|
3
|
-
"migrationManager": "Migration manager",
|
|
4
|
-
"actions": {
|
|
5
|
-
"refresh": "Refresh",
|
|
6
|
-
"cleanFilter": "Clean filter",
|
|
7
|
-
"applyMigration": "Apply migration"
|
|
8
|
-
},
|
|
9
|
-
"columns": {
|
|
10
|
-
"name": "Migration name",
|
|
11
|
-
"applied": "Applied",
|
|
12
|
-
"exist": "Exist",
|
|
13
|
-
"pending": "Pending"
|
|
14
|
-
},
|
|
15
|
-
"messages": {
|
|
16
|
-
"errorRefreshing": "Error refreshing database"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"db-migration": {
|
|
3
|
-
"migrationManager": "Менеджер миграций",
|
|
4
|
-
"actions": {
|
|
5
|
-
"refresh": "Обновить",
|
|
6
|
-
"cleanFilter": "Очистить фильтр",
|
|
7
|
-
"applyMigration": "Применить миграцию"
|
|
8
|
-
},
|
|
9
|
-
"columns": {
|
|
10
|
-
"name": "Название миграции",
|
|
11
|
-
"applied": "Применена",
|
|
12
|
-
"exist": "Существует",
|
|
13
|
-
"pending": "Ожидает"
|
|
14
|
-
},
|
|
15
|
-
"messages": {
|
|
16
|
-
"errorRefreshing": "Ошибка обновления базы данных"
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|