@mediusinc/mng-commons 7.0.0-rc.1 → 7.0.0-rc.2

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 (37) hide show
  1. package/core/index.d.ts +24 -4
  2. package/fesm2022/mediusinc-mng-commons-core.mjs +108 -72
  3. package/fesm2022/mediusinc-mng-commons-core.mjs.map +1 -1
  4. package/fesm2022/mediusinc-mng-commons-filter.mjs +16 -0
  5. package/fesm2022/mediusinc-mng-commons-filter.mjs.map +1 -1
  6. package/fesm2022/mediusinc-mng-commons-form-api.mjs.map +1 -1
  7. package/fesm2022/mediusinc-mng-commons-form.mjs +406 -49
  8. package/fesm2022/mediusinc-mng-commons-form.mjs.map +1 -1
  9. package/fesm2022/mediusinc-mng-commons-model-class.mjs.map +1 -1
  10. package/fesm2022/mediusinc-mng-commons-model.mjs.map +1 -1
  11. package/fesm2022/mediusinc-mng-commons-table-api-class.mjs.map +1 -1
  12. package/fesm2022/mediusinc-mng-commons-table-api.mjs.map +1 -1
  13. package/fesm2022/mediusinc-mng-commons-table-column-toggle.component-BQ99oqWO.mjs +30 -0
  14. package/fesm2022/mediusinc-mng-commons-table-column-toggle.component-BQ99oqWO.mjs.map +1 -0
  15. package/fesm2022/mediusinc-mng-commons-table-mediusinc-mng-commons-table-BLuM5Kpu.mjs +2700 -0
  16. package/fesm2022/mediusinc-mng-commons-table-mediusinc-mng-commons-table-BLuM5Kpu.mjs.map +1 -0
  17. package/fesm2022/mediusinc-mng-commons-table.mjs +1 -1
  18. package/fesm2022/mediusinc-mng-commons-tableview-api-class.mjs.map +1 -1
  19. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs +31 -3
  20. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs.map +1 -1
  21. package/fesm2022/mediusinc-mng-commons-tableview.mjs +155 -123
  22. package/fesm2022/mediusinc-mng-commons-tableview.mjs.map +1 -1
  23. package/fesm2022/mediusinc-mng-commons.mjs.map +1 -1
  24. package/filter/index.d.ts +13 -0
  25. package/form/index.d.ts +109 -22
  26. package/i18n/en.json +12 -1
  27. package/i18n/sl.json +12 -1
  28. package/package.json +24 -24
  29. package/table/api/index.d.ts +2 -2
  30. package/table/index.d.ts +97 -29
  31. package/tableview/api/index.d.ts +17 -2
  32. package/tableview/index.d.ts +7 -1
  33. package/version-info.json +6 -6
  34. package/fesm2022/mediusinc-mng-commons-table-column-toggle.component-0Dtv48mq.mjs +0 -30
  35. package/fesm2022/mediusinc-mng-commons-table-column-toggle.component-0Dtv48mq.mjs.map +0 -1
  36. package/fesm2022/mediusinc-mng-commons-table-mediusinc-mng-commons-table-BsAwyXiN.mjs +0 -2417
  37. package/fesm2022/mediusinc-mng-commons-table-mediusinc-mng-commons-table-BsAwyXiN.mjs.map +0 -1
