@mintplayer/ng-spark 22.22.0 → 22.24.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 (68) hide show
  1. package/README.md +181 -0
  2. package/fesm2022/mintplayer-ng-spark-attribute-description.mjs +100 -47
  3. package/fesm2022/mintplayer-ng-spark-attribute-description.mjs.map +1 -1
  4. package/fesm2022/mintplayer-ng-spark-client-operations.mjs +308 -329
  5. package/fesm2022/mintplayer-ng-spark-client-operations.mjs.map +1 -1
  6. package/fesm2022/mintplayer-ng-spark-column-filter.mjs +175 -135
  7. package/fesm2022/mintplayer-ng-spark-column-filter.mjs.map +1 -1
  8. package/fesm2022/mintplayer-ng-spark-grid.mjs +2259 -1117
  9. package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
  10. package/fesm2022/mintplayer-ng-spark-history.mjs +611 -0
  11. package/fesm2022/mintplayer-ng-spark-history.mjs.map +1 -0
  12. package/fesm2022/mintplayer-ng-spark-icon.mjs +64 -27
  13. package/fesm2022/mintplayer-ng-spark-icon.mjs.map +1 -1
  14. package/fesm2022/mintplayer-ng-spark-models.mjs +365 -753
  15. package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
  16. package/fesm2022/mintplayer-ng-spark-moderation.mjs +1212 -0
  17. package/fesm2022/mintplayer-ng-spark-moderation.mjs.map +1 -0
  18. package/fesm2022/mintplayer-ng-spark-panels.mjs +52 -0
  19. package/fesm2022/mintplayer-ng-spark-panels.mjs.map +1 -0
  20. package/fesm2022/mintplayer-ng-spark-pipes.mjs +1122 -765
  21. package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
  22. package/fesm2022/mintplayer-ng-spark-po-create.mjs +273 -169
  23. package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -1
  24. package/fesm2022/mintplayer-ng-spark-po-detail.mjs +786 -410
  25. package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
  26. package/fesm2022/mintplayer-ng-spark-po-edit.mjs +292 -284
  27. package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
  28. package/fesm2022/mintplayer-ng-spark-po-form.mjs +2187 -1225
  29. package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
  30. package/fesm2022/mintplayer-ng-spark-query-list.mjs +516 -303
  31. package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
  32. package/fesm2022/mintplayer-ng-spark-renderers.mjs +17 -55
  33. package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
  34. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +216 -177
  35. package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
  36. package/fesm2022/mintplayer-ng-spark-routes.mjs +24 -28
  37. package/fesm2022/mintplayer-ng-spark-routes.mjs.map +1 -1
  38. package/fesm2022/mintplayer-ng-spark-services.mjs +625 -640
  39. package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
  40. package/fesm2022/mintplayer-ng-spark-shell.mjs +1013 -397
  41. package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
  42. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +294 -0
  43. package/fesm2022/mintplayer-ng-spark-soft-delete.mjs.map +1 -0
  44. package/fesm2022/mintplayer-ng-spark.mjs +13 -50
  45. package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
  46. package/package.json +17 -1
  47. package/types/mintplayer-ng-spark-attribute-description.d.ts +25 -18
  48. package/types/mintplayer-ng-spark-client-operations.d.ts +133 -160
  49. package/types/mintplayer-ng-spark-column-filter.d.ts +73 -55
  50. package/types/mintplayer-ng-spark-grid.d.ts +885 -448
  51. package/types/mintplayer-ng-spark-history.d.ts +223 -0
  52. package/types/mintplayer-ng-spark-icon.d.ts +15 -13
  53. package/types/mintplayer-ng-spark-models.d.ts +624 -573
  54. package/types/mintplayer-ng-spark-moderation.d.ts +402 -0
  55. package/types/mintplayer-ng-spark-panels.d.ts +108 -0
  56. package/types/mintplayer-ng-spark-pipes.d.ts +120 -149
  57. package/types/mintplayer-ng-spark-po-create.d.ts +46 -37
  58. package/types/mintplayer-ng-spark-po-detail.d.ts +177 -117
  59. package/types/mintplayer-ng-spark-po-edit.d.ts +64 -65
  60. package/types/mintplayer-ng-spark-po-form.d.ts +507 -371
  61. package/types/mintplayer-ng-spark-query-list.d.ts +118 -82
  62. package/types/mintplayer-ng-spark-renderers.d.ts +79 -85
  63. package/types/mintplayer-ng-spark-retry-action-modal.d.ts +31 -34
  64. package/types/mintplayer-ng-spark-routes.d.ts +7 -11
  65. package/types/mintplayer-ng-spark-services.d.ts +377 -261
  66. package/types/mintplayer-ng-spark-shell.d.ts +209 -128
  67. package/types/mintplayer-ng-spark-soft-delete.d.ts +90 -0
  68. package/types/mintplayer-ng-spark.d.ts +7 -12
