@updevs/components 1.0.0-alpha.1 → 1.0.0-alpha.100

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 (198) hide show
  1. package/README.md +1 -24
  2. package/assets/styles/_bootstrap-components.scss +55 -0
  3. package/assets/styles/_bootstrap-config.scss +7 -0
  4. package/assets/styles/_bootstrap-override.scss +78 -0
  5. package/assets/styles/_config.scss +9 -0
  6. package/assets/styles/_core.scss +80 -0
  7. package/assets/styles/_debug.scss +49 -0
  8. package/assets/styles/_mixins.scss +2 -0
  9. package/assets/styles/_props.scss +91 -0
  10. package/assets/styles/_seven-columns.scss +73 -0
  11. package/assets/styles/_updevs.scss +25 -0
  12. package/assets/styles/_utilities-marketing.scss +209 -0
  13. package/assets/styles/_utilities.scss +133 -0
  14. package/assets/styles/_variables-dark.scss +19 -0
  15. package/assets/styles/_variables.scss +1003 -0
  16. package/assets/styles/fonts/_webfonts.scss +15 -0
  17. package/assets/styles/helpers/_index.scss +143 -0
  18. package/assets/styles/layout/_animations.scss +62 -0
  19. package/assets/styles/layout/_core.scss +62 -0
  20. package/assets/styles/layout/_dark.scss +77 -0
  21. package/assets/styles/layout/_footer.scss +12 -0
  22. package/assets/styles/layout/_navbar.scss +392 -0
  23. package/assets/styles/layout/_page.scss +170 -0
  24. package/assets/styles/layout/_root.scss +64 -0
  25. package/assets/styles/marketing/_browser.scss +67 -0
  26. package/assets/styles/marketing/_core.scss +8 -0
  27. package/assets/styles/marketing/_filters.scss +0 -0
  28. package/assets/styles/marketing/_hero.scss +70 -0
  29. package/assets/styles/marketing/_pricing.scss +111 -0
  30. package/assets/styles/marketing/_sections.scss +124 -0
  31. package/assets/styles/marketing/_shape.scss +31 -0
  32. package/assets/styles/mixins/_functions.scss +96 -0
  33. package/assets/styles/mixins/_mixins.scss +68 -0
  34. package/assets/styles/ui/_accordion.scss +178 -0
  35. package/assets/styles/ui/_alerts.scss +101 -0
  36. package/assets/styles/ui/_avatars.scss +145 -0
  37. package/assets/styles/ui/_badges.scss +113 -0
  38. package/assets/styles/ui/_breadcrumbs.scss +50 -0
  39. package/assets/styles/ui/_button-group.scss +16 -0
  40. package/assets/styles/ui/_buttons.scss +261 -0
  41. package/assets/styles/ui/_calendars.scss +104 -0
  42. package/assets/styles/ui/_cards.scss +595 -0
  43. package/assets/styles/ui/_carousel.scss +68 -0
  44. package/assets/styles/ui/_charts.scss +61 -0
  45. package/assets/styles/ui/_chat.scss +38 -0
  46. package/assets/styles/ui/_chips.scss +0 -0
  47. package/assets/styles/ui/_close.scss +60 -0
  48. package/assets/styles/ui/_datagrid.scss +17 -0
  49. package/assets/styles/ui/_dropdowns.scss +120 -0
  50. package/assets/styles/ui/_empty.scss +60 -0
  51. package/assets/styles/ui/_flags.scss +31 -0
  52. package/assets/styles/ui/_forms.scss +250 -0
  53. package/assets/styles/ui/_grid.scss +115 -0
  54. package/assets/styles/ui/_icons.scss +72 -0
  55. package/assets/styles/ui/_images.scss +19 -0
  56. package/assets/styles/ui/_legend.scss +12 -0
  57. package/assets/styles/ui/_lists.scss +123 -0
  58. package/assets/styles/ui/_loaders.scss +72 -0
  59. package/assets/styles/ui/_login.scss +3 -0
  60. package/assets/styles/ui/_markdown.scss +53 -0
  61. package/assets/styles/ui/_modals.scss +67 -0
  62. package/assets/styles/ui/_nav.scss +106 -0
  63. package/assets/styles/ui/_offcanvas.scss +17 -0
  64. package/assets/styles/ui/_pagination.scss +58 -0
  65. package/assets/styles/ui/_payments.scss +28 -0
  66. package/assets/styles/ui/_placeholder.scss +9 -0
  67. package/assets/styles/ui/_popovers.scss +2 -0
  68. package/assets/styles/ui/_progress.scss +107 -0
  69. package/assets/styles/ui/_ribbons.scss +157 -0
  70. package/assets/styles/ui/_segmented.scss +101 -0
  71. package/assets/styles/ui/_signature.scss +15 -0
  72. package/assets/styles/ui/_social.scss +52 -0
  73. package/assets/styles/ui/_stars.scss +13 -0
  74. package/assets/styles/ui/_status.scss +163 -0
  75. package/assets/styles/ui/_steps.scss +156 -0
  76. package/assets/styles/ui/_switch-icon.scss +211 -0
  77. package/assets/styles/ui/_tables.scss +176 -0
  78. package/assets/styles/ui/_tags.scss +57 -0
  79. package/assets/styles/ui/_timeline.scss +61 -0
  80. package/assets/styles/ui/_toasts.scss +18 -0
  81. package/assets/styles/ui/_toolbar.scss +10 -0
  82. package/assets/styles/ui/_tracking.scss +29 -0
  83. package/assets/styles/ui/_type.scss +330 -0
  84. package/assets/styles/ui/forms/_form-check.scss +91 -0
  85. package/assets/styles/ui/forms/_form-colorinput.scss +54 -0
  86. package/assets/styles/ui/forms/_form-custom.scss +28 -0
  87. package/assets/styles/ui/forms/_form-icon.scss +35 -0
  88. package/assets/styles/ui/forms/_form-imagecheck.scss +105 -0
  89. package/assets/styles/ui/forms/_form-selectgroup.scss +153 -0
  90. package/assets/styles/ui/forms/_validation.scss +13 -0
  91. package/assets/styles/ui/typo/_hr.scss +76 -0
  92. package/assets/styles/utils/_background.scss +15 -0
  93. package/assets/styles/utils/_colors.scss +101 -0
  94. package/assets/styles/utils/_opacity.scss +7 -0
  95. package/assets/styles/utils/_scroll.scss +45 -0
  96. package/assets/styles/utils/_shadow.scss +17 -0
  97. package/assets/styles/utils/_sizing.scss +10 -0
  98. package/assets/styles/utils/_text.scss +14 -0
  99. package/assets/styles/vendor/_apexcharts.scss +52 -0
  100. package/assets/styles/vendor/_coloris.scss +72 -0
  101. package/assets/styles/vendor/_dropzone.scss +27 -0
  102. package/assets/styles/vendor/_fslightbox.scss +13 -0
  103. package/assets/styles/vendor/_jsvectormap.scss +47 -0
  104. package/assets/styles/vendor/_litepicker.scss +69 -0
  105. package/assets/styles/vendor/_nouislider.scss +49 -0
  106. package/assets/styles/vendor/_plyr.scss +3 -0
  107. package/assets/styles/vendor/_stars-rating.scss +22 -0
  108. package/assets/styles/vendor/_tom-select.scss +81 -0
  109. package/assets/styles/vendor/_turbo.scss +3 -0
  110. package/assets/styles/vendor/_typed.scss +4 -0
  111. package/assets/styles/vendor/_wysiwyg.scss +46 -0
  112. package/fesm2022/updevs-components-badge.mjs +89 -0
  113. package/fesm2022/updevs-components-badge.mjs.map +1 -0
  114. package/fesm2022/updevs-components-button.mjs +193 -0
  115. package/fesm2022/updevs-components-button.mjs.map +1 -0
  116. package/fesm2022/updevs-components-calendar.mjs +582 -0
  117. package/fesm2022/updevs-components-calendar.mjs.map +1 -0
  118. package/fesm2022/updevs-components-card.mjs +242 -0
  119. package/fesm2022/updevs-components-card.mjs.map +1 -0
  120. package/fesm2022/updevs-components-drag-and-drop.mjs +185 -0
  121. package/fesm2022/updevs-components-drag-and-drop.mjs.map +1 -0
  122. package/fesm2022/updevs-components-dropdown.mjs +247 -0
  123. package/fesm2022/updevs-components-dropdown.mjs.map +1 -0
  124. package/fesm2022/updevs-components-form-controls-abstractions.mjs +106 -0
  125. package/fesm2022/updevs-components-form-controls-abstractions.mjs.map +1 -0
  126. package/fesm2022/updevs-components-form-controls-checkbox.mjs +99 -0
  127. package/fesm2022/updevs-components-form-controls-checkbox.mjs.map +1 -0
  128. package/fesm2022/updevs-components-form-controls-date-picker.mjs +175 -0
  129. package/fesm2022/updevs-components-form-controls-date-picker.mjs.map +1 -0
  130. package/fesm2022/updevs-components-form-controls-file-upload.mjs +272 -0
  131. package/fesm2022/updevs-components-form-controls-file-upload.mjs.map +1 -0
  132. package/fesm2022/updevs-components-form-controls-input.mjs +281 -0
  133. package/fesm2022/updevs-components-form-controls-input.mjs.map +1 -0
  134. package/fesm2022/updevs-components-form-controls-radio.mjs +98 -0
  135. package/fesm2022/updevs-components-form-controls-radio.mjs.map +1 -0
  136. package/fesm2022/updevs-components-form-controls-select.mjs +600 -0
  137. package/fesm2022/updevs-components-form-controls-select.mjs.map +1 -0
  138. package/fesm2022/updevs-components-form-controls-textarea.mjs +79 -0
  139. package/fesm2022/updevs-components-form-controls-textarea.mjs.map +1 -0
  140. package/fesm2022/updevs-components-form-controls-time-picker.mjs +345 -0
  141. package/fesm2022/updevs-components-form-controls-time-picker.mjs.map +1 -0
  142. package/fesm2022/updevs-components-form.mjs +562 -0
  143. package/fesm2022/updevs-components-form.mjs.map +1 -0
  144. package/fesm2022/updevs-components-layout.mjs +1054 -0
  145. package/fesm2022/updevs-components-layout.mjs.map +1 -0
  146. package/fesm2022/updevs-components-link.mjs +79 -0
  147. package/fesm2022/updevs-components-link.mjs.map +1 -0
  148. package/fesm2022/updevs-components-list.mjs +215 -0
  149. package/fesm2022/updevs-components-list.mjs.map +1 -0
  150. package/fesm2022/updevs-components-modal.mjs +505 -0
  151. package/fesm2022/updevs-components-modal.mjs.map +1 -0
  152. package/fesm2022/updevs-components-paginator.mjs +160 -0
  153. package/fesm2022/updevs-components-paginator.mjs.map +1 -0
  154. package/fesm2022/updevs-components-popover.mjs +215 -0
  155. package/fesm2022/updevs-components-popover.mjs.map +1 -0
  156. package/fesm2022/updevs-components-pricing.mjs +130 -0
  157. package/fesm2022/updevs-components-pricing.mjs.map +1 -0
  158. package/fesm2022/updevs-components-table.mjs +2060 -0
  159. package/fesm2022/updevs-components-table.mjs.map +1 -0
  160. package/fesm2022/updevs-components.mjs +33 -0
  161. package/fesm2022/updevs-components.mjs.map +1 -0
  162. package/package.json +127 -14
  163. package/types/updevs-components-badge.d.ts +44 -0
  164. package/types/updevs-components-button.d.ts +75 -0
  165. package/types/updevs-components-calendar.d.ts +175 -0
  166. package/types/updevs-components-card.d.ts +92 -0
  167. package/types/updevs-components-drag-and-drop.d.ts +74 -0
  168. package/types/updevs-components-dropdown.d.ts +124 -0
  169. package/types/updevs-components-form-controls-abstractions.d.ts +49 -0
  170. package/types/updevs-components-form-controls-checkbox.d.ts +33 -0
  171. package/types/updevs-components-form-controls-date-picker.d.ts +80 -0
  172. package/types/updevs-components-form-controls-file-upload.d.ts +69 -0
  173. package/types/updevs-components-form-controls-input.d.ts +95 -0
  174. package/types/updevs-components-form-controls-radio.d.ts +32 -0
  175. package/types/updevs-components-form-controls-select.d.ts +200 -0
  176. package/types/updevs-components-form-controls-textarea.d.ts +31 -0
  177. package/types/updevs-components-form-controls-time-picker.d.ts +164 -0
  178. package/types/updevs-components-form.d.ts +356 -0
  179. package/types/updevs-components-layout.d.ts +490 -0
  180. package/types/updevs-components-link.d.ts +34 -0
  181. package/types/updevs-components-list.d.ts +107 -0
  182. package/types/updevs-components-modal.d.ts +155 -0
  183. package/types/updevs-components-paginator.d.ts +58 -0
  184. package/types/updevs-components-popover.d.ts +63 -0
  185. package/types/updevs-components-pricing.d.ts +91 -0
  186. package/types/updevs-components-table.d.ts +619 -0
  187. package/types/updevs-components.d.ts +44 -0
  188. package/CHANGELOG.md +0 -8
  189. package/ng-package.json +0 -7
  190. package/src/lib/components.component.spec.ts +0 -23
  191. package/src/lib/components.component.ts +0 -14
  192. package/src/lib/components.module.ts +0 -17
  193. package/src/lib/components.service.spec.ts +0 -16
  194. package/src/lib/components.service.ts +0 -9
  195. package/src/public-api.ts +0 -7
  196. package/tsconfig.lib.json +0 -14
  197. package/tsconfig.lib.prod.json +0 -10
  198. package/tsconfig.spec.json +0 -14
