Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring jupyterlab-recents into the core #76

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
48fabfd
Bring jupyterlab-recents into the core
krassowski Nov 30, 2023
329cf25
Fix loading which was stalled by a dependency cycle
krassowski Dec 2, 2023
2f88a4a
Implement re-opening last closed tab
krassowski Dec 2, 2023
45e24c4
Add tests for `RecentsManager` public API
krassowski Dec 3, 2023
5e484c5
Add recently closed section to the sidebar
krassowski Dec 3, 2023
a668bb3
Implement the searchable modal dialog
krassowski Dec 3, 2023
4c2a104
Merge remote-tracking branch 'upstream/main' into feature/recents-man…
krassowski Jan 15, 2024
586d1b9
Add button to sidebar, make sidebar a separate plugin
krassowski Jan 15, 2024
32037ae
Add documentation and snapshot test for the modal
krassowski Jan 15, 2024
d9c03c4
Fix promise handling
krassowski Jan 15, 2024
6fec37b
Deduplicate the lock file
krassowski Jan 15, 2024
8160d9e
Change the shortcut for modal to Ctrl + Alt + A
krassowski Jan 15, 2024
c11c405
Clean yarn.lock
krassowski Jan 15, 2024
4be34d5
Update Playwright Snapshots
github-actions[bot] Jan 15, 2024
919fed2
Revert incorrect snapshot update
krassowski Jan 16, 2024
2dd32d8
Update Playwright Snapshots
github-actions[bot] Jan 16, 2024
94374cd
Revert spurious snapshot update
krassowski Jan 16, 2024
556f8fe
Resilience to a state when context is stuck
krassowski Jan 17, 2024
1e726b5
Fix missing labels/descriptions
krassowski Jan 17, 2024
79f350d
Change name of the setting for max recents
krassowski Feb 22, 2024
b671629
Merge branch 'main' into feature/recents-manager
krassowski Feb 22, 2024
fb99e8d
Merge branch 'main' into feature/recents-manager
krassowski Mar 5, 2024
668b26b
Apply suggestions from code review
krassowski Mar 11, 2024
63c3e30
Use debouncer to control saving of recents
krassowski Mar 11, 2024
98b7dfd
Integrity, lint (async catch) and reduce API surface
krassowski Mar 11, 2024
a5bd70f
Merge branch 'main' into feature/recents-manager
krassowski Mar 12, 2024
705063b
Merge branch 'main' into feature/recents-manager
krassowski Mar 15, 2024
237af08
Update snapshot for sidebar (as new category gets added)
krassowski Mar 15, 2024
98deb6f
Fix `ServerApp.token` deprecation warnings (#16011)
jtpio Mar 18, 2024
a1166c1
Fix manager isDisposed is not set (#15997)
fcollonval Mar 19, 2024
5598b3a
Adjust assertion to allow both Node 18 and 20+ (#16024)
krassowski Mar 20, 2024
f54a154
Bump ydoc in dev-mode (#16018)
trungleduc Mar 20, 2024
2710948
Remove no longer needed `IDisposable`
krassowski Mar 20, 2024
139ac42
Remove no longer used `IDisposable`
krassowski Mar 20, 2024
ee99e3c
Re-organise the kernel tree in sidebar (#15845)
krassowski Mar 20, 2024
738940c
Merge branch 'main' into feature/recents-manager
krassowski Mar 20, 2024
a9071d8
Merge branch 'feature/recents-manager' of github.com:krassowski/jupyt…
krassowski Mar 20, 2024
fad82b8
Fix filtering and buttons after merge, use list view in modal
krassowski Mar 21, 2024
0bcc5f5
Make the open tabs sidebar snapshot focused on open tabs
krassowski Mar 21, 2024
9061def
Update Playwright Snapshots
github-actions[bot] Mar 21, 2024
7e04c5f
Use `while` instead of `.all()` because `.all()` returns `:nth()`
krassowski Mar 21, 2024
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
2 changes: 1 addition & 1 deletion binder/jupyter_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"--debug",
"--port={port}",
"--ServerApp.ip=127.0.0.1",
'--ServerApp.token=""',
'--IdentityProvider.token=""',
# Disable dns rebinding protection here, since our 'Host' header
# is not going to be localhost when coming from hub.mybinder.org
"--ServerApp.allow_remote_access=True",
Expand Down
2 changes: 1 addition & 1 deletion dev_mode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@codemirror/view": "^6.9.6",
"@jupyter/react-components": "~0.13.3",
"@jupyter/web-components": "~0.13.3",
"@jupyter/ydoc": "~1.1.1",
"@jupyter/ydoc": "^2.0.1",
"@jupyterlab/application": "~4.2.0-alpha.1",
"@jupyterlab/application-extension": "~4.2.0-alpha.1",
"@jupyterlab/apputils": "~4.3.0-alpha.1",
Expand Down
9 changes: 9 additions & 0 deletions docs/source/user/running.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ re-open or focus the document linked to a given kernel or terminal:
<iframe src="https://www.youtube-nocookie.com/embed/gDM5lwU6Dmo?rel=0&amp;showinfo=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</div>

The recently closed and currently open documents can be searched in the
modal view, which can be opened using a keyboard shortcut,
or by clicking the [↗] icon in the running sidebar.

.. image:: ../images/running-modal.png
:align: center
:class: jp-screenshot
:alt: The modal running dialog

.. _shutdown-kernel:

Kernels or terminals can be shut down from the Running panel:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@
"id": "application:toggle-side-tabbar",
"label": "Show Left Activity Bar",
"caption": "",
"shortcuts": [
"Alt 1"
]
"shortcuts": []
},
{
"id": "application:toggle-sidebar-widget",
"label": "Toggle Sidebar Element",
"caption": "",
"shortcuts": []
"shortcuts": [
"Alt 1"
]
},
{
"id": "apputils:activate-command-palette",
Expand Down Expand Up @@ -367,6 +367,12 @@
"caption": "",
"shortcuts": []
},
{
"id": "console:redo",
"label": "Redo",
"caption": "",
"shortcuts": []
},
{
"id": "console:replace-selection",
"label": "Replace Selection in Console",
Expand Down Expand Up @@ -413,6 +419,12 @@
"caption": "",
"shortcuts": []
},
{
"id": "console:undo",
"label": "Undo",
"caption": "",
"shortcuts": []
},
{
"id": "csv:go-to-line",
"label": "Go to Line",
Expand Down Expand Up @@ -514,6 +526,12 @@
"Shift F9"
]
},
{
"id": "docmanager:clear-recents",
"label": "Clear Recent Documents",
"caption": "Clear the list of recently opened items.",
"shortcuts": []
},
{
"id": "docmanager:clone",
"label": "New View for ",
Expand Down Expand Up @@ -2077,6 +2095,20 @@
"Ctrl Shift U"
]
},
{
"id": "recentmenu:open-recent",
"label": "Open a Recent Document (given by `recent` argument)",
"caption": "",
"shortcuts": []
},
{
"id": "recentmenu:reopen-last",
"label": "Reopen Closed Document",
"caption": "Reopen recently closed file or notebook.",
"shortcuts": [
"Ctrl Shift T"
]
},
{
"id": "rendermime:handle-local-link",
"label": "Handle Local Link",
Expand Down Expand Up @@ -2133,6 +2165,14 @@
"caption": "",
"shortcuts": []
},
{
"id": "running:show-modal",
"label": "Search Tabs and Running Sessions",
"caption": "",
"shortcuts": [
"Ctrl Alt A"
]
},
{
"id": "running:show-panel",
"label": "Sessions and Tabs",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 30 additions & 6 deletions galata/test/documentation/general.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -569,15 +569,39 @@ test.describe('General', () => {

await page.click('[title="Running Terminals and Kernels"]');

await expect(
page.locator(
'.jp-RunningSessions-item.jp-mod-kernel >> text="Python 3 (ipykernel)"'
// Wait up to 5s for both kernels to startup
await expect
.soft(page.locator('.jp-RunningSessions-item.jp-mod-kernel'))
.toHaveCount(2, { timeout: 5000 });

const freeezeKernelIds = async () => {
return page.evaluate(() => {
const mockedKernelIds = ['abcd1234', 'wxyz5678'];
document
.querySelectorAll('.jp-RunningSessions-item-label-kernel-id')
.forEach((span, i) => {
span.innerText = `(${mockedKernelIds[i]})`;
});
});
};
await freeezeKernelIds();

expect
.soft(
await page.screenshot({
clip: { y: 27, x: 0, width: 283, height: 400 }
})
)
).toHaveCount(2);
.toMatchSnapshot('running_layout.png');

await page.click('jp-button[data-command="running:show-modal"]');
await freeezeKernelIds();

expect(
await page.screenshot({ clip: { y: 27, x: 0, width: 283, height: 400 } })
).toMatchSnapshot('running_layout.png');
await page
.locator('.jp-SearchableSessions-modal .jp-Dialog-content')
.screenshot()
).toMatchSnapshot('running_modal.png');
});

test('Command Palette', async ({ page }) => {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 9 additions & 6 deletions galata/test/documentation/overview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@ test.describe('Overview', () => {

await page.click('[title="Running Terminals and Kernels"]');

await page
.locator(
'.jp-RunningSessions-item.jp-mod-kernel >> text="Python 3 (ipykernel)"'
)
.waitFor();
// Close all other sections
const otherSession = page.locator(
'#jp-running-sessions .jp-AccordionPanel-title.lm-mod-expanded:not([aria-label="Open Tabs Section"])'
);
while ((await otherSession.count()) != 0) {
await otherSession.first().click();
}

expect(
await page.screenshot({ clip: { y: 27, x: 0, width: 283, height: 400 } })
await page.screenshot({ clip: { y: 27, x: 0, width: 283, height: 200 } })
).toMatchSnapshot('interface_tabs.png');
});

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"@jupyterlab/docmanager-extension:download": "Adds command to download files.",
"@jupyterlab/docmanager-extension:open-browser-tab": "Adds command to open a browser tab.",
"@jupyterlab/docmanager-extension:opener": "Provides the widget opener.",
"@jupyterlab/docmanager-extension:recents": "Provides a manager of recently opened and closed documents.",
"@jupyterlab/documentsearch-extension:plugin": "Provides the document search registry.",
"@jupyterlab/documentsearch-extension:labShellWidgetListener": "Active search on valid document",
"@jupyterlab/extensionmanager-extension:plugin": "Adds the extension manager plugin.",
Expand Down Expand Up @@ -122,6 +123,7 @@
"@jupyterlab/lsp:ILSPCodeExtractorsManager": "Provides the code extractor manager.",
"@jupyterlab/lsp-extension:tracker": "Provides the tracker of `WidgetLSPAdapter`.",
"@jupyterlab/mainmenu-extension:plugin": "Adds and provides the application main menu.",
"@jupyterlab/mainmenu-extension:recents": "Adds sub-menu for opening recent documents to the File section of the main menu.",
"@jupyterlab/markdownviewer-extension:plugin": "Adds markdown file viewer and provides its tracker.",
"@jupyterlab/markedparser-extension:plugin": "Provides the Markdown parser.",
"@jupyterlab/mathjax-extension:plugin": "Provides the LaTeX mathematical expression interpreter.",
Expand Down Expand Up @@ -153,6 +155,9 @@
"@jupyterlab/pluginmanager-extension:plugin": "Enable or disable individual plugins.",
"@jupyterlab/rendermime-extension:plugin": "Provides the render mime registry.",
"@jupyterlab/running-extension:plugin": "Provides the running session managers.",
"@jupyterlab/running-extension:sidebar": "Provides the running session sidebar.",
"@jupyterlab/running-extension:recently-closed": "Adds recently closed documents list.",
"@jupyterlab/running-extension:search-tabs": "Adds a widget to search open and closed tabs.",
"@jupyterlab/settingeditor-extension:form-ui": "Adds the interactive settings editor and provides its tracker.",
"@jupyterlab/settingeditor-extension:plugin": "Adds the JSON settings editor and provides its tracker.",
"@jupyterlab/shortcuts-extension:shortcuts": "Adds the keyboard shortcuts editor.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@jupyterlab/debugger:IDebuggerConfig": "A service to handle the debugger configuration.",
"@jupyterlab/docmanager:IDocumentManager": "A service for the manager for all\n documents used by the application. Use this if you want to open and close documents,\n create and delete files, and otherwise interact with the file system.",
"@jupyterlab/docmanager:IDocumentWidgetOpener": "A service to open a widget.",
"@jupyterlab/docmanager:IRecentsManager": "A service providing information about recently opened and closed documents",
"@jupyterlab/documentsearch:ISearchProviderRegistry": "A service for a registry of search\n providers for the application. Plugins can register their UI elements with this registry\n to provide find/replace support.",
"@jupyterlab/filebrowser:IFileBrowserFactory": "A factory object that creates file browsers.\n Use this if you want to create your own file browser (e.g., for a custom storage backend),\n or to interact with other file browsers that have been created by extensions.",
"@jupyterlab/filebrowser:IDefaultFileBrowser": "A service for the default file browser.",
Expand Down Expand Up @@ -65,6 +66,7 @@
"@jupyterlab/pluginmanager:IPluginManager": "A canary for plugin manager presence, with a method to open the plugin manager widget.",
"@jupyterlab/rendermime:IRenderMimeRegistry": "A service for the rendermime registry for the application. Use this to create renderers for various mime-types in your extension. Many times it will be easier to create a \"mime renderer extension\" rather than using this service directly.",
"@jupyterlab/running:IRunningSessionManagers": "A service to add running session managers.",
"@jupyterlab/running:IRunningSessionsSidebar": "A token allowing to modify the running sessions sidebar.",
"@jupyterlab/settingeditor:ISettingEditorTracker": "A widget tracker for the interactive setting editor.\n Use this if you want to be able to iterate over and interact with setting editors\n created by the application.",
"@jupyterlab/settingeditor:IJSONSettingEditorTracker": "A widget tracker for the JSON setting editor.\n Use this if you want to be able to iterate over and interact with setting editors\n created by the application.",
"@jupyterlab/statusbar:IStatusBar": "A service for the status bar on the application. Use this if you want to add new status bar items.",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion jupyterlab/galata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def configure_jupyter_server(c):
c.ServerApp.root_dir = os.environ.get(
"JUPYTERLAB_GALATA_ROOT_DIR", mkdtemp(prefix="galata-test-")
)
c.ServerApp.token = ""
c.IdentityProvider.token = ""
c.ServerApp.password = ""
c.ServerApp.disable_check_xsrf = True
c.LabApp.expose_app_in_browser = True
2 changes: 1 addition & 1 deletion jupyterlab/labapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ def initialize_handlers(self): # noqa
page_config.setdefault("buildAvailable", not self.core_mode and not self.dev_mode)
page_config.setdefault("buildCheck", not self.core_mode and not self.dev_mode)
page_config["devMode"] = self.dev_mode
page_config["token"] = self.serverapp.token
page_config["token"] = self.serverapp.identity_provider.token
page_config["exposeAppInBrowser"] = self.expose_app_in_browser
page_config["quitButton"] = self.serverapp.quit_button
page_config["allow_hidden_files"] = self.serverapp.contents_manager.allow_hidden
Expand Down
1 change: 1 addition & 0 deletions packages/docmanager-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@jupyterlab/docregistry": "^4.2.0-alpha.1",
"@jupyterlab/services": "^7.2.0-alpha.1",
"@jupyterlab/settingregistry": "^4.2.0-alpha.1",
"@jupyterlab/statedb": "^4.2.0-alpha.1",
"@jupyterlab/statusbar": "^4.2.0-alpha.1",
"@jupyterlab/translation": "^4.2.0-alpha.1",
"@jupyterlab/ui-components": "^4.2.0-alpha.1",
Expand Down
7 changes: 7 additions & 0 deletions packages/docmanager-extension/schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@
"title": "Rename Untitled File On First Save",
"description": "Whether to prompt to rename untitled file on first manual save.",
"default": true
},
"maxNumberRecents": {
"type": "number",
"title": "Recent Items Number",
"description": "Number of recently opened/closed files and directories to remember.",
"default": 10,
"minimum": 0
}
},
"additionalProperties": false,
Expand Down
19 changes: 15 additions & 4 deletions packages/docmanager-extension/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
DocumentManager,
IDocumentManager,
IDocumentWidgetOpener,
IRecentsManager,
PathStatus,
renameDialog,
SavingStatus
Expand All @@ -52,6 +53,7 @@ import { IDisposable } from '@lumino/disposable';
import { ISignal, Signal } from '@lumino/signaling';
import { Widget } from '@lumino/widgets';
import * as React from 'react';
import { recentsManagerPlugin } from './recents';

/**
* The command IDs used by the document manager plugin.
Expand Down Expand Up @@ -168,14 +170,21 @@ const manager: JupyterFrontEndPlugin<IDocumentManager> = {
description: 'Provides the document manager.',
provides: IDocumentManager,
requires: [IDocumentWidgetOpener],
optional: [ITranslator, ILabStatus, ISessionContextDialogs, JupyterLab.IInfo],
optional: [
ITranslator,
ILabStatus,
ISessionContextDialogs,
JupyterLab.IInfo,
IRecentsManager
],
activate: (
app: JupyterFrontEnd,
widgetOpener: IDocumentWidgetOpener,
translator_: ITranslator | null,
status: ILabStatus | null,
sessionDialogs_: ISessionContextDialogs | null,
info: JupyterLab.IInfo | null
info: JupyterLab.IInfo | null,
recentsManager: IRecentsManager | null
) => {
const { serviceManager: manager, docRegistry: registry } = app;
const translator = translator_ ?? nullTranslator;
Expand All @@ -196,7 +205,8 @@ const manager: JupyterFrontEndPlugin<IDocumentManager> = {
return info.isConnected;
}
return true;
}
},
recentsManager: recentsManager ?? undefined
});

return docManager;
Expand Down Expand Up @@ -556,7 +566,8 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
savingStatusPlugin,
downloadPlugin,
openBrowserTabPlugin,
openerPlugin
openerPlugin,
recentsManagerPlugin
];
export default plugins;

Expand Down
Loading
Loading