@@ -1,110 +1,77 @@
1
- import * as i0 from '@angular/core';
2
- import { inject, computed, signal, effect, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { CommonModule } from '@angular/common';
4
- import { Color } from '@mintplayer/ng-bootstrap';
5
- import { BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective } from '@mintplayer/ng-bootstrap/modal';
6
- import { BsButtonTypeDirective } from '@mintplayer/ng-bootstrap/button-type';
7
- import { RetryActionService, SparkService } from '@mintplayer/ng-spark/services';
8
- import { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';
9
- import { nestedPoToDict, dictToNestedPo } from '@mintplayer/ng-spark/models';
10
-
11
- /**
12
- * Renders a retry-action popup. Before PRD §3 this component rendered title / message /
13
- * option buttons only and silently forwarded the incoming <c>persistentObject</c> back to
14
- * the server on submit — meaning any <c>Retry.Action(..., persistentObject)</c> flow had
15
- * no UI to actually edit the PO. This component now embeds the shared PO form so every
16
- * scalar / Reference / AsDetail attribute on the scaffolded Virtual PO is a real form
17
- * field, and the values the user fills in flow back to the server via
18
- * <c>RetryResult.PersistentObject</c>.
19
- */
20
- class SparkRetryActionModalComponent {
21
- retryActionService = inject(RetryActionService);
22
- sparkService = inject(SparkService);
23
- colors = Color;
24
- isOpen = computed(() => this.retryActionService.payload() !== null, /* @ts-ignore */
25
- ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
26
- /**
27
- * EntityType definition for the incoming PO — fetched lazily via SparkService so the
28
- * form knows which attributes are editable, their labels, rules, renderers, etc.
29
- * `null` when the payload has no persistentObject or its objectTypeId doesn't match
30
- * any registered entity type (renders the modal as a simple option picker).
31
- */
32
- entityType = signal(null, /* @ts-ignore */
33
- ...(ngDevMode ? [{ debugName: "entityType" }] : /* istanbul ignore next */ []));
34
- formData = signal({}, /* @ts-ignore */
35
- ...(ngDevMode ? [{ debugName: "formData" }] : /* istanbul ignore next */ []));
36
- allEntityTypes = [];
37
- constructor() {
38
- // Reseed form state every time the retry service opens/closes the modal. Effect
39
- // cleanup isn't needed since `payload` is a signal and the component's own lifetime
40
- // is root-scoped.
41
- effect(() => {
42
- const payload = this.retryActionService.payload();
43
- if (!payload?.persistentObject) {
44
- this.entityType.set(null);
45
- this.formData.set({});
46
- return;
47
- }
48
- void this.seedForm(payload.persistentObject);
49
- });
50
- }
51
- async seedForm(po) {
52
- // Virtual POs used for retry prompts (e.g. ConfirmDeleteCar) typically have no
53
- // security.json grant — so `getEntityTypes()` filters them out for the current user
54
- // and the lookup-by-id would return null, leaving the form blank. The scaffolded PO
55
- // already carries full attribute metadata (label / dataType / rules / renderer / etc.),
56
- // so we synthesize an EntityType from the attributes directly and skip the HTTP
57
- // lookup altogether. `getEntityTypes()` is still fetched because the embedded
58
- // spark-po-form needs the full list to resolve nested AsDetail / Reference types the
59
- // retry PO might point at. The guard below is a COMPONENT-local cache and is the only
60
- // one there is: the service does not cache, so every caller that skips such a guard
61
- // issues another request.
62
- if (this.allEntityTypes.length === 0) {
63
- try {
64
- this.allEntityTypes = await this.sparkService.getEntityTypes();
65
- }
66
- catch {
67
- this.allEntityTypes = [];
68
- }
69
- }
70
- this.entityType.set(entityTypeFromPo(po));
71
- // Flatten the nested PO into the Record<string, any> shape the shared form uses
72
- // throughout the rest of ng-spark — same transformation po-edit applies.
73
- this.formData.set(nestedPoToDict(po));
74
- }
75
- onOption(option) {
76
- const payload = this.retryActionService.payload();
77
- if (!payload)
78
- return;
79
- const populated = this.populatedPersistentObject(payload.persistentObject);
80
- this.retryActionService.respond({
81
- step: payload.step,
82
- option,
83
- persistentObject: populated,
84
- });
85
- }
86
- /**
87
- * Builds the PO the server sees under <c>Retry.Result.PersistentObject</c>. If the
88
- * form resolved an EntityType, rebuild from the schema + formData (identical to the
89
- * po-edit save path — AsDetail recursion included). Otherwise forward the incoming
90
- * PO unmodified so pre-§3 flows without editable attributes keep working.
91
- */
92
- populatedPersistentObject(incoming) {
93
- if (!incoming)
94
- return undefined;
95
- const type = this.entityType();
96
- if (!type)
97
- return incoming;
98
- const resolver = (clrName) => this.allEntityTypes.find(t => t.clrType === clrName);
99
- const rebuilt = dictToNestedPo(this.formData(), type, resolver);
100
- const populated = {
101
- ...incoming,
102
- attributes: mergeAttributeMetadata(incoming.attributes ?? [], rebuilt.attributes),
103
- };
104
- return populated;
105
- }
106
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SparkRetryActionModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
107
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: SparkRetryActionModalComponent, isStandalone: true, selector: "spark-retry-action-modal", ngImport: i0, template: `
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from "@angular/core";
3
+ import { CommonModule } from "@angular/common";
4
+ import { Color } from "@mintplayer/ng-bootstrap";
5
+ import { BsModalBodyDirective, BsModalDirective, BsModalFooterDirective, BsModalHeaderDirective, BsModalHostComponent } from "@mintplayer/ng-bootstrap/modal";
6
+ import { BsButtonTypeDirective } from "@mintplayer/ng-bootstrap/button-type";
7
+ import { RetryActionService, SparkService } from "@mintplayer/ng-spark/services";
8
+ import { SparkPoFormComponent } from "@mintplayer/ng-spark/po-form";
9
+ import { dictToNestedPo, nestedPoToDict } from "@mintplayer/ng-spark/models";
10
+ var SparkRetryActionModalComponent = class SparkRetryActionModalComponent {
11
+ retryActionService = inject(RetryActionService);
12
+ sparkService = inject(SparkService);
13
+ colors = Color;
14
+ isOpen = computed(() => this.retryActionService.payload() !== null, ...ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []);
15
+ entityType = signal(null, ...ngDevMode ? [{ debugName: "entityType" }] : /* istanbul ignore next */ []);
16
+ formData = signal({}, ...ngDevMode ? [{ debugName: "formData" }] : /* istanbul ignore next */ []);
17
+ allEntityTypes = [];
18
+ constructor() {
19
+ effect(() => {
20
+ const payload = this.retryActionService.payload();
21
+ if (!payload?.persistentObject) {
22
+ this.entityType.set(null);
23
+ this.formData.set({});
24
+ return;
25
+ }
26
+ this.seedForm(payload.persistentObject);
27
+ });
28
+ }
29
+ async seedForm(po) {
30
+ if (this.allEntityTypes.length === 0) try {
31
+ this.allEntityTypes = await this.sparkService.getEntityTypes();
32
+ } catch {
33
+ this.allEntityTypes = [];
34
+ }
35
+ this.entityType.set(entityTypeFromPo(po));
36
+ this.formData.set(nestedPoToDict(po));
37
+ }
38
+ onOption(option) {
39
+ const payload = this.retryActionService.payload();
40
+ if (!payload) return;
41
+ const populated = this.populatedPersistentObject(payload.persistentObject);
42
+ this.retryActionService.respond({
43
+ step: payload.step,
44
+ option,
45
+ persistentObject: populated
46
+ });
47
+ }
48
+ populatedPersistentObject(incoming) {
49
+ if (!incoming) return void 0;
50
+ const type = this.entityType();
51
+ if (!type) return incoming;
52
+ const resolver = (clrName) => this.allEntityTypes.find((t) => t.clrType === clrName);
53
+ const rebuilt = dictToNestedPo(this.formData(), type, resolver);
54
+ return {
55
+ ...incoming,
56
+ attributes: mergeAttributeMetadata(incoming.attributes ?? [], rebuilt.attributes)
57
+ };
58
+ }
59
+ static ɵfac = i0.ɵɵngDeclareFactory({
60
+ minVersion: "12.0.0",
61
+ version: "22.2.0",
62
+ ngImport: i0,
63
+ type: SparkRetryActionModalComponent,
64
+ deps: [],
65
+ target: i0.ɵɵFactoryTarget.Component
66
+ });
67
+ static ɵcmp = i0.ɵɵngDeclareComponent({
68
+ minVersion: "17.0.0",
69
+ version: "22.2.0",
70
+ type: SparkRetryActionModalComponent,
71
+ isStandalone: true,
72
+ selector: "spark-retry-action-modal",
73
+ ngImport: i0,
74
+ template: `
108
75
  <bs-modal [isOpen]="isOpen()" (isOpenChange)="!$event && onOption('Cancel')">
109
76
  <div *bsModal>
110
77
  <div bsModalHeader>
@@ -134,14 +101,100 @@ class SparkRetryActionModalComponent {
134
101
  </div>
135
102
  </div>
136
103
  </bs-modal>
137
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BsModalHostComponent, selector: "bs-modal", inputs: ["isOpen", "closeOnEscape", "scrollable"], 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: "directive", type: BsButtonTypeDirective, selector: "button[color],input[type=\"button\"][color],input[type=\"submit\"][color],a[color]", inputs: ["color"] }, { kind: "component", type: SparkPoFormComponent, selector: "spark-po-form", inputs: ["entityType", "formData", "validationErrors", "showButtons", "isSaving", "parentId", "parentType", "objectTypeId", "objectId", "triggerPathPrefix", "refreshOverlay"], outputs: ["formDataChange", "save", "cancel", "nestedTriggerRequested", "nestedTriggerBlurred", "refreshOverlayChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
138
- }
139
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SparkRetryActionModalComponent, decorators: [{
140
- type: Component,
141
- args: [{
142
- selector: 'spark-retry-action-modal',
143
- imports: [CommonModule, BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective, BsButtonTypeDirective, SparkPoFormComponent],
144
- template: `
104
+ `,
105
+ isInline: true,
106
+ dependencies: [
107
+ {
108
+ kind: "ngmodule",
109
+ type: CommonModule
110
+ },
111
+ {
112
+ kind: "component",
113
+ type: BsModalHostComponent,
114
+ selector: "bs-modal",
115
+ inputs: [
116
+ "isOpen",
117
+ "closeOnEscape",
118
+ "scrollable"
119
+ ],
120
+ outputs: ["isOpenChange"]
121
+ },
122
+ {
123
+ kind: "directive",
124
+ type: BsModalDirective,
125
+ selector: "[bsModal]"
126
+ },
127
+ {
128
+ kind: "directive",
129
+ type: BsModalHeaderDirective,
130
+ selector: "[bsModalHeader]"
131
+ },
132
+ {
133
+ kind: "directive",
134
+ type: BsModalBodyDirective,
135
+ selector: "[bsModalBody]"
136
+ },
137
+ {
138
+ kind: "directive",
139
+ type: BsModalFooterDirective,
140
+ selector: "[bsModalFooter]"
141
+ },
142
+ {
143
+ kind: "directive",
144
+ type: BsButtonTypeDirective,
145
+ selector: "button[color],input[type=\"button\"][color],input[type=\"submit\"][color],a[color]",
146
+ inputs: ["color"]
147
+ },
148
+ {
149
+ kind: "component",
150
+ type: SparkPoFormComponent,
151
+ selector: "spark-po-form",
152
+ inputs: [
153
+ "entityType",
154
+ "formData",
155
+ "validationErrors",
156
+ "showButtons",
157
+ "isSaving",
158
+ "parentId",
159
+ "parentType",
160
+ "objectTypeId",
161
+ "objectId",
162
+ "triggerPathPrefix",
163
+ "refreshOverlay"
164
+ ],
165
+ outputs: [
166
+ "formDataChange",
167
+ "save",
168
+ "cancel",
169
+ "nestedTriggerRequested",
170
+ "nestedTriggerBlurred",
171
+ "refreshOverlayChange"
172
+ ]
173
+ }
174
+ ],
175
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
176
+ });
177
+ };
178
+ i0.ɵɵngDeclareClassMetadata({
179
+ minVersion: "12.0.0",
180
+ version: "22.2.0",
181
+ ngImport: i0,
182
+ type: SparkRetryActionModalComponent,
183
+ decorators: [{
184
+ type: Component,
185
+ args: [{
186
+ selector: "spark-retry-action-modal",
187
+ imports: [
188
+ CommonModule,
189
+ BsModalHostComponent,
190
+ BsModalDirective,
191
+ BsModalHeaderDirective,
192
+ BsModalBodyDirective,
193
+ BsModalFooterDirective,
194
+ BsButtonTypeDirective,
195
+ SparkPoFormComponent
196
+ ],
197
+ template: `
145
198
  <bs-modal [isOpen]="isOpen()" (isOpenChange)="!$event && onOption('Cancel')">
146
199
  <div *bsModal>
147
200
  <div bsModalHeader>
@@ -172,72 +225,58 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
172
225
  </div>
173
226
  </bs-modal>
174
227
  `,
175
- changeDetection: ChangeDetectionStrategy.OnPush
176
- }]
177
- }], ctorParameters: () => [] });
178
- /**
179
- * Builds a synthetic <see cref="EntityType"/> from the PO's own scaffolded attributes so
180
- * the embedded spark-po-form can render without having to locate the matching server-side
181
- * EntityType registration. Used for Virtual POs that are schema-registered but not
182
- * security-granted (retry-action popups).
183
- */
228
+ changeDetection: ChangeDetectionStrategy.OnPush
229
+ }]
230
+ }],
231
+ ctorParameters: () => []
232
+ });
184
233
  function entityTypeFromPo(po) {
185
- return {
186
- id: po.objectTypeId,
187
- name: po.name,
188
- clrType: '', // Not needed by the form's rendering path; the PO's attributes carry the schema.
189
- breadcrumb: undefined,
190
- tabs: [],
191
- groups: [],
192
- attributes: (po.attributes ?? []).map(attrToDefinition),
193
- queries: [],
194
- };
234
+ return {
235
+ id: po.objectTypeId,
236
+ name: po.name,
237
+ clrType: "",
238
+ breadcrumb: void 0,
239
+ tabs: [],
240
+ groups: [],
241
+ attributes: (po.attributes ?? []).map(attrToDefinition),
242
+ queries: []
243
+ };
195
244
  }
