Skip to content

Commit 4441109

Browse files
authored
feat: Add copy/rename/delete options to notebook overflow menu (#1551)
* Adds options to make a copy of, rename, or delete the file currently being viewed in the notebook panel * Resolves #1359 #### Testing Instructions: * Open any file create a new file * Navigate to the overflow menu in the top right of the notebook panel * The "copy file" option should create a copy of the currently open file with all of its contents copied over * The created copy should not appear in the file explorer until a save operation is done on it * The "rename file" option should cause the file to appear in the file explorer with the same contents and specified name * If the file was saved under a different name before, the old file should be deleted * If the file was never saved before, this operation will be identical to a save * The "delete file" option should close the file that the notebook panel is currently displaying. * If the file has been saved before, the saved file should be deleted and no longer in the file explorer * If the file was never saved before, this operation will be identical to closing the file and discarding any changes --------- Co-authored-by: georgecwan <georgecwan@users.noreply.github.com>
1 parent f06fbb0 commit 4441109

1 file changed

Lines changed: 68 additions & 2 deletions

File tree

packages/dashboard-core-plugins/src/panels/NotebookPanel.tsx

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ import {
2828
vsPlay,
2929
dhRunSelection,
3030
vsCheck,
31+
vsCopy,
32+
dhICursor,
33+
vsTrash,
3134
} from '@deephaven/icons';
3235
import {
3336
getFileStorage,
@@ -112,6 +115,7 @@ interface NotebookPanelState {
112115
panelState: PanelState;
113116

114117
showCloseModal: boolean;
118+
showDeleteModal: boolean;
115119
showSaveAsModal: boolean;
116120

117121
scriptCode: string;
@@ -164,6 +168,9 @@ class NotebookPanel extends Component<NotebookPanelProps, NotebookPanelState> {
164168
this.handleCloseDiscard = this.handleCloseDiscard.bind(this);
165169
this.handleCloseSave = this.handleCloseSave.bind(this);
166170
this.handleCopy = this.handleCopy.bind(this);
171+
this.handleDelete = this.handleDelete.bind(this);
172+
this.handleDeleteConfirm = this.handleDeleteConfirm.bind(this);
173+
this.handleDeleteCancel = this.handleDeleteCancel.bind(this);
167174
this.handleEditorInitialized = this.handleEditorInitialized.bind(this);
168175
this.handleEditorWillDestroy = this.handleEditorWillDestroy.bind(this);
169176
this.handleEditorChange = this.handleEditorChange.bind(this);
@@ -268,6 +275,7 @@ class NotebookPanel extends Component<NotebookPanelProps, NotebookPanelState> {
268275
},
269276

270277
showCloseModal: false,
278+
showDeleteModal: false,
271279
showSaveAsModal: false,
272280

273281
scriptCode: '',
@@ -547,19 +555,40 @@ class NotebookPanel extends Component<NotebookPanelProps, NotebookPanelState> {
547555
shortcut: SHORTCUTS.NOTEBOOK.FIND,
548556
order: 10,
549557
},
558+
{
559+
title: 'Copy File',
560+
icon: vsCopy,
561+
action: this.handleCopy,
562+
group: ContextActions.groups.medium,
563+
order: 20,
564+
},
565+
{
566+
title: 'Rename File',
567+
icon: dhICursor,
568+
action: this.handleShowRename,
569+
group: ContextActions.groups.medium,
570+
order: 30,
571+
},
572+
{
573+
title: 'Delete File',
574+
icon: vsTrash,
575+
action: this.handleDelete,
576+
group: ContextActions.groups.medium,
577+
order: 40,
578+
},
550579
{
551580
title: 'Show Minimap',
552581
icon: isMinimapEnabled ? vsCheck : undefined,
553582
action: this.handleMinimapChange,
554-
group: ContextActions.groups.medium,
583+
group: ContextActions.groups.low,
555584
shortcut: SHORTCUTS.NOTEBOOK.MINIMAP,
556585
order: 20,
557586
},
558587
{
559588
title: 'Word Wrap',
560589
icon: isWordWrapEnabled ? vsCheck : undefined,
561590
action: this.handleWordWrapChange,
562-
group: ContextActions.groups.medium,
591+
group: ContextActions.groups.low,
563592
shortcut: SHORTCUTS.NOTEBOOK.WORDWRAP,
564593
order: 30,
565594
},
@@ -650,6 +679,34 @@ class NotebookPanel extends Component<NotebookPanelProps, NotebookPanelState> {
650679
this.createNotebook(copyName, language, content);
651680
}
652681

682+
handleDelete(): void {
683+
log.debug('handleDelete, pending confirmation');
684+
this.setState({ showDeleteModal: true });
685+
}
686+
687+
handleDeleteConfirm(): void {
688+
const { fileStorage, glContainer, glEventHub } = this.props;
689+
const { fileMetadata } = this.state;
690+
691+
log.debug('handleDeleteConfirm', fileMetadata?.itemName);
692+
this.setState({ showDeleteModal: false });
693+
694+
if (!fileMetadata) {
695+
return;
696+
}
697+
698+
if (FileUtils.hasPath(fileMetadata.itemName)) {
699+
glEventHub.emit(NotebookEvent.CLOSE_FILE, fileMetadata, { force: true });
700+
fileStorage.deleteFile(fileMetadata.itemName);
701+
} else {
702+
glContainer.close({ force: true });
703+
}
704+
}
705+
706+
handleDeleteCancel(): void {
707+
this.setState({ showDeleteModal: false });
708+
}
709+
653710
handleEditorInitialized(innerEditor: editor.IStandaloneCodeEditor): void {
654711
this.editor = innerEditor;
655712
}
@@ -1118,6 +1175,7 @@ class NotebookPanel extends Component<NotebookPanelProps, NotebookPanelState> {
11181175
sessionLanguage,
11191176
settings: initialSettings,
11201177
showCloseModal,
1178+
showDeleteModal,
11211179
showSaveAsModal,
11221180
} = this.state;
11231181
// We don't want to steal focus if this isn't shown or it's just a preview
@@ -1308,6 +1366,14 @@ class NotebookPanel extends Component<NotebookPanelProps, NotebookPanelState> {
13081366
notifyOnExtensionChange
13091367
storage={fileStorage}
13101368
/>
1369+
<BasicModal
1370+
isOpen={showDeleteModal}
1371+
headerText={`Are you sure you want to delete "${itemName}"?`}
1372+
bodyText="You cannot undo this action."
1373+
onCancel={this.handleDeleteCancel}
1374+
onConfirm={this.handleDeleteConfirm}
1375+
confirmButtonText="Delete"
1376+
/>
13111377
<BasicModal
13121378
isOpen={showCloseModal}
13131379
headerText={`Do you want to save the changes you made to ${itemName}?`}

0 commit comments

Comments
 (0)