@verisoft/ui-primeng 18.0.0 → 18.3.1

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 (157) hide show
  1. package/{src/assets → assets}/sass/base/_typography.scss +2 -2
  2. package/assets/sass/layout/_button.scss +57 -0
  3. package/{src/assets → assets}/sass/layout/_sidemenu.scss +1 -15
  4. package/package.json +5 -4
  5. package/src/index.ts +2 -4
  6. package/src/lib/components/breadcrumb/breadcrumb.component.html +2 -2
  7. package/src/lib/components/breadcrumb/breadcrumb.component.ts +6 -1
  8. package/src/lib/components/breadcrumb/breadcrumb.pipe.ts +13 -0
  9. package/src/lib/components/button/button.component.html +2 -2
  10. package/src/lib/components/button/button.component.ts +7 -1
  11. package/src/lib/components/button/index.ts +0 -1
  12. package/src/lib/components/calendar/calendar.component.html +2 -2
  13. package/src/lib/components/calendar/calendar.component.ts +7 -2
  14. package/src/lib/components/checkbox/checkbox.component.html +1 -1
  15. package/src/lib/components/checkbox/checkbox.component.ts +5 -1
  16. package/src/lib/components/confirm-dialog/confirm-dialog.component.ts +3 -3
  17. package/src/lib/components/confirm-dialog/index.ts +0 -1
  18. package/src/lib/components/dropdown/dropdown.component.html +1 -1
  19. package/src/lib/components/dropdown/dropdown.component.ts +8 -3
  20. package/src/lib/components/errors/error.component.html +6 -0
  21. package/src/lib/components/errors/error.component.scss +3 -0
  22. package/src/lib/components/errors/error.component.ts +35 -0
  23. package/src/lib/components/errors/index.ts +1 -0
  24. package/src/lib/components/form-field/form-field.component.html +3 -8
  25. package/src/lib/components/form-field/form-field.component.ts +17 -13
  26. package/src/lib/components/header/header.component.html +2 -3
  27. package/src/lib/components/header/header.component.ts +3 -1
  28. package/src/lib/components/header/services/header-provider.service.ts +1 -1
  29. package/src/lib/components/input-group/input-group.component.html +1 -3
  30. package/src/lib/components/multiselect/multiselect.component.html +2 -1
  31. package/src/lib/components/multiselect/multiselect.component.ts +5 -3
  32. package/src/lib/components/number-input/number-input.component.html +1 -1
  33. package/src/lib/components/number-input/number-input.component.ts +3 -0
  34. package/src/lib/components/page-header/index.ts +0 -1
  35. package/src/lib/components/page-header/page-header.component.html +1 -1
  36. package/src/lib/components/page-header/page-header.component.ts +6 -34
  37. package/src/lib/components/password/password.component.html +1 -1
  38. package/src/lib/components/password/password.component.ts +3 -1
  39. package/src/lib/components/radiobutton/radiobutton.component.html +1 -1
  40. package/src/lib/components/radiobutton/radiobutton.component.ts +2 -0
  41. package/src/lib/components/section/section.component.html +1 -2
  42. package/src/lib/components/section/section.component.ts +4 -2
  43. package/src/lib/components/{action-button-group → shared-components/action-button-group}/action-button-group.component.html +2 -4
  44. package/src/lib/components/{action-button-group → shared-components/action-button-group}/action-button-group.component.ts +21 -11
  45. package/src/lib/components/{action-button-group → shared-components/action-button-group}/components/action-button/action-button.component.html +1 -2
  46. package/src/lib/components/shared-components/action-button-group/components/action-button/action-button.component.ts +71 -0
  47. package/src/lib/components/shared-components/dynamic-component/dynamic-component-factory.service.ts +142 -0
  48. package/src/lib/components/{dynamic-component → shared-components/dynamic-component}/dynamic-component.component.ts +5 -4
  49. package/src/lib/components/shared-components/dynamic-component/index.ts +2 -0
  50. package/src/lib/components/shared-components/feature-list/directives/feature-list-column.directive.ts +32 -0
  51. package/src/lib/components/shared-components/feature-list/directives/feature-list-filter-field.directive.ts +8 -0
  52. package/src/lib/components/shared-components/feature-list/feature-list-filter.pipe.ts +21 -0
  53. package/src/lib/components/shared-components/feature-list/feature-list-page.component.ts +31 -0
  54. package/src/lib/components/shared-components/feature-list/feature-list-page.model.ts +42 -0
  55. package/src/lib/components/shared-components/feature-list/feature-list.component.html +59 -0
  56. package/src/lib/components/shared-components/feature-list/feature-list.component.scss +10 -0
  57. package/src/lib/components/shared-components/feature-list/feature-list.component.ts +342 -0
  58. package/src/lib/components/shared-components/feature-list/index.ts +5 -0
  59. package/src/lib/components/shared-components/filter/directives/filter-field.directive.ts +35 -0
  60. package/src/lib/components/{filter → shared-components/filter}/filter.component.html +8 -7
  61. package/src/lib/components/{filter → shared-components/filter}/filter.component.ts +53 -26
  62. package/src/lib/components/shared-components/filter/filter.model.ts +18 -0
  63. package/src/lib/components/{filter → shared-components/filter}/index.ts +0 -1
  64. package/src/lib/components/shared-components/generic-field/generic-field.component.html +97 -0
  65. package/src/lib/components/{generic-field → shared-components/generic-field}/generic-field.component.ts +28 -10
  66. package/src/lib/components/{generic-field → shared-components/generic-field}/index.ts +0 -1
  67. package/src/lib/components/shared-components/generic-form/generic-form.component.html +46 -0
  68. package/src/lib/components/{generic-form → shared-components/generic-form}/generic-form.component.ts +11 -2
  69. package/src/lib/components/{generic-form → shared-components/generic-form}/generic-form.model.ts +11 -19
  70. package/src/lib/components/shared-components/index.ts +6 -0
  71. package/src/lib/components/side-menu/side-menu.component.html +7 -10
  72. package/src/lib/components/side-menu/side-menu.component.ts +7 -6
  73. package/src/lib/components/slider/slider.component.html +2 -2
  74. package/src/lib/components/slider/slider.component.ts +2 -0
  75. package/src/lib/components/stepper/stepper.component.html +2 -2
  76. package/src/lib/components/stepper/stepper.component.ts +16 -1
  77. package/src/lib/components/switch/switch.component.html +1 -2
  78. package/src/lib/components/switch/switch.component.ts +2 -0
  79. package/src/lib/components/tab-view/tab-menu.pipe.ts +22 -0
  80. package/src/lib/components/tab-view/tab-view-item.component.ts +2 -0
  81. package/src/lib/components/tab-view/tab-view.component.html +2 -3
  82. package/src/lib/components/tab-view/tab-view.component.ts +4 -4
  83. package/src/lib/components/tab-view/tab-view.module.ts +2 -1
  84. package/src/lib/components/table/index.ts +0 -1
  85. package/src/lib/components/table/table-filter.pipe.ts +59 -0
  86. package/src/lib/components/table/table.component.html +120 -180
  87. package/src/lib/components/table/table.component.scss +11 -0
  88. package/src/lib/components/table/table.component.ts +131 -98
  89. package/src/lib/components/table/table.models.ts +26 -0
  90. package/src/lib/components/textarea/textarea.component.html +1 -1
  91. package/src/lib/components/textarea/textarea.component.ts +2 -0
  92. package/src/lib/components/textfield/textfield.component.html +1 -1
  93. package/src/lib/components/textfield/textfield.component.ts +6 -1
  94. package/src/lib/components/tristatecheckbox/tristatecheckbox.component.html +2 -2
  95. package/src/lib/components/tristatecheckbox/tristatecheckbox.component.ts +4 -0
  96. package/src/lib/icons.ts +36 -0
  97. package/src/lib/pages/not-found-page/not-found-page.component.html +1 -2
  98. package/src/assets/sass/layout/_button.scss +0 -57
  99. package/src/lib/components/action-button-group/components/action-button/action-button.component.ts +0 -36
  100. package/src/lib/components/button/directives/shortcut.directive.ts +0 -37
  101. package/src/lib/components/confirm-dialog/services/confirm-dialog.service.ts +0 -14
  102. package/src/lib/components/dynamic-component/dynamic-component-factory.service.ts +0 -90
  103. package/src/lib/components/filter/directives/filter-field.directive.ts +0 -25
  104. package/src/lib/components/filter/directives/table-filter.directive.ts +0 -22
  105. package/src/lib/components/filter/filter.model.ts +0 -18
  106. package/src/lib/components/generic-field/generic-field.component.html +0 -54
  107. package/src/lib/components/generic-field/generic-field.model.ts +0 -9
  108. package/src/lib/components/generic-form/generic-form.component.html +0 -33
  109. package/src/lib/components/page-header/services/page-header.service.ts +0 -9
  110. package/src/lib/components/table/directives/table-store.directive.ts +0 -61
  111. package/src/lib/components/table-filter/filter.component.html +0 -205
  112. package/src/lib/components/table-filter/filter.component.scss +0 -0
  113. package/src/lib/components/table-filter/filter.component.spec.ts +0 -21
  114. package/src/lib/components/table-filter/filter.component.stories.ts +0 -23
  115. package/src/lib/services/screen-size.service.ts +0 -25
  116. /package/{src/assets → assets}/.gitkeep +0 -0
  117. /package/{src/assets → assets}/fonts/orbitron-black.ttf +0 -0
  118. /package/{src/assets → assets}/fonts/orbitron-bold.otf +0 -0
  119. /package/{src/assets → assets}/icons/complex/v-logo.svg +0 -0
  120. /package/{src/assets → assets}/images/_global/elon.jpg +0 -0
  121. /package/{src/assets → assets}/images/_global/jara.png +0 -0
  122. /package/{src/assets → assets}/images/_global/logos/v-logo.webp +0 -0
  123. /package/{src/assets → assets}/sass/base/_scrollbar.scss +0 -0
  124. /package/{src/assets → assets}/sass/layout/_app.scss +0 -0
  125. /package/{src/assets → assets}/sass/layout/_checkbox.scss +0 -0
  126. /package/{src/assets → assets}/sass/layout/_dialog.scss +0 -0
  127. /package/{src/assets → assets}/sass/layout/_dropdown.scss +0 -0
  128. /package/{src/assets → assets}/sass/layout/_formField.scss +0 -0
  129. /package/{src/assets → assets}/sass/layout/_header.scss +0 -0
  130. /package/{src/assets → assets}/sass/layout/_icons.scss +0 -0
  131. /package/{src/assets → assets}/sass/layout/_inputSwitch.scss +0 -0
  132. /package/{src/assets → assets}/sass/layout/_layout.scss +0 -0
  133. /package/{src/assets → assets}/sass/layout/_loader.scss +0 -0
  134. /package/{src/assets → assets}/sass/layout/_radiobutton.scss +0 -0
  135. /package/{src/assets → assets}/sass/layout/_snackbar.scss +0 -0
  136. /package/{src/assets → assets}/sass/layout/_tables.scss +0 -0
  137. /package/{src/assets → assets}/sass/layout/_tree.scss +0 -0
  138. /package/{src/assets → assets}/sass/layout/_tristatecheckbox.scss +0 -0
  139. /package/{src/assets → assets}/sass/main.scss +0 -0
  140. /package/{src/assets → assets}/sass/themes/_verisoft_theme.scss +0 -0
  141. /package/{src/assets → assets}/sass/utils/_mixins.scss +0 -0
  142. /package/{src/assets → assets}/sass/utils/_utils.scss +0 -0
  143. /package/{src/assets → assets}/sass/utils/_variables.scss +0 -0
  144. /package/{src/assets → assets}/sass/vendors/_bootstrap.scss +0 -0
  145. /package/{src/assets → assets}/sass/vendors/_primeng.scss +0 -0
  146. /package/src/lib/components/{action-button-group → shared-components/action-button-group}/action-button-group.component.scss +0 -0
  147. /package/src/lib/components/{action-button-group → shared-components/action-button-group}/action-button-group.component.spec.ts +0 -0
  148. /package/src/lib/components/{action-button-group → shared-components/action-button-group}/components/action-button/action-button.component.scss +0 -0
  149. /package/src/lib/components/{action-button-group → shared-components/action-button-group}/components/action-button/action-button.component.spec.ts +0 -0
  150. /package/src/lib/components/{action-button-group → shared-components/action-button-group}/index.ts +0 -0
  151. /package/src/lib/components/{filter → shared-components/filter}/filter.component.scss +0 -0
  152. /package/src/lib/components/{filter → shared-components/filter}/filter.component.spec.ts +0 -0
  153. /package/src/lib/components/{filter → shared-components/filter}/filter.component.stories.ts +0 -0
  154. /package/src/lib/components/{generic-field → shared-components/generic-field}/generic-field.component.spec.ts +0 -0
  155. /package/src/lib/components/{generic-form → shared-components/generic-form}/generic-form.component.spec.ts +0 -0
  156. /package/src/lib/components/{generic-form → shared-components/generic-form}/generic-form.model.spec.ts +0 -0
  157. /package/src/lib/components/{generic-form → shared-components/generic-form}/index.ts +0 -0
