@mintplayer/ng-spark 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/fesm2022/mintplayer-ng-spark-icon.mjs +35 -0
  2. package/fesm2022/mintplayer-ng-spark-icon.mjs.map +1 -0
  3. package/fesm2022/mintplayer-ng-spark-models.mjs +48 -0
  4. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -0
  5. package/fesm2022/mintplayer-ng-spark-pipes.mjs +427 -0
  6. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -0
  7. package/fesm2022/mintplayer-ng-spark-po-create.mjs +121 -0
  8. package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -0
  9. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +368 -0
  10. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -0
  11. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +139 -0
  12. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -0
  13. package/fesm2022/mintplayer-ng-spark-po-form.mjs +393 -0
  14. package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -0
  15. package/fesm2022/mintplayer-ng-spark-query-list.mjs +392 -0
  16. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -0
  17. package/fesm2022/mintplayer-ng-spark-renderers.mjs +25 -0
  18. package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -0
  19. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +87 -0
  20. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -0
  21. package/fesm2022/mintplayer-ng-spark-routes.mjs +31 -0
  22. package/fesm2022/mintplayer-ng-spark-routes.mjs.map +1 -0
  23. package/fesm2022/mintplayer-ng-spark-services.mjs +348 -0
  24. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -0
  25. package/fesm2022/mintplayer-ng-spark.mjs +17 -2262
  26. package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
  27. package/package.json +49 -1
  28. package/types/mintplayer-ng-spark-icon.d.ts +13 -0
  29. package/types/mintplayer-ng-spark-models.d.ts +275 -0
  30. package/types/mintplayer-ng-spark-pipes.d.ts +143 -0
  31. package/types/mintplayer-ng-spark-po-create.d.ts +29 -0
  32. package/types/mintplayer-ng-spark-po-detail.d.ts +88 -0
  33. package/types/mintplayer-ng-spark-po-edit.d.ts +31 -0
  34. package/types/mintplayer-ng-spark-po-form.d.ts +84 -0
  35. package/types/mintplayer-ng-spark-query-list.d.ts +60 -0
  36. package/types/mintplayer-ng-spark-renderers.d.ts +68 -0
  37. package/types/mintplayer-ng-spark-retry-action-modal.d.ts +14 -0
  38. package/types/mintplayer-ng-spark-routes.d.ts +12 -0
  39. package/types/mintplayer-ng-spark-services.d.ts +100 -0
  40. package/types/mintplayer-ng-spark.d.ts +3 -855
