oip-common 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +3 -0
  2. package/package.json +24 -5
  3. package/ng-package.json +0 -19
  4. package/src/api/FolderModule.ts +0 -124
  5. package/src/api/Menu.ts +0 -134
  6. package/src/api/Module.ts +0 -92
  7. package/src/api/Security.ts +0 -40
  8. package/src/api/Service.ts +0 -57
  9. package/src/api/data-contracts.ts +0 -186
  10. package/src/api/http-client.ts +0 -276
  11. package/src/components/app-configurator.component.ts +0 -491
  12. package/src/components/app-floating-configurator.component.ts +0 -47
  13. package/src/components/app-modules.component.ts +0 -144
  14. package/src/components/app.layout.component.ts +0 -130
  15. package/src/components/auth/access/access.component.ts +0 -42
  16. package/src/components/auth/error/error.component.ts +0 -42
  17. package/src/components/auth/login/login.component.ts +0 -120
  18. package/src/components/auth/unauthorized/unauthorized.component.ts +0 -51
  19. package/src/components/base-module.component.ts +0 -258
  20. package/src/components/config.component.ts +0 -131
  21. package/src/components/db-migration/db-migration.component.ts +0 -164
  22. package/src/components/db-migration.component.ts +0 -155
  23. package/src/components/footer.component.ts +0 -17
  24. package/src/components/logo.component.ts +0 -34
  25. package/src/components/menu/menu-item-create-dialog.component.ts +0 -119
  26. package/src/components/menu/menu-item-edit-dialog.component.ts +0 -124
  27. package/src/components/menu/menu-item.component.ts +0 -295
  28. package/src/components/menu/menu.component.ts +0 -85
  29. package/src/components/notfound.component.ts +0 -31
  30. package/src/components/profile.component.ts +0 -44
  31. package/src/components/security.component.ts +0 -102
  32. package/src/components/sidebar.component.ts +0 -12
  33. package/src/components/top-bar.component.ts +0 -147
  34. package/src/dtos/context-menu-item.dto.ts +0 -23
  35. package/src/dtos/edit-module-instance.dto.ts +0 -8
  36. package/src/dtos/no-settings.dto.ts +0 -4
  37. package/src/dtos/put-security.dto.ts +0 -6
  38. package/src/dtos/security.dto.ts +0 -6
  39. package/src/dtos/top-bar.dto.ts +0 -13
  40. package/src/events/menu-change.event.ts +0 -23
  41. package/src/helpers/date.helper.ts +0 -94
  42. package/src/intercepts/i18n-intercept.service.ts +0 -13
  43. package/src/modules/http-loader.factory.ts +0 -40
  44. package/src/modules/secure.pipe.ts +0 -19
  45. package/src/public-api.ts +0 -42
  46. package/src/services/app-title.service.ts +0 -22
  47. package/src/services/app.layout.service.ts +0 -236
  48. package/src/services/app.menu.service.ts +0 -64
  49. package/src/services/auth.service.ts +0 -58
  50. package/src/services/base-data.service.ts +0 -74
  51. package/src/services/l10n.service.ts +0 -71
  52. package/src/services/msg.service.ts +0 -76
  53. package/src/services/security-data.service.ts +0 -19
  54. package/src/services/security-storage.service.ts +0 -21
  55. package/src/services/security.service.ts +0 -116
  56. package/src/services/top-bar.service.ts +0 -44
  57. package/src/services/user.service.ts +0 -77
  58. package/src/test.ts +0 -11
  59. package/src/user-api/UserProfile.ts +0 -85
  60. package/src/user-api/data-contracts.ts +0 -42
  61. package/src/user-api/http-client.ts +0 -253
  62. package/templates/api.ejs +0 -30
  63. package/templates/data-contract-jsdoc.ejs +0 -37
  64. package/templates/data-contracts.ejs +0 -52
  65. package/templates/enum-data-contract.ejs +0 -12
  66. package/templates/http-client.ejs +0 -245
  67. package/templates/interface-data-contract.ejs +0 -10
  68. package/templates/object-field-jsdoc.ejs +0 -28
  69. package/templates/procedure-call.ejs +0 -100
  70. package/templates/route-docs.ejs +0 -29
  71. package/templates/route-name.ejs +0 -42
  72. package/templates/route-type.ejs +0 -23
  73. package/templates/route-types.ejs +0 -18
  74. package/templates/type-data-contract.ejs +0 -15
  75. package/tsconfig.lib.json +0 -12
  76. package/tsconfig.lib.prod.json +0 -10
  77. package/tsconfig.spec.json +0 -9
  78. /package/{src/assets → assets}/demo/code.scss +0 -0
  79. /package/{src/assets → assets}/demo/demo.scss +0 -0
  80. /package/{src/assets → assets}/demo/flags/flags.scss +0 -0
  81. /package/{src/assets → assets}/demo/flags/flags_responsive.png +0 -0
  82. /package/{src/assets → assets}/demo/images/access/asset-access.svg +0 -0
  83. /package/{src/assets → assets}/demo/images/error/asset-error.svg +0 -0
  84. /package/{src/assets → assets}/demo/images/flag/flag_placeholder.png +0 -0
  85. /package/{src/assets → assets}/favicon.svg +0 -0
  86. /package/{src/assets → assets}/i18n/app-modules.en.json +0 -0
  87. /package/{src/assets → assets}/i18n/app-modules.ru.json +0 -0
  88. /package/{src/assets → assets}/i18n/config.en.json +0 -0
  89. /package/{src/assets → assets}/i18n/config.ru.json +0 -0
  90. /package/{src/assets → assets}/layout/_core.scss +0 -0
  91. /package/{src/assets → assets}/layout/_footer.scss +0 -0
  92. /package/{src/assets → assets}/layout/_logo.scss +0 -0
  93. /package/{src/assets → assets}/layout/_main.scss +0 -0
  94. /package/{src/assets → assets}/layout/_menu.scss +0 -0
  95. /package/{src/assets → assets}/layout/_mixins.scss +0 -0
  96. /package/{src/assets → assets}/layout/_preloading.scss +0 -0
  97. /package/{src/assets → assets}/layout/_responsive.scss +0 -0
  98. /package/{src/assets → assets}/layout/_topbar.scss +0 -0
  99. /package/{src/assets → assets}/layout/_typography.scss +0 -0
  100. /package/{src/assets → assets}/layout/_utils.scss +0 -0
  101. /package/{src/assets → assets}/layout/layout.scss +0 -0
  102. /package/{src/assets → assets}/layout/variables/_common.scss +0 -0
  103. /package/{src/assets → assets}/layout/variables/_dark.scss +0 -0
  104. /package/{src/assets → assets}/layout/variables/_light.scss +0 -0
  105. /package/{src/assets → assets}/oip-common.scss +0 -0
  106. /package/{src/assets → assets}/tailwind.css +0 -0
