nucleus-core-ts 0.8.128 → 0.8.130
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/fe/components/VerificationFlowPage/components/FlowNode.d.ts +9 -9
- package/dist/fe/components/VerificationFlowPage/components/FlowNode.js +12 -12
- package/dist/fe/components/VerificationFlowPage/components/NodePropertiesPanel.d.ts +1 -1
- package/dist/fe/components/VerificationFlowPage/components/NodePropertiesPanel.js +21 -21
- package/dist/fe/components/VerificationFlowPage/components/PendingTab.d.ts +2 -2
- package/dist/fe/components/VerificationFlowPage/components/PendingTab.js +13 -10
- package/dist/fe/components/VerificationFlowPage/components/PropertiesPanel.d.ts +3 -1
- package/dist/fe/components/VerificationFlowPage/components/PropertiesPanel.js +60 -17
- package/dist/fe/components/VerificationFlowPage/components/VerificationEntityList.d.ts +2 -1
- package/dist/fe/components/VerificationFlowPage/components/VerificationEntityList.js +46 -5
- package/dist/fe/components/VerificationFlowPage/components/VerificationFlowPage.d.ts +1 -1
- package/dist/fe/components/VerificationFlowPage/components/VerificationFlowPage.js +485 -112
- package/dist/fe/components/VerificationFlowPage/index.d.ts +1 -1
- package/dist/fe/components/VerificationFlowPage/index.js +1 -1
- package/dist/fe/components/VerificationFlowPage/theme/index.d.ts +30 -0
- package/dist/fe/components/VerificationFlowPage/theme/index.js +212 -3
- package/dist/fe/components/VerificationFlowPage/theme/store.d.ts +4 -0
- package/dist/fe/components/VerificationFlowPage/theme/store.js +8 -0
- package/dist/fe/components/VerificationFlowPage/types/index.d.ts +10 -0
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ReactElement } from
|
|
2
|
-
import type { NotificationChannel } from
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { NotificationChannel } from "../types";
|
|
3
3
|
interface StepNodeDataProps {
|
|
4
4
|
label?: string;
|
|
5
5
|
description?: string;
|
|
6
|
-
nodeType:
|
|
6
|
+
nodeType: "step";
|
|
7
7
|
stepOrder: number;
|
|
8
8
|
selected?: boolean;
|
|
9
9
|
[key: string]: unknown;
|
|
@@ -11,9 +11,9 @@ interface StepNodeDataProps {
|
|
|
11
11
|
interface VerifierNodeDataProps {
|
|
12
12
|
label?: string;
|
|
13
13
|
description?: string;
|
|
14
|
-
nodeType:
|
|
14
|
+
nodeType: "verifier";
|
|
15
15
|
stepOrder: number;
|
|
16
|
-
verifierType?:
|
|
16
|
+
verifierType?: "user" | "role";
|
|
17
17
|
verifierRole?: string;
|
|
18
18
|
verifierUserEmail?: string;
|
|
19
19
|
requireSignature?: boolean;
|
|
@@ -24,20 +24,20 @@ interface VerifierNodeDataProps {
|
|
|
24
24
|
interface NotificationNodeDataProps {
|
|
25
25
|
label?: string;
|
|
26
26
|
description?: string;
|
|
27
|
-
nodeType:
|
|
27
|
+
nodeType: "notification";
|
|
28
28
|
stepOrder: number;
|
|
29
29
|
trigger?: string;
|
|
30
30
|
channels?: NotificationChannel[];
|
|
31
31
|
selected?: boolean;
|
|
32
32
|
[key: string]: unknown;
|
|
33
33
|
}
|
|
34
|
-
export declare function StepFlowNode({ data }: {
|
|
34
|
+
export declare function StepFlowNode({ data, }: {
|
|
35
35
|
data: StepNodeDataProps;
|
|
36
36
|
}): ReactElement;
|
|
37
|
-
export declare function VerifierFlowNode({ data }: {
|
|
37
|
+
export declare function VerifierFlowNode({ data, }: {
|
|
38
38
|
data: VerifierNodeDataProps;
|
|
39
39
|
}): ReactElement;
|
|
40
|
-
export declare function NotificationFlowNode({ data }: {
|
|
40
|
+
export declare function NotificationFlowNode({ data, }: {
|
|
41
41
|
data: NotificationNodeDataProps;
|
|
42
42
|
}): ReactElement;
|
|
43
43
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Handle, Position } from
|
|
4
|
-
import {
|
|
3
|
+
import { Handle, Position } from "@xyflow/react";
|
|
4
|
+
import { getActiveTheme } from "../theme/store";
|
|
5
5
|
// ─── Shared icon components ───────────────────────────────────────
|
|
6
6
|
const StepIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
|
|
7
7
|
className: className,
|
|
@@ -56,7 +56,7 @@ const NotificationIcon = ({ className })=>/*#__PURE__*/ _jsxs("svg", {
|
|
|
56
56
|
});
|
|
57
57
|
// ─── Step Node ────────────────────────────────────────────────────
|
|
58
58
|
export function StepFlowNode({ data }) {
|
|
59
|
-
const theme =
|
|
59
|
+
const theme = getActiveTheme().stepNode;
|
|
60
60
|
const isSelected = data.selected === true;
|
|
61
61
|
return /*#__PURE__*/ _jsxs("div", {
|
|
62
62
|
className: isSelected ? theme.containerSelected : theme.container,
|
|
@@ -100,9 +100,9 @@ export function StepFlowNode({ data }) {
|
|
|
100
100
|
}
|
|
101
101
|
// ─── Verifier Node ────────────────────────────────────────────────
|
|
102
102
|
export function VerifierFlowNode({ data }) {
|
|
103
|
-
const theme =
|
|
103
|
+
const theme = getActiveTheme().verifierNode;
|
|
104
104
|
const isSelected = data.selected === true;
|
|
105
|
-
const assignedLabel = data.verifierType ===
|
|
105
|
+
const assignedLabel = data.verifierType === "role" ? data.verifierRole || "No role" : data.verifierUserEmail || "No user";
|
|
106
106
|
return /*#__PURE__*/ _jsxs("div", {
|
|
107
107
|
className: isSelected ? theme.containerSelected : theme.container,
|
|
108
108
|
children: [
|
|
@@ -125,7 +125,7 @@ export function VerifierFlowNode({ data }) {
|
|
|
125
125
|
}),
|
|
126
126
|
/*#__PURE__*/ _jsx("p", {
|
|
127
127
|
className: theme.nameLabel,
|
|
128
|
-
children: data.label ||
|
|
128
|
+
children: data.label || "Verifier"
|
|
129
129
|
}),
|
|
130
130
|
data.description ? /*#__PURE__*/ _jsx("p", {
|
|
131
131
|
className: theme.description,
|
|
@@ -137,7 +137,7 @@ export function VerifierFlowNode({ data }) {
|
|
|
137
137
|
/*#__PURE__*/ _jsxs("span", {
|
|
138
138
|
className: theme.assignedBadge,
|
|
139
139
|
children: [
|
|
140
|
-
data.verifierType ===
|
|
140
|
+
data.verifierType === "role" ? "⛊" : "⚇",
|
|
141
141
|
" ",
|
|
142
142
|
assignedLabel
|
|
143
143
|
]
|
|
@@ -158,11 +158,11 @@ export function VerifierFlowNode({ data }) {
|
|
|
158
158
|
}
|
|
159
159
|
// ─── Notification Node ────────────────────────────────────────────
|
|
160
160
|
export function NotificationFlowNode({ data }) {
|
|
161
|
-
const theme =
|
|
161
|
+
const theme = getActiveTheme().notificationNode;
|
|
162
162
|
const isSelected = data.selected === true;
|
|
163
163
|
const channels = data.channels || [];
|
|
164
|
-
const trigger = data.trigger ||
|
|
165
|
-
const triggerLabel = trigger.replace(/^on_/,
|
|
164
|
+
const trigger = data.trigger || "on_step_reached";
|
|
165
|
+
const triggerLabel = trigger.replace(/^on_/, "").replace(/_/g, " ");
|
|
166
166
|
return /*#__PURE__*/ _jsxs("div", {
|
|
167
167
|
className: isSelected ? theme.containerSelected : theme.container,
|
|
168
168
|
children: [
|
|
@@ -185,7 +185,7 @@ export function NotificationFlowNode({ data }) {
|
|
|
185
185
|
}),
|
|
186
186
|
/*#__PURE__*/ _jsx("p", {
|
|
187
187
|
className: theme.nameLabel,
|
|
188
|
-
children: data.label ||
|
|
188
|
+
children: data.label || "Notification"
|
|
189
189
|
}),
|
|
190
190
|
data.description ? /*#__PURE__*/ _jsx("p", {
|
|
191
191
|
className: theme.description,
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { cn } from
|
|
4
|
-
import {
|
|
3
|
+
import { cn } from "../../../utils/cn";
|
|
4
|
+
import { getActiveTheme } from "../theme/store";
|
|
5
5
|
const paletteItems = [
|
|
6
6
|
{
|
|
7
|
-
type:
|
|
8
|
-
label:
|
|
9
|
-
description:
|
|
10
|
-
iconBg:
|
|
11
|
-
themeKey:
|
|
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
12
|
},
|
|
13
13
|
{
|
|
14
|
-
type:
|
|
15
|
-
label:
|
|
16
|
-
description:
|
|
17
|
-
iconBg:
|
|
18
|
-
themeKey:
|
|
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
19
|
},
|
|
20
20
|
{
|
|
21
|
-
type:
|
|
22
|
-
label:
|
|
23
|
-
description:
|
|
24
|
-
iconBg:
|
|
25
|
-
themeKey:
|
|
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
26
|
}
|
|
27
27
|
];
|
|
28
28
|
const StepPaletteIcon = ()=>/*#__PURE__*/ _jsxs("svg", {
|
|
@@ -82,10 +82,10 @@ const iconComponents = {
|
|
|
82
82
|
notification: NotificationPaletteIcon
|
|
83
83
|
};
|
|
84
84
|
export function NodePalette() {
|
|
85
|
-
const theme =
|
|
85
|
+
const theme = getActiveTheme().palette;
|
|
86
86
|
const onDragStart = (e, nodeType)=>{
|
|
87
|
-
e.dataTransfer.setData(
|
|
88
|
-
e.dataTransfer.effectAllowed =
|
|
87
|
+
e.dataTransfer.setData("application/reactflow-nodetype", nodeType);
|
|
88
|
+
e.dataTransfer.effectAllowed = "move";
|
|
89
89
|
};
|
|
90
90
|
return /*#__PURE__*/ _jsxs("div", {
|
|
91
91
|
className: theme.container,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ReactElement } from
|
|
2
|
-
import type { VerificationDecideAction, VerificationPendingAction } from
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { VerificationDecideAction, VerificationPendingAction } from "../types";
|
|
3
3
|
interface PendingTabProps {
|
|
4
4
|
pendingAction: VerificationPendingAction;
|
|
5
5
|
decideAction: VerificationDecideAction;
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useEffectEvent } from
|
|
4
|
-
import { useVerificationFlowStore } from
|
|
5
|
-
import {
|
|
3
|
+
import { useEffect, useEffectEvent } from "react";
|
|
4
|
+
import { useVerificationFlowStore } from "../store";
|
|
5
|
+
import { getActiveTheme } from "../theme/store";
|
|
6
6
|
export function PendingTab({ pendingAction, decideAction, onDecisionMade }) {
|
|
7
|
-
const theme =
|
|
7
|
+
const theme = getActiveTheme();
|
|
8
8
|
const store = useVerificationFlowStore();
|
|
9
9
|
const loadPending = useEffectEvent(()=>{
|
|
10
10
|
store.setLoadingPending(true);
|
|
11
|
+
console.log("[PendingTab] Loading pending verifications...");
|
|
11
12
|
pendingAction.start({
|
|
12
13
|
payload: undefined,
|
|
13
14
|
onAfterHandle: (res)=>{
|
|
15
|
+
console.log("[PendingTab] Pending response:", res);
|
|
14
16
|
const data = res.data;
|
|
15
17
|
store.setPendingItems(data ?? []);
|
|
16
18
|
store.setLoadingPending(false);
|
|
17
19
|
},
|
|
18
|
-
onErrorHandle: ()=>{
|
|
20
|
+
onErrorHandle: (err)=>{
|
|
21
|
+
console.error("[PendingTab] Pending error:", err);
|
|
19
22
|
store.setLoadingPending(false);
|
|
20
23
|
}
|
|
21
24
|
});
|
|
@@ -33,7 +36,7 @@ export function PendingTab({ pendingAction, decideAction, onDecisionMade }) {
|
|
|
33
36
|
},
|
|
34
37
|
onAfterHandle: ()=>{
|
|
35
38
|
store.setDecidingId(null);
|
|
36
|
-
store.setDecisionReason(
|
|
39
|
+
store.setDecisionReason("");
|
|
37
40
|
onDecisionMade?.(item.entity_name, item.entity_id);
|
|
38
41
|
loadPending();
|
|
39
42
|
}
|
|
@@ -123,13 +126,13 @@ export function PendingTab({ pendingAction, decideAction, onDecisionMade }) {
|
|
|
123
126
|
}),
|
|
124
127
|
/*#__PURE__*/ _jsx("button", {
|
|
125
128
|
type: "button",
|
|
126
|
-
onClick: ()=>handleDecide(item,
|
|
129
|
+
onClick: ()=>handleDecide(item, "approved"),
|
|
127
130
|
className: theme.pending.approveButton,
|
|
128
131
|
children: "Approve"
|
|
129
132
|
}),
|
|
130
133
|
/*#__PURE__*/ _jsx("button", {
|
|
131
134
|
type: "button",
|
|
132
|
-
onClick: ()=>handleDecide(item,
|
|
135
|
+
onClick: ()=>handleDecide(item, "rejected"),
|
|
133
136
|
className: theme.pending.rejectButton,
|
|
134
137
|
children: "Reject"
|
|
135
138
|
}),
|
|
@@ -137,7 +140,7 @@ export function PendingTab({ pendingAction, decideAction, onDecisionMade }) {
|
|
|
137
140
|
type: "button",
|
|
138
141
|
onClick: ()=>{
|
|
139
142
|
store.setDecidingId(null);
|
|
140
|
-
store.setDecisionReason(
|
|
143
|
+
store.setDecisionReason("");
|
|
141
144
|
},
|
|
142
145
|
className: theme.pending.cancelButton,
|
|
143
146
|
children: "Cancel"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
|
+
import type { VerificationFlowPageTheme } from "../theme";
|
|
2
3
|
import type { ListRolesAction, ListUsersAction, NodeType, NotificationChannel, RecipientType, VerificationTrigger } from "../types";
|
|
3
4
|
interface NodeData {
|
|
4
5
|
nodeType: NodeType;
|
|
@@ -28,7 +29,8 @@ interface PropertiesPanelProps {
|
|
|
28
29
|
onClose: () => void;
|
|
29
30
|
listUsersAction?: ListUsersAction;
|
|
30
31
|
listRolesAction?: ListRolesAction;
|
|
32
|
+
panelTheme: VerificationFlowPageTheme["propertiesPanel"];
|
|
31
33
|
}
|
|
32
|
-
export declare function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode, onClose, listUsersAction, listRolesAction, }: PropertiesPanelProps): ReactElement;
|
|
34
|
+
export declare function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode, onClose, listUsersAction, listRolesAction, panelTheme, }: PropertiesPanelProps): ReactElement;
|
|
33
35
|
export {};
|
|
34
36
|
//# sourceMappingURL=PropertiesPanel.d.ts.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useEffectEvent, useState } from "react";
|
|
4
|
-
import { verificationFlowPageTheme } from "../theme";
|
|
5
4
|
// ─── Constants ────────────────────────────────────────────────────
|
|
6
5
|
const ALL_CHANNELS = [
|
|
7
6
|
"portal",
|
|
@@ -55,8 +54,8 @@ const ALL_RECIPIENT_TYPES = [
|
|
|
55
54
|
}
|
|
56
55
|
];
|
|
57
56
|
// ─── Channel Multi-Select ─────────────────────────────────────────
|
|
58
|
-
function ChannelMultiSelect({ selected, onChange }) {
|
|
59
|
-
const theme =
|
|
57
|
+
function ChannelMultiSelect({ selected, onChange, msTheme }) {
|
|
58
|
+
const theme = msTheme;
|
|
60
59
|
const [isOpen, setIsOpen] = useState(false);
|
|
61
60
|
const toggle = (channel)=>{
|
|
62
61
|
if (selected.includes(channel)) {
|
|
@@ -130,11 +129,14 @@ function ChannelMultiSelect({ selected, onChange }) {
|
|
|
130
129
|
]
|
|
131
130
|
});
|
|
132
131
|
}
|
|
132
|
+
// ─── Module-level caches ─────────────────────────────────────────
|
|
133
|
+
let cachedUsers = [];
|
|
134
|
+
let cachedRoles = [];
|
|
133
135
|
// ─── User/Role Search List ────────────────────────────────────────
|
|
134
|
-
function UserSearchList({ listUsersAction, selectedUserId, onSelect }) {
|
|
135
|
-
const theme =
|
|
136
|
+
function UserSearchList({ listUsersAction, selectedUserId, onSelect, ursTheme }) {
|
|
137
|
+
const theme = ursTheme;
|
|
136
138
|
const [searchTerm, setSearchTerm] = useState("");
|
|
137
|
-
const [users, setUsers] = useState(
|
|
139
|
+
const [users, setUsers] = useState(cachedUsers);
|
|
138
140
|
const [page, setPage] = useState(1);
|
|
139
141
|
const [hasMore, setHasMore] = useState(false);
|
|
140
142
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -155,6 +157,7 @@ function UserSearchList({ listUsersAction, selectedUserId, onSelect }) {
|
|
|
155
157
|
const nextPage = meta?.hasNextPage === true || items.length >= 20;
|
|
156
158
|
if (pageNum === 1) {
|
|
157
159
|
setUsers(items);
|
|
160
|
+
if (!search) cachedUsers = items;
|
|
158
161
|
} else {
|
|
159
162
|
setUsers((prev)=>[
|
|
160
163
|
...prev,
|
|
@@ -170,6 +173,10 @@ function UserSearchList({ listUsersAction, selectedUserId, onSelect }) {
|
|
|
170
173
|
});
|
|
171
174
|
});
|
|
172
175
|
useEffect(()=>{
|
|
176
|
+
if (searchTerm === "" && cachedUsers.length > 0) {
|
|
177
|
+
setUsers(cachedUsers);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
173
180
|
loadUsers(1, searchTerm);
|
|
174
181
|
setPage(1);
|
|
175
182
|
}, [
|
|
@@ -186,9 +193,32 @@ function UserSearchList({ listUsersAction, selectedUserId, onSelect }) {
|
|
|
186
193
|
children: "No user data source configured"
|
|
187
194
|
});
|
|
188
195
|
}
|
|
196
|
+
const selectedUser = selectedUserId ? users.find((u)=>u.id === selectedUserId) : null;
|
|
189
197
|
return /*#__PURE__*/ _jsxs("div", {
|
|
190
198
|
className: theme.container,
|
|
191
199
|
children: [
|
|
200
|
+
selectedUser && /*#__PURE__*/ _jsxs("div", {
|
|
201
|
+
className: "flex items-center gap-2 rounded-lg bg-blue-500/15 border border-blue-500/25 px-3 py-2",
|
|
202
|
+
children: [
|
|
203
|
+
/*#__PURE__*/ _jsx("span", {
|
|
204
|
+
className: "w-6 h-6 rounded-full bg-blue-500/20 flex items-center justify-center text-[10px] font-bold text-blue-300 flex-shrink-0",
|
|
205
|
+
children: (selectedUser.name || selectedUser.email || "?").charAt(0).toUpperCase()
|
|
206
|
+
}),
|
|
207
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
208
|
+
className: "flex flex-col min-w-0",
|
|
209
|
+
children: [
|
|
210
|
+
/*#__PURE__*/ _jsx("span", {
|
|
211
|
+
className: "text-[11px] font-medium text-blue-300 truncate",
|
|
212
|
+
children: selectedUser.name || selectedUser.email
|
|
213
|
+
}),
|
|
214
|
+
selectedUser.name && /*#__PURE__*/ _jsx("span", {
|
|
215
|
+
className: "text-[10px] text-blue-300/50 truncate",
|
|
216
|
+
children: selectedUser.email
|
|
217
|
+
})
|
|
218
|
+
]
|
|
219
|
+
})
|
|
220
|
+
]
|
|
221
|
+
}),
|
|
192
222
|
/*#__PURE__*/ _jsx("input", {
|
|
193
223
|
type: "text",
|
|
194
224
|
className: theme.searchInput,
|
|
@@ -206,13 +236,16 @@ function UserSearchList({ listUsersAction, selectedUserId, onSelect }) {
|
|
|
206
236
|
users.map((user)=>/*#__PURE__*/ _jsxs("button", {
|
|
207
237
|
type: "button",
|
|
208
238
|
className: user.id === selectedUserId ? theme.listItemSelected : theme.listItem,
|
|
209
|
-
onClick: ()=>
|
|
239
|
+
onClick: ()=>{
|
|
240
|
+
onSelect(user);
|
|
241
|
+
},
|
|
210
242
|
children: [
|
|
211
243
|
/*#__PURE__*/ _jsx("span", {
|
|
212
244
|
className: theme.listItemAvatar,
|
|
213
245
|
children: (user.name || user.email || "?").charAt(0).toUpperCase()
|
|
214
246
|
}),
|
|
215
247
|
/*#__PURE__*/ _jsxs("span", {
|
|
248
|
+
className: "flex flex-col min-w-0",
|
|
216
249
|
children: [
|
|
217
250
|
/*#__PURE__*/ _jsx("span", {
|
|
218
251
|
className: theme.listItemName,
|
|
@@ -237,10 +270,10 @@ function UserSearchList({ listUsersAction, selectedUserId, onSelect }) {
|
|
|
237
270
|
]
|
|
238
271
|
});
|
|
239
272
|
}
|
|
240
|
-
function RoleSearchList({ listRolesAction, selectedRole, onSelect }) {
|
|
241
|
-
const theme =
|
|
273
|
+
function RoleSearchList({ listRolesAction, selectedRole, onSelect, ursTheme }) {
|
|
274
|
+
const theme = ursTheme;
|
|
242
275
|
const [searchTerm, setSearchTerm] = useState("");
|
|
243
|
-
const [roles, setRoles] = useState(
|
|
276
|
+
const [roles, setRoles] = useState(cachedRoles);
|
|
244
277
|
const [page, setPage] = useState(1);
|
|
245
278
|
const [hasMore, setHasMore] = useState(false);
|
|
246
279
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -261,6 +294,7 @@ function RoleSearchList({ listRolesAction, selectedRole, onSelect }) {
|
|
|
261
294
|
const nextPage = meta?.hasNextPage === true || items.length >= 20;
|
|
262
295
|
if (pageNum === 1) {
|
|
263
296
|
setRoles(items);
|
|
297
|
+
if (!search) cachedRoles = items;
|
|
264
298
|
} else {
|
|
265
299
|
setRoles((prev)=>[
|
|
266
300
|
...prev,
|
|
@@ -276,6 +310,10 @@ function RoleSearchList({ listRolesAction, selectedRole, onSelect }) {
|
|
|
276
310
|
});
|
|
277
311
|
});
|
|
278
312
|
useEffect(()=>{
|
|
313
|
+
if (searchTerm === "" && cachedRoles.length > 0) {
|
|
314
|
+
setRoles(cachedRoles);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
279
317
|
loadRoles(1, searchTerm);
|
|
280
318
|
setPage(1);
|
|
281
319
|
}, [
|
|
@@ -344,8 +382,8 @@ function RoleSearchList({ listRolesAction, selectedRole, onSelect }) {
|
|
|
344
382
|
});
|
|
345
383
|
}
|
|
346
384
|
// ─── Main Properties Panel ────────────────────────────────────────
|
|
347
|
-
export function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode, onClose, listUsersAction, listRolesAction }) {
|
|
348
|
-
const theme =
|
|
385
|
+
export function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode, onClose, listUsersAction, listRolesAction, panelTheme }) {
|
|
386
|
+
const theme = panelTheme;
|
|
349
387
|
const data = nodeData;
|
|
350
388
|
const nodeType = data.nodeType;
|
|
351
389
|
const update = (partial)=>{
|
|
@@ -487,14 +525,16 @@ export function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode,
|
|
|
487
525
|
onSelect: (user)=>update({
|
|
488
526
|
verifierUserId: user.id,
|
|
489
527
|
verifierUserEmail: user.email
|
|
490
|
-
})
|
|
528
|
+
}),
|
|
529
|
+
ursTheme: theme.userRoleSearch
|
|
491
530
|
}),
|
|
492
531
|
(data.verifierType === "role" || !data.verifierType) && /*#__PURE__*/ _jsx(RoleSearchList, {
|
|
493
532
|
listRolesAction: listRolesAction,
|
|
494
533
|
selectedRole: data.verifierRole,
|
|
495
534
|
onSelect: (role)=>update({
|
|
496
535
|
verifierRole: role.name
|
|
497
|
-
})
|
|
536
|
+
}),
|
|
537
|
+
ursTheme: theme.userRoleSearch
|
|
498
538
|
})
|
|
499
539
|
]
|
|
500
540
|
}),
|
|
@@ -590,7 +630,8 @@ export function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode,
|
|
|
590
630
|
selected: data.channels || [],
|
|
591
631
|
onChange: (channels)=>update({
|
|
592
632
|
channels
|
|
593
|
-
})
|
|
633
|
+
}),
|
|
634
|
+
msTheme: theme.multiSelect
|
|
594
635
|
})
|
|
595
636
|
]
|
|
596
637
|
}),
|
|
@@ -627,14 +668,16 @@ export function PropertiesPanel({ nodeId, nodeData, onUpdateNode, onDeleteNode,
|
|
|
627
668
|
selectedUserId: data.recipientUserId,
|
|
628
669
|
onSelect: (user)=>update({
|
|
629
670
|
recipientUserId: user.id
|
|
630
|
-
})
|
|
671
|
+
}),
|
|
672
|
+
ursTheme: theme.userRoleSearch
|
|
631
673
|
}),
|
|
632
674
|
data.recipientType === "role" && /*#__PURE__*/ _jsx(RoleSearchList, {
|
|
633
675
|
listRolesAction: listRolesAction,
|
|
634
676
|
selectedRole: data.recipientRole,
|
|
635
677
|
onSelect: (role)=>update({
|
|
636
678
|
recipientRole: role.name
|
|
637
|
-
})
|
|
679
|
+
}),
|
|
680
|
+
ursTheme: theme.userRoleSearch
|
|
638
681
|
})
|
|
639
682
|
]
|
|
640
683
|
}),
|
|
@@ -40,8 +40,9 @@ export type VerificationEntityListProps = {
|
|
|
40
40
|
entityName: string;
|
|
41
41
|
entityStatusesAction: VerificationEntityStatusesAction;
|
|
42
42
|
theme?: Partial<VerificationEntityListTheme>;
|
|
43
|
+
themeMode?: "dark" | "light";
|
|
43
44
|
onEntityClick?: (item: VerificationBulkStatusItem) => void;
|
|
44
45
|
pageSize?: number;
|
|
45
46
|
};
|
|
46
|
-
export declare function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, onEntityClick, pageSize, }: VerificationEntityListProps): import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
export declare function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, themeMode, onEntityClick, pageSize, }: VerificationEntityListProps): import("react/jsx-runtime").JSX.Element;
|
|
47
48
|
//# sourceMappingURL=VerificationEntityList.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffectEvent } from "react";
|
|
4
|
-
const
|
|
3
|
+
import { useEffect, useState, useEffectEvent } from "react";
|
|
4
|
+
const darkTheme = {
|
|
5
5
|
container: "space-y-4",
|
|
6
6
|
header: "space-y-1",
|
|
7
7
|
title: "text-lg font-bold text-white/90 tracking-tight",
|
|
@@ -38,6 +38,43 @@ const defaultTheme = {
|
|
|
38
38
|
pageInfo: "text-xs text-white/30",
|
|
39
39
|
loadingSpinner: "flex items-center justify-center py-8"
|
|
40
40
|
};
|
|
41
|
+
const lightTheme = {
|
|
42
|
+
container: "space-y-4",
|
|
43
|
+
header: "space-y-1",
|
|
44
|
+
title: "text-lg font-bold text-gray-900 tracking-tight",
|
|
45
|
+
description: "text-sm text-gray-500",
|
|
46
|
+
tabs: "flex items-center gap-1 p-1 rounded-xl bg-gray-100 border border-gray-200",
|
|
47
|
+
tab: "px-3.5 py-1.5 rounded-lg text-xs font-medium text-gray-400 transition-all cursor-pointer hover:text-gray-600",
|
|
48
|
+
tabActive: "px-3.5 py-1.5 rounded-lg text-xs font-semibold bg-white text-gray-900 shadow-sm cursor-pointer",
|
|
49
|
+
tabCount: "ml-1 text-[10px] opacity-50",
|
|
50
|
+
list: "space-y-2",
|
|
51
|
+
listItem: "flex items-center gap-4 p-4 rounded-xl border border-gray-200 bg-white transition-all",
|
|
52
|
+
listItemHover: "hover:bg-gray-50 hover:border-gray-300",
|
|
53
|
+
entityInfo: "flex-1 min-w-0 space-y-0.5",
|
|
54
|
+
entityName: "text-sm font-semibold text-gray-800 truncate",
|
|
55
|
+
entityId: "text-[11px] text-gray-400 font-mono truncate",
|
|
56
|
+
flowName: "text-[11px] text-gray-500",
|
|
57
|
+
statusBadge: "px-2.5 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider shrink-0",
|
|
58
|
+
statusActive: "bg-amber-100 text-amber-700 ring-1 ring-amber-200",
|
|
59
|
+
statusCompleted: "bg-emerald-100 text-emerald-700 ring-1 ring-emerald-200",
|
|
60
|
+
statusRejected: "bg-red-100 text-red-700 ring-1 ring-red-200",
|
|
61
|
+
statusCancelled: "bg-gray-100 text-gray-400 ring-1 ring-gray-200",
|
|
62
|
+
progressSection: "flex items-center gap-2.5 shrink-0 w-[140px]",
|
|
63
|
+
progressBar: "flex-1 h-1.5 rounded-full bg-gray-200 overflow-hidden",
|
|
64
|
+
progressFill: "h-full rounded-full transition-all duration-500",
|
|
65
|
+
progressLabel: "text-[10px] text-gray-500 font-medium whitespace-nowrap w-[45px] text-right",
|
|
66
|
+
metaSection: "flex items-center gap-4 shrink-0",
|
|
67
|
+
metaLabel: "text-[10px] text-gray-400 uppercase tracking-wider",
|
|
68
|
+
metaValue: "text-xs text-gray-600",
|
|
69
|
+
emptyState: "flex flex-col items-center gap-3 py-12",
|
|
70
|
+
emptyIcon: "text-gray-300",
|
|
71
|
+
emptyText: "text-sm text-gray-400",
|
|
72
|
+
pagination: "flex items-center justify-center gap-2 pt-2",
|
|
73
|
+
pageButton: "px-3 py-1.5 rounded-lg text-xs font-medium text-gray-500 bg-white border border-gray-200 hover:bg-gray-50 transition-all cursor-pointer",
|
|
74
|
+
pageButtonActive: "px-3 py-1.5 rounded-lg text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-300",
|
|
75
|
+
pageInfo: "text-xs text-gray-400",
|
|
76
|
+
loadingSpinner: "flex items-center justify-center py-8"
|
|
77
|
+
};
|
|
41
78
|
const STATUS_TABS = [
|
|
42
79
|
{
|
|
43
80
|
value: "all",
|
|
@@ -60,9 +97,10 @@ const STATUS_TABS = [
|
|
|
60
97
|
label: "Cancelled"
|
|
61
98
|
}
|
|
62
99
|
];
|
|
63
|
-
export function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, onEntityClick, pageSize = 20 }) {
|
|
100
|
+
export function VerificationEntityList({ entityName, entityStatusesAction, theme: themeOverrides, themeMode = "dark", onEntityClick, pageSize = 20 }) {
|
|
101
|
+
const baseTheme = themeMode === "light" ? lightTheme : darkTheme;
|
|
64
102
|
const t = {
|
|
65
|
-
...
|
|
103
|
+
...baseTheme,
|
|
66
104
|
...themeOverrides
|
|
67
105
|
};
|
|
68
106
|
const [activeTab, setActiveTab] = useState("all");
|
|
@@ -86,6 +124,9 @@ export function VerificationEntityList({ entityName, entityStatusesAction, theme
|
|
|
86
124
|
setCurrentPage(page);
|
|
87
125
|
loadStatuses(activeTab === "all" ? undefined : activeTab, page);
|
|
88
126
|
});
|
|
127
|
+
useEffect(()=>{
|
|
128
|
+
loadStatuses(undefined, 1);
|
|
129
|
+
}, []);
|
|
89
130
|
const data = entityStatusesAction.state.data;
|
|
90
131
|
const isPending = entityStatusesAction.state.isPending;
|
|
91
132
|
const responseData = data;
|
|
@@ -157,7 +198,7 @@ export function VerificationEntityList({ entityName, entityStatusesAction, theme
|
|
|
157
198
|
isPending ? /*#__PURE__*/ _jsx("div", {
|
|
158
199
|
className: t.loadingSpinner,
|
|
159
200
|
children: /*#__PURE__*/ _jsx("div", {
|
|
160
|
-
className:
|
|
201
|
+
className: `w-6 h-6 rounded-full border-2 animate-spin ${themeMode === "light" ? "border-gray-200 border-t-blue-500" : "border-white/10 border-t-cyan-400"}`
|
|
161
202
|
})
|
|
162
203
|
}) : items.length === 0 ? /*#__PURE__*/ _jsxs("div", {
|
|
163
204
|
className: t.emptyState,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "@xyflow/react/dist/style.css";
|
|
2
2
|
import type { ReactElement } from "react";
|
|
3
3
|
import type { VerificationFlowPageProps } from "../types";
|
|
4
|
-
export declare function VerificationFlowPage({ entityName, title, subtitle, flowListAction, flowGetAction, flowSaveAction, flowPublishAction, pendingAction, decideAction, listUsersAction, listRolesAction, entityStatusesAction, onFlowSelected, onDecisionMade, onEntityClick, showPending, showEntityStatuses, className, }: VerificationFlowPageProps): ReactElement;
|
|
4
|
+
export declare function VerificationFlowPage({ entityName, title, subtitle, flowListAction, flowGetAction, flowSaveAction, flowPublishAction, flowDeleteAction, pendingAction, decideAction, listUsersAction, listRolesAction, entityStatusesAction, onFlowSelected, onDecisionMade, onEntityClick, onBack, showPending, showEntityStatuses, className, themeMode, }: VerificationFlowPageProps): ReactElement;
|
|
5
5
|
//# sourceMappingURL=VerificationFlowPage.d.ts.map
|