@natoe/colab 0.1.12 → 0.1.13
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/dist/index.d.mts +132 -13
- package/dist/index.d.ts +132 -13
- package/dist/index.js +1056 -608
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1055 -610
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -321,6 +321,173 @@ var CollabSocket = class {
|
|
|
321
321
|
this.config = null;
|
|
322
322
|
}
|
|
323
323
|
};
|
|
324
|
+
|
|
325
|
+
// src/core/theme.ts
|
|
326
|
+
var FONT_SIZE = {
|
|
327
|
+
xs: "12px",
|
|
328
|
+
sm: "13px",
|
|
329
|
+
md: "15px",
|
|
330
|
+
lg: "17px",
|
|
331
|
+
xxl: "28px"
|
|
332
|
+
};
|
|
333
|
+
var FONT_WEIGHT = {
|
|
334
|
+
regular: 400,
|
|
335
|
+
medium: 500,
|
|
336
|
+
semibold: 600,
|
|
337
|
+
bold: 700
|
|
338
|
+
};
|
|
339
|
+
var LINE_HEIGHT = {
|
|
340
|
+
tight: 1.3,
|
|
341
|
+
normal: 1.45};
|
|
342
|
+
var SPACE = {
|
|
343
|
+
S1: "4px",
|
|
344
|
+
S2: "8px",
|
|
345
|
+
S3: "12px",
|
|
346
|
+
S4: "16px",
|
|
347
|
+
S5: "20px",
|
|
348
|
+
S6: "24px",
|
|
349
|
+
S12: "48px"
|
|
350
|
+
};
|
|
351
|
+
var RADIUS = {
|
|
352
|
+
sm: "4px",
|
|
353
|
+
md: "8px",
|
|
354
|
+
lg: "12px",
|
|
355
|
+
xl: "16px",
|
|
356
|
+
pill: "9999px",
|
|
357
|
+
full: "50%"
|
|
358
|
+
};
|
|
359
|
+
var THEME_VAR = {
|
|
360
|
+
primary: "--natoe-colab-primary",
|
|
361
|
+
primaryHover: "--natoe-colab-primary-hover",
|
|
362
|
+
primaryBg: "--natoe-colab-primary-bg",
|
|
363
|
+
primaryFg: "--natoe-colab-primary-fg",
|
|
364
|
+
success: "--natoe-colab-success",
|
|
365
|
+
warning: "--natoe-colab-warning",
|
|
366
|
+
danger: "--natoe-colab-danger",
|
|
367
|
+
dangerBg: "--natoe-colab-danger-bg",
|
|
368
|
+
dangerBorder: "--natoe-colab-danger-border",
|
|
369
|
+
dangerFg: "--natoe-colab-danger-fg",
|
|
370
|
+
fontStack: "--natoe-colab-font-stack"
|
|
371
|
+
};
|
|
372
|
+
var THEME_DEFAULTS = {
|
|
373
|
+
primary: "#2563eb",
|
|
374
|
+
primaryHover: "#1d4ed8",
|
|
375
|
+
primaryBg: "#dbeafe",
|
|
376
|
+
primaryFg: "#1d4ed8",
|
|
377
|
+
success: "#059669",
|
|
378
|
+
warning: "#d97706",
|
|
379
|
+
danger: "#dc2626",
|
|
380
|
+
dangerBg: "#fef2f2",
|
|
381
|
+
dangerBorder: "#fecaca",
|
|
382
|
+
dangerFg: "#b91c1c",
|
|
383
|
+
fontStack: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
|
|
384
|
+
};
|
|
385
|
+
var cssVar = (name, fallback) => `var(${name}, ${fallback})`;
|
|
386
|
+
var COLOR = {
|
|
387
|
+
// Brand — themeable
|
|
388
|
+
primary: cssVar(THEME_VAR.primary, THEME_DEFAULTS.primary),
|
|
389
|
+
primaryHover: cssVar(THEME_VAR.primaryHover, THEME_DEFAULTS.primaryHover),
|
|
390
|
+
/** Tinted surface for chips/cards on brand-coloured states. */
|
|
391
|
+
primaryBg: cssVar(THEME_VAR.primaryBg, THEME_DEFAULTS.primaryBg),
|
|
392
|
+
primaryFg: cssVar(THEME_VAR.primaryFg, THEME_DEFAULTS.primaryFg),
|
|
393
|
+
// Neutral grayscale — not themeable, taken from Tailwind's zinc-leaning
|
|
394
|
+
// slate to match the package's existing tonal balance.
|
|
395
|
+
white: "#ffffff",
|
|
396
|
+
neutral50: "#f9fafb",
|
|
397
|
+
neutral100: "#f3f4f6",
|
|
398
|
+
neutral200: "#e5e7eb",
|
|
399
|
+
neutral300: "#d1d5db",
|
|
400
|
+
neutral400: "#9ca3af",
|
|
401
|
+
neutral500: "#6b7280",
|
|
402
|
+
neutral600: "#4b5563",
|
|
403
|
+
neutral700: "#374151",
|
|
404
|
+
neutral800: "#1f2937",
|
|
405
|
+
neutral900: "#111827",
|
|
406
|
+
slate800: "#1e293b",
|
|
407
|
+
// Semantic — themeable
|
|
408
|
+
success: cssVar(THEME_VAR.success, THEME_DEFAULTS.success),
|
|
409
|
+
warning: cssVar(THEME_VAR.warning, THEME_DEFAULTS.warning),
|
|
410
|
+
danger: cssVar(THEME_VAR.danger, THEME_DEFAULTS.danger),
|
|
411
|
+
dangerBg: cssVar(THEME_VAR.dangerBg, THEME_DEFAULTS.dangerBg),
|
|
412
|
+
dangerBorder: cssVar(THEME_VAR.dangerBorder, THEME_DEFAULTS.dangerBorder),
|
|
413
|
+
dangerFg: cssVar(THEME_VAR.dangerFg, THEME_DEFAULTS.dangerFg)
|
|
414
|
+
};
|
|
415
|
+
var SIZE = {
|
|
416
|
+
/** Default interactive height (text buttons, list rows). */
|
|
417
|
+
control: "40px",
|
|
418
|
+
/** Square icon-only buttons inside chrome (popup title, menu trigger). */
|
|
419
|
+
controlIcon: "36px"};
|
|
420
|
+
var SHADOW = {
|
|
421
|
+
/** Cards / floating popovers (message-actions menu). */
|
|
422
|
+
popover: "0 6px 18px rgba(0, 0, 0, 0.12)",
|
|
423
|
+
toast: "0 4px 12px rgba(0, 0, 0, 0.18)"
|
|
424
|
+
};
|
|
425
|
+
var Z_INDEX = {
|
|
426
|
+
/** Sticky day divider — above bubbles, below interactive popovers. */
|
|
427
|
+
sticky: 1,
|
|
428
|
+
/** Toasts inside a panel. */
|
|
429
|
+
toast: 20,
|
|
430
|
+
/** Floating CollabPopup dialog. */
|
|
431
|
+
dialog: 9999,
|
|
432
|
+
/** Portaled message-actions menu — must sit above the dialog. */
|
|
433
|
+
menu: 1e4
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
// src/core/styles.ts
|
|
437
|
+
var FONT_STACK = `var(${THEME_VAR.fontStack}, ${THEME_DEFAULTS.fontStack})`;
|
|
438
|
+
var ROOT_CLASS = "natoe-colab-root";
|
|
439
|
+
var GLOBAL_STYLE_ID = "natoe-colab-global-styles";
|
|
440
|
+
var ROOT_DEFAULTS_BLOCK = Object.keys(THEME_DEFAULTS).map((key) => ` ${THEME_VAR[key]}: ${THEME_DEFAULTS[key]};`).join("\n");
|
|
441
|
+
var GLOBAL_CSS = `
|
|
442
|
+
:root {
|
|
443
|
+
${ROOT_DEFAULTS_BLOCK}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }
|
|
447
|
+
|
|
448
|
+
@keyframes natoe-colab-message-in {
|
|
449
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
450
|
+
to { opacity: 1; transform: translateY(0); }
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* High-contrast adjustments \u2014 older users on OS-level high-contrast mode
|
|
454
|
+
get heavier borders and stronger text without losing the package look. */
|
|
455
|
+
@media (prefers-contrast: more) {
|
|
456
|
+
.${ROOT_CLASS} {
|
|
457
|
+
color: #000000;
|
|
458
|
+
}
|
|
459
|
+
.${ROOT_CLASS} button {
|
|
460
|
+
outline: 1px solid currentColor;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* Honour reduced-motion preferences by killing entry animations. */
|
|
465
|
+
@media (prefers-reduced-motion: reduce) {
|
|
466
|
+
.${ROOT_CLASS} [data-natoe-message-bubble] {
|
|
467
|
+
animation: none !important;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
`;
|
|
471
|
+
function ensureGlobalStyles() {
|
|
472
|
+
if (typeof document === "undefined") return;
|
|
473
|
+
if (document.getElementById(GLOBAL_STYLE_ID)) return;
|
|
474
|
+
const style = document.createElement("style");
|
|
475
|
+
style.id = GLOBAL_STYLE_ID;
|
|
476
|
+
style.textContent = GLOBAL_CSS;
|
|
477
|
+
document.head.appendChild(style);
|
|
478
|
+
}
|
|
479
|
+
function applyThemeOverrides(theme) {
|
|
480
|
+
if (typeof document === "undefined") return;
|
|
481
|
+
const root = document.documentElement;
|
|
482
|
+
Object.keys(THEME_VAR).forEach((key) => {
|
|
483
|
+
const value = theme?.[key];
|
|
484
|
+
if (value) {
|
|
485
|
+
root.style.setProperty(THEME_VAR[key], value);
|
|
486
|
+
} else {
|
|
487
|
+
root.style.removeProperty(THEME_VAR[key]);
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
}
|
|
324
491
|
var CollabContext = React4.createContext(null);
|
|
325
492
|
function useCollab() {
|
|
326
493
|
const context = React4.useContext(CollabContext);
|
|
@@ -339,6 +506,9 @@ function CollabProvider({ config, apiBaseUrl, children }) {
|
|
|
339
506
|
const pendingResolvers = React4.useRef(/* @__PURE__ */ new Map());
|
|
340
507
|
const previewCache = React4.useRef(/* @__PURE__ */ new Map());
|
|
341
508
|
const batchScheduled = React4.useRef(false);
|
|
509
|
+
React4.useEffect(() => {
|
|
510
|
+
applyThemeOverrides(config.theme);
|
|
511
|
+
}, [config.theme]);
|
|
342
512
|
React4.useEffect(() => {
|
|
343
513
|
if (typeof window === "undefined") return;
|
|
344
514
|
let s = socket;
|
|
@@ -554,6 +724,7 @@ function CollabProvider({ config, apiBaseUrl, children }) {
|
|
|
554
724
|
config,
|
|
555
725
|
apiBaseUrl,
|
|
556
726
|
totalUnread,
|
|
727
|
+
unreadCounts,
|
|
557
728
|
requestPreview,
|
|
558
729
|
invalidatePreview,
|
|
559
730
|
fetchMessages,
|
|
@@ -731,26 +902,22 @@ function useConversation({
|
|
|
731
902
|
setConversation(existingConv);
|
|
732
903
|
setParticipants(preview.participants);
|
|
733
904
|
joinChannel(existingConv);
|
|
734
|
-
setMessages(preview.lastMessages);
|
|
735
|
-
setHasMore(preview.messageCount > preview.lastMessages.length);
|
|
736
|
-
setPinnedMessages(preview.lastMessages.filter((m) => m.isPinned));
|
|
737
|
-
setIsLoading(false);
|
|
738
905
|
if (loadHistory) {
|
|
739
906
|
fetchMessages(preview.conversationId).then((history) => {
|
|
740
907
|
if (cancelled) return;
|
|
741
|
-
setMessages(
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
});
|
|
746
|
-
setHasMore(history.length > 0);
|
|
747
|
-
setPinnedMessages((prev) => {
|
|
748
|
-
const fromHistory = history.filter((m) => m.isPinned);
|
|
749
|
-
const seen = new Set(prev.map((m) => m.id));
|
|
750
|
-
return [...fromHistory.filter((m) => !seen.has(m.id)), ...prev];
|
|
751
|
-
});
|
|
908
|
+
setMessages(history);
|
|
909
|
+
setHasMore(history.length >= MESSAGES_PAGE_SIZE);
|
|
910
|
+
setPinnedMessages(history.filter((m) => m.isPinned));
|
|
911
|
+
setIsLoading(false);
|
|
752
912
|
}).catch(() => {
|
|
913
|
+
if (cancelled) return;
|
|
914
|
+
setIsLoading(false);
|
|
753
915
|
});
|
|
916
|
+
} else {
|
|
917
|
+
setMessages([]);
|
|
918
|
+
setHasMore(false);
|
|
919
|
+
setPinnedMessages([]);
|
|
920
|
+
setIsLoading(false);
|
|
754
921
|
}
|
|
755
922
|
} catch (err) {
|
|
756
923
|
if (cancelled) return;
|
|
@@ -831,7 +998,7 @@ function useConversation({
|
|
|
831
998
|
const payload = {
|
|
832
999
|
body,
|
|
833
1000
|
type: "text",
|
|
834
|
-
...replyTo ? {
|
|
1001
|
+
...replyTo ? { reply_to_id: replyTo.id } : {}
|
|
835
1002
|
};
|
|
836
1003
|
const { conv, persistedByCreate } = await ensureConversation(payload);
|
|
837
1004
|
setReplyTo(null);
|
|
@@ -884,7 +1051,7 @@ function useConversation({
|
|
|
884
1051
|
const payload = {
|
|
885
1052
|
body: target.body,
|
|
886
1053
|
type: "text",
|
|
887
|
-
...target.replyToId ? {
|
|
1054
|
+
...target.replyToId ? { reply_to_id: target.replyToId } : {}
|
|
888
1055
|
};
|
|
889
1056
|
try {
|
|
890
1057
|
await socket.sendMessage(conversation.id, payload);
|
|
@@ -1209,102 +1376,6 @@ function BackIcon({ size = 22, color = "currentColor" }) {
|
|
|
1209
1376
|
}
|
|
1210
1377
|
);
|
|
1211
1378
|
}
|
|
1212
|
-
|
|
1213
|
-
// src/core/theme.ts
|
|
1214
|
-
var FONT_SIZE = {
|
|
1215
|
-
xs: "12px",
|
|
1216
|
-
sm: "13px",
|
|
1217
|
-
md: "15px",
|
|
1218
|
-
lg: "17px",
|
|
1219
|
-
xxl: "28px"
|
|
1220
|
-
};
|
|
1221
|
-
var FONT_WEIGHT = {
|
|
1222
|
-
regular: 400,
|
|
1223
|
-
medium: 500,
|
|
1224
|
-
semibold: 600,
|
|
1225
|
-
bold: 700
|
|
1226
|
-
};
|
|
1227
|
-
var LINE_HEIGHT = {
|
|
1228
|
-
tight: 1.3,
|
|
1229
|
-
normal: 1.45};
|
|
1230
|
-
var SPACE = {
|
|
1231
|
-
S1: "4px",
|
|
1232
|
-
S2: "8px",
|
|
1233
|
-
S3: "12px",
|
|
1234
|
-
S4: "16px",
|
|
1235
|
-
S5: "20px",
|
|
1236
|
-
S6: "24px",
|
|
1237
|
-
S12: "48px"
|
|
1238
|
-
};
|
|
1239
|
-
var RADIUS = {
|
|
1240
|
-
sm: "4px",
|
|
1241
|
-
md: "8px",
|
|
1242
|
-
lg: "12px",
|
|
1243
|
-
pill: "9999px",
|
|
1244
|
-
full: "50%"
|
|
1245
|
-
};
|
|
1246
|
-
var COLOR = {
|
|
1247
|
-
// Brand
|
|
1248
|
-
primary: "#2563eb",
|
|
1249
|
-
/** Tinted surface for chips/cards on brand-coloured states. */
|
|
1250
|
-
primaryBg: "#dbeafe",
|
|
1251
|
-
primaryFg: "#1d4ed8",
|
|
1252
|
-
// Neutral grayscale — taken from Tailwind's zinc-leaning slate, the
|
|
1253
|
-
// existing dominant family in the package.
|
|
1254
|
-
white: "#ffffff",
|
|
1255
|
-
neutral50: "#f9fafb",
|
|
1256
|
-
neutral100: "#f3f4f6",
|
|
1257
|
-
neutral200: "#e5e7eb",
|
|
1258
|
-
neutral300: "#d1d5db",
|
|
1259
|
-
neutral400: "#9ca3af",
|
|
1260
|
-
neutral500: "#6b7280",
|
|
1261
|
-
neutral600: "#4b5563",
|
|
1262
|
-
neutral700: "#374151",
|
|
1263
|
-
neutral800: "#1f2937",
|
|
1264
|
-
neutral900: "#111827",
|
|
1265
|
-
// Slate (used by day dividers + dialog title bar)
|
|
1266
|
-
slate200: "#e2e8f0",
|
|
1267
|
-
slate700: "#334155",
|
|
1268
|
-
slate800: "#1e293b",
|
|
1269
|
-
// Semantic
|
|
1270
|
-
success: "#059669",
|
|
1271
|
-
warning: "#d97706",
|
|
1272
|
-
danger: "#dc2626",
|
|
1273
|
-
dangerBg: "#fef2f2",
|
|
1274
|
-
dangerBorder: "#fecaca",
|
|
1275
|
-
dangerFg: "#b91c1c"
|
|
1276
|
-
};
|
|
1277
|
-
var SIZE = {
|
|
1278
|
-
/** Default interactive height (text buttons, list rows). */
|
|
1279
|
-
control: "40px",
|
|
1280
|
-
/** Square icon-only buttons inside chrome (popup title, menu trigger). */
|
|
1281
|
-
controlIcon: "36px",
|
|
1282
|
-
/** Primary input controls (textarea send/attach). 44px = WCAG min. */
|
|
1283
|
-
controlPrimary: "44px",
|
|
1284
|
-
/** Avatar in the inbox row. */
|
|
1285
|
-
avatar: "40px",
|
|
1286
|
-
/** Unread dot. */
|
|
1287
|
-
dot: "10px"
|
|
1288
|
-
};
|
|
1289
|
-
var SHADOW = {
|
|
1290
|
-
/** Cards / floating popovers (message-actions menu). */
|
|
1291
|
-
popover: "0 6px 18px rgba(0, 0, 0, 0.12)",
|
|
1292
|
-
/** Dialog (CollabPopup). */
|
|
1293
|
-
dialog: "0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08)",
|
|
1294
|
-
/** Subtle separator shadow (sticky day divider, toast). */
|
|
1295
|
-
subtle: "0 1px 2px rgba(0, 0, 0, 0.04)",
|
|
1296
|
-
toast: "0 4px 12px rgba(0, 0, 0, 0.18)"
|
|
1297
|
-
};
|
|
1298
|
-
var Z_INDEX = {
|
|
1299
|
-
/** Sticky day divider — above bubbles, below interactive popovers. */
|
|
1300
|
-
sticky: 1,
|
|
1301
|
-
/** Toasts inside a panel. */
|
|
1302
|
-
toast: 20,
|
|
1303
|
-
/** Floating CollabPopup dialog. */
|
|
1304
|
-
dialog: 9999,
|
|
1305
|
-
/** Portaled message-actions menu — must sit above the dialog. */
|
|
1306
|
-
menu: 1e4
|
|
1307
|
-
};
|
|
1308
1379
|
function resolveDisplayName(patientData, displayName) {
|
|
1309
1380
|
const localComplete = !!patientData.labName && !!patientData.displayOrderId;
|
|
1310
1381
|
if (localComplete) return buildChannelName(patientData);
|
|
@@ -1321,15 +1392,28 @@ function PatientHeader({
|
|
|
1321
1392
|
}) {
|
|
1322
1393
|
const hasDicom = !!(patientData.studyId && patientData.storageId);
|
|
1323
1394
|
const meta = [];
|
|
1324
|
-
if (patientData.patientAge
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1395
|
+
if (patientData.patientAge && patientData.patientSex) {
|
|
1396
|
+
meta.push({
|
|
1397
|
+
key: "ageSex",
|
|
1398
|
+
label: "Age / Sex",
|
|
1399
|
+
value: `${patientData.patientAge} \xB7 ${patientData.patientSex}`
|
|
1400
|
+
});
|
|
1401
|
+
} else if (patientData.patientAge) {
|
|
1402
|
+
meta.push({ key: "age", label: "Age", value: String(patientData.patientAge) });
|
|
1403
|
+
} else if (patientData.patientSex) {
|
|
1404
|
+
meta.push({ key: "sex", label: "Sex", value: String(patientData.patientSex) });
|
|
1405
|
+
}
|
|
1406
|
+
if (patientData.studyType) {
|
|
1407
|
+
meta.push({ key: "modality", label: "Modality", value: patientData.studyType });
|
|
1329
1408
|
}
|
|
1330
|
-
if (patientData.
|
|
1331
|
-
meta.push({
|
|
1409
|
+
if (patientData.bodyParts && patientData.bodyParts.length > 0) {
|
|
1410
|
+
meta.push({
|
|
1411
|
+
key: "body",
|
|
1412
|
+
label: "Body part",
|
|
1413
|
+
value: patientData.bodyParts.join(", ")
|
|
1414
|
+
});
|
|
1332
1415
|
}
|
|
1416
|
+
const hasActions = hasDicom && onOpenDicom || onOpenSettings;
|
|
1333
1417
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: styles.container, children: [
|
|
1334
1418
|
!hideName && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.nameRow, children: [
|
|
1335
1419
|
onBack && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1345,54 +1429,55 @@ function PatientHeader({
|
|
|
1345
1429
|
),
|
|
1346
1430
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.nameText, children: resolveDisplayName(patientData, displayName) })
|
|
1347
1431
|
] }),
|
|
1348
|
-
|
|
1349
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1350
|
-
item.label,
|
|
1351
|
-
":
|
|
1352
|
-
] }),
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
]
|
|
1381
|
-
}
|
|
1382
|
-
)
|
|
1383
|
-
] }) : null
|
|
1432
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.caseCard, children: [
|
|
1433
|
+
meta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.metaRow, children: meta.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.metaCol, children: [
|
|
1434
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.metaLabel, children: item.label }),
|
|
1435
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.metaValue, children: item.value })
|
|
1436
|
+
] }, item.key)) }),
|
|
1437
|
+
hasActions && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.actions, children: [
|
|
1438
|
+
hasDicom && onOpenDicom && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1439
|
+
"button",
|
|
1440
|
+
{
|
|
1441
|
+
onClick: onOpenDicom,
|
|
1442
|
+
style: styles.dicomButton,
|
|
1443
|
+
type: "button",
|
|
1444
|
+
"aria-label": "View DICOM study",
|
|
1445
|
+
children: [
|
|
1446
|
+
/* @__PURE__ */ jsxRuntime.jsx(DicomIcon, { size: 18, color: COLOR.primary }),
|
|
1447
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "View DICOM" })
|
|
1448
|
+
]
|
|
1449
|
+
}
|
|
1450
|
+
),
|
|
1451
|
+
onOpenSettings && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1452
|
+
"button",
|
|
1453
|
+
{
|
|
1454
|
+
onClick: onOpenSettings,
|
|
1455
|
+
style: styles.settingsIconButton,
|
|
1456
|
+
type: "button",
|
|
1457
|
+
"aria-label": "Open channel settings",
|
|
1458
|
+
title: "Settings",
|
|
1459
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SettingsIcon, { size: 18, color: COLOR.neutral600 })
|
|
1460
|
+
}
|
|
1461
|
+
)
|
|
1462
|
+
] })
|
|
1463
|
+
] })
|
|
1384
1464
|
] });
|
|
1385
1465
|
}
|
|
1386
1466
|
var styles = {
|
|
1387
1467
|
container: {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
backgroundColor: COLOR.
|
|
1468
|
+
display: "flex",
|
|
1469
|
+
flexDirection: "column",
|
|
1470
|
+
backgroundColor: COLOR.primaryBg,
|
|
1471
|
+
borderBottom: `1px solid ${COLOR.neutral200}`
|
|
1391
1472
|
},
|
|
1473
|
+
// Optional name row, only when `hideName` is false (compact-inbox path)
|
|
1392
1474
|
nameRow: {
|
|
1393
1475
|
display: "flex",
|
|
1394
1476
|
alignItems: "center",
|
|
1395
|
-
gap: SPACE.S2
|
|
1477
|
+
gap: SPACE.S2,
|
|
1478
|
+
padding: `${SPACE.S3} ${SPACE.S4} ${SPACE.S2}`,
|
|
1479
|
+
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
1480
|
+
backgroundColor: COLOR.white
|
|
1396
1481
|
},
|
|
1397
1482
|
backButton: {
|
|
1398
1483
|
width: SIZE.controlIcon,
|
|
@@ -1409,65 +1494,90 @@ var styles = {
|
|
|
1409
1494
|
},
|
|
1410
1495
|
nameText: {
|
|
1411
1496
|
fontSize: FONT_SIZE.lg,
|
|
1412
|
-
fontWeight: FONT_WEIGHT.
|
|
1497
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
1413
1498
|
color: COLOR.neutral900,
|
|
1414
1499
|
lineHeight: LINE_HEIGHT.tight,
|
|
1500
|
+
letterSpacing: "-0.01em",
|
|
1415
1501
|
minWidth: 0,
|
|
1416
1502
|
overflow: "hidden",
|
|
1417
1503
|
textOverflow: "ellipsis",
|
|
1418
1504
|
whiteSpace: "nowrap"
|
|
1419
1505
|
},
|
|
1506
|
+
// Case card: meta columns flowing in a wrap-row, actions stacked
|
|
1507
|
+
// below. Each meta column is a small label-above-value pair so the
|
|
1508
|
+
// user can scan field names quickly without a legend.
|
|
1509
|
+
caseCard: {
|
|
1510
|
+
display: "flex",
|
|
1511
|
+
flexDirection: "column",
|
|
1512
|
+
gap: SPACE.S3,
|
|
1513
|
+
padding: `${SPACE.S3} ${SPACE.S5}`
|
|
1514
|
+
},
|
|
1515
|
+
// Wrap-row of stacked label/value columns. Compact column gap keeps
|
|
1516
|
+
// the row dense without crowding; row gap kicks in when columns
|
|
1517
|
+
// wrap to a second line on narrow popups.
|
|
1420
1518
|
metaRow: {
|
|
1421
1519
|
display: "flex",
|
|
1422
1520
|
flexWrap: "wrap",
|
|
1423
|
-
columnGap: SPACE.
|
|
1424
|
-
rowGap: SPACE.
|
|
1425
|
-
|
|
1521
|
+
columnGap: SPACE.S5,
|
|
1522
|
+
rowGap: SPACE.S2,
|
|
1523
|
+
minWidth: 0
|
|
1426
1524
|
},
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1525
|
+
metaCol: {
|
|
1526
|
+
display: "flex",
|
|
1527
|
+
flexDirection: "column",
|
|
1528
|
+
gap: "2px",
|
|
1529
|
+
minWidth: 0
|
|
1431
1530
|
},
|
|
1432
1531
|
metaLabel: {
|
|
1532
|
+
fontSize: "11px",
|
|
1533
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
1534
|
+
letterSpacing: "0.06em",
|
|
1535
|
+
textTransform: "uppercase",
|
|
1433
1536
|
color: COLOR.neutral500,
|
|
1434
|
-
|
|
1537
|
+
whiteSpace: "nowrap"
|
|
1435
1538
|
},
|
|
1436
1539
|
metaValue: {
|
|
1437
|
-
|
|
1540
|
+
fontSize: FONT_SIZE.sm,
|
|
1541
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
1542
|
+
color: COLOR.neutral900,
|
|
1543
|
+
whiteSpace: "nowrap",
|
|
1544
|
+
overflow: "hidden",
|
|
1545
|
+
textOverflow: "ellipsis",
|
|
1546
|
+
maxWidth: "180px"
|
|
1438
1547
|
},
|
|
1439
1548
|
actions: {
|
|
1440
1549
|
display: "flex",
|
|
1441
1550
|
gap: SPACE.S2,
|
|
1442
|
-
|
|
1551
|
+
flexShrink: 0
|
|
1443
1552
|
},
|
|
1444
1553
|
dicomButton: {
|
|
1445
1554
|
display: "inline-flex",
|
|
1446
1555
|
alignItems: "center",
|
|
1447
1556
|
gap: SPACE.S2,
|
|
1448
1557
|
minHeight: SIZE.control,
|
|
1449
|
-
padding: `${SPACE.S2}
|
|
1558
|
+
padding: `${SPACE.S2} 14px`,
|
|
1450
1559
|
fontSize: FONT_SIZE.sm,
|
|
1451
|
-
fontWeight: FONT_WEIGHT.
|
|
1452
|
-
color: COLOR.
|
|
1453
|
-
backgroundColor: COLOR.
|
|
1454
|
-
border:
|
|
1455
|
-
borderRadius: RADIUS.
|
|
1560
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
1561
|
+
color: COLOR.primary,
|
|
1562
|
+
backgroundColor: COLOR.white,
|
|
1563
|
+
border: `1.5px solid ${COLOR.primary}`,
|
|
1564
|
+
borderRadius: RADIUS.lg,
|
|
1456
1565
|
cursor: "pointer"
|
|
1457
1566
|
},
|
|
1458
|
-
|
|
1567
|
+
// Settings is icon-only (40x40 tile) since it's a secondary action
|
|
1568
|
+
// and View DICOM already carries a label.
|
|
1569
|
+
settingsIconButton: {
|
|
1570
|
+
width: SIZE.control,
|
|
1571
|
+
height: SIZE.control,
|
|
1459
1572
|
display: "inline-flex",
|
|
1460
1573
|
alignItems: "center",
|
|
1461
|
-
|
|
1462
|
-
minHeight: SIZE.control,
|
|
1463
|
-
padding: `${SPACE.S2} ${SPACE.S4}`,
|
|
1464
|
-
fontSize: FONT_SIZE.sm,
|
|
1465
|
-
fontWeight: FONT_WEIGHT.medium,
|
|
1466
|
-
color: COLOR.neutral700,
|
|
1574
|
+
justifyContent: "center",
|
|
1467
1575
|
backgroundColor: COLOR.white,
|
|
1468
|
-
border: `1px solid ${COLOR.
|
|
1469
|
-
borderRadius: RADIUS.
|
|
1470
|
-
|
|
1576
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
1577
|
+
borderRadius: RADIUS.lg,
|
|
1578
|
+
color: COLOR.neutral600,
|
|
1579
|
+
cursor: "pointer",
|
|
1580
|
+
flexShrink: 0
|
|
1471
1581
|
}
|
|
1472
1582
|
};
|
|
1473
1583
|
function ReplyQuoteBlock({
|
|
@@ -1476,10 +1586,10 @@ function ReplyQuoteBlock({
|
|
|
1476
1586
|
onClick,
|
|
1477
1587
|
className
|
|
1478
1588
|
}) {
|
|
1479
|
-
const baseBg = inOwnBubble ? "rgba(255,255,255,0.
|
|
1589
|
+
const baseBg = inOwnBubble ? "rgba(255,255,255,0.22)" : COLOR.white;
|
|
1480
1590
|
const barColor = inOwnBubble ? COLOR.white : COLOR.primary;
|
|
1481
1591
|
const nameColor = inOwnBubble ? COLOR.white : COLOR.primary;
|
|
1482
|
-
const bodyColor = inOwnBubble ? "rgba(255,255,255,0.
|
|
1592
|
+
const bodyColor = inOwnBubble ? "rgba(255,255,255,0.9)" : COLOR.neutral700;
|
|
1483
1593
|
const preview = renderSnapshotPreview(snapshot);
|
|
1484
1594
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1485
1595
|
"div",
|
|
@@ -1851,43 +1961,50 @@ var styles4 = {
|
|
|
1851
1961
|
position: "relative",
|
|
1852
1962
|
display: "inline-block"
|
|
1853
1963
|
},
|
|
1964
|
+
// Pill-shaped trigger matching the prototype's `.nc-msg-act` style —
|
|
1965
|
+
// always visible (touch-friendly) rather than hover-only.
|
|
1854
1966
|
trigger: {
|
|
1855
|
-
|
|
1856
|
-
height: SIZE.controlIcon,
|
|
1857
|
-
display: "flex",
|
|
1967
|
+
display: "inline-flex",
|
|
1858
1968
|
alignItems: "center",
|
|
1859
1969
|
justifyContent: "center",
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1970
|
+
width: "32px",
|
|
1971
|
+
height: "32px",
|
|
1972
|
+
backgroundColor: COLOR.white,
|
|
1973
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
1974
|
+
borderRadius: "999px",
|
|
1863
1975
|
cursor: "pointer",
|
|
1864
|
-
color: COLOR.neutral600
|
|
1976
|
+
color: COLOR.neutral600,
|
|
1977
|
+
transition: "background-color 120ms ease, color 120ms ease, border-color 120ms ease"
|
|
1865
1978
|
},
|
|
1866
1979
|
menu: {
|
|
1867
1980
|
position: "fixed",
|
|
1868
|
-
minWidth: "
|
|
1981
|
+
minWidth: "200px",
|
|
1869
1982
|
backgroundColor: COLOR.white,
|
|
1870
|
-
border: `1px solid ${COLOR.
|
|
1871
|
-
borderRadius: RADIUS.
|
|
1983
|
+
border: `1px solid ${COLOR.neutral300}`,
|
|
1984
|
+
borderRadius: RADIUS.lg,
|
|
1872
1985
|
boxShadow: SHADOW.popover,
|
|
1873
|
-
padding:
|
|
1986
|
+
padding: "6px",
|
|
1987
|
+
display: "flex",
|
|
1988
|
+
flexDirection: "column",
|
|
1989
|
+
gap: "2px",
|
|
1874
1990
|
// Above the floating popup (z-index dialog) but below any future modal.
|
|
1875
1991
|
zIndex: Z_INDEX.menu
|
|
1876
1992
|
},
|
|
1877
1993
|
item: {
|
|
1878
1994
|
display: "flex",
|
|
1879
1995
|
alignItems: "center",
|
|
1880
|
-
gap: SPACE.
|
|
1996
|
+
gap: SPACE.S2,
|
|
1881
1997
|
width: "100%",
|
|
1882
1998
|
minHeight: SIZE.control,
|
|
1883
|
-
padding:
|
|
1999
|
+
padding: `10px ${SPACE.S3}`,
|
|
1884
2000
|
fontSize: FONT_SIZE.sm,
|
|
1885
|
-
color: COLOR.
|
|
2001
|
+
color: COLOR.neutral700,
|
|
1886
2002
|
backgroundColor: "transparent",
|
|
1887
2003
|
border: "none",
|
|
1888
|
-
borderRadius: RADIUS.
|
|
2004
|
+
borderRadius: RADIUS.md,
|
|
1889
2005
|
cursor: "pointer",
|
|
1890
|
-
textAlign: "left"
|
|
2006
|
+
textAlign: "left",
|
|
2007
|
+
fontFamily: "inherit"
|
|
1891
2008
|
},
|
|
1892
2009
|
itemDisabled: {
|
|
1893
2010
|
color: COLOR.neutral400,
|
|
@@ -2001,71 +2118,116 @@ function MessageBubble({
|
|
|
2001
2118
|
},
|
|
2002
2119
|
children: [
|
|
2003
2120
|
isOwn && actionsSlot,
|
|
2004
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2005
|
-
"div",
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
message.type === "image" && /* @__PURE__ */ jsxRuntime.jsx(ImageContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2031
|
-
message.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2032
|
-
message.type === "deep_link" && /* @__PURE__ */ jsxRuntime.jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
|
|
2033
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
|
|
2034
|
-
isOwn && message.status === "sending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.statusRow, children: [
|
|
2035
|
-
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 12, color: "rgba(255,255,255,0.85)" }),
|
|
2036
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.statusText, children: "Sending\u2026" })
|
|
2037
|
-
] }),
|
|
2038
|
-
isOwn && message.status === "failed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.statusRow, children: [
|
|
2039
|
-
/* @__PURE__ */ jsxRuntime.jsx(AlertIcon, { size: 12, color: "#fecaca" }),
|
|
2040
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.statusText, children: "Not sent" }),
|
|
2041
|
-
onRetry && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2042
|
-
"button",
|
|
2121
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.bubbleWrapper, children: [
|
|
2122
|
+
!isOwn && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.authorRow, children: [
|
|
2123
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2124
|
+
"span",
|
|
2125
|
+
{
|
|
2126
|
+
style: {
|
|
2127
|
+
...styles5.authorAvatar,
|
|
2128
|
+
backgroundColor: roleColor(message.senderRole)
|
|
2129
|
+
},
|
|
2130
|
+
"aria-hidden": "true",
|
|
2131
|
+
children: computeInitials(message.senderName)
|
|
2132
|
+
}
|
|
2133
|
+
),
|
|
2134
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.authorName, children: message.senderName }),
|
|
2135
|
+
/* @__PURE__ */ jsxRuntime.jsx(RoleBadge, { role: message.senderRole })
|
|
2136
|
+
] }),
|
|
2137
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2138
|
+
"div",
|
|
2139
|
+
{
|
|
2140
|
+
style: {
|
|
2141
|
+
...styles5.bubble,
|
|
2142
|
+
...isOwn ? styles5.ownBubble : styles5.otherBubble
|
|
2143
|
+
},
|
|
2144
|
+
children: [
|
|
2145
|
+
message.isPinned && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2146
|
+
"div",
|
|
2043
2147
|
{
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
children:
|
|
2148
|
+
style: {
|
|
2149
|
+
...styles5.pinnedBadge,
|
|
2150
|
+
...isOwn ? styles5.pinnedBadgeOwn : styles5.pinnedBadgeOther
|
|
2151
|
+
},
|
|
2152
|
+
children: [
|
|
2153
|
+
/* @__PURE__ */ jsxRuntime.jsx(PinIcon, { size: 12 }),
|
|
2154
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Pinned" })
|
|
2155
|
+
]
|
|
2049
2156
|
}
|
|
2050
|
-
)
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2157
|
+
),
|
|
2158
|
+
message.replyToSnapshot && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2159
|
+
ReplyQuoteBlock,
|
|
2160
|
+
{
|
|
2161
|
+
snapshot: message.replyToSnapshot,
|
|
2162
|
+
inOwnBubble: isOwn,
|
|
2163
|
+
onClick: onReplyJumpTo
|
|
2164
|
+
}
|
|
2165
|
+
),
|
|
2166
|
+
message.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextContent, { body: message.body, onDeepLinkClick }),
|
|
2167
|
+
message.type === "audio" && /* @__PURE__ */ jsxRuntime.jsx(AudioContent, { mediaUrl: message.mediaUrl, duration: message.mediaDuration }),
|
|
2168
|
+
message.type === "image" && /* @__PURE__ */ jsxRuntime.jsx(ImageContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2169
|
+
message.type === "file" && /* @__PURE__ */ jsxRuntime.jsx(FileContent, { mediaUrl: message.mediaUrl, fileName: message.fileName }),
|
|
2170
|
+
message.type === "deep_link" && /* @__PURE__ */ jsxRuntime.jsx(DeepLinkContent, { body: message.body, metadata: message.metadata, onDeepLinkClick }),
|
|
2171
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.bubbleFoot, children: [
|
|
2172
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.timestamp, children: formatTime(message.insertedAt) }),
|
|
2173
|
+
isOwn && message.status === "sending" && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.footStatus, children: [
|
|
2174
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 11, color: "rgba(255,255,255,0.85)" }),
|
|
2175
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Sending\u2026" })
|
|
2176
|
+
] }),
|
|
2177
|
+
isOwn && message.status === "failed" && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.footStatusFailed, children: [
|
|
2178
|
+
/* @__PURE__ */ jsxRuntime.jsx(AlertIcon, { size: 11, color: "#fecaca" }),
|
|
2179
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Not sent" }),
|
|
2180
|
+
onRetry && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2181
|
+
"button",
|
|
2182
|
+
{
|
|
2183
|
+
type: "button",
|
|
2184
|
+
onClick: () => onRetry(message.id),
|
|
2185
|
+
style: styles5.retryButton,
|
|
2186
|
+
"aria-label": "Retry sending message",
|
|
2187
|
+
children: "Retry"
|
|
2188
|
+
}
|
|
2189
|
+
)
|
|
2190
|
+
] }),
|
|
2191
|
+
showSeenBy && isOwn && !message.status && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2192
|
+
SeenByIndicator,
|
|
2193
|
+
{
|
|
2194
|
+
readBy: message.readBy ?? [],
|
|
2195
|
+
participants,
|
|
2196
|
+
currentUserId,
|
|
2197
|
+
senderId: message.senderId
|
|
2198
|
+
}
|
|
2199
|
+
)
|
|
2200
|
+
] })
|
|
2201
|
+
]
|
|
2202
|
+
}
|
|
2203
|
+
)
|
|
2204
|
+
] }),
|
|
2064
2205
|
!isOwn && actionsSlot
|
|
2065
2206
|
]
|
|
2066
2207
|
}
|
|
2067
2208
|
);
|
|
2068
2209
|
}
|
|
2210
|
+
function computeInitials(name) {
|
|
2211
|
+
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((p) => p[0]?.toUpperCase() ?? "").join("") || "?";
|
|
2212
|
+
}
|
|
2213
|
+
function roleColor(role) {
|
|
2214
|
+
switch (role) {
|
|
2215
|
+
case "radiologist":
|
|
2216
|
+
return "#4f46e5";
|
|
2217
|
+
// indigo (blue-leaning)
|
|
2218
|
+
case "lab":
|
|
2219
|
+
return "#2563eb";
|
|
2220
|
+
// brand blue
|
|
2221
|
+
case "physician":
|
|
2222
|
+
return "#0284c7";
|
|
2223
|
+
// sky
|
|
2224
|
+
case "admin":
|
|
2225
|
+
return "#64748b";
|
|
2226
|
+
// slate (muted)
|
|
2227
|
+
default:
|
|
2228
|
+
return "#6b7280";
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2069
2231
|
function TextContent({ body, onDeepLinkClick }) {
|
|
2070
2232
|
if (body.includes(DEEP_LINK_PREFIX)) {
|
|
2071
2233
|
const parts = body.split(new RegExp(`(${escapeRegex2(DEEP_LINK_PREFIX)}[\\w/.-]+)`, "g"));
|
|
@@ -2127,19 +2289,13 @@ function DeepLinkContent({
|
|
|
2127
2289
|
);
|
|
2128
2290
|
}
|
|
2129
2291
|
function SystemBubble({ message }) {
|
|
2130
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
2292
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.systemWrapper, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.systemPill, children: [
|
|
2131
2293
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: message.body }),
|
|
2132
2294
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.systemTime, children: formatTime(message.insertedAt) })
|
|
2133
|
-
] });
|
|
2295
|
+
] }) });
|
|
2134
2296
|
}
|
|
2135
2297
|
function RoleBadge({ role }) {
|
|
2136
|
-
|
|
2137
|
-
radiologist: "#7c3aed",
|
|
2138
|
-
lab: "#2563eb",
|
|
2139
|
-
physician: "#059669",
|
|
2140
|
-
admin: "#dc2626"
|
|
2141
|
-
};
|
|
2142
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles5.roleBadge, backgroundColor: `${colors[role]}15`, color: colors[role] }, children: ROLE_LABELS[role] ?? role });
|
|
2298
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles5.roleBadge, backgroundColor: roleColor(role) }, children: ROLE_LABELS[role] ?? role });
|
|
2143
2299
|
}
|
|
2144
2300
|
function formatTime(iso) {
|
|
2145
2301
|
try {
|
|
@@ -2161,89 +2317,134 @@ var styles5 = {
|
|
|
2161
2317
|
display: "flex",
|
|
2162
2318
|
alignItems: "flex-end",
|
|
2163
2319
|
gap: SPACE.S1,
|
|
2164
|
-
marginBottom: SPACE.
|
|
2320
|
+
marginBottom: SPACE.S3,
|
|
2165
2321
|
paddingLeft: SPACE.S4,
|
|
2166
2322
|
paddingRight: SPACE.S4
|
|
2167
2323
|
},
|
|
2168
2324
|
bubbleWrapper: {
|
|
2169
2325
|
position: "relative",
|
|
2170
|
-
maxWidth: "
|
|
2326
|
+
maxWidth: "78%",
|
|
2327
|
+
display: "flex",
|
|
2328
|
+
flexDirection: "column",
|
|
2329
|
+
gap: "4px"
|
|
2171
2330
|
},
|
|
2172
2331
|
actionsSlot: {
|
|
2173
2332
|
flexShrink: 0,
|
|
2174
2333
|
alignSelf: "flex-end"
|
|
2175
2334
|
},
|
|
2335
|
+
// Author row above the bubble — only rendered for others' messages.
|
|
2336
|
+
authorRow: {
|
|
2337
|
+
display: "flex",
|
|
2338
|
+
alignItems: "center",
|
|
2339
|
+
gap: SPACE.S2
|
|
2340
|
+
},
|
|
2341
|
+
authorAvatar: {
|
|
2342
|
+
width: "36px",
|
|
2343
|
+
height: "36px",
|
|
2344
|
+
borderRadius: "50%",
|
|
2345
|
+
color: COLOR.white,
|
|
2346
|
+
fontSize: FONT_SIZE.sm,
|
|
2347
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
2348
|
+
display: "flex",
|
|
2349
|
+
alignItems: "center",
|
|
2350
|
+
justifyContent: "center",
|
|
2351
|
+
flexShrink: 0,
|
|
2352
|
+
letterSpacing: "0.02em"
|
|
2353
|
+
},
|
|
2354
|
+
authorName: {
|
|
2355
|
+
fontSize: FONT_SIZE.sm,
|
|
2356
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
2357
|
+
color: COLOR.neutral700,
|
|
2358
|
+
overflow: "hidden",
|
|
2359
|
+
textOverflow: "ellipsis",
|
|
2360
|
+
whiteSpace: "nowrap",
|
|
2361
|
+
minWidth: 0
|
|
2362
|
+
},
|
|
2176
2363
|
bubble: {
|
|
2177
2364
|
padding: `${SPACE.S3} ${SPACE.S4}`,
|
|
2178
|
-
borderRadius:
|
|
2179
|
-
wordBreak: "break-word"
|
|
2365
|
+
borderRadius: "18px",
|
|
2366
|
+
wordBreak: "break-word",
|
|
2367
|
+
border: "1px solid transparent"
|
|
2180
2368
|
},
|
|
2181
2369
|
ownBubble: {
|
|
2182
2370
|
backgroundColor: COLOR.primary,
|
|
2183
2371
|
color: COLOR.white,
|
|
2184
|
-
|
|
2372
|
+
borderColor: COLOR.primary,
|
|
2373
|
+
borderBottomRightRadius: "6px"
|
|
2185
2374
|
},
|
|
2186
2375
|
otherBubble: {
|
|
2187
2376
|
backgroundColor: COLOR.neutral100,
|
|
2188
2377
|
color: COLOR.neutral900,
|
|
2189
|
-
|
|
2378
|
+
borderColor: COLOR.neutral200,
|
|
2379
|
+
borderBottomLeftRadius: "6px"
|
|
2190
2380
|
},
|
|
2191
2381
|
pinnedBadge: {
|
|
2192
2382
|
display: "inline-flex",
|
|
2193
2383
|
alignItems: "center",
|
|
2194
|
-
gap:
|
|
2195
|
-
fontSize:
|
|
2196
|
-
fontWeight: FONT_WEIGHT.
|
|
2197
|
-
marginBottom: SPACE.
|
|
2198
|
-
|
|
2384
|
+
gap: "4px",
|
|
2385
|
+
fontSize: "11px",
|
|
2386
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
2387
|
+
marginBottom: SPACE.S2,
|
|
2388
|
+
padding: `2px ${SPACE.S2}`,
|
|
2389
|
+
borderRadius: "999px",
|
|
2390
|
+
textTransform: "uppercase",
|
|
2391
|
+
letterSpacing: "0.05em"
|
|
2199
2392
|
},
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
gap: SPACE.S2,
|
|
2204
|
-
marginBottom: SPACE.S1
|
|
2393
|
+
pinnedBadgeOther: {
|
|
2394
|
+
color: "#b8680f",
|
|
2395
|
+
backgroundColor: "#fff7e0"
|
|
2205
2396
|
},
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
color: COLOR.neutral700
|
|
2397
|
+
pinnedBadgeOwn: {
|
|
2398
|
+
color: "#fff4d6",
|
|
2399
|
+
backgroundColor: "rgba(255, 255, 255, 0.2)"
|
|
2210
2400
|
},
|
|
2211
2401
|
roleBadge: {
|
|
2212
|
-
fontSize:
|
|
2213
|
-
fontWeight: FONT_WEIGHT.
|
|
2214
|
-
padding:
|
|
2215
|
-
borderRadius: RADIUS.sm
|
|
2402
|
+
fontSize: "10px",
|
|
2403
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
2404
|
+
padding: "2px 7px",
|
|
2405
|
+
borderRadius: RADIUS.sm,
|
|
2406
|
+
textTransform: "uppercase",
|
|
2407
|
+
letterSpacing: "0.06em",
|
|
2408
|
+
color: COLOR.white,
|
|
2409
|
+
flexShrink: 0
|
|
2216
2410
|
},
|
|
2217
2411
|
textBody: {
|
|
2218
2412
|
margin: 0,
|
|
2219
2413
|
fontSize: FONT_SIZE.md,
|
|
2220
|
-
lineHeight:
|
|
2414
|
+
lineHeight: 1.5
|
|
2415
|
+
},
|
|
2416
|
+
bubbleFoot: {
|
|
2417
|
+
display: "flex",
|
|
2418
|
+
alignItems: "center",
|
|
2419
|
+
justifyContent: "flex-end",
|
|
2420
|
+
gap: SPACE.S2,
|
|
2421
|
+
marginTop: SPACE.S2,
|
|
2422
|
+
fontSize: "11px",
|
|
2423
|
+
opacity: 0.85
|
|
2221
2424
|
},
|
|
2222
2425
|
timestamp: {
|
|
2223
|
-
fontSize:
|
|
2426
|
+
fontSize: "11px",
|
|
2224
2427
|
color: "inherit",
|
|
2225
|
-
|
|
2226
|
-
marginTop: SPACE.S1,
|
|
2227
|
-
textAlign: "right"
|
|
2428
|
+
fontVariantNumeric: "tabular-nums"
|
|
2228
2429
|
},
|
|
2229
|
-
|
|
2230
|
-
display: "flex",
|
|
2430
|
+
footStatus: {
|
|
2431
|
+
display: "inline-flex",
|
|
2231
2432
|
alignItems: "center",
|
|
2232
|
-
gap:
|
|
2233
|
-
|
|
2234
|
-
fontSize: FONT_SIZE.xs,
|
|
2235
|
-
justifyContent: "flex-end",
|
|
2236
|
-
color: "rgba(255, 255, 255, 0.9)"
|
|
2433
|
+
gap: "4px",
|
|
2434
|
+
fontSize: "11px"
|
|
2237
2435
|
},
|
|
2238
|
-
|
|
2239
|
-
|
|
2436
|
+
footStatusFailed: {
|
|
2437
|
+
display: "inline-flex",
|
|
2438
|
+
alignItems: "center",
|
|
2439
|
+
gap: "4px",
|
|
2440
|
+
fontSize: "11px"
|
|
2240
2441
|
},
|
|
2241
2442
|
retryButton: {
|
|
2242
2443
|
background: "transparent",
|
|
2243
2444
|
border: "none",
|
|
2244
2445
|
color: COLOR.white,
|
|
2245
2446
|
fontWeight: FONT_WEIGHT.semibold,
|
|
2246
|
-
fontSize:
|
|
2447
|
+
fontSize: "11px",
|
|
2247
2448
|
textDecoration: "underline",
|
|
2248
2449
|
cursor: "pointer",
|
|
2249
2450
|
padding: `0 ${SPACE.S1}`
|
|
@@ -2306,18 +2507,25 @@ var styles5 = {
|
|
|
2306
2507
|
color: COLOR.neutral500,
|
|
2307
2508
|
fontFamily: "monospace"
|
|
2308
2509
|
},
|
|
2309
|
-
|
|
2510
|
+
systemWrapper: {
|
|
2310
2511
|
display: "flex",
|
|
2311
2512
|
justifyContent: "center",
|
|
2513
|
+
margin: `${SPACE.S2} 0`
|
|
2514
|
+
},
|
|
2515
|
+
systemPill: {
|
|
2516
|
+
display: "inline-flex",
|
|
2312
2517
|
alignItems: "center",
|
|
2313
2518
|
gap: SPACE.S2,
|
|
2314
|
-
padding:
|
|
2315
|
-
|
|
2519
|
+
padding: `5px ${SPACE.S3}`,
|
|
2520
|
+
backgroundColor: COLOR.neutral100,
|
|
2521
|
+
borderRadius: "999px",
|
|
2522
|
+
fontSize: FONT_SIZE.xs,
|
|
2316
2523
|
color: COLOR.neutral500
|
|
2317
2524
|
},
|
|
2318
2525
|
systemTime: {
|
|
2319
|
-
fontSize:
|
|
2320
|
-
color: COLOR.neutral400
|
|
2526
|
+
fontSize: "11px",
|
|
2527
|
+
color: COLOR.neutral400,
|
|
2528
|
+
fontVariantNumeric: "tabular-nums"
|
|
2321
2529
|
}
|
|
2322
2530
|
};
|
|
2323
2531
|
function ChatIllustration({ size = 96 }) {
|
|
@@ -2456,6 +2664,7 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
2456
2664
|
const containerRef = React4.useRef(null);
|
|
2457
2665
|
const bottomRef = React4.useRef(null);
|
|
2458
2666
|
const prevMessageCount = React4.useRef(messages.length);
|
|
2667
|
+
const hasInitiallyScrolledRef = React4.useRef(false);
|
|
2459
2668
|
React4.useImperativeHandle(
|
|
2460
2669
|
ref,
|
|
2461
2670
|
() => ({
|
|
@@ -2473,7 +2682,31 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
2473
2682
|
}),
|
|
2474
2683
|
[]
|
|
2475
2684
|
);
|
|
2685
|
+
React4.useLayoutEffect(() => {
|
|
2686
|
+
const container = containerRef.current;
|
|
2687
|
+
if (!container || messages.length === 0) return;
|
|
2688
|
+
if (hasInitiallyScrolledRef.current) return;
|
|
2689
|
+
hasInitiallyScrolledRef.current = true;
|
|
2690
|
+
prevMessageCount.current = messages.length;
|
|
2691
|
+
const firstUnread = messages.find(
|
|
2692
|
+
(m) => m.type !== "system" && m.senderId !== currentUserId && !(m.readBy ?? []).includes(currentUserId)
|
|
2693
|
+
);
|
|
2694
|
+
if (firstUnread) {
|
|
2695
|
+
const el = container.querySelector(
|
|
2696
|
+
`[data-message-id="${firstUnread.id}"]`
|
|
2697
|
+
);
|
|
2698
|
+
if (el) {
|
|
2699
|
+
const containerRect = container.getBoundingClientRect();
|
|
2700
|
+
const elRect = el.getBoundingClientRect();
|
|
2701
|
+
const offset = elRect.top - containerRect.top + container.scrollTop;
|
|
2702
|
+
container.scrollTop = Math.max(0, offset - 16);
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
container.scrollTop = container.scrollHeight;
|
|
2707
|
+
}, [messages, currentUserId]);
|
|
2476
2708
|
React4.useEffect(() => {
|
|
2709
|
+
if (!hasInitiallyScrolledRef.current) return;
|
|
2477
2710
|
if (messages.length > prevMessageCount.current) {
|
|
2478
2711
|
const lastMessage = messages[messages.length - 1];
|
|
2479
2712
|
const isOwnMessage = lastMessage?.senderId === currentUserId;
|
|
@@ -2532,7 +2765,11 @@ var MessageList = React4.forwardRef(function MessageList2({
|
|
|
2532
2765
|
const showDivider = !!currentBucket && currentBucket !== lastValidBucket;
|
|
2533
2766
|
if (currentBucket) lastValidBucket = currentBucket;
|
|
2534
2767
|
return /* @__PURE__ */ jsxRuntime.jsxs(React4__default.default.Fragment, { children: [
|
|
2535
|
-
showDivider && /* @__PURE__ */ jsxRuntime.
|
|
2768
|
+
showDivider && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.dayDivider, role: "separator", "aria-label": "Date", children: [
|
|
2769
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.dayHr, "aria-hidden": "true" }),
|
|
2770
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.dayLabel, children: formatDayDivider(message.insertedAt) }),
|
|
2771
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.dayHr, "aria-hidden": "true" })
|
|
2772
|
+
] }),
|
|
2536
2773
|
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-message-id": message.id, "data-natoe-message-bubble": true, style: styles6.bubbleSlot, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2537
2774
|
MessageBubble,
|
|
2538
2775
|
{
|
|
@@ -2631,23 +2868,32 @@ var styles6 = {
|
|
|
2631
2868
|
},
|
|
2632
2869
|
dayDivider: {
|
|
2633
2870
|
display: "flex",
|
|
2634
|
-
|
|
2635
|
-
|
|
2871
|
+
alignItems: "center",
|
|
2872
|
+
gap: SPACE.S3,
|
|
2873
|
+
margin: `${SPACE.S4} 0 ${SPACE.S3}`,
|
|
2636
2874
|
position: "sticky",
|
|
2637
2875
|
top: SPACE.S1,
|
|
2638
2876
|
zIndex: Z_INDEX.sticky,
|
|
2639
2877
|
pointerEvents: "none"
|
|
2640
2878
|
},
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2879
|
+
dayHr: {
|
|
2880
|
+
flex: 1,
|
|
2881
|
+
height: "1px",
|
|
2882
|
+
backgroundColor: COLOR.neutral200
|
|
2883
|
+
},
|
|
2884
|
+
dayLabel: {
|
|
2885
|
+
flexShrink: 0,
|
|
2886
|
+
fontSize: FONT_SIZE.xs,
|
|
2887
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
2888
|
+
color: COLOR.neutral500,
|
|
2889
|
+
textTransform: "uppercase",
|
|
2890
|
+
letterSpacing: "0.06em",
|
|
2891
|
+
// Subtle pill background so the label is readable when it overlays
|
|
2892
|
+
// bubbles passing under it during sticky scroll. Without this the
|
|
2893
|
+
// hairlines visually run through the text on tinted backgrounds.
|
|
2894
|
+
padding: `2px ${SPACE.S2}`,
|
|
2895
|
+
backgroundColor: COLOR.white,
|
|
2896
|
+
borderRadius: RADIUS.sm
|
|
2651
2897
|
},
|
|
2652
2898
|
bubbleSlot: {
|
|
2653
2899
|
animation: "natoe-colab-message-in 180ms ease-out"
|
|
@@ -2901,11 +3147,11 @@ function MessageInput({
|
|
|
2901
3147
|
{
|
|
2902
3148
|
onClick: () => fileInputRef.current?.click(),
|
|
2903
3149
|
disabled: disabled || isSending,
|
|
2904
|
-
style: styles8.
|
|
3150
|
+
style: styles8.attachButton,
|
|
2905
3151
|
"aria-label": "Attach file",
|
|
2906
3152
|
title: "Attach file",
|
|
2907
3153
|
type: "button",
|
|
2908
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(AttachIcon, { size: 22, color:
|
|
3154
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(AttachIcon, { size: 22, color: COLOR.neutral700 })
|
|
2909
3155
|
}
|
|
2910
3156
|
),
|
|
2911
3157
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2944,7 +3190,7 @@ function MessageInput({
|
|
|
2944
3190
|
style: styles8.textarea
|
|
2945
3191
|
}
|
|
2946
3192
|
),
|
|
2947
|
-
/* @__PURE__ */ jsxRuntime.
|
|
3193
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2948
3194
|
"button",
|
|
2949
3195
|
{
|
|
2950
3196
|
onClick: handleSendText,
|
|
@@ -2953,10 +3199,13 @@ function MessageInput({
|
|
|
2953
3199
|
title: "Send message",
|
|
2954
3200
|
style: {
|
|
2955
3201
|
...styles8.sendButton,
|
|
2956
|
-
opacity: text.trim() ? 1 : 0.
|
|
3202
|
+
opacity: text.trim() ? 1 : 0.5
|
|
2957
3203
|
},
|
|
2958
3204
|
type: "button",
|
|
2959
|
-
children:
|
|
3205
|
+
children: [
|
|
3206
|
+
/* @__PURE__ */ jsxRuntime.jsx(SendIcon, { size: 20, color: COLOR.white }),
|
|
3207
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles8.sendLabel, children: "Send" })
|
|
3208
|
+
]
|
|
2960
3209
|
}
|
|
2961
3210
|
)
|
|
2962
3211
|
] })
|
|
@@ -3018,46 +3267,64 @@ var styles8 = {
|
|
|
3018
3267
|
inputBar: {
|
|
3019
3268
|
display: "flex",
|
|
3020
3269
|
alignItems: "flex-end",
|
|
3021
|
-
gap:
|
|
3022
|
-
padding: `${SPACE.S3} ${SPACE.
|
|
3023
|
-
},
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3270
|
+
gap: "10px",
|
|
3271
|
+
padding: `${SPACE.S3} ${SPACE.S4} 14px`
|
|
3272
|
+
},
|
|
3273
|
+
// 48px square tile with a 14px corner radius — visually grounds the
|
|
3274
|
+
// attach affordance as part of the composer chrome rather than a stray
|
|
3275
|
+
// round icon button.
|
|
3276
|
+
attachButton: {
|
|
3277
|
+
width: "48px",
|
|
3278
|
+
height: "48px",
|
|
3027
3279
|
display: "flex",
|
|
3028
3280
|
alignItems: "center",
|
|
3029
3281
|
justifyContent: "center",
|
|
3030
|
-
backgroundColor:
|
|
3031
|
-
border:
|
|
3032
|
-
borderRadius:
|
|
3282
|
+
backgroundColor: COLOR.neutral100,
|
|
3283
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
3284
|
+
borderRadius: "14px",
|
|
3033
3285
|
cursor: "pointer",
|
|
3034
|
-
flexShrink: 0
|
|
3286
|
+
flexShrink: 0,
|
|
3287
|
+
color: COLOR.neutral700,
|
|
3288
|
+
transition: "background-color 120ms ease, color 120ms ease, border-color 120ms ease"
|
|
3035
3289
|
},
|
|
3036
3290
|
textarea: {
|
|
3037
3291
|
flex: 1,
|
|
3038
|
-
|
|
3292
|
+
minHeight: "48px",
|
|
3293
|
+
maxHeight: "140px",
|
|
3294
|
+
padding: "13px 16px",
|
|
3039
3295
|
fontSize: FONT_SIZE.md,
|
|
3040
3296
|
lineHeight: LINE_HEIGHT.normal,
|
|
3041
|
-
|
|
3042
|
-
|
|
3297
|
+
color: COLOR.neutral900,
|
|
3298
|
+
backgroundColor: COLOR.neutral100,
|
|
3299
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
3300
|
+
borderRadius: "14px",
|
|
3043
3301
|
resize: "none",
|
|
3044
3302
|
outline: "none",
|
|
3045
3303
|
fontFamily: "inherit",
|
|
3046
|
-
|
|
3047
|
-
minHeight: SIZE.controlPrimary
|
|
3304
|
+
transition: "background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease"
|
|
3048
3305
|
},
|
|
3306
|
+
// Pill-shaped send: icon + "Send" label. Always labelled (never icon-
|
|
3307
|
+
// only) so the affordance is obvious to first-time users.
|
|
3049
3308
|
sendButton: {
|
|
3050
|
-
|
|
3051
|
-
height: SIZE.controlPrimary,
|
|
3052
|
-
display: "flex",
|
|
3309
|
+
display: "inline-flex",
|
|
3053
3310
|
alignItems: "center",
|
|
3054
|
-
|
|
3311
|
+
gap: "6px",
|
|
3312
|
+
minWidth: "48px",
|
|
3313
|
+
height: "48px",
|
|
3314
|
+
padding: `0 ${SPACE.S4}`,
|
|
3055
3315
|
backgroundColor: COLOR.primary,
|
|
3056
3316
|
color: COLOR.white,
|
|
3057
3317
|
border: "none",
|
|
3058
|
-
borderRadius:
|
|
3318
|
+
borderRadius: "14px",
|
|
3059
3319
|
cursor: "pointer",
|
|
3060
|
-
flexShrink: 0
|
|
3320
|
+
flexShrink: 0,
|
|
3321
|
+
fontFamily: "inherit",
|
|
3322
|
+
fontSize: "15px",
|
|
3323
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
3324
|
+
transition: "opacity 120ms ease, background-color 120ms ease"
|
|
3325
|
+
},
|
|
3326
|
+
sendLabel: {
|
|
3327
|
+
lineHeight: 1
|
|
3061
3328
|
}};
|
|
3062
3329
|
function ParticipantsList({
|
|
3063
3330
|
participants,
|
|
@@ -3114,10 +3381,14 @@ function fallbackName(role) {
|
|
|
3114
3381
|
}
|
|
3115
3382
|
function RoleBadge2({ role }) {
|
|
3116
3383
|
const colors = {
|
|
3117
|
-
radiologist: { bg: "#
|
|
3384
|
+
radiologist: { bg: "#eef2ff", text: "#4f46e5" },
|
|
3385
|
+
// indigo
|
|
3118
3386
|
lab: { bg: "#eff6ff", text: "#2563eb" },
|
|
3119
|
-
|
|
3120
|
-
|
|
3387
|
+
// brand blue
|
|
3388
|
+
physician: { bg: "#e0f2fe", text: "#0284c7" },
|
|
3389
|
+
// sky
|
|
3390
|
+
admin: { bg: "#f1f5f9", text: "#64748b" }
|
|
3391
|
+
// slate
|
|
3121
3392
|
};
|
|
3122
3393
|
const color = colors[role];
|
|
3123
3394
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles9.roleBadge, backgroundColor: color.bg, color: color.text }, children: role });
|
|
@@ -3726,45 +3997,6 @@ var styles12 = {
|
|
|
3726
3997
|
letterSpacing: "0.4px"
|
|
3727
3998
|
}
|
|
3728
3999
|
};
|
|
3729
|
-
|
|
3730
|
-
// src/core/styles.ts
|
|
3731
|
-
var FONT_STACK = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
|
|
3732
|
-
var ROOT_CLASS = "natoe-colab-root";
|
|
3733
|
-
var GLOBAL_STYLE_ID = "natoe-colab-global-styles";
|
|
3734
|
-
var GLOBAL_CSS = `
|
|
3735
|
-
@keyframes natoe-colab-spin { to { transform: rotate(360deg); } }
|
|
3736
|
-
|
|
3737
|
-
@keyframes natoe-colab-message-in {
|
|
3738
|
-
from { opacity: 0; transform: translateY(4px); }
|
|
3739
|
-
to { opacity: 1; transform: translateY(0); }
|
|
3740
|
-
}
|
|
3741
|
-
|
|
3742
|
-
/* High-contrast adjustments \u2014 older users on OS-level high-contrast mode
|
|
3743
|
-
get heavier borders and stronger text without losing the package look. */
|
|
3744
|
-
@media (prefers-contrast: more) {
|
|
3745
|
-
.${ROOT_CLASS} {
|
|
3746
|
-
color: #000000;
|
|
3747
|
-
}
|
|
3748
|
-
.${ROOT_CLASS} button {
|
|
3749
|
-
outline: 1px solid currentColor;
|
|
3750
|
-
}
|
|
3751
|
-
}
|
|
3752
|
-
|
|
3753
|
-
/* Honour reduced-motion preferences by killing entry animations. */
|
|
3754
|
-
@media (prefers-reduced-motion: reduce) {
|
|
3755
|
-
.${ROOT_CLASS} [data-natoe-message-bubble] {
|
|
3756
|
-
animation: none !important;
|
|
3757
|
-
}
|
|
3758
|
-
}
|
|
3759
|
-
`;
|
|
3760
|
-
function ensureGlobalStyles() {
|
|
3761
|
-
if (typeof document === "undefined") return;
|
|
3762
|
-
if (document.getElementById(GLOBAL_STYLE_ID)) return;
|
|
3763
|
-
const style = document.createElement("style");
|
|
3764
|
-
style.id = GLOBAL_STYLE_ID;
|
|
3765
|
-
style.textContent = GLOBAL_CSS;
|
|
3766
|
-
document.head.appendChild(style);
|
|
3767
|
-
}
|
|
3768
4000
|
ensureGlobalStyles();
|
|
3769
4001
|
function CollabPanel({
|
|
3770
4002
|
orderId,
|
|
@@ -4013,6 +4245,7 @@ function CollabPopup({
|
|
|
4013
4245
|
isOpen,
|
|
4014
4246
|
onClose,
|
|
4015
4247
|
onBack,
|
|
4248
|
+
onMinimize,
|
|
4016
4249
|
initialPosition,
|
|
4017
4250
|
width = 380,
|
|
4018
4251
|
height = 520,
|
|
@@ -4128,35 +4361,48 @@ function CollabPopup({
|
|
|
4128
4361
|
"button",
|
|
4129
4362
|
{
|
|
4130
4363
|
onClick: onBack,
|
|
4131
|
-
style: styles13.
|
|
4132
|
-
"aria-label": "
|
|
4364
|
+
style: styles13.titleSquare,
|
|
4365
|
+
"aria-label": "Back to messages",
|
|
4133
4366
|
title: "Back",
|
|
4134
4367
|
type: "button",
|
|
4135
|
-
children:
|
|
4368
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(BackIcon, { size: 18, color: COLOR.neutral700 })
|
|
4136
4369
|
}
|
|
4137
4370
|
),
|
|
4138
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4371
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.titleCenter, children: [
|
|
4372
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: titleId, style: styles13.patientName, children: patientData.patientName || titleText }),
|
|
4373
|
+
(patientData.labName || patientData.displayOrderId) && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.subRow, children: [
|
|
4374
|
+
patientData.labName && /* @__PURE__ */ jsxRuntime.jsx("span", { children: patientData.labName }),
|
|
4375
|
+
patientData.labName && patientData.displayOrderId && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles13.subDot, "aria-hidden": "true", children: "\xB7" }),
|
|
4376
|
+
patientData.displayOrderId && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles13.mono, children: [
|
|
4377
|
+
"#",
|
|
4378
|
+
patientData.displayOrderId.slice(-4)
|
|
4379
|
+
] })
|
|
4380
|
+
] })
|
|
4381
|
+
] }),
|
|
4139
4382
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.titleActions, children: [
|
|
4140
4383
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4141
4384
|
"button",
|
|
4142
4385
|
{
|
|
4143
|
-
onClick: () =>
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4386
|
+
onClick: () => {
|
|
4387
|
+
if (onMinimize) onMinimize();
|
|
4388
|
+
else setIsMinimized(!isMinimized);
|
|
4389
|
+
},
|
|
4390
|
+
style: styles13.titleSquare,
|
|
4391
|
+
"aria-label": onMinimize ? "Minimize chat" : isMinimized ? "Expand chat" : "Minimize chat",
|
|
4392
|
+
title: onMinimize ? "Minimize" : isMinimized ? "Expand" : "Minimize",
|
|
4147
4393
|
type: "button",
|
|
4148
|
-
children: isMinimized ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4394
|
+
children: onMinimize || !isMinimized ? /* @__PURE__ */ jsxRuntime.jsx(MinimizeIcon, { size: 18, color: COLOR.neutral700 }) : /* @__PURE__ */ jsxRuntime.jsx(ExpandIcon, { size: 18, color: COLOR.neutral700 })
|
|
4149
4395
|
}
|
|
4150
4396
|
),
|
|
4151
4397
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4152
4398
|
"button",
|
|
4153
4399
|
{
|
|
4154
4400
|
onClick: onClose,
|
|
4155
|
-
style: styles13.
|
|
4401
|
+
style: styles13.titleSquare,
|
|
4156
4402
|
"aria-label": "Close chat",
|
|
4157
4403
|
title: "Close",
|
|
4158
4404
|
type: "button",
|
|
4159
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { size:
|
|
4405
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { size: 18, color: COLOR.neutral700 })
|
|
4160
4406
|
}
|
|
4161
4407
|
)
|
|
4162
4408
|
] })
|
|
@@ -4179,51 +4425,78 @@ var styles13 = {
|
|
|
4179
4425
|
container: {
|
|
4180
4426
|
position: "fixed",
|
|
4181
4427
|
zIndex: Z_INDEX.dialog,
|
|
4182
|
-
borderRadius:
|
|
4183
|
-
boxShadow:
|
|
4428
|
+
borderRadius: "20px",
|
|
4429
|
+
boxShadow: "0 20px 48px rgba(20, 21, 28, 0.16), 0 6px 16px rgba(20, 21, 28, 0.08)",
|
|
4184
4430
|
overflow: "hidden",
|
|
4185
4431
|
display: "flex",
|
|
4186
4432
|
flexDirection: "column",
|
|
4187
4433
|
backgroundColor: COLOR.white,
|
|
4188
|
-
border: `1px solid ${COLOR.
|
|
4434
|
+
border: `1px solid ${COLOR.neutral300}`,
|
|
4189
4435
|
transition: "height 0.2s ease",
|
|
4190
4436
|
fontFamily: FONT_STACK
|
|
4191
4437
|
},
|
|
4192
4438
|
titleBar: {
|
|
4193
4439
|
display: "flex",
|
|
4194
|
-
justifyContent: "space-between",
|
|
4195
4440
|
alignItems: "center",
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
backgroundColor: COLOR.
|
|
4441
|
+
gap: SPACE.S2,
|
|
4442
|
+
padding: `10px ${SPACE.S3}`,
|
|
4443
|
+
backgroundColor: COLOR.white,
|
|
4444
|
+
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
4199
4445
|
cursor: "grab",
|
|
4200
4446
|
userSelect: "none",
|
|
4201
4447
|
flexShrink: 0
|
|
4202
4448
|
},
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4449
|
+
titleCenter: {
|
|
4450
|
+
flex: 1,
|
|
4451
|
+
minWidth: 0,
|
|
4452
|
+
display: "flex",
|
|
4453
|
+
flexDirection: "column",
|
|
4454
|
+
gap: "2px"
|
|
4455
|
+
},
|
|
4456
|
+
patientName: {
|
|
4457
|
+
margin: 0,
|
|
4458
|
+
fontSize: FONT_SIZE.lg,
|
|
4459
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
4460
|
+
letterSpacing: "-0.01em",
|
|
4461
|
+
color: COLOR.neutral900,
|
|
4207
4462
|
overflow: "hidden",
|
|
4208
4463
|
textOverflow: "ellipsis",
|
|
4209
4464
|
whiteSpace: "nowrap"
|
|
4210
4465
|
},
|
|
4466
|
+
subRow: {
|
|
4467
|
+
display: "flex",
|
|
4468
|
+
alignItems: "center",
|
|
4469
|
+
gap: SPACE.S2,
|
|
4470
|
+
fontSize: FONT_SIZE.sm,
|
|
4471
|
+
color: COLOR.neutral500,
|
|
4472
|
+
overflow: "hidden",
|
|
4473
|
+
textOverflow: "ellipsis",
|
|
4474
|
+
whiteSpace: "nowrap"
|
|
4475
|
+
},
|
|
4476
|
+
subDot: {
|
|
4477
|
+
color: COLOR.neutral400
|
|
4478
|
+
},
|
|
4479
|
+
mono: {
|
|
4480
|
+
fontFamily: "'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
4481
|
+
fontVariantNumeric: "tabular-nums"
|
|
4482
|
+
},
|
|
4211
4483
|
titleActions: {
|
|
4212
4484
|
display: "flex",
|
|
4213
4485
|
gap: SPACE.S1,
|
|
4214
4486
|
flexShrink: 0
|
|
4215
4487
|
},
|
|
4216
|
-
|
|
4217
|
-
width:
|
|
4218
|
-
height:
|
|
4488
|
+
titleSquare: {
|
|
4489
|
+
width: "36px",
|
|
4490
|
+
height: "36px",
|
|
4219
4491
|
display: "flex",
|
|
4220
4492
|
alignItems: "center",
|
|
4221
4493
|
justifyContent: "center",
|
|
4222
|
-
backgroundColor:
|
|
4223
|
-
border:
|
|
4494
|
+
backgroundColor: COLOR.neutral100,
|
|
4495
|
+
border: `1px solid ${COLOR.neutral200}`,
|
|
4224
4496
|
borderRadius: RADIUS.md,
|
|
4225
4497
|
cursor: "pointer",
|
|
4226
|
-
color: COLOR.
|
|
4498
|
+
color: COLOR.neutral700,
|
|
4499
|
+
flexShrink: 0
|
|
4227
4500
|
},
|
|
4228
4501
|
panelWrapper: {
|
|
4229
4502
|
flex: 1,
|
|
@@ -4527,10 +4800,14 @@ function InlineMessageRow({ message }) {
|
|
|
4527
4800
|
}
|
|
4528
4801
|
function RoleDot({ role }) {
|
|
4529
4802
|
const colors = {
|
|
4530
|
-
radiologist: "#
|
|
4803
|
+
radiologist: "#4f46e5",
|
|
4804
|
+
// indigo
|
|
4531
4805
|
lab: "#2563eb",
|
|
4532
|
-
|
|
4533
|
-
|
|
4806
|
+
// brand blue
|
|
4807
|
+
physician: "#0284c7",
|
|
4808
|
+
// sky
|
|
4809
|
+
admin: "#64748b"
|
|
4810
|
+
// slate
|
|
4534
4811
|
};
|
|
4535
4812
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles14.roleDot, backgroundColor: colors[role] } });
|
|
4536
4813
|
}
|
|
@@ -4952,6 +5229,10 @@ function ConversationListItem({
|
|
|
4952
5229
|
}) {
|
|
4953
5230
|
const hasUnread = item.unreadCount > 0;
|
|
4954
5231
|
const displayName = item.name || item.patientSnapshot?.patientName || "Unknown";
|
|
5232
|
+
const studyType = item.patientSnapshot?.studyType;
|
|
5233
|
+
const patientId = item.patientSnapshot?.patientId;
|
|
5234
|
+
const showStudyRow = !!(studyType || patientId);
|
|
5235
|
+
const initials = computeInitials2(item.patientSnapshot?.patientName || displayName);
|
|
4955
5236
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4956
5237
|
"button",
|
|
4957
5238
|
{
|
|
@@ -4959,15 +5240,11 @@ function ConversationListItem({
|
|
|
4959
5240
|
onClick,
|
|
4960
5241
|
style: {
|
|
4961
5242
|
...styles15.container,
|
|
4962
|
-
...isSelected ? styles15.selected : {}
|
|
4963
|
-
...hasUnread ? styles15.unread : {}
|
|
5243
|
+
...isSelected ? styles15.selected : {}
|
|
4964
5244
|
},
|
|
4965
5245
|
type: "button",
|
|
4966
5246
|
children: [
|
|
4967
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4968
|
-
item.picture ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.picture, alt: "", style: styles15.avatar }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.avatarFallback, children: (displayName).charAt(0).toUpperCase() }),
|
|
4969
|
-
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.unreadDot })
|
|
4970
|
-
] }),
|
|
5247
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.avatarWrapper, children: item.picture ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.picture, alt: "", style: styles15.avatarImg }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles15.avatarTile, "aria-hidden": "true", children: initials }) }),
|
|
4971
5248
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.content, children: [
|
|
4972
5249
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.topRow, children: [
|
|
4973
5250
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4991,101 +5268,120 @@ function ConversationListItem({
|
|
|
4991
5268
|
}
|
|
4992
5269
|
)
|
|
4993
5270
|
] }),
|
|
5271
|
+
showStudyRow && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.studyRow, children: [
|
|
5272
|
+
studyType && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.studyType, children: studyType }),
|
|
5273
|
+
studyType && patientId && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.studyDivider, children: "\xB7" }),
|
|
5274
|
+
patientId && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles15.studyId, children: [
|
|
5275
|
+
"MRN ",
|
|
5276
|
+
patientId
|
|
5277
|
+
] })
|
|
5278
|
+
] }),
|
|
4994
5279
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles15.bottomRow, children: [
|
|
4995
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4996
|
-
|
|
4997
|
-
{
|
|
4998
|
-
style: {
|
|
4999
|
-
...styles15.preview,
|
|
5000
|
-
...hasUnread ? styles15.previewUnread : {}
|
|
5001
|
-
},
|
|
5002
|
-
children: renderLastMessagePreview(item.lastMessage)
|
|
5003
|
-
}
|
|
5004
|
-
),
|
|
5005
|
-
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.badge, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
|
|
5280
|
+
/* @__PURE__ */ jsxRuntime.jsx(PreviewLine, { message: item.lastMessage, hasUnread }),
|
|
5281
|
+
hasUnread && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.badge, "aria-label": `${item.unreadCount} unread`, children: item.unreadCount > 99 ? "99+" : item.unreadCount })
|
|
5006
5282
|
] })
|
|
5007
5283
|
] })
|
|
5008
5284
|
]
|
|
5009
5285
|
}
|
|
5010
5286
|
);
|
|
5011
5287
|
}
|
|
5012
|
-
function
|
|
5013
|
-
if (!message)
|
|
5014
|
-
|
|
5288
|
+
function PreviewLine({ message, hasUnread }) {
|
|
5289
|
+
if (!message) {
|
|
5290
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.preview, children: "No messages yet" });
|
|
5291
|
+
}
|
|
5292
|
+
if (message.type === "system") {
|
|
5293
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles15.preview, children: message.body });
|
|
5294
|
+
}
|
|
5295
|
+
const text = previewText(message);
|
|
5296
|
+
const sender = message.senderName ? `${message.senderName.split(" ")[0]}:` : "";
|
|
5297
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5298
|
+
"span",
|
|
5299
|
+
{
|
|
5300
|
+
style: {
|
|
5301
|
+
...styles15.preview,
|
|
5302
|
+
...hasUnread ? styles15.previewUnread : {}
|
|
5303
|
+
},
|
|
5304
|
+
children: [
|
|
5305
|
+
sender && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles15.previewSender, children: [
|
|
5306
|
+
sender,
|
|
5307
|
+
" "
|
|
5308
|
+
] }),
|
|
5309
|
+
text
|
|
5310
|
+
]
|
|
5311
|
+
}
|
|
5312
|
+
);
|
|
5313
|
+
}
|
|
5314
|
+
function previewText(message) {
|
|
5015
5315
|
switch (message.type) {
|
|
5016
5316
|
case "audio":
|
|
5017
|
-
return
|
|
5317
|
+
return "Voice message";
|
|
5018
5318
|
case "image":
|
|
5019
|
-
return
|
|
5319
|
+
return message.fileName || "Image";
|
|
5020
5320
|
case "file":
|
|
5021
|
-
return
|
|
5321
|
+
return message.fileName || "File";
|
|
5022
5322
|
case "deep_link":
|
|
5023
|
-
return
|
|
5024
|
-
case "system":
|
|
5025
|
-
return message.body;
|
|
5323
|
+
return message.body || "Shared link";
|
|
5026
5324
|
default: {
|
|
5027
5325
|
const body = message.body || "";
|
|
5028
|
-
|
|
5029
|
-
return `${prefix}${preview}`;
|
|
5326
|
+
return body.length > 60 ? `${body.slice(0, 60)}\u2026` : body;
|
|
5030
5327
|
}
|
|
5031
5328
|
}
|
|
5032
5329
|
}
|
|
5330
|
+
function computeInitials2(name) {
|
|
5331
|
+
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("") || "?";
|
|
5332
|
+
}
|
|
5033
5333
|
var styles15 = {
|
|
5034
5334
|
container: {
|
|
5035
5335
|
display: "flex",
|
|
5036
|
-
alignItems: "
|
|
5037
|
-
gap:
|
|
5038
|
-
padding: `${SPACE.S3} ${SPACE.S3}`,
|
|
5336
|
+
alignItems: "flex-start",
|
|
5337
|
+
gap: "14px",
|
|
5039
5338
|
width: "100%",
|
|
5339
|
+
padding: `14px ${SPACE.S5}`,
|
|
5340
|
+
minHeight: "84px",
|
|
5040
5341
|
backgroundColor: "transparent",
|
|
5041
5342
|
border: "none",
|
|
5042
|
-
|
|
5343
|
+
borderLeft: "4px solid transparent",
|
|
5043
5344
|
cursor: "pointer",
|
|
5044
|
-
textAlign: "left"
|
|
5345
|
+
textAlign: "left",
|
|
5346
|
+
color: "inherit",
|
|
5347
|
+
fontFamily: "inherit",
|
|
5348
|
+
transition: "background-color 120ms ease"
|
|
5045
5349
|
},
|
|
5046
5350
|
selected: {
|
|
5047
|
-
backgroundColor: COLOR.primaryBg
|
|
5351
|
+
backgroundColor: COLOR.primaryBg,
|
|
5352
|
+
borderLeftColor: COLOR.primary
|
|
5048
5353
|
},
|
|
5049
|
-
unread: {},
|
|
5050
5354
|
avatarWrapper: {
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
height: SIZE.avatar,
|
|
5355
|
+
width: "52px",
|
|
5356
|
+
height: "52px",
|
|
5054
5357
|
flexShrink: 0
|
|
5055
5358
|
},
|
|
5056
|
-
|
|
5057
|
-
width:
|
|
5058
|
-
height:
|
|
5059
|
-
borderRadius: RADIUS.
|
|
5060
|
-
objectFit: "cover"
|
|
5359
|
+
avatarImg: {
|
|
5360
|
+
width: "52px",
|
|
5361
|
+
height: "52px",
|
|
5362
|
+
borderRadius: RADIUS.xl,
|
|
5363
|
+
objectFit: "cover",
|
|
5364
|
+
boxShadow: "inset 0 -2px 0 rgba(0, 0, 0, 0.08)"
|
|
5061
5365
|
},
|
|
5062
|
-
|
|
5063
|
-
width:
|
|
5064
|
-
height:
|
|
5065
|
-
borderRadius: RADIUS.
|
|
5066
|
-
backgroundColor: COLOR.
|
|
5366
|
+
avatarTile: {
|
|
5367
|
+
width: "52px",
|
|
5368
|
+
height: "52px",
|
|
5369
|
+
borderRadius: RADIUS.xl,
|
|
5370
|
+
backgroundColor: COLOR.primary,
|
|
5371
|
+
color: COLOR.white,
|
|
5067
5372
|
display: "flex",
|
|
5068
5373
|
alignItems: "center",
|
|
5069
5374
|
justifyContent: "center",
|
|
5070
|
-
fontSize: FONT_SIZE.
|
|
5071
|
-
fontWeight: FONT_WEIGHT.
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
unreadDot: {
|
|
5075
|
-
position: "absolute",
|
|
5076
|
-
top: "0",
|
|
5077
|
-
left: "0",
|
|
5078
|
-
width: SIZE.dot,
|
|
5079
|
-
height: SIZE.dot,
|
|
5080
|
-
borderRadius: RADIUS.full,
|
|
5081
|
-
backgroundColor: COLOR.primary,
|
|
5082
|
-
border: `2px solid ${COLOR.white}`
|
|
5375
|
+
fontSize: FONT_SIZE.lg,
|
|
5376
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
5377
|
+
letterSpacing: "0.02em",
|
|
5378
|
+
boxShadow: "inset 0 -2px 0 rgba(0, 0, 0, 0.08)"
|
|
5083
5379
|
},
|
|
5084
5380
|
content: {
|
|
5085
5381
|
flex: 1,
|
|
5086
5382
|
display: "flex",
|
|
5087
5383
|
flexDirection: "column",
|
|
5088
|
-
gap: "
|
|
5384
|
+
gap: "3px",
|
|
5089
5385
|
minWidth: 0
|
|
5090
5386
|
},
|
|
5091
5387
|
topRow: {
|
|
@@ -5110,123 +5406,191 @@ var styles15 = {
|
|
|
5110
5406
|
time: {
|
|
5111
5407
|
fontSize: FONT_SIZE.xs,
|
|
5112
5408
|
color: COLOR.neutral500,
|
|
5409
|
+
fontVariantNumeric: "tabular-nums",
|
|
5113
5410
|
flexShrink: 0
|
|
5114
5411
|
},
|
|
5115
5412
|
timeUnread: {
|
|
5116
5413
|
color: COLOR.primary,
|
|
5117
5414
|
fontWeight: FONT_WEIGHT.semibold
|
|
5118
5415
|
},
|
|
5416
|
+
studyRow: {
|
|
5417
|
+
display: "flex",
|
|
5418
|
+
alignItems: "center",
|
|
5419
|
+
gap: SPACE.S2,
|
|
5420
|
+
minWidth: 0
|
|
5421
|
+
},
|
|
5422
|
+
studyType: {
|
|
5423
|
+
fontSize: FONT_SIZE.sm,
|
|
5424
|
+
color: COLOR.neutral500,
|
|
5425
|
+
overflow: "hidden",
|
|
5426
|
+
textOverflow: "ellipsis",
|
|
5427
|
+
whiteSpace: "nowrap"
|
|
5428
|
+
},
|
|
5429
|
+
studyDivider: {
|
|
5430
|
+
fontSize: FONT_SIZE.sm,
|
|
5431
|
+
color: COLOR.neutral400,
|
|
5432
|
+
flexShrink: 0
|
|
5433
|
+
},
|
|
5434
|
+
studyId: {
|
|
5435
|
+
fontSize: FONT_SIZE.sm,
|
|
5436
|
+
color: COLOR.neutral500,
|
|
5437
|
+
fontFamily: "'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
5438
|
+
fontVariantNumeric: "tabular-nums",
|
|
5439
|
+
flexShrink: 0
|
|
5440
|
+
},
|
|
5119
5441
|
bottomRow: {
|
|
5120
5442
|
display: "flex",
|
|
5121
5443
|
justifyContent: "space-between",
|
|
5122
5444
|
alignItems: "center",
|
|
5123
|
-
gap: SPACE.S2
|
|
5445
|
+
gap: SPACE.S2,
|
|
5446
|
+
marginTop: "2px"
|
|
5124
5447
|
},
|
|
5125
5448
|
preview: {
|
|
5126
5449
|
fontSize: FONT_SIZE.sm,
|
|
5127
|
-
color: COLOR.
|
|
5450
|
+
color: COLOR.neutral500,
|
|
5128
5451
|
overflow: "hidden",
|
|
5129
5452
|
textOverflow: "ellipsis",
|
|
5130
5453
|
whiteSpace: "nowrap",
|
|
5131
5454
|
flex: 1,
|
|
5132
5455
|
minWidth: 0
|
|
5133
5456
|
},
|
|
5457
|
+
previewSender: {
|
|
5458
|
+
color: COLOR.neutral700,
|
|
5459
|
+
fontWeight: FONT_WEIGHT.semibold
|
|
5460
|
+
},
|
|
5134
5461
|
previewUnread: {
|
|
5135
5462
|
color: COLOR.neutral900,
|
|
5136
5463
|
fontWeight: FONT_WEIGHT.medium
|
|
5137
5464
|
},
|
|
5138
5465
|
badge: {
|
|
5139
|
-
minWidth: "
|
|
5140
|
-
height: "
|
|
5141
|
-
padding:
|
|
5466
|
+
minWidth: "22px",
|
|
5467
|
+
height: "22px",
|
|
5468
|
+
padding: "0 9px",
|
|
5142
5469
|
fontSize: FONT_SIZE.xs,
|
|
5143
|
-
fontWeight: FONT_WEIGHT.
|
|
5470
|
+
fontWeight: FONT_WEIGHT.bold,
|
|
5144
5471
|
color: COLOR.white,
|
|
5145
|
-
backgroundColor: COLOR.
|
|
5472
|
+
backgroundColor: COLOR.danger,
|
|
5146
5473
|
borderRadius: RADIUS.pill,
|
|
5147
5474
|
display: "flex",
|
|
5148
5475
|
alignItems: "center",
|
|
5149
5476
|
justifyContent: "center",
|
|
5477
|
+
fontVariantNumeric: "tabular-nums",
|
|
5150
5478
|
flexShrink: 0
|
|
5151
5479
|
}
|
|
5152
5480
|
};
|
|
5481
|
+
function SearchIcon({ size = 20, color = "currentColor" }) {
|
|
5482
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5483
|
+
"svg",
|
|
5484
|
+
{
|
|
5485
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5486
|
+
width: size,
|
|
5487
|
+
height: size,
|
|
5488
|
+
viewBox: "0 0 24 24",
|
|
5489
|
+
fill: "none",
|
|
5490
|
+
stroke: color,
|
|
5491
|
+
strokeWidth: "2",
|
|
5492
|
+
strokeLinecap: "round",
|
|
5493
|
+
strokeLinejoin: "round",
|
|
5494
|
+
"aria-hidden": "true",
|
|
5495
|
+
children: [
|
|
5496
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "7" }),
|
|
5497
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 20l-4-4" })
|
|
5498
|
+
]
|
|
5499
|
+
}
|
|
5500
|
+
);
|
|
5501
|
+
}
|
|
5153
5502
|
function ConversationList({
|
|
5154
5503
|
conversations,
|
|
5155
5504
|
selectedId,
|
|
5156
5505
|
isLoading,
|
|
5157
5506
|
error,
|
|
5158
5507
|
onSelect,
|
|
5159
|
-
title = "Conversations",
|
|
5160
5508
|
className
|
|
5161
5509
|
}) {
|
|
5162
5510
|
const [query, setQuery] = React4.useState("");
|
|
5163
|
-
const [
|
|
5511
|
+
const [filter, setFilter] = React4.useState("all");
|
|
5512
|
+
const [searchFocused, setSearchFocused] = React4.useState(false);
|
|
5513
|
+
const unreadCount = React4.useMemo(
|
|
5514
|
+
() => conversations.filter((c) => c.unreadCount > 0).length,
|
|
5515
|
+
[conversations]
|
|
5516
|
+
);
|
|
5517
|
+
const autoDefaultedRef = React4.useRef(false);
|
|
5518
|
+
React4.useEffect(() => {
|
|
5519
|
+
if (autoDefaultedRef.current) return;
|
|
5520
|
+
if (conversations.length === 0) return;
|
|
5521
|
+
autoDefaultedRef.current = true;
|
|
5522
|
+
if (unreadCount > 0) setFilter("unread");
|
|
5523
|
+
}, [conversations.length, unreadCount]);
|
|
5164
5524
|
const filtered = React4.useMemo(() => {
|
|
5165
5525
|
let result = conversations;
|
|
5166
|
-
if (
|
|
5526
|
+
if (filter === "unread") {
|
|
5167
5527
|
result = result.filter((c) => c.unreadCount > 0);
|
|
5168
5528
|
}
|
|
5169
5529
|
const q = query.trim().toLowerCase();
|
|
5170
5530
|
if (q) {
|
|
5171
5531
|
result = result.filter((c) => {
|
|
5172
|
-
const patient = c.patientSnapshot?.patientName?.toLowerCase() || "";
|
|
5173
5532
|
const name = c.name.toLowerCase();
|
|
5174
|
-
|
|
5533
|
+
const patient = c.patientSnapshot?.patientName?.toLowerCase() || "";
|
|
5534
|
+
const studyType = c.patientSnapshot?.studyType?.toLowerCase() || "";
|
|
5535
|
+
const patientId = c.patientSnapshot?.patientId?.toLowerCase() || "";
|
|
5536
|
+
return name.includes(q) || patient.includes(q) || studyType.includes(q) || patientId.includes(q);
|
|
5175
5537
|
});
|
|
5176
5538
|
}
|
|
5177
5539
|
return result;
|
|
5178
|
-
}, [conversations, query,
|
|
5179
|
-
const totalUnread = conversations.reduce((sum, c) => sum + c.unreadCount, 0);
|
|
5540
|
+
}, [conversations, query, filter]);
|
|
5180
5541
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: styles16.container, children: [
|
|
5181
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.
|
|
5182
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5183
|
-
|
|
5184
|
-
totalUnread > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles16.totalBadge, children: totalUnread })
|
|
5185
|
-
] }),
|
|
5186
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.searchRow, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5187
|
-
"input",
|
|
5542
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.tabs, children: [
|
|
5543
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5544
|
+
TabButton,
|
|
5188
5545
|
{
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
style: styles16.searchInput
|
|
5546
|
+
label: "Unread",
|
|
5547
|
+
count: unreadCount,
|
|
5548
|
+
isActive: filter === "unread",
|
|
5549
|
+
onClick: () => setFilter("unread")
|
|
5194
5550
|
}
|
|
5195
|
-
)
|
|
5196
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
type: "button",
|
|
5206
|
-
children: "All"
|
|
5207
|
-
}
|
|
5208
|
-
),
|
|
5209
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5210
|
-
"button",
|
|
5211
|
-
{
|
|
5212
|
-
onClick: () => setShowUnreadOnly(true),
|
|
5213
|
-
style: {
|
|
5214
|
-
...styles16.filterButton,
|
|
5215
|
-
...showUnreadOnly ? styles16.filterButtonActive : {}
|
|
5216
|
-
},
|
|
5217
|
-
type: "button",
|
|
5218
|
-
children: [
|
|
5219
|
-
"Unread ",
|
|
5220
|
-
totalUnread > 0 && `(${totalUnread})`
|
|
5221
|
-
]
|
|
5222
|
-
}
|
|
5223
|
-
)
|
|
5224
|
-
] })
|
|
5551
|
+
),
|
|
5552
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5553
|
+
TabButton,
|
|
5554
|
+
{
|
|
5555
|
+
label: "All",
|
|
5556
|
+
count: conversations.length,
|
|
5557
|
+
isActive: filter === "all",
|
|
5558
|
+
onClick: () => setFilter("all")
|
|
5559
|
+
}
|
|
5560
|
+
)
|
|
5225
5561
|
] }),
|
|
5562
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5563
|
+
"div",
|
|
5564
|
+
{
|
|
5565
|
+
style: {
|
|
5566
|
+
...styles16.search,
|
|
5567
|
+
...searchFocused ? styles16.searchFocused : {}
|
|
5568
|
+
},
|
|
5569
|
+
children: [
|
|
5570
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles16.searchIcon, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { size: 20, color: COLOR.neutral500 }) }),
|
|
5571
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5572
|
+
"input",
|
|
5573
|
+
{
|
|
5574
|
+
type: "text",
|
|
5575
|
+
value: query,
|
|
5576
|
+
onChange: (e) => setQuery(e.target.value),
|
|
5577
|
+
onFocus: () => setSearchFocused(true),
|
|
5578
|
+
onBlur: () => setSearchFocused(false),
|
|
5579
|
+
placeholder: "Search by patient name or MRN",
|
|
5580
|
+
"aria-label": "Search conversations",
|
|
5581
|
+
style: styles16.searchInput
|
|
5582
|
+
}
|
|
5583
|
+
)
|
|
5584
|
+
]
|
|
5585
|
+
}
|
|
5586
|
+
),
|
|
5226
5587
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.list, children: [
|
|
5227
|
-
isLoading && /* @__PURE__ */ jsxRuntime.
|
|
5228
|
-
|
|
5229
|
-
|
|
5588
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.loading, children: [
|
|
5589
|
+
/* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 16 }),
|
|
5590
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Loading conversations\u2026" })
|
|
5591
|
+
] }),
|
|
5592
|
+
error && !isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles16.errorState, children: error }),
|
|
5593
|
+
!isLoading && !error && filtered.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { filter, hasQuery: query.trim().length > 0 }),
|
|
5230
5594
|
filtered.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5231
5595
|
ConversationListItem,
|
|
5232
5596
|
{
|
|
@@ -5239,95 +5603,178 @@ function ConversationList({
|
|
|
5239
5603
|
] })
|
|
5240
5604
|
] });
|
|
5241
5605
|
}
|
|
5606
|
+
function TabButton({
|
|
5607
|
+
label,
|
|
5608
|
+
count,
|
|
5609
|
+
isActive,
|
|
5610
|
+
onClick
|
|
5611
|
+
}) {
|
|
5612
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5613
|
+
"button",
|
|
5614
|
+
{
|
|
5615
|
+
type: "button",
|
|
5616
|
+
onClick,
|
|
5617
|
+
style: {
|
|
5618
|
+
...styles16.tab,
|
|
5619
|
+
...isActive ? styles16.tabActive : {}
|
|
5620
|
+
},
|
|
5621
|
+
children: [
|
|
5622
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
|
|
5623
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5624
|
+
"span",
|
|
5625
|
+
{
|
|
5626
|
+
style: {
|
|
5627
|
+
...styles16.tabCount,
|
|
5628
|
+
...isActive ? styles16.tabCountActive : {}
|
|
5629
|
+
},
|
|
5630
|
+
children: count
|
|
5631
|
+
}
|
|
5632
|
+
)
|
|
5633
|
+
]
|
|
5634
|
+
}
|
|
5635
|
+
);
|
|
5636
|
+
}
|
|
5637
|
+
function EmptyState({ filter, hasQuery }) {
|
|
5638
|
+
let title = "No conversations yet";
|
|
5639
|
+
let subtitle = "New chats will show up here as cases come in.";
|
|
5640
|
+
if (filter === "unread") {
|
|
5641
|
+
title = "No unread messages";
|
|
5642
|
+
subtitle = "You're all caught up.";
|
|
5643
|
+
} else if (hasQuery) {
|
|
5644
|
+
title = "No conversations match";
|
|
5645
|
+
subtitle = "Try a different search.";
|
|
5646
|
+
}
|
|
5647
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles16.empty, children: [
|
|
5648
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChatIllustration, { size: 88 }),
|
|
5649
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles16.emptyTitle, children: title }),
|
|
5650
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles16.emptySubtitle, children: subtitle })
|
|
5651
|
+
] });
|
|
5652
|
+
}
|
|
5242
5653
|
var styles16 = {
|
|
5243
5654
|
container: {
|
|
5244
5655
|
display: "flex",
|
|
5245
5656
|
flexDirection: "column",
|
|
5246
5657
|
height: "100%",
|
|
5247
|
-
backgroundColor: COLOR.white
|
|
5248
|
-
borderRight: `1px solid ${COLOR.neutral200}`
|
|
5658
|
+
backgroundColor: COLOR.white
|
|
5249
5659
|
},
|
|
5250
|
-
header
|
|
5251
|
-
|
|
5660
|
+
// Tabs sit at the top of the panel now (header section removed).
|
|
5661
|
+
// A bit more top padding so they don't crowd the top edge.
|
|
5662
|
+
tabs: {
|
|
5663
|
+
display: "flex",
|
|
5664
|
+
gap: SPACE.S2,
|
|
5665
|
+
padding: `${SPACE.S5} ${SPACE.S5} ${SPACE.S2}`,
|
|
5252
5666
|
borderBottom: `1px solid ${COLOR.neutral200}`,
|
|
5253
|
-
backgroundColor: COLOR.neutral50,
|
|
5254
5667
|
flexShrink: 0
|
|
5255
5668
|
},
|
|
5256
|
-
|
|
5257
|
-
display: "flex",
|
|
5669
|
+
tab: {
|
|
5670
|
+
display: "inline-flex",
|
|
5258
5671
|
alignItems: "center",
|
|
5259
5672
|
gap: SPACE.S2,
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5673
|
+
padding: `${SPACE.S2} ${SPACE.S4}`,
|
|
5674
|
+
backgroundColor: "transparent",
|
|
5675
|
+
border: "none",
|
|
5676
|
+
borderRadius: RADIUS.lg,
|
|
5677
|
+
cursor: "pointer",
|
|
5678
|
+
color: COLOR.neutral500,
|
|
5679
|
+
fontFamily: "inherit",
|
|
5680
|
+
fontSize: FONT_SIZE.sm,
|
|
5265
5681
|
fontWeight: FONT_WEIGHT.semibold,
|
|
5266
|
-
|
|
5682
|
+
transition: "background-color 120ms ease, color 120ms ease"
|
|
5267
5683
|
},
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5684
|
+
tabActive: {
|
|
5685
|
+
backgroundColor: COLOR.primaryBg,
|
|
5686
|
+
color: COLOR.primary
|
|
5687
|
+
},
|
|
5688
|
+
tabCount: {
|
|
5272
5689
|
fontSize: FONT_SIZE.xs,
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
backgroundColor: COLOR.primary,
|
|
5690
|
+
fontVariantNumeric: "tabular-nums",
|
|
5691
|
+
padding: "1px 8px",
|
|
5276
5692
|
borderRadius: RADIUS.pill,
|
|
5693
|
+
backgroundColor: COLOR.neutral200,
|
|
5694
|
+
color: COLOR.neutral500,
|
|
5695
|
+
fontWeight: FONT_WEIGHT.semibold
|
|
5696
|
+
},
|
|
5697
|
+
tabCountActive: {
|
|
5698
|
+
backgroundColor: COLOR.primary,
|
|
5699
|
+
color: COLOR.white
|
|
5700
|
+
},
|
|
5701
|
+
search: {
|
|
5277
5702
|
display: "flex",
|
|
5278
5703
|
alignItems: "center",
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5704
|
+
gap: SPACE.S2,
|
|
5705
|
+
margin: `14px ${SPACE.S5} ${SPACE.S3}`,
|
|
5706
|
+
padding: `${SPACE.S3} 14px`,
|
|
5707
|
+
backgroundColor: COLOR.neutral100,
|
|
5708
|
+
border: `1.5px solid ${COLOR.neutral200}`,
|
|
5709
|
+
borderRadius: "14px",
|
|
5710
|
+
transition: "background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease"
|
|
5283
5711
|
},
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
border: `1px solid ${COLOR.neutral200}`,
|
|
5289
|
-
borderRadius: RADIUS.md,
|
|
5290
|
-
outline: "none",
|
|
5291
|
-
fontFamily: "inherit"
|
|
5712
|
+
searchFocused: {
|
|
5713
|
+
backgroundColor: COLOR.white,
|
|
5714
|
+
borderColor: COLOR.primary,
|
|
5715
|
+
boxShadow: `0 0 0 3px ${COLOR.primaryBg}`
|
|
5292
5716
|
},
|
|
5293
|
-
|
|
5717
|
+
searchIcon: {
|
|
5294
5718
|
display: "flex",
|
|
5295
|
-
|
|
5719
|
+
alignItems: "center",
|
|
5720
|
+
justifyContent: "center",
|
|
5721
|
+
flexShrink: 0
|
|
5296
5722
|
},
|
|
5297
|
-
|
|
5723
|
+
searchInput: {
|
|
5298
5724
|
flex: 1,
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
},
|
|
5307
|
-
filterButtonActive: {
|
|
5308
|
-
color: COLOR.white,
|
|
5309
|
-
backgroundColor: COLOR.primary,
|
|
5310
|
-
borderColor: COLOR.primary,
|
|
5311
|
-
fontWeight: FONT_WEIGHT.medium
|
|
5725
|
+
minWidth: 0,
|
|
5726
|
+
border: "none",
|
|
5727
|
+
background: "transparent",
|
|
5728
|
+
outline: "none",
|
|
5729
|
+
fontFamily: "inherit",
|
|
5730
|
+
fontSize: FONT_SIZE.md,
|
|
5731
|
+
color: COLOR.neutral900
|
|
5312
5732
|
},
|
|
5313
5733
|
list: {
|
|
5314
5734
|
flex: 1,
|
|
5315
|
-
overflowY: "auto"
|
|
5735
|
+
overflowY: "auto",
|
|
5736
|
+
padding: "4px 0 12px"
|
|
5316
5737
|
},
|
|
5317
|
-
|
|
5318
|
-
|
|
5738
|
+
loading: {
|
|
5739
|
+
display: "flex",
|
|
5740
|
+
alignItems: "center",
|
|
5741
|
+
justifyContent: "center",
|
|
5742
|
+
gap: SPACE.S2,
|
|
5743
|
+
padding: `44px ${SPACE.S5}`,
|
|
5319
5744
|
fontSize: FONT_SIZE.sm,
|
|
5320
|
-
color: COLOR.neutral500
|
|
5321
|
-
textAlign: "center"
|
|
5745
|
+
color: COLOR.neutral500
|
|
5322
5746
|
},
|
|
5323
5747
|
errorState: {
|
|
5324
5748
|
padding: SPACE.S4,
|
|
5749
|
+
margin: SPACE.S3,
|
|
5325
5750
|
fontSize: FONT_SIZE.sm,
|
|
5326
5751
|
color: COLOR.danger,
|
|
5327
5752
|
backgroundColor: COLOR.dangerBg,
|
|
5328
|
-
|
|
5753
|
+
border: `1px solid ${COLOR.dangerBorder}`,
|
|
5329
5754
|
borderRadius: RADIUS.md,
|
|
5330
5755
|
textAlign: "center"
|
|
5756
|
+
},
|
|
5757
|
+
empty: {
|
|
5758
|
+
display: "flex",
|
|
5759
|
+
flexDirection: "column",
|
|
5760
|
+
alignItems: "center",
|
|
5761
|
+
justifyContent: "center",
|
|
5762
|
+
padding: "44px 24px",
|
|
5763
|
+
textAlign: "center",
|
|
5764
|
+
color: COLOR.neutral500
|
|
5765
|
+
},
|
|
5766
|
+
emptyTitle: {
|
|
5767
|
+
margin: "12px 0 4px",
|
|
5768
|
+
fontSize: FONT_SIZE.md,
|
|
5769
|
+
fontWeight: FONT_WEIGHT.semibold,
|
|
5770
|
+
color: COLOR.neutral700
|
|
5771
|
+
},
|
|
5772
|
+
emptySubtitle: {
|
|
5773
|
+
margin: 0,
|
|
5774
|
+
fontSize: FONT_SIZE.sm,
|
|
5775
|
+
color: COLOR.neutral500,
|
|
5776
|
+
maxWidth: "280px",
|
|
5777
|
+
lineHeight: LINE_HEIGHT.normal
|
|
5331
5778
|
}
|
|
5332
5779
|
};
|
|
5333
5780
|
ensureGlobalStyles();
|
|
@@ -5335,7 +5782,6 @@ var COMPACT_BREAKPOINT = 720;
|
|
|
5335
5782
|
function CollabInbox({
|
|
5336
5783
|
initialConversationId,
|
|
5337
5784
|
onSelectConversation,
|
|
5338
|
-
title,
|
|
5339
5785
|
className,
|
|
5340
5786
|
style
|
|
5341
5787
|
}) {
|
|
@@ -5372,8 +5818,7 @@ function CollabInbox({
|
|
|
5372
5818
|
selectedId,
|
|
5373
5819
|
isLoading,
|
|
5374
5820
|
error,
|
|
5375
|
-
onSelect: handleSelect
|
|
5376
|
-
title
|
|
5821
|
+
onSelect: handleSelect
|
|
5377
5822
|
}
|
|
5378
5823
|
) }),
|
|
5379
5824
|
showDetail && /* @__PURE__ */ jsxRuntime.jsx("div", { style: isCompact ? styles17.mainCompact : styles17.main, children: selected ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5386,7 +5831,7 @@ function CollabInbox({
|
|
|
5386
5831
|
onBack: isCompact ? () => setSelectedId(null) : void 0
|
|
5387
5832
|
},
|
|
5388
5833
|
selected.id
|
|
5389
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
5834
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(EmptyState2, { hasAny: conversations.length > 0 }) })
|
|
5390
5835
|
]
|
|
5391
5836
|
}
|
|
5392
5837
|
);
|
|
@@ -5420,7 +5865,7 @@ function parseChannelName(name, orderId) {
|
|
|
5420
5865
|
orderId
|
|
5421
5866
|
};
|
|
5422
5867
|
}
|
|
5423
|
-
function
|
|
5868
|
+
function EmptyState2({ hasAny }) {
|
|
5424
5869
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles17.empty, children: [
|
|
5425
5870
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles17.emptyIcon, children: "\u{1F4AC}" }),
|
|
5426
5871
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { style: styles17.emptyTitle, children: hasAny ? "Select a conversation" : "No conversations yet" }),
|
|
@@ -5826,7 +6271,10 @@ exports.ReplyPreview = ReplyPreview;
|
|
|
5826
6271
|
exports.ReplyQuoteBlock = ReplyQuoteBlock;
|
|
5827
6272
|
exports.SUPPORTED_IMAGE_TYPES = SUPPORTED_IMAGE_TYPES;
|
|
5828
6273
|
exports.SeenByIndicator = SeenByIndicator;
|
|
6274
|
+
exports.THEME_DEFAULTS = THEME_DEFAULTS;
|
|
6275
|
+
exports.THEME_VAR = THEME_VAR;
|
|
5829
6276
|
exports.TYPING_DEBOUNCE_MS = TYPING_DEBOUNCE_MS;
|
|
6277
|
+
exports.applyThemeOverrides = applyThemeOverrides;
|
|
5830
6278
|
exports.useAudioRecorder = useAudioRecorder;
|
|
5831
6279
|
exports.useChannelSettings = useChannelSettings;
|
|
5832
6280
|
exports.useCollab = useCollab;
|