@@ -1,12 +0,0 @@
1
- import { Component } from '@angular/core';
2
- import { MenuComponent } from './menu/menu.component';
3
-
4
- @Component({
5
- selector: 'app-sidebar',
6
- template: ` <app-menu></app-menu>`,
7
- standalone: true,
8
- imports: [MenuComponent]
9
- })
10
- export class SidebarComponent {
11
- constructor() {}
12
- }
@@ -1,147 +0,0 @@
1
- import { Component, inject } from '@angular/core';
2
- import { MenuItem } from 'primeng/api';
3
- import { RouterModule } from '@angular/router';
4
- import { CommonModule } from '@angular/common';
5
- import { StyleClassModule } from 'primeng/styleclass';
6
- import { LayoutService } from '../services/app.layout.service';
7
- import { AppConfiguratorComponent } from './app-configurator.component';
8
- import { LogoComponent } from './logo.component';
9
- import { SecurityService } from '../services/security.service';
10
- import { TopBarService } from '../services/top-bar.service';
11
- import { Tab, TabList, Tabs } from 'primeng/tabs';
12
- import { AvatarModule } from 'primeng/avatar';
13
- import { UserService } from '../services/user.service';
14
- import { ButtonModule } from 'primeng/button';
15
-
16
- @Component({
17
- selector: 'app-topbar',
18
- standalone: true,
19
- imports: [
20
- RouterModule,
21
- CommonModule,
22
- StyleClassModule,
23
- AppConfiguratorComponent,
24
- LogoComponent,
25
- Tabs,
26
- TabList,
27
- Tab,
28
- AvatarModule,
29
- ButtonModule
30
- ],
31
- template: ` <div class="layout-topbar">
32
- <div class="layout-topbar-logo-container">
33
- <button class="layout-menu-button layout-topbar-action" (click)="layoutService.onMenuToggle()">
34
- <i class="pi pi-bars"></i>
35
- </button>
36
- <a class="layout-topbar-logo" id="oip-app-topbar-logo-link" routerLink="">
37
- <logo [height]="36" [width]="36"></logo>
38
- <span>OIP</span>
39
- </a>
40
- </div>
41
-
42
- @if (securityService.isAdmin && topBarService.topBarItems.length > 0) {
43
- <p-tabs class="layout-topbar-tabs ml-2" [(value)]="topBarService.activeId">
44
- <p-tablist>
45
- @for (tab of topBarService.availableTopBarItems; track tab.id) {
46
- <p-tab id="oip-app-topbar-tab-{{ tab.id }}" [value]="tab.id">
47
- <i class="pi {{ tab.icon }}"></i>
48
- <span class="ml-2">{{ tab.caption }}</span>
49
- </p-tab>
50
- }
51
- </p-tablist>
52
- </p-tabs>
53
- }
54
- <div class="layout-topbar-actions">
55
- <div class="layout-config-menu">
56
- <p-button
57
- class="layout-topbar-action"
58
- id="oip-app-topbar-theme-button"
59
- severity="secondary"
60
- type="button"
61
- [rounded]="true"
62
- [text]="true"
63
- (click)="toggleDarkMode()">
64
- <i
65
- class="pi"
66
- [ngClass]="{
67
- 'pi-moon': layoutService.isDarkTheme(),
68
- 'pi-sun': !layoutService.isDarkTheme()
69
- }"></i>
70
- </p-button>
71
- <div class="relative">
72
- <p-button
73
- class="layout-topbar-action layout-topbar-action-highlight"
74
- enterActiveClass="animate-scalein"
75
- enterFromClass="hidden"
76
- id="oip-app-topbar-palette-button"
77
- leaveActiveClass="animate-fadeout"
78
- leaveToClass="hidden"
79
- pStyleClass="@next"
80
- [hideOnOutsideClick]="true"
81
- [rounded]="true">
82
- <i class="pi pi-palette"></i>
83
- </p-button>
84
- <app-configurator />
85
- </div>
86
- </div>
87
-
88
- <button
89
- class="layout-topbar-menu-button layout-topbar-action"
90
- enterActiveClass="animate-scalein"
91
- enterFromClass="hidden"
92
- id="oip-app-topbar-menu-expand-button"
93
- leaveActiveClass="animate-fadeout"
94
- leaveToClass="hidden"
95
- pStyleClass="@next"
96
- [hideOnOutsideClick]="true">
97
- <i class="pi pi-ellipsis-v"></i>
98
- </button>
99
-
100
- <div class="layout-topbar-menu hidden lg:block">
101
- <div class="layout-topbar-menu-content">
102
- <button
103
- class="layout-topbar-action"
104
- id="oip-app-topbar-logout-button"
105
- type="button"
106
- (click)="securityService.logout()"
107
- (keydown)="logoutKeyDown($event)">
108
- <i class="pi pi-sign-out"></i>
109
- <span>Logout</span>
110
- </button>
111
- <button class="layout-topbar-action" routerLink="config">
112
- <p-avatar
113
- class="p-link flex align-items-center"
114
- id="oip-app-topbar-user-avatar"
115
- shape="circle"
116
- size="normal"
117
- [image]="userService.photoLoaded ? userService.photo : null"
118
- >{{ !userService.photoLoaded ? userService.shortLabel : null }}
119
- </p-avatar>
120
- <span class="ml-2">Profile</span>
121
- </button>
122
- </div>
123
- </div>
124
- </div>
125
- </div>`
126
- })
127
- export class AppTopbar {
128
- items!: MenuItem[];
129
- securityService = inject(SecurityService);
130
- topBarService = inject(TopBarService);
131
- userService = inject(UserService);
132
-
133
- constructor(public layoutService: LayoutService) {}
134
-
135
- toggleDarkMode() {
136
- this.layoutService.layoutConfig.update((state) => ({
137
- ...state,
138
- darkTheme: !state.darkTheme
139
- }));
140
- }
141
-
142
- logoutKeyDown($event: KeyboardEvent) {
143
- if ($event.key === 'Enter') {
144
- this.securityService.logout();
145
- }
146
- }
147
- }
@@ -1,23 +0,0 @@
1
- import { IsActiveMatchOptions, Params, QueryParamsHandling } from '@angular/router';
2
-
3
- export interface ContextMenuItemDto {
4
- url: any;
5
- class: string | string[] | Set<string> | { [p: string]: any } | null | undefined;
6
- command: any;
7
- disabled: boolean;
8
- fragment: string | undefined;
9
- icon: string | string[] | Set<string> | { [p: string]: any } | null | undefined;
10
- items: ContextMenuItemDto[];
11
- label: string;
12
- preserveFragment: unknown;
13
- queryParamsHandling: QueryParamsHandling | null | undefined;
14
- routerLink: string;
15
- routerLinkActiveOptions: { exact: boolean } | IsActiveMatchOptions;
16
- visible: boolean;
17
- skipLocationChange: unknown;
18
- queryParams: Params | null | undefined;
19
- target: string;
20
- state: { [p: string]: any } | undefined;
21
- replaceUrl: unknown;
22
- badgeClass: string;
23
- }
@@ -1,8 +0,0 @@
1
- export interface EditModuleInstanceDto {
2
- moduleInstanceId: number;
3
- moduleId: number;
4
- parentId: number;
5
- label: string;
6
- icon: string;
7
- viewRoles: string[];
8
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * A data transfer object indicating the absence of settings.
3
- */
4
- export interface NoSettingsDto {}
@@ -1,6 +0,0 @@
1
- import { SecurityDto } from './security.dto';
2
-
3
- export interface PutSecurityDto {
4
- id: number;
5
- securities: SecurityDto[];
6
- }
@@ -1,6 +0,0 @@
1
- export interface SecurityDto {
2
- code: string;
3
- name: string;
4
- description: string;
5
- roles: string[];
6
- }
@@ -1,13 +0,0 @@
1
- // TopBarDto interface
2
- export interface TopBarDto {
3
- // Identifier of item
4
- id: 'content' | 'settings' | 'security';
5
- // Icon from prime icon
6
- icon: string;
7
- // Caption
8
- caption: string;
9
- // Claims from SSO
10
- claims?: string[];
11
- // Method from module call when index toolbar change
12
- click?(): void;
13
- }
@@ -1,23 +0,0 @@
1
- import { ContextMenuItemDto } from '../dtos/context-menu-item.dto';
2
-
3
- /**
4
- * Represents an event triggered when a menu item is clicked.
5
- * @interface MenuChangeEvent
6
- * @class
7
- */
8
- export interface MenuChangeEvent {
9
- /**
10
- * A string representing a key, used for identification or access.
11
- */
12
- key: string;
13
- /**
14
- * Indicates whether a route event has occurred.
15
- * @type {boolean}
16
- */
17
- routeEvent?: boolean;
18
- /**
19
- * Represents a single item within a context menu. Contains data necessary to display the item
20
- * and execute its associated action.
21
- */
22
- item: ContextMenuItemDto;
23
- }
@@ -1,94 +0,0 @@
1
- /**
2
- * Convert Date to string in format 2022-02-22
3
- * @param date
4
- */
5
- export function dateToString(date: Date): string {
6
- const year = date.getFullYear();
7
- const month = (date.getMonth() + 1).toString().padStart(2, '0');
8
- const day = date.getDate().toString().padStart(2, '0');
9
-
10
- return `${year}-${month}-${day}`;
11
- }
12
-
13
- /**
14
- * Convert string in format 2022-02-22 to Date
15
- * @param date
16
- */
17
- export function stringToDate(date: string): Date {
18
- const dateParts = date.split('-');
19
- const day = parseInt(dateParts[2], 10);
20
- const month = parseInt(dateParts[1], 10) - 1;
21
- const year = parseInt(dateParts[0], 10);
22
-
23
- return new Date(year, month, day);
24
- }
25
-
26
- /**
27
- * Add days to date
28
- * @param date
29
- * @param days
30
- */
31
- export function addDays(date: Date, days: number): Date {
32
- const clonedDate = structuredClone(date);
33
- clonedDate.setDate(clonedDate.getDate() + days);
34
- return clonedDate;
35
- }
36
-
37
- /**
38
- * Get today's date
39
- * @param date
40
- */
41
- export function getTodayDate(): Date {
42
- const date = new Date();
43
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
44
- }
45
-
46
- /* Convert dateformat from DatePipe to PrimeNG*/
47
- export function convertToPrimeNgDateFormat(dateformat: string): string {
48
- switch (dateformat) {
49
- case 'dd.MM.yyyy':
50
- return 'dd.mm.yy';
51
- case 'dd.MM.yy':
52
- return 'dd.mm.y';
53
- case 'yyyy-MM-dd':
54
- return 'yy-mm-dd';
55
- case 'dd.MMM.yyyy':
56
- return 'dd.M.yy';
57
- default:
58
- console.error(`Failed to convert format: ${dateformat}`);
59
- }
60
- }
61
-
62
- /**
63
- * Convert all properties of an object with string dates to Date objects
64
- * @param obj
65
- */
66
- export function restoreDates(obj: any) {
67
- if (obj === null || typeof obj !== 'object') return obj;
68
-
69
- if (Array.isArray(obj)) {
70
- return obj.map((item) => restoreDates(item));
71
- }
72
-
73
- const result = {};
74
- for (const key in obj) {
75
- const value = obj[key];
76
-
77
- if (typeof value === 'string' && isIsoDate(value)) {
78
- result[key] = new Date(value);
79
- } else if (typeof value === 'object' && value !== null && !(value instanceof Date)) {
80
- result[key] = restoreDates(value);
81
- } else {
82
- result[key] = value;
83
- }
84
- }
85
- return result;
86
- }
87
-
88
- /**
89
- * Check if a string is a date in ISO format
90
- * @param str
91
- */
92
- export function isIsoDate(str: string) {
93
- return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/.test(str);
94
- }
@@ -1,13 +0,0 @@
1
- import { inject } from '@angular/core';
2
- import { HttpInterceptorFn } from '@angular/common/http';
3
- import { LayoutService } from '../services/app.layout.service';
4
-
5
- export const langIntercept: HttpInterceptorFn = (req, next) => {
6
- const layoutService = inject(LayoutService);
7
- const lang = layoutService.language() ? layoutService.language() : 'en';
8
- const httpHeaders = req.headers.set('Accept-language', lang);
9
- const authReq = req.clone({
10
- headers: httpHeaders
11
- });
12
- return next(authReq);
13
- };
@@ -1,40 +0,0 @@
1
- import { HttpClient } from '@angular/common/http';
2
- import { map, Observable } from 'rxjs';
3
- import { OpenIdConfiguration, StsConfigHttpLoader } from 'angular-auth-oidc-client';
4
- import { GetKeycloakClientSettingsResponse } from '../api/data-contracts';
5
-
6
- /**
7
- * Load keycloak settings from backend and save to sessionStorage
8
- * @param httpClient
9
- * @returns StsConfigHttpLoader
10
- */
11
- export const httpLoaderAuthFactory = (httpClient: HttpClient) => {
12
- const KEYCLOAK_SETTINGS_KEY = 'keycloak-client-settings';
13
- const settingsStings = sessionStorage.getItem(KEYCLOAK_SETTINGS_KEY);
14
- if (settingsStings) {
15
- const config$ = new Observable<GetKeycloakClientSettingsResponse>((subscribe) => {
16
- subscribe.next(JSON.parse(settingsStings));
17
- });
18
- return new StsConfigHttpLoader(config$);
19
- } else {
20
- const config$ = httpClient.get<GetKeycloakClientSettingsResponse>(`api/security/get-keycloak-client-settings`).pipe(
21
- map((config: GetKeycloakClientSettingsResponse) => {
22
- const authConfig: OpenIdConfiguration = {
23
- authority: config.authority,
24
- redirectUrl: window.location.origin,
25
- postLogoutRedirectUri: window.location.origin,
26
- clientId: config.clientId,
27
- scope: config.scope,
28
- responseType: config.responseType,
29
- useRefreshToken: config.useRefreshToken,
30
- silentRenew: config.silentRenew,
31
- logLevel: config.logLevel,
32
- secureRoutes: config.secureRoutes
33
- };
34
- sessionStorage.setItem(KEYCLOAK_SETTINGS_KEY, JSON.stringify(authConfig));
35
- return authConfig;
36
- })
37
- );
38
- return new StsConfigHttpLoader(config$);
39
- }
40
- };
@@ -1,19 +0,0 @@
1
- import { inject, Pipe, PipeTransform } from '@angular/core';
2
- import { HttpClient } from '@angular/common/http';
3
- import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
4
- import { map, Observable } from 'rxjs';
5
-
6
- @Pipe({
7
- standalone: true,
8
- name: 'secure'
9
- })
10
- export class SecurePipe implements PipeTransform {
11
- private readonly http = inject(HttpClient);
12
- private readonly sanitizer = inject(DomSanitizer);
13
-
14
- transform(url: any): Observable<SafeUrl> {
15
- return this.http
16
- .get(url, { responseType: 'blob' })
17
- .pipe(map((val) => this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(val))));
18
- }
19
- }
package/src/public-api.ts DELETED
@@ -1,42 +0,0 @@
1
- // Components
2
- export * from './components/base-module.component';
3
- export * from './components/security.component';
4
- export * from './components/top-bar.component';
5
- export * from './components/footer.component';
6
- export * from './components/menu/menu.component';
7
- export * from './components/app.layout.component';
8
- export * from './components/sidebar.component';
9
- export * from './components/logo.component';
10
- export * from './components/notfound.component';
11
- export * from './components/auth/unauthorized/unauthorized.component';
12
- export * from './components/auth/error/error.component';
13
- export * from './components/profile.component';
14
- export { ConfigComponent } from './components/config.component';
15
- export * from './components/db-migration.component';
16
- export { AppModulesComponent } from './components/app-modules.component';
17
-
18
- // Dtos
19
- export * from './dtos/top-bar.dto';
20
- export * from './dtos/security.dto';
21
- export * from './dtos/put-security.dto';
22
- export * from './dtos/no-settings.dto';
23
-
24
- // Services
25
- export * from './services/base-data.service';
26
- export * from './services/top-bar.service';
27
- export * from './services/security.service';
28
- export * from './services/security-data.service';
29
- export * from './services/msg.service';
30
- export * from './services/auth.service';
31
- export * from './services/app.layout.service';
32
- export * from './services/app.menu.service';
33
- export * from './services/user.service';
34
- export * from './services/security-storage.service';
35
-
36
- // Events
37
- export * from './events/menu-change.event';
38
-
39
- // other
40
- export { langIntercept } from './intercepts/i18n-intercept.service';
41
- export { SecurePipe } from './modules/secure.pipe';
42
- export { httpLoaderAuthFactory } from './modules/http-loader.factory';
@@ -1,22 +0,0 @@
1
- import { inject, Injectable } from '@angular/core';
2
- import { BehaviorSubject } from 'rxjs';
3
- import { Title } from '@angular/platform-browser';
4
-
5
- /**
6
- * Service to manage the application title.
7
- */
8
- @Injectable({ providedIn: 'root' })
9
- export class AppTitleService {
10
- private readonly title = inject(Title);
11
- private titleSubject = new BehaviorSubject<string>('');
12
- public title$ = this.titleSubject.asObservable();
13
-
14
- /**
15
- * Set the title of the current HTML document.
16
- * @param newTitle
17
- */
18
- setTitle(newTitle: string): void {
19
- this.title.setTitle(newTitle);
20
- this.titleSubject.next(newTitle);
21
- }
22
- }