From d417b6ec7ff721b84a5892e284d579db7afb5965 Mon Sep 17 00:00:00 2001 From: Gordon Date: Mon, 19 Apr 2021 03:37:40 +0100 Subject: [PATCH] Singleton burndown panel --- ext-src/KanbnBoardPanel.ts | 7 ++- ext-src/KanbnBurndownPanel.ts | 106 +++++++++++++++------------------- ext-src/extension.ts | 6 +- src/App.tsx | 1 - 4 files changed, 55 insertions(+), 65 deletions(-) diff --git a/ext-src/KanbnBoardPanel.ts b/ext-src/KanbnBoardPanel.ts index 2692979..aba4619 100644 --- a/ext-src/KanbnBoardPanel.ts +++ b/ext-src/KanbnBoardPanel.ts @@ -113,11 +113,13 @@ export default class KanbnBoardPanel { this._panel.webview.onDidReceiveMessage( async (message) => { switch (message.command) { + // Display error message case "error": vscode.window.showErrorMessage(message.text); return; + // Open a task in the editor case "kanbn.task": KanbnTaskPanel.show( this._extensionPath, @@ -144,8 +146,8 @@ export default class KanbnBoardPanel { // Open a burndown chart case "kanbn.burndown": - KanbnBurndownPanel.show(this._extensionPath, this._workspacePath, this._kanbn); - KanbnBurndownPanel.updateAll(); + KanbnBurndownPanel.createOrShow(this._extensionPath, this._workspacePath, this._kanbn); + KanbnBurndownPanel.update(); return; // Start a new sprint @@ -163,6 +165,7 @@ export default class KanbnBoardPanel { vscode.window.showErrorMessage(e.message); } } + KanbnBurndownPanel.update(); return; } }, diff --git a/ext-src/KanbnBurndownPanel.ts b/ext-src/KanbnBurndownPanel.ts index 53d7c39..58f696e 100644 --- a/ext-src/KanbnBurndownPanel.ts +++ b/ext-src/KanbnBurndownPanel.ts @@ -1,11 +1,11 @@ import * as path from "path"; import * as vscode from "vscode"; import getNonce from "./getNonce"; -import { v4 as uuidv4 } from "uuid"; export default class KanbnBurndownPanel { + public static currentPanel: KanbnBurndownPanel | undefined; + private static readonly viewType = "react"; - private static panels: KanbnBurndownPanel[] = []; private readonly _panel: vscode.WebviewPanel; private readonly _extensionPath: string; @@ -15,32 +15,58 @@ export default class KanbnBurndownPanel { private sprint: string = ''; private startDate: string = ''; private endDate: string = ''; - private assigned: string = ''; private _disposables: vscode.Disposable[] = []; - public static async show( + public static async createOrShow( extensionPath: string, workspacePath: string, kanbn: typeof import("@basementuniverse/kanbn/src/main") ) { const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined; - // Create a panel - const burndownPanel = new KanbnBurndownPanel( - extensionPath, - workspacePath, - column || vscode.ViewColumn.One, - kanbn - ); - KanbnBurndownPanel.panels.push(burndownPanel); + // If we already have a panel, show it, otherwise create a new panel + if (KanbnBurndownPanel.currentPanel) { + KanbnBurndownPanel.currentPanel._panel.reveal(column); + } else { + KanbnBurndownPanel.currentPanel = new KanbnBurndownPanel( + extensionPath, + workspacePath, + column || vscode.ViewColumn.One, + kanbn + ); + } } - public static async updateAll() { - if (KanbnBurndownPanel.panels.length === 0) { - return; + public static async update() { + if (KanbnBurndownPanel.currentPanel) { + let index: any; + try { + index = await KanbnBurndownPanel.currentPanel._kanbn.getIndex(); + } catch (error) { + vscode.window.showErrorMessage(error instanceof Error ? error.message : error); + return; + } + KanbnBurndownPanel.currentPanel._panel.webview.postMessage({ + type: "burndown", + index, + dateFormat: KanbnBurndownPanel.currentPanel._kanbn.getDateFormat(index), + burndownData: await KanbnBurndownPanel.currentPanel._kanbn.burndown( + (KanbnBurndownPanel.currentPanel.sprintMode && KanbnBurndownPanel.currentPanel.sprint) + ? [KanbnBurndownPanel.currentPanel.sprint] + : null, + ( + !KanbnBurndownPanel.currentPanel.sprintMode && + KanbnBurndownPanel.currentPanel.startDate && + KanbnBurndownPanel.currentPanel.endDate + ) + ? [ + new Date(Date.parse(KanbnBurndownPanel.currentPanel.startDate)), + new Date(Date.parse(KanbnBurndownPanel.currentPanel.endDate)) + ] + : null + ) + }); } - const { index, tasks } = await KanbnBurndownPanel.panels[0].getKanbnIndexAndTasks(); - KanbnBurndownPanel.panels.forEach((panel) => panel._update(index, tasks)); } private constructor( @@ -101,8 +127,7 @@ export default class KanbnBurndownPanel { this.sprint = message.sprint; this.startDate = message.startDate; this.endDate = message.endDate; - this.assigned = message.assigned; - KanbnBurndownPanel.updateAll(); + KanbnBurndownPanel.update(); return; } }, @@ -112,6 +137,9 @@ export default class KanbnBurndownPanel { } public dispose() { + KanbnBurndownPanel.currentPanel = undefined; + + // Clean up our resources this._panel.dispose(); while (this._disposables.length) { const x = this._disposables.pop(); @@ -121,46 +149,6 @@ export default class KanbnBurndownPanel { } } - private async _update(index: any|null, tasks: any[]|null) { - if (!index && !tasks) { - ({ index, tasks } = await this.getKanbnIndexAndTasks()); - } - this._panel.webview.postMessage({ - type: "burndown", - index, - tasks, - dateFormat: this._kanbn.getDateFormat(index), - burndownData: await this._kanbn.burndown( - (this.sprintMode && this.sprint) ? [this.sprint] : null, - (!this.sprintMode && this.startDate && this.endDate) - ? [ - new Date(Date.parse(this.startDate)), - new Date(Date.parse(this.endDate)) - ] - : null, - this.assigned || null - ) - }); - } - - private async getKanbnIndexAndTasks(): Promise<{ index: any|null, tasks: any[]|null }> { - let index: any; - try { - index = await this._kanbn.getIndex(); - } catch (error) { - vscode.window.showErrorMessage(error instanceof Error ? error.message : error); - return { index: null, tasks: null }; - } - let tasks: any[]; - try { - tasks = (await this._kanbn.loadAllTrackedTasks(index)).map((task) => this._kanbn.hydrateTask(index, task)); - } catch (error) { - vscode.window.showErrorMessage(error instanceof Error ? error.message : error); - return { index: null, tasks: null }; - } - return { index, tasks }; - } - private _getHtmlForWebview() { const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json")); const mainScript = manifest["main.js"]; diff --git a/ext-src/extension.ts b/ext-src/extension.ts index 6b81d18..ad9a521 100644 --- a/ext-src/extension.ts +++ b/ext-src/extension.ts @@ -110,8 +110,8 @@ export async function activate(context: vscode.ExtensionContext) { // If kanbn is initialised, view the burndown chart if (await kanbn.initialised()) { - KanbnBurndownPanel.show(context.extensionPath, vscode.workspace.workspaceFolders[0].uri.fsPath, kanbn); - KanbnBurndownPanel.updateAll(); + KanbnBurndownPanel.createOrShow(context.extensionPath, vscode.workspace.workspaceFolders[0].uri.fsPath, kanbn); + KanbnBurndownPanel.update(); } else { vscode.window.showErrorMessage("You need to initialise Kanbn before viewing the burndown chart."); } @@ -138,7 +138,7 @@ export async function activate(context: vscode.ExtensionContext) { fileWatcher.onDidChange(() => { kanbnStatusBarItem.update(); KanbnBoardPanel.update(); - KanbnBurndownPanel.updateAll(); + KanbnBurndownPanel.update(); }); } diff --git a/src/App.tsx b/src/App.tsx index 93dec7e..f540ce7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -114,7 +114,6 @@ function App() { type === 'burndown' &&