@confidencesystemsinc/sdk 1.2.0 → 1.2.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.
Files changed (61) hide show
  1. package/dist/components/playbook/confidence-playbook.d.ts +12 -5
  2. package/dist/components/playbook/playbook-header.d.ts +3 -1
  3. package/dist/components/playbook-button/ConfidencePlaybookButton.d.ts +2 -1
  4. package/dist/components/task/confidence-task.d.ts +10 -3
  5. package/dist/components/task/task-buttons.d.ts +2 -1
  6. package/dist/components/task/task-expanded-content.d.ts +3 -0
  7. package/dist/components/ui/button.d.ts +1 -0
  8. package/dist/confidence_logo.png +0 -0
  9. package/dist/constants/settings.constants.d.ts +2 -2
  10. package/dist/context/confidence-context.d.ts +10 -0
  11. package/dist/hooks/task/useTaskDetails.d.ts +173 -0
  12. package/dist/hooks/usePlaybookExpandedTasks.d.ts +4 -0
  13. package/dist/hooks/useTaskButtons.d.ts +2 -1
  14. package/dist/index.cjs +15 -15
  15. package/dist/index.js +3596 -3336
  16. package/dist/services/task-details.service.d.ts +4 -0
  17. package/dist/stories/confidence-task.stories.d.ts +50 -0
  18. package/dist/theme.css +1 -1
  19. package/package.json +3 -2
  20. package/src/components/badge.tsx +116 -0
  21. package/src/components/initiate-playbook-modal/InitiatePlaybookModal.tsx +53 -0
  22. package/src/components/playbook/confidence-playbook.tsx +309 -0
  23. package/src/components/playbook/playbook-header.tsx +34 -0
  24. package/src/components/playbook-button/ConfidencePlaybookButton.tsx +79 -0
  25. package/src/components/task/confidence-task.tsx +297 -0
  26. package/src/components/task/task-buttons.tsx +35 -0
  27. package/src/components/task/task-dropdown-badge.tsx +121 -0
  28. package/src/components/task/task-expanded-content.tsx +46 -0
  29. package/src/components/task/task-left-panel.tsx +60 -0
  30. package/src/components/task/task-status-badge.tsx +23 -0
  31. package/src/components/ui/button.tsx +272 -0
  32. package/src/components/ui/header.tsx +12 -0
  33. package/src/components/ui/input.tsx +39 -0
  34. package/src/components/ui/modal.tsx +88 -0
  35. package/src/components/ui/ui-wrapper.tsx +7 -0
  36. package/src/constants/settings.constants.ts +4 -0
  37. package/src/context/confidence-context.tsx +25 -0
  38. package/src/hooks/task/useCompleteTask.ts +32 -0
  39. package/src/hooks/task/useStartTask.ts +35 -0
  40. package/src/hooks/task/useTaskDetails.ts +42 -0
  41. package/src/hooks/usePlaybook.ts +54 -0
  42. package/src/hooks/usePlaybookActions.ts +69 -0
  43. package/src/hooks/usePlaybookExpandedTasks.ts +35 -0
  44. package/src/hooks/useTaskButtons.ts +47 -0
  45. package/src/index.ts +7 -0
  46. package/src/services/complete-task.service.ts +25 -0
  47. package/src/services/initiate-playbook.service.ts +26 -0
  48. package/src/services/start-task.services.ts +27 -0
  49. package/src/services/task-details.service.ts +17 -0
  50. package/src/stories/confidence-playbook.stories.tsx +124 -0
  51. package/src/stories/confidence-task.stories.tsx +63 -0
  52. package/src/stories/initiate-playbook-modal.stories.tsx +31 -0
  53. package/src/stories/modal.stories.tsx +50 -0
  54. package/src/task-description.css +629 -0
  55. package/src/theme.css +11 -0
  56. package/src/types/playbook.types.ts +22 -0
  57. package/src/types/task.types.ts +20 -0
  58. package/src/utils/cn.ts +6 -0
  59. package/src/vite-env.d.ts +1 -0
  60. /package/dist/hooks/{task-events → task}/useCompleteTask.d.ts +0 -0
  61. /package/dist/hooks/{task-events → task}/useStartTask.d.ts +0 -0
