@contractspec/example.workflow-system 0.0.0-canary-20260113170453

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/dist/approval/approval.enum.d.ts +14 -0
  4. package/dist/approval/approval.enum.d.ts.map +1 -0
  5. package/dist/approval/approval.enum.js +29 -0
  6. package/dist/approval/approval.enum.js.map +1 -0
  7. package/dist/approval/approval.event.d.ts +131 -0
  8. package/dist/approval/approval.event.d.ts.map +1 -0
  9. package/dist/approval/approval.event.js +220 -0
  10. package/dist/approval/approval.event.js.map +1 -0
  11. package/dist/approval/approval.handler.d.ts +23 -0
  12. package/dist/approval/approval.handler.d.ts.map +1 -0
  13. package/dist/approval/approval.handler.js +72 -0
  14. package/dist/approval/approval.handler.js.map +1 -0
  15. package/dist/approval/approval.operations.d.ts +535 -0
  16. package/dist/approval/approval.operations.d.ts.map +1 -0
  17. package/dist/approval/approval.operations.js +345 -0
  18. package/dist/approval/approval.operations.js.map +1 -0
  19. package/dist/approval/approval.schema.d.ts +100 -0
  20. package/dist/approval/approval.schema.d.ts.map +1 -0
  21. package/dist/approval/approval.schema.js +110 -0
  22. package/dist/approval/approval.schema.js.map +1 -0
  23. package/dist/approval/index.d.ts +5 -0
  24. package/dist/approval/index.js +6 -0
  25. package/dist/docs/index.d.ts +1 -0
  26. package/dist/docs/index.js +1 -0
  27. package/dist/docs/workflow-system.docblock.d.ts +1 -0
  28. package/dist/docs/workflow-system.docblock.js +115 -0
  29. package/dist/docs/workflow-system.docblock.js.map +1 -0
  30. package/dist/entities/approval.d.ts +58 -0
  31. package/dist/entities/approval.d.ts.map +1 -0
  32. package/dist/entities/approval.js +128 -0
  33. package/dist/entities/approval.js.map +1 -0
  34. package/dist/entities/index.d.ts +139 -0
  35. package/dist/entities/index.d.ts.map +1 -0
  36. package/dist/entities/index.js +32 -0
  37. package/dist/entities/index.js.map +1 -0
  38. package/dist/entities/instance.d.ts +69 -0
  39. package/dist/entities/instance.d.ts.map +1 -0
  40. package/dist/entities/instance.js +168 -0
  41. package/dist/entities/instance.js.map +1 -0
  42. package/dist/entities/step.d.ts +50 -0
  43. package/dist/entities/step.d.ts.map +1 -0
  44. package/dist/entities/step.js +135 -0
  45. package/dist/entities/step.js.map +1 -0
  46. package/dist/entities/workflow.d.ts +41 -0
  47. package/dist/entities/workflow.d.ts.map +1 -0
  48. package/dist/entities/workflow.js +102 -0
  49. package/dist/entities/workflow.js.map +1 -0
  50. package/dist/example.d.ts +7 -0
  51. package/dist/example.d.ts.map +1 -0
  52. package/dist/example.js +58 -0
  53. package/dist/example.js.map +1 -0
  54. package/dist/handlers/index.d.ts +2 -0
  55. package/dist/handlers/index.js +3 -0
  56. package/dist/handlers/workflow.handlers.d.ts +122 -0
  57. package/dist/handlers/workflow.handlers.d.ts.map +1 -0
  58. package/dist/handlers/workflow.handlers.js +263 -0
  59. package/dist/handlers/workflow.handlers.js.map +1 -0
  60. package/dist/index.d.ts +26 -0
  61. package/dist/index.js +26 -0
  62. package/dist/instance/index.d.ts +5 -0
  63. package/dist/instance/index.js +6 -0
  64. package/dist/instance/instance.enum.d.ts +10 -0
  65. package/dist/instance/instance.enum.d.ts.map +1 -0
  66. package/dist/instance/instance.enum.js +20 -0
  67. package/dist/instance/instance.enum.js.map +1 -0
  68. package/dist/instance/instance.event.d.ts +356 -0
  69. package/dist/instance/instance.event.d.ts.map +1 -0
  70. package/dist/instance/instance.event.js +293 -0
  71. package/dist/instance/instance.event.js.map +1 -0
  72. package/dist/instance/instance.handler.d.ts +27 -0
  73. package/dist/instance/instance.handler.d.ts.map +1 -0
  74. package/dist/instance/instance.handler.js +94 -0
  75. package/dist/instance/instance.handler.js.map +1 -0
  76. package/dist/instance/instance.operations.d.ts +1024 -0
  77. package/dist/instance/instance.operations.d.ts.map +1 -0
  78. package/dist/instance/instance.operations.js +464 -0
  79. package/dist/instance/instance.operations.js.map +1 -0
  80. package/dist/instance/instance.schema.d.ts +223 -0
  81. package/dist/instance/instance.schema.d.ts.map +1 -0
  82. package/dist/instance/instance.schema.js +172 -0
  83. package/dist/instance/instance.schema.js.map +1 -0
  84. package/dist/presentations/index.d.ts +63 -0
  85. package/dist/presentations/index.d.ts.map +1 -0
  86. package/dist/presentations/index.js +340 -0
  87. package/dist/presentations/index.js.map +1 -0
  88. package/dist/seeders/index.d.ts +10 -0
  89. package/dist/seeders/index.d.ts.map +1 -0
  90. package/dist/seeders/index.js +19 -0
  91. package/dist/seeders/index.js.map +1 -0
  92. package/dist/shared/index.d.ts +3 -0
  93. package/dist/shared/index.js +3 -0
  94. package/dist/shared/mock-data.d.ts +19 -0
  95. package/dist/shared/mock-data.d.ts.map +1 -0
  96. package/dist/shared/mock-data.js +12 -0
  97. package/dist/shared/mock-data.js.map +1 -0
  98. package/dist/shared/types.d.ts +81 -0
  99. package/dist/shared/types.d.ts.map +1 -0
  100. package/dist/shared/types.js +0 -0
  101. package/dist/state-machine/index.d.ts +148 -0
  102. package/dist/state-machine/index.d.ts.map +1 -0
  103. package/dist/state-machine/index.js +158 -0
  104. package/dist/state-machine/index.js.map +1 -0
  105. package/dist/tests/operations.test-spec.d.ts +10 -0
  106. package/dist/tests/operations.test-spec.d.ts.map +1 -0
  107. package/dist/tests/operations.test-spec.js +123 -0
  108. package/dist/tests/operations.test-spec.js.map +1 -0
  109. package/dist/ui/WorkflowDashboard.d.ts +7 -0
  110. package/dist/ui/WorkflowDashboard.d.ts.map +1 -0
  111. package/dist/ui/WorkflowDashboard.js +223 -0
  112. package/dist/ui/WorkflowDashboard.js.map +1 -0
  113. package/dist/ui/hooks/index.d.ts +2 -0
  114. package/dist/ui/hooks/index.js +5 -0
  115. package/dist/ui/hooks/useWorkflowList.d.ts +22 -0
  116. package/dist/ui/hooks/useWorkflowList.d.ts.map +1 -0
  117. package/dist/ui/hooks/useWorkflowList.js +55 -0
  118. package/dist/ui/hooks/useWorkflowList.js.map +1 -0
  119. package/dist/ui/index.d.ts +6 -0
  120. package/dist/ui/index.js +6 -0
  121. package/dist/ui/renderers/index.d.ts +2 -0
  122. package/dist/ui/renderers/index.js +3 -0
  123. package/dist/ui/renderers/workflow.markdown.d.ts +28 -0
  124. package/dist/ui/renderers/workflow.markdown.d.ts.map +1 -0
  125. package/dist/ui/renderers/workflow.markdown.js +234 -0
  126. package/dist/ui/renderers/workflow.markdown.js.map +1 -0
  127. package/dist/workflow/index.d.ts +5 -0
  128. package/dist/workflow/index.js +6 -0
  129. package/dist/workflow/workflow.enum.d.ts +22 -0
  130. package/dist/workflow/workflow.enum.d.ts.map +1 -0
  131. package/dist/workflow/workflow.enum.js +47 -0
  132. package/dist/workflow/workflow.enum.js.map +1 -0
  133. package/dist/workflow/workflow.event.d.ts +135 -0
  134. package/dist/workflow/workflow.event.d.ts.map +1 -0
  135. package/dist/workflow/workflow.event.js +150 -0
  136. package/dist/workflow/workflow.event.js.map +1 -0
  137. package/dist/workflow/workflow.handler.d.ts +29 -0
  138. package/dist/workflow/workflow.handler.d.ts.map +1 -0
  139. package/dist/workflow/workflow.handler.js +66 -0
  140. package/dist/workflow/workflow.handler.js.map +1 -0
  141. package/dist/workflow/workflow.operations.d.ts +1011 -0
  142. package/dist/workflow/workflow.operations.d.ts.map +1 -0
  143. package/dist/workflow/workflow.operations.js +345 -0
  144. package/dist/workflow/workflow.operations.js.map +1 -0
  145. package/dist/workflow/workflow.schema.d.ts +265 -0
  146. package/dist/workflow/workflow.schema.d.ts.map +1 -0
  147. package/dist/workflow/workflow.schema.js +249 -0
  148. package/dist/workflow/workflow.schema.js.map +1 -0
  149. package/dist/workflow-system.capability.d.ts +9 -0
  150. package/dist/workflow-system.capability.d.ts.map +1 -0
  151. package/dist/workflow-system.capability.js +34 -0
  152. package/dist/workflow-system.capability.js.map +1 -0
  153. package/dist/workflow-system.feature.d.ts +12 -0
  154. package/dist/workflow-system.feature.d.ts.map +1 -0
  155. package/dist/workflow-system.feature.js +346 -0
  156. package/dist/workflow-system.feature.js.map +1 -0
  157. package/package.json +133 -0