@@ -32,6 +32,7 @@ import { ScrollerOptions } from 'primeng/api';
32
32
  import { FloatLabelModule } from 'primeng/floatlabel';
33
33
  import { MultiSelectModule } from 'primeng/multiselect';
34
34
  import { ScrollerLazyLoadEvent } from 'primeng/scroller';
35
+ import { ErrorComponent } from '../errors';
35
36
  import { FormFieldComponent } from '../form-field';
36
37
 
37
38
  @Component({
@@ -42,6 +43,7 @@ import { FormFieldComponent } from '../form-field';
42
43
  ReactiveFormsModule,
43
44
  FloatLabelModule,
44
45
  MultiSelectModule,
46
+ ErrorComponent,
45
47
  FormFieldComponent,
46
48
  ],
47
49
  templateUrl: './multiselect.component.html',
@@ -67,9 +69,9 @@ export class MultiselectComponent<T>
67
69
  super(ngControl);
68
70
  }
69
71
 
70
- @Input() options?: T[] = [];
71
- @Input() optionLabel?: string;
72
- @Input() optionValue?: string;
72
+ @Input() options: T[] | undefined = [];
73
+ @Input() optionLabel: string | undefined;
74
+ @Input() optionValue: string | undefined;
73
75
  @Input() dropdownIcon?: string;
