@corp-products/app-core 2.0.4 → 2.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.
- package/eslint.config.js +48 -0
- package/ng-package.json +7 -0
- package/package.json +20 -36
- package/project.json +29 -0
- package/{index.d.ts → src/index.ts} +10 -10
- package/src/lib/core/components/global-loader/global-loader.component.html +18 -0
- package/src/lib/core/components/global-loader/global-loader.component.scss +0 -0
- package/src/lib/core/components/global-loader/global-loader.component.spec.ts +24 -0
- package/src/lib/core/components/global-loader/global-loader.component.ts +16 -0
- package/{lib/core/components/index.d.ts → src/lib/core/components/index.ts} +1 -1
- package/src/lib/core/components/no-access/no-access.component.html +9 -0
- package/src/lib/core/components/no-access/no-access.component.ts +17 -0
- package/src/lib/core/core-config.ts +21 -0
- package/src/lib/core/directives/index.ts +2 -0
- package/src/lib/core/directives/permissions.directive.ts +114 -0
- package/src/lib/core/directives/responsive-element.directive.ts +46 -0
- package/src/lib/core/enums/date-formatter.enum.ts +16 -0
- package/src/lib/core/enums/display-types.enum.ts +4 -0
- package/src/lib/core/enums/index.ts +4 -0
- package/src/lib/core/enums/localization.enum.ts +9 -0
- package/src/lib/core/enums/user-permissions.enum.ts +36 -0
- package/src/lib/core/guards/auth.guard.ts +17 -0
- package/{lib/core/guards/index.d.ts → src/lib/core/guards/index.ts} +2 -2
- package/src/lib/core/guards/permissions.guard.ts +17 -0
- package/src/lib/core/handlers/http-context-handler.ts +14 -0
- package/{lib/core/handlers/index.d.ts → src/lib/core/handlers/index.ts} +3 -3
- package/src/lib/core/handlers/storage-handler.ts +37 -0
- package/src/lib/core/handlers/stortage.ts +7 -0
- package/src/lib/core/interceptors/app-http-config.ts +8 -0
- package/src/lib/core/interceptors/base-http.interceptor.ts +53 -0
- package/src/lib/core/interceptors/global-http-error.interceptor.ts +21 -0
- package/{lib/core/interceptors/index.d.ts → src/lib/core/interceptors/index.ts} +3 -3
- package/src/lib/core/interfaces/index.ts +4 -0
- package/{lib/core/interfaces/jwt-token-decoded.interface.d.ts → src/lib/core/interfaces/jwt-token-decoded.interface.ts} +7 -7
- package/src/lib/core/interfaces/list-response.interface.ts +5 -0
- package/src/lib/core/interfaces/router-data.interface.ts +20 -0
- package/src/lib/core/interfaces/toaster.interface.ts +5 -0
- package/src/lib/core/interfaces/user-info.interface.ts +4 -0
- package/src/lib/core/interfaces/user-profile-data.ts +19 -0
- package/src/lib/core/services/auth.service.ts +63 -0
- package/src/lib/core/services/base-http-service/base-http-response.ts +14 -0
- package/src/lib/core/services/base-http-service/base-http-types.ts +42 -0
- package/src/lib/core/services/base-http-service/base-http-utils.ts +43 -0
- package/src/lib/core/services/base-http-service/base-http.service.ts +106 -0
- package/src/lib/core/services/base-http-service/http-context-handler.ts +9 -0
- package/{lib/core/services/base-http-service/index.d.ts → src/lib/core/services/base-http-service/index.ts} +4 -4
- package/src/lib/core/services/base-pagination-service/base-pagination.service.ts +59 -0
- package/{lib/core/services/base-pagination-service/index.d.ts → src/lib/core/services/base-pagination-service/index.ts} +3 -3
- package/src/lib/core/services/base-pagination-service/list-options.interface.ts +8 -0
- package/src/lib/core/services/base-pagination-service/pagination.ts +6 -0
- package/src/lib/core/services/detect-device.service.ts +80 -0
- package/src/lib/core/services/enviroment.base.service.ts +16 -0
- package/src/lib/core/services/error-handler.service.ts +58 -0
- package/{lib/core/services/index.d.ts → src/lib/core/services/index.ts} +9 -8
- package/src/lib/core/services/jwt-decoder.service.ts +23 -0
- package/src/lib/core/services/loader.service.ts +32 -0
- package/src/lib/core/services/lov.service.ts +22 -0
- package/src/lib/core/services/permissions.service.ts +66 -0
- package/src/lib/core/services/toaster.service.ts +65 -0
- package/src/lib/core/utilities/index.ts +0 -0
- package/tsconfig.json +26 -0
- package/tsconfig.lib.json +11 -0
- package/tsconfig.lib.prod.json +9 -0
- package/esm2022/corp-products-app-core.mjs +0 -5
- package/esm2022/index.mjs +0 -11
- package/esm2022/lib/core/components/global-loader/global-loader.component.mjs +0 -20
- package/esm2022/lib/core/components/index.mjs +0 -2
- package/esm2022/lib/core/core-config.mjs +0 -4
- package/esm2022/lib/core/directives/index.mjs +0 -2
- package/esm2022/lib/core/directives/permissions.directive.mjs +0 -99
- package/esm2022/lib/core/enums/index.mjs +0 -2
- package/esm2022/lib/core/enums/user-permissions.enum.mjs +0 -38
- package/esm2022/lib/core/guards/auth.guard.mjs +0 -14
- package/esm2022/lib/core/guards/index.mjs +0 -3
- package/esm2022/lib/core/guards/permissions.guard.mjs +0 -16
- package/esm2022/lib/core/handlers/http-context-handler.mjs +0 -12
- package/esm2022/lib/core/handlers/index.mjs +0 -4
- package/esm2022/lib/core/handlers/storage-handler.mjs +0 -33
- package/esm2022/lib/core/handlers/stortage.mjs +0 -9
- package/esm2022/lib/core/interceptors/app-http-config.mjs +0 -9
- package/esm2022/lib/core/interceptors/base-http.interceptor.mjs +0 -53
- package/esm2022/lib/core/interceptors/global-http-error.interceptor.mjs +0 -17
- package/esm2022/lib/core/interceptors/index.mjs +0 -4
- package/esm2022/lib/core/interfaces/index.mjs +0 -5
- package/esm2022/lib/core/interfaces/jwt-token-decoded.interface.mjs +0 -2
- package/esm2022/lib/core/interfaces/list-response.interface.mjs +0 -2
- package/esm2022/lib/core/interfaces/router-data.interface.mjs +0 -2
- package/esm2022/lib/core/interfaces/toaster.interface.mjs +0 -2
- package/esm2022/lib/core/interfaces/user-info.interface.mjs +0 -2
- package/esm2022/lib/core/interfaces/user-profile-data.mjs +0 -2
- package/esm2022/lib/core/services/auth.service.mjs +0 -64
- package/esm2022/lib/core/services/base-http-service/base-http-response.mjs +0 -2
- package/esm2022/lib/core/services/base-http-service/base-http-types.mjs +0 -2
- package/esm2022/lib/core/services/base-http-service/base-http-utils.mjs +0 -32
- package/esm2022/lib/core/services/base-http-service/base-http.service.mjs +0 -79
- package/esm2022/lib/core/services/base-http-service/index.mjs +0 -5
- package/esm2022/lib/core/services/base-pagination-service/base-pagination.service.mjs +0 -49
- package/esm2022/lib/core/services/base-pagination-service/index.mjs +0 -4
- package/esm2022/lib/core/services/base-pagination-service/list-options.interface.mjs +0 -2
- package/esm2022/lib/core/services/base-pagination-service/pagination.mjs +0 -8
- package/esm2022/lib/core/services/error-handler.service.mjs +0 -76
- package/esm2022/lib/core/services/index.mjs +0 -9
- package/esm2022/lib/core/services/jwt-decoder.service.mjs +0 -25
- package/esm2022/lib/core/services/loader.service.mjs +0 -33
- package/esm2022/lib/core/services/lov.service.mjs +0 -26
- package/esm2022/lib/core/services/permissions.service.mjs +0 -64
- package/esm2022/lib/core/services/toaster.service.mjs +0 -67
- package/fesm2022/corp-products-app-core.mjs +0 -802
- package/fesm2022/corp-products-app-core.mjs.map +0 -1
- package/lib/core/components/global-loader/global-loader.component.d.ts +0 -9
- package/lib/core/core-config.d.ts +0 -17
- package/lib/core/directives/index.d.ts +0 -1
- package/lib/core/directives/permissions.directive.d.ts +0 -31
- package/lib/core/enums/index.d.ts +0 -1
- package/lib/core/enums/user-permissions.enum.d.ts +0 -35
- package/lib/core/guards/auth.guard.d.ts +0 -2
- package/lib/core/guards/permissions.guard.d.ts +0 -2
- package/lib/core/handlers/http-context-handler.d.ts +0 -7
- package/lib/core/handlers/storage-handler.d.ts +0 -16
- package/lib/core/handlers/stortage.d.ts +0 -7
- package/lib/core/interceptors/app-http-config.d.ts +0 -8
- package/lib/core/interceptors/base-http.interceptor.d.ts +0 -15
- package/lib/core/interceptors/global-http-error.interceptor.d.ts +0 -6
- package/lib/core/interfaces/index.d.ts +0 -4
- package/lib/core/interfaces/list-response.interface.d.ts +0 -5
- package/lib/core/interfaces/router-data.interface.d.ts +0 -17
- package/lib/core/interfaces/toaster.interface.d.ts +0 -5
- package/lib/core/interfaces/user-info.interface.d.ts +0 -4
- package/lib/core/interfaces/user-profile-data.d.ts +0 -16
- package/lib/core/services/auth.service.d.ts +0 -19
- package/lib/core/services/base-http-service/base-http-response.d.ts +0 -14
- package/lib/core/services/base-http-service/base-http-types.d.ts +0 -37
- package/lib/core/services/base-http-service/base-http-utils.d.ts +0 -6
- package/lib/core/services/base-http-service/base-http.service.d.ts +0 -22
- package/lib/core/services/base-pagination-service/base-pagination.service.d.ts +0 -21
- package/lib/core/services/base-pagination-service/list-options.interface.d.ts +0 -8
- package/lib/core/services/base-pagination-service/pagination.d.ts +0 -6
- package/lib/core/services/error-handler.service.d.ts +0 -7
- package/lib/core/services/jwt-decoder.service.d.ts +0 -11
- package/lib/core/services/loader.service.d.ts +0 -13
- package/lib/core/services/lov.service.d.ts +0 -9
- package/lib/core/services/permissions.service.d.ts +0 -20
- package/lib/core/services/toaster.service.d.ts +0 -15
package/eslint.config.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const nx = require('@nx/eslint-plugin');
|
|
2
|
+
const baseConfig = require('../../eslint.config.js');
|
|
3
|
+
|
|
4
|
+
module.exports = [
|
|
5
|
+
...baseConfig,
|
|
6
|
+
{
|
|
7
|
+
files: ['**/*.json'],
|
|
8
|
+
rules: {
|
|
9
|
+
'@nx/dependency-checks': [
|
|
10
|
+
'error',
|
|
11
|
+
{
|
|
12
|
+
ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs}'],
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
languageOptions: {
|
|
17
|
+
parser: require('jsonc-eslint-parser'),
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
...nx.configs['flat/angular'],
|
|
21
|
+
...nx.configs['flat/angular-template'],
|
|
22
|
+
{
|
|
23
|
+
files: ['**/*.ts'],
|
|
24
|
+
rules: {
|
|
25
|
+
'@angular-eslint/directive-selector': [
|
|
26
|
+
'error',
|
|
27
|
+
{
|
|
28
|
+
type: 'attribute',
|
|
29
|
+
prefix: 'app',
|
|
30
|
+
style: 'camelCase',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
'@angular-eslint/component-selector': [
|
|
34
|
+
'error',
|
|
35
|
+
{
|
|
36
|
+
type: 'element',
|
|
37
|
+
prefix: 'app',
|
|
38
|
+
style: 'kebab-case',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
files: ['**/*.html'],
|
|
45
|
+
// Override or add rules here
|
|
46
|
+
rules: {},
|
|
47
|
+
},
|
|
48
|
+
];
|
package/ng-package.json
ADDED
package/package.json
CHANGED
|
@@ -1,36 +1,20 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@corp-products/app-core",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"author": "shireen Omar",
|
|
5
|
-
"description": "shared core services across our apps",
|
|
6
|
-
"peerDependencies": {
|
|
7
|
-
"@angular/common": "
|
|
8
|
-
"@angular/core": "
|
|
9
|
-
"primeng": "^17.6.0"
|
|
10
|
-
},
|
|
11
|
-
"keywords": [
|
|
12
|
-
"angular",
|
|
13
|
-
"library"
|
|
14
|
-
],
|
|
15
|
-
"publishConfig": {
|
|
16
|
-
"access": "public"
|
|
17
|
-
},
|
|
18
|
-
"license": "MIT",
|
|
19
|
-
"sideEffects": false
|
|
20
|
-
|
|
21
|
-
"typings": "index.d.ts",
|
|
22
|
-
"exports": {
|
|
23
|
-
"./package.json": {
|
|
24
|
-
"default": "./package.json"
|
|
25
|
-
},
|
|
26
|
-
".": {
|
|
27
|
-
"types": "./index.d.ts",
|
|
28
|
-
"esm2022": "./esm2022/corp-products-app-core.mjs",
|
|
29
|
-
"esm": "./esm2022/corp-products-app-core.mjs",
|
|
30
|
-
"default": "./fesm2022/corp-products-app-core.mjs"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"tslib": "^2.3.0"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@corp-products/app-core",
|
|
3
|
+
"version": "2.0.6",
|
|
4
|
+
"author": "shireen Omar",
|
|
5
|
+
"description": "shared core services across our apps",
|
|
6
|
+
"peerDependencies": {
|
|
7
|
+
"@angular/common": ">=18.0.0 <19.0.0",
|
|
8
|
+
"@angular/core": ">=18.0.0 <19.0.0",
|
|
9
|
+
"primeng": "^17.6.0"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"angular",
|
|
13
|
+
"library"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"sideEffects": false
|
|
20
|
+
}
|
package/project.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "core",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "libs/core/src",
|
|
5
|
+
"prefix": "",
|
|
6
|
+
"projectType": "library",
|
|
7
|
+
"tags": [],
|
|
8
|
+
"targets": {
|
|
9
|
+
"build": {
|
|
10
|
+
"executor": "@nx/angular:package",
|
|
11
|
+
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
|
|
12
|
+
"options": {
|
|
13
|
+
"project": "libs/core/ng-package.json"
|
|
14
|
+
},
|
|
15
|
+
"configurations": {
|
|
16
|
+
"production": {
|
|
17
|
+
"tsConfig": "libs/core/tsconfig.lib.prod.json"
|
|
18
|
+
},
|
|
19
|
+
"development": {
|
|
20
|
+
"tsConfig": "libs/core/tsconfig.lib.json"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"defaultConfiguration": "production"
|
|
24
|
+
},
|
|
25
|
+
"lint": {
|
|
26
|
+
"executor": "@nx/eslint:lint"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export * from "./lib/core/services/base-pagination-service";
|
|
2
|
-
export * from "./lib/core/components";
|
|
3
|
-
export * from "./lib/core/services";
|
|
4
|
-
export * from "./lib/core/interfaces";
|
|
5
|
-
export * from "./lib/core/guards";
|
|
6
|
-
export * from "./lib/core/interceptors";
|
|
7
|
-
export * from "./lib/core/enums";
|
|
8
|
-
export * from "./lib/core/directives";
|
|
9
|
-
export * from "./lib/core/core-config";
|
|
10
|
-
export * from "./lib/core/handlers";
|
|
1
|
+
export * from "./lib/core/services/base-pagination-service";
|
|
2
|
+
export * from "./lib/core/components";
|
|
3
|
+
export * from "./lib/core/services";
|
|
4
|
+
export * from "./lib/core/interfaces";
|
|
5
|
+
export * from "./lib/core/guards";
|
|
6
|
+
export * from "./lib/core/interceptors";
|
|
7
|
+
export * from "./lib/core/enums";
|
|
8
|
+
export * from "./lib/core/directives";
|
|
9
|
+
export * from "./lib/core/core-config";
|
|
10
|
+
export * from "./lib/core/handlers";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@if (loaderService.isLoading$ | async; as data) {
|
|
2
|
+
@if (data.show) {
|
|
3
|
+
<div
|
|
4
|
+
class="fixed inset-0 z-[1111] flex justify-center items-center"
|
|
5
|
+
[ngClass]="{
|
|
6
|
+
'bg-white/75': data?.isSystemLoader,
|
|
7
|
+
'absolute': !data?.isSystemLoader
|
|
8
|
+
}"
|
|
9
|
+
>
|
|
10
|
+
<div class="text-center flex flex-col gap-5 items-center">
|
|
11
|
+
<div
|
|
12
|
+
class="animate-spin inline-block w-12 h-12 border-[3px] border-current border-t-transparent text-gray-800 rounded-full">
|
|
13
|
+
</div>
|
|
14
|
+
<span>{{ 'loading' | translate }}</span>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
}
|
|
18
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { GlobalLoaderComponent } from 'libs/core/src/lib/core/components/global-loader/global-loader.component';
|
|
4
|
+
|
|
5
|
+
describe("LoaderComponent", () => {
|
|
6
|
+
let component: GlobalLoaderComponent;
|
|
7
|
+
let fixture: ComponentFixture<GlobalLoaderComponent>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
await TestBed.configureTestingModule({
|
|
11
|
+
declarations: [GlobalLoaderComponent]
|
|
12
|
+
}).compileComponents();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
fixture = TestBed.createComponent(GlobalLoaderComponent);
|
|
17
|
+
component = fixture.componentInstance;
|
|
18
|
+
fixture.detectChanges();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("should create", () => {
|
|
22
|
+
expect(component).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AsyncPipe, NgClass } from '@angular/common';
|
|
2
|
+
import { Component, Input } from '@angular/core';
|
|
3
|
+
import {TranslatePipe} from "@ngx-translate/core";
|
|
4
|
+
import {LoaderService} from "../../services";
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: "global-loader",
|
|
8
|
+
templateUrl: "./global-loader.component.html",
|
|
9
|
+
styleUrls: ["./global-loader.component.scss"],
|
|
10
|
+
standalone: true,
|
|
11
|
+
imports: [AsyncPipe, NgClass, TranslatePipe]
|
|
12
|
+
})
|
|
13
|
+
export class GlobalLoaderComponent {
|
|
14
|
+
@Input() color: string;
|
|
15
|
+
constructor(public loaderService: LoaderService) {}
|
|
16
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./global-loader/global-loader.component";
|
|
1
|
+
export * from "./global-loader/global-loader.component";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="flex items-center justify-center flex-col h-full gap-4 w-full">
|
|
2
|
+
<img [src]="imageSrc" alt="no-access" class="h-[300px]" />
|
|
3
|
+
<strong class="text-secondary font-size-22">{{ "oops" | translate }}</strong>
|
|
4
|
+
<p class="font-size-22 text-gray-500">{{ "do_not_have_permission" | translate }}</p>
|
|
5
|
+
|
|
6
|
+
<!-- @if (authService.isUserLoggedIn$ | async) {
|
|
7
|
+
<app-button (click)="router.navigate(['/'])" [title]="'home' | translate"/>
|
|
8
|
+
} -->
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component, inject } from "@angular/core";
|
|
2
|
+
import { Router } from "@angular/router";
|
|
3
|
+
import { AuthService } from "../../services/auth.service";
|
|
4
|
+
import { AsyncPipe } from "@angular/common";
|
|
5
|
+
import { TranslatePipe } from "@ngx-translate/core";
|
|
6
|
+
|
|
7
|
+
@Component({
|
|
8
|
+
selector: "app-no-access",
|
|
9
|
+
templateUrl: "./no-access.component.html",
|
|
10
|
+
imports: [AsyncPipe, TranslatePipe],
|
|
11
|
+
standalone: true
|
|
12
|
+
})
|
|
13
|
+
export class NoAccessComponent {
|
|
14
|
+
imageSrc: string = "assets/images/no-access.svg";
|
|
15
|
+
authService = inject(AuthService);
|
|
16
|
+
public router = inject(Router);
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { InjectionToken } from "@angular/core";
|
|
2
|
+
import { ToasterOptions } from "./interfaces";
|
|
3
|
+
|
|
4
|
+
export interface CoreConfig {
|
|
5
|
+
apiPrefix: string;
|
|
6
|
+
production: boolean;
|
|
7
|
+
gatewayUrl: string;
|
|
8
|
+
loginUrl: string;
|
|
9
|
+
logoutEndpoint: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const CORE_CONFIG = new InjectionToken<CoreConfig>("CoreConfig");
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
export interface ToasterInterface {
|
|
16
|
+
success(options:ToasterOptions): void;
|
|
17
|
+
error(options:ToasterOptions): void;
|
|
18
|
+
warning(options:ToasterOptions): void;
|
|
19
|
+
info(options:ToasterOptions): void;
|
|
20
|
+
}
|
|
21
|
+
export const TOASTER_SERVICE = new InjectionToken<ToasterInterface>("ToasterService");
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Directive,
|
|
3
|
+
Input,
|
|
4
|
+
OnDestroy,
|
|
5
|
+
OnInit,
|
|
6
|
+
TemplateRef,
|
|
7
|
+
ViewContainerRef,
|
|
8
|
+
} from '@angular/core';
|
|
9
|
+
import { PermissionsService } from '../services';
|
|
10
|
+
import { PermissionsActions, UserPermissionsEnum } from '../enums';
|
|
11
|
+
import { Subscription } from 'rxjs';
|
|
12
|
+
|
|
13
|
+
@Directive({
|
|
14
|
+
selector: '[hasPermissions]',
|
|
15
|
+
standalone: true
|
|
16
|
+
})
|
|
17
|
+
export class HasPermissionsDirective implements OnInit, OnDestroy {
|
|
18
|
+
private _actions: string[];
|
|
19
|
+
private _key: string;
|
|
20
|
+
private _newPermissions: string[];
|
|
21
|
+
private _isDomain: boolean;
|
|
22
|
+
|
|
23
|
+
private isViewCreated = false;
|
|
24
|
+
private subscription: Subscription;
|
|
25
|
+
|
|
26
|
+
constructor(
|
|
27
|
+
private permissionsService: PermissionsService,
|
|
28
|
+
private viewContainer: ViewContainerRef,
|
|
29
|
+
private templateRef: TemplateRef<unknown>
|
|
30
|
+
) {}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* make sure that the key value looks like the UserPermissionsEnum enum
|
|
34
|
+
* usage: *permissions="[PermissionsActions.EDIT]; key: LOOKUPS
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
@Input({ required: true }) set hasPermissions(actions: string[]) {
|
|
38
|
+
if (this.arraysChanged(this._actions, actions)) {
|
|
39
|
+
this._actions = actions;
|
|
40
|
+
this.updateView();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Input({ required: true }) set hasPermissionsKey(key: string) {
|
|
45
|
+
if (this._key !== key) {
|
|
46
|
+
this._key = key;
|
|
47
|
+
this.updateView();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@Input() set hasPermissionsNewPermissions(newPermissions: string[]) {
|
|
52
|
+
if (this.arraysChanged(this._newPermissions, newPermissions)) {
|
|
53
|
+
this._newPermissions = newPermissions;
|
|
54
|
+
this.updateView();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Input() set hasPermissionsIsDomain(isDomain: boolean) {
|
|
59
|
+
if (this._isDomain !== isDomain) {
|
|
60
|
+
this._isDomain = isDomain;
|
|
61
|
+
this.updateView();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
ngOnInit(): void {
|
|
66
|
+
this.subscription = this.permissionsService.domainPermissions$.subscribe(() => {
|
|
67
|
+
if (this._isDomain) {
|
|
68
|
+
this.updateView();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
ngOnDestroy(): void {
|
|
74
|
+
this.subscription?.unsubscribe();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private updateView() {
|
|
78
|
+
const canShow = this._actions.some(action => this.hasPermission(action));
|
|
79
|
+
|
|
80
|
+
if (canShow && !this.isViewCreated) {
|
|
81
|
+
this.viewContainer.createEmbeddedView(this.templateRef);
|
|
82
|
+
this.isViewCreated = true;
|
|
83
|
+
} else if (!canShow && this.isViewCreated) {
|
|
84
|
+
this.clearView();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private hasPermission(action: string): boolean {
|
|
89
|
+
if (this._isDomain) {
|
|
90
|
+
return this.permissionsService.checkDomainHasPermission(
|
|
91
|
+
this._key as UserPermissionsEnum,
|
|
92
|
+
action as PermissionsActions
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return this.permissionsService.checkKeyHasPermission(
|
|
97
|
+
this._key as UserPermissionsEnum,
|
|
98
|
+
action as PermissionsActions,
|
|
99
|
+
this._newPermissions
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private clearView() {
|
|
104
|
+
this.viewContainer.clear();
|
|
105
|
+
this.isViewCreated = false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private arraysChanged(a?: string[], b?: string[]): boolean {
|
|
109
|
+
if (a === b) return false;
|
|
110
|
+
if (!a || !b) return true;
|
|
111
|
+
if (a.length !== b.length) return true;
|
|
112
|
+
return a.some((v, i) => v !== b[i]);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Directive, Input, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from "@angular/core";
|
|
2
|
+
import { Subscription } from "rxjs";
|
|
3
|
+
import { DetectDeviceService } from "../services/detect-device.service";
|
|
4
|
+
import { DisplayTypesEnum } from "../enums/display-types.enum";
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Usage:
|
|
8
|
+
* <div *responsiveElement="DisplayTypes.WEB_ONLY">Web</div>
|
|
9
|
+
* <div *responsiveElement="DisplayTypes.MOBILE_ONLY">Mobile</div>
|
|
10
|
+
* */
|
|
11
|
+
|
|
12
|
+
@Directive({
|
|
13
|
+
selector: "[responsiveElement]",
|
|
14
|
+
standalone: true
|
|
15
|
+
})
|
|
16
|
+
export class ResponsiveElementDirective implements OnInit, OnDestroy {
|
|
17
|
+
@Input("responsiveElement") displayFor: DisplayTypesEnum.WEB_ONLY | DisplayTypesEnum.MOBILE_ONLY;
|
|
18
|
+
|
|
19
|
+
private resizeSubscription: Subscription = new Subscription();
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
private templateRef: TemplateRef<any>,
|
|
24
|
+
private viewContainer: ViewContainerRef,
|
|
25
|
+
private detectDeviceServiceService: DetectDeviceService
|
|
26
|
+
) {}
|
|
27
|
+
|
|
28
|
+
ngOnInit() {
|
|
29
|
+
this.resizeSubscription.add(this.detectDeviceServiceService.onResize$.subscribe(this.checkWidth.bind(this)));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
ngOnDestroy() {
|
|
33
|
+
this.resizeSubscription.unsubscribe();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private checkWidth() {
|
|
37
|
+
const shouldDisplay =
|
|
38
|
+
(this.displayFor === DisplayTypesEnum.WEB_ONLY && !this.detectDeviceServiceService.isMobile()) ||
|
|
39
|
+
(this.displayFor === DisplayTypesEnum.MOBILE_ONLY && this.detectDeviceServiceService.isMobile());
|
|
40
|
+
if (shouldDisplay) {
|
|
41
|
+
this.viewContainer.length === 0 && this.viewContainer.createEmbeddedView(this.templateRef);
|
|
42
|
+
} else {
|
|
43
|
+
this.viewContainer.clear();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export enum DateFormatter {
|
|
2
|
+
FULL_DATE_TIME = "dd MMM yyyy - hh:mm a",
|
|
3
|
+
DATE_TIME_ZONE = "yyyy-MM-dd'T'HH:mm:ssxxx",
|
|
4
|
+
DATE_UTC = "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
|
5
|
+
dd_MM_yyyy = "dd-MM-yyyy",
|
|
6
|
+
yyyy_MM_dd = "yyyy-MM-dd",
|
|
7
|
+
MMM_dd_yyyy = "MMM dd ,yyyy",
|
|
8
|
+
MM_D_yyy = "MM dd ,yyy",
|
|
9
|
+
MMM_D_YYY_Time = "MMM dd ,YYYY - hh:mm a",
|
|
10
|
+
MMM_d_y_Time = "MMM d, y, h:mm a",
|
|
11
|
+
d_MM_y = "d MMM y",
|
|
12
|
+
MMM_D_Y = "MMM d, y",
|
|
13
|
+
DD_MM = "dd MMM",
|
|
14
|
+
DATE_PICKER = "dd/MM/yyyy",
|
|
15
|
+
DATE_FULL_YEAR = "yyyy"
|
|
16
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export enum UserPermissionsEnum {
|
|
2
|
+
BOD = "BOD",
|
|
3
|
+
BOARD_COMMITTEES = "BOARD_COMMITTEES",
|
|
4
|
+
BOARD_MEETINGS = "BOARD_MEETINGS",
|
|
5
|
+
MEETING_INSIDE_THE_BOD = "MEETING_INSIDE_THE_BOD",
|
|
6
|
+
COMMITTEE = "COMMITTEE",
|
|
7
|
+
MEETING_INSIDE_THE_COMMITTEE = "MEETING_INSIDE_THE_COMMITTEE",
|
|
8
|
+
MEETING = "MEETING",
|
|
9
|
+
DECISION = "DECISION",
|
|
10
|
+
RECOMMENDATION = "RECOMMENDATION",
|
|
11
|
+
TASK = "TASK",
|
|
12
|
+
VOTING = "VOTING",
|
|
13
|
+
VOTING_SECRETARY_RESULTS = "VOTING_SECRETARY_RESULTS",
|
|
14
|
+
VOTING_RESULTS = "VOTING_RESULTS",
|
|
15
|
+
DRAFT_MOM = "DRAFT_MOM",
|
|
16
|
+
FINAL_MOM = "FINAL_MOM",
|
|
17
|
+
MOM = "MOM",
|
|
18
|
+
AGENDA = "AGENDA",
|
|
19
|
+
ATTENDEES = "ATTENDEES",
|
|
20
|
+
COMMENT = "COMMENT"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export enum PermissionsActions {
|
|
24
|
+
VIEW = "VIEW",
|
|
25
|
+
CREATE = "CREATE",
|
|
26
|
+
EDIT = "EDIT",
|
|
27
|
+
DELETE = "DELETE",
|
|
28
|
+
REORDER = "REORDER",
|
|
29
|
+
DOWNLOAD = "DOWNLOAD",
|
|
30
|
+
MARK = "MARK",
|
|
31
|
+
GENERATE = "GENERATE",
|
|
32
|
+
TERMINATE = "TERMINATE",
|
|
33
|
+
START = "START",
|
|
34
|
+
END = "END",
|
|
35
|
+
ACTIVATE = "ACTIVATE"
|
|
36
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { inject } from "@angular/core";
|
|
2
|
+
import { CanActivateFn } from "@angular/router";
|
|
3
|
+
import { AuthService } from "../services";
|
|
4
|
+
import { CORE_CONFIG, CoreConfig } from "../core-config";
|
|
5
|
+
|
|
6
|
+
export const authGuard: CanActivateFn = () => {
|
|
7
|
+
const appConfig = inject<CoreConfig>(CORE_CONFIG);
|
|
8
|
+
const authService = inject(AuthService);
|
|
9
|
+
const token: string | null = authService.getUserToken();
|
|
10
|
+
|
|
11
|
+
if (!token) {
|
|
12
|
+
window.location.href = appConfig.loginUrl;
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return true;
|
|
17
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './auth.guard';
|
|
2
|
-
export * from './permissions.guard';
|
|
1
|
+
export * from './auth.guard';
|
|
2
|
+
export * from './permissions.guard';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { inject } from "@angular/core";
|
|
2
|
+
import { CanActivateFn, Router } from "@angular/router";
|
|
3
|
+
import { PermissionsService } from "../services";
|
|
4
|
+
import { RoutePermissionsInfo } from "../interfaces";
|
|
5
|
+
|
|
6
|
+
export const permissionsGuard: CanActivateFn = (route) => {
|
|
7
|
+
const permissionsService = inject(PermissionsService);
|
|
8
|
+
const router = inject(Router);
|
|
9
|
+
const { key, action }: RoutePermissionsInfo = route.data["permissions"];
|
|
10
|
+
|
|
11
|
+
if (!route.data["permissions"] || (route.data["permissions"] && permissionsService.routeGuardChecker(key, action))) {
|
|
12
|
+
return true;
|
|
13
|
+
} else {
|
|
14
|
+
router.navigate(["no-access"]);
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HttpContext, HttpContextToken } from "@angular/common/http";
|
|
2
|
+
|
|
3
|
+
export const IS_SYSTEM_LOADER = new HttpContextToken<boolean>(() => true); // set default loader
|
|
4
|
+
export const USE_API_PREFIX = new HttpContextToken<boolean>(() => true); // set default loader
|
|
5
|
+
|
|
6
|
+
export class HttpContextHandler {
|
|
7
|
+
static setLoaderType(isSystemLoader: boolean) {
|
|
8
|
+
return new HttpContext().set(IS_SYSTEM_LOADER, isSystemLoader);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static useApiPrefix(hasBaseSegment: boolean) {
|
|
12
|
+
return new HttpContext().set(USE_API_PREFIX, hasBaseSegment);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./http-context-handler";
|
|
2
|
-
export * from "./storage-handler";
|
|
3
|
-
export * from "./stortage";
|
|
1
|
+
export * from "./http-context-handler";
|
|
2
|
+
export * from "./storage-handler";
|
|
3
|
+
export * from "./stortage";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Important for global context
|
|
2
|
+
import { LocalStorageKeys, SessionStorageKeys, StorageEnum } from "./stortage";
|
|
3
|
+
|
|
4
|
+
const setLocalStorage = (key: string, value: string) => localStorage.setItem(key, value);
|
|
5
|
+
const getLocalStorage = (key: string) => localStorage.getItem(key);
|
|
6
|
+
const clearLocalStorage = () => localStorage.clear();
|
|
7
|
+
const setSessionStorage = (key: string, value: string) => sessionStorage.setItem(key, value);
|
|
8
|
+
const getSessionStorage = (key: string) => sessionStorage.getItem(key);
|
|
9
|
+
const clearSessionStorage = () => sessionStorage.clear();
|
|
10
|
+
|
|
11
|
+
export class StorageHandler {
|
|
12
|
+
public static local = {
|
|
13
|
+
set: (key: LocalStorageKeys, value: unknown) => this.setItem(key, value, setLocalStorage),
|
|
14
|
+
get: <T>(key: LocalStorageKeys) => this.getItem<T>(key, getLocalStorage),
|
|
15
|
+
clear: () => this.clearStorage(clearLocalStorage)
|
|
16
|
+
};
|
|
17
|
+
public static session = {
|
|
18
|
+
set: (key: SessionStorageKeys, value: unknown) => this.setItem(key, value, setSessionStorage),
|
|
19
|
+
get: <T>(key: SessionStorageKeys) => this.getItem<T>(key, getSessionStorage),
|
|
20
|
+
clear: () => this.clearStorage(clearSessionStorage)
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
private static setItem(key: StorageEnum, value: unknown, set: (key: string, value: string) => void): void {
|
|
24
|
+
if (!key) return;
|
|
25
|
+
set(key as string, typeof value === "string" ? value : JSON.stringify(value));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private static getItem<T>(key: StorageEnum, get: (key: string) => string | null, withParsing = false): T | null {
|
|
29
|
+
const data: string | null = get(key as string) ?? null;
|
|
30
|
+
if (data) return withParsing ? JSON.parse(data) as T : data as T;
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private static clearStorage(clear: () => void): void {
|
|
35
|
+
clear();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const COMMON_BASE_URL = "common/api/v1";
|
|
2
|
+
export const APP_HTTP_CONFIG = {
|
|
3
|
+
BOARD_BASE_URL: "board-acl/private/v1",
|
|
4
|
+
MEETING_BASE_URL: "meeting-acl/private/v1",
|
|
5
|
+
IGATE_BASE_URL: COMMON_BASE_URL + "/igate-users",
|
|
6
|
+
LOV_BASE_URL: COMMON_BASE_URL + "/lov",
|
|
7
|
+
ATTACHMENT_BASE_URL: COMMON_BASE_URL + "/attachment"
|
|
8
|
+
};
|