@burdenoff/microfe-workflows 2026.923.4 → 2026.1014.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 +55 -77
- package/dist/WorkflowsRoot.js +1 -1
- package/dist/providers/WorkflowsProvider.js +98 -81
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,88 +1,66 @@
|
|
|
1
|
-
# @burdenoff/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
# @burdenoff/microfe-workflows
|
|
2
|
+
|
|
3
|
+
Shared Layer 2 workflow UI for Fluidgrids and product shells. This package hosts
|
|
4
|
+
`@burdenoff/fluidgrids-fe-sdk`; product MFEs must not initialize a parallel SDK.
|
|
5
|
+
|
|
6
|
+
## Host integration
|
|
7
|
+
|
|
8
|
+
Mount inside the shell's gateway providers, router and permission context. The
|
|
9
|
+
shell supplies both workspace and global gateway clients. Wait until workspace
|
|
10
|
+
selection has issued a workspace JWT before mounting:
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { WorkflowsRoot } from '@burdenoff/microfe-workflows';
|
|
14
|
+
|
|
15
|
+
return workspaceId && workspaceToken ? (
|
|
16
|
+
<WorkflowsRoot
|
|
17
|
+
basePath="/myproduct/workflows"
|
|
18
|
+
navigate={navigate}
|
|
19
|
+
currentUser={user}
|
|
20
|
+
productId="myproduct"
|
|
21
|
+
productName="My Product"
|
|
22
|
+
workspaceId={workspaceId}
|
|
23
|
+
workspaceToken={workspaceToken}
|
|
24
|
+
tenantId={tenantId}
|
|
25
|
+
apiGatewayUrl={workspaceGatewayUrl}
|
|
26
|
+
authToken={authToken}
|
|
27
|
+
/>
|
|
28
|
+
) : <div role="status">Loading your workspace…</div>;
|
|
16
29
|
```
|
|
17
30
|
|
|
18
|
-
|
|
31
|
+
`workspaceToken` is required. Upgrading hosts must pass it explicitly and gate
|
|
32
|
+
mounting until it is available; `authToken` alone cannot authorize workspace
|
|
33
|
+
operations. The shell client sends both `Authorization` and
|
|
34
|
+
`X-Workspace-Authorization`. Product selection narrows access; the gateway
|
|
35
|
+
still enforces authentication, product access and RBAC.
|
|
19
36
|
|
|
20
|
-
|
|
21
|
-
|
|
37
|
+
Pin the same SDK version in the shell as this package's peer dependency. Include
|
|
38
|
+
this package's published files in Tailwind's source scan. Do not use local source
|
|
39
|
+
aliases to validate a production package build.
|
|
22
40
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
currentUser={user}
|
|
28
|
-
workspaceId={workspaceId}
|
|
29
|
-
apiGatewayUrl={apiGatewayUrl}
|
|
30
|
-
authToken={authToken}
|
|
31
|
-
/>
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Development
|
|
41
|
+
The provider initializes configuration before the node palette. Gateway, tenant,
|
|
42
|
+
workspace, product or user changes end the execution session and clear old
|
|
43
|
+
selections and local run state. Token and callback refreshes preserve the current
|
|
44
|
+
view. Mount one workflow host at a time.
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
# Install dependencies
|
|
38
|
-
bun install
|
|
46
|
+
## Routes
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
bun run codegen
|
|
48
|
+
Routes are relative to `basePath`:
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
- `list`: workflow definitions
|
|
51
|
+
- `new`: new workflow builder
|
|
52
|
+
- `workflow/:id/:version`: existing workflow builder
|
|
53
|
+
- `runs` and `runs/:runId`: current user's product-scoped runs
|
|
54
|
+
- `insights`, `templates`, `nodes`, `settings`: shared SDK pages
|
|
45
55
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# Run all checks
|
|
50
|
-
bun run sanity
|
|
51
|
-
```
|
|
56
|
+
Product-specific bot or application bindings use the workspace gateway and
|
|
57
|
+
navigate to these routes; they do not own SDK configuration.
|
|
52
58
|
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
Complete workflow automation microfrontend with:
|
|
56
|
-
|
|
57
|
-
- **WorkflowsList** - List all workflows
|
|
58
|
-
- **WorkflowBuilder** - Visual workflow builder with node palette
|
|
59
|
-
- **WorkflowRuns** - Execution history
|
|
60
|
-
- **WorkflowRunDetails** - Detailed run monitoring
|
|
61
|
-
|
|
62
|
-
### Routes
|
|
63
|
-
|
|
64
|
-
- `/` - Workflows list
|
|
65
|
-
- `/builder/:workflowKey?` - Workflow builder (create/edit)
|
|
66
|
-
- `/runs` - Workflow runs history
|
|
67
|
-
- `/runs/:runId` - Run details
|
|
68
|
-
|
|
69
|
-
## GraphQL Integration
|
|
70
|
-
|
|
71
|
-
Uses GraphQL Codegen to generate typed hooks from operations:
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
import { useGetWorkflowDefinitionsQuery } from './graphql/generated/operations';
|
|
75
|
-
|
|
76
|
-
const { data, loading } = useGetWorkflowDefinitionsQuery({
|
|
77
|
-
variables: { input: { limit: 10 } }
|
|
78
|
-
});
|
|
79
|
-
```
|
|
59
|
+
## Development
|
|
80
60
|
|
|
81
|
-
|
|
61
|
+
Run `bun install` and `bun run sanity` to validate lint, formatting, types and the
|
|
62
|
+
published library build. GraphQL operations are owned by the SDK; this wrapper
|
|
63
|
+
has no separate generated operation layer.
|
|
82
64
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- Apollo Client for GraphQL
|
|
86
|
-
- Zustand for state management
|
|
87
|
-
- @burdenoff/fe-libs for UI primitives
|
|
88
|
-
- TailwindCSS v4 for styling
|
|
65
|
+
The complete reusable guide is in the dev repository:
|
|
66
|
+
`platform/context/automation/fluidgrids/HOW_TO_INTEGRATE_FLUIDGRIDS.md`.
|
package/dist/WorkflowsRoot.js
CHANGED
|
@@ -130,7 +130,7 @@ function C(C) {
|
|
|
130
130
|
children: /* @__PURE__ */ x(t, {
|
|
131
131
|
...C,
|
|
132
132
|
children: /* @__PURE__ */ x(n, {})
|
|
133
|
-
})
|
|
133
|
+
}, `${C.apiGatewayUrl ?? ""}:${C.tenantId ?? ""}:${C.workspaceId ?? ""}:${C.productId ?? ""}:${C.currentUser?.id ?? ""}`)
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
136
|
//#endregion
|
|
@@ -1,85 +1,102 @@
|
|
|
1
1
|
import { setWorkflowsConfig as e } from "../config/index.js";
|
|
2
2
|
import { useWorkflowsTranslation as t } from "../i18n.js";
|
|
3
|
-
import { createContext as n, useEffect as r, useState as i } from "react";
|
|
4
|
-
import { EmphasisPanel as
|
|
5
|
-
import { Boxes as
|
|
6
|
-
import { FluidGridsPermissionsProvider as
|
|
7
|
-
import { useGatewayClient as
|
|
8
|
-
import { PermissionProvider as
|
|
9
|
-
import { jsx as
|
|
3
|
+
import { createContext as n, useEffect as r, useState as i, useSyncExternalStore as a } from "react";
|
|
4
|
+
import { EmphasisPanel as o, GlassCard as s, IllustratedEmptyState as c, NextSteps as l, PagePurpose as u } from "@burdenoff/fe-libs/ui";
|
|
5
|
+
import { Boxes as d, LayoutDashboard as f, Workflow as p } from "lucide-react";
|
|
6
|
+
import { FluidGridsPermissionsProvider as m, FluidGridsTranslationProvider as h, refetchStoreNodes as g, resetFluidGridsClient as _, resetFluidGridsConfig as v, resetFluidGridsExecutionState as y, resetGlobalStoreClient as b, setFluidGridsClient as x, setFluidGridsConfig as S, setGlobalStoreClient as C } from "@burdenoff/fluidgrids-fe-sdk";
|
|
7
|
+
import { useGatewayClient as w } from "@burdenoff/fe-libs/shared/graphql";
|
|
8
|
+
import { PermissionProvider as T, usePermissions as E } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
9
|
+
import { jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
10
10
|
//#region src/providers/WorkflowsProvider.tsx
|
|
11
|
-
var
|
|
12
|
-
function
|
|
13
|
-
let { hasPermission: t, isLoading: n } =
|
|
14
|
-
return /* @__PURE__ */
|
|
11
|
+
var k = n(null);
|
|
12
|
+
function A({ children: e }) {
|
|
13
|
+
let { hasPermission: t, isLoading: n } = E();
|
|
14
|
+
return /* @__PURE__ */ D(m, {
|
|
15
15
|
hasPermission: t,
|
|
16
16
|
isLoading: n,
|
|
17
17
|
children: e
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function j(e) {
|
|
21
21
|
let t = e.endsWith("/") ? e.slice(0, -1) : e;
|
|
22
22
|
return t.endsWith("/graphql") ? t : `${t}/workspaces/graphql`;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
let
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
e
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
24
|
+
function M({ children: n, ...m }) {
|
|
25
|
+
let E = t(), M = w("workspace"), N = w("global"), [P] = i(() => {
|
|
26
|
+
let e = !1, t = /* @__PURE__ */ new Set();
|
|
27
|
+
return {
|
|
28
|
+
subscribe: (e) => (t.add(e), () => {
|
|
29
|
+
t.delete(e);
|
|
30
|
+
}),
|
|
31
|
+
snapshot: () => e,
|
|
32
|
+
set: (n) => {
|
|
33
|
+
e = n;
|
|
34
|
+
for (let e of t) e();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}), F = a(P.subscribe, P.snapshot, () => !1);
|
|
38
|
+
if (r(() => (y(), y), []), r(() => {
|
|
39
|
+
if (!m.apiGatewayUrl || !m.productId || !m.workspaceId || !m.workspaceToken || !M || !N) return;
|
|
40
|
+
let t = m.apiGatewayUrl.replace(/\/+$/, "");
|
|
41
|
+
e({
|
|
42
|
+
workflowSvcUrl: j(t),
|
|
43
|
+
apiGatewayUrl: t
|
|
44
|
+
});
|
|
45
|
+
let n = m.callbacks?.onWorkflowSaved;
|
|
46
|
+
return S({
|
|
47
|
+
apiGatewayUrl: t,
|
|
48
|
+
authToken: m.authToken,
|
|
49
|
+
workspaceId: m.workspaceId,
|
|
50
|
+
tenantId: m.tenantId,
|
|
51
|
+
productId: m.productId,
|
|
52
|
+
productName: m.productName,
|
|
53
|
+
onWorkflowSaved: n
|
|
54
|
+
}), x(M), C(N), g().catch((e) => {
|
|
55
|
+
console.warn("[Workflows] Could not refresh installed nodes", e);
|
|
56
|
+
}), P.set(!0), () => {
|
|
57
|
+
P.set(!1), _(), b(), v();
|
|
58
|
+
};
|
|
46
59
|
}, [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
P,
|
|
61
|
+
M,
|
|
62
|
+
N,
|
|
63
|
+
m.apiGatewayUrl,
|
|
64
|
+
m.authToken,
|
|
65
|
+
m.workspaceToken,
|
|
66
|
+
m.workspaceId,
|
|
67
|
+
m.tenantId,
|
|
68
|
+
m.productId,
|
|
69
|
+
m.productName,
|
|
70
|
+
m.callbacks
|
|
71
|
+
]), !m.workspaceId) {
|
|
72
|
+
let e = (e, t) => `${e.endsWith("/") ? e.slice(0, -1) : e}/${t}`, t = (t) => m.navigate(e(m.basePath ?? "/", t));
|
|
73
|
+
return /* @__PURE__ */ O("div", {
|
|
57
74
|
className: "mx-auto flex h-full min-h-[60vh] w-full max-w-2xl flex-col justify-center gap-6 px-4 py-10",
|
|
58
75
|
children: [
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
-
icon: /* @__PURE__ */
|
|
76
|
+
/* @__PURE__ */ D(u, {
|
|
77
|
+
icon: /* @__PURE__ */ D(p, {
|
|
61
78
|
className: "size-4",
|
|
62
79
|
"aria-hidden": "true"
|
|
63
80
|
}),
|
|
64
|
-
children:
|
|
81
|
+
children: E("workflows.provider.purpose", "Workflows let you automate multi-step processes — for example, sync a new signup into your CRM, post run results to Slack, or transform and route data between apps. You build them visually by wiring nodes together, then trigger them on a schedule, a webhook, or on demand.")
|
|
65
82
|
}),
|
|
66
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ D(o, {
|
|
67
84
|
className: "p-6",
|
|
68
|
-
children: /* @__PURE__ */
|
|
85
|
+
children: /* @__PURE__ */ D(c, {
|
|
69
86
|
illustration: "onboarding",
|
|
70
|
-
title:
|
|
71
|
-
description:
|
|
87
|
+
title: E("workflows.provider.workspaceRequired.title", "Pick a workspace to start building"),
|
|
88
|
+
description: E("workflows.provider.workspaceRequired.description", "Workflows live inside a workspace so your automations, runs, and connections stay scoped to the right team. Select or create an active workspace from the shell to load your workflows.")
|
|
72
89
|
})
|
|
73
90
|
}),
|
|
74
|
-
/* @__PURE__ */
|
|
91
|
+
/* @__PURE__ */ D(l, {
|
|
75
92
|
storageKey: "workflows-get-started",
|
|
76
|
-
title:
|
|
93
|
+
title: E("workflows.provider.nextSteps.title", "Once your workspace is active"),
|
|
77
94
|
steps: [
|
|
78
95
|
{
|
|
79
96
|
id: "open-workflows",
|
|
80
|
-
label:
|
|
81
|
-
description:
|
|
82
|
-
icon: /* @__PURE__ */
|
|
97
|
+
label: E("workflows.provider.nextSteps.open.label", "Open your workflows"),
|
|
98
|
+
description: E("workflows.provider.nextSteps.open.description", "Browse, search, and manage every automation in this workspace."),
|
|
99
|
+
icon: /* @__PURE__ */ D(p, {
|
|
83
100
|
className: "size-4",
|
|
84
101
|
"aria-hidden": "true"
|
|
85
102
|
}),
|
|
@@ -87,9 +104,9 @@ function k({ children: n, ...p }) {
|
|
|
87
104
|
},
|
|
88
105
|
{
|
|
89
106
|
id: "start-template",
|
|
90
|
-
label:
|
|
91
|
-
description:
|
|
92
|
-
icon: /* @__PURE__ */
|
|
107
|
+
label: E("workflows.provider.nextSteps.template.label", "Start from a template"),
|
|
108
|
+
description: E("workflows.provider.nextSteps.template.description", "Skip the blank canvas — adapt a ready-made workflow to your use-case."),
|
|
109
|
+
icon: /* @__PURE__ */ D(f, {
|
|
93
110
|
className: "size-4",
|
|
94
111
|
"aria-hidden": "true"
|
|
95
112
|
}),
|
|
@@ -97,9 +114,9 @@ function k({ children: n, ...p }) {
|
|
|
97
114
|
},
|
|
98
115
|
{
|
|
99
116
|
id: "build-new",
|
|
100
|
-
label:
|
|
101
|
-
description:
|
|
102
|
-
icon: /* @__PURE__ */
|
|
117
|
+
label: E("workflows.provider.nextSteps.build.label", "Build a workflow from scratch"),
|
|
118
|
+
description: E("workflows.provider.nextSteps.build.description", "Open the visual builder and wire nodes together step by step."),
|
|
119
|
+
icon: /* @__PURE__ */ D(d, {
|
|
103
120
|
className: "size-4",
|
|
104
121
|
"aria-hidden": "true"
|
|
105
122
|
}),
|
|
@@ -110,35 +127,35 @@ function k({ children: n, ...p }) {
|
|
|
110
127
|
]
|
|
111
128
|
});
|
|
112
129
|
}
|
|
113
|
-
return
|
|
114
|
-
value: p,
|
|
115
|
-
children: /* @__PURE__ */ w(m, {
|
|
116
|
-
t: C,
|
|
117
|
-
children: /* @__PURE__ */ w(S, {
|
|
118
|
-
scopeId: p.workspaceId ?? null,
|
|
119
|
-
gateway: "workspace",
|
|
120
|
-
children: /* @__PURE__ */ w(D, { children: n })
|
|
121
|
-
})
|
|
122
|
-
})
|
|
123
|
-
}) : /* @__PURE__ */ T("div", {
|
|
130
|
+
return !F || !m.workspaceToken || !m.productId ? /* @__PURE__ */ O("div", {
|
|
124
131
|
className: "mx-auto flex h-full min-h-[60vh] w-full max-w-md flex-col items-center justify-center gap-4 px-4 py-10 text-center",
|
|
125
132
|
role: "status",
|
|
126
133
|
"aria-live": "polite",
|
|
127
134
|
"aria-busy": "true",
|
|
128
|
-
"aria-label":
|
|
129
|
-
children: [/* @__PURE__ */
|
|
135
|
+
"aria-label": E("workflows.provider.loading.ariaLabel", "Loading workflows"),
|
|
136
|
+
children: [/* @__PURE__ */ O(s, {
|
|
130
137
|
treatment: "glass",
|
|
131
138
|
className: "flex w-full flex-col items-center gap-4 border-border-seam p-6",
|
|
132
139
|
children: [
|
|
133
|
-
/* @__PURE__ */
|
|
134
|
-
/* @__PURE__ */
|
|
135
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ D("div", { className: "h-12 w-12 rounded-full bg-muted/60 motion-safe:animate-vc-shimmer" }),
|
|
141
|
+
/* @__PURE__ */ D("div", { className: "h-4 w-40 rounded bg-muted/50 motion-safe:animate-vc-shimmer" }),
|
|
142
|
+
/* @__PURE__ */ D("div", { className: "h-3 w-56 max-w-full rounded bg-muted/30 motion-safe:animate-vc-shimmer" })
|
|
136
143
|
]
|
|
137
|
-
}), /* @__PURE__ */
|
|
144
|
+
}), /* @__PURE__ */ D("p", {
|
|
138
145
|
className: "text-sm text-text-secondary",
|
|
139
|
-
children:
|
|
146
|
+
children: E("workflows.provider.loading.message", "Connecting workflows...")
|
|
140
147
|
})]
|
|
148
|
+
}) : /* @__PURE__ */ D(k.Provider, {
|
|
149
|
+
value: m,
|
|
150
|
+
children: /* @__PURE__ */ D(h, {
|
|
151
|
+
t: E,
|
|
152
|
+
children: /* @__PURE__ */ D(T, {
|
|
153
|
+
scopeId: m.workspaceId ?? null,
|
|
154
|
+
gateway: "workspace",
|
|
155
|
+
children: /* @__PURE__ */ D(A, { children: n })
|
|
156
|
+
})
|
|
157
|
+
})
|
|
141
158
|
});
|
|
142
159
|
}
|
|
143
160
|
//#endregion
|
|
144
|
-
export {
|
|
161
|
+
export { M as WorkflowsProvider };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-workflows",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.1014.1",
|
|
4
4
|
"description": "Workflows microfrontend for Burdenoff products - thin shell over @burdenoff/fluidgrids-fe-sdk",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"react-router": "^8.3.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@burdenoff/fluidgrids-fe-sdk": "2026.
|
|
38
|
+
"@burdenoff/fluidgrids-fe-sdk": "2026.1008.3",
|
|
39
39
|
"@eslint/js": "^9.39.2",
|
|
40
40
|
"@types/react": "^19.0.2",
|
|
41
41
|
"@types/react-dom": "^19.0.2",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"vite-plugin-dts": "3.9.1"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@burdenoff/fluidgrids-fe-sdk": "2026.
|
|
58
|
+
"@burdenoff/fluidgrids-fe-sdk": "2026.1008.3",
|
|
59
59
|
"react": "^19.0.0",
|
|
60
60
|
"react-dom": "^19.0.0"
|
|
61
61
|
},
|