@jupyter/chat 0.23.0-alpha.2 → 0.23.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/__tests__/input-model.spec.d.ts +9 -0
- package/lib/__tests__/input-model.spec.js +102 -0
- package/lib/__tests__/model.spec.js +17 -3
- package/lib/__tests__/multichat-panel.spec.js +78 -27
- package/lib/components/messages/message.js +15 -8
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/input-model.d.ts +50 -2
- package/lib/input-model.js +57 -1
- package/lib/model.d.ts +14 -0
- package/lib/model.js +4 -1
- package/lib/tokens.d.ts +21 -5
- package/lib/types.d.ts +1 -4
- package/lib/utils.d.ts +11 -0
- package/lib/utils.js +42 -0
- package/lib/widgets/multichat-panel.d.ts +20 -20
- package/lib/widgets/multichat-panel.js +33 -48
- package/package.json +3 -1
- package/src/__tests__/input-model.spec.ts +129 -0
- package/src/__tests__/model.spec.ts +18 -0
- package/src/__tests__/multichat-panel.spec.ts +93 -37
- package/src/components/messages/message.tsx +21 -11
- package/src/index.ts +1 -0
- package/src/input-model.ts +106 -4
- package/src/model.ts +19 -1
- package/src/tokens.ts +21 -5
- package/src/types.ts +6 -4
- package/src/utils.ts +59 -0
- package/src/widgets/multichat-panel.tsx +54 -66
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
* Originally adapted from jupyterlab-chat's ChatPanel
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { InputDialog } from '@jupyterlab/apputils';
|
|
11
|
+
import { InputDialog, ToolbarRegistry } from '@jupyterlab/apputils';
|
|
12
|
+
import { IObservableList } from '@jupyterlab/observables';
|
|
12
13
|
import { nullTranslator, TranslationBundle } from '@jupyterlab/translation';
|
|
13
14
|
import {
|
|
14
15
|
addIcon,
|
|
15
16
|
closeIcon,
|
|
16
|
-
launchIcon,
|
|
17
17
|
PanelWithToolbar,
|
|
18
18
|
ReactiveToolbar,
|
|
19
19
|
ReactWidget,
|
|
@@ -37,9 +37,10 @@ import {
|
|
|
37
37
|
IInputToolbarRegistryFactory
|
|
38
38
|
} from '../components';
|
|
39
39
|
import { TRANSLATION_DOMAIN } from '../context';
|
|
40
|
-
import { chatIcon
|
|
40
|
+
import { chatIcon } from '../icons';
|
|
41
41
|
import { IChatModel } from '../model';
|
|
42
|
-
import { IChatPlaceholderFactory } from '../tokens';
|
|
42
|
+
import { IChatPanel, IChatPlaceholderFactory } from '../tokens';
|
|
43
|
+
import { ChatArea } from '../types';
|
|
43
44
|
|
|
44
45
|
const SIDEPANEL_CLASS = 'jp-chat-sidepanel';
|
|
45
46
|
const ADD_BUTTON_CLASS = 'jp-chat-add';
|
|
@@ -86,10 +87,10 @@ export class MultiChatPanel extends PanelWithToolbar {
|
|
|
86
87
|
|
|
87
88
|
this._chatOptions = options;
|
|
88
89
|
this._inputToolbarFactory = options.inputToolbarFactory;
|
|
90
|
+
this._chatToolbarFactory = options.chatToolbarFactory;
|
|
89
91
|
|
|
90
92
|
this._getChatNames = options.getChatNames;
|
|
91
93
|
this._createModel = options.createModel;
|
|
92
|
-
this._openInMain = options.openInMain;
|
|
93
94
|
this._renameChat = options.renameChat;
|
|
94
95
|
this._placeholderFactory = options.placeholderFactory;
|
|
95
96
|
|
|
@@ -101,6 +102,7 @@ export class MultiChatPanel extends PanelWithToolbar {
|
|
|
101
102
|
this.open(addChatArgs);
|
|
102
103
|
},
|
|
103
104
|
icon: addIcon,
|
|
105
|
+
label: this._trans.__('New chat'),
|
|
104
106
|
tooltip: this._trans.__('Create a new chat')
|
|
105
107
|
});
|
|
106
108
|
addChat.addClass(ADD_BUTTON_CLASS);
|
|
@@ -149,9 +151,9 @@ export class MultiChatPanel extends PanelWithToolbar {
|
|
|
149
151
|
}
|
|
150
152
|
|
|
151
153
|
/**
|
|
152
|
-
* A signal emitting when a chat
|
|
154
|
+
* A signal emitting when a chat panel is opened in the sidepanel.
|
|
153
155
|
*/
|
|
154
|
-
get chatOpened(): ISignal<MultiChatPanel,
|
|
156
|
+
get chatOpened(): ISignal<MultiChatPanel, IChatPanel> {
|
|
155
157
|
return this._chatOpened;
|
|
156
158
|
}
|
|
157
159
|
|
|
@@ -293,8 +295,8 @@ export class MultiChatPanel extends PanelWithToolbar {
|
|
|
293
295
|
const widget = new SidePanelWidget({
|
|
294
296
|
widget: chatWidget,
|
|
295
297
|
displayName: name,
|
|
296
|
-
openInMain: this._openInMain,
|
|
297
298
|
renameChat: this._renameChat,
|
|
299
|
+
toolbarFactory: this._chatToolbarFactory,
|
|
298
300
|
onClose: (name: string, disposeModel = true) => {
|
|
299
301
|
this.unsetLoadedModel(name, disposeModel);
|
|
300
302
|
},
|
|
@@ -313,7 +315,7 @@ export class MultiChatPanel extends PanelWithToolbar {
|
|
|
313
315
|
this._chatSelectorPopup.setCurrentChat(name);
|
|
314
316
|
}
|
|
315
317
|
|
|
316
|
-
this._chatOpened.emit(
|
|
318
|
+
this._chatOpened.emit(widget);
|
|
317
319
|
return chatWidget;
|
|
318
320
|
}
|
|
319
321
|
|
|
@@ -437,20 +439,22 @@ export class MultiChatPanel extends PanelWithToolbar {
|
|
|
437
439
|
this._chatSelectorPopup?.hide();
|
|
438
440
|
};
|
|
439
441
|
|
|
440
|
-
private _chatOpened = new Signal<MultiChatPanel,
|
|
442
|
+
private _chatOpened = new Signal<MultiChatPanel, IChatPanel>(this);
|
|
441
443
|
private _chatNamesChanged = new Signal<
|
|
442
444
|
MultiChatPanel,
|
|
443
445
|
{ [name: string]: string }
|
|
444
446
|
>(this);
|
|
445
447
|
private _chatOptions: Omit<Chat.IOptions, 'model' | 'inputToolbarRegistry'>;
|
|
446
448
|
private _inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
449
|
+
private _chatToolbarFactory?: (
|
|
450
|
+
panel: IChatPanel
|
|
451
|
+
) => IObservableList<ToolbarRegistry.IToolbarItem>;
|
|
447
452
|
private _updateChatListDebouncer: Debouncer;
|
|
448
453
|
|
|
449
454
|
private _createModel?: (
|
|
450
455
|
name?: string
|
|
451
456
|
) => Promise<MultiChatPanel.IOpenChatArgs>;
|
|
452
457
|
private _getChatNames?: () => Promise<{ [name: string]: string }>;
|
|
453
|
-
private _openInMain?: (name: string) => Promise<boolean>;
|
|
454
458
|
private _renameChat?: boolean | ((oldName: string) => Promise<string | null>);
|
|
455
459
|
private _placeholderFactory?: IChatPlaceholderFactory;
|
|
456
460
|
private _openChatWidget?: ReactWidget;
|
|
@@ -476,6 +480,12 @@ export namespace MultiChatPanel {
|
|
|
476
480
|
* The input toolbar factory;
|
|
477
481
|
*/
|
|
478
482
|
inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
483
|
+
/**
|
|
484
|
+
* An optional toolbar factory for each opened chat.
|
|
485
|
+
*/
|
|
486
|
+
chatToolbarFactory?: (
|
|
487
|
+
panel: IChatPanel
|
|
488
|
+
) => IObservableList<ToolbarRegistry.IToolbarItem>;
|
|
479
489
|
/**
|
|
480
490
|
* An optional callback to create a chat model.
|
|
481
491
|
*
|
|
@@ -489,12 +499,6 @@ export namespace MultiChatPanel {
|
|
|
489
499
|
* @returns an object mapping chat display names to identifiers.
|
|
490
500
|
*/
|
|
491
501
|
getChatNames?: () => Promise<{ [name: string]: string }>;
|
|
492
|
-
/**
|
|
493
|
-
* An optional callback to open the chat in the main area.
|
|
494
|
-
*
|
|
495
|
-
* @param name - the name of the chat to move.
|
|
496
|
-
*/
|
|
497
|
-
openInMain?: (name: string) => Promise<boolean>;
|
|
498
502
|
/**
|
|
499
503
|
* An optional callback to rename a chat.
|
|
500
504
|
*
|
|
@@ -531,7 +535,7 @@ export namespace MultiChatPanel {
|
|
|
531
535
|
/**
|
|
532
536
|
* A widget containing the chat and its toolbar.
|
|
533
537
|
*/
|
|
534
|
-
class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
538
|
+
class SidePanelWidget extends ReactivePanelWithToolbar implements IChatPanel {
|
|
535
539
|
constructor(options: SidePanelWidget.IOptions) {
|
|
536
540
|
super();
|
|
537
541
|
this._chatWidget = options.widget;
|
|
@@ -557,19 +561,6 @@ class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
|
557
561
|
// Add the chat widget
|
|
558
562
|
this.addWidget(this._chatWidget);
|
|
559
563
|
|
|
560
|
-
// Add toolbar buttons
|
|
561
|
-
this._markAsRead = new ToolbarButton({
|
|
562
|
-
icon: readIcon,
|
|
563
|
-
iconLabel: trans.__('Mark chat as read'),
|
|
564
|
-
className: 'jp-mod-styled',
|
|
565
|
-
onClick: () => {
|
|
566
|
-
if (this.model) {
|
|
567
|
-
this.model.unreadMessages = [];
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
this.toolbar.addItem('markRead', this._markAsRead);
|
|
572
|
-
|
|
573
564
|
if (options.renameChat) {
|
|
574
565
|
const renameButton = new ToolbarButton({
|
|
575
566
|
iconClass: 'jp-EditIcon',
|
|
@@ -606,21 +597,6 @@ class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
|
606
597
|
this.toolbar.addItem('rename', renameButton);
|
|
607
598
|
}
|
|
608
599
|
|
|
609
|
-
if (options.openInMain) {
|
|
610
|
-
const moveToMain = new ToolbarButton({
|
|
611
|
-
icon: launchIcon,
|
|
612
|
-
iconLabel: trans.__('Move the chat to the main area'),
|
|
613
|
-
className: 'jp-mod-styled',
|
|
614
|
-
onClick: async () => {
|
|
615
|
-
const name = this.model.name;
|
|
616
|
-
if (await options.openInMain?.(name)) {
|
|
617
|
-
options.onClose(this._displayName, false);
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
this.toolbar.addItem('moveMain', moveToMain);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
600
|
const closeButton = new ToolbarButton({
|
|
625
601
|
icon: closeIcon,
|
|
626
602
|
iconLabel: trans.__('Close the chat'),
|
|
@@ -631,9 +607,24 @@ class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
|
631
607
|
});
|
|
632
608
|
this.toolbar.addItem('close', closeButton);
|
|
633
609
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
610
|
+
if (options.toolbarFactory) {
|
|
611
|
+
const items = options.toolbarFactory(this);
|
|
612
|
+
for (let i = 0; i < items.length; i++) {
|
|
613
|
+
const { name, widget } = items.get(i);
|
|
614
|
+
this.toolbar.insertBefore('close', name, widget);
|
|
615
|
+
}
|
|
616
|
+
items.changed.connect((_, change) => {
|
|
617
|
+
if (change.type === 'add') {
|
|
618
|
+
for (const { name, widget } of change.newValues) {
|
|
619
|
+
this.toolbar.insertBefore('close', name, widget);
|
|
620
|
+
}
|
|
621
|
+
} else if (change.type === 'remove') {
|
|
622
|
+
for (const { widget } of change.oldValues) {
|
|
623
|
+
widget.dispose();
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
}
|
|
637
628
|
}
|
|
638
629
|
|
|
639
630
|
protected onAfterAttach(msg: Message): void {
|
|
@@ -646,6 +637,13 @@ class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
|
646
637
|
this._updateReactiveToolbar();
|
|
647
638
|
}
|
|
648
639
|
|
|
640
|
+
/**
|
|
641
|
+
* The area of the widget.
|
|
642
|
+
*/
|
|
643
|
+
get area(): ChatArea {
|
|
644
|
+
return 'sidebar';
|
|
645
|
+
}
|
|
646
|
+
|
|
649
647
|
/**
|
|
650
648
|
* The chat widget embedded in the sidepanel widget.
|
|
651
649
|
*/
|
|
@@ -687,10 +685,6 @@ class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
|
687
685
|
* Dispose of the resources held by the widget.
|
|
688
686
|
*/
|
|
689
687
|
dispose(): void {
|
|
690
|
-
const model = this.model;
|
|
691
|
-
if (model) {
|
|
692
|
-
model.unreadChanged?.disconnect(this._unreadChanged);
|
|
693
|
-
}
|
|
694
688
|
super.dispose();
|
|
695
689
|
}
|
|
696
690
|
|
|
@@ -716,13 +710,6 @@ class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
|
716
710
|
this.toolbar.insertItem(0, 'title', this._titleWidget);
|
|
717
711
|
}
|
|
718
712
|
|
|
719
|
-
/**
|
|
720
|
-
* Enable/disable unread icon.
|
|
721
|
-
*/
|
|
722
|
-
private _unreadChanged = (_: IChatModel, unread: number[]) => {
|
|
723
|
-
this._markAsRead.enabled = unread.length > 0;
|
|
724
|
-
};
|
|
725
|
-
|
|
726
713
|
/**
|
|
727
714
|
* Trigger reactive toolbar overflow computation from rendered toolbar size.
|
|
728
715
|
*/
|
|
@@ -739,7 +726,6 @@ class SidePanelWidget extends ReactivePanelWithToolbar {
|
|
|
739
726
|
}
|
|
740
727
|
|
|
741
728
|
private _chatWidget: ChatWidget;
|
|
742
|
-
private _markAsRead: ToolbarButton;
|
|
743
729
|
private _displayName: string;
|
|
744
730
|
private _titleWidget: Widget | undefined;
|
|
745
731
|
private _nameChanged = new Signal<
|
|
@@ -768,14 +754,16 @@ namespace SidePanelWidget {
|
|
|
768
754
|
* The displayed name of the chat.
|
|
769
755
|
*/
|
|
770
756
|
displayName?: string;
|
|
771
|
-
/**
|
|
772
|
-
* The callback to open the chat in main area.
|
|
773
|
-
*/
|
|
774
|
-
openInMain?: (name: string) => Promise<boolean>;
|
|
775
757
|
/**
|
|
776
758
|
* The callback to rename the chat.
|
|
777
759
|
*/
|
|
778
760
|
renameChat?: boolean | ((oldName: string) => Promise<string | null>);
|
|
761
|
+
/**
|
|
762
|
+
* An optional toolbar factory.
|
|
763
|
+
*/
|
|
764
|
+
toolbarFactory?: (
|
|
765
|
+
panel: IChatPanel
|
|
766
|
+
) => IObservableList<ToolbarRegistry.IToolbarItem>;
|
|
779
767
|
/**
|
|
780
768
|
* The translation bundle.
|
|
781
769
|
*/
|
|
@@ -795,7 +783,7 @@ type ChatSearchInputProps = {
|
|
|
795
783
|
/**
|
|
796
784
|
* Signal emitting when a chat is opened.
|
|
797
785
|
*/
|
|
798
|
-
chatOpened: ISignal<MultiChatPanel,
|
|
786
|
+
chatOpened: ISignal<MultiChatPanel, IChatPanel>;
|
|
799
787
|
/**
|
|
800
788
|
* The translation bundle.
|
|
801
789
|
*/
|