@@ -0,0 +1,393 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, input, model, output, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
5
+ import * as i2 from '@angular/forms';
6
+ import { FormsModule } from '@angular/forms';
7
+ import { Color } from '@mintplayer/ng-bootstrap';
8
+ import { BsCardComponent, BsCardHeaderComponent } from '@mintplayer/ng-bootstrap/card';
9
+ import { BsFormComponent, BsFormControlDirective } from '@mintplayer/ng-bootstrap/form';
10
+ import { BsGridComponent, BsGridRowDirective, BsGridColumnDirective, BsGridColDirective, BsColFormLabelDirective } from '@mintplayer/ng-bootstrap/grid';
11
+ import { BsInputGroupComponent } from '@mintplayer/ng-bootstrap/input-group';
12
+ import { BsButtonTypeDirective } from '@mintplayer/ng-bootstrap/button-type';
13
+ import { BsSelectComponent, BsSelectOption } from '@mintplayer/ng-bootstrap/select';
14
+ import { BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective } from '@mintplayer/ng-bootstrap/modal';
15
+ import { DatatableSettings, BsDatatableComponent, BsDatatableColumnDirective, BsRowTemplateDirective } from '@mintplayer/ng-bootstrap/datatable';
16
+ import { BsToggleButtonComponent } from '@mintplayer/ng-bootstrap/toggle-button';
17
+ import { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';
18
+ import { BsTabControlComponent, BsTabPageComponent, BsTabPageHeaderDirective } from '@mintplayer/ng-bootstrap/tab-control';
19
+ import { BsTableComponent } from '@mintplayer/ng-bootstrap/table';
20
+ import { SparkService, SparkLanguageService } from '@mintplayer/ng-spark/services';
21
+ import { TranslateKeyPipe, ResolveTranslationPipe, InputTypePipe, LookupDisplayValuePipe, LookupDisplayTypePipe, LookupOptionsPipe, ReferenceDisplayValuePipe, AsDetailDisplayValuePipe, AsDetailTypePipe, AsDetailColumnsPipe, AsDetailCellValuePipe, CanCreateDetailRowPipe, CanDeleteDetailRowPipe, InlineRefOptionsPipe, ReferenceAttrValuePipe, ErrorForAttributePipe } from '@mintplayer/ng-spark/pipes';
22
+ import { ELookupDisplayType, hasShowedOnFlag, ShowedOn, resolveTranslation } from '@mintplayer/ng-spark/models';
23
+ import { SparkIconComponent } from '@mintplayer/ng-spark/icon';
24
+ import { SPARK_ATTRIBUTE_RENDERERS } from '@mintplayer/ng-spark/renderers';
25
+
26
+ class SparkPoFormComponent {
27
+ sparkService = inject(SparkService);
28
+ translations = inject(SparkLanguageService);
29
+ rendererRegistry = inject(SPARK_ATTRIBUTE_RENDERERS);
30
+ entityType = input(null, ...(ngDevMode ? [{ debugName: "entityType" }] : []));
31
+ formData = model({}, ...(ngDevMode ? [{ debugName: "formData" }] : []));
32
+ validationErrors = input([], ...(ngDevMode ? [{ debugName: "validationErrors" }] : []));
33
+ showButtons = input(false, ...(ngDevMode ? [{ debugName: "showButtons" }] : []));
34
+ isSaving = input(false, ...(ngDevMode ? [{ debugName: "isSaving" }] : []));
35
+ parentId = input(undefined, ...(ngDevMode ? [{ debugName: "parentId" }] : []));
36
+ parentType = input(undefined, ...(ngDevMode ? [{ debugName: "parentType" }] : []));
37
+ save = output();
38
+ cancel = output();
39
+ colors = Color;
40
+ referenceOptions = signal({}, ...(ngDevMode ? [{ debugName: "referenceOptions" }] : []));
41
+ asDetailTypes = signal({}, ...(ngDevMode ? [{ debugName: "asDetailTypes" }] : []));
42
+ lookupReferenceOptions = signal({}, ...(ngDevMode ? [{ debugName: "lookupReferenceOptions" }] : []));
43
+ // Modal state for AsDetail object editing
44
+ editingAsDetailAttr = signal(null, ...(ngDevMode ? [{ debugName: "editingAsDetailAttr" }] : []));
45
+ asDetailFormData = signal({}, ...(ngDevMode ? [{ debugName: "asDetailFormData" }] : []));
46
+ showAsDetailModal = signal(false, ...(ngDevMode ? [{ debugName: "showAsDetailModal" }] : []));
47
+ editingArrayIndex = signal(null, ...(ngDevMode ? [{ debugName: "editingArrayIndex" }] : []));
48
+ // Permissions for array AsDetail entity types
49
+ asDetailPermissions = signal({}, ...(ngDevMode ? [{ debugName: "asDetailPermissions" }] : []));
50
+ // Reference options for columns within array AsDetail types (keyed by parent attr name, then column name)
51
+ asDetailReferenceOptions = signal({}, ...(ngDevMode ? [{ debugName: "asDetailReferenceOptions" }] : []));
52
+ // Modal state for Reference selection
53
+ editingReferenceAttr = signal(null, ...(ngDevMode ? [{ debugName: "editingReferenceAttr" }] : []));
54
+ showReferenceModal = signal(false, ...(ngDevMode ? [{ debugName: "showReferenceModal" }] : []));
55
+ referenceModalItems = signal([], ...(ngDevMode ? [{ debugName: "referenceModalItems" }] : []));
56
+ referenceModalEntityType = signal(null, ...(ngDevMode ? [{ debugName: "referenceModalEntityType" }] : []));
57
+ referenceModalPagination = signal(undefined, ...(ngDevMode ? [{ debugName: "referenceModalPagination" }] : []));
58
+ referenceModalSettings = signal(new DatatableSettings({
59
+ perPage: { values: [10, 25, 50], selected: 10 },
60
+ page: { values: [1], selected: 1 },
61
+ sortColumns: []
62
+ }), ...(ngDevMode ? [{ debugName: "referenceModalSettings" }] : []));
63
+ referenceSearchTerm = '';
64
+ // Modal state for LookupReference selection (Modal display type)
65
+ editingLookupAttr = signal(null, ...(ngDevMode ? [{ debugName: "editingLookupAttr" }] : []));
66
+ showLookupModal = signal(false, ...(ngDevMode ? [{ debugName: "showLookupModal" }] : []));
67
+ lookupModalItems = signal([], ...(ngDevMode ? [{ debugName: "lookupModalItems" }] : []));
68
+ lookupSearchTerm = signal('', ...(ngDevMode ? [{ debugName: "lookupSearchTerm" }] : []));
69
+ ELookupDisplayType = ELookupDisplayType;
70
+ editableAttributes = computed(() => {
71
+ return this.entityType()?.attributes
72
+ .filter(a => a.isVisible && !a.isReadOnly && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))
73
+ .sort((a, b) => a.order - b.order) || [];
74
+ }, ...(ngDevMode ? [{ debugName: "editableAttributes" }] : []));
75
+ static DEFAULT_TAB = { id: '__default__', name: 'Algemeen', label: { nl: 'Algemeen', en: 'General' }, order: 0 };
76
+ ungroupedAttributes = computed(() => {
77
+ const attrs = this.editableAttributes();
78
+ const groupIds = new Set((this.entityType()?.groups || []).map(g => g.id));
79
+ return attrs.filter(a => !a.group || !groupIds.has(a.group));
80
+ }, ...(ngDevMode ? [{ debugName: "ungroupedAttributes" }] : []));
81
+ resolvedTabs = computed(() => {
82
+ const et = this.entityType();
83
+ const definedTabs = et?.tabs?.length ? [...et.tabs].sort((a, b) => a.order - b.order) : [];
84
+ const hasUngroupedAttrs = this.ungroupedAttributes().length > 0;
85
+ const hasUntabbedGroups = (et?.groups || []).some(g => !g.tab);
86
+ if (hasUngroupedAttrs || hasUntabbedGroups || definedTabs.length === 0) {
87
+ return [SparkPoFormComponent.DEFAULT_TAB, ...definedTabs];
88
+ }
89
+ return definedTabs;
90
+ }, ...(ngDevMode ? [{ debugName: "resolvedTabs" }] : []));
91
+ groupsForTab(tab) {
92
+ const groups = this.entityType()?.groups || [];
93
+ if (tab.id === '__default__') {
94
+ return groups.filter(g => !g.tab).sort((a, b) => a.order - b.order);
95
+ }
96
+ return groups.filter(g => g.tab === tab.id).sort((a, b) => a.order - b.order);
97
+ }
98
+ attrsForGroup(group) {
99
+ return this.editableAttributes().filter(a => a.group === group.id);
100
+ }
101
+ referenceVisibleAttributes = computed(() => {
102
+ return this.referenceModalEntityType()?.attributes
103
+ .filter(a => a.isVisible)
104
+ .sort((a, b) => a.order - b.order) || [];
105
+ }, ...(ngDevMode ? [{ debugName: "referenceVisibleAttributes" }] : []));
106
+ filteredLookupItems = computed(() => {
107
+ if (!this.lookupSearchTerm().trim()) {
108
+ return this.lookupModalItems();
109
+ }
110
+ const term = this.lookupSearchTerm().toLowerCase().trim();
111
+ return this.lookupModalItems().filter(item => {
112
+ const translation = resolveTranslation(item.values);
113
+ return translation.toLowerCase().includes(term) || item.key.toLowerCase().includes(term);
114
+ });
115
+ }, ...(ngDevMode ? [{ debugName: "filteredLookupItems" }] : []));
116
+ constructor() {
117
+ effect(() => {
118
+ const et = this.entityType();
119
+ const _pid = this.parentId();
120
+ const _ptype = this.parentType();
121
+ if (et) {
122
+ this.loadReferenceOptions();
123
+ this.loadAsDetailTypes();
124
+ this.loadLookupReferenceOptions();
125
+ }
126
+ });
127
+ }
128
+ toRecord(entries) {
129
+ const result = {};
130
+ for (const [key, value] of entries) {
131
+ result[key] = value;
132
+ }
133
+ return result;
134
+ }
135
+ async loadReferenceOptions() {
136
+ const refAttrs = this.editableAttributes().filter(a => a.dataType === 'Reference' && a.query);
137
+ if (refAttrs.length === 0)
138
+ return;
139
+ const entries = await Promise.all(refAttrs.filter(a => a.query).map(async (attr) => {
140
+ const result = await this.sparkService.executeQueryByName(attr.query, {
141
+ parentId: this.parentId(),
142
+ parentType: this.parentType(),
143
+ });
144
+ return [attr.name, result.data];
145
+ }));
146
+ this.referenceOptions.set(this.toRecord(entries));
147
+ }
148
+ async loadAsDetailTypes() {
149
+ const asDetailAttrs = this.editableAttributes().filter(a => a.dataType === 'AsDetail' && a.asDetailType);
150
+ if (asDetailAttrs.length === 0)
151
+ return;
152
+ const types = await this.sparkService.getEntityTypes();
153
+ const newAsDetailTypes = {};
154
+ for (const attr of asDetailAttrs) {
155
+ const asDetailType = types.find(t => t.clrType === attr.asDetailType);
156
+ if (asDetailType) {
157
+ newAsDetailTypes[attr.name] = asDetailType;
158
+ if (attr.isArray) {
159
+ const perms = await this.sparkService.getPermissions(asDetailType.id);
160
+ this.asDetailPermissions.update(prev => ({ ...prev, [attr.name]: perms }));
161
+ const refCols = asDetailType.attributes.filter(a => a.dataType === 'Reference' && a.query);
162
+ if (refCols.length > 0) {
163
+ const refEntries = await Promise.all(refCols.filter(c => c.query).map(async (col) => {
164
+ const result = await this.sparkService.executeQueryByName(col.query, {
165
+ parentId: this.parentId(),
166
+ parentType: this.parentType(),
167
+ });
168
+ return [col.name, result.data];
169
+ }));
170
+ this.asDetailReferenceOptions.update(prev => ({ ...prev, [attr.name]: this.toRecord(refEntries) }));
171
+ }
172
+ }
173
+ }
174
+ }
175
+ this.asDetailTypes.set(newAsDetailTypes);
176
+ }
177
+ async loadLookupReferenceOptions() {
178
+ const lookupAttrs = this.editableAttributes().filter(a => a.lookupReferenceType);
179
+ if (lookupAttrs.length === 0)
180
+ return;
181
+ const lookupNames = [...new Set(lookupAttrs.map(a => a.lookupReferenceType))];
182
+ const entries = await Promise.all(lookupNames.map(async (name) => {
183
+ const ref = await this.sparkService.getLookupReference(name);
184
+ return [name, ref];
185
+ }));
186
+ this.lookupReferenceOptions.set(this.toRecord(entries));
187
+ }
188
+ getReferenceOptions(attr) {
189
+ return this.referenceOptions()[attr.name] || [];
190
+ }
191
+ getLookupOptions(attr) {
192
+ const lookupRef = attr.lookupReferenceType ? this.lookupReferenceOptions()[attr.lookupReferenceType] : null;
193
+ return lookupRef?.values.filter(v => v.isActive) || [];
194
+ }
195
+ // LookupReference modal methods
196
+ openLookupSelector(attr) {
197
+ this.editingLookupAttr.set(attr);
198
+ this.lookupSearchTerm.set('');
199
+ this.lookupModalItems.set(this.getLookupOptions(attr));
200
+ this.showLookupModal.set(true);
201
+ }
202
+ selectLookupItem(item) {
203
+ const attr = this.editingLookupAttr();
204
+ if (attr) {
205
+ const data = { ...this.formData() };
206
+ data[attr.name] = item.key;
207
+ this.formData.set(data);
208
+ }
209
+ this.closeLookupModal();
210
+ }
211
+ closeLookupModal() {
212
+ this.showLookupModal.set(false);
213
+ this.editingLookupAttr.set(null);
214
+ this.lookupModalItems.set([]);
215
+ this.lookupSearchTerm.set('');
216
+ }
217
+ getEditRendererComponent(attr) {
218
+ if (!attr.renderer)
219
+ return null;
220
+ const reg = this.rendererRegistry.find(r => r.name === attr.renderer);
221
+ return reg?.editComponent ?? null;
222
+ }
223
+ getEditRendererInputs(attr) {
224
+ return {
225
+ value: this.formData()[attr.name],
226
+ attribute: attr,
227
+ options: attr.rendererOptions,
228
+ valueChange: (newValue) => {
229
+ const data = { ...this.formData() };
230
+ data[attr.name] = newValue;
231
+ this.formData.set(data);
232
+ },
233
+ };
234
+ }
235
+ hasError(attrName) {
236
+ return this.validationErrors().some(e => e.attributeName === attrName);
237
+ }
238
+ onFieldChange() {
239
+ this.formData.set({ ...this.formData() });
240
+ }
241
+ onSave() {
242
+ this.save.emit();
243
+ }
244
+ onCancel() {
245
+ this.cancel.emit();
246
+ }
247
+ // AsDetail object modal methods
248
+ openAsDetailEditor(attr) {
249
+ this.editingAsDetailAttr.set(attr);
250
+ this.editingArrayIndex.set(null);
251
+ this.asDetailFormData.set({ ...(this.formData()[attr.name] || {}) });
252
+ this.showAsDetailModal.set(true);
253
+ }
254
+ saveAsDetailObject() {
255
+ const attr = this.editingAsDetailAttr();
256
+ if (attr) {
257
+ const data = { ...this.formData() };
258
+ if (attr.isArray) {
259
+ const arr = [...(data[attr.name] || [])];
260
+ const idx = this.editingArrayIndex();
261
+ if (idx !== null) {
262
+ arr[idx] = { ...this.asDetailFormData() };
263
+ }
264
+ else {
265
+ arr.push({ ...this.asDetailFormData() });
266
+ }
267
+ data[attr.name] = arr;
268
+ }
269
+ else {
270
+ data[attr.name] = { ...this.asDetailFormData() };
271
+ }
272
+ this.formData.set(data);
273
+ }
274
+ this.closeAsDetailModal();
275
+ }
276
+ closeAsDetailModal() {
277
+ this.showAsDetailModal.set(false);
278
+ this.editingAsDetailAttr.set(null);
279
+ this.editingArrayIndex.set(null);
280
+ this.asDetailFormData.set({});
281
+ }
282
+ // Inline AsDetail methods
283
+ addInlineRow(attr) {
284
+ const data = { ...this.formData() };
285
+ const arr = [...(data[attr.name] || [])];
286
+ arr.push({});
287
+ data[attr.name] = arr;
288
+ this.formData.set(data);
289
+ }
290
+ // Array AsDetail methods
291
+ addArrayItem(attr) {
292
+ this.editingAsDetailAttr.set(attr);
293
+ this.editingArrayIndex.set(null);
294
+ this.asDetailFormData.set({});
295
+ this.showAsDetailModal.set(true);
296
+ }
297
+ editArrayItem(attr, index) {
298
+ this.editingAsDetailAttr.set(attr);
299
+ this.editingArrayIndex.set(index);
300
+ const arr = this.formData()[attr.name] || [];
301
+ this.asDetailFormData.set({ ...(arr[index] || {}) });
302
+ this.showAsDetailModal.set(true);
303
+ }
304
+ removeArrayItem(attr, index) {
305
+ const data = { ...this.formData() };
306
+ const arr = [...(data[attr.name] || [])];
307
+ arr.splice(index, 1);
308
+ data[attr.name] = arr;
309
+ this.formData.set(data);
310
+ }
311
+ // Reference modal methods
312
+ async openReferenceSelector(attr) {
313
+ this.editingReferenceAttr.set(attr);
314
+ this.referenceSearchTerm = '';
315
+ this.referenceModalItems.set(this.getReferenceOptions(attr));
316
+ const types = await this.sparkService.getEntityTypes();
317
+ this.referenceModalEntityType.set(types.find(t => t.clrType === attr.referenceType) || null);
318
+ this.referenceModalSettings.set(new DatatableSettings({
319
+ perPage: { values: [10, 25, 50], selected: 10 },
320
+ page: { values: [1], selected: 1 },
321
+ sortColumns: []
322
+ }));
323
+ this.applyReferenceFilter();
324
+ this.showReferenceModal.set(true);
325
+ }
326
+ onReferenceSearchChange() {
327
+ this.referenceModalSettings().page.selected = 1;
328
+ this.applyReferenceFilter();
329
+ }
330
+ applyReferenceFilter() {
331
+ let filteredItems = this.referenceModalItems();
332
+ if (this.referenceSearchTerm.trim()) {
333
+ const term = this.referenceSearchTerm.toLowerCase().trim();
334
+ filteredItems = this.referenceModalItems().filter(item => {
335
+ if (item.name?.toLowerCase().includes(term))
336
+ return true;
337
+ if (item.breadcrumb?.toLowerCase().includes(term))
338
+ return true;
339
+ return item.attributes.some(attr => {
340
+ const value = attr.breadcrumb || attr.value;
341
+ if (value == null)
342
+ return false;
343
+ return String(value).toLowerCase().includes(term);
344
+ });
345
+ });
346
+ }
347
+ const totalPages = Math.ceil(filteredItems.length / this.referenceModalSettings().perPage.selected) || 1;
348
+ this.referenceModalPagination.set({
349
+ data: filteredItems,
350
+ totalRecords: filteredItems.length,
351
+ totalPages: totalPages,
352
+ perPage: this.referenceModalSettings().perPage.selected,
353
+ page: this.referenceModalSettings().page.selected
354
+ });
355
+ this.referenceModalSettings().page.values = Array.from({ length: totalPages }, (_, i) => i + 1);
356
+ if (this.referenceModalSettings().page.selected > totalPages) {
357
+ this.referenceModalSettings().page.selected = 1;
358
+ }
359
+ }
360
+ clearReferenceSearch() {
361
+ this.referenceSearchTerm = '';
362
+ this.onReferenceSearchChange();
363
+ }
364
+ selectReferenceItem(item) {
365
+ const attr = this.editingReferenceAttr();
366
+ if (attr) {
367
+ const data = { ...this.formData() };
368
+ data[attr.name] = item.id;
369
+ this.formData.set(data);
370
+ }
371
+ this.closeReferenceModal();
372
+ }
373
+ closeReferenceModal() {
374
+ this.showReferenceModal.set(false);
375
+ this.editingReferenceAttr.set(null);
376
+ this.referenceModalItems.set([]);
377
+ this.referenceModalEntityType.set(null);
378
+ this.referenceSearchTerm = '';
379
+ }
380
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkPoFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
381
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.6", type: SparkPoFormComponent, isStandalone: true, selector: "spark-po-form", inputs: { entityType: { classPropertyName: "entityType", publicName: "entityType", isSignal: true, isRequired: false, transformFunction: null }, formData: { classPropertyName: "formData", publicName: "formData", isSignal: true, isRequired: false, transformFunction: null }, validationErrors: { classPropertyName: "validationErrors", publicName: "validationErrors", isSignal: true, isRequired: false, transformFunction: null }, showButtons: { classPropertyName: "showButtons", publicName: "showButtons", isSignal: true, isRequired: false, transformFunction: null }, isSaving: { classPropertyName: "isSaving", publicName: "isSaving", isSignal: true, isRequired: false, transformFunction: null }, parentId: { classPropertyName: "parentId", publicName: "parentId", isSignal: true, isRequired: false, transformFunction: null }, parentType: { classPropertyName: "parentType", publicName: "parentType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formData: "formDataChange", save: "save", cancel: "cancel" }, ngImport: i0, template: "<bs-form>\n @if (entityType()) {\n <bs-grid>\n <bs-tab-control>\n @for (tab of resolvedTabs(); track tab.id) {\n <bs-tab-page>\n <ng-template bsTabPageHeader>{{ tab.label | resolveTranslation:tab.name }}</ng-template>\n <ng-container *ngTemplateOutlet=\"tabContent; context: { $implicit: tab }\"></ng-container>\n </bs-tab-page>\n }\n </bs-tab-control>\n\n <ng-template #tabContent let-tab>\n @if (tab.id === '__default__') {\n @if (ungroupedAttributes().length > 0) {\n <bs-card class=\"d-block m-3\">\n <div class=\"p-3\">\n @for (attr of ungroupedAttributes(); track attr.id) {\n <ng-container *ngTemplateOutlet=\"attrField; context: { $implicit: attr }\"></ng-container>\n }\n </div>\n </bs-card>\n }\n }\n @for (group of groupsForTab(tab); track group.id) {\n @if (attrsForGroup(group); as groupAttrs) {\n @if (groupAttrs.length > 0) {\n <bs-card class=\"d-block m-3\">\n @if (group.label) {\n <bs-card-header>{{ group.label | resolveTranslation:group.name }}</bs-card-header>\n }\n <div class=\"p-3\">\n @for (attr of groupAttrs; track attr.id) {\n <ng-container *ngTemplateOutlet=\"attrField; context: { $implicit: attr }\"></ng-container>\n }\n </div>\n </bs-card>\n }\n }\n }\n </ng-template>\n\n <ng-template #attrField let-attr>\n <div bsRow class=\"mb-3\">\n <label [md]=\"4\" bsColFormLabel [for]=\"attr.name\">\n {{ attr.label | resolveTranslation:attr.name }}\n @if (attr.isRequired) {\n <span class=\"text-danger\">*</span>\n }\n </label>\n <div [md]=\"8\">\n @if (attr.dataType === 'boolean') {\n <bs-toggle-button\n [ngModel]=\"formData()[attr.name]\"\n (ngModelChange)=\"formData()[attr.name] = $event; onFieldChange()\">\n </bs-toggle-button>\n } @else if (attr.lookupReferenceType) {\n @if ((attr | lookupDisplayType:lookupReferenceOptions()) === ELookupDisplayType.Modal) {\n <bs-input-group>\n <input\n type=\"text\"\n [id]=\"attr.name\"\n [value]=\"attr | lookupDisplayValue:formData():lookupReferenceOptions()\"\n readonly\n [class.is-invalid]=\"hasError(attr.name)\">\n <button\n type=\"button\"\n bsInputGroupBtn\n [color]=\"colors.secondary\"\n (click)=\"openLookupSelector(attr)\">\n ...\n </button>\n </bs-input-group>\n } @else {\n <bs-select\n [ngModel]=\"formData()[attr.name]\"\n (ngModelChange)=\"formData()[attr.name] = $event; onFieldChange()\"\n [id]=\"attr.name\"\n [class.is-invalid]=\"hasError(attr.name)\">\n <option [ngValue]=\"null\">{{ 'common.selectPlaceholder' | t }}</option>\n @for (option of (attr | lookupOptions:lookupReferenceOptions()); track option.key) {\n <option [ngValue]=\"option.key\">\n {{ option.values | resolveTranslation:option.key }}\n </option>\n }\n </bs-select>\n }\n } @else if (attr.dataType === 'Reference') {\n <bs-input-group>\n <input\n type=\"text\"\n [id]=\"attr.name\"\n [value]=\"attr | referenceDisplayValue:formData():referenceOptions()\"\n readonly\n [class.is-invalid]=\"hasError(attr.name)\">\n <button\n type=\"button\"\n bsInputGroupBtn\n [color]=\"colors.secondary\"\n (click)=\"openReferenceSelector(attr)\">\n ...\n </button>\n </bs-input-group>\n } @else if (attr.dataType === 'AsDetail' && attr.isArray && attr.editMode === 'inline') {\n <bs-table [isResponsive]=\"true\" class=\"mb-1\">\n <thead>\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <th>{{ col.label | resolveTranslation:col.name }}</th>\n }\n <th style=\"width: 50px\"></th>\n </tr>\n </thead>\n <tbody class=\"align-middle\">\n @for (row of formData()[attr.name] || []; track $index) {\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <td>\n @if (col.dataType === 'boolean') {\n <bs-toggle-button\n [(ngModel)]=\"row[col.name]\"\n (ngModelChange)=\"onFieldChange()\">\n </bs-toggle-button>\n } @else if (col.dataType === 'Reference' && col.query) {\n <bs-select\n [(ngModel)]=\"row[col.name]\"\n (ngModelChange)=\"onFieldChange()\">\n <option [ngValue]=\"null\">{{ 'common.selectPlaceholder' | t }}</option>\n @for (option of (attr | inlineRefOptions:col:asDetailReferenceOptions()); track option.id) {\n <option [ngValue]=\"option.id\">\n {{ option.breadcrumb || option.name || option.id }}\n </option>\n }\n </bs-select>\n } @else {\n <input\n [type]=\"col.dataType | inputType\"\n [(ngModel)]=\"row[col.name]\"\n [required]=\"col.isRequired\"\n [step]=\"col.dataType === 'decimal' ? '0.01' : '1'\"\n (ngModelChange)=\"onFieldChange()\">\n }\n </td>\n }\n <td class=\"text-nowrap\">\n @if (attr | canDeleteDetailRow:asDetailPermissions()) {\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"removeArrayItem(attr, $index)\">\n <spark-icon name=\"trash\" />\n </button>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td [attr.colspan]=\"(attr | asDetailColumns:asDetailTypes()).length + 1\" class=\"text-center text-muted\">\n {{ 'common.noItemsFound' | t }}\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n @if (attr | canCreateDetailRow:asDetailPermissions()) {\n <button type=\"button\" [color]=\"colors.primary\" class=\"w-100 rounded-0\" (click)=\"addInlineRow(attr)\">\n <spark-icon name=\"plus\" /> {{ 'common.add' | t }}\n </button>\n }\n } @else if (attr.dataType === 'AsDetail' && attr.isArray) {\n <bs-table [isResponsive]=\"true\" class=\"mb-1\">\n <thead>\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <th>{{ col.label | resolveTranslation:col.name }}</th>\n }\n <th style=\"width: 80px\"></th>\n </tr>\n </thead>\n <tbody class=\"align-middle\">\n @for (row of formData()[attr.name] || []; track $index) {\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <td>{{ row | asDetailCellValue:attr:col:asDetailReferenceOptions() }}</td>\n }\n <td class=\"text-nowrap\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary me-1\" (click)=\"editArrayItem(attr, $index)\">\n <spark-icon name=\"pencil\" />\n </button>\n @if (attr | canDeleteDetailRow:asDetailPermissions()) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeArrayItem(attr, $index)\">\n <spark-icon name=\"trash\" />\n </button>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td [attr.colspan]=\"(attr | asDetailColumns:asDetailTypes()).length + 1\" class=\"text-center text-muted\">\n {{ 'common.noItemsFound' | t }}\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n @if (attr | canCreateDetailRow:asDetailPermissions()) {\n <button type=\"button\" [color]=\"colors.primary\" class=\"w-100 rounded-0\" (click)=\"addArrayItem(attr)\">\n <spark-icon name=\"plus\" /> {{ 'common.add' | t }}\n </button>\n }\n } @else if (attr.dataType === 'AsDetail') {\n <bs-input-group>\n <input\n type=\"text\"\n [id]=\"attr.name\"\n [value]=\"attr | asDetailDisplayValue:formData():asDetailTypes()\"\n readonly\n [class.is-invalid]=\"hasError(attr.name)\">\n <button\n type=\"button\"\n bsInputGroupBtn\n [color]=\"colors.secondary\"\n (click)=\"openAsDetailEditor(attr)\">\n <spark-icon name=\"pencil\" />\n </button>\n </bs-input-group>\n } @else if (getEditRendererComponent(attr); as editComp) {\n <ng-container *ngComponentOutlet=\"editComp; inputs: getEditRendererInputs(attr)\"></ng-container>\n } @else {\n <input\n [type]=\"attr.dataType | inputType\"\n [id]=\"attr.name\"\n [ngModel]=\"formData()[attr.name]\"\n (ngModelChange)=\"formData()[attr.name] = $event; onFieldChange()\"\n [name]=\"attr.name\"\n [required]=\"attr.isRequired\"\n [step]=\"attr.dataType === 'decimal' ? '0.01' : '1'\"\n [class.is-invalid]=\"hasError(attr.name)\">\n }\n @if (attr.name | errorForAttribute:validationErrors(); as errorMsg) {\n <div class=\"invalid-feedback d-block\">\n {{ errorMsg }}\n </div>\n }\n </div>\n </div>\n </ng-template>\n\n @if (showButtons()) {\n <div bsRow class=\"mt-4\">\n <div [md]=\"4\"></div>\n <div [md]=\"8\" class=\"d-flex justify-content-end gap-2\">\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"onCancel()\" [disabled]=\"isSaving()\">{{ 'common.cancel' | t }}</button>\n <button type=\"submit\" [color]=\"colors.primary\" [disabled]=\"isSaving()\" (click)=\"onSave()\">\n @if (isSaving()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'common.save' | t }}\n </button>\n </div>\n </div>\n }\n </bs-grid>\n}\n\n<!-- Modal for editing AsDetail objects -->\n<bs-modal [isOpen]=\"showAsDetailModal()\" (isOpenChange)=\"!$event && closeAsDetailModal()\">\n <div *bsModal>\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ 'common.edit' | t }} {{ editingAsDetailAttr()?.label | resolveTranslation:editingAsDetailAttr()?.name }}</h5>\n </div>\n\n @if (editingAsDetailAttr(); as attr) {\n <div bsModalBody>\n <spark-po-form\n [entityType]=\"attr | asDetailType:asDetailTypes()\"\n [(formData)]=\"asDetailFormData\"\n [parentId]=\"parentId()\"\n [parentType]=\"parentType()\">\n </spark-po-form>\n </div>\n }\n\n <div bsModalFooter>\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"closeAsDetailModal()\">{{ 'common.cancel' | t }}</button>\n <button type=\"button\" [color]=\"colors.primary\" (click)=\"saveAsDetailObject()\">{{ 'common.save' | t }}</button>\n </div>\n </div>\n</bs-modal>\n\n<!-- Modal for selecting Reference items -->\n<bs-modal [isOpen]=\"showReferenceModal()\" (isOpenChange)=\"!$event && closeReferenceModal()\">\n <div *bsModal class=\"reference-modal\">\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ 'common.select' | t }} {{ editingReferenceAttr()?.label | resolveTranslation:editingReferenceAttr()?.name }}</h5>\n </div>\n\n <div bsModalBody>\n @if (referenceModalEntityType()) {\n <!-- Search box -->\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [md]=\"6\">\n <bs-input-group>\n <span class=\"input-group-text\">\n <spark-icon name=\"search\" />\n </span>\n <input\n type=\"text\"\n [placeholder]=\"'common.search' | t\"\n [(ngModel)]=\"referenceSearchTerm\"\n (ngModelChange)=\"onReferenceSearchChange()\">\n @if (referenceSearchTerm) {\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"clearReferenceSearch()\">\n <spark-icon name=\"x-lg\" />\n </button>\n }\n </bs-input-group>\n </div>\n <div [md]=\"6\" class=\"text-end\">\n @if (referenceSearchTerm && referenceModalPagination()) {\n <span class=\"text-muted\">\n {{ referenceModalPagination()!.totalRecords }} {{ referenceModalPagination()!.totalRecords === 1 ? ('common.resultFound' | t) : ('common.resultsFound' | t) }}\n </span>\n }\n </div>\n </div>\n </bs-grid>\n\n <bs-datatable [(settings)]=\"referenceModalSettings\" (settingsChange)=\"applyReferenceFilter()\">\n @for (attr of referenceVisibleAttributes(); track attr.id) {\n <div *bsDatatableColumn=\"attr.name; sortable: true\">\n {{ attr.label | resolveTranslation:attr.name }}\n </div>\n }\n\n <tr *bsRowTemplate=\"let item of referenceModalPagination()\" (click)=\"selectReferenceItem(item)\" style=\"cursor: pointer;\">\n @for (attr of referenceVisibleAttributes(); track attr.id) {\n <td>{{ item | referenceAttrValue:attr.name }}</td>\n }\n </tr>\n </bs-datatable>\n } @else {\n <div class=\"text-center p-3\">\n <bs-spinner />\n </div>\n }\n </div>\n\n <div bsModalFooter>\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"closeReferenceModal()\">{{ 'common.cancel' | t }}</button>\n </div>\n </div>\n</bs-modal>\n\n<!-- Modal for selecting LookupReference items -->\n<bs-modal [isOpen]=\"showLookupModal()\" (isOpenChange)=\"!$event && closeLookupModal()\">\n <div *bsModal>\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ 'common.select' | t }} {{ editingLookupAttr()?.label | resolveTranslation:editingLookupAttr()?.name }}</h5>\n </div>\n\n <div bsModalBody>\n <!-- Search box -->\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [col]>\n <bs-input-group>\n <span class=\"input-group-text\">\n <spark-icon name=\"search\" />\n </span>\n <input\n type=\"text\"\n [placeholder]=\"'common.search' | t\"\n [ngModel]=\"lookupSearchTerm()\"\n (ngModelChange)=\"lookupSearchTerm.set($event)\">\n @if (lookupSearchTerm()) {\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"lookupSearchTerm.set('')\">\n <spark-icon name=\"x-lg\" />\n </button>\n }\n </bs-input-group>\n </div>\n </div>\n </bs-grid>\n\n <!-- List of items -->\n <bs-table [striped]=\"true\" [hover]=\"true\">\n <tbody class=\"align-middle\">\n @for (item of filteredLookupItems(); track item.key) {\n <tr\n [class.table-primary]=\"formData()[editingLookupAttr()?.name ?? ''] === item.key\"\n (click)=\"selectLookupItem(item)\"\n style=\"cursor: pointer;\">\n <td>{{ item.values | resolveTranslation:item.key }}</td>\n </tr>\n } @empty {\n <tr>\n <td class=\"text-center text-muted\">{{ 'common.noItemsFound' | t }}</td>\n </tr>\n }\n </tbody>\n </bs-table>\n </div>\n\n <div bsModalFooter>\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"closeLookupModal()\">{{ 'common.cancel' | t }}</button>\n </div>\n </div>\n</bs-modal>\n</bs-form>\n", dependencies: [{ kind: "component", type: SparkPoFormComponent, selector: "spark-po-form", inputs: ["entityType", "formData", "validationErrors", "showButtons", "isSaving", "parentId", "parentType"], outputs: ["formDataChange", "save", "cancel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BsCardComponent, selector: "bs-card", inputs: ["rounded"] }, { kind: "component", type: BsCardHeaderComponent, selector: "bs-card-header", inputs: ["noPadding"] }, { kind: "component", type: BsFormComponent, selector: "bs-form", inputs: ["action", "method"], outputs: ["submitted"] }, { kind: "directive", type: BsFormControlDirective, selector: "bs-form input:not(.no-form-control), bs-form textarea:not(.no-form-control)" }, { kind: "component", type: BsGridComponent, selector: "bs-grid", inputs: ["stopFullWidthAt"] }, { kind: "directive", type: BsGridRowDirective, selector: "[bsRow]" }, { kind: "directive", type: BsGridColumnDirective, selector: "[xxs],[xs],[sm],[md],[lg],[xl],[xxl]", inputs: ["xxs", "xs", "sm", "md", "lg", "xl", "xxl"] }, { kind: "directive", type: BsGridColDirective, selector: "[col]", inputs: ["col"] }, { kind: "directive", type: BsColFormLabelDirective, selector: "[bsColFormLabel]" }, { kind: "directive", type: BsButtonTypeDirective, selector: "button[color],input[type=\"button\"][color],input[type=\"submit\"][color],a[color]", inputs: ["color"] }, { kind: "component", type: BsInputGroupComponent, selector: "bs-input-group" }, { kind: "component", type: BsSelectComponent, selector: "bs-select", inputs: ["identifier", "size", "multiple", "numberVisible", "disabled"] }, { kind: "directive", type: BsSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "component", type: BsModalHostComponent, selector: "bs-modal", inputs: ["isOpen", "closeOnEscape"], outputs: ["isOpenChange"] }, { kind: "directive", type: BsModalDirective, selector: "[bsModal]" }, { kind: "directive", type: BsModalHeaderDirective, selector: "[bsModalHeader]" }, { kind: "directive", type: BsModalBodyDirective, selector: "[bsModalBody]" }, { kind: "directive", type: BsModalFooterDirective, selector: "[bsModalFooter]" }, { kind: "component", type: BsDatatableComponent, selector: "bs-datatable", inputs: ["data"], outputs: ["dataChange"] }, { kind: "directive", type: BsDatatableColumnDirective, selector: "[bsDatatableColumn]", inputs: ["bsDatatableColumn", "bsDatatableColumnSortable"] }, { kind: "directive", type: BsRowTemplateDirective, selector: "[bsRowTemplate]", inputs: ["bsRowTemplateOf"] }, { kind: "component", type: BsTableComponent, selector: "bs-table", inputs: ["isResponsive", "striped", "hover"] }, { kind: "component", type: BsToggleButtonComponent, selector: "bs-toggle-button", inputs: ["type", "isToggled", "name", "value", "group"], outputs: ["isToggledChange"] }, { kind: "component", type: BsSpinnerComponent, selector: "bs-spinner", inputs: ["type", "color"] }, { kind: "component", type: BsTabControlComponent, selector: "bs-tab-control", inputs: ["border", "restrictDragging", "selectFirstTab", "tabsPosition", "allowDragDrop"] }, { kind: "component", type: BsTabPageComponent, selector: "bs-tab-page", inputs: ["disabled"] }, { kind: "directive", type: BsTabPageHeaderDirective, selector: "[bsTabPageHeader]" }, { kind: "component", type: SparkIconComponent, selector: "spark-icon", inputs: ["name"] }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }, { kind: "pipe", type: ResolveTranslationPipe, name: "resolveTranslation" }, { kind: "pipe", type: InputTypePipe, name: "inputType" }, { kind: "pipe", type: LookupDisplayValuePipe, name: "lookupDisplayValue" }, { kind: "pipe", type: LookupDisplayTypePipe, name: "lookupDisplayType" }, { kind: "pipe", type: LookupOptionsPipe, name: "lookupOptions" }, { kind: "pipe", type: ReferenceDisplayValuePipe, name: "referenceDisplayValue" }, { kind: "pipe", type: AsDetailDisplayValuePipe, name: "asDetailDisplayValue" }, { kind: "pipe", type: AsDetailTypePipe, name: "asDetailType" }, { kind: "pipe", type: AsDetailColumnsPipe, name: "asDetailColumns" }, { kind: "pipe", type: AsDetailCellValuePipe, name: "asDetailCellValue" }, { kind: "pipe", type: CanCreateDetailRowPipe, name: "canCreateDetailRow" }, { kind: "pipe", type: CanDeleteDetailRowPipe, name: "canDeleteDetailRow" }, { kind: "pipe", type: InlineRefOptionsPipe, name: "inlineRefOptions" }, { kind: "pipe", type: ReferenceAttrValuePipe, name: "referenceAttrValue" }, { kind: "pipe", type: ErrorForAttributePipe, name: "errorForAttribute" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
382
+ }
383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.6", ngImport: i0, type: SparkPoFormComponent, decorators: [{
384
+ type: Component,
385
+ args: [{ selector: 'spark-po-form', imports: [CommonModule, NgTemplateOutlet, NgComponentOutlet, FormsModule, BsCardComponent, BsCardHeaderComponent, BsFormComponent, BsFormControlDirective, BsGridComponent, BsGridRowDirective, BsGridColumnDirective, BsGridColDirective, BsColFormLabelDirective, BsButtonTypeDirective, BsInputGroupComponent, BsSelectComponent, BsSelectOption, BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective, BsDatatableComponent, BsDatatableColumnDirective, BsRowTemplateDirective, BsTableComponent, BsToggleButtonComponent, BsSpinnerComponent, BsTabControlComponent, BsTabPageComponent, BsTabPageHeaderDirective, SparkIconComponent, SparkPoFormComponent, TranslateKeyPipe, ResolveTranslationPipe, InputTypePipe, LookupDisplayValuePipe, LookupDisplayTypePipe, LookupOptionsPipe, ReferenceDisplayValuePipe, AsDetailDisplayValuePipe, AsDetailTypePipe, AsDetailColumnsPipe, AsDetailCellValuePipe, CanCreateDetailRowPipe, CanDeleteDetailRowPipe, InlineRefOptionsPipe, ReferenceAttrValuePipe, ErrorForAttributePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<bs-form>\n @if (entityType()) {\n <bs-grid>\n <bs-tab-control>\n @for (tab of resolvedTabs(); track tab.id) {\n <bs-tab-page>\n <ng-template bsTabPageHeader>{{ tab.label | resolveTranslation:tab.name }}</ng-template>\n <ng-container *ngTemplateOutlet=\"tabContent; context: { $implicit: tab }\"></ng-container>\n </bs-tab-page>\n }\n </bs-tab-control>\n\n <ng-template #tabContent let-tab>\n @if (tab.id === '__default__') {\n @if (ungroupedAttributes().length > 0) {\n <bs-card class=\"d-block m-3\">\n <div class=\"p-3\">\n @for (attr of ungroupedAttributes(); track attr.id) {\n <ng-container *ngTemplateOutlet=\"attrField; context: { $implicit: attr }\"></ng-container>\n }\n </div>\n </bs-card>\n }\n }\n @for (group of groupsForTab(tab); track group.id) {\n @if (attrsForGroup(group); as groupAttrs) {\n @if (groupAttrs.length > 0) {\n <bs-card class=\"d-block m-3\">\n @if (group.label) {\n <bs-card-header>{{ group.label | resolveTranslation:group.name }}</bs-card-header>\n }\n <div class=\"p-3\">\n @for (attr of groupAttrs; track attr.id) {\n <ng-container *ngTemplateOutlet=\"attrField; context: { $implicit: attr }\"></ng-container>\n }\n </div>\n </bs-card>\n }\n }\n }\n </ng-template>\n\n <ng-template #attrField let-attr>\n <div bsRow class=\"mb-3\">\n <label [md]=\"4\" bsColFormLabel [for]=\"attr.name\">\n {{ attr.label | resolveTranslation:attr.name }}\n @if (attr.isRequired) {\n <span class=\"text-danger\">*</span>\n }\n </label>\n <div [md]=\"8\">\n @if (attr.dataType === 'boolean') {\n <bs-toggle-button\n [ngModel]=\"formData()[attr.name]\"\n (ngModelChange)=\"formData()[attr.name] = $event; onFieldChange()\">\n </bs-toggle-button>\n } @else if (attr.lookupReferenceType) {\n @if ((attr | lookupDisplayType:lookupReferenceOptions()) === ELookupDisplayType.Modal) {\n <bs-input-group>\n <input\n type=\"text\"\n [id]=\"attr.name\"\n [value]=\"attr | lookupDisplayValue:formData():lookupReferenceOptions()\"\n readonly\n [class.is-invalid]=\"hasError(attr.name)\">\n <button\n type=\"button\"\n bsInputGroupBtn\n [color]=\"colors.secondary\"\n (click)=\"openLookupSelector(attr)\">\n ...\n </button>\n </bs-input-group>\n } @else {\n <bs-select\n [ngModel]=\"formData()[attr.name]\"\n (ngModelChange)=\"formData()[attr.name] = $event; onFieldChange()\"\n [id]=\"attr.name\"\n [class.is-invalid]=\"hasError(attr.name)\">\n <option [ngValue]=\"null\">{{ 'common.selectPlaceholder' | t }}</option>\n @for (option of (attr | lookupOptions:lookupReferenceOptions()); track option.key) {\n <option [ngValue]=\"option.key\">\n {{ option.values | resolveTranslation:option.key }}\n </option>\n }\n </bs-select>\n }\n } @else if (attr.dataType === 'Reference') {\n <bs-input-group>\n <input\n type=\"text\"\n [id]=\"attr.name\"\n [value]=\"attr | referenceDisplayValue:formData():referenceOptions()\"\n readonly\n [class.is-invalid]=\"hasError(attr.name)\">\n <button\n type=\"button\"\n bsInputGroupBtn\n [color]=\"colors.secondary\"\n (click)=\"openReferenceSelector(attr)\">\n ...\n </button>\n </bs-input-group>\n } @else if (attr.dataType === 'AsDetail' && attr.isArray && attr.editMode === 'inline') {\n <bs-table [isResponsive]=\"true\" class=\"mb-1\">\n <thead>\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <th>{{ col.label | resolveTranslation:col.name }}</th>\n }\n <th style=\"width: 50px\"></th>\n </tr>\n </thead>\n <tbody class=\"align-middle\">\n @for (row of formData()[attr.name] || []; track $index) {\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <td>\n @if (col.dataType === 'boolean') {\n <bs-toggle-button\n [(ngModel)]=\"row[col.name]\"\n (ngModelChange)=\"onFieldChange()\">\n </bs-toggle-button>\n } @else if (col.dataType === 'Reference' && col.query) {\n <bs-select\n [(ngModel)]=\"row[col.name]\"\n (ngModelChange)=\"onFieldChange()\">\n <option [ngValue]=\"null\">{{ 'common.selectPlaceholder' | t }}</option>\n @for (option of (attr | inlineRefOptions:col:asDetailReferenceOptions()); track option.id) {\n <option [ngValue]=\"option.id\">\n {{ option.breadcrumb || option.name || option.id }}\n </option>\n }\n </bs-select>\n } @else {\n <input\n [type]=\"col.dataType | inputType\"\n [(ngModel)]=\"row[col.name]\"\n [required]=\"col.isRequired\"\n [step]=\"col.dataType === 'decimal' ? '0.01' : '1'\"\n (ngModelChange)=\"onFieldChange()\">\n }\n </td>\n }\n <td class=\"text-nowrap\">\n @if (attr | canDeleteDetailRow:asDetailPermissions()) {\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"removeArrayItem(attr, $index)\">\n <spark-icon name=\"trash\" />\n </button>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td [attr.colspan]=\"(attr | asDetailColumns:asDetailTypes()).length + 1\" class=\"text-center text-muted\">\n {{ 'common.noItemsFound' | t }}\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n @if (attr | canCreateDetailRow:asDetailPermissions()) {\n <button type=\"button\" [color]=\"colors.primary\" class=\"w-100 rounded-0\" (click)=\"addInlineRow(attr)\">\n <spark-icon name=\"plus\" /> {{ 'common.add' | t }}\n </button>\n }\n } @else if (attr.dataType === 'AsDetail' && attr.isArray) {\n <bs-table [isResponsive]=\"true\" class=\"mb-1\">\n <thead>\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <th>{{ col.label | resolveTranslation:col.name }}</th>\n }\n <th style=\"width: 80px\"></th>\n </tr>\n </thead>\n <tbody class=\"align-middle\">\n @for (row of formData()[attr.name] || []; track $index) {\n <tr>\n @for (col of (attr | asDetailColumns:asDetailTypes()); track col.name) {\n <td>{{ row | asDetailCellValue:attr:col:asDetailReferenceOptions() }}</td>\n }\n <td class=\"text-nowrap\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary me-1\" (click)=\"editArrayItem(attr, $index)\">\n <spark-icon name=\"pencil\" />\n </button>\n @if (attr | canDeleteDetailRow:asDetailPermissions()) {\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeArrayItem(attr, $index)\">\n <spark-icon name=\"trash\" />\n </button>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td [attr.colspan]=\"(attr | asDetailColumns:asDetailTypes()).length + 1\" class=\"text-center text-muted\">\n {{ 'common.noItemsFound' | t }}\n </td>\n </tr>\n }\n </tbody>\n </bs-table>\n @if (attr | canCreateDetailRow:asDetailPermissions()) {\n <button type=\"button\" [color]=\"colors.primary\" class=\"w-100 rounded-0\" (click)=\"addArrayItem(attr)\">\n <spark-icon name=\"plus\" /> {{ 'common.add' | t }}\n </button>\n }\n } @else if (attr.dataType === 'AsDetail') {\n <bs-input-group>\n <input\n type=\"text\"\n [id]=\"attr.name\"\n [value]=\"attr | asDetailDisplayValue:formData():asDetailTypes()\"\n readonly\n [class.is-invalid]=\"hasError(attr.name)\">\n <button\n type=\"button\"\n bsInputGroupBtn\n [color]=\"colors.secondary\"\n (click)=\"openAsDetailEditor(attr)\">\n <spark-icon name=\"pencil\" />\n </button>\n </bs-input-group>\n } @else if (getEditRendererComponent(attr); as editComp) {\n <ng-container *ngComponentOutlet=\"editComp; inputs: getEditRendererInputs(attr)\"></ng-container>\n } @else {\n <input\n [type]=\"attr.dataType | inputType\"\n [id]=\"attr.name\"\n [ngModel]=\"formData()[attr.name]\"\n (ngModelChange)=\"formData()[attr.name] = $event; onFieldChange()\"\n [name]=\"attr.name\"\n [required]=\"attr.isRequired\"\n [step]=\"attr.dataType === 'decimal' ? '0.01' : '1'\"\n [class.is-invalid]=\"hasError(attr.name)\">\n }\n @if (attr.name | errorForAttribute:validationErrors(); as errorMsg) {\n <div class=\"invalid-feedback d-block\">\n {{ errorMsg }}\n </div>\n }\n </div>\n </div>\n </ng-template>\n\n @if (showButtons()) {\n <div bsRow class=\"mt-4\">\n <div [md]=\"4\"></div>\n <div [md]=\"8\" class=\"d-flex justify-content-end gap-2\">\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"onCancel()\" [disabled]=\"isSaving()\">{{ 'common.cancel' | t }}</button>\n <button type=\"submit\" [color]=\"colors.primary\" [disabled]=\"isSaving()\" (click)=\"onSave()\">\n @if (isSaving()) {\n <bs-spinner class=\"me-1\" />\n }\n {{ 'common.save' | t }}\n </button>\n </div>\n </div>\n }\n </bs-grid>\n}\n\n<!-- Modal for editing AsDetail objects -->\n<bs-modal [isOpen]=\"showAsDetailModal()\" (isOpenChange)=\"!$event && closeAsDetailModal()\">\n <div *bsModal>\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ 'common.edit' | t }} {{ editingAsDetailAttr()?.label | resolveTranslation:editingAsDetailAttr()?.name }}</h5>\n </div>\n\n @if (editingAsDetailAttr(); as attr) {\n <div bsModalBody>\n <spark-po-form\n [entityType]=\"attr | asDetailType:asDetailTypes()\"\n [(formData)]=\"asDetailFormData\"\n [parentId]=\"parentId()\"\n [parentType]=\"parentType()\">\n </spark-po-form>\n </div>\n }\n\n <div bsModalFooter>\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"closeAsDetailModal()\">{{ 'common.cancel' | t }}</button>\n <button type=\"button\" [color]=\"colors.primary\" (click)=\"saveAsDetailObject()\">{{ 'common.save' | t }}</button>\n </div>\n </div>\n</bs-modal>\n\n<!-- Modal for selecting Reference items -->\n<bs-modal [isOpen]=\"showReferenceModal()\" (isOpenChange)=\"!$event && closeReferenceModal()\">\n <div *bsModal class=\"reference-modal\">\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ 'common.select' | t }} {{ editingReferenceAttr()?.label | resolveTranslation:editingReferenceAttr()?.name }}</h5>\n </div>\n\n <div bsModalBody>\n @if (referenceModalEntityType()) {\n <!-- Search box -->\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [md]=\"6\">\n <bs-input-group>\n <span class=\"input-group-text\">\n <spark-icon name=\"search\" />\n </span>\n <input\n type=\"text\"\n [placeholder]=\"'common.search' | t\"\n [(ngModel)]=\"referenceSearchTerm\"\n (ngModelChange)=\"onReferenceSearchChange()\">\n @if (referenceSearchTerm) {\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"clearReferenceSearch()\">\n <spark-icon name=\"x-lg\" />\n </button>\n }\n </bs-input-group>\n </div>\n <div [md]=\"6\" class=\"text-end\">\n @if (referenceSearchTerm && referenceModalPagination()) {\n <span class=\"text-muted\">\n {{ referenceModalPagination()!.totalRecords }} {{ referenceModalPagination()!.totalRecords === 1 ? ('common.resultFound' | t) : ('common.resultsFound' | t) }}\n </span>\n }\n </div>\n </div>\n </bs-grid>\n\n <bs-datatable [(settings)]=\"referenceModalSettings\" (settingsChange)=\"applyReferenceFilter()\">\n @for (attr of referenceVisibleAttributes(); track attr.id) {\n <div *bsDatatableColumn=\"attr.name; sortable: true\">\n {{ attr.label | resolveTranslation:attr.name }}\n </div>\n }\n\n <tr *bsRowTemplate=\"let item of referenceModalPagination()\" (click)=\"selectReferenceItem(item)\" style=\"cursor: pointer;\">\n @for (attr of referenceVisibleAttributes(); track attr.id) {\n <td>{{ item | referenceAttrValue:attr.name }}</td>\n }\n </tr>\n </bs-datatable>\n } @else {\n <div class=\"text-center p-3\">\n <bs-spinner />\n </div>\n }\n </div>\n\n <div bsModalFooter>\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"closeReferenceModal()\">{{ 'common.cancel' | t }}</button>\n </div>\n </div>\n</bs-modal>\n\n<!-- Modal for selecting LookupReference items -->\n<bs-modal [isOpen]=\"showLookupModal()\" (isOpenChange)=\"!$event && closeLookupModal()\">\n <div *bsModal>\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ 'common.select' | t }} {{ editingLookupAttr()?.label | resolveTranslation:editingLookupAttr()?.name }}</h5>\n </div>\n\n <div bsModalBody>\n <!-- Search box -->\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [col]>\n <bs-input-group>\n <span class=\"input-group-text\">\n <spark-icon name=\"search\" />\n </span>\n <input\n type=\"text\"\n [placeholder]=\"'common.search' | t\"\n [ngModel]=\"lookupSearchTerm()\"\n (ngModelChange)=\"lookupSearchTerm.set($event)\">\n @if (lookupSearchTerm()) {\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary\"\n (click)=\"lookupSearchTerm.set('')\">\n <spark-icon name=\"x-lg\" />\n </button>\n }\n </bs-input-group>\n </div>\n </div>\n </bs-grid>\n\n <!-- List of items -->\n <bs-table [striped]=\"true\" [hover]=\"true\">\n <tbody class=\"align-middle\">\n @for (item of filteredLookupItems(); track item.key) {\n <tr\n [class.table-primary]=\"formData()[editingLookupAttr()?.name ?? ''] === item.key\"\n (click)=\"selectLookupItem(item)\"\n style=\"cursor: pointer;\">\n <td>{{ item.values | resolveTranslation:item.key }}</td>\n </tr>\n } @empty {\n <tr>\n <td class=\"text-center text-muted\">{{ 'common.noItemsFound' | t }}</td>\n </tr>\n }\n </tbody>\n </bs-table>\n </div>\n\n <div bsModalFooter>\n <button type=\"button\" [color]=\"colors.secondary\" (click)=\"closeLookupModal()\">{{ 'common.cancel' | t }}</button>\n </div>\n </div>\n</bs-modal>\n</bs-form>\n" }]
386
+ }], ctorParameters: () => [], propDecorators: { entityType: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityType", required: false }] }], formData: [{ type: i0.Input, args: [{ isSignal: true, alias: "formData", required: false }] }, { type: i0.Output, args: ["formDataChange"] }], validationErrors: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationErrors", required: false }] }], showButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showButtons", required: false }] }], isSaving: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSaving", required: false }] }], parentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentId", required: false }] }], parentType: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentType", required: false }] }], save: [{ type: i0.Output, args: ["save"] }], cancel: [{ type: i0.Output, args: ["cancel"] }] } });
387
+
388
+ /**
389
+ * Generated bundle index. Do not edit.
390
+ */
391
+
392
+ export { SparkPoFormComponent };
393
+ //# sourceMappingURL=mintplayer-ng-spark-po-form.mjs.map