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

Workspaces #3490

Merged
merged 34 commits into from
Jan 4, 2018
Merged

Workspaces #3490

merged 34 commits into from
Jan 4, 2018

Conversation

afshin
Copy link
Member

@afshin afshin commented Dec 27, 2017

This PR adds the concept of named sessions that are saved on the server, these are called workspaces. This is a new feature and is not prominently exposed while we consider what the best user interface and experience should be.

To use this feature:

  • A user navigates to a workspace URL at /lab/workspaces/<workspace_name>
  • If <workspace_name> exists on the back-end, the workspace data will load the saved layout and open files in the JupyterLab interface. If it does not exist, it will be created.
  • The workspace will be automatically saved as the user changes the state of the application.

Depends on jupyterlab/jupyterlab_server#34

@afshin afshin self-assigned this Dec 27, 2017
@afshin afshin changed the title Sessions [wip] Workspaces [wip] Dec 30, 2017
@ellisonbg ellisonbg added this to the Beta milestone Jan 2, 2018
@afshin afshin changed the title Workspaces [wip] Workspaces Jan 4, 2018
Copy link
Contributor

@ellisonbg ellisonbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested this locally and the user experience is magical! I really like how it turned out and the 2s debounce time is very reasonable. It is really easy and intuitive to create workspaces, return to them, branch of existing ones, etc. Super excited about this!

dev_mode/static
dev_mode/themes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this :)


commands.addCommand(CommandIDs.tree, {
execute: (args: IRouter.ICommandArgs) => {
const path = (args.path as string).replace('/tree', '');
return app.restored.then(() => {
const path = decodeURIComponent((args.path.match(pattern)[1]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this now handle filenames and paths with spaces?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encode/decode URI component fixes spaces.

/**
* The command string that will be invoked upon matching.
*/
command: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it also make sense to provide command args for the router to use?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would. I just wanted to keep the surface area of the router exactly as small as we currently need and then expand as we expand. But if you think it should go in now, I'm happy to add it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fine to leave it as is for the beta

}
});

// Order the matching rules by rank and execute them.
matches.sort((a, b) => a.rank - b.rank).forEach(rule => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this trigger only the first matching rule, or all of them? Server side routing definitely only triggers one, so it would be a bit surprising if multiple can get triggered. If the promises are ignored, that also makes it difficult to ensure ordering between them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This triggers all of them. This is a decision all routers need to make. One idea we've been considering is having the resolution of the promise contain a value that can stop the further execution of commands. This requires some thought.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok make sense that we still have to figure that out. For the beta I would probably feel better if we only ran the first one.

.catch(reason => {
console.warn(`Saving workspace (${id}) failed.`, reason);
});
}, 2000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use a module const for this and add documentation so our future selves can understand the meaning of 2000.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

resolved = true;

// Populate the workspace placeholder.
workspace = decodeURIComponent((args.path.match(pattern)[1]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have verified that workspaces can have spaces!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup :)

@ellisonbg
Copy link
Contributor

@afshin after using it a bit more I think we should change the default state of the application to have the left panel expanded. I think that in most layout restorations, the left panel will be open so starting with it open will make the state restoration less "everything moving around"

@ellisonbg
Copy link
Contributor

The splash screen behavior is much improved! Awesome!

@ellisonbg
Copy link
Contributor

This can be merged once the tests pass. Fantastic!

@ellisonbg ellisonbg merged commit cf002f5 into jupyterlab:master Jan 4, 2018
@jasongrout
Copy link
Contributor

Presumably we also need to merge jupyterlab/jupyterlab_server#34 and release a new jupyterlab_launcher too, right?

@afshin afshin deleted the sessions branch February 9, 2018 23:22
@lock lock bot added the status:resolved-locked Closed issues are locked after 30 days inactivity. Please open a new issue for related discussion. label Aug 9, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Aug 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status:resolved-locked Closed issues are locked after 30 days inactivity. Please open a new issue for related discussion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants