chordia-ui 3.7.2 → 3.7.4

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 (36) hide show
  1. package/dist/CustomFilterChips.cjs.js +1 -1
  2. package/dist/CustomFilterChips.cjs.js.map +1 -1
  3. package/dist/CustomFilterChips.es.js +239 -125
  4. package/dist/CustomFilterChips.es.js.map +1 -1
  5. package/dist/DataTable2.cjs.js +2 -0
  6. package/dist/DataTable2.cjs.js.map +1 -0
  7. package/dist/DataTable2.es.js +1863 -0
  8. package/dist/DataTable2.es.js.map +1 -0
  9. package/dist/components/UpdatedInteractionDetails.cjs.js +2 -2
  10. package/dist/components/UpdatedInteractionDetails.cjs.js.map +1 -1
  11. package/dist/components/UpdatedInteractionDetails.es.js +14 -13
  12. package/dist/components/UpdatedInteractionDetails.es.js.map +1 -1
  13. package/dist/components/data.cjs.js +1 -1
  14. package/dist/components/data.cjs.js.map +1 -1
  15. package/dist/components/data.es.js +157 -153
  16. package/dist/components/data.es.js.map +1 -1
  17. package/dist/components/performance.cjs.js +1 -1
  18. package/dist/components/performance.cjs.js.map +1 -1
  19. package/dist/components/performance.es.js +1900 -480
  20. package/dist/components/performance.es.js.map +1 -1
  21. package/dist/index.cjs.js +1 -1
  22. package/dist/index.es.js +94 -89
  23. package/dist/index.es.js.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/UpdatedInteractionDetails/UpdatedInteractionDetails.jsx +13 -13
  26. package/src/components/UpdatedInteractionDetails/UpdatedThreads.jsx +1 -0
  27. package/src/components/common/CustomFilterChips.jsx +5 -1
  28. package/src/components/common/Pagination.jsx +152 -39
  29. package/src/components/data/DataTable2.jsx +2449 -0
  30. package/src/components/data/DataTableFilters2.jsx +186 -0
  31. package/src/components/data/index.js +2 -0
  32. package/src/components/index.js +2 -2
  33. package/src/components/performance/PerformanceDetailsPage.jsx +940 -0
  34. package/src/components/performance/PerformancePanel.jsx +423 -297
  35. package/src/components/performance/SupervisorSelect.jsx +386 -0
  36. package/src/components/performance/index.js +3 -1