196
245
  function attrToDefinition(attr) {
197
- return {
198
- id: attr.id ?? '',
199
- name: attr.name,
200
- label: attr.label,
201
- dataType: attr.dataType,
202
- isArray: attr.isArray,
203
- isRequired: attr.isRequired,
204
- isVisible: attr.isVisible,
205
- isReadOnly: attr.isReadOnly,
206
- order: attr.order,
207
- query: attr.query,
208
- asDetailType: attr.asDetailType,
209
- showedOn: attr.showedOn,
210
- rules: attr.rules ?? [],
211
- group: attr.group,
212
- renderer: attr.renderer,
213
- rendererOptions: attr.rendererOptions,
214
- };
246
+ return {
247
+ id: attr.id ?? "",
248
+ name: attr.name,
249
+ label: attr.label,
250
+ dataType: attr.dataType,
251
+ isArray: attr.isArray,
252
+ isRequired: attr.isRequired,
253
+ isVisible: attr.isVisible,
254
+ isReadOnly: attr.isReadOnly,
255
+ order: attr.order,
256
+ query: attr.query,
257
+ asDetailType: attr.asDetailType,
258
+ showedOn: attr.showedOn,
259
+ rules: attr.rules ?? [],
260
+ group: attr.group,
261
+ renderer: attr.renderer,
262
+ rendererOptions: attr.rendererOptions
263
+ };
215
264
  }
