@eherve/angular-material-entity-wizard 0.0.0-stage → 22.1.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.
package/README.md
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Angular Material entity wizard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Independent creation wizard using the shared forms session and renderers. This package has no dependency on edit-entity-dialog.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { CreateEntityWizardService, createEntityWizardOptions, CreateEntityWizardComponentOptions } from '@eherve/angular-material-entity-wizard';
|
|
7
|
+
|
|
8
|
+
const options = createEntityWizardOptions({
|
|
9
|
+
title: 'Create',
|
|
10
|
+
steps: [{ id: 'main', label: 'Main', displayOptions: { section: { id: 'main', label: '', cards: [] } } }],
|
|
11
|
+
service: { create: async value => ({ _id: 'created', ...value }) },
|
|
12
|
+
});
|
|
13
|
+
wizard.open(options);
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`CreateEntityWizardComponentOptions<TRecord>` extends the canonical `EditEntityComponentOptions<TRecord>` from `@eherve/angular-material-forms/core` with `wizard`. The normalization helper retains the established wizard configuration shape and options identity when opened. Standard edit options contain no wizard property.
|
|
17
|
+
|
|
18
|
+
Each wizard owns one shared `EntityFormSession`; changing a step does not replace the form. Its scoped save policy projects only current-step and always-in-upsert fields, preserves other-step drafts during server hydration, blocks navigation during saves or pending validation and accumulates created/updated results. Component-managed steps use the supplied `markUpdated` callback. The independent modal wrapper retains top-dialog keyboard and focused-input key ownership behavior.
|
|
19
|
+
|
|
20
|
+
Include `@eherve/angular-material-forms/styles.css` once. Public `EntityWizardComponent` supports page or modal display, and `CreateEntityWizardService` opens its own `EntityWizardDialog`. Version `22.0.0` requires `@eherve/angular-material-forms@^22.0.0` and has no dependency on edit-dialog.
|
|
21
|
+
|
|
22
|
+
### Restoring navigation
|
|
23
|
+
|
|
24
|
+
`CreateEntityWizardOptions` accepts the shared `navigation` options. Each step's stable
|
|
25
|
+
`id` is its `navigation.tab`; child section navigation uses the existing adapters.
|
|
26
|
+
Initial selection applies after record hydration and visible-step computation. Existing
|
|
27
|
+
persisted records can select an allowed visible step; a record without an id retains
|
|
28
|
+
the first-step restriction. Restoration never calls create, update or Continue.
|
|
29
|
+
`stateChanges` and lifecycle-handle navigation update the actual wizard selection,
|
|
30
|
+
respecting pending validation/updating restrictions. User step changes publish `onChange`.
|
|
31
|
+
The forms connection lifecycle (`ready`, `presentationChanged`, `failed`, `beforeClose`)
|
|
32
|
+
also applies to wizard sessions.
|
|
33
|
+
|
|
34
|
+
The optional lifecycle connection `opened(handle)` receives a close-only `requestClose(): Promise<boolean>` handle before asynchronous loading. It supports cancelling loading or failed content through the existing close guards; it does not signal readiness. `ready` remains the rendered-content barrier. Handles from previous openings return `false`.
|
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
import * as i2 from "@angular/forms";
|
|
2
|
+
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from "@angular/forms";
|
|
3
|
+
import { EditEntityConditionalStateService, EditEntityFormBuilderService, EditEntityRenderService, EditEntitySubmitValueService, isNonEditable } from "@eherve/angular-material-forms/core";
|
|
4
|
+
import { cloneDeep, get, has, isEqual, set } from "lodash-es";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import { ChangeDetectionStrategy, Component, Inject, Injectable, Input, Output, ViewChild, computed, inject, signal } from "@angular/core";
|
|
7
|
+
import { EntityDialogKeyboardHost, EntityDialogLauncher, EntityFormSession } from "@eherve/angular-material-forms/editor";
|
|
8
|
+
import * as i1 from "@angular/material/dialog";
|
|
9
|
+
import { MAT_DIALOG_DATA } from "@angular/material/dialog";
|
|
10
|
+
import * as i1$1 from "@angular/common";
|
|
11
|
+
import { CommonModule } from "@angular/common";
|
|
12
|
+
import * as i3 from "@angular/material/button";
|
|
13
|
+
import { MatButtonModule } from "@angular/material/button";
|
|
14
|
+
import * as i4 from "@angular/material/icon";
|
|
15
|
+
import { MatIconModule } from "@angular/material/icon";
|
|
16
|
+
import * as i5 from "@angular/material/progress-spinner";
|
|
17
|
+
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
|
18
|
+
import * as i7 from "@angular/material/stepper";
|
|
19
|
+
import { MatStepper, MatStepperModule } from "@angular/material/stepper";
|
|
20
|
+
import * as i6 from "@angular/material/tooltip";
|
|
21
|
+
import { MatTooltipModule } from "@angular/material/tooltip";
|
|
22
|
+
import { FormContentComponent } from "@eherve/angular-material-forms/layout";
|
|
23
|
+
var CreateEntityWizardState = class {
|
|
24
|
+
valid(form, paths) {
|
|
25
|
+
return paths.every((path) => {
|
|
26
|
+
const control = form.getControl(path);
|
|
27
|
+
return !control || control.disabled || !control.pending && control.valid;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
project(form, paths, changedOnly, always = []) {
|
|
31
|
+
const value = {};
|
|
32
|
+
for (const path of /* @__PURE__ */ new Set([...paths, ...always])) {
|
|
33
|
+
const control = form.getControl(path);
|
|
34
|
+
if (!control || isNonEditable(control)) continue;
|
|
35
|
+
const current = control.getRawValue();
|
|
36
|
+
const initial = this.read(form.initialValue, path);
|
|
37
|
+
if (!changedOnly || always.includes(path) || !isEqual(current, initial)) set(value, path, cloneDeep(current));
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
hydrate(form, record, submitted) {
|
|
42
|
+
const baseline = cloneDeep(form.initialValue);
|
|
43
|
+
const visit = (control, path) => {
|
|
44
|
+
if (control instanceof FormGroup) {
|
|
45
|
+
for (const [key, child] of Object.entries(control.controls)) visit(child, path ? `${path}.${key}` : key);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const saved = submitted.some((name) => path === name || path.startsWith(`${name}.`));
|
|
49
|
+
const current = control.getRawValue();
|
|
50
|
+
const draft = !isEqual(current, this.read(baseline, path));
|
|
51
|
+
if (saved || !draft) {
|
|
52
|
+
if (has(record, path)) control.patchValue(cloneDeep(get(record, path)), { emitEvent: false });
|
|
53
|
+
if (Object.prototype.hasOwnProperty.call(form.controls, path)) baseline[path] = cloneDeep(control.getRawValue());
|
|
54
|
+
else set(baseline, path, cloneDeep(control.getRawValue()));
|
|
55
|
+
control.markAsPristine();
|
|
56
|
+
control.markAsUntouched();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
visit(form, "");
|
|
60
|
+
form.setInitialValue(baseline);
|
|
61
|
+
}
|
|
62
|
+
read(value, path) {
|
|
63
|
+
return Object.prototype.hasOwnProperty.call(value, path) ? value[path] : get(value, path);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var EntityWizardComponent = class EntityWizardComponent {
|
|
67
|
+
options;
|
|
68
|
+
displayMode = "page";
|
|
69
|
+
session = inject(EntityFormSession);
|
|
70
|
+
result = this.session.result;
|
|
71
|
+
closeRequest = this.session.closeRequest;
|
|
72
|
+
ngOnInit() {
|
|
73
|
+
this.session.options = this.options;
|
|
74
|
+
this.session.displayMode = this.displayMode;
|
|
75
|
+
this.session.policy = {
|
|
76
|
+
valid: () => this.wizardValid,
|
|
77
|
+
value: (create) => this.wizardValue(create),
|
|
78
|
+
patch: (record, value) => this.patchWizardRecord(record, value),
|
|
79
|
+
saved: (record, value) => this.hydrateWizard(record, value),
|
|
80
|
+
hydrate: (record) => this.wizardState.hydrate(this.session.formGroup, record, []),
|
|
81
|
+
refresh: () => this.refreshWizardState(),
|
|
82
|
+
navigate: () => this.restoreWizardNavigation(),
|
|
83
|
+
reset: () => {
|
|
84
|
+
this.wizardIndex.set(0);
|
|
85
|
+
this.wizardCompleted.set(this.options.wizard.steps.map(() => false));
|
|
86
|
+
this.wizardVisibleIndices.set([]);
|
|
87
|
+
this.wizardNavigationControls = [];
|
|
88
|
+
},
|
|
89
|
+
componentUpdated: () => this.completeWizardStep(),
|
|
90
|
+
beforeClose: () => this.session.formGroup.setInitialValue(this.session.formGroup.initialValue),
|
|
91
|
+
stickyResult: true
|
|
92
|
+
};
|
|
93
|
+
this.session.initialize();
|
|
94
|
+
}
|
|
95
|
+
ngOnChanges(changes) {
|
|
96
|
+
if (changes["options"] && !changes["options"].firstChange) {
|
|
97
|
+
this.session.options = this.options;
|
|
98
|
+
this.session.initialize();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
ngOnDestroy() {
|
|
102
|
+
this.session.destroy();
|
|
103
|
+
}
|
|
104
|
+
requestClose() {
|
|
105
|
+
return this.session.requestClose();
|
|
106
|
+
}
|
|
107
|
+
refreshPresentation() {
|
|
108
|
+
this.session.refreshPresentation();
|
|
109
|
+
}
|
|
110
|
+
submitFromKeyboard() {
|
|
111
|
+
if (!this.options.validateOnEnter || this.session.loading || this.session.updating) return false;
|
|
112
|
+
this.wizardNext();
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
wizardIndex = signal(0, ...ngDevMode ? [{ debugName: "wizardIndex" }] : /* istanbul ignore next */ []);
|
|
116
|
+
wizardDrafts = signal([], ...ngDevMode ? [{ debugName: "wizardDrafts" }] : /* istanbul ignore next */ []);
|
|
117
|
+
wizardCompleted = signal([], ...ngDevMode ? [{ debugName: "wizardCompleted" }] : /* istanbul ignore next */ []);
|
|
118
|
+
wizardVisibleIndices = signal([], ...ngDevMode ? [{ debugName: "wizardVisibleIndices" }] : /* istanbul ignore next */ []);
|
|
119
|
+
wizardVisualIndex = computed(() => Math.max(0, this.wizardVisibleIndices().indexOf(this.wizardIndex())), ...ngDevMode ? [{ debugName: "wizardVisualIndex" }] : /* istanbul ignore next */ []);
|
|
120
|
+
wizardNavigationBlocked = signal(false, ...ngDevMode ? [{ debugName: "wizardNavigationBlocked" }] : /* istanbul ignore next */ []);
|
|
121
|
+
wizardLinear = signal(true, ...ngDevMode ? [{ debugName: "wizardLinear" }] : /* istanbul ignore next */ []);
|
|
122
|
+
wizardNavigationControls = [];
|
|
123
|
+
wizardStepper;
|
|
124
|
+
wizardState = new CreateEntityWizardState();
|
|
125
|
+
get wizardStep() {
|
|
126
|
+
return this.options?.wizard?.steps[this.wizardIndex()];
|
|
127
|
+
}
|
|
128
|
+
get wizardLast() {
|
|
129
|
+
return this.wizardIndex() === this.wizardVisibleIndices().at(-1);
|
|
130
|
+
}
|
|
131
|
+
get wizardPrimaryLabel() {
|
|
132
|
+
const wizard = this.options.wizard;
|
|
133
|
+
if (!this.options.record?._id) return wizard?.createNextLabel ?? this.session.intl.messages.wizardCreateNext;
|
|
134
|
+
return this.wizardLast ? wizard?.finishLabel ?? this.session.intl.messages.wizardFinish : wizard?.nextLabel ?? this.session.intl.messages.wizardNext;
|
|
135
|
+
}
|
|
136
|
+
get wizardExitLabel() {
|
|
137
|
+
return this.options.record?._id ? this.options.wizard?.finishLaterLabel ?? this.session.intl.messages.wizardFinishLater : this.session.cancelLabel;
|
|
138
|
+
}
|
|
139
|
+
selectWizardVisualStep(position) {
|
|
140
|
+
const index = this.wizardVisibleIndices()[position];
|
|
141
|
+
if (index !== void 0) this.selectWizardStep(index);
|
|
142
|
+
}
|
|
143
|
+
advanceWizard() {
|
|
144
|
+
const next = this.wizardVisibleIndices()[this.wizardVisualIndex() + 1];
|
|
145
|
+
if (next !== void 0) {
|
|
146
|
+
this.wizardIndex.set(next);
|
|
147
|
+
this.publishWizardNavigation();
|
|
148
|
+
this.refreshWizardNavigation();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
completeWizardStep() {
|
|
152
|
+
const completed = [...this.wizardCompleted()];
|
|
153
|
+
completed[this.wizardIndex()] = true;
|
|
154
|
+
this.wizardCompleted.set(completed);
|
|
155
|
+
this.refreshWizardNavigation();
|
|
156
|
+
}
|
|
157
|
+
refreshWizardNavigation() {
|
|
158
|
+
if (!this.options?.wizard) return;
|
|
159
|
+
const blocked = this.session.updating || this.wizardPending;
|
|
160
|
+
this.wizardNavigationBlocked.set(blocked);
|
|
161
|
+
const linear = !this.options.record?._id || blocked;
|
|
162
|
+
this.wizardLinear.set(linear);
|
|
163
|
+
if (this.wizardStepper) this.wizardStepper.linear = linear;
|
|
164
|
+
const count = this.options.wizard.steps.length;
|
|
165
|
+
if (this.wizardNavigationControls.length !== count) this.wizardNavigationControls = Array.from({ length: count }, () => new FormControl(false, {
|
|
166
|
+
nonNullable: true,
|
|
167
|
+
validators: Validators.requiredTrue
|
|
168
|
+
}));
|
|
169
|
+
for (const [index, control] of this.wizardNavigationControls.entries()) control.setValue(!blocked && (index !== 0 || !!this.options.record?._id), { emitEvent: false });
|
|
170
|
+
this.wizardStepper?.steps.forEach((step, position) => {
|
|
171
|
+
const index = this.wizardVisibleIndices()[position];
|
|
172
|
+
step.optional = false;
|
|
173
|
+
step.interacted = true;
|
|
174
|
+
step.completed = !blocked && !!this.wizardCompleted()[index];
|
|
175
|
+
step.editable = !blocked && (index === 0 || !!this.options.record?._id);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
get wizardValid() {
|
|
179
|
+
return this.wizardState.valid(this.session.formGroup, [...this.wizardPaths(), ...this.wizardAlwaysPaths()]);
|
|
180
|
+
}
|
|
181
|
+
get wizardPending() {
|
|
182
|
+
return [...this.wizardPaths(), ...this.wizardAlwaysPaths()].some((path) => this.session.formGroup.getControl(path)?.pending);
|
|
183
|
+
}
|
|
184
|
+
get wizardUnsaved() {
|
|
185
|
+
return Object.keys(this.wizardState.project(this.session.formGroup, this.wizardPaths(), true)).length > 0;
|
|
186
|
+
}
|
|
187
|
+
selectWizardStep(index) {
|
|
188
|
+
if (this.session.updating || this.wizardPending || !this.options.wizard || index < 0 || index >= this.options.wizard.steps.length || !this.wizardVisibleIndices().includes(index)) return;
|
|
189
|
+
if (index > 0 && !this.options.record?._id) return;
|
|
190
|
+
this.wizardIndex.set(index);
|
|
191
|
+
this.publishWizardNavigation();
|
|
192
|
+
this.refreshWizardNavigation();
|
|
193
|
+
}
|
|
194
|
+
skipWizardStep() {
|
|
195
|
+
if (this.session.updating || this.wizardPending || !this.wizardStep?.optional || !this.options.record?._id) return;
|
|
196
|
+
if (this.wizardLast) this.requestClose();
|
|
197
|
+
else this.advanceWizard();
|
|
198
|
+
}
|
|
199
|
+
async wizardNext() {
|
|
200
|
+
if (this.session.updating || !this.options.wizard) return;
|
|
201
|
+
const isCurrent = this.session.captureCurrentOperation();
|
|
202
|
+
if (!this.wizardStep?.componentManaged) {
|
|
203
|
+
for (const path of this.wizardPaths()) this.session.formGroup.getControl(path)?.markAllAsTouched();
|
|
204
|
+
if (!this.wizardValid) return;
|
|
205
|
+
const previous = this.session.savedResult;
|
|
206
|
+
if (!this.options.record?._id) await this.session.create();
|
|
207
|
+
else if (this.wizardUnsaved) await this.session.update();
|
|
208
|
+
else {
|
|
209
|
+
this.completeWizardStep();
|
|
210
|
+
if (this.wizardLast) await this.requestClose();
|
|
211
|
+
else this.advanceWizard();
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (!isCurrent() || previous === this.session.savedResult) return;
|
|
215
|
+
}
|
|
216
|
+
if (this.wizardLast) await this.requestClose();
|
|
217
|
+
else this.advanceWizard();
|
|
218
|
+
}
|
|
219
|
+
wizardPaths(index = this.wizardIndex()) {
|
|
220
|
+
const display = this.options?.displayOptions;
|
|
221
|
+
const tab = display && "tabs" in display ? display.tabs[index] : void 0;
|
|
222
|
+
const names = tab ? this.session.renderService.collectFields(tab.displayOptions).flatMap((field) => field.kind === "separator" || field.kind === "metadata" || field.kind === "display" ? [] : [field.name]) : [];
|
|
223
|
+
return [.../* @__PURE__ */ new Set([...names, ...this.options.wizard?.steps[index]?.fields ?? []])];
|
|
224
|
+
}
|
|
225
|
+
wizardAlwaysPaths() {
|
|
226
|
+
return this.session.fields.flatMap((field) => field.kind !== "separator" && field.kind !== "metadata" && field.kind !== "display" && field.alwaysInUpsert ? [field.name] : []);
|
|
227
|
+
}
|
|
228
|
+
wizardValue(create) {
|
|
229
|
+
const paths = this.wizardPaths();
|
|
230
|
+
const always = this.wizardAlwaysPaths();
|
|
231
|
+
const value = this.wizardState.project(this.session.formGroup, paths, !create, always);
|
|
232
|
+
if (create) {
|
|
233
|
+
for (const path of [...paths, ...always]) if (!this.session.formGroup.getControl(path) && has(this.options.defaultValues, path)) set(value, path, cloneDeep(get(this.options.defaultValues, path)));
|
|
234
|
+
}
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
patchWizardRecord(record, value) {
|
|
238
|
+
const updated = cloneDeep(record);
|
|
239
|
+
for (const path of [...this.wizardPaths(), ...this.wizardAlwaysPaths()]) if (has(value, path)) set(updated, path, cloneDeep(get(value, path)));
|
|
240
|
+
return updated;
|
|
241
|
+
}
|
|
242
|
+
async hydrateWizard(record, value) {
|
|
243
|
+
const paths = [...this.wizardPaths(), ...this.wizardAlwaysPaths()].filter((path) => has(value, path));
|
|
244
|
+
this.wizardState.hydrate(this.session.formGroup, record, paths);
|
|
245
|
+
this.completeWizardStep();
|
|
246
|
+
this.session.updated = this.session.formGroup.isUpdated;
|
|
247
|
+
this.session.refreshAllowedActions();
|
|
248
|
+
this.session.refreshRuntimeState();
|
|
249
|
+
}
|
|
250
|
+
publishWizardNavigation() {
|
|
251
|
+
this.session.navigationController.selectTab(this.wizardVisualIndex());
|
|
252
|
+
}
|
|
253
|
+
restoreWizardNavigation() {
|
|
254
|
+
const index = this.wizardVisibleIndices()[this.session.navigationController.selectedIndex];
|
|
255
|
+
if (index !== void 0 && !this.session.updating && !this.wizardPending && (index === 0 || !!this.options.record?._id)) this.wizardIndex.set(index);
|
|
256
|
+
this.publishWizardNavigation();
|
|
257
|
+
this.refreshWizardNavigation();
|
|
258
|
+
}
|
|
259
|
+
refreshWizardState() {
|
|
260
|
+
const visible = (this.session.renderState().tabs ?? []).flatMap((tab, index) => tab.isVisible ? [index] : []);
|
|
261
|
+
this.wizardVisibleIndices.set(visible);
|
|
262
|
+
this.restoreWizardNavigation();
|
|
263
|
+
if (!visible.includes(this.wizardIndex()) && visible.length) this.wizardIndex.set(visible[0]);
|
|
264
|
+
this.wizardDrafts.set(this.options.wizard.steps.map((_, index) => Object.keys(this.wizardState.project(this.session.formGroup, this.wizardPaths(index), true)).length > 0));
|
|
265
|
+
this.refreshWizardNavigation();
|
|
266
|
+
}
|
|
267
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
268
|
+
minVersion: "12.0.0",
|
|
269
|
+
version: "22.2.1",
|
|
270
|
+
ngImport: i0,
|
|
271
|
+
type: EntityWizardComponent,
|
|
272
|
+
deps: [],
|
|
273
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
274
|
+
});
|
|
275
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
276
|
+
minVersion: "17.0.0",
|
|
277
|
+
version: "22.2.1",
|
|
278
|
+
type: EntityWizardComponent,
|
|
279
|
+
isStandalone: true,
|
|
280
|
+
selector: "ame-entity-wizard",
|
|
281
|
+
inputs: {
|
|
282
|
+
options: "options",
|
|
283
|
+
displayMode: "displayMode"
|
|
284
|
+
},
|
|
285
|
+
outputs: {
|
|
286
|
+
result: "result",
|
|
287
|
+
closeRequest: "closeRequest"
|
|
288
|
+
},
|
|
289
|
+
providers: [
|
|
290
|
+
EntityFormSession,
|
|
291
|
+
EditEntityConditionalStateService,
|
|
292
|
+
EditEntityFormBuilderService,
|
|
293
|
+
EditEntityRenderService,
|
|
294
|
+
EditEntitySubmitValueService
|
|
295
|
+
],
|
|
296
|
+
viewQueries: [{
|
|
297
|
+
propertyName: "wizardStepper",
|
|
298
|
+
first: true,
|
|
299
|
+
predicate: MatStepper,
|
|
300
|
+
descendants: true
|
|
301
|
+
}],
|
|
302
|
+
usesOnChanges: true,
|
|
303
|
+
ngImport: i0,
|
|
304
|
+
template: "<!-- @format -->\n\n@if (session.loading) {\n <div class=\"edit-entity-loading\">\n <mat-spinner [diameter]=\"72\" />\n <span>{{ session.loadingLabel }}</span>\n </div>\n} @else if (session.errorLabel) {\n <div class=\"edit-entity-empty-state\">\n <mat-icon>info</mat-icon>\n <span>{{ session.errorLabel }}</span>\n\n @if (displayMode === \"dialog\") {\n <button mat-stroked-button type=\"button\" (click)=\"requestClose()\">\n {{ session.closeLabel }}\n </button>\n }\n </div>\n} @else {\n @if (\n session.title ||\n session.subtitle ||\n displayMode === \"dialog\" ||\n session.getActions(\"top\").length\n ) {\n <header\n class=\"edit-entity-title-bar\"\n [class.edit-entity-wizard-header]=\"options.wizard\"\n >\n @if (options.wizard?.icon) {\n <mat-icon>{{ options.wizard?.icon }}</mat-icon>\n }\n <div class=\"edit-entity-title-content\">\n @if (session.title) {\n <h2 [innerHTML]=\"session.title\"></h2>\n }\n @if (session.subtitle) {\n <p [innerHTML]=\"session.subtitle\"></p>\n }\n </div>\n\n <div class=\"edit-entity-title-actions\">\n @for (\n action of session.getActions(\"top\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n\n @if (options.showJsonDataButton === true) {\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"session.intl.messages.showJson\"\n [attr.aria-label]=\"session.intl.messages.showJson\"\n (click)=\"session.openJsonDataDialog()\"\n >\n <mat-icon>file_json</mat-icon>\n </button>\n }\n\n @if (displayMode === \"dialog\") {\n <button\n mat-icon-button\n type=\"button\"\n [attr.aria-label]=\"session.closeLabel\"\n (click)=\"requestClose()\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n </header>\n }\n\n <form class=\"edit-entity-form\" [formGroup]=\"session.formGroup\">\n <main class=\"edit-entity-content\">\n @if (options.wizard; as wizard) {\n <mat-stepper\n class=\"edit-entity-wizard\"\n orientation=\"horizontal\"\n labelPosition=\"end\"\n [linear]=\"wizardLinear()\"\n [selectedIndex]=\"wizardVisualIndex()\"\n (selectionChange)=\"selectWizardVisualStep($event.selectedIndex)\"\n >\n <!-- Material icon context.active also includes completed steps; selection follows the wizard index. -->\n <ng-template matStepperIcon=\"number\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template matStepperIcon=\"edit\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template matStepperIcon=\"done\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template #wizardStateIcon let-index=\"index\" let-active=\"active\">\n <span\n class=\"edit-entity-wizard-state-icon\"\n [class.edit-entity-wizard-state-icon--selected]=\"active\"\n [class.edit-entity-wizard-state-icon--completed]=\"\n !active && wizardCompleted()[wizardVisibleIndices()[index]]\n \"\n >\n @if (\n !active && wizardCompleted()[wizardVisibleIndices()[index]]\n ) {\n <mat-icon>check</mat-icon>\n } @else {\n {{ index + 1 }}\n }\n </span>\n </ng-template>\n @for (index of wizardVisibleIndices(); track index) {\n @let step = wizard.steps[index];\n <mat-step\n [optional]=\"false\"\n [stepControl]=\"wizardNavigationControls[index]\"\n [completed]=\"\n !wizardNavigationBlocked() && wizardCompleted()[index]\n \"\n [editable]=\"\n !wizardNavigationBlocked() &&\n (index === 0 || !!options.record?._id)\n \"\n >\n <ng-template matStepLabel>\n <div\n class=\"edit-entity-wizard-step-label\"\n [class.edit-entity-wizard-step-label--selected]=\"\n index === wizardIndex()\n \"\n >\n <span class=\"edit-entity-wizard-step-name\">{{\n step.label\n }}</span>\n @if (wizardDrafts()[index]) {\n <span\n class=\"edit-entity-wizard-unsaved\"\n [title]=\"\n wizard.unsavedLabel ||\n session.intl.messages.wizardUnsaved\n \"\n >{{\n wizard.unsavedLabel ||\n session.intl.messages.wizardUnsaved\n }}</span\n >\n }\n </div>\n </ng-template>\n <ng-template matStepContent>\n @if (index === wizardIndex()) {\n <header class=\"edit-entity-wizard-content-heading\">\n <div>\n <h3>{{ step.label }}</h3>\n @if (step.description) {\n <p>{{ step.description }}</p>\n }\n </div>\n @if (step.optional && index > 0) {\n <span class=\"edit-entity-wizard-optional\">{{\n wizard.optionalLabel ||\n session.intl.messages.wizardOptional\n }}</span>\n }\n </header>\n <ame-form-content\n [state]=\"\n session.renderState().tabs?.[index]?.renderState || {\n kind: 'empty',\n }\n \"\n [formGroup]=\"session.formGroup\"\n [options]=\"options\"\n [context]=\"session\"\n />\n }\n </ng-template>\n </mat-step>\n }\n </mat-stepper>\n }\n </main>\n </form>\n\n <footer\n class=\"edit-entity-actions\"\n [class.edit-entity-wizard-actions]=\"options.wizard\"\n >\n <div class=\"edit-entity-actions-left\">\n @for (\n action of session.getActions(\"bottom\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n </div>\n\n <div class=\"edit-entity-actions-right\">\n @for (\n action of session.getActions(\"bottom-end\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n\n @if (options.wizard; as wizard) {\n <button\n mat-stroked-button\n type=\"button\"\n [disabled]=\"session.updating\"\n (click)=\"requestClose()\"\n >\n {{ wizardExitLabel }}\n </button>\n @if (wizardStep?.optional && options.record?._id) {\n <button\n mat-raised-button\n class=\"edit-entity-wizard-skip\"\n type=\"button\"\n [disabled]=\"wizardNavigationBlocked()\"\n (click)=\"skipWizardStep()\"\n >\n {{ wizard.skipLabel || session.intl.messages.wizardSkip }}\n </button>\n }\n <button\n mat-raised-button\n color=\"secondary\"\n type=\"button\"\n [disabled]=\"\n session.updating || (!wizardStep?.componentManaged && !wizardValid)\n \"\n (click)=\"wizardNext()\"\n >\n {{ wizardPrimaryLabel }}\n </button>\n }\n </div>\n </footer>\n\n @if (session.updating) {\n <div class=\"edit-entity-updating\">\n <mat-spinner [diameter]=\"72\" />\n </div>\n }\n}\n\n<ng-template #actionTemplate let-action=\"action\">\n @if (session.isRuntimeButtonAction(action)) {\n @if (action.buttonType === \"raised\") {\n <button\n class=\"action-btn\"\n mat-raised-button\n type=\"button\"\n [style.--action-color]=\"action.contrastColor\"\n [style.--action-background-color]=\"action.color\"\n [disabled]=\"session.updating || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"session.handleAction(action)\"\n >\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n <span [innerHTML]=\"action.label\"></span>\n </button>\n } @else {\n <button\n class=\"action-btn\"\n mat-button\n type=\"button\"\n [style.--action-color]=\"action.color\"\n [disabled]=\"session.updating || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"session.handleAction(action)\"\n >\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n <span [innerHTML]=\"action.label\"></span>\n </button>\n }\n } @else if (session.isRuntimeComponentAction(action)) {\n <ng-container\n *ngComponentOutlet=\"action.component; inputs: action.componentInputs\"\n ></ng-container>\n }\n</ng-template>\n",
|
|
305
|
+
styles: [":host{--edit-entity-background: var( --ngx-mat-edit-entity-dialog-background, var(--ngx-mat-extended-surface, #f4f6f8) );--edit-entity-border: var( --ngx-mat-edit-entity-dialog-border, var(--ngx-mat-extended-border, rgba(14, 43, 67, .12)) );--edit-entity-text: var( --ngx-mat-edit-entity-dialog-text, var(--ngx-mat-extended-text, #102f49) );--edit-entity-muted: var( --ngx-mat-edit-entity-dialog-muted, var(--ngx-mat-extended-muted, #61718a) );--edit-entity-primary: var(--ngx-mat-edit-entity-dialog-primary, #0f334d);position:relative;display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden;color:var(--edit-entity-text)}.edit-entity-loading,.edit-entity-empty-state{display:flex;flex:1 1 auto;min-height:240px;align-items:center;justify-content:center;flex-direction:column;gap:var(--ngx-mat-extended-space-3, 16px);color:var(--edit-entity-primary)}.edit-entity-empty-state{padding:var(--ngx-mat-extended-space-4, 24px);color:var(--edit-entity-muted);text-align:center}.edit-entity-empty-state mat-icon{width:42px;height:42px;color:var(--edit-entity-primary);font-size:42px}.edit-entity-empty-state span,.edit-entity-empty-state strong{color:var(--edit-entity-text);font-size:15px;font-weight:700}.edit-entity-title-bar{display:flex;flex:0 0 auto;align-items:center;justify-content:start;gap:var(--ngx-mat-extended-space-3, 16px);min-height:48px;padding:var(--ngx-mat-extended-space-2, 8px);margin:0;border-bottom:1px solid var(--edit-entity-border);box-sizing:border-box;background:var(--ngx-mat-edit-entity-dialog-header-background, var(--ngx-mat-extended-surface, #0f334d));color:var(--ngx-mat-edit-entity-dialog-header-text, var(--ngx-mat-extended-text, #fff))}.edit-entity-title-bar h2{margin:0;font-size:var(--mat-sys-title-medium-size, 18px);font-weight:700;line-height:1.2}.edit-entity-title-bar p{margin:var(--ngx-mat-extended-space-1, 4px) 0 0;color:var(--ngx-mat-edit-entity-dialog-header-text, var(--ngx-mat-extended-text, #fff));font-size:var(--mat-sys-body-small-size, 13px)}.edit-entity-title-content{min-width:0;overflow:hidden}.edit-entity-title-content h2,.edit-entity-title-content p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.edit-entity-title-actions{display:inline-flex;flex:0 0 auto;align-items:center;gap:var(--ngx-mat-extended-space-2, 8px);margin-left:auto}.edit-entity-title-actions .mat-mdc-icon-button{--mat-icon-button-icon-color: var(--ngx-mat-edit-entity-dialog-header-text, var(--ngx-mat-extended-text, #fff))}.edit-entity-form,.edit-entity-content{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;max-height:none;margin:0;overflow:hidden;padding:0;background:var(--edit-entity-background);box-sizing:border-box}.edit-entity-actions{display:flex;flex:0 0 auto;align-items:center;justify-content:space-between;gap:var(--ngx-mat-extended-space-2, 8px);min-height:54px;padding:var(--ngx-mat-extended-space-2, 8px);border-top:1px solid var(--edit-entity-border);background:var(--ngx-mat-edit-entity-dialog-background, var(--ngx-mat-extended-surface, #ffffff));box-sizing:border-box}.edit-entity-actions-left,.edit-entity-actions-right{display:inline-flex;align-items:center;gap:var(--ngx-mat-extended-space-2, 8px);min-width:0}.edit-entity-updating{position:absolute;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;background:#fff9}.action-btn{--mat-button-text-label-text-color: var(--action-color);--mat-button-filled-label-text-color: var(--action-color);--mat-button-filled-container-color: var(--action-background-color);--mat-button-protected-label-text-color: var(--action-color);--mat-button-protected-container-color: var(--action-background-color)}:host ::ng-deep mat-form-field{--mat-form-field-outlined-disabled-input-text-color: var(--mat-form-field-outlined-input-text-color)}:host ::ng-deep mat-form-field .mat-mdc-chip.mat-mdc-chip-row{--mat-chip-disabled-container-opacity: 1;--mat-chip-elevated-disabled-container-color: var(--mat-chip-elevated-container-color)}@media(max-width:900px){.edit-entity-actions{align-items:stretch;flex-direction:column}.edit-entity-actions-left,.edit-entity-actions-right{justify-content:flex-end;width:100%}}.edit-entity-wizard-header{background:var(--edit-entity-primary);color:var(--ngx-mat-edit-entity-dialog-header-text, var(--mat-sys-on-primary))}.edit-entity-wizard{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;min-width:0;background:transparent;--mat-stepper-header-selected-state-icon-background-color: var(--ngx-mat-edit-entity-wizard-alert, var(--mat-sys-primary));--mat-stepper-header-selected-state-icon-foreground-color: var(--ngx-mat-edit-entity-wizard-on-alert, var(--mat-sys-on-primary));--mat-stepper-header-selected-state-label-text-color: var(--ngx-mat-edit-entity-wizard-toolbar-text, var(--edit-entity-text));--mat-stepper-header-done-state-icon-background-color: var(--ngx-mat-edit-entity-wizard-ok, var(--mat-sys-tertiary));--mat-stepper-header-done-state-icon-foreground-color: var(--ngx-mat-edit-entity-wizard-on-ok, var(--mat-sys-on-tertiary));--mat-stepper-header-edit-state-icon-background-color: var(--ngx-mat-edit-entity-wizard-ok, var(--mat-sys-tertiary));--mat-stepper-header-edit-state-icon-foreground-color: var(--ngx-mat-edit-entity-wizard-on-ok, var(--mat-sys-on-tertiary));--mat-stepper-header-label-text-color: var(--ngx-mat-edit-entity-wizard-toolbar-text, var(--edit-entity-text));--mat-stepper-line-color: transparent;--mat-stepper-container-color: transparent;--mat-stepper-header-height: 56px;--mat-stepper-header-focus-state-layer-shape: 0;--mat-stepper-header-hover-state-layer-shape: 0}.edit-entity-wizard-optional{display:block;align-self:center;padding:2px 5px;border-radius:4px;font-size:11px}.edit-entity-wizard-optional{background:var(--ngx-mat-edit-entity-dialog-secondary, var(--mat-sys-secondary));color:var(--mat-sys-on-secondary)}.edit-entity-wizard-unsaved{position:absolute;inset-inline:8px;bottom:1px;display:block;overflow:hidden;color:var(--edit-entity-muted);font-size:10px;line-height:10px;text-overflow:ellipsis;white-space:nowrap}.edit-entity-wizard-skip{--mat-button-protected-container-color: var(--ngx-mat-edit-entity-dialog-secondary, var(--mat-sys-secondary));--mat-button-protected-label-text-color: var(--mat-sys-on-secondary)}.edit-entity-wizard-step-label{display:flex;flex-direction:column;align-items:flex-start;gap:4px;width:112px;max-width:100%;white-space:normal;line-height:16px;text-align:start;color:var(--ngx-mat-edit-entity-wizard-toolbar-text, var(--edit-entity-text))}.edit-entity-wizard-step-label--selected{color:var(--ngx-mat-edit-entity-wizard-alert, var(--mat-sys-primary))}.edit-entity-wizard-step-name{overflow-wrap:anywhere}.edit-entity-wizard-actions{flex-wrap:wrap}.edit-entity-wizard-actions .edit-entity-actions-left:empty{display:none}.edit-entity-wizard-actions .edit-entity-actions-right{flex:1 1 auto;flex-wrap:wrap;justify-content:flex-end}.edit-entity-wizard-actions .edit-entity-actions-right button{max-width:100%;white-space:normal}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-wrapper,:host ::ng-deep .edit-entity-wizard .mat-horizontal-content-container{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;min-width:0}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-header-container{flex:0 0 auto;min-width:0;overflow-x:auto;overscroll-behavior-x:contain;border-bottom:1px solid var(--edit-entity-border);background:var(--ngx-mat-edit-entity-wizard-toolbar-background, var(--mat-sys-surface))}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-header{flex:1 0 160px;min-width:160px;padding-inline:8px;box-sizing:border-box}:host ::ng-deep .edit-entity-wizard .mat-stepper-horizontal-line{display:none}:host ::ng-deep .edit-entity-wizard .mat-horizontal-content-container{padding:0}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-content.mat-horizontal-stepper-content-current{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;overflow:hidden}.edit-entity-wizard-content-heading{display:flex;flex:0 0 auto;align-items:flex-start;justify-content:space-between;gap:8px;padding:8px}.edit-entity-wizard-content-heading>div{min-width:0}.edit-entity-wizard-content-heading h3{margin:0;color:var(--edit-entity-text);font-size:16px;line-height:24px}.edit-entity-wizard-content-heading p{margin:4px 0 0;color:var(--edit-entity-muted);font-size:13px;line-height:18px}.edit-entity-wizard-content-heading .edit-entity-wizard-optional{flex:0 0 auto;align-self:flex-start;margin-block-start:2px}.edit-entity-wizard-state-icon{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;box-sizing:border-box;border:1px solid var(--edit-entity-border);background:var(--ngx-mat-edit-entity-wizard-toolbar-background, var(--mat-sys-surface));color:var(--edit-entity-muted)}.edit-entity-wizard-state-icon mat-icon{font-size:18px;width:18px;height:18px}.edit-entity-wizard-state-icon--completed{border-color:transparent;background:var(--ngx-mat-edit-entity-wizard-ok, var(--mat-sys-tertiary));color:var(--ngx-mat-edit-entity-wizard-on-ok, var(--mat-sys-on-tertiary))}.edit-entity-wizard-state-icon--selected{border-color:transparent;background:var(--ngx-mat-edit-entity-wizard-alert, var(--mat-sys-primary));color:var(--ngx-mat-edit-entity-wizard-on-alert, var(--mat-sys-on-primary))}\n"],
|
|
306
|
+
dependencies: [
|
|
307
|
+
{
|
|
308
|
+
kind: "ngmodule",
|
|
309
|
+
type: CommonModule
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
kind: "directive",
|
|
313
|
+
type: i1$1.NgComponentOutlet,
|
|
314
|
+
selector: "[ngComponentOutlet]",
|
|
315
|
+
inputs: [
|
|
316
|
+
"ngComponentOutlet",
|
|
317
|
+
"ngComponentOutletInputs",
|
|
318
|
+
"ngComponentOutletInjector",
|
|
319
|
+
"ngComponentOutletEnvironmentInjector",
|
|
320
|
+
"ngComponentOutletContent",
|
|
321
|
+
"ngComponentOutletNgModule"
|
|
322
|
+
],
|
|
323
|
+
exportAs: ["ngComponentOutlet"]
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
kind: "directive",
|
|
327
|
+
type: i1$1.NgTemplateOutlet,
|
|
328
|
+
selector: "[ngTemplateOutlet]",
|
|
329
|
+
inputs: [
|
|
330
|
+
"ngTemplateOutletContext",
|
|
331
|
+
"ngTemplateOutlet",
|
|
332
|
+
"ngTemplateOutletInjector"
|
|
333
|
+
]
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
kind: "ngmodule",
|
|
337
|
+
type: ReactiveFormsModule
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
kind: "directive",
|
|
341
|
+
type: i2.ɵNgNoValidate,
|
|
342
|
+
selector: "form:not([ngNoForm]):not([ngNativeValidate])"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
kind: "directive",
|
|
346
|
+
type: i2.NgControlStatusGroup,
|
|
347
|
+
selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
kind: "directive",
|
|
351
|
+
type: i2.FormGroupDirective,
|
|
352
|
+
selector: "[formGroup]",
|
|
353
|
+
inputs: ["formGroup"],
|
|
354
|
+
outputs: ["ngSubmit"],
|
|
355
|
+
exportAs: ["ngForm"]
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
kind: "ngmodule",
|
|
359
|
+
type: MatButtonModule
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
kind: "component",
|
|
363
|
+
type: i3.MatButton,
|
|
364
|
+
selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ",
|
|
365
|
+
inputs: ["matButton"],
|
|
366
|
+
exportAs: ["matButton", "matAnchor"]
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
kind: "component",
|
|
370
|
+
type: i3.MatIconButton,
|
|
371
|
+
selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]",
|
|
372
|
+
exportAs: ["matButton", "matAnchor"]
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
kind: "ngmodule",
|
|
376
|
+
type: MatIconModule
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
kind: "component",
|
|
380
|
+
type: i4.MatIcon,
|
|
381
|
+
selector: "mat-icon",
|
|
382
|
+
inputs: [
|
|
383
|
+
"color",
|
|
384
|
+
"inline",
|
|
385
|
+
"svgIcon",
|
|
386
|
+
"fontSet",
|
|
387
|
+
"fontIcon"
|
|
388
|
+
],
|
|
389
|
+
exportAs: ["matIcon"]
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
kind: "ngmodule",
|
|
393
|
+
type: MatProgressSpinnerModule
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
kind: "component",
|
|
397
|
+
type: i5.MatProgressSpinner,
|
|
398
|
+
selector: "mat-progress-spinner, mat-spinner",
|
|
399
|
+
inputs: [
|
|
400
|
+
"color",
|
|
401
|
+
"mode",
|
|
402
|
+
"value",
|
|
403
|
+
"diameter",
|
|
404
|
+
"strokeWidth"
|
|
405
|
+
],
|
|
406
|
+
exportAs: ["matProgressSpinner"]
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
kind: "ngmodule",
|
|
410
|
+
type: MatTooltipModule
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
kind: "directive",
|
|
414
|
+
type: i6.MatTooltip,
|
|
415
|
+
selector: "[matTooltip]",
|
|
416
|
+
inputs: [
|
|
417
|
+
"matTooltipPosition",
|
|
418
|
+
"matTooltipPositionAtOrigin",
|
|
419
|
+
"matTooltipDisabled",
|
|
420
|
+
"matTooltipShowDelay",
|
|
421
|
+
"matTooltipHideDelay",
|
|
422
|
+
"matTooltipTouchGestures",
|
|
423
|
+
"matTooltip",
|
|
424
|
+
"matTooltipClass"
|
|
425
|
+
],
|
|
426
|
+
exportAs: ["matTooltip"]
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
kind: "component",
|
|
430
|
+
type: FormContentComponent,
|
|
431
|
+
selector: "ame-form-content",
|
|
432
|
+
inputs: [
|
|
433
|
+
"state",
|
|
434
|
+
"formGroup",
|
|
435
|
+
"options",
|
|
436
|
+
"context"
|
|
437
|
+
]
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
kind: "ngmodule",
|
|
441
|
+
type: MatStepperModule
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
kind: "component",
|
|
445
|
+
type: i7.MatStep,
|
|
446
|
+
selector: "mat-step",
|
|
447
|
+
inputs: ["color"],
|
|
448
|
+
exportAs: ["matStep"]
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
kind: "directive",
|
|
452
|
+
type: i7.MatStepLabel,
|
|
453
|
+
selector: "[matStepLabel]"
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
kind: "component",
|
|
457
|
+
type: i7.MatStepper,
|
|
458
|
+
selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]",
|
|
459
|
+
inputs: [
|
|
460
|
+
"disableRipple",
|
|
461
|
+
"color",
|
|
462
|
+
"labelPosition",
|
|
463
|
+
"headerPosition",
|
|
464
|
+
"aria-label",
|
|
465
|
+
"headerPrefix",
|
|
466
|
+
"animationDuration"
|
|
467
|
+
],
|
|
468
|
+
outputs: ["animationDone"],
|
|
469
|
+
exportAs: [
|
|
470
|
+
"matStepper",
|
|
471
|
+
"matVerticalStepper",
|
|
472
|
+
"matHorizontalStepper"
|
|
473
|
+
]
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
kind: "directive",
|
|
477
|
+
type: i7.MatStepperIcon,
|
|
478
|
+
selector: "ng-template[matStepperIcon]",
|
|
479
|
+
inputs: ["matStepperIcon"]
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
kind: "directive",
|
|
483
|
+
type: i7.MatStepContent,
|
|
484
|
+
selector: "ng-template[matStepContent]"
|
|
485
|
+
}
|
|
486
|
+
],
|
|
487
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
488
|
+
});
|
|
489
|
+
};
|
|
490
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
491
|
+
minVersion: "12.0.0",
|
|
492
|
+
version: "22.2.1",
|
|
493
|
+
ngImport: i0,
|
|
494
|
+
type: EntityWizardComponent,
|
|
495
|
+
decorators: [{
|
|
496
|
+
type: Component,
|
|
497
|
+
args: [{
|
|
498
|
+
selector: "ame-entity-wizard",
|
|
499
|
+
imports: [
|
|
500
|
+
CommonModule,
|
|
501
|
+
ReactiveFormsModule,
|
|
502
|
+
MatButtonModule,
|
|
503
|
+
MatIconModule,
|
|
504
|
+
MatProgressSpinnerModule,
|
|
505
|
+
MatTooltipModule,
|
|
506
|
+
FormContentComponent,
|
|
507
|
+
MatStepperModule
|
|
508
|
+
],
|
|
509
|
+
providers: [
|
|
510
|
+
EntityFormSession,
|
|
511
|
+
EditEntityConditionalStateService,
|
|
512
|
+
EditEntityFormBuilderService,
|
|
513
|
+
EditEntityRenderService,
|
|
514
|
+
EditEntitySubmitValueService
|
|
515
|
+
],
|
|
516
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
517
|
+
template: "<!-- @format -->\n\n@if (session.loading) {\n <div class=\"edit-entity-loading\">\n <mat-spinner [diameter]=\"72\" />\n <span>{{ session.loadingLabel }}</span>\n </div>\n} @else if (session.errorLabel) {\n <div class=\"edit-entity-empty-state\">\n <mat-icon>info</mat-icon>\n <span>{{ session.errorLabel }}</span>\n\n @if (displayMode === \"dialog\") {\n <button mat-stroked-button type=\"button\" (click)=\"requestClose()\">\n {{ session.closeLabel }}\n </button>\n }\n </div>\n} @else {\n @if (\n session.title ||\n session.subtitle ||\n displayMode === \"dialog\" ||\n session.getActions(\"top\").length\n ) {\n <header\n class=\"edit-entity-title-bar\"\n [class.edit-entity-wizard-header]=\"options.wizard\"\n >\n @if (options.wizard?.icon) {\n <mat-icon>{{ options.wizard?.icon }}</mat-icon>\n }\n <div class=\"edit-entity-title-content\">\n @if (session.title) {\n <h2 [innerHTML]=\"session.title\"></h2>\n }\n @if (session.subtitle) {\n <p [innerHTML]=\"session.subtitle\"></p>\n }\n </div>\n\n <div class=\"edit-entity-title-actions\">\n @for (\n action of session.getActions(\"top\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n\n @if (options.showJsonDataButton === true) {\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"session.intl.messages.showJson\"\n [attr.aria-label]=\"session.intl.messages.showJson\"\n (click)=\"session.openJsonDataDialog()\"\n >\n <mat-icon>file_json</mat-icon>\n </button>\n }\n\n @if (displayMode === \"dialog\") {\n <button\n mat-icon-button\n type=\"button\"\n [attr.aria-label]=\"session.closeLabel\"\n (click)=\"requestClose()\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n </header>\n }\n\n <form class=\"edit-entity-form\" [formGroup]=\"session.formGroup\">\n <main class=\"edit-entity-content\">\n @if (options.wizard; as wizard) {\n <mat-stepper\n class=\"edit-entity-wizard\"\n orientation=\"horizontal\"\n labelPosition=\"end\"\n [linear]=\"wizardLinear()\"\n [selectedIndex]=\"wizardVisualIndex()\"\n (selectionChange)=\"selectWizardVisualStep($event.selectedIndex)\"\n >\n <!-- Material icon context.active also includes completed steps; selection follows the wizard index. -->\n <ng-template matStepperIcon=\"number\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template matStepperIcon=\"edit\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template matStepperIcon=\"done\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template #wizardStateIcon let-index=\"index\" let-active=\"active\">\n <span\n class=\"edit-entity-wizard-state-icon\"\n [class.edit-entity-wizard-state-icon--selected]=\"active\"\n [class.edit-entity-wizard-state-icon--completed]=\"\n !active && wizardCompleted()[wizardVisibleIndices()[index]]\n \"\n >\n @if (\n !active && wizardCompleted()[wizardVisibleIndices()[index]]\n ) {\n <mat-icon>check</mat-icon>\n } @else {\n {{ index + 1 }}\n }\n </span>\n </ng-template>\n @for (index of wizardVisibleIndices(); track index) {\n @let step = wizard.steps[index];\n <mat-step\n [optional]=\"false\"\n [stepControl]=\"wizardNavigationControls[index]\"\n [completed]=\"\n !wizardNavigationBlocked() && wizardCompleted()[index]\n \"\n [editable]=\"\n !wizardNavigationBlocked() &&\n (index === 0 || !!options.record?._id)\n \"\n >\n <ng-template matStepLabel>\n <div\n class=\"edit-entity-wizard-step-label\"\n [class.edit-entity-wizard-step-label--selected]=\"\n index === wizardIndex()\n \"\n >\n <span class=\"edit-entity-wizard-step-name\">{{\n step.label\n }}</span>\n @if (wizardDrafts()[index]) {\n <span\n class=\"edit-entity-wizard-unsaved\"\n [title]=\"\n wizard.unsavedLabel ||\n session.intl.messages.wizardUnsaved\n \"\n >{{\n wizard.unsavedLabel ||\n session.intl.messages.wizardUnsaved\n }}</span\n >\n }\n </div>\n </ng-template>\n <ng-template matStepContent>\n @if (index === wizardIndex()) {\n <header class=\"edit-entity-wizard-content-heading\">\n <div>\n <h3>{{ step.label }}</h3>\n @if (step.description) {\n <p>{{ step.description }}</p>\n }\n </div>\n @if (step.optional && index > 0) {\n <span class=\"edit-entity-wizard-optional\">{{\n wizard.optionalLabel ||\n session.intl.messages.wizardOptional\n }}</span>\n }\n </header>\n <ame-form-content\n [state]=\"\n session.renderState().tabs?.[index]?.renderState || {\n kind: 'empty',\n }\n \"\n [formGroup]=\"session.formGroup\"\n [options]=\"options\"\n [context]=\"session\"\n />\n }\n </ng-template>\n </mat-step>\n }\n </mat-stepper>\n }\n </main>\n </form>\n\n <footer\n class=\"edit-entity-actions\"\n [class.edit-entity-wizard-actions]=\"options.wizard\"\n >\n <div class=\"edit-entity-actions-left\">\n @for (\n action of session.getActions(\"bottom\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n </div>\n\n <div class=\"edit-entity-actions-right\">\n @for (\n action of session.getActions(\"bottom-end\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n\n @if (options.wizard; as wizard) {\n <button\n mat-stroked-button\n type=\"button\"\n [disabled]=\"session.updating\"\n (click)=\"requestClose()\"\n >\n {{ wizardExitLabel }}\n </button>\n @if (wizardStep?.optional && options.record?._id) {\n <button\n mat-raised-button\n class=\"edit-entity-wizard-skip\"\n type=\"button\"\n [disabled]=\"wizardNavigationBlocked()\"\n (click)=\"skipWizardStep()\"\n >\n {{ wizard.skipLabel || session.intl.messages.wizardSkip }}\n </button>\n }\n <button\n mat-raised-button\n color=\"secondary\"\n type=\"button\"\n [disabled]=\"\n session.updating || (!wizardStep?.componentManaged && !wizardValid)\n \"\n (click)=\"wizardNext()\"\n >\n {{ wizardPrimaryLabel }}\n </button>\n }\n </div>\n </footer>\n\n @if (session.updating) {\n <div class=\"edit-entity-updating\">\n <mat-spinner [diameter]=\"72\" />\n </div>\n }\n}\n\n<ng-template #actionTemplate let-action=\"action\">\n @if (session.isRuntimeButtonAction(action)) {\n @if (action.buttonType === \"raised\") {\n <button\n class=\"action-btn\"\n mat-raised-button\n type=\"button\"\n [style.--action-color]=\"action.contrastColor\"\n [style.--action-background-color]=\"action.color\"\n [disabled]=\"session.updating || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"session.handleAction(action)\"\n >\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n <span [innerHTML]=\"action.label\"></span>\n </button>\n } @else {\n <button\n class=\"action-btn\"\n mat-button\n type=\"button\"\n [style.--action-color]=\"action.color\"\n [disabled]=\"session.updating || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"session.handleAction(action)\"\n >\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n <span [innerHTML]=\"action.label\"></span>\n </button>\n }\n } @else if (session.isRuntimeComponentAction(action)) {\n <ng-container\n *ngComponentOutlet=\"action.component; inputs: action.componentInputs\"\n ></ng-container>\n }\n</ng-template>\n",
|
|
518
|
+
styles: [":host{--edit-entity-background: var( --ngx-mat-edit-entity-dialog-background, var(--ngx-mat-extended-surface, #f4f6f8) );--edit-entity-border: var( --ngx-mat-edit-entity-dialog-border, var(--ngx-mat-extended-border, rgba(14, 43, 67, .12)) );--edit-entity-text: var( --ngx-mat-edit-entity-dialog-text, var(--ngx-mat-extended-text, #102f49) );--edit-entity-muted: var( --ngx-mat-edit-entity-dialog-muted, var(--ngx-mat-extended-muted, #61718a) );--edit-entity-primary: var(--ngx-mat-edit-entity-dialog-primary, #0f334d);position:relative;display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden;color:var(--edit-entity-text)}.edit-entity-loading,.edit-entity-empty-state{display:flex;flex:1 1 auto;min-height:240px;align-items:center;justify-content:center;flex-direction:column;gap:var(--ngx-mat-extended-space-3, 16px);color:var(--edit-entity-primary)}.edit-entity-empty-state{padding:var(--ngx-mat-extended-space-4, 24px);color:var(--edit-entity-muted);text-align:center}.edit-entity-empty-state mat-icon{width:42px;height:42px;color:var(--edit-entity-primary);font-size:42px}.edit-entity-empty-state span,.edit-entity-empty-state strong{color:var(--edit-entity-text);font-size:15px;font-weight:700}.edit-entity-title-bar{display:flex;flex:0 0 auto;align-items:center;justify-content:start;gap:var(--ngx-mat-extended-space-3, 16px);min-height:48px;padding:var(--ngx-mat-extended-space-2, 8px);margin:0;border-bottom:1px solid var(--edit-entity-border);box-sizing:border-box;background:var(--ngx-mat-edit-entity-dialog-header-background, var(--ngx-mat-extended-surface, #0f334d));color:var(--ngx-mat-edit-entity-dialog-header-text, var(--ngx-mat-extended-text, #fff))}.edit-entity-title-bar h2{margin:0;font-size:var(--mat-sys-title-medium-size, 18px);font-weight:700;line-height:1.2}.edit-entity-title-bar p{margin:var(--ngx-mat-extended-space-1, 4px) 0 0;color:var(--ngx-mat-edit-entity-dialog-header-text, var(--ngx-mat-extended-text, #fff));font-size:var(--mat-sys-body-small-size, 13px)}.edit-entity-title-content{min-width:0;overflow:hidden}.edit-entity-title-content h2,.edit-entity-title-content p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.edit-entity-title-actions{display:inline-flex;flex:0 0 auto;align-items:center;gap:var(--ngx-mat-extended-space-2, 8px);margin-left:auto}.edit-entity-title-actions .mat-mdc-icon-button{--mat-icon-button-icon-color: var(--ngx-mat-edit-entity-dialog-header-text, var(--ngx-mat-extended-text, #fff))}.edit-entity-form,.edit-entity-content{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;max-height:none;margin:0;overflow:hidden;padding:0;background:var(--edit-entity-background);box-sizing:border-box}.edit-entity-actions{display:flex;flex:0 0 auto;align-items:center;justify-content:space-between;gap:var(--ngx-mat-extended-space-2, 8px);min-height:54px;padding:var(--ngx-mat-extended-space-2, 8px);border-top:1px solid var(--edit-entity-border);background:var(--ngx-mat-edit-entity-dialog-background, var(--ngx-mat-extended-surface, #ffffff));box-sizing:border-box}.edit-entity-actions-left,.edit-entity-actions-right{display:inline-flex;align-items:center;gap:var(--ngx-mat-extended-space-2, 8px);min-width:0}.edit-entity-updating{position:absolute;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;background:#fff9}.action-btn{--mat-button-text-label-text-color: var(--action-color);--mat-button-filled-label-text-color: var(--action-color);--mat-button-filled-container-color: var(--action-background-color);--mat-button-protected-label-text-color: var(--action-color);--mat-button-protected-container-color: var(--action-background-color)}:host ::ng-deep mat-form-field{--mat-form-field-outlined-disabled-input-text-color: var(--mat-form-field-outlined-input-text-color)}:host ::ng-deep mat-form-field .mat-mdc-chip.mat-mdc-chip-row{--mat-chip-disabled-container-opacity: 1;--mat-chip-elevated-disabled-container-color: var(--mat-chip-elevated-container-color)}@media(max-width:900px){.edit-entity-actions{align-items:stretch;flex-direction:column}.edit-entity-actions-left,.edit-entity-actions-right{justify-content:flex-end;width:100%}}.edit-entity-wizard-header{background:var(--edit-entity-primary);color:var(--ngx-mat-edit-entity-dialog-header-text, var(--mat-sys-on-primary))}.edit-entity-wizard{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;min-width:0;background:transparent;--mat-stepper-header-selected-state-icon-background-color: var(--ngx-mat-edit-entity-wizard-alert, var(--mat-sys-primary));--mat-stepper-header-selected-state-icon-foreground-color: var(--ngx-mat-edit-entity-wizard-on-alert, var(--mat-sys-on-primary));--mat-stepper-header-selected-state-label-text-color: var(--ngx-mat-edit-entity-wizard-toolbar-text, var(--edit-entity-text));--mat-stepper-header-done-state-icon-background-color: var(--ngx-mat-edit-entity-wizard-ok, var(--mat-sys-tertiary));--mat-stepper-header-done-state-icon-foreground-color: var(--ngx-mat-edit-entity-wizard-on-ok, var(--mat-sys-on-tertiary));--mat-stepper-header-edit-state-icon-background-color: var(--ngx-mat-edit-entity-wizard-ok, var(--mat-sys-tertiary));--mat-stepper-header-edit-state-icon-foreground-color: var(--ngx-mat-edit-entity-wizard-on-ok, var(--mat-sys-on-tertiary));--mat-stepper-header-label-text-color: var(--ngx-mat-edit-entity-wizard-toolbar-text, var(--edit-entity-text));--mat-stepper-line-color: transparent;--mat-stepper-container-color: transparent;--mat-stepper-header-height: 56px;--mat-stepper-header-focus-state-layer-shape: 0;--mat-stepper-header-hover-state-layer-shape: 0}.edit-entity-wizard-optional{display:block;align-self:center;padding:2px 5px;border-radius:4px;font-size:11px}.edit-entity-wizard-optional{background:var(--ngx-mat-edit-entity-dialog-secondary, var(--mat-sys-secondary));color:var(--mat-sys-on-secondary)}.edit-entity-wizard-unsaved{position:absolute;inset-inline:8px;bottom:1px;display:block;overflow:hidden;color:var(--edit-entity-muted);font-size:10px;line-height:10px;text-overflow:ellipsis;white-space:nowrap}.edit-entity-wizard-skip{--mat-button-protected-container-color: var(--ngx-mat-edit-entity-dialog-secondary, var(--mat-sys-secondary));--mat-button-protected-label-text-color: var(--mat-sys-on-secondary)}.edit-entity-wizard-step-label{display:flex;flex-direction:column;align-items:flex-start;gap:4px;width:112px;max-width:100%;white-space:normal;line-height:16px;text-align:start;color:var(--ngx-mat-edit-entity-wizard-toolbar-text, var(--edit-entity-text))}.edit-entity-wizard-step-label--selected{color:var(--ngx-mat-edit-entity-wizard-alert, var(--mat-sys-primary))}.edit-entity-wizard-step-name{overflow-wrap:anywhere}.edit-entity-wizard-actions{flex-wrap:wrap}.edit-entity-wizard-actions .edit-entity-actions-left:empty{display:none}.edit-entity-wizard-actions .edit-entity-actions-right{flex:1 1 auto;flex-wrap:wrap;justify-content:flex-end}.edit-entity-wizard-actions .edit-entity-actions-right button{max-width:100%;white-space:normal}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-wrapper,:host ::ng-deep .edit-entity-wizard .mat-horizontal-content-container{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;min-width:0}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-header-container{flex:0 0 auto;min-width:0;overflow-x:auto;overscroll-behavior-x:contain;border-bottom:1px solid var(--edit-entity-border);background:var(--ngx-mat-edit-entity-wizard-toolbar-background, var(--mat-sys-surface))}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-header{flex:1 0 160px;min-width:160px;padding-inline:8px;box-sizing:border-box}:host ::ng-deep .edit-entity-wizard .mat-stepper-horizontal-line{display:none}:host ::ng-deep .edit-entity-wizard .mat-horizontal-content-container{padding:0}:host ::ng-deep .edit-entity-wizard .mat-horizontal-stepper-content.mat-horizontal-stepper-content-current{display:flex;flex:1 1 auto;flex-direction:column;min-height:0;overflow:hidden}.edit-entity-wizard-content-heading{display:flex;flex:0 0 auto;align-items:flex-start;justify-content:space-between;gap:8px;padding:8px}.edit-entity-wizard-content-heading>div{min-width:0}.edit-entity-wizard-content-heading h3{margin:0;color:var(--edit-entity-text);font-size:16px;line-height:24px}.edit-entity-wizard-content-heading p{margin:4px 0 0;color:var(--edit-entity-muted);font-size:13px;line-height:18px}.edit-entity-wizard-content-heading .edit-entity-wizard-optional{flex:0 0 auto;align-self:flex-start;margin-block-start:2px}.edit-entity-wizard-state-icon{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;box-sizing:border-box;border:1px solid var(--edit-entity-border);background:var(--ngx-mat-edit-entity-wizard-toolbar-background, var(--mat-sys-surface));color:var(--edit-entity-muted)}.edit-entity-wizard-state-icon mat-icon{font-size:18px;width:18px;height:18px}.edit-entity-wizard-state-icon--completed{border-color:transparent;background:var(--ngx-mat-edit-entity-wizard-ok, var(--mat-sys-tertiary));color:var(--ngx-mat-edit-entity-wizard-on-ok, var(--mat-sys-on-tertiary))}.edit-entity-wizard-state-icon--selected{border-color:transparent;background:var(--ngx-mat-edit-entity-wizard-alert, var(--mat-sys-primary));color:var(--ngx-mat-edit-entity-wizard-on-alert, var(--mat-sys-on-primary))}\n"]
|
|
519
|
+
}]
|
|
520
|
+
}],
|
|
521
|
+
propDecorators: {
|
|
522
|
+
options: [{
|
|
523
|
+
type: Input,
|
|
524
|
+
args: [{ required: true }]
|
|
525
|
+
}],
|
|
526
|
+
displayMode: [{ type: Input }],
|
|
527
|
+
result: [{ type: Output }],
|
|
528
|
+
closeRequest: [{ type: Output }],
|
|
529
|
+
wizardStepper: [{
|
|
530
|
+
type: ViewChild,
|
|
531
|
+
args: [MatStepper]
|
|
532
|
+
}]
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
var EntityWizardDialog = class EntityWizardDialog extends EntityDialogKeyboardHost {
|
|
536
|
+
data;
|
|
537
|
+
editEntityComponent;
|
|
538
|
+
constructor(data, dialogRef, matDialog) {
|
|
539
|
+
super(dialogRef, matDialog);
|
|
540
|
+
this.data = data;
|
|
541
|
+
}
|
|
542
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
543
|
+
minVersion: "12.0.0",
|
|
544
|
+
version: "22.2.1",
|
|
545
|
+
ngImport: i0,
|
|
546
|
+
type: EntityWizardDialog,
|
|
547
|
+
deps: [
|
|
548
|
+
{ token: MAT_DIALOG_DATA },
|
|
549
|
+
{ token: i1.MatDialogRef },
|
|
550
|
+
{ token: i1.MatDialog }
|
|
551
|
+
],
|
|
552
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
553
|
+
});
|
|
554
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
555
|
+
minVersion: "14.0.0",
|
|
556
|
+
version: "22.2.1",
|
|
557
|
+
type: EntityWizardDialog,
|
|
558
|
+
isStandalone: true,
|
|
559
|
+
selector: "ame-entity-wizard-dialog",
|
|
560
|
+
viewQueries: [{
|
|
561
|
+
propertyName: "editEntityComponent",
|
|
562
|
+
first: true,
|
|
563
|
+
predicate: EntityWizardComponent,
|
|
564
|
+
descendants: true
|
|
565
|
+
}],
|
|
566
|
+
usesInheritance: true,
|
|
567
|
+
ngImport: i0,
|
|
568
|
+
template: "<ame-entity-wizard\n [options]=\"data\"\n displayMode=\"dialog\"\n (closeRequest)=\"close($event)\"\n/>\n",
|
|
569
|
+
styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}app-edit-entity-component{display:flex;flex:1 1 auto;height:auto;min-height:0;overflow:hidden}\n"],
|
|
570
|
+
dependencies: [{
|
|
571
|
+
kind: "component",
|
|
572
|
+
type: EntityWizardComponent,
|
|
573
|
+
selector: "ame-entity-wizard",
|
|
574
|
+
inputs: ["options", "displayMode"],
|
|
575
|
+
outputs: ["result", "closeRequest"]
|
|
576
|
+
}],
|
|
577
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
581
|
+
minVersion: "12.0.0",
|
|
582
|
+
version: "22.2.1",
|
|
583
|
+
ngImport: i0,
|
|
584
|
+
type: EntityWizardDialog,
|
|
585
|
+
decorators: [{
|
|
586
|
+
type: Component,
|
|
587
|
+
args: [{
|
|
588
|
+
selector: "ame-entity-wizard-dialog",
|
|
589
|
+
imports: [EntityWizardComponent],
|
|
590
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
591
|
+
template: "<ame-entity-wizard\n [options]=\"data\"\n displayMode=\"dialog\"\n (closeRequest)=\"close($event)\"\n/>\n",
|
|
592
|
+
styles: [":host{display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden}app-edit-entity-component{display:flex;flex:1 1 auto;height:auto;min-height:0;overflow:hidden}\n"]
|
|
593
|
+
}]
|
|
594
|
+
}],
|
|
595
|
+
ctorParameters: () => [
|
|
596
|
+
{
|
|
597
|
+
type: void 0,
|
|
598
|
+
decorators: [{
|
|
599
|
+
type: Inject,
|
|
600
|
+
args: [MAT_DIALOG_DATA]
|
|
601
|
+
}]
|
|
602
|
+
},
|
|
603
|
+
{ type: i1.MatDialogRef },
|
|
604
|
+
{ type: i1.MatDialog }
|
|
605
|
+
],
|
|
606
|
+
propDecorators: { editEntityComponent: [{
|
|
607
|
+
type: ViewChild,
|
|
608
|
+
args: [EntityWizardComponent]
|
|
609
|
+
}] }
|
|
610
|
+
});
|
|
611
|
+
var CreateEntityWizardService = class CreateEntityWizardService {
|
|
612
|
+
launcher = inject(EntityDialogLauncher);
|
|
613
|
+
open(options, config = {}) {
|
|
614
|
+
if (!options.wizard?.steps.length || !("tabs" in options.displayOptions)) throw new Error("Use createEntityWizardOptions before opening a creation wizard");
|
|
615
|
+
return this.launcher.open(EntityWizardDialog, options, config);
|
|
616
|
+
}
|
|
617
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
618
|
+
minVersion: "12.0.0",
|
|
619
|
+
version: "22.2.1",
|
|
620
|
+
ngImport: i0,
|
|
621
|
+
type: CreateEntityWizardService,
|
|
622
|
+
deps: [],
|
|
623
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
624
|
+
});
|
|
625
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
626
|
+
minVersion: "12.0.0",
|
|
627
|
+
version: "22.2.1",
|
|
628
|
+
ngImport: i0,
|
|
629
|
+
type: CreateEntityWizardService,
|
|
630
|
+
providedIn: "root"
|
|
631
|
+
});
|
|
632
|
+
};
|
|
633
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
634
|
+
minVersion: "12.0.0",
|
|
635
|
+
version: "22.2.1",
|
|
636
|
+
ngImport: i0,
|
|
637
|
+
type: CreateEntityWizardService,
|
|
638
|
+
decorators: [{
|
|
639
|
+
type: Injectable,
|
|
640
|
+
args: [{ providedIn: "root" }]
|
|
641
|
+
}]
|
|
642
|
+
});
|
|
643
|
+
function createEntityWizardOptions(options) {
|
|
644
|
+
if (!options.steps.length) throw new Error("A creation wizard requires at least one step");
|
|
645
|
+
const { steps, icon, nextLabel, createNextLabel, skipLabel, finishLaterLabel, finishLabel, optionalLabel, unsavedLabel, ...base } = options;
|
|
646
|
+
return {
|
|
647
|
+
...base,
|
|
648
|
+
service: base.service ? {
|
|
649
|
+
...base.service,
|
|
650
|
+
closeOnUpsert: false
|
|
651
|
+
} : void 0,
|
|
652
|
+
wizard: {
|
|
653
|
+
steps,
|
|
654
|
+
icon,
|
|
655
|
+
nextLabel,
|
|
656
|
+
createNextLabel,
|
|
657
|
+
skipLabel,
|
|
658
|
+
finishLaterLabel,
|
|
659
|
+
finishLabel,
|
|
660
|
+
optionalLabel,
|
|
661
|
+
unsavedLabel
|
|
662
|
+
},
|
|
663
|
+
displayOptions: { tabs: steps.map((step) => ({
|
|
664
|
+
id: step.id,
|
|
665
|
+
label: step.label,
|
|
666
|
+
icon: step.icon,
|
|
667
|
+
displayOptions: step.displayOptions
|
|
668
|
+
})) }
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
export { CreateEntityWizardService, CreateEntityWizardState, EntityWizardComponent, EntityWizardDialog, createEntityWizardOptions };
|
|
672
|
+
|
|
673
|
+
//# sourceMappingURL=eherve-angular-material-entity-wizard.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eherve-angular-material-entity-wizard.mjs","names":["i1"],"sources":["../../../projects/entity-wizard/src/lib/create-entity-wizard-state.ts","../../../projects/entity-wizard/src/lib/entity-wizard.component.ts","../../../projects/entity-wizard/src/lib/entity-wizard.component.html","../../../projects/entity-wizard/src/lib/entity-wizard-dialog.component.ts","../../../projects/entity-wizard/src/lib/entity-wizard-dialog.component.html","../../../projects/entity-wizard/src/lib/create-entity-wizard.service.ts","../../../projects/entity-wizard/src/lib/create-entity-wizard.types.ts"],"sourcesContent":["import { AbstractControl, FormGroup } from \"@angular/forms\";\nimport {\n EditEntityFormGroup,\n isNonEditable,\n} from \"@eherve/angular-material-forms/core\";\nimport { cloneDeep, get, has, isEqual, set } from \"lodash-es\";\n\n/** Scoped persistence shared by the wizard engine; no host-specific model assumptions. */\nexport class CreateEntityWizardState {\n valid(form: EditEntityFormGroup, paths: string[]): boolean {\n return paths.every((path) => {\n const control = form.getControl(path);\n return (\n !control || control.disabled || (!control.pending && control.valid)\n );\n });\n }\n\n project(\n form: EditEntityFormGroup,\n paths: string[],\n changedOnly: boolean,\n always: string[] = [],\n ): Record<string, unknown> {\n const value: Record<string, unknown> = {};\n for (const path of new Set([...paths, ...always])) {\n const control = form.getControl(path);\n if (!control || isNonEditable(control)) continue;\n const current = control.getRawValue();\n const initial = this.read(form.initialValue, path);\n if (!changedOnly || always.includes(path) || !isEqual(current, initial))\n set(value, path, cloneDeep(current));\n }\n return value;\n }\n\n hydrate(\n form: EditEntityFormGroup,\n record: object,\n submitted: string[],\n ): void {\n const baseline = cloneDeep(form.initialValue);\n const visit = (control: AbstractControl, path: string): void => {\n if (control instanceof FormGroup) {\n for (const [key, child] of Object.entries(control.controls))\n visit(child, path ? `${path}.${key}` : key);\n return;\n }\n const saved = submitted.some(\n (name) => path === name || path.startsWith(`${name}.`),\n );\n const current = control.getRawValue();\n const draft = !isEqual(current, this.read(baseline, path));\n if (saved || !draft) {\n if (has(record, path))\n control.patchValue(cloneDeep(get(record, path)), {\n emitEvent: false,\n });\n if (Object.prototype.hasOwnProperty.call(form.controls, path))\n baseline[path] = cloneDeep(control.getRawValue());\n else set(baseline, path, cloneDeep(control.getRawValue()));\n control.markAsPristine();\n control.markAsUntouched();\n }\n };\n visit(form, \"\");\n form.setInitialValue(baseline);\n }\n\n private read(value: Record<string, unknown>, path: string): unknown {\n return Object.prototype.hasOwnProperty.call(value, path)\n ? value[path]\n : get(value, path);\n }\n}\n","import { CdkStepper } from \"@angular/cdk/stepper\";\nimport { CommonModule } from \"@angular/common\";\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n Input,\n OnChanges,\n OnDestroy,\n OnInit,\n Output,\n signal,\n SimpleChanges,\n ViewChild,\n} from \"@angular/core\";\nimport { FormControl, ReactiveFormsModule, Validators } from \"@angular/forms\";\nimport { MatButtonModule } from \"@angular/material/button\";\nimport { MatIconModule } from \"@angular/material/icon\";\nimport { MatProgressSpinnerModule } from \"@angular/material/progress-spinner\";\nimport { MatStepper, MatStepperModule } from \"@angular/material/stepper\";\nimport { MatTooltipModule } from \"@angular/material/tooltip\";\nimport {\n EditEntityConditionalStateService,\n EditEntityFormBuilderService,\n EditEntityRecord,\n EditEntityRenderService,\n EditEntitySubmitValueService,\n} from \"@eherve/angular-material-forms/core\";\nimport { EntityFormSession } from \"@eherve/angular-material-forms/editor\";\nimport { FormContentComponent } from \"@eherve/angular-material-forms/layout\";\nimport { cloneDeep, get, has, set } from \"lodash-es\";\nimport { CreateEntityWizardState } from \"./create-entity-wizard-state\";\nimport {\n CreateEntityWizardComponentOptions,\n CreateEntityWizardStep,\n} from \"./create-entity-wizard.types\";\n@Component({\n selector: \"ame-entity-wizard\",\n imports: [\n CommonModule,\n ReactiveFormsModule,\n MatButtonModule,\n MatIconModule,\n MatProgressSpinnerModule,\n MatTooltipModule,\n FormContentComponent,\n MatStepperModule,\n ],\n providers: [\n EntityFormSession,\n EditEntityConditionalStateService,\n EditEntityFormBuilderService,\n EditEntityRenderService,\n EditEntitySubmitValueService,\n ],\n templateUrl: \"./entity-wizard.component.html\",\n styleUrl: \"./entity-wizard.component.scss\",\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EntityWizardComponent<\n TRecord extends EditEntityRecord = EditEntityRecord,\n >\n implements OnInit, OnChanges, OnDestroy\n{\n @Input({ required: true })\n options!: CreateEntityWizardComponentOptions<TRecord>;\n @Input() displayMode: \"page\" | \"dialog\" = \"page\";\n readonly session = inject<EntityFormSession<TRecord>>(EntityFormSession);\n @Output() readonly result = this.session.result;\n @Output() readonly closeRequest = this.session.closeRequest;\n ngOnInit(): void {\n this.session.options = this.options;\n this.session.displayMode = this.displayMode;\n this.session.policy = {\n valid: () => this.wizardValid,\n value: (create) => this.wizardValue(create),\n patch: (record, value) => this.patchWizardRecord(record, value),\n saved: (record, value) => this.hydrateWizard(record, value),\n hydrate: (record) =>\n this.wizardState.hydrate(this.session.formGroup, record, []),\n refresh: () => this.refreshWizardState(),\n navigate: () => this.restoreWizardNavigation(),\n reset: () => {\n this.wizardIndex.set(0);\n this.wizardCompleted.set(this.options.wizard.steps.map(() => false));\n this.wizardVisibleIndices.set([]);\n this.wizardNavigationControls = [];\n },\n componentUpdated: () => this.completeWizardStep(),\n beforeClose: () =>\n this.session.formGroup.setInitialValue(\n this.session.formGroup.initialValue,\n ),\n stickyResult: true,\n };\n void this.session.initialize();\n }\n ngOnChanges(changes: SimpleChanges): void {\n if (changes[\"options\"] && !changes[\"options\"].firstChange) {\n this.session.options = this.options;\n void this.session.initialize();\n }\n }\n ngOnDestroy(): void {\n this.session.destroy();\n }\n requestClose(): Promise<void> {\n return this.session.requestClose();\n }\n refreshPresentation(): void {\n this.session.refreshPresentation();\n }\n submitFromKeyboard(): boolean {\n if (\n !this.options.validateOnEnter ||\n this.session.loading ||\n this.session.updating\n )\n return false;\n void this.wizardNext();\n return true;\n }\n readonly wizardIndex = signal(0);\n readonly wizardDrafts = signal<boolean[]>([]);\n readonly wizardCompleted = signal<boolean[]>([]);\n readonly wizardVisibleIndices = signal<number[]>([]);\n readonly wizardVisualIndex = computed(() =>\n Math.max(0, this.wizardVisibleIndices().indexOf(this.wizardIndex())),\n );\n readonly wizardNavigationBlocked = signal(false);\n readonly wizardLinear = signal(true);\n wizardNavigationControls: FormControl<boolean>[] = [];\n @ViewChild(MatStepper) wizardStepper?: CdkStepper;\n private readonly wizardState = new CreateEntityWizardState();\n get wizardStep(): CreateEntityWizardStep<TRecord> | undefined {\n return this.options?.wizard?.steps[this.wizardIndex()];\n }\n\n get wizardLast(): boolean {\n return this.wizardIndex() === this.wizardVisibleIndices().at(-1);\n }\n\n get wizardPrimaryLabel(): string {\n const wizard = this.options.wizard;\n if (!this.options.record?._id)\n return (\n wizard?.createNextLabel ?? this.session.intl.messages.wizardCreateNext\n );\n return this.wizardLast\n ? (wizard?.finishLabel ?? this.session.intl.messages.wizardFinish)\n : (wizard?.nextLabel ?? this.session.intl.messages.wizardNext);\n }\n\n get wizardExitLabel(): string {\n return this.options.record?._id\n ? (this.options.wizard?.finishLaterLabel ??\n this.session.intl.messages.wizardFinishLater)\n : this.session.cancelLabel;\n }\n\n selectWizardVisualStep(position: number): void {\n const index = this.wizardVisibleIndices()[position];\n if (index !== undefined) this.selectWizardStep(index);\n }\n\n private advanceWizard(): void {\n const next = this.wizardVisibleIndices()[this.wizardVisualIndex() + 1];\n if (next !== undefined) {\n this.wizardIndex.set(next);\n this.publishWizardNavigation();\n this.refreshWizardNavigation();\n }\n }\n\n private completeWizardStep(): void {\n const completed = [...this.wizardCompleted()];\n completed[this.wizardIndex()] = true;\n this.wizardCompleted.set(completed);\n this.refreshWizardNavigation();\n }\n\n private refreshWizardNavigation(): void {\n if (!this.options?.wizard) return;\n const blocked = this.session.updating || this.wizardPending;\n this.wizardNavigationBlocked.set(blocked);\n const linear = !this.options.record?._id || blocked;\n this.wizardLinear.set(linear);\n if (this.wizardStepper) this.wizardStepper.linear = linear;\n const count = this.options.wizard.steps.length;\n if (this.wizardNavigationControls.length !== count) {\n this.wizardNavigationControls = Array.from(\n { length: count },\n () =>\n new FormControl(false, {\n nonNullable: true,\n validators: Validators.requiredTrue,\n }),\n );\n }\n for (const [index, control] of this.wizardNavigationControls.entries()) {\n control.setValue(\n !blocked && (index !== 0 || !!this.options.record?._id),\n { emitEvent: false },\n );\n }\n // CDK checks these public step properties synchronously when a header is selected.\n // Synchronize immediately, including before Angular's next rendering pass.\n this.wizardStepper?.steps.forEach((step, position) => {\n const index = this.wizardVisibleIndices()[position];\n step.optional = false;\n step.interacted = true;\n step.completed = !blocked && !!this.wizardCompleted()[index];\n step.editable = !blocked && (index === 0 || !!this.options.record?._id);\n });\n }\n\n get wizardValid(): boolean {\n return this.wizardState.valid(this.session.formGroup, [\n ...this.wizardPaths(),\n ...this.wizardAlwaysPaths(),\n ]);\n }\n\n get wizardPending(): boolean {\n return [...this.wizardPaths(), ...this.wizardAlwaysPaths()].some(\n (path) => this.session.formGroup.getControl(path)?.pending,\n );\n }\n\n get wizardUnsaved(): boolean {\n return (\n Object.keys(\n this.wizardState.project(\n this.session.formGroup,\n this.wizardPaths(),\n true,\n ),\n ).length > 0\n );\n }\n\n selectWizardStep(index: number): void {\n if (\n this.session.updating ||\n this.wizardPending ||\n !this.options.wizard ||\n index < 0 ||\n index >= this.options.wizard.steps.length ||\n !this.wizardVisibleIndices().includes(index)\n )\n return;\n if (index > 0 && !this.options.record?._id) return;\n this.wizardIndex.set(index);\n this.publishWizardNavigation();\n this.refreshWizardNavigation();\n }\n\n skipWizardStep(): void {\n if (\n this.session.updating ||\n this.wizardPending ||\n !this.wizardStep?.optional ||\n !this.options.record?._id\n )\n return;\n if (this.wizardLast) void this.requestClose();\n else this.advanceWizard();\n }\n\n async wizardNext(): Promise<void> {\n if (this.session.updating || !this.options.wizard) return;\n const isCurrent = this.session.captureCurrentOperation();\n if (!this.wizardStep?.componentManaged) {\n for (const path of this.wizardPaths())\n this.session.formGroup.getControl(path)?.markAllAsTouched();\n if (!this.wizardValid) return;\n const previous = this.session.savedResult;\n if (!this.options.record?._id) await this.session.create();\n else if (this.wizardUnsaved) await this.session.update();\n else {\n this.completeWizardStep();\n if (this.wizardLast) await this.requestClose();\n else this.advanceWizard();\n return;\n }\n if (!isCurrent() || previous === this.session.savedResult) return;\n }\n if (this.wizardLast) await this.requestClose();\n else this.advanceWizard();\n }\n\n private wizardPaths(index = this.wizardIndex()): string[] {\n const display = this.options?.displayOptions;\n const tab = display && \"tabs\" in display ? display.tabs[index] : undefined;\n const names = tab\n ? this.session.renderService\n .collectFields(tab.displayOptions)\n .flatMap((field) =>\n field.kind === \"separator\" ||\n field.kind === \"metadata\" ||\n field.kind === \"display\"\n ? []\n : [field.name],\n )\n : [];\n return [\n ...new Set([\n ...names,\n ...(this.options.wizard?.steps[index]?.fields ?? []),\n ]),\n ];\n }\n\n private wizardAlwaysPaths(): string[] {\n return this.session.fields.flatMap((field) =>\n field.kind !== \"separator\" &&\n field.kind !== \"metadata\" &&\n field.kind !== \"display\" &&\n field.alwaysInUpsert\n ? [field.name]\n : [],\n );\n }\n\n private wizardValue(create: boolean): Record<string, unknown> {\n const paths = this.wizardPaths();\n const always = this.wizardAlwaysPaths();\n const value = this.wizardState.project(\n this.session.formGroup,\n paths,\n !create,\n always,\n );\n if (create)\n for (const path of [...paths, ...always]) {\n if (\n !this.session.formGroup.getControl(path) &&\n has(this.options.defaultValues, path)\n )\n set(value, path, cloneDeep(get(this.options.defaultValues, path)));\n }\n return value;\n }\n\n private patchWizardRecord(\n record: TRecord,\n value: Record<string, unknown>,\n ): TRecord {\n const updated = cloneDeep(record);\n for (const path of [...this.wizardPaths(), ...this.wizardAlwaysPaths()]) {\n if (has(value, path)) set(updated, path, cloneDeep(get(value, path)));\n }\n return updated;\n }\n\n private async hydrateWizard(\n record: TRecord,\n value: Record<string, unknown>,\n ): Promise<void> {\n const paths = [...this.wizardPaths(), ...this.wizardAlwaysPaths()].filter(\n (path) => has(value, path),\n );\n this.wizardState.hydrate(this.session.formGroup, record, paths);\n this.completeWizardStep();\n this.session.updated = this.session.formGroup.isUpdated;\n this.session.refreshAllowedActions();\n this.session.refreshRuntimeState();\n }\n\n private publishWizardNavigation(): void {\n this.session.navigationController.selectTab(this.wizardVisualIndex());\n }\n\n private restoreWizardNavigation(): void {\n const index =\n this.wizardVisibleIndices()[\n this.session.navigationController.selectedIndex\n ];\n if (\n index !== undefined &&\n !this.session.updating &&\n !this.wizardPending &&\n (index === 0 || !!this.options.record?._id)\n )\n this.wizardIndex.set(index);\n this.publishWizardNavigation();\n this.refreshWizardNavigation();\n }\n\n private refreshWizardState(): void {\n const visible = (this.session.renderState().tabs ?? []).flatMap(\n (tab, index) => (tab.isVisible ? [index] : []),\n );\n this.wizardVisibleIndices.set(visible);\n this.restoreWizardNavigation();\n if (!visible.includes(this.wizardIndex()) && visible.length)\n this.wizardIndex.set(visible[0]);\n this.wizardDrafts.set(\n this.options.wizard.steps.map(\n (_, index) =>\n Object.keys(\n this.wizardState.project(\n this.session.formGroup,\n this.wizardPaths(index),\n true,\n ),\n ).length > 0,\n ),\n );\n this.refreshWizardNavigation();\n }\n}\n","<!-- @format -->\n\n@if (session.loading) {\n <div class=\"edit-entity-loading\">\n <mat-spinner [diameter]=\"72\" />\n <span>{{ session.loadingLabel }}</span>\n </div>\n} @else if (session.errorLabel) {\n <div class=\"edit-entity-empty-state\">\n <mat-icon>info</mat-icon>\n <span>{{ session.errorLabel }}</span>\n\n @if (displayMode === \"dialog\") {\n <button mat-stroked-button type=\"button\" (click)=\"requestClose()\">\n {{ session.closeLabel }}\n </button>\n }\n </div>\n} @else {\n @if (\n session.title ||\n session.subtitle ||\n displayMode === \"dialog\" ||\n session.getActions(\"top\").length\n ) {\n <header\n class=\"edit-entity-title-bar\"\n [class.edit-entity-wizard-header]=\"options.wizard\"\n >\n @if (options.wizard?.icon) {\n <mat-icon>{{ options.wizard?.icon }}</mat-icon>\n }\n <div class=\"edit-entity-title-content\">\n @if (session.title) {\n <h2 [innerHTML]=\"session.title\"></h2>\n }\n @if (session.subtitle) {\n <p [innerHTML]=\"session.subtitle\"></p>\n }\n </div>\n\n <div class=\"edit-entity-title-actions\">\n @for (\n action of session.getActions(\"top\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n\n @if (options.showJsonDataButton === true) {\n <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"session.intl.messages.showJson\"\n [attr.aria-label]=\"session.intl.messages.showJson\"\n (click)=\"session.openJsonDataDialog()\"\n >\n <mat-icon>file_json</mat-icon>\n </button>\n }\n\n @if (displayMode === \"dialog\") {\n <button\n mat-icon-button\n type=\"button\"\n [attr.aria-label]=\"session.closeLabel\"\n (click)=\"requestClose()\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n </div>\n </header>\n }\n\n <form class=\"edit-entity-form\" [formGroup]=\"session.formGroup\">\n <main class=\"edit-entity-content\">\n @if (options.wizard; as wizard) {\n <mat-stepper\n class=\"edit-entity-wizard\"\n orientation=\"horizontal\"\n labelPosition=\"end\"\n [linear]=\"wizardLinear()\"\n [selectedIndex]=\"wizardVisualIndex()\"\n (selectionChange)=\"selectWizardVisualStep($event.selectedIndex)\"\n >\n <!-- Material icon context.active also includes completed steps; selection follows the wizard index. -->\n <ng-template matStepperIcon=\"number\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template matStepperIcon=\"edit\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template matStepperIcon=\"done\" let-index=\"index\">\n <ng-container\n *ngTemplateOutlet=\"\n wizardStateIcon;\n context: { index, active: index === wizardVisualIndex() }\n \"\n ></ng-container>\n </ng-template>\n <ng-template #wizardStateIcon let-index=\"index\" let-active=\"active\">\n <span\n class=\"edit-entity-wizard-state-icon\"\n [class.edit-entity-wizard-state-icon--selected]=\"active\"\n [class.edit-entity-wizard-state-icon--completed]=\"\n !active && wizardCompleted()[wizardVisibleIndices()[index]]\n \"\n >\n @if (\n !active && wizardCompleted()[wizardVisibleIndices()[index]]\n ) {\n <mat-icon>check</mat-icon>\n } @else {\n {{ index + 1 }}\n }\n </span>\n </ng-template>\n @for (index of wizardVisibleIndices(); track index) {\n @let step = wizard.steps[index];\n <mat-step\n [optional]=\"false\"\n [stepControl]=\"wizardNavigationControls[index]\"\n [completed]=\"\n !wizardNavigationBlocked() && wizardCompleted()[index]\n \"\n [editable]=\"\n !wizardNavigationBlocked() &&\n (index === 0 || !!options.record?._id)\n \"\n >\n <ng-template matStepLabel>\n <div\n class=\"edit-entity-wizard-step-label\"\n [class.edit-entity-wizard-step-label--selected]=\"\n index === wizardIndex()\n \"\n >\n <span class=\"edit-entity-wizard-step-name\">{{\n step.label\n }}</span>\n @if (wizardDrafts()[index]) {\n <span\n class=\"edit-entity-wizard-unsaved\"\n [title]=\"\n wizard.unsavedLabel ||\n session.intl.messages.wizardUnsaved\n \"\n >{{\n wizard.unsavedLabel ||\n session.intl.messages.wizardUnsaved\n }}</span\n >\n }\n </div>\n </ng-template>\n <ng-template matStepContent>\n @if (index === wizardIndex()) {\n <header class=\"edit-entity-wizard-content-heading\">\n <div>\n <h3>{{ step.label }}</h3>\n @if (step.description) {\n <p>{{ step.description }}</p>\n }\n </div>\n @if (step.optional && index > 0) {\n <span class=\"edit-entity-wizard-optional\">{{\n wizard.optionalLabel ||\n session.intl.messages.wizardOptional\n }}</span>\n }\n </header>\n <ame-form-content\n [state]=\"\n session.renderState().tabs?.[index]?.renderState || {\n kind: 'empty',\n }\n \"\n [formGroup]=\"session.formGroup\"\n [options]=\"options\"\n [context]=\"session\"\n />\n }\n </ng-template>\n </mat-step>\n }\n </mat-stepper>\n }\n </main>\n </form>\n\n <footer\n class=\"edit-entity-actions\"\n [class.edit-entity-wizard-actions]=\"options.wizard\"\n >\n <div class=\"edit-entity-actions-left\">\n @for (\n action of session.getActions(\"bottom\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n </div>\n\n <div class=\"edit-entity-actions-right\">\n @for (\n action of session.getActions(\"bottom-end\");\n track session.trackRuntimeAction($index, action)\n ) {\n <ng-container\n *ngTemplateOutlet=\"actionTemplate; context: { action }\"\n ></ng-container>\n }\n\n @if (options.wizard; as wizard) {\n <button\n mat-stroked-button\n type=\"button\"\n [disabled]=\"session.updating\"\n (click)=\"requestClose()\"\n >\n {{ wizardExitLabel }}\n </button>\n @if (wizardStep?.optional && options.record?._id) {\n <button\n mat-raised-button\n class=\"edit-entity-wizard-skip\"\n type=\"button\"\n [disabled]=\"wizardNavigationBlocked()\"\n (click)=\"skipWizardStep()\"\n >\n {{ wizard.skipLabel || session.intl.messages.wizardSkip }}\n </button>\n }\n <button\n mat-raised-button\n color=\"secondary\"\n type=\"button\"\n [disabled]=\"\n session.updating || (!wizardStep?.componentManaged && !wizardValid)\n \"\n (click)=\"wizardNext()\"\n >\n {{ wizardPrimaryLabel }}\n </button>\n }\n </div>\n </footer>\n\n @if (session.updating) {\n <div class=\"edit-entity-updating\">\n <mat-spinner [diameter]=\"72\" />\n </div>\n }\n}\n\n<ng-template #actionTemplate let-action=\"action\">\n @if (session.isRuntimeButtonAction(action)) {\n @if (action.buttonType === \"raised\") {\n <button\n class=\"action-btn\"\n mat-raised-button\n type=\"button\"\n [style.--action-color]=\"action.contrastColor\"\n [style.--action-background-color]=\"action.color\"\n [disabled]=\"session.updating || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"session.handleAction(action)\"\n >\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n <span [innerHTML]=\"action.label\"></span>\n </button>\n } @else {\n <button\n class=\"action-btn\"\n mat-button\n type=\"button\"\n [style.--action-color]=\"action.color\"\n [disabled]=\"session.updating || action.isDisabled\"\n [matTooltip]=\"action.tooltip || ''\"\n (click)=\"session.handleAction(action)\"\n >\n @if (action.icon) {\n <mat-icon>{{ action.icon }}</mat-icon>\n }\n <span [innerHTML]=\"action.label\"></span>\n </button>\n }\n } @else if (session.isRuntimeComponentAction(action)) {\n <ng-container\n *ngComponentOutlet=\"action.component; inputs: action.componentInputs\"\n ></ng-container>\n }\n</ng-template>\n","import {\n ChangeDetectionStrategy,\n Component,\n Inject,\n ViewChild,\n} from \"@angular/core\";\nimport {\n MAT_DIALOG_DATA,\n MatDialog,\n MatDialogRef,\n} from \"@angular/material/dialog\";\nimport {\n EditEntityRecord,\n EditEntityDialogResult,\n} from \"@eherve/angular-material-forms/core\";\nimport { EntityDialogKeyboardHost } from \"@eherve/angular-material-forms/editor\";\nimport { EntityWizardComponent } from \"./entity-wizard.component\";\nimport { CreateEntityWizardComponentOptions } from \"./create-entity-wizard.types\";\n@Component({\n selector: \"ame-entity-wizard-dialog\",\n imports: [EntityWizardComponent],\n templateUrl: \"./entity-wizard-dialog.component.html\",\n styleUrl: \"./entity-wizard-dialog.component.scss\",\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class EntityWizardDialog<\n TRecord extends EditEntityRecord = EditEntityRecord,\n> extends EntityDialogKeyboardHost<TRecord, EntityWizardDialog<TRecord>> {\n @ViewChild(EntityWizardComponent)\n protected override editEntityComponent?: EntityWizardComponent<TRecord>;\n constructor(\n @Inject(MAT_DIALOG_DATA)\n public readonly data: CreateEntityWizardComponentOptions<TRecord>,\n dialogRef: MatDialogRef<\n EntityWizardDialog<TRecord>,\n EditEntityDialogResult<TRecord>\n >,\n matDialog: MatDialog,\n ) {\n super(dialogRef, matDialog);\n }\n}\n","<ame-entity-wizard\n [options]=\"data\"\n displayMode=\"dialog\"\n (closeRequest)=\"close($event)\"\n/>\n","import { inject, Injectable } from \"@angular/core\";\nimport { MatDialogRef } from \"@angular/material/dialog\";\nimport {\n EditEntityDialogResult,\n EditEntityRecord,\n} from \"@eherve/angular-material-forms/core\";\nimport {\n EntityDialogLauncher,\n EntityDialogOpenConfig,\n} from \"@eherve/angular-material-forms/editor\";\nimport { CreateEntityWizardComponentOptions } from \"./create-entity-wizard.types\";\nimport { EntityWizardDialog } from \"./entity-wizard-dialog.component\";\nexport type CreateEntityWizardOpenConfig<TRecord extends EditEntityRecord> =\n EntityDialogOpenConfig<TRecord>;\n@Injectable({ providedIn: \"root\" })\nexport class CreateEntityWizardService {\n private readonly launcher = inject(EntityDialogLauncher);\n open<TRecord extends EditEntityRecord>(\n options: CreateEntityWizardComponentOptions<TRecord>,\n config: CreateEntityWizardOpenConfig<TRecord> = {},\n ): MatDialogRef<\n EntityWizardDialog<TRecord>,\n EditEntityDialogResult<TRecord>\n > {\n if (!options.wizard?.steps.length || !(\"tabs\" in options.displayOptions))\n throw new Error(\n \"Use createEntityWizardOptions before opening a creation wizard\",\n );\n return this.launcher.open(EntityWizardDialog<TRecord>, options, config);\n }\n}\n","import {\n EditEntityComponentOptions,\n EditEntityRecord,\n EditEntityTabDisplayOptions,\n} from \"@eherve/angular-material-forms/core\";\n\nexport interface CreateEntityWizardStep<\n TRecord extends EditEntityRecord = EditEntityRecord,\n> {\n id: string;\n label: string;\n description?: string;\n icon?: string;\n optional?: boolean;\n displayOptions: EditEntityTabDisplayOptions<TRecord>;\n /** Explicit control paths, including controls prepared by the host. Defaults to rendered fields. */\n fields?: string[];\n /** This step's components persist their own mutations; Continue never submits the form. */\n componentManaged?: boolean;\n}\n\nexport interface CreateEntityWizardConfiguration<\n TRecord extends EditEntityRecord = EditEntityRecord,\n> {\n steps: CreateEntityWizardStep<TRecord>[];\n icon?: string;\n nextLabel?: string;\n createNextLabel?: string;\n skipLabel?: string;\n finishLaterLabel?: string;\n finishLabel?: string;\n optionalLabel?: string;\n unsavedLabel?: string;\n}\n\nexport interface CreateEntityWizardComponentOptions<\n TRecord extends EditEntityRecord = EditEntityRecord,\n> extends EditEntityComponentOptions<TRecord> {\n wizard: CreateEntityWizardConfiguration<TRecord>;\n}\n\nexport type CreateEntityWizardOptions<\n TRecord extends EditEntityRecord = EditEntityRecord,\n> = Omit<\n EditEntityComponentOptions<TRecord>,\n \"displayOptions\" | \"record\" | \"wizard\"\n> &\n CreateEntityWizardConfiguration<TRecord>;\n\n/** Normalize before decorating access/fields. The opening service uses this exact options object. */\nexport function createEntityWizardOptions<TRecord extends EditEntityRecord>(\n options: CreateEntityWizardOptions<TRecord>,\n): CreateEntityWizardComponentOptions<TRecord> {\n if (!options.steps.length)\n throw new Error(\"A creation wizard requires at least one step\");\n const {\n steps,\n icon,\n nextLabel,\n createNextLabel,\n skipLabel,\n finishLaterLabel,\n finishLabel,\n optionalLabel,\n unsavedLabel,\n ...base\n } = options;\n return {\n ...base,\n service: base.service\n ? { ...base.service, closeOnUpsert: false }\n : undefined,\n wizard: {\n steps,\n icon,\n nextLabel,\n createNextLabel,\n skipLabel,\n finishLaterLabel,\n finishLabel,\n optionalLabel,\n unsavedLabel,\n },\n displayOptions: {\n tabs: steps.map((step) => ({\n id: step.id,\n label: step.label,\n icon: step.icon,\n displayOptions: step.displayOptions,\n })),\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eherve/angular-material-entity-wizard",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "22.1.0",
|
|
4
|
+
"author": "Eric Herve <eric.herve.95@gmail.com>",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/eherve/angular-material-extended.git"
|
|
8
|
+
},
|
|
9
|
+
"private": false,
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"@angular/animations": "^22.0.0",
|
|
15
|
+
"@angular/cdk": "^22.0.0",
|
|
16
|
+
"@angular/common": "^22.0.0",
|
|
17
|
+
"@angular/core": "^22.0.0",
|
|
18
|
+
"@angular/material": "^22.0.0",
|
|
19
|
+
"rxjs": "^7.8.0",
|
|
20
|
+
"@angular/forms": "^22.0.0",
|
|
21
|
+
"@eherve/angular-material-section-tabs": "^22.3.0",
|
|
22
|
+
"moment": "^2.30.1",
|
|
23
|
+
"dayjs": "^1.11.20",
|
|
24
|
+
"@angular/material-moment-adapter": "^22.0.0",
|
|
25
|
+
"@ng-matero/extensions": "^22.1.1",
|
|
26
|
+
"@ng-matero/extensions-moment-adapter": "^22.0.0",
|
|
27
|
+
"@eherve/angular-material-forms": "^22.2.0"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"tslib": "^2.3.0",
|
|
31
|
+
"lodash-es": "^4.17.21",
|
|
32
|
+
"subsink": "^1.0.2"
|
|
33
|
+
},
|
|
34
|
+
"module": "fesm2022/eherve-angular-material-entity-wizard.mjs",
|
|
35
|
+
"typings": "types/eherve-angular-material-entity-wizard.d.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
"./package.json": {
|
|
38
|
+
"default": "./package.json"
|
|
39
|
+
},
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./types/eherve-angular-material-entity-wizard.d.ts",
|
|
42
|
+
"default": "./fesm2022/eherve-angular-material-entity-wizard.mjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"sideEffects": false,
|
|
46
|
+
"type": "module"
|
|
6
47
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { EditEntityComponentOptions, EditEntityDialogResult, EditEntityFormGroup, EditEntityRecord, EditEntityTabDisplayOptions } from "@eherve/angular-material-forms/core";
|
|
2
|
+
import { MatDialog, MatDialogRef } from "@angular/material/dialog";
|
|
3
|
+
import { EntityDialogKeyboardHost, EntityDialogOpenConfig, EntityFormSession } from "@eherve/angular-material-forms/editor";
|
|
4
|
+
import { CdkStepper } from "@angular/cdk/stepper";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import { OnChanges, OnDestroy, OnInit, SimpleChanges } from "@angular/core";
|
|
7
|
+
import { FormControl } from "@angular/forms";
|
|
8
|
+
/** Scoped persistence shared by the wizard engine; no host-specific model assumptions. */
|
|
9
|
+
export declare class CreateEntityWizardState {
|
|
10
|
+
valid(form: EditEntityFormGroup, paths: string[]): boolean;
|
|
11
|
+
project(form: EditEntityFormGroup, paths: string[], changedOnly: boolean, always?: string[]): Record<string, unknown>;
|
|
12
|
+
hydrate(form: EditEntityFormGroup, record: object, submitted: string[]): void;
|
|
13
|
+
private read;
|
|
14
|
+
}
|
|
15
|
+
export interface CreateEntityWizardStep<TRecord extends EditEntityRecord = EditEntityRecord> {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
icon?: string;
|
|
20
|
+
optional?: boolean;
|
|
21
|
+
displayOptions: EditEntityTabDisplayOptions<TRecord>;
|
|
22
|
+
/** Explicit control paths, including controls prepared by the host. Defaults to rendered fields. */
|
|
23
|
+
fields?: string[];
|
|
24
|
+
/** This step's components persist their own mutations; Continue never submits the form. */
|
|
25
|
+
componentManaged?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface CreateEntityWizardConfiguration<TRecord extends EditEntityRecord = EditEntityRecord> {
|
|
28
|
+
steps: CreateEntityWizardStep<TRecord>[];
|
|
29
|
+
icon?: string;
|
|
30
|
+
nextLabel?: string;
|
|
31
|
+
createNextLabel?: string;
|
|
32
|
+
skipLabel?: string;
|
|
33
|
+
finishLaterLabel?: string;
|
|
34
|
+
finishLabel?: string;
|
|
35
|
+
optionalLabel?: string;
|
|
36
|
+
unsavedLabel?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface CreateEntityWizardComponentOptions<TRecord extends EditEntityRecord = EditEntityRecord> extends EditEntityComponentOptions<TRecord> {
|
|
39
|
+
wizard: CreateEntityWizardConfiguration<TRecord>;
|
|
40
|
+
}
|
|
41
|
+
export type CreateEntityWizardOptions<TRecord extends EditEntityRecord = EditEntityRecord> = Omit<EditEntityComponentOptions<TRecord>, "displayOptions" | "record" | "wizard"> & CreateEntityWizardConfiguration<TRecord>;
|
|
42
|
+
/** Normalize before decorating access/fields. The opening service uses this exact options object. */
|
|
43
|
+
export declare function createEntityWizardOptions<TRecord extends EditEntityRecord>(options: CreateEntityWizardOptions<TRecord>): CreateEntityWizardComponentOptions<TRecord>;
|
|
44
|
+
export declare class EntityWizardComponent<TRecord extends EditEntityRecord = EditEntityRecord> implements OnInit, OnChanges, OnDestroy {
|
|
45
|
+
options: CreateEntityWizardComponentOptions<TRecord>;
|
|
46
|
+
displayMode: "page" | "dialog";
|
|
47
|
+
readonly session: EntityFormSession<TRecord>;
|
|
48
|
+
readonly result: import("@angular/core").EventEmitter<import("@eherve/angular-material-forms/core").EditEntityDialogResult<TRecord>>;
|
|
49
|
+
readonly closeRequest: import("@angular/core").EventEmitter<import("@eherve/angular-material-forms/core").EditEntityDialogResult<TRecord>>;
|
|
50
|
+
ngOnInit(): void;
|
|
51
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
52
|
+
ngOnDestroy(): void;
|
|
53
|
+
requestClose(): Promise<void>;
|
|
54
|
+
refreshPresentation(): void;
|
|
55
|
+
submitFromKeyboard(): boolean;
|
|
56
|
+
readonly wizardIndex: import("@angular/core").WritableSignal<number>;
|
|
57
|
+
readonly wizardDrafts: import("@angular/core").WritableSignal<boolean[]>;
|
|
58
|
+
readonly wizardCompleted: import("@angular/core").WritableSignal<boolean[]>;
|
|
59
|
+
readonly wizardVisibleIndices: import("@angular/core").WritableSignal<number[]>;
|
|
60
|
+
readonly wizardVisualIndex: import("@angular/core").Signal<number>;
|
|
61
|
+
readonly wizardNavigationBlocked: import("@angular/core").WritableSignal<boolean>;
|
|
62
|
+
readonly wizardLinear: import("@angular/core").WritableSignal<boolean>;
|
|
63
|
+
wizardNavigationControls: FormControl<boolean>[];
|
|
64
|
+
wizardStepper?: CdkStepper;
|
|
65
|
+
private readonly wizardState;
|
|
66
|
+
get wizardStep(): CreateEntityWizardStep<TRecord> | undefined;
|
|
67
|
+
get wizardLast(): boolean;
|
|
68
|
+
get wizardPrimaryLabel(): string;
|
|
69
|
+
get wizardExitLabel(): string;
|
|
70
|
+
selectWizardVisualStep(position: number): void;
|
|
71
|
+
private advanceWizard;
|
|
72
|
+
private completeWizardStep;
|
|
73
|
+
private refreshWizardNavigation;
|
|
74
|
+
get wizardValid(): boolean;
|
|
75
|
+
get wizardPending(): boolean;
|
|
76
|
+
get wizardUnsaved(): boolean;
|
|
77
|
+
selectWizardStep(index: number): void;
|
|
78
|
+
skipWizardStep(): void;
|
|
79
|
+
wizardNext(): Promise<void>;
|
|
80
|
+
private wizardPaths;
|
|
81
|
+
private wizardAlwaysPaths;
|
|
82
|
+
private wizardValue;
|
|
83
|
+
private patchWizardRecord;
|
|
84
|
+
private hydrateWizard;
|
|
85
|
+
private publishWizardNavigation;
|
|
86
|
+
private restoreWizardNavigation;
|
|
87
|
+
private refreshWizardState;
|
|
88
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EntityWizardComponent<any>, never>;
|
|
89
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<EntityWizardComponent<any>, "ame-entity-wizard", never, {
|
|
90
|
+
"options": {
|
|
91
|
+
"alias": "options";
|
|
92
|
+
"required": true;
|
|
93
|
+
};
|
|
94
|
+
"displayMode": {
|
|
95
|
+
"alias": "displayMode";
|
|
96
|
+
"required": false;
|
|
97
|
+
};
|
|
98
|
+
}, {
|
|
99
|
+
"result": "result";
|
|
100
|
+
"closeRequest": "closeRequest";
|
|
101
|
+
}, never, never, true, never>;
|
|
102
|
+
}
|
|
103
|
+
export declare class EntityWizardDialog<TRecord extends EditEntityRecord = EditEntityRecord> extends EntityDialogKeyboardHost<TRecord, EntityWizardDialog<TRecord>> {
|
|
104
|
+
readonly data: CreateEntityWizardComponentOptions<TRecord>;
|
|
105
|
+
protected editEntityComponent?: EntityWizardComponent<TRecord>;
|
|
106
|
+
constructor(data: CreateEntityWizardComponentOptions<TRecord>, dialogRef: MatDialogRef<EntityWizardDialog<TRecord>, EditEntityDialogResult<TRecord>>, matDialog: MatDialog);
|
|
107
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EntityWizardDialog<any>, never>;
|
|
108
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<EntityWizardDialog<any>, "ame-entity-wizard-dialog", never, {}, {}, never, never, true, never>;
|
|
109
|
+
}
|
|
110
|
+
export type CreateEntityWizardOpenConfig<TRecord extends EditEntityRecord> = EntityDialogOpenConfig<TRecord>;
|
|
111
|
+
export declare class CreateEntityWizardService {
|
|
112
|
+
private readonly launcher;
|
|
113
|
+
open<TRecord extends EditEntityRecord>(options: CreateEntityWizardComponentOptions<TRecord>, config?: CreateEntityWizardOpenConfig<TRecord>): MatDialogRef<EntityWizardDialog<TRecord>, EditEntityDialogResult<TRecord>>;
|
|
114
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CreateEntityWizardService, never>;
|
|
115
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
116
|
+
}
|