@contractspec/lib.presentation-runtime-react 10.0.1 → 12.0.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/dist/WorkflowStepRenderer.d.ts +14 -30
- package/dist/WorkflowStepRenderer.d.ts.map +1 -1
- package/dist/WorkflowStepRenderer.js +131 -101
- package/dist/WorkflowStepper.d.ts +7 -17
- package/dist/WorkflowStepper.d.ts.map +1 -1
- package/dist/WorkflowStepper.js +48 -35
- package/dist/browser/WorkflowStepRenderer.js +132 -0
- package/dist/browser/WorkflowStepper.js +51 -0
- package/dist/browser/index.js +366 -0
- package/dist/browser/nativewind-env.d.js +0 -0
- package/dist/browser/useWorkflow.js +78 -0
- package/dist/index.d.ts +88 -106
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +363 -126
- package/dist/nativewind-env.d.js +1 -0
- package/dist/useWorkflow.d.ts +15 -24
- package/dist/useWorkflow.d.ts.map +1 -1
- package/dist/useWorkflow.js +77 -77
- package/package.json +50 -22
- package/dist/WorkflowStepRenderer.js.map +0 -1
- package/dist/WorkflowStepper.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/nativewind-env.d.ts +0 -1
- package/dist/useWorkflow.js.map +0 -1
|
@@ -1,32 +1,16 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
completedFallback?: React.ReactNode;
|
|
15
|
-
cancelledFallback?: React.ReactNode;
|
|
16
|
-
failedFallback?: (state: WorkflowState, last: StepExecution | undefined) => React.ReactNode;
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { FormRef, Step, WorkflowSpec, WorkflowState, StepExecution } from '@contractspec/lib.contracts/workflow';
|
|
3
|
+
export interface WorkflowStepRendererProps {
|
|
4
|
+
spec: WorkflowSpec;
|
|
5
|
+
state: WorkflowState | null;
|
|
6
|
+
className?: string;
|
|
7
|
+
renderHumanStep?: (form: FormRef, step: Step) => React.ReactNode;
|
|
8
|
+
renderAutomationStep?: (step: Step) => React.ReactNode;
|
|
9
|
+
renderDecisionStep?: (step: Step) => React.ReactNode;
|
|
10
|
+
loadingFallback?: React.ReactNode;
|
|
11
|
+
completedFallback?: React.ReactNode;
|
|
12
|
+
cancelledFallback?: React.ReactNode;
|
|
13
|
+
failedFallback?: (state: WorkflowState, last: StepExecution | undefined) => React.ReactNode;
|
|
17
14
|
}
|
|
18
|
-
declare function WorkflowStepRenderer({
|
|
19
|
-
spec,
|
|
20
|
-
state,
|
|
21
|
-
className,
|
|
22
|
-
renderHumanStep,
|
|
23
|
-
renderAutomationStep,
|
|
24
|
-
renderDecisionStep,
|
|
25
|
-
loadingFallback,
|
|
26
|
-
completedFallback,
|
|
27
|
-
cancelledFallback,
|
|
28
|
-
failedFallback
|
|
29
|
-
}: WorkflowStepRendererProps): react_jsx_runtime0.JSX.Element;
|
|
30
|
-
//#endregion
|
|
31
|
-
export { WorkflowStepRenderer, WorkflowStepRendererProps };
|
|
15
|
+
export declare function WorkflowStepRenderer({ spec, state, className, renderHumanStep, renderAutomationStep, renderDecisionStep, loadingFallback, completedFallback, cancelledFallback, failedFallback, }: WorkflowStepRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
32
16
|
//# sourceMappingURL=WorkflowStepRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowStepRenderer.d.ts","
|
|
1
|
+
{"version":3,"file":"WorkflowStepRenderer.d.ts","sourceRoot":"","sources":["../src/WorkflowStepRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EACV,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,aAAa,EACb,aAAa,EACd,MAAM,sCAAsC,CAAC;AAE9C,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,SAAS,CAAC;IACjE,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,SAAS,CAAC;IACvD,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,SAAS,CAAC;IACrD,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAClC,iBAAiB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,iBAAiB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,cAAc,CAAC,EAAE,CACf,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,aAAa,GAAG,SAAS,KAC5B,KAAK,CAAC,SAAS,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,KAAK,EACL,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACf,EAAE,yBAAyB,2CA6I3B"}
|
|
@@ -1,103 +1,133 @@
|
|
|
1
|
-
|
|
1
|
+
// @bun
|
|
2
|
+
// src/WorkflowStepRenderer.tsx
|
|
2
3
|
import { EmptyState, LoaderBlock } from "@contractspec/lib.design-system";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
4
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
5
|
+
function WorkflowStepRenderer({
|
|
6
|
+
spec,
|
|
7
|
+
state,
|
|
8
|
+
className,
|
|
9
|
+
renderHumanStep,
|
|
10
|
+
renderAutomationStep,
|
|
11
|
+
renderDecisionStep,
|
|
12
|
+
loadingFallback,
|
|
13
|
+
completedFallback,
|
|
14
|
+
cancelledFallback,
|
|
15
|
+
failedFallback
|
|
16
|
+
}) {
|
|
17
|
+
const steps = spec.definition.steps;
|
|
18
|
+
if (!steps.length) {
|
|
19
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
20
|
+
className,
|
|
21
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
22
|
+
title: "No steps defined",
|
|
23
|
+
description: "Add at least one step to this workflow to render it."
|
|
24
|
+
}, undefined, false, undefined, this)
|
|
25
|
+
}, undefined, false, undefined, this);
|
|
26
|
+
}
|
|
27
|
+
if (!state) {
|
|
28
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
29
|
+
className,
|
|
30
|
+
children: loadingFallback ?? /* @__PURE__ */ jsxDEV(LoaderBlock, {
|
|
31
|
+
label: "Loading workflow",
|
|
32
|
+
description: "Fetching workflow state..."
|
|
33
|
+
}, undefined, false, undefined, this)
|
|
34
|
+
}, undefined, false, undefined, this);
|
|
35
|
+
}
|
|
36
|
+
const lastExecution = state.history.at(-1);
|
|
37
|
+
if (state.status === "failed") {
|
|
38
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
39
|
+
className,
|
|
40
|
+
children: failedFallback?.(state, lastExecution) ?? /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
41
|
+
title: "Workflow failed",
|
|
42
|
+
description: lastExecution?.error ?? "Fix the underlying issue and retry the step."
|
|
43
|
+
}, undefined, false, undefined, this)
|
|
44
|
+
}, undefined, false, undefined, this);
|
|
45
|
+
}
|
|
46
|
+
if (state.status === "cancelled") {
|
|
47
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
48
|
+
className,
|
|
49
|
+
children: cancelledFallback ?? /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
50
|
+
title: "Workflow cancelled",
|
|
51
|
+
description: "This workflow has been cancelled. Restart it to resume."
|
|
52
|
+
}, undefined, false, undefined, this)
|
|
53
|
+
}, undefined, false, undefined, this);
|
|
54
|
+
}
|
|
55
|
+
if (state.status === "completed") {
|
|
56
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
57
|
+
className,
|
|
58
|
+
children: completedFallback ?? /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
59
|
+
title: "Workflow complete",
|
|
60
|
+
description: "All steps have been executed successfully."
|
|
61
|
+
}, undefined, false, undefined, this)
|
|
62
|
+
}, undefined, false, undefined, this);
|
|
63
|
+
}
|
|
64
|
+
const activeStep = steps.find((step) => step.id === state.currentStep) ?? steps[0];
|
|
65
|
+
if (!activeStep) {
|
|
66
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
67
|
+
className,
|
|
68
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
69
|
+
title: "No active step",
|
|
70
|
+
description: "This workflow has no active step."
|
|
71
|
+
}, undefined, false, undefined, this)
|
|
72
|
+
}, undefined, false, undefined, this);
|
|
73
|
+
}
|
|
74
|
+
switch (activeStep.type) {
|
|
75
|
+
case "human": {
|
|
76
|
+
const form = activeStep.action?.form;
|
|
77
|
+
if (form && renderHumanStep) {
|
|
78
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
79
|
+
className,
|
|
80
|
+
children: renderHumanStep(form, activeStep)
|
|
81
|
+
}, undefined, false, undefined, this);
|
|
82
|
+
}
|
|
83
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
84
|
+
className,
|
|
85
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
86
|
+
title: "Form renderer missing",
|
|
87
|
+
description: "Provide renderHumanStep to render this human step's form."
|
|
88
|
+
}, undefined, false, undefined, this)
|
|
89
|
+
}, undefined, false, undefined, this);
|
|
90
|
+
}
|
|
91
|
+
case "automation": {
|
|
92
|
+
if (renderAutomationStep) {
|
|
93
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
94
|
+
className,
|
|
95
|
+
children: renderAutomationStep(activeStep)
|
|
96
|
+
}, undefined, false, undefined, this);
|
|
97
|
+
}
|
|
98
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
99
|
+
className,
|
|
100
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
101
|
+
title: "Automation step in progress",
|
|
102
|
+
description: `Waiting for automation "${activeStep.label}" to finish.`
|
|
103
|
+
}, undefined, false, undefined, this)
|
|
104
|
+
}, undefined, false, undefined, this);
|
|
105
|
+
}
|
|
106
|
+
case "decision": {
|
|
107
|
+
if (renderDecisionStep) {
|
|
108
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
109
|
+
className,
|
|
110
|
+
children: renderDecisionStep(activeStep)
|
|
111
|
+
}, undefined, false, undefined, this);
|
|
112
|
+
}
|
|
113
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
114
|
+
className,
|
|
115
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
116
|
+
title: "Decision step awaiting input",
|
|
117
|
+
description: "Provide a custom decision renderer via renderDecisionStep."
|
|
118
|
+
}, undefined, false, undefined, this)
|
|
119
|
+
}, undefined, false, undefined, this);
|
|
120
|
+
}
|
|
121
|
+
default:
|
|
122
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
123
|
+
className,
|
|
124
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
125
|
+
title: "Unknown step type",
|
|
126
|
+
description: `Step "${activeStep.id}" has an unsupported type.`
|
|
127
|
+
}, undefined, false, undefined, this)
|
|
128
|
+
}, undefined, false, undefined, this);
|
|
129
|
+
}
|
|
99
130
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
//# sourceMappingURL=WorkflowStepRenderer.js.map
|
|
131
|
+
export {
|
|
132
|
+
WorkflowStepRenderer
|
|
133
|
+
};
|
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
state: WorkflowState | null;
|
|
8
|
-
className?: string;
|
|
9
|
-
showLabels?: boolean;
|
|
1
|
+
import type { WorkflowSpec, WorkflowState } from '@contractspec/lib.contracts/workflow';
|
|
2
|
+
export interface WorkflowStepperProps {
|
|
3
|
+
spec: WorkflowSpec;
|
|
4
|
+
state: WorkflowState | null;
|
|
5
|
+
className?: string;
|
|
6
|
+
showLabels?: boolean;
|
|
10
7
|
}
|
|
11
|
-
declare function WorkflowStepper({
|
|
12
|
-
spec,
|
|
13
|
-
state,
|
|
14
|
-
className,
|
|
15
|
-
showLabels
|
|
16
|
-
}: WorkflowStepperProps): react_jsx_runtime0.JSX.Element;
|
|
17
|
-
//#endregion
|
|
18
|
-
export { WorkflowStepper, WorkflowStepperProps };
|
|
8
|
+
export declare function WorkflowStepper({ spec, state, className, showLabels, }: WorkflowStepperProps): import("react/jsx-runtime").JSX.Element;
|
|
19
9
|
//# sourceMappingURL=WorkflowStepper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowStepper.d.ts","
|
|
1
|
+
{"version":3,"file":"WorkflowStepper.d.ts","sourceRoot":"","sources":["../src/WorkflowStepper.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACd,MAAM,sCAAsC,CAAC;AAG9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAkB,GACnB,EAAE,oBAAoB,2CAiCtB"}
|
package/dist/WorkflowStepper.js
CHANGED
|
@@ -1,39 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
// @bun
|
|
2
|
+
// src/WorkflowStepper.tsx
|
|
2
3
|
import { Stepper } from "@contractspec/lib.design-system";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
4
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
5
|
+
function WorkflowStepper({
|
|
6
|
+
spec,
|
|
7
|
+
state,
|
|
8
|
+
className,
|
|
9
|
+
showLabels = false
|
|
10
|
+
}) {
|
|
11
|
+
const steps = spec.definition.steps;
|
|
12
|
+
const total = steps.length;
|
|
13
|
+
const current = computeCurrent(steps, state);
|
|
14
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
15
|
+
className: ["flex flex-col gap-2", className].filter(Boolean).join(" "),
|
|
16
|
+
children: [
|
|
17
|
+
/* @__PURE__ */ jsxDEV(Stepper, {
|
|
18
|
+
current,
|
|
19
|
+
total
|
|
20
|
+
}, undefined, false, undefined, this),
|
|
21
|
+
showLabels && total > 0 && /* @__PURE__ */ jsxDEV("ol", {
|
|
22
|
+
className: "text-muted-foreground flex flex-wrap gap-2 text-sm",
|
|
23
|
+
children: steps.map((step, index) => {
|
|
24
|
+
const isActive = state?.status === "completed" ? index === total - 1 : step.id === state?.currentStep;
|
|
25
|
+
return /* @__PURE__ */ jsxDEV("li", {
|
|
26
|
+
className: [
|
|
27
|
+
"rounded border px-2 py-1",
|
|
28
|
+
isActive ? "border-primary text-primary" : "border-border"
|
|
29
|
+
].join(" "),
|
|
30
|
+
children: /* @__PURE__ */ jsxDEV("span", {
|
|
31
|
+
className: "font-medium",
|
|
32
|
+
children: step.label
|
|
33
|
+
}, undefined, false, undefined, this)
|
|
34
|
+
}, step.id, false, undefined, this);
|
|
35
|
+
})
|
|
36
|
+
}, undefined, false, undefined, this)
|
|
37
|
+
]
|
|
38
|
+
}, undefined, true, undefined, this);
|
|
28
39
|
}
|
|
29
40
|
function computeCurrent(steps, state) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
if (!steps.length)
|
|
42
|
+
return 0;
|
|
43
|
+
if (!state)
|
|
44
|
+
return 1;
|
|
45
|
+
if (state.status === "completed")
|
|
46
|
+
return steps.length;
|
|
47
|
+
const idx = steps.findIndex((step) => step.id === state.currentStep);
|
|
48
|
+
return idx === -1 ? 1 : idx + 1;
|
|
35
49
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
//# sourceMappingURL=WorkflowStepper.js.map
|
|
50
|
+
export {
|
|
51
|
+
WorkflowStepper
|
|
52
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// src/WorkflowStepRenderer.tsx
|
|
2
|
+
import { EmptyState, LoaderBlock } from "@contractspec/lib.design-system";
|
|
3
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
4
|
+
function WorkflowStepRenderer({
|
|
5
|
+
spec,
|
|
6
|
+
state,
|
|
7
|
+
className,
|
|
8
|
+
renderHumanStep,
|
|
9
|
+
renderAutomationStep,
|
|
10
|
+
renderDecisionStep,
|
|
11
|
+
loadingFallback,
|
|
12
|
+
completedFallback,
|
|
13
|
+
cancelledFallback,
|
|
14
|
+
failedFallback
|
|
15
|
+
}) {
|
|
16
|
+
const steps = spec.definition.steps;
|
|
17
|
+
if (!steps.length) {
|
|
18
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
19
|
+
className,
|
|
20
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
21
|
+
title: "No steps defined",
|
|
22
|
+
description: "Add at least one step to this workflow to render it."
|
|
23
|
+
}, undefined, false, undefined, this)
|
|
24
|
+
}, undefined, false, undefined, this);
|
|
25
|
+
}
|
|
26
|
+
if (!state) {
|
|
27
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
28
|
+
className,
|
|
29
|
+
children: loadingFallback ?? /* @__PURE__ */ jsxDEV(LoaderBlock, {
|
|
30
|
+
label: "Loading workflow",
|
|
31
|
+
description: "Fetching workflow state..."
|
|
32
|
+
}, undefined, false, undefined, this)
|
|
33
|
+
}, undefined, false, undefined, this);
|
|
34
|
+
}
|
|
35
|
+
const lastExecution = state.history.at(-1);
|
|
36
|
+
if (state.status === "failed") {
|
|
37
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
38
|
+
className,
|
|
39
|
+
children: failedFallback?.(state, lastExecution) ?? /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
40
|
+
title: "Workflow failed",
|
|
41
|
+
description: lastExecution?.error ?? "Fix the underlying issue and retry the step."
|
|
42
|
+
}, undefined, false, undefined, this)
|
|
43
|
+
}, undefined, false, undefined, this);
|
|
44
|
+
}
|
|
45
|
+
if (state.status === "cancelled") {
|
|
46
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
47
|
+
className,
|
|
48
|
+
children: cancelledFallback ?? /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
49
|
+
title: "Workflow cancelled",
|
|
50
|
+
description: "This workflow has been cancelled. Restart it to resume."
|
|
51
|
+
}, undefined, false, undefined, this)
|
|
52
|
+
}, undefined, false, undefined, this);
|
|
53
|
+
}
|
|
54
|
+
if (state.status === "completed") {
|
|
55
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
56
|
+
className,
|
|
57
|
+
children: completedFallback ?? /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
58
|
+
title: "Workflow complete",
|
|
59
|
+
description: "All steps have been executed successfully."
|
|
60
|
+
}, undefined, false, undefined, this)
|
|
61
|
+
}, undefined, false, undefined, this);
|
|
62
|
+
}
|
|
63
|
+
const activeStep = steps.find((step) => step.id === state.currentStep) ?? steps[0];
|
|
64
|
+
if (!activeStep) {
|
|
65
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
66
|
+
className,
|
|
67
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
68
|
+
title: "No active step",
|
|
69
|
+
description: "This workflow has no active step."
|
|
70
|
+
}, undefined, false, undefined, this)
|
|
71
|
+
}, undefined, false, undefined, this);
|
|
72
|
+
}
|
|
73
|
+
switch (activeStep.type) {
|
|
74
|
+
case "human": {
|
|
75
|
+
const form = activeStep.action?.form;
|
|
76
|
+
if (form && renderHumanStep) {
|
|
77
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
78
|
+
className,
|
|
79
|
+
children: renderHumanStep(form, activeStep)
|
|
80
|
+
}, undefined, false, undefined, this);
|
|
81
|
+
}
|
|
82
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
83
|
+
className,
|
|
84
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
85
|
+
title: "Form renderer missing",
|
|
86
|
+
description: "Provide renderHumanStep to render this human step's form."
|
|
87
|
+
}, undefined, false, undefined, this)
|
|
88
|
+
}, undefined, false, undefined, this);
|
|
89
|
+
}
|
|
90
|
+
case "automation": {
|
|
91
|
+
if (renderAutomationStep) {
|
|
92
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
93
|
+
className,
|
|
94
|
+
children: renderAutomationStep(activeStep)
|
|
95
|
+
}, undefined, false, undefined, this);
|
|
96
|
+
}
|
|
97
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
98
|
+
className,
|
|
99
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
100
|
+
title: "Automation step in progress",
|
|
101
|
+
description: `Waiting for automation "${activeStep.label}" to finish.`
|
|
102
|
+
}, undefined, false, undefined, this)
|
|
103
|
+
}, undefined, false, undefined, this);
|
|
104
|
+
}
|
|
105
|
+
case "decision": {
|
|
106
|
+
if (renderDecisionStep) {
|
|
107
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
108
|
+
className,
|
|
109
|
+
children: renderDecisionStep(activeStep)
|
|
110
|
+
}, undefined, false, undefined, this);
|
|
111
|
+
}
|
|
112
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
113
|
+
className,
|
|
114
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
115
|
+
title: "Decision step awaiting input",
|
|
116
|
+
description: "Provide a custom decision renderer via renderDecisionStep."
|
|
117
|
+
}, undefined, false, undefined, this)
|
|
118
|
+
}, undefined, false, undefined, this);
|
|
119
|
+
}
|
|
120
|
+
default:
|
|
121
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
122
|
+
className,
|
|
123
|
+
children: /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
124
|
+
title: "Unknown step type",
|
|
125
|
+
description: `Step "${activeStep.id}" has an unsupported type.`
|
|
126
|
+
}, undefined, false, undefined, this)
|
|
127
|
+
}, undefined, false, undefined, this);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export {
|
|
131
|
+
WorkflowStepRenderer
|
|
132
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/WorkflowStepper.tsx
|
|
2
|
+
import { Stepper } from "@contractspec/lib.design-system";
|
|
3
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
4
|
+
function WorkflowStepper({
|
|
5
|
+
spec,
|
|
6
|
+
state,
|
|
7
|
+
className,
|
|
8
|
+
showLabels = false
|
|
9
|
+
}) {
|
|
10
|
+
const steps = spec.definition.steps;
|
|
11
|
+
const total = steps.length;
|
|
12
|
+
const current = computeCurrent(steps, state);
|
|
13
|
+
return /* @__PURE__ */ jsxDEV("div", {
|
|
14
|
+
className: ["flex flex-col gap-2", className].filter(Boolean).join(" "),
|
|
15
|
+
children: [
|
|
16
|
+
/* @__PURE__ */ jsxDEV(Stepper, {
|
|
17
|
+
current,
|
|
18
|
+
total
|
|
19
|
+
}, undefined, false, undefined, this),
|
|
20
|
+
showLabels && total > 0 && /* @__PURE__ */ jsxDEV("ol", {
|
|
21
|
+
className: "text-muted-foreground flex flex-wrap gap-2 text-sm",
|
|
22
|
+
children: steps.map((step, index) => {
|
|
23
|
+
const isActive = state?.status === "completed" ? index === total - 1 : step.id === state?.currentStep;
|
|
24
|
+
return /* @__PURE__ */ jsxDEV("li", {
|
|
25
|
+
className: [
|
|
26
|
+
"rounded border px-2 py-1",
|
|
27
|
+
isActive ? "border-primary text-primary" : "border-border"
|
|
28
|
+
].join(" "),
|
|
29
|
+
children: /* @__PURE__ */ jsxDEV("span", {
|
|
30
|
+
className: "font-medium",
|
|
31
|
+
children: step.label
|
|
32
|
+
}, undefined, false, undefined, this)
|
|
33
|
+
}, step.id, false, undefined, this);
|
|
34
|
+
})
|
|
35
|
+
}, undefined, false, undefined, this)
|
|
36
|
+
]
|
|
37
|
+
}, undefined, true, undefined, this);
|
|
38
|
+
}
|
|
39
|
+
function computeCurrent(steps, state) {
|
|
40
|
+
if (!steps.length)
|
|
41
|
+
return 0;
|
|
42
|
+
if (!state)
|
|
43
|
+
return 1;
|
|
44
|
+
if (state.status === "completed")
|
|
45
|
+
return steps.length;
|
|
46
|
+
const idx = steps.findIndex((step) => step.id === state.currentStep);
|
|
47
|
+
return idx === -1 ? 1 : idx + 1;
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
WorkflowStepper
|
|
51
|
+
};
|