@@ -0,0 +1,309 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import { ConfidenceContext } from "../../context/confidence-context";
3
+ import { usePlaybook } from "../../hooks/usePlaybook";
4
+ import { TASK_BUTTONS, TaskButton } from "../../hooks/useTaskButtons";
5
+ import { initiatePlaybook } from "../../services/initiate-playbook.service";
6
+ import { Playbook } from "../../types/playbook.types";
7
+ import { TASK_STATUS } from "../../types/task.types";
8
+ import { cn } from "../../utils/cn";
9
+ import { ConfidencePlaybookButton } from "../playbook-button/ConfidencePlaybookButton";
10
+ import { ConfidenceTask } from "../task/confidence-task";
11
+ import { PlaybookHeader } from "./playbook-header";
12
+ import ConfidenceLogo from "../../../public/confidence_logo.png";
13
+ import { usePlaybookExpandedTasks } from "../../hooks/usePlaybookExpandedTasks";
14
+ export interface ConfidencePlaybookStyleConfiguration {
15
+ overlay?: {
16
+ position?: "left" | "right";
17
+ width?: number | string; // Use string to allow 'calc()' or other CSS values
18
+ height?: number | string;
19
+ right?: number; // For right positioning
20
+ left?: number; // For left positioning
21
+ };
22
+ whiteLabel?: {
23
+ titleBackgroundColor?: string;
24
+ titleTextColor?: string;
25
+ primaryColor?: string;
26
+ };
27
+ }
28
+
29
+ const ConfidencePlaybookInternal = ({
30
+ playbookInstanceId,
31
+ playbookMode,
32
+ playbookStyle,
33
+ }: {
34
+ playbookInstanceId: string | number;
35
+ playbookMode: "list" | "card";
36
+ playbookStyle?: ConfidencePlaybookStyleConfiguration;
37
+ }) => {
38
+ const { playbook, actions: playbookActions } =
39
+ usePlaybook(playbookInstanceId);
40
+
41
+ if (!playbook) {
42
+ return <div></div>;
43
+ }
44
+
45
+ const handleButtonClick = async (buttonType: TaskButton, taskId: number) => {
46
+ if (buttonType === TASK_BUTTONS.COMPLETE) {
47
+ const sequenceOrder = playbook.tasks.find(
48
+ (task) => task.taskInstanceId === taskId,
49
+ )?.sequenceOrder;
50
+ if (sequenceOrder === undefined) {
51
+ console.error("Task not found in playbook");
52
+ return;
53
+ }
54
+
55
+ return playbookActions.completeTask(taskId, sequenceOrder);
56
+ }
57
+
58
+ if (buttonType === TASK_BUTTONS.START) {
59
+ return playbookActions.startTask(taskId);
60
+ }
61
+ };
62
+
63
+ return (
64
+ <PlaybookView
65
+ playbook={playbook}
66
+ playbookMode={playbookMode}
67
+ onTaskButtonClick={handleButtonClick}
68
+ playbookStyle={playbookStyle}
69
+ />
70
+ );
71
+ };
72
+
73
+ const TasksContainer = ({
74
+ className,
75
+ children,
76
+ }: {
77
+ className?: string;
78
+ children: React.ReactNode;
79
+ }) => {
80
+ return (
81
+ <div className={cn("w-full mx-auto space-y-4 py-4 container", className)}>
82
+ {children}
83
+ </div>
84
+ );
85
+ };
86
+
87
+ const PlaybookView = ({
88
+ playbook,
89
+ playbookMode,
90
+ onTaskButtonClick,
91
+ playbookStyle,
92
+ }: {
93
+ playbookMode: "list" | "card";
94
+ playbook: Playbook;
95
+ onTaskButtonClick: (btn: TaskButton, taskId: number) => Promise<void>;
96
+ playbookStyle?: ConfidencePlaybookStyleConfiguration;
97
+ }) => {
98
+ const { playbookInstanceName, tasks } = playbook;
99
+
100
+ const { isTaskExpanded, toggleTaskExpanded } = usePlaybookExpandedTasks(
101
+ playbook.playbookInstanceId,
102
+ );
103
+ const sequenceOrderToStart = useMemo(() => {
104
+ const lastCompletedTask = tasks.find(
105
+ (task) => task.workflowStatus === TASK_STATUS.COMPLETED,
106
+ );
107
+ if (!lastCompletedTask) {
108
+ return 0;
109
+ }
110
+
111
+ return lastCompletedTask.sequenceOrder + 1;
112
+ }, [tasks]);
113
+
114
+ return (
115
+ <div
116
+ className={cn(
117
+ !playbookStyle?.overlay && "min-h-screen",
118
+ playbookStyle?.overlay && "fixed bottom-0 z-[99999999999999] flex",
119
+ )}
120
+ {...(playbookStyle?.overlay && {
121
+ style: {
122
+ width: playbookStyle.overlay.width || 450,
123
+ height: playbookStyle.overlay.height || "calc(100vh - 4rem)",
124
+ maxHeight: "calc(100vh - 4rem)",
125
+ right:
126
+ playbookStyle.overlay.right !== undefined
127
+ ? playbookStyle.overlay.right
128
+ : playbookStyle.overlay.position === "right"
129
+ ? 32
130
+ : undefined,
131
+ left:
132
+ playbookStyle.overlay.left !== undefined
133
+ ? playbookStyle.overlay.left
134
+ : playbookStyle.overlay.position === "left"
135
+ ? 32
136
+ : undefined,
137
+ },
138
+ })}
139
+ >
140
+ {playbookStyle?.overlay && (
141
+ <div
142
+ className={cn(
143
+ "size-9 relative p-1 top-3 z-[99999999999999] border-none rounded-l-sm ",
144
+ )}
145
+ style={{
146
+ backgroundColor:
147
+ playbookStyle?.whiteLabel?.primaryColor || "#007BFF",
148
+ boxShadow: "0px 3px 3px 0px #00000040",
149
+ }}
150
+ >
151
+ <img
152
+ src={ConfidenceLogo}
153
+ alt="Confidence Logo"
154
+ className="w-full h-full object-contain"
155
+ />
156
+ </div>
157
+ )}
158
+ <div
159
+ className={cn(
160
+ "flex flex-col flex-1 bg-gray-50",
161
+ playbookStyle?.overlay &&
162
+ "border border-gray-200 shadow-2xl rounded-t-sm overflow-y-auto",
163
+ )}
164
+ >
165
+ <PlaybookHeader
166
+ title={playbookInstanceName}
167
+ className={cn("top-0 sticky z-2 h-[104px")}
168
+ playbookStyle={playbookStyle}
169
+ />
170
+ <TasksContainer
171
+ className={cn(
172
+ "flex-1",
173
+ playbookMode === "list" && "space-y-0 px-5 relative",
174
+ )}
175
+ >
176
+ {tasks.map((task, index) => {
177
+ return (
178
+ <ConfidenceTask
179
+ key={index}
180
+ task={task}
181
+ step={index + 1}
182
+ viewMode={playbookMode}
183
+ playbookId={playbook.playbookId}
184
+ canStart={task.sequenceOrder === sequenceOrderToStart}
185
+ onButtonClick={(btn) => {
186
+ return onTaskButtonClick(btn, task.taskInstanceId);
187
+ }}
188
+ playbookType={"Non-Sequential"}
189
+ taskStyle={{
190
+ titleColor: playbookStyle?.whiteLabel?.primaryColor,
191
+ }}
192
+ isExpanded={isTaskExpanded(task.taskInstanceId)}
193
+ toggleExpanded={() => toggleTaskExpanded(task.taskInstanceId)}
194
+ listStickyTopBase={104} // Adjust this value based on your header height
195
+ />
196
+ );
197
+ })}
198
+ </TasksContainer>
199
+ </div>
200
+ </div>
201
+ );
202
+ };
203
+
204
+ const AutoInstantiated = ({
205
+ email,
206
+ playbookId,
207
+ playbookMode,
208
+ }: {
209
+ email: string;
210
+ playbookId: string;
211
+ playbookMode: "list" | "card";
212
+ }) => {
213
+ const [playbookInstanceId, setPlaybookInstanceId] = useState<number | null>(
214
+ null,
215
+ );
216
+
217
+ useEffect(() => {
218
+ (async () => {
219
+ const { playbookInstanceId, errorCode, details, message } =
220
+ (await initiatePlaybook({
221
+ bank: "public-sdk",
222
+ email,
223
+ timezone:
224
+ Intl.DateTimeFormat().resolvedOptions().timeZone ||
225
+ "America/Los_Angeles",
226
+ playbookUid: playbookId,
227
+ })) || {};
228
+
229
+ if (errorCode) {
230
+ throw new Error(
231
+ `Error initiating playbook: ${message} (Code: ${errorCode}) - Details: ${details}`,
232
+ );
233
+ }
234
+
235
+ setPlaybookInstanceId(playbookInstanceId);
236
+ })();
237
+ }, []);
238
+
239
+ if (!playbookInstanceId) {
240
+ return <div>Loading...</div>;
241
+ }
242
+
243
+ return (
244
+ <ConfidencePlaybook
245
+ playbookInstanceId={playbookInstanceId}
246
+ playbookMode={playbookMode}
247
+ />
248
+ );
249
+ };
250
+
251
+ const WithInstantiateButton = ({
252
+ playbookId,
253
+ playbookMode = "list",
254
+ playbookStyle,
255
+ btnLabel = "Start Playbook",
256
+ }: {
257
+ playbookId: string;
258
+ playbookMode?: "list" | "card";
259
+ playbookStyle?: ConfidencePlaybookStyleConfiguration;
260
+ btnLabel?: string;
261
+ }) => {
262
+ const [playbookInstanceId, setPlaybookInstanceId] = useState<number | null>(
263
+ null,
264
+ );
265
+
266
+ return (
267
+ <>
268
+ <ConfidencePlaybookButton
269
+ playbookId={playbookId}
270
+ disabled={!!playbookInstanceId}
271
+ onInitiated={setPlaybookInstanceId}
272
+ btnLabel={btnLabel}
273
+ />
274
+
275
+ {playbookInstanceId && (
276
+ <ConfidencePlaybook
277
+ playbookInstanceId={playbookInstanceId}
278
+ playbookMode={playbookMode}
279
+ playbookStyle={playbookStyle}
280
+ />
281
+ )}
282
+ </>
283
+ );
284
+ };
285
+
286
+ export const ConfidencePlaybook = ({
287
+ playbookInstanceId,
288
+ playbookMode,
289
+ playbookStyle,
290
+ }: {
291
+ playbookInstanceId: string | number;
292
+ playbookMode: "list" | "card";
293
+ playbookStyle?: ConfidencePlaybookStyleConfiguration;
294
+ }) => {
295
+ return (
296
+ <ConfidenceContext>
297
+ <ConfidencePlaybookInternal
298
+ playbookInstanceId={playbookInstanceId}
299
+ playbookMode={playbookMode}
300
+ playbookStyle={playbookStyle}
301
+ />
302
+ </ConfidenceContext>
303
+ );
304
+ };
305
+
306
+ ConfidencePlaybook.Context = ConfidenceContext;
307
+ ConfidencePlaybook.View = PlaybookView;
308
+ ConfidencePlaybook.AutoInstantiated = AutoInstantiated;
309
+ ConfidencePlaybook.WithInstantiateButton = WithInstantiateButton;
@@ -0,0 +1,34 @@
1
+ import { cn } from "../../utils/cn";
2
+ import { type ConfidencePlaybookStyleConfiguration } from "./confidence-playbook";
3
+
4
+ export const PlaybookHeader = ({
5
+ title,
6
+ className,
7
+ playbookStyle,
8
+ ...props
9
+ }: React.ComponentProps<"div"> & {
10
+ title: string;
11
+ playbookStyle?: ConfidencePlaybookStyleConfiguration;
12
+ }) => {
13
+ return (
14
+ <div
15
+ className={cn("border-b border-gray-200 flex items-center", className)}
16
+ style={{
17
+ backgroundColor:
18
+ playbookStyle?.whiteLabel?.titleBackgroundColor || "#f8f9fa",
19
+ minHeight: 104,
20
+ height: 104,
21
+ }}
22
+ {...props}
23
+ >
24
+ <h1
25
+ className="text-xl px-5 line-clamp-2"
26
+ style={{
27
+ color: playbookStyle?.whiteLabel?.titleTextColor,
28
+ }}
29
+ >
30
+ {title}
31
+ </h1>
32
+ </div>
33
+ );
34
+ };
@@ -0,0 +1,79 @@
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
+ disabled,
13
+ btnLabel = "Run Playbook",
14
+ }: {
15
+ btnClassName?: string;
16
+ buttonNode?: React.ReactNode;
17
+ size?: ButtonSizeType;
18
+ playbookId: string;
19
+ disabled?: boolean;
20
+ btnLabel?: string;
21
+ onInitiated: (playbookInstanceId: number) => void;
22
+ }) => {
23
+ const [isOpen, setIsOpen] = useState(false);
24
+
25
+ function open() {
26
+ setIsOpen(true);
27
+ }
28
+
29
+ function close() {
30
+ setIsOpen(false);
31
+ }
32
+
33
+ const onInitiatePlaybook = async (email: string) => {
34
+ const { playbookInstanceId, errorCode, details, message } =
35
+ (await initiatePlaybook({
36
+ bank: "public-sdk",
37
+ email,
38
+ timezone:
39
+ Intl.DateTimeFormat().resolvedOptions().timeZone ||
40
+ "America/Los_Angeles",
41
+ playbookUid: playbookId,
42
+ })) || {};
43
+
44
+ if (errorCode) {
45
+ throw new Error(
46
+ `Error initiating playbook: ${message} (Code: ${errorCode}) - Details: ${details}`,
47
+ );
48
+ }
49
+
50
+ onInitiated(playbookInstanceId);
51
+ };
52
+
53
+ return (
54
+ <>
55
+ {buttonNode ? (
56
+ { buttonNode }
57
+ ) : (
58
+ <Button
59
+ onClick={open}
60
+ className={btnClassName}
61
+ color="primary"
62
+ size={size}
63
+ disabled={disabled}
64
+ >
65
+ {btnLabel}
66
+ </Button>
67
+ )}
68
+
69
+ <InitiatePlaybookModal
70
+ isOpen={isOpen}
71
+ onClose={close}
72
+ onConfirm={async (email) => {
73
+ await onInitiatePlaybook(email);
74
+ close();
75
+ }}
76
+ />
77
+ </>
78
+ );
79
+ };