@confidencesystemsinc/sdk 1.0.2 → 1.0.3
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/package.json +2 -3
- package/src/App.css +0 -2
- package/src/components/badge.tsx +0 -116
- package/src/components/initiate-playbook-modal/InitiatePlaybookModal.tsx +0 -53
- package/src/components/playbook/confidence-playbook.tsx +0 -217
- package/src/components/playbook/playbook-header.tsx +0 -13
- package/src/components/playbook-button/ConfidencePlaybookButton.tsx +0 -74
- package/src/components/task/confidence-task.tsx +0 -198
- package/src/components/task/task-buttons.tsx +0 -32
- package/src/components/task/task-dropdown-badge.tsx +0 -121
- package/src/components/task/task-left-panel.tsx +0 -60
- package/src/components/task/task-status-badge.tsx +0 -23
- package/src/components/ui/button.tsx +0 -269
- package/src/components/ui/header.tsx +0 -12
- package/src/components/ui/input.tsx +0 -39
- package/src/components/ui/modal.tsx +0 -88
- package/src/constants/settings.constants.ts +0 -2
- package/src/hooks/task-events/useCompleteTask.ts +0 -26
- package/src/hooks/task-events/useStartTask.ts +0 -29
- package/src/hooks/usePlaybook.ts +0 -48
- package/src/hooks/usePlaybookActions.ts +0 -69
- package/src/hooks/useTaskButtons.ts +0 -46
- package/src/index.ts +0 -6
- package/src/services/complete-task.service.ts +0 -21
- package/src/services/initiate-playbook.service.ts +0 -24
- package/src/services/start-task.services.ts +0 -23
- package/src/stories/initiate-playbook-modal.stories.tsx +0 -31
- package/src/stories/modal.stories.tsx +0 -50
- package/src/stories/playbook-container.stories.tsx +0 -79
- package/src/types/playbook.types.ts +0 -22
- package/src/types/task.types.ts +0 -20
- package/src/utils/cn.ts +0 -6
- package/src/vite-env.d.ts +0 -1
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@confidencesystemsinc/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/sdk.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"dist"
|
|
9
|
-
"src"
|
|
8
|
+
"dist"
|
|
10
9
|
],
|
|
11
10
|
"scripts": {
|
|
12
11
|
"build": "tsc -b && vite build",
|
package/src/App.css
DELETED
package/src/components/badge.tsx
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { ComponentPropsWithoutRef, useMemo } from "react";
|
|
2
|
-
import { twMerge } from "tailwind-merge";
|
|
3
|
-
|
|
4
|
-
export const BadgeSolid = {
|
|
5
|
-
white: "bg-white text-dark-300 border border-gray-300",
|
|
6
|
-
primary: "bg-primary-600",
|
|
7
|
-
secondary: "bg-secondary-500",
|
|
8
|
-
success: "bg-success-600",
|
|
9
|
-
info: "bg-info-500",
|
|
10
|
-
warning: "bg-warning-500 text-gray-800",
|
|
11
|
-
danger: "bg-danger-500",
|
|
12
|
-
steel: "bg-steel-500",
|
|
13
|
-
orange: "bg-orange-500",
|
|
14
|
-
purple: "bg-purple-500",
|
|
15
|
-
grayDark: "bg-gray-900",
|
|
16
|
-
grayLight: "bg-gray-100 text-gray-800",
|
|
17
|
-
} as const;
|
|
18
|
-
|
|
19
|
-
export const BadgeOutline = {
|
|
20
|
-
white: "text-white border border-white",
|
|
21
|
-
primary: "text-primary-600 border border-primary-600",
|
|
22
|
-
secondary: "text-secondary-500 border border-secondary-500",
|
|
23
|
-
success: "text-success-600 border border-success-600",
|
|
24
|
-
info: "text-info-500 border border-info-500",
|
|
25
|
-
warning: "text-warning-500 border border-warning-500",
|
|
26
|
-
danger: "text-danger-500 border border-danger-500",
|
|
27
|
-
steel: "text-steel-500 border border-steel-500",
|
|
28
|
-
orange: "text-orange-500 border border-orange-500",
|
|
29
|
-
purple: "text-purple-500 border border-purple-500",
|
|
30
|
-
grayDark: "text-gray-700 border border-gray-700",
|
|
31
|
-
grayLight: "text-gray-500 border border-gray-100",
|
|
32
|
-
} as const;
|
|
33
|
-
|
|
34
|
-
const BadgeFontColor = {
|
|
35
|
-
white: "text-dark-300",
|
|
36
|
-
primary: "text-white",
|
|
37
|
-
secondary: "text-white",
|
|
38
|
-
success: "text-white",
|
|
39
|
-
info: "text-black",
|
|
40
|
-
warning: "text-gray-800",
|
|
41
|
-
danger: "text-white",
|
|
42
|
-
steel: "text-white",
|
|
43
|
-
orange: "text-black",
|
|
44
|
-
purple: "text-white",
|
|
45
|
-
grayDark: "text-white",
|
|
46
|
-
grayLight: "text-gray-800",
|
|
47
|
-
} as const;
|
|
48
|
-
|
|
49
|
-
export const BadgeRoundness = {
|
|
50
|
-
normal: "rounded",
|
|
51
|
-
pill: "rounded-pill",
|
|
52
|
-
} as const;
|
|
53
|
-
|
|
54
|
-
const BadgeSize = {
|
|
55
|
-
big: "h-[24px] leading-[24px] text-md px-1",
|
|
56
|
-
medium: "h-[22px] leading-[22px] text-sm px-[2px]",
|
|
57
|
-
small: "h-[18px] leading-[18px] text-xs px-[2px]",
|
|
58
|
-
} as const;
|
|
59
|
-
|
|
60
|
-
export interface BadgeProps extends ComponentPropsWithoutRef<"div"> {
|
|
61
|
-
category?: "solid" | "outline";
|
|
62
|
-
color?: keyof typeof BadgeSolid;
|
|
63
|
-
roundness?: keyof typeof BadgeRoundness;
|
|
64
|
-
size?: keyof typeof BadgeSize;
|
|
65
|
-
textClassName?: string;
|
|
66
|
-
children: React.ReactNode;
|
|
67
|
-
onClose?: () => void;
|
|
68
|
-
onArrowClick?: () => void;
|
|
69
|
-
className?: string;
|
|
70
|
-
onCustomIconClick?: () => void;
|
|
71
|
-
arrowTitle?: string;
|
|
72
|
-
closeTitle?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export const Badge = ({
|
|
76
|
-
category = "solid",
|
|
77
|
-
color = "primary",
|
|
78
|
-
roundness = "normal",
|
|
79
|
-
size = "medium",
|
|
80
|
-
textClassName = "uppercase",
|
|
81
|
-
children,
|
|
82
|
-
className,
|
|
83
|
-
...rest
|
|
84
|
-
}: BadgeProps) => {
|
|
85
|
-
const fontColor = useMemo(
|
|
86
|
-
() => BadgeFontColor[color] ?? "text-white",
|
|
87
|
-
[color],
|
|
88
|
-
);
|
|
89
|
-
const BadgeClasses = useMemo(
|
|
90
|
-
() =>
|
|
91
|
-
twMerge(
|
|
92
|
-
fontColor,
|
|
93
|
-
category === "outline" ? BadgeOutline[color] : BadgeSolid[color],
|
|
94
|
-
BadgeRoundness[roundness],
|
|
95
|
-
BadgeSize[size],
|
|
96
|
-
),
|
|
97
|
-
[fontColor, category, color, size, roundness],
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
return (
|
|
101
|
-
<div
|
|
102
|
-
className={twMerge(
|
|
103
|
-
"ui-badge flex items-center font-bold",
|
|
104
|
-
BadgeClasses,
|
|
105
|
-
className,
|
|
106
|
-
)}
|
|
107
|
-
style={rest?.style}
|
|
108
|
-
data-testid={`badge`}
|
|
109
|
-
data-category={category}
|
|
110
|
-
data-color={color}
|
|
111
|
-
{...rest}
|
|
112
|
-
>
|
|
113
|
-
<p className={twMerge("mx-1", textClassName)}>{children}</p>
|
|
114
|
-
</div>
|
|
115
|
-
);
|
|
116
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { Modal } from "../ui/modal";
|
|
3
|
-
import { InputField } from "../ui/input";
|
|
4
|
-
|
|
5
|
-
export const InitiatePlaybookModal = ({
|
|
6
|
-
onConfirm,
|
|
7
|
-
onClose,
|
|
8
|
-
isOpen,
|
|
9
|
-
title,
|
|
10
|
-
}: {
|
|
11
|
-
onConfirm: (email: string) => void | Promise<void>;
|
|
12
|
-
onClose: () => void;
|
|
13
|
-
isOpen: boolean;
|
|
14
|
-
title?: string;
|
|
15
|
-
}) => {
|
|
16
|
-
const [email, setEmail] = useState("");
|
|
17
|
-
const [isConfirming, setIsConfirming] = useState(false);
|
|
18
|
-
const handleConfirm = async () => {
|
|
19
|
-
if (email) {
|
|
20
|
-
try {
|
|
21
|
-
setIsConfirming(true);
|
|
22
|
-
await onConfirm(email);
|
|
23
|
-
setEmail(""); // Reset email after confirmation
|
|
24
|
-
} finally {
|
|
25
|
-
setIsConfirming(false);
|
|
26
|
-
}
|
|
27
|
-
} else {
|
|
28
|
-
alert("Please enter a valid email address.");
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
return (
|
|
32
|
-
<Modal
|
|
33
|
-
title={title || "Initiate Confidence Playbook"}
|
|
34
|
-
isOpen={isOpen}
|
|
35
|
-
close={onClose}
|
|
36
|
-
dismissOptions={{ label: "Cancel", onClick: onClose }}
|
|
37
|
-
confirmOptions={{
|
|
38
|
-
label: "Initiate",
|
|
39
|
-
onClick: handleConfirm,
|
|
40
|
-
disabled: isConfirming || !email,
|
|
41
|
-
}}
|
|
42
|
-
>
|
|
43
|
-
<>
|
|
44
|
-
<InputField
|
|
45
|
-
label="Email"
|
|
46
|
-
disabled={isConfirming}
|
|
47
|
-
description="Enter the email address to initiate the playbook."
|
|
48
|
-
onChange={(e) => setEmail(e.target.value)}
|
|
49
|
-
/>
|
|
50
|
-
</>
|
|
51
|
-
</Modal>
|
|
52
|
-
);
|
|
53
|
-
};
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
2
|
-
import { ReactNode, useEffect, useMemo, useState } from "react";
|
|
3
|
-
import { usePlaybook } from "../../hooks/usePlaybook";
|
|
4
|
-
import { TASK_BUTTONS, TaskButton } from "../../hooks/useTaskButtons";
|
|
5
|
-
import { Playbook } from "../../types/playbook.types";
|
|
6
|
-
import { TASK_STATUS } from "../../types/task.types";
|
|
7
|
-
import { cn } from "../../utils/cn";
|
|
8
|
-
import { ConfidenceTask } from "../task/confidence-task";
|
|
9
|
-
import { PlaybookHeader } from "./playbook-header";
|
|
10
|
-
import { initiatePlaybook } from "../../services/initiate-playbook.service";
|
|
11
|
-
import { ConfidencePlaybookButton } from "../playbook-button/ConfidencePlaybookButton";
|
|
12
|
-
|
|
13
|
-
const ConfidencePlaybookInternal = ({
|
|
14
|
-
playbookInstanceId,
|
|
15
|
-
viewMode,
|
|
16
|
-
}: {
|
|
17
|
-
playbookInstanceId: string | number;
|
|
18
|
-
viewMode: "list" | "card";
|
|
19
|
-
}) => {
|
|
20
|
-
const { playbook, actions: playbookActions } =
|
|
21
|
-
usePlaybook(playbookInstanceId);
|
|
22
|
-
if (!playbook) {
|
|
23
|
-
return <div>Playbook not found</div>;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const handleButtonClick = (buttonType: TaskButton, taskId: number) => {
|
|
27
|
-
if (buttonType === TASK_BUTTONS.COMPLETE) {
|
|
28
|
-
const sequenceOrder = playbook.tasks.find(
|
|
29
|
-
(task) => task.taskInstanceId === taskId,
|
|
30
|
-
)?.sequenceOrder;
|
|
31
|
-
if (sequenceOrder === undefined) {
|
|
32
|
-
console.error("Task not found in playbook");
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
playbookActions.completeTask(taskId, sequenceOrder);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (buttonType === TASK_BUTTONS.START) {
|
|
40
|
-
playbookActions.startTask(taskId);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<div className="flex flex-col">
|
|
46
|
-
<PlaybookView
|
|
47
|
-
playbook={playbook}
|
|
48
|
-
viewMode={viewMode}
|
|
49
|
-
onTaskButtonClick={handleButtonClick}
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const TasksContainer = ({
|
|
56
|
-
className,
|
|
57
|
-
children,
|
|
58
|
-
}: {
|
|
59
|
-
className?: string;
|
|
60
|
-
children: React.ReactNode;
|
|
61
|
-
}) => {
|
|
62
|
-
return (
|
|
63
|
-
<div className={cn("w-full mx-auto space-y-4 py-4 container", className)}>
|
|
64
|
-
{children}
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const Context = ({ children }: { children: ReactNode }) => {
|
|
70
|
-
const [queryClient] = useState(new QueryClient());
|
|
71
|
-
console.log("Confidence Playbook Context Initialized");
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
75
|
-
);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const PlaybookView = ({
|
|
79
|
-
playbook,
|
|
80
|
-
viewMode,
|
|
81
|
-
onTaskButtonClick,
|
|
82
|
-
}: {
|
|
83
|
-
viewMode: "list" | "card";
|
|
84
|
-
playbook: Playbook;
|
|
85
|
-
onTaskButtonClick: (btn: TaskButton, taskId: number) => void;
|
|
86
|
-
}) => {
|
|
87
|
-
const { playbookInstanceName, tasks } = playbook;
|
|
88
|
-
|
|
89
|
-
const sequenceOrderToStart = useMemo(() => {
|
|
90
|
-
const lastCompletedTask = tasks.find(
|
|
91
|
-
(task) => task.workflowStatus === TASK_STATUS.COMPLETED,
|
|
92
|
-
);
|
|
93
|
-
if (!lastCompletedTask) {
|
|
94
|
-
return 0;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return lastCompletedTask.sequenceOrder + 1;
|
|
98
|
-
}, [tasks]);
|
|
99
|
-
return (
|
|
100
|
-
<div className="min-h-screen flex flex-col items-stretch bg-gray-50">
|
|
101
|
-
<PlaybookHeader title={playbookInstanceName} className="top-0 sticky" />
|
|
102
|
-
|
|
103
|
-
<TasksContainer
|
|
104
|
-
className={cn("flex-1", viewMode === "list" && "space-y-0")}
|
|
105
|
-
>
|
|
106
|
-
{tasks.map((task, index) => {
|
|
107
|
-
return (
|
|
108
|
-
<ConfidenceTask
|
|
109
|
-
key={index}
|
|
110
|
-
task={task}
|
|
111
|
-
step={index + 1}
|
|
112
|
-
viewMode={viewMode}
|
|
113
|
-
canStart={task.sequenceOrder === sequenceOrderToStart}
|
|
114
|
-
onButtonClick={(btn) => {
|
|
115
|
-
console.log("Button clicked:", btn);
|
|
116
|
-
onTaskButtonClick(btn, task.taskInstanceId);
|
|
117
|
-
}}
|
|
118
|
-
playbookType={"Non-Sequential"}
|
|
119
|
-
/>
|
|
120
|
-
);
|
|
121
|
-
})}
|
|
122
|
-
</TasksContainer>
|
|
123
|
-
</div>
|
|
124
|
-
);
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export const ConfidencePlaybook = ({
|
|
128
|
-
playbookInstanceId,
|
|
129
|
-
viewMode,
|
|
130
|
-
}: {
|
|
131
|
-
playbookInstanceId: string | number;
|
|
132
|
-
viewMode: "list" | "card";
|
|
133
|
-
}) => {
|
|
134
|
-
return (
|
|
135
|
-
<Context>
|
|
136
|
-
<ConfidencePlaybookInternal
|
|
137
|
-
playbookInstanceId={playbookInstanceId}
|
|
138
|
-
viewMode={viewMode}
|
|
139
|
-
/>
|
|
140
|
-
</Context>
|
|
141
|
-
);
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const AutoInstantiated = ({
|
|
145
|
-
email,
|
|
146
|
-
playbookId,
|
|
147
|
-
viewMode,
|
|
148
|
-
}: {
|
|
149
|
-
email: string;
|
|
150
|
-
playbookId: string;
|
|
151
|
-
viewMode: "list" | "card";
|
|
152
|
-
}) => {
|
|
153
|
-
const [playbookInstanceId, setPlaybookInstanceId] = useState<number | null>(
|
|
154
|
-
null,
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
useEffect(() => {
|
|
158
|
-
(async () => {
|
|
159
|
-
const { playbookInstanceId, errorCode, details, message } =
|
|
160
|
-
(await initiatePlaybook({
|
|
161
|
-
bank: "public-sdk",
|
|
162
|
-
email,
|
|
163
|
-
timezone:
|
|
164
|
-
Intl.DateTimeFormat().resolvedOptions().timeZone ||
|
|
165
|
-
"America/Los_Angeles",
|
|
166
|
-
playbookUid: playbookId,
|
|
167
|
-
})) || {};
|
|
168
|
-
|
|
169
|
-
if (errorCode) {
|
|
170
|
-
throw new Error(
|
|
171
|
-
`Error initiating playbook: ${message} (Code: ${errorCode}) - Details: ${details}`,
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
setPlaybookInstanceId(playbookInstanceId);
|
|
176
|
-
})();
|
|
177
|
-
}, []);
|
|
178
|
-
|
|
179
|
-
if (!playbookInstanceId) {
|
|
180
|
-
return <div>Loading...</div>;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return (
|
|
184
|
-
<ConfidencePlaybook
|
|
185
|
-
playbookInstanceId={playbookInstanceId}
|
|
186
|
-
viewMode={viewMode}
|
|
187
|
-
/>
|
|
188
|
-
);
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const WithInstantiateButton = ({ playbookId }: { playbookId: string }) => {
|
|
192
|
-
const [playbookInstanceId, setPlaybookInstanceId] = useState<number | null>(
|
|
193
|
-
null,
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
if (playbookInstanceId) {
|
|
197
|
-
return (
|
|
198
|
-
<ConfidencePlaybook
|
|
199
|
-
playbookInstanceId={playbookInstanceId}
|
|
200
|
-
viewMode="list"
|
|
201
|
-
/>
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
return (
|
|
205
|
-
<>
|
|
206
|
-
<ConfidencePlaybookButton
|
|
207
|
-
playbookId={playbookId}
|
|
208
|
-
onInitiated={setPlaybookInstanceId}
|
|
209
|
-
/>
|
|
210
|
-
</>
|
|
211
|
-
);
|
|
212
|
-
};
|
|
213
|
-
ConfidencePlaybook.Context = Context;
|
|
214
|
-
ConfidencePlaybook.View = PlaybookView;
|
|
215
|
-
ConfidencePlaybook.TasksContainer = TasksContainer;
|
|
216
|
-
ConfidencePlaybook.AutoInstantiated = AutoInstantiated;
|
|
217
|
-
ConfidencePlaybook.WithInstantiateButton = WithInstantiateButton;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export const PlaybookHeader = ({
|
|
2
|
-
title,
|
|
3
|
-
className,
|
|
4
|
-
...props
|
|
5
|
-
}: React.ComponentProps<"div"> & { title: string }) => {
|
|
6
|
-
return (
|
|
7
|
-
<div className={className} {...props}>
|
|
8
|
-
<div className="border-y border-gray-200 bg-white">
|
|
9
|
-
<h1 className="container mx-auto py-3 text-2xl">{title}</h1>
|
|
10
|
-
</div>
|
|
11
|
-
</div>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { initiatePlaybook } from "../../services/initiate-playbook.service";
|
|
3
|
-
import { InitiatePlaybookModal } from "../initiate-playbook-modal/InitiatePlaybookModal";
|
|
4
|
-
import Button, { ButtonSizeType } from "../ui/button";
|
|
5
|
-
|
|
6
|
-
export const ConfidencePlaybookButton = ({
|
|
7
|
-
btnClassName,
|
|
8
|
-
buttonNode,
|
|
9
|
-
size,
|
|
10
|
-
playbookId,
|
|
11
|
-
onInitiated,
|
|
12
|
-
}: {
|
|
13
|
-
btnClassName?: string;
|
|
14
|
-
buttonNode?: React.ReactNode;
|
|
15
|
-
size?: ButtonSizeType;
|
|
16
|
-
playbookId: string;
|
|
17
|
-
onInitiated: (playbookInstanceId: number) => void;
|
|
18
|
-
}) => {
|
|
19
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
20
|
-
|
|
21
|
-
function open() {
|
|
22
|
-
setIsOpen(true);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function close() {
|
|
26
|
-
setIsOpen(false);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const onInitiatePlaybook = async (email: string) => {
|
|
30
|
-
const { playbookInstanceId, errorCode, details, message } =
|
|
31
|
-
(await initiatePlaybook({
|
|
32
|
-
bank: "public-sdk",
|
|
33
|
-
email,
|
|
34
|
-
timezone:
|
|
35
|
-
Intl.DateTimeFormat().resolvedOptions().timeZone ||
|
|
36
|
-
"America/Los_Angeles",
|
|
37
|
-
playbookUid: playbookId,
|
|
38
|
-
})) || {};
|
|
39
|
-
|
|
40
|
-
if (errorCode) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
`Error initiating playbook: ${message} (Code: ${errorCode}) - Details: ${details}`,
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
onInitiated(playbookInstanceId);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<>
|
|
51
|
-
{buttonNode ? (
|
|
52
|
-
{ buttonNode }
|
|
53
|
-
) : (
|
|
54
|
-
<Button
|
|
55
|
-
onClick={open}
|
|
56
|
-
className={btnClassName}
|
|
57
|
-
color="primary"
|
|
58
|
-
size={size}
|
|
59
|
-
>
|
|
60
|
-
Run Playbook
|
|
61
|
-
</Button>
|
|
62
|
-
)}
|
|
63
|
-
|
|
64
|
-
<InitiatePlaybookModal
|
|
65
|
-
isOpen={isOpen}
|
|
66
|
-
onClose={close}
|
|
67
|
-
onConfirm={async (email) => {
|
|
68
|
-
await onInitiatePlaybook(email);
|
|
69
|
-
close();
|
|
70
|
-
}}
|
|
71
|
-
/>
|
|
72
|
-
</>
|
|
73
|
-
);
|
|
74
|
-
};
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import clsx from "clsx";
|
|
2
|
-
import { TaskButton, useTaskButtons } from "../../hooks/useTaskButtons";
|
|
3
|
-
import { PlaybookType } from "../../types/playbook.types";
|
|
4
|
-
import { Task, TASK_STATUS, TaskStatus } from "../../types/task.types";
|
|
5
|
-
import { TaskButtons } from "./task-buttons";
|
|
6
|
-
import { TaskLeftPanel } from "./task-left-panel";
|
|
7
|
-
import { TaskStatusBadge } from "./task-status-badge";
|
|
8
|
-
import { faCheckSquare } from "@fortawesome/free-solid-svg-icons";
|
|
9
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
10
|
-
import { useMemo } from "react";
|
|
11
|
-
import { cn } from "../../utils/cn";
|
|
12
|
-
import { TaskDropdownBadge } from "./task-dropdown-badge";
|
|
13
|
-
|
|
14
|
-
const TASK_CARD_COLOR: {
|
|
15
|
-
[key in TaskStatus]?: string;
|
|
16
|
-
} = {
|
|
17
|
-
[TASK_STATUS.OPEN]: "border-[#C1C5C8] bg-[#F0F1F2]",
|
|
18
|
-
[TASK_STATUS.IN_PROGRESS]: "bg-[#E6F2FF] border-[#94C8FF]",
|
|
19
|
-
[TASK_STATUS.IN_REVIEW]: "bg-[#EAF6EC] border-[#A5DAB1]",
|
|
20
|
-
[TASK_STATUS.COMPLETED]: "bg-[#EAF6EC] border-[#A5DAB1]",
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const TASK_VERIFICATION_TYPE = {
|
|
24
|
-
PHOTO: "photo",
|
|
25
|
-
SCREENSHOT: "screenshot",
|
|
26
|
-
} as const;
|
|
27
|
-
|
|
28
|
-
export type TaskVerificationType =
|
|
29
|
-
(typeof TASK_VERIFICATION_TYPE)[keyof typeof TASK_VERIFICATION_TYPE];
|
|
30
|
-
|
|
31
|
-
export const ConfidenceTask = ({
|
|
32
|
-
task,
|
|
33
|
-
step,
|
|
34
|
-
playbookType,
|
|
35
|
-
onButtonClick,
|
|
36
|
-
viewMode = "card",
|
|
37
|
-
canStart = false,
|
|
38
|
-
}: {
|
|
39
|
-
task: Task;
|
|
40
|
-
playbookType: PlaybookType;
|
|
41
|
-
step: number;
|
|
42
|
-
onButtonClick: (buttonType: TaskButton) => void;
|
|
43
|
-
viewMode?: "card" | "list";
|
|
44
|
-
canStart?: boolean;
|
|
45
|
-
}) => {
|
|
46
|
-
const { buttons } = useTaskButtons({
|
|
47
|
-
taskStatus: task.workflowStatus,
|
|
48
|
-
canStart,
|
|
49
|
-
});
|
|
50
|
-
const verificationType = useMemo(() => {
|
|
51
|
-
if (task.imageRequired === 0) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
if (task.imageRequired === 1) {
|
|
55
|
-
return TASK_VERIFICATION_TYPE.SCREENSHOT;
|
|
56
|
-
}
|
|
57
|
-
if (task.imageRequired === 2) {
|
|
58
|
-
return TASK_VERIFICATION_TYPE.PHOTO;
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
}, [task.imageRequired]);
|
|
62
|
-
|
|
63
|
-
if (viewMode === "list") {
|
|
64
|
-
const BADGE_VARIANT = useMemo(() => {
|
|
65
|
-
if (task.workflowStatus === TASK_STATUS.COMPLETED) {
|
|
66
|
-
return "success";
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (task.workflowStatus === TASK_STATUS.IN_PROGRESS) {
|
|
70
|
-
return "primary";
|
|
71
|
-
}
|
|
72
|
-
return "default";
|
|
73
|
-
}, [task.workflowStatus]);
|
|
74
|
-
|
|
75
|
-
const BADGE_TRANSICTIONS = useMemo(() => {
|
|
76
|
-
const transitions: {
|
|
77
|
-
color: "primary" | "success";
|
|
78
|
-
id: TaskButton;
|
|
79
|
-
action: string;
|
|
80
|
-
to: TaskStatus;
|
|
81
|
-
}[] = [];
|
|
82
|
-
buttons.forEach((button) => {
|
|
83
|
-
if (button === "START") {
|
|
84
|
-
transitions.push({
|
|
85
|
-
id: "START",
|
|
86
|
-
color: "primary",
|
|
87
|
-
action: "Start",
|
|
88
|
-
to: TASK_STATUS.IN_PROGRESS,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (button === "COMPLETE") {
|
|
93
|
-
transitions.push({
|
|
94
|
-
id: "COMPLETE",
|
|
95
|
-
color: "success",
|
|
96
|
-
action: "Complete",
|
|
97
|
-
to: TASK_STATUS.COMPLETED,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
return transitions;
|
|
103
|
-
}, [buttons]);
|
|
104
|
-
return (
|
|
105
|
-
<div className="flex gap-3 p-2 border-b border-gray-200">
|
|
106
|
-
<div className="text-gray-200 text-base">{task.sequenceOrder + 1}</div>
|
|
107
|
-
<div
|
|
108
|
-
className={cn(
|
|
109
|
-
"text-dark flex-1 truncate",
|
|
110
|
-
task.workflowStatus === TASK_STATUS.COMPLETED &&
|
|
111
|
-
"text-secondary-400 line-through",
|
|
112
|
-
)}
|
|
113
|
-
>
|
|
114
|
-
{task.taskInstanceName}
|
|
115
|
-
</div>
|
|
116
|
-
<TaskDropdownBadge
|
|
117
|
-
title={task.workflowStatus}
|
|
118
|
-
variant={BADGE_VARIANT}
|
|
119
|
-
transitions={BADGE_TRANSICTIONS}
|
|
120
|
-
onClick={(action) => {
|
|
121
|
-
onButtonClick(action as TaskButton);
|
|
122
|
-
}}
|
|
123
|
-
/>
|
|
124
|
-
</div>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return (
|
|
129
|
-
<div
|
|
130
|
-
className={clsx(
|
|
131
|
-
"flex items-stretch rounded-sm overflow-hidden border",
|
|
132
|
-
TASK_CARD_COLOR[task.workflowStatus],
|
|
133
|
-
)}
|
|
134
|
-
>
|
|
135
|
-
<TaskLeftPanel
|
|
136
|
-
playbookType={playbookType}
|
|
137
|
-
status={task.workflowStatus}
|
|
138
|
-
step={step}
|
|
139
|
-
/>
|
|
140
|
-
{/* <input
|
|
141
|
-
type="file"
|
|
142
|
-
ref={photoInputRef}
|
|
143
|
-
hidden
|
|
144
|
-
onChange={(e) => {
|
|
145
|
-
if (e.target.files?.length) {
|
|
146
|
-
void onUploadAsset(e.target.files[0]);
|
|
147
|
-
handleExpand(true);
|
|
148
|
-
}
|
|
149
|
-
}}
|
|
150
|
-
/> */}
|
|
151
|
-
<div className="flex w-full flex-col overflow-x-hidden p-2">
|
|
152
|
-
{playbookType === "Sequential" && (
|
|
153
|
-
<div className="-mb-3 elf-end pr-2 pt-2">
|
|
154
|
-
<TaskStatusBadge status={task.workflowStatus} />
|
|
155
|
-
</div>
|
|
156
|
-
)}
|
|
157
|
-
|
|
158
|
-
<div className="space-y-2 divide-y divide-black/20 flex flex-1 flex-col">
|
|
159
|
-
<div className="space-y-2">
|
|
160
|
-
<div className="text-lg font-medium text-[#1C232D] flex-1">
|
|
161
|
-
{task.taskInstanceName}
|
|
162
|
-
</div>
|
|
163
|
-
|
|
164
|
-
{verificationType ? (
|
|
165
|
-
<div className="flex items-center gap-2 text-sm">
|
|
166
|
-
<FontAwesomeIcon icon={faCheckSquare} className="size-[16px]" />
|
|
167
|
-
<div>
|
|
168
|
-
<span className="font-medium">
|
|
169
|
-
{verificationType === TASK_VERIFICATION_TYPE.PHOTO
|
|
170
|
-
? "Photo"
|
|
171
|
-
: "Screenshot"}
|
|
172
|
-
</span>{" "}
|
|
173
|
-
required
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
) : (
|
|
177
|
-
<></>
|
|
178
|
-
)}
|
|
179
|
-
</div>
|
|
180
|
-
{/* <div>
|
|
181
|
-
<PublicTaskExpandedContent
|
|
182
|
-
showScreenshotHints={showScreenshotHints}
|
|
183
|
-
description={taskDetails?.description}
|
|
184
|
-
onUploadScreenshot={handleUploadScreenshot}
|
|
185
|
-
onDeleteAsset={onDeleteAsset}
|
|
186
|
-
closeScreenshotHints={() => setShowScreenshotHints(false)}
|
|
187
|
-
taskAssets={taskAssets}
|
|
188
|
-
/>
|
|
189
|
-
</div> */}
|
|
190
|
-
|
|
191
|
-
{buttons.length > 0 && (
|
|
192
|
-
<TaskButtons buttons={buttons} onButtonClick={onButtonClick} />
|
|
193
|
-
)}
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
);
|
|
198
|
-
};
|