@natoe/colab 0.1.14 → 0.1.17
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 +61 -16
- package/dist/index.d.ts +61 -16
- package/dist/index.js +263 -175
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +263 -175
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -78,6 +78,13 @@ interface CollabConfig {
|
|
|
78
78
|
theme?: Theme;
|
|
79
79
|
/** Host app callbacks — colab calls these, never implements them */
|
|
80
80
|
onOpenDicom?: (studyId: string, storageId: string) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Open the case behind this conversation. Wired to the package's
|
|
83
|
+
* PatientHeader "Open" button (sibling to "View DICOM"). The host
|
|
84
|
+
* decides how to route — typically role-aware: lab → case page,
|
|
85
|
+
* radiologist → viewer, physician → order history.
|
|
86
|
+
*/
|
|
87
|
+
onOpenCase?: (orderId: string, displayOrderId?: string) => void;
|
|
81
88
|
onUploadFile?: (file: File | Blob, fileName?: string) => Promise<string>;
|
|
82
89
|
onDeepLink?: (path: string) => void;
|
|
83
90
|
onError?: (error: CollabError) => void;
|
|
@@ -256,6 +263,14 @@ interface CollabPanelProps {
|
|
|
256
263
|
onBack?: () => void;
|
|
257
264
|
/** Hide the patient name row in the header — set when a parent already shows it (e.g. CollabPopup title bar) */
|
|
258
265
|
hidePatientName?: boolean;
|
|
266
|
+
/**
|
|
267
|
+
* Suppress the PatientHeader "Open" button even when the host has
|
|
268
|
+
* supplied `config.onOpenCase`. Set this when the panel is rendered
|
|
269
|
+
* for the same case the user is already on (e.g. embedded in the
|
|
270
|
+
* viewer's left panel) — otherwise clicking Open would re-fetch the
|
|
271
|
+
* current order and overwrite in-progress context.
|
|
272
|
+
*/
|
|
273
|
+
hideOpenCase?: boolean;
|
|
259
274
|
/**
|
|
260
275
|
* Notified whenever the underlying conversation state changes (initial
|
|
261
276
|
* preview load, create, channel deletion). Lets a parent like CollabPopup
|
|
@@ -280,7 +295,7 @@ interface CollabPanelProps {
|
|
|
280
295
|
* Full collaboration panel: patient header + pinned bar + message thread + input.
|
|
281
296
|
* Supports reply, pin/unpin, and (optionally) seen-by indicators.
|
|
282
297
|
*/
|
|
283
|
-
declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, onConversationChange, themeMode, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
|
|
298
|
+
declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, hideOpenCase, onConversationChange, themeMode, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
|
|
284
299
|
|
|
285
300
|
interface CollabPopupProps {
|
|
286
301
|
/** Order ID for this conversation */
|
|
@@ -380,6 +395,20 @@ type PresenceCallback = (presences: Record<string, {
|
|
|
380
395
|
userId: string;
|
|
381
396
|
isOnline: boolean;
|
|
382
397
|
}>) => void;
|
|
398
|
+
/**
|
|
399
|
+
* Server-pushed unread counts. The backend broadcasts BOTH keyings in
|
|
400
|
+
* one payload so consumers can render badges at either granularity (FAB
|
|
401
|
+
* + inbox row use `conversation`; table-row chat icons use `order`) off
|
|
402
|
+
* a single socket event. Legacy backends that send a flat
|
|
403
|
+
* `Record<string, number>` are normalised at the socket boundary into
|
|
404
|
+
* `{ conversation: <flat>, order: {} }` for forward compatibility.
|
|
405
|
+
*/
|
|
406
|
+
interface UnreadCounts {
|
|
407
|
+
/** keyed by conversation id */
|
|
408
|
+
conversation: Record<string, number>;
|
|
409
|
+
/** keyed by order id — used for table-row chat-icon badges */
|
|
410
|
+
order: Record<string, number>;
|
|
411
|
+
}
|
|
383
412
|
interface ConversationCallbacks {
|
|
384
413
|
onMessage?: MessageCallback;
|
|
385
414
|
onTyping?: TypingCallback;
|
|
@@ -433,8 +462,10 @@ declare class CollabSocket {
|
|
|
433
462
|
connect(config: CollabConfig): void;
|
|
434
463
|
/** Subscribe to user-level events (unread counts, notifications) */
|
|
435
464
|
private joinUserChannel;
|
|
436
|
-
/** Register callback for unread count changes
|
|
437
|
-
|
|
465
|
+
/** Register callback for unread count changes. The callback receives
|
|
466
|
+
* the normalised {@link UnreadCounts} shape regardless of which
|
|
467
|
+
* payload format the backend pushed. */
|
|
468
|
+
onUnreadCountUpdate(callback: (counts: UnreadCounts) => void): void;
|
|
438
469
|
/**
|
|
439
470
|
* Join a conversation channel and subscribe to events.
|
|
440
471
|
*
|
|
@@ -512,6 +543,13 @@ interface CollabContextValue {
|
|
|
512
543
|
* mounting their own useConversation.
|
|
513
544
|
*/
|
|
514
545
|
unreadCounts: Record<string, number>;
|
|
546
|
+
/**
|
|
547
|
+
* Same unread counts, but keyed by **order ID** instead of
|
|
548
|
+
* conversation ID. Useful for table-row chat-icon badges where the
|
|
549
|
+
* row only knows its order_id, not the conversation_id. Same socket
|
|
550
|
+
* push updates both maps in lock-step.
|
|
551
|
+
*/
|
|
552
|
+
unreadCountsByOrder: Record<string, number>;
|
|
515
553
|
/** Batched preview lookup — coalesces calls within a microtask */
|
|
516
554
|
requestPreview: (orderId: string) => Promise<ConversationPreview | null>;
|
|
517
555
|
/** Invalidate a cached preview (e.g. when a new message arrives) */
|
|
@@ -834,30 +872,37 @@ interface PatientHeaderProps {
|
|
|
834
872
|
patientData: PatientData;
|
|
835
873
|
participants: Participant[];
|
|
836
874
|
onOpenDicom?: () => void;
|
|
875
|
+
/**
|
|
876
|
+
* Open the case behind this conversation — bound to the "Open" button
|
|
877
|
+
* that sits next to "View DICOM". When undefined, the button is
|
|
878
|
+
* hidden.
|
|
879
|
+
*/
|
|
880
|
+
onOpenCase?: () => void;
|
|
837
881
|
onOpenSettings?: () => void;
|
|
838
882
|
/** When set, renders a back-arrow button (compact inbox returning to list) */
|
|
839
883
|
onBack?: () => void;
|
|
840
|
-
/** Suppress the
|
|
884
|
+
/** Suppress the patient name row — use when the name is already shown in a parent title bar */
|
|
841
885
|
hideName?: boolean;
|
|
842
886
|
/** Override the displayed name — use the stored conversation.name to avoid reconstructing from patientData components */
|
|
843
887
|
displayName?: string;
|
|
844
888
|
className?: string;
|
|
845
889
|
}
|
|
846
890
|
/**
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
*
|
|
851
|
-
*
|
|
891
|
+
* Compact case header. One zone, two rows:
|
|
892
|
+
*
|
|
893
|
+
* Row 1: [back?] Patient Name [View DICOM] [Open] [👥 4]
|
|
894
|
+
* Row 2: 54 · M · CT · Knee
|
|
895
|
+
*
|
|
896
|
+
* Replaces the older "case card" layout (labelled meta columns —
|
|
897
|
+
* Age/Sex, Modality, Body part — stacked below the name row). That
|
|
898
|
+
* layout cost ~70-80px of vertical real estate on every chat surface
|
|
899
|
+
* and pushed the message thread further down the panel. This version
|
|
900
|
+
* lands at ~52-60px and conveys the same identifying context inline.
|
|
852
901
|
*
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
* shows the patient name, so we render the case card only.
|
|
856
|
-
* - Compact-inbox path (`hideName=false`): the panel is a full-page
|
|
857
|
-
* experience and there's no outer title, so we still show the name +
|
|
858
|
-
* back button stacked above the case card.
|
|
902
|
+
* When `hideName=true` (CollabPopup wraps the conversation in its own
|
|
903
|
+
* window title), only the meta + actions row renders.
|
|
859
904
|
*/
|
|
860
|
-
declare function PatientHeader({ patientData, participants, onOpenDicom, onOpenSettings, onBack, hideName, displayName, className, }: PatientHeaderProps): react_jsx_runtime.JSX.Element;
|
|
905
|
+
declare function PatientHeader({ patientData, participants, onOpenDicom, onOpenCase, onOpenSettings, onBack, hideName, displayName, className, }: PatientHeaderProps): react_jsx_runtime.JSX.Element;
|
|
861
906
|
|
|
862
907
|
interface MessageListHandle {
|
|
863
908
|
/** Scroll to a specific message by ID (used by pin jump-to) */
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,13 @@ interface CollabConfig {
|
|
|
78
78
|
theme?: Theme;
|
|
79
79
|
/** Host app callbacks — colab calls these, never implements them */
|
|
80
80
|
onOpenDicom?: (studyId: string, storageId: string) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Open the case behind this conversation. Wired to the package's
|
|
83
|
+
* PatientHeader "Open" button (sibling to "View DICOM"). The host
|
|
84
|
+
* decides how to route — typically role-aware: lab → case page,
|
|
85
|
+
* radiologist → viewer, physician → order history.
|
|
86
|
+
*/
|
|
87
|
+
onOpenCase?: (orderId: string, displayOrderId?: string) => void;
|
|
81
88
|
onUploadFile?: (file: File | Blob, fileName?: string) => Promise<string>;
|
|
82
89
|
onDeepLink?: (path: string) => void;
|
|
83
90
|
onError?: (error: CollabError) => void;
|
|
@@ -256,6 +263,14 @@ interface CollabPanelProps {
|
|
|
256
263
|
onBack?: () => void;
|
|
257
264
|
/** Hide the patient name row in the header — set when a parent already shows it (e.g. CollabPopup title bar) */
|
|
258
265
|
hidePatientName?: boolean;
|
|
266
|
+
/**
|
|
267
|
+
* Suppress the PatientHeader "Open" button even when the host has
|
|
268
|
+
* supplied `config.onOpenCase`. Set this when the panel is rendered
|
|
269
|
+
* for the same case the user is already on (e.g. embedded in the
|
|
270
|
+
* viewer's left panel) — otherwise clicking Open would re-fetch the
|
|
271
|
+
* current order and overwrite in-progress context.
|
|
272
|
+
*/
|
|
273
|
+
hideOpenCase?: boolean;
|
|
259
274
|
/**
|
|
260
275
|
* Notified whenever the underlying conversation state changes (initial
|
|
261
276
|
* preview load, create, channel deletion). Lets a parent like CollabPopup
|
|
@@ -280,7 +295,7 @@ interface CollabPanelProps {
|
|
|
280
295
|
* Full collaboration panel: patient header + pinned bar + message thread + input.
|
|
281
296
|
* Supports reply, pin/unpin, and (optionally) seen-by indicators.
|
|
282
297
|
*/
|
|
283
|
-
declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, onConversationChange, themeMode, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
|
|
298
|
+
declare function CollabPanel({ orderId, patientData, participantIds, showSeenBy, onBack, hidePatientName, hideOpenCase, onConversationChange, themeMode, className, style, }: CollabPanelProps): react_jsx_runtime.JSX.Element;
|
|
284
299
|
|
|
285
300
|
interface CollabPopupProps {
|
|
286
301
|
/** Order ID for this conversation */
|
|
@@ -380,6 +395,20 @@ type PresenceCallback = (presences: Record<string, {
|
|
|
380
395
|
userId: string;
|
|
381
396
|
isOnline: boolean;
|
|
382
397
|
}>) => void;
|
|
398
|
+
/**
|
|
399
|
+
* Server-pushed unread counts. The backend broadcasts BOTH keyings in
|
|
400
|
+
* one payload so consumers can render badges at either granularity (FAB
|
|
401
|
+
* + inbox row use `conversation`; table-row chat icons use `order`) off
|
|
402
|
+
* a single socket event. Legacy backends that send a flat
|
|
403
|
+
* `Record<string, number>` are normalised at the socket boundary into
|
|
404
|
+
* `{ conversation: <flat>, order: {} }` for forward compatibility.
|
|
405
|
+
*/
|
|
406
|
+
interface UnreadCounts {
|
|
407
|
+
/** keyed by conversation id */
|
|
408
|
+
conversation: Record<string, number>;
|
|
409
|
+
/** keyed by order id — used for table-row chat-icon badges */
|
|
410
|
+
order: Record<string, number>;
|
|
411
|
+
}
|
|
383
412
|
interface ConversationCallbacks {
|
|
384
413
|
onMessage?: MessageCallback;
|
|
385
414
|
onTyping?: TypingCallback;
|
|
@@ -433,8 +462,10 @@ declare class CollabSocket {
|
|
|
433
462
|
connect(config: CollabConfig): void;
|
|
434
463
|
/** Subscribe to user-level events (unread counts, notifications) */
|
|
435
464
|
private joinUserChannel;
|
|
436
|
-
/** Register callback for unread count changes
|
|
437
|
-
|
|
465
|
+
/** Register callback for unread count changes. The callback receives
|
|
466
|
+
* the normalised {@link UnreadCounts} shape regardless of which
|
|
467
|
+
* payload format the backend pushed. */
|
|
468
|
+
onUnreadCountUpdate(callback: (counts: UnreadCounts) => void): void;
|
|
438
469
|
/**
|
|
439
470
|
* Join a conversation channel and subscribe to events.
|
|
440
471
|
*
|
|
@@ -512,6 +543,13 @@ interface CollabContextValue {
|
|
|
512
543
|
* mounting their own useConversation.
|
|
513
544
|
*/
|
|
514
545
|
unreadCounts: Record<string, number>;
|
|
546
|
+
/**
|
|
547
|
+
* Same unread counts, but keyed by **order ID** instead of
|
|
548
|
+
* conversation ID. Useful for table-row chat-icon badges where the
|
|
549
|
+
* row only knows its order_id, not the conversation_id. Same socket
|
|
550
|
+
* push updates both maps in lock-step.
|
|
551
|
+
*/
|
|
552
|
+
unreadCountsByOrder: Record<string, number>;
|
|
515
553
|
/** Batched preview lookup — coalesces calls within a microtask */
|
|
516
554
|
requestPreview: (orderId: string) => Promise<ConversationPreview | null>;
|
|
517
555
|
/** Invalidate a cached preview (e.g. when a new message arrives) */
|
|
@@ -834,30 +872,37 @@ interface PatientHeaderProps {
|
|
|
834
872
|
patientData: PatientData;
|
|
835
873
|
participants: Participant[];
|
|
836
874
|
onOpenDicom?: () => void;
|
|
875
|
+
/**
|
|
876
|
+
* Open the case behind this conversation — bound to the "Open" button
|
|
877
|
+
* that sits next to "View DICOM". When undefined, the button is
|
|
878
|
+
* hidden.
|
|
879
|
+
*/
|
|
880
|
+
onOpenCase?: () => void;
|
|
837
881
|
onOpenSettings?: () => void;
|
|
838
882
|
/** When set, renders a back-arrow button (compact inbox returning to list) */
|
|
839
883
|
onBack?: () => void;
|
|
840
|
-
/** Suppress the
|
|
884
|
+
/** Suppress the patient name row — use when the name is already shown in a parent title bar */
|
|
841
885
|
hideName?: boolean;
|
|
842
886
|
/** Override the displayed name — use the stored conversation.name to avoid reconstructing from patientData components */
|
|
843
887
|
displayName?: string;
|
|
844
888
|
className?: string;
|
|
845
889
|
}
|
|
846
890
|
/**
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
*
|
|
851
|
-
*
|
|
891
|
+
* Compact case header. One zone, two rows:
|
|
892
|
+
*
|
|
893
|
+
* Row 1: [back?] Patient Name [View DICOM] [Open] [👥 4]
|
|
894
|
+
* Row 2: 54 · M · CT · Knee
|
|
895
|
+
*
|
|
896
|
+
* Replaces the older "case card" layout (labelled meta columns —
|
|
897
|
+
* Age/Sex, Modality, Body part — stacked below the name row). That
|
|
898
|
+
* layout cost ~70-80px of vertical real estate on every chat surface
|
|
899
|
+
* and pushed the message thread further down the panel. This version
|
|
900
|
+
* lands at ~52-60px and conveys the same identifying context inline.
|
|
852
901
|
*
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
* shows the patient name, so we render the case card only.
|
|
856
|
-
* - Compact-inbox path (`hideName=false`): the panel is a full-page
|
|
857
|
-
* experience and there's no outer title, so we still show the name +
|
|
858
|
-
* back button stacked above the case card.
|
|
902
|
+
* When `hideName=true` (CollabPopup wraps the conversation in its own
|
|
903
|
+
* window title), only the meta + actions row renders.
|
|
859
904
|
*/
|
|
860
|
-
declare function PatientHeader({ patientData, participants, onOpenDicom, onOpenSettings, onBack, hideName, displayName, className, }: PatientHeaderProps): react_jsx_runtime.JSX.Element;
|
|
905
|
+
declare function PatientHeader({ patientData, participants, onOpenDicom, onOpenCase, onOpenSettings, onBack, hideName, displayName, className, }: PatientHeaderProps): react_jsx_runtime.JSX.Element;
|
|
861
906
|
|
|
862
907
|
interface MessageListHandle {
|
|
863
908
|
/** Scroll to a specific message by ID (used by pin jump-to) */
|