@@ -0,0 +1,2700 @@
1
+ import { trigger, transition, style, animate } from '@angular/animations';
2
+ import { NgTemplateOutlet, NgClass, DecimalPipe, CurrencyPipe, DatePipe, AsyncPipe } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { Injectable, inject, signal, computed, untracked, ElementRef, Renderer2, ChangeDetectorRef, input, booleanAttribute, viewChild, ChangeDetectionStrategy, ViewEncapsulation, Component, LOCALE_ID, Pipe, output, forwardRef, model, InjectionToken, Directive, contentChildren, HostListener, Injector, DestroyRef, afterNextRender } from '@angular/core';
5
+ import { takeUntilDestroyed, toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
6
+ import * as i1 from '@angular/forms';
7
+ import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
8
+ import { TranslatePipe, TranslateService } from '@ngx-translate/core';
9
+ import { OverlayService, MessageService, PrimeTemplate } from 'primeng/api';
10
+ import { DomHandler, ConnectedOverlayScrollHandler } from 'primeng/dom';
11
+ import { InputGroup } from 'primeng/inputgroup';
12
+ import { InputGroupAddon } from 'primeng/inputgroupaddon';
13
+ import { InputNumber } from 'primeng/inputnumber';
14
+ import { InputText } from 'primeng/inputtext';
15
+ import * as i1$1 from 'primeng/table';
16
+ import { TableModule, Table } from 'primeng/table';
17
+ import { ToggleSwitch } from 'primeng/toggleswitch';
18
+ import { ZIndexUtils } from 'primeng/utils';
19
+ import { Subject, debounceTime, distinctUntilChanged, ReplaySubject, switchMap, NEVER, BehaviorSubject, combineLatest, skip, of, filter } from 'rxjs';
20
+ import { FilterMatchMode, dateToIsoString, angularDateFormatHasTime, angularDateFormatHasSeconds, fromAngularDateFormatToPrime, fromAngularNumberFormatToFractions, effectWithDeps, getI18nTypePropertyKey, RerenderDirective, GetterPipe, TemplatePipe, JsonPathPipe, ComponentDirective, BooleanPipe, EnumPipe, isMac, TemplateDirective, findTemplateByName, getI18nErrorParams, getI18nForError, toastMessage, CommonsService, COMMONS_MODULE_CONFIG_IT, toObservable as toObservable$1, CommonsStorageService, LoggerService, booleanOrUndefinedAttribute, mergeDataListParamsWithDefaults, fromTableLoadToDataListParams, dataListParamsToUrlQuery, fromSubscribeError, getErrorLogLevel, fromUrlQueryToDataListParams, I18nPropertyPipe, ClassMapPipe, CommonsFeatureTypeEnum } from '@mediusinc/mng-commons/core';
21
+ import { FilterTypeEnum, FilterDescriptor, FilterLookupTypeEnum, FilterLookupDescriptor, FilterDisplayTypeEnum } from '@mediusinc/mng-commons/filter';
22
+ import { DateRangeComponent, AutocompleteComponent, DropdownComponent, InputTrimDirective, NumberRangeComponent, AutocompleteTemplateDirective, DropdownTemplateDirective, DateRangeTemplateDirective, NumberRangeTemplateDirective, DatetimePickerComponent } from '@mediusinc/mng-commons/form';
23
+ import { ButtonDirective } from 'primeng/button';
24
+ import { Tooltip } from 'primeng/tooltip';
25
+ import { ColumnDisplayTypeEnum, tableDescriptor, TableDynamicDescriptorInst, TablePaginationModeEnum, TableSizeEnum } from '@mediusinc/mng-commons/table/api';
26
+ import { Divider } from 'primeng/divider';
27
+ import { Menu } from 'primeng/menu';
28
+ import { Tag, TagModule } from 'primeng/tag';
29
+ import { Checkbox } from 'primeng/checkbox';
30
+ import { Message } from 'primeng/message';
31
+ import { ToggleButton } from 'primeng/togglebutton';
32
+ import { lookupDataProvider } from '@mediusinc/mng-commons/form/api';
33
+ import { Chip } from 'primeng/chip';
34
+ import { MultiSelect } from 'primeng/multiselect';
35
+ import { IconField } from 'primeng/iconfield';
36
+ import { InputIcon } from 'primeng/inputicon';
37
+ import { Popover } from 'primeng/popover';
38
+ import { Skeleton } from 'primeng/skeleton';
39
+ import { SplitButton } from 'primeng/splitbutton';
40
+ import { Router, ActivatedRoute, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
41
+ import { getI18nForModel } from '@mediusinc/mng-commons/model';
42
+ import { PrimeNG } from 'primeng/config';
43
+
44
+ function filterGenerateMatchModeOptions(primeConfig, descriptor, cmpSerCfg) {
45
+ let options = undefined;
46
+ if (descriptor == null || descriptor.filterType === FilterTypeEnum.String) {
47
+ options = [
48
+ { value: FilterMatchMode.Contains, label: primeConfig.getTranslation(FilterMatchMode.Contains) },
49
+ { value: FilterMatchMode.NotContains, label: primeConfig.getTranslation(FilterMatchMode.NotContains) },
50
+ { value: FilterMatchMode.Equals, label: primeConfig.getTranslation(FilterMatchMode.Equals) },
51
+ { value: FilterMatchMode.NotEquals, label: primeConfig.getTranslation(FilterMatchMode.NotEquals) },
52
+ { value: FilterMatchMode.In, label: primeConfig.getTranslation(FilterMatchMode.In) },
53
+ { value: FilterMatchMode.NotIn, label: primeConfig.getTranslation(FilterMatchMode.NotIn) },
54
+ { value: FilterMatchMode.StartsWith, label: primeConfig.getTranslation(FilterMatchMode.StartsWith) },
55
+ { value: FilterMatchMode.EndsWith, label: primeConfig.getTranslation(FilterMatchMode.EndsWith) }
56
+ ];
57
+ }
58
+ else if (descriptor.filterType === FilterTypeEnum.Boolean) {
59
+ options = [{ value: FilterMatchMode.Equals, label: primeConfig.getTranslation(FilterMatchMode.Equals) }];
60
+ }
61
+ else if (descriptor.filterType === FilterTypeEnum.Number) {
62
+ options = [
63
+ { value: FilterMatchMode.Equals, label: primeConfig.getTranslation(FilterMatchMode.Equals) },
64
+ { value: FilterMatchMode.NotEquals, label: primeConfig.getTranslation(FilterMatchMode.NotEquals) },
65
+ { value: FilterMatchMode.LessThan, label: primeConfig.getTranslation(FilterMatchMode.LessThan) },
66
+ { value: FilterMatchMode.LessThanOrEqualTo, label: primeConfig.getTranslation(FilterMatchMode.LessThanOrEqualTo) },
67
+ { value: FilterMatchMode.GreaterThan, label: primeConfig.getTranslation(FilterMatchMode.GreaterThan) },
68
+ { value: FilterMatchMode.GreaterThanOrEqualTo, label: primeConfig.getTranslation(FilterMatchMode.GreaterThanOrEqualTo) },
69
+ { value: FilterMatchMode.Between, label: primeConfig.getTranslation(FilterMatchMode.Between) },
70
+ ...(descriptor.displayFormat === undefined
71
+ ? [
72
+ { value: FilterMatchMode.In, label: primeConfig.getTranslation(FilterMatchMode.In) },
73
+ { value: FilterMatchMode.NotIn, label: primeConfig.getTranslation(FilterMatchMode.NotIn) }
74
+ ]
75
+ : [])
76
+ ];
77
+ }
78
+ else if (descriptor.filterType === FilterTypeEnum.Lookup || descriptor.filterType === FilterTypeEnum.LookupEnum) {
79
+ options = [
80
+ { value: FilterMatchMode.Equals, label: primeConfig.getTranslation(FilterMatchMode.Equals) },
81
+ { value: FilterMatchMode.NotEquals, label: primeConfig.getTranslation(FilterMatchMode.NotEquals) },
82
+ { value: FilterMatchMode.In, label: primeConfig.getTranslation(FilterMatchMode.In) },
83
+ { value: FilterMatchMode.NotIn, label: primeConfig.getTranslation(FilterMatchMode.NotIn) }
84
+ ];
85
+ }
86
+ else if (descriptor.filterType === FilterTypeEnum.Date) {
87
+ if (!descriptor.datePickerShowTime && !descriptor.dateValueNoTime && !cmpSerCfg?.filtersDateOnlyDisabled) {
88
+ options = [
89
+ { value: FilterMatchMode.Equals, label: primeConfig.getTranslation(FilterMatchMode.Equals) },
90
+ { value: FilterMatchMode.NotEquals, label: primeConfig.getTranslation(FilterMatchMode.NotEquals) },
91
+ { value: FilterMatchMode.LessThanOrEqualTo, label: primeConfig.getTranslation(FilterMatchMode.LessThanOrEqualTo) },
92
+ { value: FilterMatchMode.GreaterThanOrEqualTo, label: primeConfig.getTranslation(FilterMatchMode.GreaterThanOrEqualTo) },
93
+ { value: FilterMatchMode.Between, label: primeConfig.getTranslation(FilterMatchMode.Between) }
94
+ ];
95
+ }
96
+ else {
97
+ options = [
98
+ { value: FilterMatchMode.Equals, label: primeConfig.getTranslation(FilterMatchMode.Equals) },
99
+ { value: FilterMatchMode.LessThanOrEqualTo, label: primeConfig.getTranslation(FilterMatchMode.LessThanOrEqualTo) },
100
+ { value: FilterMatchMode.GreaterThanOrEqualTo, label: primeConfig.getTranslation(FilterMatchMode.GreaterThanOrEqualTo) },
101
+ { value: FilterMatchMode.Between, label: primeConfig.getTranslation(FilterMatchMode.Between) }
102
+ ];
103
+ }
104
+ }
105
+ options?.push({ value: FilterMatchMode.Exists, label: primeConfig.getTranslation(FilterMatchMode.Exists) }, { value: FilterMatchMode.DoesNotExist, label: primeConfig.getTranslation(FilterMatchMode.DoesNotExist) });
106
+ if (descriptor?.matchModes) {
107
+ options = descriptor.matchModes.map(mm => ({ value: mm, label: primeConfig.getTranslation(mm) }));
108
+ }
109
+ return options || [];
110
+ }
111
+ /**
112
+ * Gets the default match mode for a filter.
113
+ *
114
+ * @param {FilterDescriptor<any, any>} [descriptor] - The filter descriptor.
115
+ * @param {SelectItem[]} [matchModes=[]] - The available match modes options.
116
+ *
117
+ * @return {FilterMatchModeExtendedType} The default match mode for the filter.
118
+ */
119
+ function filterGetDefaultMatchMode(descriptor, matchModes = []) {
120
+ let defaultMatchMode = FilterMatchMode.Equals;
121
+ if (descriptor?.filterType === FilterTypeEnum.String)
122
+ defaultMatchMode = FilterMatchMode.StartsWith;
123
+ // overwrite type default set in descriptor
124
+ if (descriptor?.defaultMatchMode) {
125
+ defaultMatchMode = descriptor.defaultMatchMode;
126
+ }
127
+ // check if default mode exists!
128
+ if (matchModes.length > 0 && !matchModes.some(m => m.value === defaultMatchMode)) {
129
+ defaultMatchMode = matchModes[0].value;
130
+ }
131
+ return defaultMatchMode;
132
+ }
133
+ function filterSetStateOnChange(filter, matchMode, value, filterType, filterDateCfg) {
134
+ let displayValue = filter?.displayValue ?? value;
135
+ let displayMatchMode = filter?.displayMatchMode ?? matchMode;
136
+ // when equals is used on dates with time, the actual filter will be between, but displayed as equals
137
+ if (filterType === FilterTypeEnum.Date && !filterDateCfg?.valueNoTime) {
138
+ if (matchMode === FilterMatchMode.Between &&
139
+ Array.isArray(value) &&
140
+ value.length === 2 &&
141
+ value.every(v => v instanceof Date || typeof v === 'string' || typeof v === 'number')) {
142
+ if (filterAreDatesEqual(value[0], value[1], filterDateCfg)) {
143
+ displayMatchMode = FilterMatchMode.Equals;
144
+ displayValue = new Date(value[0]);
145
+ }
146
+ }
147
+ else if (matchMode === FilterMatchMode.Equals && !value) {
148
+ matchMode = FilterMatchMode.Between;
149
+ }
150
+ }
151
+ if (filterType === FilterTypeEnum.Date && displayValue) {
152
+ // display value for calendar cannot be string, convert to date
153
+ displayValue = Array.isArray(displayValue)
154
+ ? displayValue.map(v => (!(v instanceof Date) ? new Date(v) : v))
155
+ : displayValue instanceof Date
156
+ ? displayValue
157
+ : new Date(displayValue);
158
+ }
159
+ if (filterType === FilterTypeEnum.Boolean && displayValue != null && typeof displayValue !== 'boolean') {
160
+ displayValue = (typeof displayValue === 'string' && displayValue.toLowerCase() === 'true') || displayValue === 1;
161
+ }
162
+ if (filterType === FilterTypeEnum.Number && displayValue != null) {
163
+ if (Array.isArray(value) && value.every(v => !isNaN(Number(v)))) {
164
+ displayValue = value.map(v => (typeof v === 'string' ? Number(v) : v));
165
+ }
166
+ else if (typeof displayValue !== 'number') {
167
+ const numValue = +displayValue;
168
+ if (!isNaN(numValue)) {
169
+ displayValue = numValue;
170
+ }
171
+ }
172
+ }
173
+ return {
174
+ ...filter,
175
+ matchMode,
176
+ value: value,
177
+ displayMatchMode,
178
+ displayValue
179
+ };
180
+ }
181
+ function filterSetStateOnDisplayChange(filter, displayMatchMode, displayValue, filterType, filterDateCfg) {
182
+ let matchMode = displayMatchMode;
183
+ let value = displayValue;
184
+ if (filterType === FilterTypeEnum.Date) {
185
+ if (!filterDateCfg?.valueNoTime && displayValue !== null) {
186
+ if (displayMatchMode === FilterMatchMode.Equals) {
187
+ if (value instanceof Date || typeof value === 'string' || typeof value === 'number') {
188
+ const fromDate = new Date(value);
189
+ const toDate = new Date(value);
190
+ if (filterDateCfg?.showTime) {
191
+ if (filterDateCfg?.showSeconds) {
192
+ fromDate.setMilliseconds(0);
193
+ toDate.setMilliseconds(999);
194
+ }
195
+ else {
196
+ fromDate.setSeconds(0, 0);
197
+ toDate.setSeconds(59, 999);
198
+ }
199
+ }
200
+ else {
201
+ fromDate.setHours(0, 0, 0, 0);
202
+ toDate.setHours(23, 59, 59, 999);
203
+ }
204
+ value = [fromDate, toDate];
205
+ matchMode = FilterMatchMode.Between;
206
+ }
207
+ else {
208
+ value = null;
209
+ }
210
+ }
211
+ else if (displayMatchMode === FilterMatchMode.Between) {
212
+ if (Array.isArray(value) && value.length === 2 && value.every(i => i instanceof Date || typeof i === 'string' || typeof i === 'number')) {
213
+ const fromDate = new Date(value[0]);
214
+ let toDate = new Date(value[1]);
215
+ if (filterAreDatesEqual(fromDate, toDate, filterDateCfg)) {
216
+ toDate = new Date(fromDate);
217
+ if (filterDateCfg?.showTime) {
218
+ if (filterDateCfg?.showSeconds) {
219
+ toDate.setSeconds(toDate.getSeconds() + 1);
220
+ }
221
+ else {
222
+ toDate.setMinutes(toDate.getMinutes() + 1);
223
+ }
224
+ }
225
+ else {
226
+ toDate.setDate(toDate.getDate() + 1);
227
+ }
228
+ value = [fromDate, toDate];
229
+ matchMode = FilterMatchMode.Between;
230
+ }
231
+ }
232
+ else {
233
+ value = null;
234
+ }
235
+ }
236
+ }
237
+ const convertDateType = filterDateCfg?.valueNoTime ? 'date' : 'date-time';
238
+ const convertDateTimeOpts = {
239
+ utc: filterDateCfg?.valueUtc,
240
+ noMillis: filterDateCfg?.valueNoMillis,
241
+ noTimezone: filterDateCfg?.valueNoTimezone
242
+ };
243
+ value =
244
+ value == null
245
+ ? value
246
+ : Array.isArray(value)
247
+ ? value.filter(i => i != null).map(i => dateToIsoString(i, convertDateType, convertDateTimeOpts))
248
+ : dateToIsoString(value, convertDateType, convertDateTimeOpts);
249
+ }
250
+ if (matchMode === FilterMatchMode.Exists || matchMode === FilterMatchMode.DoesNotExist) {
251
+ value = null;
252
+ }
253
+ return {
254
+ ...filter,
255
+ displayMatchMode: displayMatchMode,
256
+ matchMode: matchMode,
257
+ displayValue: displayValue,
258
+ value: value,
259
+ caseSensitive: filterType === FilterTypeEnum.String ? filter?.caseSensitive : undefined
260
+ };
261
+ }
262
+ function filterAreDatesEqual(fromDate, toDate, filterDateCfg) {
263
+ const startDate = dateToIsoString(fromDate);
264
+ const endDate = dateToIsoString(toDate);
265
+ // 2020-11-02T11:12:12.000
266
+ const cmpLength = filterDateCfg?.showTime ? (filterDateCfg?.showSeconds ? 19 : 16) : 10;
267
+ return startDate.substring(0, cmpLength) === endDate.substring(0, cmpLength);
268
+ }
269
+ function filterApplySerializationConfigToCmp(config, cmpSerCfg) {
270
+ // set default
271
+ cmpSerCfg.dateTimeInUtc = false;
272
+ cmpSerCfg.dateTimeWithTimezone = true;
273
+ cmpSerCfg.dateTimeWithMillis = true;
274
+ cmpSerCfg.filtersDateOnlyDisabled = false;
275
+ // set customizations
276
+ if (config?.serialization) {
277
+ if (config.serialization.dateTimeInUtc !== undefined)
278
+ cmpSerCfg.dateTimeInUtc = config.serialization.dateTimeInUtc;
279
+ if (config.serialization.dateTimeWithTimezone !== undefined)
280
+ cmpSerCfg.dateTimeWithTimezone = config.serialization.dateTimeWithTimezone;
281
+ if (config.serialization.dateTimeWithMillis !== undefined)
282
+ cmpSerCfg.dateTimeWithMillis = config.serialization.dateTimeWithMillis;
283
+ if (config.serialization.filtersDateOnlyDisabled !== undefined)
284
+ cmpSerCfg.filtersDateOnlyDisabled = config.serialization.filtersDateOnlyDisabled;
285
+ }
286
+ }
287
+ function filterAdjustDisplayValueOnMatchModeChange(matchMode, value) {
288
+ if (matchMode == null || matchMode === FilterMatchMode.Exists || matchMode === FilterMatchMode.DoesNotExist) {
289
+ return value; // never change, only change later if something else changes here
290
+ }
291
+ if (matchMode === FilterMatchMode.Between) {
292
+ if (!Array.isArray(value)) {
293
+ return value != null ? [value, value] : [];
294
+ }
295
+ else if (value.length === 0 || value.length === 2) {
296
+ return value;
297
+ }
298
+ else if (value.length === 1) {
299
+ return [value[0], value[0]];
300
+ }
301
+ else {
302
+ return [value[0], value[1]];
303
+ }
304
+ }
305
+ if (matchMode === FilterMatchMode.In || matchMode === FilterMatchMode.NotIn) {
306
+ return Array.isArray(value) ? value : value == null ? [] : [value];
307
+ }
308
+ return Array.isArray(value) && value.length > 0 ? value[0] : value;
309
+ }
310
+ function filterGetDateConfig(descriptor, serCfg) {
311
+ if (!descriptor || descriptor.filterType !== FilterTypeEnum.Date) {
312
+ return undefined;
313
+ }
314
+ const showTime = descriptor.datePickerShowTime ?? (descriptor.displayFormatApplyToField && descriptor.displayFormat ? angularDateFormatHasTime(descriptor.displayFormat) : false);
315
+ return {
316
+ valueNoTime: descriptor.dateValueNoTime || (!serCfg?.filtersDateOnlyDisabled && !showTime),
317
+ valueUtc: descriptor.dateValueUtc ?? serCfg?.dateTimeInUtc,
318
+ valueNoTimezone: descriptor.dateValueNoTimezone ?? !serCfg?.dateTimeWithTimezone,
319
+ valueNoMillis: !serCfg?.dateTimeWithMillis,
320
+ format: descriptor.datePickerFormat ?? (descriptor.displayFormatApplyToField && descriptor.displayFormat ? fromAngularDateFormatToPrime(descriptor.displayFormat) : undefined),
321
+ showTime: showTime,
322
+ showSeconds: showTime &&
323
+ (descriptor.datePickerShowSeconds ?? (descriptor.displayFormatApplyToField && descriptor.displayFormat ? angularDateFormatHasSeconds(descriptor.displayFormat) : false))
324
+ };
325
+ }
326
+ function filterGetNumberConfig(descriptor) {
327
+ if (!descriptor || descriptor.filterType !== FilterTypeEnum.Number) {
328
+ return undefined;
329
+ }
330
+ const displayCfg = descriptor.displayFormatApplyToField && descriptor.displayFormat ? fromAngularNumberFormatToFractions(descriptor.displayFormat) : undefined;
331
+ return {
332
+ fractionsMin: descriptor.numberMinFractionDigits ?? displayCfg?.fractionsMin,
333
+ fractionsMax: descriptor.numberMaxFractionDigits ?? displayCfg?.fractionsMax
334
+ };
335
+ }
336
+ /**
337
+ * Creates an array of filter descriptors from an array of generic filter properties.
338
+ *
339
+ * @param {FilterGenericProperty[]} properties - The array of filterable properties, their types and options.
340
+ * @param {LookupDataProviderInst<string, any, any, 'field'>} [valueLookup] - The lookup data provider for value suggestions.
341
+ */
342
+ function createFilterDescriptorsFromGeneric(properties, valueLookup) {
343
+ return properties.map(genericFilter => {
344
+ // when no generic value lookup is provided, lookup enum filters are treated as string filters
345
+ const filterType = genericFilter.type === FilterTypeEnum.LookupEnum && valueLookup === undefined ? FilterTypeEnum.String : genericFilter.type;
346
+ const filterDescriptor = new FilterDescriptor(genericFilter.property).asFilterType(filterType).asGenericFilter();
347
+ if ((genericFilter.type === FilterTypeEnum.String || genericFilter.type === FilterTypeEnum.LookupEnum) && valueLookup) {
348
+ filterDescriptor.withGenericValueProvider(valueLookup);
349
+ }
350
+ if (genericFilter.opts !== undefined) {
351
+ switch (genericFilter.type) {
352
+ case FilterTypeEnum.Number:
353
+ filterDescriptor.asNumber(genericFilter.opts);
354
+ break;
355
+ case FilterTypeEnum.Date:
356
+ filterDescriptor.asDate(genericFilter.opts);
357
+ break;
358
+ }
359
+ }
360
+ genericFilter.modify?.(filterDescriptor);
361
+ return filterDescriptor;
362
+ });
363
+ }
364
+ function isFilterValueBlank(value) {
365
+ return value == null || (typeof value === 'string' && value.trim().length === 0) || (Array.isArray(value) && value.length === 0);
366
+ }
367
+
368
+ class ADataListService {
369
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ADataListService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
370
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ADataListService }); }
371
+ }
372
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ADataListService, decorators: [{
373
+ type: Injectable
374
+ }] });
375
+
376
+ class FilterService {
377
+ #tableData;
378
+ #config;
379
+ #state;
380
+ #tableFilterState;
381
+ constructor() {
382
+ this.#tableData = inject((ADataListService));
383
+ this.#config = signal(undefined, ...(ngDevMode ? [{ debugName: "#config" }] : []));
384
+ this.#state = signal(undefined, ...(ngDevMode ? [{ debugName: "#state" }] : []));
385
+ this.state = this.#state.asReadonly();
386
+ this.isActive = computed(() => this.state()?.matchMode === FilterMatchMode.Exists || this.state()?.matchMode === FilterMatchMode.DoesNotExist || !isFilterValueBlank(this.state()?.value), ...(ngDevMode ? [{ debugName: "isActive" }] : []));
387
+ this.#tableFilterState = computed(() => {
388
+ const property = this.#config()?.descriptor.property;
389
+ return property ? this.#tableData.filterStates()?.[property] : undefined;
390
+ }, ...(ngDevMode ? [{ debugName: "#tableFilterState" }] : []));
391
+ effectWithDeps([this.#config, this.state], ([config, state]) => {
392
+ this.#updateStateIfRequired(config, state, this.#tableFilterState());
393
+ });
394
+ effectWithDeps([this.#tableFilterState], ([currTableFilterState]) => {
395
+ this.#updateStateIfRequired(this.#config(), this.state(), currTableFilterState, false);
396
+ });
397
+ }
398
+ setConfig(config) {
399
+ this.#config.set(config);
400
+ }
401
+ setMatchMode(displayMatchMode) {
402
+ const config = this.#config();
403
+ if (this.state()?.displayMatchMode === displayMatchMode || config == null) {
404
+ return;
405
+ }
406
+ this.setState(filterSetStateOnDisplayChange(this.state(), displayMatchMode, filterAdjustDisplayValueOnMatchModeChange(displayMatchMode, this.state()?.displayValue), config.descriptor.filterType, config.dateConfig));
407
+ }
408
+ toggleCaseSensitivity() {
409
+ if (this.#config()?.descriptor.filterType === FilterTypeEnum.String) {
410
+ this.setState({
411
+ ...this.state(),
412
+ caseSensitive: !(this.state()?.caseSensitive ?? false)
413
+ });
414
+ }
415
+ }
416
+ clear() {
417
+ const currConfig = this.#config();
418
+ if (currConfig == null) {
419
+ return;
420
+ }
421
+ const config = { value: null, matchMode: currConfig.defaultMatchMode };
422
+ // set internal filter constraint
423
+ this.setState(filterSetStateOnChange(config, config?.matchMode, config?.value, currConfig.descriptor.filterType, currConfig.dateConfig));
424
+ }
425
+ setDisplayValue(displayValue) {
426
+ const config = this.#config();
427
+ if (config == null) {
428
+ return;
429
+ }
430
+ this.setState(filterSetStateOnDisplayChange(this.state(), this.state()?.displayMatchMode ?? config.defaultMatchMode, displayValue, config.descriptor.filterType, config.dateConfig));
431
+ }
432
+ setState(state, updateTable = true) {
433
+ const currentMetadata = this.#config();
434
+ if (currentMetadata == null) {
435
+ return;
436
+ }
437
+ if (state && !state.displayMatchMode)
438
+ state.displayMatchMode = state.matchMode;
439
+ if (state && !state.displayValue)
440
+ state.displayValue = state.value;
441
+ this.#state.set(state);
442
+ if (updateTable) {
443
+ this.#tableData.updateFilters({ [currentMetadata.descriptor.property]: state });
444
+ }
445
+ }
446
+ #updateStateIfRequired(config, state, currTableFilterState, updateTable = true) {
447
+ if (config == null) {
448
+ return;
449
+ }
450
+ if (!updateTable && currTableFilterState == undefined) {
451
+ currTableFilterState = {};
452
+ }
453
+ if (currTableFilterState && (!state || state.value !== currTableFilterState.value || state.matchMode !== currTableFilterState.matchMode)) {
454
+ this.setState(filterSetStateOnChange(currTableFilterState, currTableFilterState.matchMode, currTableFilterState.value, untracked(() => config.descriptor.filterType), untracked(() => config.dateConfig)), updateTable);
455
+ }
456
+ }
457
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FilterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
458
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FilterService }); }
459
+ }
460
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FilterService, decorators: [{
461
+ type: Injectable
462
+ }], ctorParameters: () => [] });
463
+
464
+ /**
465
+ * Cannot be on push change detection strategy because of filter updates triggered from route which causes to force update values in force metadata
466
+ * and these must be propagated through to this component and beyond to primeNG.
467
+ */
468
+ class TableFilterComponent {
469
+ #el;
470
+ #renderer;
471
+ #overlayService;
472
+ #cd;
473
+ #document;
474
+ #window;
475
+ #overlaySubscription;
476
+ #overlay;
477
+ #scrollHandler;
478
+ #documentClickListener;
479
+ #documentResizeListener;
480
+ #resetSubscription;
481
+ #selfClick;
482
+ #overlayEventListener;
483
+ #numericValueFromModelChange;
484
+ #dateDebounceSubject;
485
+ constructor() {
486
+ this.lookupTypeDropdown = FilterLookupTypeEnum.Dropdown;
487
+ this.lookupTypeAutocomplete = FilterLookupTypeEnum.Autocomplete;
488
+ this.FilterTypeEnum = FilterTypeEnum;
489
+ this.FilterMatchMode = FilterMatchMode;
490
+ this.#el = inject(ElementRef);
491
+ this.#renderer = inject(Renderer2);
492
+ this.#overlayService = inject(OverlayService);
493
+ this.#cd = inject(ChangeDetectorRef);
494
+ this.filter = inject(FilterService);
495
+ this.#document = window.document;
496
+ this.#window = this.#document.defaultView;
497
+ this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
498
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
499
+ this.showFilterIcon = input(false, ...(ngDevMode ? [{ debugName: "showFilterIcon", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
500
+ this.showTitleAsPlaceholder = input(false, ...(ngDevMode ? [{ debugName: "showTitleAsPlaceholder", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
501
+ this.descriptorAsLookup = computed(() => this.config().descriptor instanceof FilterLookupDescriptor ? this.config().descriptor : undefined, ...(ngDevMode ? [{ debugName: "descriptorAsLookup" }] : []));
502
+ this.icon = viewChild('icon', ...(ngDevMode ? [{ debugName: "icon" }] : []));
503
+ this.matchModes = computed(() => this.config().matchModes, ...(ngDevMode ? [{ debugName: "matchModes" }] : []));
504
+ this.isInputDisabled = computed(() => this.filter.state()?.matchMode === FilterMatchMode.Exists || this.filter.state()?.matchMode === FilterMatchMode.DoesNotExist, ...(ngDevMode ? [{ debugName: "isInputDisabled" }] : []));
505
+ this.overlayVisible = signal(false, ...(ngDevMode ? [{ debugName: "overlayVisible" }] : []));
506
+ // display configs
507
+ this.isMultiselect = computed(() => {
508
+ const ft = this.filter.state();
509
+ const matchMode = ft?.displayMatchMode ?? this.config().defaultMatchMode;
510
+ return (matchMode === FilterMatchMode.In || matchMode === FilterMatchMode.NotIn) && (ft?.displayValue == null || Array.isArray(ft.displayValue));
511
+ }, ...(ngDevMode ? [{ debugName: "isMultiselect" }] : []));
512
+ this.placeholderKey = computed(() => {
513
+ const descriptor = this.config().descriptor;
514
+ let defaultPlaceholderKey = 'mngTable.typeToFilter';
515
+ const descriptorAsLookup = this.descriptorAsLookup();
516
+ if (descriptorAsLookup) {
517
+ if (descriptorAsLookup.lookupType === FilterLookupTypeEnum.Autocomplete) {
518
+ defaultPlaceholderKey = 'mngTable.searchToFilter';
519
+ }
520
+ else if (descriptorAsLookup.lookupType === FilterLookupTypeEnum.Dropdown) {
521
+ defaultPlaceholderKey = 'mngTable.selectToFilter';
522
+ }
523
+ }
524
+ else if (descriptor.filterType === FilterTypeEnum.Boolean) {
525
+ defaultPlaceholderKey = 'mngTable.selectToFilter';
526
+ }
527
+ return this.showTitleAsPlaceholder() ? this.#getPropertyLabelKey(this.config().descriptor) : defaultPlaceholderKey;
528
+ }, ...(ngDevMode ? [{ debugName: "placeholderKey" }] : []));
529
+ this.booleanOptions = [
530
+ { label: 'general.yes', value: true },
531
+ { label: 'general.no', value: false }
532
+ ];
533
+ this.#numericValueFromModelChange = null;
534
+ this.#dateDebounceSubject = new Subject();
535
+ effectWithDeps([this.config], ([config]) => {
536
+ this.filter.setConfig(config);
537
+ });
538
+ this.#dateDebounceSubject.pipe(debounceTime(500), distinctUntilChanged(), takeUntilDestroyed()).subscribe(v => this.filter.setDisplayValue(v));
539
+ }
540
+ ngOnDestroy() {
541
+ if (this.#overlay) {
542
+ this.#renderer.appendChild(this.#el.nativeElement, this.#overlay);
543
+ ZIndexUtils.clear(this.#overlay);
544
+ this.#onOverlayHide();
545
+ }
546
+ this.#resetSubscription?.unsubscribe();
547
+ this.#overlaySubscription?.unsubscribe();
548
+ }
549
+ onTextModelChange(event) {
550
+ const value = event.target.value;
551
+ if (value === '') {
552
+ this.filter.setDisplayValue(value);
553
+ }
554
+ }
555
+ onTextInputEnterKeyDown(event) {
556
+ const value = event.target.value;
557
+ this.filter.setDisplayValue(value);
558
+ event.preventDefault();
559
+ }
560
+ onNumericModelChange(value) {
561
+ this.#numericValueFromModelChange = value;
562
+ if (value === null) {
563
+ this.filter.setDisplayValue(value);
564
+ }
565
+ }
566
+ onNumericInputKeyDown(event) {
567
+ if (event.key === 'Enter') {
568
+ if (this.filter.state()?.displayMatchMode === FilterMatchMode.Between && Array.isArray(this.#numericValueFromModelChange)) {
569
+ const numberValues = this.#numericValueFromModelChange.filter(v => typeof v === 'number');
570
+ if (numberValues.length !== 2) {
571
+ return;
572
+ }
573
+ }
574
+ this.filter.setDisplayValue(this.#numericValueFromModelChange);
575
+ event.preventDefault();
576
+ }
577
+ }
578
+ onDateFilterModelChange(value) {
579
+ if (this.filter.state()?.displayMatchMode === FilterMatchMode.Between && Array.isArray(value)) {
580
+ const dateValues = value.filter(v => v instanceof Date);
581
+ if (dateValues.length !== 2) {
582
+ return;
583
+ }
584
+ }
585
+ this.#dateDebounceSubject.next(value);
586
+ }
587
+ booleanFilter(value) {
588
+ this.filter.setDisplayValue(value);
589
+ }
590
+ autocompleteFilter(value) {
591
+ this.filter.setDisplayValue(value);
592
+ }
593
+ dropdownFilter(value) {
594
+ this.filter.setDisplayValue(value);
595
+ }
596
+ onMatchModeChange(displayMatchMode) {
597
+ this.filter.setMatchMode(displayMatchMode);
598
+ this.#hideOverlay();
599
+ }
600
+ onMatchModeKeyDown(event) {
601
+ const item = event.target;
602
+ switch (event.key) {
603
+ case 'ArrowDown':
604
+ // eslint-disable-next-line no-case-declarations
605
+ const nextItem = this.#findNextMenuModeItem(item);
606
+ if (nextItem) {
607
+ item.removeAttribute('tabindex');
608
+ nextItem.tabIndex = '0';
609
+ nextItem.focus();
610
+ }
611
+ event.preventDefault();
612
+ break;
613
+ case 'ArrowUp':
614
+ // eslint-disable-next-line no-case-declarations
615
+ const prevItem = this.#findPrevMenuModeItem(item);
616
+ if (prevItem) {
617
+ item.removeAttribute('tabindex');
618
+ prevItem.tabIndex = '0';
619
+ prevItem.focus();
620
+ }
621
+ event.preventDefault();
622
+ break;
623
+ }
624
+ }
625
+ onCaseSensitivityToggle() {
626
+ this.filter.toggleCaseSensitivity();
627
+ }
628
+ clear() {
629
+ this.filter.clear();
630
+ this.#hideOverlay();
631
+ }
632
+ toggleMenu(event) {
633
+ this.overlayVisible.set(!this.overlayVisible());
634
+ event.stopPropagation();
635
+ }
636
+ onToggleButtonKeyDown(event) {
637
+ switch (event.key) {
638
+ case 'Escape':
639
+ case 'Tab':
640
+ this.overlayVisible.set(false);
641
+ break;
642
+ case 'ArrowDown':
643
+ if (this.overlayVisible()) {
644
+ const focusable = DomHandler.getFocusableElements(this.#overlay);
645
+ if (focusable) {
646
+ focusable[0].focus();
647
+ }
648
+ event.preventDefault();
649
+ }
650
+ else if (event.altKey) {
651
+ this.overlayVisible.set(true);
652
+ event.preventDefault();
653
+ }
654
+ break;
655
+ }
656
+ }
657
+ onEscape() {
658
+ this.overlayVisible.set(false);
659
+ }
660
+ onContentClick() {
661
+ this.#selfClick = true;
662
+ }
663
+ // onOverlayAnimationStart(event: AnimationEvent) {
664
+ onOverlayAnimationStart(event) {
665
+ switch (event.toState) {
666
+ case 'visible':
667
+ this.#overlay = event.element;
668
+ this.#renderer.appendChild(this.#document.body, this.#overlay);
669
+ // instead of following (commented) line, we use the one below to set z-index of overlay to 1000 (which is primeNG default)
670
+ // ZIndexUtils.set('overlay', this.#overlay, this.#tableMetadata.primeConfig.zIndex.overlay);
671
+ ZIndexUtils.set('overlay', this.#overlay, 1000);
672
+ DomHandler.absolutePosition(this.#overlay, this.icon()?.nativeElement);
673
+ this.#bindDocumentClickListener();
674
+ this.#bindDocumentResizeListener();
675
+ this.#bindScrollListener();
676
+ this.#overlayEventListener = (e) => {
677
+ if (this.#overlay && this.#overlay.contains(e.target)) {
678
+ this.#selfClick = true;
679
+ }
680
+ };
681
+ this.#overlaySubscription = this.#overlayService.clickObservable.subscribe(this.#overlayEventListener);
682
+ break;
683
+ case 'void':
684
+ this.#onOverlayHide();
685
+ this.#overlaySubscription?.unsubscribe();
686
+ break;
687
+ }
688
+ }
689
+ // onOverlayAnimationEnd(event: AnimationEvent) {
690
+ onOverlayAnimationEnd(event) {
691
+ switch (event.toState) {
692
+ case 'void':
693
+ ZIndexUtils.clear(event.element);
694
+ break;
695
+ }
696
+ }
697
+ #findNextMenuModeItem(item) {
698
+ const nextItem = item.nextElementSibling;
699
+ if (nextItem)
700
+ return DomHandler.hasClass(nextItem, 'p-column-filter-separator') ? this.#findNextMenuModeItem(nextItem) : nextItem;
701
+ else
702
+ return item.parentElement?.firstElementChild;
703
+ }
704
+ #findPrevMenuModeItem(item) {
705
+ const prevItem = item.previousElementSibling;
706
+ if (prevItem)
707
+ return DomHandler.hasClass(prevItem, 'p-column-filter-separator') ? this.#findPrevMenuModeItem(prevItem) : prevItem;
708
+ else
709
+ return item.parentElement?.lastElementChild;
710
+ }
711
+ #isOutsideClicked(event) {
712
+ return !(this.#overlay?.isSameNode(event.target) ||
713
+ this.#overlay?.contains(event.target) ||
714
+ this.icon()?.nativeElement.isSameNode(event.target) ||
715
+ this.icon()?.nativeElement.contains(event.target) ||
716
+ DomHandler.hasClass(event.target, 'p-column-filter-add-button') ||
717
+ DomHandler.hasClass(event.target.parentElement, 'p-column-filter-add-button') ||
718
+ DomHandler.hasClass(event.target, 'p-column-filter-remove-button') ||
719
+ DomHandler.hasClass(event.target.parentElement, 'p-column-filter-remove-button'));
720
+ }
721
+ #bindDocumentClickListener() {
722
+ if (!this.#documentClickListener) {
723
+ const documentTarget = this.#el ? this.#el.nativeElement.ownerDocument : 'document';
724
+ this.#documentClickListener = this.#renderer.listen(documentTarget, 'click', event => {
725
+ if (this.overlayVisible() && !this.#selfClick && this.#isOutsideClicked(event)) {
726
+ this.#hideOverlay();
727
+ }
728
+ this.#selfClick = false;
729
+ });
730
+ }
731
+ }
732
+ #unbindDocumentClickListener() {
733
+ if (this.#documentClickListener) {
734
+ this.#documentClickListener();
735
+ this.#documentClickListener = null;
736
+ this.#selfClick = false;
737
+ }
738
+ }
739
+ #bindDocumentResizeListener() {
740
+ if (!this.#documentResizeListener) {
741
+ this.#documentResizeListener = this.#renderer.listen(this.#window, 'resize', () => {
742
+ if (this.overlayVisible() && !DomHandler.isTouchDevice()) {
743
+ this.#hideOverlay();
744
+ }
745
+ });
746
+ }
747
+ }
748
+ #unbindDocumentResizeListener() {
749
+ if (this.#documentResizeListener) {
750
+ this.#documentResizeListener();
751
+ this.#documentResizeListener = null;
752
+ }
753
+ }
754
+ #bindScrollListener() {
755
+ if (!this.#scrollHandler) {
756
+ this.#scrollHandler = new ConnectedOverlayScrollHandler(this.icon()?.nativeElement, () => {
757
+ if (this.overlayVisible()) {
758
+ this.#hideOverlay();
759
+ }
760
+ });
761
+ }
762
+ this.#scrollHandler.bindScrollListener();
763
+ }
764
+ #unbindScrollListener() {
765
+ if (this.#scrollHandler) {
766
+ this.#scrollHandler.unbindScrollListener();
767
+ }
768
+ }
769
+ #hideOverlay() {
770
+ this.overlayVisible.set(false);
771
+ this.#cd.markForCheck();
772
+ }
773
+ #onOverlayHide() {
774
+ this.#unbindDocumentClickListener();
775
+ this.#unbindDocumentResizeListener();
776
+ this.#unbindScrollListener();
777
+ this.#overlay = null;
778
+ }
779
+ #getPropertyLabelKey(filterDescriptor) {
780
+ let labelKey;
781
+ if (filterDescriptor.title !== undefined && !filterDescriptor.titleUseModelBase) {
782
+ labelKey = filterDescriptor.title;
783
+ }
784
+ else {
785
+ labelKey = getI18nTypePropertyKey(this.model().i18nBaseKey, filterDescriptor.title ?? filterDescriptor.property);
786
+ }
787
+ return labelKey;
788
+ }
789
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
790
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableFilterComponent, isStandalone: true, selector: "mng-table-filter", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, showFilterIcon: { classPropertyName: "showFilterIcon", publicName: "showFilterIcon", isSignal: true, isRequired: false, transformFunction: null }, showTitleAsPlaceholder: { classPropertyName: "showTitleAsPlaceholder", publicName: "showTitleAsPlaceholder", isSignal: true, isRequired: false, transformFunction: null } }, providers: [FilterService], viewQueries: [{ propertyName: "icon", first: true, predicate: ["icon"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex items-center\">\n @let requiredFilterMissing = config().descriptor.isRequired && !filter.isActive();\n @let placeholder = (placeholderKey() | translate) + (config().descriptor.isRequired ? ' *' : '');\n <div\n class=\"flex items-center [&_p-inputgroup-addon]:p-0!\"\n [class.mng-filter-active]=\"filter.isActive()\"\n [class.[&_*]:border-red-500!]=\"requiredFilterMissing\"\n [class.mng-filter-required]=\"requiredFilterMissing\">\n @switch (config().descriptor.filterType) {\n @case (FilterTypeEnum.Number) {\n @if (filter.state()?.displayMatchMode === 'between') {\n <mng-number-range\n vertical=\"true\"\n className=\"mng-filter-number\"\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (keyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"placeholder\"\n [useGrouping]=\"config().descriptor.numberUseGrouping\"\n [minFractionDigits]=\"config().numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"config().numberConfig?.fractionsMax\"\n [disabled]=\"isInputDisabled()\"\n [templates]=\"showFilterIcon() ? [numberRangePrependIcon] : []\" />\n } @else {\n <p-inputgroup>\n @if (showFilterIcon()) {\n <p-inputgroup-addon>\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </p-inputgroup-addon>\n }\n <p-inputNumber\n inputStyleClass=\"mng-filter-number\"\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (onKeyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"placeholder\"\n [useGrouping]=\"config().descriptor.numberUseGrouping\"\n [minFractionDigits]=\"config().numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"config().numberConfig?.fractionsMax\"\n [disabled]=\"isInputDisabled()\" />\n </p-inputgroup>\n }\n }\n\n @case (FilterTypeEnum.Boolean) {\n <mng-dropdown\n optionsLabelProperty=\"label\"\n optionsValueProperty=\"value\"\n [ngModel]=\"filter.state()?.displayValue\"\n [options]=\"booleanOptions\"\n [optionsLabelTranslate]=\"true\"\n [placeholder]=\"placeholder\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"booleanFilter($event)\"\n [templates]=\"showFilterIcon() ? [dropdownPrependIcon] : []\">\n </mng-dropdown>\n }\n @case (FilterTypeEnum.Date) {\n @if (filter.state()?.displayMatchMode === FilterMatchMode.Between) {\n <mng-date-range\n vertical=\"true\"\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [inputStyleClass]=\"showFilterIcon() ? '!rounded-s-none' : ''\"\n [showTime]=\"config().dateConfig?.showTime ?? false\"\n [showSeconds]=\"config().dateConfig?.showSeconds ?? false\"\n [dateFormat]=\"config().dateConfig?.format\"\n [placeholder]=\"placeholder\"\n [disabled]=\"isInputDisabled()\"\n [templates]=\"showFilterIcon() ? [dateRangePrependIcon] : []\" />\n } @else {\n <p-inputgroup>\n @if (showFilterIcon()) {\n <p-inputgroup-addon>\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </p-inputgroup-addon>\n }\n <mng-datetime-picker\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [inputStyleClass]=\"showFilterIcon() ? '!rounded-s-none' : ''\"\n [placeholder]=\"placeholder\"\n showIcon=\"true\"\n [time]=\"config().dateConfig?.showTime ?? false\"\n [seconds]=\"config().dateConfig?.showSeconds ?? false\"\n [milliseconds]=\"config().dateConfig?.showMilliseconds ?? false\"\n [primeTimePicker]=\"config().dateConfig?.primeTimePicker ?? false\"\n [timeSelect]=\"config().dateConfig?.timeSelect ?? true\"\n [timeSelectInterval]=\"config().dateConfig?.timeSelectInterval ?? 60\"\n [dateFormat]=\"config().dateConfig?.format\"\n required=\"true\" />\n </p-inputgroup>\n }\n }\n @case (FilterTypeEnum.Lookup) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\" />\n }\n @case (FilterTypeEnum.LookupEnum) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\" />\n }\n @default {\n <p-inputgroup>\n @if (showFilterIcon()) {\n <p-inputgroup-addon>\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </p-inputgroup-addon>\n }\n <input\n type=\"text\"\n pInputText\n class=\"mng-filter-string\"\n [value]=\"filter.state()?.displayValue ?? ''\"\n [disabled]=\"isInputDisabled()\"\n (input)=\"onTextModelChange($event)\"\n (keydown.enter)=\"onTextInputEnterKeyDown($event)\"\n [attr.placeholder]=\"placeholder\"\n [mngInputTrim]=\"config().descriptor.trimOption\" />\n </p-inputgroup>\n }\n }\n\n <ng-template #lookupFilter>\n @if (descriptorAsLookup(); as lookup) {\n @switch (lookup.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n *mngRerender=\"isMultiselect()\"\n [ngModel]=\"filter.state()?.displayValue\"\n [dataProvider]=\"lookup.dataProvider\"\n [optionsTrackProperty]=\"lookup.optionsValueProperty\"\n [optionsValueProperty]=\"lookup.optionsValueProperty\"\n [optionsLabelProperty]=\"lookup.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookup.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [autoClear]=\"lookup.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookup.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookup.autocompleteInlineSearch ?? false\"\n [placeholder]=\"placeholder\"\n [className]=\"lookup.className\"\n [dropdownClassName]=\"lookup.dropdownClassName\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"autocompleteFilter($event)\"\n [searchTrim]=\"config().descriptor.trimOption\"\n [templates]=\"showFilterIcon() ? [autocompletePrependIcon] : []\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n *mngRerender=\"isMultiselect()\"\n [ngModel]=\"filter.state()?.displayValue\"\n [dataProvider]=\"lookup.dataProvider\"\n [optionsValueProperty]=\"lookup.optionsValueProperty\"\n [optionsLabelProperty]=\"lookup.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookup.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [placeholder]=\"placeholder\"\n [className]=\"lookup.className\"\n [dropdownClassName]=\"lookup.dropdownClassName\"\n [showClear]=\"false\"\n [changeValueOnBlur]=\"isMultiselect()\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"dropdownFilter($event)\"\n [templates]=\"showFilterIcon() ? [dropdownPrependIcon] : []\">\n </mng-dropdown>\n }\n }\n }\n </ng-template>\n\n <ng-template mngAutocompleteTemplate name=\"prepend\" #autocompletePrependIcon=\"mngAutocompleteTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n <ng-template mngDropdownTemplate name=\"prepend\" #dropdownPrependIcon=\"mngDropdownTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n <ng-template mngDateRangeTemplate name=\"prepend\" #dateRangePrependIcon=\"mngDateRangeTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n <ng-template mngNumberRangeTemplate name=\"prepend\" #numberRangePrependIcon=\"mngNumberRangeTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n\n <ng-template #iconTemplate>\n <button\n #icon\n class=\"mng-filter-options mng-filter-icon cursor-pointer pi pi-filter w-full h-full rounded-tl-md rounded-bl-md\"\n (click)=\"toggleMenu($event)\"\n (keydown)=\"onToggleButtonKeyDown($event)\"></button>\n </ng-template>\n\n @if (overlayVisible()) {\n <div\n class=\"p-datatable-filter-overlay\"\n (click)=\"onContentClick()\"\n [@overlayAnimation]=\"'visible'\"\n (@overlayAnimation.start)=\"onOverlayAnimationStart($event)\"\n (@overlayAnimation.done)=\"onOverlayAnimationEnd($event)\"\n (keydown.escape)=\"onEscape()\">\n <ul class=\"p-datatable-filter-constraint-list\">\n @for (matchMode of matchModes(); track matchMode; let i = $index) {\n <li\n class=\"p-datatable-filter-constraint\"\n [class.p-datatable-filter-constraint-selected]=\"matchMode.value === filter.state()?.displayMatchMode\"\n (click)=\"onMatchModeChange(matchMode.value)\"\n (keydown)=\"onMatchModeKeyDown($event)\"\n (keydown.enter)=\"this.onMatchModeChange(matchMode.value)\"\n [attr.tabindex]=\"i === 0 ? '0' : null\">\n {{ matchMode.label }}\n </li>\n }\n @if (config().descriptor.filterType === FilterTypeEnum.String) {\n <li class=\"p-datatable-filter-constraint-separator\" (keydown)=\"onMatchModeKeyDown($event)\"></li>\n <li\n class=\"p-datatable-filter-constraint\"\n (click)=\"onCaseSensitivityToggle()\"\n (keydown)=\"onMatchModeKeyDown($event)\"\n (keydown.enter)=\"onCaseSensitivityToggle()\">\n <div class=\"flex items-center\">\n <span class=\"mr-2\"> {{ 'mngFilter.caseSensitive' | translate }} </span>\n <p-toggle-switch [ngModel]=\"filter.state()?.caseSensitive || false\" class=\"ml-auto pointer-events-none\"></p-toggle-switch>\n </div>\n </li>\n }\n <li class=\"p-datatable-filter-constraint-separator\" (keydown)=\"onMatchModeKeyDown($event)\"></li>\n <li class=\"p-datatable-filter-constraint\" (click)=\"clear()\" (keydown)=\"onMatchModeKeyDown($event)\" (keydown.enter)=\"clear()\">\n {{ 'mngPrime.noFilter' | translate }}\n </li>\n </ul>\n </div>\n }\n </div>\n\n @if (!showFilterIcon()) {\n <button\n #icon\n class=\"mng-filter-options cursor-pointer ml-1\"\n [ngClass]=\"{\n 'text-primary': filter.isActive(),\n 'text-slate-400': !filter.isActive()\n }\"\n (click)=\"toggleMenu($event)\"\n (keydown)=\"onToggleButtonKeyDown($event)\">\n <i class=\"pi pi-ellipsis-v\"></i>\n </button>\n }\n</div>\n", styles: ["mng-table-filter{--filter-active-bg: var(--color-primary-50);--filter-active-color: var(--color-primary-600)}mng-table-filter .mng-filter-string{min-width:135px}mng-table-filter .mng-filter-number{min-width:165px}mng-table-filter .mng-filter-date{min-width:170px}mng-table-filter .mng-filter-boolean{min-width:80px}mng-table-filter .mng-filter-lookup,mng-table-filter .mng-filter-lookupenum{min-width:180px}mng-table-filter .mng-filter-required{position:relative}mng-table-filter p-tag.mng-filter-required{border:1px solid var(--color-red-500)}mng-table-filter .mng-filter-required:after{content:\"\";position:absolute;top:0;right:0;width:1rem;height:1rem;background-color:var(--color-red-500);z-index:1;clip-path:polygon(0 0,100% 0,100% 100%,0 0);border-top-right-radius:var(--p-inputgroup-addon-border-radius)}mng-table-filter .mng-filter-icon{color:var(--p-inputgroup-addon-color)}mng-table-filter .mng-filter-icon:hover{background:var(--p-select-filled-hover-background)}mng-table-filter .mng-filter-active *{border-color:var(--filter-active-color)!important}mng-table-filter .mng-filter-active p-inputgroup-addon,mng-table-filter .mng-filter-active input,mng-table-filter .mng-filter-active p-select,mng-table-filter .mng-filter-active p-multiselect,mng-table-filter .mng-filter-active .p-autocomplete-input-multiple{background:var(--filter-active-bg)}mng-table-filter .mng-filter-active .mng-filter-icon{color:var(--filter-active-color)}:root[class*=app-dark] mng-table-filter{--filter-active-bg: var(--p-surface-800);--filter-active-color: var(--p-surface-400)}\n"], dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: DateRangeComponent, selector: "mng-date-range", inputs: ["placeholder", "showTime", "showSeconds", "milliseconds", "primeTimePicker", "timeSelect", "timeSelectInterval", "dateFormat", "className", "inputStyleClass", "required", "disabled", "vertical", "templates"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AutocompleteComponent, selector: "mng-autocomplete", inputs: ["dataProvider", "optionsTrackProperty", "optionsValueProperty", "optionsLabelProperty", "optionsLabelTranslate", "inlineSearch", "openOnFocus", "multiselect", "placeholder", "className", "dropdownClassName", "showClear", "autoClear", "selectFirst", "searchTrim", "disabled", "templates"], outputs: ["valueChange", "blur"] }, { kind: "component", type: DropdownComponent, selector: "mng-dropdown", inputs: ["dataProvider", "options", "optionsTrackProperty", "optionsLabelProperty", "optionsLabelTranslate", "optionsValueProperty", "optionsDisabledProperty", "multiselect", "placeholder", "showClear", "selectFirstItem", "className", "dropdownClassName", "changeValueOnBlur", "loading", "disabled", "allowInput", "appendTo", "templates", "inlineSearch", "searchTrim"], outputs: ["valueChange", "blur"] }, { kind: "component", type: InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: InputTrimDirective, selector: "[mngInputTrim]", inputs: ["mngInputTrim"] }, { kind: "component", type: NumberRangeComponent, selector: "mng-number-range", inputs: ["placeholder", "useGrouping", "minFractionDigits", "maxFractionDigits", "required", "disabled", "vertical", "templates", "className"], outputs: ["keyDown"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RerenderDirective, selector: "[mngRerender]", inputs: ["mngRerender"] }, { kind: "component", type: InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "component", type: InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "directive", type: AutocompleteTemplateDirective, selector: "[mngAutocompleteTemplate]", inputs: ["name"], exportAs: ["mngAutocompleteTemplate"] }, { kind: "directive", type: DropdownTemplateDirective, selector: "[mngDropdownTemplate]", inputs: ["name"], exportAs: ["mngDropdownTemplate"] }, { kind: "directive", type: DateRangeTemplateDirective, selector: "[mngDateRangeTemplate]", inputs: ["name"], exportAs: ["mngDateRangeTemplate"] }, { kind: "directive", type: NumberRangeTemplateDirective, selector: "[mngNumberRangeTemplate]", inputs: ["name"], exportAs: ["mngNumberRangeTemplate"] }, { kind: "component", type: DatetimePickerComponent, selector: "mng-datetime-picker", inputs: ["templates", "time", "timeSelect", "timeSelectInterval", "seconds", "milliseconds", "primeTimePicker", "dateFormat", "placeholder", "minDate", "maxDate", "disabled", "required", "showIcon", "showButtonBar", "showClear", "className", "panelStyleClass", "inputStyleClass", "dateRange"], outputs: ["blur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], animations: [
791
+ trigger('overlayAnimation', [
792
+ transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('.12s cubic-bezier(0, 0, 0.2, 1)')]),
793
+ transition(':leave', [animate('.1s linear', style({ opacity: 0 }))])
794
+ ])
795
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
796
+ }
797
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterComponent, decorators: [{
798
+ type: Component,
799
+ args: [{ selector: 'mng-table-filter', imports: [
800
+ TableModule,
801
+ TranslatePipe,
802
+ DateRangeComponent,
803
+ FormsModule,
804
+ AutocompleteComponent,
805
+ DropdownComponent,
806
+ InputNumber,
807
+ InputText,
808
+ InputTrimDirective,
809
+ NumberRangeComponent,
810
+ NgTemplateOutlet,
811
+ RerenderDirective,
812
+ InputGroup,
813
+ InputGroupAddon,
814
+ NgClass,
815
+ ToggleSwitch,
816
+ AutocompleteTemplateDirective,
817
+ DropdownTemplateDirective,
818
+ DateRangeTemplateDirective,
819
+ NumberRangeTemplateDirective,
820
+ DatetimePickerComponent
821
+ ], animations: [
822
+ trigger('overlayAnimation', [
823
+ transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('.12s cubic-bezier(0, 0, 0.2, 1)')]),
824
+ transition(':leave', [animate('.1s linear', style({ opacity: 0 }))])
825
+ ])
826
+ ], providers: [FilterService], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex items-center\">\n @let requiredFilterMissing = config().descriptor.isRequired && !filter.isActive();\n @let placeholder = (placeholderKey() | translate) + (config().descriptor.isRequired ? ' *' : '');\n <div\n class=\"flex items-center [&_p-inputgroup-addon]:p-0!\"\n [class.mng-filter-active]=\"filter.isActive()\"\n [class.[&_*]:border-red-500!]=\"requiredFilterMissing\"\n [class.mng-filter-required]=\"requiredFilterMissing\">\n @switch (config().descriptor.filterType) {\n @case (FilterTypeEnum.Number) {\n @if (filter.state()?.displayMatchMode === 'between') {\n <mng-number-range\n vertical=\"true\"\n className=\"mng-filter-number\"\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (keyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"placeholder\"\n [useGrouping]=\"config().descriptor.numberUseGrouping\"\n [minFractionDigits]=\"config().numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"config().numberConfig?.fractionsMax\"\n [disabled]=\"isInputDisabled()\"\n [templates]=\"showFilterIcon() ? [numberRangePrependIcon] : []\" />\n } @else {\n <p-inputgroup>\n @if (showFilterIcon()) {\n <p-inputgroup-addon>\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </p-inputgroup-addon>\n }\n <p-inputNumber\n inputStyleClass=\"mng-filter-number\"\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onNumericModelChange($event)\"\n (onKeyDown)=\"onNumericInputKeyDown($event)\"\n [placeholder]=\"placeholder\"\n [useGrouping]=\"config().descriptor.numberUseGrouping\"\n [minFractionDigits]=\"config().numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"config().numberConfig?.fractionsMax\"\n [disabled]=\"isInputDisabled()\" />\n </p-inputgroup>\n }\n }\n\n @case (FilterTypeEnum.Boolean) {\n <mng-dropdown\n optionsLabelProperty=\"label\"\n optionsValueProperty=\"value\"\n [ngModel]=\"filter.state()?.displayValue\"\n [options]=\"booleanOptions\"\n [optionsLabelTranslate]=\"true\"\n [placeholder]=\"placeholder\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"booleanFilter($event)\"\n [templates]=\"showFilterIcon() ? [dropdownPrependIcon] : []\">\n </mng-dropdown>\n }\n @case (FilterTypeEnum.Date) {\n @if (filter.state()?.displayMatchMode === FilterMatchMode.Between) {\n <mng-date-range\n vertical=\"true\"\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [inputStyleClass]=\"showFilterIcon() ? '!rounded-s-none' : ''\"\n [showTime]=\"config().dateConfig?.showTime ?? false\"\n [showSeconds]=\"config().dateConfig?.showSeconds ?? false\"\n [dateFormat]=\"config().dateConfig?.format\"\n [placeholder]=\"placeholder\"\n [disabled]=\"isInputDisabled()\"\n [templates]=\"showFilterIcon() ? [dateRangePrependIcon] : []\" />\n } @else {\n <p-inputgroup>\n @if (showFilterIcon()) {\n <p-inputgroup-addon>\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </p-inputgroup-addon>\n }\n <mng-datetime-picker\n [ngModel]=\"filter.state()?.displayValue\"\n (ngModelChange)=\"onDateFilterModelChange($event)\"\n [inputStyleClass]=\"showFilterIcon() ? '!rounded-s-none' : ''\"\n [placeholder]=\"placeholder\"\n showIcon=\"true\"\n [time]=\"config().dateConfig?.showTime ?? false\"\n [seconds]=\"config().dateConfig?.showSeconds ?? false\"\n [milliseconds]=\"config().dateConfig?.showMilliseconds ?? false\"\n [primeTimePicker]=\"config().dateConfig?.primeTimePicker ?? false\"\n [timeSelect]=\"config().dateConfig?.timeSelect ?? true\"\n [timeSelectInterval]=\"config().dateConfig?.timeSelectInterval ?? 60\"\n [dateFormat]=\"config().dateConfig?.format\"\n required=\"true\" />\n </p-inputgroup>\n }\n }\n @case (FilterTypeEnum.Lookup) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\" />\n }\n @case (FilterTypeEnum.LookupEnum) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\" />\n }\n @default {\n <p-inputgroup>\n @if (showFilterIcon()) {\n <p-inputgroup-addon>\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </p-inputgroup-addon>\n }\n <input\n type=\"text\"\n pInputText\n class=\"mng-filter-string\"\n [value]=\"filter.state()?.displayValue ?? ''\"\n [disabled]=\"isInputDisabled()\"\n (input)=\"onTextModelChange($event)\"\n (keydown.enter)=\"onTextInputEnterKeyDown($event)\"\n [attr.placeholder]=\"placeholder\"\n [mngInputTrim]=\"config().descriptor.trimOption\" />\n </p-inputgroup>\n }\n }\n\n <ng-template #lookupFilter>\n @if (descriptorAsLookup(); as lookup) {\n @switch (lookup.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n *mngRerender=\"isMultiselect()\"\n [ngModel]=\"filter.state()?.displayValue\"\n [dataProvider]=\"lookup.dataProvider\"\n [optionsTrackProperty]=\"lookup.optionsValueProperty\"\n [optionsValueProperty]=\"lookup.optionsValueProperty\"\n [optionsLabelProperty]=\"lookup.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookup.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [autoClear]=\"lookup.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookup.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookup.autocompleteInlineSearch ?? false\"\n [placeholder]=\"placeholder\"\n [className]=\"lookup.className\"\n [dropdownClassName]=\"lookup.dropdownClassName\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"autocompleteFilter($event)\"\n [searchTrim]=\"config().descriptor.trimOption\"\n [templates]=\"showFilterIcon() ? [autocompletePrependIcon] : []\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n *mngRerender=\"isMultiselect()\"\n [ngModel]=\"filter.state()?.displayValue\"\n [dataProvider]=\"lookup.dataProvider\"\n [optionsValueProperty]=\"lookup.optionsValueProperty\"\n [optionsLabelProperty]=\"lookup.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookup.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [placeholder]=\"placeholder\"\n [className]=\"lookup.className\"\n [dropdownClassName]=\"lookup.dropdownClassName\"\n [showClear]=\"false\"\n [changeValueOnBlur]=\"isMultiselect()\"\n [disabled]=\"isInputDisabled()\"\n (valueChange)=\"dropdownFilter($event)\"\n [templates]=\"showFilterIcon() ? [dropdownPrependIcon] : []\">\n </mng-dropdown>\n }\n }\n }\n </ng-template>\n\n <ng-template mngAutocompleteTemplate name=\"prepend\" #autocompletePrependIcon=\"mngAutocompleteTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n <ng-template mngDropdownTemplate name=\"prepend\" #dropdownPrependIcon=\"mngDropdownTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n <ng-template mngDateRangeTemplate name=\"prepend\" #dateRangePrependIcon=\"mngDateRangeTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n <ng-template mngNumberRangeTemplate name=\"prepend\" #numberRangePrependIcon=\"mngNumberRangeTemplate\">\n <ng-container *ngTemplateOutlet=\"iconTemplate\"></ng-container>\n </ng-template>\n\n <ng-template #iconTemplate>\n <button\n #icon\n class=\"mng-filter-options mng-filter-icon cursor-pointer pi pi-filter w-full h-full rounded-tl-md rounded-bl-md\"\n (click)=\"toggleMenu($event)\"\n (keydown)=\"onToggleButtonKeyDown($event)\"></button>\n </ng-template>\n\n @if (overlayVisible()) {\n <div\n class=\"p-datatable-filter-overlay\"\n (click)=\"onContentClick()\"\n [@overlayAnimation]=\"'visible'\"\n (@overlayAnimation.start)=\"onOverlayAnimationStart($event)\"\n (@overlayAnimation.done)=\"onOverlayAnimationEnd($event)\"\n (keydown.escape)=\"onEscape()\">\n <ul class=\"p-datatable-filter-constraint-list\">\n @for (matchMode of matchModes(); track matchMode; let i = $index) {\n <li\n class=\"p-datatable-filter-constraint\"\n [class.p-datatable-filter-constraint-selected]=\"matchMode.value === filter.state()?.displayMatchMode\"\n (click)=\"onMatchModeChange(matchMode.value)\"\n (keydown)=\"onMatchModeKeyDown($event)\"\n (keydown.enter)=\"this.onMatchModeChange(matchMode.value)\"\n [attr.tabindex]=\"i === 0 ? '0' : null\">\n {{ matchMode.label }}\n </li>\n }\n @if (config().descriptor.filterType === FilterTypeEnum.String) {\n <li class=\"p-datatable-filter-constraint-separator\" (keydown)=\"onMatchModeKeyDown($event)\"></li>\n <li\n class=\"p-datatable-filter-constraint\"\n (click)=\"onCaseSensitivityToggle()\"\n (keydown)=\"onMatchModeKeyDown($event)\"\n (keydown.enter)=\"onCaseSensitivityToggle()\">\n <div class=\"flex items-center\">\n <span class=\"mr-2\"> {{ 'mngFilter.caseSensitive' | translate }} </span>\n <p-toggle-switch [ngModel]=\"filter.state()?.caseSensitive || false\" class=\"ml-auto pointer-events-none\"></p-toggle-switch>\n </div>\n </li>\n }\n <li class=\"p-datatable-filter-constraint-separator\" (keydown)=\"onMatchModeKeyDown($event)\"></li>\n <li class=\"p-datatable-filter-constraint\" (click)=\"clear()\" (keydown)=\"onMatchModeKeyDown($event)\" (keydown.enter)=\"clear()\">\n {{ 'mngPrime.noFilter' | translate }}\n </li>\n </ul>\n </div>\n }\n </div>\n\n @if (!showFilterIcon()) {\n <button\n #icon\n class=\"mng-filter-options cursor-pointer ml-1\"\n [ngClass]=\"{\n 'text-primary': filter.isActive(),\n 'text-slate-400': !filter.isActive()\n }\"\n (click)=\"toggleMenu($event)\"\n (keydown)=\"onToggleButtonKeyDown($event)\">\n <i class=\"pi pi-ellipsis-v\"></i>\n </button>\n }\n</div>\n", styles: ["mng-table-filter{--filter-active-bg: var(--color-primary-50);--filter-active-color: var(--color-primary-600)}mng-table-filter .mng-filter-string{min-width:135px}mng-table-filter .mng-filter-number{min-width:165px}mng-table-filter .mng-filter-date{min-width:170px}mng-table-filter .mng-filter-boolean{min-width:80px}mng-table-filter .mng-filter-lookup,mng-table-filter .mng-filter-lookupenum{min-width:180px}mng-table-filter .mng-filter-required{position:relative}mng-table-filter p-tag.mng-filter-required{border:1px solid var(--color-red-500)}mng-table-filter .mng-filter-required:after{content:\"\";position:absolute;top:0;right:0;width:1rem;height:1rem;background-color:var(--color-red-500);z-index:1;clip-path:polygon(0 0,100% 0,100% 100%,0 0);border-top-right-radius:var(--p-inputgroup-addon-border-radius)}mng-table-filter .mng-filter-icon{color:var(--p-inputgroup-addon-color)}mng-table-filter .mng-filter-icon:hover{background:var(--p-select-filled-hover-background)}mng-table-filter .mng-filter-active *{border-color:var(--filter-active-color)!important}mng-table-filter .mng-filter-active p-inputgroup-addon,mng-table-filter .mng-filter-active input,mng-table-filter .mng-filter-active p-select,mng-table-filter .mng-filter-active p-multiselect,mng-table-filter .mng-filter-active .p-autocomplete-input-multiple{background:var(--filter-active-bg)}mng-table-filter .mng-filter-active .mng-filter-icon{color:var(--filter-active-color)}:root[class*=app-dark] mng-table-filter{--filter-active-bg: var(--p-surface-800);--filter-active-color: var(--p-surface-400)}\n"] }]
827
+ }], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], showFilterIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFilterIcon", required: false }] }], showTitleAsPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTitleAsPlaceholder", required: false }] }], icon: [{ type: i0.ViewChild, args: ['icon', { isSignal: true }] }] } });
828
+
829
+ var filter_component = /*#__PURE__*/Object.freeze({
830
+ __proto__: null,
831
+ TableFilterComponent: TableFilterComponent
832
+ });
833
+
834
+ class TableColumnValueComponent {
835
+ constructor() {
836
+ this.columnDisplayTypeString = ColumnDisplayTypeEnum.String;
837
+ this.columnDisplayTypeNumber = ColumnDisplayTypeEnum.Number;
838
+ this.columnDisplayTypeCurrency = ColumnDisplayTypeEnum.Currency;
839
+ this.columnDisplayTypeBoolean = ColumnDisplayTypeEnum.Boolean;
840
+ this.columnDisplayTypeDate = ColumnDisplayTypeEnum.Date;
841
+ this.columnDisplayTypeEnum = ColumnDisplayTypeEnum.Enum;
842
+ this.columnDisplayTypeComponent = ColumnDisplayTypeEnum.Component;
843
+ this.columnDisplayTypeHtml = ColumnDisplayTypeEnum.Html;
844
+ this.elementRef = inject(ElementRef);
845
+ this.messageService = inject(MessageService);
846
+ this.translate = inject(TranslateService);
847
+ this.getterPipe = new GetterPipe();
848
+ this.templatePipe = new TemplatePipe();
849
+ this.jsonPathPipe = new JsonPathPipe();
850
+ this.descriptor = input.required(...(ngDevMode ? [{ debugName: "descriptor" }] : []));
851
+ this.item = input.required(...(ngDevMode ? [{ debugName: "item" }] : []));
852
+ this.styleMaxWidth = computed(() => this.descriptor().maxWidth ?? null, ...(ngDevMode ? [{ debugName: "styleMaxWidth" }] : []));
853
+ this.className = computed(() => {
854
+ let className = 'nowrap';
855
+ if (this.descriptor().columnDisplayType === ColumnDisplayTypeEnum.String && this.descriptor().isMultiline) {
856
+ className += ' multiline';
857
+ }
858
+ return className;
859
+ }, ...(ngDevMode ? [{ debugName: "className" }] : []));
860
+ this.value = computed(() => {
861
+ let value = this.jsonPathPipe.transform(this.item(), `$.${this.descriptor().property}`);
862
+ if (typeof this.descriptor().getter === 'function') {
863
+ value = this.getterPipe.transform(value, this.descriptor().getter, this.item());
864
+ }
865
+ if (this.descriptor().template) {
866
+ value = this.templatePipe.transform(value, this.descriptor().template);
867
+ }
868
+ return value;
869
+ }, ...(ngDevMode ? [{ debugName: "value" }] : []));
870
+ this.currency = computed(() => {
871
+ if (this.descriptor().columnDisplayType === ColumnDisplayTypeEnum.Currency) {
872
+ return this.descriptor().currencyProperty ? this.item()[this.descriptor().currencyProperty] : (this.descriptor().currencyCode ?? 'EUR');
873
+ }
874
+ return;
875
+ }, ...(ngDevMode ? [{ debugName: "currency" }] : []));
876
+ this.hasCopyToClipboard = computed(() => this.descriptor().hasCopyToClipboard && this.value() != null, ...(ngDevMode ? [{ debugName: "hasCopyToClipboard" }] : []));
877
+ this.componentInputs = computed(() => {
878
+ const inputs = {
879
+ value: this.value(),
880
+ item: this.item(),
881
+ descriptor: this.descriptor()
882
+ };
883
+ if (this.descriptor().customComponentInputs) {
884
+ return { ...inputs, ...this.descriptor().customComponentInputs };
885
+ }
886
+ return inputs;
887
+ }, ...(ngDevMode ? [{ debugName: "componentInputs" }] : []));
888
+ }
889
+ copyToClipboard(event) {
890
+ event.stopPropagation();
891
+ let value = this.elementRef.nativeElement.innerText.trim();
892
+ const clipboardValueGetter = this.descriptor().clipboardValueGetter;
893
+ if (clipboardValueGetter) {
894
+ value = clipboardValueGetter(this.value(), this.item());
895
+ }
896
+ navigator.clipboard.writeText(value);
897
+ const title = this.translate.instant('mngTable.copyNotificationTitle');
898
+ const message = this.translate.instant('mngTable.copyNotificationMessage', { value });
899
+ this.messageService.add({ severity: 'info', summary: title, detail: message });
900
+ }
901
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnValueComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
902
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableColumnValueComponent, isStandalone: true, selector: "mng-table-column-value", inputs: { descriptor: { classPropertyName: "descriptor", publicName: "descriptor", isSignal: true, isRequired: true, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class": "className()", "style.max-width.px": "styleMaxWidth()" } }, ngImport: i0, template: "@if (descriptor().localizationExistsProperty && !item()[descriptor().localizationExistsProperty!]) {\n <i class=\"pi pi-exclamation-circle\" [pTooltip]=\"'mngTable.translationMissing' | translate\"></i>\n}\n@switch (descriptor().columnDisplayType) {\n @case (columnDisplayTypeString) {\n @if (descriptor().hasValueAsTooltip) {\n <span [pTooltip]=\"value()\" tooltipPosition=\"left\">{{ value() }}</span>\n } @else {\n {{ value() }}\n }\n }\n @case (columnDisplayTypeHtml) {\n <span [innerHTML]=\"value()\"></span>\n }\n @case (columnDisplayTypeNumber) {\n {{ value() | number: descriptor().displayFormat : descriptor().locale }}\n }\n @case (columnDisplayTypeCurrency) {\n {{ value() | currency: currency() : descriptor().currencyDisplay : descriptor().displayFormat : descriptor().locale }}\n }\n @case (columnDisplayTypeDate) {\n {{ value() | date: descriptor().displayFormat }}\n }\n @case (columnDisplayTypeBoolean) {\n @if (descriptor().booleanAsIcon) {\n <i [class]=\"value() | mngBoolean: descriptor().booleanYes : descriptor().booleanNo : true\"></i>\n } @else {\n {{ value() | mngBoolean: descriptor().booleanYes : descriptor().booleanNo | translate }}\n }\n }\n @case (columnDisplayTypeEnum) {\n {{ value() | mngEnum: descriptor().enum | translate }}\n }\n @case (columnDisplayTypeComponent) {\n <ng-container [mngComponent]=\"descriptor().customComponentType!\" [inputs]=\"componentInputs()\"></ng-container>\n }\n}\n@if (hasCopyToClipboard()) {\n <div class=\"help-buttons\">\n <button pButton type=\"button\" icon=\"pi pi-copy\" class=\"p-button-rounded p-button-info p-button-sm\" (click)=\"copyToClipboard($event)\"></button>\n </div>\n}\n", styles: [":host{display:inline-block;overflow:hidden}:host.nowrap{white-space:nowrap;text-overflow:ellipsis}:host.multiline{white-space:pre-wrap;word-wrap:break-word}.help-buttons{display:none;position:absolute;right:0;top:50%;transform:translateY(-50%)}.help-buttons .p-button{height:1.9rem;width:1.9rem;padding:0}\n"], dependencies: [{ kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "directive", type: ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: BooleanPipe, name: "mngBoolean" }, { kind: "pipe", type: EnumPipe, name: "mngEnum" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: CurrencyPipe, name: "currency" }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
903
+ }
904
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableColumnValueComponent, decorators: [{
905
+ type: Component,
906
+ args: [{ selector: 'mng-table-column-value', imports: [TranslatePipe, BooleanPipe, EnumPipe, ComponentDirective, DecimalPipe, CurrencyPipe, DatePipe, ButtonDirective, Tooltip], changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'className()', '[style.max-width.px]': 'styleMaxWidth()' }, template: "@if (descriptor().localizationExistsProperty && !item()[descriptor().localizationExistsProperty!]) {\n <i class=\"pi pi-exclamation-circle\" [pTooltip]=\"'mngTable.translationMissing' | translate\"></i>\n}\n@switch (descriptor().columnDisplayType) {\n @case (columnDisplayTypeString) {\n @if (descriptor().hasValueAsTooltip) {\n <span [pTooltip]=\"value()\" tooltipPosition=\"left\">{{ value() }}</span>\n } @else {\n {{ value() }}\n }\n }\n @case (columnDisplayTypeHtml) {\n <span [innerHTML]=\"value()\"></span>\n }\n @case (columnDisplayTypeNumber) {\n {{ value() | number: descriptor().displayFormat : descriptor().locale }}\n }\n @case (columnDisplayTypeCurrency) {\n {{ value() | currency: currency() : descriptor().currencyDisplay : descriptor().displayFormat : descriptor().locale }}\n }\n @case (columnDisplayTypeDate) {\n {{ value() | date: descriptor().displayFormat }}\n }\n @case (columnDisplayTypeBoolean) {\n @if (descriptor().booleanAsIcon) {\n <i [class]=\"value() | mngBoolean: descriptor().booleanYes : descriptor().booleanNo : true\"></i>\n } @else {\n {{ value() | mngBoolean: descriptor().booleanYes : descriptor().booleanNo | translate }}\n }\n }\n @case (columnDisplayTypeEnum) {\n {{ value() | mngEnum: descriptor().enum | translate }}\n }\n @case (columnDisplayTypeComponent) {\n <ng-container [mngComponent]=\"descriptor().customComponentType!\" [inputs]=\"componentInputs()\"></ng-container>\n }\n}\n@if (hasCopyToClipboard()) {\n <div class=\"help-buttons\">\n <button pButton type=\"button\" icon=\"pi pi-copy\" class=\"p-button-rounded p-button-info p-button-sm\" (click)=\"copyToClipboard($event)\"></button>\n </div>\n}\n", styles: [":host{display:inline-block;overflow:hidden}:host.nowrap{white-space:nowrap;text-overflow:ellipsis}:host.multiline{white-space:pre-wrap;word-wrap:break-word}.help-buttons{display:none;position:absolute;right:0;top:50%;transform:translateY(-50%)}.help-buttons .p-button{height:1.9rem;width:1.9rem;padding:0}\n"] }]
907
+ }], propDecorators: { descriptor: [{ type: i0.Input, args: [{ isSignal: true, alias: "descriptor", required: true }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }] } });
908
+
909
+ class FilterValuePipe {
910
+ constructor() {
911
+ this.locale = inject(LOCALE_ID);
912
+ this.translate = inject(TranslateService);
913
+ this.enumPipe = new EnumPipe();
914
+ this.subject = new ReplaySubject(1);
915
+ }
916
+ transform(value, descriptor) {
917
+ const valTransform = this.prepareValueTransform(value, descriptor);
918
+ this.subscription?.unsubscribe();
919
+ if (valTransform.translate && valTransform.valueArr.length > 0) {
920
+ this.subscription = this.translate.stream(valTransform.valueArr).subscribe((i18n) => {
921
+ this.subject.next(valTransform.valueArr.map(k => i18n[k]).join(', '));
922
+ });
923
+ }
924
+ else {
925
+ this.subject.next(valTransform.valueArr.join(', '));
926
+ }
927
+ return this.subject.asObservable();
928
+ }
929
+ /**
930
+ * If returns a string, this represents i18n key that must go through translation. If translation is not needed, undefined is returned.
931
+ */
932
+ prepareValueTransform(value, descriptor) {
933
+ const result = {
934
+ translate: false,
935
+ valueArr: Array.isArray(value) ? value : [value]
936
+ };
937
+ if (value == null) {
938
+ result.valueArr = [];
939
+ }
940
+ switch (descriptor?.filterType) {
941
+ case FilterTypeEnum.Date:
942
+ // eslint-disable-next-line no-case-declarations
943
+ const datePipe = new DatePipe(this.locale);
944
+ result.valueArr = result.valueArr.map(v => datePipe.transform(v, descriptor.displayFormat, descriptor.locale));
945
+ break;
946
+ case FilterTypeEnum.Number:
947
+ // eslint-disable-next-line no-case-declarations
948
+ const decimalPipe = new DecimalPipe(this.locale);
949
+ result.valueArr = result.valueArr.map(v => decimalPipe.transform(v, descriptor.displayFormat, descriptor.locale));
950
+ break;
951
+ case FilterTypeEnum.Boolean:
952
+ // eslint-disable-next-line no-case-declarations
953
+ const booleanPipe = new BooleanPipe();
954
+ result.valueArr = result.valueArr.map(v => booleanPipe.transform(v));
955
+ result.translate = true;
956
+ break;
957
+ case FilterTypeEnum.LookupEnum:
958
+ // eslint-disable-next-line no-case-declarations
959
+ const enumPipe = new EnumPipe();
960
+ result.valueArr = result.valueArr.map(v => enumPipe.transform(v, descriptor.enum));
961
+ result.translate = true;
962
+ break;
963
+ }
964
+ return result;
965
+ }
966
+ ngOnDestroy() {
967
+ this.subscription?.unsubscribe();
968
+ this.subject.complete();
969
+ }
970
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FilterValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
971
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FilterValuePipe, isStandalone: true, name: "mngFilterValue" }); }
972
+ }
973
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FilterValuePipe, decorators: [{
974
+ type: Pipe,
975
+ args: [{
976
+ name: 'mngFilterValue',
977
+ pure: true
978
+ }]
979
+ }] });
980
+
981
+ class TableFilterActiveTagComponent {
982
+ constructor() {
983
+ this.translateService = inject(TranslateService);
984
+ this.FilterMatchMode = FilterMatchMode;
985
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
986
+ this.filter = input.required(...(ngDevMode ? [{ debugName: "filter" }] : []));
987
+ this.edit = output();
988
+ this.remove = output();
989
+ this.toggleDisabled = output();
990
+ this.label = computed(() => this.getPropertyLabelKey(this.filter().config.descriptor), ...(ngDevMode ? [{ debugName: "label" }] : []));
991
+ this.matchMode = computed(() => this.filter().displayMatchMode, ...(ngDevMode ? [{ debugName: "matchMode" }] : []));
992
+ this.matchModeSymbol = computed(() => `mngFilterActiveTag.matchMode.${this.matchMode()}`, ...(ngDevMode ? [{ debugName: "matchModeSymbol" }] : []));
993
+ this.value = computed(() => this.filter().displayValue, ...(ngDevMode ? [{ debugName: "value" }] : []));
994
+ this.isActive = computed(() => this.filter()?.matchMode === FilterMatchMode.Exists || this.filter()?.matchMode === FilterMatchMode.DoesNotExist || !isFilterValueBlank(this.value()), ...(ngDevMode ? [{ debugName: "isActive" }] : []));
995
+ this.menuItems = signal([], ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
996
+ this.tagMenu = viewChild.required(Menu);
997
+ }
998
+ onRemove(event) {
999
+ event.stopPropagation();
1000
+ this.remove.emit({
1001
+ filter: this.filter(),
1002
+ event: event
1003
+ });
1004
+ }
1005
+ onEdit(event) {
1006
+ this.edit.emit({
1007
+ filter: this.filter(),
1008
+ event: event
1009
+ });
1010
+ }
1011
+ onDisable(event) {
1012
+ this.filter().disabled = !this.filter().disabled;
1013
+ this.toggleDisabled.emit({
1014
+ filter: this.filter(),
1015
+ event: event
1016
+ });
1017
+ }
1018
+ openTagMenu(event) {
1019
+ this.menuItems.set([
1020
+ {
1021
+ label: this.translateService.instant('mngFilterActiveTag.edit'),
1022
+ icon: 'pi pi-pencil',
1023
+ command: () => {
1024
+ // close the menu first
1025
+ this.tagMenu().hide();
1026
+ // open edit second
1027
+ setTimeout(() => this.onEdit(event), 0);
1028
+ }
1029
+ },
1030
+ { separator: true },
1031
+ {
1032
+ label: this.filter().disabled ? this.translateService.instant('mngFilterActiveTag.enable') : this.translateService.instant('mngFilterActiveTag.disable'),
1033
+ icon: this.filter().disabled ? 'pi pi-check-circle' : 'pi pi-ban',
1034
+ command: () => {
1035
+ this.onDisable(event);
1036
+ }
1037
+ },
1038
+ { separator: true },
1039
+ { label: this.translateService.instant('mngFilterActiveTag.remove'), icon: 'pi pi-times', command: () => this.onRemove(event) }
1040
+ ]);
1041
+ this.tagMenu().toggle(event);
1042
+ }
1043
+ getPropertyLabelKey(filterDescriptor) {
1044
+ if (filterDescriptor.isGenericFilter) {
1045
+ return filterDescriptor.property;
1046
+ }
1047
+ let labelKey;
1048
+ if (filterDescriptor.title !== undefined && !filterDescriptor.titleUseModelBase) {
1049
+ labelKey = filterDescriptor.title;
1050
+ }
1051
+ else {
1052
+ labelKey = getI18nTypePropertyKey(this.model().i18nBaseKey, filterDescriptor.title ?? filterDescriptor.property);
1053
+ }
1054
+ return labelKey;
1055
+ }
1056
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterActiveTagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1057
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableFilterActiveTagComponent, isStandalone: true, selector: "mng-table-filter-active-tag", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { edit: "edit", remove: "remove", toggleDisabled: "toggleDisabled" }, viewQueries: [{ propertyName: "tagMenu", first: true, predicate: Menu, descendants: true, isSignal: true }], ngImport: i0, template: "<p-tag\n [class.opacity-70]=\"filter().disabled\"\n severity=\"secondary\"\n styleClass=\"mr-1 mng-tag-outlined\"\n [class.mng-filter-required]=\"!isActive() && filter().config.descriptor.isRequired\">\n <div class=\"flex relative items-center gap-2 p-1 cursor-pointer\" (click)=\"openTagMenu($event)\">\n <span>{{ label() | translate }}</span>\n @if (matchMode() === FilterMatchMode.Between) {\n <span class=\"font-semibold\">{{ value()?.[0] | mngFilterValue: filter().config.descriptor | async }}</span>\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value()?.[1] | mngFilterValue: filter().config.descriptor | async }}</span>\n } @else {\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value() | mngFilterValue: filter().config.descriptor | async }}</span>\n @if (filter().caseSensitive) {\n <small class=\"border-solid border rounded px-1 text-primary-400\">Aa</small>\n }\n }\n <p-divider layout=\"vertical\" class=\"!p-0 !mx-[3px]\" />\n\n @if (isActive()) {\n <span class=\"pi pi-times text-xs\" (click)=\"onRemove($event)\"></span>\n }\n\n @if (filter().disabled) {\n <p-divider layout=\"horizontal\" class=\"!absolute left-0 !m-0 border-t opacity-50\"></p-divider>\n }\n </div>\n</p-tag>\n<p-menu [popup]=\"true\" [model]=\"menuItems()\" appendTo=\"body\"></p-menu>\n", styles: ["mng-table-filter-active-tag.p-tag.p-tag-secondary.mng-tag-outlined{background-color:unset;border:1px solid var(--mng-tag-secondary-outlined-border)}\n"], dependencies: [{ kind: "component", type: Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: Menu, selector: "p-menu", inputs: ["model", "popup", "style", "styleClass", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "ariaLabel", "ariaLabelledBy", "id", "tabindex", "appendTo"], outputs: ["onShow", "onHide", "onBlur", "onFocus"] }, { kind: "component", type: Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FilterValuePipe, name: "mngFilterValue" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1058
+ }
1059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterActiveTagComponent, decorators: [{
1060
+ type: Component,
1061
+ args: [{ selector: 'mng-table-filter-active-tag', imports: [TranslatePipe, FilterValuePipe, AsyncPipe, Tag, Menu, Divider], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<p-tag\n [class.opacity-70]=\"filter().disabled\"\n severity=\"secondary\"\n styleClass=\"mr-1 mng-tag-outlined\"\n [class.mng-filter-required]=\"!isActive() && filter().config.descriptor.isRequired\">\n <div class=\"flex relative items-center gap-2 p-1 cursor-pointer\" (click)=\"openTagMenu($event)\">\n <span>{{ label() | translate }}</span>\n @if (matchMode() === FilterMatchMode.Between) {\n <span class=\"font-semibold\">{{ value()?.[0] | mngFilterValue: filter().config.descriptor | async }}</span>\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value()?.[1] | mngFilterValue: filter().config.descriptor | async }}</span>\n } @else {\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value() | mngFilterValue: filter().config.descriptor | async }}</span>\n @if (filter().caseSensitive) {\n <small class=\"border-solid border rounded px-1 text-primary-400\">Aa</small>\n }\n }\n <p-divider layout=\"vertical\" class=\"!p-0 !mx-[3px]\" />\n\n @if (isActive()) {\n <span class=\"pi pi-times text-xs\" (click)=\"onRemove($event)\"></span>\n }\n\n @if (filter().disabled) {\n <p-divider layout=\"horizontal\" class=\"!absolute left-0 !m-0 border-t opacity-50\"></p-divider>\n }\n </div>\n</p-tag>\n<p-menu [popup]=\"true\" [model]=\"menuItems()\" appendTo=\"body\"></p-menu>\n", styles: ["mng-table-filter-active-tag.p-tag.p-tag-secondary.mng-tag-outlined{background-color:unset;border:1px solid var(--mng-tag-secondary-outlined-border)}\n"] }]
1062
+ }], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: true }] }], edit: [{ type: i0.Output, args: ["edit"] }], remove: [{ type: i0.Output, args: ["remove"] }], toggleDisabled: [{ type: i0.Output, args: ["toggleDisabled"] }], tagMenu: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Menu), { isSignal: true }] }] } });
1063
+
1064
+ var filterActiveTag_component = /*#__PURE__*/Object.freeze({
1065
+ __proto__: null,
1066
+ TableFilterActiveTagComponent: TableFilterActiveTagComponent
1067
+ });
1068
+
1069
+ const VALUE_ACCESSOR = {
1070
+ provide: NG_VALUE_ACCESSOR,
1071
+ useExisting: forwardRef(() => TableFilterFormMultiselectComponent),
1072
+ multi: true
1073
+ };
1074
+ class TableFilterFormMultiselectComponent {
1075
+ constructor() {
1076
+ this.String = String;
1077
+ this.FilterTypeEnum = FilterTypeEnum;
1078
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1079
+ this.onChangeFn = () => { };
1080
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1081
+ this.onTouchedFn = () => { };
1082
+ this.filterType = input(...(ngDevMode ? [undefined, { debugName: "filterType" }] : []));
1083
+ this.enableCaseSensitive = input(false, ...(ngDevMode ? [{ debugName: "enableCaseSensitive", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
1084
+ this.caseSensitiveModel = model(...(ngDevMode ? [undefined, { debugName: "caseSensitiveModel" }] : []));
1085
+ this.inputTrim = input(...(ngDevMode ? [undefined, { debugName: "inputTrim" }] : []));
1086
+ this.disabledInput = input(false, ...(ngDevMode ? [{ debugName: "disabledInput", alias: 'disabled', transform: booleanAttribute }] : [{ alias: 'disabled', transform: booleanAttribute }]));
1087
+ this._disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
1088
+ this.disabled = computed(() => this.disabledInput() || this._disabled(), ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1089
+ this.value = signal([], ...(ngDevMode ? [{ debugName: "value" }] : []));
1090
+ this.stringValues = computed(() => this.value().map(v => String(v)), ...(ngDevMode ? [{ debugName: "stringValues" }] : []));
1091
+ }
1092
+ registerOnChange(fn) {
1093
+ this.onChangeFn = fn;
1094
+ }
1095
+ registerOnTouched(fn) {
1096
+ this.onTouchedFn = fn;
1097
+ }
1098
+ setDisabledState(isDisabled) {
1099
+ this._disabled.set(isDisabled);
1100
+ }
1101
+ onBlur() {
1102
+ this.onTouchedFn();
1103
+ }
1104
+ writeValue(obj) {
1105
+ if (obj === undefined || obj === null || !Array.isArray(obj)) {
1106
+ this.value.set([]);
1107
+ }
1108
+ else {
1109
+ this.value.set(obj);
1110
+ }
1111
+ }
1112
+ onValueNumberChange(event) {
1113
+ const el = event?.target;
1114
+ const rawValue = el?.value;
1115
+ const value = Number(rawValue);
1116
+ const values = Array.isArray(this.value()) ? [...this.value()] : [];
1117
+ if (rawValue && !Number.isNaN(value) && !values.includes(value))
1118
+ values.push(value);
1119
+ this.value.set(values);
1120
+ if (el)
1121
+ el.value = '';
1122
+ this.onChangeFn(this.value());
1123
+ }
1124
+ onValueChange(event) {
1125
+ const el = event?.target;
1126
+ const inputValue = el?.value ?? '';
1127
+ const splitValues = this.splitValues(inputValue);
1128
+ const values = Array.isArray(this.value()) ? [...this.value()] : [];
1129
+ for (const val of splitValues) {
1130
+ if (val && !values.includes(val))
1131
+ values.push(val);
1132
+ }
1133
+ this.value.set(values);
1134
+ if (el)
1135
+ el.value = '';
1136
+ this.onChangeFn(this.value());
1137
+ }
1138
+ splitValues(value) {
1139
+ // split on comma, semicolon, newline, or tab
1140
+ return value.split(/[\n,;\t]/g).filter(x => x.length > 0);
1141
+ }
1142
+ removeValue(index) {
1143
+ const values = [...(this.value() || [])];
1144
+ values.splice(index, 1);
1145
+ this.value.set(values);
1146
+ this.onChangeFn(this.value());
1147
+ }
1148
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterFormMultiselectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1149
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableFilterFormMultiselectComponent, isStandalone: true, selector: "mng-table-filter-form-multiselect", inputs: { filterType: { classPropertyName: "filterType", publicName: "filterType", isSignal: true, isRequired: false, transformFunction: null }, enableCaseSensitive: { classPropertyName: "enableCaseSensitive", publicName: "enableCaseSensitive", isSignal: true, isRequired: false, transformFunction: null }, caseSensitiveModel: { classPropertyName: "caseSensitiveModel", publicName: "caseSensitiveModel", isSignal: true, isRequired: false, transformFunction: null }, inputTrim: { classPropertyName: "inputTrim", publicName: "inputTrim", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { caseSensitiveModel: "caseSensitiveModelChange" }, providers: [VALUE_ACCESSOR], ngImport: i0, template: "<p-inputgroup>\n <p-multiSelect\n [ngModel]=\"value()\"\n (ngModelChange)=\"value.set($event)\"\n [options]=\"value()\"\n [showToggleAll]=\"false\"\n [filter]=\"false\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [maxSelectedLabels]=\"1\"\n [selectedItemsLabel]=\"'mngDropdown.multiselectOverMaxDisplayLimit' | translate\"\n [selectAll]=\"false\"\n [disabled]=\"disabled()\"\n display=\"chip\"\n appendTo=\"body\"\n required=\"true\"\n panelStyleClass=\"table-filter-form-multiselect-panel p-2 flex flex-col gap-2 w-full max-w-72\">\n <ng-template pTemplate=\"header\">\n @if (filterType() === FilterTypeEnum.String) {\n <input\n type=\"text\"\n pInputText\n class=\"mng-filter-string w-full\"\n [disabled]=\"disabled()\"\n (keydown.enter)=\"onValueChange($event); $event.preventDefault()\"\n (keydown.tab)=\"onValueChange($event)\"\n (blur)=\"onValueChange($event)\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [mngInputTrim]=\"inputTrim()\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-filter-number\"\n [disabled]=\"disabled()\"\n (keydown.enter)=\"onValueNumberChange($event); $event.preventDefault()\"\n (keydown.tab)=\"onValueNumberChange($event)\"\n (onBlur)=\"onValueNumberChange($event)\"\n [placeholder]=\"'mngFilter.value' | translate\"\n useGrouping=\"false\"\n required=\"true\" />\n }\n </ng-template>\n <ng-template pTemplate=\"footer\">\n <div class=\"flex flex-wrap gap-1 overflow-auto\">\n @if (value().length) {\n @for (val of stringValues(); track val; let i = $index) {\n <p-chip [label]=\"val\" removable (onRemove)=\"removeValue(i)\" />\n }\n } @else {\n <span class=\"p-1\">{{ 'mngFilter.noValues' | translate }}</span>\n }\n </div>\n </ng-template>\n </p-multiSelect>\n @if (filterType() === FilterTypeEnum.String && enableCaseSensitive()) {\n <p-toggle-button\n [ngModel]=\"caseSensitiveModel()\"\n (ngModelChange)=\"caseSensitiveModel.set($event)\"\n [disabled]=\"disabled()\"\n name=\"caseSensitive\"\n class=\"mng-button-xs mng-toggle-button-addon-right\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n }\n</p-inputgroup>\n", dependencies: [{ kind: "component", type: Chip, selector: "p-chip", inputs: ["label", "icon", "image", "alt", "styleClass", "disabled", "removable", "removeIcon", "chipProps"], outputs: ["onRemove", "onImageError"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "directive", type: PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "styleClass", "inputId", "tabindex", "iconPos", "autofocus", "size", "allowEmpty", "fluid"], outputs: ["onChange"] }, { kind: "directive", type: InputTrimDirective, selector: "[mngInputTrim]", inputs: ["mngInputTrim"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1150
+ }
1151
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterFormMultiselectComponent, decorators: [{
1152
+ type: Component,
1153
+ args: [{ selector: 'mng-table-filter-form-multiselect', providers: [VALUE_ACCESSOR], imports: [Chip, FormsModule, InputNumber, MultiSelect, PrimeTemplate, TranslatePipe, InputGroup, InputText, ToggleButton, InputTrimDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-inputgroup>\n <p-multiSelect\n [ngModel]=\"value()\"\n (ngModelChange)=\"value.set($event)\"\n [options]=\"value()\"\n [showToggleAll]=\"false\"\n [filter]=\"false\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [maxSelectedLabels]=\"1\"\n [selectedItemsLabel]=\"'mngDropdown.multiselectOverMaxDisplayLimit' | translate\"\n [selectAll]=\"false\"\n [disabled]=\"disabled()\"\n display=\"chip\"\n appendTo=\"body\"\n required=\"true\"\n panelStyleClass=\"table-filter-form-multiselect-panel p-2 flex flex-col gap-2 w-full max-w-72\">\n <ng-template pTemplate=\"header\">\n @if (filterType() === FilterTypeEnum.String) {\n <input\n type=\"text\"\n pInputText\n class=\"mng-filter-string w-full\"\n [disabled]=\"disabled()\"\n (keydown.enter)=\"onValueChange($event); $event.preventDefault()\"\n (keydown.tab)=\"onValueChange($event)\"\n (blur)=\"onValueChange($event)\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [mngInputTrim]=\"inputTrim()\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-filter-number\"\n [disabled]=\"disabled()\"\n (keydown.enter)=\"onValueNumberChange($event); $event.preventDefault()\"\n (keydown.tab)=\"onValueNumberChange($event)\"\n (onBlur)=\"onValueNumberChange($event)\"\n [placeholder]=\"'mngFilter.value' | translate\"\n useGrouping=\"false\"\n required=\"true\" />\n }\n </ng-template>\n <ng-template pTemplate=\"footer\">\n <div class=\"flex flex-wrap gap-1 overflow-auto\">\n @if (value().length) {\n @for (val of stringValues(); track val; let i = $index) {\n <p-chip [label]=\"val\" removable (onRemove)=\"removeValue(i)\" />\n }\n } @else {\n <span class=\"p-1\">{{ 'mngFilter.noValues' | translate }}</span>\n }\n </div>\n </ng-template>\n </p-multiSelect>\n @if (filterType() === FilterTypeEnum.String && enableCaseSensitive()) {\n <p-toggle-button\n [ngModel]=\"caseSensitiveModel()\"\n (ngModelChange)=\"caseSensitiveModel.set($event)\"\n [disabled]=\"disabled()\"\n name=\"caseSensitive\"\n class=\"mng-button-xs mng-toggle-button-addon-right\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n }\n</p-inputgroup>\n" }]
1154
+ }], propDecorators: { filterType: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterType", required: false }] }], enableCaseSensitive: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableCaseSensitive", required: false }] }], caseSensitiveModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "caseSensitiveModel", required: false }] }, { type: i0.Output, args: ["caseSensitiveModelChange"] }], inputTrim: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputTrim", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
1155
+
1156
+ class TableFilterFormComponent {
1157
+ constructor() {
1158
+ this.lookupTypeDropdown = FilterLookupTypeEnum.Dropdown;
1159
+ this.lookupTypeAutocomplete = FilterLookupTypeEnum.Autocomplete;
1160
+ this.FilterTypeEnum = FilterTypeEnum;
1161
+ this.FilterMatchMode = FilterMatchMode;
1162
+ this.elementRef = inject(ElementRef);
1163
+ this.translate = inject(TranslateService);
1164
+ this.title = input(...(ngDevMode ? [undefined, { debugName: "title" }] : []));
1165
+ this.metadata = input.required(...(ngDevMode ? [{ debugName: "metadata" }] : []));
1166
+ this.genericDescriptor = input(...(ngDevMode ? [undefined, { debugName: "genericDescriptor" }] : []));
1167
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
1168
+ this.filter = input(...(ngDevMode ? [undefined, { debugName: "filter" }] : []));
1169
+ this.overlay = input(...(ngDevMode ? [undefined, { debugName: "overlay" }] : []));
1170
+ this.disabledProperties = input([], ...(ngDevMode ? [{ debugName: "disabledProperties" }] : []));
1171
+ this.enableCaseSensitive = input(true, ...(ngDevMode ? [{ debugName: "enableCaseSensitive" }] : []));
1172
+ this.propertySearch = input(false, ...(ngDevMode ? [{ debugName: "propertySearch", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
1173
+ this.apply = output();
1174
+ this.propertyOptionsWithTranslations = computed(() => {
1175
+ const disabledProperties = this.disabledProperties();
1176
+ const filter = this.filter();
1177
+ return (this.metadata()?.map(d => {
1178
+ return {
1179
+ property: d.descriptor.property,
1180
+ label: d.descriptor.isGenericFilter ? d.descriptor.property : this.getPropertyLabelKey(d.descriptor),
1181
+ disabled: !filter && disabledProperties.includes(d.descriptor.property)
1182
+ };
1183
+ }) ?? []);
1184
+ }, ...(ngDevMode ? [{ debugName: "propertyOptionsWithTranslations" }] : []));
1185
+ this.selectedFilterMetadata = computed(() => {
1186
+ const property = this.propertyModel();
1187
+ return this.metadata().find(d => d.descriptor.property === property);
1188
+ }, ...(ngDevMode ? [{ debugName: "selectedFilterMetadata" }] : []));
1189
+ // change value lookup function to include the property name of the generic filter
1190
+ this.genericValueDataProvider = computed(() => {
1191
+ const genericValueProvider = this.genericDescriptor()?.valueLookup;
1192
+ if (genericValueProvider && genericValueProvider.serviceType) {
1193
+ const lookupFn = genericValueProvider.lookup;
1194
+ return lookupDataProvider({ service: genericValueProvider.serviceType }).withLookup((params, service, search) => {
1195
+ params = {
1196
+ ...params,
1197
+ filters: {
1198
+ ...params?.filters,
1199
+ field: {
1200
+ value: this.selectedFilterMetadata()?.descriptor.property,
1201
+ matchMode: this.selectedFilterMetadata()?.descriptor.filterType === FilterTypeEnum.LookupEnum ? FilterMatchMode.In : FilterMatchMode.StartsWith
1202
+ }
1203
+ }
1204
+ };
1205
+ return lookupFn(params, service, search);
1206
+ });
1207
+ }
1208
+ return;
1209
+ }, ...(ngDevMode ? [{ debugName: "genericValueDataProvider" }] : []));
1210
+ this.selectedDescriptorAsLookup = computed(() => {
1211
+ const filterDescriptor = this.selectedFilterMetadata()?.descriptor;
1212
+ return filterDescriptor !== undefined &&
1213
+ !filterDescriptor.isGenericFilter &&
1214
+ (filterDescriptor.filterType === FilterTypeEnum.Lookup || filterDescriptor.filterType === FilterTypeEnum.LookupEnum)
1215
+ ? filterDescriptor
1216
+ : undefined;
1217
+ }, ...(ngDevMode ? [{ debugName: "selectedDescriptorAsLookup" }] : []));
1218
+ this.isEdit = computed(() => this.filter() != null, ...(ngDevMode ? [{ debugName: "isEdit" }] : []));
1219
+ this.formSubmitted = signal(false, ...(ngDevMode ? [{ debugName: "formSubmitted" }] : []));
1220
+ this.formErrorMessage = signal([], ...(ngDevMode ? [{ debugName: "formErrorMessage" }] : []));
1221
+ // UI utilities
1222
+ this.filterForm = viewChild.required('filterForm');
1223
+ // Filter form model and form utilities
1224
+ this.propertyModel = signal(null, ...(ngDevMode ? [{ debugName: "propertyModel" }] : []));
1225
+ this.matchModeModel = signal(null, ...(ngDevMode ? [{ debugName: "matchModeModel" }] : []));
1226
+ this.valueModel = signal(null, ...(ngDevMode ? [{ debugName: "valueModel" }] : []));
1227
+ this.caseSensitiveModel = signal(false, ...(ngDevMode ? [{ debugName: "caseSensitiveModel" }] : []));
1228
+ this.isMultiselect = computed(() => this.matchModeModel() === FilterMatchMode.In || this.matchModeModel() === FilterMatchMode.NotIn, ...(ngDevMode ? [{ debugName: "isMultiselect" }] : []));
1229
+ this.addFilterShortcutText = isMac() ? '⌘ + /' : 'Ctrl + /';
1230
+ effectWithDeps([this.filter], ([edit]) => {
1231
+ if (edit) {
1232
+ this.resetForm({
1233
+ property: edit.config.descriptor.property,
1234
+ matchMode: edit.displayMatchMode ?? edit.matchMode ?? null,
1235
+ value: edit.displayValue ?? edit.value,
1236
+ caseSensitive: edit.caseSensitive ?? false
1237
+ });
1238
+ }
1239
+ else {
1240
+ this.resetForm();
1241
+ }
1242
+ });
1243
+ effectWithDeps([this.selectedFilterMetadata], ([selectedFilterMetadata]) => {
1244
+ const descriptor = selectedFilterMetadata?.descriptor;
1245
+ const value = this.valueModel();
1246
+ if (value != null) {
1247
+ // reset value if filter type and value type mismatch
1248
+ if ((descriptor?.filterType === FilterTypeEnum.String && (value === true || value === false || value === 'true' || value === 'false' || value instanceof Date)) ||
1249
+ (descriptor?.filterType === FilterTypeEnum.Number &&
1250
+ (Array.isArray(value) ? value.some(v => typeof v !== 'number' || isNaN(v)) : typeof value !== 'number' && isNaN(+value))) ||
1251
+ (descriptor?.filterType === FilterTypeEnum.Date && !(value instanceof Date) && !(Array.isArray(value) && value.every(item => item instanceof Date)))) {
1252
+ this.valueModel.set(null);
1253
+ }
1254
+ else if (descriptor?.filterType === FilterTypeEnum.Boolean && typeof value !== 'boolean') {
1255
+ this.valueModel.set(false);
1256
+ }
1257
+ }
1258
+ const matchModeOptions = selectedFilterMetadata?.matchModes ?? [];
1259
+ const matchMode = this.matchModeModel();
1260
+ const filterForm = this.filterForm();
1261
+ const isEdit = this.isEdit();
1262
+ if (matchModeOptions.length > 0 &&
1263
+ (!matchMode ||
1264
+ (!isEdit && (filterForm.controls['matchMode']?.pristine || filterForm.controls['matchMode']?.untouched)) ||
1265
+ !matchModeOptions.find(o => o.value === matchMode))) {
1266
+ // reset match mode is needed
1267
+ this.matchModeModel.set(filterGetDefaultMatchMode(this.selectedFilterMetadata()?.descriptor, matchModeOptions));
1268
+ }
1269
+ });
1270
+ effectWithDeps([this.matchModeModel], ([matchModeModel]) => this.valueModel.set(filterAdjustDisplayValueOnMatchModeChange(matchModeModel ?? undefined, this.valueModel())));
1271
+ toObservable(this.overlay)
1272
+ .pipe(switchMap(o => (o ? o.onShow : NEVER)), takeUntilDestroyed())
1273
+ .subscribe(() => {
1274
+ const formFields = this.elementRef.nativeElement.querySelectorAll('input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [role="combobox"]:not([disabled])');
1275
+ const activeEl = document.activeElement;
1276
+ const activeInputIdx = activeEl ? [...formFields].findIndex(el => activeEl.isEqualNode(el)) : 0;
1277
+ if (activeInputIdx <= 0) {
1278
+ formFields[0]?.focus();
1279
+ }
1280
+ });
1281
+ }
1282
+ onFormSubmit(form) {
1283
+ this.formSubmitted.set(true);
1284
+ // mark all as dirty
1285
+ for (const key in form.controls) {
1286
+ form.controls[key].markAsDirty();
1287
+ }
1288
+ const property = this.propertyModel();
1289
+ const matchMode = this.matchModeModel();
1290
+ if (form.invalid || !property || !matchMode) {
1291
+ this.formErrorMessage.set([
1292
+ {
1293
+ severity: 'warn',
1294
+ summary: this.translate.instant('mngFilter.messages.invalidFormTitle'),
1295
+ detail: this.translate.instant('mngFilter.messages.invalidFormMessage')
1296
+ }
1297
+ ]);
1298
+ return;
1299
+ }
1300
+ this.apply.emit({
1301
+ property: property,
1302
+ matchMode: matchMode,
1303
+ value: this.valueModel(),
1304
+ caseSensitive: this.caseSensitiveModel()
1305
+ });
1306
+ // resetting the form is done from the parent component (filter-overlay-with-tag) for smoother animations
1307
+ }
1308
+ resetForm(value) {
1309
+ // somehow have to set case sensitivity manually
1310
+ this.propertyModel.set(value?.property ?? null);
1311
+ this.matchModeModel.set(value?.matchMode ?? null);
1312
+ this.valueModel.set(value?.value ?? null);
1313
+ this.caseSensitiveModel.set(value?.caseSensitive ?? false);
1314
+ // submitted control
1315
+ this.formSubmitted.set(false);
1316
+ }
1317
+ getPropertyLabelKey(filterDescriptor) {
1318
+ let labelKey;
1319
+ if (filterDescriptor.title !== undefined && !filterDescriptor.titleUseModelBase) {
1320
+ labelKey = filterDescriptor.title;
1321
+ }
1322
+ else {
1323
+ labelKey = getI18nTypePropertyKey(this.model().i18nBaseKey, filterDescriptor.title ?? filterDescriptor.property);
1324
+ }
1325
+ return labelKey;
1326
+ }
1327
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1328
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableFilterFormComponent, isStandalone: true, selector: "mng-table-filter-form", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: true, transformFunction: null }, genericDescriptor: { classPropertyName: "genericDescriptor", publicName: "genericDescriptor", isSignal: true, isRequired: false, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, overlay: { classPropertyName: "overlay", publicName: "overlay", isSignal: true, isRequired: false, transformFunction: null }, disabledProperties: { classPropertyName: "disabledProperties", publicName: "disabledProperties", isSignal: true, isRequired: false, transformFunction: null }, enableCaseSensitive: { classPropertyName: "enableCaseSensitive", publicName: "enableCaseSensitive", isSignal: true, isRequired: false, transformFunction: null }, propertySearch: { classPropertyName: "propertySearch", publicName: "propertySearch", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { apply: "apply" }, host: { classAttribute: "flex grow" }, viewQueries: [{ propertyName: "filterForm", first: true, predicate: ["filterForm"], descendants: true, isSignal: true }], ngImport: i0, template: "<div>\n <div class=\"flex items-center gap-2\">\n <h5>{{ filter() ? ('mngFilter.titleEdit' | translate) : ('mngFilter.titleAdd' | translate) }}</h5>\n @if (!filter()) {\n <div class=\"text-sm opacity-50 font-normal self-start pt-[2px]\">( {{ addFilterShortcutText }} )</div>\n }\n </div>\n <form #filterForm=\"ngForm\" (ngSubmit)=\"onFormSubmit(filterForm)\" class=\"flex flex-col items-baseline lg:flex-row gap-4\">\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"property\"\n id=\"property\"\n tabindex=\"1\"\n #propertyControl=\"ngModel\"\n [(ngModel)]=\"propertyModel\"\n [options]=\"propertyOptionsWithTranslations()\"\n optionsValueProperty=\"property\"\n optionsDisabledProperty=\"disabled\"\n optionsLabelProperty=\"label\"\n [placeholder]=\"'mngFilter.property' | translate\"\n [optionsLabelTranslate]=\"!propertySearch()\"\n [inlineSearch]=\"propertySearch()\"\n required=\"true\"\n className=\"w-full\"\n [disabled]=\"isEdit()\"\n [appendTo]=\"null\" />\n </div>\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"matchMode\"\n id=\"matchMode\"\n [(ngModel)]=\"matchModeModel\"\n className=\"w-full\"\n [options]=\"selectedFilterMetadata()?.matchModes ?? []\"\n [placeholder]=\"'mngFilter.matchMode' | translate\"\n [disabled]=\"!propertyControl.value\"\n class=\"self-end\"\n required=\"true\"\n [appendTo]=\"null\" />\n </div>\n @if (!(matchModeModel() === FilterMatchMode.Exists || matchModeModel() === FilterMatchMode.DoesNotExist)) {\n <div class=\"w-full lg:w-auto flex flex-col\">\n @switch (selectedFilterMetadata()?.descriptor?.filterType) {\n @case (FilterTypeEnum.Number) {\n @if (matchModeModel() === FilterMatchMode.In || matchModeModel() === FilterMatchMode.NotIn) {\n <mng-table-filter-form-multiselect\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [filterType]=\"selectedFilterMetadata()?.descriptor?.filterType\"\n [disabled]=\"!matchModeModel()\" />\n } @else if (matchModeModel() === FilterMatchMode.Between) {\n <mng-number-range\n className=\"mng-filter-number\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedFilterMetadata()?.descriptor?.numberUseGrouping ?? false\"\n [minFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMax\"\n required=\"true\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-filter-number\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [styleClass]=\"'w-full'\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedFilterMetadata()?.descriptor?.numberUseGrouping\"\n [minFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMax\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\" />\n }\n }\n\n @case (FilterTypeEnum.Boolean) {\n <p-checkbox [(ngModel)]=\"valueModel\" [disabled]=\"!matchModeModel()\" name=\"value\" binary=\"true\" required=\"true\" />\n }\n @case (FilterTypeEnum.Date) {\n @if (matchModeModel() === FilterMatchMode.Between) {\n <mng-date-range\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n vertical=\"true\"\n [showTime]=\"selectedFilterMetadata()?.dateConfig?.showTime\"\n [showSeconds]=\"selectedFilterMetadata()?.dateConfig?.showSeconds\"\n [milliseconds]=\"selectedFilterMetadata()?.dateConfig?.showMilliseconds\"\n [primeTimePicker]=\"selectedFilterMetadata()?.dateConfig?.primeTimePicker\"\n [timeSelect]=\"selectedFilterMetadata()?.dateConfig?.timeSelect\"\n [timeSelectInterval]=\"selectedFilterMetadata()?.dateConfig?.timeSelectInterval\"\n [dateFormat]=\"selectedFilterMetadata()?.dateConfig?.format\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\" />\n } @else {\n <mng-datetime-picker\n name=\"value\"\n className=\"w-full\"\n [(ngModel)]=\"valueModel\"\n [placeholder]=\"'mngFilter.value' | translate\"\n showIcon=\"true\"\n [time]=\"selectedFilterMetadata()?.dateConfig?.showTime\"\n [seconds]=\"selectedFilterMetadata()?.dateConfig?.showSeconds\"\n [milliseconds]=\"selectedFilterMetadata()?.dateConfig?.showMilliseconds\"\n [primeTimePicker]=\"selectedFilterMetadata()?.dateConfig?.primeTimePicker\"\n [timeSelect]=\"selectedFilterMetadata()?.dateConfig?.timeSelect\"\n [timeSelectInterval]=\"selectedFilterMetadata()?.dateConfig?.timeSelectInterval\"\n [dateFormat]=\"selectedFilterMetadata()?.dateConfig?.format\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\" />\n }\n }\n @case (FilterTypeEnum.Lookup) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @case (FilterTypeEnum.LookupEnum) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @default {\n @if (selectedFilterMetadata()?.descriptor?.genericValueProvider && genericValueDataProvider()) {\n <div class=\"flex\">\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"genericValueDataProvider()\"\n [className]=\"selectedFilterMetadata()?.descriptor?.className + ' ' + (enableCaseSensitive() ? 'rounded-r-none!' : '')\"\n [dropdownClassName]=\"selectedFilterMetadata()?.descriptor?.dropdownClassName\"\n [placeholder]=\"valueModel() ? undefined : ('mngFilter.value' | translate)\"\n allowInput=\"true\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\" />\n @if (enableCaseSensitive()) {\n <p-toggle-button\n [(ngModel)]=\"caseSensitiveModel\"\n [disabled]=\"!matchModeModel()\"\n name=\"caseSensitive\"\n styleClass=\"mng-button-xs mng-toggle-button-addon-right\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n }\n </div>\n } @else if (matchModeModel() === FilterMatchMode.In || matchModeModel() === FilterMatchMode.NotIn) {\n <mng-table-filter-form-multiselect\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [filterType]=\"selectedFilterMetadata()?.descriptor?.filterType\"\n [enableCaseSensitive]=\"enableCaseSensitive()\"\n [(caseSensitiveModel)]=\"caseSensitiveModel\"\n [inputTrim]=\"selectedFilterMetadata()?.descriptor?.trimOption\"\n [disabled]=\"!matchModeModel()\" />\n } @else {\n <div class=\"flex\">\n <input\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n type=\"text\"\n pInputText\n class=\"mng-filter-string w-full\"\n [class.rounded-r-none!]=\"enableCaseSensitive()\"\n [attr.placeholder]=\"'mngFilter.value' | translate\"\n [mngInputTrim]=\"selectedFilterMetadata()?.descriptor?.trimOption\"\n [disabled]=\"!matchModeModel()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\" />\n @if (enableCaseSensitive()) {\n <p-toggle-button\n [(ngModel)]=\"caseSensitiveModel\"\n [disabled]=\"!matchModeModel()\"\n name=\"caseSensitive\"\n styleClass=\"mng-button-xs mng-toggle-button-addon-right\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n }\n </div>\n }\n }\n }\n <ng-template #lookupFilter>\n @if (selectedDescriptorAsLookup(); as lookupFilterDescriptor) {\n @switch (lookupFilterDescriptor.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsTrackProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [autoClear]=\"lookupFilterDescriptor.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookupFilterDescriptor.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookupFilterDescriptor.autocompleteInlineSearch ?? false\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n [searchTrim]=\"selectedFilterMetadata()?.descriptor?.trimOption\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className + ' w-full'\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n showClear=\"false\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\">\n </mng-dropdown>\n }\n }\n } @else if (selectedFilterMetadata()?.descriptor?.isGenericFilter && genericValueDataProvider()) {\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"genericValueDataProvider()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n showClear=\"false\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\">\n </mng-dropdown>\n }\n </ng-template>\n </div>\n }\n <div class=\"flex justify-end\">\n <button pButton type=\"submit\" class=\"mng-filter-submit-button self-end\">\n {{ (filter() ? 'general.apply' : 'general.add') | translate }}\n </button>\n </div>\n </form>\n @if (formSubmitted() && filterForm.invalid) {\n @for (message of formErrorMessage(); track message) {\n <p-message [severity]=\"message.severity\" [text]=\"message.detail\" [icon]=\"message.icon\" styleClass=\"mt-2\" />\n }\n }\n</div>\n", styles: [".mng-toggle-button-addon-right{border-color:var(--p-select-border-color)!important;border-left:none!important;border-top-left-radius:0!important;border-bottom-left-radius:0!important;min-width:35px}.mng-toggle-button-addon-right .p-togglebutton-content{padding-left:.25rem;padding-right:.25rem}.table-filter-form-multiselect-panel .p-multiselect-list-container,.table-filter-form-multiselect-panel .p-multiselect-header{display:none!important}\n"], dependencies: [{ kind: "component", type: DropdownComponent, selector: "mng-dropdown", inputs: ["dataProvider", "options", "optionsTrackProperty", "optionsLabelProperty", "optionsLabelTranslate", "optionsValueProperty", "optionsDisabledProperty", "multiselect", "placeholder", "showClear", "selectFirstItem", "className", "dropdownClassName", "changeValueOnBlur", "loading", "disabled", "allowInput", "appendTo", "templates", "inlineSearch", "searchTrim"], outputs: ["valueChange", "blur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: InputTrimDirective, selector: "[mngInputTrim]", inputs: ["mngInputTrim"] }, { kind: "component", type: NumberRangeComponent, selector: "mng-number-range", inputs: ["placeholder", "useGrouping", "minFractionDigits", "maxFractionDigits", "required", "disabled", "vertical", "templates", "className"], outputs: ["keyDown"] }, { kind: "component", type: InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: DateRangeComponent, selector: "mng-date-range", inputs: ["placeholder", "showTime", "showSeconds", "milliseconds", "primeTimePicker", "timeSelect", "timeSelectInterval", "dateFormat", "className", "inputStyleClass", "required", "disabled", "vertical", "templates"] }, { kind: "component", type: AutocompleteComponent, selector: "mng-autocomplete", inputs: ["dataProvider", "optionsTrackProperty", "optionsValueProperty", "optionsLabelProperty", "optionsLabelTranslate", "inlineSearch", "openOnFocus", "multiselect", "placeholder", "className", "dropdownClassName", "showClear", "autoClear", "selectFirst", "searchTrim", "disabled", "templates"], outputs: ["valueChange", "blur"] }, { kind: "component", type: Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "styleClass", "inputId", "tabindex", "iconPos", "autofocus", "size", "allowEmpty", "fluid"], outputs: ["onChange"] }, { kind: "directive", type: ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: TableFilterFormMultiselectComponent, selector: "mng-table-filter-form-multiselect", inputs: ["filterType", "enableCaseSensitive", "caseSensitiveModel", "inputTrim", "disabled"], outputs: ["caseSensitiveModelChange"] }, { kind: "component", type: DatetimePickerComponent, selector: "mng-datetime-picker", inputs: ["templates", "time", "timeSelect", "timeSelectInterval", "seconds", "milliseconds", "primeTimePicker", "dateFormat", "placeholder", "minDate", "maxDate", "disabled", "required", "showIcon", "showButtonBar", "showClear", "className", "panelStyleClass", "inputStyleClass", "dateRange"], outputs: ["blur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1329
+ }
1330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterFormComponent, decorators: [{
1331
+ type: Component,
1332
+ args: [{ selector: 'mng-table-filter-form', imports: [
1333
+ DropdownComponent,
1334
+ FormsModule,
1335
+ TranslatePipe,
1336
+ InputTrimDirective,
1337
+ NumberRangeComponent,
1338
+ InputNumber,
1339
+ DateRangeComponent,
1340
+ AutocompleteComponent,
1341
+ Checkbox,
1342
+ Message,
1343
+ InputText,
1344
+ NgTemplateOutlet,
1345
+ ToggleButton,
1346
+ ButtonDirective,
1347
+ TableFilterFormMultiselectComponent,
1348
+ DatetimePickerComponent
1349
+ ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1350
+ class: 'flex grow'
1351
+ }, encapsulation: ViewEncapsulation.None, template: "<div>\n <div class=\"flex items-center gap-2\">\n <h5>{{ filter() ? ('mngFilter.titleEdit' | translate) : ('mngFilter.titleAdd' | translate) }}</h5>\n @if (!filter()) {\n <div class=\"text-sm opacity-50 font-normal self-start pt-[2px]\">( {{ addFilterShortcutText }} )</div>\n }\n </div>\n <form #filterForm=\"ngForm\" (ngSubmit)=\"onFormSubmit(filterForm)\" class=\"flex flex-col items-baseline lg:flex-row gap-4\">\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"property\"\n id=\"property\"\n tabindex=\"1\"\n #propertyControl=\"ngModel\"\n [(ngModel)]=\"propertyModel\"\n [options]=\"propertyOptionsWithTranslations()\"\n optionsValueProperty=\"property\"\n optionsDisabledProperty=\"disabled\"\n optionsLabelProperty=\"label\"\n [placeholder]=\"'mngFilter.property' | translate\"\n [optionsLabelTranslate]=\"!propertySearch()\"\n [inlineSearch]=\"propertySearch()\"\n required=\"true\"\n className=\"w-full\"\n [disabled]=\"isEdit()\"\n [appendTo]=\"null\" />\n </div>\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"matchMode\"\n id=\"matchMode\"\n [(ngModel)]=\"matchModeModel\"\n className=\"w-full\"\n [options]=\"selectedFilterMetadata()?.matchModes ?? []\"\n [placeholder]=\"'mngFilter.matchMode' | translate\"\n [disabled]=\"!propertyControl.value\"\n class=\"self-end\"\n required=\"true\"\n [appendTo]=\"null\" />\n </div>\n @if (!(matchModeModel() === FilterMatchMode.Exists || matchModeModel() === FilterMatchMode.DoesNotExist)) {\n <div class=\"w-full lg:w-auto flex flex-col\">\n @switch (selectedFilterMetadata()?.descriptor?.filterType) {\n @case (FilterTypeEnum.Number) {\n @if (matchModeModel() === FilterMatchMode.In || matchModeModel() === FilterMatchMode.NotIn) {\n <mng-table-filter-form-multiselect\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [filterType]=\"selectedFilterMetadata()?.descriptor?.filterType\"\n [disabled]=\"!matchModeModel()\" />\n } @else if (matchModeModel() === FilterMatchMode.Between) {\n <mng-number-range\n className=\"mng-filter-number\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedFilterMetadata()?.descriptor?.numberUseGrouping ?? false\"\n [minFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMax\"\n required=\"true\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-filter-number\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [styleClass]=\"'w-full'\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedFilterMetadata()?.descriptor?.numberUseGrouping\"\n [minFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMin\"\n [maxFractionDigits]=\"selectedFilterMetadata()?.numberConfig?.fractionsMax\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\" />\n }\n }\n\n @case (FilterTypeEnum.Boolean) {\n <p-checkbox [(ngModel)]=\"valueModel\" [disabled]=\"!matchModeModel()\" name=\"value\" binary=\"true\" required=\"true\" />\n }\n @case (FilterTypeEnum.Date) {\n @if (matchModeModel() === FilterMatchMode.Between) {\n <mng-date-range\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n vertical=\"true\"\n [showTime]=\"selectedFilterMetadata()?.dateConfig?.showTime\"\n [showSeconds]=\"selectedFilterMetadata()?.dateConfig?.showSeconds\"\n [milliseconds]=\"selectedFilterMetadata()?.dateConfig?.showMilliseconds\"\n [primeTimePicker]=\"selectedFilterMetadata()?.dateConfig?.primeTimePicker\"\n [timeSelect]=\"selectedFilterMetadata()?.dateConfig?.timeSelect\"\n [timeSelectInterval]=\"selectedFilterMetadata()?.dateConfig?.timeSelectInterval\"\n [dateFormat]=\"selectedFilterMetadata()?.dateConfig?.format\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\" />\n } @else {\n <mng-datetime-picker\n name=\"value\"\n className=\"w-full\"\n [(ngModel)]=\"valueModel\"\n [placeholder]=\"'mngFilter.value' | translate\"\n showIcon=\"true\"\n [time]=\"selectedFilterMetadata()?.dateConfig?.showTime\"\n [seconds]=\"selectedFilterMetadata()?.dateConfig?.showSeconds\"\n [milliseconds]=\"selectedFilterMetadata()?.dateConfig?.showMilliseconds\"\n [primeTimePicker]=\"selectedFilterMetadata()?.dateConfig?.primeTimePicker\"\n [timeSelect]=\"selectedFilterMetadata()?.dateConfig?.timeSelect\"\n [timeSelectInterval]=\"selectedFilterMetadata()?.dateConfig?.timeSelectInterval\"\n [dateFormat]=\"selectedFilterMetadata()?.dateConfig?.format\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\" />\n }\n }\n @case (FilterTypeEnum.Lookup) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @case (FilterTypeEnum.LookupEnum) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @default {\n @if (selectedFilterMetadata()?.descriptor?.genericValueProvider && genericValueDataProvider()) {\n <div class=\"flex\">\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"genericValueDataProvider()\"\n [className]=\"selectedFilterMetadata()?.descriptor?.className + ' ' + (enableCaseSensitive() ? 'rounded-r-none!' : '')\"\n [dropdownClassName]=\"selectedFilterMetadata()?.descriptor?.dropdownClassName\"\n [placeholder]=\"valueModel() ? undefined : ('mngFilter.value' | translate)\"\n allowInput=\"true\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\" />\n @if (enableCaseSensitive()) {\n <p-toggle-button\n [(ngModel)]=\"caseSensitiveModel\"\n [disabled]=\"!matchModeModel()\"\n name=\"caseSensitive\"\n styleClass=\"mng-button-xs mng-toggle-button-addon-right\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n }\n </div>\n } @else if (matchModeModel() === FilterMatchMode.In || matchModeModel() === FilterMatchMode.NotIn) {\n <mng-table-filter-form-multiselect\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [filterType]=\"selectedFilterMetadata()?.descriptor?.filterType\"\n [enableCaseSensitive]=\"enableCaseSensitive()\"\n [(caseSensitiveModel)]=\"caseSensitiveModel\"\n [inputTrim]=\"selectedFilterMetadata()?.descriptor?.trimOption\"\n [disabled]=\"!matchModeModel()\" />\n } @else {\n <div class=\"flex\">\n <input\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n type=\"text\"\n pInputText\n class=\"mng-filter-string w-full\"\n [class.rounded-r-none!]=\"enableCaseSensitive()\"\n [attr.placeholder]=\"'mngFilter.value' | translate\"\n [mngInputTrim]=\"selectedFilterMetadata()?.descriptor?.trimOption\"\n [disabled]=\"!matchModeModel()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\" />\n @if (enableCaseSensitive()) {\n <p-toggle-button\n [(ngModel)]=\"caseSensitiveModel\"\n [disabled]=\"!matchModeModel()\"\n name=\"caseSensitive\"\n styleClass=\"mng-button-xs mng-toggle-button-addon-right\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n }\n </div>\n }\n }\n }\n <ng-template #lookupFilter>\n @if (selectedDescriptorAsLookup(); as lookupFilterDescriptor) {\n @switch (lookupFilterDescriptor.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsTrackProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [autoClear]=\"lookupFilterDescriptor.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookupFilterDescriptor.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookupFilterDescriptor.autocompleteInlineSearch ?? false\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n [searchTrim]=\"selectedFilterMetadata()?.descriptor?.trimOption\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"isMultiselect()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className + ' w-full'\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n showClear=\"false\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\">\n </mng-dropdown>\n }\n }\n } @else if (selectedFilterMetadata()?.descriptor?.isGenericFilter && genericValueDataProvider()) {\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"genericValueDataProvider()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n showClear=\"false\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\">\n </mng-dropdown>\n }\n </ng-template>\n </div>\n }\n <div class=\"flex justify-end\">\n <button pButton type=\"submit\" class=\"mng-filter-submit-button self-end\">\n {{ (filter() ? 'general.apply' : 'general.add') | translate }}\n </button>\n </div>\n </form>\n @if (formSubmitted() && filterForm.invalid) {\n @for (message of formErrorMessage(); track message) {\n <p-message [severity]=\"message.severity\" [text]=\"message.detail\" [icon]=\"message.icon\" styleClass=\"mt-2\" />\n }\n }\n</div>\n", styles: [".mng-toggle-button-addon-right{border-color:var(--p-select-border-color)!important;border-left:none!important;border-top-left-radius:0!important;border-bottom-left-radius:0!important;min-width:35px}.mng-toggle-button-addon-right .p-togglebutton-content{padding-left:.25rem;padding-right:.25rem}.table-filter-form-multiselect-panel .p-multiselect-list-container,.table-filter-form-multiselect-panel .p-multiselect-header{display:none!important}\n"] }]
1352
+ }], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], metadata: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: true }] }], genericDescriptor: [{ type: i0.Input, args: [{ isSignal: true, alias: "genericDescriptor", required: false }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], overlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlay", required: false }] }], disabledProperties: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledProperties", required: false }] }], enableCaseSensitive: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableCaseSensitive", required: false }] }], propertySearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertySearch", required: false }] }], apply: [{ type: i0.Output, args: ["apply"] }], filterForm: [{ type: i0.ViewChild, args: ['filterForm', { isSignal: true }] }] } });
1353
+
1354
+ const COMMONS_TABLE_FEATURE_CONFIG_IT = new InjectionToken('COMMONS_TABLE_FEATURE_CONFIG');
1355
+
1356
+ class TableHeaderWithFiltersTemplateDirective extends TemplateDirective {
1357
+ constructor() {
1358
+ super(...arguments);
1359
+ this.name = input.required(...(ngDevMode ? [{ debugName: "name" }] : []));
1360
+ }
1361
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableHeaderWithFiltersTemplateDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1362
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.15", type: TableHeaderWithFiltersTemplateDirective, isStandalone: true, selector: "[mngTableHeaderWithFiltersTemplate]", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
1363
+ }
1364
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableHeaderWithFiltersTemplateDirective, decorators: [{
1365
+ type: Directive,
1366
+ args: [{
1367
+ selector: '[mngTableHeaderWithFiltersTemplate]'
1368
+ }]
1369
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }] } });
1370
+
1371
+ class TableHeaderWithFiltersComponent {
1372
+ static { this.SEARCH_WORD_LIMIT_MAX = 4; }
1373
+ constructor() {
1374
+ this.translateService = inject(TranslateService);
1375
+ this.tableData = inject((ADataListService));
1376
+ this.tableConfig = inject(COMMONS_TABLE_FEATURE_CONFIG_IT, { optional: true });
1377
+ this.defaultFilterDisplayType = this.tableConfig?.filterDisplayType ?? FilterDisplayTypeEnum.Column;
1378
+ this.metadata = input.required(...(ngDevMode ? [{ debugName: "metadata" }] : []));
1379
+ this.genericFilterDescriptor = input(...(ngDevMode ? [undefined, { debugName: "genericFilterDescriptor" }] : []));
1380
+ this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : []));
1381
+ this.enableSearch = input(false, ...(ngDevMode ? [{ debugName: "enableSearch", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
1382
+ this.search = input(...(ngDevMode ? [undefined, { debugName: "search" }] : []));
1383
+ this.searchLimitWordMax = input(undefined, ...(ngDevMode ? [{ debugName: "searchLimitWordMax" }] : []));
1384
+ this.enableCaseSensitive = input(true, ...(ngDevMode ? [{ debugName: "enableCaseSensitive", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
1385
+ this.filterMenuItems = signal([], ...(ngDevMode ? [{ debugName: "filterMenuItems" }] : []));
1386
+ this.filterOverlay = viewChild.required(Popover);
1387
+ this.filterFormComponent = viewChild(TableFilterFormComponent, ...(ngDevMode ? [{ debugName: "filterFormComponent" }] : []));
1388
+ this.templates = contentChildren(TableHeaderWithFiltersTemplateDirective, ...(ngDevMode ? [{ debugName: "templates" }] : []));
1389
+ this.titleTemplate = computed(() => findTemplateByName([...this.templates()], 'title'), ...(ngDevMode ? [{ debugName: "titleTemplate" }] : []));
1390
+ this.titleRowRightTemplate = computed(() => findTemplateByName([...this.templates()], 'titleRowRight'), ...(ngDevMode ? [{ debugName: "titleRowRightTemplate" }] : []));
1391
+ this.overlayFormMetadata = computed(() => this.metadata().filter(f => (f.descriptor.displayType == null && FilterDisplayTypeEnum.OverlayWithTag === this.defaultFilterDisplayType) ||
1392
+ f.descriptor.displayType === FilterDisplayTypeEnum.OverlayWithTag), ...(ngDevMode ? [{ debugName: "overlayFormMetadata" }] : []));
1393
+ this.directInputMetadata = computed(() => this.metadata().filter(f => (f.descriptor.displayType == null && FilterDisplayTypeEnum.DirectInput === this.defaultFilterDisplayType) ||
1394
+ f.descriptor.displayType === FilterDisplayTypeEnum.DirectInput), ...(ngDevMode ? [{ debugName: "directInputMetadata" }] : []));
1395
+ this.overlayFormFilters = computed(() => {
1396
+ return this.getInitialFilters(this.tableData.filterStates(), this.overlayFormMetadata());
1397
+ }, ...(ngDevMode ? [{ debugName: "overlayFormFilters" }] : []));
1398
+ this.showOverlayFilterFormButton = computed(() => this.overlayFormMetadata().length > 0, ...(ngDevMode ? [{ debugName: "showOverlayFilterFormButton" }] : []));
1399
+ this.activeFilters = computed(() => {
1400
+ const filterEntry = this.overlayFormFilters();
1401
+ return this.overlayFormMetadata()
1402
+ .filter(d => {
1403
+ const filter = filterEntry[d.descriptor.property];
1404
+ return (filter &&
1405
+ filter.matchMode !== undefined &&
1406
+ filter.displayMatchMode !== undefined &&
1407
+ (filter.matchMode === FilterMatchMode.Exists ||
1408
+ filter.matchMode === FilterMatchMode.DoesNotExist ||
1409
+ (filter.value !== undefined && filter.displayValue !== undefined)));
1410
+ })
1411
+ .map(d => filterEntry[d.descriptor.property]);
1412
+ }, ...(ngDevMode ? [{ debugName: "activeFilters" }] : []));
1413
+ this.activeFilterProperties = computed(() => this.activeFilters().map(f => f.config.descriptor.property), ...(ngDevMode ? [{ debugName: "activeFilterProperties" }] : []));
1414
+ this.filterEdit = signal(undefined, ...(ngDevMode ? [{ debugName: "filterEdit" }] : []));
1415
+ this.unsetRequiredFilters = computed(() => {
1416
+ const activeFilters = this.activeFilters().map(el => el.config.descriptor.property);
1417
+ return this.overlayFormMetadata()
1418
+ .filter(el => el.descriptor.isRequired && !activeFilters.includes(el.descriptor.property))
1419
+ .map(el => {
1420
+ return {
1421
+ matchMode: el.defaultMatchMode,
1422
+ displayMatchMode: el.defaultMatchMode,
1423
+ config: el
1424
+ };
1425
+ });
1426
+ }, ...(ngDevMode ? [{ debugName: "unsetRequiredFilters" }] : []));
1427
+ this.allActiveFiltersDisabled = computed(() => this.activeFilters().filter(f => f.disabled).length === this.activeFilters().length, ...(ngDevMode ? [{ debugName: "allActiveFiltersDisabled" }] : []));
1428
+ this.addFilterShortcutText = isMac() ? '⌘ + /' : 'Ctrl + /';
1429
+ // global search model
1430
+ this.searchValue = computed(() => this.search()?.value, ...(ngDevMode ? [{ debugName: "searchValue" }] : []));
1431
+ this.searchCaseSensitive = computed(() => this.search()?.caseSensitive, ...(ngDevMode ? [{ debugName: "searchCaseSensitive" }] : []));
1432
+ this.searchWordLimitMaxError = signal(false, ...(ngDevMode ? [{ debugName: "searchWordLimitMaxError" }] : []));
1433
+ this.searchWordLimitMaxCmp = computed(() => {
1434
+ const inputLimit = this.searchLimitWordMax();
1435
+ if (inputLimit !== undefined) {
1436
+ return inputLimit;
1437
+ }
1438
+ return this.tableConfig?.searchLimitMaxWords !== undefined ? this.tableConfig?.searchLimitMaxWords : TableHeaderWithFiltersComponent.SEARCH_WORD_LIMIT_MAX;
1439
+ }, ...(ngDevMode ? [{ debugName: "searchWordLimitMaxCmp" }] : []));
1440
+ this.searchValueSubject = new BehaviorSubject(undefined);
1441
+ this.searchCaseSensitiveSubject = new BehaviorSubject(undefined);
1442
+ // UI utilities
1443
+ this.clickedOnFilterEvent = undefined;
1444
+ this.filterSplitButton = viewChild.required('filterSplitButton');
1445
+ this.searchInput = viewChild.required('searchInput');
1446
+ this.overlaySelectors = [
1447
+ '.p-dialog',
1448
+ '.p-overlaypanel',
1449
+ '.p-popover',
1450
+ '.p-confirm-popup',
1451
+ '.p-confirm-dialog',
1452
+ '.p-drawer',
1453
+ '.p-menu.p-menu-overlay',
1454
+ '.p-tieredmenu-overlay'
1455
+ ];
1456
+ this.FilterTypeEnum = FilterTypeEnum;
1457
+ combineLatest([this.searchValueSubject.pipe(debounceTime(500), distinctUntilChanged()), this.searchCaseSensitiveSubject])
1458
+ // NOTE: skip is used to ignore propagating the initial value of the subjects
1459
+ .pipe(skip(1), takeUntilDestroyed())
1460
+ .subscribe(([value, caseSensitive]) => {
1461
+ this.updateSearch(value == null ? (this.search()?.value ?? '') : value, caseSensitive == null ? (this.search()?.caseSensitive ?? undefined) : caseSensitive);
1462
+ });
1463
+ }
1464
+ onFilterFormApply(event) {
1465
+ const filterMetadata = this.metadata().find(d => d.descriptor.property === event.property);
1466
+ if (!filterMetadata) {
1467
+ return;
1468
+ }
1469
+ const filterData = {
1470
+ ...filterSetStateOnDisplayChange({ caseSensitive: event.caseSensitive }, event.matchMode, event.value, filterMetadata.descriptor.filterType, filterMetadata.dateConfig),
1471
+ config: filterMetadata
1472
+ };
1473
+ this.updateFilter(filterData);
1474
+ // this keeps the UI updated properly before closing the overlay
1475
+ this.filterEdit.set(filterData);
1476
+ // Resetting the form is done in the onOverlayHide callback because resetting the
1477
+ // values here renders empty inputs for a split second before closing the overlay
1478
+ this.filterOverlay().hide();
1479
+ }
1480
+ onFilterRemove(event) {
1481
+ this.updateFilter({
1482
+ ...this.overlayFormFilters()[event.filter.config.descriptor.property],
1483
+ matchMode: undefined,
1484
+ displayMatchMode: undefined,
1485
+ value: undefined,
1486
+ displayValue: undefined,
1487
+ disabled: undefined
1488
+ });
1489
+ }
1490
+ onFilterEdit(event) {
1491
+ this.onFilterAddOrEdit(event.filter, event.event);
1492
+ }
1493
+ isOverlayOpen() {
1494
+ return this.overlaySelectors.some(sel => !!document.querySelector(sel));
1495
+ }
1496
+ filterShortcuts(event) {
1497
+ // Add Filter shortcut: ctrl + / or ⌘ + /
1498
+ if (((!isMac() && event.ctrlKey) || (isMac() && event.metaKey)) && event.key === '/') {
1499
+ event.preventDefault();
1500
+ if (this.isOverlayOpen() && !this.filterOverlay().overlayVisible)
1501
+ return;
1502
+ this.onFilterAdd(event);
1503
+ }
1504
+ // Search shortcut: /
1505
+ else if (this.enableSearch() && event.key === '/') {
1506
+ const target = event.target;
1507
+ const isTyping = !!target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable);
1508
+ if (isTyping)
1509
+ return; // don’t interrupt typing
1510
+ event.preventDefault();
1511
+ if (this.isOverlayOpen())
1512
+ return;
1513
+ this.searchInput().nativeElement.focus();
1514
+ }
1515
+ }
1516
+ onFilterSplitButtonShow() {
1517
+ this.filterMenuItems.set([
1518
+ {
1519
+ label: this.allActiveFiltersDisabled() ? this.translateService.instant('mngFilter.enableAll') : this.translateService.instant('mngFilter.disableAll'),
1520
+ icon: this.allActiveFiltersDisabled() ? 'pi pi-check-circle' : 'pi pi-ban',
1521
+ command: () => this.onFilterToggleDisableAll(),
1522
+ disabled: !this.activeFilters()?.length
1523
+ },
1524
+ { separator: true },
1525
+ {
1526
+ label: this.translateService.instant('mngFilter.removeAll'),
1527
+ icon: 'pi pi-times',
1528
+ command: () => this.onFilterRemoveAll(),
1529
+ disabled: !this.activeFilters()?.length
1530
+ }
1531
+ ]);
1532
+ }
1533
+ onFilterAdd(event) {
1534
+ this.onFilterAddOrEdit(undefined, event);
1535
+ }
1536
+ onFilterToggleDisabled(event) {
1537
+ this.updateFilter({
1538
+ ...this.overlayFormFilters()[event.filter.config.descriptor.property],
1539
+ disabled: event.filter.disabled
1540
+ });
1541
+ }
1542
+ onFilterToggleDisableAll() {
1543
+ this.tableData.updateFilters(Object.fromEntries(this.activeFilters().map(f => [f.config.descriptor.property, { ...f, disabled: !this.allActiveFiltersDisabled() }])));
1544
+ }
1545
+ onFilterRemoveAll() {
1546
+ this.tableData.updateFilters(Object.fromEntries(this.activeFilters().map(f => [f.config.descriptor.property, undefined])));
1547
+ }
1548
+ onSearchChange(value) {
1549
+ const searchWordLimitMax = this.searchWordLimitMaxCmp();
1550
+ if (searchWordLimitMax !== null) {
1551
+ const wordCount = value.split(/\s+/).filter(word => word.length > 0).length;
1552
+ this.searchWordLimitMaxError.set(wordCount > searchWordLimitMax);
1553
+ }
1554
+ else {
1555
+ this.searchWordLimitMaxError.set(false);
1556
+ }
1557
+ if (!this.searchWordLimitMaxError()) {
1558
+ this.searchValueSubject.next(value);
1559
+ }
1560
+ }
1561
+ // if inside a form prevent the default 'enter' event to submit it
1562
+ onSearchSubmit(event) {
1563
+ event.preventDefault(); // functionality still works because it's bound to change and not enter/submit.
1564
+ }
1565
+ onSearchCaseSensitiveChange(value) {
1566
+ this.searchCaseSensitiveSubject.next(value);
1567
+ }
1568
+ onOverlayHide() {
1569
+ // resetting the form is done here for a smoother animation
1570
+ if (this.filterFormComponent !== undefined) {
1571
+ this.filterFormComponent()?.resetForm();
1572
+ }
1573
+ if (this.clickedOnFilterEvent) {
1574
+ // show the overlay again if the user clicked another filter
1575
+ setTimeout(() => {
1576
+ this.filterEdit.set(this.clickedOnFilterEvent?.filter);
1577
+ const event = this.clickedOnFilterEvent?.event;
1578
+ if (event instanceof KeyboardEvent) {
1579
+ this.filterOverlay().show(event, this.filterSplitButton().el.nativeElement); // a keyboard event doesn't have a target, so we add it manually
1580
+ }
1581
+ else {
1582
+ this.filterOverlay().show(event);
1583
+ }
1584
+ this.clickedOnFilterEvent = undefined;
1585
+ }, 0);
1586
+ return;
1587
+ }
1588
+ else {
1589
+ // clean state
1590
+ this.filterEdit.set(undefined);
1591
+ }
1592
+ }
1593
+ onFilterAddOrEdit(filter, event) {
1594
+ // If user clicks on the same filter or add that is already open, close the overlay
1595
+ if (this.filterOverlay().overlayVisible && this.filterEdit()?.config.descriptor.property === filter?.config.descriptor.property) {
1596
+ this.filterOverlay().hide();
1597
+ return;
1598
+ }
1599
+ if (this.filterOverlay().overlayVisible) {
1600
+ // In case the user clicks another filter, 're-showing' the overlay in
1601
+ // the new position is done in the onOverlayHide callback
1602
+ this.clickedOnFilterEvent = { event, filter };
1603
+ this.filterOverlay().hide();
1604
+ }
1605
+ else {
1606
+ this.filterEdit.set(filter);
1607
+ // When invoked via keyboard, provide a concrete anchor element for positioning
1608
+ if (event instanceof KeyboardEvent) {
1609
+ this.filterOverlay().show(event, this.filterSplitButton().el.nativeElement); // a keyboard event doesn't have a target, so we add it manually
1610
+ }
1611
+ else {
1612
+ this.filterOverlay().show(event);
1613
+ }
1614
+ }
1615
+ }
1616
+ getInitialFilters(filtersInit, metadata) {
1617
+ const filtersResult = {};
1618
+ if (filtersInit) {
1619
+ for (const property in filtersInit) {
1620
+ const filterInit = filtersInit[property];
1621
+ const filterMetadata = metadata.find(m => m.descriptor.property === property);
1622
+ if (!filterMetadata) {
1623
+ continue;
1624
+ }
1625
+ filtersResult[property] = {
1626
+ ...filterSetStateOnChange(filterInit, filterInit.matchMode, filterInit.value, filterMetadata.descriptor.filterType, filterMetadata.dateConfig),
1627
+ config: filterMetadata
1628
+ };
1629
+ }
1630
+ }
1631
+ return filtersResult;
1632
+ }
1633
+ updateFilter(filter) {
1634
+ this.tableData.updateFilters({ [filter.config.descriptor.property]: filter });
1635
+ }
1636
+ updateSearch(searchQuery, caseSensitive = false) {
1637
+ // match mode needs to be set for inline search
1638
+ this.tableData.updateSearch(searchQuery != null ? { value: searchQuery, caseSensitive: caseSensitive } : undefined);
1639
+ }
1640
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableHeaderWithFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1641
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableHeaderWithFiltersComponent, isStandalone: true, selector: "mng-table-header-with-filters", inputs: { metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: true, transformFunction: null }, genericFilterDescriptor: { classPropertyName: "genericFilterDescriptor", publicName: "genericFilterDescriptor", isSignal: true, isRequired: false, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, enableSearch: { classPropertyName: "enableSearch", publicName: "enableSearch", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, searchLimitWordMax: { classPropertyName: "searchLimitWordMax", publicName: "searchLimitWordMax", isSignal: true, isRequired: false, transformFunction: null }, enableCaseSensitive: { classPropertyName: "enableCaseSensitive", publicName: "enableCaseSensitive", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:keydown": "filterShortcuts($event)" } }, queries: [{ propertyName: "templates", predicate: TableHeaderWithFiltersTemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "filterOverlay", first: true, predicate: Popover, descendants: true, isSignal: true }, { propertyName: "filterFormComponent", first: true, predicate: TableFilterFormComponent, descendants: true, isSignal: true }, { propertyName: "filterSplitButton", first: true, predicate: ["filterSplitButton"], descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex items-center grow flex-wrap\">\n @if (titleTemplate()) {\n <ng-container *ngTemplateOutlet=\"titleTemplate()\"></ng-container>\n }\n @if (showOverlayFilterFormButton()) {\n <p-splitbutton\n #filterSplitButton\n [label]=\"'mngFilter.titleAdd' | translate\"\n [severity]=\"'secondary'\"\n (onClick)=\"onFilterAdd($event)\"\n [class]=\"'mng-filter-add-button mr-2' + (titleTemplate() ? ' ml-3' : '')\"\n (onMenuShow)=\"onFilterSplitButtonShow()\"\n showDelay=\"500\"\n [pTooltip]=\"('mngFilter.titleAdd' | translate) + ' ( ' + addFilterShortcutText + ' )'\"\n icon=\"pi pi-filter\"\n [model]=\"filterMenuItems()\">\n </p-splitbutton>\n }\n @if (enableSearch()) {\n <div\n class=\"mng-search mr-3\"\n [ngClass]=\"{'ml-3': !showOverlayFilterFormButton() && titleTemplate()}\"\n showDelay=\"500\"\n [pTooltip]=\"('mngFilter.search.input' | translate) + ' ( / )'\">\n <span class=\"p-input-icon-left w-full\">\n <p-iconfield>\n <p-inputicon class=\"pi pi-search\" />\n <input\n #searchInput\n [ngModel]=\"searchValue()\"\n (ngModelChange)=\"onSearchChange($event)\"\n (keydown.enter)=\"onSearchSubmit($event)\"\n name=\"globalSearch\"\n type=\"text\"\n pInputText\n class=\"search-input w-full\"\n [ngClass]=\"{'ng-invalid': searchWordLimitMaxError()}\"\n [attr.placeholder]=\"'mngFilter.search.input' | translate\"\n [placeholder]=\"'mngFilter.search.input' | translate\" />\n <span class=\"search-shortcut-hint\">/</span>\n </p-iconfield>\n @if (enableCaseSensitive()) {\n <span class=\"toggle-button-input\">\n <p-toggleButton\n styleClass=\"ml-1 p-1 p-button-sm\"\n [ngModel]=\"searchCaseSensitive()\"\n (ngModelChange)=\"onSearchCaseSensitiveChange($event)\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n </span>\n }\n </span>\n @if (searchWordLimitMaxError()) {\n <small class=\"p-error block\">\n {{ 'mngFilter.search.maxWordsExceededMessage' | translate }}\n </small>\n }\n </div>\n }\n @if (directInputMetadata().length > 0) {\n <div class=\"mng-direct-input-filters flex flex-wrap items-center my-1\">\n @for (metadata of directInputMetadata(); track metadata.descriptor.property) {\n @if (metadata.descriptor.filterType !== FilterTypeEnum.Component) {\n @defer (on idle) {\n <mng-table-filter [config]=\"metadata\" [model]=\"model()\" [showFilterIcon]=\"true\" [showTitleAsPlaceholder]=\"true\" class=\"mx-1 my-1\" />\n }\n } @else if (metadata.descriptor.customComponentType) {\n <ng-container [mngComponent]=\"metadata.descriptor.customComponentType\" [inputs]=\"{descriptor: metadata.descriptor}\"></ng-container>\n }\n }\n </div>\n }\n @if (titleRowRightTemplate()) {\n <ng-container *ngTemplateOutlet=\"titleRowRightTemplate()\"></ng-container>\n }\n</div>\n@if (activeFilters().length > 0 || unsetRequiredFilters().length > 0) {\n <div class=\"flex items-center flex-wrap mt-2\">\n @for (filter of unsetRequiredFilters(); track filter.config.descriptor.property) {\n @defer (on viewport) {\n <mng-table-filter-active-tag\n [model]=\"model()\"\n [filter]=\"filter\"\n (edit)=\"onFilterEdit($event)\"\n (remove)=\"onFilterRemove($event)\"\n (toggleDisabled)=\"onFilterToggleDisabled($event)\" />\n } @placeholder {\n <p-skeleton width=\"10rem\" height=\"2rem\"></p-skeleton>\n }\n }\n @for (filter of activeFilters(); track filter.config.descriptor.property) {\n @defer (on viewport) {\n <mng-table-filter-active-tag\n [model]=\"model()\"\n [filter]=\"filter\"\n (edit)=\"onFilterEdit($event)\"\n (remove)=\"onFilterRemove($event)\"\n (toggleDisabled)=\"onFilterToggleDisabled($event)\" />\n } @placeholder {\n <p-skeleton width=\"10rem\" height=\"2rem\"></p-skeleton>\n }\n }\n </div>\n}\n<p-popover #op showCloseIcon=\"true\" (onHide)=\"onOverlayHide()\" appendTo=\"body\">\n @defer (on viewport) {\n <mng-table-filter-form\n [model]=\"model()\"\n [metadata]=\"overlayFormMetadata()\"\n [genericDescriptor]=\"genericFilterDescriptor()\"\n [filter]=\"filterEdit()\"\n [disabledProperties]=\"activeFilterProperties()\"\n [propertySearch]=\"genericFilterDescriptor()?.propertySearch\"\n [overlay]=\"op\"\n [enableCaseSensitive]=\"enableCaseSensitive()\"\n (apply)=\"onFilterFormApply($event)\" />\n } @placeholder {\n <p-skeleton width=\"20rem\" height=\"3rem\"></p-skeleton>\n }\n</p-popover>\n", styles: [".toggle-button-input{position:absolute;right:.35rem;top:50%;transform:translateY(-50%)}.mng-search{min-width:20rem}.search-shortcut-hint{position:absolute;right:1rem;top:50%;transform:translateY(-50%);font-size:1.1rem;pointer-events:none;opacity:.5;transition:opacity .15s}.search-input:not(:placeholder-shown)~.search-shortcut-hint,.search-input:focus~.search-shortcut-hint{opacity:0;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: TagModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "styleClass", "inputId", "tabindex", "iconPos", "autofocus", "size", "allowEmpty", "fluid"], outputs: ["onChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "component", type: InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "component", type: Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "component", type: SplitButton, selector: "p-splitbutton, p-splitButton, p-split-button", inputs: ["model", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "icon", "iconPos", "label", "tooltip", "tooltipOptions", "styleClass", "menuStyle", "menuStyleClass", "dropdownIcon", "appendTo", "dir", "expandAriaLabel", "showTransitionOptions", "hideTransitionOptions", "buttonProps", "menuButtonProps", "autofocus", "disabled", "tabindex", "menuButtonDisabled", "buttonDisabled"], outputs: ["onClick", "onMenuHide", "onMenuShow", "onDropdownClick"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [Promise.resolve().then(function () { return filter_component; }).then(m => m.TableFilterComponent)], () => [Promise.resolve().then(function () { return filterActiveTag_component; }).then(m => m.TableFilterActiveTagComponent)], () => [Promise.resolve().then(function () { return filterActiveTag_component; }).then(m => m.TableFilterActiveTagComponent)], () => [TableFilterFormComponent]] }); }
1642
+ }
1643
+ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.3.15", ngImport: i0, type: TableHeaderWithFiltersComponent, resolveDeferredDeps: () => [Promise.resolve().then(function () { return filter_component; }).then(m => m.TableFilterComponent), Promise.resolve().then(function () { return filterActiveTag_component; }).then(m => m.TableFilterActiveTagComponent)], resolveMetadata: (TableFilterComponent, TableFilterActiveTagComponent) => ({ decorators: [{
1644
+ type: Component,
1645
+ args: [{ selector: 'mng-table-header-with-filters', imports: [
1646
+ TranslatePipe,
1647
+ TagModule,
1648
+ TableFilterFormComponent,
1649
+ TableFilterActiveTagComponent,
1650
+ NgTemplateOutlet,
1651
+ InputText,
1652
+ NgClass,
1653
+ ToggleButton,
1654
+ FormsModule,
1655
+ IconField,
1656
+ InputIcon,
1657
+ Popover,
1658
+ TableFilterComponent,
1659
+ ComponentDirective,
1660
+ Skeleton,
1661
+ SplitButton,
1662
+ Tooltip
1663
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex items-center grow flex-wrap\">\n @if (titleTemplate()) {\n <ng-container *ngTemplateOutlet=\"titleTemplate()\"></ng-container>\n }\n @if (showOverlayFilterFormButton()) {\n <p-splitbutton\n #filterSplitButton\n [label]=\"'mngFilter.titleAdd' | translate\"\n [severity]=\"'secondary'\"\n (onClick)=\"onFilterAdd($event)\"\n [class]=\"'mng-filter-add-button mr-2' + (titleTemplate() ? ' ml-3' : '')\"\n (onMenuShow)=\"onFilterSplitButtonShow()\"\n showDelay=\"500\"\n [pTooltip]=\"('mngFilter.titleAdd' | translate) + ' ( ' + addFilterShortcutText + ' )'\"\n icon=\"pi pi-filter\"\n [model]=\"filterMenuItems()\">\n </p-splitbutton>\n }\n @if (enableSearch()) {\n <div\n class=\"mng-search mr-3\"\n [ngClass]=\"{'ml-3': !showOverlayFilterFormButton() && titleTemplate()}\"\n showDelay=\"500\"\n [pTooltip]=\"('mngFilter.search.input' | translate) + ' ( / )'\">\n <span class=\"p-input-icon-left w-full\">\n <p-iconfield>\n <p-inputicon class=\"pi pi-search\" />\n <input\n #searchInput\n [ngModel]=\"searchValue()\"\n (ngModelChange)=\"onSearchChange($event)\"\n (keydown.enter)=\"onSearchSubmit($event)\"\n name=\"globalSearch\"\n type=\"text\"\n pInputText\n class=\"search-input w-full\"\n [ngClass]=\"{'ng-invalid': searchWordLimitMaxError()}\"\n [attr.placeholder]=\"'mngFilter.search.input' | translate\"\n [placeholder]=\"'mngFilter.search.input' | translate\" />\n <span class=\"search-shortcut-hint\">/</span>\n </p-iconfield>\n @if (enableCaseSensitive()) {\n <span class=\"toggle-button-input\">\n <p-toggleButton\n styleClass=\"ml-1 p-1 p-button-sm\"\n [ngModel]=\"searchCaseSensitive()\"\n (ngModelChange)=\"onSearchCaseSensitiveChange($event)\"\n onLabel=\"Aa\"\n offLabel=\"Aa\" />\n </span>\n }\n </span>\n @if (searchWordLimitMaxError()) {\n <small class=\"p-error block\">\n {{ 'mngFilter.search.maxWordsExceededMessage' | translate }}\n </small>\n }\n </div>\n }\n @if (directInputMetadata().length > 0) {\n <div class=\"mng-direct-input-filters flex flex-wrap items-center my-1\">\n @for (metadata of directInputMetadata(); track metadata.descriptor.property) {\n @if (metadata.descriptor.filterType !== FilterTypeEnum.Component) {\n @defer (on idle) {\n <mng-table-filter [config]=\"metadata\" [model]=\"model()\" [showFilterIcon]=\"true\" [showTitleAsPlaceholder]=\"true\" class=\"mx-1 my-1\" />\n }\n } @else if (metadata.descriptor.customComponentType) {\n <ng-container [mngComponent]=\"metadata.descriptor.customComponentType\" [inputs]=\"{descriptor: metadata.descriptor}\"></ng-container>\n }\n }\n </div>\n }\n @if (titleRowRightTemplate()) {\n <ng-container *ngTemplateOutlet=\"titleRowRightTemplate()\"></ng-container>\n }\n</div>\n@if (activeFilters().length > 0 || unsetRequiredFilters().length > 0) {\n <div class=\"flex items-center flex-wrap mt-2\">\n @for (filter of unsetRequiredFilters(); track filter.config.descriptor.property) {\n @defer (on viewport) {\n <mng-table-filter-active-tag\n [model]=\"model()\"\n [filter]=\"filter\"\n (edit)=\"onFilterEdit($event)\"\n (remove)=\"onFilterRemove($event)\"\n (toggleDisabled)=\"onFilterToggleDisabled($event)\" />\n } @placeholder {\n <p-skeleton width=\"10rem\" height=\"2rem\"></p-skeleton>\n }\n }\n @for (filter of activeFilters(); track filter.config.descriptor.property) {\n @defer (on viewport) {\n <mng-table-filter-active-tag\n [model]=\"model()\"\n [filter]=\"filter\"\n (edit)=\"onFilterEdit($event)\"\n (remove)=\"onFilterRemove($event)\"\n (toggleDisabled)=\"onFilterToggleDisabled($event)\" />\n } @placeholder {\n <p-skeleton width=\"10rem\" height=\"2rem\"></p-skeleton>\n }\n }\n </div>\n}\n<p-popover #op showCloseIcon=\"true\" (onHide)=\"onOverlayHide()\" appendTo=\"body\">\n @defer (on viewport) {\n <mng-table-filter-form\n [model]=\"model()\"\n [metadata]=\"overlayFormMetadata()\"\n [genericDescriptor]=\"genericFilterDescriptor()\"\n [filter]=\"filterEdit()\"\n [disabledProperties]=\"activeFilterProperties()\"\n [propertySearch]=\"genericFilterDescriptor()?.propertySearch\"\n [overlay]=\"op\"\n [enableCaseSensitive]=\"enableCaseSensitive()\"\n (apply)=\"onFilterFormApply($event)\" />\n } @placeholder {\n <p-skeleton width=\"20rem\" height=\"3rem\"></p-skeleton>\n }\n</p-popover>\n", styles: [".toggle-button-input{position:absolute;right:.35rem;top:50%;transform:translateY(-50%)}.mng-search{min-width:20rem}.search-shortcut-hint{position:absolute;right:1rem;top:50%;transform:translateY(-50%);font-size:1.1rem;pointer-events:none;opacity:.5;transition:opacity .15s}.search-input:not(:placeholder-shown)~.search-shortcut-hint,.search-input:focus~.search-shortcut-hint{opacity:0;pointer-events:none}\n"] }]
1664
+ }], ctorParameters: () => [], propDecorators: { metadata: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: true }] }], genericFilterDescriptor: [{ type: i0.Input, args: [{ isSignal: true, alias: "genericFilterDescriptor", required: false }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], enableSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSearch", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }], searchLimitWordMax: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchLimitWordMax", required: false }] }], enableCaseSensitive: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableCaseSensitive", required: false }] }], filterOverlay: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Popover), { isSignal: true }] }], filterFormComponent: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TableFilterFormComponent), { isSignal: true }] }], templates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TableHeaderWithFiltersTemplateDirective), { isSignal: true }] }], filterSplitButton: [{ type: i0.ViewChild, args: ['filterSplitButton', { isSignal: true }] }], searchInput: [{ type: i0.ViewChild, args: ['searchInput', { isSignal: true }] }], filterShortcuts: [{
1665
+ type: HostListener,
1666
+ args: ['window:keydown', ['$event']]
1667
+ }] } }) });
1668
+
1669
+ /**
1670
+ * Generates and displays a notification for a table-related error with localized error messages and details.
1671
+ *
1672
+ * @param {TranslateService} translate - The service used to handle localization and translations.
1673
+ * @param {MessageService} messageService - The service used to manage and display messages.
1674
+ * @param {TableDescriptorInst<any>} table - The table descriptor containing table-specific information and model data.
1675
+ * @param {Error} error - The error object providing details about the error that occurred.
1676
+ * @return {Message | null} The generated message object for the error notification or null if no notification was created.
1677
+ */
1678
+ function tableNotificationError(translate, messageService, table, error) {
1679
+ const params = {
1680
+ errorMessage: getI18nForError(translate, error) ?? error.message,
1681
+ ...getI18nErrorParams(error)
1682
+ };
1683
+ const tableErrorTitle = getI18nForModel(translate, table.model, 'table.error.title', { fallbackKey: 'general.error', params }) ?? undefined;
1684
+ const tableErrorMessage = getI18nForModel(translate, table.model, 'table.error.message', { fallbackKey: 'general.errorMessage', params }) ?? undefined;
1685
+ return toastMessage(tableErrorMessage ?? error.message, 'error', { messageService: messageService, title: tableErrorTitle, icon: 'pi-exclamation-triangle' });
1686
+ }
1687
+
1688
+ class LocaleDefaultRowClassPipe {
1689
+ constructor() {
1690
+ this.injector = inject(Injector);
1691
+ }
1692
+ transform(value, descriptor, item) {
1693
+ if (descriptor?.isLocalized) {
1694
+ if (item[descriptor.localizationLocaleProperty] === this.injector.get(CommonsService).getDefaultLocale()) {
1695
+ return value + ' mng-table-row-localization-default-locale';
1696
+ }
1697
+ }
1698
+ return value ?? '';
1699
+ }
1700
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LocaleDefaultRowClassPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1701
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: LocaleDefaultRowClassPipe, isStandalone: true, name: "mngLocaleDefaultRowClass" }); }
1702
+ }
1703
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LocaleDefaultRowClassPipe, decorators: [{
1704
+ type: Pipe,
1705
+ args: [{
1706
+ name: 'mngLocaleDefaultRowClass',
1707
+ pure: true
1708
+ }]
1709
+ }] });
1710
+
1711
+ class TableFilterClassPipe {
1712
+ transform(value, filter, isEnabled) {
1713
+ const strValue = typeof value === 'string' ? value : '';
1714
+ if (isEnabled && filter?.filterType !== undefined) {
1715
+ return `${strValue} mng-filter-${FilterTypeEnum[filter.filterType].toLowerCase()}`;
1716
+ }
1717
+ else {
1718
+ return strValue;
1719
+ }
1720
+ }
1721
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterClassPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
1722
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: TableFilterClassPipe, isStandalone: true, name: "mngTableFilterClass" }); }
1723
+ }
1724
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFilterClassPipe, decorators: [{
1725
+ type: Pipe,
1726
+ args: [{
1727
+ pure: true,
1728
+ name: 'mngTableFilterClass'
1729
+ }]
1730
+ }] });
1731
+
1732
+ function tableCreateFilterMeta(paramsWithDefaults) {
1733
+ const primeFilterMeta = {};
1734
+ // if any filter is present, no default filters should be applied!
1735
+ if (paramsWithDefaults?.filters) {
1736
+ Object.entries(paramsWithDefaults.filters).forEach(([key, value]) => {
1737
+ primeFilterMeta[key] = {
1738
+ value: value?.value,
1739
+ matchMode: value?.matchMode,
1740
+ caseSensitive: value?.caseSensitive,
1741
+ disabled: value?.disabled
1742
+ };
1743
+ });
1744
+ }
1745
+ return primeFilterMeta;
1746
+ }
1747
+ function tableCreateSortMeta(paramsWithDefaults) {
1748
+ if (paramsWithDefaults?.sort !== undefined && Array.isArray(paramsWithDefaults?.sort) && paramsWithDefaults?.sort.length > 0) {
1749
+ return paramsWithDefaults?.sort.map(s => ({
1750
+ field: s.property,
1751
+ order: s.ascending ? 1 : -1
1752
+ }));
1753
+ }
1754
+ return undefined;
1755
+ }
1756
+
1757
+ class TableMetadataService {
1758
+ static { this.cmpTypeName = 'TableComponent'; }
1759
+ #injector;
1760
+ #primeConfig;
1761
+ #translationObserver;
1762
+ // signal sources
1763
+ #signalSources;
1764
+ #descriptor;
1765
+ #updateDescriptorFromSourceEffect;
1766
+ #genericFilters;
1767
+ // search
1768
+ #searchFieldsFromSignalSource;
1769
+ #searchFields;
1770
+ #searchFieldsEffect;
1771
+ constructor() {
1772
+ this.#injector = inject(Injector);
1773
+ this.#primeConfig = inject(PrimeNG);
1774
+ this.moduleConfig = inject(COMMONS_MODULE_CONFIG_IT, { optional: true });
1775
+ this.tableModuleConfig = inject(COMMONS_TABLE_FEATURE_CONFIG_IT, { optional: true });
1776
+ this.serializationCfg = {};
1777
+ this.#translationObserver = toSignal(this.#primeConfig.translationObserver);
1778
+ this.defaultFilterDisplayType = this.tableModuleConfig?.filterDisplayType ?? FilterDisplayTypeEnum.Column;
1779
+ // signal sources
1780
+ this.#signalSources = signal({}, ...(ngDevMode ? [{ debugName: "#signalSources" }] : []));
1781
+ // descriptors
1782
+ this.descriptorFromSource = computed(() => this.#signalSources().descriptor?.(), ...(ngDevMode ? [{ debugName: "descriptorFromSource" }] : []));
1783
+ this.#descriptor = signal(tableDescriptor(), ...(ngDevMode ? [{ debugName: "#descriptor" }] : []));
1784
+ this.descriptor = this.#descriptor.asReadonly();
1785
+ this.#updateDescriptorFromSourceEffect = effectWithDeps([this.descriptorFromSource], ([d]) => {
1786
+ if (d != null) {
1787
+ this.#descriptor.set(d);
1788
+ }
1789
+ });
1790
+ // pagination
1791
+ this.rowsPerPageOptions = computed(() => {
1792
+ const descriptor = this.descriptor();
1793
+ if (Array.isArray(descriptor.rowsPerPageOptions) && descriptor.rowsPerPageOptions.length > 0) {
1794
+ return descriptor.rowsPerPageOptions;
1795
+ }
1796
+ else {
1797
+ return [25, 50, 100];
1798
+ }
1799
+ }, ...(ngDevMode ? [{ debugName: "rowsPerPageOptions" }] : []));
1800
+ // filters
1801
+ this.filterDescriptors = computed(() => this.descriptor().filters, ...(ngDevMode ? [{ debugName: "filterDescriptors" }] : []));
1802
+ this.filters = computed(() => {
1803
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1804
+ const observer = this.#translationObserver(); // need this one to track language changes
1805
+ return this.filterDescriptors().map(d => this.mapFilterDescriptorToMetadata(d));
1806
+ }, ...(ngDevMode ? [{ debugName: "filters" }] : []));
1807
+ this.genericFilterDescriptor = computed(() => this.descriptor().genericFilter, ...(ngDevMode ? [{ debugName: "genericFilterDescriptor" }] : []));
1808
+ this.#genericFilters = signal([], ...(ngDevMode ? [{ debugName: "#genericFilters" }] : []));
1809
+ this.genericFilters = this.#genericFilters.asReadonly();
1810
+ // search
1811
+ this.#searchFieldsFromSignalSource = computed(() => this.#signalSources().searchFields?.(), ...(ngDevMode ? [{ debugName: "#searchFieldsFromSignalSource" }] : []));
1812
+ this.#searchFields = signal([], ...(ngDevMode ? [{ debugName: "#searchFields" }] : []));
1813
+ this.searchFields = this.#searchFields.asReadonly();
1814
+ this.#searchFieldsEffect = effectWithDeps([this.descriptor, this.#searchFieldsFromSignalSource], ([descriptor, searchFieldsFromSignalSource]) => {
1815
+ this.#searchFields.set(searchFieldsFromSignalSource ?? (descriptor.search && descriptor.searchFields ? descriptor.searchFields : this.descriptor().columns.map(c => c.property)));
1816
+ });
1817
+ // params
1818
+ this.defaultParams = computed(() => {
1819
+ const params = {
1820
+ offset: 0,
1821
+ limit: this.rowsPerPageOptions()[0],
1822
+ sort: this.descriptor()
1823
+ .sorts.filter(s => s.defaultIsEnabled)
1824
+ .sort((s1, s2) => (s1.defaultOrder ?? 1000) - (s2.defaultOrder ?? 1000))
1825
+ .map(s => ({
1826
+ property: s.property,
1827
+ ascending: s.defaultIsAscending
1828
+ })),
1829
+ filters: {}
1830
+ };
1831
+ this.filters()
1832
+ .filter(f => f.descriptor.hasDefaultValue)
1833
+ .forEach(f => {
1834
+ params.filters[f.descriptor.property] = {
1835
+ value: f.descriptor.defaultValue,
1836
+ matchMode: f.defaultMatchMode
1837
+ };
1838
+ });
1839
+ return params;
1840
+ }, ...(ngDevMode ? [{ debugName: "defaultParams" }] : []));
1841
+ filterApplySerializationConfigToCmp(this.moduleConfig, this.serializationCfg);
1842
+ combineLatest([toObservable(this.genericFilterDescriptor), toObservable(this.#translationObserver)])
1843
+ .pipe(switchMap(([genericFilterDescriptor]) => {
1844
+ if (genericFilterDescriptor) {
1845
+ const dataProvider = this.genericFilterDescriptor()?.propertyLookup;
1846
+ const genericFilterService = dataProvider?.serviceType ? this.#injector.get(dataProvider.serviceType) : null;
1847
+ // fetch filterable properties
1848
+ return toObservable$1(genericFilterDescriptor.propertyLookup.lookup({}, genericFilterService));
1849
+ }
1850
+ return of([]);
1851
+ }), takeUntilDestroyed())
1852
+ .subscribe({
1853
+ next: genericFilters => {
1854
+ // set descriptors from generic filter data
1855
+ this.#genericFilters.set(createFilterDescriptorsFromGeneric(genericFilters, this.genericFilterDescriptor()?.valueLookup).map(d => this.mapFilterDescriptorToMetadata(d)));
1856
+ }
1857
+ });
1858
+ }
1859
+ setSignalSources(descriptor, searchFields) {
1860
+ this.#signalSources.set({ descriptor, searchFields });
1861
+ }
1862
+ setDescriptor(descriptor) {
1863
+ if (this.descriptorFromSource() instanceof TableDynamicDescriptorInst) {
1864
+ this.#descriptor.set(descriptor);
1865
+ }
1866
+ }
1867
+ mapFilterDescriptorToMetadata(descriptor) {
1868
+ const matchModes = filterGenerateMatchModeOptions(this.#primeConfig, descriptor, this.serializationCfg);
1869
+ return {
1870
+ descriptor: descriptor,
1871
+ matchModes: matchModes,
1872
+ defaultMatchMode: filterGetDefaultMatchMode(descriptor, matchModes),
1873
+ dateConfig: filterGetDateConfig(descriptor, this.serializationCfg),
1874
+ numberConfig: filterGetNumberConfig(descriptor)
1875
+ };
1876
+ }
1877
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableMetadataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1878
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableMetadataService }); }
1879
+ }
1880
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableMetadataService, decorators: [{
1881
+ type: Injectable
1882
+ }], ctorParameters: () => [] });
1883
+
1884
+ class TableDataService extends ADataListService {
1885
+ #injector;
1886
+ #destroyRef;
1887
+ #commons;
1888
+ #metadata;
1889
+ #primeTable;
1890
+ // signal sources
1891
+ #dataSources;
1892
+ // data sources
1893
+ #manualLoading;
1894
+ // results that are set directly via input and are not result of a asynchronous operation (aka data provider)
1895
+ #synchronousResult;
1896
+ #dataProvider;
1897
+ #dataProviderService;
1898
+ #synchronousResultEffect;
1899
+ #synchronousLoadingEffect;
1900
+ #manualLoadingEffect;
1901
+ #dataProviderSubscription;
1902
+ // pagination
1903
+ #params;
1904
+ #sortStates;
1905
+ #filterStates;
1906
+ #isSortAndFilterMetaInitialized;
1907
+ #defaultParamsEffect;
1908
+ #isSearchMetaInitialized;
1909
+ #searchState;
1910
+ // data
1911
+ #data;
1912
+ #count;
1913
+ #loading;
1914
+ constructor() {
1915
+ super();
1916
+ this.#injector = inject(Injector);
1917
+ this.#destroyRef = inject(DestroyRef);
1918
+ this.#commons = inject(CommonsService);
1919
+ this.#metadata = inject(TableMetadataService);
1920
+ // signal sources
1921
+ this.#dataSources = signal({}, ...(ngDevMode ? [{ debugName: "#dataSources" }] : []));
1922
+ // data sources
1923
+ this.#manualLoading = computed(() => this.#dataSources()?.manualLoading?.(), ...(ngDevMode ? [{ debugName: "#manualLoading" }] : []));
1924
+ // results that are set directly via input and are not result of a asynchronous operation (aka data provider)
1925
+ this.#synchronousResult = computed(() => {
1926
+ const dataSources = this.#dataSources();
1927
+ if (dataSources?.dataProvider?.() !== undefined) {
1928
+ return undefined;
1929
+ }
1930
+ if (dataSources?.dataListResult?.() !== undefined) {
1931
+ return dataSources?.dataListResult();
1932
+ }
1933
+ if (dataSources?.arrayItems?.() !== undefined) {
1934
+ return { data: dataSources.arrayItems(), totalCount: dataSources.arrayItems()?.length ?? 0 };
1935
+ }
1936
+ return undefined;
1937
+ }, ...(ngDevMode ? [{ debugName: "#synchronousResult" }] : []));
1938
+ this.#dataProvider = computed(() => this.#dataSources()?.dataProvider?.(), ...(ngDevMode ? [{ debugName: "#dataProvider" }] : []));
1939
+ this.#dataProviderService = computed(() => {
1940
+ const dataProvider = this.#dataProvider();
1941
+ return dataProvider?.serviceType ? this.#injector.get(dataProvider.serviceType) : null;
1942
+ }, ...(ngDevMode ? [{ debugName: "#dataProviderService" }] : []));
1943
+ this.#synchronousResultEffect = effectWithDeps([this.#synchronousResult], ([res]) => {
1944
+ if (res != null) {
1945
+ this.#setData(res.data ?? [], res.totalCount);
1946
+ }
1947
+ });
1948
+ this.#synchronousLoadingEffect = effectWithDeps([this.#synchronousResult, this.#manualLoading], ([res, manualLoading]) => {
1949
+ if (res != null && manualLoading == null) {
1950
+ this.#loading.set(false);
1951
+ }
1952
+ });
1953
+ this.#manualLoadingEffect = effectWithDeps([this.#manualLoading], ([manualLoading]) => {
1954
+ if (manualLoading != null) {
1955
+ this.#loading.set(manualLoading);
1956
+ }
1957
+ });
1958
+ // pagination
1959
+ this.#params = signal(undefined, ...(ngDevMode ? [{ debugName: "#params" }] : []));
1960
+ this.params = this.#params.asReadonly();
1961
+ this.#sortStates = signal(undefined, ...(ngDevMode ? [{ debugName: "#sortStates" }] : []));
1962
+ this.sortStates = this.#sortStates.asReadonly();
1963
+ this.#filterStates = signal({}, ...(ngDevMode ? [{ debugName: "#filterStates" }] : []));
1964
+ this.filterStates = this.#filterStates.asReadonly();
1965
+ this.primeFilterStates = computed(() => {
1966
+ const filterStates = this.#filterStates();
1967
+ const searchState = this.#searchState();
1968
+ const primeFilterStates = { ...filterStates };
1969
+ if (searchState != null) {
1970
+ primeFilterStates['global'] = { ...searchState, matchMode: 'contains' };
1971
+ }
1972
+ return primeFilterStates;
1973
+ }, ...(ngDevMode ? [{ debugName: "primeFilterStates" }] : []));
1974
+ this.#isSortAndFilterMetaInitialized = signal(false, ...(ngDevMode ? [{ debugName: "#isSortAndFilterMetaInitialized" }] : []));
1975
+ this.#defaultParamsEffect = effectWithDeps([this.#metadata.defaultParams], ([defaultParams]) => {
1976
+ this.#sortStates.set(tableCreateSortMeta(defaultParams));
1977
+ this.#filterStates.set(tableCreateFilterMeta(defaultParams));
1978
+ this.#isSortAndFilterMetaInitialized.set(true);
1979
+ }, { firstOnly: true });
1980
+ this.#isSearchMetaInitialized = signal(false, ...(ngDevMode ? [{ debugName: "#isSearchMetaInitialized" }] : []));
1981
+ this.#searchState = signal(undefined, ...(ngDevMode ? [{ debugName: "#searchState" }] : []));
1982
+ this.searchState = this.#searchState.asReadonly();
1983
+ this.isAllPaginationMetaInitialized = computed(() => this.#isSortAndFilterMetaInitialized() && this.#isSortAndFilterMetaInitialized(), ...(ngDevMode ? [{ debugName: "isAllPaginationMetaInitialized" }] : []));
1984
+ this.paginationMode = computed(() => {
1985
+ const descriptor = this.#metadata.descriptor();
1986
+ if (descriptor.paginationMode != null) {
1987
+ // descriptor choice is the strongest - if defined, use this value
1988
+ return descriptor.paginationMode;
1989
+ }
1990
+ else if (this.#dataProvider() != null) {
1991
+ // when data provider is used, use pagination
1992
+ return TablePaginationModeEnum.Pagination;
1993
+ }
1994
+ else {
1995
+ return TablePaginationModeEnum.None;
1996
+ }
1997
+ }, ...(ngDevMode ? [{ debugName: "paginationMode" }] : []));
1998
+ this.offset = computed(() => this.params()?.offset ?? 0, ...(ngDevMode ? [{ debugName: "offset" }] : []));
1999
+ this.rows = computed(() => {
2000
+ const params = this.params();
2001
+ if (params?.limit) {
2002
+ return params.limit;
2003
+ }
2004
+ const descriptor = this.#metadata.descriptor();
2005
+ const rowsPerPageOptions = this.#metadata.rowsPerPageOptions();
2006
+ if (descriptor.defaultNumRows && rowsPerPageOptions.includes(descriptor.defaultNumRows)) {
2007
+ return descriptor.defaultNumRows;
2008
+ }
2009
+ return rowsPerPageOptions[0];
2010
+ }, ...(ngDevMode ? [{ debugName: "rows" }] : []));
2011
+ // data
2012
+ this.#data = signal([], ...(ngDevMode ? [{ debugName: "#data" }] : []));
2013
+ this.data = this.#data.asReadonly();
2014
+ this.#count = signal(0, ...(ngDevMode ? [{ debugName: "#count" }] : []));
2015
+ this.count = this.#count.asReadonly();
2016
+ this.#loading = signal(false, ...(ngDevMode ? [{ debugName: "#loading" }] : []));
2017
+ this.loading = this.#loading.asReadonly();
2018
+ this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
2019
+ this.#destroyRef.onDestroy(() => this.#dataProviderSubscription?.unsubscribe());
2020
+ }
2021
+ setDataSources(arrayItems, dataListResult, dataProvider, manualLoading) {
2022
+ this.#dataSources.set({ arrayItems, dataListResult, dataProvider, manualLoading });
2023
+ }
2024
+ setPrimeTable(cmp) {
2025
+ this.#primeTable = cmp;
2026
+ }
2027
+ fetchWithDataProvider(paramsList, onErrorFn) {
2028
+ // remove disabled filters from fetch
2029
+ const params = {
2030
+ ...paramsList,
2031
+ filters: paramsList.filters ? Object.fromEntries(Object.entries(paramsList.filters).filter(([_, f]) => !f?.disabled)) : undefined
2032
+ };
2033
+ const dataProvider = this.#dataProvider();
2034
+ if (!dataProvider || params.limit === 0) {
2035
+ return false;
2036
+ }
2037
+ this.#dataProviderSubscription?.unsubscribe();
2038
+ this.#loading.set(true);
2039
+ this.#dataProviderSubscription = toObservable$1(dataProvider.getAll(params, this.#dataProviderService(), this.#metadata.descriptor().isLocalized ? (this.#commons.appDataLocale() ?? undefined) : undefined)).subscribe({
2040
+ next: res => {
2041
+ const descriptorInput = this.#metadata.descriptorFromSource();
2042
+ if (descriptorInput instanceof TableDynamicDescriptorInst) {
2043
+ this.#metadata.setDescriptor(descriptorInput.toTableDescriptorFromData(res));
2044
+ }
2045
+ this.#setData(res?.data ?? [], res?.totalCount);
2046
+ this.#loading.set(false);
2047
+ },
2048
+ error: err => {
2049
+ onErrorFn(err);
2050
+ this.#setData([]);
2051
+ this.#loading.set(false);
2052
+ }
2053
+ });
2054
+ return true;
2055
+ }
2056
+ setParams(params, fromQueryParams = false) {
2057
+ if (!fromQueryParams && this.compareWithCurrentParams(params)) {
2058
+ return;
2059
+ }
2060
+ this.#params.set(params);
2061
+ this.#sortStates.set(tableCreateSortMeta(params));
2062
+ this.#filterStates.set(tableCreateFilterMeta(params));
2063
+ this.#isSortAndFilterMetaInitialized.set(true);
2064
+ if (fromQueryParams && !this.#isSearchMetaInitialized() && params?.search) {
2065
+ this.#searchState.set({ value: params.search, caseSensitive: params.filters?.['global']?.caseSensitive ?? false });
2066
+ }
2067
+ this.#isSearchMetaInitialized.set(true);
2068
+ }
2069
+ /**
2070
+ * Updates primeNG component with new filters and triggers data reload (if lazy load) or inline filtering.ž
2071
+ * Usually setting the params should trigger the cycle to load data and calculate other states (sort, filter, search, etc.) from params.
2072
+ * In case of PrimeNG's inline filtering, the internal primeNG state must be updated first and the states must subsequently be updated via callback functions.
2073
+ *
2074
+ * @param filters - { [fieldName]: FilterState | undefined } where:
2075
+ * - fieldName = column field identifier
2076
+ * - FilterState = full filter config
2077
+ * - undefined = clears filter for that field
2078
+ */
2079
+ updateFilters(filters) {
2080
+ if (!this.#primeTable)
2081
+ return;
2082
+ for (const key of Object.keys(filters)) {
2083
+ this.#primeTable.filters[key] = { ...filters[key] };
2084
+ }
2085
+ this.#primeTable._filter();
2086
+ }
2087
+ updateSearch(search) {
2088
+ if (!this.#primeTable)
2089
+ return;
2090
+ this.#primeTable.filters['global'] = { ...search, matchMode: 'contains' };
2091
+ this.#primeTable._filter();
2092
+ }
2093
+ /**
2094
+ * Compare the given params with the stored params in the DataListService.
2095
+ *
2096
+ * @param {DataListParams} params - The params to compare with the stored params.
2097
+ *
2098
+ * @return {boolean} - True if the given params match the stored params, otherwise false.
2099
+ */
2100
+ compareWithCurrentParams(params) {
2101
+ return (params.offset === this.offset() &&
2102
+ params.limit === this.rows() &&
2103
+ JSON.stringify(tableCreateSortMeta(params)) === JSON.stringify(this.#sortStates()) &&
2104
+ JSON.stringify(tableCreateFilterMeta(params)) === JSON.stringify(this.#filterStates()));
2105
+ }
2106
+ #setData(data, count) {
2107
+ this.#data.set([...data]);
2108
+ this.#count.set(count ?? data.length);
2109
+ }
2110
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableDataService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2111
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableDataService }); }
2112
+ }
2113
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableDataService, decorators: [{
2114
+ type: Injectable
2115
+ }], ctorParameters: () => [] });
2116
+
2117
+ /**
2118
+ * generates table layout preferences key used when saving preferences to localstorage
2119
+ * @param typeName string, required
2120
+ * @param url string, required
2121
+ * @param trackProperty string, not required
2122
+ */
2123
+ function generateTableLayoutPrefsKey(typeName, url, trackProperty) {
2124
+ return `commonsTableLayoutPrefs~~${typeName}~~${trackProperty ?? url.split('?')[0].split('#')[0]}`;
2125
+ }
2126
+
2127
+ class TablePreferencesService {
2128
+ constructor() {
2129
+ this.#router = inject(Router);
2130
+ this.#storageService = inject(CommonsStorageService);
2131
+ this.#metadata = inject(TableMetadataService);
2132
+ this.localstorageKey = computed(() => {
2133
+ const descriptor = this.#metadata.descriptor();
2134
+ return descriptor.model.i18nBaseKey ? generateTableLayoutPrefsKey(descriptor.model.i18nBaseKey, this.#router.url, descriptor.identifier) : null;
2135
+ }, ...(ngDevMode ? [{ debugName: "localstorageKey" }] : []));
2136
+ this.#layoutPrefsSaveCnt = signal(0, ...(ngDevMode ? [{ debugName: "#layoutPrefsSaveCnt" }] : []));
2137
+ this.layoutPreferences = computed(() => {
2138
+ const lsKey = this.localstorageKey();
2139
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2140
+ const cnt = this.#layoutPrefsSaveCnt(); // needed to force updates on user changes
2141
+ const layoutPrefs = lsKey ? this.#storageService.getItem(TableMetadataService.cmpTypeName, lsKey) : undefined;
2142
+ return layoutPrefs ?? { columnWidths: {} };
2143
+ }, ...(ngDevMode ? [{ debugName: "layoutPreferences" }] : []));
2144
+ // columns
2145
+ this.columnsWithPrefs = computed(() => this.#computeColumnsWithLayout(), ...(ngDevMode ? [{ debugName: "columnsWithPrefs" }] : []));
2146
+ }
2147
+ #router;
2148
+ #storageService;
2149
+ #metadata;
2150
+ #layoutPrefsSaveCnt;
2151
+ /**
2152
+ * Method is called on column resize
2153
+ * @param element event's element
2154
+ */
2155
+ onColumnResize({ element }) {
2156
+ const fieldId = element.id;
2157
+ const width = element.offsetWidth;
2158
+ const layoutPrefs = this.layoutPreferences();
2159
+ const col = this.columnsWithPrefs().find(el => el.descriptor.property === fieldId);
2160
+ if (col)
2161
+ col.width = width;
2162
+ if (!layoutPrefs.columnWidths)
2163
+ layoutPrefs.columnWidths = {};
2164
+ layoutPrefs.columnWidths[fieldId] = width;
2165
+ this.#saveLayoutPreferences(layoutPrefs);
2166
+ }
2167
+ onColumnToggle(event) {
2168
+ const layoutPrefs = this.layoutPreferences();
2169
+ const selectedColumns = event.value.map(v => v.descriptor.property);
2170
+ layoutPrefs.columnHidden = this.columnsWithPrefs()
2171
+ .filter(c => selectedColumns.indexOf(c.descriptor.property) < 0)
2172
+ .map(c => c.descriptor.property);
2173
+ this.#saveLayoutPreferences(layoutPrefs, true);
2174
+ }
2175
+ onColumnToggleAll() {
2176
+ const layoutPrefs = this.layoutPreferences();
2177
+ const columns = [...this.columnsWithPrefs()];
2178
+ const isVisible = !this.columnsWithPrefs().some(c => c.isVisible);
2179
+ for (const col of columns) {
2180
+ if (isVisible !== col.isVisible) {
2181
+ col.isVisible = isVisible;
2182
+ }
2183
+ }
2184
+ layoutPrefs.columnHidden = columns.filter(c => !c.isVisible).map(c => c.descriptor.property);
2185
+ this.#saveLayoutPreferences(layoutPrefs, true);
2186
+ }
2187
+ onColumnReorder(event) {
2188
+ if (event.dropIndex !== undefined && event.dropIndex >= 0 && event.dragIndex !== undefined && event.dragIndex >= 0 && event.dropIndex !== event.dragIndex) {
2189
+ const eventDropIndex = event.dropIndex;
2190
+ const eventDragIndex = event.dragIndex;
2191
+ const prevVisibleColumns = this.columnsWithPrefs().filter(c => c.isVisible);
2192
+ const colAtDrop = prevVisibleColumns[eventDropIndex];
2193
+ const colAtDrag = prevVisibleColumns[eventDragIndex];
2194
+ const colAtDropIndex = this.columnsWithPrefs().findIndex(el => el.id === colAtDrop.id);
2195
+ const colAtDragIndex = this.columnsWithPrefs().findIndex(el => el.id === colAtDrag.id);
2196
+ if (colAtDropIndex > -1 && colAtDragIndex > -1) {
2197
+ let columns = [...this.columnsWithPrefs()];
2198
+ columns.splice(colAtDragIndex, 1);
2199
+ const dropIndex = columns.findIndex(el => el.id === colAtDrop.id) + (eventDropIndex > eventDragIndex ? 1 : 0);
2200
+ columns = [...columns.slice(0, dropIndex), colAtDrag, ...columns.slice(dropIndex)];
2201
+ const layoutPrefs = this.layoutPreferences();
2202
+ layoutPrefs.columnOrder = columns.map(el => el.descriptor.property);
2203
+ this.#saveLayoutPreferences(layoutPrefs);
2204
+ }
2205
+ }
2206
+ }
2207
+ /**
2208
+ * Reset column order and column visibility to default settings
2209
+ */
2210
+ clearLayoutPreferences() {
2211
+ const key = this.localstorageKey();
2212
+ if (key) {
2213
+ this.#storageService.removeItem(TableMetadataService.cmpTypeName, key);
2214
+ this.#layoutPrefsSaveCnt.update(v => v + 1);
2215
+ }
2216
+ }
2217
+ #saveLayoutPreferences(layoutPrefs, forceUpdate = false) {
2218
+ const key = this.localstorageKey();
2219
+ if (key) {
2220
+ this.#storageService.setItem(TableMetadataService.cmpTypeName, key, layoutPrefs);
2221
+ if (forceUpdate) {
2222
+ this.#layoutPrefsSaveCnt.update(v => v + 1);
2223
+ }
2224
+ }
2225
+ }
2226
+ #computeColumnsWithLayout() {
2227
+ const descriptor = this.#metadata.descriptor();
2228
+ const layoutPrefs = this.layoutPreferences();
2229
+ // initialize columns with additional properties
2230
+ const timestamp = new Date().getTime();
2231
+ const columns = descriptor.columns.map(col => ({
2232
+ id: `${col.property}-${timestamp}`,
2233
+ descriptor: col,
2234
+ filter: this.#metadata
2235
+ .filters()
2236
+ .find(f => f.descriptor.showOnColumn === col.property &&
2237
+ ((f.descriptor.displayType == null && this.#metadata.defaultFilterDisplayType === FilterDisplayTypeEnum.Column) ||
2238
+ f.descriptor.displayType === FilterDisplayTypeEnum.Column)),
2239
+ sort: descriptor.sorts.find(f => f.showOnColumn === col.property),
2240
+ disabled: !col.isToggleable,
2241
+ isVisible: layoutPrefs.columnHidden ? !layoutPrefs.columnHidden.includes(col.property) : col.isVisible,
2242
+ width: layoutPrefs.columnWidths?.[col.property]
2243
+ }));
2244
+ if (layoutPrefs.columnOrder) {
2245
+ for (let i = 0; i < layoutPrefs.columnOrder.length; i++) {
2246
+ const colName = layoutPrefs.columnOrder[i];
2247
+ const colWithPrefs = columns.find(el => el.descriptor.property === colName);
2248
+ if (colWithPrefs) {
2249
+ colWithPrefs.orderIdx = i;
2250
+ }
2251
+ }
2252
+ }
2253
+ return columns.sort((a, b) => (a.orderIdx !== undefined && b.orderIdx !== undefined ? a.orderIdx - b.orderIdx : 0));
2254
+ }
2255
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TablePreferencesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2256
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TablePreferencesService }); }
2257
+ }
2258
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TablePreferencesService, decorators: [{
2259
+ type: Injectable
2260
+ }] });
2261
+
2262
+ class TableRemovableSortDirective {
2263
+ #pTable = inject(Table);
2264
+ constructor() {
2265
+ this.#overrideSortMethod(this.#pTable);
2266
+ }
2267
+ #overrideSortMethod(pTable) {
2268
+ pTable.sort = (event) => {
2269
+ const originalEvent = event.originalEvent;
2270
+ const metaKey = originalEvent.metaKey || originalEvent.ctrlKey;
2271
+ const sortMeta = pTable.getSortMeta(event.field);
2272
+ if (sortMeta) {
2273
+ if (!metaKey) {
2274
+ this.#updateSingleSortMeta(pTable, sortMeta, event.field);
2275
+ }
2276
+ else {
2277
+ this.#updateMultiSortMeta(pTable, sortMeta);
2278
+ }
2279
+ }
2280
+ else {
2281
+ this.#addNewSortMeta(pTable, metaKey, event.field);
2282
+ }
2283
+ this.#applySort(pTable);
2284
+ if (pTable.isStateful()) {
2285
+ pTable.saveState();
2286
+ }
2287
+ pTable.anchorRowIndex = null;
2288
+ };
2289
+ }
2290
+ #updateSingleSortMeta(pTable, sortMeta, field) {
2291
+ if (pTable.multiSortMeta && pTable.multiSortMeta.length > 1) {
2292
+ pTable.multiSortMeta = [{ field, order: pTable.defaultSortOrder }];
2293
+ }
2294
+ else if (sortMeta.order === -1) {
2295
+ pTable.multiSortMeta = [];
2296
+ }
2297
+ else {
2298
+ pTable.multiSortMeta = [{ field, order: sortMeta.order * -1 }];
2299
+ }
2300
+ }
2301
+ #updateMultiSortMeta(pTable, sortMeta) {
2302
+ pTable.multiSortMeta ??= [];
2303
+ for (let i = 0; i < pTable.multiSortMeta.length; i++) {
2304
+ if (pTable.multiSortMeta[i].field === sortMeta.field) {
2305
+ pTable.multiSortMeta.splice(i, 1);
2306
+ }
2307
+ }
2308
+ if (sortMeta.order === 1) {
2309
+ sortMeta.order = sortMeta.order * -1;
2310
+ pTable.multiSortMeta?.push(sortMeta);
2311
+ }
2312
+ }
2313
+ #addNewSortMeta(pTable, metaKey, field) {
2314
+ if (!metaKey || !pTable.multiSortMeta) {
2315
+ pTable.multiSortMeta = [];
2316
+ }
2317
+ pTable.multiSortMeta?.push({ field, order: pTable.defaultSortOrder });
2318
+ }
2319
+ #applySort(pTable) {
2320
+ if (pTable.multiSortMeta?.length === 0 && !pTable.lazy) {
2321
+ pTable.multiSortMeta = this.#defaultMultiSortMeta();
2322
+ }
2323
+ pTable.sortMultiple();
2324
+ }
2325
+ #defaultMultiSortMeta() {
2326
+ const multiSortMeta = this.#pTable.columns
2327
+ ?.filter(column => column.sort?._defaultIsEnabled)
2328
+ .sort((a, b) => a.sort._defaultOrder - b.sort._defaultOrder)
2329
+ .map(column => ({ field: column.sort._property, order: column.sort._defaultIsAscending ? 1 : -1 }));
2330
+ if (!multiSortMeta || multiSortMeta.length === 0) {
2331
+ return [{ field: this.#pTable.columns?.filter(column => column.sort)?.[0].sort._property, order: 1 }];
2332
+ }
2333
+ return multiSortMeta;
2334
+ }
2335
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableRemovableSortDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2336
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: TableRemovableSortDirective, isStandalone: true, selector: "[mngRemovableSort]", ngImport: i0 }); }
2337
+ }
2338
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableRemovableSortDirective, decorators: [{
2339
+ type: Directive,
2340
+ args: [{
2341
+ selector: '[mngRemovableSort]'
2342
+ }]
2343
+ }], ctorParameters: () => [] });
2344
+
2345
+ class TableTemplateDirective extends TemplateDirective {
2346
+ constructor() {
2347
+ super(...arguments);
2348
+ this.name = input.required(...(ngDevMode ? [{ debugName: "name" }] : []));
2349
+ }
2350
+ // narrow the type of the context using the generic type of the directive.
2351
+ static ngTemplateContextGuard(dir, ctx) {
2352
+ return true;
2353
+ }
2354
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableTemplateDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2355
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.15", type: TableTemplateDirective, isStandalone: true, selector: "[mngTableTemplate]", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0 }); }
2356
+ }
2357
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableTemplateDirective, decorators: [{
2358
+ type: Directive,
2359
+ args: [{
2360
+ selector: '[mngTableTemplate]'
2361
+ }]
2362
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }] } });
2363
+
2364
+ class TableComponent {
2365
+ #primeTableEffect;
2366
+ // templates
2367
+ #templatesMerged;
2368
+ // subscriptions and refs
2369
+ #previousDataProvider;
2370
+ #dataProviderEagerFirstLoad;
2371
+ #dataProviderReloadSubscription;
2372
+ #routeQueryParamsSubscription;
2373
+ #routerEventsSubscription;
2374
+ #afterNextRenderRef;
2375
+ constructor() {
2376
+ this.filterKeyPrepend = 'f_';
2377
+ this.FilterTypeEnum = FilterTypeEnum;
2378
+ this.logger = inject(LoggerService).create(TableMetadataService.cmpTypeName);
2379
+ this.router = inject(Router);
2380
+ this.route = inject(ActivatedRoute);
2381
+ this.translate = inject(TranslateService);
2382
+ this.messageService = inject(MessageService);
2383
+ this.metadata = inject(TableMetadataService);
2384
+ this.prefs = inject(TablePreferencesService);
2385
+ this.data = inject((TableDataService));
2386
+ // descriptor
2387
+ this.descriptorInput = input.required(...(ngDevMode ? [{ debugName: "descriptorInput", alias: 'descriptor' }] : [{ alias: 'descriptor' }]));
2388
+ // data source inputs
2389
+ this.items = input(...(ngDevMode ? [undefined, { debugName: "items" }] : []));
2390
+ this.result = input(...(ngDevMode ? [undefined, { debugName: "result" }] : []));
2391
+ this.loadingInput = input(undefined, ...(ngDevMode ? [{ debugName: "loadingInput", alias: 'loading', transform: booleanOrUndefinedAttribute }] : [{ alias: 'loading', transform: booleanOrUndefinedAttribute }]));
2392
+ this.dataProvider = input(...(ngDevMode ? [undefined, { debugName: "dataProvider" }] : []));
2393
+ // extra features input
2394
+ this.useQueryParams = input(false, ...(ngDevMode ? [{ debugName: "useQueryParams", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2395
+ this.cellClickEnabled = input(true, ...(ngDevMode ? [{ debugName: "cellClickEnabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2396
+ this.selectionMode = input('multiple', ...(ngDevMode ? [{ debugName: "selectionMode" }] : []));
2397
+ this.selectionEnabled = input(false, ...(ngDevMode ? [{ debugName: "selectionEnabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2398
+ this.rowReorderEnabledInput = input(true, ...(ngDevMode ? [{ debugName: "rowReorderEnabledInput", alias: 'rowReorderEnabled', transform: booleanAttribute }] : [{ alias: 'rowReorderEnabled', transform: booleanAttribute }]));
2399
+ this.rowReorderEnabled = computed(() => this.rowReorderEnabledInput() && this.metadata.descriptor().rowReorderable, ...(ngDevMode ? [{ debugName: "rowReorderEnabled" }] : []));
2400
+ this.expandedRowKeys = computed(() => {
2401
+ const descriptor = this.metadata.descriptor();
2402
+ if (typeof descriptor.isRowExpanded === 'string') {
2403
+ return this.data.data()?.reduce((acc, item) => {
2404
+ acc[item[descriptor.trackProperty]] = !!item[descriptor.isRowExpanded];
2405
+ return acc;
2406
+ }, {});
2407
+ }
2408
+ else if (typeof descriptor.isRowExpanded === 'function') {
2409
+ return this.data.data()?.reduce((acc, item) => {
2410
+ acc[item[descriptor.trackProperty]] = descriptor.isRowExpanded(item);
2411
+ return acc;
2412
+ }, {});
2413
+ }
2414
+ return {};
2415
+ }, ...(ngDevMode ? [{ debugName: "expandedRowKeys" }] : []));
2416
+ // styling
2417
+ this.columnLastMinWidth = input(...(ngDevMode ? [undefined, { debugName: "columnLastMinWidth" }] : []));
2418
+ this.columnsColspan = computed(() => this.visibleColumns().length + (this.hasLastColumn() ? 1 : 0) + (this.selectionEnabled() ? 1 : 0) + (this.rowReorderEnabled() ? 1 : 0), ...(ngDevMode ? [{ debugName: "columnsColspan" }] : []));
2419
+ this.hasTitleDisplay = computed(() => this.headerTitleTemplate() || this.metadata.descriptor().title, ...(ngDevMode ? [{ debugName: "hasTitleDisplay" }] : []));
2420
+ this.isCaptionVisible = computed(() => this.headerTemplate() || this.hasTitleDisplay() || this.tableHeaderFilters().length > 0 || this.metadata.descriptor().search, ...(ngDevMode ? [{ debugName: "isCaptionVisible" }] : []));
2421
+ // component inputs
2422
+ this.globalFilterFieldsInput = input(undefined, ...(ngDevMode ? [{ debugName: "globalFilterFieldsInput", alias: 'globalFilterFields' }] : [{ alias: 'globalFilterFields' }]));
2423
+ // cell click
2424
+ this.cellClickSubject = new Subject();
2425
+ this.isCellClickObserved = signal(this.cellClickSubject.observed, ...(ngDevMode ? [{ debugName: "isCellClickObserved" }] : []));
2426
+ this.isCellClickEnabled = computed(() => this.cellClickEnabled() && this.isCellClickObserved(), ...(ngDevMode ? [{ debugName: "isCellClickEnabled" }] : []));
2427
+ // event outputs
2428
+ this.tableLoad = output();
2429
+ this.cellClick = outputFromObservable(this.cellClickSubject);
2430
+ this.selectionChange = output();
2431
+ this.rowReorder = output();
2432
+ // content and view queries
2433
+ this.templates = input([], ...(ngDevMode ? [{ debugName: "templates" }] : []));
2434
+ this.contentTemplates = contentChildren(TableTemplateDirective, ...(ngDevMode ? [{ debugName: "contentTemplates" }] : []));
2435
+ this.primeTable = viewChild((Table), ...(ngDevMode ? [{ debugName: "primeTable" }] : []));
2436
+ this.#primeTableEffect = effectWithDeps([this.primeTable], ([table]) => this.data.setPrimeTable(table));
2437
+ // templates
2438
+ this.#templatesMerged = computed(() => [...this.contentTemplates(), ...this.templates()], ...(ngDevMode ? [{ debugName: "#templatesMerged" }] : []));
2439
+ this.headerTemplate = computed(() => findTemplateByName([...this.#templatesMerged()], 'header'), ...(ngDevMode ? [{ debugName: "headerTemplate" }] : []));
2440
+ this.headerTitleTemplate = computed(() => findTemplateByName([...this.#templatesMerged()], 'headerTitle'), ...(ngDevMode ? [{ debugName: "headerTitleTemplate" }] : []));
2441
+ this.titleRowRightTemplate = computed(() => findTemplateByName([...this.#templatesMerged()], 'headerTitleRowRight'), ...(ngDevMode ? [{ debugName: "titleRowRightTemplate" }] : []));
2442
+ this.columnCustomLastTemplate = computed(() => findTemplateByName([...this.#templatesMerged()], 'columnCustomLast'), ...(ngDevMode ? [{ debugName: "columnCustomLastTemplate" }] : []));
2443
+ this.footerTemplate = computed(() => findTemplateByName([...this.#templatesMerged()], 'footer'), ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
2444
+ this.rowExpandTemplate = computed(() => findTemplateByName([...this.#templatesMerged()], 'rowExpandContent'), ...(ngDevMode ? [{ debugName: "rowExpandTemplate" }] : []));
2445
+ this.columnHeaderTemplate = computed(() => findTemplateByName([...this.#templatesMerged()], 'columnHeader'), ...(ngDevMode ? [{ debugName: "columnHeaderTemplate" }] : []));
2446
+ // data provider and items
2447
+ this.isLazy = computed(() => this.dataProvider()?.isLazy === true, ...(ngDevMode ? [{ debugName: "isLazy" }] : []));
2448
+ this.isPagination = computed(() => this.data.paginationMode() === TablePaginationModeEnum.Pagination, ...(ngDevMode ? [{ debugName: "isPagination" }] : []));
2449
+ // visual
2450
+ this.className = computed(() => {
2451
+ let className = this.metadata.descriptor().className ?? '';
2452
+ switch (this.metadata.descriptor().size) {
2453
+ case TableSizeEnum.Small:
2454
+ className += ' p-datatable-sm';
2455
+ break;
2456
+ case undefined:
2457
+ case TableSizeEnum.Large:
2458
+ className += ' p-datatable-lg';
2459
+ break;
2460
+ }
2461
+ if (this.metadata.descriptor().hasGridlines) {
2462
+ className += ' p-datatable-gridlines';
2463
+ }
2464
+ return className;
2465
+ }, ...(ngDevMode ? [{ debugName: "className" }] : []));
2466
+ // columns
2467
+ this.visibleColumns = computed(() => this.prefs.columnsWithPrefs().filter(col => col.isVisible), ...(ngDevMode ? [{ debugName: "visibleColumns" }] : []));
2468
+ this.areColumnsReorderable = computed(() => this.prefs.columnsWithPrefs().some(col => col.descriptor.isReorderable), ...(ngDevMode ? [{ debugName: "areColumnsReorderable" }] : []));
2469
+ this.areColumnsToggleable = computed(() => this.prefs.columnsWithPrefs().some(col => col.descriptor.isToggleable), ...(ngDevMode ? [{ debugName: "areColumnsToggleable" }] : []));
2470
+ // filter, sort
2471
+ this.hasColumnFilters = computed(() => (this.metadata.defaultFilterDisplayType === FilterDisplayTypeEnum.OverlayWithTag &&
2472
+ this.metadata.filterDescriptors().some(d => d.displayType === FilterDisplayTypeEnum.Column)) ||
2473
+ (this.metadata.defaultFilterDisplayType === FilterDisplayTypeEnum.Column && this.metadata.filterDescriptors().some(d => d.displayType == null)), ...(ngDevMode ? [{ debugName: "hasColumnFilters" }] : []));
2474
+ this.tableHeaderFilters = computed(() => {
2475
+ // statically defined filters AND generic filters
2476
+ const filters = this.metadata
2477
+ .filters()
2478
+ .filter(d => (d.descriptor.displayType == null &&
2479
+ [FilterDisplayTypeEnum.OverlayWithTag, FilterDisplayTypeEnum.DirectInput].includes(this.metadata.defaultFilterDisplayType)) ||
2480
+ (d.descriptor.displayType != null && [FilterDisplayTypeEnum.OverlayWithTag, FilterDisplayTypeEnum.DirectInput].includes(d.descriptor.displayType)));
2481
+ return filters.concat(this.metadata.genericFilters());
2482
+ }, ...(ngDevMode ? [{ debugName: "tableHeaderFilters" }] : []));
2483
+ this.requiredFiltersMissing = computed(() => {
2484
+ const paramsWithDefaults = this.data.params() ?? this.metadata.defaultParams();
2485
+ const requiredFilters = this.metadata
2486
+ .filters()
2487
+ .filter(f => f.descriptor.isRequired)
2488
+ .map(f => f.descriptor.property);
2489
+ return requiredFilters.some(filterProperty => {
2490
+ const filter = paramsWithDefaults.filters?.[filterProperty];
2491
+ return (filter === undefined ||
2492
+ filter.matchMode === undefined ||
2493
+ (!['exists', 'doesNotExist'].includes(filter.matchMode) && isFilterValueBlank(filter.value)));
2494
+ });
2495
+ }, ...(ngDevMode ? [{ debugName: "requiredFiltersMissing" }] : []));
2496
+ this.hasLastColumn = computed(() => this.columnCustomLastTemplate() || this.areColumnsToggleable() || this.areColumnsReorderable(), ...(ngDevMode ? [{ debugName: "hasLastColumn" }] : []));
2497
+ // other
2498
+ this.navigationOutOfTableInProgress = false;
2499
+ this.navigationInTableInProgress = false;
2500
+ this.#dataProviderEagerFirstLoad = effectWithDeps([this.dataProvider], ([dataProvider]) => {
2501
+ if (dataProvider?.isLazy === false) {
2502
+ this.loadTableWithDataProvider(this.metadata.defaultParams());
2503
+ }
2504
+ else if (this.#previousDataProvider && dataProvider) {
2505
+ this.reload();
2506
+ }
2507
+ this.#previousDataProvider = dataProvider;
2508
+ });
2509
+ this.#dataProviderReloadSubscription = toObservable(this.dataProvider)
2510
+ .pipe(switchMap(dp => dp?.tableReload$ ?? of({})), takeUntilDestroyed())
2511
+ .subscribe({
2512
+ next: e => {
2513
+ this.reload(e);
2514
+ }
2515
+ });
2516
+ this.#routeQueryParamsSubscription = toObservable(this.useQueryParams)
2517
+ .pipe(switchMap(useQp => (useQp ? this.route.queryParams : NEVER)), takeUntilDestroyed())
2518
+ .subscribe(qp => {
2519
+ this.loadTableFromRouteUpdate(qp);
2520
+ });
2521
+ this.#routerEventsSubscription = toObservable(this.useQueryParams)
2522
+ .pipe(switchMap(useQp => (useQp ? this.router.events : NEVER)), filter(e => (e instanceof NavigationStart && e.url.split('?')[0].split('#')[0] !== this.router.url.split('?')[0].split('#')[0]) ||
2523
+ e instanceof NavigationEnd ||
2524
+ e instanceof NavigationCancel ||
2525
+ e instanceof NavigationError), takeUntilDestroyed())
2526
+ .subscribe(e => {
2527
+ this.navigationOutOfTableInProgress = e instanceof NavigationStart;
2528
+ });
2529
+ this.#afterNextRenderRef = afterNextRender(() => {
2530
+ this.isCellClickObserved.set(this.cellClickSubject.observed);
2531
+ });
2532
+ this.metadata.setSignalSources(this.descriptorInput, this.globalFilterFieldsInput);
2533
+ this.data.setDataSources(this.items, this.result, this.dataProvider, this.loadingInput);
2534
+ }
2535
+ reload(emitEvent) {
2536
+ const params = emitEvent?.params ? emitEvent?.params : emitEvent?.resetParams ? undefined : this.lastParamsWithDefaults;
2537
+ const reloadParams = mergeDataListParamsWithDefaults(params ?? {}, this.metadata.defaultParams());
2538
+ this.loadTableWithDataProvider(reloadParams, emitEvent?.emitEvent ?? false);
2539
+ }
2540
+ onTableLazyLoad(event) {
2541
+ this.lastLazyLoadEvent = event;
2542
+ const params = fromTableLoadToDataListParams(event);
2543
+ if (this.useQueryParams()) {
2544
+ if (!this.navigationOutOfTableInProgress && !this.navigationInTableInProgress) {
2545
+ // this check is necessary: from some reason, primeNG commits one last lazy load event whenever any angular router navigation occurs
2546
+ this.navigationInTableInProgress = true;
2547
+ const newParams = dataListParamsToUrlQuery(params, this.metadata.defaultParams(), { prependFilterName: this.filterKeyPrepend, skipPresetDefaultsLimit: true });
2548
+ const newParamsWithParamsToRemove = { ...newParams };
2549
+ const currentQp = this.route.snapshot.queryParams;
2550
+ if (currentQp) {
2551
+ Object.keys(currentQp)
2552
+ .filter(k => (k.startsWith(this.filterKeyPrepend) || ['offset', 'limit', 'sort', 'q'].indexOf(k) >= 0) && newParams[k] === undefined)
2553
+ .forEach(k => (newParamsWithParamsToRemove[k] = null));
2554
+ }
2555
+ this.router
2556
+ .navigate([], {
2557
+ relativeTo: this.route,
2558
+ replaceUrl: true,
2559
+ queryParams: newParamsWithParamsToRemove,
2560
+ queryParamsHandling: 'merge'
2561
+ })
2562
+ .then(() => {
2563
+ this.navigationInTableInProgress = false;
2564
+ });
2565
+ }
2566
+ }
2567
+ else {
2568
+ const paramsWithDefaults = mergeDataListParamsWithDefaults(params, this.metadata.defaultParams());
2569
+ this.data.setParams(paramsWithDefaults);
2570
+ this.loadTableWithDataProvider(paramsWithDefaults);
2571
+ }
2572
+ }
2573
+ onTableFilter(event) {
2574
+ if (this.useQueryParams()) {
2575
+ return;
2576
+ }
2577
+ const params = fromTableLoadToDataListParams({ filters: event.filters });
2578
+ const paramsWithDefaults = mergeDataListParamsWithDefaults(params, this.metadata.defaultParams());
2579
+ // if table doesn't use lazy loading, filter params need to be set here
2580
+ // because the onTableLazyLoad event is not emitted
2581
+ if (!this.isLazy()) {
2582
+ this.data.setParams(paramsWithDefaults);
2583
+ }
2584
+ }
2585
+ onCellClick(event, col, item, idx) {
2586
+ if (!this.isCellClickEnabled()) {
2587
+ return;
2588
+ }
2589
+ const tableEvent = {
2590
+ column: col,
2591
+ rowItem: item,
2592
+ rowIndex: idx,
2593
+ event: event
2594
+ };
2595
+ this.cellClickSubject.next(tableEvent);
2596
+ }
2597
+ onSelectionChange(event) {
2598
+ this.data.selectedItems.set(event);
2599
+ this.selectionChange.emit(event);
2600
+ }
2601
+ onRowReorder(event) {
2602
+ this.rowReorder.emit(event);
2603
+ }
2604
+ loadTableWithDataProvider(paramsWithDefaults, emitEvent = true) {
2605
+ if (this.requiredFiltersMissing() && this.isLazy()) {
2606
+ return;
2607
+ }
2608
+ const isFetched = this.data.fetchWithDataProvider(paramsWithDefaults, error => {
2609
+ tableNotificationError(this.translate, this.messageService, this.metadata.descriptor(), error);
2610
+ const commonsError = fromSubscribeError(error, 'TableComponentError', {
2611
+ params: paramsWithDefaults
2612
+ });
2613
+ this.logger.log(commonsError, getErrorLogLevel(commonsError));
2614
+ });
2615
+ if (isFetched) {
2616
+ this.lastParamsWithDefaults = paramsWithDefaults;
2617
+ if (emitEvent) {
2618
+ const tableEvent = {
2619
+ originalEvent: this.lastLazyLoadEvent,
2620
+ params: paramsWithDefaults
2621
+ };
2622
+ this.tableLoad.emit(tableEvent);
2623
+ }
2624
+ }
2625
+ }
2626
+ loadTableFromRouteUpdate(urlParams) {
2627
+ const paramsWithDefaults = mergeDataListParamsWithDefaults(fromUrlQueryToDataListParams(urlParams, {
2628
+ prependFilterName: this.filterKeyPrepend,
2629
+ searchAsGlobal: true
2630
+ }), this.metadata.defaultParams());
2631
+ this.data.setParams(paramsWithDefaults, true);
2632
+ this.loadTableWithDataProvider(paramsWithDefaults);
2633
+ }
2634
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2635
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableComponent, isStandalone: true, selector: "mng-table", inputs: { descriptorInput: { classPropertyName: "descriptorInput", publicName: "descriptor", isSignal: true, isRequired: true, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, result: { classPropertyName: "result", publicName: "result", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, dataProvider: { classPropertyName: "dataProvider", publicName: "dataProvider", isSignal: true, isRequired: false, transformFunction: null }, useQueryParams: { classPropertyName: "useQueryParams", publicName: "useQueryParams", isSignal: true, isRequired: false, transformFunction: null }, cellClickEnabled: { classPropertyName: "cellClickEnabled", publicName: "cellClickEnabled", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selectionEnabled: { classPropertyName: "selectionEnabled", publicName: "selectionEnabled", isSignal: true, isRequired: false, transformFunction: null }, rowReorderEnabledInput: { classPropertyName: "rowReorderEnabledInput", publicName: "rowReorderEnabled", isSignal: true, isRequired: false, transformFunction: null }, columnLastMinWidth: { classPropertyName: "columnLastMinWidth", publicName: "columnLastMinWidth", isSignal: true, isRequired: false, transformFunction: null }, globalFilterFieldsInput: { classPropertyName: "globalFilterFieldsInput", publicName: "globalFilterFields", isSignal: true, isRequired: false, transformFunction: null }, templates: { classPropertyName: "templates", publicName: "templates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tableLoad: "tableLoad", cellClick: "cellClick", selectionChange: "selectionChange", rowReorder: "rowReorder" }, host: { properties: { "class.mng-table-no-header": "!isCaptionVisible()" } }, providers: [TableMetadataService, TableDataService, { provide: ADataListService, useExisting: TableDataService }, TablePreferencesService], queries: [{ propertyName: "contentTemplates", predicate: TableTemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "primeTable", first: true, predicate: (Table), descendants: true, isSignal: true }], ngImport: i0, template: "<div>\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (data.isAllPaginationMetaInitialized()) {\n <p-table\n [value]=\"requiredFiltersMissing() ? [] : data.data()\"\n [dataKey]=\"metadata.descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"data.loading()\"\n [paginator]=\"isPagination()\"\n [rows]=\"data.rows()\"\n [first]=\"data.offset()\"\n [totalRecords]=\"data.count()\"\n [rowsPerPageOptions]=\"metadata.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"true\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"data.sortStates()\"\n [filters]=\"data.primeFilterStates()\"\n [globalFilterFields]=\"metadata.searchFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [rowHover]=\"metadata.descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"metadata.descriptor().hasResizableColumns\"\n [columnResizeMode]=\"metadata.descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n [expandedRowKeys]=\"expandedRowKeys()\"\n (onColResize)=\"prefs.onColumnResize($event)\"\n (onColReorder)=\"prefs.onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onFilter)=\"onTableFilter($event)\"\n (onRowReorder)=\"onRowReorder($event)\"\n mngRemovableSort>\n <ng-template #caption>\n @if (isCaptionVisible()) {\n <div class=\"table-header\">\n @if (headerTemplate()) {\n <ng-container *ngTemplateOutlet=\"headerTemplate(); context: {data: data.data(), totalCount: data.count(), table: this}\"></ng-container>\n } @else {\n <mng-table-header-with-filters\n [metadata]=\"tableHeaderFilters()\"\n [genericFilterDescriptor]=\"metadata.genericFilterDescriptor()\"\n [model]=\"metadata.descriptor().model\"\n [enableSearch]=\"metadata.descriptor().search\"\n [search]=\"data.searchState()\"\n [searchLimitWordMax]=\"metadata.descriptor().searchLimitMaxWords\"\n [enableCaseSensitive]=\"isLazy()\">\n @if (hasTitleDisplay()) {\n <ng-template mngTableHeaderWithFiltersTemplate name=\"title\">\n @if (headerTitleTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"headerTitleTemplate(); context: {data: data.data(), totalCount: data.count(), table: this}\"></ng-container>\n } @else if (metadata.descriptor().title) {\n <h5 class=\"p-0 m-0\">{{ metadata.descriptor().title! | translate }}</h5>\n }\n </ng-template>\n }\n @if (titleRowRightTemplate()) {\n <ng-template mngTableHeaderWithFiltersTemplate name=\"titleRowRight\">\n <ng-container *ngTemplateOutlet=\"titleRowRightTemplate()\"></ng-container>\n </ng-template>\n }\n </mng-table-header-with-filters>\n }\n </div>\n }\n </ng-template>\n <ng-template #header>\n @if (!metadata.descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"metadata.descriptor().headerClassName\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox />\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (metadata.descriptor().rowExpandable) {\n <th scope=\"col\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n @if (columnHeaderTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n columnHeaderTemplate();\n context: {data: data.data(), totalCount: data.count(), property: col.descriptor.property, table: this}\n \"></ng-container>\n } @else {\n <div class=\"flex justify-between items-center\">\n {{\n (col.descriptor.title && !col.descriptor.titleUseModelBase\n ? col.descriptor.title\n : (col.descriptor.title ?? col.descriptor.property | mngI18nProperty: metadata.descriptor().model)\n ) | translate\n }}\n <p-sortIcon [field]=\"col.sort?.property\" class=\"flex\"></p-sortIcon>\n </div>\n }\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n @if (columnHeaderTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n columnHeaderTemplate();\n context: {data: data.data(), totalCount: data.count(), property: col.descriptor.property, table: this}\n \"></ng-container>\n } @else {\n {{\n (col.descriptor.title && !col.descriptor.titleUseModelBase\n ? col.descriptor.title\n : (col.descriptor.title ?? col.descriptor.property | mngI18nProperty: metadata.descriptor().model)\n ) | translate\n }}\n }\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"metadata.descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"mng-table-column-custom-last text-right!\">\n @if (areColumnsToggleable()) {\n @defer (on idle) {\n <mng-table-column-toggle [columns]=\"visibleColumns()\" />\n }\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @if (metadata.descriptor().rowExpandable) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"'px-1! ' + col.filter?.descriptor?.columnClassName | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : (col.filter?.descriptor?.columnWidth ?? col.descriptor.width ?? null)\"\n [style.min-width.px]=\"col.width ? null : (col.filter?.descriptor?.columnMinWidth ?? col.descriptor.minWidth)\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter && col.filter.descriptor.filterType !== FilterTypeEnum.Component) {\n @defer (on idle) {\n <mng-table-filter [config]=\"col.filter\" [model]=\"metadata.descriptor().model\"></mng-table-filter>\n }\n } @else if (col.filter && col.filter.descriptor.customComponentType) {\n <ng-container [mngComponent]=\"col.filter.descriptor.customComponentType\" [inputs]=\"{descriptor: col.filter.descriptor}\"></ng-container>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th pFrozenColumn alignFrozen=\"right\" class=\"mng-table-column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template #body let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [pReorderableRow]=\"idx\"\n [ngClass]=\"\n metadata.descriptor().rowClassName | mngClassMap: metadata.descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: metadata.descriptor() : item\n \">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (metadata.descriptor().rowExpandable) {\n <td>\n @let expandProp = metadata.descriptor().rowExpandableProperty;\n @if (!expandProp || item[expandProp]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n rounded=\"true\"\n text=\"true\"\n class=\"mng-button-sm\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @if (rowReorderEnabled()) {\n <td>\n <span class=\"pi pi-bars\" pReorderableRowHandle></span>\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"mng-table-column-custom-last justify-end text-right!\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n alignFrozen=\"right\"\n [frozen]=\"metadata.descriptor().actionColumnFrozen ?? true\">\n @if (columnCustomLastTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n columnCustomLastTemplate();\n context: {item: item, index: idx, data: data.data(), totalCount: data.count(), table: this}\n \"></ng-container>\n }\n </td>\n }\n </tr>\n </ng-template>\n <ng-template #expandedrow let-item let-idx=\"rowIndex\">\n @if (metadata.descriptor().rowExpandable) {\n <tr>\n <td></td>\n <td [colSpan]=\"metadata.descriptor().rowExpandableColSpan\">\n @if (metadata.descriptor().rowExpandableComponentType !== undefined) {\n <ng-container [mngComponent]=\"metadata.descriptor().rowExpandableComponentType\" [inputs]=\"{item}\"> </ng-container>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n rowExpandTemplate();\n context: {item: item, index: idx, data: data.data(), totalCount: data.count(), table: this}\n \"></ng-container>\n }\n </td>\n </tr>\n }\n </ng-template>\n <ng-template #loadingicon>\n <div class=\"flex flex-col items-center\">\n @if (metadata.descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + metadata.descriptor().loadingIcon\"></i>\n }\n @if (metadata.descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': metadata.descriptor().loadingIcon}\">\n {{ metadata.descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template #loadingbody>\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n <div class=\"loading-text\"></div>\n <p-skeleton width=\"100%\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template #emptymessage>\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n @if (requiredFiltersMissing()) {\n <i class=\"pi pi-exclamation-triangle mr-2\"></i> <strong>{{ 'mngTable.requiredFiltersMissing' | translate }}</strong>\n } @else {\n {{ 'mngTable.noItems' | translate }}\n }\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template #summary>\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: data.data(), totalCount: data.count(), table: this}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n", styles: ["mng-table .p-datatable .p-datatable-header{border-top:0}mng-table .p-datatable:not(.p-datatable-gridlines) .p-datatable-tbody>tr>td{cursor:auto}mng-table .p-datatable:not(.p-datatable-gridlines) .p-datatable-tbody>tr>td.clickable{cursor:pointer}:is(mng-table .p-datatable .p-datatable-thead>tr>th,mng-table .p-datatable .p-datatable-tbody>tr>td):hover mng-table-column-value .help-buttons{display:block}mng-table .p-datatable .p-datatable-thead>tr>th.mng-table-column-custom-last{padding:var(--mng-table-column-head-custom-last, .1rem 1rem)}mng-table .p-datatable .p-datatable-tbody>tr>td{position:relative}mng-table .p-datatable .p-datatable-tbody>tr>td.mng-table-column-custom-last{padding-top:.1rem;padding-bottom:.1rem}mng-table .p-datatable .p-datatable-tbody>tr>td.p-datatable-frozen-column{position:sticky;z-index:1;background:transparent}mng-table .p-datatable.p-datatable-lg .p-datatable-tbody>tr>td.mng-table-column-custom-last{padding:var(--mng-table-column-body-custom-last, .15rem 1rem)}mng-table .p-datatable.p-datatable-sm .p-datatable-tbody>tr>td.mng-table-column-custom-last{padding:var(--mng-table-sm-column-body-custom-last, .05rem 1rem)}mng-table .p-datatable.p-datatable-flex-scrollable .p-datatable-thead>tr>th{overflow:hidden;text-overflow:ellipsis}mng-table .p-datatable.p-datatable-flex-scrollable .p-datatable-tbody>tr>td{overflow:hidden}mng-table .p-datatable .mng-table-row-localization-default-locale{background:var(--p-surface-100)!important}mng-table .mng-table-header>th:not(:first-child):not(:last-child){border-radius:0!important}mng-table .mng-table-header>th:first-child{border-top-right-radius:0!important;border-bottom-right-radius:0!important}mng-table .mng-table-header>th:last-child{border-radius:0!important}mng-table .mng-table-header .mng-table-columns-multiselect{width:36px}mng-table .mng-table-header .mng-table-columns-multiselect .p-multiselect-label-container{width:0}mng-table.mng-table-no-header p-datatable .p-datatable-header{display:none}mng-table.mng-table-header-compact .p-datatable-header{padding:var(--mng-table-header-compact-padding, 0 0 .5rem 0)!important}\n"], dependencies: [{ kind: "directive", type: ComponentDirective, selector: "[mngComponent]", inputs: ["mngComponent", "injectionToken", "inputs", "attachToHost", "parentInjector"], outputs: ["instanceCreated"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TableColumnValueComponent, selector: "mng-table-column-value", inputs: ["descriptor", "item"] }, { kind: "component", type: TableHeaderWithFiltersComponent, selector: "mng-table-header-with-filters", inputs: ["metadata", "genericFilterDescriptor", "model", "enableSearch", "search", "searchLimitWordMax", "enableCaseSensitive"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1$1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i1$1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1$1.FrozenColumn, selector: "[pFrozenColumn]", inputs: ["frozen", "alignFrozen"] }, { kind: "directive", type: i1$1.RowToggler, selector: "[pRowToggler]", inputs: ["pRowToggler", "pRowTogglerDisabled"] }, { kind: "directive", type: i1$1.ResizableColumn, selector: "[pResizableColumn]", inputs: ["pResizableColumnDisabled"] }, { kind: "directive", type: i1$1.ReorderableColumn, selector: "[pReorderableColumn]", inputs: ["pReorderableColumnDisabled"] }, { kind: "component", type: i1$1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "component", type: i1$1.TableRadioButton, selector: "p-tableRadioButton", inputs: ["value", "disabled", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i1$1.TableCheckbox, selector: "p-tableCheckbox", inputs: ["value", "disabled", "required", "index", "inputId", "name", "ariaLabel"] }, { kind: "component", type: i1$1.TableHeaderCheckbox, selector: "p-tableHeaderCheckbox", inputs: ["disabled", "inputId", "name", "ariaLabel"] }, { kind: "directive", type: i1$1.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i1$1.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "directive", type: ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "directive", type: TableRemovableSortDirective, selector: "[mngRemovableSort]" }, { kind: "directive", type: TableHeaderWithFiltersTemplateDirective, selector: "[mngTableHeaderWithFiltersTemplate]", inputs: ["name"] }, { kind: "pipe", type: I18nPropertyPipe, name: "mngI18nProperty" }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: ClassMapPipe, name: "mngClassMap" }, { kind: "pipe", type: LocaleDefaultRowClassPipe, name: "mngLocaleDefaultRowClass" }, { kind: "pipe", type: TableFilterClassPipe, name: "mngTableFilterClass" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None, deferBlockDependencies: [() => [import('./mediusinc-mng-commons-table-column-toggle.component-BQ99oqWO.mjs').then(m => m.TableColumnToggleComponent)], () => [Promise.resolve().then(function () { return filter_component; }).then(m => m.TableFilterComponent)]] }); }
2636
+ }
2637
+ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "20.3.15", ngImport: i0, type: TableComponent, resolveDeferredDeps: () => [import('./mediusinc-mng-commons-table-column-toggle.component-BQ99oqWO.mjs').then(m => m.TableColumnToggleComponent), Promise.resolve().then(function () { return filter_component; }).then(m => m.TableFilterComponent)], resolveMetadata: (TableColumnToggleComponent, TableFilterComponent) => ({ decorators: [{
2638
+ type: Component,
2639
+ args: [{ selector: 'mng-table', imports: [
2640
+ ComponentDirective,
2641
+ I18nPropertyPipe,
2642
+ TranslatePipe,
2643
+ NgClass,
2644
+ NgTemplateOutlet,
2645
+ TableColumnValueComponent,
2646
+ ClassMapPipe,
2647
+ LocaleDefaultRowClassPipe,
2648
+ TableFilterComponent,
2649
+ TableFilterClassPipe,
2650
+ TableHeaderWithFiltersComponent,
2651
+ FormsModule,
2652
+ TableModule,
2653
+ Skeleton,
2654
+ TableColumnToggleComponent,
2655
+ ButtonDirective,
2656
+ TableRemovableSortDirective,
2657
+ TableHeaderWithFiltersTemplateDirective
2658
+ ], providers: [TableMetadataService, TableDataService, { provide: ADataListService, useExisting: TableDataService }, TablePreferencesService], host: {
2659
+ '[class.mng-table-no-header]': '!isCaptionVisible()'
2660
+ }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div>\n <!-- MUST NOT use observable for value when using virtual scroll - does not work for some reason -->\n @if (data.isAllPaginationMetaInitialized()) {\n <p-table\n [value]=\"requiredFiltersMissing() ? [] : data.data()\"\n [dataKey]=\"metadata.descriptor().trackProperty\"\n [lazy]=\"isLazy()\"\n [loading]=\"data.loading()\"\n [paginator]=\"isPagination()\"\n [rows]=\"data.rows()\"\n [first]=\"data.offset()\"\n [totalRecords]=\"data.count()\"\n [rowsPerPageOptions]=\"metadata.rowsPerPageOptions()\"\n [showCurrentPageReport]=\"true\"\n [currentPageReportTemplate]=\"'mngTable.paginationMsg' | translate\"\n [multiSortMeta]=\"data.sortStates()\"\n [filters]=\"data.primeFilterStates()\"\n [globalFilterFields]=\"metadata.searchFields()\"\n sortMode=\"multiple\"\n [selection]=\"[]\"\n (selectionChange)=\"onSelectionChange($event)\"\n [selectionMode]=\"selectionEnabled() ? selectionMode() : null\"\n [scrollable]=\"true\"\n scrollHeight=\"flex\"\n [rowHover]=\"metadata.descriptor().hasHover\"\n [styleClass]=\"className()\"\n [resizableColumns]=\"metadata.descriptor().hasResizableColumns\"\n [columnResizeMode]=\"metadata.descriptor().columnResizeMode ?? 'expand'\"\n [reorderableColumns]=\"areColumnsReorderable()\"\n paginatorDropdownAppendTo=\"body\"\n [columns]=\"visibleColumns()\"\n [expandedRowKeys]=\"expandedRowKeys()\"\n (onColResize)=\"prefs.onColumnResize($event)\"\n (onColReorder)=\"prefs.onColumnReorder($event)\"\n (onLazyLoad)=\"onTableLazyLoad($event)\"\n (onFilter)=\"onTableFilter($event)\"\n (onRowReorder)=\"onRowReorder($event)\"\n mngRemovableSort>\n <ng-template #caption>\n @if (isCaptionVisible()) {\n <div class=\"table-header\">\n @if (headerTemplate()) {\n <ng-container *ngTemplateOutlet=\"headerTemplate(); context: {data: data.data(), totalCount: data.count(), table: this}\"></ng-container>\n } @else {\n <mng-table-header-with-filters\n [metadata]=\"tableHeaderFilters()\"\n [genericFilterDescriptor]=\"metadata.genericFilterDescriptor()\"\n [model]=\"metadata.descriptor().model\"\n [enableSearch]=\"metadata.descriptor().search\"\n [search]=\"data.searchState()\"\n [searchLimitWordMax]=\"metadata.descriptor().searchLimitMaxWords\"\n [enableCaseSensitive]=\"isLazy()\">\n @if (hasTitleDisplay()) {\n <ng-template mngTableHeaderWithFiltersTemplate name=\"title\">\n @if (headerTitleTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"headerTitleTemplate(); context: {data: data.data(), totalCount: data.count(), table: this}\"></ng-container>\n } @else if (metadata.descriptor().title) {\n <h5 class=\"p-0 m-0\">{{ metadata.descriptor().title! | translate }}</h5>\n }\n </ng-template>\n }\n @if (titleRowRightTemplate()) {\n <ng-template mngTableHeaderWithFiltersTemplate name=\"titleRowRight\">\n <ng-container *ngTemplateOutlet=\"titleRowRightTemplate()\"></ng-container>\n </ng-template>\n }\n </mng-table-header-with-filters>\n }\n </div>\n }\n </ng-template>\n <ng-template #header>\n @if (!metadata.descriptor().hideHeader) {\n <tr class=\"mng-table-header\" [class]=\"metadata.descriptor().headerClassName\">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\">\n <p-tableHeaderCheckbox />\n </th>\n } @else {\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\"></th>\n }\n }\n @if (metadata.descriptor().rowExpandable) {\n <th scope=\"col\" pFrozenColumn [frozen]=\"true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <ng-template #sortableColumnTHTemplate>\n @if (columnHeaderTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n columnHeaderTemplate();\n context: {data: data.data(), totalCount: data.count(), property: col.descriptor.property, table: this}\n \"></ng-container>\n } @else {\n <div class=\"flex justify-between items-center\">\n {{\n (col.descriptor.title && !col.descriptor.titleUseModelBase\n ? col.descriptor.title\n : (col.descriptor.title ?? col.descriptor.property | mngI18nProperty: metadata.descriptor().model)\n ) | translate\n }}\n <p-sortIcon [field]=\"col.sort?.property\" class=\"flex\"></p-sortIcon>\n </div>\n }\n </ng-template>\n <ng-template #nonSortableColumnTHTemplate>\n @if (columnHeaderTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n columnHeaderTemplate();\n context: {data: data.data(), totalCount: data.count(), property: col.descriptor.property, table: this}\n \"></ng-container>\n } @else {\n {{\n (col.descriptor.title && !col.descriptor.titleUseModelBase\n ? col.descriptor.title\n : (col.descriptor.title ?? col.descriptor.property | mngI18nProperty: metadata.descriptor().model)\n ) | translate\n }}\n }\n </ng-template>\n @if (col.descriptor.isReorderable) {\n <th\n pResizableColumn\n pReorderableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n } @else {\n <th\n pResizableColumn\n [id]=\"col.descriptor.property\"\n [pSortableColumn]=\"col.sort?.property\"\n [pSortableColumnDisabled]=\"!col.sort\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\"\n [class]=\"col.descriptor.headerClassName | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\">\n <ng-container *ngTemplateOutlet=\"col.sort ? sortableColumnTHTemplate : nonSortableColumnTHTemplate\"></ng-container>\n </th>\n }\n }\n @if (hasLastColumn()) {\n <th\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n [frozen]=\"metadata.descriptor().actionColumnFrozen ?? areColumnsToggleable()\"\n alignFrozen=\"right\"\n class=\"mng-table-column-custom-last text-right!\">\n @if (areColumnsToggleable()) {\n @defer (on idle) {\n <mng-table-column-toggle [columns]=\"visibleColumns()\" />\n }\n }\n </th>\n }\n </tr>\n }\n @if (hasColumnFilters()) {\n <tr class=\"mng-column-filter-row\">\n <!-- We need the line below, because otherwise p-tableRadioButton shifts the rest of the columns in table -->\n @if (selectionEnabled()) {\n <th style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\"></th>\n }\n @if (rowReorderEnabled()) {\n <th scope=\"col\"></th>\n }\n @if (metadata.descriptor().rowExpandable) {\n <th scope=\"col\"></th>\n }\n @for (col of visibleColumns(); track col.id) {\n <th\n [class]=\"'px-1! ' + col.filter?.descriptor?.columnClassName | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\"\n [style.width.px]=\"col.width\"\n [style.width.%]=\"col.width ? null : (col.filter?.descriptor?.columnWidth ?? col.descriptor.width ?? null)\"\n [style.min-width.px]=\"col.width ? null : (col.filter?.descriptor?.columnMinWidth ?? col.descriptor.minWidth)\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n @if (col.filter && col.filter.descriptor.filterType !== FilterTypeEnum.Component) {\n @defer (on idle) {\n <mng-table-filter [config]=\"col.filter\" [model]=\"metadata.descriptor().model\"></mng-table-filter>\n }\n } @else if (col.filter && col.filter.descriptor.customComponentType) {\n <ng-container [mngComponent]=\"col.filter.descriptor.customComponentType\" [inputs]=\"{descriptor: col.filter.descriptor}\"></ng-container>\n }\n </th>\n }\n @if (hasLastColumn()) {\n <th pFrozenColumn alignFrozen=\"right\" class=\"mng-table-column-custom-last\" [style.min-width.px]=\"columnLastMinWidth()\"></th>\n }\n </tr>\n }\n </ng-template>\n <ng-template #body let-item let-idx=\"rowIndex\" let-expanded=\"expanded\">\n <tr\n [pReorderableRow]=\"idx\"\n [ngClass]=\"\n metadata.descriptor().rowClassName | mngClassMap: metadata.descriptor().rowClassNameMapFn : item | mngLocaleDefaultRowClass: metadata.descriptor() : item\n \">\n @if (selectionEnabled()) {\n @if (selectionMode() === 'multiple') {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\">\n <p-tableCheckbox [value]=\"item\"></p-tableCheckbox>\n </td>\n } @else {\n <td style=\"min-width: 36px\" pFrozenColumn [frozen]=\"metadata.descriptor().selectionColumnFrozen ?? true\">\n <p-tableRadioButton [value]=\"item\"></p-tableRadioButton>\n </td>\n }\n }\n @if (metadata.descriptor().rowExpandable) {\n <td>\n @let expandProp = metadata.descriptor().rowExpandableProperty;\n @if (!expandProp || item[expandProp]) {\n <button\n pButton\n type=\"button\"\n [pRowToggler]=\"item\"\n rounded=\"true\"\n text=\"true\"\n class=\"mng-button-sm\"\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"></button>\n }\n </td>\n }\n @if (rowReorderEnabled()) {\n <td>\n <span class=\"pi pi-bars\" pReorderableRowHandle></span>\n </td>\n }\n @for (col of visibleColumns(); track col.id) {\n <td\n (click)=\"onCellClick($event, col.descriptor, item, idx)\"\n [class]=\"\n col.descriptor.className\n | mngClassMap: col.descriptor.classNameMapFn : item\n | mngTableFilterClass: col.filter?.descriptor : hasColumnFilters() && !col.width\n \"\n [class.clickable]=\"isCellClickEnabled()\"\n [style.width]=\"col.width ? col.width + 'px' : col.descriptor.width + '%'\"\n [style.min-width.px]=\"col.width ? null : col.descriptor.minWidth\"\n [style.max-width.px]=\"col.width ?? col.descriptor.maxWidth\">\n <mng-table-column-value [descriptor]=\"col.descriptor\" [item]=\"item\"></mng-table-column-value>\n </td>\n }\n @if (hasLastColumn()) {\n <td\n class=\"mng-table-column-custom-last justify-end text-right!\"\n [style.min-width.px]=\"columnLastMinWidth()\"\n pFrozenColumn\n alignFrozen=\"right\"\n [frozen]=\"metadata.descriptor().actionColumnFrozen ?? true\">\n @if (columnCustomLastTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n columnCustomLastTemplate();\n context: {item: item, index: idx, data: data.data(), totalCount: data.count(), table: this}\n \"></ng-container>\n }\n </td>\n }\n </tr>\n </ng-template>\n <ng-template #expandedrow let-item let-idx=\"rowIndex\">\n @if (metadata.descriptor().rowExpandable) {\n <tr>\n <td></td>\n <td [colSpan]=\"metadata.descriptor().rowExpandableColSpan\">\n @if (metadata.descriptor().rowExpandableComponentType !== undefined) {\n <ng-container [mngComponent]=\"metadata.descriptor().rowExpandableComponentType\" [inputs]=\"{item}\"> </ng-container>\n } @else {\n <ng-container\n *ngTemplateOutlet=\"\n rowExpandTemplate();\n context: {item: item, index: idx, data: data.data(), totalCount: data.count(), table: this}\n \"></ng-container>\n }\n </td>\n </tr>\n }\n </ng-template>\n <ng-template #loadingicon>\n <div class=\"flex flex-col items-center\">\n @if (metadata.descriptor().loadingIcon) {\n <i [class]=\"'text-white text-4xl pi-spin ' + metadata.descriptor().loadingIcon\"></i>\n }\n @if (metadata.descriptor().loadingText) {\n <div class=\"text text-white text-lg font-semibold\" [ngClass]=\"{'mt-3': metadata.descriptor().loadingIcon}\">\n {{ metadata.descriptor().loadingText ?? '' | translate }}\n </div>\n }\n </div>\n </ng-template>\n <ng-template #loadingbody>\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n <div class=\"loading-text\"></div>\n <p-skeleton width=\"100%\"></p-skeleton>\n </td>\n </tr>\n </ng-template>\n <ng-template #emptymessage>\n <tr>\n <td [attr.colspan]=\"columnsColspan()\">\n @if (requiredFiltersMissing()) {\n <i class=\"pi pi-exclamation-triangle mr-2\"></i> <strong>{{ 'mngTable.requiredFiltersMissing' | translate }}</strong>\n } @else {\n {{ 'mngTable.noItems' | translate }}\n }\n </td>\n </tr>\n </ng-template>\n @if (footerTemplate()) {\n <ng-template #summary>\n <ng-container *ngTemplateOutlet=\"footerTemplate(); context: {data: data.data(), totalCount: data.count(), table: this}\"></ng-container>\n </ng-template>\n }\n </p-table>\n }\n</div>\n", styles: ["mng-table .p-datatable .p-datatable-header{border-top:0}mng-table .p-datatable:not(.p-datatable-gridlines) .p-datatable-tbody>tr>td{cursor:auto}mng-table .p-datatable:not(.p-datatable-gridlines) .p-datatable-tbody>tr>td.clickable{cursor:pointer}:is(mng-table .p-datatable .p-datatable-thead>tr>th,mng-table .p-datatable .p-datatable-tbody>tr>td):hover mng-table-column-value .help-buttons{display:block}mng-table .p-datatable .p-datatable-thead>tr>th.mng-table-column-custom-last{padding:var(--mng-table-column-head-custom-last, .1rem 1rem)}mng-table .p-datatable .p-datatable-tbody>tr>td{position:relative}mng-table .p-datatable .p-datatable-tbody>tr>td.mng-table-column-custom-last{padding-top:.1rem;padding-bottom:.1rem}mng-table .p-datatable .p-datatable-tbody>tr>td.p-datatable-frozen-column{position:sticky;z-index:1;background:transparent}mng-table .p-datatable.p-datatable-lg .p-datatable-tbody>tr>td.mng-table-column-custom-last{padding:var(--mng-table-column-body-custom-last, .15rem 1rem)}mng-table .p-datatable.p-datatable-sm .p-datatable-tbody>tr>td.mng-table-column-custom-last{padding:var(--mng-table-sm-column-body-custom-last, .05rem 1rem)}mng-table .p-datatable.p-datatable-flex-scrollable .p-datatable-thead>tr>th{overflow:hidden;text-overflow:ellipsis}mng-table .p-datatable.p-datatable-flex-scrollable .p-datatable-tbody>tr>td{overflow:hidden}mng-table .p-datatable .mng-table-row-localization-default-locale{background:var(--p-surface-100)!important}mng-table .mng-table-header>th:not(:first-child):not(:last-child){border-radius:0!important}mng-table .mng-table-header>th:first-child{border-top-right-radius:0!important;border-bottom-right-radius:0!important}mng-table .mng-table-header>th:last-child{border-radius:0!important}mng-table .mng-table-header .mng-table-columns-multiselect{width:36px}mng-table .mng-table-header .mng-table-columns-multiselect .p-multiselect-label-container{width:0}mng-table.mng-table-no-header p-datatable .p-datatable-header{display:none}mng-table.mng-table-header-compact .p-datatable-header{padding:var(--mng-table-header-compact-padding, 0 0 .5rem 0)!important}\n"] }]
2661
+ }], ctorParameters: () => [], propDecorators: { descriptorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "descriptor", required: true }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], result: [{ type: i0.Input, args: [{ isSignal: true, alias: "result", required: false }] }], loadingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], dataProvider: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataProvider", required: false }] }], useQueryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "useQueryParams", required: false }] }], cellClickEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellClickEnabled", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selectionEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionEnabled", required: false }] }], rowReorderEnabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowReorderEnabled", required: false }] }], columnLastMinWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnLastMinWidth", required: false }] }], globalFilterFieldsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "globalFilterFields", required: false }] }], tableLoad: [{ type: i0.Output, args: ["tableLoad"] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowReorder: [{ type: i0.Output, args: ["rowReorder"] }], templates: [{ type: i0.Input, args: [{ isSignal: true, alias: "templates", required: false }] }], contentTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TableTemplateDirective), { isSignal: true }] }], primeTable: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Table), { isSignal: true }] }] } }) });
2662
+
2663
+ /**
2664
+ * Prepares providers for usage of the tableview functionalities.
2665
+ *
2666
+ * @returns {CommonsFeature} The `CommonsFeature` object with the layout configuration.
2667
+ */
2668
+ function withTable(config) {
2669
+ return {
2670
+ type: CommonsFeatureTypeEnum.Table,
2671
+ providers: [
2672
+ {
2673
+ provide: COMMONS_TABLE_FEATURE_CONFIG_IT,
2674
+ useValue: config
2675
+ }
2676
+ ]
2677
+ };
2678
+ }
2679
+ /**
2680
+ * Provides a list of providers for configuring a table feature. Useful for lazy-loading table chunk in child (lazy loaded routes).
2681
+ *
2682
+ * @param {TableFeatureConfig} [config] - An optional configuration object for the table feature.
2683
+ */
2684
+ function provideTableChild(config) {
2685
+ return [
2686
+ {
2687
+ provide: COMMONS_TABLE_FEATURE_CONFIG_IT,
2688
+ useValue: config
2689
+ }
2690
+ ];
2691
+ }
2692
+
2693
+ // components
2694
+
2695
+ /**
2696
+ * Generated bundle index. Do not edit.
2697
+ */
2698
+
2699
+ export { ADataListService as A, COMMONS_TABLE_FEATURE_CONFIG_IT as C, FilterService as F, LocaleDefaultRowClassPipe as L, TableMetadataService as T, TablePreferencesService as a, TableFilterComponent as b, TableColumnValueComponent as c, TableFilterActiveTagComponent as d, TableFilterFormComponent as e, TableHeaderWithFiltersComponent as f, TableComponent as g, TableTemplateDirective as h, filterGenerateMatchModeOptions as i, filterGetDefaultMatchMode as j, filterSetStateOnChange as k, filterSetStateOnDisplayChange as l, filterAreDatesEqual as m, filterApplySerializationConfigToCmp as n, filterAdjustDisplayValueOnMatchModeChange as o, filterGetDateConfig as p, filterGetNumberConfig as q, createFilterDescriptorsFromGeneric as r, isFilterValueBlank as s, tableNotificationError as t, generateTableLayoutPrefsKey as u, FilterValuePipe as v, TableFilterClassPipe as w, TableDataService as x, withTable as y, provideTableChild as z };
2700
+ //# sourceMappingURL=mediusinc-mng-commons-table-mediusinc-mng-commons-table-BLuM5Kpu.mjs.map