74
76
  @Input() floatLabel?: string;
75
77
  @Input() editable = true;
@@ -4,7 +4,6 @@
4
4
  [label]="label"
5
5
  [tooltip]="tooltip"
6
6
  [required]="isRequired()"
7
- [ngControl]="ngControl"
8
7
  [testId]="testId"
9
8
  >
10
9
  <p-inputNumber
@@ -18,5 +17,6 @@
18
17
  [step]="step"
19
18
  [currency]="currency"
20
19
  />
20
+ <v-validation-message [ngControl]="ngControl"></v-validation-message>
21
21
  </v-form-field>
22
22
  </div>
@@ -14,6 +14,7 @@ import {
14
14
  } from '@angular/forms';
15
15
  import { BaseFormInputComponent, BaseInputControls, NUMBER_INPUT_COMPONENT_TOKEN, NumberInputCore } from '@verisoft/ui-core';
16
16
  import { InputNumberModule } from 'primeng/inputnumber';
17
+ import { ErrorComponent } from '../errors';
17
18
  import { FormFieldComponent } from '../form-field';
18
19
 
19
20
  @Component({
@@ -24,6 +25,7 @@ import { FormFieldComponent } from '../form-field';
24
25
  InputNumberModule,
25
26
  ReactiveFormsModule,
26
27
  FormFieldComponent,
28
+ ErrorComponent,
27
29
  ],
28
30
  templateUrl: './number-input.component.html',
29
31
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -51,4 +53,5 @@ export class NumberInputComponent
51
53
  @Input() min!: number;
52
54
  @Input() max!: number;
53
55
  @Input() step = 1;
56
+ @Input() errorMessage?: string = 'test';
54
57
  }
