@smartsoft001/crud-shell-angular 1.2.91 → 2.69.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.
Files changed (214) hide show
  1. package/.storybook/addons.js +1 -0
  2. package/.storybook/config.js +5 -0
  3. package/.storybook/tsconfig.json +8 -0
  4. package/.storybook/webpack.config.js +7 -0
  5. package/jest.config.ts +38 -0
  6. package/ng-package.json +7 -0
  7. package/package.json +12 -23
  8. package/project.json +49 -0
  9. package/src/index.ts +13 -0
  10. package/src/lib/+state/crud.facade.ts +82 -0
  11. package/src/lib/+state/crud.feature.methods.ts +258 -0
  12. package/src/lib/+state/crud.feature.store.ts +77 -0
  13. package/src/lib/components/components.module.ts +58 -0
  14. package/src/lib/components/export/export.component.ts +69 -0
  15. package/src/lib/components/filter/base/base.component.ts +175 -0
  16. package/src/lib/components/filter/check/check.component.scss +25 -0
  17. package/src/lib/components/filter/check/check.component.ts +72 -0
  18. package/src/lib/components/filter/date/date.component.html +30 -0
  19. package/src/lib/components/filter/date/date.component.ts +70 -0
  20. package/src/lib/components/filter/date-time/date-time.component.html +62 -0
  21. package/src/lib/components/filter/date-time/date-time.component.ts +56 -0
  22. package/src/lib/components/filter/date-with-edit/date-with-edit.component.html +109 -0
  23. package/src/lib/components/filter/date-with-edit/date-with-edit.component.ts +70 -0
  24. package/src/lib/components/filter/filter.component.html +52 -0
  25. package/src/lib/components/filter/filter.component.ts +34 -0
  26. package/src/lib/components/filter/flag/flag.component.ts +55 -0
  27. package/src/lib/components/filter/index.ts +9 -0
  28. package/src/lib/components/filter/int/int.component.html +74 -0
  29. package/src/lib/components/filter/int/int.component.ts +57 -0
  30. package/src/lib/components/filter/radio/radio.component.ts +74 -0
  31. package/src/lib/components/filter/text/text.component.ts +46 -0
  32. package/src/lib/components/filters/filters.component.scss +150 -0
  33. package/src/lib/components/filters/filters.component.ts +157 -0
  34. package/src/lib/components/filters-config/filters-config.component.ts +69 -0
  35. package/src/lib/components/group/group.component.ts +93 -0
  36. package/src/lib/components/index.ts +7 -0
  37. package/src/lib/components/multiselect/multiselect.component.html +41 -0
  38. package/src/lib/components/multiselect/multiselect.component.scss +125 -0
  39. package/src/lib/components/multiselect/multiselect.component.ts +104 -0
  40. package/src/lib/crud-full.module.ts +51 -0
  41. package/src/lib/crud.config.ts +79 -0
  42. package/src/lib/crud.module.ts +72 -0
  43. package/src/lib/factories/list-pagination/list-pagination.factory.ts +77 -0
  44. package/src/lib/models/index.ts +1 -0
  45. package/src/lib/models/interfaces.ts +34 -0
  46. package/src/lib/pages/index.ts +6 -0
  47. package/src/lib/pages/item/base/base.component.ts +54 -0
  48. package/src/lib/pages/item/item.component.ts +513 -0
  49. package/src/lib/pages/item/standard/standard.component.scss +0 -0
  50. package/src/lib/pages/item/standard/standard.component.ts +50 -0
  51. package/src/lib/pages/list/base/base.component.ts +29 -0
  52. package/src/lib/pages/list/list.component.stories.ts +77 -0
  53. package/src/lib/pages/list/list.component.ts +438 -0
  54. package/src/lib/pages/list/standard/standard.component.ts +42 -0
  55. package/src/lib/pipes/form-options/form-options.pipe.ts +61 -0
  56. package/src/lib/pipes/index.ts +2 -0
  57. package/src/lib/pipes/pipes.module.ts +9 -0
  58. package/src/lib/providers/model-possibilities/model-possibilities.provider.ts +19 -0
  59. package/src/lib/services/crud/crud.service.spec.ts +303 -0
  60. package/src/lib/services/crud/crud.service.ts +178 -0
  61. package/src/lib/services/list-group/list-group.service.spec.ts +87 -0
  62. package/src/lib/services/list-group/list-group.service.ts +65 -0
  63. package/src/lib/services/page/page.service.spec.ts +143 -0
  64. package/src/lib/services/page/page.service.ts +44 -0
  65. package/src/lib/services/search/search.service.spec.ts +134 -0
  66. package/src/lib/services/search/search.service.ts +42 -0
  67. package/test-setup.ts +0 -0
  68. package/tsconfig.json +13 -0
  69. package/tsconfig.lib.json +31 -0
  70. package/tsconfig.lib.prod.json +11 -0
  71. package/tsconfig.spec.json +10 -0
  72. package/tslint.json +10 -0
  73. package/esm2022/index.mjs +0 -18
  74. package/esm2022/lib/+state/crud.actions.mjs +0 -224
  75. package/esm2022/lib/+state/crud.effects.mjs +0 -182
  76. package/esm2022/lib/+state/crud.facade.mjs +0 -91
  77. package/esm2022/lib/+state/crud.reducer.mjs +0 -214
  78. package/esm2022/lib/+state/crud.selectors.mjs +0 -11
  79. package/esm2022/lib/components/components.module.mjs +0 -110
  80. package/esm2022/lib/components/export/export.component.mjs +0 -47
  81. package/esm2022/lib/components/filter/base/base.component.mjs +0 -152
  82. package/esm2022/lib/components/filter/check/check.component.mjs +0 -36
  83. package/esm2022/lib/components/filter/date/date.component.mjs +0 -47
  84. package/esm2022/lib/components/filter/date-time/date-time.component.mjs +0 -43
  85. package/esm2022/lib/components/filter/date-with-edit/date-with-edit.component.mjs +0 -49
  86. package/esm2022/lib/components/filter/filter.component.mjs +0 -30
  87. package/esm2022/lib/components/filter/flag/flag.component.mjs +0 -16
  88. package/esm2022/lib/components/filter/index.mjs +0 -10
  89. package/esm2022/lib/components/filter/int/int.component.mjs +0 -38
  90. package/esm2022/lib/components/filter/radio/radio.component.mjs +0 -16
  91. package/esm2022/lib/components/filter/text/text.component.mjs +0 -16
  92. package/esm2022/lib/components/filters/filters.component.mjs +0 -111
  93. package/esm2022/lib/components/filters-config/filters-config.component.mjs +0 -37
  94. package/esm2022/lib/components/group/group.component.mjs +0 -54
  95. package/esm2022/lib/components/index.mjs +0 -8
  96. package/esm2022/lib/components/multiselect/multiselect.component.mjs +0 -71
  97. package/esm2022/lib/crud-full.module.mjs +0 -103
  98. package/esm2022/lib/crud.config.mjs +0 -17
  99. package/esm2022/lib/crud.module.mjs +0 -106
  100. package/esm2022/lib/factories/list-pagination/list-pagination.factory.mjs +0 -69
  101. package/esm2022/lib/models/index.mjs +0 -2
  102. package/esm2022/lib/models/interfaces.mjs +0 -2
  103. package/esm2022/lib/pages/index.mjs +0 -7
  104. package/esm2022/lib/pages/item/base/base.component.mjs +0 -44
  105. package/esm2022/lib/pages/item/item.component.mjs +0 -395
  106. package/esm2022/lib/pages/item/standard/standard.component.mjs +0 -15
  107. package/esm2022/lib/pages/list/base/base.component.mjs +0 -23
  108. package/esm2022/lib/pages/list/list.component.mjs +0 -355
  109. package/esm2022/lib/pages/list/standard/standard.component.mjs +0 -34
  110. package/esm2022/lib/pipes/form-options/form-options.pipe.mjs +0 -55
  111. package/esm2022/lib/pipes/index.mjs +0 -3
  112. package/esm2022/lib/pipes/pipes.module.mjs +0 -20
  113. package/esm2022/lib/providers/model-possibilities/model-possibilities.provider.mjs +0 -11
  114. package/esm2022/lib/services/crud/crud.service.mjs +0 -138
  115. package/esm2022/lib/services/list-group/list-group.service.mjs +0 -60
  116. package/esm2022/lib/services/page/page.service.mjs +0 -41
  117. package/esm2022/lib/services/search/search.service.mjs +0 -41
  118. package/esm2022/lib/services/socket/socket.service.mjs +0 -17
  119. package/esm2022/smartsoft001-crud-shell-angular.mjs +0 -5
  120. package/fesm2022/smartsoft001-crud-shell-angular.mjs +0 -2810
  121. package/fesm2022/smartsoft001-crud-shell-angular.mjs.map +0 -1
  122. package/index.d.ts +0 -18
  123. package/index.d.ts.map +0 -1
  124. package/lib/+state/crud.actions.d.ts +0 -152
  125. package/lib/+state/crud.actions.d.ts.map +0 -1
  126. package/lib/+state/crud.effects.d.ts +0 -18
  127. package/lib/+state/crud.effects.d.ts.map +0 -1
  128. package/lib/+state/crud.facade.d.ts +0 -44
  129. package/lib/+state/crud.facade.d.ts.map +0 -1
  130. package/lib/+state/crud.reducer.d.ts +0 -43
  131. package/lib/+state/crud.reducer.d.ts.map +0 -1
  132. package/lib/+state/crud.selectors.d.ts +0 -10
  133. package/lib/+state/crud.selectors.d.ts.map +0 -1
  134. package/lib/components/components.module.d.ts +0 -27
  135. package/lib/components/components.module.d.ts.map +0 -1
  136. package/lib/components/export/export.component.d.ts +0 -21
  137. package/lib/components/export/export.component.d.ts.map +0 -1
  138. package/lib/components/filter/base/base.component.d.ts +0 -39
  139. package/lib/components/filter/base/base.component.d.ts.map +0 -1
  140. package/lib/components/filter/check/check.component.d.ts +0 -19
  141. package/lib/components/filter/check/check.component.d.ts.map +0 -1
  142. package/lib/components/filter/date/date.component.d.ts +0 -16
  143. package/lib/components/filter/date/date.component.d.ts.map +0 -1
  144. package/lib/components/filter/date-time/date-time.component.d.ts +0 -15
  145. package/lib/components/filter/date-time/date-time.component.d.ts.map +0 -1
  146. package/lib/components/filter/date-with-edit/date-with-edit.component.d.ts +0 -17
  147. package/lib/components/filter/date-with-edit/date-with-edit.component.d.ts.map +0 -1
  148. package/lib/components/filter/filter.component.d.ts +0 -14
  149. package/lib/components/filter/filter.component.d.ts.map +0 -1
  150. package/lib/components/filter/flag/flag.component.d.ts +0 -8
  151. package/lib/components/filter/flag/flag.component.d.ts.map +0 -1
  152. package/lib/components/filter/index.d.ts +0 -10
  153. package/lib/components/filter/index.d.ts.map +0 -1
  154. package/lib/components/filter/int/int.component.d.ts +0 -15
  155. package/lib/components/filter/int/int.component.d.ts.map +0 -1
  156. package/lib/components/filter/radio/radio.component.d.ts +0 -8
  157. package/lib/components/filter/radio/radio.component.d.ts.map +0 -1
  158. package/lib/components/filter/text/text.component.d.ts +0 -8
  159. package/lib/components/filter/text/text.component.d.ts.map +0 -1
  160. package/lib/components/filters/filters.component.d.ts +0 -83
  161. package/lib/components/filters/filters.component.d.ts.map +0 -1
  162. package/lib/components/filters-config/filters-config.component.d.ts +0 -19
  163. package/lib/components/filters-config/filters-config.component.d.ts.map +0 -1
  164. package/lib/components/group/group.component.d.ts +0 -23
  165. package/lib/components/group/group.component.d.ts.map +0 -1
  166. package/lib/components/index.d.ts +0 -8
  167. package/lib/components/index.d.ts.map +0 -1
  168. package/lib/components/multiselect/multiselect.component.d.ts +0 -28
  169. package/lib/components/multiselect/multiselect.component.d.ts.map +0 -1
  170. package/lib/crud-full.module.d.ts +0 -28
  171. package/lib/crud-full.module.d.ts.map +0 -1
  172. package/lib/crud.config.d.ts +0 -65
  173. package/lib/crud.config.d.ts.map +0 -1
  174. package/lib/crud.module.d.ts +0 -34
  175. package/lib/crud.module.d.ts.map +0 -1
  176. package/lib/factories/list-pagination/list-pagination.factory.d.ts +0 -20
  177. package/lib/factories/list-pagination/list-pagination.factory.d.ts.map +0 -1
  178. package/lib/models/index.d.ts +0 -2
  179. package/lib/models/index.d.ts.map +0 -1
  180. package/lib/models/interfaces.d.ts +0 -30
  181. package/lib/models/interfaces.d.ts.map +0 -1
  182. package/lib/pages/index.d.ts +0 -7
  183. package/lib/pages/index.d.ts.map +0 -1
  184. package/lib/pages/item/base/base.component.d.ts +0 -25
  185. package/lib/pages/item/base/base.component.d.ts.map +0 -1
  186. package/lib/pages/item/item.component.d.ts +0 -70
  187. package/lib/pages/item/item.component.d.ts.map +0 -1
  188. package/lib/pages/item/standard/standard.component.d.ts +0 -8
  189. package/lib/pages/item/standard/standard.component.d.ts.map +0 -1
  190. package/lib/pages/list/base/base.component.d.ts +0 -15
  191. package/lib/pages/list/base/base.component.d.ts.map +0 -1
  192. package/lib/pages/list/list.component.d.ts +0 -54
  193. package/lib/pages/list/list.component.d.ts.map +0 -1
  194. package/lib/pages/list/standard/standard.component.d.ts +0 -14
  195. package/lib/pages/list/standard/standard.component.d.ts.map +0 -1
  196. package/lib/pipes/form-options/form-options.pipe.d.ts +0 -15
  197. package/lib/pipes/form-options/form-options.pipe.d.ts.map +0 -1
  198. package/lib/pipes/index.d.ts +0 -3
  199. package/lib/pipes/index.d.ts.map +0 -1
  200. package/lib/pipes/pipes.module.d.ts +0 -8
  201. package/lib/pipes/pipes.module.d.ts.map +0 -1
  202. package/lib/providers/model-possibilities/model-possibilities.provider.d.ts +0 -18
  203. package/lib/providers/model-possibilities/model-possibilities.provider.d.ts.map +0 -1
  204. package/lib/services/crud/crud.service.d.ts +0 -38
  205. package/lib/services/crud/crud.service.d.ts.map +0 -1
  206. package/lib/services/list-group/list-group.service.d.ts +0 -15
  207. package/lib/services/list-group/list-group.service.d.ts.map +0 -1
  208. package/lib/services/page/page.service.d.ts +0 -12
  209. package/lib/services/page/page.service.d.ts.map +0 -1
  210. package/lib/services/search/search.service.d.ts +0 -16
  211. package/lib/services/search/search.service.d.ts.map +0 -1
  212. package/lib/services/socket/socket.service.d.ts +0 -10
  213. package/lib/services/socket/socket.service.d.ts.map +0 -1
  214. package/smartsoft001-crud-shell-angular.d.ts.map +0 -1
