@smartsoft001/crud-shell-angular 2.76.0 → 2.80.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 (75) hide show
  1. package/fesm2022/smartsoft001-crud-shell-angular.mjs +2840 -0
  2. package/fesm2022/smartsoft001-crud-shell-angular.mjs.map +1 -0
  3. package/index.d.ts +632 -0
  4. package/package.json +18 -3
  5. package/.storybook/addons.js +0 -1
  6. package/.storybook/config.js +0 -5
  7. package/.storybook/tsconfig.json +0 -8
  8. package/.storybook/webpack.config.js +0 -7
  9. package/jest.config.ts +0 -38
  10. package/ng-package.json +0 -7
  11. package/project.json +0 -49
  12. package/src/index.ts +0 -13
  13. package/src/lib/+state/crud.facade.ts +0 -82
  14. package/src/lib/+state/crud.methods.ts +0 -258
  15. package/src/lib/+state/crud.store.ts +0 -77
  16. package/src/lib/components/components.module.ts +0 -58
  17. package/src/lib/components/export/export.component.ts +0 -69
  18. package/src/lib/components/filter/base/base.component.ts +0 -175
  19. package/src/lib/components/filter/check/check.component.scss +0 -25
  20. package/src/lib/components/filter/check/check.component.ts +0 -72
  21. package/src/lib/components/filter/date/date.component.html +0 -30
  22. package/src/lib/components/filter/date/date.component.ts +0 -70
  23. package/src/lib/components/filter/date-time/date-time.component.html +0 -62
  24. package/src/lib/components/filter/date-time/date-time.component.ts +0 -56
  25. package/src/lib/components/filter/date-with-edit/date-with-edit.component.html +0 -109
  26. package/src/lib/components/filter/date-with-edit/date-with-edit.component.ts +0 -70
  27. package/src/lib/components/filter/filter.component.html +0 -52
  28. package/src/lib/components/filter/filter.component.ts +0 -34
  29. package/src/lib/components/filter/flag/flag.component.ts +0 -55
  30. package/src/lib/components/filter/index.ts +0 -9
  31. package/src/lib/components/filter/int/int.component.html +0 -74
  32. package/src/lib/components/filter/int/int.component.ts +0 -57
  33. package/src/lib/components/filter/radio/radio.component.ts +0 -74
  34. package/src/lib/components/filter/text/text.component.ts +0 -46
  35. package/src/lib/components/filters/filters.component.scss +0 -150
  36. package/src/lib/components/filters/filters.component.ts +0 -157
  37. package/src/lib/components/filters-config/filters-config.component.ts +0 -69
  38. package/src/lib/components/group/group.component.ts +0 -93
  39. package/src/lib/components/index.ts +0 -7
  40. package/src/lib/components/multiselect/multiselect.component.html +0 -41
  41. package/src/lib/components/multiselect/multiselect.component.scss +0 -125
  42. package/src/lib/components/multiselect/multiselect.component.ts +0 -104
  43. package/src/lib/crud-full.module.ts +0 -51
  44. package/src/lib/crud.config.ts +0 -79
  45. package/src/lib/crud.module.ts +0 -72
  46. package/src/lib/factories/list-pagination/list-pagination.factory.ts +0 -77
  47. package/src/lib/models/index.ts +0 -1
  48. package/src/lib/models/interfaces.ts +0 -34
  49. package/src/lib/pages/index.ts +0 -6
  50. package/src/lib/pages/item/base/base.component.ts +0 -54
  51. package/src/lib/pages/item/item.component.ts +0 -513
  52. package/src/lib/pages/item/standard/standard.component.scss +0 -0
  53. package/src/lib/pages/item/standard/standard.component.ts +0 -50
  54. package/src/lib/pages/list/base/base.component.ts +0 -29
  55. package/src/lib/pages/list/list.component.stories.ts +0 -77
  56. package/src/lib/pages/list/list.component.ts +0 -438
  57. package/src/lib/pages/list/standard/standard.component.ts +0 -42
  58. package/src/lib/pipes/form-options/form-options.pipe.ts +0 -61
  59. package/src/lib/pipes/index.ts +0 -2
  60. package/src/lib/pipes/pipes.module.ts +0 -9
  61. package/src/lib/providers/model-possibilities/model-possibilities.provider.ts +0 -19
  62. package/src/lib/services/crud/crud.service.spec.ts +0 -303
  63. package/src/lib/services/crud/crud.service.ts +0 -178
  64. package/src/lib/services/list-group/list-group.service.spec.ts +0 -87
  65. package/src/lib/services/list-group/list-group.service.ts +0 -65
  66. package/src/lib/services/page/page.service.spec.ts +0 -143
  67. package/src/lib/services/page/page.service.ts +0 -44
  68. package/src/lib/services/search/search.service.spec.ts +0 -134
  69. package/src/lib/services/search/search.service.ts +0 -42
  70. package/test-setup.ts +0 -0
  71. package/tsconfig.json +0 -13
  72. package/tsconfig.lib.json +0 -31
  73. package/tsconfig.lib.prod.json +0 -11
  74. package/tsconfig.spec.json +0 -10
  75. package/tslint.json +0 -10