216
- /**
217
- * Keeps the server-issued id + metadata on each attribute while overlaying the user's
218
- * values from the rebuilt PO. Prevents the modal from accidentally dropping server-only
219
- * fields (e.g. rules, renderer options) that the form didn't need to know about.
220
- */
221
265
  function mergeAttributeMetadata(incoming, rebuilt) {
222
- const byName = new Map(rebuilt.map(a => [a.name, a]));
223
- return incoming.map(source => {
224
- const updated = byName.get(source.name);
225
- if (!updated)
226
- return source;
227
- return {
228
- ...source,
229
- value: updated.value,
230
- object: updated.object,
231
- objects: updated.objects,
232
- asDetailType: updated.asDetailType ?? source.asDetailType,
233
- isValueChanged: true,
234
- };
235
- });
266
+ const byName = new Map(rebuilt.map((a) => [a.name, a]));
267
+ return incoming.map((source) => {
268
+ const updated = byName.get(source.name);
269
+ if (!updated) return source;
270
+ return {
271
+ ...source,
272
+ value: updated.value,
273
+ object: updated.object,
274
+ objects: updated.objects,
275
+ asDetailType: updated.asDetailType ?? source.asDetailType,
276
+ isValueChanged: true
277
+ };
278
+ });
236
279
  }
237
-
238
- /**
239
- * Generated bundle index. Do not edit.
240
- */
241
-
242
280
  export { SparkRetryActionModalComponent };