@@ -0,0 +1,157 @@
1
+ import {
2
+ Component,
3
+ ElementRef,
4
+ inject,
5
+ input,
6
+ InputSignal,
7
+ OnInit,
8
+ Signal,
9
+ WritableSignal,
10
+ } from '@angular/core';
11
+ import { TranslatePipe } from '@ngx-translate/core';
12
+
13
+ import { MenuService, StyleService } from '@smartsoft001/angular';
14
+ import { IEntity } from '@smartsoft001/domain-core';
15
+ import {
16
+ FieldType,
17
+ getModelFieldsWithOptions,
18
+ getModelOptions,
19
+ IFieldListMetadata,
20
+ IModelFilter,
21
+ } from '@smartsoft001/models';
22
+
23
+ import { CrudFacade } from '../../+state/crud.facade';
24
+ import { CrudConfig } from '../../crud.config';
25
+ import { ICrudFilter } from '../../models';
26
+ import { FilterComponent } from '../filter';
27
+
28
+ /**
29
+ * This component is only to use in crud module
30
+ * @requires CrudModule
31
+ * @example
32
+ *
33
+ * html: <smart-crud-filters></smart-crud-filters>
34
+ *
35
+ * use on the model:
36
+ * @Model({
37
+ titleKey: 'body',
38
+ filters: [
39
+ {
40
+ label: 'testNegation',
41
+ key: 'body',
42
+ type: '!=',
43
+ },
44
+ {
45
+ label: 'fromDate',
46
+ key: 'createDate',
47
+ type: '<=',
48
+ fieldType: FieldType.dateWithEdit
49
+ },
50
+ {
51
+ label: 'select',
52
+ key: 'type',
53
+ type: '=',
54
+ fieldType: FieldType.radio,
55
+ possibilities$: of([
56
+ {
57
+ id: 1, text: 'Test 1'
58
+ },
59
+ {
60
+ id: 2, text: 'Test 2'
61
+ }
62
+ ])
63
+ }
64
+ ]
65
+ })
66
+ *
67
+ * use on the field (list.filter property):
68
+ * @Field({
69
+ create: modifyMetdata,
70
+ update: {
71
+ ...modifyMetdata,
72
+ multi: true
73
+ },
74
+ type: FieldType.longText,
75
+ details: true,
76
+ list: {
77
+ order: 2,
78
+ filter: true
79
+ }
80
+ })
81
+ body: string;
82
+ */
83
+ @Component({
84
+ selector: 'smart-crud-filters',
85
+ template: `
86
+ <!--<ion-header [hidden]="hideMenu()">-->
87
+ <!-- <ion-toolbar>-->
88
+ <!-- <ion-buttons slot="end">-->
89
+ <!-- <ion-button (click)="onClose()">-->
90
+ <!-- <ion-icon slot="icon-only" name="close"> </ion-icon>-->
91
+ <!-- </ion-button>-->
92
+ <!-- </ion-buttons>-->
93
+ <!-- <ion-title>{{ 'filters' | translate }}</ion-title>-->
94
+ <!-- </ion-toolbar>-->
95
+ <!--</ion-header>-->
96
+ <!--<ion-content style="height: 100vh">-->
97
+ <!-- <ion-list>-->
98
+ @for (item of list(); track item) {
99
+ <smart-crud-filter [item]="item" [filter]="filter()"></smart-crud-filter>
100
+ }
101
+ <!-- </ion-list>-->
102
+ <div class="h-20">&nbsp;</div>
103
+ <!--</ion-content>-->
104
+ `,
105
+ imports: [FilterComponent, TranslatePipe],
106
+ styleUrls: ['./filters.component.scss'],
107
+ })
108
+ export class FiltersComponent<T extends IEntity<string>> implements OnInit {
109
+ private menuService = inject(MenuService);
110
+ private config = inject(CrudConfig<T>);
111
+ private facade = inject(CrudFacade<T>);
112
+ private styleService = inject(StyleService);
113
+ private elementRef = inject(ElementRef);
114
+
115
+ list: WritableSignal<Array<IModelFilter>>;
116
+
117
+ filter: Signal<ICrudFilter | undefined>;
118
+
119
+ /**
120
+ * Hide menu used only from MenuService
121
+ */
122
+ readonly hideMenu: InputSignal<boolean> = input<boolean>(false);
123
+
124
+ async onClose(): Promise<void> {
125
+ await this.menuService.closeEnd();
126
+ }
127
+
128
+ ngOnInit(): void {
129
+ this.styleService.init(this.elementRef);
130
+
131
+ const modelFilters = getModelOptions(this.config.type).filters;
132
+
133
+ this.list.set([
134
+ ...(modelFilters
135
+ ? modelFilters.map((item) => {
136
+ if (!item.label) {
137
+ item.label = 'MODEL.' + item.key;
138
+ }
139
+ return item;
140
+ })
141
+ : []),
142
+ ...getModelFieldsWithOptions(new this.config.type())
143
+ .filter((item) => (item.options?.list as IFieldListMetadata)?.filter)
144
+ .map((item) => ({
145
+ key: item.key,
146
+ type:
147
+ item.options.type === FieldType.text ||
148
+ item.options.type === FieldType.longText
149
+ ? ('~=' as const)
150
+ : ('=' as const),
151
+ label: 'MODEL.' + item.key,
152
+ fieldType: item.options.type,
153
+ })),
154
+ ]);
155
+ this.filter = this.facade.filter;
156
+ }
157
+ }
@@ -0,0 +1,69 @@
1
+ import {
2
+ Component,
3
+ computed,
4
+ ElementRef,
5
+ inject,
6
+ OnInit,
7
+ Signal,
8
+ } from '@angular/core';
9
+ import { TranslatePipe } from '@ngx-translate/core';
10
+
11
+ import { StyleService } from '@smartsoft001/angular';
12
+
13
+ import { CrudFacade } from '../../+state/crud.facade';
14
+ import { ICrudFilterQueryItem } from '../../models';
15
+
16
+ @Component({
17
+ selector: 'smart-crud-filters-config',
18
+ template: `
19
+ @let query = this.query();
20
+ @if (query && query?.length) {
21
+ <!-- <ion-toolbar>-->
22
+ @for (item of query; track item) {
23
+ <!-- <ion-chip (click)="onRemoveQuery(item)" color="medium" outline="true">-->
24
+ <!-- <ion-icon name="filter-circle-outline" color="primary"></ion-icon>-->
25
+ <!-- <ion-label>-->
26
+ {{ 'MODEL.' + item.key | translate }} {{ item.type }}
27
+ {{ item.value | translate }}
28
+ <!-- </ion-label>-->
29
+ <!-- <ion-icon name="close" color="danger"></ion-icon>-->
30
+ <!-- </ion-chip>-->
31
+ }
32
+ <!-- </ion-toolbar>-->
33
+ }
34
+ `,
35
+ imports: [TranslatePipe],
36
+ styles: [
37
+ `
38
+ :host {
39
+ ion-label {
40
+ font-size: var(--small-font-size);
41
+ }
42
+ }
43
+ `,
44
+ ],
45
+ })
46
+ export class FiltersConfigComponent implements OnInit {
47
+ private readonly facade = inject(CrudFacade<any>);
48
+ private styleService = inject(StyleService);
49
+ private elementRef = inject(ElementRef);
50
+
51
+ query: Signal<ICrudFilterQueryItem[]>;
52
+
53
+ onRemoveQuery(item: ICrudFilterQueryItem): void {
54
+ const index = this.facade.filter().query.indexOf(item);
55
+ if (index > -1) {
56
+ this.facade.filter().query.splice(index, 1);
57
+ }
58
+ this.facade.read(this.facade.filter());
59
+ }
60
+
61
+ ngOnInit(): void {
62
+ this.styleService.init(this.elementRef);
63
+
64
+ this.query = computed(() => {
65
+ const filter = this.facade.filter();
66
+ return filter?.query?.filter((i) => !i.hidden);
67
+ });
68
+ }
69
+ }
@@ -0,0 +1,93 @@
1
+ import { NgClass } from '@angular/common';
2
+ import {
3
+ Component,
4
+ ElementRef,
5
+ inject,
6
+ input,
7
+ InputSignal,
8
+ OnDestroy,
9
+ OnInit,
10
+ } from '@angular/core';
11
+ import { TranslatePipe } from '@ngx-translate/core';
12
+
13
+ import {
14
+ AccordionBodyComponent,
15
+ AccordionComponent,
16
+ AccordionHeaderComponent,
17
+ BaseComponent,
18
+ IListOptions,
19
+ ListComponent,
20
+ StyleService,
21
+ } from '@smartsoft001/angular';
22
+ import { IEntity } from '@smartsoft001/domain-core';
23
+
24
+ import { ICrudListGroup } from '../../models';
25
+ import { CrudListGroupService } from '../../services/list-group/list-group.service';
26
+
27
+ @Component({
28
+ selector: 'smart-crud-group',
29
+ template: `
30
+ @for (item of groups(); track item.key) {
31
+ <smart-accordion [show]="item.show" (showChange)="change($event, item)">
32
+ <smart-accordion-header [ngClass]="{ 'font-bold': item.show }"
33
+ >{{ item.text | translate }}
34
+ </smart-accordion-header>
35
+ <smart-accordion-body>
36
+ @if (item.show && !item.children && listOptions) {
37
+ <smart-list [options]="listOptions()"></smart-list>
38
+ }
39
+ @if (item.children) {
40
+ <div style="margin-left: 50px">
41
+ <smart-crud-group
42
+ [groups]="item.children"
43
+ [listOptions]="listOptions()"
44
+ ></smart-crud-group>
45
+ </div>
46
+ }
47
+ </smart-accordion-body>
48
+ </smart-accordion>
49
+ }
50
+ <br /><br /><br />
51
+ `,
52
+ imports: [
53
+ AccordionComponent,
54
+ AccordionHeaderComponent,
55
+ AccordionBodyComponent,
56
+ ListComponent,
57
+ NgClass,
58
+ TranslatePipe,
59
+ ],
60
+ })
61
+ export class GroupComponent<T extends IEntity<string>>
62
+ extends BaseComponent
63
+ implements OnInit, OnDestroy
64
+ {
65
+ private styleService = inject(StyleService);
66
+ private elementRef = inject(ElementRef);
67
+ private groupService = inject(CrudListGroupService<T>);
68
+
69
+ readonly groups: InputSignal<Array<ICrudListGroup>> =
70
+ input<Array<ICrudListGroup>>();
71
+ readonly listOptions: InputSignal<IListOptions<T>> = input<IListOptions<T>>();
72
+
73
+ change(val: boolean, item: ICrudListGroup, force = false): void {
74
+ this.groups()
75
+ .filter((i) => i.value !== item.value || i.key !== item.key)
76
+ .forEach((i) => {
77
+ i.show = false;
78
+ });
79
+
80
+ this.groupService.change(val, item, force);
81
+
82
+ item.show = val;
83
+ }
84
+
85
+ ngOnInit(): void {
86
+ this.styleService.init(this.elementRef);
87
+ }
88
+
89
+ ngOnDestroy(): void {
90
+ this.groupService.destroy(this.groups());
91
+ super.ngOnDestroy();
92
+ }
93
+ }
@@ -0,0 +1,7 @@
1
+ export * from './export/export.component';
2
+ export * from './filter';
3
+ export * from './filters/filters.component';
4
+ export * from './filters-config/filters-config.component';
5
+ export * from './multiselect/multiselect.component';
6
+ export * from './group/group.component';
7
+ export * from './components.module';
@@ -0,0 +1,41 @@
1
+ @let list = this.list();
2
+ @if (list) {
3
+ <!-- <ion-header>-->
4
+ <!-- <ion-toolbar>-->
5
+ <!-- <ion-buttons slot="end">-->
6
+ <!-- <ion-button (click)="onClose()">-->
7
+ <!-- <ion-icon slot="icon-only" name="close"> </ion-icon>-->
8
+ <!-- </ion-button>-->
9
+ <!-- </ion-buttons>-->
10
+ <!--<ion-title>-->{{ 'selected' | translate }}: {{ list?.length
11
+ }}<!--</ion-title>-->
12
+ <!-- </ion-toolbar>-->
13
+ <!-- </ion-header>-->
14
+
15
+ @if (config?.list?.components?.multi) {
16
+ <div>
17
+ <ng-template
18
+ [ngComponentOutlet]="config?.list?.components?.multi"
19
+ [ndcDynamicInputs]="{ items: list }"
20
+ ></ng-template>
21
+ </div>
22
+ }
23
+
24
+ @if (showForm && item) {
25
+ <div>
26
+ <smart-form
27
+ [options]="item | smartFormOptions: 'multiUpdate' : config.type"
28
+ (valuePartialChange)="onPartialChange($event, list)"
29
+ (validChange)="onValidChange($event)"
30
+ ></smart-form>
31
+
32
+ <smart-button
33
+ style="float: right"
34
+ [disabled]="lock || !valid"
35
+ [options]="buttonOptions"
36
+ >
37
+ {{ 'change' | translate }}
38
+ </smart-button>
39
+ </div>
40
+ }
41
+ }
@@ -0,0 +1,125 @@
1
+ //:host {
2
+ // ion-toolbar {
3
+ // --background: linear-gradient(
4
+ // 33deg,
5
+ // var(--ion-color-light),
6
+ // var(--ion-color-light-shade)
7
+ // );
8
+ // --color: var(--ion-color-dark);
9
+ // // @media (max-width: var(--smart-tablet-breakpoint)) {
10
+ // @media only screen and (max-width: 992px) {
11
+ // --background: linear-gradient(
12
+ // 33deg,
13
+ // var(--ion-color-primary),
14
+ // var(--ion-color-tertiary)
15
+ // );
16
+ // --color: var(--ion-color-light);
17
+ // }
18
+ // // @media (max-width: var(--smart-phone-breakpoint)) {
19
+ // @media only screen and (max-width: 420px) {
20
+ // --background: linear-gradient(
21
+ // 33deg,
22
+ // var(--ion-color-primary),
23
+ // var(--ion-color-tertiary)
24
+ // );
25
+ // --color: var(--ion-color-light);
26
+ // }
27
+ // &.ios {
28
+ // height: 4.6rem;
29
+ // --background: linear-gradient(
30
+ // 33deg,
31
+ // var(--ion-color-light),
32
+ // var(--ion-color-light-shade)
33
+ // );
34
+ // --color: var(--ion-color-dark);
35
+ // // @media (max-width: var(--smart-tablet-breakpoint)) {
36
+ // @media only screen and (max-width: 992px) {
37
+ // --background: linear-gradient(
38
+ // 33deg,
39
+ // var(--ion-color-primary),
40
+ // var(--ion-color-tertiary)
41
+ // );
42
+ // --color: var(--ion-color-light);
43
+ // ion-title {
44
+ // text-align: left;
45
+ // padding-left: 5.2rem;
46
+ // }
47
+ // ion-icon {
48
+ // color: var(--ion-color-light);
49
+ // }
50
+ // }
51
+ // // @media (max-width: var(--smart-phone-breakpoint)) {
52
+ // @media only screen and (max-width: 420px) {
53
+ // --background: linear-gradient(
54
+ // 33deg,
55
+ // var(--ion-color-primary),
56
+ // var(--ion-color-tertiary)
57
+ // );
58
+ // --color: var(--ion-color-light);
59
+ // ion-title {
60
+ // text-align: left;
61
+ // padding-left: 5.2rem;
62
+ // }
63
+ // ion-icon {
64
+ // color: var(--ion-color-light);
65
+ // }
66
+ // }
67
+ // .modal-wrapper & {
68
+ // --background: linear-gradient(
69
+ // 33deg,
70
+ // var(--ion-color-light),
71
+ // var(--ion-color-light-shade)
72
+ // );
73
+ // --color: var(--ion-color-dark);
74
+ // // @media (max-width: var(--smart-tablet-breakpoint)) {
75
+ // @media only screen and (max-width: 992px) {
76
+ // --background: linear-gradient(
77
+ // 33deg,
78
+ // var(--ion-color-light),
79
+ // var(--ion-color-light-shade)
80
+ // );
81
+ // color: var(--ion-color-dark);
82
+ // ion-title {
83
+ // text-align: left;
84
+ // padding-left: 1.2rem;
85
+ // }
86
+ // ion-icon {
87
+ // color: var(--ion-color-dark);
88
+ // }
89
+ // ion-buttons {
90
+ // margin: 0;
91
+ // }
92
+ // }
93
+ // // @media (max-width: var(--smart-phone-breakpoint)) {
94
+ // @media only screen and (max-width: 420px) {
95
+ // --background: linear-gradient(
96
+ // 33deg,
97
+ // var(--ion-color-light),
98
+ // var(--ion-color-light-shade)
99
+ // );
100
+ // color: var(--ion-color-dark);
101
+ // ion-title {
102
+ // text-align: left;
103
+ // padding-left: 1.2rem;
104
+ // }
105
+ // ion-icon {
106
+ // color: var(--ion-color-dark);
107
+ // }
108
+ // ion-buttons {
109
+ // margin: 0;
110
+ // }
111
+ // }
112
+ // }
113
+ // }
114
+ // ion-menu-button {
115
+ // color: var(--ion-color-light);
116
+ // }
117
+ // ion-buttons {
118
+ // //height: var(--smart-button-height);
119
+ // &.ios {
120
+ // height: var(--smart-button-height);
121
+ // margin: 0;
122
+ // }
123
+ // }
124
+ // }
125
+ //}
@@ -0,0 +1,104 @@
1
+ import { NgComponentOutlet } from '@angular/common';
2
+ import { Component, computed, inject, Signal } from '@angular/core';
3
+ import { TranslatePipe } from '@ngx-translate/core';
4
+ import * as _ from 'lodash';
5
+ import { DynamicIoDirective } from 'ng-dynamic-component';
6
+
7
+ import {
8
+ ButtonComponent,
9
+ FormComponent,
10
+ IButtonOptions,
11
+ MenuService,
12
+ } from '@smartsoft001/angular';
13
+ import { IEntity } from '@smartsoft001/domain-core';
14
+ import {
15
+ getModelFieldsWithOptions,
16
+ IFieldEditMetadata,
17
+ } from '@smartsoft001/models';
18
+
19
+ import { CrudFacade } from '../../+state/crud.facade';
20
+ import { CrudFullConfig } from '../../crud.config';
21
+ import { FormOptionsPipe } from '../../pipes';
22
+
23
+ @Component({
24
+ selector: 'smart-crud-multiselect',
25
+ templateUrl: './multiselect.component.html',
26
+ imports: [
27
+ TranslatePipe,
28
+ NgComponentOutlet,
29
+ DynamicIoDirective,
30
+ FormOptionsPipe,
31
+ FormComponent,
32
+ ButtonComponent,
33
+ ],
34
+ styleUrls: ['./multiselect.component.scss'],
35
+ })
36
+ export class MultiselectComponent<T extends IEntity<string>> {
37
+ private facade = inject(CrudFacade<T>);
38
+ public config = inject(CrudFullConfig<T>);
39
+ private menuService = inject(MenuService);
40
+
41
+ private _list: Array<T>;
42
+ private _changes: Partial<T>;
43
+
44
+ item: T;
45
+ valid: boolean;
46
+ buttonOptions: IButtonOptions = {
47
+ click: async () => {
48
+ const result = this._list.map((item) => {
49
+ return {
50
+ ...this._changes,
51
+ id: item.id,
52
+ };
53
+ });
54
+
55
+ this.facade.updatePartialMany(result);
56
+ await this.menuService.closeEnd();
57
+ },
58
+ confirm: true,
59
+ };
60
+ lock: boolean;
61
+ showForm = false;
62
+
63
+ list: Signal<T[]>;
64
+
65
+ constructor() {
66
+ this.list = computed(() => {
67
+ const list = this.facade.multiSelected();
68
+ this.lock = true;
69
+ const model = new this.config.type();
70
+
71
+ const fieldsWithOptions = getModelFieldsWithOptions(model).filter(
72
+ (f) => (f.options.update as IFieldEditMetadata)?.multi,
73
+ );
74
+
75
+ this.showForm = !!fieldsWithOptions.length;
76
+
77
+ fieldsWithOptions.forEach(({ key }) => {
78
+ const uniques = _.uniq(list.map((i) => i[key]));
79
+
80
+ if (uniques.length === 1) {
81
+ model[key] = uniques[0];
82
+ }
83
+ });
84
+
85
+ this.item = model;
86
+
87
+ return list;
88
+ });
89
+ }
90
+
91
+ async onClose(): Promise<void> {
92
+ await this.menuService.closeEnd();
93
+ }
94
+
95
+ onPartialChange(changes: Partial<T>, list: Array<T>) {
96
+ this.lock = false;
97
+ this._list = list;
98
+ this._changes = changes;
99
+ }
100
+
101
+ onValidChange(valid: boolean) {
102
+ this.valid = valid;
103
+ }
104
+ }
@@ -0,0 +1,51 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { NgModule } from '@angular/core';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { RouterModule } from '@angular/router';
5
+
6
+ import { SharedModule } from '@smartsoft001/angular';
7
+ import { IEntity } from '@smartsoft001/domain-core';
8
+
9
+ import { CrudFacade } from './+state/crud.facade';
10
+ import { CrudComponentsModule } from './components';
11
+ import { CrudListPaginationFactory } from './factories/list-pagination/list-pagination.factory';
12
+ import { ListComponent } from './pages';
13
+ import { ItemComponent } from './pages';
14
+ import { ListStandardComponent } from './pages';
15
+ import { ItemStandardComponent } from './pages';
16
+ import { CrudPipesModule } from './pipes';
17
+ import { CrudService } from './services/crud/crud.service';
18
+ import { CrudListGroupService } from './services/list-group/list-group.service';
19
+ import { PageService } from './services/page/page.service';
20
+
21
+ export const PAGES = [
22
+ ItemComponent,
23
+ ListComponent,
24
+ ListStandardComponent,
25
+ ItemStandardComponent,
26
+ ];
27
+
28
+ @NgModule({
29
+ imports: [
30
+ ...PAGES,
31
+ SharedModule,
32
+ CrudPipesModule,
33
+ RouterModule.forChild([
34
+ { path: '', component: ListComponent },
35
+ { path: 'add', component: ItemComponent },
36
+ { path: ':id', component: ItemComponent },
37
+ ]),
38
+ FormsModule,
39
+ CommonModule,
40
+ CrudComponentsModule,
41
+ ],
42
+ exports: [...PAGES, CrudComponentsModule],
43
+ providers: [
44
+ CrudService,
45
+ CrudListGroupService,
46
+ PageService,
47
+ CrudFacade,
48
+ CrudListPaginationFactory,
49
+ ],
50
+ })
51
+ export class CrudFullModule<T extends IEntity<string>> {}