@@ -0,0 +1,223 @@
1
+ 'use client';
2
+
3
+ import { useWorkflowList } from "./hooks/useWorkflowList.js";
4
+ import { useState } from "react";
5
+ import { Button, ErrorState, LoaderBlock, StatCard, StatCardGroup } from "@contractspec/lib.design-system";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/ui/WorkflowDashboard.tsx
9
+ /**
10
+ * Workflow Dashboard
11
+ *
12
+ * Interactive dashboard for the workflow-system template.
13
+ * Displays workflow definitions and instances with stats.
14
+ */
15
+ const STATUS_COLORS = {
16
+ ACTIVE: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
17
+ DRAFT: "bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400",
18
+ ARCHIVED: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400",
19
+ PENDING: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400",
20
+ IN_PROGRESS: "bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400",
21
+ COMPLETED: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
22
+ REJECTED: "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400",
23
+ CANCELLED: "bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400"
24
+ };
25
+ function WorkflowDashboard() {
26
+ const [activeTab, setActiveTab] = useState("definitions");
27
+ const { definitions, instances, loading, error, stats, refetch } = useWorkflowList();
28
+ const tabs = [{
29
+ id: "definitions",
30
+ label: "Definitions",
31
+ icon: "📋"
32
+ }, {
33
+ id: "instances",
34
+ label: "Instances",
35
+ icon: "🔄"
36
+ }];
37
+ if (loading) return /* @__PURE__ */ jsx(LoaderBlock, { label: "Loading Workflows..." });
38
+ if (error) return /* @__PURE__ */ jsx(ErrorState, {
39
+ title: "Failed to load Workflows",
40
+ description: error.message,
41
+ onRetry: refetch,
42
+ retryLabel: "Retry"
43
+ });
44
+ return /* @__PURE__ */ jsxs("div", {
45
+ className: "space-y-6",
46
+ children: [
47
+ /* @__PURE__ */ jsxs("div", {
48
+ className: "flex items-center justify-between",
49
+ children: [/* @__PURE__ */ jsx("h2", {
50
+ className: "text-2xl font-bold",
51
+ children: "Workflow System"
52
+ }), /* @__PURE__ */ jsxs(Button, {
53
+ onClick: () => alert("Create workflow modal"),
54
+ children: [/* @__PURE__ */ jsx("span", {
55
+ className: "mr-2",
56
+ children: "+"
57
+ }), " New Workflow"]
58
+ })]
59
+ }),
60
+ /* @__PURE__ */ jsxs(StatCardGroup, { children: [
61
+ /* @__PURE__ */ jsx(StatCard, {
62
+ label: "Workflows",
63
+ value: stats.totalDefinitions,
64
+ hint: `${stats.activeDefinitions} active`
65
+ }),
66
+ /* @__PURE__ */ jsx(StatCard, {
67
+ label: "Instances",
68
+ value: stats.totalInstances,
69
+ hint: "total runs"
70
+ }),
71
+ /* @__PURE__ */ jsx(StatCard, {
72
+ label: "Pending",
73
+ value: stats.pendingInstances,
74
+ hint: "awaiting action"
75
+ }),
76
+ /* @__PURE__ */ jsx(StatCard, {
77
+ label: "Completed",
78
+ value: stats.completedInstances,
79
+ hint: "finished"
80
+ })
81
+ ] }),
82
+ /* @__PURE__ */ jsx("nav", {
83
+ className: "bg-muted flex gap-1 rounded-lg p-1",
84
+ role: "tablist",
85
+ children: tabs.map((tab) => /* @__PURE__ */ jsxs(Button, {
86
+ type: "button",
87
+ role: "tab",
88
+ "aria-selected": activeTab === tab.id,
89
+ onClick: () => setActiveTab(tab.id),
90
+ className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
91
+ children: [/* @__PURE__ */ jsx("span", { children: tab.icon }), tab.label]
92
+ }, tab.id))
93
+ }),
94
+ /* @__PURE__ */ jsxs("div", {
95
+ className: "min-h-[400px]",
96
+ role: "tabpanel",
97
+ children: [activeTab === "definitions" && /* @__PURE__ */ jsx("div", {
98
+ className: "border-border rounded-lg border",
99
+ children: /* @__PURE__ */ jsxs("table", {
100
+ className: "w-full",
101
+ children: [/* @__PURE__ */ jsx("thead", {
102
+ className: "border-border bg-muted/30 border-b",
103
+ children: /* @__PURE__ */ jsxs("tr", { children: [
104
+ /* @__PURE__ */ jsx("th", {
105
+ className: "px-4 py-3 text-left text-sm font-medium",
106
+ children: "Name"
107
+ }),
108
+ /* @__PURE__ */ jsx("th", {
109
+ className: "px-4 py-3 text-left text-sm font-medium",
110
+ children: "Type"
111
+ }),
112
+ /* @__PURE__ */ jsx("th", {
113
+ className: "px-4 py-3 text-left text-sm font-medium",
114
+ children: "Status"
115
+ }),
116
+ /* @__PURE__ */ jsx("th", {
117
+ className: "px-4 py-3 text-left text-sm font-medium",
118
+ children: "Created"
119
+ })
120
+ ] })
121
+ }), /* @__PURE__ */ jsxs("tbody", {
122
+ className: "divide-border divide-y",
123
+ children: [definitions.map((def) => /* @__PURE__ */ jsxs("tr", {
124
+ className: "hover:bg-muted/50",
125
+ children: [
126
+ /* @__PURE__ */ jsxs("td", {
127
+ className: "px-4 py-3",
128
+ children: [/* @__PURE__ */ jsx("div", {
129
+ className: "font-medium",
130
+ children: def.name
131
+ }), /* @__PURE__ */ jsx("div", {
132
+ className: "text-muted-foreground text-sm",
133
+ children: def.description
134
+ })]
135
+ }),
136
+ /* @__PURE__ */ jsx("td", {
137
+ className: "px-4 py-3 font-mono text-sm",
138
+ children: def.type
139
+ }),
140
+ /* @__PURE__ */ jsx("td", {
141
+ className: "px-4 py-3",
142
+ children: /* @__PURE__ */ jsx("span", {
143
+ className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[def.status] ?? ""}`,
144
+ children: def.status
145
+ })
146
+ }),
147
+ /* @__PURE__ */ jsx("td", {
148
+ className: "text-muted-foreground px-4 py-3 text-sm",
149
+ children: def.createdAt.toLocaleDateString()
150
+ })
151
+ ]
152
+ }, def.id)), definitions.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
153
+ colSpan: 4,
154
+ className: "text-muted-foreground px-4 py-8 text-center",
155
+ children: "No workflow definitions found"
156
+ }) })]
157
+ })]
158
+ })
159
+ }), activeTab === "instances" && /* @__PURE__ */ jsx("div", {
160
+ className: "border-border rounded-lg border",
161
+ children: /* @__PURE__ */ jsxs("table", {
162
+ className: "w-full",
163
+ children: [/* @__PURE__ */ jsx("thead", {
164
+ className: "border-border bg-muted/30 border-b",
165
+ children: /* @__PURE__ */ jsxs("tr", { children: [
166
+ /* @__PURE__ */ jsx("th", {
167
+ className: "px-4 py-3 text-left text-sm font-medium",
168
+ children: "Instance ID"
169
+ }),
170
+ /* @__PURE__ */ jsx("th", {
171
+ className: "px-4 py-3 text-left text-sm font-medium",
172
+ children: "Status"
173
+ }),
174
+ /* @__PURE__ */ jsx("th", {
175
+ className: "px-4 py-3 text-left text-sm font-medium",
176
+ children: "Requested By"
177
+ }),
178
+ /* @__PURE__ */ jsx("th", {
179
+ className: "px-4 py-3 text-left text-sm font-medium",
180
+ children: "Started"
181
+ })
182
+ ] })
183
+ }), /* @__PURE__ */ jsxs("tbody", {
184
+ className: "divide-border divide-y",
185
+ children: [instances.map((inst) => /* @__PURE__ */ jsxs("tr", {
186
+ className: "hover:bg-muted/50",
187
+ children: [
188
+ /* @__PURE__ */ jsx("td", {
189
+ className: "px-4 py-3 font-mono text-sm",
190
+ children: inst.id
191
+ }),
192
+ /* @__PURE__ */ jsx("td", {
193
+ className: "px-4 py-3",
194
+ children: /* @__PURE__ */ jsx("span", {
195
+ className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[inst.status] ?? ""}`,
196
+ children: inst.status
197
+ })
198
+ }),
199
+ /* @__PURE__ */ jsx("td", {
200
+ className: "px-4 py-3 text-sm",
201
+ children: inst.requestedBy
202
+ }),
203
+ /* @__PURE__ */ jsx("td", {
204
+ className: "text-muted-foreground px-4 py-3 text-sm",
205
+ children: inst.startedAt.toLocaleDateString()
206
+ })
207
+ ]
208
+ }, inst.id)), instances.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
209
+ colSpan: 4,
210
+ className: "text-muted-foreground px-4 py-8 text-center",
211
+ children: "No workflow instances found"
212
+ }) })]
213
+ })]
214
+ })
215
+ })]
216
+ })
217
+ ]
218
+ });
219
+ }
220
+
221
+ //#endregion
222
+ export { WorkflowDashboard };
223
+ //# sourceMappingURL=WorkflowDashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowDashboard.js","names":[],"sources":["../../src/ui/WorkflowDashboard.tsx"],"sourcesContent":["'use client';\n\n/**\n * Workflow Dashboard\n *\n * Interactive dashboard for the workflow-system template.\n * Displays workflow definitions and instances with stats.\n */\nimport { useState } from 'react';\nimport {\n Button,\n ErrorState,\n LoaderBlock,\n StatCard,\n StatCardGroup,\n} from '@contractspec/lib.design-system';\nimport { useWorkflowList } from './hooks/useWorkflowList';\n\ntype Tab = 'definitions' | 'instances';\n\nconst STATUS_COLORS: Record<string, string> = {\n ACTIVE:\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n DRAFT: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',\n ARCHIVED:\n 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400',\n PENDING: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n IN_PROGRESS:\n 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400',\n COMPLETED:\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n REJECTED: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n CANCELLED: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',\n};\n\nexport function WorkflowDashboard() {\n const [activeTab, setActiveTab] = useState<Tab>('definitions');\n const { definitions, instances, loading, error, stats, refetch } =\n useWorkflowList();\n\n const tabs: { id: Tab; label: string; icon: string }[] = [\n { id: 'definitions', label: 'Definitions', icon: '📋' },\n { id: 'instances', label: 'Instances', icon: '🔄' },\n ];\n\n if (loading) {\n return <LoaderBlock label=\"Loading Workflows...\" />;\n }\n\n if (error) {\n return (\n <ErrorState\n title=\"Failed to load Workflows\"\n description={error.message}\n onRetry={refetch}\n retryLabel=\"Retry\"\n />\n );\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-2xl font-bold\">Workflow System</h2>\n <Button onClick={() => alert('Create workflow modal')}>\n <span className=\"mr-2\">+</span> New Workflow\n </Button>\n </div>\n\n {/* Stats Row */}\n <StatCardGroup>\n <StatCard\n label=\"Workflows\"\n value={stats.totalDefinitions}\n hint={`${stats.activeDefinitions} active`}\n />\n <StatCard\n label=\"Instances\"\n value={stats.totalInstances}\n hint=\"total runs\"\n />\n <StatCard\n label=\"Pending\"\n value={stats.pendingInstances}\n hint=\"awaiting action\"\n />\n <StatCard\n label=\"Completed\"\n value={stats.completedInstances}\n hint=\"finished\"\n />\n </StatCardGroup>\n\n {/* Navigation Tabs */}\n <nav className=\"bg-muted flex gap-1 rounded-lg p-1\" role=\"tablist\">\n {tabs.map((tab) => (\n <Button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={`flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n <span>{tab.icon}</span>\n {tab.label}\n </Button>\n ))}\n </nav>\n\n {/* Tab Content */}\n <div className=\"min-h-[400px]\" role=\"tabpanel\">\n {activeTab === 'definitions' && (\n <div className=\"border-border rounded-lg border\">\n <table className=\"w-full\">\n <thead className=\"border-border bg-muted/30 border-b\">\n <tr>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Name\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Type\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Status\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Created\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-border divide-y\">\n {definitions.map((def) => (\n <tr key={def.id} className=\"hover:bg-muted/50\">\n <td className=\"px-4 py-3\">\n <div className=\"font-medium\">{def.name}</div>\n <div className=\"text-muted-foreground text-sm\">\n {def.description}\n </div>\n </td>\n <td className=\"px-4 py-3 font-mono text-sm\">{def.type}</td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[def.status] ?? ''}`}\n >\n {def.status}\n </span>\n </td>\n <td className=\"text-muted-foreground px-4 py-3 text-sm\">\n {def.createdAt.toLocaleDateString()}\n </td>\n </tr>\n ))}\n {definitions.length === 0 && (\n <tr>\n <td\n colSpan={4}\n className=\"text-muted-foreground px-4 py-8 text-center\"\n >\n No workflow definitions found\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n )}\n\n {activeTab === 'instances' && (\n <div className=\"border-border rounded-lg border\">\n <table className=\"w-full\">\n <thead className=\"border-border bg-muted/30 border-b\">\n <tr>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Instance ID\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Status\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Requested By\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Started\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-border divide-y\">\n {instances.map((inst) => (\n <tr key={inst.id} className=\"hover:bg-muted/50\">\n <td className=\"px-4 py-3 font-mono text-sm\">{inst.id}</td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[inst.status] ?? ''}`}\n >\n {inst.status}\n </span>\n </td>\n <td className=\"px-4 py-3 text-sm\">{inst.requestedBy}</td>\n <td className=\"text-muted-foreground px-4 py-3 text-sm\">\n {inst.startedAt.toLocaleDateString()}\n </td>\n </tr>\n ))}\n {instances.length === 0 && (\n <tr>\n <td\n colSpan={4}\n className=\"text-muted-foreground px-4 py-8 text-center\"\n >\n No workflow instances found\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { WorkflowStats, useWorkflowList } from "./useWorkflowList.js";
2
+ export { type WorkflowStats, useWorkflowList };
@@ -0,0 +1,5 @@
1
+ 'use client';
2
+
3
+ import { useWorkflowList } from "./useWorkflowList.js";
4
+
5
+ export { useWorkflowList };
@@ -0,0 +1,22 @@
1
+ import { WorkflowDefinition, WorkflowInstance } from "../../handlers/workflow.handlers.js";
2
+
3
+ //#region src/ui/hooks/useWorkflowList.d.ts
4
+ interface WorkflowStats {
5
+ totalDefinitions: number;
6
+ activeDefinitions: number;
7
+ totalInstances: number;
8
+ pendingInstances: number;
9
+ completedInstances: number;
10
+ rejectedInstances: number;
11
+ }
12
+ declare function useWorkflowList(projectId?: string): {
13
+ definitions: WorkflowDefinition[];
14
+ instances: WorkflowInstance[];
15
+ loading: boolean;
16
+ error: Error | null;
17
+ stats: WorkflowStats;
18
+ refetch: () => Promise<void>;
19
+ };
20
+ //#endregion
21
+ export { WorkflowStats, useWorkflowList };
22
+ //# sourceMappingURL=useWorkflowList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWorkflowList.d.ts","names":[],"sources":["../../../src/ui/hooks/useWorkflowList.ts"],"sourcesContent":[],"mappings":";;;UAUiB,aAAA;;EAAA,iBAAa,EAAA,MAAA;EASd,cAAA,EAAA,MAAe;;;;;iBAAf,eAAA"}
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
5
+
6
+ //#region src/ui/hooks/useWorkflowList.ts
7
+ function useWorkflowList(projectId = "local-project") {
8
+ const { handlers } = useTemplateRuntime();
9
+ const workflow = handlers.workflow;
10
+ const [definitions, setDefinitions] = useState([]);
11
+ const [instances, setInstances] = useState([]);
12
+ const [loading, setLoading] = useState(true);
13
+ const [error, setError] = useState(null);
14
+ const fetchData = useCallback(async () => {
15
+ try {
16
+ setLoading(true);
17
+ setError(null);
18
+ const [defResult, instResult] = await Promise.all([workflow.listDefinitions({
19
+ projectId,
20
+ limit: 100
21
+ }), workflow.listInstances({
22
+ projectId,
23
+ limit: 100
24
+ })]);
25
+ setDefinitions(defResult.definitions);
26
+ setInstances(instResult.instances);
27
+ } catch (err) {
28
+ setError(err instanceof Error ? err : /* @__PURE__ */ new Error("Failed to load workflows"));
29
+ } finally {
30
+ setLoading(false);
31
+ }
32
+ }, [handlers, projectId]);
33
+ useEffect(() => {
34
+ fetchData();
35
+ }, [fetchData]);
36
+ return {
37
+ definitions,
38
+ instances,
39
+ loading,
40
+ error,
41
+ stats: {
42
+ totalDefinitions: definitions.length,
43
+ activeDefinitions: definitions.filter((d) => d.status === "ACTIVE").length,
44
+ totalInstances: instances.length,
45
+ pendingInstances: instances.filter((i) => i.status === "PENDING").length,
46
+ completedInstances: instances.filter((i) => i.status === "COMPLETED").length,
47
+ rejectedInstances: instances.filter((i) => i.status === "REJECTED").length
48
+ },
49
+ refetch: fetchData
50
+ };
51
+ }
52
+
53
+ //#endregion
54
+ export { useWorkflowList };
55
+ //# sourceMappingURL=useWorkflowList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWorkflowList.js","names":[],"sources":["../../../src/ui/hooks/useWorkflowList.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport type {\n WorkflowDefinition,\n WorkflowInstance,\n WorkflowHandlers,\n} from '../../handlers/workflow.handlers';\nimport { useTemplateRuntime } from '@contractspec/lib.example-shared-ui';\n\nexport interface WorkflowStats {\n totalDefinitions: number;\n activeDefinitions: number;\n totalInstances: number;\n pendingInstances: number;\n completedInstances: number;\n rejectedInstances: number;\n}\n\nexport function useWorkflowList(projectId = 'local-project') {\n const { handlers } = useTemplateRuntime<{ workflow: WorkflowHandlers }>();\n const workflow = handlers.workflow;\n const [definitions, setDefinitions] = useState<WorkflowDefinition[]>([]);\n const [instances, setInstances] = useState<WorkflowInstance[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n try {\n setLoading(true);\n setError(null);\n\n const [defResult, instResult] = await Promise.all([\n workflow.listDefinitions({ projectId, limit: 100 }),\n workflow.listInstances({ projectId, limit: 100 }),\n ]);\n\n setDefinitions(defResult.definitions);\n setInstances(instResult.instances);\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error('Failed to load workflows')\n );\n } finally {\n setLoading(false);\n }\n }, [handlers, projectId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n const stats: WorkflowStats = {\n totalDefinitions: definitions.length,\n activeDefinitions: definitions.filter((d) => d.status === 'ACTIVE').length,\n totalInstances: instances.length,\n pendingInstances: instances.filter((i) => i.status === 'PENDING').length,\n completedInstances: instances.filter((i) => i.status === 'COMPLETED')\n .length,\n rejectedInstances: instances.filter((i) => i.status === 'REJECTED').length,\n };\n\n return {\n definitions,\n instances,\n loading,\n error,\n stats,\n refetch: fetchData,\n };\n}\n"],"mappings":";;;;;;AAmBA,SAAgB,gBAAgB,YAAY,iBAAiB;CAC3D,MAAM,EAAE,aAAa,oBAAoD;CACzE,MAAM,WAAW,SAAS;CAC1B,MAAM,CAAC,aAAa,kBAAkB,SAA+B,EAAE,CAAC;CACxE,MAAM,CAAC,WAAW,gBAAgB,SAA6B,EAAE,CAAC;CAClE,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,CAAC,OAAO,YAAY,SAAuB,KAAK;CAEtD,MAAM,YAAY,YAAY,YAAY;AACxC,MAAI;AACF,cAAW,KAAK;AAChB,YAAS,KAAK;GAEd,MAAM,CAAC,WAAW,cAAc,MAAM,QAAQ,IAAI,CAChD,SAAS,gBAAgB;IAAE;IAAW,OAAO;IAAK,CAAC,EACnD,SAAS,cAAc;IAAE;IAAW,OAAO;IAAK,CAAC,CAClD,CAAC;AAEF,kBAAe,UAAU,YAAY;AACrC,gBAAa,WAAW,UAAU;WAC3B,KAAK;AACZ,YACE,eAAe,QAAQ,sBAAM,IAAI,MAAM,2BAA2B,CACnE;YACO;AACR,cAAW,MAAM;;IAElB,CAAC,UAAU,UAAU,CAAC;AAEzB,iBAAgB;AACd,aAAW;IACV,CAAC,UAAU,CAAC;AAYf,QAAO;EACL;EACA;EACA;EACA;EACA,OAf2B;GAC3B,kBAAkB,YAAY;GAC9B,mBAAmB,YAAY,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC;GACpE,gBAAgB,UAAU;GAC1B,kBAAkB,UAAU,QAAQ,MAAM,EAAE,WAAW,UAAU,CAAC;GAClE,oBAAoB,UAAU,QAAQ,MAAM,EAAE,WAAW,YAAY,CAClE;GACH,mBAAmB,UAAU,QAAQ,MAAM,EAAE,WAAW,WAAW,CAAC;GACrE;EAQC,SAAS;EACV"}
@@ -0,0 +1,6 @@
1
+ import { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer } from "./renderers/workflow.markdown.js";
2
+ import "./renderers/index.js";
3
+ import { WorkflowDashboard } from "./WorkflowDashboard.js";
4
+ import { WorkflowStats, useWorkflowList } from "./hooks/useWorkflowList.js";
5
+ import "./hooks/index.js";
6
+ export { WorkflowDashboard, WorkflowStats, useWorkflowList, workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer };
@@ -0,0 +1,6 @@
1
+ import { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer } from "./renderers/workflow.markdown.js";
2
+ import { useWorkflowList } from "./hooks/useWorkflowList.js";
3
+ import { WorkflowDashboard } from "./WorkflowDashboard.js";
4
+ import "./hooks/index.js";
5
+
6
+ export { WorkflowDashboard, useWorkflowList, workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer };
@@ -0,0 +1,2 @@
1
+ import { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer } from "./workflow.markdown.js";
2
+ export { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer };
@@ -0,0 +1,3 @@
1
+ import { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer } from "./workflow.markdown.js";
2
+
3
+ export { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer };
@@ -0,0 +1,28 @@
1
+ import { PresentationRenderer } from "@contractspec/lib.contracts";
2
+
3
+ //#region src/ui/renderers/workflow.markdown.d.ts
4
+
5
+ /**
6
+ * Markdown renderer for Workflow Dashboard
7
+ */
8
+ declare const workflowDashboardMarkdownRenderer: PresentationRenderer<{
9
+ mimeType: string;
10
+ body: string;
11
+ }>;
12
+ /**
13
+ * Markdown renderer for Workflow Definition List
14
+ */
15
+ declare const workflowDefinitionListMarkdownRenderer: PresentationRenderer<{
16
+ mimeType: string;
17
+ body: string;
18
+ }>;
19
+ /**
20
+ * Markdown renderer for Workflow Instance Detail
21
+ */
22
+ declare const workflowInstanceDetailMarkdownRenderer: PresentationRenderer<{
23
+ mimeType: string;
24
+ body: string;
25
+ }>;
26
+ //#endregion
27
+ export { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer };
28
+ //# sourceMappingURL=workflow.markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.markdown.d.ts","names":[],"sources":["../../../src/ui/renderers/workflow.markdown.ts"],"sourcesContent":[],"mappings":";;;;AA+KA;AAmDA;;cAxIa,mCAAmC;;;;;;;cAqFnC,wCAAwC;;;;;;;cAmDxC,wCAAwC"}
@@ -0,0 +1,234 @@
1
+ //#region src/ui/renderers/workflow.markdown.ts
2
+ const mockWorkflowDefinitions = [
3
+ {
4
+ id: "wf-1",
5
+ name: "Purchase Approval",
6
+ type: "APPROVAL",
7
+ steps: [
8
+ {
9
+ id: "s1",
10
+ name: "Manager Review",
11
+ order: 1,
12
+ requiredRoles: ["manager"]
13
+ },
14
+ {
15
+ id: "s2",
16
+ name: "Finance Review",
17
+ order: 2,
18
+ requiredRoles: ["finance"]
19
+ },
20
+ {
21
+ id: "s3",
22
+ name: "Final Approval",
23
+ order: 3,
24
+ requiredRoles: ["admin"]
25
+ }
26
+ ],
27
+ status: "ACTIVE"
28
+ },
29
+ {
30
+ id: "wf-2",
31
+ name: "Leave Request",
32
+ type: "APPROVAL",
33
+ steps: [{
34
+ id: "s1",
35
+ name: "Supervisor Approval",
36
+ order: 1,
37
+ requiredRoles: ["supervisor"]
38
+ }, {
39
+ id: "s2",
40
+ name: "HR Review",
41
+ order: 2,
42
+ requiredRoles: ["hr"]
43
+ }],
44
+ status: "ACTIVE"
45
+ },
46
+ {
47
+ id: "wf-3",
48
+ name: "Document Review",
49
+ type: "SEQUENTIAL",
50
+ steps: [
51
+ {
52
+ id: "s1",
53
+ name: "Author Review",
54
+ order: 1,
55
+ requiredRoles: ["author"]
56
+ },
57
+ {
58
+ id: "s2",
59
+ name: "Peer Review",
60
+ order: 2,
61
+ requiredRoles: ["reviewer"]
62
+ },
63
+ {
64
+ id: "s3",
65
+ name: "Publish",
66
+ order: 3,
67
+ requiredRoles: ["publisher"]
68
+ }
69
+ ],
70
+ status: "DRAFT"
71
+ }
72
+ ];
73
+ const mockWorkflowInstances = [
74
+ {
75
+ id: "inst-1",
76
+ definitionId: "wf-1",
77
+ definitionName: "Purchase Approval",
78
+ status: "IN_PROGRESS",
79
+ currentStepId: "s2",
80
+ startedAt: "2024-01-15T10:00:00Z",
81
+ requestedBy: "John Doe"
82
+ },
83
+ {
84
+ id: "inst-2",
85
+ definitionId: "wf-1",
86
+ definitionName: "Purchase Approval",
87
+ status: "COMPLETED",
88
+ currentStepId: null,
89
+ startedAt: "2024-01-10T09:00:00Z",
90
+ completedAt: "2024-01-12T14:00:00Z",
91
+ requestedBy: "Jane Smith"
92
+ },
93
+ {
94
+ id: "inst-3",
95
+ definitionId: "wf-2",
96
+ definitionName: "Leave Request",
97
+ status: "PENDING",
98
+ currentStepId: "s1",
99
+ startedAt: "2024-01-16T08:00:00Z",
100
+ requestedBy: "Bob Wilson"
101
+ }
102
+ ];
103
+ /**
104
+ * Markdown renderer for Workflow Dashboard
105
+ */
106
+ const workflowDashboardMarkdownRenderer = {
107
+ target: "markdown",
108
+ render: async (desc) => {
109
+ if (desc.source.type !== "component" || desc.source.componentKey !== "WorkflowDashboard") throw new Error("workflowDashboardMarkdownRenderer: not WorkflowDashboard");
110
+ const definitions = mockWorkflowDefinitions;
111
+ const instances = mockWorkflowInstances;
112
+ const activeDefinitions = definitions.filter((d) => d.status === "ACTIVE");
113
+ const pendingInstances = instances.filter((i) => i.status === "PENDING");
114
+ const inProgressInstances = instances.filter((i) => i.status === "IN_PROGRESS");
115
+ const completedInstances = instances.filter((i) => i.status === "COMPLETED");
116
+ const lines = [
117
+ "# Workflow Dashboard",
118
+ "",
119
+ "> Workflow and approval management overview",
120
+ "",
121
+ "## Summary",
122
+ "",
123
+ "| Metric | Value |",
124
+ "|--------|-------|",
125
+ `| Active Workflows | ${activeDefinitions.length} |`,
126
+ `| Pending Approvals | ${pendingInstances.length} |`,
127
+ `| In Progress | ${inProgressInstances.length} |`,
128
+ `| Completed | ${completedInstances.length} |`,
129
+ "",
130
+ "## Active Workflow Definitions",
131
+ ""
132
+ ];
133
+ if (activeDefinitions.length === 0) lines.push("_No active workflow definitions._");
134
+ else {
135
+ lines.push("| Name | Type | Steps | Status |");
136
+ lines.push("|------|------|-------|--------|");
137
+ for (const def of activeDefinitions) lines.push(`| ${def.name} | ${def.type} | ${def.steps.length} | ${def.status} |`);
138
+ }
139
+ lines.push("");
140
+ lines.push("## Recent Instances");
141
+ lines.push("");
142
+ if (instances.length === 0) lines.push("_No workflow instances._");
143
+ else {
144
+ lines.push("| Workflow | Requested By | Status | Started |");
145
+ lines.push("|----------|--------------|--------|---------|");
146
+ for (const inst of instances.slice(0, 10)) {
147
+ const startedDate = new Date(inst.startedAt).toLocaleDateString();
148
+ lines.push(`| ${inst.definitionName} | ${inst.requestedBy} | ${inst.status} | ${startedDate} |`);
149
+ }
150
+ }
151
+ return {
152
+ mimeType: "text/markdown",
153
+ body: lines.join("\n")
154
+ };
155
+ }
156
+ };
157
+ /**
158
+ * Markdown renderer for Workflow Definition List
159
+ */
160
+ const workflowDefinitionListMarkdownRenderer = {
161
+ target: "markdown",
162
+ render: async (desc) => {
163
+ if (desc.source.type !== "component" || desc.source.componentKey !== "WorkflowDefinitionList") throw new Error("workflowDefinitionListMarkdownRenderer: not WorkflowDefinitionList");
164
+ const definitions = mockWorkflowDefinitions;
165
+ const lines = [
166
+ "# Workflow Definitions",
167
+ "",
168
+ "> Configure automated approval and process workflows",
169
+ ""
170
+ ];
171
+ for (const def of definitions) {
172
+ lines.push(`## ${def.name}`);
173
+ lines.push("");
174
+ lines.push(`**Type:** ${def.type} | **Status:** ${def.status}`);
175
+ lines.push("");
176
+ lines.push("### Steps");
177
+ lines.push("");
178
+ for (const step of def.steps) lines.push(`${step.order}. **${step.name}** - Roles: ${step.requiredRoles.join(", ")}`);
179
+ lines.push("");
180
+ }
181
+ return {
182
+ mimeType: "text/markdown",
183
+ body: lines.join("\n")
184
+ };
185
+ }
186
+ };
187
+ /**
188
+ * Markdown renderer for Workflow Instance Detail
189
+ */
190
+ const workflowInstanceDetailMarkdownRenderer = {
191
+ target: "markdown",
192
+ render: async (desc) => {
193
+ if (desc.source.type !== "component" || desc.source.componentKey !== "WorkflowInstanceDetail") throw new Error("workflowInstanceDetailMarkdownRenderer: not WorkflowInstanceDetail");
194
+ const instance = mockWorkflowInstances[0];
195
+ if (!instance) return {
196
+ mimeType: "text/markdown",
197
+ body: "# No Workflow Instances\n\nNo workflow instances available."
198
+ };
199
+ const definition = mockWorkflowDefinitions.find((d) => d.id === instance.definitionId);
200
+ const lines = [
201
+ `# Workflow: ${instance.definitionName}`,
202
+ "",
203
+ `**Instance ID:** ${instance.id}`,
204
+ `**Status:** ${instance.status}`,
205
+ `**Requested By:** ${instance.requestedBy}`,
206
+ `**Started:** ${new Date(instance.startedAt).toLocaleString()}`,
207
+ "",
208
+ "## Steps Progress",
209
+ ""
210
+ ];
211
+ if (definition) for (const step of definition.steps) {
212
+ const isCurrent = step.id === instance.currentStepId;
213
+ const isCompleted = definition.steps.indexOf(step) < definition.steps.findIndex((s) => s.id === instance.currentStepId);
214
+ let status = "⬜ Pending";
215
+ if (isCompleted) status = "✅ Completed";
216
+ if (isCurrent) status = "🔄 In Progress";
217
+ lines.push(`- ${status} **${step.name}**`);
218
+ }
219
+ lines.push("");
220
+ lines.push("## Actions");
221
+ lines.push("");
222
+ lines.push("- **Approve** - Move to next step");
223
+ lines.push("- **Reject** - Reject and return");
224
+ lines.push("- **Delegate** - Assign to another approver");
225
+ return {
226
+ mimeType: "text/markdown",
227
+ body: lines.join("\n")
228
+ };
229
+ }
230
+ };
231
+
232
+ //#endregion
233
+ export { workflowDashboardMarkdownRenderer, workflowDefinitionListMarkdownRenderer, workflowInstanceDetailMarkdownRenderer };
234
+ //# sourceMappingURL=workflow.markdown.js.map