243
- //# sourceMappingURL=mintplayer-ng-spark-retry-action-modal.mjs.map
281
+
282
+ //# sourceMappingURL=mintplayer-ng-spark-retry-action-modal.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-retry-action-modal.mjs","sources":["../../retry-action-modal/src/spark-retry-action-modal.component.ts","../../retry-action-modal/mintplayer-ng-spark-retry-action-modal.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective } from '@mintplayer/ng-bootstrap/modal';\nimport { BsButtonTypeDirective } from '@mintplayer/ng-bootstrap/button-type';\nimport { RetryActionService, SparkService } from '@mintplayer/ng-spark/services';\nimport { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';\nimport {\n dictToNestedPo,\n EntityAttributeDefinition,\n EntityType,\n EntityTypeResolver,\n nestedPoToDict,\n PersistentObject,\n PersistentObjectAttribute,\n} from '@mintplayer/ng-spark/models';\n\n/**\n * Renders a retry-action popup. Before PRD §3 this component rendered title / message /\n * option buttons only and silently forwarded the incoming <c>persistentObject</c> back to\n * the server on submit — meaning any <c>Retry.Action(..., persistentObject)</c> flow had\n * no UI to actually edit the PO. This component now embeds the shared PO form so every\n * scalar / Reference / AsDetail attribute on the scaffolded Virtual PO is a real form\n * field, and the values the user fills in flow back to the server via\n * <c>RetryResult.PersistentObject</c>.\n */\n@Component({\n selector: 'spark-retry-action-modal',\n imports: [CommonModule, BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective, BsButtonTypeDirective, SparkPoFormComponent],\n template: `\n <bs-modal [isOpen]=\"isOpen()\" (isOpenChange)=\"!$event && onOption('Cancel')\">\n <div *bsModal>\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ retryActionService.payload()?.title }}</h5>\n </div>\n <div bsModalBody>\n @if (retryActionService.payload()?.message; as message) {\n <p>{{ message }}</p>\n }\n @if (entityType(); as et) {\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [showButtons]=\"false\">\n </spark-po-form>\n }\n </div>\n <div bsModalFooter>\n @for (option of retryActionService.payload()?.options; track option) {\n <button\n type=\"button\"\n [color]=\"option === 'Cancel' ? colors.secondary : colors.primary\"\n (click)=\"onOption(option)\">\n {{ option }}\n </button>\n }\n </div>\n </div>\n </bs-modal>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SparkRetryActionModalComponent {\n protected readonly retryActionService = inject(RetryActionService);\n private readonly sparkService = inject(SparkService);\n\n colors = Color;\n isOpen = computed(() => this.retryActionService.payload() !== null);\n\n /**\n * EntityType definition for the incoming PO — fetched lazily via SparkService so the\n * form knows which attributes are editable, their labels, rules, renderers, etc.\n * `null` when the payload has no persistentObject or its objectTypeId doesn't match\n * any registered entity type (renders the modal as a simple option picker).\n */\n entityType = signal<EntityType | null>(null);\n formData = signal<Record<string, any>>({});\n private allEntityTypes: EntityType[] = [];\n\n constructor() {\n // Reseed form state every time the retry service opens/closes the modal. Effect\n // cleanup isn't needed since `payload` is a signal and the component's own lifetime\n // is root-scoped.\n effect(() => {\n const payload = this.retryActionService.payload();\n if (!payload?.persistentObject) {\n this.entityType.set(null);\n this.formData.set({});\n return;\n }\n void this.seedForm(payload.persistentObject);\n });\n }\n\n private async seedForm(po: PersistentObject): Promise<void> {\n // Virtual POs used for retry prompts (e.g. ConfirmDeleteCar) typically have no\n // security.json grant — so `getEntityTypes()` filters them out for the current user\n // and the lookup-by-id would return null, leaving the form blank. The scaffolded PO\n // already carries full attribute metadata (label / dataType / rules / renderer / etc.),\n // so we synthesize an EntityType from the attributes directly and skip the HTTP\n // lookup altogether. `getEntityTypes()` is still fetched because the embedded\n // spark-po-form needs the full list to resolve nested AsDetail / Reference types the\n // retry PO might point at. The guard below is a COMPONENT-local cache and is the only\n // one there is: the service does not cache, so every caller that skips such a guard\n // issues another request.\n if (this.allEntityTypes.length === 0) {\n try { this.allEntityTypes = await this.sparkService.getEntityTypes(); }\n catch { this.allEntityTypes = []; }\n }\n this.entityType.set(entityTypeFromPo(po));\n // Flatten the nested PO into the Record<string, any> shape the shared form uses\n // throughout the rest of ng-spark — same transformation po-edit applies.\n this.formData.set(nestedPoToDict(po));\n }\n\n onOption(option: string): void {\n const payload = this.retryActionService.payload();\n if (!payload) return;\n\n const populated = this.populatedPersistentObject(payload.persistentObject);\n this.retryActionService.respond({\n step: payload.step,\n option,\n persistentObject: populated,\n });\n }\n\n /**\n * Builds the PO the server sees under <c>Retry.Result.PersistentObject</c>. If the\n * form resolved an EntityType, rebuild from the schema + formData (identical to the\n * po-edit save path — AsDetail recursion included). Otherwise forward the incoming\n * PO unmodified so pre-§3 flows without editable attributes keep working.\n */\n private populatedPersistentObject(incoming: PersistentObject | undefined): PersistentObject | undefined {\n if (!incoming) return undefined;\n const type = this.entityType();\n if (!type) return incoming;\n\n const resolver: EntityTypeResolver = (clrName) => this.allEntityTypes.find(t => t.clrType === clrName);\n const rebuilt = dictToNestedPo(this.formData(), type, resolver);\n const populated: PersistentObject = {\n ...incoming,\n attributes: mergeAttributeMetadata(incoming.attributes ?? [], rebuilt.attributes),\n };\n return populated;\n }\n}\n\n/**\n * Builds a synthetic <see cref=\"EntityType\"/> from the PO's own scaffolded attributes so\n * the embedded spark-po-form can render without having to locate the matching server-side\n * EntityType registration. Used for Virtual POs that are schema-registered but not\n * security-granted (retry-action popups).\n */\nfunction entityTypeFromPo(po: PersistentObject): EntityType {\n return {\n id: po.objectTypeId,\n name: po.name,\n clrType: '', // Not needed by the form's rendering path; the PO's attributes carry the schema.\n breadcrumb: undefined,\n tabs: [],\n groups: [],\n attributes: (po.attributes ?? []).map(attrToDefinition),\n queries: [],\n };\n}\n\nfunction attrToDefinition(attr: PersistentObjectAttribute): EntityAttributeDefinition {\n return {\n id: attr.id ?? '',\n name: attr.name,\n label: attr.label,\n dataType: attr.dataType,\n isArray: attr.isArray,\n isRequired: attr.isRequired,\n isVisible: attr.isVisible,\n isReadOnly: attr.isReadOnly,\n order: attr.order,\n query: attr.query,\n asDetailType: attr.asDetailType,\n showedOn: attr.showedOn,\n rules: attr.rules ?? [],\n group: attr.group,\n renderer: attr.renderer,\n rendererOptions: attr.rendererOptions,\n };\n}\n\n/**\n * Keeps the server-issued id + metadata on each attribute while overlaying the user's\n * values from the rebuilt PO. Prevents the modal from accidentally dropping server-only\n * fields (e.g. rules, renderer options) that the form didn't need to know about.\n */\nfunction mergeAttributeMetadata(\n incoming: PersistentObjectAttribute[],\n rebuilt: PersistentObjectAttribute[],\n): PersistentObjectAttribute[] {\n const byName = new Map(rebuilt.map(a => [a.name, a]));\n return incoming.map(source => {\n const updated = byName.get(source.name);\n if (!updated) return source;\n return {\n ...source,\n value: updated.value,\n object: updated.object,\n objects: updated.objects,\n asDetailType: updated.asDetailType ?? source.asDetailType,\n isValueChanged: true,\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mintplayer-ng-spark-retry-action-modal.mjs","names":[],"sources":["../../retry-action-modal/src/spark-retry-action-modal.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, effect, inject, signal } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective } from '@mintplayer/ng-bootstrap/modal';\nimport { BsButtonTypeDirective } from '@mintplayer/ng-bootstrap/button-type';\nimport { RetryActionService, SparkService } from '@mintplayer/ng-spark/services';\nimport { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';\nimport {\n dictToNestedPo,\n EntityAttributeDefinition,\n EntityType,\n EntityTypeResolver,\n nestedPoToDict,\n PersistentObject,\n PersistentObjectAttribute,\n} from '@mintplayer/ng-spark/models';\n\n/**\n * Renders a retry-action popup. Before PRD §3 this component rendered title / message /\n * option buttons only and silently forwarded the incoming <c>persistentObject</c> back to\n * the server on submit — meaning any <c>Retry.Action(..., persistentObject)</c> flow had\n * no UI to actually edit the PO. This component now embeds the shared PO form so every\n * scalar / Reference / AsDetail attribute on the scaffolded Virtual PO is a real form\n * field, and the values the user fills in flow back to the server via\n * <c>RetryResult.PersistentObject</c>.\n */\n@Component({\n selector: 'spark-retry-action-modal',\n imports: [CommonModule, BsModalHostComponent, BsModalDirective, BsModalHeaderDirective, BsModalBodyDirective, BsModalFooterDirective, BsButtonTypeDirective, SparkPoFormComponent],\n template: `\n <bs-modal [isOpen]=\"isOpen()\" (isOpenChange)=\"!$event && onOption('Cancel')\">\n <div *bsModal>\n <div bsModalHeader>\n <h5 class=\"modal-title\">{{ retryActionService.payload()?.title }}</h5>\n </div>\n <div bsModalBody>\n @if (retryActionService.payload()?.message; as message) {\n <p>{{ message }}</p>\n }\n @if (entityType(); as et) {\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [showButtons]=\"false\">\n </spark-po-form>\n }\n </div>\n <div bsModalFooter>\n @for (option of retryActionService.payload()?.options; track option) {\n <button\n type=\"button\"\n [color]=\"option === 'Cancel' ? colors.secondary : colors.primary\"\n (click)=\"onOption(option)\">\n {{ option }}\n </button>\n }\n </div>\n </div>\n </bs-modal>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SparkRetryActionModalComponent {\n protected readonly retryActionService = inject(RetryActionService);\n private readonly sparkService = inject(SparkService);\n\n colors = Color;\n isOpen = computed(() => this.retryActionService.payload() !== null);\n\n /**\n * EntityType definition for the incoming PO — fetched lazily via SparkService so the\n * form knows which attributes are editable, their labels, rules, renderers, etc.\n * `null` when the payload has no persistentObject or its objectTypeId doesn't match\n * any registered entity type (renders the modal as a simple option picker).\n */\n entityType = signal<EntityType | null>(null);\n formData = signal<Record<string, any>>({});\n private allEntityTypes: EntityType[] = [];\n\n constructor() {\n // Reseed form state every time the retry service opens/closes the modal. Effect\n // cleanup isn't needed since `payload` is a signal and the component's own lifetime\n // is root-scoped.\n effect(() => {\n const payload = this.retryActionService.payload();\n if (!payload?.persistentObject) {\n this.entityType.set(null);\n this.formData.set({});\n return;\n }\n void this.seedForm(payload.persistentObject);\n });\n }\n\n private async seedForm(po: PersistentObject): Promise<void> {\n // Virtual POs used for retry prompts (e.g. ConfirmDeleteCar) typically have no\n // security.json grant — so `getEntityTypes()` filters them out for the current user\n // and the lookup-by-id would return null, leaving the form blank. The scaffolded PO\n // already carries full attribute metadata (label / dataType / rules / renderer / etc.),\n // so we synthesize an EntityType from the attributes directly and skip the HTTP\n // lookup altogether. `getEntityTypes()` is still fetched because the embedded\n // spark-po-form needs the full list to resolve nested AsDetail / Reference types the\n // retry PO might point at. The guard below is a COMPONENT-local cache and is the only\n // one there is: the service does not cache, so every caller that skips such a guard\n // issues another request.\n if (this.allEntityTypes.length === 0) {\n try { this.allEntityTypes = await this.sparkService.getEntityTypes(); }\n catch { this.allEntityTypes = []; }\n }\n this.entityType.set(entityTypeFromPo(po));\n // Flatten the nested PO into the Record<string, any> shape the shared form uses\n // throughout the rest of ng-spark — same transformation po-edit applies.\n this.formData.set(nestedPoToDict(po));\n }\n\n onOption(option: string): void {\n const payload = this.retryActionService.payload();\n if (!payload) return;\n\n const populated = this.populatedPersistentObject(payload.persistentObject);\n this.retryActionService.respond({\n step: payload.step,\n option,\n persistentObject: populated,\n });\n }\n\n /**\n * Builds the PO the server sees under <c>Retry.Result.PersistentObject</c>. If the\n * form resolved an EntityType, rebuild from the schema + formData (identical to the\n * po-edit save path — AsDetail recursion included). Otherwise forward the incoming\n * PO unmodified so pre-§3 flows without editable attributes keep working.\n */\n private populatedPersistentObject(incoming: PersistentObject | undefined): PersistentObject | undefined {\n if (!incoming) return undefined;\n const type = this.entityType();\n if (!type) return incoming;\n\n const resolver: EntityTypeResolver = (clrName) => this.allEntityTypes.find(t => t.clrType === clrName);\n const rebuilt = dictToNestedPo(this.formData(), type, resolver);\n const populated: PersistentObject = {\n ...incoming,\n attributes: mergeAttributeMetadata(incoming.attributes ?? [], rebuilt.attributes),\n };\n return populated;\n }\n}\n\n/**\n * Builds a synthetic <see cref=\"EntityType\"/> from the PO's own scaffolded attributes so\n * the embedded spark-po-form can render without having to locate the matching server-side\n * EntityType registration. Used for Virtual POs that are schema-registered but not\n * security-granted (retry-action popups).\n */\nfunction entityTypeFromPo(po: PersistentObject): EntityType {\n return {\n id: po.objectTypeId,\n name: po.name,\n clrType: '', // Not needed by the form's rendering path; the PO's attributes carry the schema.\n breadcrumb: undefined,\n tabs: [],\n groups: [],\n attributes: (po.attributes ?? []).map(attrToDefinition),\n queries: [],\n };\n}\n\nfunction attrToDefinition(attr: PersistentObjectAttribute): EntityAttributeDefinition {\n return {\n id: attr.id ?? '',\n name: attr.name,\n label: attr.label,\n dataType: attr.dataType,\n isArray: attr.isArray,\n isRequired: attr.isRequired,\n isVisible: attr.isVisible,\n isReadOnly: attr.isReadOnly,\n order: attr.order,\n query: attr.query,\n asDetailType: attr.asDetailType,\n showedOn: attr.showedOn,\n rules: attr.rules ?? [],\n group: attr.group,\n renderer: attr.renderer,\n rendererOptions: attr.rendererOptions,\n };\n}\n\n/**\n * Keeps the server-issued id + metadata on each attribute while overlaying the user's\n * values from the rebuilt PO. Prevents the modal from accidentally dropping server-only\n * fields (e.g. rules, renderer options) that the form didn't need to know about.\n */\nfunction mergeAttributeMetadata(\n incoming: PersistentObjectAttribute[],\n rebuilt: PersistentObjectAttribute[],\n): PersistentObjectAttribute[] {\n const byName = new Map(rebuilt.map(a => [a.name, a]));\n return incoming.map(source => {\n const updated = byName.get(source.name);\n if (!updated) return source;\n return {\n ...source,\n value: updated.value,\n object: updated.object,\n objects: updated.objects,\n asDetailType: updated.asDetailType ?? source.asDetailType,\n isValueChanged: true,\n };\n });\n}\n"],"mappings":"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"}
@@ -1,31 +1,27 @@
1
1
  function sparkRoutes(config) {
2
- return [
3
- {
4
- path: 'query/:queryId',
5
- loadComponent: config?.queryList ?? (() => import('@mintplayer/ng-spark/query-list').then(m => m.SparkQueryListComponent))
6
- },
7
- {
8
- path: 'po/:type/new',
9
- loadComponent: config?.poCreate ?? (() => import('@mintplayer/ng-spark/po-create').then(m => m.SparkPoCreateComponent))
10
- },
11
- {
12
- path: 'po/:type/:id/edit',
13
- loadComponent: config?.poEdit ?? (() => import('@mintplayer/ng-spark/po-edit').then(m => m.SparkPoEditComponent))
14
- },
15
- {
16
- path: 'po/:type/:id',
17
- loadComponent: config?.poDetail ?? (() => import('@mintplayer/ng-spark/po-detail').then(m => m.SparkPoDetailComponent))
18
- },
19
- {
20
- path: 'po/:type',
21
- loadComponent: config?.queryList ?? (() => import('@mintplayer/ng-spark/query-list').then(m => m.SparkQueryListComponent))
22
- }
23
- ];
2
+ return [
3
+ {
4
+ path: "query/:queryId",
5
+ loadComponent: config?.queryList ?? (() => import("@mintplayer/ng-spark/query-list").then((m) => m.SparkQueryListComponent))
6
+ },
7
+ {
8
+ path: "po/:type/new",
9
+ loadComponent: config?.poCreate ?? (() => import("@mintplayer/ng-spark/po-create").then((m) => m.SparkPoCreateComponent))
10
+ },
11
+ {
12
+ path: "po/:type/:id/edit",
13
+ loadComponent: config?.poEdit ?? (() => import("@mintplayer/ng-spark/po-edit").then((m) => m.SparkPoEditComponent))
14
+ },
15
+ {
16
+ path: "po/:type/:id",
17
+ loadComponent: config?.poDetail ?? (() => import("@mintplayer/ng-spark/po-detail").then((m) => m.SparkPoDetailComponent))
18
+ },
19
+ {
20
+ path: "po/:type",
21
+ loadComponent: config?.queryList ?? (() => import("@mintplayer/ng-spark/query-list").then((m) => m.SparkQueryListComponent))
22
+ }
23
+ ];
24
24
  }