@@ -0,0 +1,2840 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, inject, computed, ElementRef, Component, input, Directive, signal, InjectionToken, Pipe, NgModule, viewChild, viewChildren, output, ChangeDetectorRef, effect, Injector } from '@angular/core';
3
+ import { PaginationMode, BaseComponent as BaseComponent$1, PopoverService, StyleService, ButtonComponent, MenuService, FormComponent, AccordionComponent, AccordionHeaderComponent, AccordionBodyComponent, ListComponent as ListComponent$1, SharedModule, DetailsComponent, AuthService, CreateDynamicComponent, DynamicComponentLoader, ToastService, DetailsService, DynamicContentDirective, PageComponent, HardwareService, ListMode, FILE_SERVICE_CONFIG } from '@smartsoft001/angular';
4
+ import { patchState, signalStore, withState, withComputed, withMethods } from '@ngrx/signals';
5
+ import { HttpClient } from '@angular/common/http';
6
+ import { firstValueFrom, Subscription, BehaviorSubject, combineLatest, Subject } from 'rxjs';
7
+ import { map } from 'rxjs/operators';
8
+ import { FieldType, getModelOptions, getModelFieldsWithOptions } from '@smartsoft001/models';
9
+ import { TranslateService, TranslatePipe } from '@ngx-translate/core';
10
+ import { __decorate, __metadata } from 'tslib';
11
+ import { Debounce, debounce } from 'lodash-decorators';
12
+ import { FormsModule, UntypedFormControl, UntypedFormGroup, UntypedFormArray } from '@angular/forms';
13
+ import * as moment from 'moment';
14
+ import { GuidService, SpecificationService } from '@smartsoft001/utils';
15
+ import { NgComponentOutlet, NgClass, CommonModule, NgTemplateOutlet, Location } from '@angular/common';
16
+ import * as _ from 'lodash';
17
+ import { DynamicIoDirective, DynamicIoModule } from 'ng-dynamic-component';
18
+ import * as i1 from '@angular/router';
19
+ import { Router, ActivatedRoute, RouterModule } from '@angular/router';
20
+
21
+ class CrudConfig {
22
+ apiUrl;
23
+ entity;
24
+ type;
25
+ reducerFactory;
26
+ baseQuery;
27
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
28
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudConfig });
29
+ }
30
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudConfig, decorators: [{
31
+ type: Injectable
32
+ }] });
33
+ class CrudFullConfig extends CrudConfig {
34
+ title;
35
+ details;
36
+ edit;
37
+ add;
38
+ remove;
39
+ search;
40
+ export;
41
+ pagination;
42
+ sort;
43
+ list;
44
+ buttons;
45
+ inputComponents;
46
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFullConfig, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
47
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFullConfig });
48
+ }
49
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFullConfig, decorators: [{
50
+ type: Injectable
51
+ }] });
52
+
53
+ class CrudService {
54
+ config = inject((CrudConfig));
55
+ http = inject(HttpClient);
56
+ _formatMap = {
57
+ csv: 'text/csv',
58
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
59
+ };
60
+ create(item) {
61
+ return firstValueFrom(this.http
62
+ .post(this.config.apiUrl, item, { observe: 'response' })
63
+ .pipe(map((response) => {
64
+ const location = response.headers['Location'];
65
+ if (!location)
66
+ return null;
67
+ const array = location.split('/');
68
+ return array[array.length - 1];
69
+ })));
70
+ }
71
+ createMany(items, options) {
72
+ return firstValueFrom(this.http.post(this.config.apiUrl + '/bulk?mode=' + options.mode, items));
73
+ }
74
+ getById(id) {
75
+ return firstValueFrom(this.http.get(this.config.apiUrl + '/' + id));
76
+ }
77
+ getList(filter = null) {
78
+ return firstValueFrom(this.http.get(this.config.apiUrl + this.getQuery(filter)));
79
+ }
80
+ exportList(filter = null, format) {
81
+ if (!format) {
82
+ format = 'csv';
83
+ }
84
+ if (format === 'xlsx') {
85
+ return firstValueFrom(this.http
86
+ .get(this.config.apiUrl + this.getQuery(filter), {
87
+ headers: {
88
+ 'Content-Type': this._formatMap[format],
89
+ },
90
+ observe: 'response',
91
+ reportProgress: false,
92
+ responseType: 'blob',
93
+ })
94
+ .pipe(map((res) => {
95
+ const downloadLink = document.createElement('a');
96
+ const blob = res.body;
97
+ downloadLink.href = URL.createObjectURL(blob);
98
+ downloadLink.download = 'data.' + format;
99
+ document.body.appendChild(downloadLink);
100
+ downloadLink.click();
101
+ document.body.removeChild(downloadLink);
102
+ })));
103
+ }
104
+ return firstValueFrom(this.http
105
+ .get(this.config.apiUrl + this.getQuery(filter), {
106
+ headers: {
107
+ 'Content-Type': this._formatMap[format],
108
+ },
109
+ responseType: 'text',
110
+ })
111
+ .pipe(map((res) => {
112
+ const downloadLink = document.createElement('a');
113
+ const blob = new Blob(['\ufeff', res]);
114
+ downloadLink.href = URL.createObjectURL(blob);
115
+ downloadLink.download = 'data.' + format;
116
+ document.body.appendChild(downloadLink);
117
+ downloadLink.click();
118
+ document.body.removeChild(downloadLink);
119
+ })));
120
+ }
121
+ update(item) {
122
+ return firstValueFrom(this.http.put(this.config.apiUrl + '/' + item.id, item));
123
+ }
124
+ updatePartial(item) {
125
+ return firstValueFrom(this.http.patch(this.config.apiUrl + '/' + item.id, item));
126
+ }
127
+ updatePartialMany(items) {
128
+ const updatePromises = items.map((item) => {
129
+ return this.updatePartial(item);
130
+ });
131
+ return Promise.all(updatePromises);
132
+ }
133
+ delete(id) {
134
+ return firstValueFrom(this.http.delete(this.config.apiUrl + '/' + id));
135
+ }
136
+ getQuery(filter) {
137
+ let query = '';
138
+ if (filter && filter.searchText) {
139
+ query += '&$search=' + filter.searchText;
140
+ }
141
+ if (filter && filter.limit) {
142
+ query += `&limit=${filter.limit}&offset=${filter.offset ? filter.offset : 0}`;
143
+ }
144
+ if (filter && filter.sortBy) {
145
+ query += `&sort=${(filter.sortDesc ? '-' : '') + filter.sortBy}`;
146
+ }
147
+ if (filter && filter.query) {
148
+ filter.query.forEach((q) => {
149
+ if (q.value &&
150
+ typeof q.value === 'string' &&
151
+ q.value.match(/^-?\d+$/) &&
152
+ q.value[0] !== "'" &&
153
+ q.value[0] !== '"') {
154
+ query += '&' + q.key + q.type + `'${q.value}'`;
155
+ }
156
+ else {
157
+ query += '&' + q.key + q.type + q.value;
158
+ }
159
+ });
160
+ }
161
+ return query ? '?' + query.replace('&', '') : '';
162
+ }
163
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
164
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudService });
165
+ }
166
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudService, decorators: [{
167
+ type: Injectable
168
+ }] });
169
+
170
+ // "Actions, Reducers, Effects" in a normal store
171
+ function CrudMethodsFactory() {
172
+ return (store, crudService = inject((CrudService))) => {
173
+ const methods = {
174
+ async create(item) {
175
+ patchState(store, {
176
+ loaded: false,
177
+ error: null,
178
+ });
179
+ try {
180
+ await crudService.create(item);
181
+ await this.createSuccess();
182
+ }
183
+ catch (error) {
184
+ methods.defaultFailure(error);
185
+ }
186
+ },
187
+ async createSuccess() {
188
+ patchState(store, {
189
+ loaded: true,
190
+ error: null,
191
+ });
192
+ await methods.read(store.filter ? { ...store.filter, offset: 0 } : null);
193
+ },
194
+ async createMany(data) {
195
+ patchState(store, {
196
+ loaded: false,
197
+ error: null,
198
+ });
199
+ try {
200
+ await crudService.createMany(data.items, data.options);
201
+ await methods.createManySuccess();
202
+ }
203
+ catch (e) {
204
+ methods.defaultFailure(e);
205
+ }
206
+ },
207
+ async createManySuccess() {
208
+ patchState(store, {
209
+ loaded: true,
210
+ error: null,
211
+ });
212
+ await methods.read(store.filter ? { ...store.filter, offset: 0 } : null);
213
+ },
214
+ async export(filter, format) {
215
+ patchState(store, {
216
+ loaded: false,
217
+ });
218
+ try {
219
+ await crudService.exportList(filter, format);
220
+ methods.exportSuccess();
221
+ }
222
+ catch (e) {
223
+ methods.defaultFailure(e);
224
+ }
225
+ },
226
+ exportSuccess() {
227
+ patchState(store, {
228
+ loaded: true,
229
+ });
230
+ },
231
+ async read(filter) {
232
+ patchState(store, {
233
+ loaded: false,
234
+ filter,
235
+ error: null,
236
+ totalCount: null,
237
+ links: null,
238
+ });
239
+ try {
240
+ const result = await crudService.getList(filter);
241
+ methods.readSuccess({
242
+ list: result.data,
243
+ filter,
244
+ totalCount: result.totalCount,
245
+ links: result.links,
246
+ });
247
+ }
248
+ catch (error) {
249
+ methods.defaultFailure(error);
250
+ }
251
+ },
252
+ readSuccess(data) {
253
+ let list = [];
254
+ if (data.filter?.offset &&
255
+ store.list() &&
256
+ data.filter.paginationMode !== PaginationMode.singlePage) {
257
+ list = [...store.list(), ...data.list];
258
+ }
259
+ else {
260
+ list = data.list;
261
+ }
262
+ patchState(store, {
263
+ loaded: true,
264
+ list,
265
+ totalCount: data.totalCount,
266
+ links: data.links,
267
+ error: null,
268
+ });
269
+ },
270
+ clear() {
271
+ store.set(() => ({ ...initialState }));
272
+ },
273
+ async select(id) {
274
+ patchState(store, {
275
+ loaded: false,
276
+ selected: null,
277
+ error: null,
278
+ });
279
+ try {
280
+ const result = await crudService.getById(id);
281
+ methods.selectSuccess(result);
282
+ }
283
+ catch (e) {
284
+ methods.defaultFailure(e);
285
+ }
286
+ },
287
+ selectSuccess(selected) {
288
+ patchState(store, {
289
+ loaded: true,
290
+ selected,
291
+ error: null,
292
+ });
293
+ },
294
+ unselect() {
295
+ patchState(store, {
296
+ loaded: true,
297
+ selected: null,
298
+ error: null,
299
+ });
300
+ },
301
+ multiSelect(items) {
302
+ patchState(store, {
303
+ multiSelected: [...items],
304
+ });
305
+ },
306
+ async update(item) {
307
+ patchState(store, {
308
+ loaded: false,
309
+ error: null,
310
+ });
311
+ try {
312
+ await crudService.updatePartial(item);
313
+ await methods.updateSuccess(item.id);
314
+ }
315
+ catch (e) {
316
+ methods.defaultFailure(e);
317
+ }
318
+ },
319
+ async updateSuccess(id) {
320
+ await methods.read({ ...store.filter, offset: 0 });
321
+ await methods.select(id);
322
+ },
323
+ async updatePartial(item) {
324
+ patchState(store, {
325
+ loaded: false,
326
+ error: null,
327
+ });
328
+ try {
329
+ await crudService.updatePartial(item);
330
+ await methods.updatePartialSuccess(item.id);
331
+ }
332
+ catch (e) {
333
+ methods.defaultFailure(e);
334
+ }
335
+ },
336
+ async updatePartialSuccess(id) {
337
+ await methods.read({ ...store.filter, offset: 0 });
338
+ await methods.select(id);
339
+ },
340
+ async updatePartialMany(items) {
341
+ patchState(store, {
342
+ loaded: false,
343
+ error: null,
344
+ });
345
+ try {
346
+ await crudService.updatePartialMany(items);
347
+ await methods.updatePartialManySuccess();
348
+ }
349
+ catch (e) {
350
+ methods.defaultFailure(e);
351
+ }
352
+ },
353
+ async updatePartialManySuccess() {
354
+ await methods.read({ ...store.filter, offset: 0 });
355
+ },
356
+ async delete(id) {
357
+ patchState(store, {
358
+ loaded: false,
359
+ error: null,
360
+ });
361
+ try {
362
+ await crudService.delete(id);
363
+ await methods.deleteSuccess();
364
+ }
365
+ catch (e) {
366
+ methods.defaultFailure(e);
367
+ }
368
+ },
369
+ async deleteSuccess() {
370
+ await methods.read({ ...store.filter, offset: 0 });
371
+ },
372
+ defaultFailure(error) {
373
+ patchState(store, {
374
+ loaded: true,
375
+ error,
376
+ });
377
+ },
378
+ };
379
+ return methods;
380
+ };
381
+ }
382
+
383
+ const initialState = {
384
+ loaded: false,
385
+ };
386
+ function createCrudFeatureStore() {
387
+ return signalStore({ providedIn: 'root' }, withState(initialState), withComputed((store) => {
388
+ return {
389
+ getError: computed(() => (store.error ? store.error() : null)),
390
+ getLoaded: computed(() => store.loaded()),
391
+ getSelected: computed(() => store.selected ? store.selected() : undefined),
392
+ getMultiSelected: computed(() => store.multiSelected ? store.multiSelected() : undefined),
393
+ getList: computed(() => (store.list ? store.list() : undefined)),
394
+ getTotalCount: computed(() => store.totalCount ? store.totalCount() : undefined),
395
+ getLinks: computed(() => (store.links ? store.links() : undefined)),
396
+ getFilter: computed(() => (store.filter ? store.filter() : undefined)),
397
+ };
398
+ }), withMethods(CrudMethodsFactory()));
399
+ }
400
+
401
+ class CrudFacade {
402
+ config;
403
+ store = createCrudFeatureStore();
404
+ loaded = this.store.getLoaded;
405
+ loading = computed(() => !this.store.getLoaded(), ...(ngDevMode ? [{ debugName: "loading" }] : []));
406
+ selected = this.store.getSelected;
407
+ multiSelected = this.store.getMultiSelected;
408
+ list = this.store.getList;
409
+ filter = this.store.getFilter;
410
+ totalCount = this.store.getTotalCount;
411
+ links = this.store.getLinks;
412
+ error = this.store.getError;
413
+ constructor(config) {
414
+ this.config = config;
415
+ }
416
+ create(item) {
417
+ this.store.create(item);
418
+ }
419
+ createMany(items, options) {
420
+ this.store.createMany({ items, options });
421
+ }
422
+ read(filter = null) {
423
+ let baseQuery = [];
424
+ if (this.config.baseQuery) {
425
+ baseQuery = this.config.baseQuery;
426
+ }
427
+ const fullFilter = {
428
+ ...(filter ? filter : {}),
429
+ query: filter && filter.query ? filter.query : baseQuery,
430
+ };
431
+ this.store.read(fullFilter);
432
+ }
433
+ clear() {
434
+ this.store.clear();
435
+ }
436
+ select(id) {
437
+ this.store.select(id);
438
+ }
439
+ unselect() {
440
+ this.store.unselect();
441
+ }
442
+ multiSelect(items) {
443
+ this.store.multiSelect(items);
444
+ }
445
+ update(item) {
446
+ this.store.update(item);
447
+ }
448
+ export(filter = null, format = null) {
449
+ this.store.export(filter || {}, format);
450
+ }
451
+ updatePartial(item) {
452
+ this.store.updatePartial(item);
453
+ }
454
+ updatePartialMany(items) {
455
+ this.store.updatePartialMany(items);
456
+ }
457
+ delete(id) {
458
+ this.store.delete(id);
459
+ }
460
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFacade, deps: [{ token: CrudConfig }], target: i0.ɵɵFactoryTarget.Injectable });
461
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFacade });
462
+ }
463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFacade, decorators: [{
464
+ type: Injectable
465
+ }], ctorParameters: () => [{ type: CrudConfig }] });
466
+
467
+ class ExportComponent extends BaseComponent$1 {
468
+ facade = inject((CrudFacade));
469
+ popoverService = inject(PopoverService);
470
+ styleService = inject(StyleService);
471
+ elementRef = inject(ElementRef);
472
+ buttonExportCsvOptions = this.initButtonExportOptions('csv');
473
+ buttonExportXlsxOptions = this.initButtonExportOptions('xlsx');
474
+ ngOnInit() {
475
+ this.styleService.init(this.elementRef);
476
+ }
477
+ initButtonExportOptions(format) {
478
+ return {
479
+ click: () => {
480
+ this.facade.export({
481
+ ...this.facade.filter(),
482
+ offset: undefined,
483
+ limit: undefined,
484
+ }, format);
485
+ const loading = this.facade.loading();
486
+ if (loading)
487
+ return;
488
+ this.popoverService.close();
489
+ },
490
+ loading: this.facade.loading,
491
+ expand: 'block',
492
+ };
493
+ }
494
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ExportComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
495
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.0", type: ExportComponent, isStandalone: true, selector: "smart-crud-export", usesInheritance: true, ngImport: i0, template: `
496
+ <div class="p-5">
497
+ <p class="my-2.5 mx-0">
498
+ <smart-button [options]="buttonExportCsvOptions" class="w-full block"
499
+ >CSV</smart-button
500
+ >
501
+ </p>
502
+ <p>
503
+ <smart-button [options]="buttonExportXlsxOptions" class="w-full block"
504
+ >XLSX</smart-button
505
+ >
506
+ </p>
507
+ </div>
508
+ `, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "smart-button", inputs: ["options", "disabled"] }] });
509
+ }
510
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ExportComponent, decorators: [{
511
+ type: Component,
512
+ args: [{
513
+ selector: 'smart-crud-export',
514
+ template: `
515
+ <div class="p-5">
516
+ <p class="my-2.5 mx-0">
517
+ <smart-button [options]="buttonExportCsvOptions" class="w-full block"
518
+ >CSV</smart-button
519
+ >
520
+ </p>
521
+ <p>
522
+ <smart-button [options]="buttonExportXlsxOptions" class="w-full block"
523
+ >XLSX</smart-button
524
+ >
525
+ </p>
526
+ </div>
527
+ `,
528
+ imports: [ButtonComponent],
529
+ }]
530
+ }] });
531
+
532
+ class BaseComponent {
533
+ facade = inject((CrudFacade));
534
+ translateService = inject(TranslateService);
535
+ possibilities;
536
+ item = input(...(ngDevMode ? [undefined, { debugName: "item" }] : []));
537
+ filter = input(...(ngDevMode ? [undefined, { debugName: "filter" }] : []));
538
+ get value() {
539
+ const filter = this.filter();
540
+ const item = this.item();
541
+ if (!filter || !item || !filter.query)
542
+ return null;
543
+ if (this.isArrayType()) {
544
+ return filter.query
545
+ .filter((q) => q.key === item.key && q.type === item.type)
546
+ .map((q) => q.value);
547
+ }
548
+ const query = filter.query.find((q) => q.key === item.key && q.type === item.type);
549
+ return query?.value;
550
+ }
551
+ set value(val) {
552
+ this.refresh(val);
553
+ }
554
+ get minValue() {
555
+ const filter = this.filter();
556
+ const item = this.item();
557
+ if (!filter || !item || !filter.query)
558
+ return null;
559
+ if (this.isArrayType()) {
560
+ return filter.query
561
+ .filter((q) => q.key === item.key && q.type === '>=')
562
+ .map((q) => q.value);
563
+ }
564
+ const query = filter.query.find((q) => q.key === item.key && q.type === '>=');
565
+ return query?.value;
566
+ }
567
+ set minValue(val) {
568
+ this.refresh(val, '>=');
569
+ }
570
+ get maxValue() {
571
+ const filter = this.filter();
572
+ const item = this.item();
573
+ if (!filter || !item || !filter.query)
574
+ return null;
575
+ if (this.isArrayType()) {
576
+ return filter.query
577
+ .filter((q) => q.key === item.key && q.type === '<=')
578
+ .map((q) => q.value);
579
+ }
580
+ const query = filter.query.find((q) => q.key === item.key && q.type === '<=');
581
+ return query?.value;
582
+ }
583
+ set maxValue(val) {
584
+ this.refresh(val, '<=');
585
+ }
586
+ get lang() {
587
+ return this.translateService.currentLang;
588
+ }
589
+ refresh(val, type = null) {
590
+ const filter = this.filter();
591
+ const item = this.item();
592
+ if (!filter || !item)
593
+ return;
594
+ if (!type)
595
+ type = item.type;
596
+ if (!filter.query)
597
+ filter.query = [];
598
+ filter.offset = 0;
599
+ if (this.isArrayType()) {
600
+ this.refreshForArray(val, type);
601
+ return;
602
+ }
603
+ let query = filter.query.find((q) => q.key === item.key && q.type === type);
604
+ if (val === null || val === undefined || val === '') {
605
+ if (query) {
606
+ const index = filter.query.indexOf(query);
607
+ if (index > -1) {
608
+ filter.query.splice(index, 1);
609
+ }
610
+ }
611
+ this.facade.read(filter);
612
+ return;
613
+ }
614
+ if (!query) {
615
+ query = {
616
+ key: item.key,
617
+ type: type,
618
+ value: null,
619
+ };
620
+ filter.query.push(query);
621
+ }
622
+ query.value = val;
623
+ query.label = item.label;
624
+ this.facade.read(filter);
625
+ }
626
+ clear() {
627
+ const filter = this.filter();
628
+ const item = this.item();
629
+ if (!filter || !item || !filter.query)
630
+ return;
631
+ filter.query = filter.query.filter((q) => q.key !== item.key);
632
+ filter.offset = 0;
633
+ this.facade.read(filter);
634
+ }
635
+ ngOnInit() {
636
+ this.initPossibilities();
637
+ }
638
+ initPossibilities() {
639
+ const item = this.item();
640
+ if (item?.possibilities) {
641
+ this.possibilities = item.possibilities;
642
+ }
643
+ }
644
+ isArrayType() {
645
+ const item = this.item();
646
+ return item?.fieldType === FieldType.check;
647
+ }
648
+ refreshForArray(vals, type) {
649
+ const filter = this.filter();
650
+ const item = this.item();
651
+ if (!filter || !item)
652
+ return;
653
+ if (!filter.query)
654
+ filter.query = [];
655
+ const queries = filter.query.filter((q) => q.key === item.key && q.type === type);
656
+ queries.forEach((query) => {
657
+ const index = filter.query.indexOf(query);
658
+ if (index > -1) {
659
+ filter.query.splice(index, 1);
660
+ }
661
+ });
662
+ if (vals === null || vals === undefined || !vals.length) {
663
+ this.facade.read(filter);
664
+ return;
665
+ }
666
+ vals.forEach((val) => {
667
+ const query = {
668
+ key: item.key,
669
+ type: type,
670
+ value: val,
671
+ };
672
+ filter.query.push(query);
673
+ });
674
+ this.facade.read(filter);
675
+ }
676
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: BaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
677
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.0", type: BaseComponent, isStandalone: true, inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
678
+ }
679
+ __decorate([
680
+ Debounce(500),
681
+ __metadata("design:type", Function),
682
+ __metadata("design:paramtypes", [Object, Object]),
683
+ __metadata("design:returntype", void 0)
684
+ ], BaseComponent.prototype, "refresh", null);
685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: BaseComponent, decorators: [{
686
+ type: Directive
687
+ }], propDecorators: { refresh: [] } });
688
+
689
+ class FilterCheckComponent extends BaseComponent {
690
+ list;
691
+ ngAfterContentInit() {
692
+ this.list = computed(() => {
693
+ const possibilities = this.possibilities();
694
+ return possibilities.map((pos) => ({
695
+ value: pos,
696
+ isCheck: this.value.some((r) => r === pos.id),
697
+ }));
698
+ }, ...(ngDevMode ? [{ debugName: "list" }] : []));
699
+ }
700
+ onCheckChange(checked, entry) {
701
+ if (checked && !this.value.some((r) => r === entry.value.id)) {
702
+ this.value = [...this.value, entry.value.id];
703
+ }
704
+ if (!checked && this.value.some((r) => r === entry.value.id)) {
705
+ this.value = this.value.filter((r) => r !== entry.value.id);
706
+ }
707
+ }
708
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterCheckComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
709
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterCheckComponent, isStandalone: true, selector: "smart-crud-filter-check", usesInheritance: true, ngImport: i0, template: `
710
+ <!-- <ion-row>-->
711
+ <!-- <ion-col>-->
712
+ <!-- <ion-item-divider class="text-xl font-light">-->
713
+ <!-- <ion-icon class="mr-6 text-2xl" slot="start" name="filter-outline"></ion-icon>-->
714
+ <!-- <ion-label>-->
715
+ {{ item()?.label || '' | translate }}
716
+ <!-- </ion-label>-->
717
+ @if (value?.length) {
718
+ <!-- <ion-button-->
719
+ <!-- slot="end"-->
720
+ <!-- color="danger"-->
721
+ <!-- (click)="refresh([])"-->
722
+ <!-- class="square-button m-0 p-0 text-lg h-9 w-9"-->
723
+ <!-- >-->
724
+ <!-- <ion-icon class="text-2xl m-0 p-0" slot="icon-only" name="close-outline"></ion-icon>-->
725
+ <!-- </ion-button>-->
726
+ }
727
+ <!-- </ion-item-divider>-->
728
+
729
+ @for (entry of list(); track entry) {
730
+ <!-- <ion-item>-->
731
+ <!--<ion-label>-->{{ entry.value.text | translate
732
+ }}<!--</ion-label>-->
733
+ <!-- <ion-checkbox-->
734
+ <!-- slot="end"-->
735
+ <!-- [checked]="entry.isCheck"-->
736
+ <!-- (ionChange)="onCheckChange($event.detail.checked, entry)"-->
737
+ <!-- ></ion-checkbox>-->
738
+ <!-- </ion-item>-->
739
+ }
740
+ <!-- </ion-col>-->
741
+ <!-- </ion-row>-->
742
+ `, isInline: true, styles: [":host{width:100%;margin-bottom:1.2rem}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }] });
743
+ }
744
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterCheckComponent, decorators: [{
745
+ type: Component,
746
+ args: [{ selector: 'smart-crud-filter-check', template: `
747
+ <!-- <ion-row>-->
748
+ <!-- <ion-col>-->
749
+ <!-- <ion-item-divider class="text-xl font-light">-->
750
+ <!-- <ion-icon class="mr-6 text-2xl" slot="start" name="filter-outline"></ion-icon>-->
751
+ <!-- <ion-label>-->
752
+ {{ item()?.label || '' | translate }}
753
+ <!-- </ion-label>-->
754
+ @if (value?.length) {
755
+ <!-- <ion-button-->
756
+ <!-- slot="end"-->
757
+ <!-- color="danger"-->
758
+ <!-- (click)="refresh([])"-->
759
+ <!-- class="square-button m-0 p-0 text-lg h-9 w-9"-->
760
+ <!-- >-->
761
+ <!-- <ion-icon class="text-2xl m-0 p-0" slot="icon-only" name="close-outline"></ion-icon>-->
762
+ <!-- </ion-button>-->
763
+ }
764
+ <!-- </ion-item-divider>-->
765
+
766
+ @for (entry of list(); track entry) {
767
+ <!-- <ion-item>-->
768
+ <!--<ion-label>-->{{ entry.value.text | translate
769
+ }}<!--</ion-label>-->
770
+ <!-- <ion-checkbox-->
771
+ <!-- slot="end"-->
772
+ <!-- [checked]="entry.isCheck"-->
773
+ <!-- (ionChange)="onCheckChange($event.detail.checked, entry)"-->
774
+ <!-- ></ion-checkbox>-->
775
+ <!-- </ion-item>-->
776
+ }
777
+ <!-- </ion-col>-->
778
+ <!-- </ion-row>-->
779
+ `, imports: [TranslatePipe], styles: [":host{width:100%;margin-bottom:1.2rem}\n"] }]
780
+ }] });
781
+
782
+ class FilterDateComponent extends BaseComponent {
783
+ id = GuidService.create();
784
+ get allowAdvanced() {
785
+ const item = this.item();
786
+ return item?.type === '=';
787
+ }
788
+ set customValue(val) {
789
+ const momentDate = moment(val);
790
+ this.value =
791
+ val?.length >= 10 && momentDate.isValid()
792
+ ? momentDate.format('YYYY-MM-DD')
793
+ : val;
794
+ }
795
+ get customValue() {
796
+ return this.value;
797
+ }
798
+ set customMinValue(val) {
799
+ const momentDate = moment(val);
800
+ this.minValue =
801
+ val?.length >= 10 && momentDate.isValid()
802
+ ? momentDate.format('YYYY-MM-DD')
803
+ : val;
804
+ }
805
+ get customMinValue() {
806
+ return this.minValue;
807
+ }
808
+ set customMaxValue(val) {
809
+ const momentDate = moment(val);
810
+ this.maxValue =
811
+ val?.length >= 10 && momentDate.isValid()
812
+ ? momentDate.format('YYYY-MM-DD')
813
+ : val;
814
+ }
815
+ get customMaxValue() {
816
+ return this.maxValue;
817
+ }
818
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterDateComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
819
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterDateComponent, isStandalone: true, selector: "smart-crud-filter-date", usesInheritance: true, ngImport: i0, template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n<!-- <ion-item button=\"true\" id=\"open-date-input-{{ id }}\" color=\"primary\">-->\n<!-- <ion-text>-->\n{{ customValue ? customValue : ('select' | translate) }}\n<!-- </ion-text>-->\n<!-- <ion-popover trigger=\"open-date-input-{{ id }}\" show-backdrop=\"false\">-->\n<ng-template>\n <!-- <ion-datetime-->\n <!-- displayFormat=\"YYYY-MM-DD\"-->\n <!-- pickerFormat=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customValue\"-->\n <!-- presentation=\"date\"-->\n <!-- ></ion-datetime>-->\n</ng-template>\n<!-- </ion-popover>-->\n<!-- </ion-item>-->\n<!-- </ion-col>-->\n\n@if (value) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"refresh(null)\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
820
+ }
821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterDateComponent, decorators: [{
822
+ type: Component,
823
+ args: [{ selector: 'smart-crud-filter-date', imports: [FormsModule, TranslatePipe], template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n<!-- <ion-item button=\"true\" id=\"open-date-input-{{ id }}\" color=\"primary\">-->\n<!-- <ion-text>-->\n{{ customValue ? customValue : ('select' | translate) }}\n<!-- </ion-text>-->\n<!-- <ion-popover trigger=\"open-date-input-{{ id }}\" show-backdrop=\"false\">-->\n<ng-template>\n <!-- <ion-datetime-->\n <!-- displayFormat=\"YYYY-MM-DD\"-->\n <!-- pickerFormat=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customValue\"-->\n <!-- presentation=\"date\"-->\n <!-- ></ion-datetime>-->\n</ng-template>\n<!-- </ion-popover>-->\n<!-- </ion-item>-->\n<!-- </ion-col>-->\n\n@if (value) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"refresh(null)\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"] }]
824
+ }] });
825
+
826
+ class FilterDateTimeComponent extends FilterDateComponent {
827
+ _subscriptions = new Subscription();
828
+ id = GuidService.create();
829
+ // @ViewChild(IonDatetime, { read: IonDatetime, static: false })
830
+ // dateTimePicker: IonDatetime;
831
+ ngOnInit() {
832
+ super.ngOnInit();
833
+ // if (this.dateTimePicker) {
834
+ // this._subscriptions.add(
835
+ // this.dateTimePicker.ionChange.subscribe((val: CustomEvent) => {
836
+ // this.customValue = val.detail.value;
837
+ // }),
838
+ // );
839
+ // } else {
840
+ // console.error('dateTimePicker not found!');
841
+ // }
842
+ }
843
+ ngOnDestroy() {
844
+ if (this._subscriptions) {
845
+ this._subscriptions.unsubscribe();
846
+ }
847
+ }
848
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterDateTimeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
849
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterDateTimeComponent, isStandalone: true, selector: "smart-crud-filter-date-time", usesInheritance: true, ngImport: i0, template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n<!-- </ion-col>-->\n@if (value || minValue || maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"clear()\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-item>-->\n<!-- <ion-label>-->\n{{ 'from' | translate }}\n<!-- </ion-label>-->\n<!-- <ion-input-->\n<!-- placeholder=\"YYYY-MM-DD HH:mm:ss\"-->\n<!-- [(ngModel)]=\"customMinValue\"-->\n<!-- pattern=\"^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$\"-->\n<!-- ></ion-input>-->\n<!-- </ion-item>-->\n<!-- </ion-col>-->\n@if (customMinValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '>=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!-- <ion-col>-->\n<!-- <ion-item>-->\n<!-- <ion-label>-->\n{{ 'to' | translate }}\n<!-- </ion-label>-->\n<!-- <ion-input-->\n<!-- placeholder=\"YYYY-MM-DD HH:mm:ss\"-->\n<!-- [(ngModel)]=\"customMaxValue\"-->\n<!-- pattern=\"^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$\"-->\n<!-- ></ion-input>-->\n<!-- </ion-item>-->\n<!-- </ion-col>-->\n@if (customMaxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '<=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
850
+ }
851
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterDateTimeComponent, decorators: [{
852
+ type: Component,
853
+ args: [{ selector: 'smart-crud-filter-date-time', imports: [TranslatePipe, FormsModule], template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n<!-- </ion-col>-->\n@if (value || minValue || maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"clear()\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-item>-->\n<!-- <ion-label>-->\n{{ 'from' | translate }}\n<!-- </ion-label>-->\n<!-- <ion-input-->\n<!-- placeholder=\"YYYY-MM-DD HH:mm:ss\"-->\n<!-- [(ngModel)]=\"customMinValue\"-->\n<!-- pattern=\"^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$\"-->\n<!-- ></ion-input>-->\n<!-- </ion-item>-->\n<!-- </ion-col>-->\n@if (customMinValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '>=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!-- <ion-col>-->\n<!-- <ion-item>-->\n<!-- <ion-label>-->\n{{ 'to' | translate }}\n<!-- </ion-label>-->\n<!-- <ion-input-->\n<!-- placeholder=\"YYYY-MM-DD HH:mm:ss\"-->\n<!-- [(ngModel)]=\"customMaxValue\"-->\n<!-- pattern=\"^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$\"-->\n<!-- ></ion-input>-->\n<!-- </ion-item>-->\n<!-- </ion-col>-->\n@if (customMaxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '<=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"] }]
854
+ }] });
855
+
856
+ class FilterDateWithEditComponent extends FilterDateComponent {
857
+ _subscriptions = new Subscription();
858
+ advanced = signal(false, ...(ngDevMode ? [{ debugName: "advanced" }] : []));
859
+ id = GuidService.create();
860
+ // @ViewChild(IonDatetime, { read: IonDatetime, static: false })
861
+ // dateTimePicker: IonDatetime;
862
+ toggleAdvanced() {
863
+ this.advanced.update((val) => !val);
864
+ if (this.advanced()) {
865
+ this.value = null;
866
+ }
867
+ }
868
+ ngOnInit() {
869
+ super.ngOnInit();
870
+ // if (this.dateTimePicker) {
871
+ // this._subscriptions.add(
872
+ // this.dateTimePicker.ionChange.subscribe((val: CustomEvent) => {
873
+ // this.customValue = val.detail.value;
874
+ // }),
875
+ // );
876
+ // } else {
877
+ // console.error('dateTimePicker not found!');
878
+ // }
879
+ }
880
+ ngOnDestroy() {
881
+ if (this._subscriptions) {
882
+ this._subscriptions.unsubscribe();
883
+ }
884
+ }
885
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterDateWithEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
886
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterDateWithEditComponent, isStandalone: true, selector: "smart-crud-filter-date-with-edit", usesInheritance: true, ngImport: i0, template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n\n@if (!advanced()) {\n <!-- <ion-input-->\n <!-- placeholder=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customValue\"-->\n <!-- [pattern]=\"'([12]\\\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01]))'\"-->\n <!-- ></ion-input>-->\n}\n<!-- </ion-col>-->\n\n@if (!advanced()) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button id=\"open-date-input-{{ id }}\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"calendar-outline\"></ion-icon>-->\n <!-- <ion-popover trigger=\"open-date-input-{{ id }}\" show-backdrop=\"false\">-->\n <ng-template>\n <!-- <ion-datetime-->\n <!-- displayFormat=\"YYYY-MM-DD\"-->\n <!-- pickerFormat=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customValue\"-->\n <!-- presentation=\"date\"-->\n <!-- first-day-of-week=\"1\"-->\n <!-- locale=\"{{ lang }}\"-->\n <!-- ></ion-datetime>-->\n </ng-template>\n <!-- </ion-popover>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n@if (allowAdvanced) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- (click)=\"toggleAdvanced()\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- [disabled]=\"minValue || maxValue\"-->\n <!-- >-->\n @if (!advanced()) {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings-outline\"></ion-icon>-->\n } @else {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings\"></ion-icon>-->\n }\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n@if (value || minValue || maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"clear()\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n\n@if ((advanced() || minValue || maxValue) && allowAdvanced) {\n <!-- <ion-row>-->\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'from' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input-->\n <!-- placeholder=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customMinValue\"-->\n <!-- [pattern]=\"'([12]\\\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01]))'\"-->\n <!-- ></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n @if (customMinValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '>=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'to' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input-->\n <!-- placeholder=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customMaxValue\"-->\n <!-- [pattern]=\"'([12]\\\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01]))'\"-->\n <!-- ></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n\n @if (customMaxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '<=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- </ion-row>-->\n}\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
887
+ }
888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterDateWithEditComponent, decorators: [{
889
+ type: Component,
890
+ args: [{ selector: 'smart-crud-filter-date-with-edit', imports: [TranslatePipe, FormsModule], template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n\n@if (!advanced()) {\n <!-- <ion-input-->\n <!-- placeholder=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customValue\"-->\n <!-- [pattern]=\"'([12]\\\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01]))'\"-->\n <!-- ></ion-input>-->\n}\n<!-- </ion-col>-->\n\n@if (!advanced()) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button id=\"open-date-input-{{ id }}\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"calendar-outline\"></ion-icon>-->\n <!-- <ion-popover trigger=\"open-date-input-{{ id }}\" show-backdrop=\"false\">-->\n <ng-template>\n <!-- <ion-datetime-->\n <!-- displayFormat=\"YYYY-MM-DD\"-->\n <!-- pickerFormat=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customValue\"-->\n <!-- presentation=\"date\"-->\n <!-- first-day-of-week=\"1\"-->\n <!-- locale=\"{{ lang }}\"-->\n <!-- ></ion-datetime>-->\n </ng-template>\n <!-- </ion-popover>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n@if (allowAdvanced) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- (click)=\"toggleAdvanced()\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- [disabled]=\"minValue || maxValue\"-->\n <!-- >-->\n @if (!advanced()) {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings-outline\"></ion-icon>-->\n } @else {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings\"></ion-icon>-->\n }\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n@if (value || minValue || maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"clear()\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n\n@if ((advanced() || minValue || maxValue) && allowAdvanced) {\n <!-- <ion-row>-->\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'from' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input-->\n <!-- placeholder=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customMinValue\"-->\n <!-- [pattern]=\"'([12]\\\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01]))'\"-->\n <!-- ></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n @if (customMinValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '>=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'to' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input-->\n <!-- placeholder=\"YYYY-MM-DD\"-->\n <!-- [(ngModel)]=\"customMaxValue\"-->\n <!-- [pattern]=\"'([12]\\\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01]))'\"-->\n <!-- ></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n\n @if (customMaxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '<=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- </ion-row>-->\n}\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"] }]
891
+ }] });
892
+
893
+ class FilterFlagComponent extends BaseComponent {
894
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterFlagComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
895
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterFlagComponent, isStandalone: true, selector: "smart-crud-filter-flag", usesInheritance: true, ngImport: i0, template: `
896
+ <!-- <ion-row>-->
897
+ <!-- <ion-col>-->
898
+ <div
899
+ class="flag-container w-full flex flex-row flex-nowrap justify-between pr-5"
900
+ >
901
+ <!-- <ion-label class="align-middle my-6" position="static">-->
902
+ {{ item()?.label || '' | translate }}
903
+ <!-- </ion-label>-->
904
+ <!-- <ion-checkbox [(ngModel)]="value" slot="end"></ion-checkbox>-->
905
+ </div>
906
+ <!-- </ion-col>-->
907
+ @if (typeof value === 'boolean') {
908
+ <!-- <ion-col size="auto">-->
909
+ <!-- <ion-button-->
910
+ <!-- color="danger"-->
911
+ <!-- (click)="refresh(null)"-->
912
+ <!-- class="square-button m-3"-->
913
+ <!-- >-->
914
+ <!-- <ion-icon slot="icon-only" name="close-outline"></ion-icon>-->
915
+ <!-- </ion-button>-->
916
+ <!-- </ion-col>-->
917
+ }
918
+ <!-- </ion-row>-->
919
+ `, isInline: true, styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
920
+ }
921
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterFlagComponent, decorators: [{
922
+ type: Component,
923
+ args: [{ selector: 'smart-crud-filter-flag', template: `
924
+ <!-- <ion-row>-->
925
+ <!-- <ion-col>-->
926
+ <div
927
+ class="flag-container w-full flex flex-row flex-nowrap justify-between pr-5"
928
+ >
929
+ <!-- <ion-label class="align-middle my-6" position="static">-->
930
+ {{ item()?.label || '' | translate }}
931
+ <!-- </ion-label>-->
932
+ <!-- <ion-checkbox [(ngModel)]="value" slot="end"></ion-checkbox>-->
933
+ </div>
934
+ <!-- </ion-col>-->
935
+ @if (typeof value === 'boolean') {
936
+ <!-- <ion-col size="auto">-->
937
+ <!-- <ion-button-->
938
+ <!-- color="danger"-->
939
+ <!-- (click)="refresh(null)"-->
940
+ <!-- class="square-button m-3"-->
941
+ <!-- >-->
942
+ <!-- <ion-icon slot="icon-only" name="close-outline"></ion-icon>-->
943
+ <!-- </ion-button>-->
944
+ <!-- </ion-col>-->
945
+ }
946
+ <!-- </ion-row>-->
947
+ `, imports: [TranslatePipe, FormsModule], styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"] }]
948
+ }] });
949
+
950
+ class FilterIntComponent extends BaseComponent {
951
+ _subscriptions = new Subscription();
952
+ advanced = signal(false, ...(ngDevMode ? [{ debugName: "advanced" }] : []));
953
+ get allowAdvanced() {
954
+ return this.item()?.type === '=';
955
+ }
956
+ ngOnInit() {
957
+ super.ngOnInit();
958
+ }
959
+ ngOnDestroy() {
960
+ if (this._subscriptions) {
961
+ this._subscriptions.unsubscribe();
962
+ }
963
+ }
964
+ toggleAdvanced() {
965
+ this.advanced.update((val) => !val);
966
+ if (this.advanced())
967
+ this.value = null;
968
+ }
969
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterIntComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
970
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterIntComponent, isStandalone: true, selector: "smart-crud-filter-int", usesInheritance: true, ngImport: i0, template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n@if (!advanced()) {\n <!-- <ion-input [(ngModel)]=\"value\" type=\"number\" step=\"1\"></ion-input>-->\n}\n<!-- </ion-col>-->\n@if (allowAdvanced) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- (click)=\"toggleAdvanced()\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- [disabled]=\"minValue || maxValue\"-->\n <!-- >-->\n @if (!advanced()) {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings-outline\"></ion-icon>-->\n } @else {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings\"></ion-icon>-->\n }\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n@if (value || minValue || maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"clear()\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n@if ((advanced() || minValue || maxValue) && allowAdvanced) {\n <!-- <ion-row>-->\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'from' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input [(ngModel)]=\"minValue\" type=\"number\" step=\"1\"></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n @if (minValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '>=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'to' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input [(ngModel)]=\"maxValue\" type=\"number\" step=\"1\"></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n @if (maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '<=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- </ion-row>-->\n}\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
971
+ }
972
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterIntComponent, decorators: [{
973
+ type: Component,
974
+ args: [{ selector: 'smart-crud-filter-int', imports: [TranslatePipe, FormsModule], template: "<!--<ion-row>-->\n<!-- <ion-col>-->\n<!-- <ion-label>-->\n{{ item()?.label || '' | translate }}\n<!-- </ion-label>-->\n@if (!advanced()) {\n <!-- <ion-input [(ngModel)]=\"value\" type=\"number\" step=\"1\"></ion-input>-->\n}\n<!-- </ion-col>-->\n@if (allowAdvanced) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- (click)=\"toggleAdvanced()\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- [disabled]=\"minValue || maxValue\"-->\n <!-- >-->\n @if (!advanced()) {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings-outline\"></ion-icon>-->\n } @else {\n <!-- <ion-icon slot=\"icon-only\" name=\"settings\"></ion-icon>-->\n }\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n@if (value || minValue || maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button color=\"danger\" (click)=\"clear()\" class=\"square-button m-3\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n}\n<!--</ion-row>-->\n@if ((advanced() || minValue || maxValue) && allowAdvanced) {\n <!-- <ion-row>-->\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'from' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input [(ngModel)]=\"minValue\" type=\"number\" step=\"1\"></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n @if (minValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '>=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- <ion-col>-->\n <!-- <ion-item>-->\n <!-- <ion-label>-->\n {{ 'to' | translate }}\n <!-- </ion-label>-->\n <!-- <ion-input [(ngModel)]=\"maxValue\" type=\"number\" step=\"1\"></ion-input>-->\n <!-- </ion-item>-->\n <!-- </ion-col>-->\n @if (maxValue) {\n <!-- <ion-col size=\"auto\">-->\n <!-- <ion-button-->\n <!-- color=\"danger\"-->\n <!-- (click)=\"refresh(null, '<=')\"-->\n <!-- class=\"square-button m-3\"-->\n <!-- >-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-col>-->\n }\n <!-- </ion-row>-->\n}\n", styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"] }]
975
+ }] });
976
+
977
+ class FilterRadioComponent extends BaseComponent {
978
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterRadioComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
979
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterRadioComponent, isStandalone: true, selector: "smart-crud-filter-radio", usesInheritance: true, ngImport: i0, template: `
980
+ <!-- <ion-row>-->
981
+ <!-- <ion-col>-->
982
+ <!-- <ion-radio-group [(ngModel)]="value">-->
983
+ <!-- <ion-item-divider class="font-light text-xl">-->
984
+ <!-- <ion-icon class="mr-6 text-2xl" slot="start" name="filter-outline"></ion-icon>-->
985
+ <!-- <ion-label>-->
986
+ {{ item()?.label || '' | translate }}
987
+ <!-- </ion-label>-->
988
+ @if (value || value === false) {
989
+ <!-- <ion-button-->
990
+ <!-- slot="end"-->
991
+ <!-- color="danger"-->
992
+ <!-- (click)="refresh(null)"-->
993
+ <!-- class="square-button m-0 text-lg h-9 w-9 p-0"-->
994
+ <!-- >-->
995
+ <!-- <ion-icon class="mr-6 text-2xl m-0 p-0" slot="icon-only" name="close-outline"></ion-icon>-->
996
+ <!-- </ion-button>-->
997
+ }
998
+ <!-- </ion-item-divider>-->
999
+
1000
+ @for (item of possibilities(); track item) {
1001
+ <!-- <ion-item>-->
1002
+ <!-- <ion-label>{{ item.text | translate }}</ion-label>-->
1003
+ <!-- <ion-radio class="mr-10" [value]="item.id"></ion-radio>-->
1004
+ <!-- </ion-item>-->
1005
+ }
1006
+ <!-- </ion-radio-group>-->
1007
+ <!-- </ion-col>-->
1008
+ <!-- </ion-row>-->
1009
+ `, isInline: true, styles: [":host{width:100%;margin-bottom:1.2rem}:host ion-item-divider{//--padding-end: .8rem;//--ion-background-color: linear-gradient(// 90deg,// transparent,// var(--ion-color-light) //)}:host ion-item-divider ion-icon{//--color: var(--ion-color-primary)}:host ion-item-divider ion-label{//--padding: var(--smart-button-padding-left) / 2 // var(--smart-button-padding-top) / 2 var(--smart-button-padding-right) / // 2 var(--smart-button-padding-bottom) / 2}:host ion-item-divider .square-button{//--padding-start: .2em;//--padding-end: .2em}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1010
+ }
1011
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterRadioComponent, decorators: [{
1012
+ type: Component,
1013
+ args: [{ selector: 'smart-crud-filter-radio', template: `
1014
+ <!-- <ion-row>-->
1015
+ <!-- <ion-col>-->
1016
+ <!-- <ion-radio-group [(ngModel)]="value">-->
1017
+ <!-- <ion-item-divider class="font-light text-xl">-->
1018
+ <!-- <ion-icon class="mr-6 text-2xl" slot="start" name="filter-outline"></ion-icon>-->
1019
+ <!-- <ion-label>-->
1020
+ {{ item()?.label || '' | translate }}
1021
+ <!-- </ion-label>-->
1022
+ @if (value || value === false) {
1023
+ <!-- <ion-button-->
1024
+ <!-- slot="end"-->
1025
+ <!-- color="danger"-->
1026
+ <!-- (click)="refresh(null)"-->
1027
+ <!-- class="square-button m-0 text-lg h-9 w-9 p-0"-->
1028
+ <!-- >-->
1029
+ <!-- <ion-icon class="mr-6 text-2xl m-0 p-0" slot="icon-only" name="close-outline"></ion-icon>-->
1030
+ <!-- </ion-button>-->
1031
+ }
1032
+ <!-- </ion-item-divider>-->
1033
+
1034
+ @for (item of possibilities(); track item) {
1035
+ <!-- <ion-item>-->
1036
+ <!-- <ion-label>{{ item.text | translate }}</ion-label>-->
1037
+ <!-- <ion-radio class="mr-10" [value]="item.id"></ion-radio>-->
1038
+ <!-- </ion-item>-->
1039
+ }
1040
+ <!-- </ion-radio-group>-->
1041
+ <!-- </ion-col>-->
1042
+ <!-- </ion-row>-->
1043
+ `, imports: [TranslatePipe, FormsModule], styles: [":host{width:100%;margin-bottom:1.2rem}:host ion-item-divider{//--padding-end: .8rem;//--ion-background-color: linear-gradient(// 90deg,// transparent,// var(--ion-color-light) //)}:host ion-item-divider ion-icon{//--color: var(--ion-color-primary)}:host ion-item-divider ion-label{//--padding: var(--smart-button-padding-left) / 2 // var(--smart-button-padding-top) / 2 var(--smart-button-padding-right) / // 2 var(--smart-button-padding-bottom) / 2}:host ion-item-divider .square-button{//--padding-start: .2em;//--padding-end: .2em}\n"] }]
1044
+ }] });
1045
+
1046
+ class FilterTextComponent extends BaseComponent {
1047
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1048
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterTextComponent, isStandalone: true, selector: "smart-crud-filter-text", usesInheritance: true, ngImport: i0, template: `
1049
+ <!-- <ion-row>-->
1050
+ <!-- <ion-col>-->
1051
+ <!-- <ion-label position="floating">-->
1052
+ {{ item()?.label || '' | translate }}
1053
+ <!-- </ion-label>-->
1054
+ <!-- <ion-input [(ngModel)]="value"></ion-input>-->
1055
+ <!-- </ion-col>-->
1056
+ @if (value) {
1057
+ <!-- <ion-col size="auto">-->
1058
+ <!-- <ion-button-->
1059
+ <!-- color="danger"-->
1060
+ <!-- (click)="refresh(null)"-->
1061
+ <!-- class="square-button m-3"-->
1062
+ <!-- >-->
1063
+ <!-- <ion-icon slot="icon-only" name="close-outline"></ion-icon>-->
1064
+ <!-- </ion-button>-->
1065
+ <!-- </ion-col>-->
1066
+ }
1067
+ <!-- </ion-row>-->
1068
+ `, isInline: true, styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1069
+ }
1070
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterTextComponent, decorators: [{
1071
+ type: Component,
1072
+ args: [{ selector: 'smart-crud-filter-text', template: `
1073
+ <!-- <ion-row>-->
1074
+ <!-- <ion-col>-->
1075
+ <!-- <ion-label position="floating">-->
1076
+ {{ item()?.label || '' | translate }}
1077
+ <!-- </ion-label>-->
1078
+ <!-- <ion-input [(ngModel)]="value"></ion-input>-->
1079
+ <!-- </ion-col>-->
1080
+ @if (value) {
1081
+ <!-- <ion-col size="auto">-->
1082
+ <!-- <ion-button-->
1083
+ <!-- color="danger"-->
1084
+ <!-- (click)="refresh(null)"-->
1085
+ <!-- class="square-button m-3"-->
1086
+ <!-- >-->
1087
+ <!-- <ion-icon slot="icon-only" name="close-outline"></ion-icon>-->
1088
+ <!-- </ion-button>-->
1089
+ <!-- </ion-col>-->
1090
+ }
1091
+ <!-- </ion-row>-->
1092
+ `, imports: [TranslatePipe, FormsModule], styles: [":host{width:100%}:host .square-button{height:var(--smart-button-height)!important}\n"] }]
1093
+ }] });
1094
+
1095
+ class FilterComponent {
1096
+ FieldType = FieldType;
1097
+ item = input(...(ngDevMode ? [undefined, { debugName: "item" }] : []));
1098
+ filter = input(...(ngDevMode ? [undefined, { debugName: "filter" }] : []));
1099
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1100
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FilterComponent, isStandalone: true, selector: "smart-crud-filter", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!--<ion-item>-->\n@switch (item()?.fieldType) {\n @case (FieldType.date) {\n <smart-crud-filter-date\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-date>\n }\n @case (FieldType.dateWithEdit) {\n <smart-crud-filter-date-with-edit\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-date-with-edit>\n }\n @case (FieldType.dateTime) {\n <smart-crud-filter-date-time\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-date-time>\n }\n @case (FieldType.radio) {\n <smart-crud-filter-radio\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-radio>\n }\n @case (FieldType.check) {\n <smart-crud-filter-check\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-check>\n }\n @case (FieldType.flag) {\n <smart-crud-filter-flag\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-flag>\n }\n @case (FieldType.int) {\n <smart-crud-filter-int\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-int>\n }\n @default {\n <smart-crud-filter-text\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-text>\n }\n}\n<!--</ion-item>-->\n", dependencies: [{ kind: "component", type: FilterTextComponent, selector: "smart-crud-filter-text" }, { kind: "component", type: FilterIntComponent, selector: "smart-crud-filter-int" }, { kind: "component", type: FilterFlagComponent, selector: "smart-crud-filter-flag" }, { kind: "component", type: FilterCheckComponent, selector: "smart-crud-filter-check" }, { kind: "component", type: FilterRadioComponent, selector: "smart-crud-filter-radio" }, { kind: "component", type: FilterDateTimeComponent, selector: "smart-crud-filter-date-time" }, { kind: "component", type: FilterDateWithEditComponent, selector: "smart-crud-filter-date-with-edit" }, { kind: "component", type: FilterDateComponent, selector: "smart-crud-filter-date" }] });
1101
+ }
1102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FilterComponent, decorators: [{
1103
+ type: Component,
1104
+ args: [{ selector: 'smart-crud-filter', imports: [
1105
+ FilterTextComponent,
1106
+ FilterIntComponent,
1107
+ FilterFlagComponent,
1108
+ FilterCheckComponent,
1109
+ FilterRadioComponent,
1110
+ FilterDateTimeComponent,
1111
+ FilterDateWithEditComponent,
1112
+ FilterDateComponent,
1113
+ ], template: "<!--<ion-item>-->\n@switch (item()?.fieldType) {\n @case (FieldType.date) {\n <smart-crud-filter-date\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-date>\n }\n @case (FieldType.dateWithEdit) {\n <smart-crud-filter-date-with-edit\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-date-with-edit>\n }\n @case (FieldType.dateTime) {\n <smart-crud-filter-date-time\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-date-time>\n }\n @case (FieldType.radio) {\n <smart-crud-filter-radio\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-radio>\n }\n @case (FieldType.check) {\n <smart-crud-filter-check\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-check>\n }\n @case (FieldType.flag) {\n <smart-crud-filter-flag\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-flag>\n }\n @case (FieldType.int) {\n <smart-crud-filter-int\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-int>\n }\n @default {\n <smart-crud-filter-text\n [item]=\"item()\"\n [filter]=\"filter()\"\n ></smart-crud-filter-text>\n }\n}\n<!--</ion-item>-->\n" }]
1114
+ }] });
1115
+
1116
+ /**
1117
+ * This component is only to use in crud module
1118
+ * @requires CrudModule
1119
+ * @example
1120
+ *
1121
+ * html: <smart-crud-filters></smart-crud-filters>
1122
+ *
1123
+ * use on the model:
1124
+ * @Model({
1125
+ titleKey: 'body',
1126
+ filters: [
1127
+ {
1128
+ label: 'testNegation',
1129
+ key: 'body',
1130
+ type: '!=',
1131
+ },
1132
+ {
1133
+ label: 'fromDate',
1134
+ key: 'createDate',
1135
+ type: '<=',
1136
+ fieldType: FieldType.dateWithEdit
1137
+ },
1138
+ {
1139
+ label: 'select',
1140
+ key: 'type',
1141
+ type: '=',
1142
+ fieldType: FieldType.radio,
1143
+ possibilities$: of([
1144
+ {
1145
+ id: 1, text: 'Test 1'
1146
+ },
1147
+ {
1148
+ id: 2, text: 'Test 2'
1149
+ }
1150
+ ])
1151
+ }
1152
+ ]
1153
+ })
1154
+ *
1155
+ * use on the field (list.filter property):
1156
+ * @Field({
1157
+ create: modifyMetdata,
1158
+ update: {
1159
+ ...modifyMetdata,
1160
+ multi: true
1161
+ },
1162
+ type: FieldType.longText,
1163
+ details: true,
1164
+ list: {
1165
+ order: 2,
1166
+ filter: true
1167
+ }
1168
+ })
1169
+ body: string;
1170
+ */
1171
+ class FiltersComponent {
1172
+ menuService = inject(MenuService);
1173
+ config = inject((CrudConfig));
1174
+ facade = inject((CrudFacade));
1175
+ styleService = inject(StyleService);
1176
+ elementRef = inject(ElementRef);
1177
+ list;
1178
+ filter;
1179
+ /**
1180
+ * Hide menu used only from MenuService
1181
+ */
1182
+ hideMenu = input(false, ...(ngDevMode ? [{ debugName: "hideMenu" }] : []));
1183
+ async onClose() {
1184
+ await this.menuService.closeEnd();
1185
+ }
1186
+ ngOnInit() {
1187
+ this.styleService.init(this.elementRef);
1188
+ this.list = signal([], ...(ngDevMode ? [{ debugName: "list" }] : []));
1189
+ const modelFilters = getModelOptions(this.config.type).filters;
1190
+ this.list.set([
1191
+ ...(modelFilters
1192
+ ? modelFilters.map((item) => {
1193
+ if (!item.label) {
1194
+ item.label = 'MODEL.' + item.key;
1195
+ }
1196
+ return item;
1197
+ })
1198
+ : []),
1199
+ ...getModelFieldsWithOptions(new this.config.type())
1200
+ .filter((item) => item.options?.list?.filter)
1201
+ .map((item) => ({
1202
+ key: item.key,
1203
+ type: item.options.type === FieldType.text ||
1204
+ item.options.type === FieldType.longText
1205
+ ? '~='
1206
+ : '=',
1207
+ label: 'MODEL.' + item.key,
1208
+ fieldType: item.options.type,
1209
+ })),
1210
+ ]);
1211
+ this.filter = this.facade.filter;
1212
+ }
1213
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1214
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FiltersComponent, isStandalone: true, selector: "smart-crud-filters", inputs: { hideMenu: { classPropertyName: "hideMenu", publicName: "hideMenu", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1215
+ <!--<ion-header [hidden]="hideMenu()">-->
1216
+ <!-- <ion-toolbar>-->
1217
+ <!-- <ion-buttons slot="end">-->
1218
+ <!-- <ion-button (click)="onClose()">-->
1219
+ <!-- <ion-icon slot="icon-only" name="close"> </ion-icon>-->
1220
+ <!-- </ion-button>-->
1221
+ <!-- </ion-buttons>-->
1222
+ <!-- <ion-title>{{ 'filters' | translate }}</ion-title>-->
1223
+ <!-- </ion-toolbar>-->
1224
+ <!--</ion-header>-->
1225
+ <!--<ion-content style="height: 100vh">-->
1226
+ <!-- <ion-list>-->
1227
+ @for (item of list(); track item) {
1228
+ <smart-crud-filter [item]="item" [filter]="filter()"></smart-crud-filter>
1229
+ }
1230
+ <!-- </ion-list>-->
1231
+ <div class="h-20">&nbsp;</div>
1232
+ <!--</ion-content>-->
1233
+ `, isInline: true, styles: [":host ion-toolbar.ios{height:4.6rem}:host ion-toolbar ion-buttons.ios{height:var(--smart-button-height);margin:0}\n"], dependencies: [{ kind: "component", type: FilterComponent, selector: "smart-crud-filter", inputs: ["item", "filter"] }] });
1234
+ }
1235
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FiltersComponent, decorators: [{
1236
+ type: Component,
1237
+ args: [{ selector: 'smart-crud-filters', template: `
1238
+ <!--<ion-header [hidden]="hideMenu()">-->
1239
+ <!-- <ion-toolbar>-->
1240
+ <!-- <ion-buttons slot="end">-->
1241
+ <!-- <ion-button (click)="onClose()">-->
1242
+ <!-- <ion-icon slot="icon-only" name="close"> </ion-icon>-->
1243
+ <!-- </ion-button>-->
1244
+ <!-- </ion-buttons>-->
1245
+ <!-- <ion-title>{{ 'filters' | translate }}</ion-title>-->
1246
+ <!-- </ion-toolbar>-->
1247
+ <!--</ion-header>-->
1248
+ <!--<ion-content style="height: 100vh">-->
1249
+ <!-- <ion-list>-->
1250
+ @for (item of list(); track item) {
1251
+ <smart-crud-filter [item]="item" [filter]="filter()"></smart-crud-filter>
1252
+ }
1253
+ <!-- </ion-list>-->
1254
+ <div class="h-20">&nbsp;</div>
1255
+ <!--</ion-content>-->
1256
+ `, imports: [FilterComponent, TranslatePipe], styles: [":host ion-toolbar.ios{height:4.6rem}:host ion-toolbar ion-buttons.ios{height:var(--smart-button-height);margin:0}\n"] }]
1257
+ }] });
1258
+
1259
+ class FiltersConfigComponent {
1260
+ facade = inject((CrudFacade));
1261
+ styleService = inject(StyleService);
1262
+ elementRef = inject(ElementRef);
1263
+ query;
1264
+ onRemoveQuery(item) {
1265
+ const filter = this.facade.filter();
1266
+ if (filter?.query) {
1267
+ const index = filter.query.indexOf(item);
1268
+ if (index > -1) {
1269
+ filter.query.splice(index, 1);
1270
+ }
1271
+ }
1272
+ this.facade.read(this.facade.filter());
1273
+ }
1274
+ ngOnInit() {
1275
+ this.styleService.init(this.elementRef);
1276
+ this.query = computed(() => {
1277
+ const filter = this.facade.filter();
1278
+ return filter?.query?.filter((i) => !i.hidden) || [];
1279
+ }, ...(ngDevMode ? [{ debugName: "query" }] : []));
1280
+ }
1281
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FiltersConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1282
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: FiltersConfigComponent, isStandalone: true, selector: "smart-crud-filters-config", ngImport: i0, template: `
1283
+ @let query = this.query();
1284
+ @if (query && query?.length) {
1285
+ <!-- <ion-toolbar>-->
1286
+ @for (item of query; track item) {
1287
+ <!-- <ion-chip (click)="onRemoveQuery(item)" color="medium" outline="true">-->
1288
+ <!-- <ion-icon name="filter-circle-outline" color="primary"></ion-icon>-->
1289
+ <!-- <ion-label>-->
1290
+ {{ 'MODEL.' + item.key | translate }} {{ item.type }}
1291
+ {{ item.value | translate }}
1292
+ <!-- </ion-label>-->
1293
+ <!-- <ion-icon name="close" color="danger"></ion-icon>-->
1294
+ <!-- </ion-chip>-->
1295
+ }
1296
+ <!-- </ion-toolbar>-->
1297
+ }
1298
+ `, isInline: true, styles: [":host ion-label{font-size:var(--small-font-size)}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }] });
1299
+ }
1300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FiltersConfigComponent, decorators: [{
1301
+ type: Component,
1302
+ args: [{ selector: 'smart-crud-filters-config', template: `
1303
+ @let query = this.query();
1304
+ @if (query && query?.length) {
1305
+ <!-- <ion-toolbar>-->
1306
+ @for (item of query; track item) {
1307
+ <!-- <ion-chip (click)="onRemoveQuery(item)" color="medium" outline="true">-->
1308
+ <!-- <ion-icon name="filter-circle-outline" color="primary"></ion-icon>-->
1309
+ <!-- <ion-label>-->
1310
+ {{ 'MODEL.' + item.key | translate }} {{ item.type }}
1311
+ {{ item.value | translate }}
1312
+ <!-- </ion-label>-->
1313
+ <!-- <ion-icon name="close" color="danger"></ion-icon>-->
1314
+ <!-- </ion-chip>-->
1315
+ }
1316
+ <!-- </ion-toolbar>-->
1317
+ }
1318
+ `, imports: [TranslatePipe], styles: [":host ion-label{font-size:var(--small-font-size)}\n"] }]
1319
+ }] });
1320
+
1321
+ /**
1322
+ * @deprecated - please, use IModelPossibilitiesProvider from @smartsoft001/angular
1323
+ */
1324
+ class ICrudModelPossibilitiesProvider {
1325
+ }
1326
+ /**
1327
+ * @deprecated - please, use MODEL_POSSIBILITIES_PROVIDER from @smartsoft001/angular
1328
+ */
1329
+ const CRUD_MODEL_POSSIBILITIES_PROVIDER = new InjectionToken('CRUD_MODEL_POSSIBILITIES_PROVIDER');
1330
+
1331
+ class FormOptionsPipe {
1332
+ modelPossibilitiesProvider = inject(CRUD_MODEL_POSSIBILITIES_PROVIDER);
1333
+ transform(item, mode, type, uniqueProvider, inputComponents) {
1334
+ if (!mode || !type)
1335
+ return null;
1336
+ let possibilities = {};
1337
+ if (type && this.modelPossibilitiesProvider) {
1338
+ possibilities = this.modelPossibilitiesProvider.get(type);
1339
+ }
1340
+ if (mode === 'create') {
1341
+ return {
1342
+ mode: 'create',
1343
+ possibilities,
1344
+ inputComponents,
1345
+ uniqueProvider,
1346
+ model: new type(),
1347
+ show: true,
1348
+ };
1349
+ }
1350
+ else {
1351
+ const model = new type();
1352
+ if (item) {
1353
+ Object.keys(item).forEach((key) => {
1354
+ model[key] = item[key];
1355
+ });
1356
+ }
1357
+ return {
1358
+ mode: mode,
1359
+ uniqueProvider,
1360
+ possibilities: possibilities,
1361
+ inputComponents,
1362
+ model: model,
1363
+ show: true,
1364
+ };
1365
+ }
1366
+ }
1367
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FormOptionsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1368
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: FormOptionsPipe, isStandalone: true, name: "smartFormOptions" });
1369
+ }
1370
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: FormOptionsPipe, decorators: [{
1371
+ type: Pipe,
1372
+ args: [{
1373
+ name: 'smartFormOptions',
1374
+ }]
1375
+ }] });
1376
+
1377
+ class CrudPipesModule {
1378
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudPipesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1379
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: CrudPipesModule, imports: [FormOptionsPipe], exports: [FormOptionsPipe] });
1380
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudPipesModule });
1381
+ }
1382
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudPipesModule, decorators: [{
1383
+ type: NgModule,
1384
+ args: [{
1385
+ exports: [FormOptionsPipe],
1386
+ imports: [FormOptionsPipe],
1387
+ }]
1388
+ }] });
1389
+
1390
+ class MultiselectComponent {
1391
+ facade = inject((CrudFacade));
1392
+ config = inject((CrudFullConfig));
1393
+ menuService = inject(MenuService);
1394
+ _list;
1395
+ _changes;
1396
+ item;
1397
+ valid;
1398
+ buttonOptions = {
1399
+ click: async () => {
1400
+ const result = this._list.map((item) => {
1401
+ return {
1402
+ ...this._changes,
1403
+ id: item.id,
1404
+ };
1405
+ });
1406
+ this.facade.updatePartialMany(result);
1407
+ await this.menuService.closeEnd();
1408
+ },
1409
+ confirm: true,
1410
+ };
1411
+ lock;
1412
+ showForm = false;
1413
+ list;
1414
+ constructor() {
1415
+ this.list = computed(() => {
1416
+ const list = this.facade.multiSelected() || [];
1417
+ this.lock = true;
1418
+ const model = new this.config.type();
1419
+ const fieldsWithOptions = getModelFieldsWithOptions(model).filter((f) => f.options.update?.multi);
1420
+ this.showForm = !!fieldsWithOptions.length;
1421
+ fieldsWithOptions.forEach(({ key }) => {
1422
+ const uniques = _.uniq(list.map((i) => i[key]));
1423
+ if (uniques.length === 1) {
1424
+ model[key] = uniques[0];
1425
+ }
1426
+ });
1427
+ this.item = model;
1428
+ return list;
1429
+ }, ...(ngDevMode ? [{ debugName: "list" }] : []));
1430
+ }
1431
+ async onClose() {
1432
+ await this.menuService.closeEnd();
1433
+ }
1434
+ onPartialChange(changes, list) {
1435
+ this.lock = false;
1436
+ this._list = list;
1437
+ this._changes = changes;
1438
+ }
1439
+ onValidChange(valid) {
1440
+ this.valid = valid;
1441
+ }
1442
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: MultiselectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1443
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: MultiselectComponent, isStandalone: true, selector: "smart-crud-multiselect", ngImport: i0, template: "@let list = this.list();\n@if (list) {\n <!-- <ion-header>-->\n <!-- <ion-toolbar>-->\n <!-- <ion-buttons slot=\"end\">-->\n <!-- <ion-button (click)=\"onClose()\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close\"> </ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-buttons>-->\n <!--<ion-title>-->{{ 'selected' | translate }}: {{ list?.length\n }}<!--</ion-title>-->\n <!-- </ion-toolbar>-->\n <!-- </ion-header>-->\n\n @if (config?.list?.components?.multi) {\n <div>\n <ng-template\n [ngComponentOutlet]=\"config?.list?.components?.multi\"\n [ndcDynamicInputs]=\"{ items: list }\"\n ></ng-template>\n </div>\n }\n\n @if (showForm && item) {\n <div>\n <smart-form\n [options]=\"item | smartFormOptions: 'multiUpdate' : config.type\"\n (valuePartialChange)=\"onPartialChange($event, list)\"\n (validChange)=\"onValidChange($event)\"\n ></smart-form>\n\n <smart-button\n style=\"float: right\"\n [disabled]=\"lock || !valid\"\n [options]=\"buttonOptions\"\n >\n {{ 'change' | translate }}\n </smart-button>\n </div>\n }\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: DynamicIoDirective, selector: "[ndcDynamicInputs],[ndcDynamicOutputs]", inputs: ["ndcDynamicInputs", "ndcDynamicOutputs"], exportAs: ["ndcDynamicIo"] }, { kind: "component", type: FormComponent, selector: "smart-form", inputs: ["options"], outputs: ["invokeSubmit", "valueChange", "valuePartialChange", "validChange"] }, { kind: "component", type: ButtonComponent, selector: "smart-button", inputs: ["options", "disabled"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FormOptionsPipe, name: "smartFormOptions" }] });
1444
+ }
1445
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: MultiselectComponent, decorators: [{
1446
+ type: Component,
1447
+ args: [{ selector: 'smart-crud-multiselect', imports: [
1448
+ TranslatePipe,
1449
+ NgComponentOutlet,
1450
+ DynamicIoDirective,
1451
+ FormOptionsPipe,
1452
+ FormComponent,
1453
+ ButtonComponent,
1454
+ ], template: "@let list = this.list();\n@if (list) {\n <!-- <ion-header>-->\n <!-- <ion-toolbar>-->\n <!-- <ion-buttons slot=\"end\">-->\n <!-- <ion-button (click)=\"onClose()\">-->\n <!-- <ion-icon slot=\"icon-only\" name=\"close\"> </ion-icon>-->\n <!-- </ion-button>-->\n <!-- </ion-buttons>-->\n <!--<ion-title>-->{{ 'selected' | translate }}: {{ list?.length\n }}<!--</ion-title>-->\n <!-- </ion-toolbar>-->\n <!-- </ion-header>-->\n\n @if (config?.list?.components?.multi) {\n <div>\n <ng-template\n [ngComponentOutlet]=\"config?.list?.components?.multi\"\n [ndcDynamicInputs]=\"{ items: list }\"\n ></ng-template>\n </div>\n }\n\n @if (showForm && item) {\n <div>\n <smart-form\n [options]=\"item | smartFormOptions: 'multiUpdate' : config.type\"\n (valuePartialChange)=\"onPartialChange($event, list)\"\n (validChange)=\"onValidChange($event)\"\n ></smart-form>\n\n <smart-button\n style=\"float: right\"\n [disabled]=\"lock || !valid\"\n [options]=\"buttonOptions\"\n >\n {{ 'change' | translate }}\n </smart-button>\n </div>\n }\n}\n" }]
1455
+ }], ctorParameters: () => [] });
1456
+
1457
+ class CrudListGroupService {
1458
+ facade = inject((CrudFacade));
1459
+ _destroyed = [];
1460
+ change(val, item, force = false) {
1461
+ if (val || force) {
1462
+ item.changed = true;
1463
+ const filter = this.facade.filter();
1464
+ let current = filter?.query?.find((q) => q.key === item.key && q.type === '=');
1465
+ if (!current) {
1466
+ current = {
1467
+ key: item.key,
1468
+ type: '=',
1469
+ value: null,
1470
+ };
1471
+ if (filter?.query) {
1472
+ filter.query.push(current);
1473
+ }
1474
+ }
1475
+ current.value = item.value;
1476
+ current.hidden = true;
1477
+ this.facade.read({
1478
+ ...this.facade.filter(),
1479
+ offset: 0,
1480
+ });
1481
+ }
1482
+ }
1483
+ destroy(groups) {
1484
+ this._destroyed = [
1485
+ ...(this._destroyed ? this._destroyed : []),
1486
+ ...groups.filter((g) => g.changed),
1487
+ ];
1488
+ this.refresh();
1489
+ }
1490
+ refresh() {
1491
+ const list = this._destroyed;
1492
+ this._destroyed = [];
1493
+ const filter = this.facade.filter();
1494
+ const newQuery = filter?.query?.filter((q) => !list.some((i) => q.key === i.key)) || [];
1495
+ this.facade.read({
1496
+ ...this.facade.filter(),
1497
+ query: newQuery,
1498
+ });
1499
+ }
1500
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListGroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1501
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListGroupService });
1502
+ }
1503
+ __decorate([
1504
+ debounce(250),
1505
+ __metadata("design:type", Function),
1506
+ __metadata("design:paramtypes", []),
1507
+ __metadata("design:returntype", void 0)
1508
+ ], CrudListGroupService.prototype, "refresh", null);
1509
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListGroupService, decorators: [{
1510
+ type: Injectable
1511
+ }], propDecorators: { refresh: [] } });
1512
+
1513
+ class GroupComponent extends BaseComponent$1 {
1514
+ styleService = inject(StyleService);
1515
+ elementRef = inject(ElementRef);
1516
+ groupService = inject((CrudListGroupService));
1517
+ groups = input(...(ngDevMode ? [undefined, { debugName: "groups" }] : []));
1518
+ listOptions = input(...(ngDevMode ? [undefined, { debugName: "listOptions" }] : []));
1519
+ change(val, item, force = false) {
1520
+ const groups = this.groups();
1521
+ if (groups) {
1522
+ groups
1523
+ .filter((i) => i.value !== item.value || i.key !== item.key)
1524
+ .forEach((i) => {
1525
+ i.show = false;
1526
+ });
1527
+ }
1528
+ this.groupService.change(val, item, force);
1529
+ item.show = val;
1530
+ }
1531
+ ngOnInit() {
1532
+ this.styleService.init(this.elementRef);
1533
+ }
1534
+ ngOnDestroy() {
1535
+ const groups = this.groups();
1536
+ if (groups) {
1537
+ this.groupService.destroy(groups);
1538
+ }
1539
+ super.ngOnDestroy();
1540
+ }
1541
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: GroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1542
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: GroupComponent, isStandalone: true, selector: "smart-crud-group", inputs: { groups: { classPropertyName: "groups", publicName: "groups", isSignal: true, isRequired: false, transformFunction: null }, listOptions: { classPropertyName: "listOptions", publicName: "listOptions", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
1543
+ @for (item of groups(); track item.key) {
1544
+ <smart-accordion
1545
+ [show]="item.show || false"
1546
+ (showChange)="change($event, item)"
1547
+ >
1548
+ <smart-accordion-header [ngClass]="{ 'font-bold': item.show }"
1549
+ >{{ item.text | translate }}
1550
+ </smart-accordion-header>
1551
+ <smart-accordion-body>
1552
+ @if (item.show && !item.children && listOptions()) {
1553
+ <smart-list [options]="listOptions()!"></smart-list>
1554
+ }
1555
+ @if (item.children) {
1556
+ <div style="margin-left: 50px">
1557
+ <smart-crud-group
1558
+ [groups]="item.children"
1559
+ [listOptions]="listOptions()"
1560
+ ></smart-crud-group>
1561
+ </div>
1562
+ }
1563
+ </smart-accordion-body>
1564
+ </smart-accordion>
1565
+ }
1566
+ <br /><br /><br />
1567
+ `, isInline: true, dependencies: [{ kind: "component", type: GroupComponent, selector: "smart-crud-group", inputs: ["groups", "listOptions"] }, { kind: "component", type: AccordionComponent, selector: "smart-accordion", inputs: ["show"], outputs: ["showChange"] }, { kind: "component", type: AccordionHeaderComponent, selector: "smart-accordion-header" }, { kind: "component", type: AccordionBodyComponent, selector: "smart-accordion-body" }, { kind: "component", type: ListComponent$1, selector: "smart-list", inputs: ["options"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
1568
+ }
1569
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: GroupComponent, decorators: [{
1570
+ type: Component,
1571
+ args: [{
1572
+ selector: 'smart-crud-group',
1573
+ template: `
1574
+ @for (item of groups(); track item.key) {
1575
+ <smart-accordion
1576
+ [show]="item.show || false"
1577
+ (showChange)="change($event, item)"
1578
+ >
1579
+ <smart-accordion-header [ngClass]="{ 'font-bold': item.show }"
1580
+ >{{ item.text | translate }}
1581
+ </smart-accordion-header>
1582
+ <smart-accordion-body>
1583
+ @if (item.show && !item.children && listOptions()) {
1584
+ <smart-list [options]="listOptions()!"></smart-list>
1585
+ }
1586
+ @if (item.children) {
1587
+ <div style="margin-left: 50px">
1588
+ <smart-crud-group
1589
+ [groups]="item.children"
1590
+ [listOptions]="listOptions()"
1591
+ ></smart-crud-group>
1592
+ </div>
1593
+ }
1594
+ </smart-accordion-body>
1595
+ </smart-accordion>
1596
+ }
1597
+ <br /><br /><br />
1598
+ `,
1599
+ imports: [
1600
+ AccordionComponent,
1601
+ AccordionHeaderComponent,
1602
+ AccordionBodyComponent,
1603
+ ListComponent$1,
1604
+ NgClass,
1605
+ TranslatePipe,
1606
+ ],
1607
+ }]
1608
+ }] });
1609
+
1610
+ class CrudListPaginationFactory {
1611
+ facade = inject((CrudFacade));
1612
+ async create(options) {
1613
+ return {
1614
+ mode: options.mode,
1615
+ limit: options.limit,
1616
+ loadNextPage: () => {
1617
+ if (!options.provider.getLinks() || !options.provider.getLinks().next)
1618
+ return Promise.resolve(false);
1619
+ return new Promise((res) => {
1620
+ if (this.facade.loaded()) {
1621
+ setTimeout(() => {
1622
+ res(options.provider.getLinks() && options.provider.getLinks().next);
1623
+ });
1624
+ }
1625
+ const filter = options.provider.getFilter();
1626
+ this.facade.read({
1627
+ ...filter,
1628
+ offset: (filter.offset || 0) + (filter.limit || 0),
1629
+ });
1630
+ });
1631
+ },
1632
+ loadPrevPage: () => {
1633
+ if (!options.provider.getLinks() || !options.provider.getLinks().prev)
1634
+ return Promise.resolve(false);
1635
+ return new Promise((res) => {
1636
+ const loaded = this.facade.loaded();
1637
+ if (loaded) {
1638
+ setTimeout(() => {
1639
+ res(options.provider.getLinks() && options.provider.getLinks().prev);
1640
+ });
1641
+ }
1642
+ const filter = options.provider.getFilter();
1643
+ this.facade.read({
1644
+ ...filter,
1645
+ offset: (filter.offset || 0) - (filter.limit || 0),
1646
+ });
1647
+ });
1648
+ },
1649
+ page: computed(() => {
1650
+ const f = this.facade.filter();
1651
+ return f?.limit ? (f.offset || 0) / f.limit + 1 : 0;
1652
+ }),
1653
+ totalPages: computed(() => {
1654
+ const filter = this.facade.filter();
1655
+ const totalCount = this.facade.totalCount();
1656
+ return filter?.limit && totalCount
1657
+ ? Math.ceil(totalCount / filter.limit)
1658
+ : 0;
1659
+ }),
1660
+ };
1661
+ }
1662
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListPaginationFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1663
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListPaginationFactory });
1664
+ }
1665
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListPaginationFactory, decorators: [{
1666
+ type: Injectable
1667
+ }] });
1668
+
1669
+ const COMPONENTS = [
1670
+ ExportComponent,
1671
+ FilterComponent,
1672
+ FilterTextComponent,
1673
+ FiltersConfigComponent,
1674
+ FilterDateComponent,
1675
+ FilterDateWithEditComponent,
1676
+ FilterDateTimeComponent,
1677
+ FilterRadioComponent,
1678
+ FiltersComponent,
1679
+ FilterFlagComponent,
1680
+ FilterCheckComponent,
1681
+ FilterIntComponent,
1682
+ MultiselectComponent,
1683
+ GroupComponent,
1684
+ ];
1685
+ class CrudComponentsModule {
1686
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1687
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: CrudComponentsModule, imports: [ExportComponent,
1688
+ FilterComponent,
1689
+ FilterTextComponent,
1690
+ FiltersConfigComponent,
1691
+ FilterDateComponent,
1692
+ FilterDateWithEditComponent,
1693
+ FilterDateTimeComponent,
1694
+ FilterRadioComponent,
1695
+ FiltersComponent,
1696
+ FilterFlagComponent,
1697
+ FilterCheckComponent,
1698
+ FilterIntComponent,
1699
+ MultiselectComponent,
1700
+ GroupComponent, SharedModule,
1701
+ CrudPipesModule,
1702
+ FormsModule,
1703
+ CommonModule,
1704
+ DynamicIoModule], exports: [CrudPipesModule, ExportComponent,
1705
+ FilterComponent,
1706
+ FilterTextComponent,
1707
+ FiltersConfigComponent,
1708
+ FilterDateComponent,
1709
+ FilterDateWithEditComponent,
1710
+ FilterDateTimeComponent,
1711
+ FilterRadioComponent,
1712
+ FiltersComponent,
1713
+ FilterFlagComponent,
1714
+ FilterCheckComponent,
1715
+ FilterIntComponent,
1716
+ MultiselectComponent,
1717
+ GroupComponent] });
1718
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudComponentsModule, providers: [CrudService, CrudFacade, CrudListPaginationFactory], imports: [ExportComponent,
1719
+ FilterComponent,
1720
+ FilterTextComponent,
1721
+ FilterDateComponent,
1722
+ FilterDateWithEditComponent,
1723
+ FilterDateTimeComponent,
1724
+ FilterRadioComponent,
1725
+ FiltersComponent,
1726
+ FilterFlagComponent,
1727
+ FilterIntComponent,
1728
+ MultiselectComponent,
1729
+ GroupComponent, SharedModule,
1730
+ CrudPipesModule,
1731
+ FormsModule,
1732
+ CommonModule,
1733
+ DynamicIoModule, CrudPipesModule] });
1734
+ }
1735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudComponentsModule, decorators: [{
1736
+ type: NgModule,
1737
+ args: [{
1738
+ imports: [
1739
+ ...COMPONENTS,
1740
+ SharedModule,
1741
+ CrudPipesModule,
1742
+ FormsModule,
1743
+ CommonModule,
1744
+ DynamicIoModule,
1745
+ ],
1746
+ exports: [CrudPipesModule, ...COMPONENTS],
1747
+ providers: [CrudService, CrudFacade, CrudListPaginationFactory],
1748
+ }]
1749
+ }] });
1750
+
1751
+ class CrudItemPageBaseComponent extends BaseComponent$1 {
1752
+ config = inject((CrudFullConfig));
1753
+ facade = inject((CrudFacade));
1754
+ static smartType = 'crud-item-page';
1755
+ selected;
1756
+ contentTpl = viewChild('contentTpl', ...(ngDevMode ? [{ debugName: "contentTpl" }] : []));
1757
+ formComponents = viewChildren(FormComponent, ...(ngDevMode ? [{ debugName: "formComponents" }] : []));
1758
+ detailsOptions = input(...(ngDevMode ? [undefined, { debugName: "detailsOptions" }] : []));
1759
+ mode = input(...(ngDevMode ? [undefined, { debugName: "mode" }] : []));
1760
+ uniqueProvider = input(...(ngDevMode ? [undefined, { debugName: "uniqueProvider" }] : []));
1761
+ onPartialChange = output();
1762
+ onChange = output();
1763
+ onValidChange = output();
1764
+ constructor() {
1765
+ super();
1766
+ this.selected = this.facade.selected;
1767
+ }
1768
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudItemPageBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1769
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.1.0", type: CrudItemPageBaseComponent, isStandalone: true, inputs: { detailsOptions: { classPropertyName: "detailsOptions", publicName: "detailsOptions", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, uniqueProvider: { classPropertyName: "uniqueProvider", publicName: "uniqueProvider", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onPartialChange: "onPartialChange", onChange: "onChange", onValidChange: "onValidChange" }, viewQueries: [{ propertyName: "contentTpl", first: true, predicate: ["contentTpl"], descendants: true, isSignal: true }, { propertyName: "formComponents", predicate: FormComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0 });
1770
+ }
1771
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudItemPageBaseComponent, decorators: [{
1772
+ type: Directive
1773
+ }], ctorParameters: () => [] });
1774
+
1775
+ class ItemStandardComponent extends CrudItemPageBaseComponent {
1776
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ItemStandardComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1777
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: ItemStandardComponent, isStandalone: true, selector: "smart-crud-item-standard-page", usesInheritance: true, ngImport: i0, template: `
1778
+ @if (mode() === 'details') {
1779
+ @if (detailsOptions()) {
1780
+ <smart-details [options]="detailsOptions()"></smart-details>
1781
+ }
1782
+ } @else {
1783
+ <ng-container [ngTemplateOutlet]="editTpl"></ng-container>
1784
+ }
1785
+
1786
+ <ng-template #editTpl>
1787
+ <smart-form
1788
+ [options]="
1789
+ selected()
1790
+ | smartFormOptions
1791
+ : mode()
1792
+ : config?.type
1793
+ : uniqueProvider()
1794
+ : config.inputComponents
1795
+ "
1796
+ (valuePartialChange)="onPartialChange.emit($event)"
1797
+ (valueChange)="onChange.emit($event)"
1798
+ (validChange)="onValidChange.emit($event)"
1799
+ ></smart-form>
1800
+ </ng-template>
1801
+
1802
+ <br /><br />
1803
+ `, isInline: true, styles: [""], dependencies: [{ kind: "component", type: DetailsComponent, selector: "smart-details", inputs: ["options"] }, { kind: "component", type: FormComponent, selector: "smart-form", inputs: ["options"], outputs: ["invokeSubmit", "valueChange", "valuePartialChange", "validChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: FormOptionsPipe, name: "smartFormOptions" }] });
1804
+ }
1805
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ItemStandardComponent, decorators: [{
1806
+ type: Component,
1807
+ args: [{ selector: 'smart-crud-item-standard-page', template: `
1808
+ @if (mode() === 'details') {
1809
+ @if (detailsOptions()) {
1810
+ <smart-details [options]="detailsOptions()"></smart-details>
1811
+ }
1812
+ } @else {
1813
+ <ng-container [ngTemplateOutlet]="editTpl"></ng-container>
1814
+ }
1815
+
1816
+ <ng-template #editTpl>
1817
+ <smart-form
1818
+ [options]="
1819
+ selected()
1820
+ | smartFormOptions
1821
+ : mode()
1822
+ : config?.type
1823
+ : uniqueProvider()
1824
+ : config.inputComponents
1825
+ "
1826
+ (valuePartialChange)="onPartialChange.emit($event)"
1827
+ (valueChange)="onChange.emit($event)"
1828
+ (validChange)="onValidChange.emit($event)"
1829
+ ></smart-form>
1830
+ </ng-template>
1831
+
1832
+ <br /><br />
1833
+ `, imports: [
1834
+ DetailsComponent,
1835
+ FormComponent,
1836
+ FormOptionsPipe,
1837
+ NgTemplateOutlet,
1838
+ FormComponent,
1839
+ ] }]
1840
+ }] });
1841
+
1842
+ class PageService {
1843
+ authService = inject(AuthService);
1844
+ config = inject((CrudFullConfig));
1845
+ checkPermissions() {
1846
+ const val = this.config;
1847
+ const modelOptions = getModelOptions(val.type);
1848
+ if (val.add &&
1849
+ modelOptions.create &&
1850
+ modelOptions.create.permissions &&
1851
+ !this.authService.expectPermissions(modelOptions.create.permissions)) {
1852
+ val.add = false;
1853
+ }
1854
+ if (val.edit &&
1855
+ modelOptions.update &&
1856
+ modelOptions.update.permissions &&
1857
+ !this.authService.expectPermissions(modelOptions.update.permissions)) {
1858
+ val.edit = false;
1859
+ }
1860
+ if (val.remove &&
1861
+ modelOptions.remove &&
1862
+ modelOptions.remove.permissions &&
1863
+ !this.authService.expectPermissions(modelOptions.remove.permissions)) {
1864
+ val.remove = false;
1865
+ }
1866
+ }
1867
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: PageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1868
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: PageService });
1869
+ }
1870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: PageService, decorators: [{
1871
+ type: Injectable
1872
+ }] });
1873
+
1874
+ class ItemComponent extends CreateDynamicComponent('crud-item-page') {
1875
+ router = inject(Router);
1876
+ activeRoute = inject(ActivatedRoute);
1877
+ facade = inject((CrudFacade));
1878
+ service = inject((CrudService));
1879
+ dynamicComponentLoader = inject((DynamicComponentLoader));
1880
+ translateService = inject(TranslateService);
1881
+ config = inject((CrudFullConfig));
1882
+ location = inject(Location);
1883
+ cd = inject(ChangeDetectorRef);
1884
+ styleService = inject(StyleService);
1885
+ elementRef = inject(ElementRef);
1886
+ toastService = inject(ToastService);
1887
+ pageService = inject((PageService));
1888
+ detailsService = inject(DetailsService);
1889
+ _mode;
1890
+ pageOptions = signal({
1891
+ title: '',
1892
+ showBackButton: true,
1893
+ hideMenuButton: true,
1894
+ }, ...(ngDevMode ? [{ debugName: "pageOptions" }] : []));
1895
+ detailsOptions;
1896
+ id;
1897
+ formValue;
1898
+ formValid = false;
1899
+ item;
1900
+ formPartialValue;
1901
+ uniqueProvider;
1902
+ set mode(val) {
1903
+ this._mode = signal(val, ...(ngDevMode ? [{ debugName: "_mode" }] : []));
1904
+ this.refreshDynamicInstance();
1905
+ }
1906
+ get mode() {
1907
+ return this._mode();
1908
+ }
1909
+ selected;
1910
+ standardComponents = viewChildren(ItemStandardComponent, ...(ngDevMode ? [{ debugName: "standardComponents" }] : []));
1911
+ // @ViewChild(IonContent, { static: true }) content: IonContent; //TODO: rewrite when rewriting ionic
1912
+ contentTpl = viewChild('contentTpl', ...(ngDevMode ? [{ debugName: "contentTpl" }] : []));
1913
+ topTpl = viewChild('topTpl', ...(ngDevMode ? [{ debugName: "topTpl" }] : []));
1914
+ bottomTpl = viewChild('bottomTpl', ...(ngDevMode ? [{ debugName: "bottomTpl" }] : []));
1915
+ dynamicContents = viewChildren(DynamicContentDirective, ...(ngDevMode ? [{ debugName: "dynamicContents" }] : []));
1916
+ subscription = new Subscription();
1917
+ constructor() {
1918
+ super();
1919
+ this.selected = this.facade.selected;
1920
+ }
1921
+ refreshProperties() {
1922
+ this.baseComponentRef.setInput('detailsOptions', this.detailsOptions());
1923
+ this.baseComponentRef.setInput('mode', this.mode);
1924
+ this.baseComponentRef.setInput('uniqueProvider', this.uniqueProvider());
1925
+ this.subscription.add(this.baseInstance.onPartialChange.subscribe((val) => this.onPartialChange(val)));
1926
+ this.subscription.add(this.baseInstance.onChange.subscribe((val) => this.onChange(val)));
1927
+ this.subscription.add(this.baseInstance.onValidChange.subscribe((val) => this.onValidChange(val)));
1928
+ }
1929
+ async ngOnInit() {
1930
+ this.detailsService.init();
1931
+ this.styleService.init(this.elementRef);
1932
+ this.pageService.checkPermissions();
1933
+ if (this.router.routerState.snapshot.url.split('?')[0].endsWith('/add')) {
1934
+ this.mode = 'create';
1935
+ await this.generateComponents('add');
1936
+ }
1937
+ else {
1938
+ this.mode = this.config.details ? 'details' : 'update';
1939
+ if (this.mode === 'update') {
1940
+ await this.generateComponents('edit');
1941
+ }
1942
+ this.activeRoute.params
1943
+ .pipe(this.takeUntilDestroy)
1944
+ .subscribe(({ id }) => {
1945
+ this.facade.select(id);
1946
+ this.id = id;
1947
+ });
1948
+ this.activeRoute.queryParams
1949
+ .pipe(this.takeUntilDestroy)
1950
+ .subscribe(({ edit }) => {
1951
+ if (edit) {
1952
+ this.mode = 'update';
1953
+ this.generateComponents('edit');
1954
+ }
1955
+ });
1956
+ }
1957
+ this.uniqueProvider.set(async (values) => {
1958
+ const filter = {
1959
+ query: [],
1960
+ };
1961
+ Object.keys(values).forEach((key) => {
1962
+ filter.query.push({
1963
+ key: key,
1964
+ value: values[key],
1965
+ type: '=',
1966
+ });
1967
+ });
1968
+ if (this.id) {
1969
+ filter.query.push({
1970
+ key: 'id',
1971
+ value: this.id,
1972
+ type: '!=',
1973
+ });
1974
+ }
1975
+ const { totalCount } = await this.service.getList(filter);
1976
+ return !totalCount;
1977
+ });
1978
+ if (this.config.details) {
1979
+ const compiledComponents = await this.dynamicComponentLoader.getComponentsWithFactories({
1980
+ components: [
1981
+ ...(this.config.details &&
1982
+ this.config.details['components'] &&
1983
+ this.config.details['components'].top
1984
+ ? [this.config.details['components'].top]
1985
+ : []),
1986
+ ...(this.config.details &&
1987
+ this.config.details['components'] &&
1988
+ this.config.details['components'].bottom
1989
+ ? [this.config.details['components'].bottom]
1990
+ : []),
1991
+ ],
1992
+ });
1993
+ this.detailsOptions.set({
1994
+ type: this.config.type,
1995
+ item: this.facade.selected,
1996
+ cellPipe: this.config.details
1997
+ ? this.config.details.cellPipe
1998
+ : undefined,
1999
+ componentFactories: {
2000
+ top: this.config.details &&
2001
+ this.config.details['components'] &&
2002
+ this.config.details['components'].top
2003
+ ? compiledComponents.find((cc) => cc.component ===
2004
+ this.config.details['components'].top)?.factory
2005
+ : undefined,
2006
+ bottom: this.config.details &&
2007
+ this.config.details['components'] &&
2008
+ this.config.details['components'].bottom
2009
+ ? compiledComponents.find((cc) => cc.component ===
2010
+ this.config.details['components'].bottom)?.factory
2011
+ : undefined,
2012
+ },
2013
+ });
2014
+ }
2015
+ this.initPageOptions();
2016
+ effect(() => {
2017
+ this.item = this.facade.selected();
2018
+ this.initPageOptions();
2019
+ this.cd.detectChanges();
2020
+ });
2021
+ this.refreshDynamicInstance();
2022
+ }
2023
+ ngOnDestroy() {
2024
+ super.ngOnDestroy();
2025
+ this.subscription.unsubscribe();
2026
+ }
2027
+ async generateComponents(mode) {
2028
+ const compiledComponents = await this.dynamicComponentLoader.getComponentsWithFactories({
2029
+ components: [
2030
+ ...(this.config[mode] &&
2031
+ this.config[mode]['components'] &&
2032
+ this.config[mode]['components'].top
2033
+ ? [this.config[mode]['components'].top]
2034
+ : []),
2035
+ ...(this.config[mode] &&
2036
+ this.config[mode]['components'] &&
2037
+ this.config[mode]['components'].bottom
2038
+ ? [this.config[mode]['components'].bottom]
2039
+ : []),
2040
+ ],
2041
+ });
2042
+ const topComponentFactory = compiledComponents.find((cc) => cc.component === this.config[mode]['components']?.top)?.factory;
2043
+ const bottomComponentFactory = compiledComponents.find((cc) => cc.component === this.config[mode]['components']?.bottom)?.factory;
2044
+ if (!this.topTpl()?.get(0) && topComponentFactory) {
2045
+ this.topTpl()?.createComponent(topComponentFactory);
2046
+ }
2047
+ if (!this.bottomTpl()?.get(0) && bottomComponentFactory) {
2048
+ this.bottomTpl()?.createComponent(bottomComponentFactory);
2049
+ }
2050
+ }
2051
+ onPartialChange(val) {
2052
+ this.formPartialValue = val;
2053
+ }
2054
+ onChange(val) {
2055
+ this.formValue = val;
2056
+ }
2057
+ onValidChange(val) {
2058
+ this.formValid = val;
2059
+ }
2060
+ initPageOptions() {
2061
+ this.pageOptions.set({
2062
+ ...this.pageOptions(),
2063
+ title: this.getTitle() || '',
2064
+ endButtons: this.getButtons(),
2065
+ });
2066
+ }
2067
+ getButtons() {
2068
+ const options = getModelOptions(this.config.type);
2069
+ switch (this.mode) {
2070
+ case 'create':
2071
+ return [
2072
+ {
2073
+ icon: 'add',
2074
+ text: 'add',
2075
+ handler: () => {
2076
+ if (this.checkFirstInvalid()) {
2077
+ return;
2078
+ }
2079
+ this.facade.create(this.formValue);
2080
+ this.location.back();
2081
+ },
2082
+ },
2083
+ ];
2084
+ case 'update':
2085
+ return [
2086
+ ...(this.config.details
2087
+ ? [
2088
+ {
2089
+ icon: 'close',
2090
+ text: 'cancel',
2091
+ handler: () => {
2092
+ this.mode = 'details';
2093
+ this.initPageOptions();
2094
+ this.topTpl()?.clear();
2095
+ this.bottomTpl()?.clear();
2096
+ },
2097
+ disabled$: new BehaviorSubject(false),
2098
+ },
2099
+ ]
2100
+ : []),
2101
+ {
2102
+ icon: 'save',
2103
+ text: 'save',
2104
+ handler: () => {
2105
+ if (this.checkFirstInvalid()) {
2106
+ return;
2107
+ }
2108
+ this.formPartialValue.id = this.id;
2109
+ this.facade.updatePartial(this.formPartialValue);
2110
+ if (this.config.details) {
2111
+ this.mode = 'details';
2112
+ this.initPageOptions();
2113
+ }
2114
+ else {
2115
+ this.location.back();
2116
+ }
2117
+ },
2118
+ },
2119
+ ];
2120
+ case 'details':
2121
+ return this.config.edit &&
2122
+ (!options?.update?.enabled ||
2123
+ SpecificationService.valid(this.item, options?.update?.enabled))
2124
+ ? [
2125
+ {
2126
+ icon: 'create',
2127
+ text: 'edit',
2128
+ handler: () => {
2129
+ this.mode = 'update';
2130
+ this.generateComponents('edit');
2131
+ this.initPageOptions();
2132
+ },
2133
+ disabled$: new BehaviorSubject(false),
2134
+ },
2135
+ ]
2136
+ : [];
2137
+ default:
2138
+ return undefined;
2139
+ }
2140
+ }
2141
+ getTitle() {
2142
+ const options = getModelOptions(this.config.type);
2143
+ const prefix = options.titleKey && this.item
2144
+ ? this.removeParagraph(this.item[options.titleKey]) + ' - '
2145
+ : '';
2146
+ switch (this.mode) {
2147
+ case 'create':
2148
+ return 'add';
2149
+ case 'update':
2150
+ return prefix + this.translateService.instant('change');
2151
+ case 'details':
2152
+ return prefix + this.translateService.instant('details');
2153
+ default:
2154
+ return undefined;
2155
+ }
2156
+ }
2157
+ removeParagraph(val) {
2158
+ if (!val || val.indexOf('<p>') !== 0)
2159
+ return val;
2160
+ const div = document.createElement('div');
2161
+ div.innerHTML = val;
2162
+ const item = div.querySelectorAll('p').item(0);
2163
+ return item.innerHTML;
2164
+ }
2165
+ checkFirstInvalid() {
2166
+ this.cd.detectChanges();
2167
+ const form = this.template() === 'default'
2168
+ ? this.standardComponents()?.[0]?.formComponents?.[0]?.form
2169
+ : this.baseInstance.formComponents()[0].form;
2170
+ this.cd.detectChanges();
2171
+ if (form.valid)
2172
+ return false;
2173
+ const invalidFields = [];
2174
+ this.getInvalidFields(form, invalidFields, '');
2175
+ this.toastService.info({
2176
+ title: this.translateService.instant('INPUT.ERRORS.requires'),
2177
+ message: invalidFields.slice(0, 3).join('<br/>'),
2178
+ });
2179
+ return true;
2180
+ }
2181
+ getInvalidFields(control, invalidFields, baseField, key = null) {
2182
+ if (control.valid)
2183
+ return;
2184
+ const field = key
2185
+ ? baseField + ' > ' + this.translateService.instant('MODEL.' + key)
2186
+ : baseField;
2187
+ if (control.errors?.['customMessage']) {
2188
+ invalidFields.push(field + ` (${control.errors['customMessage']})`);
2189
+ return;
2190
+ }
2191
+ if (control instanceof UntypedFormControl) {
2192
+ invalidFields.push(field);
2193
+ }
2194
+ if (control instanceof UntypedFormGroup) {
2195
+ Object.keys(control.controls).forEach((groupKey) => {
2196
+ this.getInvalidFields(control.controls[groupKey], invalidFields, field, groupKey);
2197
+ });
2198
+ }
2199
+ if (control instanceof UntypedFormArray) {
2200
+ control.controls.forEach((c, index) => {
2201
+ this.getInvalidFields(c, invalidFields, field + `(${index + 1})`);
2202
+ });
2203
+ }
2204
+ }
2205
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2206
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: ItemComponent, isStandalone: true, selector: "smart-crud-item-page", viewQueries: [{ propertyName: "standardComponents", predicate: ItemStandardComponent, descendants: true, isSignal: true }, { propertyName: "contentTpl", first: true, predicate: ["contentTpl"], descendants: true, isSignal: true }, { propertyName: "topTpl", first: true, predicate: ["topTpl"], descendants: true, isSignal: true }, { propertyName: "bottomTpl", first: true, predicate: ["bottomTpl"], descendants: true, isSignal: true }, { propertyName: "dynamicContents", predicate: DynamicContentDirective, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2207
+ <smart-page [options]="pageOptions()">
2208
+ <div #topTpl class="text-xl py-2.5 separator"></div>
2209
+ @if (template() === 'default') {
2210
+ <smart-crud-item-standard-page
2211
+ [detailsOptions]="detailsOptions()"
2212
+ [mode]="mode"
2213
+ [uniqueProvider]="uniqueProvider()"
2214
+ (onPartialChange)="onPartialChange($event)"
2215
+ (onChange)="onChange($event)"
2216
+ (onValidChange)="onValidChange($event)"
2217
+ >
2218
+ <ng-container [ngTemplateOutlet]="contentTpl"></ng-container>
2219
+ </smart-crud-item-standard-page>
2220
+ }
2221
+ <ng-template #contentTpl>
2222
+ <ng-content></ng-content>
2223
+ </ng-template>
2224
+ <div class="dynamic-content"></div>
2225
+ <div #bottomTpl class="text-xl py-2.5 separator"></div>
2226
+ </smart-page>
2227
+ `, isInline: true, dependencies: [{ kind: "component", type: PageComponent, selector: "smart-page", inputs: ["options"] }, { kind: "component", type: ItemStandardComponent, selector: "smart-crud-item-standard-page" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
2228
+ }
2229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ItemComponent, decorators: [{
2230
+ type: Component,
2231
+ args: [{
2232
+ selector: 'smart-crud-item-page',
2233
+ imports: [PageComponent, ItemStandardComponent, NgTemplateOutlet],
2234
+ template: `
2235
+ <smart-page [options]="pageOptions()">
2236
+ <div #topTpl class="text-xl py-2.5 separator"></div>
2237
+ @if (template() === 'default') {
2238
+ <smart-crud-item-standard-page
2239
+ [detailsOptions]="detailsOptions()"
2240
+ [mode]="mode"
2241
+ [uniqueProvider]="uniqueProvider()"
2242
+ (onPartialChange)="onPartialChange($event)"
2243
+ (onChange)="onChange($event)"
2244
+ (onValidChange)="onValidChange($event)"
2245
+ >
2246
+ <ng-container [ngTemplateOutlet]="contentTpl"></ng-container>
2247
+ </smart-crud-item-standard-page>
2248
+ }
2249
+ <ng-template #contentTpl>
2250
+ <ng-content></ng-content>
2251
+ </ng-template>
2252
+ <div class="dynamic-content"></div>
2253
+ <div #bottomTpl class="text-xl py-2.5 separator"></div>
2254
+ </smart-page>
2255
+ `,
2256
+ }]
2257
+ }], ctorParameters: () => [] });
2258
+
2259
+ class CrudListPageBaseComponent extends BaseComponent$1 {
2260
+ config = inject((CrudFullConfig));
2261
+ static smartType = 'crud-list-page';
2262
+ contentTpl = viewChild('contentTpl', ...(ngDevMode ? [{ debugName: "contentTpl" }] : []));
2263
+ listOptions = input(...(ngDevMode ? [undefined, { debugName: "listOptions" }] : []));
2264
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListPageBaseComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
2265
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "20.1.0", type: CrudListPageBaseComponent, isStandalone: true, inputs: { listOptions: { classPropertyName: "listOptions", publicName: "listOptions", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "contentTpl", first: true, predicate: ["contentTpl"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0 });
2266
+ }
2267
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudListPageBaseComponent, decorators: [{
2268
+ type: Directive
2269
+ }] });
2270
+
2271
+ class ListStandardComponent extends CrudListPageBaseComponent {
2272
+ facade = inject((CrudFacade));
2273
+ config = inject((CrudFullConfig));
2274
+ isSearch = computed(() => !!this.facade.filter()?.searchText, ...(ngDevMode ? [{ debugName: "isSearch" }] : []));
2275
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ListStandardComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2276
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: ListStandardComponent, isStandalone: true, selector: "smart-crud-list-standard-page", providers: [CrudListGroupService], usesInheritance: true, ngImport: i0, template: `
2277
+ <smart-crud-filters-config></smart-crud-filters-config>
2278
+ @let groups = config.list?.groups;
2279
+ @if (listOptions()) {
2280
+ <smart-list
2281
+ [hidden]="groups && !isSearch()"
2282
+ [options]="listOptions()!"
2283
+ ></smart-list>
2284
+ }
2285
+ @if (groups && !isSearch()) {
2286
+ <smart-crud-group
2287
+ [groups]="groups"
2288
+ [listOptions]="listOptions()"
2289
+ ></smart-crud-group>
2290
+ }
2291
+ `, isInline: true, dependencies: [{ kind: "component", type: FiltersConfigComponent, selector: "smart-crud-filters-config" }, { kind: "component", type: ListComponent$1, selector: "smart-list", inputs: ["options"] }, { kind: "component", type: GroupComponent, selector: "smart-crud-group", inputs: ["groups", "listOptions"] }] });
2292
+ }
2293
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ListStandardComponent, decorators: [{
2294
+ type: Component,
2295
+ args: [{
2296
+ selector: 'smart-crud-list-standard-page',
2297
+ template: `
2298
+ <smart-crud-filters-config></smart-crud-filters-config>
2299
+ @let groups = config.list?.groups;
2300
+ @if (listOptions()) {
2301
+ <smart-list
2302
+ [hidden]="groups && !isSearch()"
2303
+ [options]="listOptions()!"
2304
+ ></smart-list>
2305
+ }
2306
+ @if (groups && !isSearch()) {
2307
+ <smart-crud-group
2308
+ [groups]="groups"
2309
+ [listOptions]="listOptions()"
2310
+ ></smart-crud-group>
2311
+ }
2312
+ `,
2313
+ imports: [FiltersConfigComponent, ListComponent$1, GroupComponent],
2314
+ providers: [CrudListGroupService],
2315
+ }]
2316
+ }] });
2317
+
2318
+ class CrudSearchService {
2319
+ _filterSource = new BehaviorSubject({});
2320
+ _enabledSource = new BehaviorSubject(false);
2321
+ get filter() {
2322
+ if (!this._enabledSource.value)
2323
+ return {};
2324
+ return this._filterSource.value || {};
2325
+ }
2326
+ get enabled() {
2327
+ return this._enabledSource.value;
2328
+ }
2329
+ enabled$ = this._enabledSource.asObservable();
2330
+ filter$ = combineLatest([
2331
+ this._filterSource.asObservable(),
2332
+ this.enabled$,
2333
+ ]).pipe(map(([filter, enabled]) => {
2334
+ if (!enabled)
2335
+ return {};
2336
+ return filter;
2337
+ }));
2338
+ setFilter(val) {
2339
+ this._filterSource.next(val);
2340
+ }
2341
+ setEnabled(val) {
2342
+ this._enabledSource.next(val);
2343
+ }
2344
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudSearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2345
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudSearchService, providedIn: 'root' });
2346
+ }
2347
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudSearchService, decorators: [{
2348
+ type: Injectable,
2349
+ args: [{
2350
+ providedIn: 'root',
2351
+ }]
2352
+ }] });
2353
+
2354
+ class ListComponent extends CreateDynamicComponent('crud-list-page') {
2355
+ facade = inject((CrudFacade));
2356
+ router = inject(Router);
2357
+ dynamicComponentLoader = inject((DynamicComponentLoader));
2358
+ injector = inject(Injector);
2359
+ cd = inject(ChangeDetectorRef);
2360
+ menuService = inject(MenuService);
2361
+ hardwareService = inject(HardwareService);
2362
+ paginationFacade = inject((CrudListPaginationFactory));
2363
+ pageService = inject((PageService));
2364
+ config = inject((CrudFullConfig));
2365
+ searchService = inject(CrudSearchService);
2366
+ _cleanMultiSelected$ = new Subject();
2367
+ pageOptions;
2368
+ listOptions;
2369
+ links;
2370
+ filter = this.facade.filter;
2371
+ topTpl = viewChild('topTpl', ...(ngDevMode ? [{ debugName: "topTpl" }] : []));
2372
+ contentTpl = viewChild('contentTpl', ...(ngDevMode ? [{ debugName: "contentTpl" }] : []));
2373
+ dynamicContents = viewChildren(DynamicContentDirective, ...(ngDevMode ? [{ debugName: "dynamicContents" }] : []));
2374
+ constructor() {
2375
+ super();
2376
+ this.links = this.facade.links();
2377
+ }
2378
+ refreshProperties() {
2379
+ this.baseComponentRef.setInput('listOptions', this.listOptions());
2380
+ }
2381
+ async ngOnInit() {
2382
+ this.pageService.checkPermissions();
2383
+ const options = getModelOptions(this.config.type);
2384
+ let newFilter = null;
2385
+ if (this.config.list?.resetQuery === 'beforeInit') {
2386
+ newFilter = {
2387
+ query: this.config.baseQuery ? [...this.config.baseQuery] : [],
2388
+ paginationMode: this.config.list.paginationMode,
2389
+ limit: this.config.pagination
2390
+ ? this.config.pagination.limit
2391
+ : undefined,
2392
+ offset: this.config.pagination ? 0 : undefined,
2393
+ sortBy: this.config.sort
2394
+ ? this.config.sort['default']
2395
+ : undefined,
2396
+ sortDesc: this.config.sort
2397
+ ? this.config.sort['defaultDesc']
2398
+ : undefined,
2399
+ ...this.searchService.filter,
2400
+ };
2401
+ }
2402
+ else if (this.filter()) {
2403
+ newFilter = this.filter();
2404
+ }
2405
+ else {
2406
+ newFilter = {
2407
+ paginationMode: this.config.list.paginationMode,
2408
+ limit: this.searchService.filter?.limit
2409
+ ? this.searchService.filter.limit
2410
+ : this.config.pagination
2411
+ ? this.config.pagination.limit
2412
+ : undefined,
2413
+ offset: this.searchService.filter?.offset ||
2414
+ this.searchService.filter?.offset === 0
2415
+ ? this.searchService.filter.offset
2416
+ : this.config.pagination
2417
+ ? 0
2418
+ : undefined,
2419
+ sortBy: this.searchService.filter?.sortBy
2420
+ ? this.searchService.filter.sortBy
2421
+ : this.config.sort
2422
+ ? this.config.sort['default']
2423
+ : undefined,
2424
+ sortDesc: this.searchService.filter?.sortDesc
2425
+ ? this.searchService.filter.sortDesc
2426
+ : this.config.sort
2427
+ ? this.config.sort['defaultDesc']
2428
+ : undefined,
2429
+ query: this.config.baseQuery ? [...this.config.baseQuery] : [],
2430
+ ...this.searchService.filter,
2431
+ };
2432
+ }
2433
+ this.facade.read(newFilter);
2434
+ const endButtons = this.getEndButtons();
2435
+ this.pageOptions = computed(() => ({
2436
+ title: this.config.title || '',
2437
+ search: this.config.search
2438
+ ? {
2439
+ text: computed(() => this.filter()?.searchText ?? ''),
2440
+ set: (txt) => {
2441
+ if (txt !== this.filter()?.searchText)
2442
+ this.facade.read({
2443
+ ...this.filter(),
2444
+ searchText: txt,
2445
+ offset: 0,
2446
+ });
2447
+ },
2448
+ }
2449
+ : undefined,
2450
+ endButtons: endButtons,
2451
+ }), ...(ngDevMode ? [{ debugName: "pageOptions" }] : []));
2452
+ const compiledComponents = await this.dynamicComponentLoader.getComponentsWithFactories({
2453
+ components: [
2454
+ ...(this.config.details &&
2455
+ typeof this.config.details === 'object' &&
2456
+ 'components' in this.config.details &&
2457
+ this.config.details.components?.top
2458
+ ? [this.config.details.components.top]
2459
+ : []),
2460
+ ...(this.config.details &&
2461
+ typeof this.config.details === 'object' &&
2462
+ 'components' in this.config.details &&
2463
+ this.config.details.components?.bottom
2464
+ ? [this.config.details.components.bottom]
2465
+ : []),
2466
+ ...(this.config.list &&
2467
+ typeof this.config.list === 'object' &&
2468
+ 'components' in this.config.list &&
2469
+ this.config.list.components?.top
2470
+ ? [this.config.list.components.top]
2471
+ : []),
2472
+ ],
2473
+ });
2474
+ this.listOptions.set({
2475
+ provider: {
2476
+ getData: (filter) => {
2477
+ const global = {
2478
+ ...this.filter(),
2479
+ ...filter,
2480
+ };
2481
+ this.facade.read(global);
2482
+ },
2483
+ onChangeMultiSelected: async (list) => {
2484
+ if (list.length && !this.menuService.openedEnd) {
2485
+ await this.menuService.openEnd({
2486
+ injector: this.injector,
2487
+ component: MultiselectComponent,
2488
+ });
2489
+ }
2490
+ else if (!list.length && this.menuService.openedEnd) {
2491
+ await this.menuService.closeEnd();
2492
+ }
2493
+ this.facade.multiSelect(list);
2494
+ },
2495
+ list: computed(() => this.facade.list() || []),
2496
+ loading: this.facade.loading,
2497
+ onCleanMultiSelected$: this._cleanMultiSelected$,
2498
+ },
2499
+ cellPipe: this.config.list ? this.config.list.cellPipe : undefined,
2500
+ mode: this.config.list?.mode,
2501
+ type: this.config.type,
2502
+ details: this.config.details
2503
+ ? {
2504
+ provider: {
2505
+ getData: (id) => {
2506
+ this.facade.select(id);
2507
+ },
2508
+ clearData: () => {
2509
+ this.facade.unselect();
2510
+ },
2511
+ item: this.facade.selected,
2512
+ loading: this.facade.loading,
2513
+ },
2514
+ componentFactories: {
2515
+ top: this.config.details &&
2516
+ typeof this.config.details === 'object' &&
2517
+ 'components' in this.config.details &&
2518
+ this.config.details.components?.top
2519
+ ? compiledComponents.find((cc) => cc.component ===
2520
+ this.config.details.components.top)?.factory
2521
+ : undefined,
2522
+ bottom: this.config.details &&
2523
+ typeof this.config.details === 'object' &&
2524
+ 'components' in this.config.details &&
2525
+ this.config.details.components?.bottom
2526
+ ? compiledComponents.find((cc) => cc.component ===
2527
+ this.config.details.components.bottom)?.factory
2528
+ : undefined,
2529
+ },
2530
+ }
2531
+ : undefined,
2532
+ item: !!this.config.edit || this.config.details
2533
+ ? {
2534
+ options: {
2535
+ routingPrefix: '/' + this.router.routerState.snapshot.url + '/',
2536
+ edit: !!this.config.edit,
2537
+ },
2538
+ }
2539
+ : undefined,
2540
+ remove: this.config.remove
2541
+ ? {
2542
+ provider: {
2543
+ invoke: (id) => this.facade.delete(id),
2544
+ check: (item) => {
2545
+ return options?.remove?.enabled
2546
+ ? SpecificationService.valid(item, options?.remove?.enabled)
2547
+ : true;
2548
+ },
2549
+ },
2550
+ }
2551
+ : undefined,
2552
+ pagination: await this.paginationFacade.create({
2553
+ mode: this.config.list.paginationMode,
2554
+ limit: this.config.pagination.limit,
2555
+ provider: {
2556
+ getFilter: () => {
2557
+ return this.filter() || {};
2558
+ },
2559
+ getLinks: () => this.links,
2560
+ },
2561
+ }),
2562
+ sort: this.config.sort,
2563
+ });
2564
+ this.cd.detectChanges();
2565
+ this.initCloseMenu();
2566
+ this.initTopComponent(compiledComponents);
2567
+ this.refreshDynamicInstance();
2568
+ }
2569
+ initCloseMenu() {
2570
+ this.router.events.pipe(this.takeUntilDestroy).subscribe(async () => {
2571
+ await this.clear();
2572
+ });
2573
+ }
2574
+ async clear() {
2575
+ await this.menuService.closeEnd();
2576
+ this.listOptions.update((val) => ({
2577
+ ...val,
2578
+ select: undefined,
2579
+ }));
2580
+ this.facade.multiSelect([]);
2581
+ }
2582
+ getEndButtons() {
2583
+ const fieldsWithOptions = getModelFieldsWithOptions(new this.config.type());
2584
+ const modelOptions = getModelOptions(this.config.type);
2585
+ const showFilters = fieldsWithOptions.some((x) => x.options?.list?.filter) || modelOptions?.filters?.length;
2586
+ const showMultiEdit = this.config.list?.components?.multi ||
2587
+ (this.config.edit &&
2588
+ fieldsWithOptions.some((x) => x.options?.update?.multi) &&
2589
+ !this.hardwareService.isMobile &&
2590
+ (!this.config?.list?.mode ||
2591
+ this.config?.list?.mode === ListMode.desktop));
2592
+ return [
2593
+ ...(showMultiEdit
2594
+ ? [
2595
+ {
2596
+ icon: 'checkbox-outline',
2597
+ text: 'multi',
2598
+ handler: () => {
2599
+ this.facade.multiSelect([]);
2600
+ this._cleanMultiSelected$.next();
2601
+ setTimeout(async () => {
2602
+ this.listOptions.update((val) => ({
2603
+ ...val,
2604
+ select: val.select === 'multi' ? undefined : 'multi',
2605
+ }));
2606
+ if (this.menuService.openedEnd)
2607
+ await this.menuService.closeEnd();
2608
+ this.cd.detectChanges();
2609
+ });
2610
+ },
2611
+ },
2612
+ ]
2613
+ : []),
2614
+ ...(showFilters
2615
+ ? [
2616
+ {
2617
+ icon: 'filter-outline',
2618
+ text: 'filters',
2619
+ handler: async () => {
2620
+ await this.menuService.openEnd({
2621
+ injector: this.injector,
2622
+ component: FiltersComponent,
2623
+ });
2624
+ },
2625
+ },
2626
+ ]
2627
+ : []),
2628
+ ...(this.config.add
2629
+ ? [
2630
+ {
2631
+ icon: 'add',
2632
+ text: 'add',
2633
+ handler: () => {
2634
+ this.router.navigate([
2635
+ '/' + this.router.routerState.snapshot.url + '/add',
2636
+ ]);
2637
+ },
2638
+ },
2639
+ ]
2640
+ : []),
2641
+ ...(this.config.export
2642
+ ? [
2643
+ {
2644
+ text: 'export',
2645
+ icon: 'download-outline',
2646
+ type: 'popover',
2647
+ component: ExportComponent,
2648
+ },
2649
+ ]
2650
+ : []),
2651
+ ...(this.config.buttons ? this.config.buttons : []),
2652
+ ];
2653
+ }
2654
+ initTopComponent(compiledComponents) {
2655
+ const factory = this.config.list &&
2656
+ typeof this.config.list === 'object' &&
2657
+ 'components' in this.config.list &&
2658
+ this.config.list.components?.top
2659
+ ? compiledComponents.find((cc) => cc.component === this.config.list.components.top)?.factory
2660
+ : null;
2661
+ setTimeout(() => {
2662
+ if (factory && !this.topTpl()?.get(0)) {
2663
+ this.topTpl()?.createComponent(factory);
2664
+ }
2665
+ });
2666
+ }
2667
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2668
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.0", type: ListComponent, isStandalone: true, selector: "smart-crud-list-page", viewQueries: [{ propertyName: "topTpl", first: true, predicate: ["topTpl"], descendants: true, isSignal: true }, { propertyName: "contentTpl", first: true, predicate: ["contentTpl"], descendants: true, isSignal: true }, { propertyName: "dynamicContents", predicate: DynamicContentDirective, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2669
+ @if (filter()) {
2670
+ <smart-page [options]="pageOptions()">
2671
+ <div #topTpl></div>
2672
+
2673
+ @if (template() === 'default') {
2674
+ <smart-crud-list-standard-page [listOptions]="listOptions()">
2675
+ <ng-container [ngTemplateOutlet]="contentTpl"></ng-container>
2676
+ </smart-crud-list-standard-page>
2677
+ }
2678
+ <ng-template #contentTpl>
2679
+ <ng-content></ng-content>
2680
+ </ng-template>
2681
+ <div class="dynamic-content"></div>
2682
+ </smart-page>
2683
+ }
2684
+ `, isInline: true, dependencies: [{ kind: "component", type: PageComponent, selector: "smart-page", inputs: ["options"] }, { kind: "component", type: ListStandardComponent, selector: "smart-crud-list-standard-page" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
2685
+ }
2686
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: ListComponent, decorators: [{
2687
+ type: Component,
2688
+ args: [{
2689
+ selector: 'smart-crud-list-page',
2690
+ imports: [PageComponent, ListStandardComponent, NgTemplateOutlet],
2691
+ template: `
2692
+ @if (filter()) {
2693
+ <smart-page [options]="pageOptions()">
2694
+ <div #topTpl></div>
2695
+
2696
+ @if (template() === 'default') {
2697
+ <smart-crud-list-standard-page [listOptions]="listOptions()">
2698
+ <ng-container [ngTemplateOutlet]="contentTpl"></ng-container>
2699
+ </smart-crud-list-standard-page>
2700
+ }
2701
+ <ng-template #contentTpl>
2702
+ <ng-content></ng-content>
2703
+ </ng-template>
2704
+ <div class="dynamic-content"></div>
2705
+ </smart-page>
2706
+ }
2707
+ `,
2708
+ }]
2709
+ }], ctorParameters: () => [] });
2710
+
2711
+ const PAGES = [
2712
+ ItemComponent,
2713
+ ListComponent,
2714
+ ListStandardComponent,
2715
+ ItemStandardComponent,
2716
+ ];
2717
+ class CrudFullModule {
2718
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFullModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2719
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: CrudFullModule, imports: [ItemComponent,
2720
+ ListComponent,
2721
+ ListStandardComponent,
2722
+ ItemStandardComponent, SharedModule,
2723
+ CrudPipesModule, i1.RouterModule, FormsModule,
2724
+ CommonModule,
2725
+ CrudComponentsModule], exports: [ItemComponent,
2726
+ ListComponent,
2727
+ ListStandardComponent,
2728
+ ItemStandardComponent, CrudComponentsModule] });
2729
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFullModule, providers: [
2730
+ CrudService,
2731
+ CrudListGroupService,
2732
+ PageService,
2733
+ CrudFacade,
2734
+ CrudListPaginationFactory,
2735
+ ], imports: [PAGES, SharedModule,
2736
+ CrudPipesModule,
2737
+ RouterModule.forChild([
2738
+ { path: '', component: ListComponent },
2739
+ { path: 'add', component: ItemComponent },
2740
+ { path: ':id', component: ItemComponent },
2741
+ ]),
2742
+ FormsModule,
2743
+ CommonModule,
2744
+ CrudComponentsModule, CrudComponentsModule] });
2745
+ }
2746
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudFullModule, decorators: [{
2747
+ type: NgModule,
2748
+ args: [{
2749
+ imports: [
2750
+ ...PAGES,
2751
+ SharedModule,
2752
+ CrudPipesModule,
2753
+ RouterModule.forChild([
2754
+ { path: '', component: ListComponent },
2755
+ { path: 'add', component: ItemComponent },
2756
+ { path: ':id', component: ItemComponent },
2757
+ ]),
2758
+ FormsModule,
2759
+ CommonModule,
2760
+ CrudComponentsModule,
2761
+ ],
2762
+ exports: [...PAGES, CrudComponentsModule],
2763
+ providers: [
2764
+ CrudService,
2765
+ CrudListGroupService,
2766
+ PageService,
2767
+ CrudFacade,
2768
+ CrudListPaginationFactory,
2769
+ ],
2770
+ }]
2771
+ }] });
2772
+
2773
+ class CrudCoreModule {
2774
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2775
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: CrudCoreModule, imports: [SharedModule,
2776
+ CrudPipesModule,
2777
+ FormsModule,
2778
+ CommonModule,
2779
+ CrudComponentsModule], exports: [CrudComponentsModule] });
2780
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudCoreModule, providers: [
2781
+ CrudService,
2782
+ CrudListGroupService,
2783
+ PageService,
2784
+ CrudFacade,
2785
+ CrudListPaginationFactory,
2786
+ ], imports: [SharedModule,
2787
+ CrudPipesModule,
2788
+ FormsModule,
2789
+ CommonModule,
2790
+ CrudComponentsModule, CrudComponentsModule] });
2791
+ }
2792
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudCoreModule, decorators: [{
2793
+ type: NgModule,
2794
+ args: [{
2795
+ imports: [
2796
+ SharedModule,
2797
+ CrudPipesModule,
2798
+ FormsModule,
2799
+ CommonModule,
2800
+ CrudComponentsModule,
2801
+ ],
2802
+ exports: [CrudComponentsModule],
2803
+ providers: [
2804
+ CrudService,
2805
+ CrudListGroupService,
2806
+ PageService,
2807
+ CrudFacade,
2808
+ CrudListPaginationFactory,
2809
+ ],
2810
+ }]
2811
+ }] });
2812
+ class CrudModule {
2813
+ static forFeature(options) {
2814
+ return {
2815
+ ngModule: options.routing ? CrudFullModule : CrudCoreModule,
2816
+ providers: [
2817
+ { provide: CrudConfig, useValue: options.config },
2818
+ { provide: CrudFullConfig, useValue: options.config },
2819
+ {
2820
+ provide: FILE_SERVICE_CONFIG,
2821
+ useValue: { apiUrl: options.config.apiUrl },
2822
+ },
2823
+ ],
2824
+ };
2825
+ }
2826
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2827
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.0", ngImport: i0, type: CrudModule });
2828
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudModule });
2829
+ }
2830
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.0", ngImport: i0, type: CrudModule, decorators: [{
2831
+ type: NgModule,
2832
+ args: [{}]
2833
+ }] });
2834
+
2835
+ /**
2836
+ * Generated bundle index. Do not edit.
2837
+ */
2838
+
2839
+ export { CRUD_MODEL_POSSIBILITIES_PROVIDER, CrudComponentsModule, CrudConfig, CrudCoreModule, CrudFacade, CrudFullConfig, CrudFullModule, CrudItemPageBaseComponent, CrudListPageBaseComponent, CrudListPaginationFactory, CrudModule, CrudPipesModule, CrudSearchService, CrudService, ExportComponent, FilterCheckComponent, FilterComponent, FilterDateComponent, FilterDateTimeComponent, FilterDateWithEditComponent, FilterFlagComponent, FilterIntComponent, FilterRadioComponent, FilterTextComponent, FiltersComponent, FiltersConfigComponent, FormOptionsPipe, GroupComponent, ICrudModelPossibilitiesProvider, ItemComponent, ItemStandardComponent, ListComponent, ListStandardComponent, MultiselectComponent, PAGES, PageService };
2840
+ //# sourceMappingURL=smartsoft001-crud-shell-angular.mjs.map