@@ -0,0 +1,2060 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, Directive, Component, input, ViewContainerRef, effect, computed, signal, Injectable, model, InjectionToken, Inject, EventEmitter, Output, HostBinding, viewChild, ElementRef, NgModule } from '@angular/core';
3
+ import { TextService } from '@updevs/sdk';
4
+ import { DataTypeEnum, StringColumnFilter, FilterTypeEnum, GuidColumnFilter, SelectColumnFilter, NumberColumnFilter, DateColumnFilter, BooleanColumnFilter, SortDirectionEnum, ColumnSort, BaseStore, FilterOperandEnum, FilterDateOperandEnum, FilterNumberOperandEnum, FilterBooleanOperandEnum, FilterGuidOperandEnum } from '@updevs/sdk/stores';
5
+ import { DynamicComponentLoaderService, BaseComponent, ButtonModel } from '@updevs/sdk/layout';
6
+ import * as i1 from '@angular/common';
7
+ import { CommonModule } from '@angular/common';
8
+ import * as i3 from '@updevs/icons';
9
+ import { UpdIconsModule } from '@updevs/icons';
10
+ import { DateTimeFormatEnum, Tools, SelectionModel, ServerResponseService } from '@updevs/sdk/core';
11
+ import { BaseModal, ModalService, ModalAlertService, UpdModalModule } from '@updevs/components/modal';
12
+ import { Subject, distinctUntilChanged, debounceTime, tap, switchMap, catchError, of, finalize, forkJoin } from 'rxjs';
13
+ import * as i1$1 from '@jsverse/transloco';
14
+ import { TranslocoDirective } from '@jsverse/transloco';
15
+ import * as i2 from '@updevs/components/drag-and-drop';
16
+ import { UpdDragAndDropModule } from '@updevs/components/drag-and-drop';
17
+ import { FormGroup, Validators } from '@angular/forms';
18
+ import * as i3$1 from '@updevs/components/form';
19
+ import { DynamicFieldType, UpdFormModule } from '@updevs/components/form';
20
+ import { BaseByUserSignalStorage } from '@updevs/sdk/security';
21
+ import * as i4 from '@updevs/components/button';
22
+ import { UpdButtonModule } from '@updevs/components/button';
23
+ import * as i5$1 from '@updevs/components/paginator';
24
+ import { UpdPaginatorModule } from '@updevs/components/paginator';
25
+ import * as i6 from '@updevs/components/form-controls/checkbox';
26
+ import { UpdCheckboxModule } from '@updevs/components/form-controls/checkbox';
27
+ import * as i7 from '@updevs/components/dropdown';
28
+ import { UpdDropdownModule } from '@updevs/components/dropdown';
29
+ import * as i8 from '@updevs/components/popover';
30
+ import { UpdPopoverModule } from '@updevs/components/popover';
31
+ import * as i5 from '@updevs/components/form-controls/input';
32
+ import { UpdInputModule } from '@updevs/components/form-controls/input';
33
+ import * as i3$2 from '@updevs/components/form-controls/select';
34
+ import { UpdSelectModule } from '@updevs/components/form-controls/select';
35
+ import { UpdTimePickerModule } from '@updevs/components/form-controls/time-picker';
36
+ import { UpdBadgeModule } from '@updevs/components/badge';
37
+
38
+ var ColumnTypeEnum;
39
+ (function (ColumnTypeEnum) {
40
+ ColumnTypeEnum[ColumnTypeEnum["Text"] = 1] = "Text";
41
+ ColumnTypeEnum[ColumnTypeEnum["DateTime"] = 2] = "DateTime";
42
+ ColumnTypeEnum[ColumnTypeEnum["Number"] = 3] = "Number";
43
+ ColumnTypeEnum[ColumnTypeEnum["Boolean"] = 4] = "Boolean";
44
+ ColumnTypeEnum[ColumnTypeEnum["Date"] = 5] = "Date";
45
+ ColumnTypeEnum[ColumnTypeEnum["Time"] = 6] = "Time";
46
+ ColumnTypeEnum[ColumnTypeEnum["Image"] = 7] = "Image";
47
+ ColumnTypeEnum[ColumnTypeEnum["Currency"] = 8] = "Currency";
48
+ ColumnTypeEnum[ColumnTypeEnum["Custom"] = 9] = "Custom";
49
+ ColumnTypeEnum[ColumnTypeEnum["Masked"] = 10] = "Masked";
50
+ ColumnTypeEnum[ColumnTypeEnum["Guid"] = 11] = "Guid";
51
+ })(ColumnTypeEnum || (ColumnTypeEnum = {}));
52
+
53
+ class BaseColumn {
54
+ constructor() {
55
+ this.textService = inject(TextService);
56
+ }
57
+ static { this.alignmentClassMap = {
58
+ justify: { text: 'text-justify', nonText: 'justify-content-between' },
59
+ center: { text: 'text-center', nonText: 'justify-content-center' },
60
+ right: { text: 'text-end', nonText: 'justify-content-end' },
61
+ left: { text: 'text-start', nonText: 'justify-content-start' }
62
+ }; }
63
+ static { this.overflowClassMap = {
64
+ 'no-wrap': 'text-nowrap',
65
+ wrap: 'text-wrap',
66
+ 'word-break': 'text-break',
67
+ truncate: 'text-truncate'
68
+ }; }
69
+ static { this.decorationClassMap = {
70
+ underline: 'text-decoration-underline',
71
+ strikethrough: 'text-decoration-line-through',
72
+ none: 'text-decoration-none'
73
+ }; }
74
+ static { this.weightClassMap = {
75
+ bold: 'fw-bold',
76
+ bolder: 'fw-bolder',
77
+ light: 'fw-light',
78
+ lighter: 'fw-lighter',
79
+ normal: 'fw-normal'
80
+ }; }
81
+ get value() {
82
+ return this.record[this.config.name];
83
+ }
84
+ get isTextType() {
85
+ return this.config.type !== ColumnTypeEnum.Boolean
86
+ && this.config.type !== ColumnTypeEnum.Image
87
+ && this.config.type !== ColumnTypeEnum.Custom;
88
+ }
89
+ get prefix() {
90
+ return this.textService.getText(this.config.prefix);
91
+ }
92
+ get suffix() {
93
+ return this.textService.getText(this.config.suffix);
94
+ }
95
+ get prefixSpace() {
96
+ return !!this.prefix && this.config.shouldSpaceAfterPrefix ? ' ' : '';
97
+ }
98
+ get suffixSpace() {
99
+ return !!this.suffix && this.config.shouldSpaceBeforeSuffix ? ' ' : '';
100
+ }
101
+ get alignmentClass() {
102
+ const map = BaseColumn.alignmentClassMap[this.config.alignment] || BaseColumn.alignmentClassMap['left'];
103
+ return this.isTextType ? map.text : map.nonText;
104
+ }
105
+ get overflowClass() {
106
+ return BaseColumn.overflowClassMap[this.config.overflowStrategy] || 'text-truncate';
107
+ }
108
+ get decorationClass() {
109
+ return this.config.decoration ? BaseColumn.decorationClassMap[this.config.decoration] : '';
110
+ }
111
+ get weightClass() {
112
+ return BaseColumn.weightClassMap[this.config.weight] || 'fw-normal';
113
+ }
114
+ getRecordAs() {
115
+ return this.record;
116
+ }
117
+ getClasses() {
118
+ return [
119
+ this.alignmentClass,
120
+ this.overflowClass,
121
+ this.decorationClass,
122
+ this.weightClass,
123
+ this.config.isItalic ? 'fst-italic' : ''
124
+ ];
125
+ }
126
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: BaseColumn, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
127
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.4", type: BaseColumn, isStandalone: false, ngImport: i0 }); }
128
+ }
129
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: BaseColumn, decorators: [{
130
+ type: Directive,
131
+ args: [{ standalone: false }]
132
+ }] });
133
+
134
+ class BaseColumnModel {
135
+ get dataType() {
136
+ switch (this.type) {
137
+ case ColumnTypeEnum.Boolean:
138
+ return DataTypeEnum.Boolean;
139
+ case ColumnTypeEnum.DateTime:
140
+ case ColumnTypeEnum.Date:
141
+ case ColumnTypeEnum.Time:
142
+ return DataTypeEnum.Date;
143
+ case ColumnTypeEnum.Currency:
144
+ case ColumnTypeEnum.Number:
145
+ return DataTypeEnum.Number;
146
+ case ColumnTypeEnum.Guid:
147
+ return DataTypeEnum.Guid;
148
+ default:
149
+ return DataTypeEnum.String;
150
+ }
151
+ }
152
+ get widthClass() {
153
+ if (!this.width || !!this.width.pixels) {
154
+ return '';
155
+ }
156
+ const prefix = !!this.width.gridColumn ? 'col' : 'w';
157
+ const auto = !!this.width.gridColumn && this.width.gridColumn === 0 ? 'auto' : '';
158
+ return `${prefix}-${auto || this.widthSize}`;
159
+ }
160
+ get widthSize() {
161
+ return !this.width ? 0 : this.width.gridColumn || this.width.percentage || 0;
162
+ }
163
+ get pixelsSize() {
164
+ return this.width?.pixels;
165
+ }
166
+ constructor(columnType, init) {
167
+ this.titleAlignment = 'left';
168
+ this.allowSort = true;
169
+ this.isItalic = false;
170
+ this.type = ColumnTypeEnum.Text;
171
+ this.alignment = 'left';
172
+ this.weight = 'normal';
173
+ this.overflowStrategy = 'truncate';
174
+ this.shouldSpaceAfterPrefix = true;
175
+ this.shouldSpaceBeforeSuffix = true;
176
+ this.isHidden = false;
177
+ if (!!init) {
178
+ Object.assign(this, init);
179
+ }
180
+ this.type = columnType;
181
+ }
182
+ }
183
+
184
+ class FiltersOperandsService {
185
+ }
186
+
187
+ class TextColumnComponent extends BaseColumn {
188
+ getClasses() {
189
+ return [
190
+ ...super.getClasses(),
191
+ this.transformClass
192
+ ];
193
+ }
194
+ get transformClass() {
195
+ switch (this.config.transform) {
196
+ case 'capitalize':
197
+ return 'text-capitalize';
198
+ case 'lowercase':
199
+ return 'text-lowercase';
200
+ case 'uppercase':
201
+ return 'text-uppercase';
202
+ default:
203
+ return '';
204
+ }
205
+ }
206
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TextColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
207
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: TextColumnComponent, isStandalone: false, selector: "upd-text-column", usesInheritance: true, ngImport: i0, template: "<span [ngClass]=\"getClasses()\">{{ prefix }}{{ prefixSpace }}{{ value }}{{ suffixSpace }}{{ suffix }}</span>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
208
+ }
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TextColumnComponent, decorators: [{
210
+ type: Component,
211
+ args: [{ standalone: false, selector: 'upd-text-column', template: "<span [ngClass]=\"getClasses()\">{{ prefix }}{{ prefixSpace }}{{ value }}{{ suffixSpace }}{{ suffix }}</span>\n" }]
212
+ }] });
213
+
214
+ class NumberColumnComponent extends BaseColumn {
215
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NumberColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
216
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: NumberColumnComponent, isStandalone: false, selector: "upd-number-column", usesInheritance: true, ngImport: i0, template: "<span [ngClass]=\"getClasses()\">{{ prefix }}{{ prefixSpace }}{{ value | number:config.numberFormat }}{{ suffixSpace }}{{ suffix }}</span>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] }); }
217
+ }
218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NumberColumnComponent, decorators: [{
219
+ type: Component,
220
+ args: [{ standalone: false, selector: 'upd-number-column', template: "<span [ngClass]=\"getClasses()\">{{ prefix }}{{ prefixSpace }}{{ value | number:config.numberFormat }}{{ suffixSpace }}{{ suffix }}</span>\n" }]
221
+ }] });
222
+
223
+ class BooleanColumnComponent extends BaseColumn {
224
+ getClasses() {
225
+ return [
226
+ ...super.getClasses(),
227
+ this.colorClass
228
+ ];
229
+ }
230
+ get colorClass() {
231
+ if (!this.config.shouldColorHighlight) {
232
+ return '';
233
+ }
234
+ return `text-${(!!this.value ? this.config.trueColor : this.config.falseColor)}`;
235
+ }
236
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: BooleanColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
237
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: BooleanColumnComponent, isStandalone: false, selector: "upd-boolean-column", usesInheritance: true, ngImport: i0, template: "<div [ngClass]=\"getClasses()\">\n @switch (config.displayType) {\n @case ('text') {\n {{ prefix }}{{ prefixSpace }}{{ !!value ? textService.getText(config.trueText) : textService.getText(config.falseText) }}{{ suffixSpace }}{{ suffix }}\n }\n @case ('toggle') {\n {{ prefix }}{{ prefixSpace }}\n <upd-icon [tablerIcon]=\"!!value ? 'toggle-right' : 'toggle-left'\"></upd-icon>{{ suffixSpace }}{{ suffix }}\n }\n @case ('icon') {\n {{ prefix }}{{ prefixSpace }}\n <upd-icon [model]=\"!!value ? config.trueIcon : config.falseIcon\"></upd-icon>{{ suffixSpace }}{{ suffix }}\n }\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i3.IconComponent, selector: "upd-icon", inputs: ["model", "wrapperClasses", "color", "colorClass", "removeDefaultClasses", "customClasses", "tablerIcon", "tablerIconWeight", "tablerIconType", "tablerIconSize", "heroIcon", "heroIconSize", "heroIconType"] }] }); }
238
+ }
239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: BooleanColumnComponent, decorators: [{
240
+ type: Component,
241
+ args: [{ standalone: false, selector: 'upd-boolean-column', template: "<div [ngClass]=\"getClasses()\">\n @switch (config.displayType) {\n @case ('text') {\n {{ prefix }}{{ prefixSpace }}{{ !!value ? textService.getText(config.trueText) : textService.getText(config.falseText) }}{{ suffixSpace }}{{ suffix }}\n }\n @case ('toggle') {\n {{ prefix }}{{ prefixSpace }}\n <upd-icon [tablerIcon]=\"!!value ? 'toggle-right' : 'toggle-left'\"></upd-icon>{{ suffixSpace }}{{ suffix }}\n }\n @case ('icon') {\n {{ prefix }}{{ prefixSpace }}\n <upd-icon [model]=\"!!value ? config.trueIcon : config.falseIcon\"></upd-icon>{{ suffixSpace }}{{ suffix }}\n }\n }\n</div>\n" }]
242
+ }] });
243
+
244
+ class DateTimeColumnComponent extends BaseColumn {
245
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DateTimeColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
246
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: DateTimeColumnComponent, isStandalone: false, selector: "upd-date-time-column", usesInheritance: true, ngImport: i0, template: "<span [ngClass]=\"getClasses()\">{{ prefix }}{{ prefixSpace }}{{ value | date:config.dateTimeFormat }}{{ suffixSpace }}{{ suffix }}</span>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] }); }
247
+ }
248
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DateTimeColumnComponent, decorators: [{
249
+ type: Component,
250
+ args: [{ standalone: false, selector: 'upd-date-time-column', template: "<span [ngClass]=\"getClasses()\">{{ prefix }}{{ prefixSpace }}{{ value | date:config.dateTimeFormat }}{{ suffixSpace }}{{ suffix }}</span>\n" }]
251
+ }] });
252
+
253
+ class TableColumnDirective {
254
+ constructor() {
255
+ this.record = input.required(...(ngDevMode ? [{ debugName: "record" }] : []));
256
+ this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
257
+ this.viewContainerRef = inject(ViewContainerRef);
258
+ this.dynamicLoaderService = inject(DynamicComponentLoaderService);
259
+ effect(() => {
260
+ const component = this.dynamicLoaderService.load(this.getComponentType(), this.viewContainerRef);
261
+ component.instance.record = this.record();
262
+ component.instance.config = this.config();
263
+ });
264
+ }
265
+ getComponentType() {
266
+ switch (this.config().type) {
267
+ case ColumnTypeEnum.Text:
268
+ // @ts-ignore
269
+ return TextColumnComponent;
270
+ case ColumnTypeEnum.Number:
271
+ // @ts-ignore
272
+ return NumberColumnComponent;
273
+ case ColumnTypeEnum.Boolean:
274
+ // @ts-ignore
275
+ return BooleanColumnComponent;
276
+ case ColumnTypeEnum.Date:
277
+ case ColumnTypeEnum.DateTime:
278
+ // @ts-ignore
279
+ return DateTimeColumnComponent;
280
+ case ColumnTypeEnum.Guid:
281
+ // @ts-ignore
282
+ return TextColumnComponent;
283
+ case ColumnTypeEnum.Custom:
284
+ return this.config().component;
285
+ default:
286
+ throw Error();
287
+ }
288
+ }
289
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableColumnDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
290
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.4", type: TableColumnDirective, isStandalone: false, selector: "[updTableColumn]", inputs: { record: { classPropertyName: "record", publicName: "record", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
291
+ }
292
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableColumnDirective, decorators: [{
293
+ type: Directive,
294
+ args: [{
295
+ standalone: false,
296
+ selector: '[updTableColumn]'
297
+ }]
298
+ }], ctorParameters: () => [], propDecorators: { record: [{ type: i0.Input, args: [{ isSignal: true, alias: "record", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
299
+
300
+ class BooleanColumnModel extends BaseColumnModel {
301
+ constructor(init) {
302
+ super(ColumnTypeEnum.Boolean, init);
303
+ this.displayType = 'text';
304
+ this.trueText = { text: 'UpDevs.Table.Filters.Boolean.True', isTranslated: false };
305
+ this.falseText = { text: 'UpDevs.Table.Filters.Boolean.False', isTranslated: false };
306
+ this.trueIcon = { tablerIcon: 'square-check' };
307
+ this.falseIcon = { tablerIcon: 'square' };
308
+ this.trueColor = 'success';
309
+ this.falseColor = 'secondary';
310
+ this.shouldColorHighlight = true;
311
+ if (this.displayType !== 'text') {
312
+ this.alignment = 'center';
313
+ }
314
+ if (!!init) {
315
+ Object.assign(this, init);
316
+ }
317
+ }
318
+ }
319
+
320
+ class CustomColumnModel extends BaseColumnModel {
321
+ constructor(init) {
322
+ super(ColumnTypeEnum.Custom, init);
323
+ if (!!init) {
324
+ Object.assign(this, init);
325
+ }
326
+ }
327
+ }
328
+
329
+ class DateTimeColumnModel extends BaseColumnModel {
330
+ get dateTimeFormat() {
331
+ return this.customFormat || this.format;
332
+ }
333
+ constructor(init) {
334
+ super(ColumnTypeEnum.DateTime, init);
335
+ this.format = DateTimeFormatEnum.ShortDate;
336
+ if (!!init) {
337
+ Object.assign(this, init);
338
+ }
339
+ }
340
+ }
341
+
342
+ class TextColumnModel extends BaseColumnModel {
343
+ constructor(init) {
344
+ super(ColumnTypeEnum.Text, init);
345
+ if (!!init) {
346
+ Object.assign(this, init);
347
+ }
348
+ }
349
+ }
350
+
351
+ class GuidColumnModel extends TextColumnModel {
352
+ constructor(init) {
353
+ super(init);
354
+ this.transform = 'uppercase';
355
+ if (!!init) {
356
+ Object.assign(this, init);
357
+ }
358
+ this.type = ColumnTypeEnum.Guid;
359
+ }
360
+ }
361
+
362
+ class ImageColumnModel extends BaseColumnModel {
363
+ constructor(init) {
364
+ super(ColumnTypeEnum.Image, init);
365
+ if (!!init) {
366
+ Object.assign(this, init);
367
+ }
368
+ }
369
+ }
370
+
371
+ class NumberColumnModel extends BaseColumnModel {
372
+ get numberFormat() {
373
+ return `${this.minIntegerDigits}.${this.minFractionDigits}-${this.maxFractionDigits}`;
374
+ }
375
+ constructor(init) {
376
+ super(ColumnTypeEnum.Number, init);
377
+ this.minIntegerDigits = 1;
378
+ this.minFractionDigits = 0;
379
+ this.maxFractionDigits = 3;
380
+ if (!!init) {
381
+ Object.assign(this, init);
382
+ }
383
+ }
384
+ }
385
+
386
+ class TableConfigModel {
387
+ constructor(init) {
388
+ this.columns = [];
389
+ this.canSearch = true;
390
+ this.canSaveViews = true;
391
+ this.canLoadSavedViews = true;
392
+ this.canManageColumns = true;
393
+ this.shouldAutoSearch = true;
394
+ this.hasCheckboxColumn = true;
395
+ this.isResponsive = true;
396
+ this.hasStickyHeader = false;
397
+ this.data = [];
398
+ this.preSelectedItems = [];
399
+ this.searchInputDebounceTime = 300;
400
+ /**
401
+ * Actions added to each record row as a group of buttons.
402
+ */
403
+ this.customActions = [];
404
+ /**
405
+ * Actions added to the header of the table as regular buttons.
406
+ */
407
+ this.customHeaderActions = [];
408
+ /**
409
+ * Define custom filterable fields.
410
+ * If not provided and useColumnsAsFilters is true, filters will be auto-generated from columns.
411
+ */
412
+ this.filterFields = [];
413
+ /**
414
+ * Whether to use columns as filters.
415
+ * If false, filterFields must be provided.
416
+ */
417
+ this.useColumnsAsFilters = false;
418
+ this.getIdFunction = (item) => item.id;
419
+ if (!!init) {
420
+ Object.assign(this, init);
421
+ }
422
+ }
423
+ }
424
+
425
+ class ColumnsManagerComponent extends BaseModal {
426
+ constructor() {
427
+ super(...arguments);
428
+ this.config = computed(() => ({ columns: [this.visibleColumn(), this.hiddenColumn()], canReorder: true }), ...(ngDevMode ? [{ debugName: "config" }] : []));
429
+ this.columns = signal([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
430
+ this.visibleColumn = computed(() => ({
431
+ name: 'visible',
432
+ title: { text: 'UpDevs.Table.VisibleColumns', isTranslated: false },
433
+ canBeEmpty: false,
434
+ items: this.data().columns.filter(c => !c.isHidden).map(c => ({
435
+ name: c.name,
436
+ text: c.title || { text: 'UpDevs.Table.ColumnTitleNotSet', isTranslated: false }
437
+ }))
438
+ }), ...(ngDevMode ? [{ debugName: "visibleColumn" }] : []));
439
+ this.hiddenColumn = computed(() => ({
440
+ name: 'hidden',
441
+ title: { text: 'UpDevs.Table.HiddenColumns', isTranslated: false },
442
+ items: this.data().columns.filter(c => c.isHidden).map(c => ({
443
+ name: c.name,
444
+ text: c.title || { text: 'UpDevs.Table.ColumnTitleNotSet', isTranslated: false }
445
+ }))
446
+ }), ...(ngDevMode ? [{ debugName: "hiddenColumn" }] : []));
447
+ }
448
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ColumnsManagerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
449
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: ColumnsManagerComponent, isStandalone: false, selector: "upd-columns-manager", usesInheritance: true, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table.ColumnsManager'\">\n <upd-drag-and-drop [config]=\"config()\" [(columns)]=\"columns\"></upd-drag-and-drop>\n</ng-container>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: i2.DragAndDropComponent, selector: "upd-drag-and-drop", inputs: ["config", "columns"], outputs: ["columnsChange"] }] }); }
450
+ }
451
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ColumnsManagerComponent, decorators: [{
452
+ type: Component,
453
+ args: [{ standalone: false, selector: 'upd-columns-manager', template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table.ColumnsManager'\">\n <upd-drag-and-drop [config]=\"config()\" [(columns)]=\"columns\"></upd-drag-and-drop>\n</ng-container>\n" }]
454
+ }] });
455
+
456
+ class SavedViewsStorage extends BaseByUserSignalStorage {
457
+ constructor() {
458
+ super('saved-views');
459
+ this.lastStateKey = 'last-state';
460
+ }
461
+ saveView(data) {
462
+ data.id = data.id || Tools.Guid.generate();
463
+ data.userId = this._loggedUserId;
464
+ this.save(data, this._getUserKey(data.id, data.tableName));
465
+ }
466
+ saveLastState(data) {
467
+ data.id = this.lastStateKey;
468
+ this.saveView(data);
469
+ }
470
+ getById(tableName, id) {
471
+ return this.get(this._getUserKey(id, tableName));
472
+ }
473
+ getAll(tableName) {
474
+ return computed(() => {
475
+ const records = this.getAllItems();
476
+ return records().filter(sv => sv.tableName.toLowerCase() === tableName.toLowerCase()
477
+ && sv.userId === this._loggedUserId
478
+ && sv.id !== this.lastStateKey);
479
+ });
480
+ }
481
+ getLastState(tableName) {
482
+ return this.getById(tableName, this.lastStateKey);
483
+ }
484
+ resetAllIsDefault(tableName) {
485
+ const savedViews = this.getAll(tableName)();
486
+ savedViews.forEach(sv => {
487
+ sv.isDefault = false;
488
+ this.saveView(sv);
489
+ });
490
+ }
491
+ removeViews(tableName, ...keys) {
492
+ super.remove(...keys.map(k => this._getUserKey(k, tableName)));
493
+ }
494
+ getByName(tableName, name) {
495
+ const records = this.getAllItems();
496
+ return records().find(sv => sv.tableName.toLowerCase() === tableName.toLowerCase()
497
+ && sv.userId === this._loggedUserId
498
+ && sv.name?.toLowerCase() === name?.toLowerCase()
499
+ && sv.id !== this.lastStateKey);
500
+ }
501
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SavedViewsStorage, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
502
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SavedViewsStorage }); }
503
+ }
504
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SavedViewsStorage, decorators: [{
505
+ type: Injectable
506
+ }], ctorParameters: () => [] });
507
+
508
+ class SaveSearchComponent extends BaseModal {
509
+ constructor() {
510
+ super(...arguments);
511
+ this.formGroup = model(new FormGroup({}), ...(ngDevMode ? [{ debugName: "formGroup" }] : []));
512
+ this.formRows = [];
513
+ this.savedViewsStorage = inject(SavedViewsStorage);
514
+ this.uniqueNameValidator = () => (control) => {
515
+ const existingRecord = this.savedViewsStorage.getByName(this.data().tableName, control.value);
516
+ return !!existingRecord
517
+ ? { nameNotUnique: { errorText: { text: 'UpDevs.Table.SavedViews.NameNotUnique', isTranslated: false } } }
518
+ // eslint-disable-next-line no-null/no-null
519
+ : null;
520
+ };
521
+ }
522
+ ngOnInit() {
523
+ this.formRows = [
524
+ {
525
+ fields: [
526
+ {
527
+ name: 'name',
528
+ type: DynamicFieldType.Input,
529
+ colSize: { default: 12 },
530
+ label: { text: 'UpDevs.Table.SaveSearch.Name', isTranslated: false },
531
+ validators: [Validators.required, Validators.minLength(3), this.uniqueNameValidator()],
532
+ initValue: this.data().name
533
+ }
534
+ ]
535
+ },
536
+ {
537
+ fields: [
538
+ {
539
+ name: 'isDefault',
540
+ type: DynamicFieldType.Checkbox,
541
+ colSize: { default: 6 },
542
+ label: { text: 'UpDevs.Table.SaveSearch.IsDefault', isTranslated: false },
543
+ hint: { text: 'UpDevs.Table.SaveSearch.IsDefaultHint', isTranslated: false },
544
+ hintAsTooltip: true,
545
+ initValue: this.data().isDefault || false
546
+ }
547
+ ]
548
+ }
549
+ ];
550
+ }
551
+ cancel() {
552
+ this.modalRef().close();
553
+ }
554
+ save() {
555
+ const formValue = this.formGroup().value;
556
+ const data = { ...this.data(), name: formValue.name, isDefault: formValue.isDefault };
557
+ if (data.isDefault) {
558
+ this.savedViewsStorage.resetAllIsDefault(this.data().tableName);
559
+ }
560
+ this.savedViewsStorage.saveView(data);
561
+ this.modalRef().close();
562
+ }
563
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SaveSearchComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
564
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: SaveSearchComponent, isStandalone: false, selector: "upd-save-search", inputs: { formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formGroup: "formGroupChange" }, usesInheritance: true, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table.SaveSearch'\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">{{ t('Title') }}</h5>\n </div>\n <div class=\"modal-body py-4\">\n <upd-form [rows]=\"formRows\" [hasActionsSection]=\"false\" [(formGroup)]=\"formGroup\"></upd-form>\n </div>\n <div class=\"modal-footer\">\n <upd-button colorStyle=\"secondary\" [isLink]=\"true\" (clicked)=\"cancel()\">\n {{ t('Cancel') }}\n </upd-button>\n <upd-button colorStyle=\"primary\" [iconModel]=\"{tablerIcon:'device-floppy'}\" (clicked)=\"save()\" [isDisabled]=\"!formGroup().valid\">\n {{ t('Save') }}\n </upd-button>\n </div>\n</ng-container>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: i4.ButtonComponent, selector: "upd-button", inputs: ["model", "text", "brandColorStyle", "customClasses", "isOutline", "isGhost", "isSquare", "isPill", "isIcon", "isLoading", "isList", "isFloating", "isAction", "isNavigationLink", "isLink", "shouldIgnoreBtnClass", "iconModel", "iconPosition", "isDisabled", "isActive", "badgeConfig", "colorStyle", "size", "title", "stopPropagation"], outputs: ["clicked"] }, { kind: "component", type: i3$1.FormComponent, selector: "upd-form", inputs: ["rows", "layout", "title", "hasActionsSection", "isCard", "isDisabled", "isLoading", "isSaving", "formData", "formGroup"], outputs: ["initialized", "dataLoaded", "submitted", "formDataChange", "formGroupChange"] }] }); }
565
+ }
566
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SaveSearchComponent, decorators: [{
567
+ type: Component,
568
+ args: [{ standalone: false, selector: 'upd-save-search', template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table.SaveSearch'\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">{{ t('Title') }}</h5>\n </div>\n <div class=\"modal-body py-4\">\n <upd-form [rows]=\"formRows\" [hasActionsSection]=\"false\" [(formGroup)]=\"formGroup\"></upd-form>\n </div>\n <div class=\"modal-footer\">\n <upd-button colorStyle=\"secondary\" [isLink]=\"true\" (clicked)=\"cancel()\">\n {{ t('Cancel') }}\n </upd-button>\n <upd-button colorStyle=\"primary\" [iconModel]=\"{tablerIcon:'device-floppy'}\" (clicked)=\"save()\" [isDisabled]=\"!formGroup().valid\">\n {{ t('Save') }}\n </upd-button>\n </div>\n</ng-container>\n" }]
569
+ }], propDecorators: { formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: false }] }, { type: i0.Output, args: ["formGroupChange"] }] } });
570
+
571
+ /**
572
+ * Service to manage the current search request state across table components.
573
+ * Uses Angular signals for reactive state management, eliminating the need for prop drilling.
574
+ * Should be provided at the table component level so each table instance has its own state.
575
+ */
576
+ class CurrentSearchRequestService {
577
+ constructor() {
578
+ this._searchRequest = signal({}, ...(ngDevMode ? [{ debugName: "_searchRequest" }] : []));
579
+ this._isSearching = signal(false, ...(ngDevMode ? [{ debugName: "_isSearching" }] : []));
580
+ this._hasChanges = signal(false, ...(ngDevMode ? [{ debugName: "_hasChanges" }] : []));
581
+ /**
582
+ * Read-only signal for the current search request
583
+ */
584
+ this.searchRequest = this._searchRequest.asReadonly();
585
+ /**
586
+ * Read-only signal for the searching state
587
+ */
588
+ this.isSearching = this._isSearching.asReadonly();
589
+ /**
590
+ * Read-only signal indicating if the search request has changed from default
591
+ */
592
+ this.hasChanges = this._hasChanges.asReadonly();
593
+ /**
594
+ * Subject to trigger search operations
595
+ */
596
+ this.searchRequestSubject = new Subject();
597
+ /**
598
+ * Count of active filters (non-hidden)
599
+ */
600
+ this.activeFilterCount = computed(() => this.searchRequest().filters?.filter(f => !f.isHidden).length || 0, ...(ngDevMode ? [{ debugName: "activeFilterCount" }] : []));
601
+ /**
602
+ * Whether there are any active filters
603
+ */
604
+ this.hasFilters = computed(() => (this.searchRequest().filters?.length || 0) > 0, ...(ngDevMode ? [{ debugName: "hasFilters" }] : []));
605
+ /**
606
+ * Count of visible (non-hidden) filters
607
+ */
608
+ this.visibleFilterCount = computed(() => this.searchRequest().filters?.filter(f => !f.isHidden).length || 0, ...(ngDevMode ? [{ debugName: "visibleFilterCount" }] : []));
609
+ /**
610
+ * Whether there's a search description/text query
611
+ */
612
+ this.hasDescription = computed(() => !!this.searchRequest().description && this.searchRequest().description.length > 0, ...(ngDevMode ? [{ debugName: "hasDescription" }] : []));
613
+ /**
614
+ * Whether there are any sortings applied
615
+ */
616
+ this.hasSorting = computed(() => (this.searchRequest().sortings?.length || 0) > 0, ...(ngDevMode ? [{ debugName: "hasSorting" }] : []));
617
+ /**
618
+ * The current sorting (first one if multiple exist)
619
+ */
620
+ this.currentSorting = computed(() => this.hasSorting() ? this.searchRequest().sortings[0] : undefined, ...(ngDevMode ? [{ debugName: "currentSorting" }] : []));
621
+ /**
622
+ * Whether any search criteria is active (filters, description, or sorting)
623
+ */
624
+ this.hasAnySearchCriteria = computed(() => this.hasFilters() || this.hasDescription() || this.hasSorting(), ...(ngDevMode ? [{ debugName: "hasAnySearchCriteria" }] : []));
625
+ /**
626
+ * Current page number (1-indexed for display)
627
+ */
628
+ this.currentPageNumber = computed(() => (this.searchRequest().pageIndex || 0) + 1, ...(ngDevMode ? [{ debugName: "currentPageNumber" }] : []));
629
+ /**
630
+ * Whether pagination is configured
631
+ */
632
+ this.hasPagination = computed(() => !!this.searchRequest().pageSize && this.searchRequest().pageSize > 0, ...(ngDevMode ? [{ debugName: "hasPagination" }] : []));
633
+ }
634
+ /**
635
+ * Updates the entire search request
636
+ * @param request The new search request
637
+ */
638
+ updateSearchRequest(request) {
639
+ const previousRequest = this._searchRequest();
640
+ this._searchRequest.set(request);
641
+ // Only mark as changed if the new request is actually different from previous
642
+ if (!this.areSearchRequestsEqual(previousRequest, request)) {
643
+ this._hasChanges.set(true);
644
+ }
645
+ }
646
+ /**
647
+ * Partially updates the search request
648
+ * @param partial Partial search request properties to update
649
+ */
650
+ patchSearchRequest(partial) {
651
+ const previousRequest = this._searchRequest();
652
+ const newRequest = { ...previousRequest, ...partial };
653
+ this._searchRequest.set(newRequest);
654
+ // Only mark as changed if the patch actually changed something
655
+ if (!this.areSearchRequestsEqual(previousRequest, newRequest)) {
656
+ this._hasChanges.set(true);
657
+ }
658
+ }
659
+ /**
660
+ * Sets the searching state
661
+ * @param isSearching Whether a search is in progress
662
+ */
663
+ setSearching(isSearching) {
664
+ this._isSearching.set(isSearching);
665
+ }
666
+ /**
667
+ * Resets the search request to default state
668
+ */
669
+ reset() {
670
+ this._searchRequest.set({});
671
+ this._isSearching.set(false);
672
+ this._hasChanges.set(false);
673
+ }
674
+ /**
675
+ * Triggers a search operation by emitting on the searchRequestSubject
676
+ */
677
+ triggerSearch() {
678
+ this.searchRequestSubject.next(this._searchRequest());
679
+ }
680
+ /**
681
+ * Manually sets the hasChanges flag
682
+ * Useful for changes that aren't part of the search request but should enable Save View
683
+ * (e.g., column visibility changes)
684
+ * @param hasChanges Whether there are changes
685
+ */
686
+ setHasChanges(hasChanges) {
687
+ this._hasChanges.set(hasChanges);
688
+ }
689
+ /**
690
+ * Adds a filter to the search request
691
+ * @param filter The filter to add
692
+ */
693
+ addFilter(filter) {
694
+ const currentFilters = this.searchRequest().filters || [];
695
+ this.patchSearchRequest({ filters: [...currentFilters, filter] });
696
+ }
697
+ /**
698
+ * Removes a filter by name
699
+ * @param filterName The name of the filter column to remove
700
+ */
701
+ removeFilter(filterName) {
702
+ const currentFilters = this.searchRequest().filters || [];
703
+ this.patchSearchRequest({ filters: currentFilters.filter(f => f.column !== filterName) });
704
+ }
705
+ /**
706
+ * Removes a filter by index
707
+ * @param index The index of the filter to remove
708
+ */
709
+ removeFilterByIndex(index) {
710
+ const currentFilters = this.searchRequest().filters || [];
711
+ this.patchSearchRequest({ filters: currentFilters.filter((_, i) => i !== index) });
712
+ }
713
+ /**
714
+ * Updates a specific filter by column name
715
+ * @param columnName The column name of the filter to update
716
+ * @param newData Partial filter properties to update
717
+ */
718
+ updateFilter(columnName, newData) {
719
+ const currentFilters = this.searchRequest().filters || [];
720
+ this.patchSearchRequest({ filters: currentFilters.map(f => f.column === columnName ? { ...f, ...newData } : f) });
721
+ }
722
+ /**
723
+ * Updates a filter by its index position
724
+ * @param index The index of the filter to update
725
+ * @param newData Partial filter properties to update
726
+ */
727
+ updateFilterByIndex(index, newData) {
728
+ const currentFilters = this.searchRequest().filters || [];
729
+ if (index >= 0 && index < currentFilters.length) {
730
+ this.patchSearchRequest({ filters: currentFilters.map((f, i) => i === index ? { ...f, ...newData } : f) });
731
+ }
732
+ }
733
+ /**
734
+ * Clears all filters
735
+ */
736
+ clearFilters() {
737
+ this.patchSearchRequest({ filters: [] });
738
+ }
739
+ /**
740
+ * Sets the sorting (replaces existing sortings)
741
+ * @param column The column name to sort by
742
+ * @param direction The sort direction
743
+ */
744
+ setSorting(column, direction) {
745
+ this.patchSearchRequest({ sortings: [{ column, direction }] });
746
+ }
747
+ /**
748
+ * Clears all sorting
749
+ */
750
+ clearSorting() {
751
+ this.patchSearchRequest({ sortings: [] });
752
+ }
753
+ /**
754
+ * Sets the search description/text query
755
+ * @param description The search text
756
+ */
757
+ setDescription(description) {
758
+ this.patchSearchRequest({ description });
759
+ }
760
+ /**
761
+ * Clears the search description
762
+ */
763
+ clearDescription() {
764
+ this.patchSearchRequest({ description: '' });
765
+ }
766
+ /**
767
+ * Clears ALL search criteria (filters, description, sorting)
768
+ * Note: Does not reset pagination - use reset() for that
769
+ */
770
+ clearAll() {
771
+ this.patchSearchRequest({ filters: [], description: '', sortings: [] });
772
+ }
773
+ /**
774
+ * Clears all search criteria except pagination
775
+ * Useful when you want to reset search but maintain current page
776
+ */
777
+ clearAllExceptPagination() {
778
+ this.clearAll();
779
+ }
780
+ /**
781
+ * Deep comparison of two search requests
782
+ * @param a First search request
783
+ * @param b Second search request
784
+ * @returns true if they are equal, false otherwise
785
+ */
786
+ areSearchRequestsEqual(a, b) {
787
+ if ((a.description || '') !== (b.description || '')) {
788
+ return false;
789
+ }
790
+ const aFilters = a.filters || [];
791
+ const bFilters = b.filters || [];
792
+ if (aFilters.length !== bFilters.length) {
793
+ return false;
794
+ }
795
+ for (let i = 0; i < aFilters.length; i++) {
796
+ if (JSON.stringify(aFilters[i]) !== JSON.stringify(bFilters[i])) {
797
+ return false;
798
+ }
799
+ }
800
+ const aSortings = a.sortings || [];
801
+ const bSortings = b.sortings || [];
802
+ if (aSortings.length !== bSortings.length) {
803
+ return false;
804
+ }
805
+ for (let i = 0; i < aSortings.length; i++) {
806
+ if (JSON.stringify(aSortings[i]) !== JSON.stringify(bSortings[i])) {
807
+ return false;
808
+ }
809
+ }
810
+ if (a.pageSize !== b.pageSize || a.pageIndex !== b.pageIndex) {
811
+ return false;
812
+ }
813
+ return true;
814
+ }
815
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CurrentSearchRequestService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
816
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CurrentSearchRequestService }); }
817
+ }
818
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CurrentSearchRequestService, decorators: [{
819
+ type: Injectable
820
+ }] });
821
+
822
+ class FilterTools {
823
+ static convertToFilterItem(filters, operands) {
824
+ return filters.map(f => ({
825
+ name: f.column,
826
+ value: f.value,
827
+ operandConfig: f.type && operands[f.type] ? operands[f.type].find(op => op.operand === f.operand) : undefined,
828
+ isHidden: f.isHidden,
829
+ type: f.type
830
+ }));
831
+ }
832
+ static convertToRequestFilter(filters, filtersConfigs = [], columns = []) {
833
+ return filters.map(af => {
834
+ const filterType = filtersConfigs.length > 0
835
+ ? filtersConfigs.find(c => c.name === af.name).type
836
+ : columns.find(c => c.name === af.name).filterType;
837
+ switch (filterType) {
838
+ case FilterTypeEnum.Boolean:
839
+ return new BooleanColumnFilter({
840
+ column: af.name,
841
+ value: af.value,
842
+ operand: !!af.operandConfig ? af.operandConfig.operand : undefined,
843
+ isHidden: af.isHidden,
844
+ type: filterType
845
+ });
846
+ case FilterTypeEnum.Date:
847
+ return new DateColumnFilter({
848
+ column: af.name,
849
+ value: af.value,
850
+ operand: !!af.operandConfig ? af.operandConfig.operand : undefined,
851
+ isHidden: af.isHidden,
852
+ type: filterType
853
+ });
854
+ case FilterTypeEnum.Number:
855
+ return new NumberColumnFilter({
856
+ column: af.name,
857
+ value: af.value,
858
+ operand: !!af.operandConfig ? af.operandConfig.operand : undefined,
859
+ isHidden: af.isHidden,
860
+ type: filterType
861
+ });
862
+ case FilterTypeEnum.Select:
863
+ return new SelectColumnFilter({
864
+ column: af.name,
865
+ value: af.value,
866
+ operand: !!af.operandConfig ? af.operandConfig.operand : undefined,
867
+ isHidden: af.isHidden,
868
+ type: filterType
869
+ });
870
+ case FilterTypeEnum.Guid:
871
+ return new GuidColumnFilter({
872
+ column: af.name,
873
+ value: af.value,
874
+ operand: !!af.operandConfig ? af.operandConfig.operand : undefined,
875
+ isHidden: af.isHidden,
876
+ type: filterType
877
+ });
878
+ default:
879
+ return new StringColumnFilter({
880
+ column: af.name,
881
+ value: af.value,
882
+ operand: !!af.operandConfig ? af.operandConfig.operand : undefined,
883
+ isHidden: af.isHidden,
884
+ type: filterType
885
+ });
886
+ }
887
+ });
888
+ }
889
+ }
890
+
891
+ /**
892
+ * Table constants.
893
+ */
894
+ class TableConstants {
895
+ /**
896
+ * Key to inject the default configuration.
897
+ */
898
+ static { this.defaultOptionsKey = 'upd-table-default-options'; }
899
+ /**
900
+ * Injection token for the default configuration.
901
+ */
902
+ static { this.defaultOptionsInjectionToken = new InjectionToken(TableConstants.defaultOptionsKey); }
903
+ }
904
+
905
+ class UpdTableConfigModel {
906
+ constructor(init) {
907
+ this.shouldLoadFieldsFromServer = false;
908
+ if (!!init) {
909
+ Object.assign(this, init);
910
+ }
911
+ }
912
+ }
913
+
914
+ class UpdTableConfigService {
915
+ constructor(layoutConfig) {
916
+ this.config = new UpdTableConfigModel(layoutConfig);
917
+ }
918
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UpdTableConfigService, deps: [{ token: TableConstants.defaultOptionsInjectionToken }], target: i0.ɵɵFactoryTarget.Injectable }); }
919
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UpdTableConfigService }); }
920
+ }
921
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UpdTableConfigService, decorators: [{
922
+ type: Injectable
923
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
924
+ type: Inject,
925
+ args: [TableConstants.defaultOptionsInjectionToken]
926
+ }] }] });
927
+
928
+ class FilterRowComponent extends BaseComponent {
929
+ constructor() {
930
+ super(...arguments);
931
+ this.wrapperClasses = 'd-flex gap-2';
932
+ this.removed = new EventEmitter();
933
+ this.FilterTypeEnum = FilterTypeEnum;
934
+ this.rowIndex = input.required(...(ngDevMode ? [{ debugName: "rowIndex" }] : []));
935
+ this.columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
936
+ this.isDisabled = input.required(...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
937
+ this.store = input(...(ngDevMode ? [undefined, { debugName: "store" }] : []));
938
+ this.filterFields = input(...(ngDevMode ? [undefined, { debugName: "filterFields" }] : []));
939
+ this.currentFilter = input(...(ngDevMode ? [undefined, { debugName: "currentFilter" }] : []));
940
+ this.currentField = signal(undefined, ...(ngDevMode ? [{ debugName: "currentField" }] : []));
941
+ this.currentOperand = signal(undefined, ...(ngDevMode ? [{ debugName: "currentOperand" }] : []));
942
+ this.fieldsOptions = signal([], ...(ngDevMode ? [{ debugName: "fieldsOptions" }] : []));
943
+ this.comparisonOperatorOptions = signal([], ...(ngDevMode ? [{ debugName: "comparisonOperatorOptions" }] : []));
944
+ this.fieldAllowedValues = signal([], ...(ngDevMode ? [{ debugName: "fieldAllowedValues" }] : []));
945
+ this.isValueSectionEnabled = signal(true, ...(ngDevMode ? [{ debugName: "isValueSectionEnabled" }] : []));
946
+ this.currentOperands = [];
947
+ this.configService = inject(UpdTableConfigService);
948
+ this.filtersOperandsService = inject(FiltersOperandsService);
949
+ this.textService = inject(TextService);
950
+ this.currentSearchRequestService = inject(CurrentSearchRequestService);
951
+ }
952
+ get fieldType() {
953
+ return this.currentField()?.objectData || FilterTypeEnum.Text;
954
+ }
955
+ get selectedField() {
956
+ const currentFilter = this.currentFilter();
957
+ return !!currentFilter?.name
958
+ ? this.fieldsOptions().find(f => f.value === currentFilter.name)
959
+ : undefined;
960
+ }
961
+ get selectedOperand() {
962
+ const currentFilter = this.currentFilter();
963
+ return !!currentFilter?.name
964
+ ? this.comparisonOperatorOptions().find(co => co.value === currentFilter.operandConfig?.operand)
965
+ : undefined;
966
+ }
967
+ get selectedValue() {
968
+ const currentFilter = this.currentFilter();
969
+ return !!currentFilter?.name ? currentFilter.value : undefined;
970
+ }
971
+ ngOnInit() {
972
+ // Priority 1: User-defined filter fields
973
+ if (!!this.filterFields() && this.filterFields().length > 0) {
974
+ this.fieldsOptions.set(this.filterFields().map(f => ({
975
+ value: f.name,
976
+ text: this.textService.getText(f.label),
977
+ objectData: f.type
978
+ })));
979
+ }
980
+ // Priority 2: Server-loaded fields
981
+ else if (!!this.store() && this.configService.config.shouldLoadFieldsFromServer) {
982
+ this.store().getFilterableFields().subscribe(fields => this.fieldsOptions.set(fields.map(f => ({
983
+ value: f.name,
984
+ text: f.description,
985
+ objectData: f.type
986
+ }))));
987
+ }
988
+ // Priority 3: Fallback to columns
989
+ else {
990
+ this.fieldsOptions.set(this.columns().filter(c => !!c.title).map(c => ({
991
+ value: c.name,
992
+ text: this.textService.getText(c.title),
993
+ objectData: c.dataType
994
+ })));
995
+ }
996
+ if (!!this.selectedField) {
997
+ this.onSelectField(this.selectedField);
998
+ if (!!this.selectedOperand) {
999
+ this.onSelectOperand(this.selectedOperand);
1000
+ }
1001
+ if (!!this.selectedValue) {
1002
+ this.updateValue(this.selectedValue);
1003
+ }
1004
+ }
1005
+ }
1006
+ onSelectField(item) {
1007
+ this.currentField.set(item);
1008
+ const dataType = item?.objectData;
1009
+ if (!!dataType) {
1010
+ this.currentOperands = this.filtersOperandsService.getOperands(dataType);
1011
+ this.comparisonOperatorOptions.set(this.currentOperands.map(o => ({ value: o.operand, text: this.textService.getText(o.text), listItem: { icon: o.icon } })));
1012
+ }
1013
+ else {
1014
+ this.comparisonOperatorOptions.set([]);
1015
+ }
1016
+ this.currentSearchRequestService.updateFilterByIndex(this.rowIndex(), {
1017
+ column: this.currentField()?.value,
1018
+ type: this.fieldType,
1019
+ dataType: dataType
1020
+ });
1021
+ }
1022
+ onSelectOperand(item) {
1023
+ this.currentOperand.set(this.currentOperands.find(co => co.operand === item?.value));
1024
+ this.isValueSectionEnabled.set(!!this.currentOperand()?.requiresValue);
1025
+ this.currentSearchRequestService.updateFilterByIndex(this.rowIndex(), { operand: this.currentOperand()?.operand });
1026
+ if (this.fieldType === FilterTypeEnum.Select) {
1027
+ const values = this.filterFields()?.find(f => f.name === this.currentField()?.value)?.allowedValues || [];
1028
+ this.fieldAllowedValues.set(values.map(v => ({ value: v.key, text: v.value })));
1029
+ }
1030
+ }
1031
+ updateValue(value) {
1032
+ this.currentSearchRequestService.updateFilterByIndex(this.rowIndex(), { value });
1033
+ }
1034
+ removeFilterItem() {
1035
+ this.currentSearchRequestService.removeFilterByIndex(this.rowIndex());
1036
+ this.removed.emit();
1037
+ }
1038
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FilterRowComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1039
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: FilterRowComponent, isStandalone: false, selector: "upd-filter-row", inputs: { rowIndex: { classPropertyName: "rowIndex", publicName: "rowIndex", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: true, transformFunction: null }, store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: false, transformFunction: null }, filterFields: { classPropertyName: "filterFields", publicName: "filterFields", isSignal: true, isRequired: false, transformFunction: null }, currentFilter: { classPropertyName: "currentFilter", publicName: "currentFilter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { properties: { "class": "this.wrapperClasses" } }, usesInheritance: true, ngImport: i0, template: "<upd-select class=\"w-100\" [isDisabled]=\"isDisabled()\" [items]=\"fieldsOptions()\" (selectedItem)=\"onSelectField($event)\"\n [value]=\"selectedField?.value\">\n</upd-select>\n<upd-select class=\"w-100\" [isDisabled]=\"isDisabled()\" [items]=\"comparisonOperatorOptions()\"\n (selectedItem)=\"onSelectOperand($event)\" [value]=\"selectedOperand?.value\">\n</upd-select>\n\n@if (isValueSectionEnabled()) {\n @switch (fieldType) {\n @case (FilterTypeEnum.Number) {\n <upd-input wrapperClasses=\"w-100\" customClasses=\"h-100\" type=\"number\" (valueChange)=\"updateValue($event)\"\n [value]=\"selectedValue\"></upd-input>\n }\n @case (FilterTypeEnum.Date) {\n\n }\n @case (FilterTypeEnum.Select) {\n <upd-select class=\"w-100\" [isDisabled]=\"isDisabled()\" [items]=\"fieldAllowedValues()\"\n (selectedItem)=\"updateValue($event?.value)\" [value]=\"selectedValue\">\n </upd-select>\n }\n @default {\n <upd-input wrapperClasses=\"w-100\" customClasses=\"h-100\" type=\"text\" (valueChange)=\"updateValue($event)\"\n [value]=\"selectedValue\"></upd-input>\n }\n }\n} @else {\n <div class=\"w-100\">\n <input type=\"text\" class=\"form-control h-100\" disabled>\n </div>\n}\n\n<upd-button class=\"flex-shrink-1\" colorStyle=\"danger\" [isDisabled]=\"isDisabled()\" [isOutline]=\"true\" [isIcon]=\"true\"\n [iconModel]=\"{tablerIcon:'x'}\" (clicked)=\"removeFilterItem()\"></upd-button>", styles: [""], dependencies: [{ kind: "component", type: i4.ButtonComponent, selector: "upd-button", inputs: ["model", "text", "brandColorStyle", "customClasses", "isOutline", "isGhost", "isSquare", "isPill", "isIcon", "isLoading", "isList", "isFloating", "isAction", "isNavigationLink", "isLink", "shouldIgnoreBtnClass", "iconModel", "iconPosition", "isDisabled", "isActive", "badgeConfig", "colorStyle", "size", "title", "stopPropagation"], outputs: ["clicked"] }, { kind: "component", type: i5.InputComponent, selector: "upd-input", inputs: ["type", "mask", "maskConfig", "value", "size", "customClasses", "wrapperClasses", "maxLength", "isPlainText", "isReadOnly", "isLoading", "isRound", "isFlush", "isInputGroupFlat", "isPrependButton", "isAppendButton", "isFloating", "loaderPosition", "prependIconModel", "appendIconModel", "isValidationStatusLight", "layout"], outputs: ["valueChange", "blurred", "keyDown", "keyDownEsc", "keyUpEnter"] }, { kind: "component", type: i3$2.SelectComponent, selector: "upd-select", inputs: ["useSystemStyle", "shouldShowClearButton", "shouldTruncateSelectedText", "isCompact", "value"], outputs: ["valueChange", "selectedItem"] }] }); }
1040
+ }
1041
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FilterRowComponent, decorators: [{
1042
+ type: Component,
1043
+ args: [{ standalone: false, selector: 'upd-filter-row', template: "<upd-select class=\"w-100\" [isDisabled]=\"isDisabled()\" [items]=\"fieldsOptions()\" (selectedItem)=\"onSelectField($event)\"\n [value]=\"selectedField?.value\">\n</upd-select>\n<upd-select class=\"w-100\" [isDisabled]=\"isDisabled()\" [items]=\"comparisonOperatorOptions()\"\n (selectedItem)=\"onSelectOperand($event)\" [value]=\"selectedOperand?.value\">\n</upd-select>\n\n@if (isValueSectionEnabled()) {\n @switch (fieldType) {\n @case (FilterTypeEnum.Number) {\n <upd-input wrapperClasses=\"w-100\" customClasses=\"h-100\" type=\"number\" (valueChange)=\"updateValue($event)\"\n [value]=\"selectedValue\"></upd-input>\n }\n @case (FilterTypeEnum.Date) {\n\n }\n @case (FilterTypeEnum.Select) {\n <upd-select class=\"w-100\" [isDisabled]=\"isDisabled()\" [items]=\"fieldAllowedValues()\"\n (selectedItem)=\"updateValue($event?.value)\" [value]=\"selectedValue\">\n </upd-select>\n }\n @default {\n <upd-input wrapperClasses=\"w-100\" customClasses=\"h-100\" type=\"text\" (valueChange)=\"updateValue($event)\"\n [value]=\"selectedValue\"></upd-input>\n }\n }\n} @else {\n <div class=\"w-100\">\n <input type=\"text\" class=\"form-control h-100\" disabled>\n </div>\n}\n\n<upd-button class=\"flex-shrink-1\" colorStyle=\"danger\" [isDisabled]=\"isDisabled()\" [isOutline]=\"true\" [isIcon]=\"true\"\n [iconModel]=\"{tablerIcon:'x'}\" (clicked)=\"removeFilterItem()\"></upd-button>" }]
1044
+ }], propDecorators: { wrapperClasses: [{
1045
+ type: HostBinding,
1046
+ args: ['class']
1047
+ }], removed: [{
1048
+ type: Output
1049
+ }], rowIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIndex", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], isDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDisabled", required: true }] }], store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: false }] }], filterFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFields", required: false }] }], currentFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentFilter", required: false }] }] } });
1050
+
1051
+ class SearchSectionComponent extends BaseComponent {
1052
+ constructor() {
1053
+ super();
1054
+ this.wrapperClass = 'card-body border-bottom py-3 d-flex flex-column gap-2';
1055
+ this.columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
1056
+ this.config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
1057
+ this.actionsTpl = input(...(ngDevMode ? [undefined, { debugName: "actionsTpl" }] : []));
1058
+ this.activeFilters = computed(() => FilterTools.convertToFilterItem(this.currentSearchRequestService.searchRequest().filters?.filter(af => !af.isHidden) || [], this.filtersOperandsService.getAllOperands()), ...(ngDevMode ? [{ debugName: "activeFilters" }] : []));
1059
+ this.isFilterSectionOpen = signal(false, ...(ngDevMode ? [{ debugName: "isFilterSectionOpen" }] : []));
1060
+ this.canApplyFilters = computed(() => this.activeFilters().length > 0
1061
+ && this.activeFilters().every(af => !af.isHidden && !!af.name && !!af.operandConfig?.operand && (!af.operandConfig?.requiresValue || !!af.value)), ...(ngDevMode ? [{ debugName: "canApplyFilters" }] : []));
1062
+ this.canPerformActions = computed(() => this.canApplyFilters() && !this.currentSearchRequestService.isSearching(), ...(ngDevMode ? [{ debugName: "canPerformActions" }] : []));
1063
+ this.badgeConfig = computed(() => this.currentSearchRequestService.visibleFilterCount() > 0
1064
+ ? ({
1065
+ isNotification: true,
1066
+ isPill: true,
1067
+ bgColor: 'primary-lt',
1068
+ text: { text: this.currentSearchRequestService.visibleFilterCount().toString(), isTranslated: true }
1069
+ })
1070
+ : undefined, ...(ngDevMode ? [{ debugName: "badgeConfig" }] : []));
1071
+ this.filterSectionBtnColor = computed(() => this.isFilterSectionOpen() ? 'primary' : undefined, ...(ngDevMode ? [{ debugName: "filterSectionBtnColor" }] : []));
1072
+ this.searchSubject = new Subject();
1073
+ this.filtersOperandsService = inject(FiltersOperandsService);
1074
+ this.currentSearchRequestService = inject(CurrentSearchRequestService);
1075
+ effect(() => {
1076
+ // Auto-close filter section when all filters are removed
1077
+ if (this.currentSearchRequestService.visibleFilterCount() === 0 && this.isFilterSectionOpen()) {
1078
+ this.isFilterSectionOpen.set(false);
1079
+ }
1080
+ }, { allowSignalWrites: true });
1081
+ }
1082
+ ngOnInit() {
1083
+ const searchSub = this.searchSubject
1084
+ .pipe(distinctUntilChanged(), debounceTime(this.config().searchInputDebounceTime))
1085
+ .subscribe(term => this.currentSearchRequestService.setDescription(term));
1086
+ this.addSubscriptions(searchSub);
1087
+ }
1088
+ search() {
1089
+ this.currentSearchRequestService.patchSearchRequest({
1090
+ filters: FilterTools.convertToRequestFilter(this.activeFilters(), this.config().filterFields, this.config().columns)
1091
+ });
1092
+ this.currentSearchRequestService.triggerSearch();
1093
+ }
1094
+ toggleFilterSection() {
1095
+ if (this.activeFilters().length === 0) {
1096
+ this.addEmptyFilterRow();
1097
+ }
1098
+ this.isFilterSectionOpen.update(isOpen => !isOpen);
1099
+ }
1100
+ onRowRemoved() {
1101
+ if (this.activeFilters().length === 0) {
1102
+ this.isFilterSectionOpen.set(false);
1103
+ }
1104
+ this.search();
1105
+ }
1106
+ addEmptyFilterRow() {
1107
+ this.currentSearchRequestService.addFilter({});
1108
+ }
1109
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SearchSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1110
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: SearchSectionComponent, isStandalone: false, selector: "upd-search-section", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, actionsTpl: { classPropertyName: "actionsTpl", publicName: "actionsTpl", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.wrapperClass" } }, usesInheritance: true, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table'\">\n @if (!!actionsTpl()) {\n <ng-template [ngTemplateOutlet]=\"actionsTpl()!\"></ng-template>\n }\n\n <div class=\"d-flex align-items-center gap-2\">\n <upd-input wrapperClasses=\"w-100\" [placeholder]=\"{text:'UpDevs.Table.Search', isTranslated:false}\"\n [isAppendButton]=\"true\" (valueChange)=\"searchSubject.next($event)\"\n [value]=\"currentSearchRequestService.searchRequest().description\">\n <ng-template updInputAppend>\n <upd-button [isIcon]=\"true\" [colorStyle]=\"filterSectionBtnColor()\" (clicked)=\"toggleFilterSection()\"\n [badgeConfig]=\"badgeConfig()\">\n <upd-icon [tablerIcon]=\"isFilterSectionOpen() ? 'filter-up' : 'filter-down'\"\n [tablerIconSize]=\"20\"></upd-icon>\n </upd-button>\n </ng-template>\n </upd-input>\n </div>\n\n @if (isFilterSectionOpen()) {\n @for (row of activeFilters(); track row.name; let i = $index) {\n <upd-filter-row [store]=\"config().store\" [currentFilter]=\"row\" [columns]=\"columns()\" [rowIndex]=\"i\"\n (removed)=\"onRowRemoved()\" [isDisabled]=\"currentSearchRequestService.isSearching()\"\n [filterFields]=\"config().filterFields\">\n </upd-filter-row>\n }\n\n <div class=\"ms-auto d-flex gap-2\">\n <upd-button customClasses=\"gap-2\" colorStyle=\"primary\" [isOutline]=\"true\" (clicked)=\"addEmptyFilterRow()\"\n [isDisabled]=\"!canPerformActions()\">\n <upd-icon tablerIcon=\"plus\" tablerIconWeight=\"bold\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('AddNewFilter') }}\n </upd-button>\n <upd-button customClasses=\"gap-2\" colorStyle=\"success\" [isDisabled]=\"!canPerformActions()\"\n (clicked)=\"search()\">\n <upd-icon tablerIcon=\"checks\" tablerIconWeight=\"bold\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('ApplyFilters') }}\n </upd-button>\n </div>\n }\n</ng-container>", styles: [""], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: i3.IconComponent, selector: "upd-icon", inputs: ["model", "wrapperClasses", "color", "colorClass", "removeDefaultClasses", "customClasses", "tablerIcon", "tablerIconWeight", "tablerIconType", "tablerIconSize", "heroIcon", "heroIconSize", "heroIconType"] }, { kind: "component", type: i4.ButtonComponent, selector: "upd-button", inputs: ["model", "text", "brandColorStyle", "customClasses", "isOutline", "isGhost", "isSquare", "isPill", "isIcon", "isLoading", "isList", "isFloating", "isAction", "isNavigationLink", "isLink", "shouldIgnoreBtnClass", "iconModel", "iconPosition", "isDisabled", "isActive", "badgeConfig", "colorStyle", "size", "title", "stopPropagation"], outputs: ["clicked"] }, { kind: "component", type: i5.InputComponent, selector: "upd-input", inputs: ["type", "mask", "maskConfig", "value", "size", "customClasses", "wrapperClasses", "maxLength", "isPlainText", "isReadOnly", "isLoading", "isRound", "isFlush", "isInputGroupFlat", "isPrependButton", "isAppendButton", "isFloating", "loaderPosition", "prependIconModel", "appendIconModel", "isValidationStatusLight", "layout"], outputs: ["valueChange", "blurred", "keyDown", "keyDownEsc", "keyUpEnter"] }, { kind: "directive", type: i5.InputAppendDirective, selector: "ng-template[updInputAppend]" }, { kind: "component", type: FilterRowComponent, selector: "upd-filter-row", inputs: ["rowIndex", "columns", "isDisabled", "store", "filterFields", "currentFilter"], outputs: ["removed"] }] }); }
1111
+ }
1112
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: SearchSectionComponent, decorators: [{
1113
+ type: Component,
1114
+ args: [{ standalone: false, selector: 'upd-search-section', template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table'\">\n @if (!!actionsTpl()) {\n <ng-template [ngTemplateOutlet]=\"actionsTpl()!\"></ng-template>\n }\n\n <div class=\"d-flex align-items-center gap-2\">\n <upd-input wrapperClasses=\"w-100\" [placeholder]=\"{text:'UpDevs.Table.Search', isTranslated:false}\"\n [isAppendButton]=\"true\" (valueChange)=\"searchSubject.next($event)\"\n [value]=\"currentSearchRequestService.searchRequest().description\">\n <ng-template updInputAppend>\n <upd-button [isIcon]=\"true\" [colorStyle]=\"filterSectionBtnColor()\" (clicked)=\"toggleFilterSection()\"\n [badgeConfig]=\"badgeConfig()\">\n <upd-icon [tablerIcon]=\"isFilterSectionOpen() ? 'filter-up' : 'filter-down'\"\n [tablerIconSize]=\"20\"></upd-icon>\n </upd-button>\n </ng-template>\n </upd-input>\n </div>\n\n @if (isFilterSectionOpen()) {\n @for (row of activeFilters(); track row.name; let i = $index) {\n <upd-filter-row [store]=\"config().store\" [currentFilter]=\"row\" [columns]=\"columns()\" [rowIndex]=\"i\"\n (removed)=\"onRowRemoved()\" [isDisabled]=\"currentSearchRequestService.isSearching()\"\n [filterFields]=\"config().filterFields\">\n </upd-filter-row>\n }\n\n <div class=\"ms-auto d-flex gap-2\">\n <upd-button customClasses=\"gap-2\" colorStyle=\"primary\" [isOutline]=\"true\" (clicked)=\"addEmptyFilterRow()\"\n [isDisabled]=\"!canPerformActions()\">\n <upd-icon tablerIcon=\"plus\" tablerIconWeight=\"bold\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('AddNewFilter') }}\n </upd-button>\n <upd-button customClasses=\"gap-2\" colorStyle=\"success\" [isDisabled]=\"!canPerformActions()\"\n (clicked)=\"search()\">\n <upd-icon tablerIcon=\"checks\" tablerIconWeight=\"bold\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('ApplyFilters') }}\n </upd-button>\n </div>\n }\n</ng-container>" }]
1115
+ }], ctorParameters: () => [], propDecorators: { wrapperClass: [{
1116
+ type: HostBinding,
1117
+ args: ['class']
1118
+ }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], actionsTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsTpl", required: false }] }] } });
1119
+
1120
+ var Utils = Tools.Utils;
1121
+ class TableComponent extends BaseComponent {
1122
+ get numberOfColumns() {
1123
+ return this.columns().length
1124
+ + (this.configModel().hasCheckboxColumn ? 1 : 0)
1125
+ + (this.configModel().customActions.length > 0 ? 1 : 0)
1126
+ + (!!this.pendingWidthColClass ? 1 : 0);
1127
+ }
1128
+ get hasWidth() {
1129
+ return this.columns().some(rec => !!rec.width);
1130
+ }
1131
+ get pendingWidthColClass() {
1132
+ if (!this.hasWidth || this.isWidthInPixels) {
1133
+ return '';
1134
+ }
1135
+ const isGrid = this.columns().some(rec => !!rec.width?.gridColumn);
1136
+ const total = isGrid ? 12 : 100;
1137
+ const remainingSize = total - this.columns().reduce((acc, item) => acc + item.widthSize, 0);
1138
+ // TODO: add spaces of checkbox and customactions columns
1139
+ return remainingSize > 0 ? `${(isGrid ? 'col' : 'w')}-${remainingSize}` : '';
1140
+ }
1141
+ get isWidthInPixels() {
1142
+ return this.columns().some(rec => !!rec.width?.pixels);
1143
+ }
1144
+ get isRemote() {
1145
+ return !!this.configModel().store;
1146
+ }
1147
+ get store() {
1148
+ return this.configModel().store;
1149
+ }
1150
+ constructor() {
1151
+ super();
1152
+ this.savedViewsRef = viewChild('savedViewsBtn', { ...(ngDevMode ? { debugName: "savedViewsRef" } : {}), read: ElementRef });
1153
+ this.config = model.required(...(ngDevMode ? [{ debugName: "config" }] : []));
1154
+ this.selectedItems = computed(() => this.selectionModel().selected(), ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
1155
+ this.activeSavedView = signal(undefined, ...(ngDevMode ? [{ debugName: "activeSavedView" }] : []));
1156
+ this.isMainCheckboxChecked = false;
1157
+ this.isMainCheckboxIndeterminate = false;
1158
+ this.isSavedViewsDropdownOpen = false;
1159
+ this.currentPage = model(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
1160
+ this.pageSize = model(0, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
1161
+ this.totalRecords = signal(0, ...(ngDevMode ? [{ debugName: "totalRecords" }] : []));
1162
+ this.configModel = computed(() => new TableConfigModel(this.config()), ...(ngDevMode ? [{ debugName: "configModel" }] : []));
1163
+ this.data = computed(() => this.configModel().data.length > 0 ? this.configModel().data : this.currentData(), ...(ngDevMode ? [{ debugName: "data" }] : []));
1164
+ this.selectionModel = computed(() => new SelectionModel(this.configModel().getIdFunction), ...(ngDevMode ? [{ debugName: "selectionModel" }] : []));
1165
+ this.currentSorting = signal(undefined, ...(ngDevMode ? [{ debugName: "currentSorting" }] : []));
1166
+ this.hiddenColumns = computed(() => this.configModel().canManageColumns ? this.configModel().columns.filter(c => c.isHidden).length : 0, ...(ngDevMode ? [{ debugName: "hiddenColumns" }] : []));
1167
+ this.columns = signal([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
1168
+ this.textService = inject(TextService);
1169
+ this.currentSearchRequestService = inject(CurrentSearchRequestService);
1170
+ this.savedViewsOptions = computed(() => {
1171
+ const allSavedViewsOptions = [];
1172
+ this.allSavedViews().forEach(sv => allSavedViewsOptions.push(this.getSavedViewOption(sv)));
1173
+ return allSavedViewsOptions;
1174
+ }, ...(ngDevMode ? [{ debugName: "savedViewsOptions" }] : []));
1175
+ this.shouldForceSearch = false;
1176
+ this.columnsBackup = [];
1177
+ this.currentData = signal([], ...(ngDevMode ? [{ debugName: "currentData" }] : []));
1178
+ this.currentFavoriteButtons = computed(() => this.favoriteButtons, ...(ngDevMode ? [{ debugName: "currentFavoriteButtons" }] : []));
1179
+ this.smallSizeSignal = signal('small', ...(ngDevMode ? [{ debugName: "smallSizeSignal" }] : []));
1180
+ this.allSavedViews = computed(() => this.savedViewsStorage.getAll(this.configModel().name)(), ...(ngDevMode ? [{ debugName: "allSavedViews" }] : []));
1181
+ this.favoriteButtons = [];
1182
+ this.serverResponseService = inject(ServerResponseService);
1183
+ this.savedViewsStorage = inject(SavedViewsStorage);
1184
+ this.modalService = inject(ModalService);
1185
+ this.modalAlertService = inject(ModalAlertService);
1186
+ effect(() => {
1187
+ if (this.data().length > 0 && this.configModel().data.length > 0) {
1188
+ this.setupPreSelected();
1189
+ }
1190
+ if (this.selectedItems().length > 0) {
1191
+ if (this.selectedItems().length !== this.data().length) {
1192
+ this.isMainCheckboxChecked = false;
1193
+ this.isMainCheckboxIndeterminate = true;
1194
+ }
1195
+ else {
1196
+ this.isMainCheckboxIndeterminate = false;
1197
+ this.isMainCheckboxChecked = true;
1198
+ }
1199
+ }
1200
+ else {
1201
+ this.isMainCheckboxChecked = false;
1202
+ this.isMainCheckboxIndeterminate = false;
1203
+ }
1204
+ });
1205
+ }
1206
+ ngOnInit() {
1207
+ this.columnsBackup = [...this.config().columns];
1208
+ const searchSubjectSub = this.currentSearchRequestService.searchRequestSubject
1209
+ .pipe(distinctUntilChanged((prev, curr) => !this.shouldForceSearch ? Utils.areEqual(prev, curr) : false), tap((request) => {
1210
+ this.currentSearchRequestService.setSearching(true);
1211
+ this.currentData.set([]);
1212
+ this.currentSearchRequestService.updateSearchRequest(request);
1213
+ }), switchMap(() => this.store.search(this.currentSearchRequestService.searchRequest()).pipe(catchError(() => of()) // Already handled by the ServerResponseService.
1214
+ )), finalize(() => this.shouldForceSearch = false))
1215
+ .subscribe(resp => this.setupSearchResults(resp));
1216
+ const serverResponseSub = this.serverResponseService.onError.subscribe(error => {
1217
+ if (!!error) {
1218
+ this.currentSearchRequestService.setSearching(false);
1219
+ }
1220
+ });
1221
+ if (this.configModel().shouldAutoSearch && this.isRemote) {
1222
+ this.shouldForceSearch = true;
1223
+ this.currentSearchRequestService.searchRequestSubject.next({});
1224
+ }
1225
+ this.updateColumns(this.configModel().columns);
1226
+ this.addSubscriptions(searchSubjectSub, serverResponseSub);
1227
+ }
1228
+ toggleAllSelection(isChecked) {
1229
+ if (isChecked) {
1230
+ this.selectionModel().select(...this.currentData());
1231
+ }
1232
+ else {
1233
+ this.selectionModel().clearSelection();
1234
+ }
1235
+ }
1236
+ toggleItemSelection(record) {
1237
+ if (this.selectionModel().isSelected(record)) {
1238
+ this.selectionModel().deselect(record);
1239
+ }
1240
+ else {
1241
+ this.selectionModel().select(record);
1242
+ }
1243
+ }
1244
+ canSortColumn(columnName) {
1245
+ return this.getColumnByName(columnName).allowSort;
1246
+ }
1247
+ sortByColumn(columnName) {
1248
+ const currentSort = this.currentSorting();
1249
+ const nextDirection = (currentSort?.column === columnName && currentSort.direction === SortDirectionEnum.Asc)
1250
+ ? SortDirectionEnum.Desc
1251
+ : SortDirectionEnum.Asc;
1252
+ this.currentSorting.set(new ColumnSort({
1253
+ column: columnName,
1254
+ direction: nextDirection
1255
+ }));
1256
+ if (this.isRemote) {
1257
+ this.currentSearchRequestService.setSorting(columnName, nextDirection);
1258
+ this.currentSearchRequestService.triggerSearch();
1259
+ }
1260
+ else {
1261
+ const col = this.getColumnByName(columnName);
1262
+ // TODO: local sort
1263
+ }
1264
+ }
1265
+ getSortingIcon(columnName) {
1266
+ return !!this.currentSorting() && this.currentSorting().column === columnName
1267
+ ? (this.currentSorting().direction === SortDirectionEnum.Asc ? 'sort-ascending' : 'sort-descending')
1268
+ : 'arrows-sort';
1269
+ }
1270
+ onPageSettingsChanged() {
1271
+ this.currentSearchRequestService.patchSearchRequest({
1272
+ pageSize: this.pageSize(),
1273
+ pageIndex: this.currentPage()
1274
+ });
1275
+ this.currentSearchRequestService.searchRequestSubject.next(this.currentSearchRequestService.searchRequest());
1276
+ }
1277
+ getRecordId(record) {
1278
+ return this.configModel().getIdFunction(record);
1279
+ }
1280
+ openColumnsManagerModal() {
1281
+ const ref = this.modalService.open(undefined, {
1282
+ bodyContentType: ColumnsManagerComponent,
1283
+ showCloseButton: false,
1284
+ showCancelButton: true,
1285
+ data: this.config(),
1286
+ isTextCentered: false,
1287
+ actionButtons: [
1288
+ new ButtonModel({
1289
+ text: signal({ text: 'UpDevs.Table.ColumnsManager.Apply', isTranslated: false }),
1290
+ colorStyle: signal('primary'),
1291
+ iconModel: signal({ tablerIcon: 'checks' }),
1292
+ clickFunction: () => ref.close()
1293
+ })
1294
+ ]
1295
+ });
1296
+ ref.afterClose = () => {
1297
+ const result = ref.getBodyInstance()?.columns();
1298
+ if (!!result) {
1299
+ const previousVisibleColumnsOrder = this.columns().map(c => c.name);
1300
+ const visibleColumnsNames = result.find(c => c.name === 'visible')?.items().map(i => i.name) || [];
1301
+ const newColumns = [];
1302
+ this.config.update(config => {
1303
+ visibleColumnsNames.forEach(name => {
1304
+ const col = config.columns.find(c => c.name === name);
1305
+ col.isHidden = false;
1306
+ newColumns.push(col);
1307
+ });
1308
+ config.columns.forEach(c => {
1309
+ if (!visibleColumnsNames.includes(c.name)) {
1310
+ c.isHidden = true;
1311
+ newColumns.push(c);
1312
+ }
1313
+ });
1314
+ return { ...config, columns: [...newColumns] };
1315
+ });
1316
+ this.updateColumns(newColumns);
1317
+ const newVisibleColumnsOrder = newColumns.map(c => c.name);
1318
+ // Column visibility changes should enable "Save View" button since views include column config
1319
+ if (previousVisibleColumnsOrder.length !== newVisibleColumnsOrder.length
1320
+ || !previousVisibleColumnsOrder.every((v, i) => v === newVisibleColumnsOrder[i])) {
1321
+ // Manually trigger hasChanges since column visibility isn't part of search request
1322
+ this.currentSearchRequestService.setHasChanges(true);
1323
+ }
1324
+ }
1325
+ };
1326
+ }
1327
+ openSaveSearchModal(data) {
1328
+ data = data || {
1329
+ tableName: this.configModel().name,
1330
+ request: this.currentSearchRequestService.searchRequest(),
1331
+ columns: this.configModel().columns
1332
+ };
1333
+ this.modalService.open(SaveSearchComponent, { showCloseButton: false, data });
1334
+ }
1335
+ selectSavedView(item) {
1336
+ const savedView = this.savedViewsStorage.getById(this.configModel().name, item.id)();
1337
+ this.isSavedViewsDropdownOpen = false;
1338
+ if (!!savedView) {
1339
+ this.updateColumns(savedView.columns);
1340
+ this.config.update(curr => {
1341
+ curr.columns = savedView.columns;
1342
+ return { ...curr };
1343
+ });
1344
+ this.activeSavedView.set(savedView);
1345
+ this.currentSearchRequestService.searchRequestSubject.next({ ...savedView.request });
1346
+ }
1347
+ }
1348
+ resetViewState() {
1349
+ this.activeSavedView.set(undefined);
1350
+ this.updateColumns(this.columnsBackup);
1351
+ this.config.update(curr => {
1352
+ curr.columns = this.columnsBackup;
1353
+ return { ...curr };
1354
+ });
1355
+ this.currentSearchRequestService.searchRequestSubject.next({});
1356
+ }
1357
+ reload() {
1358
+ this.shouldForceSearch = true;
1359
+ this.currentSearchRequestService.searchRequestSubject.next({});
1360
+ }
1361
+ adaptCustomAction(btn, item) {
1362
+ const newBtn = new ButtonModel({
1363
+ id: btn.id,
1364
+ iconModel: btn.iconModel,
1365
+ title: btn.title,
1366
+ isIcon: signal(true),
1367
+ isLink: signal(true),
1368
+ size: signal('small'),
1369
+ text: undefined,
1370
+ colorStyle: btn.colorStyle,
1371
+ isOutline: btn.isOutline
1372
+ });
1373
+ const defaultFunction = btn.clickFunction;
1374
+ newBtn.clickFunction = (evt) => {
1375
+ evt.event?.preventDefault();
1376
+ evt.event?.stopPropagation();
1377
+ if (!!defaultFunction) {
1378
+ defaultFunction({ event: evt.event, data: item });
1379
+ }
1380
+ };
1381
+ return newBtn;
1382
+ }
1383
+ updateColumns(columns) {
1384
+ this.columns.set(columns.filter(c => !c.isHidden).map(c => this.createColumnModel(c)));
1385
+ }
1386
+ createColumnModel(data) {
1387
+ switch (data.type) {
1388
+ case ColumnTypeEnum.Text:
1389
+ return new TextColumnModel({ ...data });
1390
+ case ColumnTypeEnum.Number:
1391
+ return new NumberColumnModel({ ...data });
1392
+ case ColumnTypeEnum.Boolean:
1393
+ return new BooleanColumnModel({ ...data });
1394
+ case ColumnTypeEnum.DateTime:
1395
+ case ColumnTypeEnum.Date:
1396
+ case ColumnTypeEnum.Time:
1397
+ return new DateTimeColumnModel({ ...data });
1398
+ case ColumnTypeEnum.Image:
1399
+ return new ImageColumnModel({ ...data });
1400
+ case ColumnTypeEnum.Guid:
1401
+ return new GuidColumnModel({ ...data });
1402
+ case ColumnTypeEnum.Masked:
1403
+ case ColumnTypeEnum.Custom:
1404
+ case ColumnTypeEnum.Currency:
1405
+ default:
1406
+ return new BaseColumnModel(data.type, { ...data });
1407
+ }
1408
+ }
1409
+ getColumnByName(columnName) {
1410
+ const col = this.columns().find(c => c.name === columnName);
1411
+ if (!col) {
1412
+ throw Error('Tried accessing non existing column');
1413
+ }
1414
+ return col;
1415
+ }
1416
+ setupPreSelected() {
1417
+ this.configModel().preSelectedItems.forEach(item => {
1418
+ const id = this.getRecordId(item);
1419
+ if (this.data().find(d => this.getRecordId(d) === id) && !this.selectionModel().isSelected(item)) {
1420
+ this.selectionModel().select(item);
1421
+ }
1422
+ });
1423
+ }
1424
+ setupSearchResults(resp) {
1425
+ this.currentSearchRequestService.setSearching(false);
1426
+ this.currentSearchRequestService.setHasChanges(false);
1427
+ this.currentData.set(resp.records);
1428
+ this.totalRecords.set(resp.totalRecords || 0);
1429
+ this.currentPage.set(resp.pageIndex || 0);
1430
+ this.pageSize.set(resp.pageSize || 0);
1431
+ this.setupPreSelected();
1432
+ }
1433
+ getActionButtons(currentFavoriteButtons, savedView) {
1434
+ return [
1435
+ new ButtonModel({
1436
+ isIcon: signal(true),
1437
+ isGhost: signal(true),
1438
+ colorStyle: signal('primary'),
1439
+ size: this.smallSizeSignal,
1440
+ title: signal({ text: 'UpDevs.Table.SavedViews.MarkAsDefault', isTranslated: false }),
1441
+ isActive: signal(savedView.isDefault || false),
1442
+ iconModel: signal({ tablerIcon: 'heart' }),
1443
+ clickFunction: (evt) => {
1444
+ const btnModel = evt.data;
1445
+ const isButtonActive = btnModel.button.isActive();
1446
+ if (!isButtonActive) {
1447
+ this.savedViewsStorage.resetAllIsDefault(this.configModel().name);
1448
+ }
1449
+ savedView.isDefault = !isButtonActive;
1450
+ currentFavoriteButtons().forEach(cfb => cfb.isActive.set(false));
1451
+ btnModel.button.isActive.set(!isButtonActive);
1452
+ this.savedViewsStorage.saveView(savedView);
1453
+ }
1454
+ }),
1455
+ new ButtonModel({
1456
+ isIcon: signal(true),
1457
+ isGhost: signal(true),
1458
+ colorStyle: signal('secondary'),
1459
+ size: this.smallSizeSignal,
1460
+ title: signal({ text: 'UpDevs.Table.SavedViews.Duplicate', isTranslated: false }),
1461
+ iconModel: signal({ tablerIcon: 'copy' }),
1462
+ clickFunction: () => {
1463
+ const duplicateView = {
1464
+ ...savedView,
1465
+ id: Tools.Guid.generate(),
1466
+ name: savedView.name +
1467
+ ` (${this.textService.getText({ text: 'UpDevs.Table.SavedViews.DuplicateSuffix', isTranslated: false })})`
1468
+ };
1469
+ this.openSaveSearchModal(duplicateView);
1470
+ }
1471
+ }),
1472
+ new ButtonModel({
1473
+ isIcon: signal(true),
1474
+ isGhost: signal(true),
1475
+ colorStyle: signal('secondary'),
1476
+ size: this.smallSizeSignal,
1477
+ title: signal({ text: 'UpDevs.Table.SavedViews.Edit', isTranslated: false }),
1478
+ iconModel: signal({ tablerIcon: 'edit' }),
1479
+ clickFunction: () => this.openSaveSearchModal(savedView)
1480
+ }),
1481
+ new ButtonModel({
1482
+ isIcon: signal(true),
1483
+ isGhost: signal(true),
1484
+ colorStyle: signal('danger'),
1485
+ size: this.smallSizeSignal,
1486
+ title: signal({ text: 'UpDevs.Table.SavedViews.Remove', isTranslated: false }),
1487
+ iconModel: signal({ tablerIcon: 'x' }),
1488
+ clickFunction: () => {
1489
+ const title = this.textService.getText({ text: 'UpDevs.Table.SavedViews.ConfirmRemove', isTranslated: false }, { view: savedView.name });
1490
+ this.modalAlertService.showConfirm({ text: title, isTranslated: true }).subscribe(isConfirmed => {
1491
+ if (isConfirmed) {
1492
+ this.savedViewsStorage.removeViews(this.configModel().name, savedView.id);
1493
+ }
1494
+ });
1495
+ }
1496
+ })
1497
+ ];
1498
+ }
1499
+ getSavedViewOption(savedView) {
1500
+ const actionButtons = this.getActionButtons(this.currentFavoriteButtons, savedView);
1501
+ this.favoriteButtons.push(actionButtons.find(ab => ab.iconModel?.().tablerIcon === 'heart'));
1502
+ return {
1503
+ id: savedView.id,
1504
+ type: 'with-toolbar',
1505
+ text: { text: savedView.name, isTranslated: true },
1506
+ toolbarType: 'spaced',
1507
+ isActive: this.activeSavedView()?.id === savedView.id,
1508
+ actionButtons
1509
+ };
1510
+ }
1511
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1512
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: TableComponent, isStandalone: false, selector: "upd-table", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { config: "configChange", currentPage: "currentPageChange", pageSize: "pageSizeChange" }, providers: [CurrentSearchRequestService], viewQueries: [{ propertyName: "savedViewsRef", first: true, predicate: ["savedViewsBtn"], descendants: true, read: ElementRef, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table'\">\n <div class=\"card\">\n @if (!!configModel().title || !configModel().canSearch) {\n <div class=\"card-header\">\n @if (!!configModel().title) {\n <h3 class=\"card-title\">{{ textService.getText(configModel().title) }}</h3>\n }\n <ng-template [ngTemplateOutlet]=\"actionsTpl\"></ng-template>\n </div>\n }\n\n @if (configModel().customHeaderActions.length > 0) {\n <div class=\"card-body py-3 d-flex flex-column gap-2\">\n <div class=\"ms-auto d-flex gap-2\">\n @for (btn of configModel().customHeaderActions; track btn) {\n <upd-button customClasses=\"gap-2\" [model]=\"btn\"></upd-button>\n }\n </div>\n </div>\n }\n\n @if (configModel().canSearch) {\n <upd-search-section [actionsTpl]=\"!configModel().title ? actionsTpl : undefined\" [config]=\"configModel()\"\n [columns]=\"columns()\">\n </upd-search-section>\n }\n\n <div [class.table-responsive]=\"configModel().isResponsive\">\n <!-- TODO: implement pixel sized table -->\n <table class=\"table card-table table-vcenter table-nowrap\" [class.fixed]=\"hasWidth\"\n [class.pixel-sized]=\"isWidthInPixels\">\n <thead [class.sticky-top]=\"configModel().hasStickyHeader\">\n <tr>\n @if (configModel().hasCheckboxColumn) {\n <th class=\"checkbox-selector\">\n <upd-checkbox customClasses=\"m-0 ps-0\" (changed)=\"toggleAllSelection($event)\"\n [(isChecked)]=\"isMainCheckboxChecked\"\n [(isIndeterminate)]=\"isMainCheckboxIndeterminate\"></upd-checkbox>\n </th>\n }\n\n @for (col of columns(); track col) {\n <th [ngClass]=\"col.widthClass\" [style.width.px]=\"col.pixelsSize\">\n {{ textService.getText(col.title) }}\n @if (canSortColumn(col.name)) {\n <upd-icon [tablerIcon]=\"getSortingIcon(col.name)\" tablerIconWeight=\"bold\"\n colorClass=\"text-body-tertiary\" [tablerIconSize]=\"16\"\n (click)=\"sortByColumn(col.name)\">\n </upd-icon>\n }\n </th>\n }\n\n @if (!!pendingWidthColClass) {\n <th [ngClass]=\"pendingWidthColClass\"></th>\n }\n\n @if (configModel().customActions.length > 0) {\n <th class=\"custom-actions\"></th>\n }\n </tr>\n </thead>\n\n <tbody>\n @if (currentSearchRequestService.isSearching()) {\n <tr>\n <td [colSpan]=\"numberOfColumns\">\n <div class=\"empty\">\n <h1 class=\"text-body-tertiary\">{{ t('Loading') }}...</h1>\n <div class=\"progress progress-sm w-25\">\n <div class=\"progress-bar progress-bar-indeterminate bg-body-tertiary\"></div>\n </div>\n </div>\n </td>\n </tr>\n } @else {\n @for (record of data(); track record) {\n <tr>\n @if (configModel().hasCheckboxColumn) {\n <td class=\"checkbox-selector\">\n <upd-checkbox customClasses=\"m-0 ps-0\" (changed)=\"toggleItemSelection(record)\"\n [isChecked]=\"selectionModel().isSelected(record)\"></upd-checkbox>\n </td>\n }\n\n @for (col of columns(); track col) {\n <td [style.width.px]=\"col.pixelsSize\">\n <ng-container updTableColumn [record]=\"record\" [config]=\"col\"></ng-container>\n </td>\n }\n\n @if (!!pendingWidthColClass) {\n <td></td>\n }\n\n @if (configModel().customActions.length > 0) {\n <td style=\"overflow: unset\">\n <div class=\"grow-left d-flex\">\n @if (configModel().customActions.length > 1) {\n <upd-button customClasses=\"ca-item\" [iconModel]=\"{tablerIcon:'dots'}\"\n [isIcon]=\"true\" [isLink]=\"true\" size=\"small\"></upd-button>\n\n <div class=\"ca-dropdown-content rounded shadow-sm\">\n @for (btn of configModel().customActions; track btn) {\n <upd-button\n [model]=\"adaptCustomAction(btn, record)\"></upd-button>\n }\n </div>\n } @else {\n <upd-button\n [model]=\"adaptCustomAction(configModel().customActions[0], record)\">\n </upd-button>\n }\n </div>\n </td>\n }\n </tr>\n } @empty {\n <tr>\n <td [colSpan]=\"numberOfColumns\">\n <div class=\"empty\">\n <p class=\"empty-title\">{{ t('NoRecordsFoundTitle') }}</p>\n <p class=\"empty-subtitle text-secondary\">{{ t('NoRecordsFoundSubtitle') }}</p>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n <upd-paginator wrapperClasses=\"card-footer\" [shouldDisplayPreviousText]=\"false\" [shouldDisplayNextText]=\"false\"\n [(pageSize)]=\"pageSize\" [shouldDisplayFirstText]=\"false\" [shouldDisplayLastText]=\"false\"\n [(currentPage)]=\"currentPage\" [totalRecords]=\"totalRecords()\" (changed)=\"onPageSettingsChanged()\">\n </upd-paginator>\n </div>\n\n <ng-template #actionsTpl>\n <div class=\"ms-auto d-flex gap-2\">\n @if (!!activeSavedView()) {\n @if (activeSavedView()!.isDefault) {\n <div class=\"ribbon ribbon-top ribbon-start\">\n <upd-icon tablerIcon=\"heart\" [tablerIconSize]=\"20\"></upd-icon>\n </div>\n }\n <div class=\"tag align-self-center py-3 text-primary bg-primary-lt border-primary\"\n updPopover=\"{{ t('CurrentSavedView') }}\" [updPopoverActAsTooltip]=\"true\">\n <upd-icon tablerIcon=\"list-details\" [tablerIconSize]=\"20\"></upd-icon>\n <span class=\"me-1\">{{ activeSavedView()!.name }}</span>\n </div>\n }\n @if (hiddenColumns() > 0) {\n <div class=\"tag align-self-center py-3 text-orange bg-orange-lt border-orange\"\n updPopover=\"{{ t('HiddenColumnsTooltip') }}\" [updPopoverActAsTooltip]=\"true\">\n <upd-icon tablerIcon=\"eye-off\" [tablerIconSize]=\"20\"></upd-icon>\n <span class=\"me-1\">{{ hiddenColumns() }}</span>\n </div>\n }\n @if (!!activeSavedView() || hiddenColumns() > 0) {\n <upd-button (clicked)=\"resetViewState()\" colorStyle=\"danger\" updPopover=\"{{ t('ResetView') }}\"\n [updPopoverActAsTooltip]=\"true\" [isIcon]=\"true\" [isOutline]=\"true\">\n <upd-icon tablerIcon=\"restore\" [tablerIconSize]=\"20\"></upd-icon>\n </upd-button>\n }\n @if (configModel().canSaveViews) {\n <upd-button customClasses=\"gap-2\" [isDisabled]=\"!currentSearchRequestService.hasChanges()\"\n (clicked)=\"openSaveSearchModal()\" updPopover=\"{{ t('SaveCurrentView') }}\"\n [updPopoverActAsTooltip]=\"true\" [isIcon]=\"true\">\n <upd-icon tablerIcon=\"device-floppy\" [tablerIconSize]=\"20\"></upd-icon>\n </upd-button>\n }\n @if (configModel().canManageColumns) {\n <upd-button customClasses=\"gap-2\" (clicked)=\"openColumnsManagerModal()\">\n <upd-icon tablerIcon=\"columns\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('ColumnsManagerButton') }}\n </upd-button>\n }\n @if (configModel().canSaveViews || configModel().canLoadSavedViews) {\n <upd-button customClasses=\"gap-2\" (clicked)=\"isSavedViewsDropdownOpen = true\" #savedViewsBtn>\n <upd-icon tablerIcon=\"folders\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('SavedViews.ButtonTitle') }}\n </upd-button>\n <upd-dropdown wrapperClasses=\"overflow-x-hidden mt-1\" [isOpen]=\"isSavedViewsDropdownOpen\"\n [dropdownReference]=\"savedViewsRef()\" [items]=\"savedViewsOptions()\"\n [shouldCloseOnOutsideClick]=\"true\" (isOpenChange)=\"isSavedViewsDropdownOpen = $event\"\n [minWidth]=\"350\" (selectedItem)=\"selectSavedView($event)\">\n @if (savedViewsOptions().length < 1) {\n <span class=\"m-2\">{{ t('NoSavedViews') }}</span>\n }\n </upd-dropdown>\n }\n </div>\n </ng-template>\n</ng-container>", styles: [".fixed{table-layout:fixed!important}.fixed td,.fixed th{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.checkbox-selector{width:52px!important}.custom-actions{width:56px!important}.ca-item{transition:all,.5s}.ca-item:hover{width:400px}.grow-left{direction:rtl}.ca-dropdown-content{display:none;background:var(--upd-secondary-lt)}.grow-left:hover .ca-dropdown-content{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: i3.IconComponent, selector: "upd-icon", inputs: ["model", "wrapperClasses", "color", "colorClass", "removeDefaultClasses", "customClasses", "tablerIcon", "tablerIconWeight", "tablerIconType", "tablerIconSize", "heroIcon", "heroIconSize", "heroIconType"] }, { kind: "component", type: i4.ButtonComponent, selector: "upd-button", inputs: ["model", "text", "brandColorStyle", "customClasses", "isOutline", "isGhost", "isSquare", "isPill", "isIcon", "isLoading", "isList", "isFloating", "isAction", "isNavigationLink", "isLink", "shouldIgnoreBtnClass", "iconModel", "iconPosition", "isDisabled", "isActive", "badgeConfig", "colorStyle", "size", "title", "stopPropagation"], outputs: ["clicked"] }, { kind: "component", type: i5$1.PaginatorComponent, selector: "upd-paginator", inputs: ["startPageIndex", "currentPage", "wrapperClasses", "availablePageSizes", "defaultInitPageSize", "pageSize", "shouldDisplayFirstIcon", "shouldDisplayFirstText", "shouldDisplayPreviousIcon", "shouldDisplayPreviousText", "shouldDisplayNextIcon", "shouldDisplayNextText", "shouldDisplayLastIcon", "shouldDisplayLastText", "previousDescription", "nextDescription", "totalRecords"], outputs: ["changed", "currentPageChange", "pageSizeChange"] }, { kind: "component", type: i6.CheckboxComponent, selector: "upd-checkbox", inputs: ["wrapperClasses", "value", "customClasses", "isChecked", "isInline", "isSwitch", "isIndeterminate"], outputs: ["changed", "isCheckedChange", "isIndeterminateChange"] }, { kind: "component", type: i7.DropdownComponent, selector: "upd-dropdown", inputs: ["items", "header", "isOpen", "shouldCloseOnOutsideClick", "arrowType", "wrapperClasses", "elementsExcludedFromOutsideClick", "minHeight", "maxHeight", "minWidth", "maxWidth", "dropdownReference", "dropdownReferencePosition", "textOverflowStrategy"], outputs: ["isOpenChange", "selectedItem", "checkboxChanged"] }, { kind: "directive", type: i8.PopoverDirective, selector: "[updPopover]", inputs: ["updPopover", "updPopoverTitle", "updPopoverTitleTemplate", "updPopoverTemplate", "updPopoverPlacement", "updPopoverCustomClasses", "updPopoverActAsTooltip"] }, { kind: "component", type: SearchSectionComponent, selector: "upd-search-section", inputs: ["columns", "config", "actionsTpl"] }, { kind: "directive", type: TableColumnDirective, selector: "[updTableColumn]", inputs: ["record", "config"] }] }); }
1513
+ }
1514
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableComponent, decorators: [{
1515
+ type: Component,
1516
+ args: [{ standalone: false, selector: 'upd-table', providers: [CurrentSearchRequestService], template: "<ng-container *transloco=\"let t; prefix: 'UpDevs.Table'\">\n <div class=\"card\">\n @if (!!configModel().title || !configModel().canSearch) {\n <div class=\"card-header\">\n @if (!!configModel().title) {\n <h3 class=\"card-title\">{{ textService.getText(configModel().title) }}</h3>\n }\n <ng-template [ngTemplateOutlet]=\"actionsTpl\"></ng-template>\n </div>\n }\n\n @if (configModel().customHeaderActions.length > 0) {\n <div class=\"card-body py-3 d-flex flex-column gap-2\">\n <div class=\"ms-auto d-flex gap-2\">\n @for (btn of configModel().customHeaderActions; track btn) {\n <upd-button customClasses=\"gap-2\" [model]=\"btn\"></upd-button>\n }\n </div>\n </div>\n }\n\n @if (configModel().canSearch) {\n <upd-search-section [actionsTpl]=\"!configModel().title ? actionsTpl : undefined\" [config]=\"configModel()\"\n [columns]=\"columns()\">\n </upd-search-section>\n }\n\n <div [class.table-responsive]=\"configModel().isResponsive\">\n <!-- TODO: implement pixel sized table -->\n <table class=\"table card-table table-vcenter table-nowrap\" [class.fixed]=\"hasWidth\"\n [class.pixel-sized]=\"isWidthInPixels\">\n <thead [class.sticky-top]=\"configModel().hasStickyHeader\">\n <tr>\n @if (configModel().hasCheckboxColumn) {\n <th class=\"checkbox-selector\">\n <upd-checkbox customClasses=\"m-0 ps-0\" (changed)=\"toggleAllSelection($event)\"\n [(isChecked)]=\"isMainCheckboxChecked\"\n [(isIndeterminate)]=\"isMainCheckboxIndeterminate\"></upd-checkbox>\n </th>\n }\n\n @for (col of columns(); track col) {\n <th [ngClass]=\"col.widthClass\" [style.width.px]=\"col.pixelsSize\">\n {{ textService.getText(col.title) }}\n @if (canSortColumn(col.name)) {\n <upd-icon [tablerIcon]=\"getSortingIcon(col.name)\" tablerIconWeight=\"bold\"\n colorClass=\"text-body-tertiary\" [tablerIconSize]=\"16\"\n (click)=\"sortByColumn(col.name)\">\n </upd-icon>\n }\n </th>\n }\n\n @if (!!pendingWidthColClass) {\n <th [ngClass]=\"pendingWidthColClass\"></th>\n }\n\n @if (configModel().customActions.length > 0) {\n <th class=\"custom-actions\"></th>\n }\n </tr>\n </thead>\n\n <tbody>\n @if (currentSearchRequestService.isSearching()) {\n <tr>\n <td [colSpan]=\"numberOfColumns\">\n <div class=\"empty\">\n <h1 class=\"text-body-tertiary\">{{ t('Loading') }}...</h1>\n <div class=\"progress progress-sm w-25\">\n <div class=\"progress-bar progress-bar-indeterminate bg-body-tertiary\"></div>\n </div>\n </div>\n </td>\n </tr>\n } @else {\n @for (record of data(); track record) {\n <tr>\n @if (configModel().hasCheckboxColumn) {\n <td class=\"checkbox-selector\">\n <upd-checkbox customClasses=\"m-0 ps-0\" (changed)=\"toggleItemSelection(record)\"\n [isChecked]=\"selectionModel().isSelected(record)\"></upd-checkbox>\n </td>\n }\n\n @for (col of columns(); track col) {\n <td [style.width.px]=\"col.pixelsSize\">\n <ng-container updTableColumn [record]=\"record\" [config]=\"col\"></ng-container>\n </td>\n }\n\n @if (!!pendingWidthColClass) {\n <td></td>\n }\n\n @if (configModel().customActions.length > 0) {\n <td style=\"overflow: unset\">\n <div class=\"grow-left d-flex\">\n @if (configModel().customActions.length > 1) {\n <upd-button customClasses=\"ca-item\" [iconModel]=\"{tablerIcon:'dots'}\"\n [isIcon]=\"true\" [isLink]=\"true\" size=\"small\"></upd-button>\n\n <div class=\"ca-dropdown-content rounded shadow-sm\">\n @for (btn of configModel().customActions; track btn) {\n <upd-button\n [model]=\"adaptCustomAction(btn, record)\"></upd-button>\n }\n </div>\n } @else {\n <upd-button\n [model]=\"adaptCustomAction(configModel().customActions[0], record)\">\n </upd-button>\n }\n </div>\n </td>\n }\n </tr>\n } @empty {\n <tr>\n <td [colSpan]=\"numberOfColumns\">\n <div class=\"empty\">\n <p class=\"empty-title\">{{ t('NoRecordsFoundTitle') }}</p>\n <p class=\"empty-subtitle text-secondary\">{{ t('NoRecordsFoundSubtitle') }}</p>\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n <upd-paginator wrapperClasses=\"card-footer\" [shouldDisplayPreviousText]=\"false\" [shouldDisplayNextText]=\"false\"\n [(pageSize)]=\"pageSize\" [shouldDisplayFirstText]=\"false\" [shouldDisplayLastText]=\"false\"\n [(currentPage)]=\"currentPage\" [totalRecords]=\"totalRecords()\" (changed)=\"onPageSettingsChanged()\">\n </upd-paginator>\n </div>\n\n <ng-template #actionsTpl>\n <div class=\"ms-auto d-flex gap-2\">\n @if (!!activeSavedView()) {\n @if (activeSavedView()!.isDefault) {\n <div class=\"ribbon ribbon-top ribbon-start\">\n <upd-icon tablerIcon=\"heart\" [tablerIconSize]=\"20\"></upd-icon>\n </div>\n }\n <div class=\"tag align-self-center py-3 text-primary bg-primary-lt border-primary\"\n updPopover=\"{{ t('CurrentSavedView') }}\" [updPopoverActAsTooltip]=\"true\">\n <upd-icon tablerIcon=\"list-details\" [tablerIconSize]=\"20\"></upd-icon>\n <span class=\"me-1\">{{ activeSavedView()!.name }}</span>\n </div>\n }\n @if (hiddenColumns() > 0) {\n <div class=\"tag align-self-center py-3 text-orange bg-orange-lt border-orange\"\n updPopover=\"{{ t('HiddenColumnsTooltip') }}\" [updPopoverActAsTooltip]=\"true\">\n <upd-icon tablerIcon=\"eye-off\" [tablerIconSize]=\"20\"></upd-icon>\n <span class=\"me-1\">{{ hiddenColumns() }}</span>\n </div>\n }\n @if (!!activeSavedView() || hiddenColumns() > 0) {\n <upd-button (clicked)=\"resetViewState()\" colorStyle=\"danger\" updPopover=\"{{ t('ResetView') }}\"\n [updPopoverActAsTooltip]=\"true\" [isIcon]=\"true\" [isOutline]=\"true\">\n <upd-icon tablerIcon=\"restore\" [tablerIconSize]=\"20\"></upd-icon>\n </upd-button>\n }\n @if (configModel().canSaveViews) {\n <upd-button customClasses=\"gap-2\" [isDisabled]=\"!currentSearchRequestService.hasChanges()\"\n (clicked)=\"openSaveSearchModal()\" updPopover=\"{{ t('SaveCurrentView') }}\"\n [updPopoverActAsTooltip]=\"true\" [isIcon]=\"true\">\n <upd-icon tablerIcon=\"device-floppy\" [tablerIconSize]=\"20\"></upd-icon>\n </upd-button>\n }\n @if (configModel().canManageColumns) {\n <upd-button customClasses=\"gap-2\" (clicked)=\"openColumnsManagerModal()\">\n <upd-icon tablerIcon=\"columns\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('ColumnsManagerButton') }}\n </upd-button>\n }\n @if (configModel().canSaveViews || configModel().canLoadSavedViews) {\n <upd-button customClasses=\"gap-2\" (clicked)=\"isSavedViewsDropdownOpen = true\" #savedViewsBtn>\n <upd-icon tablerIcon=\"folders\" [tablerIconSize]=\"20\"></upd-icon>\n {{ t('SavedViews.ButtonTitle') }}\n </upd-button>\n <upd-dropdown wrapperClasses=\"overflow-x-hidden mt-1\" [isOpen]=\"isSavedViewsDropdownOpen\"\n [dropdownReference]=\"savedViewsRef()\" [items]=\"savedViewsOptions()\"\n [shouldCloseOnOutsideClick]=\"true\" (isOpenChange)=\"isSavedViewsDropdownOpen = $event\"\n [minWidth]=\"350\" (selectedItem)=\"selectSavedView($event)\">\n @if (savedViewsOptions().length < 1) {\n <span class=\"m-2\">{{ t('NoSavedViews') }}</span>\n }\n </upd-dropdown>\n }\n </div>\n </ng-template>\n</ng-container>", styles: [".fixed{table-layout:fixed!important}.fixed td,.fixed th{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.checkbox-selector{width:52px!important}.custom-actions{width:56px!important}.ca-item{transition:all,.5s}.ca-item:hover{width:400px}.grow-left{direction:rtl}.ca-dropdown-content{display:none;background:var(--upd-secondary-lt)}.grow-left:hover .ca-dropdown-content{display:block}\n"] }]
1517
+ }], ctorParameters: () => [], propDecorators: { savedViewsRef: [{ type: i0.ViewChild, args: ['savedViewsBtn', { ...{ read: ElementRef }, isSignal: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }, { type: i0.Output, args: ["configChange"] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }] } });
1518
+
1519
+ var UpDevs$1 = {
1520
+ Table: {
1521
+ Search: "Search",
1522
+ NoRecordsFoundTitle: "No records found",
1523
+ NoRecordsFoundSubtitle: "Please, adjust your search terms to find what you're looking for",
1524
+ HiddenColumnsTooltip: "Hidden columns",
1525
+ SaveCurrentView: "Save current view",
1526
+ ApplyFilters: "Apply filters",
1527
+ AddNewFilter: "Add new filter",
1528
+ Loading: "Loading",
1529
+ VisibleColumns: "Visible",
1530
+ HiddenColumns: "Hidden",
1531
+ ColumnTitleNotSet: "Title not set",
1532
+ NoSavedViews: "No saved views",
1533
+ CurrentSavedView: "View currently applied",
1534
+ ColumnsManagerButton: "Columns manager",
1535
+ ResetView: "Reset table state",
1536
+ Filters: {
1537
+ General: {
1538
+ Equals: "Equals",
1539
+ NotEquals: "Different than",
1540
+ IsEmpty: "Is empty",
1541
+ IsNotEmpty: "Is not empty"
1542
+ },
1543
+ "String": {
1544
+ StartsWith: "Starts with",
1545
+ EndsWith: "Ends with",
1546
+ Contains: "Contains",
1547
+ NotContains: "Doesn't contain",
1548
+ In: "In"
1549
+ },
1550
+ "Boolean": {
1551
+ True: "True",
1552
+ False: "False"
1553
+ },
1554
+ DateOrNumber: {
1555
+ GreaterThan: "Greater than",
1556
+ LessThan: "Less than",
1557
+ GreaterThanOrEqualTo: "Greater than or equal to",
1558
+ LessThanOrEqualTo: "Less than or equal to"
1559
+ },
1560
+ "Date": {
1561
+ Between: "Between"
1562
+ },
1563
+ "Number": {
1564
+ In: "In"
1565
+ }
1566
+ },
1567
+ ColumnsManager: {
1568
+ Apply: "Apply"
1569
+ },
1570
+ SaveSearch: {
1571
+ Title: "Save view",
1572
+ Save: "Save",
1573
+ Cancel: "Cancel",
1574
+ Name: "Name",
1575
+ IsDefault: "Is default",
1576
+ IsDefaultHint: "If this option is checked, this view will be loaded by default.",
1577
+ NoSavedViews: "No saved views"
1578
+ },
1579
+ SavedViews: {
1580
+ ButtonTitle: "Saved views",
1581
+ MarkAsDefault: "Mark as default (loads on start)",
1582
+ Duplicate: "Duplicate",
1583
+ DuplicateSuffix: "copy",
1584
+ Edit: "Edit",
1585
+ Remove: "Remove",
1586
+ ConfirmRemove: "Are you sure you would like to remove the view \"{{view}}\"?<br><br><b class='text-danger'>This action can not be undone.</b>",
1587
+ NameNotUnique: "There is already a saved view with that name, please choose another."
1588
+ }
1589
+ }
1590
+ };
1591
+ var en = {
1592
+ UpDevs: UpDevs$1
1593
+ };
1594
+
1595
+ var en$1 = /*#__PURE__*/Object.freeze({
1596
+ __proto__: null,
1597
+ UpDevs: UpDevs$1,
1598
+ default: en
1599
+ });
1600
+
1601
+ var UpDevs = {
1602
+ Table: {
1603
+ Search: "Pesquisar",
1604
+ NoRecordsFoundTitle: "Nenhum registro encontrado",
1605
+ NoRecordsFoundSubtitle: "Por favor, ajuste sua pesquisa para encontrar o que você está procurando",
1606
+ HiddenColumnsTooltip: "Colunas ocultas",
1607
+ SaveCurrentView: "Salvar consulta atual",
1608
+ ApplyFilters: "Aplicar filtros",
1609
+ AddNewFilter: "Adicionar novo filtro",
1610
+ Loading: "Carregando",
1611
+ VisibleColumns: "Visíveis",
1612
+ HiddenColumns: "Ocultas",
1613
+ ColumnTitleNotSet: "Título não definido",
1614
+ NoSavedViews: "Nenhuma consulta salva",
1615
+ CurrentSavedView: "Consulta sendo visualizada",
1616
+ ColumnsManagerButton: "Gerenciar colunas",
1617
+ ResetView: "Restaurar a condição tabela",
1618
+ Filters: {
1619
+ General: {
1620
+ Equals: "Igual à",
1621
+ NotEquals: "Diferente de",
1622
+ IsEmpty: "Está vazio",
1623
+ IsNotEmpty: "Não está vazio"
1624
+ },
1625
+ "String": {
1626
+ StartsWith: "Começa com",
1627
+ EndsWith: "Termina com",
1628
+ Contains: "Contém",
1629
+ NotContains: "Não contém",
1630
+ In: "Está em"
1631
+ },
1632
+ "Boolean": {
1633
+ True: "Verdadeiro",
1634
+ False: "Falso"
1635
+ },
1636
+ DateOrNumber: {
1637
+ GreaterThan: "Maior que",
1638
+ LessThan: "Menor que",
1639
+ GreaterThanOrEqualTo: "Maior que ou igual à",
1640
+ LessThanOrEqualTo: "Menor que ou igual à"
1641
+ },
1642
+ "Date": {
1643
+ Between: "Entre"
1644
+ },
1645
+ "Number": {
1646
+ In: "Está em"
1647
+ }
1648
+ },
1649
+ ColumnsManager: {
1650
+ Apply: "Aplicar"
1651
+ },
1652
+ SaveSearch: {
1653
+ Title: "Salvar consulta",
1654
+ Save: "Salvar",
1655
+ Cancel: "Cancelar",
1656
+ Name: "Nome",
1657
+ IsDefault: "É padrão",
1658
+ IsDefaultHint: "Se esta opção estiver marcada, esta consulta será carregada por padrão.",
1659
+ NoSavedViews: "Sem consultas salvas"
1660
+ },
1661
+ SavedViews: {
1662
+ ButtonTitle: "Consultas salvas",
1663
+ MarkAsDefault: "Mark como padrão (carrega automaticamente)",
1664
+ Duplicate: "Duplicar",
1665
+ DuplicateSuffix: "cópia",
1666
+ Edit: "Editar",
1667
+ Remove: "Remover",
1668
+ ConfirmRemove: "Deseja realmente remover a consulta \"{{view}}\"?<br><br><b class='text-danger'>Esta ação não pode ser desfeita.</b>",
1669
+ NameNotUnique: "Já existe uma consulta com esse nome, favor escolher outro."
1670
+ }
1671
+ }
1672
+ };
1673
+ var pt = {
1674
+ UpDevs: UpDevs
1675
+ };
1676
+
1677
+ var pt$1 = /*#__PURE__*/Object.freeze({
1678
+ __proto__: null,
1679
+ UpDevs: UpDevs,
1680
+ default: pt
1681
+ });
1682
+
1683
+ class FiltersOperandsStore extends BaseStore {
1684
+ constructor(configService) {
1685
+ super({ baseUrl: configService.config.urlToLoadOperandsFromServer || '' });
1686
+ }
1687
+ load(fieldType) {
1688
+ return this._requestService.makeGet(this.getRequestModel(fieldType.toString()));
1689
+ }
1690
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FiltersOperandsStore, deps: [{ token: UpdTableConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1691
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FiltersOperandsStore }); }
1692
+ }
1693
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FiltersOperandsStore, decorators: [{
1694
+ type: Injectable
1695
+ }], ctorParameters: () => [{ type: UpdTableConfigService }] });
1696
+
1697
+ const translationKey$3 = 'UpDevs.Table.Filters.General';
1698
+ class FilterOperandsListConfig {
1699
+ static { this.options = {
1700
+ [FilterOperandEnum.Equals]: {
1701
+ operand: FilterOperandEnum.Equals,
1702
+ text: { text: `${translationKey$3}.Equals`, isTranslated: false },
1703
+ icon: { tablerIcon: 'equal' },
1704
+ requiresValue: true
1705
+ },
1706
+ [FilterOperandEnum.NotEquals]: {
1707
+ operand: FilterOperandEnum.NotEquals,
1708
+ text: { text: `${translationKey$3}.NotEquals`, isTranslated: false },
1709
+ icon: { tablerIcon: 'equal-not' },
1710
+ requiresValue: true
1711
+ },
1712
+ [FilterOperandEnum.IsEmpty]: {
1713
+ operand: FilterOperandEnum.IsEmpty,
1714
+ text: { text: `${translationKey$3}.IsEmpty`, isTranslated: false },
1715
+ icon: { tablerIcon: 'droplet' },
1716
+ requiresValue: false
1717
+ },
1718
+ [FilterOperandEnum.IsNotEmpty]: {
1719
+ operand: FilterOperandEnum.IsNotEmpty,
1720
+ text: { text: `${translationKey$3}.IsNotEmpty`, isTranslated: false },
1721
+ icon: { tablerIcon: 'droplet', tablerIconType: 'solid' },
1722
+ requiresValue: false
1723
+ }
1724
+ }; }
1725
+ }
1726
+
1727
+ const translationKey$2 = 'UpDevs.Table.Filters.String';
1728
+ class StringFilterOperandsListModel {
1729
+ static { this.options = {
1730
+ [FilterOperandEnum.Equals]: FilterOperandsListConfig.options[FilterOperandEnum.Equals],
1731
+ [FilterOperandEnum.NotEquals]: FilterOperandsListConfig.options[FilterOperandEnum.NotEquals],
1732
+ [FilterOperandEnum.StartsWith]: {
1733
+ operand: FilterOperandEnum.StartsWith,
1734
+ text: { text: `${translationKey$2}.StartsWith`, isTranslated: false },
1735
+ icon: { tablerIcon: 'brackets-contain-start' },
1736
+ requiresValue: true
1737
+ },
1738
+ [FilterOperandEnum.EndsWith]: {
1739
+ operand: FilterOperandEnum.EndsWith,
1740
+ text: { text: `${translationKey$2}.EndsWith`, isTranslated: false },
1741
+ icon: { tablerIcon: 'brackets-contain-end' },
1742
+ requiresValue: true
1743
+ },
1744
+ [FilterOperandEnum.Contains]: {
1745
+ operand: FilterOperandEnum.Contains,
1746
+ text: { text: `${translationKey$2}.Contains`, isTranslated: false },
1747
+ icon: { tablerIcon: 'brackets-contain' },
1748
+ requiresValue: true
1749
+ },
1750
+ [FilterOperandEnum.NotContains]: {
1751
+ operand: FilterOperandEnum.NotContains,
1752
+ text: { text: `${translationKey$2}.NotContains`, isTranslated: false },
1753
+ icon: { tablerIcon: 'brackets-off' },
1754
+ requiresValue: true
1755
+ },
1756
+ [FilterOperandEnum.IsEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsEmpty],
1757
+ [FilterOperandEnum.IsNotEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsNotEmpty],
1758
+ [FilterOperandEnum.In]: {
1759
+ operand: FilterOperandEnum.In,
1760
+ text: { text: `${translationKey$2}.In`, isTranslated: false },
1761
+ icon: { tablerIcon: 'spacing-horizontal' },
1762
+ requiresValue: true
1763
+ }
1764
+ }; }
1765
+ static get optionsAsList() {
1766
+ return (Object.values(this.options) || []);
1767
+ }
1768
+ }
1769
+
1770
+ const translationKey$1 = 'UpDevs.Table.Filters.DateOrNumber';
1771
+ class DateOrNumberOperandsListConfig {
1772
+ static { this.options = {
1773
+ [FilterDateOperandEnum.GreaterThan]: {
1774
+ operand: FilterDateOperandEnum.GreaterThan,
1775
+ text: { text: `${translationKey$1}.GreaterThan`, isTranslated: false },
1776
+ icon: { tablerIcon: 'math-greater' },
1777
+ requiresValue: true
1778
+ },
1779
+ [FilterDateOperandEnum.LessThan]: {
1780
+ operand: FilterDateOperandEnum.LessThan,
1781
+ text: { text: `${translationKey$1}.LessThan`, isTranslated: false },
1782
+ icon: { tablerIcon: 'math-lower' },
1783
+ requiresValue: true
1784
+ },
1785
+ [FilterDateOperandEnum.GreaterThanOrEqualTo]: {
1786
+ operand: FilterDateOperandEnum.GreaterThanOrEqualTo,
1787
+ text: { text: `${translationKey$1}.GreaterThanOrEqualTo`, isTranslated: false },
1788
+ icon: { tablerIcon: 'math-equal-greater' },
1789
+ requiresValue: true
1790
+ },
1791
+ [FilterDateOperandEnum.LessThanOrEqualTo]: {
1792
+ operand: FilterDateOperandEnum.LessThanOrEqualTo,
1793
+ text: { text: `${translationKey$1}.LessThanOrEqualTo`, isTranslated: false },
1794
+ icon: { tablerIcon: 'math-equal-lower' },
1795
+ requiresValue: true
1796
+ }
1797
+ }; }
1798
+ }
1799
+
1800
+ class NumberFilterOperandsListModel {
1801
+ static { this.options = {
1802
+ [FilterNumberOperandEnum.Equals]: FilterOperandsListConfig.options[FilterOperandEnum.Equals],
1803
+ [FilterNumberOperandEnum.NotEquals]: FilterOperandsListConfig.options[FilterOperandEnum.NotEquals],
1804
+ [FilterNumberOperandEnum.GreaterThan]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.GreaterThan],
1805
+ [FilterNumberOperandEnum.LessThan]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.LessThan],
1806
+ [FilterNumberOperandEnum.GreaterThanOrEqualTo]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.GreaterThanOrEqualTo],
1807
+ [FilterNumberOperandEnum.LessThanOrEqualTo]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.LessThanOrEqualTo],
1808
+ [FilterNumberOperandEnum.IsEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsEmpty],
1809
+ [FilterNumberOperandEnum.IsNotEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsNotEmpty],
1810
+ [FilterNumberOperandEnum.In]: {
1811
+ operand: FilterNumberOperandEnum.In,
1812
+ text: { text: 'UpDevs.Table.Filters.Number.In', isTranslated: false },
1813
+ icon: { tablerIcon: 'spacing-horizontal' },
1814
+ requiresValue: true
1815
+ }
1816
+ }; }
1817
+ static get optionsAsList() {
1818
+ return (Object.values(this.options) || []);
1819
+ }
1820
+ }
1821
+
1822
+ const translationKey = 'UpDevs.Table.Filters.Boolean';
1823
+ class BooleanFilterOperandsListModel {
1824
+ static { this.options = {
1825
+ [FilterBooleanOperandEnum.True]: {
1826
+ operand: FilterBooleanOperandEnum.True,
1827
+ text: { text: `${translationKey}.True`, isTranslated: false },
1828
+ icon: { tablerIcon: 'toggle-right' },
1829
+ requiresValue: false
1830
+ },
1831
+ [FilterBooleanOperandEnum.False]: {
1832
+ operand: FilterBooleanOperandEnum.False,
1833
+ text: { text: `${translationKey}.False`, isTranslated: false },
1834
+ icon: { tablerIcon: 'toggle-left' },
1835
+ requiresValue: false
1836
+ },
1837
+ [FilterBooleanOperandEnum.IsEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsEmpty],
1838
+ [FilterBooleanOperandEnum.IsNotEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsNotEmpty]
1839
+ }; }
1840
+ static get optionsAsList() {
1841
+ return (Object.values(this.options) || []);
1842
+ }
1843
+ }
1844
+
1845
+ class DateFilterOperandsListModel {
1846
+ static { this.options = {
1847
+ [FilterDateOperandEnum.Equals]: FilterOperandsListConfig.options[FilterOperandEnum.Equals],
1848
+ [FilterDateOperandEnum.NotEquals]: FilterOperandsListConfig.options[FilterOperandEnum.NotEquals],
1849
+ [FilterDateOperandEnum.GreaterThan]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.GreaterThan],
1850
+ [FilterDateOperandEnum.LessThan]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.LessThan],
1851
+ [FilterDateOperandEnum.GreaterThanOrEqualTo]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.GreaterThanOrEqualTo],
1852
+ [FilterDateOperandEnum.LessThanOrEqualTo]: DateOrNumberOperandsListConfig.options[FilterDateOperandEnum.LessThanOrEqualTo],
1853
+ [FilterDateOperandEnum.IsEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsEmpty],
1854
+ [FilterDateOperandEnum.IsNotEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsNotEmpty],
1855
+ [FilterDateOperandEnum.Between]: {
1856
+ operand: FilterDateOperandEnum.Between,
1857
+ text: { text: 'UpDevs.Table.Filters.Date.Between', isTranslated: false },
1858
+ icon: { tablerIcon: 'spacing-horizontal' },
1859
+ requiresValue: true
1860
+ }
1861
+ }; }
1862
+ static get optionsAsList() {
1863
+ return (Object.values(this.options) || []);
1864
+ }
1865
+ }
1866
+
1867
+ class GuidFilterOperandsListModel {
1868
+ static { this.options = {
1869
+ [FilterGuidOperandEnum.Equals]: FilterOperandsListConfig.options[FilterOperandEnum.Equals],
1870
+ [FilterGuidOperandEnum.NotEquals]: FilterOperandsListConfig.options[FilterOperandEnum.NotEquals],
1871
+ [FilterGuidOperandEnum.IsEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsEmpty],
1872
+ [FilterGuidOperandEnum.IsNotEmpty]: FilterOperandsListConfig.options[FilterOperandEnum.IsNotEmpty],
1873
+ [FilterGuidOperandEnum.In]: StringFilterOperandsListModel.options[FilterOperandEnum.In]
1874
+ }; }
1875
+ static get optionsAsList() {
1876
+ return (Object.values(this.options) || []);
1877
+ }
1878
+ }
1879
+
1880
+ class SelectFilterOperandsListModel {
1881
+ static { this.options = {
1882
+ [FilterOperandEnum.Equals]: FilterOperandsListConfig.options[FilterOperandEnum.Equals],
1883
+ [FilterOperandEnum.NotEquals]: FilterOperandsListConfig.options[FilterOperandEnum.NotEquals]
1884
+ }; }
1885
+ static get optionsAsList() {
1886
+ return (Object.values(this.options) || []);
1887
+ }
1888
+ }
1889
+
1890
+ class DefaultFiltersOperandsService extends FiltersOperandsService {
1891
+ get isLoaded() {
1892
+ return this._isLoaded;
1893
+ }
1894
+ constructor() {
1895
+ super();
1896
+ this._isLoaded = false;
1897
+ this.configService = inject(UpdTableConfigService);
1898
+ this.filterOperandsStore = inject(FiltersOperandsStore);
1899
+ this.cachedData = {};
1900
+ if (!!this.configService.config.urlToLoadOperandsFromServer) {
1901
+ forkJoin({
1902
+ guidOps: this.filterOperandsStore.load(FilterTypeEnum.Guid),
1903
+ stringOps: this.filterOperandsStore.load(FilterTypeEnum.Text),
1904
+ numberOps: this.filterOperandsStore.load(FilterTypeEnum.Number),
1905
+ dateOps: this.filterOperandsStore.load(FilterTypeEnum.Date),
1906
+ booleanOps: this.filterOperandsStore.load(FilterTypeEnum.Boolean),
1907
+ selectOps: this.filterOperandsStore.load(FilterTypeEnum.Select)
1908
+ }).subscribe(resp => {
1909
+ this.cachedData[FilterTypeEnum.Guid] = resp.guidOps;
1910
+ this.cachedData[FilterTypeEnum.Text] = resp.stringOps;
1911
+ this.cachedData[FilterTypeEnum.Number] = resp.numberOps;
1912
+ this.cachedData[FilterTypeEnum.Date] = resp.dateOps;
1913
+ this.cachedData[FilterTypeEnum.Boolean] = resp.booleanOps;
1914
+ this.cachedData[FilterTypeEnum.Select] = resp.selectOps;
1915
+ this._isLoaded = true;
1916
+ });
1917
+ }
1918
+ else {
1919
+ this.cachedData[FilterTypeEnum.Guid] = GuidFilterOperandsListModel.optionsAsList;
1920
+ this.cachedData[FilterTypeEnum.Text] = StringFilterOperandsListModel.optionsAsList;
1921
+ this.cachedData[FilterTypeEnum.Number] = NumberFilterOperandsListModel.optionsAsList;
1922
+ this.cachedData[FilterTypeEnum.Date] = DateFilterOperandsListModel.optionsAsList;
1923
+ this.cachedData[FilterTypeEnum.Boolean] = BooleanFilterOperandsListModel.optionsAsList;
1924
+ this.cachedData[FilterTypeEnum.Select] = SelectFilterOperandsListModel.optionsAsList;
1925
+ this._isLoaded = true;
1926
+ }
1927
+ }
1928
+ getOperands(type) {
1929
+ return this._isLoaded ? this.cachedData[type] : [];
1930
+ }
1931
+ getAllOperands() {
1932
+ return this.cachedData;
1933
+ }
1934
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultFiltersOperandsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1935
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultFiltersOperandsService }); }
1936
+ }
1937
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DefaultFiltersOperandsService, decorators: [{
1938
+ type: Injectable
1939
+ }], ctorParameters: () => [] });
1940
+
1941
+ class UpdTableModule {
1942
+ constructor(translocoService) {
1943
+ translocoService.setFallbackLangForMissingTranslation({ fallbackLang: 'en' });
1944
+ translocoService.setTranslation(en$1, 'en');
1945
+ translocoService.setTranslation(pt$1, 'pt');
1946
+ }
1947
+ /**
1948
+ * Sets up the table module with the provided configuration.
1949
+ * @param config Configuration.
1950
+ */
1951
+ static forRoot(config) {
1952
+ const customizableProviders = [
1953
+ config.filtersOperandsService || {
1954
+ provide: FiltersOperandsService,
1955
+ useClass: DefaultFiltersOperandsService
1956
+ }
1957
+ ];
1958
+ return {
1959
+ ngModule: UpdTableModule,
1960
+ providers: [
1961
+ { provide: TableConstants.defaultOptionsInjectionToken, useValue: config },
1962
+ ...customizableProviders
1963
+ ]
1964
+ };
1965
+ }
1966
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UpdTableModule, deps: [{ token: i1$1.TranslocoService }], target: i0.ɵɵFactoryTarget.NgModule }); }
1967
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.4", ngImport: i0, type: UpdTableModule, declarations: [TableComponent,
1968
+ SearchSectionComponent,
1969
+ FilterRowComponent,
1970
+ TableColumnDirective,
1971
+ NumberColumnComponent,
1972
+ DateTimeColumnComponent,
1973
+ BooleanColumnComponent,
1974
+ TextColumnComponent,
1975
+ ColumnsManagerComponent,
1976
+ SaveSearchComponent], imports: [CommonModule,
1977
+ TranslocoDirective,
1978
+ UpdIconsModule,
1979
+ UpdButtonModule,
1980
+ UpdModalModule,
1981
+ UpdPaginatorModule,
1982
+ UpdInputModule,
1983
+ UpdCheckboxModule,
1984
+ UpdSelectModule,
1985
+ UpdDragAndDropModule,
1986
+ UpdFormModule,
1987
+ UpdDropdownModule,
1988
+ UpdTimePickerModule,
1989
+ UpdBadgeModule,
1990
+ UpdPopoverModule], exports: [TableComponent,
1991
+ TableColumnDirective] }); }
1992
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UpdTableModule, providers: [
1993
+ UpdTableConfigService,
1994
+ FiltersOperandsStore,
1995
+ SavedViewsStorage
1996
+ ], imports: [CommonModule,
1997
+ UpdIconsModule,
1998
+ UpdButtonModule,
1999
+ UpdModalModule,
2000
+ UpdPaginatorModule,
2001
+ UpdInputModule,
2002
+ UpdCheckboxModule,
2003
+ UpdSelectModule,
2004
+ UpdDragAndDropModule,
2005
+ UpdFormModule,
2006
+ UpdDropdownModule,
2007
+ UpdTimePickerModule,
2008
+ UpdBadgeModule,
2009
+ UpdPopoverModule] }); }
2010
+ }
2011
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: UpdTableModule, decorators: [{
2012
+ type: NgModule,
2013
+ args: [{
2014
+ imports: [
2015
+ CommonModule,
2016
+ TranslocoDirective,
2017
+ UpdIconsModule,
2018
+ UpdButtonModule,
2019
+ UpdModalModule,
2020
+ UpdPaginatorModule,
2021
+ UpdInputModule,
2022
+ UpdCheckboxModule,
2023
+ UpdSelectModule,
2024
+ UpdDragAndDropModule,
2025
+ UpdFormModule,
2026
+ UpdDropdownModule,
2027
+ UpdTimePickerModule,
2028
+ UpdBadgeModule,
2029
+ UpdPopoverModule
2030
+ ],
2031
+ declarations: [
2032
+ TableComponent,
2033
+ SearchSectionComponent,
2034
+ FilterRowComponent,
2035
+ TableColumnDirective,
2036
+ NumberColumnComponent,
2037
+ DateTimeColumnComponent,
2038
+ BooleanColumnComponent,
2039
+ TextColumnComponent,
2040
+ ColumnsManagerComponent,
2041
+ SaveSearchComponent
2042
+ ],
2043
+ exports: [
2044
+ TableComponent,
2045
+ TableColumnDirective
2046
+ ],
2047
+ providers: [
2048
+ UpdTableConfigService,
2049
+ FiltersOperandsStore,
2050
+ SavedViewsStorage
2051
+ ]
2052
+ }]
2053
+ }], ctorParameters: () => [{ type: i1$1.TranslocoService }] });
2054
+
2055
+ /**
2056
+ * Generated bundle index. Do not edit.
2057
+ */
2058
+
2059
+ export { BaseColumn, BaseColumnModel, BooleanColumnModel, ColumnTypeEnum, CustomColumnModel, DateTimeColumnModel, FiltersOperandsService, GuidColumnModel, ImageColumnModel, NumberColumnModel, TableColumnDirective, TableComponent, TextColumnModel, UpdTableModule };
2060
+ //# sourceMappingURL=updevs-components-table.mjs.map