@corp-products/ui-components 0.0.1 → 1.0.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/esm2022/corp-products-ui-components.mjs +5 -0
- package/esm2022/index.mjs +14 -0
- package/esm2022/lib/app-accordion/app-accordion.component.mjs +35 -0
- package/esm2022/lib/app-button/app-button.component.mjs +43 -0
- package/esm2022/lib/app-button/app-button.mjs +2 -0
- package/esm2022/lib/app-button/index.mjs +3 -0
- package/esm2022/lib/app-dropdown-menu/app-dropdown-menu.component.mjs +54 -0
- package/esm2022/lib/app-dropdown-menu/app-dropdown-menu.mjs +2 -0
- package/esm2022/lib/app-dropdown-menu/index.mjs +3 -0
- package/esm2022/lib/app-dropdown-menu/menu-popup.pipe.mjs +23 -0
- package/esm2022/lib/app-tabs/app-tab.interface.mjs +2 -0
- package/esm2022/lib/app-tabs/app-tabs.component.mjs +57 -0
- package/esm2022/lib/app-tabs/index.mjs +3 -0
- package/esm2022/lib/confirmation-dialog/confirmation-dialog.component.mjs +44 -0
- package/esm2022/lib/dynamic-form/dynamic-form.component.mjs +31 -0
- package/esm2022/lib/dynamic-form/dynamic-form.interface.mjs +6 -0
- package/esm2022/lib/form-components/@utils/form-utils.mjs +11 -0
- package/esm2022/lib/form-components/@utils/validations/error-keys.enum.mjs +27 -0
- package/esm2022/lib/form-components/@utils/validations/form-validation.service.mjs +50 -0
- package/esm2022/lib/form-components/@utils/validations/index.mjs +4 -0
- package/esm2022/lib/form-components/@utils/validations/validation-message.pipe.mjs +30 -0
- package/esm2022/lib/form-components/components/auto-complete/auto-complete.component.mjs +59 -0
- package/esm2022/lib/form-components/components/base-input.component.mjs +57 -0
- package/esm2022/lib/form-components/components/date-picker/date-picker.component.mjs +58 -0
- package/esm2022/lib/form-components/components/input/input.component.mjs +48 -0
- package/esm2022/lib/form-components/components/select/select.component.mjs +72 -0
- package/esm2022/lib/form-components/components/select-button/select-button.component.mjs +29 -0
- package/esm2022/lib/form-components/components/switcher/switch.component.mjs +34 -0
- package/esm2022/lib/form-components/index.mjs +10 -0
- package/esm2022/lib/form-components/interfaces/index.mjs +2 -0
- package/esm2022/lib/form-components/interfaces/label-value.mjs +2 -0
- package/esm2022/lib/ico-moon-icon/ico-moon-icon.component.mjs +41 -0
- package/esm2022/lib/read-more/read-more.component.mjs +30 -0
- package/esm2022/lib/side-bar/side-bar.component.mjs +51 -0
- package/esm2022/lib/user-autocomplete-card/user-autocomplete-card.component.mjs +32 -0
- package/esm2022/lib/user-info/user-info.component.mjs +15 -0
- package/fesm2022/corp-products-ui-components.mjs +840 -0
- package/fesm2022/corp-products-ui-components.mjs.map +1 -0
- package/{src/index.ts → index.d.ts} +13 -13
- package/lib/app-accordion/app-accordion.component.d.ts +11 -0
- package/lib/app-button/app-button.component.d.ts +18 -0
- package/{src/lib/app-button/app-button.ts → lib/app-button/app-button.d.ts} +4 -15
- package/{src/lib/app-button/index.ts → lib/app-button/index.d.ts} +2 -2
- package/lib/app-dropdown-menu/app-dropdown-menu.component.d.ts +20 -0
- package/lib/app-dropdown-menu/app-dropdown-menu.d.ts +15 -0
- package/{src/lib/app-dropdown-menu/index.ts → lib/app-dropdown-menu/index.d.ts} +2 -2
- package/lib/app-dropdown-menu/menu-popup.pipe.d.ts +8 -0
- package/lib/app-tabs/app-tab.interface.d.ts +23 -0
- package/lib/app-tabs/app-tabs.component.d.ts +18 -0
- package/{src/lib/app-tabs/index.ts → lib/app-tabs/index.d.ts} +2 -2
- package/lib/confirmation-dialog/confirmation-dialog.component.d.ts +19 -0
- package/lib/dynamic-form/dynamic-form.component.d.ts +16 -0
- package/lib/dynamic-form/dynamic-form.interface.d.ts +44 -0
- package/lib/form-components/@utils/form-utils.d.ts +4 -0
- package/lib/form-components/@utils/validations/error-keys.enum.d.ts +24 -0
- package/lib/form-components/@utils/validations/form-validation.service.d.ts +11 -0
- package/{src/lib/form-components/@utils/validations/index.ts → lib/form-components/@utils/validations/index.d.ts} +3 -3
- package/lib/form-components/@utils/validations/validation-message.pipe.d.ts +9 -0
- package/lib/form-components/components/auto-complete/auto-complete.component.d.ts +18 -0
- package/lib/form-components/components/base-input.component.d.ts +21 -0
- package/lib/form-components/components/date-picker/date-picker.component.d.ts +21 -0
- package/lib/form-components/components/input/input.component.d.ts +17 -0
- package/lib/form-components/components/select/select.component.d.ts +23 -0
- package/lib/form-components/components/select-button/select-button.component.d.ts +13 -0
- package/lib/form-components/components/switcher/switch.component.d.ts +11 -0
- package/{src/lib/form-components/index.ts → lib/form-components/index.d.ts} +9 -9
- package/{src/lib/form-components/interfaces/index.ts → lib/form-components/interfaces/index.d.ts} +1 -1
- package/lib/form-components/interfaces/label-value.d.ts +4 -0
- package/lib/ico-moon-icon/ico-moon-icon.component.d.ts +9 -0
- package/lib/read-more/read-more.component.d.ts +10 -0
- package/lib/side-bar/side-bar.component.d.ts +18 -0
- package/lib/user-autocomplete-card/user-autocomplete-card.component.d.ts +12 -0
- package/lib/user-info/user-info.component.d.ts +7 -0
- package/package.json +35 -19
- package/eslint.config.js +0 -34
- package/ng-package.json +0 -7
- package/project.json +0 -29
- package/src/lib/app-accordion/app-accordion.component.html +0 -15
- package/src/lib/app-accordion/app-accordion.component.scss +0 -0
- package/src/lib/app-accordion/app-accordion.component.spec.ts +0 -21
- package/src/lib/app-accordion/app-accordion.component.ts +0 -21
- package/src/lib/app-accordion/index.ts +0 -2
- package/src/lib/app-button/app-button.component.html +0 -13
- package/src/lib/app-button/app-button.component.scss +0 -0
- package/src/lib/app-button/app-button.component.ts +0 -28
- package/src/lib/app-dropdown-menu/app-dropdown-menu.component.html +0 -25
- package/src/lib/app-dropdown-menu/app-dropdown-menu.component.scss +0 -39
- package/src/lib/app-dropdown-menu/app-dropdown-menu.component.spec.ts +0 -21
- package/src/lib/app-dropdown-menu/app-dropdown-menu.component.ts +0 -43
- package/src/lib/app-dropdown-menu/app-dropdown-menu.ts +0 -17
- package/src/lib/app-dropdown-menu/menu-popup.pipe.ts +0 -18
- package/src/lib/app-tabs/app-tab.interface.ts +0 -26
- package/src/lib/app-tabs/app-tabs.component.html +0 -35
- package/src/lib/app-tabs/app-tabs.component.scss +0 -103
- package/src/lib/app-tabs/app-tabs.component.spec.ts +0 -21
- package/src/lib/app-tabs/app-tabs.component.ts +0 -48
- package/src/lib/confirmation-dialog/confirmation-dialog.component.html +0 -54
- package/src/lib/confirmation-dialog/confirmation-dialog.component.scss +0 -0
- package/src/lib/confirmation-dialog/confirmation-dialog.component.spec.ts +0 -22
- package/src/lib/confirmation-dialog/confirmation-dialog.component.ts +0 -51
- package/src/lib/dynamic-form/dynamic-form.component.html +0 -39
- package/src/lib/dynamic-form/dynamic-form.component.scss +0 -0
- package/src/lib/dynamic-form/dynamic-form.component.spec.ts +0 -21
- package/src/lib/dynamic-form/dynamic-form.component.ts +0 -29
- package/src/lib/dynamic-form/dynamic-form.interface.ts +0 -56
- package/src/lib/form-components/@utils/form-utils.ts +0 -12
- package/src/lib/form-components/@utils/validations/error-keys.enum.ts +0 -24
- package/src/lib/form-components/@utils/validations/form-validation.service.ts +0 -53
- package/src/lib/form-components/@utils/validations/validation-message.pipe.ts +0 -24
- package/src/lib/form-components/components/auto-complete/auto-complete.component.html +0 -48
- package/src/lib/form-components/components/auto-complete/auto-complete.component.scss +0 -0
- package/src/lib/form-components/components/auto-complete/auto-complete.component.spec.ts +0 -21
- package/src/lib/form-components/components/auto-complete/auto-complete.component.ts +0 -48
- package/src/lib/form-components/components/base-input.component.ts +0 -41
- package/src/lib/form-components/components/date-picker/date-picker.component.html +0 -53
- package/src/lib/form-components/components/date-picker/date-picker.component.scss +0 -4
- package/src/lib/form-components/components/date-picker/date-picker.component.spec.ts +0 -23
- package/src/lib/form-components/components/date-picker/date-picker.component.ts +0 -45
- package/src/lib/form-components/components/input/input.component.html +0 -59
- package/src/lib/form-components/components/input/input.component.scss +0 -3
- package/src/lib/form-components/components/input/input.component.spec.ts +0 -21
- package/src/lib/form-components/components/input/input.component.ts +0 -32
- package/src/lib/form-components/components/select/select.component.html +0 -90
- package/src/lib/form-components/components/select/select.component.scss +0 -0
- package/src/lib/form-components/components/select/select.component.spec.ts +0 -21
- package/src/lib/form-components/components/select/select.component.ts +0 -51
- package/src/lib/form-components/components/select-button/select-button.component.html +0 -21
- package/src/lib/form-components/components/select-button/select-button.component.scss +0 -0
- package/src/lib/form-components/components/select-button/select-button.component.spec.ts +0 -21
- package/src/lib/form-components/components/select-button/select-button.component.ts +0 -22
- package/src/lib/form-components/components/switcher/switch.component.html +0 -5
- package/src/lib/form-components/components/switcher/switch.component.scss +0 -0
- package/src/lib/form-components/components/switcher/switch.component.spec.ts +0 -21
- package/src/lib/form-components/components/switcher/switch.component.ts +0 -25
- package/src/lib/form-components/interfaces/label-value.ts +0 -4
- package/src/lib/ico-moon-icon/ico-moon-icon.component.ts +0 -23
- package/src/lib/read-more/read-more.component.html +0 -17
- package/src/lib/read-more/read-more.component.scss +0 -0
- package/src/lib/read-more/read-more.component.spec.ts +0 -21
- package/src/lib/read-more/read-more.component.ts +0 -21
- package/src/lib/side-bar/side-bar.component.html +0 -25
- package/src/lib/side-bar/side-bar.component.scss +0 -5
- package/src/lib/side-bar/side-bar.component.spec.ts +0 -21
- package/src/lib/side-bar/side-bar.component.ts +0 -32
- package/src/lib/side-bar-dynamic/data-injector.pipe.ts +0 -15
- package/src/lib/side-bar-dynamic/dynamic-sidebar.service.ts +0 -116
- package/src/lib/side-bar-dynamic/side-bar-dynamic.component.html +0 -51
- package/src/lib/side-bar-dynamic/side-bar-dynamic.component.scss +0 -5
- package/src/lib/side-bar-dynamic/side-bar-dynamic.component.spec.ts +0 -21
- package/src/lib/side-bar-dynamic/side-bar-dynamic.component.ts +0 -37
- package/src/lib/side-bar-dynamic/side-bar-utils.ts +0 -30
- package/src/lib/side-bar-dynamic/sidebar-config.ts +0 -48
- package/src/lib/user-autocomplete-card/user-autocomplete-card.component.html +0 -20
- package/src/lib/user-autocomplete-card/user-autocomplete-card.component.scss +0 -0
- package/src/lib/user-autocomplete-card/user-autocomplete-card.component.spec.ts +0 -21
- package/src/lib/user-autocomplete-card/user-autocomplete-card.component.ts +0 -21
- package/src/lib/user-info/user-info.component.html +0 -10
- package/src/lib/user-info/user-info.component.ts +0 -11
- package/tsconfig.json +0 -25
- package/tsconfig.lib.json +0 -12
- package/tsconfig.lib.prod.json +0 -9
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { TemplateRef } from "@angular/core";
|
|
2
|
-
|
|
3
|
-
interface Tab {
|
|
4
|
-
title: string;
|
|
5
|
-
iconName?: string;
|
|
6
|
-
iconPathCount?: number;
|
|
7
|
-
disabled?: boolean;
|
|
8
|
-
count?: number;
|
|
9
|
-
permissionKey?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface RoutedTab extends Tab {
|
|
13
|
-
link: string;
|
|
14
|
-
}
|
|
15
|
-
export interface TemplateTab extends Tab {
|
|
16
|
-
contentTemplate: TemplateRef<unknown>;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export type AppTabs = ({
|
|
21
|
-
isRouted: true;
|
|
22
|
-
items: RoutedTab[];
|
|
23
|
-
} | {
|
|
24
|
-
isRouted: false;
|
|
25
|
-
items: TemplateTab[];
|
|
26
|
-
})
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
@if (tabs && tabs.items.length) {
|
|
2
|
-
<div [class]="tabsStyle + (responsive ? ' full-width' : '') + ' tabs-container'">
|
|
3
|
-
<p-tabs [value]="activeTabIndex" scrollable>
|
|
4
|
-
<p-tablist>
|
|
5
|
-
|
|
6
|
-
@for (tab of tabs.items; let i = $index; track i) {
|
|
7
|
-
<p-tab [value]="i" [routerLink]="tabs.isRouted ? $any(tab).link : null" [disabled]="tab.disabled"
|
|
8
|
-
(click)="onTabChange(i)">
|
|
9
|
-
@if (tab.iconName) {
|
|
10
|
-
<app-ico-moon-card [iconClass]="'text-[17px]'" [iconName]="tab.iconName"
|
|
11
|
-
[iconPathCount]="tab.iconPathCount || 0"/>
|
|
12
|
-
}
|
|
13
|
-
<span>{{ tab.title | translate }} @if (tab.count) {
|
|
14
|
-
<span>({{ tab.count }})</span>
|
|
15
|
-
} </span>
|
|
16
|
-
</p-tab>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
</p-tablist>
|
|
20
|
-
|
|
21
|
-
<p-tabpanels>
|
|
22
|
-
@if (tabs.isRouted) {
|
|
23
|
-
<router-outlet></router-outlet>
|
|
24
|
-
} @else {
|
|
25
|
-
@for (tab of tabs.items; let i = $index; track i) {
|
|
26
|
-
<p-tabpanel [value]="i">
|
|
27
|
-
<ng-container [ngTemplateOutlet]="tab.contentTemplate"></ng-container>
|
|
28
|
-
</p-tabpanel>
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
</p-tabpanels>
|
|
33
|
-
</p-tabs>
|
|
34
|
-
</div>
|
|
35
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
.tabs-container {
|
|
2
|
-
&.full-width {
|
|
3
|
-
.p-tabs .p-tablist-tab-list .p-tab {
|
|
4
|
-
@apply flex-grow flex justify-center max-w-[50%];
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.p-tabs {
|
|
9
|
-
.p-tablist-tab-list {
|
|
10
|
-
@apply relative;
|
|
11
|
-
|
|
12
|
-
&:after {
|
|
13
|
-
@apply content-[''] w-full h-[3px] bg-purple-800/5 absolute bottom-0 right-0 z-[1];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.p-tab {
|
|
17
|
-
@apply text-sm text-gray-400 font-normal text-[16px] border-b-[4px] border-transparent z-[2];
|
|
18
|
-
|
|
19
|
-
&:not(.p-tab-active) {
|
|
20
|
-
app-ico-moon-card {
|
|
21
|
-
@apply grayscale;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.p-tablist-active-bar {
|
|
29
|
-
@apply hidden;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.p-tabpanels.p-component {
|
|
33
|
-
@apply mt-5 rounded-lg;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
&.basic {
|
|
38
|
-
.p-tabs {
|
|
39
|
-
.p-tablist-tab-list {
|
|
40
|
-
@apply bg-transparent;
|
|
41
|
-
|
|
42
|
-
.p-tab {
|
|
43
|
-
&.p-tab-active {
|
|
44
|
-
@apply text-primary border-primary;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
&.primary_light {
|
|
52
|
-
.p-tabs {
|
|
53
|
-
.p-tablist-tab-list {
|
|
54
|
-
.p-tab {
|
|
55
|
-
@apply rounded-t-lg text-[14px];
|
|
56
|
-
|
|
57
|
-
&.p-tab-active {
|
|
58
|
-
@apply bg-purple-800/5 font-semibold text-primary border-primary;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
&.primary {
|
|
66
|
-
.p-tabs {
|
|
67
|
-
.p-tablist-tab-list {
|
|
68
|
-
&:after {
|
|
69
|
-
@apply bg-purple-800/5;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.p-tab {
|
|
73
|
-
@apply rounded-t-lg text-[14px];
|
|
74
|
-
|
|
75
|
-
&.p-tab-active {
|
|
76
|
-
@apply bg-primary font-semibold text-white border-secondary;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
[dir='rtl'] {
|
|
85
|
-
.p-tabs .p-tablist{
|
|
86
|
-
.p-iconwrapper {
|
|
87
|
-
@apply rotate-180deg;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.p-tablist-next-button {
|
|
91
|
-
@apply right-auto left-0;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.p-tablist-prev-button {
|
|
95
|
-
@apply right-0 left-auto;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// TODO : CHECK
|
|
101
|
-
// .p-tabpanels.p-component {
|
|
102
|
-
// @apply mt-5 rounded-[1.5rem];
|
|
103
|
-
// }
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
import { AppTabsComponent } from './app-tabs.component';
|
|
3
|
-
|
|
4
|
-
describe('AppTabsComponent', () => {
|
|
5
|
-
let component: AppTabsComponent;
|
|
6
|
-
let fixture: ComponentFixture<AppTabsComponent>;
|
|
7
|
-
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
await TestBed.configureTestingModule({
|
|
10
|
-
imports: [AppTabsComponent],
|
|
11
|
-
}).compileComponents();
|
|
12
|
-
|
|
13
|
-
fixture = TestBed.createComponent(AppTabsComponent);
|
|
14
|
-
component = fixture.componentInstance;
|
|
15
|
-
fixture.detectChanges();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should create', () => {
|
|
19
|
-
expect(component).toBeTruthy();
|
|
20
|
-
});
|
|
21
|
-
});
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { CommonModule } from "@angular/common";
|
|
2
|
-
import { Component, Input, OnInit, ViewEncapsulation } from "@angular/core";
|
|
3
|
-
import { TabsModule } from "primeng/tabs";
|
|
4
|
-
import { AppTabs } from "./app-tab.interface";
|
|
5
|
-
import { IcoMoonIconComponent } from "../ico-moon-icon/ico-moon-icon.component";
|
|
6
|
-
import { TranslateModule } from "@ngx-translate/core";
|
|
7
|
-
import { ActivatedRoute, NavigationEnd, Router, RouterLink, RouterOutlet } from "@angular/router";
|
|
8
|
-
import { filter } from "rxjs";
|
|
9
|
-
|
|
10
|
-
@Component({
|
|
11
|
-
selector: "app-tabs",
|
|
12
|
-
standalone: true,
|
|
13
|
-
encapsulation: ViewEncapsulation.None,
|
|
14
|
-
imports: [CommonModule, TabsModule, RouterLink, RouterOutlet, IcoMoonIconComponent, TranslateModule],
|
|
15
|
-
templateUrl: "./app-tabs.component.html",
|
|
16
|
-
styleUrl: "./app-tabs.component.scss"
|
|
17
|
-
})
|
|
18
|
-
export class AppTabsComponent implements OnInit {
|
|
19
|
-
@Input() tabs: AppTabs;
|
|
20
|
-
@Input() tabsStyle: "basic" | "primary_light" | "primary" = "basic";
|
|
21
|
-
@Input() responsive = false;
|
|
22
|
-
activeTabIndex = 0;
|
|
23
|
-
constructor(private route: ActivatedRoute, private router: Router) {}
|
|
24
|
-
|
|
25
|
-
ngOnInit(): void {
|
|
26
|
-
this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
|
|
27
|
-
this.updateActiveTab();
|
|
28
|
-
});
|
|
29
|
-
// to be refactor
|
|
30
|
-
this.updateActiveTab();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Updates the active tab index based on the current route
|
|
34
|
-
private updateActiveTab(): void {
|
|
35
|
-
if (!this.tabs.isRouted) return;
|
|
36
|
-
const currentUrl = this.router.url;
|
|
37
|
-
const matchingTabIndex = this.tabs.items.findIndex((tab) => currentUrl.includes(tab.link));
|
|
38
|
-
this.activeTabIndex = matchingTabIndex !== -1 ? matchingTabIndex : 0;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
onTabChange(index: number): void {
|
|
42
|
-
if (!this.tabs.isRouted) return;
|
|
43
|
-
const selectedTab = this.tabs.items[index];
|
|
44
|
-
if (selectedTab && !selectedTab.disabled) {
|
|
45
|
-
this.router.navigate([selectedTab.link], { relativeTo: this.route });
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
@if (dynamicDialogConfig.data) {
|
|
2
|
-
<div>
|
|
3
|
-
<div class="bg-gray-150 p-4 flex items-center">
|
|
4
|
-
<div class="flex-grow flex gap-2">
|
|
5
|
-
@if (dynamicDialogConfig.data.headerIcon) {
|
|
6
|
-
<i [class]="dynamicDialogConfig.data.headerIcon"></i>
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
<h3 class="m-0 font-bold text-[16px]">
|
|
10
|
-
{{ dynamicDialogConfig.data.header }}
|
|
11
|
-
</h3>
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
<app-button (click)="close()" icon="font-icon-close" [style]="'secondary'" variant="text"/>
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
@if (dynamicDialogConfig.data) {
|
|
18
|
-
<div class="p-4">
|
|
19
|
-
@if (dynamicDialogConfig.data.dialogIcon) {
|
|
20
|
-
<em [class]="dynamicDialogConfig.data.dialogIcon"></em>
|
|
21
|
-
}
|
|
22
|
-
<div>
|
|
23
|
-
{{ dynamicDialogConfig.data.message }}
|
|
24
|
-
</div>
|
|
25
|
-
@if (dynamicDialogConfig.data.hint) {
|
|
26
|
-
<div class="font-bold text-[14px] mt-2">
|
|
27
|
-
{{ dynamicDialogConfig.data.hint }}
|
|
28
|
-
</div>
|
|
29
|
-
}
|
|
30
|
-
</div>
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@if (dynamicDialogConfig.data.inputForm) {
|
|
34
|
-
<app-dynamic-form [dynamicFormData]="dialogFormData"></app-dynamic-form>
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
<div class="p-4 flex gap-3">
|
|
38
|
-
<app-button
|
|
39
|
-
[title]="dynamicDialogConfig.data?.confirmLabel || ('actions.confirm' | translate)" class="w-[50%]"
|
|
40
|
-
[disabled]="!!(dialogFormData && dialogFormData.formGroup?.invalid)"
|
|
41
|
-
[icon]="dynamicDialogConfig.data.confirmBtnIcon || ''"
|
|
42
|
-
[iconPos]="dynamicDialogConfig.data.confirmBtnPosition || 'left'"
|
|
43
|
-
[style]="dynamicDialogConfig.data.confirmBtnStyle ||'primary'"
|
|
44
|
-
(click)="submit()"/>
|
|
45
|
-
|
|
46
|
-
<app-button
|
|
47
|
-
[title]="dynamicDialogConfig.data?.closeLabel || ('actions.cancel' | translate)"
|
|
48
|
-
class="w-[50%]"
|
|
49
|
-
[style]="'secondary'"
|
|
50
|
-
[variant]="'outlined'"
|
|
51
|
-
(click)="close()"/>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
}
|
|
File without changes
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
|
2
|
-
|
|
3
|
-
import { ConfirmationDialogComponent } from "./confirmation-dialog.component";
|
|
4
|
-
|
|
5
|
-
describe("SharedConfirmDialogComponent", () => {
|
|
6
|
-
let component: ConfirmationDialogComponent;
|
|
7
|
-
let fixture: ComponentFixture<ConfirmationDialogComponent>;
|
|
8
|
-
|
|
9
|
-
beforeEach(async () => {
|
|
10
|
-
await TestBed.configureTestingModule({
|
|
11
|
-
imports: [ConfirmationDialogComponent]
|
|
12
|
-
}).compileComponents();
|
|
13
|
-
|
|
14
|
-
fixture = TestBed.createComponent(ConfirmationDialogComponent);
|
|
15
|
-
component = fixture.componentInstance;
|
|
16
|
-
fixture.detectChanges();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("should create", () => {
|
|
20
|
-
expect(component).toBeTruthy();
|
|
21
|
-
});
|
|
22
|
-
});
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Component, OnDestroy, OnInit, inject } from "@angular/core";
|
|
2
|
-
import { NavigationStart, Router } from "@angular/router";
|
|
3
|
-
import { AvatarModule } from "primeng/avatar";
|
|
4
|
-
import { filter, Subscription } from "rxjs";
|
|
5
|
-
import { AppButtonComponent } from "../app-button/app-button.component";
|
|
6
|
-
import { DialogService, DynamicDialog, DynamicDialogConfig, DynamicDialogRef } from "primeng/dynamicdialog";
|
|
7
|
-
import { DynamicFormComponent } from "../dynamic-form/dynamic-form.component";
|
|
8
|
-
import { DynamicFormData } from "../dynamic-form/dynamic-form.interface";
|
|
9
|
-
import {TranslatePipe} from "@ngx-translate/core";
|
|
10
|
-
|
|
11
|
-
@Component({
|
|
12
|
-
selector: "app-confirm-dialog",
|
|
13
|
-
templateUrl: "./confirmation-dialog.component.html",
|
|
14
|
-
styleUrls: ["./confirmation-dialog.component.scss"],
|
|
15
|
-
standalone: true,
|
|
16
|
-
imports: [AppButtonComponent, AvatarModule, DynamicDialog, DynamicFormComponent, TranslatePipe],
|
|
17
|
-
providers: [DialogService]
|
|
18
|
-
})
|
|
19
|
-
export class ConfirmationDialogComponent implements OnInit, OnDestroy {
|
|
20
|
-
router = inject(Router);
|
|
21
|
-
dialogService = inject(DialogService);
|
|
22
|
-
dynamicDialogConfig = inject(DynamicDialogConfig);
|
|
23
|
-
private readonly _ref = inject(DynamicDialogRef);
|
|
24
|
-
private readonly _subscription = new Subscription();
|
|
25
|
-
dialogFormData: DynamicFormData;
|
|
26
|
-
|
|
27
|
-
ngOnInit() {
|
|
28
|
-
// closing when navigating back from the browser
|
|
29
|
-
this._subscription.add(
|
|
30
|
-
this.router.events.pipe(filter((event) => event instanceof NavigationStart)).subscribe(() => {
|
|
31
|
-
if (this.dynamicDialogConfig) {
|
|
32
|
-
this._ref.close();
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
);
|
|
36
|
-
this.dialogFormData = this.dynamicDialogConfig.data?.inputForm;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
ngOnDestroy(): void {
|
|
40
|
-
this._subscription.unsubscribe();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
submit() {
|
|
44
|
-
const submitData = { submitted: true, data: this.dialogFormData?.formGroup?.value };
|
|
45
|
-
this._ref.close(this.dynamicDialogConfig.data.inputForm ? submitData : true);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
close() {
|
|
49
|
-
this._ref.close();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
<div class="border-t mx-4 py-2">
|
|
2
|
-
<form [formGroup]="formGroup">
|
|
3
|
-
<div class="grid grid-cols-12 gap-x-2">
|
|
4
|
-
@for (inputName of inputsNames; track $index) {
|
|
5
|
-
<div
|
|
6
|
-
[ngClass]="inputsMap[inputName].rowSize === 'half' ? 'col-span-6 md:col-span-6': 'col-span-12 md:col-span-12'">
|
|
7
|
-
@switch (inputsMap[inputName].fieldType) {
|
|
8
|
-
@case (fieldType.DATE_PICKER) {
|
|
9
|
-
<stc-date-picker
|
|
10
|
-
[minDate]="inputsMap[inputName]?.dateRange?.min"
|
|
11
|
-
[id]="inputsMap[inputName].inputId"
|
|
12
|
-
[control]="getFormControl(inputName, formGroup)"
|
|
13
|
-
[name]="inputName"
|
|
14
|
-
[label]="inputsMap[inputName].label"
|
|
15
|
-
[showIcon]="inputsMap[inputName].showIcon || true"
|
|
16
|
-
[isTimeOnly]="inputsMap[inputName].isTimeOnly || false"/>
|
|
17
|
-
}
|
|
18
|
-
@case (fieldType.SELECT_BUTTON) {
|
|
19
|
-
<stc-select-button
|
|
20
|
-
[control]="getFormControl(inputName, formGroup)"
|
|
21
|
-
[id]="inputsMap[inputName].inputId"
|
|
22
|
-
[name]="inputName"
|
|
23
|
-
[label]="inputsMap[inputName].label"
|
|
24
|
-
[options]="inputsMap[inputName].selectButtonOptions || []"/>
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
</div>
|
|
28
|
-
}
|
|
29
|
-
</div>
|
|
30
|
-
<div class="col-span-12">
|
|
31
|
-
<small class="p-error text-red-700">
|
|
32
|
-
@for (error of formGroup.errors | validationErrors: dynamicFormData.formValidationErrorsKeys;
|
|
33
|
-
track error) {
|
|
34
|
-
{{ error }}
|
|
35
|
-
}
|
|
36
|
-
</small>
|
|
37
|
-
</div>
|
|
38
|
-
</form>
|
|
39
|
-
</div>
|
|
File without changes
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from "@angular/core/testing";
|
|
2
|
-
import { DynamicFormComponent } from "./dynamic-form.component";
|
|
3
|
-
|
|
4
|
-
describe("DynamicFormComponent", () => {
|
|
5
|
-
let component: DynamicFormComponent;
|
|
6
|
-
let fixture: ComponentFixture<DynamicFormComponent>;
|
|
7
|
-
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
await TestBed.configureTestingModule({
|
|
10
|
-
imports: [DynamicFormComponent]
|
|
11
|
-
}).compileComponents();
|
|
12
|
-
|
|
13
|
-
fixture = TestBed.createComponent(DynamicFormComponent);
|
|
14
|
-
component = fixture.componentInstance;
|
|
15
|
-
fixture.detectChanges();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("should create", () => {
|
|
19
|
-
expect(component).toBeTruthy();
|
|
20
|
-
});
|
|
21
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Component, Input, OnInit } from "@angular/core";
|
|
2
|
-
import { CommonModule } from "@angular/common";
|
|
3
|
-
import { FormGroup, ReactiveFormsModule } from "@angular/forms";
|
|
4
|
-
import { DynamicFormData, FormFieldTypeEnum, InputsMap } from "./dynamic-form.interface";
|
|
5
|
-
import {DatePickerComponent, FormUtils, SelectButtonComponent, ValidationErrorsPipe} from "../form-components";
|
|
6
|
-
import { TranslateModule } from "@ngx-translate/core";
|
|
7
|
-
|
|
8
|
-
@Component({
|
|
9
|
-
selector: "app-dynamic-form",
|
|
10
|
-
standalone: true,
|
|
11
|
-
imports: [CommonModule, ReactiveFormsModule, DatePickerComponent, ValidationErrorsPipe, TranslateModule, SelectButtonComponent],
|
|
12
|
-
templateUrl: "./dynamic-form.component.html",
|
|
13
|
-
styleUrl: "./dynamic-form.component.scss"
|
|
14
|
-
})
|
|
15
|
-
export class DynamicFormComponent implements OnInit {
|
|
16
|
-
@Input({ required: true }) dynamicFormData: DynamicFormData;
|
|
17
|
-
inputsNames: string[] = [];
|
|
18
|
-
formGroup: FormGroup;
|
|
19
|
-
inputsMap: InputsMap;
|
|
20
|
-
readonly fieldType = FormFieldTypeEnum;
|
|
21
|
-
getFormControl = FormUtils.getFormControl;
|
|
22
|
-
|
|
23
|
-
ngOnInit(): void {
|
|
24
|
-
this.formGroup = this.dynamicFormData?.formGroup as FormGroup;
|
|
25
|
-
this.inputsMap = this.dynamicFormData?.inputsMap as InputsMap;
|
|
26
|
-
this.inputsNames = Object.keys(this.inputsMap || {});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import {FormGroup} from "@angular/forms";
|
|
2
|
-
import {LabelValue} from "../form-components";
|
|
3
|
-
|
|
4
|
-
export type InputType = "text" | "textarea";
|
|
5
|
-
export type InputContentType = "text" | "email" | "password" | "number";
|
|
6
|
-
|
|
7
|
-
export interface Dropdown<T = unknown> {
|
|
8
|
-
id?: string;
|
|
9
|
-
keyValue: T;
|
|
10
|
-
label: string;
|
|
11
|
-
hidden?: boolean;
|
|
12
|
-
disabled?: boolean;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface InputsMapData {
|
|
16
|
-
// General props
|
|
17
|
-
label: string;
|
|
18
|
-
rowSize?: "half" | "full";
|
|
19
|
-
fieldType: FormFieldTypeEnum;
|
|
20
|
-
inputId?: string;
|
|
21
|
-
|
|
22
|
-
// Date
|
|
23
|
-
dateRange?: DateRangeInterface;
|
|
24
|
-
isTimeOnly?: boolean;
|
|
25
|
-
showIcon?: boolean;
|
|
26
|
-
|
|
27
|
-
//select button
|
|
28
|
-
selectButtonOptions?: LabelValue<any>[];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface InputsMap {
|
|
32
|
-
[key: string]: InputsMapData;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface DynamicFormData {
|
|
36
|
-
isActive?: boolean;
|
|
37
|
-
formGroup: FormGroup | null;
|
|
38
|
-
inputsMap: InputsMap | null;
|
|
39
|
-
title?: string;
|
|
40
|
-
isReadOnlyForm?: boolean;
|
|
41
|
-
formValidationErrorsKeys?: string[];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface DateRangeInterface {
|
|
45
|
-
min?: Date | null; // Static range, hard coded
|
|
46
|
-
max?: Date | null; // Static range, hard coded
|
|
47
|
-
notBeforeDateInput?: string; // For dynamic date range validation
|
|
48
|
-
notAfterDateInput?: string; // For dynamic date range validation
|
|
49
|
-
notBeforeOrSameDateInput?: string;
|
|
50
|
-
notAfterOrSameDateInput?: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export enum FormFieldTypeEnum {
|
|
54
|
-
DATE_PICKER = "date-picker",
|
|
55
|
-
SELECT_BUTTON = "select-button"
|
|
56
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import {FormControl, FormGroup} from "@angular/forms";
|
|
2
|
-
|
|
3
|
-
export class FormUtils {
|
|
4
|
-
static getFormControl(controlName: string, form: FormGroup): FormControl {
|
|
5
|
-
if (!form) throw new Error(`Form is not initialized.`);
|
|
6
|
-
const formControl = form.get(controlName) as FormControl;
|
|
7
|
-
|
|
8
|
-
if (!formControl) throw new Error(`There's no form control with given name. '${controlName}'`);
|
|
9
|
-
|
|
10
|
-
return formControl;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export enum BasicErrorKeysEnum {
|
|
2
|
-
required = "REQUIRED",
|
|
3
|
-
email = "EMAIL",
|
|
4
|
-
pattern = "PATTERN",
|
|
5
|
-
invalidArFormat = "INVALID_AR_FORMAT",
|
|
6
|
-
invalidLink = "INVALID_LINK",
|
|
7
|
-
endDateBeforeStartDate = "END_DATE_BEFORE_START_DATE",
|
|
8
|
-
startDateEqualsEndDate = "START_DATE_EQUALS_END_DATE",
|
|
9
|
-
endTimeBeforeStartTime = "END_TIME_BEFORE_START_TIME",
|
|
10
|
-
startTimeEqualsEndTime = "START_TIME_EQUALS_END_TIME",
|
|
11
|
-
integer = "INTEGER",
|
|
12
|
-
positiveNumber = "POSITIVE_NUMBER",
|
|
13
|
-
fileSelected = "FILE_SELECTED",
|
|
14
|
-
default = "DEFAULT"
|
|
15
|
-
}
|
|
16
|
-
export enum ErrorsWithValuesKeysEnum {
|
|
17
|
-
minlength = "MIN_LENGTH",
|
|
18
|
-
maxlength = "MAX_LENGTH",
|
|
19
|
-
min = "MIN",
|
|
20
|
-
max = "MAX",
|
|
21
|
-
maxSize = "MAX_SIZE",
|
|
22
|
-
maxFiles = "MAX_FILES",
|
|
23
|
-
allowedTypes = "ALLOWED_TYPES"
|
|
24
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { inject, Injectable } from "@angular/core";
|
|
2
|
-
import { TranslateService } from "@ngx-translate/core";
|
|
3
|
-
import { InterpolationParameters } from "@ngx-translate/core/lib/translate.service";
|
|
4
|
-
import { BasicErrorKeysEnum, ErrorsWithValuesKeysEnum } from "./error-keys.enum";
|
|
5
|
-
|
|
6
|
-
@Injectable({
|
|
7
|
-
providedIn: "root"
|
|
8
|
-
})
|
|
9
|
-
export class FormValidationService {
|
|
10
|
-
private translate = inject(TranslateService);
|
|
11
|
-
|
|
12
|
-
private getTranslation(key: string, interpolateParams?: InterpolationParameters): string {
|
|
13
|
-
return this.translate.instant(`VALIDATION.${key}`, interpolateParams);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
getErrorMessage(errorKey: string, errorValue: any): string {
|
|
17
|
-
if (this.isBasicErrorKey(errorKey)) {
|
|
18
|
-
return this.getTranslation(BasicErrorKeysEnum[errorKey as keyof typeof BasicErrorKeysEnum]);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (this.isErrorWithValueKey(errorKey)) {
|
|
22
|
-
return this.getErrorWithValueMessage(errorKey as keyof typeof ErrorsWithValuesKeysEnum, errorValue);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return this.getTranslation(BasicErrorKeysEnum.default);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Basic error keys are the keys that don't have any values to interpolate. like required, email, etc.
|
|
29
|
-
private isBasicErrorKey(key: string): key is keyof typeof BasicErrorKeysEnum {
|
|
30
|
-
return Object.keys(BasicErrorKeysEnum).includes(key as BasicErrorKeysEnum);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Error keys with values are the keys that have values to interpolate. like minlength, maxlength, etc.
|
|
34
|
-
private isErrorWithValueKey(key: string): key is keyof typeof ErrorsWithValuesKeysEnum {
|
|
35
|
-
return Object.keys(ErrorsWithValuesKeysEnum).includes(key as ErrorsWithValuesKeysEnum);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private getErrorWithValueMessage(errorKey: keyof typeof ErrorsWithValuesKeysEnum, errorValue: any): string {
|
|
39
|
-
const messages: Record<keyof typeof ErrorsWithValuesKeysEnum, (value: any) => string> = {
|
|
40
|
-
minlength: (val) =>
|
|
41
|
-
this.getTranslation(ErrorsWithValuesKeysEnum.minlength, { requiredLength: val?.requiredLength, actualLength: val?.actualLength }),
|
|
42
|
-
maxlength: (val) =>
|
|
43
|
-
this.getTranslation(ErrorsWithValuesKeysEnum.maxlength, { requiredLength: val?.requiredLength, actualLength: val?.actualLength }),
|
|
44
|
-
min: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.min, { min: val?.min }),
|
|
45
|
-
max: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.max, { max: val?.max }),
|
|
46
|
-
maxSize: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxSize, { size: val?.requiredLength }),
|
|
47
|
-
maxFiles: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxFiles, { size: val?.requiredLength }),
|
|
48
|
-
allowedTypes: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.allowedTypes, { types: val?.join(", ") })
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
return messages[errorKey](errorValue);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { inject, Pipe, PipeTransform } from "@angular/core";
|
|
2
|
-
import { ValidationErrors } from "@angular/forms";
|
|
3
|
-
import { FormValidationService } from "./form-validation.service";
|
|
4
|
-
|
|
5
|
-
@Pipe({
|
|
6
|
-
name: "validationErrors",
|
|
7
|
-
standalone: true,
|
|
8
|
-
pure: true
|
|
9
|
-
})
|
|
10
|
-
export class ValidationErrorsPipe implements PipeTransform {
|
|
11
|
-
private formValidationService = inject(FormValidationService);
|
|
12
|
-
|
|
13
|
-
// allowed keys here to handle errors in case of cross-validators like startDate and endDate validators,
|
|
14
|
-
// we pass this custom key to handle the error messages only for the allowed keys
|
|
15
|
-
transform(errors: ValidationErrors | null, allowedKeys?: string[]): string[] {
|
|
16
|
-
if (!errors) return [];
|
|
17
|
-
|
|
18
|
-
return Object.keys(errors)
|
|
19
|
-
.filter((errorKey) => !allowedKeys || allowedKeys.includes(errorKey)) // Filter errors if allowedKeys are provided
|
|
20
|
-
.map((errorKey) => {
|
|
21
|
-
return this.formValidationService.getErrorMessage(errorKey, errors[errorKey]);
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|