Skip to content

Commit

Permalink
Merge pull request #781 from jupyterlab/ui-modes
Browse files Browse the repository at this point in the history
UI modes
  • Loading branch information
mbektas authored Mar 1, 2024
2 parents 303cd97 + 65ef5c2 commit 6b27752
Show file tree
Hide file tree
Showing 5 changed files with 326 additions and 20 deletions.
6 changes: 5 additions & 1 deletion src/main/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,11 @@ export class JupyterApplication implements IApplication, IDisposable {
SettingType.overrideDefaultServerArgs
),
serverEnvVars: userSettings.getValue(SettingType.serverEnvVars),
ctrlWBehavior: userSettings.getValue(SettingType.ctrlWBehavior)
ctrlWBehavior: userSettings.getValue(SettingType.ctrlWBehavior),
uiMode: userSettings.getValue(SettingType.uiMode),
uiModeForSingleFileOpen: userSettings.getValue(
SettingType.uiModeForSingleFileOpen
)
},
this._registry
);
Expand Down
28 changes: 25 additions & 3 deletions src/main/config/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ export enum CtrlWBehavior {
DoNotClose = 'do-not-close'
}

export enum UIMode {
MultiDocument = 'multi-document',
SingleDocument = 'single-document',
Zen = 'zen',
ManagedByWebApp = 'managed-by-web-app' // let JupyterLab web app manage the layout
}

export type KeyValueMap = { [key: string]: string };

