Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion packages/jupyter-chat/src/widgets/multichat-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
* Originally adapted from jupyterlab-chat's ChatPanel
*/

import { InputDialog } from '@jupyterlab/apputils';
import { Dialog, InputDialog, showDialog } from '@jupyterlab/apputils';
import {
addIcon,
closeIcon,
deleteIcon,
HTMLSelect,
launchIcon,
PanelWithToolbar,
Expand Down Expand Up @@ -59,6 +60,7 @@ export class MultiChatPanel extends SidePanel {
this._createModel = options.createModel;
this._openInMain = options.openInMain;
this._renameChat = options.renameChat;
this._deleteChat = options.deleteChat;

if (this._createModel) {
// Add chat button calls the createChat callback
Expand Down Expand Up @@ -147,6 +149,7 @@ export class MultiChatPanel extends SidePanel {
widget,
openInMain: this._openInMain,
renameChat: this._renameChat,
deleteChat: this._deleteChat,
displayName
});

Expand Down Expand Up @@ -261,6 +264,7 @@ export class MultiChatPanel extends SidePanel {
private _getChatNames?: () => Promise<{ [name: string]: string }>;
private _openInMain?: (name: string) => Promise<boolean>;
private _renameChat?: (oldName: string, newName: string) => Promise<boolean>;
private _deleteChat?: (name: string) => Promise<boolean>;

private _openChatWidget?: ReactWidget;
}
Expand Down Expand Up @@ -306,6 +310,13 @@ export namespace MultiChatPanel {
* @returns - a boolean, whether the chat has been renamed or not.
*/
renameChat?: (oldName: string, newName: string) => Promise<boolean>;
/**
* An optional callback to delete a chat.
*
* @param name - the name of the chat to delete.
* @returns - a boolean, whether the chat has been deleted or not.
*/
deleteChat?: (name: string) => Promise<boolean>;
}
/**
* The options for the add chat method.
Expand Down Expand Up @@ -381,6 +392,34 @@ export class ChatSection extends PanelWithToolbar {
this.toolbar.addItem('rename', renameButton);
}

if (options.deleteChat) {
const deleteButton = new ToolbarButton({
icon: deleteIcon,
iconLabel: 'Delete chat',
className: 'jp-mod-styled',
onClick: async () => {
const name = this.model.name;
const result = await showDialog({
title: 'Delete Chat',
body: `Are you sure you want to delete "${name}"?`,
buttons: [Dialog.cancelButton(), Dialog.warnButton({ label: 'Delete' })]
});
if (!result.button.accept) {
return;
}
try {
if (await options.deleteChat?.(name)) {
this.model.dispose();
this.dispose();
}
} catch (e) {
console.error('Error deleting chat', e);
}
}
});
this.toolbar.addItem('delete', deleteButton);
}

if (options.openInMain) {
const moveToMain = new ToolbarButton({
icon: launchIcon,
Expand Down Expand Up @@ -511,6 +550,13 @@ export namespace ChatSection {
* @returns - a boolean, whether the chat has been renamed or not.
*/
renameChat?: (oldName: string, newName: string) => Promise<boolean>;
/**
* An optional callback to delete a chat.
*
* @param name - the name of the chat to delete.
* @returns - a boolean, whether the chat has been deleted or not.
*/
deleteChat?: (name: string) => Promise<boolean>;
/**
* The name to display in the section title.
*/
Expand Down
12 changes: 12 additions & 0 deletions packages/jupyterlab-chat-extension/schema/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
}
]
}
],
"context": [
{
"id": "jp-browser-panel",
"items": [
{
"command": "jupyterlab-chat:deleteChat",
"selector": "[data-file-type='chat']",
"rank": 11
}
]
}
]
},
"jupyter.lab.shortcuts": [
Expand Down
23 changes: 23 additions & 0 deletions packages/jupyterlab-chat-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,26 @@ const chatCommands: JupyterFrontEndPlugin<void> = {
}
});

// Command to delete a chat
commands.addCommand(CommandIDs.deleteChat, {
label: 'Delete chat',
execute: async (args: any): Promise<boolean> => {
const path = args.path as string;
if (!path) {
showErrorMessage('Error deleting chat', 'Missing path');
return false;
}

try {
await app.serviceManager.contents.delete(path);
return true;
} catch (err) {
showErrorMessage('Error deleting chat', `${err}`);
}
return false;
}
});

// The command to focus the input of the current chat widget.
commands.addCommand(CommandIDs.focusInput, {
caption: 'Focus the input of the current chat widget',
Expand Down Expand Up @@ -902,6 +922,9 @@ const chatPanel: JupyterFrontEndPlugin<MultiChatPanel> = {
newPath
}) as Promise<boolean>;
},
deleteChat: (path: string) => {
return commands.execute(CommandIDs.deleteChat, { path }) as Promise<boolean>;
},
chatCommandRegistry,
attachmentOpenerRegistry,
inputToolbarFactory,
Expand Down
6 changes: 5 additions & 1 deletion packages/jupyterlab-chat/src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ export const CommandIDs = {
/**
* Rename the current chat.
*/
renameChat: 'jupyterlab-chat:renameChat'
renameChat: 'jupyterlab-chat:renameChat',
/**
* Delete the current chat.
*/
deleteChat: 'jupyterlab-chat:deleteChat'
};

/**
Expand Down