nucleus-core-ts 0.8.108 → 0.8.110

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.
@@ -1,15 +1,44 @@
1
1
  import type { ReactElement } from "react";
2
- interface FlowNodeData {
3
- label: string;
4
- description: string;
5
- nodeType: string;
2
+ import type { NotificationChannel } from "../types";
3
+ interface StepNodeDataProps {
4
+ label?: string;
5
+ description?: string;
6
+ nodeType: "step";
6
7
  stepOrder: number;
7
- decision: string;
8
- isActive: boolean;
8
+ selected?: boolean;
9
9
  [key: string]: unknown;
10
10
  }
11
- export declare function FlowNode({ data }: {
12
- data: FlowNodeData;
11
+ interface VerifierNodeDataProps {
12
+ label?: string;
13
+ description?: string;
14
+ nodeType: "verifier";
15
+ stepOrder: number;
16
+ verifierType?: "user" | "role";
17
+ verifierRole?: string;
18
+ verifierUserEmail?: string;
19
+ requireSignature?: boolean;
20
+ allMustApprove?: boolean;
21
+ selected?: boolean;
22
+ [key: string]: unknown;
23
+ }
24
+ interface NotificationNodeDataProps {
25
+ label?: string;
26
+ description?: string;
27
+ nodeType: "notification";
28
+ stepOrder: number;
29
+ trigger?: string;
30
+ channels?: NotificationChannel[];
31
+ selected?: boolean;
32
+ [key: string]: unknown;
33
+ }
34
+ export declare function StepFlowNode({ data, }: {
35
+ data: StepNodeDataProps;
36
+ }): ReactElement;
37
+ export declare function VerifierFlowNode({ data, }: {
38
+ data: VerifierNodeDataProps;
39
+ }): ReactElement;
40
+ export declare function NotificationFlowNode({ data, }: {
41
+ data: NotificationNodeDataProps;
13
42
  }): ReactElement;
14
43
  export {};
15
44
  //# sourceMappingURL=FlowNode.d.ts.map
@@ -1,13 +1,14 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Handle, Position } from "@xyflow/react";
4
- import { cn } from "../../../utils/cn";
5
4
  import { verificationFlowPageTheme } from "../theme";
5
+ // ─── Shared icon components ───────────────────────────────────────
6
6
  const StepIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
7
7
  className: className,
8
8
  fill: "none",
9
9
  viewBox: "0 0 24 24",
10
10
  stroke: "currentColor",
11
+ strokeWidth: 1.5,
11
12
  children: [
12
13
  /*#__PURE__*/ _jsx("title", {
13
14
  children: "Step"
@@ -15,8 +16,7 @@ const StepIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
15
16
  /*#__PURE__*/ _jsx("path", {
16
17
  strokeLinecap: "round",
17
18
  strokeLinejoin: "round",
18
- strokeWidth: 2,
19
- d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
19
+ d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
20
20
  })
21
21
  ]
22
22
  });
@@ -25,6 +25,7 @@ const VerifierIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
25
25
  fill: "none",
26
26
  viewBox: "0 0 24 24",
27
27
  stroke: "currentColor",
28
+ strokeWidth: 1.5,
28
29
  children: [
29
30
  /*#__PURE__*/ _jsx("title", {
30
31
  children: "Verifier"
@@ -32,8 +33,7 @@ const VerifierIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
32
33
  /*#__PURE__*/ _jsx("path", {
33
34
  strokeLinecap: "round",
34
35
  strokeLinejoin: "round",
35
- strokeWidth: 2,
36
- d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
36
+ d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
37
37
  })
38
38
  ]
39
39
  });
@@ -42,6 +42,7 @@ const NotificationIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
42
42
  fill: "none",
43
43
  viewBox: "0 0 24 24",
44
44
  stroke: "currentColor",
45
+ strokeWidth: 1.5,
45
46
  children: [
46
47
  /*#__PURE__*/ _jsx("title", {
47
48
  children: "Notification"
@@ -49,62 +50,167 @@ const NotificationIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
49
50
  /*#__PURE__*/ _jsx("path", {
50
51
  strokeLinecap: "round",
51
52
  strokeLinejoin: "round",
52
- strokeWidth: 2,
53
- d: "M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
53
+ d: "M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"
54
54
  })
55
55
  ]
56
56
  });
57
- const iconMap = {
58
- step: StepIcon,
59
- verifier: VerifierIcon,
60
- notification: NotificationIcon
61
- };
62
- export function FlowNode({ data }) {
63
- const theme = verificationFlowPageTheme;
64
- const nodeType = data.nodeType || "step";
65
- const colorKey = nodeType;
66
- const colors = colorKey in theme.node ? theme.node[colorKey] : theme.node.step;
67
- const decision = data.decision;
68
- const isActive = data.isActive;
69
- const Icon = iconMap[nodeType] || StepIcon;
70
- const badgeKey = decision || (isActive ? "active" : "");
71
- const badgeClass = badgeKey in theme.node.badge ? theme.node.badge[badgeKey] : "";
57
+ // ─── Step Node ────────────────────────────────────────────────────
58
+ export function StepFlowNode({ data }) {
59
+ const theme = verificationFlowPageTheme.stepNode;
60
+ const isSelected = data.selected === true;
72
61
  return /*#__PURE__*/ _jsxs("div", {
73
- className: cn(theme.node.base, colors.border, colors.bg, isActive && !decision ? theme.node.activeRing : ""),
62
+ className: isSelected ? theme.containerSelected : theme.container,
74
63
  children: [
75
64
  /*#__PURE__*/ _jsx(Handle, {
76
65
  type: "target",
77
- position: Position.Top,
78
- className: theme.node.handle
66
+ position: Position.Left,
67
+ className: theme.handleTarget
68
+ }),
69
+ data.stepOrder > 0 && /*#__PURE__*/ _jsx("span", {
70
+ className: theme.orderBadge,
71
+ children: data.stepOrder
79
72
  }),
80
73
  /*#__PURE__*/ _jsxs("div", {
81
- className: "flex items-center gap-2 mb-1",
74
+ className: "flex items-center gap-2",
82
75
  children: [
83
- /*#__PURE__*/ _jsx(Icon, {
84
- className: cn("w-4 h-4", colors.icon)
76
+ /*#__PURE__*/ _jsx(StepIcon, {
77
+ className: `w-4 h-4 ${theme.icon}`
85
78
  }),
86
79
  /*#__PURE__*/ _jsx("span", {
87
- className: theme.node.typeLabel,
88
- children: nodeType
89
- }),
90
- badgeClass && /*#__PURE__*/ _jsx("span", {
91
- className: cn("ml-auto text-[10px] font-bold px-1.5 py-0.5 rounded-full", badgeClass),
92
- children: decision || "active"
80
+ className: theme.typeLabel,
81
+ children: "Step"
93
82
  })
94
83
  ]
95
84
  }),
96
85
  /*#__PURE__*/ _jsx("p", {
97
- className: theme.node.nameLabel,
86
+ className: theme.nameLabel,
98
87
  children: data.label || `Step ${data.stepOrder}`
99
88
  }),
100
89
  data.description ? /*#__PURE__*/ _jsx("p", {
101
- className: theme.node.description,
90
+ className: theme.description,
91
+ children: String(data.description)
92
+ }) : null,
93
+ /*#__PURE__*/ _jsx(Handle, {
94
+ type: "source",
95
+ position: Position.Right,
96
+ className: theme.handleSource
97
+ })
98
+ ]
99
+ });
100
+ }
101
+ // ─── Verifier Node ────────────────────────────────────────────────
102
+ export function VerifierFlowNode({ data }) {
103
+ const theme = verificationFlowPageTheme.verifierNode;
104
+ const isSelected = data.selected === true;
105
+ const assignedLabel = data.verifierType === "role" ? data.verifierRole || "No role" : data.verifierUserEmail || "No user";
106
+ return /*#__PURE__*/ _jsxs("div", {
107
+ className: isSelected ? theme.containerSelected : theme.container,
108
+ children: [
109
+ /*#__PURE__*/ _jsx(Handle, {
110
+ type: "target",
111
+ position: Position.Left,
112
+ className: theme.handleTarget
113
+ }),
114
+ /*#__PURE__*/ _jsxs("div", {
115
+ className: "flex items-center gap-2",
116
+ children: [
117
+ /*#__PURE__*/ _jsx(VerifierIcon, {
118
+ className: `w-4 h-4 ${theme.icon}`
119
+ }),
120
+ /*#__PURE__*/ _jsx("span", {
121
+ className: theme.typeLabel,
122
+ children: "Verifier"
123
+ })
124
+ ]
125
+ }),
126
+ /*#__PURE__*/ _jsx("p", {
127
+ className: theme.nameLabel,
128
+ children: data.label || "Verifier"
129
+ }),
130
+ data.description ? /*#__PURE__*/ _jsx("p", {
131
+ className: theme.description,
102
132
  children: String(data.description)
103
133
  }) : null,
134
+ /*#__PURE__*/ _jsxs("div", {
135
+ className: "flex flex-wrap gap-1.5 mt-2",
136
+ children: [
137
+ /*#__PURE__*/ _jsxs("span", {
138
+ className: theme.assignedBadge,
139
+ children: [
140
+ data.verifierType === "role" ? "⛊" : "⚇",
141
+ " ",
142
+ assignedLabel
143
+ ]
144
+ }),
145
+ data.requireSignature && /*#__PURE__*/ _jsx("span", {
146
+ className: theme.signatureBadge,
147
+ children: "✍ Signature"
148
+ })
149
+ ]
150
+ }),
151
+ /*#__PURE__*/ _jsx(Handle, {
152
+ type: "source",
153
+ position: Position.Right,
154
+ className: theme.handleSource
155
+ })
156
+ ]
157
+ });
158
+ }
159
+ // ─── Notification Node ────────────────────────────────────────────
160
+ export function NotificationFlowNode({ data }) {
161
+ const theme = verificationFlowPageTheme.notificationNode;
162
+ const isSelected = data.selected === true;
163
+ const channels = data.channels || [];
164
+ const trigger = data.trigger || "on_step_reached";
165
+ const triggerLabel = trigger.replace(/^on_/, "").replace(/_/g, " ");
166
+ return /*#__PURE__*/ _jsxs("div", {
167
+ className: isSelected ? theme.containerSelected : theme.container,
168
+ children: [
169
+ /*#__PURE__*/ _jsx(Handle, {
170
+ type: "target",
171
+ position: Position.Left,
172
+ className: theme.handleTarget
173
+ }),
174
+ /*#__PURE__*/ _jsxs("div", {
175
+ className: "flex items-center gap-2",
176
+ children: [
177
+ /*#__PURE__*/ _jsx(NotificationIcon, {
178
+ className: `w-4 h-4 ${theme.icon}`
179
+ }),
180
+ /*#__PURE__*/ _jsx("span", {
181
+ className: theme.typeLabel,
182
+ children: "Notification"
183
+ })
184
+ ]
185
+ }),
186
+ /*#__PURE__*/ _jsx("p", {
187
+ className: theme.nameLabel,
188
+ children: data.label || "Notification"
189
+ }),
190
+ data.description ? /*#__PURE__*/ _jsx("p", {
191
+ className: theme.description,
192
+ children: String(data.description)
193
+ }) : null,
194
+ /*#__PURE__*/ _jsxs("div", {
195
+ className: "flex flex-wrap gap-1.5 mt-2",
196
+ children: [
197
+ /*#__PURE__*/ _jsxs("span", {
198
+ className: theme.triggerBadge,
199
+ children: [
200
+ "⚡ ",
201
+ triggerLabel
202
+ ]
203
+ }),
204
+ channels.map((ch)=>/*#__PURE__*/ _jsx("span", {
205
+ className: theme.channelBadge,
206
+ children: ch
207
+ }, ch))
208
+ ]
209
+ }),
104
210
  /*#__PURE__*/ _jsx(Handle, {
105
211
  type: "source",
106
- position: Position.Bottom,
107
- className: theme.node.handle
212
+ position: Position.Right,
213
+ className: theme.handleSource
108
214
  })
109
215
  ]
110
216
  });
@@ -0,0 +1,3 @@
1
+ import type { ReactElement } from "react";
2
+ export declare function NodePalette(): ReactElement;
3
+ //# sourceMappingURL=NodePropertiesPanel.d.ts.map
@@ -0,0 +1,131 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cn } from "../../../utils/cn";
4
+ import { verificationFlowPageTheme } from "../theme";
5
+ const paletteItems = [
6
+ {
7
+ type: "step",
8
+ label: "Step",
9
+ description: "A verification checkpoint in the flow",
10
+ iconBg: "bg-blue-500/20 text-blue-400",
11
+ themeKey: "stepItem"
12
+ },
13
+ {
14
+ type: "verifier",
15
+ label: "Verifier",
16
+ description: "Assign a user or role to approve",
17
+ iconBg: "bg-amber-500/20 text-amber-400",
18
+ themeKey: "verifierItem"
19
+ },
20
+ {
21
+ type: "notification",
22
+ label: "Notification",
23
+ description: "Send alerts via portal, email, or webhook",
24
+ iconBg: "bg-violet-500/20 text-violet-400",
25
+ themeKey: "notificationItem"
26
+ }
27
+ ];
28
+ const StepPaletteIcon = ()=>/*#__PURE__*/ _jsxs("svg", {
29
+ className: "w-4.5 h-4.5",
30
+ fill: "none",
31
+ viewBox: "0 0 24 24",
32
+ stroke: "currentColor",
33
+ strokeWidth: 1.5,
34
+ children: [
35
+ /*#__PURE__*/ _jsx("title", {
36
+ children: "Step"
37
+ }),
38
+ /*#__PURE__*/ _jsx("path", {
39
+ strokeLinecap: "round",
40
+ strokeLinejoin: "round",
41
+ d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
42
+ })
43
+ ]
44
+ });
45
+ const VerifierPaletteIcon = ()=>/*#__PURE__*/ _jsxs("svg", {
46
+ className: "w-4.5 h-4.5",
47
+ fill: "none",
48
+ viewBox: "0 0 24 24",
49
+ stroke: "currentColor",
50
+ strokeWidth: 1.5,
51
+ children: [
52
+ /*#__PURE__*/ _jsx("title", {
53
+ children: "Verifier"
54
+ }),
55
+ /*#__PURE__*/ _jsx("path", {
56
+ strokeLinecap: "round",
57
+ strokeLinejoin: "round",
58
+ d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
59
+ })
60
+ ]
61
+ });
62
+ const NotificationPaletteIcon = ()=>/*#__PURE__*/ _jsxs("svg", {
63
+ className: "w-4.5 h-4.5",
64
+ fill: "none",
65
+ viewBox: "0 0 24 24",
66
+ stroke: "currentColor",
67
+ strokeWidth: 1.5,
68
+ children: [
69
+ /*#__PURE__*/ _jsx("title", {
70
+ children: "Notification"
71
+ }),
72
+ /*#__PURE__*/ _jsx("path", {
73
+ strokeLinecap: "round",
74
+ strokeLinejoin: "round",
75
+ d: "M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"
76
+ })
77
+ ]
78
+ });
79
+ const iconComponents = {
80
+ step: StepPaletteIcon,
81
+ verifier: VerifierPaletteIcon,
82
+ notification: NotificationPaletteIcon
83
+ };
84
+ export function NodePalette() {
85
+ const theme = verificationFlowPageTheme.palette;
86
+ const onDragStart = (e, nodeType)=>{
87
+ e.dataTransfer.setData("application/reactflow-nodetype", nodeType);
88
+ e.dataTransfer.effectAllowed = "move";
89
+ };
90
+ return /*#__PURE__*/ _jsxs("div", {
91
+ className: theme.container,
92
+ children: [
93
+ /*#__PURE__*/ _jsx("p", {
94
+ className: theme.title,
95
+ children: "Components"
96
+ }),
97
+ paletteItems.map((item)=>{
98
+ const Icon = iconComponents[item.type];
99
+ return /*#__PURE__*/ _jsxs("div", {
100
+ role: "button",
101
+ tabIndex: 0,
102
+ className: cn(theme.item, theme[item.themeKey]),
103
+ draggable: true,
104
+ onDragStart: (e)=>onDragStart(e, item.type),
105
+ children: [
106
+ /*#__PURE__*/ _jsx("div", {
107
+ className: cn(theme.itemIcon, item.iconBg),
108
+ children: /*#__PURE__*/ _jsx(Icon, {})
109
+ }),
110
+ /*#__PURE__*/ _jsxs("div", {
111
+ children: [
112
+ /*#__PURE__*/ _jsx("p", {
113
+ className: theme.itemLabel,
114
+ children: item.label
115
+ }),
116
+ /*#__PURE__*/ _jsx("p", {
117
+ className: theme.itemDescription,
118
+ children: item.description
119
+ })
120
+ ]
121
+ })
122
+ ]
123
+ }, item.type);
124
+ }),
125
+ /*#__PURE__*/ _jsx("p", {
126
+ className: theme.dragHint,
127
+ children: "Drag a component onto the canvas to add it to your flow"
128
+ })
129
+ ]
130
+ });
131
+ }
@@ -0,0 +1,34 @@
1
+ import type { ReactElement } from "react";
2
+ import type { ListRolesAction, ListUsersAction, NodeType, NotificationChannel, RecipientType, VerificationTrigger } from "../types";
3
+ interface NodeData {
4
+ nodeType: NodeType;
5
+ label?: string;
6
+ description?: string;
7
+ stepOrder: number;
8
+ verifierType?: "user" | "role";
9
+ verifierUserId?: string;
10
+ verifierUserEmail?: string;
11
+ verifierRole?: string;
12
+ requireSignature?: boolean;
13
+ allMustApprove?: boolean;
14
+ trigger?: VerificationTrigger;
15
+ channels?: NotificationChannel[];
16
+ recipientType?: RecipientType;
17
+ recipientUserId?: string;
18
+ recipientRole?: string;
19
+ titleTemplate?: string;
20
+ bodyTemplate?: string;
21
+ [key: string]: unknown;
22
+ }
23
+ interface PropertiesPanelProps {
24
+ nodeId: string;
25
+ nodeData: NodeData;
26
+ onUpdateNode: (nodeId: string, data: NodeData) => void;
27
+ onDeleteNode: (nodeId: string) => void;
28
+ onClose: () => void;
29
+ listUsersAction?: ListUsersAction;
30
+ listRolesAction?: ListRolesAction;
31
+ }
32
+ export declare function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode, onClose, listUsersAction, listRolesAction, }: PropertiesPanelProps): ReactElement;
33
+ export {};
34
+ //# sourceMappingURL=PropertiesPanel.d.ts.map