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/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, Router } from '@angular/router';
7
- import { InterpolationParameters, Translation, TranslationObject, TranslateService } from '@ngx-translate/core';
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, id?: number | undefined): Promise<TSettings>;
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 GetModuleInstanceSettingsParams2 {
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: (query: GetModuleInstanceSettingsParams2, params?: RequestParams) => Promise<FolderModuleSettings>;
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: (query: GetModuleInstanceSettingsParams4, params?: RequestParams) => Promise<IframeModuleSettings>;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oip-common",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "A template for cross-platform web applications based on sakai-ng and primeNG",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -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
- headers: {
68
- "Accept-language": this.layoutService.language()
69
- ? this.layoutService.language()
70
- : 'en',
71
- "X-Timezone": this.layoutService.timeZone(),
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
- }