@daltonr/pathwrite-angular 0.9.0 → 0.10.1
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 +93 -930
- package/dist/index.css +86 -0
- package/dist/index.d.ts +15 -7
- package/dist/index.js +16 -6
- package/dist/index.js.map +1 -1
- package/dist/shell.d.ts +10 -5
- package/dist/shell.js +92 -22
- package/dist/shell.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +26 -10
- package/src/shell.ts +55 -14
package/dist/index.css
CHANGED
|
@@ -285,6 +285,16 @@
|
|
|
285
285
|
content: ":";
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
/* ------------------------------------------------------------------ */
|
|
289
|
+
/* Blocking error (guard-level message, not field-attached) */
|
|
290
|
+
/* ------------------------------------------------------------------ */
|
|
291
|
+
.pw-shell__blocking-error {
|
|
292
|
+
margin: 0;
|
|
293
|
+
padding: 8px 16px;
|
|
294
|
+
font-size: 13px;
|
|
295
|
+
color: var(--pw-color-error);
|
|
296
|
+
}
|
|
297
|
+
|
|
288
298
|
/* ------------------------------------------------------------------ */
|
|
289
299
|
/* Warning messages */
|
|
290
300
|
/* ------------------------------------------------------------------ */
|
|
@@ -361,6 +371,7 @@
|
|
|
361
371
|
background: var(--pw-color-primary);
|
|
362
372
|
border-color: var(--pw-color-primary);
|
|
363
373
|
color: #fff;
|
|
374
|
+
position: relative;
|
|
364
375
|
}
|
|
365
376
|
|
|
366
377
|
.pw-shell__btn--next:hover:not(:disabled) {
|
|
@@ -368,6 +379,29 @@
|
|
|
368
379
|
border-color: #1d4ed8;
|
|
369
380
|
}
|
|
370
381
|
|
|
382
|
+
@keyframes pw-spin {
|
|
383
|
+
to { transform: rotate(360deg); }
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.pw-shell__btn--next.pw-shell__btn--loading {
|
|
387
|
+
color: transparent;
|
|
388
|
+
pointer-events: none;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.pw-shell__btn--next.pw-shell__btn--loading::after {
|
|
392
|
+
content: "";
|
|
393
|
+
position: absolute;
|
|
394
|
+
top: 50%;
|
|
395
|
+
left: 50%;
|
|
396
|
+
width: 14px;
|
|
397
|
+
height: 14px;
|
|
398
|
+
margin: -7px 0 0 -7px;
|
|
399
|
+
border: 2px solid rgba(255, 255, 255, 0.35);
|
|
400
|
+
border-top-color: #fff;
|
|
401
|
+
border-radius: 50%;
|
|
402
|
+
animation: pw-spin 0.6s linear infinite;
|
|
403
|
+
}
|
|
404
|
+
|
|
371
405
|
.pw-shell__btn--back {
|
|
372
406
|
background: transparent;
|
|
373
407
|
border-color: var(--pw-color-primary);
|
|
@@ -388,3 +422,55 @@
|
|
|
388
422
|
background: var(--pw-color-primary-light);
|
|
389
423
|
}
|
|
390
424
|
|
|
425
|
+
/* ------------------------------------------------------------------ */
|
|
426
|
+
/* Error panel — replaces footer when status === "error" */
|
|
427
|
+
/* ------------------------------------------------------------------ */
|
|
428
|
+
.pw-shell__error {
|
|
429
|
+
background: var(--pw-color-error-bg);
|
|
430
|
+
border: 1px solid var(--pw-color-error-border);
|
|
431
|
+
border-radius: var(--pw-shell-radius);
|
|
432
|
+
padding: 16px 20px;
|
|
433
|
+
display: flex;
|
|
434
|
+
flex-direction: column;
|
|
435
|
+
gap: 10px;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.pw-shell__error-title {
|
|
439
|
+
font-size: 14px;
|
|
440
|
+
font-weight: 600;
|
|
441
|
+
color: var(--pw-color-error);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.pw-shell__error-message {
|
|
445
|
+
font-size: 13px;
|
|
446
|
+
color: var(--pw-color-muted);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.pw-shell__error-actions {
|
|
450
|
+
display: flex;
|
|
451
|
+
gap: 8px;
|
|
452
|
+
align-items: center;
|
|
453
|
+
margin-top: 2px;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.pw-shell__btn--retry {
|
|
457
|
+
background: var(--pw-color-error);
|
|
458
|
+
border-color: var(--pw-color-error);
|
|
459
|
+
color: #fff;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.pw-shell__btn--retry:hover:not(:disabled) {
|
|
463
|
+
opacity: 0.9;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.pw-shell__btn--suspend {
|
|
467
|
+
color: var(--pw-color-muted);
|
|
468
|
+
border-color: transparent;
|
|
469
|
+
background: transparent;
|
|
470
|
+
font-size: 13px;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.pw-shell__btn--suspend:hover:not(:disabled) {
|
|
474
|
+
background: var(--pw-color-primary-light);
|
|
475
|
+
}
|
|
476
|
+
|
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,10 @@ export declare class PathFacade<TData extends PathData = PathData> implements On
|
|
|
51
51
|
* component that provides this facade.
|
|
52
52
|
*/
|
|
53
53
|
restart(): Promise<void>;
|
|
54
|
+
/** Re-runs the operation that set `snapshot().error`. Increments `retryCount` on repeated failure. No-op when there is no pending error. */
|
|
55
|
+
retry(): Promise<void>;
|
|
56
|
+
/** Pauses the path with intent to return. Emits `suspended`. All state is preserved. */
|
|
57
|
+
suspend(): Promise<void>;
|
|
54
58
|
startSubPath(path: PathDefinition<any>, initialData?: PathData, meta?: Record<string, unknown>): Promise<void>;
|
|
55
59
|
next(): Promise<void>;
|
|
56
60
|
previous(): Promise<void>;
|
|
@@ -69,11 +73,11 @@ export declare class PathFacade<TData extends PathData = PathData> implements On
|
|
|
69
73
|
static ɵprov: i0.ɵɵInjectableDeclaration<PathFacade<any>>;
|
|
70
74
|
}
|
|
71
75
|
/**
|
|
72
|
-
* Return type of `
|
|
76
|
+
* Return type of `usePathContext()`. Provides signal-based reactive access to the
|
|
73
77
|
* path state and strongly-typed navigation actions. Mirrors React's `usePathContext()`
|
|
74
78
|
* return type for consistency across adapters.
|
|
75
79
|
*/
|
|
76
|
-
export interface
|
|
80
|
+
export interface UsePathContextReturn<TData extends PathData = PathData> {
|
|
77
81
|
/** Current path snapshot as a signal. Returns `null` when no path is active. */
|
|
78
82
|
snapshot: Signal<PathSnapshot<TData> | null>;
|
|
79
83
|
/** Start (or restart) a path. */
|
|
@@ -99,15 +103,19 @@ export interface InjectPathReturn<TData extends PathData = PathData> {
|
|
|
99
103
|
* Use for "Start over" / retry flows.
|
|
100
104
|
*/
|
|
101
105
|
restart: () => Promise<void>;
|
|
106
|
+
/** Re-run the operation that set `snapshot().error`. */
|
|
107
|
+
retry: () => Promise<void>;
|
|
108
|
+
/** Pause with intent to return, preserving all state. Emits `suspended`. */
|
|
109
|
+
suspend: () => Promise<void>;
|
|
102
110
|
}
|
|
103
111
|
/**
|
|
104
|
-
*
|
|
112
|
+
* Access the nearest `PathFacade`'s path instance for use in Angular step components.
|
|
105
113
|
* Requires `PathFacade` to be provided in the component's injector tree (either via
|
|
106
114
|
* `providers: [PathFacade]` in the component or a parent component).
|
|
107
115
|
*
|
|
108
116
|
* **This is the recommended way to consume Pathwrite in Angular components** — it
|
|
109
|
-
* provides the same ergonomic
|
|
110
|
-
*
|
|
117
|
+
* provides the same ergonomic API as React's `usePathContext()` and Vue's `usePathContext()`.
|
|
118
|
+
* No template references or manual facade injection needed.
|
|
111
119
|
*
|
|
112
120
|
* The optional generic `TData` narrows `snapshot().data` and `setData()` to your
|
|
113
121
|
* data shape. It is a **type-level assertion**, not a runtime guarantee.
|
|
@@ -126,7 +134,7 @@ export interface InjectPathReturn<TData extends PathData = PathData> {
|
|
|
126
134
|
* `
|
|
127
135
|
* })
|
|
128
136
|
* export class ContactStepComponent {
|
|
129
|
-
* protected readonly path =
|
|
137
|
+
* protected readonly path = usePathContext<ContactData>();
|
|
130
138
|
*
|
|
131
139
|
* updateName(name: string) {
|
|
132
140
|
* this.path.setData('name', name);
|
|
@@ -136,7 +144,7 @@ export interface InjectPathReturn<TData extends PathData = PathData> {
|
|
|
136
144
|
*
|
|
137
145
|
* @throws Error if PathFacade is not provided in the injector tree
|
|
138
146
|
*/
|
|
139
|
-
export declare function
|
|
147
|
+
export declare function usePathContext<TData extends PathData = PathData>(): UsePathContextReturn<TData>;
|
|
140
148
|
/**
|
|
141
149
|
* Minimal interface describing what syncFormGroup needs from an Angular
|
|
142
150
|
* FormGroup. Typed as a duck interface so that @angular/forms is not a
|
package/dist/index.js
CHANGED
|
@@ -83,6 +83,14 @@ export class PathFacade {
|
|
|
83
83
|
restart() {
|
|
84
84
|
return this._engine.restart();
|
|
85
85
|
}
|
|
86
|
+
/** Re-runs the operation that set `snapshot().error`. Increments `retryCount` on repeated failure. No-op when there is no pending error. */
|
|
87
|
+
retry() {
|
|
88
|
+
return this._engine.retry();
|
|
89
|
+
}
|
|
90
|
+
/** Pauses the path with intent to return. Emits `suspended`. All state is preserved. */
|
|
91
|
+
suspend() {
|
|
92
|
+
return this._engine.suspend();
|
|
93
|
+
}
|
|
86
94
|
startSubPath(path, initialData = {}, meta) {
|
|
87
95
|
return this._engine.startSubPath(path, initialData, meta);
|
|
88
96
|
}
|
|
@@ -122,13 +130,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
122
130
|
type: Injectable
|
|
123
131
|
}], ctorParameters: () => [] });
|
|
124
132
|
/**
|
|
125
|
-
*
|
|
133
|
+
* Access the nearest `PathFacade`'s path instance for use in Angular step components.
|
|
126
134
|
* Requires `PathFacade` to be provided in the component's injector tree (either via
|
|
127
135
|
* `providers: [PathFacade]` in the component or a parent component).
|
|
128
136
|
*
|
|
129
137
|
* **This is the recommended way to consume Pathwrite in Angular components** — it
|
|
130
|
-
* provides the same ergonomic
|
|
131
|
-
*
|
|
138
|
+
* provides the same ergonomic API as React's `usePathContext()` and Vue's `usePathContext()`.
|
|
139
|
+
* No template references or manual facade injection needed.
|
|
132
140
|
*
|
|
133
141
|
* The optional generic `TData` narrows `snapshot().data` and `setData()` to your
|
|
134
142
|
* data shape. It is a **type-level assertion**, not a runtime guarantee.
|
|
@@ -147,7 +155,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
147
155
|
* `
|
|
148
156
|
* })
|
|
149
157
|
* export class ContactStepComponent {
|
|
150
|
-
* protected readonly path =
|
|
158
|
+
* protected readonly path = usePathContext<ContactData>();
|
|
151
159
|
*
|
|
152
160
|
* updateName(name: string) {
|
|
153
161
|
* this.path.setData('name', name);
|
|
@@ -157,10 +165,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
157
165
|
*
|
|
158
166
|
* @throws Error if PathFacade is not provided in the injector tree
|
|
159
167
|
*/
|
|
160
|
-
export function
|
|
168
|
+
export function usePathContext() {
|
|
161
169
|
const facade = inject(PathFacade, { optional: true });
|
|
162
170
|
if (!facade) {
|
|
163
|
-
throw new Error("
|
|
171
|
+
throw new Error("usePathContext() requires PathFacade to be provided. " +
|
|
164
172
|
"Add 'providers: [PathFacade]' to your component or a parent component.");
|
|
165
173
|
}
|
|
166
174
|
return {
|
|
@@ -175,6 +183,8 @@ export function injectPath() {
|
|
|
175
183
|
goToStep: (stepId) => facade.goToStep(stepId),
|
|
176
184
|
goToStepChecked: (stepId) => facade.goToStepChecked(stepId),
|
|
177
185
|
restart: () => facade.restart(),
|
|
186
|
+
retry: () => facade.retry(),
|
|
187
|
+
suspend: () => facade.suspend(),
|
|
178
188
|
};
|
|
179
189
|
}
|
|
180
190
|
/**
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/shell.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TemplateRef, EventEmitter, QueryList, OnInit, OnChanges, OnDestroy, SimpleChanges, Injector } from "@angular/core";
|
|
2
|
-
import { PathData, PathDefinition, PathEngine, PathEvent, PathSnapshot, ProgressLayout } from "@daltonr/pathwrite-core";
|
|
2
|
+
import { PathData, PathDefinition, PathEngine, PathEvent, PathSnapshot, ProgressLayout, formatFieldKey, errorPhaseMessage } from "@daltonr/pathwrite-core";
|
|
3
3
|
import { PathFacade } from "./index";
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
/**
|
|
@@ -16,6 +16,10 @@ export interface PathShellActions {
|
|
|
16
16
|
setData: (key: string, value: unknown) => Promise<void>;
|
|
17
17
|
/** Restart the shell's current path with its current `initialData`. */
|
|
18
18
|
restart: () => Promise<void>;
|
|
19
|
+
/** Re-run the operation that set `snapshot.error`. */
|
|
20
|
+
retry: () => Promise<void>;
|
|
21
|
+
/** Pause with intent to return, preserving all state. Emits `suspended`. */
|
|
22
|
+
suspend: () => Promise<void>;
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
25
|
* Structural directive that associates a template with a step ID.
|
|
@@ -124,6 +128,8 @@ export declare class PathShellComponent implements OnInit, OnChanges, OnDestroy
|
|
|
124
128
|
nextLabel: string;
|
|
125
129
|
/** Label for the Next button when on the last step. */
|
|
126
130
|
completeLabel: string;
|
|
131
|
+
/** Label shown on the Next/Complete button while an async operation is in progress. When undefined, the button keeps its label and shows a CSS spinner only. */
|
|
132
|
+
loadingLabel?: string;
|
|
127
133
|
/** Label for the Cancel button. */
|
|
128
134
|
cancelLabel: string;
|
|
129
135
|
/** Hide the Cancel button entirely. */
|
|
@@ -186,9 +192,8 @@ export declare class PathShellComponent implements OnInit, OnChanges, OnDestroy
|
|
|
186
192
|
protected warningEntries(s: PathSnapshot): [string, string][];
|
|
187
193
|
/** Resolves "auto" footerLayout based on snapshot. Single-step top-level → "form", otherwise → "wizard". */
|
|
188
194
|
protected getResolvedFooterLayout(s: PathSnapshot): "wizard" | "form";
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
protected formatFieldKey(key: string): string;
|
|
195
|
+
protected errorPhaseMessage: typeof errorPhaseMessage;
|
|
196
|
+
protected formatFieldKey: typeof formatFieldKey;
|
|
192
197
|
static ɵfac: i0.ɵɵFactoryDeclaration<PathShellComponent, never>;
|
|
193
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<PathShellComponent, "pw-shell", never, { "path": { "alias": "path"; "required": false; }; "engine": { "alias": "engine"; "required": false; }; "initialData": { "alias": "initialData"; "required": false; }; "autoStart": { "alias": "autoStart"; "required": false; }; "backLabel": { "alias": "backLabel"; "required": false; }; "nextLabel": { "alias": "nextLabel"; "required": false; }; "completeLabel": { "alias": "completeLabel"; "required": false; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; }; "hideCancel": { "alias": "hideCancel"; "required": false; }; "hideProgress": { "alias": "hideProgress"; "required": false; }; "footerLayout": { "alias": "footerLayout"; "required": false; }; "validationDisplay": { "alias": "validationDisplay"; "required": false; }; "progressLayout": { "alias": "progressLayout"; "required": false; }; }, { "complete": "complete"; "cancel": "cancel"; "event": "event"; }, ["customHeader", "customFooter", "stepDirectives"], never, true, never>;
|
|
198
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PathShellComponent, "pw-shell", never, { "path": { "alias": "path"; "required": false; }; "engine": { "alias": "engine"; "required": false; }; "initialData": { "alias": "initialData"; "required": false; }; "autoStart": { "alias": "autoStart"; "required": false; }; "backLabel": { "alias": "backLabel"; "required": false; }; "nextLabel": { "alias": "nextLabel"; "required": false; }; "completeLabel": { "alias": "completeLabel"; "required": false; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; }; "hideCancel": { "alias": "hideCancel"; "required": false; }; "hideProgress": { "alias": "hideProgress"; "required": false; }; "footerLayout": { "alias": "footerLayout"; "required": false; }; "validationDisplay": { "alias": "validationDisplay"; "required": false; }; "progressLayout": { "alias": "progressLayout"; "required": false; }; }, { "complete": "complete"; "cancel": "cancel"; "event": "event"; }, ["customHeader", "customFooter", "stepDirectives"], never, true, never>;
|
|
194
199
|
}
|
package/dist/shell.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Component, Directive, Input, Output, EventEmitter, ContentChild, Conten
|
|
|
2
2
|
import { CommonModule } from "@angular/common";
|
|
3
3
|
import { Subject } from "rxjs";
|
|
4
4
|
import { takeUntil } from "rxjs/operators";
|
|
5
|
+
import { formatFieldKey, errorPhaseMessage, } from "@daltonr/pathwrite-core";
|
|
5
6
|
import { PathFacade } from "./index";
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
import * as i1 from "@angular/common";
|
|
@@ -160,8 +161,12 @@ export class PathShellComponent {
|
|
|
160
161
|
goToStepChecked: (id) => this.facade.goToStepChecked(id),
|
|
161
162
|
setData: (key, value) => this.facade.setData(key, value),
|
|
162
163
|
restart: () => this.facade.restart(),
|
|
164
|
+
retry: () => this.facade.retry(),
|
|
165
|
+
suspend: () => this.facade.suspend(),
|
|
163
166
|
};
|
|
164
167
|
this.destroy$ = new Subject();
|
|
168
|
+
this.errorPhaseMessage = errorPhaseMessage;
|
|
169
|
+
this.formatFieldKey = formatFieldKey;
|
|
165
170
|
}
|
|
166
171
|
ngOnChanges(changes) {
|
|
167
172
|
if (changes['engine'] && this.engine) {
|
|
@@ -216,13 +221,8 @@ export class PathShellComponent {
|
|
|
216
221
|
? (s.stepCount === 1 && s.nestingLevel === 0 ? "form" : "wizard")
|
|
217
222
|
: this.footerLayout;
|
|
218
223
|
}
|
|
219
|
-
/** Converts a camelCase or lowercase field key to a display label.
|
|
220
|
-
* e.g. "firstName" → "First Name", "email" → "Email" */
|
|
221
|
-
formatFieldKey(key) {
|
|
222
|
-
return key.replace(/([A-Z])/g, " $1").replace(/^./, c => c.toUpperCase()).trim();
|
|
223
|
-
}
|
|
224
224
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PathShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
225
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PathShellComponent, isStandalone: true, selector: "pw-shell", inputs: { path: "path", engine: "engine", initialData: "initialData", autoStart: "autoStart", backLabel: "backLabel", nextLabel: "nextLabel", completeLabel: "completeLabel", cancelLabel: "cancelLabel", hideCancel: "hideCancel", hideProgress: "hideProgress", footerLayout: "footerLayout", validationDisplay: "validationDisplay", progressLayout: "progressLayout" }, outputs: { complete: "complete", cancel: "cancel", event: "event" }, providers: [PathFacade], queries: [{ propertyName: "customHeader", first: true, predicate: PathShellHeaderDirective, descendants: true }, { propertyName: "customFooter", first: true, predicate: PathShellFooterDirective, descendants: true }, { propertyName: "stepDirectives", predicate: PathStepDirective }], usesOnChanges: true, ngImport: i0, template: `
|
|
225
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PathShellComponent, isStandalone: true, selector: "pw-shell", inputs: { path: "path", engine: "engine", initialData: "initialData", autoStart: "autoStart", backLabel: "backLabel", nextLabel: "nextLabel", completeLabel: "completeLabel", loadingLabel: "loadingLabel", cancelLabel: "cancelLabel", hideCancel: "hideCancel", hideProgress: "hideProgress", footerLayout: "footerLayout", validationDisplay: "validationDisplay", progressLayout: "progressLayout" }, outputs: { complete: "complete", cancel: "cancel", event: "event" }, providers: [PathFacade], queries: [{ propertyName: "customHeader", first: true, predicate: PathShellHeaderDirective, descendants: true }, { propertyName: "customFooter", first: true, predicate: PathShellFooterDirective, descendants: true }, { propertyName: "stepDirectives", predicate: PathStepDirective }], usesOnChanges: true, ngImport: i0, template: `
|
|
226
226
|
<!-- Empty state -->
|
|
227
227
|
<div class="pw-shell" *ngIf="!(facade.state$ | async)">
|
|
228
228
|
<div class="pw-shell__empty" *ngIf="!started">
|
|
@@ -296,10 +296,43 @@ export class PathShellComponent {
|
|
|
296
296
|
</li>
|
|
297
297
|
</ul>
|
|
298
298
|
|
|
299
|
+
<!-- Blocking error — guard returned { allowed: false, reason } -->
|
|
300
|
+
<p class="pw-shell__blocking-error"
|
|
301
|
+
*ngIf="validationDisplay !== 'inline' && s.hasAttemptedNext && s.blockingError">
|
|
302
|
+
{{ s.blockingError }}
|
|
303
|
+
</p>
|
|
304
|
+
|
|
305
|
+
<!-- Error panel — replaces footer when an async operation has failed -->
|
|
306
|
+
<div class="pw-shell__error" *ngIf="s.status === 'error' && s.error; else footerOrCustom">
|
|
307
|
+
<div class="pw-shell__error-title">{{ s.error!.retryCount >= 2 ? 'Still having trouble.' : 'Something went wrong.' }}</div>
|
|
308
|
+
<div class="pw-shell__error-message">{{ errorPhaseMessage(s.error!.phase) }}{{ s.error!.message ? ' ' + s.error!.message : '' }}</div>
|
|
309
|
+
<div class="pw-shell__error-actions">
|
|
310
|
+
<button
|
|
311
|
+
*ngIf="s.error!.retryCount < 2"
|
|
312
|
+
type="button"
|
|
313
|
+
class="pw-shell__btn pw-shell__btn--retry"
|
|
314
|
+
(click)="facade.retry()"
|
|
315
|
+
>Try again</button>
|
|
316
|
+
<button
|
|
317
|
+
*ngIf="s.hasPersistence"
|
|
318
|
+
type="button"
|
|
319
|
+
[class]="'pw-shell__btn ' + (s.error!.retryCount >= 2 ? 'pw-shell__btn--retry' : 'pw-shell__btn--suspend')"
|
|
320
|
+
(click)="facade.suspend()"
|
|
321
|
+
>Save and come back later</button>
|
|
322
|
+
<button
|
|
323
|
+
*ngIf="s.error!.retryCount >= 2 && !s.hasPersistence"
|
|
324
|
+
type="button"
|
|
325
|
+
class="pw-shell__btn pw-shell__btn--retry"
|
|
326
|
+
(click)="facade.retry()"
|
|
327
|
+
>Try again</button>
|
|
328
|
+
</div>
|
|
329
|
+
</div>
|
|
299
330
|
<!-- Footer — custom or default navigation buttons -->
|
|
300
|
-
<ng-
|
|
301
|
-
<ng-container *
|
|
302
|
-
|
|
331
|
+
<ng-template #footerOrCustom>
|
|
332
|
+
<ng-container *ngIf="customFooter; else defaultFooter">
|
|
333
|
+
<ng-container *ngTemplateOutlet="customFooter.templateRef; context: { $implicit: s, actions: shellActions }"></ng-container>
|
|
334
|
+
</ng-container>
|
|
335
|
+
</ng-template>
|
|
303
336
|
<ng-template #defaultFooter>
|
|
304
337
|
<div class="pw-shell__footer">
|
|
305
338
|
<div class="pw-shell__footer-left">
|
|
@@ -308,7 +341,7 @@ export class PathShellComponent {
|
|
|
308
341
|
*ngIf="getResolvedFooterLayout(s) === 'form' && !hideCancel"
|
|
309
342
|
type="button"
|
|
310
343
|
class="pw-shell__btn pw-shell__btn--cancel"
|
|
311
|
-
[disabled]="s.
|
|
344
|
+
[disabled]="s.status !== 'idle'"
|
|
312
345
|
(click)="facade.cancel()"
|
|
313
346
|
>{{ cancelLabel }}</button>
|
|
314
347
|
<!-- Wizard mode: Back on the left -->
|
|
@@ -316,7 +349,7 @@ export class PathShellComponent {
|
|
|
316
349
|
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !s.isFirstStep"
|
|
317
350
|
type="button"
|
|
318
351
|
class="pw-shell__btn pw-shell__btn--back"
|
|
319
|
-
[disabled]="s.
|
|
352
|
+
[disabled]="s.status !== 'idle' || !s.canMovePrevious"
|
|
320
353
|
(click)="facade.previous()"
|
|
321
354
|
>{{ backLabel }}</button>
|
|
322
355
|
</div>
|
|
@@ -326,16 +359,17 @@ export class PathShellComponent {
|
|
|
326
359
|
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !hideCancel"
|
|
327
360
|
type="button"
|
|
328
361
|
class="pw-shell__btn pw-shell__btn--cancel"
|
|
329
|
-
[disabled]="s.
|
|
362
|
+
[disabled]="s.status !== 'idle'"
|
|
330
363
|
(click)="facade.cancel()"
|
|
331
364
|
>{{ cancelLabel }}</button>
|
|
332
365
|
<!-- Both modes: Submit on the right -->
|
|
333
366
|
<button
|
|
334
367
|
type="button"
|
|
335
368
|
class="pw-shell__btn pw-shell__btn--next"
|
|
336
|
-
[
|
|
369
|
+
[class.pw-shell__btn--loading]="s.status !== 'idle'"
|
|
370
|
+
[disabled]="s.status !== 'idle'"
|
|
337
371
|
(click)="facade.next()"
|
|
338
|
-
>{{ s.isLastStep ? completeLabel : nextLabel }}</button>
|
|
372
|
+
>{{ s.status !== 'idle' && loadingLabel ? loadingLabel : s.isLastStep ? completeLabel : nextLabel }}</button>
|
|
339
373
|
</div>
|
|
340
374
|
</div>
|
|
341
375
|
</ng-template>
|
|
@@ -424,10 +458,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
424
458
|
</li>
|
|
425
459
|
</ul>
|
|
426
460
|
|
|
461
|
+
<!-- Blocking error — guard returned { allowed: false, reason } -->
|
|
462
|
+
<p class="pw-shell__blocking-error"
|
|
463
|
+
*ngIf="validationDisplay !== 'inline' && s.hasAttemptedNext && s.blockingError">
|
|
464
|
+
{{ s.blockingError }}
|
|
465
|
+
</p>
|
|
466
|
+
|
|
467
|
+
<!-- Error panel — replaces footer when an async operation has failed -->
|
|
468
|
+
<div class="pw-shell__error" *ngIf="s.status === 'error' && s.error; else footerOrCustom">
|
|
469
|
+
<div class="pw-shell__error-title">{{ s.error!.retryCount >= 2 ? 'Still having trouble.' : 'Something went wrong.' }}</div>
|
|
470
|
+
<div class="pw-shell__error-message">{{ errorPhaseMessage(s.error!.phase) }}{{ s.error!.message ? ' ' + s.error!.message : '' }}</div>
|
|
471
|
+
<div class="pw-shell__error-actions">
|
|
472
|
+
<button
|
|
473
|
+
*ngIf="s.error!.retryCount < 2"
|
|
474
|
+
type="button"
|
|
475
|
+
class="pw-shell__btn pw-shell__btn--retry"
|
|
476
|
+
(click)="facade.retry()"
|
|
477
|
+
>Try again</button>
|
|
478
|
+
<button
|
|
479
|
+
*ngIf="s.hasPersistence"
|
|
480
|
+
type="button"
|
|
481
|
+
[class]="'pw-shell__btn ' + (s.error!.retryCount >= 2 ? 'pw-shell__btn--retry' : 'pw-shell__btn--suspend')"
|
|
482
|
+
(click)="facade.suspend()"
|
|
483
|
+
>Save and come back later</button>
|
|
484
|
+
<button
|
|
485
|
+
*ngIf="s.error!.retryCount >= 2 && !s.hasPersistence"
|
|
486
|
+
type="button"
|
|
487
|
+
class="pw-shell__btn pw-shell__btn--retry"
|
|
488
|
+
(click)="facade.retry()"
|
|
489
|
+
>Try again</button>
|
|
490
|
+
</div>
|
|
491
|
+
</div>
|
|
427
492
|
<!-- Footer — custom or default navigation buttons -->
|
|
428
|
-
<ng-
|
|
429
|
-
<ng-container *
|
|
430
|
-
|
|
493
|
+
<ng-template #footerOrCustom>
|
|
494
|
+
<ng-container *ngIf="customFooter; else defaultFooter">
|
|
495
|
+
<ng-container *ngTemplateOutlet="customFooter.templateRef; context: { $implicit: s, actions: shellActions }"></ng-container>
|
|
496
|
+
</ng-container>
|
|
497
|
+
</ng-template>
|
|
431
498
|
<ng-template #defaultFooter>
|
|
432
499
|
<div class="pw-shell__footer">
|
|
433
500
|
<div class="pw-shell__footer-left">
|
|
@@ -436,7 +503,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
436
503
|
*ngIf="getResolvedFooterLayout(s) === 'form' && !hideCancel"
|
|
437
504
|
type="button"
|
|
438
505
|
class="pw-shell__btn pw-shell__btn--cancel"
|
|
439
|
-
[disabled]="s.
|
|
506
|
+
[disabled]="s.status !== 'idle'"
|
|
440
507
|
(click)="facade.cancel()"
|
|
441
508
|
>{{ cancelLabel }}</button>
|
|
442
509
|
<!-- Wizard mode: Back on the left -->
|
|
@@ -444,7 +511,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
444
511
|
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !s.isFirstStep"
|
|
445
512
|
type="button"
|
|
446
513
|
class="pw-shell__btn pw-shell__btn--back"
|
|
447
|
-
[disabled]="s.
|
|
514
|
+
[disabled]="s.status !== 'idle' || !s.canMovePrevious"
|
|
448
515
|
(click)="facade.previous()"
|
|
449
516
|
>{{ backLabel }}</button>
|
|
450
517
|
</div>
|
|
@@ -454,16 +521,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
454
521
|
*ngIf="getResolvedFooterLayout(s) === 'wizard' && !hideCancel"
|
|
455
522
|
type="button"
|
|
456
523
|
class="pw-shell__btn pw-shell__btn--cancel"
|
|
457
|
-
[disabled]="s.
|
|
524
|
+
[disabled]="s.status !== 'idle'"
|
|
458
525
|
(click)="facade.cancel()"
|
|
459
526
|
>{{ cancelLabel }}</button>
|
|
460
527
|
<!-- Both modes: Submit on the right -->
|
|
461
528
|
<button
|
|
462
529
|
type="button"
|
|
463
530
|
class="pw-shell__btn pw-shell__btn--next"
|
|
464
|
-
[
|
|
531
|
+
[class.pw-shell__btn--loading]="s.status !== 'idle'"
|
|
532
|
+
[disabled]="s.status !== 'idle'"
|
|
465
533
|
(click)="facade.next()"
|
|
466
|
-
>{{ s.isLastStep ? completeLabel : nextLabel }}</button>
|
|
534
|
+
>{{ s.status !== 'idle' && loadingLabel ? loadingLabel : s.isLastStep ? completeLabel : nextLabel }}</button>
|
|
467
535
|
</div>
|
|
468
536
|
</div>
|
|
469
537
|
</ng-template>
|
|
@@ -484,6 +552,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
484
552
|
type: Input
|
|
485
553
|
}], completeLabel: [{
|
|
486
554
|
type: Input
|
|
555
|
+
}], loadingLabel: [{
|
|
556
|
+
type: Input
|
|
487
557
|
}], cancelLabel: [{
|
|
488
558
|
type: Input
|
|
489
559
|
}], hideCancel: [{
|
package/dist/shell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EAET,KAAK,EACL,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,eAAe,EAMf,MAAM,EACN,QAAQ,EACR,uBAAuB,EACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daltonr/pathwrite-angular",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Angular adapter for @daltonr/pathwrite-core — RxJS observables, signal-friendly, with optional <pw-shell> default UI.",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@angular/compiler-cli": "^17.3.12"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@daltonr/pathwrite-core": "^0.
|
|
64
|
+
"@daltonr/pathwrite-core": "^0.10.1"
|
|
65
65
|
},
|
|
66
66
|
"publishConfig": {
|
|
67
67
|
"access": "public"
|