Files
azuredatastudio/extensions/notebook/src/book/bookTreeItem.ts
Karl Burtram 05a53af085 Ports to release/1.13 for 10/21 (#7879)
* Add (dummy) IPyWidgets Renderer (#7849)

* Updates to package.json to show books on stable (#7836)

* Updates to package.json to show books on stable

* remove notebookQuality context key

* renamed untitiled to unsaved

* fix the wizard opened twice issue #7866 (#7869)

* fix a typo (#7871)
2019-10-21 23:07:32 -07:00

175 lines
5.3 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import * as nls from 'vscode-nls';
import { IJupyterBookSection, IJupyterBookToc } from '../contracts/content';
const localize = nls.loadMessageBundle();
export enum BookTreeItemType {
Book = 'Book',
Notebook = 'Notebook',
Markdown = 'Markdown',
ExternalLink = 'ExternalLink'
}
export interface BookTreeItemFormat {
title: string;
root: string;
tableOfContents: IJupyterBookToc;
page: any;
type: BookTreeItemType;
treeItemCollapsibleState: number;
isUntitled: boolean;
}
export class BookTreeItem extends vscode.TreeItem {
private _sections: IJupyterBookSection[];
private _uri: string;
private _previousUri: string;
private _nextUri: string;
public command: vscode.Command;
constructor(public book: BookTreeItemFormat, icons: any) {
super(book.title, book.treeItemCollapsibleState);
if (book.type === BookTreeItemType.Book) {
this.collapsibleState = book.treeItemCollapsibleState;
this._sections = book.page;
if (book.isUntitled) {
this.contextValue = 'unsavedBook';
} else {
this.contextValue = 'savedBook';
}
} else {
this.setPageVariables();
this.setCommand();
}
this.iconPath = icons;
}
private setPageVariables() {
this.collapsibleState = (this.book.page.sections || this.book.page.subsections) && this.book.page.expand_sections ?
vscode.TreeItemCollapsibleState.Expanded :
this.book.page.sections || this.book.page.subsections ?
vscode.TreeItemCollapsibleState.Collapsed :
vscode.TreeItemCollapsibleState.None;
this._sections = this.book.page.sections || this.book.page.subsections;
this._uri = this.book.page.url;
let index = (this.book.tableOfContents.sections.indexOf(this.book.page));
this.setPreviousUri(index);
this.setNextUri(index);
}
private setCommand() {
if (this.book.type === BookTreeItemType.Notebook) {
let pathToNotebook = path.join(this.book.root, 'content', this._uri.concat('.ipynb'));
this.command = { command: this.book.isUntitled ? 'bookTreeView.openUntitledNotebook' : 'bookTreeView.openNotebook', title: localize('openNotebookCommand', "Open Notebook"), arguments: [pathToNotebook], };
} else if (this.book.type === BookTreeItemType.Markdown) {
let pathToMarkdown = path.join(this.book.root, 'content', this._uri.concat('.md'));
this.command = { command: 'bookTreeView.openMarkdown', title: localize('openMarkdownCommand', "Open Markdown"), arguments: [pathToMarkdown], };
} else if (this.book.type === BookTreeItemType.ExternalLink) {
this.command = { command: 'bookTreeView.openExternalLink', title: localize('openExternalLinkCommand', "Open External Link"), arguments: [this._uri], };
}
}
private setPreviousUri(index: number): void {
let i = --index;
while (i > -1) {
if (this.book.tableOfContents.sections[i].url) {
// TODO: Currently only navigating to notebooks. Need to add logic for markdown.
let pathToNotebook = path.join(this.book.root, 'content', this.book.tableOfContents.sections[i].url.concat('.ipynb'));
// tslint:disable-next-line:no-sync
if (fs.existsSync(pathToNotebook)) {
this._previousUri = pathToNotebook;
return;
}
}
i--;
}
}
private setNextUri(index: number): void {
let i = ++index;
while (i < this.book.tableOfContents.sections.length) {
if (this.book.tableOfContents.sections[i].url) {
// TODO: Currently only navigating to notebooks. Need to add logic for markdown.
let pathToNotebook = path.join(this.book.root, 'content', this.book.tableOfContents.sections[i].url.concat('.ipynb'));
// tslint:disable-next-line:no-sync
if (fs.existsSync(pathToNotebook)) {
this._nextUri = pathToNotebook;
return;
}
}
i++;
}
}
public get title(): string {
return this.book.title;
}
public get uri(): string {
return this._uri;
}
public get root(): string {
return this.book.root;
}
public get tableOfContents(): IJupyterBookToc {
return this.book.tableOfContents;
}
public get sections(): any[] {
return this._sections;
}
public get previousUri(): string {
return this._previousUri;
}
public get nextUri(): string {
return this._nextUri;
}
get tooltip(): string {
if (this.book.type === BookTreeItemType.ExternalLink) {
return `${this._uri}`;
}
else {
return undefined;
}
}
/**
* Helper method to find a child section with a specified URL
* @param url The url of the section we're searching for
*/
public findChildSection(url?: string): IJupyterBookSection | undefined {
if (!url) {
return undefined;
}
return this.findChildSectionRecur(this, url);
}
private findChildSectionRecur(section: IJupyterBookSection, url: string): IJupyterBookSection | undefined {
if (section.url && section.url === url) {
return section;
} else if (section.sections) {
for (const childSection of section.sections) {
const foundSection = this.findChildSectionRecur(childSection, url);
if (foundSection) {
return foundSection;
}
}
}
return undefined;
}
}