@mintplayer/ng-spark 22.23.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 -1119
  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 +366 -762
  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,170 +1,274 @@
1
- import * as i0 from '@angular/core';
2
- import { inject, output, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
- import { CommonModule } from '@angular/common';
5
- import { ActivatedRoute, Router } from '@angular/router';
6
- import { Color } from '@mintplayer/ng-bootstrap';
7
- import { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';
8
- import { BsContainerComponent } from '@mintplayer/ng-bootstrap/container';
9
- import { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';
10
- import { SparkService } from '@mintplayer/ng-spark/services';
11
- import { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';
12
- import { ResolveTranslationPipe, TranslateKeyPipe } from '@mintplayer/ng-spark/pipes';
13
- import { applyOverlay, hasShowedOnFlag, ShowedOn, isDateDataType, fromDateInputValue, dictToNestedPo } from '@mintplayer/ng-spark/models';
14
-
15
- class SparkPoCreateComponent {
16
- route = inject(ActivatedRoute);
17
- router = inject(Router);
18
- sparkService = inject(SparkService);
19
- saved = output();
20
- cancelled = output();
21
- colors = Color;
22
- entityType = signal(null, /* @ts-ignore */
23
- ...(ngDevMode ? [{ debugName: "entityType" }] : /* istanbul ignore next */ []));
24
- type = signal('', /* @ts-ignore */
25
- ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
26
- formData = signal({}, /* @ts-ignore */
27
- ...(ngDevMode ? [{ debugName: "formData" }] : /* istanbul ignore next */ []));
28
- /** Bound two-way to the form. See {@link getEditableAttributes}. */
29
- refreshOverlay = signal({}, /* @ts-ignore */
30
- ...(ngDevMode ? [{ debugName: "refreshOverlay" }] : /* istanbul ignore next */ []));
31
- validationErrors = signal([], /* @ts-ignore */
32
- ...(ngDevMode ? [{ debugName: "validationErrors" }] : /* istanbul ignore next */ []));
33
- isSaving = signal(false, /* @ts-ignore */
34
- ...(ngDevMode ? [{ debugName: "isSaving" }] : /* istanbul ignore next */ []));
35
- allEntityTypes = signal([], /* @ts-ignore */
36
- ...(ngDevMode ? [{ debugName: "allEntityTypes" }] : /* istanbul ignore next */ []));
37
- generalErrors = computed(() => this.validationErrors().filter(e => !e.attributeName), /* @ts-ignore */
38
- ...(ngDevMode ? [{ debugName: "generalErrors" }] : /* istanbul ignore next */ []));
39
- constructor() {
40
- this.route.paramMap.pipe(takeUntilDestroyed()).subscribe(params => this.onParamsChange(params));
41
- }
42
- async onParamsChange(params) {
43
- this.type.set(params.get('type') || '');
44
- const types = await this.sparkService.getEntityTypes();
45
- const entityType = types.find(t => t.id === this.type() || t.alias === this.type()) || null;
46
- this.entityType.set(entityType);
47
- this.allEntityTypes.set(types);
48
- this.initFormData();
49
- }
50
- initFormData() {
51
- const data = {};
52
- this.getEditableAttributes().forEach(attr => {
53
- if (attr.dataType === 'Reference') {
54
- data[attr.name] = null;
55
- }
56
- else if (attr.dataType === 'AsDetail') {
57
- data[attr.name] = attr.isArray ? [] : {};
58
- }
59
- else if (attr.dataType === 'boolean' && !attr.lookupReferenceType) {
60
- // Same reason as spark-po-edit: a lookup-backed boolean's third state is the absence of a
61
- // value, and seeding `false` here would make every new object explicitly opted out.
62
- data[attr.name] = false;
63
- }
64
- else {
65
- data[attr.name] = '';
66
- }
67
- });
68
- this.formData.set(data);
69
- }
70
- /**
71
- * ⚠️ Overlaid before filtering — same reason as <c>spark-po-edit</c>, and worse here: this list is
72
- * the <em>only</em> source of the create payload, so an attribute a refresh hook revealed was not
73
- * merely sent stale, it was absent from the new object entirely.
74
- */
75
- getEditableAttributes() {
76
- const overlay = this.refreshOverlay();
77
- return this.entityType()?.attributes
78
- .map(a => applyOverlay(a, overlay[a.name]))
79
- .filter(a => a.isVisible && !a.isReadOnly && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))
80
- .sort((a, b) => a.order - b.order) || [];
81
- }
82
- async onSave() {
83
- if (!this.entityType())
84
- return;
85
- this.validationErrors.set([]);
86
- this.isSaving.set(true);
87
- const resolver = (clrName) => this.allEntityTypes().find(t => t.clrType === clrName);
88
- const attributes = this.getEditableAttributes().map(attr => {
89
- const base = {
90
- id: attr.id,
91
- name: attr.name,
92
- // A date control hands back a bare local wall clock; the wire needs a complete ISO-8601
93
- // instant carrying the viewer's offset for the entered date.
94
- value: isDateDataType(attr.dataType)
95
- ? fromDateInputValue(attr.dataType, this.formData()[attr.name])
96
- : this.formData()[attr.name],
97
- dataType: attr.dataType,
98
- isArray: attr.isArray,
99
- isRequired: attr.isRequired,
100
- isVisible: attr.isVisible,
101
- isReadOnly: attr.isReadOnly,
102
- isValueChanged: true,
103
- order: attr.order,
104
- rules: attr.rules,
105
- };
106
- // AsDetail: pack the flat form dict into nested PO wire shape. Server's polymorphic
107
- // converter ignores attr.value for AsDetail and reads attr.object / attr.objects.
108
- if (attr.dataType === 'AsDetail' && attr.asDetailType) {
109
- const nestedType = resolver(attr.asDetailType);
110
- if (nestedType) {
111
- const raw = this.formData()[attr.name];
112
- base.value = null;
113
- base.asDetailType = attr.asDetailType;
114
- if (attr.isArray) {
115
- const items = Array.isArray(raw) ? raw : [];
116
- base.objects = items.map(item => dictToNestedPo((item ?? {}), nestedType, resolver));
117
- base.object = null;
118
- }
119
- else {
120
- base.object = raw ? dictToNestedPo(raw, nestedType, resolver) : null;
121
- base.objects = null;
122
- }
123
- }
124
- }
125
- return base;
126
- });
127
- const po = {
128
- name: this.formData()['Name'] || 'New Item',
129
- objectTypeId: this.entityType().id,
130
- attributes
131
- };
132
- try {
133
- const result = await this.sparkService.create(this.type(), po);
134
- this.isSaving.set(false);
135
- this.saved.emit(result);
136
- this.router.navigate(['/po', this.type(), result.id]);
137
- }
138
- catch (e) {
139
- this.isSaving.set(false);
140
- const error = e;
141
- if (error.status === 400 && error.error?.errors) {
142
- this.validationErrors.set(error.error.errors);
143
- }
144
- else {
145
- this.validationErrors.set([{
146
- attributeName: '',
147
- errorMessage: { en: error.message || 'An unexpected error occurred' },
148
- ruleType: 'error'
149
- }]);
150
- }
151
- }
152
- }
153
- onCancel() {
154
- this.cancelled.emit();
155
- window.history.back();
156
- }
157
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SparkPoCreateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
158
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: SparkPoCreateComponent, isStandalone: true, selector: "spark-po-create", outputs: { saved: "saved", cancelled: "cancelled" }, ngImport: i0, template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [(refreshOverlay)]=\"refreshOverlay\"\n [objectTypeId]=\"type()\"\n [parentType]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: BsAlertComponent, selector: "bs-alert", inputs: ["type", "announce", "isVisible"], outputs: ["isVisibleChange", "afterOpenedOrClosed"] }, { kind: "component", type: BsContainerComponent, selector: "bs-container" }, { kind: "component", type: BsSpinnerComponent, selector: "bs-spinner", inputs: ["type", "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"] }, { kind: "pipe", type: ResolveTranslationPipe, name: "resolveTranslation" }, { kind: "pipe", type: TranslateKeyPipe, name: "t" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
159
- }
160
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SparkPoCreateComponent, decorators: [{
161
- type: Component,
162
- args: [{ selector: 'spark-po-create', imports: [CommonModule, BsAlertComponent, BsContainerComponent, BsSpinnerComponent, SparkPoFormComponent, ResolveTranslationPipe, TranslateKeyPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [(refreshOverlay)]=\"refreshOverlay\"\n [objectTypeId]=\"type()\"\n [parentType]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n" }]
163
- }], ctorParameters: () => [], propDecorators: { saved: [{ type: i0.Output, args: ["saved"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
164
-
165
- /**
166
- * Generated bundle index. Do not edit.
167
- */
168
-
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, computed, inject, output, signal } from "@angular/core";
3
+ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
4
+ import { CommonModule } from "@angular/common";
5
+ import { ActivatedRoute, Router } from "@angular/router";
6
+ import { Color } from "@mintplayer/ng-bootstrap";
7
+ import { BsAlertComponent } from "@mintplayer/ng-bootstrap/alert";
8
+ import { BsContainerComponent } from "@mintplayer/ng-bootstrap/container";
9
+ import { BsSpinnerComponent } from "@mintplayer/ng-bootstrap/spinner";
10
+ import { SparkService } from "@mintplayer/ng-spark/services";
11
+ import { SparkPoFormComponent } from "@mintplayer/ng-spark/po-form";
12
+ import { ResolveTranslationPipe, TranslateKeyPipe } from "@mintplayer/ng-spark/pipes";
13
+ import { ShowedOn, applyOverlay, dictToNestedPo, fromDateInputValue, hasShowedOnFlag, isDateDataType, toDateInputValue } from "@mintplayer/ng-spark/models";
14
+ var SparkPoCreateComponent = class SparkPoCreateComponent {
15
+ route = inject(ActivatedRoute);
16
+ router = inject(Router);
17
+ sparkService = inject(SparkService);
18
+ saved = output();
19
+ cancelled = output();
20
+ colors = Color;
21
+ entityType = signal(null, ...ngDevMode ? [{ debugName: "entityType" }] : /* istanbul ignore next */ []);
22
+ type = signal("", ...ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []);
23
+ formData = signal({}, ...ngDevMode ? [{ debugName: "formData" }] : /* istanbul ignore next */ []);
24
+ refreshOverlay = signal({}, ...ngDevMode ? [{ debugName: "refreshOverlay" }] : /* istanbul ignore next */ []);
25
+ validationErrors = signal([], ...ngDevMode ? [{ debugName: "validationErrors" }] : /* istanbul ignore next */ []);
26
+ isSaving = signal(false, ...ngDevMode ? [{ debugName: "isSaving" }] : /* istanbul ignore next */ []);
27
+ allEntityTypes = signal([], ...ngDevMode ? [{ debugName: "allEntityTypes" }] : /* istanbul ignore next */ []);
28
+ generalErrors = computed(() => this.validationErrors().filter((e) => !e.attributeName), ...ngDevMode ? [{ debugName: "generalErrors" }] : /* istanbul ignore next */ []);
29
+ constructor() {
30
+ this.route.paramMap.pipe(takeUntilDestroyed()).subscribe((params) => this.onParamsChange(params));
31
+ }
32
+ async onParamsChange(params) {
33
+ this.type.set(params.get("type") || "");
34
+ const types = await this.sparkService.getEntityTypes();
35
+ const entityType = types.find((t) => t.id === this.type() || t.alias === this.type()) || null;
36
+ this.allEntityTypes.set(types);
37
+ this.initFormData(entityType);
38
+ if (entityType) await this.applyServerDefaults(entityType);
39
+ this.entityType.set(entityType);
40
+ }
41
+ async applyServerDefaults(entityType) {
42
+ const query = this.route.snapshot.queryParamMap;
43
+ const parentId = query.get("parentId") ?? void 0;
44
+ const parentType = query.get("parentType") ?? void 0;
45
+ const queryId = query.get("queryId") ?? void 0;
46
+ const fromSubQuery = !!(parentId && parentType && queryId);
47
+ try {
48
+ const po = await this.sparkService.newObject(this.type(), fromSubQuery ? {
49
+ parentId,
50
+ parentType,
51
+ queryId
52
+ } : void 0);
53
+ const editable = new Map(this.getEditableAttributes(entityType).map((a) => [a.name, a]));
54
+ const data = { ...this.formData() };
55
+ for (const attr of po?.attributes ?? []) {
56
+ const definition = editable.get(attr.name);
57
+ if (!definition || attr.value === null || attr.value === void 0 || definition.dataType === "AsDetail") continue;
58
+ data[attr.name] = isDateDataType(definition.dataType) ? toDateInputValue(definition.dataType, attr.value) : attr.value;
59
+ }
60
+ this.formData.set(data);
61
+ } catch (e) {
62
+ const error = e;
63
+ const errors = error.error?.result?.errors ?? error.error?.errors;
64
+ this.validationErrors.set(errors ?? [{
65
+ attributeName: "",
66
+ errorMessage: { en: error.message || "The new item could not be prepared." },
67
+ ruleType: "error"
68
+ }]);
69
+ }
70
+ }
71
+ initFormData(entityType = this.entityType()) {
72
+ const data = {};
73
+ this.getEditableAttributes(entityType).forEach((attr) => {
74
+ if (attr.dataType === "Reference") data[attr.name] = null;
75
+ else if (attr.dataType === "AsDetail") data[attr.name] = attr.isArray ? [] : {};
76
+ else if (attr.dataType === "boolean" && !attr.lookupReferenceType) data[attr.name] = false;
77
+ else data[attr.name] = "";
78
+ });
79
+ this.formData.set(data);
80
+ }
81
+ getEditableAttributes(entityType = this.entityType()) {
82
+ const overlay = this.refreshOverlay();
83
+ return entityType?.attributes.map((a) => applyOverlay(a, overlay[a.name])).filter((a) => a.isVisible && !a.isReadOnly && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject)).sort((a, b) => a.order - b.order) || [];
84
+ }
85
+ async onSave() {
86
+ if (!this.entityType()) return;
87
+ this.validationErrors.set([]);
88
+ this.isSaving.set(true);
89
+ const resolver = (clrName) => this.allEntityTypes().find((t) => t.clrType === clrName);
90
+ const attributes = this.getEditableAttributes().map((attr) => {
91
+ const base = {
92
+ id: attr.id,
93
+ name: attr.name,
94
+ value: isDateDataType(attr.dataType) ? fromDateInputValue(attr.dataType, this.formData()[attr.name]) : this.formData()[attr.name],
95
+ dataType: attr.dataType,
96
+ isArray: attr.isArray,
97
+ isRequired: attr.isRequired,
98
+ isVisible: attr.isVisible,
99
+ isReadOnly: attr.isReadOnly,
100
+ isValueChanged: true,
101
+ order: attr.order,
102
+ rules: attr.rules
103
+ };
104
+ if (attr.dataType === "AsDetail" && attr.asDetailType) {
105
+ const nestedType = resolver(attr.asDetailType);
106
+ if (nestedType) {
107
+ const raw = this.formData()[attr.name];
108
+ base.value = null;
109
+ base.asDetailType = attr.asDetailType;
110
+ if (attr.isArray) {
111
+ base.objects = (Array.isArray(raw) ? raw : []).map((item) => dictToNestedPo(item ?? {}, nestedType, resolver));
112
+ base.object = null;
113
+ } else {
114
+ base.object = raw ? dictToNestedPo(raw, nestedType, resolver) : null;
115
+ base.objects = null;
116
+ }
117
+ }
118
+ }
119
+ return base;
120
+ });
121
+ const po = {
122
+ name: this.formData()["Name"] || "New Item",
123
+ objectTypeId: this.entityType().id,
124
+ attributes
125
+ };
126
+ try {
127
+ const result = await this.sparkService.create(this.type(), po);
128
+ this.isSaving.set(false);
129
+ this.saved.emit(result);
130
+ this.router.navigate([
131
+ "/po",
132
+ this.type(),
133
+ result.id
134
+ ]);
135
+ } catch (e) {
136
+ this.isSaving.set(false);
137
+ const error = e;
138
+ const errors = error.error?.result?.errors ?? error.error?.errors;
139
+ if (error.status === 400 && errors) this.validationErrors.set(errors);
140
+ else this.validationErrors.set([{
141
+ attributeName: "",
142
+ errorMessage: { en: error.message || "An unexpected error occurred" },
143
+ ruleType: "error"
144
+ }]);
145
+ }
146
+ }
147
+ onCancel() {
148
+ this.cancelled.emit();
149
+ window.history.back();
150
+ }
151
+ static ɵfac = i0.ɵɵngDeclareFactory({
152
+ minVersion: "12.0.0",
153
+ version: "22.2.0",
154
+ ngImport: i0,
155
+ type: SparkPoCreateComponent,
156
+ deps: [],
157
+ target: i0.ɵɵFactoryTarget.Component
158
+ });
159
+ static ɵcmp = i0.ɵɵngDeclareComponent({
160
+ minVersion: "17.0.0",
161
+ version: "22.2.0",
162
+ type: SparkPoCreateComponent,
163
+ isStandalone: true,
164
+ selector: "spark-po-create",
165
+ outputs: {
166
+ saved: "saved",
167
+ cancelled: "cancelled"
168
+ },
169
+ ngImport: i0,
170
+ template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [(refreshOverlay)]=\"refreshOverlay\"\n [objectTypeId]=\"type()\"\n [parentType]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n",
171
+ dependencies: [
172
+ {
173
+ kind: "ngmodule",
174
+ type: CommonModule
175
+ },
176
+ {
177
+ kind: "component",
178
+ type: BsAlertComponent,
179
+ selector: "bs-alert",
180
+ inputs: [
181
+ "type",
182
+ "announce",
183
+ "isVisible"
184
+ ],
185
+ outputs: ["isVisibleChange", "afterOpenedOrClosed"]
186
+ },
187
+ {
188
+ kind: "component",
189
+ type: BsContainerComponent,
190
+ selector: "bs-container"
191
+ },
192
+ {
193
+ kind: "component",
194
+ type: BsSpinnerComponent,
195
+ selector: "bs-spinner",
196
+ inputs: ["type", "color"]
197
+ },
198
+ {
199
+ kind: "component",
200
+ type: SparkPoFormComponent,
201
+ selector: "spark-po-form",
202
+ inputs: [
203
+ "entityType",
204
+ "formData",
205
+ "validationErrors",
206
+ "showButtons",
207
+ "isSaving",
208
+ "parentId",
209
+ "parentType",
210
+ "objectTypeId",
211
+ "objectId",
212
+ "triggerPathPrefix",
213
+ "refreshOverlay"
214
+ ],
215
+ outputs: [
216
+ "formDataChange",
217
+ "save",
218
+ "cancel",
219
+ "nestedTriggerRequested",
220
+ "nestedTriggerBlurred",
221
+ "refreshOverlayChange"
222
+ ]
223
+ },
224
+ {
225
+ kind: "pipe",
226
+ type: ResolveTranslationPipe,
227
+ name: "resolveTranslation"
228
+ },
229
+ {
230
+ kind: "pipe",
231
+ type: TranslateKeyPipe,
232
+ name: "t"
233
+ }
234
+ ],
235
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
236
+ });
237
+ };
238
+ i0.ɵɵngDeclareClassMetadata({
239
+ minVersion: "12.0.0",
240
+ version: "22.2.0",
241
+ ngImport: i0,
242
+ type: SparkPoCreateComponent,
243
+ decorators: [{
244
+ type: Component,
245
+ args: [{
246
+ selector: "spark-po-create",
247
+ imports: [
248
+ CommonModule,
249
+ BsAlertComponent,
250
+ BsContainerComponent,
251
+ BsSpinnerComponent,
252
+ SparkPoFormComponent,
253
+ ResolveTranslationPipe,
254
+ TranslateKeyPipe
255
+ ],
256
+ changeDetection: ChangeDetectionStrategy.OnPush,
257
+ template: "<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [(refreshOverlay)]=\"refreshOverlay\"\n [objectTypeId]=\"type()\"\n [parentType]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n"
258
+ }]
259
+ }],
260
+ ctorParameters: () => [],
261
+ propDecorators: {
262
+ saved: [{
263
+ type: i0.Output,
264
+ args: ["saved"]
265
+ }],
266
+ cancelled: [{
267
+ type: i0.Output,
268
+ args: ["cancelled"]
269
+ }]
270
+ }
271
+ });
169
272
  export { SparkPoCreateComponent };
170
- //# sourceMappingURL=mintplayer-ng-spark-po-create.mjs.map
273
+
274
+ //# sourceMappingURL=mintplayer-ng-spark-po-create.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"mintplayer-ng-spark-po-create.mjs","sources":["../../po-create/src/spark-po-create.component.ts","../../po-create/src/spark-po-create.component.html","../../po-create/mintplayer-ng-spark-po-create.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CommonModule } from '@angular/common';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsContainerComponent } from '@mintplayer/ng-bootstrap/container';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { SparkService } from '@mintplayer/ng-spark/services';\nimport { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';\nimport { TranslateKeyPipe, ResolveTranslationPipe } from '@mintplayer/ng-spark/pipes';\nimport {\n EntityType,\n PersistentObject,\n PersistentObjectAttribute,\n ValidationError,\n ShowedOn,\n hasShowedOnFlag,\n dictToNestedPo,\n EntityTypeResolver,\n isDateDataType,\n fromDateInputValue,\n RefreshOverlay,\n applyOverlay,\n} from '@mintplayer/ng-spark/models';\n\n@Component({\n selector: 'spark-po-create',\n imports: [CommonModule, BsAlertComponent, BsContainerComponent, BsSpinnerComponent, SparkPoFormComponent, ResolveTranslationPipe, TranslateKeyPipe],\n templateUrl: './spark-po-create.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SparkPoCreateComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly sparkService = inject(SparkService);\n\n saved = output<PersistentObject>();\n cancelled = output<void>();\n\n colors = Color;\n entityType = signal<EntityType | null>(null);\n type = signal('');\n formData = signal<Record<string, any>>({});\n /** Bound two-way to the form. See {@link getEditableAttributes}. */\n refreshOverlay = signal<RefreshOverlay>({});\n validationErrors = signal<ValidationError[]>([]);\n isSaving = signal(false);\n private allEntityTypes = signal<EntityType[]>([]);\n generalErrors = computed(() => this.validationErrors().filter(e => !e.attributeName));\n\n constructor() {\n this.route.paramMap.pipe(takeUntilDestroyed()).subscribe(params => this.onParamsChange(params));\n }\n\n private async onParamsChange(params: any): Promise<void> {\n this.type.set(params.get('type') || '');\n const types = await this.sparkService.getEntityTypes();\n const entityType = types.find(t => t.id === this.type() || t.alias === this.type()) || null;\n this.entityType.set(entityType);\n this.allEntityTypes.set(types);\n this.initFormData();\n }\n\n initFormData(): void {\n const data: Record<string, any> = {};\n this.getEditableAttributes().forEach(attr => {\n if (attr.dataType === 'Reference') {\n data[attr.name] = null;\n } else if (attr.dataType === 'AsDetail') {\n data[attr.name] = attr.isArray ? [] : {};\n } else if (attr.dataType === 'boolean' && !attr.lookupReferenceType) {\n // Same reason as spark-po-edit: a lookup-backed boolean's third state is the absence of a\n // value, and seeding `false` here would make every new object explicitly opted out.\n data[attr.name] = false;\n } else {\n data[attr.name] = '';\n }\n });\n this.formData.set(data);\n }\n\n /**\n * ⚠️ Overlaid before filtering — same reason as <c>spark-po-edit</c>, and worse here: this list is\n * the <em>only</em> source of the create payload, so an attribute a refresh hook revealed was not\n * merely sent stale, it was absent from the new object entirely.\n */\n getEditableAttributes() {\n const overlay = this.refreshOverlay();\n return this.entityType()?.attributes\n .map(a => applyOverlay(a, overlay[a.name]))\n .filter(a => a.isVisible && !a.isReadOnly && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))\n .sort((a, b) => a.order - b.order) || [];\n }\n\n async onSave(): Promise<void> {\n if (!this.entityType()) return;\n\n this.validationErrors.set([]);\n this.isSaving.set(true);\n\n const resolver: EntityTypeResolver = (clrName) => this.allEntityTypes().find(t => t.clrType === clrName);\n const attributes: PersistentObjectAttribute[] = this.getEditableAttributes().map(attr => {\n const base: PersistentObjectAttribute = {\n id: attr.id,\n name: attr.name,\n // A date control hands back a bare local wall clock; the wire needs a complete ISO-8601\n // instant carrying the viewer's offset for the entered date.\n value: isDateDataType(attr.dataType)\n ? fromDateInputValue(attr.dataType, this.formData()[attr.name])\n : this.formData()[attr.name],\n dataType: attr.dataType,\n isArray: attr.isArray,\n isRequired: attr.isRequired,\n isVisible: attr.isVisible,\n isReadOnly: attr.isReadOnly,\n isValueChanged: true,\n order: attr.order,\n rules: attr.rules,\n };\n\n // AsDetail: pack the flat form dict into nested PO wire shape. Server's polymorphic\n // converter ignores attr.value for AsDetail and reads attr.object / attr.objects.\n if (attr.dataType === 'AsDetail' && attr.asDetailType) {\n const nestedType = resolver(attr.asDetailType);\n if (nestedType) {\n const raw = this.formData()[attr.name];\n base.value = null;\n base.asDetailType = attr.asDetailType;\n if (attr.isArray) {\n const items: any[] = Array.isArray(raw) ? raw : [];\n base.objects = items.map(item => dictToNestedPo((item ?? {}) as Record<string, any>, nestedType, resolver));\n base.object = null;\n } else {\n base.object = raw ? dictToNestedPo(raw as Record<string, any>, nestedType, resolver) : null;\n base.objects = null;\n }\n }\n }\n return base;\n });\n\n const po: Partial<PersistentObject> = {\n name: this.formData()['Name'] || 'New Item',\n objectTypeId: this.entityType()!.id,\n attributes\n };\n\n try {\n const result = await this.sparkService.create(this.type(), po);\n this.isSaving.set(false);\n this.saved.emit(result);\n this.router.navigate(['/po', this.type(), result.id]);\n } catch (e) {\n this.isSaving.set(false);\n const error = e as HttpErrorResponse;\n if (error.status === 400 && error.error?.errors) {\n this.validationErrors.set(error.error.errors);\n } else {\n this.validationErrors.set([{\n attributeName: '',\n errorMessage: { en: error.message || 'An unexpected error occurred' },\n ruleType: 'error'\n }]);\n }\n }\n }\n\n onCancel(): void {\n this.cancelled.emit();\n window.history.back();\n }\n}\n","<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [(refreshOverlay)]=\"refreshOverlay\"\n [objectTypeId]=\"type()\"\n [parentType]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\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-po-create.mjs","names":[],"sources":["../../po-create/src/spark-po-create.component.ts","../../po-create/src/spark-po-create.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, output, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CommonModule } from '@angular/common';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { Color } from '@mintplayer/ng-bootstrap';\nimport { BsAlertComponent } from '@mintplayer/ng-bootstrap/alert';\nimport { BsContainerComponent } from '@mintplayer/ng-bootstrap/container';\nimport { BsSpinnerComponent } from '@mintplayer/ng-bootstrap/spinner';\nimport { SparkService } from '@mintplayer/ng-spark/services';\nimport { SparkPoFormComponent } from '@mintplayer/ng-spark/po-form';\nimport { TranslateKeyPipe, ResolveTranslationPipe } from '@mintplayer/ng-spark/pipes';\nimport {\n EntityType,\n PersistentObject,\n PersistentObjectAttribute,\n ValidationError,\n ShowedOn,\n hasShowedOnFlag,\n dictToNestedPo,\n EntityTypeResolver,\n isDateDataType,\n fromDateInputValue,\n toDateInputValue,\n RefreshOverlay,\n applyOverlay,\n} from '@mintplayer/ng-spark/models';\n\n@Component({\n selector: 'spark-po-create',\n imports: [CommonModule, BsAlertComponent, BsContainerComponent, BsSpinnerComponent, SparkPoFormComponent, ResolveTranslationPipe, TranslateKeyPipe],\n templateUrl: './spark-po-create.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SparkPoCreateComponent {\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly sparkService = inject(SparkService);\n\n saved = output<PersistentObject>();\n cancelled = output<void>();\n\n colors = Color;\n entityType = signal<EntityType | null>(null);\n type = signal('');\n formData = signal<Record<string, any>>({});\n /** Bound two-way to the form. See {@link getEditableAttributes}. */\n refreshOverlay = signal<RefreshOverlay>({});\n validationErrors = signal<ValidationError[]>([]);\n isSaving = signal(false);\n private allEntityTypes = signal<EntityType[]>([]);\n generalErrors = computed(() => this.validationErrors().filter(e => !e.attributeName));\n\n constructor() {\n this.route.paramMap.pipe(takeUntilDestroyed()).subscribe(params => this.onParamsChange(params));\n }\n\n private async onParamsChange(params: any): Promise<void> {\n this.type.set(params.get('type') || '');\n const types = await this.sparkService.getEntityTypes();\n const entityType = types.find(t => t.id === this.type() || t.alias === this.type()) || null;\n this.allEntityTypes.set(types);\n this.initFormData(entityType);\n if (entityType) await this.applyServerDefaults(entityType);\n this.entityType.set(entityType);\n }\n\n /**\n * The blank object comes from the server (#460, D19): `/po/new` runs the type's `OnNewAsync`, so a\n * default a hook sets — and, for a New started from a sub-query, the reference to the parent the\n * base hook fills — reaches the form. The sub-query card passes the parent as query parameters\n * (`parentId`, `parentType`, `queryId`), so it survives the navigation and a reload of this page.\n *\n * A refusal (the parent is gone, or not the caller's to see) is shown and the client-side blank\n * form stays usable, exactly as it was before the round-trip existed.\n */\n private async applyServerDefaults(entityType: EntityType): Promise<void> {\n const query = this.route.snapshot.queryParamMap;\n const parentId = query.get('parentId') ?? undefined;\n const parentType = query.get('parentType') ?? undefined;\n const queryId = query.get('queryId') ?? undefined;\n const fromSubQuery = !!(parentId && parentType && queryId);\n\n try {\n const po = await this.sparkService.newObject(this.type(), fromSubQuery ? { parentId, parentType, queryId } : undefined);\n const editable = new Map(this.getEditableAttributes(entityType).map(a => [a.name, a] as const));\n const data = { ...this.formData() };\n for (const attr of po?.attributes ?? []) {\n const definition = editable.get(attr.name);\n if (!definition || attr.value === null || attr.value === undefined || definition.dataType === 'AsDetail') continue;\n data[attr.name] = isDateDataType(definition.dataType)\n ? toDateInputValue(definition.dataType, attr.value)\n : attr.value;\n }\n this.formData.set(data);\n } catch (e) {\n const error = e as HttpErrorResponse;\n const errors = error.error?.result?.errors ?? error.error?.errors;\n this.validationErrors.set(errors ?? [{\n attributeName: '',\n errorMessage: { en: error.message || 'The new item could not be prepared.' },\n ruleType: 'error'\n }]);\n }\n }\n\n initFormData(entityType: EntityType | null = this.entityType()): void {\n const data: Record<string, any> = {};\n this.getEditableAttributes(entityType).forEach(attr => {\n if (attr.dataType === 'Reference') {\n data[attr.name] = null;\n } else if (attr.dataType === 'AsDetail') {\n data[attr.name] = attr.isArray ? [] : {};\n } else if (attr.dataType === 'boolean' && !attr.lookupReferenceType) {\n // Same reason as spark-po-edit: a lookup-backed boolean's third state is the absence of a\n // value, and seeding `false` here would make every new object explicitly opted out.\n data[attr.name] = false;\n } else {\n data[attr.name] = '';\n }\n });\n this.formData.set(data);\n }\n\n /**\n * ⚠️ Overlaid before filtering — same reason as <c>spark-po-edit</c>, and worse here: this list is\n * the <em>only</em> source of the create payload, so an attribute a refresh hook revealed was not\n * merely sent stale, it was absent from the new object entirely.\n */\n getEditableAttributes(entityType: EntityType | null = this.entityType()) {\n const overlay = this.refreshOverlay();\n return entityType?.attributes\n .map(a => applyOverlay(a, overlay[a.name]))\n .filter(a => a.isVisible && !a.isReadOnly && hasShowedOnFlag(a.showedOn, ShowedOn.PersistentObject))\n .sort((a, b) => a.order - b.order) || [];\n }\n\n async onSave(): Promise<void> {\n if (!this.entityType()) return;\n\n this.validationErrors.set([]);\n this.isSaving.set(true);\n\n const resolver: EntityTypeResolver = (clrName) => this.allEntityTypes().find(t => t.clrType === clrName);\n const attributes: PersistentObjectAttribute[] = this.getEditableAttributes().map(attr => {\n const base: PersistentObjectAttribute = {\n id: attr.id,\n name: attr.name,\n // A date control hands back a bare local wall clock; the wire needs a complete ISO-8601\n // instant carrying the viewer's offset for the entered date.\n value: isDateDataType(attr.dataType)\n ? fromDateInputValue(attr.dataType, this.formData()[attr.name])\n : this.formData()[attr.name],\n dataType: attr.dataType,\n isArray: attr.isArray,\n isRequired: attr.isRequired,\n isVisible: attr.isVisible,\n isReadOnly: attr.isReadOnly,\n isValueChanged: true,\n order: attr.order,\n rules: attr.rules,\n };\n\n // AsDetail: pack the flat form dict into nested PO wire shape. Server's polymorphic\n // converter ignores attr.value for AsDetail and reads attr.object / attr.objects.\n if (attr.dataType === 'AsDetail' && attr.asDetailType) {\n const nestedType = resolver(attr.asDetailType);\n if (nestedType) {\n const raw = this.formData()[attr.name];\n base.value = null;\n base.asDetailType = attr.asDetailType;\n if (attr.isArray) {\n const items: any[] = Array.isArray(raw) ? raw : [];\n base.objects = items.map(item => dictToNestedPo((item ?? {}) as Record<string, any>, nestedType, resolver));\n base.object = null;\n } else {\n base.object = raw ? dictToNestedPo(raw as Record<string, any>, nestedType, resolver) : null;\n base.objects = null;\n }\n }\n }\n return base;\n });\n\n const po: Partial<PersistentObject> = {\n name: this.formData()['Name'] || 'New Item',\n objectTypeId: this.entityType()!.id,\n attributes\n };\n\n try {\n const result = await this.sparkService.create(this.type(), po);\n this.isSaving.set(false);\n this.saved.emit(result);\n this.router.navigate(['/po', this.type(), result.id]);\n } catch (e) {\n this.isSaving.set(false);\n const error = e as HttpErrorResponse;\n // The errors live under `result` (every endpoint wraps its body in a ClientOperationEnvelope:\n // `{ result: { errors: [...] }, operations: [] }`), as in po-edit. Reading only\n // `error.error.errors` showed every create-time refusal as the raw Angular HTTP string.\n const errors = error.error?.result?.errors ?? error.error?.errors;\n if (error.status === 400 && errors) {\n this.validationErrors.set(errors);\n } else {\n this.validationErrors.set([{\n attributeName: '',\n errorMessage: { en: error.message || 'An unexpected error occurred' },\n ruleType: 'error'\n }]);\n }\n }\n }\n\n onCancel(): void {\n this.cancelled.emit();\n window.history.back();\n }\n}\n","<bs-container>\n<div class=\"container\">\n @if (entityType(); as et) {\n <h2 class=\"mb-4\">{{ 'common.create' | t }} {{ (et.description | resolveTranslation) || et.name }}</h2>\n\n @for (error of generalErrors(); track error.errorMessage) {\n <bs-alert [type]=\"colors.danger\" class=\"mb-3\">\n {{ error.errorMessage | resolveTranslation }}\n </bs-alert>\n }\n\n <spark-po-form\n [entityType]=\"et\"\n [(formData)]=\"formData\"\n [(refreshOverlay)]=\"refreshOverlay\"\n [objectTypeId]=\"type()\"\n [parentType]=\"type()\"\n [validationErrors]=\"validationErrors()\"\n [showButtons]=\"true\"\n [isSaving]=\"isSaving()\"\n (save)=\"onSave()\"\n (cancel)=\"onCancel()\">\n </spark-po-form>\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n</bs-container>\n"],"mappings":";;;;;;;;;;;;;AAkCA,IAAa,yBAAb,MAAa,uBAAsB;CAChB,QAAQ,OAAO,cAAc;CAC7B,SAAS,OAAO,MAAM;CACtB,eAAe,OAAO,YAAY;CAEnD,QAAQ,OAAM;CACd,YAAY,OAAM;CAElB,SAAS;CACT,aAAa,OAA0B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAC5C,OAAO,OAAO,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CACjB,WAAW,OAA4B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAE1C,iBAAiB,OAAuB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CAC3C,mBAAmB,OAA0B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;CAChD,WAAW,OAAO,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;CAChB,iBAAiB,OAAqB,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;CACjD,gBAAgB,eAAe,KAAK,iBAAgB,CAAE,CAAC,QAAO,MAAK,CAAC,EAAE,aAAa,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;CAErF,cAAA;EACE,KAAK,MAAM,SAAS,KAAK,mBAAkB,CAAE,CAAC,CAAC,WAAU,WAAU,KAAK,eAAe,MAAM,CAAC;CAChG;CAEQ,MAAM,eAAe,QAAW;EACtC,KAAK,KAAK,IAAI,OAAO,IAAI,MAAM,KAAK,EAAE;EACtC,MAAM,QAAQ,MAAM,KAAK,aAAa,eAAc;EACpD,MAAM,aAAa,MAAM,MAAK,MAAK,EAAE,OAAO,KAAK,KAAI,KAAM,EAAE,UAAU,KAAK,KAAI,CAAE,KAAK;EACvF,KAAK,eAAe,IAAI,KAAK;EAC7B,KAAK,aAAa,UAAU;EAC5B,IAAI,YAAY,MAAM,KAAK,oBAAoB,UAAU;EACzD,KAAK,WAAW,IAAI,UAAU;CAChC;CAWQ,MAAM,oBAAoB,YAAsB;EACtD,MAAM,QAAQ,KAAK,MAAM,SAAS;EAClC,MAAM,WAAW,MAAM,IAAI,UAAU,KAAK;EAC1C,MAAM,aAAa,MAAM,IAAI,YAAY,KAAK;EAC9C,MAAM,UAAU,MAAM,IAAI,SAAS,KAAK;EACxC,MAAM,eAAe,CAAC,EAAE,YAAY,cAAc;EAElD,IAAI;GACF,MAAM,KAAK,MAAM,KAAK,aAAa,UAAU,KAAK,KAAI,GAAI,eAAe;IAAE;IAAU;IAAY;GAAO,IAAK,MAAS;GACtH,MAAM,WAAW,IAAI,IAAI,KAAK,sBAAsB,UAAU,CAAC,CAAC,KAAI,MAAK,CAAC,EAAE,MAAM,CAAC,CAAU,CAAC;GAC9F,MAAM,OAAO,EAAE,GAAG,KAAK,SAAQ,EAAE;GACjC,KAAK,MAAM,QAAQ,IAAI,cAAc,CAAA,GAAI;IACvC,MAAM,aAAa,SAAS,IAAI,KAAK,IAAI;IACzC,IAAI,CAAC,cAAc,KAAK,UAAU,QAAQ,KAAK,UAAU,UAAa,WAAW,aAAa,YAAY;IAC1G,KAAK,KAAK,QAAQ,eAAe,WAAW,QAAQ,IAChD,iBAAiB,WAAW,UAAU,KAAK,KAAK,IAChD,KAAK;GACX;GACA,KAAK,SAAS,IAAI,IAAI;EACxB,SAAS,GAAG;GACV,MAAM,QAAQ;GACd,MAAM,SAAS,MAAM,OAAO,QAAQ,UAAU,MAAM,OAAO;GAC3D,KAAK,iBAAiB,IAAI,UAAU,CAAC;IACnC,eAAe;IACf,cAAc,EAAE,IAAI,MAAM,WAAW,sCAAqC;IAC1E,UAAU;GACX,CAAA,CAAC;EACJ;CACF;CAEA,aAAa,aAAgC,KAAK,WAAU,GAAE;EAC5D,MAAM,OAA4B,CAAA;EAClC,KAAK,sBAAsB,UAAU,CAAC,CAAC,SAAQ,SAAO;GACpD,IAAI,KAAK,aAAa,aACpB,KAAK,KAAK,QAAQ;QACb,IAAI,KAAK,aAAa,YAC3B,KAAK,KAAK,QAAQ,KAAK,UAAU,CAAA,IAAK,CAAA;QACjC,IAAI,KAAK,aAAa,aAAa,CAAC,KAAK,qBAG9C,KAAK,KAAK,QAAQ;QAElB,KAAK,KAAK,QAAQ;EAEtB,CAAC;EACD,KAAK,SAAS,IAAI,IAAI;CACxB;CAOA,sBAAsB,aAAgC,KAAK,WAAU,GAAE;EACrE,MAAM,UAAU,KAAK,eAAc;EACnC,OAAO,YAAY,WAChB,KAAI,MAAK,aAAa,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC,CAC1C,QAAO,MAAK,EAAE,aAAa,CAAC,EAAE,cAAc,gBAAgB,EAAE,UAAU,SAAS,gBAAgB,CAAC,CAAC,CACnG,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,KAAK,CAAA;CAC1C;CAEA,MAAM,SAAM;EACV,IAAI,CAAC,KAAK,WAAU,GAAI;EAExB,KAAK,iBAAiB,IAAI,CAAA,CAAE;EAC5B,KAAK,SAAS,IAAI,IAAI;EAEtB,MAAM,YAAgC,YAAY,KAAK,eAAc,CAAE,CAAC,MAAK,MAAK,EAAE,YAAY,OAAO;EACvG,MAAM,aAA0C,KAAK,sBAAqB,CAAE,CAAC,KAAI,SAAO;GACtF,MAAM,OAAkC;IACtC,IAAI,KAAK;IACT,MAAM,KAAK;IAGX,OAAO,eAAe,KAAK,QAAQ,IAC/B,mBAAmB,KAAK,UAAU,KAAK,SAAQ,CAAE,CAAC,KAAK,KAAK,IAC5D,KAAK,SAAQ,CAAE,CAAC,KAAK;IACzB,UAAU,KAAK;IACf,SAAS,KAAK;IACd,YAAY,KAAK;IACjB,WAAW,KAAK;IAChB,YAAY,KAAK;IACjB,gBAAgB;IAChB,OAAO,KAAK;IACZ,OAAO,KAAK;GACb;GAID,IAAI,KAAK,aAAa,cAAc,KAAK,cAAc;IACrD,MAAM,aAAa,SAAS,KAAK,YAAY;IAC7C,IAAI,YAAY;KACd,MAAM,MAAM,KAAK,SAAQ,CAAE,CAAC,KAAK;KACjC,KAAK,QAAQ;KACb,KAAK,eAAe,KAAK;KACzB,IAAI,KAAK,SAAS;MAEhB,KAAK,WADgB,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAA,EACjC,CAAM,KAAI,SAAQ,eAAgB,QAAQ,CAAA,GAA4B,YAAY,QAAQ,CAAC;MAC1G,KAAK,SAAS;KAChB,OAAO;MACL,KAAK,SAAS,MAAM,eAAe,KAA4B,YAAY,QAAQ,IAAI;MACvF,KAAK,UAAU;KACjB;IACF;GACF;GACA,OAAO;EACT,CAAC;EAED,MAAM,KAAgC;GACpC,MAAM,KAAK,SAAQ,CAAE,CAAC,WAAW;GACjC,cAAc,KAAK,WAAU,CAAG,CAAC;GACjC;EACD;EAED,IAAI;GACF,MAAM,SAAS,MAAM,KAAK,aAAa,OAAO,KAAK,KAAI,GAAI,EAAE;GAC7D,KAAK,SAAS,IAAI,KAAK;GACvB,KAAK,MAAM,KAAK,MAAM;GACtB,KAAK,OAAO,SAAS;IAAC;IAAO,KAAK,KAAI;IAAI,OAAO;GAAE,CAAC;EACtD,SAAS,GAAG;GACV,KAAK,SAAS,IAAI,KAAK;GACvB,MAAM,QAAQ;GAId,MAAM,SAAS,MAAM,OAAO,QAAQ,UAAU,MAAM,OAAO;GAC3D,IAAI,MAAM,WAAW,OAAO,QAC1B,KAAK,iBAAiB,IAAI,MAAM;QAEhC,KAAK,iBAAiB,IAAI,CAAC;IACzB,eAAe;IACf,cAAc,EAAE,IAAI,MAAM,WAAW,+BAA8B;IACnE,UAAU;GACX,CAAA,CAAC;EAEN;CACF;CAEA,WAAQ;EACN,KAAK,UAAU,KAAI;EACnB,OAAO,QAAQ,KAAI;CACrB;CAvLW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAsB,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAtB,OAAA,OAAA,GAAA,qBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,MAAA;EAAsB,cAAA;EAAA,UAAA;EAAA,SAAA;GAAA,OAAA;GAAA,WAAA;EAAA;EAAA,UAAA;EAAA,UClCnC;EA8BA,cAAA;GAAA;IAAA,MAAA;IAAA,MDAY;GAAY;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA,CAAA,mBAAA,qBAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAoB,UAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAkB,UAAA;IAAA,QAAA,CAAA,QAAA,OAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAoB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAsB,MAAA;GAAA;GAAA;IAAA,MAAA;IAAA,MAAE;IAAgB,MAAA;GAAA;EAAA;EAAA,iBAAA,GAAA,wBAAA;CAAA,CAAA;;AAIvI,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAsB,YAAA,CAAA;EANlC,MAAA;EACW,MAAA,CAAA;GAAA,UAAA;GAAiB,SAClB;IAAC;IAAc;IAAkB;IAAsB;IAAoB;IAAsB;IAAwB;GAAgB;GAAC,iBAElI,wBAAwB;GAAM,UAAA;EAAA,CAAA"}