@@ -0,0 +1,386 @@
1
+ "use client";
2
+
3
+ import React from "react";
4
+ import { Search, Check } from "lucide-react";
5
+
6
+ const C = {
7
+ white: "#FFFFFF",
8
+ black: "#0B0B0B",
9
+ borderSubtle: "#E6E6E6",
10
+ border: "#D9D9D9",
11
+ searchBg: "#D8D8D8",
12
+ rowSelected: "#F2F2F0",
13
+ textMuted: "#989898",
14
+ textMid: "#676767",
15
+ textDark: "#323232",
16
+ applyBg: "#2E3236",
17
+ scrollbar: "#D5D9E2",
18
+ };
19
+
20
+ const FONT = "var(--font-sans, 'Averta', ui-sans-serif, system-ui, sans-serif)";
21
+
22
+ function Checkbox({ checked, mutedFill = false }) {
23
+ return (
24
+ <span
25
+ style={{
26
+ width: 20,
27
+ height: 20,
28
+ borderRadius: 4,
29
+ background: checked ? C.black : mutedFill ? C.rowSelected : C.white,
30
+ border: `1px solid ${checked ? C.black : C.textDark}`,
31
+ display: "inline-flex",
32
+ alignItems: "center",
33
+ justifyContent: "center",
34
+ flexShrink: 0,
35
+ boxSizing: "border-box",
36
+ }}
37
+ >
38
+ {checked && <Check size={14} color={C.white} strokeWidth={3} />}
39
+ </span>
40
+ );
41
+ }
42
+
43
+ function Row({ supervisor, checked, muted = false, onToggle }) {
44
+ return (
45
+ <button
46
+ type="button"
47
+ onClick={onToggle}
48
+ style={{
49
+ display: "flex",
50
+ alignItems: "center",
51
+ gap: 6,
52
+ height: 32,
53
+ padding: "0 16px 0 8px",
54
+ borderRadius: 10,
55
+ border: "none",
56
+ background: checked ? C.rowSelected : "transparent",
57
+ cursor: "pointer",
58
+ width: "100%",
59
+ textAlign: "left",
60
+ fontFamily: FONT,
61
+ flexShrink: 0,
62
+ }}
63
+ >
64
+ <span style={{ display: "flex", alignItems: "center", gap: 12, flex: 1, minWidth: 0 }}>
65
+ <Checkbox checked={checked} mutedFill={muted} />
66
+ <span
67
+ style={{
68
+ fontSize: 14,
69
+ lineHeight: "20px",
70
+ fontWeight: 400,
71
+ color: !checked && muted ? C.textMid : C.black,
72
+ whiteSpace: "nowrap",
73
+ overflow: "hidden",
74
+ textOverflow: "ellipsis",
75
+ }}
76
+ >
77
+ {supervisor.name}
78
+ </span>
79
+ </span>
80
+ <span
81
+ style={{
82
+ fontSize: 12,
83
+ fontWeight: 500,
84
+ lineHeight: 1,
85
+ color: !checked && muted ? C.textMid : C.black,
86
+ whiteSpace: "nowrap",
87
+ padding: "4px 8px",
88
+ }}
89
+ >
90
+ {supervisor.agentCount} agents
91
+ </span>
92
+ </button>
93
+ );
94
+ }
95
+
96
+ function MetaRow({ left, right }) {
97
+ return (
98
+ <div
99
+ style={{
100
+ display: "flex",
101
+ alignItems: "center",
102
+ justifyContent: "space-between",
103
+ height: 14,
104
+ fontSize: 12,
105
+ lineHeight: 1.5,
106
+ fontFamily: FONT,
107
+ flexShrink: 0,
108
+ }}
109
+ >
110
+ {left}
111
+ {right}
112
+ </div>
113
+ );
114
+ }
115
+
116
+ function ActionLink({ children, onClick, faded = false }) {
117
+ return (
118
+ <button
119
+ type="button"
120
+ onClick={onClick}
121
+ style={{
122
+ background: "transparent",
123
+ border: "none",
124
+ padding: 0,
125
+ cursor: onClick ? "pointer" : "default",
126
+ fontFamily: FONT,
127
+ fontSize: 12,
128
+ fontWeight: 500,
129
+ color: faded ? C.textMuted : C.textDark,
130
+ whiteSpace: "nowrap",
131
+ }}
132
+ >
133
+ {children}
134
+ </button>
135
+ );
136
+ }
137
+
138
+ export default function SupervisorSelect({
139
+ supervisors = [],
140
+ value = [],
141
+ onApply,
142
+ onClose,
143
+ totalLabel,
144
+ className = "",
145
+ style,
146
+ }) {
147
+ const initialValueRef = React.useRef(value);
148
+ const [staged, setStaged] = React.useState(value);
149
+ const [query, setQuery] = React.useState("");
150
+
151
+ React.useEffect(() => {
152
+ initialValueRef.current = value;
153
+ setStaged(value);
154
+ }, [value]);
155
+
156
+ const stagedSet = React.useMemo(() => new Set(staged), [staged]);
157
+
158
+ const isSearching = query.trim().length > 0;
159
+
160
+ const filtered = React.useMemo(() => {
161
+ const q = query.trim().toLowerCase();
162
+ if (!q) return supervisors;
163
+ return supervisors.filter((s) => s.name.toLowerCase().includes(q));
164
+ }, [supervisors, query]);
165
+
166
+ const allSelected = supervisors.length > 0 && staged.length === supervisors.length;
167
+ const noneSelected = staged.length === 0;
168
+ const isPartial = !allSelected && !noneSelected;
169
+
170
+ const toggle = (id) => {
171
+ setStaged((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));
172
+ };
173
+ const selectAll = () => setStaged(supervisors.map((s) => s.id));
174
+ const deselectAll = () => setStaged([]);
175
+ const reset = () => setStaged(initialValueRef.current);
176
+ const clearSearch = () => setQuery("");
177
+ const apply = () => {
178
+ onApply?.(staged);
179
+ onClose?.();
180
+ };
181
+
182
+ const headerCount = isSearching
183
+ ? `${filtered.length} Result${filtered.length === 1 ? "" : "s"}`
184
+ : totalLabel || `${supervisors.length} Supervisors`;
185
+
186
+ let headerRight;
187
+ if (isSearching) {
188
+ headerRight = filtered.length > 0 ? <ActionLink onClick={selectAll}>Select all</ActionLink> : null;
189
+ } else if (allSelected) {
190
+ headerRight = <ActionLink onClick={deselectAll}>Deselect all</ActionLink>;
191
+ } else if (noneSelected) {
192
+ headerRight = <ActionLink onClick={selectAll}>Select all</ActionLink>;
193
+ } else {
194
+ headerRight = (
195
+ <span style={{ display: "inline-flex", gap: 12 }}>
196
+ <ActionLink onClick={selectAll}>Select all</ActionLink>
197
+ <ActionLink onClick={deselectAll}>Deselect all</ActionLink>
198
+ </span>
199
+ );
200
+ }
201
+
202
+ // Decide which sections to render
203
+ const renderPartial = !isSearching && isPartial;
204
+ const flatList = isSearching ? filtered : renderPartial ? [] : supervisors;
205
+ const partialSelected = renderPartial ? supervisors.filter((s) => stagedSet.has(s.id)) : [];
206
+ const partialOthers = renderPartial ? supervisors.filter((s) => !stagedSet.has(s.id)) : [];
207
+
208
+ return (
209
+ <div
210
+ className={className}
211
+ style={{
212
+ width: 262,
213
+ background: C.white,
214
+ border: `1px solid ${C.borderSubtle}`,
215
+ borderRadius: 10,
216
+ padding: 12,
217
+ boxSizing: "border-box",
218
+ display: "flex",
219
+ flexDirection: "column",
220
+ gap: 6,
221
+ fontFamily: FONT,
222
+ boxShadow: "0 8px 24px rgba(11, 11, 11, 0.08)",
223
+ ...style,
224
+ }}
225
+ >
226
+ <div
227
+ style={{
228
+ background: C.searchBg,
229
+ height: 32,
230
+ borderRadius: 10,
231
+ padding: 1,
232
+ display: "flex",
233
+ alignItems: "center",
234
+ }}
235
+ >
236
+ <div
237
+ style={{
238
+ background: C.white,
239
+ flex: 1,
240
+ height: 30,
241
+ borderRadius: 10,
242
+ display: "flex",
243
+ alignItems: "center",
244
+ gap: 8,
245
+ padding: "0 8px",
246
+ }}
247
+ >
248
+ <Search size={16} color={C.textMuted} strokeWidth={2} />
249
+ <input
250
+ type="text"
251
+ value={query}
252
+ onChange={(e) => setQuery(e.target.value)}
253
+ placeholder="Search supervisors..."
254
+ style={{
255
+ flex: 1,
256
+ border: "none",
257
+ outline: "none",
258
+ background: "transparent",
259
+ fontFamily: FONT,
260
+ fontSize: 14,
261
+ color: C.black,
262
+ minWidth: 0,
263
+ }}
264
+ />
265
+ </div>
266
+ </div>
267
+
268
+ <MetaRow
269
+ left={
270
+ <span style={{ color: C.textMuted, fontWeight: 400 }}>{headerCount}</span>
271
+ }
272
+ right={headerRight}
273
+ />
274
+
275
+ {flatList.length > 0 && (
276
+ <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
277
+ {flatList.map((s) => (
278
+ <Row
279
+ key={s.id}
280
+ supervisor={s}
281
+ checked={stagedSet.has(s.id)}
282
+ muted={false}
283
+ onToggle={() => toggle(s.id)}
284
+ />
285
+ ))}
286
+ </div>
287
+ )}
288
+
289
+ {renderPartial && (
290
+ <>
291
+ {partialSelected.length > 0 && (
292
+ <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
293
+ {partialSelected.map((s) => (
294
+ <Row key={s.id} supervisor={s} checked onToggle={() => toggle(s.id)} />
295
+ ))}
296
+ </div>
297
+ )}
298
+ {partialSelected.length > 0 && partialOthers.length > 0 && (
299
+ <div style={{ height: 1, background: C.border, margin: "4px 0" }} />
300
+ )}
301
+ {partialOthers.length > 0 && (
302
+ <>
303
+ <MetaRow
304
+ left={<span style={{ color: C.textMuted, fontWeight: 400 }}>Others</span>}
305
+ right={null}
306
+ />
307
+ <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
308
+ {partialOthers.map((s) => (
309
+ <Row
310
+ key={s.id}
311
+ supervisor={s}
312
+ checked={false}
313
+ muted
314
+ onToggle={() => toggle(s.id)}
315
+ />
316
+ ))}
317
+ </div>
318
+ </>
319
+ )}
320
+ </>
321
+ )}
322
+
323
+ {isSearching && filtered.length === 0 && (
324
+ <div
325
+ style={{
326
+ padding: "16px 8px",
327
+ textAlign: "center",
328
+ fontSize: 14,
329
+ color: C.textMid,
330
+ fontFamily: FONT,
331
+ }}
332
+ >
333
+ No results for &ldquo;{query}&rdquo;
334
+ </div>
335
+ )}
336
+ {isSearching && filtered.length > 0 && supervisors.length > filtered.length && (
337
+ <div
338
+ style={{
339
+ padding: "10px 8px",
340
+ textAlign: "center",
341
+ fontSize: 14,
342
+ color: C.textMid,
343
+ fontFamily: FONT,
344
+ }}
345
+ >
346
+ No other results for &ldquo;{query}&rdquo;
347
+ </div>
348
+ )}
349
+
350
+ <div style={{ height: 1, background: C.border, margin: "2px 0" }} />
351
+
352
+ <div
353
+ style={{
354
+ display: "flex",
355
+ alignItems: "center",
356
+ justifyContent: "space-between",
357
+ height: 30,
358
+ }}
359
+ >
360
+ {isSearching ? (
361
+ <ActionLink onClick={clearSearch}>Clear search</ActionLink>
362
+ ) : (
363
+ <ActionLink onClick={reset}>Reset</ActionLink>
364
+ )}
365
+ <button
366
+ type="button"
367
+ onClick={apply}
368
+ style={{
369
+ background: C.applyBg,
370
+ color: C.white,
371
+ border: "none",
372
+ borderRadius: 10,
373
+ height: 28,
374
+ padding: "0 14px",
375
+ fontFamily: FONT,
376
+ fontSize: 14,
377
+ fontWeight: 600,
378
+ cursor: "pointer",
379
+ }}
380
+ >
381
+ Apply
382
+ </button>
383
+ </div>
384
+ </div>
385
+ );
386
+ }
@@ -1 +1,3 @@
1
- export { default as PerformancePanel } from './PerformancePanel';
1
+ export { default as PerformancePanel, DEFAULT_AGENT_COLUMNS } from './PerformancePanel';
2
+ export { default as PerformanceDetailsPage, DEFAULT_SESSION_COLUMNS } from './PerformanceDetailsPage';
3
+ export { default as SupervisorSelect } from './SupervisorSelect';