@@ -1,2 +1 @@
1
1
  export * from './page-header.component';
2
- export * from './services/page-header.service';
@@ -4,7 +4,7 @@
4
4
  <v-button
5
5
  *ngIf="showBackButton"
6
6
  size="small"
7
- icon="pi pi-arrow-left"
7
+ [icon]="icons.arrowLeft"
8
8
  label="Back"
9
9
  [outlined]="true"
10
10
  (click)="locationBack()"
@@ -1,18 +1,14 @@
1
1
  import { CommonModule } from '@angular/common';
2
2
  import {
3
3
  ChangeDetectionStrategy,
4
- ChangeDetectorRef,
5
4
  Component,
6
5
  ContentChild,
7
- Input,
8
6
  OnInit,
9
7
  } from '@angular/core';
10
- import { Router } from '@angular/router';
11
- import { PAGE_HEADER_COMPONENT_TOKEN, PageHeaderCore, UnsubscribeComponent } from '@verisoft/ui-core';
12
- import { takeUntil } from 'rxjs';
13
- import { ActionButtonGroupComponent } from '../action-button-group';
8
+ import { PAGE_HEADER_COMPONENT_TOKEN, PageHeaderCore, PageHeaderCoreComponent } from '@verisoft/ui-core';
9
+ import { Icons } from '../../icons';
14
10
  import { ButtonComponent } from '../button';
15
- import { PageHeaderService } from './services/page-header.service';
11
+ import { ActionButtonGroupComponent } from '../shared-components';
16
12
 
17
13
  @Component({
18
14
  selector: 'v-page-header',
@@ -26,35 +22,11 @@ import { PageHeaderService } from './services/page-header.service';
26
22
  ],
27
23
  })
28
24
  export class PageHeaderComponent
29
- extends UnsubscribeComponent
25
+ extends PageHeaderCoreComponent
30
26
  implements OnInit, PageHeaderCore
31
27
  {
32
28
  @ContentChild(ActionButtonGroupComponent)
33
29
  buttonGroup?: ActionButtonGroupComponent;
34
- @Input() title!: string;
35
- @Input() subtitle: string | undefined;
36
- @Input() showBackButton = false;
37
-
38
- constructor(
39
- readonly router: Router,
40
- readonly cdr: ChangeDetectorRef,
41
- readonly headerService: PageHeaderService
42
- ) {
43
- super();
44
- }
45
-
46
- ngOnInit(): void {
47
- this.headerService.pageHeader
48
- .pipe(takeUntil(this.destroyed$))
49
- .subscribe((x) => {
50
- this.title = x.title;
51
- this.subtitle = x.subtitle;
52
- this.showBackButton = x.showBackButton ?? false;
53
- this.cdr.detectChanges();
54
- });
55
- }
56
-
57
- protected locationBack() {
58
- history.back();
59
- }
30
+
31
+ icons = Icons;
60
32
  }
@@ -4,7 +4,6 @@
4
4
  [label]="label"
5
5
  [tooltip]="tooltip"
6
6
  [required]="isRequired()"
7
- [ngControl]="ngControl"
8
7
  [testId]="testId"
9
8
  [display]="formDisplay"
10
9
  >
@@ -20,5 +19,6 @@
20
19
  [id]="inputId"
21
20
  [toggleMask]="toggleMask"
22
21
  />
22
+ <v-validation-message [ngControl]="ngControl"></v-validation-message>
23
23
  </v-form-field>
24
24
  </div>
