Skip to content

Commit 872d007

Browse files
Add jupytereverywhere:save-and-share command to display shareable links when saving a notebook through key bindings (#102)
* Add `jupytereverywhere:save-and-share` command * Add a test to check if share dialog appears
1 parent 71d770e commit 872d007

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/index.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,36 @@ const plugin: JupyterFrontEndPlugin<void> = {
227227
}
228228
}
229229
});
230+
/**
231+
* Add a custom Save and Share notebook command. This command
232+
* is activated only on key bindings (Accel S) and is used to
233+
* display the shareable link dialog after the notebook is
234+
* saved manually by the user.
235+
*/
236+
commands.addCommand('jupytereverywhere:save-and-share', {
237+
label: 'Save and Share Notebook',
238+
execute: async () => {
239+
const panel = readonlyTracker.currentWidget ?? tracker.currentWidget;
240+
if (!panel) {
241+
console.warn('No active notebook to save');
242+
return;
243+
}
244+
if (panel.context.model.readOnly) {
245+
console.info('Notebook is read-only, skipping save-and-share.');
246+
return;
247+
}
248+
manuallySharing.add(panel);
249+
await panel.context.save();
250+
await handleNotebookSharing(panel, sharingService, true);
251+
}
252+
});
253+
254+
app.commands.addKeyBinding({
255+
command: 'jupytereverywhere:save-and-share',
256+
keys: ['Accel S'],
257+
selector: '.jp-Notebook'
258+
});
259+
230260
/**
231261
* Add custom Create Copy notebook command
232262
* Note: this command is supported and displayed only for View Only notebooks.

ui-tests/tests/jupytereverywhere.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ declare global {
1212
async function runCommand(page: Page, command: string, args: JSONObject = {}) {
1313
await page.evaluate(
1414
async ({ command, args }) => {
15-
await window.jupyterapp.commands.execute(command, args);
15+
window.jupyterapp.commands.execute(command, args);
1616
},
1717
{ command, args }
1818
);
@@ -174,6 +174,15 @@ test.describe('Sharing', () => {
174174
await shareButton.click();
175175
await expect(dialog).toHaveCount(1);
176176
});
177+
178+
test('Should show share dialog on Accel+S in interactive notebook', async ({ page }) => {
179+
await mockTokenRoute(page);
180+
await mockShareNotebookResponse(page, 'e3b0c442-98fc-1fc2-9c9f-8b6d6ed08a1d');
181+
await runCommand(page, 'jupytereverywhere:save-and-share');
182+
const dialog = page.locator('.jp-Dialog-content');
183+
await expect(dialog).toBeVisible();
184+
expect(await dialog.screenshot()).toMatchSnapshot('share-dialog.png');
185+
});
177186
});
178187

179188
test.describe('Download', () => {

0 commit comments

Comments
 (0)