export enum SettingType {
Expand Down Expand Up @@ -62,7 +69,10 @@ export enum SettingType {
condaPath = 'condaPath',
systemPythonPath = 'systemPythonPath',
pythonEnvsPath = 'pythonEnvsPath',
condaChannels = 'condaChannels'
condaChannels = 'condaChannels',

uiMode = 'uiMode',
uiModeForSingleFileOpen = 'uiModeForSingleFileOpen'
}

export const serverLaunchArgsFixed = [
Expand Down Expand Up @@ -159,7 +169,12 @@ export class UserSettings {
condaPath: new Setting<string>(''),
systemPythonPath: new Setting<string>(''),
pythonEnvsPath: new Setting<string>(''),
condaChannels: new Setting<string[]>(['conda-forge'])
condaChannels: new Setting<string[]>(['conda-forge']),

uiMode: new Setting<UIMode>(UIMode.ManagedByWebApp, {
wsOverridable: true
}),
uiModeForSingleFileOpen: new Setting<UIMode>(UIMode.Zen)
};

if (readSettings) {
Expand Down Expand Up @@ -239,6 +254,10 @@ export class WorkspaceSettings extends UserSettings {
return this._wsSettings;
}

hasValue(setting: SettingType) {
return setting in this._wsSettings;
}

getValue(setting: SettingType) {
if (setting in this._wsSettings) {
return this._wsSettings[setting].value;
Expand Down Expand Up @@ -288,12 +307,15 @@ export class WorkspaceSettings extends UserSettings {
);
const wsSettings: { [key: string]: any } = {};

// uiMode needs special handling, it needs to be saved even if same as global default.
// this is due to automatically setting uiMode to Zen for default for opening single file
for (let key in SettingType) {
const setting = this._wsSettings[key];
if (
setting &&
this._settings[key].wsOverridable &&
this._isDifferentThanUserSetting(key as SettingType)
(key === SettingType.uiMode ||
this._isDifferentThanUserSetting(key as SettingType))
) {
wsSettings[key] = setting.value;
}
Expand Down
145 changes: 140 additions & 5 deletions src/main/labview/labview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { SessionWindow } from '../sessionwindow/sessionwindow';
import {
CtrlWBehavior,
SettingType,
UIMode,
userSettings,
WorkspaceSettings
} from '../config/settings';
Expand Down Expand Up @@ -164,7 +165,47 @@ export class LabView implements IDisposable {
return path.normalize(path.join(__dirname, '../../../'));
}

/**
* if opening a single file and no workspace setting exists
*/
shouldSetToSingleFileUIMode(): boolean {
this._reloadWSSettings();

// if UI mode not specified for project directory
if (!this._wsSettings.hasValue(SettingType.uiMode)) {
return this._willOpenSingleFile();
}

return false;
}

private _reloadWSSettings() {
this._wsSettings = new WorkspaceSettings(
this._sessionConfig.workingDirectory
);
}

private _willOpenSingleFile(): boolean {
const labDir = this._sessionConfig.resolvedWorkingDirectory;

const filesToOpen = this._sessionConfig.filesToOpen;
if (filesToOpen.length === 1) {
const filePath = path.resolve(labDir, this._sessionConfig.filesToOpen[0]);
if (fs.lstatSync(filePath)?.isFile()) {
return true;
}
}

return false;
}

async openFiles() {
if (this.shouldSetToSingleFileUIMode()) {
this._setUIMode(
userSettings.getValue(SettingType.uiModeForSingleFileOpen)
);
}

const filesToOpen = this._sessionConfig.filesToOpen;
filesToOpen.forEach(async (relPath: string) => {
if (relPath === '') {
Expand Down Expand Up @@ -222,6 +263,30 @@ export class LabView implements IDisposable {
}
}

get uiMode(): UIMode {
return this._uiMode;
}

async setUIMode(uiMode: UIMode) {
if (uiMode === UIMode.ManagedByWebApp) {
this._uiMode = uiMode;
// let web app control the layout
return;
}

await this._setUIMode(uiMode);
}

async _setUIMode(uiMode: UIMode) {
this._uiMode = uiMode;

await this._view.webContents.executeJavaScript(`
{
jlabDesktop_setUIMode('${this._uiMode}');
}
`);
}

get labUIReady(): Promise<boolean> {
return new Promise<boolean>(resolve => {
const checkIfReady = () => {
Expand Down Expand Up @@ -368,13 +433,17 @@ export class LabView implements IDisposable {

private _registerWebAppFrontEndHandlers() {
this._view.webContents.on('dom-ready', () => {
const setToSingleFileUIMode = this.shouldSetToSingleFileUIMode();

this._view.webContents.executeJavaScript(`
// disable splash animation
const style = document.createElement('style');
style.textContent = '#jupyterlab-splash { display: none !important; }';
document.head.append(style);
{
const style = document.createElement('style');
style.textContent = '#jupyterlab-splash * { display: none; }';
document.head.append(style);
}
async function getLab() {
async function jlabDesktop_getLab() {
return new Promise((resolve) => {
const checkLab = () => {
return window.jupyterapp || window.jupyterlab;
Expand All @@ -394,7 +463,72 @@ export class LabView implements IDisposable {
});
}
getLab().then((lab) => {
async function jlabDesktop_setUIMode(uiMode) {
const lab = await jlabDesktop_getLab();
const labShell = lab.shell;
const statusBar = labShell.widgets('bottom').find(widget => widget.id === 'jp-main-statusbar');
const currentState = {
leftTabBarVisible: labShell.isSideTabBarVisible('left'),
leftCollapsed: labShell.leftCollapsed,
rightTabBarVisible: labShell.isSideTabBarVisible('right'),
rightCollapsed: labShell.rightCollapsed,
isSimpleInterface: labShell.mode === 'single-document',
statusBarVisible: statusBar && statusBar.isVisible,
};
if (uiMode === '${UIMode.MultiDocument}' || uiMode === '${
UIMode.SingleDocument
}') {
labShell.mode = uiMode === '${
UIMode.MultiDocument
}' ? 'multiple-document' : 'single-document';
if (currentState.leftCollapsed) {
labShell.expandLeft();
}
if (!currentState.leftTabBarVisible) {
labShell.toggleSideTabBarVisibility('left');
}
if (!currentState.rightCollapsed) {
labShell.collapseRight();
}
if (!currentState.rightTabBarVisible) {
labShell.toggleSideTabBarVisibility('right');
}
if (statusBar) {
statusBar.setHidden(false);
}
} else if (uiMode === '${UIMode.Zen}') {
if (!currentState.leftCollapsed) {
labShell.collapseLeft();
}
if (currentState.leftTabBarVisible) {
labShell.toggleSideTabBarVisibility('left');
}
if (!currentState.rightCollapsed) {
labShell.collapseRight();
}
if (currentState.rightTabBarVisible) {
labShell.toggleSideTabBarVisibility('right');
}
if (!currentState.isSimpleInterface) {
labShell.mode = 'single-document';
}
if (currentState.statusBarVisible) {
if (statusBar) {
statusBar.setHidden(true);
}
}
}
}
jlabDesktop_getLab().then((lab) => {
${
setToSingleFileUIMode
? `jlabDesktop_setUIMode('${userSettings.getValue(
SettingType.uiModeForSingleFileOpen
)}');`
: ''
}
lab.restored.then(() => {
window.electronAPI.broadcastLabUIReady();
});
Expand All @@ -410,6 +544,7 @@ export class LabView implements IDisposable {
private _wsSettings: WorkspaceSettings;
private _labUIReady = false;
private _evm = new EventManager();
private _uiMode: UIMode = UIMode.ManagedByWebApp;
}

export namespace LabView {
Expand Down
Loading

0 comments on commit 6b27752

Please sign in to comment.