Skip to content

Commit

Permalink
navigator: handle empty multi-root workspace
Browse files Browse the repository at this point in the history
When a multi-root workspace is opened, the navigator will try to draw
the file tree because `model.root` is a `WorkspaceNode` with no
children.

This commit handles this case by adding a bit of ui to help the user add
folders to his workspace, instead of displaying a blank view.

Signed-off-by: Paul Maréchal <[email protected]>
  • Loading branch information
paul-marechal authored and EstherPerelman committed Oct 29, 2020
1 parent 5e280a5 commit 7754927
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
11 changes: 11 additions & 0 deletions packages/navigator/src/browser/navigator-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,24 @@ export class FileNavigatorTree extends FileTree {
}
}

/**
* File tree root node for multi-root workspaces.
*/
export interface WorkspaceNode extends CompositeTreeNode, SelectableTreeNode {
children: WorkspaceRootNode[];
}
export namespace WorkspaceNode {

export const id = 'WorkspaceNodeId';
export const name = 'WorkspaceNode';

export function is(node: TreeNode | undefined): node is WorkspaceNode {
return CompositeTreeNode.is(node) && node.id === WorkspaceNode.id;
}

/**
* Create a `WorkspaceNode` that can be used as a `Tree` root.
*/
export function createRoot(multiRootName?: string): WorkspaceNode {
return {
id: WorkspaceNode.id,
Expand All @@ -82,10 +89,14 @@ export namespace WorkspaceNode {
}
}

/**
* A node representing a folder from a multi-root workspace.
*/
export interface WorkspaceRootNode extends DirNode {
parent: WorkspaceNode;
}
export namespace WorkspaceRootNode {

export function is(node: Object | undefined): node is WorkspaceRootNode {
return DirNode.is(node) && WorkspaceNode.is(node.parent);
}
Expand Down
37 changes: 35 additions & 2 deletions packages/navigator/src/browser/navigator-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { injectable, inject, postConstruct } from 'inversify';
import { Message } from '@phosphor/messaging';
import URI from '@theia/core/lib/common/uri';
import { CommandService, SelectionService } from '@theia/core/lib/common';
import { CorePreferences, ViewContainerTitleOptions, Key } from '@theia/core/lib/browser';
import { CorePreferences, ViewContainerTitleOptions, Key, TreeModel } from '@theia/core/lib/browser';
import {
ContextMenuRenderer, ExpandableTreeNode,
TreeProps, TreeNode
Expand Down Expand Up @@ -132,8 +132,15 @@ export class FileNavigatorWidget extends FileTreeWidget {
return undefined;
}

protected renderTree(model: TreeModel): React.ReactNode {
if (this.model.root && this.isEmptyMultiRootWorkspace(model)) {
return this.renderEmptyMultiRootWorkspace();
}
return super.renderTree(model);
}

protected shouldShowWelcomeView(): boolean {
return !this.model.root;
return this.model.root === undefined;
}

protected onAfterAttach(msg: Message): void {
Expand Down Expand Up @@ -181,12 +188,38 @@ export class FileNavigatorWidget extends FileTreeWidget {
this.commandService.executeCommand(WorkspaceCommands.OPEN_FOLDER.id);
}

protected readonly addFolder = () => this.doAddFolder();
protected doAddFolder(): void {
this.commandService.executeCommand(WorkspaceCommands.ADD_FOLDER.id);
}

protected readonly keyUpHandler = (e: React.KeyboardEvent) => {
if (Key.ENTER.keyCode === e.keyCode) {
(e.target as HTMLElement).click();
}
};

/**
* When a multi-root workspace is opened, a user can remove all the folders from it.
* Instead of displaying an empty navigator tree, this will show a button to add more folders.
*/
protected renderEmptyMultiRootWorkspace(): React.ReactNode {
return <div className='theia-navigator-container'>
<div className='center'>You have not yet added a folder to the workspace.</div>
<div className='open-workspace-button-container'>
<button className='theia-button open-workspace-button' title='Add a folder to your workspace'
onClick={this.addFolder}
onKeyUp={this.keyUpHandler}>
Add Folder
</button>
</div>
</div>;
}

protected isEmptyMultiRootWorkspace(model: TreeModel): boolean {
return WorkspaceNode.is(model.root) && model.root.children.length === 0;
}

protected handleClickEvent(node: TreeNode | undefined, event: React.MouseEvent<HTMLElement>): void {
const modifierKeyCombined: boolean = isOSX ? (event.shiftKey || event.metaKey) : (event.shiftKey || event.ctrlKey);
if (!modifierKeyCombined && node && this.corePreferences['workbench.list.openMode'] === 'singleClick') {
Expand Down

0 comments on commit 7754927

Please sign in to comment.