25
-
26
- /**
27
- * Generated bundle index. Do not edit.
28
- */
29
-
30
25
  export { sparkRoutes };
31
- //# sourceMappingURL=mintplayer-ng-spark-routes.mjs.map
26
+
27
+ //# sourceMappingURL=mintplayer-ng-spark-routes.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-routes.mjs","sources":["../../routes/src/spark-routes.ts","../../routes/mintplayer-ng-spark-routes.ts"],"sourcesContent":["import { Routes, Route } from '@angular/router';\n\nexport interface SparkRouteConfig {\n queryList?: Route['loadComponent'];\n poCreate?: Route['loadComponent'];\n poEdit?: Route['loadComponent'];\n poDetail?: Route['loadComponent'];\n}\n\nexport function sparkRoutes(config?: SparkRouteConfig): Routes {\n return [\n {\n path: 'query/:queryId',\n loadComponent: config?.queryList ?? (() => import('@mintplayer/ng-spark/query-list').then(m => m.SparkQueryListComponent))\n },\n {\n path: 'po/:type/new',\n loadComponent: config?.poCreate ?? (() => import('@mintplayer/ng-spark/po-create').then(m => m.SparkPoCreateComponent))\n },\n {\n path: 'po/:type/:id/edit',\n loadComponent: config?.poEdit ?? (() => import('@mintplayer/ng-spark/po-edit').then(m => m.SparkPoEditComponent))\n },\n {\n path: 'po/:type/:id',\n loadComponent: config?.poDetail ?? (() => import('@mintplayer/ng-spark/po-detail').then(m => m.SparkPoDetailComponent))\n },\n {\n path: 'po/:type',\n loadComponent: config?.queryList ?? (() => import('@mintplayer/ng-spark/query-list').then(m => m.SparkQueryListComponent))\n }\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AASM,SAAU,WAAW,CAAC,MAAyB,EAAA;IACnD,OAAO;AACL,QAAA;AACE,YAAA,IAAI,EAAE,gBAAgB;YACtB,aAAa,EAAE,MAAM,EAAE,SAAS,KAAK,MAAM,OAAO,iCAAiC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,uBAAuB,CAAC;AAC1H,SAAA;AACD,QAAA;AACE,YAAA,IAAI,EAAE,cAAc;YACpB,aAAa,EAAE,MAAM,EAAE,QAAQ,KAAK,MAAM,OAAO,gCAAgC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,sBAAsB,CAAC;AACvH,SAAA;AACD,QAAA;AACE,YAAA,IAAI,EAAE,mBAAmB;YACzB,aAAa,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,OAAO,8BAA8B,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC;AACjH,SAAA;AACD,QAAA;AACE,YAAA,IAAI,EAAE,cAAc;YACpB,aAAa,EAAE,MAAM,EAAE,QAAQ,KAAK,MAAM,OAAO,gCAAgC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,sBAAsB,CAAC;AACvH,SAAA;AACD,QAAA;AACE,YAAA,IAAI,EAAE,UAAU;YAChB,aAAa,EAAE,MAAM,EAAE,SAAS,KAAK,MAAM,OAAO,iCAAiC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,uBAAuB,CAAC;AAC1H;KACF;AACH;;AChCA;;AAEG;;;;"}
1
+ {"version":3,"file":"mintplayer-ng-spark-routes.mjs","names":[],"sources":["../../routes/src/spark-routes.ts"],"sourcesContent":["import { Routes, Route } from '@angular/router';\n\nexport interface SparkRouteConfig {\n queryList?: Route['loadComponent'];\n poCreate?: Route['loadComponent'];\n poEdit?: Route['loadComponent'];\n poDetail?: Route['loadComponent'];\n}\n\nexport function sparkRoutes(config?: SparkRouteConfig): Routes {\n return [\n {\n path: 'query/:queryId',\n loadComponent: config?.queryList ?? (() => import('@mintplayer/ng-spark/query-list').then(m => m.SparkQueryListComponent))\n },\n {\n path: 'po/:type/new',\n loadComponent: config?.poCreate ?? (() => import('@mintplayer/ng-spark/po-create').then(m => m.SparkPoCreateComponent))\n },\n {\n path: 'po/:type/:id/edit',\n loadComponent: config?.poEdit ?? (() => import('@mintplayer/ng-spark/po-edit').then(m => m.SparkPoEditComponent))\n },\n {\n path: 'po/:type/:id',\n loadComponent: config?.poDetail ?? (() => import('@mintplayer/ng-spark/po-detail').then(m => m.SparkPoDetailComponent))\n },\n {\n path: 'po/:type',\n loadComponent: config?.queryList ?? (() => import('@mintplayer/ng-spark/query-list').then(m => m.SparkQueryListComponent))\n }\n ];\n}\n"],"mappings":"AASA,SAAgB,YAAY,QAAyB;CACnD,OAAO;EACL;GACE,MAAM;GACN,eAAe,QAAQ,oBAAoB,OAAO,kCAAkC,CAAC,MAAK,MAAK,EAAE,uBAAuB;EACzH;EACD;GACE,MAAM;GACN,eAAe,QAAQ,mBAAmB,OAAO,iCAAiC,CAAC,MAAK,MAAK,EAAE,sBAAsB;EACtH;EACD;GACE,MAAM;GACN,eAAe,QAAQ,iBAAiB,OAAO,+BAA+B,CAAC,MAAK,MAAK,EAAE,oBAAoB;EAChH;EACD;GACE,MAAM;GACN,eAAe,QAAQ,mBAAmB,OAAO,iCAAiC,CAAC,MAAK,MAAK,EAAE,sBAAsB;EACtH;EACD;GACE,MAAM;GACN,eAAe,QAAQ,oBAAoB,OAAO,kCAAkC,CAAC,MAAK,MAAK,EAAE,uBAAuB;EACzH;CACF;AACH"}