@autobe/ui 0.22.1 → 0.23.0
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/lib/components/AutoBeChatMain.d.ts +6 -4
- package/lib/components/AutoBeChatMain.js +204 -56
- package/lib/components/AutoBeChatMain.js.map +1 -1
- package/lib/components/AutoBeChatSidebar.d.ts +36 -0
- package/lib/components/AutoBeChatSidebar.js +227 -0
- package/lib/components/AutoBeChatSidebar.js.map +1 -0
- package/lib/components/AutoBeConfigButton.d.ts +15 -0
- package/lib/components/AutoBeConfigButton.js +33 -0
- package/lib/components/AutoBeConfigButton.js.map +1 -0
- package/lib/components/AutoBeConfigModal.d.ts +59 -0
- package/lib/components/AutoBeConfigModal.js +294 -0
- package/lib/components/AutoBeConfigModal.js.map +1 -0
- package/lib/components/AutoBeStatusButton.d.ts +12 -0
- package/lib/components/AutoBeStatusButton.js +29 -0
- package/lib/components/AutoBeStatusButton.js.map +1 -0
- package/lib/components/AutoBeStatusModal.js +35 -15
- package/lib/components/AutoBeStatusModal.js.map +1 -1
- package/lib/components/common/ActionButton.d.ts +16 -0
- package/lib/components/common/ActionButton.js +115 -0
- package/lib/components/common/ActionButton.js.map +1 -0
- package/lib/components/common/ActionButtonGroup.d.ts +13 -0
- package/lib/components/common/ActionButtonGroup.js +37 -0
- package/lib/components/common/ActionButtonGroup.js.map +1 -0
- package/lib/components/common/AutoBeConfigInput.d.ts +24 -0
- package/lib/components/common/AutoBeConfigInput.js +90 -0
- package/lib/components/common/AutoBeConfigInput.js.map +1 -0
- package/lib/components/common/CompactSessionIndicator.d.ts +16 -0
- package/lib/components/common/CompactSessionIndicator.js +46 -0
- package/lib/components/common/CompactSessionIndicator.js.map +1 -0
- package/lib/components/common/CompactSessionList.d.ts +22 -0
- package/lib/components/common/CompactSessionList.js +40 -0
- package/lib/components/common/CompactSessionList.js.map +1 -0
- package/lib/components/common/index.d.ts +6 -0
- package/lib/components/common/index.js +6 -0
- package/lib/components/common/index.js.map +1 -1
- package/lib/components/events/AutoBeEventGroupMovie.d.ts +6 -0
- package/lib/components/events/AutoBeEventGroupMovie.js +11 -0
- package/lib/components/events/AutoBeEventGroupMovie.js.map +1 -0
- package/lib/components/events/AutoBeEventMovie.js +5 -0
- package/lib/components/events/AutoBeEventMovie.js.map +1 -1
- package/lib/components/events/AutoBeValidateEventMovie.js +1 -3
- package/lib/components/events/AutoBeValidateEventMovie.js.map +1 -1
- package/lib/components/events/common/CollapsibleEventGroup.d.ts +1 -1
- package/lib/components/events/groups/ValidateEventGroup.d.ts +1 -1
- package/lib/components/events/utils/eventGrouper.js.map +1 -1
- package/lib/components/index.d.ts +6 -0
- package/lib/components/index.js +7 -0
- package/lib/components/index.js.map +1 -1
- package/lib/components/upload/AutoBeChatUploadBox.js +75 -33
- package/lib/components/upload/AutoBeChatUploadBox.js.map +1 -1
- package/lib/context/AutoBeAgentContext.d.ts +22 -11
- package/lib/context/AutoBeAgentContext.js +127 -11
- package/lib/context/AutoBeAgentContext.js.map +1 -1
- package/lib/context/AutoBeAgentSessionList.d.ts +12 -0
- package/lib/context/AutoBeAgentSessionList.js +37 -0
- package/lib/context/AutoBeAgentSessionList.js.map +1 -0
- package/lib/context/SearchParamsContext.d.ts +10 -0
- package/lib/context/SearchParamsContext.js +29 -0
- package/lib/context/SearchParamsContext.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -1
- package/lib/structure/AutoBeListener.d.ts +6 -0
- package/lib/structure/AutoBeListener.js +21 -4
- package/lib/structure/AutoBeListener.js.map +1 -1
- package/lib/structure/IAutoBeAgentSessionStorageStrategy.d.ts +35 -0
- package/lib/structure/IAutoBeAgentSessionStorageStrategy.js +30 -0
- package/lib/structure/IAutoBeAgentSessionStorageStrategy.js.map +1 -0
- package/lib/structure/index.d.ts +1 -0
- package/lib/structure/index.js +1 -0
- package/lib/structure/index.js.map +1 -1
- package/lib/types/config.d.ts +26 -0
- package/lib/types/config.js +14 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +18 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/__tests__/crypto.test.d.ts +1 -0
- package/lib/utils/__tests__/crypto.test.js +222 -0
- package/lib/utils/__tests__/crypto.test.js.map +1 -0
- package/lib/utils/__tests__/storage.test.d.ts +1 -0
- package/lib/utils/__tests__/storage.test.js +174 -0
- package/lib/utils/__tests__/storage.test.js.map +1 -0
- package/lib/utils/crypto.d.ts +18 -0
- package/lib/utils/crypto.js +84 -0
- package/lib/utils/crypto.js.map +1 -0
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/storage.d.ts +29 -0
- package/lib/utils/storage.js +93 -0
- package/lib/utils/storage.js.map +1 -0
- package/package.json +11 -3
- package/src/components/AutoBeChatMain.tsx +329 -131
- package/src/components/AutoBeChatSidebar.tsx +414 -0
- package/src/components/AutoBeConfigButton.tsx +83 -0
- package/src/components/AutoBeConfigModal.tsx +444 -0
- package/src/components/AutoBeStatusButton.tsx +75 -0
- package/src/components/AutoBeStatusModal.tsx +55 -54
- package/src/components/common/ActionButton.tsx +205 -0
- package/src/components/common/ActionButtonGroup.tsx +80 -0
- package/src/components/common/AutoBeConfigInput.tsx +185 -0
- package/src/components/common/CompactSessionIndicator.tsx +73 -0
- package/src/components/common/CompactSessionList.tsx +82 -0
- package/src/components/common/index.ts +6 -0
- package/src/components/events/AutoBeEventGroupMovie.tsx +18 -0
- package/src/components/events/AutoBeEventMovie.tsx +5 -0
- package/src/components/events/AutoBeValidateEventMovie.tsx +7 -9
- package/src/components/events/common/CollapsibleEventGroup.tsx +1 -1
- package/src/components/events/groups/ValidateEventGroup.tsx +1 -1
- package/src/components/events/utils/eventGrouper.tsx +2 -1
- package/src/components/index.ts +6 -0
- package/src/components/upload/AutoBeChatUploadBox.tsx +94 -44
- package/src/context/AutoBeAgentContext.tsx +201 -22
- package/src/context/AutoBeAgentSessionList.tsx +58 -0
- package/src/context/SearchParamsContext.tsx +49 -0
- package/src/index.ts +4 -0
- package/src/structure/AutoBeListener.ts +32 -6
- package/src/structure/IAutoBeAgentSessionStorageStrategy.ts +87 -0
- package/src/structure/index.ts +1 -0
- package/src/types/config.ts +44 -0
- package/src/types/index.ts +1 -0
- package/src/utils/__tests__/crypto.test.ts +286 -0
- package/src/utils/__tests__/storage.test.ts +229 -0
- package/src/utils/crypto.ts +95 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/storage.ts +96 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
export function ActionButton(props: ActionButton.IProps) {
|
|
2
|
+
//----
|
|
3
|
+
// STYLES
|
|
4
|
+
//----
|
|
5
|
+
const baseButtonStyle: React.CSSProperties = {
|
|
6
|
+
background: "rgba(255, 255, 255, 0.9)",
|
|
7
|
+
border: "1px solid rgba(0, 0, 0, 0.1)",
|
|
8
|
+
cursor: "pointer",
|
|
9
|
+
padding: "0.25rem",
|
|
10
|
+
borderRadius: "0.375rem",
|
|
11
|
+
display: "flex",
|
|
12
|
+
alignItems: "center",
|
|
13
|
+
justifyContent: "center",
|
|
14
|
+
color: "#4b5563",
|
|
15
|
+
transition: "all 0.2s ease",
|
|
16
|
+
width: "1.5rem",
|
|
17
|
+
height: "1.5rem",
|
|
18
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.1)",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const getHoverColors = (variant: ActionButton.Variant) => {
|
|
22
|
+
switch (variant) {
|
|
23
|
+
case "edit":
|
|
24
|
+
return {
|
|
25
|
+
backgroundColor: "#f1f5f9",
|
|
26
|
+
color: "#475569",
|
|
27
|
+
borderColor: "#cbd5e1",
|
|
28
|
+
boxShadow: "0 2px 4px rgba(71, 85, 105, 0.12)",
|
|
29
|
+
};
|
|
30
|
+
case "delete":
|
|
31
|
+
return {
|
|
32
|
+
backgroundColor: "#fef2f2",
|
|
33
|
+
color: "#dc2626",
|
|
34
|
+
borderColor: "#fecaca",
|
|
35
|
+
boxShadow: "0 2px 4px rgba(220, 38, 38, 0.15)",
|
|
36
|
+
};
|
|
37
|
+
case "save":
|
|
38
|
+
return {
|
|
39
|
+
backgroundColor: "#f0fdf4",
|
|
40
|
+
color: "#22c55e",
|
|
41
|
+
borderColor: "#bbf7d0",
|
|
42
|
+
boxShadow: "0 2px 4px rgba(34, 197, 94, 0.15)",
|
|
43
|
+
};
|
|
44
|
+
case "cancel":
|
|
45
|
+
return {
|
|
46
|
+
backgroundColor: "#fff1f2",
|
|
47
|
+
color: "#ef4444",
|
|
48
|
+
borderColor: "#fecdd3",
|
|
49
|
+
boxShadow: "0 2px 4px rgba(239, 68, 68, 0.15)",
|
|
50
|
+
};
|
|
51
|
+
default:
|
|
52
|
+
return {
|
|
53
|
+
backgroundColor: "#f1f5f9",
|
|
54
|
+
color: "#475569",
|
|
55
|
+
borderColor: "#cbd5e1",
|
|
56
|
+
boxShadow: "0 2px 4px rgba(71, 85, 105, 0.12)",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleMouseEnter = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
62
|
+
const hoverColors = getHoverColors(props.variant);
|
|
63
|
+
e.currentTarget.style.backgroundColor = hoverColors.backgroundColor;
|
|
64
|
+
e.currentTarget.style.color = hoverColors.color;
|
|
65
|
+
e.currentTarget.style.borderColor = hoverColors.borderColor;
|
|
66
|
+
e.currentTarget.style.boxShadow = hoverColors.boxShadow;
|
|
67
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const handleMouseLeave = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
71
|
+
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.9)";
|
|
72
|
+
e.currentTarget.style.color = "#4b5563";
|
|
73
|
+
e.currentTarget.style.borderColor = "rgba(0, 0, 0, 0.1)";
|
|
74
|
+
e.currentTarget.style.boxShadow = "0 1px 2px rgba(0, 0, 0, 0.1)";
|
|
75
|
+
e.currentTarget.style.transform = "translateY(0)";
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
//----
|
|
79
|
+
// ICONS
|
|
80
|
+
//----
|
|
81
|
+
const renderIcon = () => {
|
|
82
|
+
switch (props.variant) {
|
|
83
|
+
case "edit":
|
|
84
|
+
return (
|
|
85
|
+
<svg
|
|
86
|
+
width="12"
|
|
87
|
+
height="12"
|
|
88
|
+
viewBox="0 0 24 24"
|
|
89
|
+
fill="none"
|
|
90
|
+
stroke="currentColor"
|
|
91
|
+
strokeWidth="2"
|
|
92
|
+
strokeLinecap="round"
|
|
93
|
+
strokeLinejoin="round"
|
|
94
|
+
>
|
|
95
|
+
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
|
|
96
|
+
<path d="m18.5 2.5 a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4Z" />
|
|
97
|
+
</svg>
|
|
98
|
+
);
|
|
99
|
+
case "delete":
|
|
100
|
+
return (
|
|
101
|
+
<svg
|
|
102
|
+
width="12"
|
|
103
|
+
height="12"
|
|
104
|
+
viewBox="0 0 24 24"
|
|
105
|
+
fill="none"
|
|
106
|
+
stroke="currentColor"
|
|
107
|
+
strokeWidth="2.5"
|
|
108
|
+
strokeLinecap="round"
|
|
109
|
+
strokeLinejoin="round"
|
|
110
|
+
>
|
|
111
|
+
<path d="M18 6L6 18" />
|
|
112
|
+
<path d="M6 6l12 12" />
|
|
113
|
+
</svg>
|
|
114
|
+
);
|
|
115
|
+
case "save":
|
|
116
|
+
return (
|
|
117
|
+
<svg
|
|
118
|
+
width="12"
|
|
119
|
+
height="12"
|
|
120
|
+
viewBox="0 0 24 24"
|
|
121
|
+
fill="none"
|
|
122
|
+
stroke="currentColor"
|
|
123
|
+
strokeWidth="2.5"
|
|
124
|
+
strokeLinecap="round"
|
|
125
|
+
strokeLinejoin="round"
|
|
126
|
+
>
|
|
127
|
+
<polyline points="20,6 9,17 4,12" />
|
|
128
|
+
</svg>
|
|
129
|
+
);
|
|
130
|
+
case "cancel":
|
|
131
|
+
return (
|
|
132
|
+
<svg
|
|
133
|
+
width="12"
|
|
134
|
+
height="12"
|
|
135
|
+
viewBox="0 0 24 24"
|
|
136
|
+
fill="none"
|
|
137
|
+
stroke="currentColor"
|
|
138
|
+
strokeWidth="2.5"
|
|
139
|
+
strokeLinecap="round"
|
|
140
|
+
strokeLinejoin="round"
|
|
141
|
+
>
|
|
142
|
+
<path d="M18 6L6 18" />
|
|
143
|
+
<path d="M6 6l12 12" />
|
|
144
|
+
</svg>
|
|
145
|
+
);
|
|
146
|
+
default:
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const getTitle = () => {
|
|
152
|
+
switch (props.variant) {
|
|
153
|
+
case "edit":
|
|
154
|
+
return "Edit title";
|
|
155
|
+
case "delete":
|
|
156
|
+
return "Delete conversation";
|
|
157
|
+
case "save":
|
|
158
|
+
return "Save changes";
|
|
159
|
+
case "cancel":
|
|
160
|
+
return "Cancel editing";
|
|
161
|
+
default:
|
|
162
|
+
return "";
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
//----
|
|
167
|
+
// RENDER
|
|
168
|
+
//----
|
|
169
|
+
return (
|
|
170
|
+
<button
|
|
171
|
+
onClick={props.onClick}
|
|
172
|
+
onMouseEnter={handleMouseEnter}
|
|
173
|
+
onMouseLeave={handleMouseLeave}
|
|
174
|
+
style={{
|
|
175
|
+
...baseButtonStyle,
|
|
176
|
+
...props.style,
|
|
177
|
+
}}
|
|
178
|
+
title={props.title ?? getTitle()}
|
|
179
|
+
disabled={props.disabled}
|
|
180
|
+
>
|
|
181
|
+
{renderIcon()}
|
|
182
|
+
</button>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export namespace ActionButton {
|
|
187
|
+
export type Variant = "edit" | "delete" | "save" | "cancel";
|
|
188
|
+
|
|
189
|
+
export interface IProps {
|
|
190
|
+
/** Button variant that determines icon and hover colors */
|
|
191
|
+
variant: Variant;
|
|
192
|
+
|
|
193
|
+
/** Click handler */
|
|
194
|
+
onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
195
|
+
|
|
196
|
+
/** Custom title for tooltip */
|
|
197
|
+
title?: string;
|
|
198
|
+
|
|
199
|
+
/** Whether button is disabled */
|
|
200
|
+
disabled?: boolean;
|
|
201
|
+
|
|
202
|
+
/** Custom style overrides */
|
|
203
|
+
style?: React.CSSProperties;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ActionButton } from "./ActionButton";
|
|
2
|
+
|
|
3
|
+
export function ActionButtonGroup(props: ActionButtonGroup.IProps) {
|
|
4
|
+
//----
|
|
5
|
+
// STYLES
|
|
6
|
+
//----
|
|
7
|
+
const containerStyle: React.CSSProperties = {
|
|
8
|
+
display: "flex",
|
|
9
|
+
alignItems: "center",
|
|
10
|
+
gap: "0.375rem",
|
|
11
|
+
flexShrink: 0,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
//----
|
|
15
|
+
// RENDER
|
|
16
|
+
//----
|
|
17
|
+
return (
|
|
18
|
+
<div style={containerStyle}>
|
|
19
|
+
{/* Edit button */}
|
|
20
|
+
{props.onEdit && (
|
|
21
|
+
<ActionButton
|
|
22
|
+
variant="edit"
|
|
23
|
+
onClick={(e) => {
|
|
24
|
+
e.stopPropagation();
|
|
25
|
+
props.onEdit?.();
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
)}
|
|
29
|
+
|
|
30
|
+
{/* Delete button */}
|
|
31
|
+
{props.onDelete && (
|
|
32
|
+
<ActionButton
|
|
33
|
+
variant="delete"
|
|
34
|
+
onClick={(e) => {
|
|
35
|
+
e.stopPropagation();
|
|
36
|
+
props.onDelete?.();
|
|
37
|
+
}}
|
|
38
|
+
/>
|
|
39
|
+
)}
|
|
40
|
+
|
|
41
|
+
{/* Save button */}
|
|
42
|
+
{props.onSave && (
|
|
43
|
+
<ActionButton
|
|
44
|
+
variant="save"
|
|
45
|
+
onClick={(e) => {
|
|
46
|
+
e.stopPropagation();
|
|
47
|
+
props.onSave?.();
|
|
48
|
+
}}
|
|
49
|
+
/>
|
|
50
|
+
)}
|
|
51
|
+
|
|
52
|
+
{/* Cancel button */}
|
|
53
|
+
{props.onCancel && (
|
|
54
|
+
<ActionButton
|
|
55
|
+
variant="cancel"
|
|
56
|
+
onClick={(e) => {
|
|
57
|
+
e.stopPropagation();
|
|
58
|
+
props.onCancel?.();
|
|
59
|
+
}}
|
|
60
|
+
/>
|
|
61
|
+
)}
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export namespace ActionButtonGroup {
|
|
67
|
+
export interface IProps {
|
|
68
|
+
/** Edit handler - if provided, edit button will be shown */
|
|
69
|
+
onEdit?: () => void;
|
|
70
|
+
|
|
71
|
+
/** Delete handler - if provided, delete button will be shown */
|
|
72
|
+
onDelete?: () => void;
|
|
73
|
+
|
|
74
|
+
/** Save handler - if provided, save button will be shown */
|
|
75
|
+
onSave?: () => void;
|
|
76
|
+
|
|
77
|
+
/** Cancel handler - if provided, cancel button will be shown */
|
|
78
|
+
onCancel?: () => void;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
export interface IAutoBeConfigInputProps {
|
|
4
|
+
label: string;
|
|
5
|
+
value: string | number;
|
|
6
|
+
onChange: (value: string) => void;
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
type?: "text" | "password" | "url" | "number" | "list";
|
|
9
|
+
icon?: string;
|
|
10
|
+
suggestions?: Array<{ value: string; label?: string }>;
|
|
11
|
+
min?: number;
|
|
12
|
+
max?: number;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
required?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Common input component for configuration forms Supports text, password, url,
|
|
20
|
+
* and number inputs with optional suggestions
|
|
21
|
+
*/
|
|
22
|
+
export const AutoBeConfigInput = (props: IAutoBeConfigInputProps) => {
|
|
23
|
+
const {
|
|
24
|
+
label,
|
|
25
|
+
value,
|
|
26
|
+
onChange,
|
|
27
|
+
placeholder,
|
|
28
|
+
type = "text",
|
|
29
|
+
icon,
|
|
30
|
+
suggestions,
|
|
31
|
+
min,
|
|
32
|
+
max,
|
|
33
|
+
style,
|
|
34
|
+
disabled = false,
|
|
35
|
+
required = false,
|
|
36
|
+
} = props;
|
|
37
|
+
|
|
38
|
+
console.log("suggestions", suggestions);
|
|
39
|
+
const suggestionId = `suggestions-${label.replace(/\s+/g, "-").toLowerCase()}`;
|
|
40
|
+
|
|
41
|
+
// Check if field is required and empty
|
|
42
|
+
const isEmpty =
|
|
43
|
+
value === "" || (typeof value === "string" && value.trim() === "");
|
|
44
|
+
const isRequiredEmpty = required && isEmpty;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div style={{ ...style }}>
|
|
48
|
+
<label
|
|
49
|
+
style={{
|
|
50
|
+
display: "block",
|
|
51
|
+
fontSize: "0.875rem",
|
|
52
|
+
fontWeight: "500",
|
|
53
|
+
color: isRequiredEmpty ? "#dc3545" : "#374151",
|
|
54
|
+
marginBottom: "0.5rem",
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
{icon && `${icon} `}
|
|
58
|
+
{label}
|
|
59
|
+
{required && (
|
|
60
|
+
<span style={{ color: "#dc3545", marginLeft: "0.25rem" }}>*</span>
|
|
61
|
+
)}
|
|
62
|
+
</label>
|
|
63
|
+
{type === "list" ? (
|
|
64
|
+
<select
|
|
65
|
+
value={value}
|
|
66
|
+
onChange={(e) => onChange(e.target.value)}
|
|
67
|
+
disabled={disabled}
|
|
68
|
+
style={{
|
|
69
|
+
width: "100%",
|
|
70
|
+
padding: "0.75rem",
|
|
71
|
+
border: `1px solid ${isRequiredEmpty ? "#dc3545" : "#d1d5db"}`,
|
|
72
|
+
borderRadius: "8px",
|
|
73
|
+
fontSize: "0.875rem",
|
|
74
|
+
transition: "border-color 0.2s ease",
|
|
75
|
+
outline: "none",
|
|
76
|
+
boxSizing: "border-box",
|
|
77
|
+
backgroundColor: disabled
|
|
78
|
+
? "#f9fafb"
|
|
79
|
+
: isRequiredEmpty
|
|
80
|
+
? "#fef2f2"
|
|
81
|
+
: "white",
|
|
82
|
+
color: disabled ? "#9ca3af" : "#000000",
|
|
83
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
84
|
+
}}
|
|
85
|
+
onFocus={(e) => {
|
|
86
|
+
if (!disabled && !isRequiredEmpty) {
|
|
87
|
+
e.currentTarget.style.borderColor = "#3b82f6";
|
|
88
|
+
}
|
|
89
|
+
}}
|
|
90
|
+
onBlur={(e) => {
|
|
91
|
+
if (!disabled) {
|
|
92
|
+
const newIsEmpty =
|
|
93
|
+
e.currentTarget.value === "" ||
|
|
94
|
+
e.currentTarget.value.trim() === "";
|
|
95
|
+
const newIsRequiredEmpty = required && newIsEmpty;
|
|
96
|
+
e.currentTarget.style.borderColor = newIsRequiredEmpty
|
|
97
|
+
? "#dc3545"
|
|
98
|
+
: "#d1d5db";
|
|
99
|
+
}
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
{placeholder && (
|
|
103
|
+
<option value="" disabled>
|
|
104
|
+
{placeholder}
|
|
105
|
+
</option>
|
|
106
|
+
)}
|
|
107
|
+
{suggestions?.map((suggestion, index) => (
|
|
108
|
+
<option key={index} value={suggestion.value}>
|
|
109
|
+
{suggestion.label || suggestion.value}
|
|
110
|
+
</option>
|
|
111
|
+
))}
|
|
112
|
+
</select>
|
|
113
|
+
) : (
|
|
114
|
+
<input
|
|
115
|
+
type={type}
|
|
116
|
+
value={value}
|
|
117
|
+
onChange={(e) => onChange(e.target.value)}
|
|
118
|
+
placeholder={placeholder}
|
|
119
|
+
list={suggestions ? suggestionId : undefined}
|
|
120
|
+
min={min}
|
|
121
|
+
max={max}
|
|
122
|
+
disabled={disabled}
|
|
123
|
+
style={{
|
|
124
|
+
width: "100%",
|
|
125
|
+
padding: "0.75rem",
|
|
126
|
+
border: `1px solid ${isRequiredEmpty ? "#dc3545" : "#d1d5db"}`,
|
|
127
|
+
borderRadius: "8px",
|
|
128
|
+
fontSize: "0.875rem",
|
|
129
|
+
transition: "border-color 0.2s ease",
|
|
130
|
+
outline: "none",
|
|
131
|
+
boxSizing: "border-box",
|
|
132
|
+
backgroundColor: disabled
|
|
133
|
+
? "#f9fafb"
|
|
134
|
+
: isRequiredEmpty
|
|
135
|
+
? "#fef2f2"
|
|
136
|
+
: "white",
|
|
137
|
+
color: disabled ? "#9ca3af" : "#000000",
|
|
138
|
+
}}
|
|
139
|
+
onFocus={(e) => {
|
|
140
|
+
if (!disabled && !isRequiredEmpty) {
|
|
141
|
+
e.currentTarget.style.borderColor = "#3b82f6";
|
|
142
|
+
}
|
|
143
|
+
}}
|
|
144
|
+
onBlur={(e) => {
|
|
145
|
+
if (!disabled) {
|
|
146
|
+
const newIsEmpty =
|
|
147
|
+
e.currentTarget.value === "" ||
|
|
148
|
+
e.currentTarget.value.trim() === "";
|
|
149
|
+
const newIsRequiredEmpty = required && newIsEmpty;
|
|
150
|
+
e.currentTarget.style.borderColor = newIsRequiredEmpty
|
|
151
|
+
? "#dc3545"
|
|
152
|
+
: "#d1d5db";
|
|
153
|
+
}
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
156
|
+
)}
|
|
157
|
+
{isRequiredEmpty && (
|
|
158
|
+
<div
|
|
159
|
+
style={{
|
|
160
|
+
fontSize: "0.75rem",
|
|
161
|
+
color: "#dc3545",
|
|
162
|
+
marginTop: "0.25rem",
|
|
163
|
+
display: "flex",
|
|
164
|
+
alignItems: "center",
|
|
165
|
+
gap: "0.25rem",
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
<span>⚠️</span>
|
|
169
|
+
This field is required
|
|
170
|
+
</div>
|
|
171
|
+
)}
|
|
172
|
+
{suggestions && type !== "list" && (
|
|
173
|
+
<datalist id={suggestionId}>
|
|
174
|
+
{suggestions.map((suggestion, index) => (
|
|
175
|
+
<option key={index} value={suggestion.value}>
|
|
176
|
+
{suggestion.label || suggestion.value}
|
|
177
|
+
</option>
|
|
178
|
+
))}
|
|
179
|
+
</datalist>
|
|
180
|
+
)}
|
|
181
|
+
</div>
|
|
182
|
+
);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export default AutoBeConfigInput;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { IAutoBeAgentSession } from "../../structure";
|
|
2
|
+
|
|
3
|
+
export function CompactSessionIndicator(props: CompactSessionIndicator.IProps) {
|
|
4
|
+
//----
|
|
5
|
+
// EVENT HANDLERS
|
|
6
|
+
//----
|
|
7
|
+
const handleMouseEnter = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
8
|
+
if (!props.isActive) {
|
|
9
|
+
e.currentTarget.style.backgroundColor = "#e5e7eb";
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const handleMouseLeave = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
14
|
+
if (!props.isActive) {
|
|
15
|
+
e.currentTarget.style.backgroundColor = "#f3f4f6";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const handleClick = () => {
|
|
20
|
+
props.onSelect?.(props.session.id);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//----
|
|
24
|
+
// STYLES
|
|
25
|
+
//----
|
|
26
|
+
const indicatorStyle: React.CSSProperties = {
|
|
27
|
+
width: "36px",
|
|
28
|
+
height: "36px",
|
|
29
|
+
borderRadius: "0.5rem",
|
|
30
|
+
backgroundColor: props.isActive ? "#3b82f6" : "#f3f4f6",
|
|
31
|
+
display: "flex",
|
|
32
|
+
alignItems: "center",
|
|
33
|
+
justifyContent: "center",
|
|
34
|
+
cursor: "pointer",
|
|
35
|
+
transition: "all 0.2s ease",
|
|
36
|
+
margin: "0 auto",
|
|
37
|
+
color: props.isActive ? "#ffffff" : "#6b7280",
|
|
38
|
+
fontSize: "0.875rem",
|
|
39
|
+
fontWeight: "500",
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
//----
|
|
43
|
+
// RENDER
|
|
44
|
+
//----
|
|
45
|
+
return (
|
|
46
|
+
<div
|
|
47
|
+
style={indicatorStyle}
|
|
48
|
+
onMouseEnter={handleMouseEnter}
|
|
49
|
+
onMouseLeave={handleMouseLeave}
|
|
50
|
+
onClick={handleClick}
|
|
51
|
+
title={props.session.title}
|
|
52
|
+
>
|
|
53
|
+
{props.session.title.charAt(0).toUpperCase()}
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export namespace CompactSessionIndicator {
|
|
59
|
+
export interface IProps {
|
|
60
|
+
/** Session data to display */
|
|
61
|
+
session: IAutoBeAgentSession;
|
|
62
|
+
|
|
63
|
+
/** Whether this session is currently active */
|
|
64
|
+
isActive: boolean;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Callback when session indicator is clicked
|
|
68
|
+
*
|
|
69
|
+
* @param sessionId - ID of the selected session
|
|
70
|
+
*/
|
|
71
|
+
onSelect?: (sessionId: string) => void;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { IAutoBeAgentSession } from "../../structure";
|
|
2
|
+
import { CompactSessionIndicator } from "./CompactSessionIndicator";
|
|
3
|
+
|
|
4
|
+
export function CompactSessionList(props: CompactSessionList.IProps) {
|
|
5
|
+
//----
|
|
6
|
+
// VARIABLES
|
|
7
|
+
//----
|
|
8
|
+
const maxItems = props.maxItems ?? 8;
|
|
9
|
+
const displaySessions = props.sessions.slice(0, maxItems);
|
|
10
|
+
const remainingCount = props.sessions.length - maxItems;
|
|
11
|
+
|
|
12
|
+
//----
|
|
13
|
+
// STYLES
|
|
14
|
+
//----
|
|
15
|
+
const containerStyle: React.CSSProperties = {
|
|
16
|
+
display: "flex",
|
|
17
|
+
flexDirection: "column",
|
|
18
|
+
gap: "0.5rem",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const remainingIndicatorStyle: React.CSSProperties = {
|
|
22
|
+
width: "36px",
|
|
23
|
+
height: "36px",
|
|
24
|
+
borderRadius: "0.5rem",
|
|
25
|
+
backgroundColor: "#f3f4f6",
|
|
26
|
+
display: "flex",
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
justifyContent: "center",
|
|
29
|
+
margin: "0 auto",
|
|
30
|
+
color: "#6b7280",
|
|
31
|
+
fontSize: "0.75rem",
|
|
32
|
+
fontWeight: "500",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
//----
|
|
36
|
+
// RENDER
|
|
37
|
+
//----
|
|
38
|
+
return (
|
|
39
|
+
<div style={containerStyle}>
|
|
40
|
+
{displaySessions.map((session) => (
|
|
41
|
+
<CompactSessionIndicator
|
|
42
|
+
key={session.id}
|
|
43
|
+
session={session}
|
|
44
|
+
isActive={session.id === props.activeSessionId}
|
|
45
|
+
onSelect={props.onSessionSelect}
|
|
46
|
+
/>
|
|
47
|
+
))}
|
|
48
|
+
{remainingCount > 0 && (
|
|
49
|
+
<div
|
|
50
|
+
style={remainingIndicatorStyle}
|
|
51
|
+
title={`+${remainingCount} more conversations`}
|
|
52
|
+
>
|
|
53
|
+
+{remainingCount}
|
|
54
|
+
</div>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export namespace CompactSessionList {
|
|
61
|
+
export interface IProps {
|
|
62
|
+
/** List of sessions to display */
|
|
63
|
+
sessions: IAutoBeAgentSession[];
|
|
64
|
+
|
|
65
|
+
/** Currently active session ID */
|
|
66
|
+
activeSessionId?: string | null;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Maximum number of sessions to display
|
|
70
|
+
*
|
|
71
|
+
* @default 8
|
|
72
|
+
*/
|
|
73
|
+
maxItems?: number;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Callback when a session is selected
|
|
77
|
+
*
|
|
78
|
+
* @param sessionId - ID of the selected session
|
|
79
|
+
*/
|
|
80
|
+
onSessionSelect?: (sessionId: string) => void;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
export * from "./ActionButton";
|
|
2
|
+
export * from "./ActionButtonGroup";
|
|
3
|
+
export * from "./AutoBeConfigInput";
|
|
1
4
|
export * from "./Collapsible";
|
|
2
5
|
export * from "./ChatBubble";
|
|
6
|
+
export * from "./CompactSessionIndicator";
|
|
7
|
+
export * from "./CompactSessionList";
|
|
8
|
+
export * from "./openai";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IAutoBeEventGroup } from "../../structure";
|
|
2
|
+
import { AutoBeEventMovie } from "./AutoBeEventMovie";
|
|
3
|
+
|
|
4
|
+
export interface IAutoBeEventGroupMovieProps {
|
|
5
|
+
eventGroups: IAutoBeEventGroup[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const AutoBeEventGroupMovie = (props: IAutoBeEventGroupMovieProps) => {
|
|
9
|
+
return props.eventGroups.map((e, index) => (
|
|
10
|
+
<AutoBeEventMovie
|
|
11
|
+
key={index}
|
|
12
|
+
events={e.events}
|
|
13
|
+
last={index === props.eventGroups.length - 1}
|
|
14
|
+
/>
|
|
15
|
+
));
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default AutoBeEventGroupMovie;
|
|
@@ -26,6 +26,10 @@ export function AutoBeEventMovie<Event extends AutoBeEvent>(
|
|
|
26
26
|
) {
|
|
27
27
|
const { service } = useAutoBeAgent();
|
|
28
28
|
|
|
29
|
+
if (service === null) {
|
|
30
|
+
console.error("Service is not available");
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
29
33
|
const back: Event = props.events[props.events.length - 1]!;
|
|
30
34
|
switch (back.type) {
|
|
31
35
|
case "userMessage":
|
|
@@ -117,6 +121,7 @@ export function AutoBeEventMovie<Event extends AutoBeEvent>(
|
|
|
117
121
|
case "realizeAuthorizationComplete":
|
|
118
122
|
case "vendorRequest":
|
|
119
123
|
case "vendorResponse":
|
|
124
|
+
case "vendorTimeout":
|
|
120
125
|
case "jsonParseError":
|
|
121
126
|
case "jsonValidateError":
|
|
122
127
|
case "consentFunctionCall":
|