@natoe/colab 0.1.10 → 0.1.12

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 CHANGED
@@ -185,6 +185,13 @@ interface CollabPanelProps {
185
185
  onBack?: () => void;
186
186
  /** Hide the patient name row in the header — set when a parent already shows it (e.g. CollabPopup title bar) */
187
187
  hidePatientName?: boolean;
188
+ /**
189
+ * Notified whenever the underlying conversation state changes (initial
190
+ * preview load, create, channel deletion). Lets a parent like CollabPopup
191
+ * render its title bar from the authoritative conversation.name instead of
192
+ * relying on potentially-incomplete patientData.
193
+ */
194
+ onConversationChange?: (conversation: Conversation | null) => void;
188
195
  /** Custom class name for the outer container */
189
196
  className?: string;
190
197
  /** Custom inline styles for the outer container */
@@ -194,7 +201,7 @@ interface CollabPanelProps {
194
201
  * Full collaboration panel: patient header + pinned bar + message thread + input.
195
202
  * Supports reply, pin/unpin, and (optionally) seen-by indicators.
196
203
  */
197
- declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
204
+ declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, onConversationChange, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
198
205
 
199
206
  interface CollabPopupProps {
200
207
  /** Order ID for this conversation */
package/dist/index.d.ts CHANGED
@@ -185,6 +185,13 @@ interface CollabPanelProps {
185
185
  onBack?: () => void;
186
186
  /** Hide the patient name row in the header — set when a parent already shows it (e.g. CollabPopup title bar) */
187
187
  hidePatientName?: boolean;
188
+ /**
189
+ * Notified whenever the underlying conversation state changes (initial
190
+ * preview load, create, channel deletion). Lets a parent like CollabPopup
191
+ * render its title bar from the authoritative conversation.name instead of
192
+ * relying on potentially-incomplete patientData.
193
+ */
194
+ onConversationChange?: (conversation: Conversation | null) => void;
188
195
  /** Custom class name for the outer container */
189
196
  className?: string;
190
197
  /** Custom inline styles for the outer container */
@@ -194,7 +201,7 @@ interface CollabPanelProps {
194
201
  * Full collaboration panel: patient header + pinned bar + message thread + input.
195
202
  * Supports reply, pin/unpin, and (optionally) seen-by indicators.
196
203
  */
197
- declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
204
+ declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, onConversationChange, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
198
205
 
199
206
  interface CollabPopupProps {
200
207
  /** Order ID for this conversation */
package/dist/index.js CHANGED
@@ -575,7 +575,11 @@ function buildChannelName(patientData) {
575
575
  const patientPart = patientData.patientName?.trim() || "Unknown";
576
576
  const labPart = patientData.labName?.trim()?.slice(0, 24) || "";
577
577
  const last4 = (patientData.displayOrderId ?? "").trim().slice(-4) || "0000";
578
- return `${patientPart} - ${labPart} - ${last4}`;
578
+ return labPart ? `${patientPart} - ${labPart} - ${last4}` : `${patientPart} - ${last4}`;
579
+ }
580
+ function cleanChannelName(name) {
581
+ if (!name) return "";
582
+ return name.replace(/\s+-\s+-\s+/g, " - ").trim();
579
583
  }
580
584
 
581
585
  // src/hooks/useConversation.ts
@@ -610,8 +614,11 @@ function useConversation({
610
614
  const ensureConversationInFlight = React4.useRef(null);
611
615
  const markedReadIdsRef = React4.useRef(/* @__PURE__ */ new Set());
612
616
  const buildName = React4.useCallback(
613
- () => buildChannelName(patientData),
614
- [patientData]
617
+ () => {
618
+ const labName = patientData.labName ?? (config.userRole === "lab" ? config.userName : void 0);
619
+ return buildChannelName({ ...patientData, labName });
620
+ },
621
+ [patientData, config.userRole, config.userName]
615
622
  );
616
623
  const joinChannel = React4.useCallback(
617
624
  (conv) => {
@@ -1298,6 +1305,11 @@ var Z_INDEX = {
1298
1305
  /** Portaled message-actions menu — must sit above the dialog. */
1299
1306
  menu: 1e4
1300
1307
  };
1308
+ function resolveDisplayName(patientData, displayName) {
1309
+ const localComplete = !!patientData.labName && !!patientData.displayOrderId;
1310
+ if (localComplete) return buildChannelName(patientData);
1311
+ return cleanChannelName(displayName) || buildChannelName(patientData);
1312
+ }
1301
1313
  function PatientHeader({
1302
1314
  patientData,
1303
1315
  onOpenDicom,
@@ -1331,7 +1343,7 @@ function PatientHeader({
1331
1343
  children: /* @__PURE__ */ jsxRuntime.jsx(BackIcon, { size: 22, color: COLOR.neutral800 })
1332
1344
  }
1333
1345
  ),
1334
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.nameText, children: displayName ?? buildChannelName(patientData) })
1346
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles.nameText, children: resolveDisplayName(patientData, displayName) })
1335
1347
  ] }),
1336
1348
  meta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles.metaRow, children: meta.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles.metaItem, children: [
1337
1349
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles.metaLabel, children: [
@@ -3761,6 +3773,7 @@ function CollabPanel({
3761
3773
  showSeenBy = true,
3762
3774
  onBack,
3763
3775
  hidePatientName = false,
3776
+ onConversationChange,
3764
3777
  className,
3765
3778
  style
3766
3779
  }) {
@@ -3789,6 +3802,9 @@ function CollabPanel({
3789
3802
  pinMessage,
3790
3803
  unpinMessage
3791
3804
  } = useConversation({ orderId, patientData, participantIds });
3805
+ React4.useEffect(() => {
3806
+ onConversationChange?.(conversation);
3807
+ }, [conversation, onConversationChange]);
3792
3808
  const channelSettings = useChannelSettings({
3793
3809
  conversationId: conversation?.id ?? null
3794
3810
  });
@@ -4010,10 +4026,12 @@ function CollabPopup({
4010
4026
  );
4011
4027
  const [isDragging, setIsDragging] = React4.useState(false);
4012
4028
  const [isMinimized, setIsMinimized] = React4.useState(false);
4029
+ const [loadedConversation, setLoadedConversation] = React4.useState(null);
4013
4030
  const dragOffset = React4.useRef({ x: 0, y: 0 });
4014
4031
  const containerRef = React4.useRef(null);
4015
4032
  const previouslyFocused = React4.useRef(null);
4016
4033
  const titleId = React4.useId();
4034
+ const titleText = cleanChannelName(loadedConversation?.name) || buildChannelName(patientData);
4017
4035
  const handleMouseDown = React4.useCallback(
4018
4036
  (e) => {
4019
4037
  if (!e.target.closest("[data-drag-handle]")) return;
@@ -4117,7 +4135,7 @@ function CollabPopup({
4117
4135
  children: "\u2190"
4118
4136
  }
4119
4137
  ),
4120
- /* @__PURE__ */ jsxRuntime.jsx("span", { id: titleId, style: { ...styles13.titleText, flex: 1 }, children: buildChannelName(patientData) }),
4138
+ /* @__PURE__ */ jsxRuntime.jsx("span", { id: titleId, style: { ...styles13.titleText, flex: 1 }, children: titleText }),
4121
4139
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles13.titleActions, children: [
4122
4140
  /* @__PURE__ */ jsxRuntime.jsx(
4123
4141
  "button",
@@ -4143,7 +4161,16 @@ function CollabPopup({
4143
4161
  )
4144
4162
  ] })
4145
4163
  ] }),
4146
- !isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(CollabPanel, { orderId, patientData, participantIds, hidePatientName: true }) })
4164
+ !isMinimized && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles13.panelWrapper, children: /* @__PURE__ */ jsxRuntime.jsx(
4165
+ CollabPanel,
4166
+ {
4167
+ orderId,
4168
+ patientData,
4169
+ participantIds,
4170
+ hidePatientName: true,
4171
+ onConversationChange: setLoadedConversation
4172
+ }
4173
+ ) })
4147
4174
  ]
4148
4175
  }
4149
4176
  );
@@ -5365,8 +5392,18 @@ function CollabInbox({
5365
5392
  );
5366
5393
  }
5367
5394
  function buildPatientData(item) {
5368
- if (item.patientSnapshot) return item.patientSnapshot;
5369
- const parts = item.name.split(" - ");
5395
+ const parsed = parseChannelName(item.name, item.orderId);
5396
+ if (item.patientSnapshot) {
5397
+ return {
5398
+ ...item.patientSnapshot,
5399
+ labName: item.patientSnapshot.labName ?? parsed.labName,
5400
+ displayOrderId: item.patientSnapshot.displayOrderId ?? parsed.displayOrderId
5401
+ };
5402
+ }
5403
+ return parsed;
5404
+ }
5405
+ function parseChannelName(name, orderId) {
5406
+ const parts = name.split(" - ");
5370
5407
  if (parts.length >= 3) {
5371
5408
  const last4 = parts[parts.length - 1];
5372
5409
  const labName = parts[parts.length - 2];
@@ -5374,13 +5411,13 @@ function buildPatientData(item) {
5374
5411
  return {
5375
5412
  patientName,
5376
5413
  labName: labName || void 0,
5377
- orderId: item.orderId,
5414
+ orderId,
5378
5415
  displayOrderId: last4
5379
5416
  };
5380
5417
  }
5381
5418
  return {
5382
- patientName: item.name,
5383
- orderId: item.orderId
5419
+ patientName: name,
5420
+ orderId
5384
5421
  };
5385
5422
  }
5386
5423
  function EmptyState({ hasAny }) {