mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Show book's notebook TOC title in pinned notebooks view (#15583)
* Show notebook title in pinned notebooks view * fix test * change interface name
This commit is contained in:
@@ -13,7 +13,7 @@ import * as fs from 'fs-extra';
|
|||||||
import * as loc from '../common/localizedConstants';
|
import * as loc from '../common/localizedConstants';
|
||||||
import { IJupyterBookToc, JupyterBookSection } from '../contracts/content';
|
import { IJupyterBookToc, JupyterBookSection } from '../contracts/content';
|
||||||
import { convertFrom, getContentPath, BookVersion } from './bookVersionHandler';
|
import { convertFrom, getContentPath, BookVersion } from './bookVersionHandler';
|
||||||
import { debounce } from '../common/utils';
|
import { debounce, IPinnedNotebook } from '../common/utils';
|
||||||
import { Deferred } from '../common/promise';
|
import { Deferred } from '../common/promise';
|
||||||
const fsPromises = fileServices.promises;
|
const fsPromises = fileServices.promises;
|
||||||
const content = 'content';
|
const content = 'content';
|
||||||
@@ -39,7 +39,7 @@ export class BookModel {
|
|||||||
public readonly isNotebook: boolean,
|
public readonly isNotebook: boolean,
|
||||||
private _extensionContext: vscode.ExtensionContext,
|
private _extensionContext: vscode.ExtensionContext,
|
||||||
private _onDidChangeTreeData: vscode.EventEmitter<BookTreeItem | undefined>,
|
private _onDidChangeTreeData: vscode.EventEmitter<BookTreeItem | undefined>,
|
||||||
public readonly notebookRootPath?: string) { }
|
public readonly pinnedNotebookDetails?: IPinnedNotebook) { }
|
||||||
|
|
||||||
public unwatchTOC(): void {
|
public unwatchTOC(): void {
|
||||||
fs.unwatchFile(this.tableOfContentsPath);
|
fs.unwatchFile(this.tableOfContentsPath);
|
||||||
@@ -141,9 +141,9 @@ export class BookModel {
|
|||||||
|
|
||||||
let pathDetails = path.parse(this.bookPath);
|
let pathDetails = path.parse(this.bookPath);
|
||||||
let notebookItem = new BookTreeItem({
|
let notebookItem = new BookTreeItem({
|
||||||
title: pathDetails.name,
|
title: this.pinnedNotebookDetails?.title ?? pathDetails.name,
|
||||||
contentPath: this.bookPath,
|
contentPath: this.bookPath,
|
||||||
root: this.notebookRootPath ? this.notebookRootPath : pathDetails.dir,
|
root: this.pinnedNotebookDetails?.bookPath ?? pathDetails.dir,
|
||||||
tableOfContents: { sections: undefined },
|
tableOfContents: { sections: undefined },
|
||||||
page: { sections: undefined },
|
page: { sections: undefined },
|
||||||
type: BookTreeItemType.Notebook,
|
type: BookTreeItemType.Notebook,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import * as path from 'path';
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as constants from './../common/constants';
|
import * as constants from './../common/constants';
|
||||||
import { BookTreeItem } from './bookTreeItem';
|
import { BookTreeItem } from './bookTreeItem';
|
||||||
import { getPinnedNotebooks, setPinnedBookPathsInConfig, IBookNotebook } from '../common/utils';
|
import { getPinnedNotebooks, setPinnedBookPathsInConfig, IPinnedNotebook } from '../common/utils';
|
||||||
|
|
||||||
export interface IBookPinManager {
|
export interface IBookPinManager {
|
||||||
pinNotebook(notebook: BookTreeItem): Promise<boolean>;
|
pinNotebook(notebook: BookTreeItem): Promise<boolean>;
|
||||||
@@ -51,14 +51,14 @@ export class BookPinManager implements IBookPinManager {
|
|||||||
let modifiedPinnedBooks = false;
|
let modifiedPinnedBooks = false;
|
||||||
let bookPathToChange: string = notebook.book.contentPath;
|
let bookPathToChange: string = notebook.book.contentPath;
|
||||||
|
|
||||||
let pinnedBooks: IBookNotebook[] = getPinnedNotebooks();
|
let pinnedBooks: IPinnedNotebook[] = getPinnedNotebooks();
|
||||||
let existingBookIndex = pinnedBooks.map(pinnedBookPath => path.normalize(pinnedBookPath?.notebookPath)).indexOf(path.normalize(bookPathToChange));
|
let existingBookIndex = pinnedBooks.map(pinnedBookPath => path.normalize(pinnedBookPath?.notebookPath)).indexOf(path.normalize(bookPathToChange));
|
||||||
|
|
||||||
if (existingBookIndex !== -1 && operation === PinBookOperation.Unpin) {
|
if (existingBookIndex !== -1 && operation === PinBookOperation.Unpin) {
|
||||||
pinnedBooks.splice(existingBookIndex, 1);
|
pinnedBooks.splice(existingBookIndex, 1);
|
||||||
modifiedPinnedBooks = true;
|
modifiedPinnedBooks = true;
|
||||||
} else if (existingBookIndex === -1 && operation === PinBookOperation.Pin) {
|
} else if (existingBookIndex === -1 && operation === PinBookOperation.Pin) {
|
||||||
let addNotebook: IBookNotebook = { notebookPath: bookPathToChange, bookPath: notebook.book.root };
|
let addNotebook: IPinnedNotebook = { notebookPath: bookPathToChange, bookPath: notebook.book.root, title: notebook.book.title };
|
||||||
pinnedBooks.push(addNotebook);
|
pinnedBooks.push(addNotebook);
|
||||||
modifiedPinnedBooks = true;
|
modifiedPinnedBooks = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { Deferred } from '../common/promise';
|
|||||||
import { IBookTrustManager, BookTrustManager } from './bookTrustManager';
|
import { IBookTrustManager, BookTrustManager } from './bookTrustManager';
|
||||||
import * as loc from '../common/localizedConstants';
|
import * as loc from '../common/localizedConstants';
|
||||||
import * as glob from 'fast-glob';
|
import * as glob from 'fast-glob';
|
||||||
import { getPinnedNotebooks, confirmMessageDialog, getNotebookType, FileExtension } from '../common/utils';
|
import { getPinnedNotebooks, confirmMessageDialog, getNotebookType, FileExtension, IPinnedNotebook } from '../common/utils';
|
||||||
import { IBookPinManager, BookPinManager } from './bookPinManager';
|
import { IBookPinManager, BookPinManager } from './bookPinManager';
|
||||||
import { BookTocManager, IBookTocManager, quickPickResults } from './bookTocManager';
|
import { BookTocManager, IBookTocManager, quickPickResults } from './bookTocManager';
|
||||||
import { CreateBookDialog } from '../dialog/createBookDialog';
|
import { CreateBookDialog } from '../dialog/createBookDialog';
|
||||||
@@ -78,7 +78,7 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
|||||||
if (this.viewId === constants.PINNED_BOOKS_VIEWID) {
|
if (this.viewId === constants.PINNED_BOOKS_VIEWID) {
|
||||||
await Promise.all(getPinnedNotebooks().map(async (notebook) => {
|
await Promise.all(getPinnedNotebooks().map(async (notebook) => {
|
||||||
try {
|
try {
|
||||||
await this.createAndAddBookModel(notebook.notebookPath, true, notebook.bookPath);
|
await this.createAndAddBookModel(notebook.notebookPath, true, notebook);
|
||||||
} catch {
|
} catch {
|
||||||
// no-op, not all workspace folders are going to be valid books
|
// no-op, not all workspace folders are going to be valid books
|
||||||
}
|
}
|
||||||
@@ -254,8 +254,8 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
|||||||
async addNotebookToPinnedView(bookItem: BookTreeItem): Promise<void> {
|
async addNotebookToPinnedView(bookItem: BookTreeItem): Promise<void> {
|
||||||
let notebookPath: string = bookItem.book.contentPath;
|
let notebookPath: string = bookItem.book.contentPath;
|
||||||
if (notebookPath) {
|
if (notebookPath) {
|
||||||
let rootPath: string = bookItem.book.root ? bookItem.book.root : '';
|
let notebookDetails: IPinnedNotebook = bookItem.book.root ? { bookPath: bookItem.book.root, notebookPath: notebookPath, title: bookItem.book.title } : { notebookPath: notebookPath };
|
||||||
await this.createAndAddBookModel(notebookPath, true, rootPath);
|
await this.createAndAddBookModel(notebookPath, true, notebookDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,9 +318,9 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
|
|||||||
* @param isNotebook A boolean value to know we are creating a model for a notebook or a book
|
* @param isNotebook A boolean value to know we are creating a model for a notebook or a book
|
||||||
* @param notebookBookRoot For pinned notebooks we need to know if the notebook is part of a book or it's a standalone notebook
|
* @param notebookBookRoot For pinned notebooks we need to know if the notebook is part of a book or it's a standalone notebook
|
||||||
*/
|
*/
|
||||||
private async createAndAddBookModel(bookPath: string, isNotebook: boolean, notebookBookRoot?: string): Promise<void> {
|
private async createAndAddBookModel(bookPath: string, isNotebook: boolean, notebookDetails?: IPinnedNotebook): Promise<void> {
|
||||||
if (!this.books.find(x => x.bookPath === bookPath)) {
|
if (!this.books.find(x => x.bookPath === bookPath)) {
|
||||||
const book: BookModel = new BookModel(bookPath, this._openAsUntitled, isNotebook, this._extensionContext, this._onDidChangeTreeData, notebookBookRoot);
|
const book: BookModel = new BookModel(bookPath, this._openAsUntitled, isNotebook, this._extensionContext, this._onDidChangeTreeData, notebookDetails);
|
||||||
await book.initializeContents();
|
await book.initializeContents();
|
||||||
this.books.push(book);
|
this.books.push(book);
|
||||||
if (!this.currentBook) {
|
if (!this.currentBook) {
|
||||||
|
|||||||
@@ -435,7 +435,7 @@ export async function getRandomToken(size: number = 24): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isBookItemPinned(notebookPath: string): boolean {
|
export function isBookItemPinned(notebookPath: string): boolean {
|
||||||
let pinnedNotebooks: IBookNotebook[] = getPinnedNotebooks();
|
let pinnedNotebooks: IPinnedNotebook[] = getPinnedNotebooks();
|
||||||
if (pinnedNotebooks?.find(x => x.notebookPath === notebookPath)) {
|
if (pinnedNotebooks?.find(x => x.notebookPath === notebookPath)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -451,16 +451,16 @@ export function getNotebookType(book: BookTreeItemFormat): BookTreeItemType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPinnedNotebooks(): IBookNotebook[] {
|
export function getPinnedNotebooks(): IPinnedNotebook[] {
|
||||||
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(notebookConfigKey);
|
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(notebookConfigKey);
|
||||||
let pinnedNotebooks: [] = config.get(pinnedBooksConfigKey);
|
let pinnedNotebooks: [] = config.get(pinnedBooksConfigKey);
|
||||||
let updateFormat: boolean = false;
|
let updateFormat: boolean = false;
|
||||||
const pinnedBookDirectories = pinnedNotebooks.map(elem => {
|
const pinnedBookDirectories = pinnedNotebooks.map(elem => {
|
||||||
if (typeof (elem) === 'string') {
|
if (typeof (elem) === 'string') {
|
||||||
updateFormat = true;
|
updateFormat = true;
|
||||||
return { notebookPath: elem, bookPath: '' };
|
return { notebookPath: elem, bookPath: '', title: '' };
|
||||||
} else {
|
} else {
|
||||||
return elem as IBookNotebook;
|
return elem as IPinnedNotebook;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (updateFormat) {
|
if (updateFormat) {
|
||||||
@@ -475,7 +475,7 @@ function hasWorkspaceFolders(): boolean {
|
|||||||
return workspaceFolders && workspaceFolders.length > 0;
|
return workspaceFolders && workspaceFolders.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setPinnedBookPathsInConfig(pinnedNotebookPaths: IBookNotebook[]): Promise<void> {
|
export async function setPinnedBookPathsInConfig(pinnedNotebookPaths: IPinnedNotebook[]): Promise<void> {
|
||||||
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(notebookConfigKey);
|
let config: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration(notebookConfigKey);
|
||||||
let storeInWorspace: boolean = hasWorkspaceFolders();
|
let storeInWorspace: boolean = hasWorkspaceFolders();
|
||||||
|
|
||||||
@@ -483,8 +483,9 @@ export async function setPinnedBookPathsInConfig(pinnedNotebookPaths: IBookNoteb
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface IBookNotebook {
|
export interface IPinnedNotebook {
|
||||||
bookPath?: string;
|
bookPath?: string;
|
||||||
|
title?: string;
|
||||||
notebookPath: string;
|
notebookPath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ describe('Utils Tests', function () {
|
|||||||
|
|
||||||
describe('getPinnedNotebooks', function (): void {
|
describe('getPinnedNotebooks', function (): void {
|
||||||
it('Should NOT have any pinned notebooks', async function (): Promise<void> {
|
it('Should NOT have any pinned notebooks', async function (): Promise<void> {
|
||||||
let pinnedNotebooks: utils.IBookNotebook[] = utils.getPinnedNotebooks();
|
let pinnedNotebooks: utils.IPinnedNotebook[] = utils.getPinnedNotebooks();
|
||||||
|
|
||||||
should(pinnedNotebooks.length).equal(0, 'Should not have any pinned notebooks');
|
should(pinnedNotebooks.length).equal(0, 'Should not have any pinned notebooks');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user