@@ -14,6 +14,7 @@ import {
14
14
  import { BaseFormInputComponent, BaseInputControls, PASSWORD_COMPONENT_TOKEN, PasswordCore } from '@verisoft/ui-core';
15
15
  import { FloatLabelModule } from 'primeng/floatlabel';
16
16
  import { PasswordModule } from 'primeng/password';
17
+ import { ErrorComponent } from '../errors';
17
18
  import { FormFieldComponent } from '../form-field';
18
19
 
19
20
  @Component({
@@ -24,7 +25,8 @@ import { FormFieldComponent } from '../form-field';
24
25
  ReactiveFormsModule,
25
26
  PasswordModule,
26
27
  FloatLabelModule,
27
- FormFieldComponent
28
+ FormFieldComponent,
29
+ ErrorComponent
28
30
  ],
29
31
  templateUrl: './password.component.html',
30
32
  styleUrl: './password.component.scss',
@@ -3,7 +3,6 @@
3
3
  [label]="label"
4
4
  [required]="required"
5
5
  [tooltip]="tooltip"
6
- [ngControl]="ngControl"
7
6
  [testId]="testId"
8
7
  >
9
8
  <div class="d-flex align-items-center gap-3">
@@ -27,6 +26,7 @@
27
26
  >
28
27
  </label>
29
28
  </div>
29
+ <v-validation-message [ngControl]="ngControl"></v-validation-message>
30
30
  </div>
31
31
  </v-form-field>
32
32
  </div>
@@ -20,6 +20,7 @@ import {
20
20
  RadioButtonItem,
21
21
  } from '@verisoft/ui-core';
22
22
  import { RadioButtonModule } from 'primeng/radiobutton';
23
+ import { ErrorComponent } from '../errors';
23
24
  import { FormFieldComponent } from '../form-field/form-field.component';
24
25
 
25
26
  @Component({
@@ -30,6 +31,7 @@ import { FormFieldComponent } from '../form-field/form-field.component';
30
31
  FormFieldComponent,
31
32
  RadioButtonModule,
32
33
  ReactiveFormsModule,
34
+ ErrorComponent
33
35
  ],
34
36
  templateUrl: './radiobutton.component.html',
35
37
  styleUrl: './radiobutton.component.scss',
@@ -12,8 +12,7 @@
12
12
  <ng-content select="[actions]"></ng-content>
13
13
  <v-button
14
14
  size="small"
15
- icon="pi {{ icon }}"
16
- [text]="true"
15
+ [icon]="icon"
17
16
  (click)="toggle()"
18
17
  />
19
18
  </div>
@@ -1,6 +1,7 @@
1
1
  import { CommonModule } from '@angular/common';
2
2
  import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
3
3
  import { SECTION_COMPONENT_TOKEN, SectionCore } from '@verisoft/ui-core';
4
+ import { Icons } from '../../icons';
4
5
  import { ButtonComponent } from '../button';
5
6
 
6
7
  @Component({
@@ -21,10 +22,11 @@ export class SectionComponent
21
22
  @Input() showContent = true;
22
23
  @Input() backgroundColor!: string;
23
24
 
24
- protected icon = 'pi-angle-down';
25
+ icons = Icons;
26
+ protected icon = Icons.chevronDown;
25
27
 
26
28
  protected toggle(): void {
27
29
  this.showContent = !this.showContent;
28
- this.icon = this.showContent ? 'pi-angle-down' : 'pi-angle-up';
30
+ this.icon = this.showContent ? Icons.chevronDown : Icons.chevronUp;
29
31
  }
30
32
  }
@@ -9,16 +9,14 @@
9
9
  [id]="action.id"
10
10
  [outlined]="action.outlined"
11
11
  [raised]="action.raised"
12
- [text]="action.text"
13
12
  [toolTip]="action.toolTip || action.label"
14
13
  [severity]="action.severity"
15
14
  [size]="action.size"
16
- (clickEvent)="action.clickEvent.emit()"
15
+ (click)="fireClick(action, $event)"
17
16
  ></v-action-button>
18
17
  } @if (actions.length > visibleActions.length) {
19
18
  <v-button
20
19
  (click)="menu.toggle($event)"
21
- [text]="true"
22
20
  [label]="label"
23
21
  [iconPos]="menuIconPos"
24
22
  [icon]="menuIcon"
@@ -26,4 +24,4 @@
26
24
  }
27
25
  </div>
28
26
  </div>
29
- <p-menu #menu [model]="menuItems" [popup]="true" />
27
+ <p-menu #menu [model]="menuItems" [popup]="true" appendTo="body" />
@@ -12,13 +12,18 @@ import {
12
12
  ActionButton,
13
13
  ActionButtonGroupCore,
14
14
  IconPositionType,
15
+ queryListChanged,
16
+ ScreenSizeService,
15
17
  UnsubscribeComponent,
16
18
  } from '@verisoft/ui-core';
17
19
  import { MenuItem } from 'primeng/api';
18
20
  import { MenuModule } from 'primeng/menu';
19
- import { combineLatestWith, map, startWith, takeUntil } from 'rxjs';
20
- import { ScreenSizeService } from '../../services/screen-size.service';
21
- import { ButtonComponent } from '../button';
21
+ import {
22
+ combineLatestWith,
23
+ takeUntil,
24
+ } from 'rxjs';
25
+ import { Icons } from '../../../icons';
26
+ import { ButtonComponent } from '../../button';
22
27
  import { ActionButtonComponent } from './components/action-button/action-button.component';
23
28
 
24
29
  @Component({
@@ -50,16 +55,19 @@ export class ActionButtonGroupComponent
50
55
 
51
56
  @Input() menuIconPos: IconPositionType = 'right';
52
57
 
53
- @Input() menuIcon = 'pi pi-ellipsis-v';
58
+ @Input() menuIcon = Icons.action;
54
59
 
55
60
  @Input() label?: string;
56
61
 
62
+ @Input() icon?: string;
63
+
64
+ icons = Icons;
57
65
  allItems: ActionButton[] = [];
58
66
  visibleActions: ActionButton[] = [];
59
67
  menuItems: MenuItem[] = [];
60
68
 
61
69
  constructor(
62
- private readonly cd: ChangeDetectorRef,
70
+ private readonly changeDetectorRef: ChangeDetectorRef,
63
71
  readonly screenSizeService: ScreenSizeService
64
72
  ) {
65
73
  super();
@@ -69,13 +77,15 @@ export class ActionButtonGroupComponent
69
77
  this.subscribeItemChange();
70
78
  }
71
79
 
80
+ fireClick(item: ActionButton, event: MouseEvent) {
81
+ event.stopPropagation();
82
+ item.click.emit();
83
+ }
84
+
72
85
  private subscribeItemChange(): void {
73
86
  const screenResize$ = this.screenSizeService.isMobileBlock;
74
87
 
75
- const actions$ = this.actions.changes.pipe(
76
- startWith({}),
77
- map(() => this.actions.toArray())
78
- );
88
+ const actions$ = queryListChanged(this.actions);
79
89
 
80
90
  screenResize$
81
91
  .pipe(takeUntil(this.destroyed$), combineLatestWith(actions$))
@@ -89,7 +99,7 @@ export class ActionButtonGroupComponent
89
99
  const maxItems = isMobile ? this.maxItemsMobile : this.maxItems;
90
100
  this.visibleActions = allItems.slice(0, maxItems);
91
101
  this.menuItems = allItems.slice(maxItems).map(this.convertToMenuItem);
92
- this.cd.detectChanges();
102
+ this.changeDetectorRef.detectChanges();
93
103
  }
94
104
 
95
105
  private convertToMenuItem(item: ActionButton): MenuItem {
@@ -97,7 +107,7 @@ export class ActionButtonGroupComponent
97
107
  label: item.label,
98
108
  icon: item.icon,
99
109
  command: () => {
100
- item.clickEvent.emit();
110
+ item.click.emit();
101
111
  },
102
112
  };
103
113
  }
@@ -6,7 +6,6 @@
6
6
  [outlined]="outlined"
7
7
  tooltipPosition="bottom"
8
8
  [size]="size"
9
- [text]="text"
10
9
  [severity]="severity"
11
- (clickEvent)="handleClick()"
10
+ (click)="handleClick($event)"
12
11
  ></v-button>
@@ -0,0 +1,71 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ EventEmitter,
5
+ inject,
6
+ Input,
7
+ OnChanges,
8
+ Output,
9
+ SimpleChanges,
10
+ } from '@angular/core';
11
+ import {
12
+ ACTION_BUTTON_GROUP_COMPONENT_TOKEN,
13
+ ActionButton,
14
+ ActionButtonGroupCore,
15
+ ControlSeverityType,
16
+ FieldSizeType,
17
+ } from '@verisoft/ui-core';
18
+ import { TooltipModule } from 'primeng/tooltip';
19
+ import { Observable, Subject } from 'rxjs';
20
+ import { Icons } from '../../../../../icons';
21
+ import { ButtonComponent } from '../../../../button';
22
+
23
+ @Component({
24
+ selector: 'v-action-button',
25
+ standalone: true,
26
+ imports: [ButtonComponent, TooltipModule],
27
+ templateUrl: './action-button.component.html',
28
+ styleUrl: './action-button.component.scss',
29
+ changeDetection: ChangeDetectionStrategy.OnPush,
30
+ })
31
+ export class ActionButtonComponent implements ActionButton, OnChanges {
32
+ @Input() disabled = false;
33
+ @Input() toolTip?: string;
34
+ @Input() id?: string;
35
+ @Input() icon?: string;
36
+ @Input() outlined = false;
37
+ @Input() raised = false;
38
+ @Input() severity?: ControlSeverityType;
39
+ @Input() label?: string;
40
+ @Input() size?: FieldSizeType;
41
+ // eslint-disable-next-line @angular-eslint/no-output-native
42
+ @Output() click = new EventEmitter<MouseEvent>();
43
+
44
+ icons = Icons
45
+
46
+ private propertyChangeSubject = new Subject();
47
+
48
+ propertyChanged: Observable<unknown> =
49
+ this.propertyChangeSubject.asObservable();
50
+
51
+ buttonGroup: ActionButtonGroupCore | null = inject<ActionButtonGroupCore>(
52
+ ACTION_BUTTON_GROUP_COMPONENT_TOKEN,
53
+ {
54
+ optional: true,
55
+ }
56
+ );
57
+
58
+ ngOnChanges(changes: SimpleChanges): void {
59
+ const isValueChange = Object.keys(changes).some(
60
+ (x) => !changes[x].firstChange
61
+ );
62
+ if (isValueChange) {
63
+ this.propertyChangeSubject.next(null);
64
+ }
65
+ }
66
+
67
+ handleClick(event: MouseEvent) {
68
+ event.stopPropagation();
69
+ this.click.emit(event);
70
+ }
71
+ }
@@ -0,0 +1,142 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import {
3
+ Injectable,
4
+ ViewContainerRef,
5
+ Type,
6
+ ComponentFactoryResolver,
7
+ Injector,
8
+ ComponentRef,
9
+ ComponentFactory,
10
+ OnChanges,
11
+ SimpleChanges,
12
+ SimpleChange,
13
+ EventEmitter,
14
+ OnDestroy,
15
+ } from '@angular/core';
16
+ import { ExtendedComponent } from '@verisoft/ui-core';
17
+ import { Subscription } from 'rxjs';
18
+
19
+ @Injectable({
20
+ providedIn: 'root',
21
+ })
22
+ export class DynamicComponentFactoryService implements OnDestroy {
23
+ constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
24
+
25
+ ngOnDestroy(): void {
26
+ this.unsubscribeComponentEvents(this);
27
+ }
28
+
29
+ async createDynamicComponent<TComponent>(
30
+ componentType: Type<TComponent>,
31
+ viewContainerRef: ViewContainerRef,
32
+ inputs: ExtendedComponent<TComponent>,
33
+ injector: Injector | undefined = undefined
34
+ ) {
35
+ const componentFactory =
36
+ this.componentFactoryResolver.resolveComponentFactory(componentType);
37
+ viewContainerRef.clear();
38
+ const component = viewContainerRef.createComponent(
39
+ componentFactory,
40
+ undefined,
41
+ injector
42
+ );
43
+ this.setComponentDataInt(componentFactory, component, inputs);
44
+ this.fireComponentEvents(component.instance, inputs);
45
+ return component;
46
+ }
47
+
48
+ setComponentData<TComponent>(
49
+ component: ComponentRef<TComponent>,
50
+ inputs: Partial<TComponent>
51
+ ) {
52
+ const factory = this.componentFactoryResolver.resolveComponentFactory(
53
+ component.componentType
54
+ );
55
+
56
+ this.setComponentDataInt(factory, component, inputs);
57
+ }
58
+
59
+ private unsubscribeComponentEvents<TComponent>(instance: TComponent) {
60
+ const subscriptionStoreKey = '__outputSubscriptions__';
61
+ const subscriptions = (instance as any)[subscriptionStoreKey] as Map<string, Subscription>;
62
+
63
+ if (subscriptions) {
64
+ subscriptions.forEach((sub) => sub.unsubscribe());
65
+ subscriptions.clear();
66
+ }
67
+ }
68
+
69
+ private fireComponentEvents<TComponent>(
70
+ instance: TComponent,
71
+ inputs: ExtendedComponent<TComponent>
72
+ ) {
73
+ if (!instance || typeof instance !== 'object') return;
74
+
75
+ this.fireInputComponentEvents(instance, inputs);
76
+ this.fireOutputComponentEvents(instance, inputs);
77
+ }
78
+
79
+ private setComponentDataInt<TComponent>(
80
+ factory: ComponentFactory<TComponent>,
81
+ component: ComponentRef<TComponent>,
82
+ inputs: Partial<TComponent>
83
+ ) {
84
+ if (inputs) {
85
+ const propertyNames = factory.inputs.map((x) => x.propName);
86
+ const inputsHash = new Set(propertyNames);
87
+ Object.keys(inputs)
88
+ .filter((x) => inputsHash.has(x))
89
+ .forEach((x) => {
90
+ (<{ [key: string]: unknown }>component.instance)[x] = (<
91
+ { [key: string]: unknown }
92
+ >inputs)[x];
93
+ });
94
+ }
95
+ }
96
+
97
+ private fireInputComponentEvents<TComponent>(
98
+ instance: TComponent,
99
+ inputs: ExtendedComponent<TComponent>
100
+ ) {
101
+ const onChangeComponent = instance as unknown as OnChanges;
102
+ if (onChangeComponent.ngOnChanges && inputs) {
103
+ const changeEventArgs = Object.keys(inputs).reduce((changes: SimpleChanges, key: string) => {
104
+ const inputValue = (inputs as { [key: string]: unknown })[key];
105
+ changes[key] = new SimpleChange(undefined, inputValue, true);
106
+ return changes;
107
+ }, {} as SimpleChanges);
108
+
109
+ onChangeComponent.ngOnChanges(changeEventArgs);
110
+ }
111
+ }
112
+
113
+ private fireOutputComponentEvents<TComponent>(
114
+ instance: TComponent & object,
115
+ inputs: ExtendedComponent<TComponent>
116
+ ) {
117
+ const outputs = Object.keys(inputs).filter((key) => {
118
+ const emitter = (instance as Record<string, any>)[key];
119
+ return emitter instanceof EventEmitter;
120
+ });
121
+
122
+ const subscriptionStoreKey = '__outputSubscriptions__';
123
+ if (!(subscriptionStoreKey in instance)) {
124
+ (instance as any)[subscriptionStoreKey] = new Map<string, Subscription>();
125
+ }
126
+ const subscriptions = (instance as any)[subscriptionStoreKey] as Map<string, Subscription>;
127
+
128
+ for (const outputKey of outputs) {
129
+ const eventEmitter = (instance as Record<string, any>)[outputKey] as EventEmitter<any>;
130
+ const callback = inputs[outputKey] as (value: any) => void;
131
+
132
+ if (eventEmitter && typeof callback === 'function') {
133
+ if (subscriptions.has(outputKey)) {
134
+ subscriptions.get(outputKey)!.unsubscribe();
135
+ }
136
+
137
+ const subscription = eventEmitter.subscribe((value: any) => callback(value));
138
+ subscriptions.set(outputKey, subscription);
139
+ }
140
+ }
141
+ }
142
+ }
@@ -11,6 +11,7 @@ import {
11
11
  ViewChild,
12
12
  ViewContainerRef,
13
13
  } from '@angular/core';
14
+ import { ExtendedComponent } from '@verisoft/ui-core';
14
15
  import { DynamicComponentFactoryService } from './dynamic-component-factory.service';
15
16
 
16
17
  @Component({
@@ -22,7 +23,7 @@ import { DynamicComponentFactoryService } from './dynamic-component-factory.serv
22
23
  export class DynamicComponent<TComponent> implements AfterViewInit, OnChanges {
23
24
  @Input() componentType!: Type<TComponent>;
24
25
 
25
- @Input() data!: Partial<TComponent>;
26
+ @Input() data!: ExtendedComponent<TComponent>;
26
27
 
27
28
  @ViewChild('dynamicContainer', { read: ViewContainerRef, static: true })
28
29
  container!: ViewContainerRef;
@@ -34,15 +35,15 @@ export class DynamicComponent<TComponent> implements AfterViewInit, OnChanges {
34
35
  private injector = inject(Injector);
35
36
 
36
37
  ngOnChanges(): void {
37
- this.crateComponent();
38
+ this.createComponent();
38
39
  }
39
40
 
40
41
  ngAfterViewInit(): void {
41
- this.crateComponent();
42
+ this.createComponent();
42
43
  this.changeDetectorRef.detectChanges();
43
44
  }
44
45
 
45
- private crateComponent() {
46
+ private createComponent() {
46
47
  if (this.container) {
47
48
  this.factoryServices.createDynamicComponent(
48
49
  this.componentType,
@@ -0,0 +1,2 @@
1
+ export * from './dynamic-component-factory.service';
2
+ export * from './dynamic-component.component';
@@ -0,0 +1,32 @@
1
+ import { Directive, Input } from '@angular/core';
2
+ import { GenericFieldType, GenericFieldTypeType, TableColumnDirective } from '@verisoft/ui-core';
3
+ import { FEATURE_LIST_COLUMN_PROVIDER, FeatureListColumnDefinition, FeatureListColumnProvider } from '../feature-list-page.model';
4
+
5
+ @Directive({
6
+ // eslint-disable-next-line @angular-eslint/directive-selector
7
+ selector: 'v-feature-list-column',
8
+ standalone: true,
9
+ providers: [
10
+ {
11
+ provide: FEATURE_LIST_COLUMN_PROVIDER,
12
+ useExisting: FeatureListColumnDirective,
13
+ multi: true,
14
+ },
15
+ ],
16
+ })
17
+ export class FeatureListColumnDirective<T>
18
+ extends TableColumnDirective<T>
19
+ implements FeatureListColumnProvider<T>
20
+ {
21
+ @Input() filter = false;
22
+
23
+ @Input() type: GenericFieldTypeType = GenericFieldType.text;
24
+
25
+ override getDefinition(): FeatureListColumnDefinition<T> {
26
+ const definition = super.getDefinition() as FeatureListColumnDefinition<T>;
27
+ definition.filter = this.filter;
28
+ definition.type = this.type;
29
+ definition.format = this.format;
30
+ return definition;
31
+ }
32
+ }
@@ -0,0 +1,8 @@
1
+ import { Directive } from '@angular/core';
2
+ import { FilterFieldDirective } from '../../filter';
3
+ @Directive({
4
+ // eslint-disable-next-line @angular-eslint/directive-selector
5
+ selector: 'v-feature-list-filter-field',
6
+ standalone: true,
7
+ })
8
+ export class FeatureListFilterFieldDirective extends FilterFieldDirective {}
@@ -0,0 +1,21 @@
1
+ import { Pipe, PipeTransform } from "@angular/core";
2
+ import { GenericFieldDefinition, GenericFieldType } from "@verisoft/ui-core";
3
+ import { FeatureListColumnDefinition } from "./feature-list-page.model";
4
+
5
+ @Pipe({
6
+ name: 'featureListColumn',
7
+ standalone: true,
8
+ })
9
+ export class FeatureListFilterPipe<T> implements PipeTransform {
10
+ transform(value: FeatureListColumnDefinition<T>[] | undefined): GenericFieldDefinition[] | undefined {
11
+ if (!value){
12
+ return undefined;
13
+ }
14
+
15
+ return value.filter(x => x.filter).map((x, index) => ({
16
+ name: x.id,
17
+ label: typeof x.headerName === 'function'? x.headerName(x.id, index) : x.headerName ?? '',
18
+ type: x.type as GenericFieldType,
19
+ }));
20
+ }
21
+ }