@autobe/ui 0.22.1 → 0.23.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 (128) hide show
  1. package/lib/components/AutoBeChatMain.d.ts +6 -4
  2. package/lib/components/AutoBeChatMain.js +204 -56
  3. package/lib/components/AutoBeChatMain.js.map +1 -1
  4. package/lib/components/AutoBeChatSidebar.d.ts +36 -0
  5. package/lib/components/AutoBeChatSidebar.js +227 -0
  6. package/lib/components/AutoBeChatSidebar.js.map +1 -0
  7. package/lib/components/AutoBeConfigButton.d.ts +15 -0
  8. package/lib/components/AutoBeConfigButton.js +33 -0
  9. package/lib/components/AutoBeConfigButton.js.map +1 -0
  10. package/lib/components/AutoBeConfigModal.d.ts +59 -0
  11. package/lib/components/AutoBeConfigModal.js +294 -0
  12. package/lib/components/AutoBeConfigModal.js.map +1 -0
  13. package/lib/components/AutoBeStatusButton.d.ts +12 -0
  14. package/lib/components/AutoBeStatusButton.js +29 -0
  15. package/lib/components/AutoBeStatusButton.js.map +1 -0
  16. package/lib/components/AutoBeStatusModal.js +35 -15
  17. package/lib/components/AutoBeStatusModal.js.map +1 -1
  18. package/lib/components/common/ActionButton.d.ts +16 -0
  19. package/lib/components/common/ActionButton.js +115 -0
  20. package/lib/components/common/ActionButton.js.map +1 -0
  21. package/lib/components/common/ActionButtonGroup.d.ts +13 -0
  22. package/lib/components/common/ActionButtonGroup.js +37 -0
  23. package/lib/components/common/ActionButtonGroup.js.map +1 -0
  24. package/lib/components/common/AutoBeConfigInput.d.ts +24 -0
  25. package/lib/components/common/AutoBeConfigInput.js +90 -0
  26. package/lib/components/common/AutoBeConfigInput.js.map +1 -0
  27. package/lib/components/common/CompactSessionIndicator.d.ts +16 -0
  28. package/lib/components/common/CompactSessionIndicator.js +46 -0
  29. package/lib/components/common/CompactSessionIndicator.js.map +1 -0
  30. package/lib/components/common/CompactSessionList.d.ts +22 -0
  31. package/lib/components/common/CompactSessionList.js +40 -0
  32. package/lib/components/common/CompactSessionList.js.map +1 -0
  33. package/lib/components/common/index.d.ts +6 -0
  34. package/lib/components/common/index.js +6 -0
  35. package/lib/components/common/index.js.map +1 -1
  36. package/lib/components/events/AutoBeEventGroupMovie.d.ts +6 -0
  37. package/lib/components/events/AutoBeEventGroupMovie.js +11 -0
  38. package/lib/components/events/AutoBeEventGroupMovie.js.map +1 -0
  39. package/lib/components/events/AutoBeEventMovie.js +5 -0
  40. package/lib/components/events/AutoBeEventMovie.js.map +1 -1
  41. package/lib/components/events/AutoBeValidateEventMovie.js +1 -3
  42. package/lib/components/events/AutoBeValidateEventMovie.js.map +1 -1
  43. package/lib/components/events/common/CollapsibleEventGroup.d.ts +1 -1
  44. package/lib/components/events/groups/ValidateEventGroup.d.ts +1 -1
  45. package/lib/components/events/utils/eventGrouper.js.map +1 -1
  46. package/lib/components/index.d.ts +6 -0
  47. package/lib/components/index.js +7 -0
  48. package/lib/components/index.js.map +1 -1
  49. package/lib/components/upload/AutoBeChatUploadBox.js +75 -33
  50. package/lib/components/upload/AutoBeChatUploadBox.js.map +1 -1
  51. package/lib/context/AutoBeAgentContext.d.ts +22 -11
  52. package/lib/context/AutoBeAgentContext.js +127 -11
  53. package/lib/context/AutoBeAgentContext.js.map +1 -1
  54. package/lib/context/AutoBeAgentSessionList.d.ts +12 -0
  55. package/lib/context/AutoBeAgentSessionList.js +37 -0
  56. package/lib/context/AutoBeAgentSessionList.js.map +1 -0
  57. package/lib/context/SearchParamsContext.d.ts +10 -0
  58. package/lib/context/SearchParamsContext.js +29 -0
  59. package/lib/context/SearchParamsContext.js.map +1 -0
  60. package/lib/index.d.ts +4 -0
  61. package/lib/index.js +4 -0
  62. package/lib/index.js.map +1 -1
  63. package/lib/structure/AutoBeListener.d.ts +6 -0
  64. package/lib/structure/AutoBeListener.js +21 -4
  65. package/lib/structure/AutoBeListener.js.map +1 -1
  66. package/lib/structure/IAutoBeAgentSessionStorageStrategy.d.ts +35 -0
  67. package/lib/structure/IAutoBeAgentSessionStorageStrategy.js +30 -0
  68. package/lib/structure/IAutoBeAgentSessionStorageStrategy.js.map +1 -0
  69. package/lib/structure/index.d.ts +1 -0
  70. package/lib/structure/index.js +1 -0
  71. package/lib/structure/index.js.map +1 -1
  72. package/lib/types/config.d.ts +26 -0
  73. package/lib/types/config.js +14 -0
  74. package/lib/types/config.js.map +1 -0
  75. package/lib/types/index.d.ts +1 -0
  76. package/lib/types/index.js +18 -0
  77. package/lib/types/index.js.map +1 -0
  78. package/lib/utils/__tests__/crypto.test.d.ts +1 -0
  79. package/lib/utils/__tests__/crypto.test.js +222 -0
  80. package/lib/utils/__tests__/crypto.test.js.map +1 -0
  81. package/lib/utils/__tests__/storage.test.d.ts +1 -0
  82. package/lib/utils/__tests__/storage.test.js +174 -0
  83. package/lib/utils/__tests__/storage.test.js.map +1 -0
  84. package/lib/utils/crypto.d.ts +18 -0
  85. package/lib/utils/crypto.js +84 -0
  86. package/lib/utils/crypto.js.map +1 -0
  87. package/lib/utils/index.d.ts +2 -0
  88. package/lib/utils/index.js +2 -0
  89. package/lib/utils/index.js.map +1 -1
  90. package/lib/utils/storage.d.ts +29 -0
  91. package/lib/utils/storage.js +93 -0
  92. package/lib/utils/storage.js.map +1 -0
  93. package/package.json +11 -3
  94. package/src/components/AutoBeChatMain.tsx +329 -131
  95. package/src/components/AutoBeChatSidebar.tsx +414 -0
  96. package/src/components/AutoBeConfigButton.tsx +83 -0
  97. package/src/components/AutoBeConfigModal.tsx +444 -0
  98. package/src/components/AutoBeStatusButton.tsx +75 -0
  99. package/src/components/AutoBeStatusModal.tsx +55 -54
  100. package/src/components/common/ActionButton.tsx +205 -0
  101. package/src/components/common/ActionButtonGroup.tsx +80 -0
  102. package/src/components/common/AutoBeConfigInput.tsx +185 -0
  103. package/src/components/common/CompactSessionIndicator.tsx +73 -0
  104. package/src/components/common/CompactSessionList.tsx +82 -0
  105. package/src/components/common/index.ts +6 -0
  106. package/src/components/events/AutoBeEventGroupMovie.tsx +18 -0
  107. package/src/components/events/AutoBeEventMovie.tsx +5 -0
  108. package/src/components/events/AutoBeValidateEventMovie.tsx +7 -9
  109. package/src/components/events/common/CollapsibleEventGroup.tsx +1 -1
  110. package/src/components/events/groups/ValidateEventGroup.tsx +1 -1
  111. package/src/components/events/utils/eventGrouper.tsx +2 -1
  112. package/src/components/index.ts +6 -0
  113. package/src/components/upload/AutoBeChatUploadBox.tsx +94 -44
  114. package/src/context/AutoBeAgentContext.tsx +201 -22
  115. package/src/context/AutoBeAgentSessionList.tsx +58 -0
  116. package/src/context/SearchParamsContext.tsx +49 -0
  117. package/src/index.ts +4 -0
  118. package/src/structure/AutoBeListener.ts +32 -6
  119. package/src/structure/IAutoBeAgentSessionStorageStrategy.ts +87 -0
  120. package/src/structure/index.ts +1 -0
  121. package/src/types/config.ts +44 -0
  122. package/src/types/index.ts +1 -0
  123. package/src/utils/__tests__/crypto.test.ts +286 -0
  124. package/src/utils/__tests__/storage.test.ts +229 -0
  125. package/src/utils/crypto.ts +95 -0
  126. package/src/utils/index.ts +2 -0
  127. package/src/utils/storage.ts +96 -0
  128. 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":