Singleton burndown panel

This commit is contained in:
Gordon 2021-04-19 03:37:40 +01:00
parent 9e0d88f69e
commit d417b6ec7f
4 changed files with 55 additions and 65 deletions

View File

@ -113,11 +113,13 @@ export default class KanbnBoardPanel {
this._panel.webview.onDidReceiveMessage( this._panel.webview.onDidReceiveMessage(
async (message) => { async (message) => {
switch (message.command) { switch (message.command) {
// Display error message // Display error message
case "error": case "error":
vscode.window.showErrorMessage(message.text); vscode.window.showErrorMessage(message.text);
return; return;
// Open a task in the editor
case "kanbn.task": case "kanbn.task":
KanbnTaskPanel.show( KanbnTaskPanel.show(
this._extensionPath, this._extensionPath,
@ -144,8 +146,8 @@ export default class KanbnBoardPanel {
// Open a burndown chart // Open a burndown chart
case "kanbn.burndown": case "kanbn.burndown":
KanbnBurndownPanel.show(this._extensionPath, this._workspacePath, this._kanbn); KanbnBurndownPanel.createOrShow(this._extensionPath, this._workspacePath, this._kanbn);
KanbnBurndownPanel.updateAll(); KanbnBurndownPanel.update();
return; return;
// Start a new sprint // Start a new sprint
@ -163,6 +165,7 @@ export default class KanbnBoardPanel {
vscode.window.showErrorMessage(e.message); vscode.window.showErrorMessage(e.message);
} }
} }
KanbnBurndownPanel.update();
return; return;
} }
}, },

View File

@ -1,11 +1,11 @@
import * as path from "path"; import * as path from "path";
import * as vscode from "vscode"; import * as vscode from "vscode";
import getNonce from "./getNonce"; import getNonce from "./getNonce";
import { v4 as uuidv4 } from "uuid";
export default class KanbnBurndownPanel { export default class KanbnBurndownPanel {
public static currentPanel: KanbnBurndownPanel | undefined;
private static readonly viewType = "react"; private static readonly viewType = "react";
private static panels: KanbnBurndownPanel[] = [];
private readonly _panel: vscode.WebviewPanel; private readonly _panel: vscode.WebviewPanel;
private readonly _extensionPath: string; private readonly _extensionPath: string;
@ -15,32 +15,58 @@ export default class KanbnBurndownPanel {
private sprint: string = ''; private sprint: string = '';
private startDate: string = ''; private startDate: string = '';
private endDate: string = ''; private endDate: string = '';
private assigned: string = '';
private _disposables: vscode.Disposable[] = []; private _disposables: vscode.Disposable[] = [];
public static async show( public static async createOrShow(
extensionPath: string, extensionPath: string,
workspacePath: string, workspacePath: string,
kanbn: typeof import("@basementuniverse/kanbn/src/main") kanbn: typeof import("@basementuniverse/kanbn/src/main")
) { ) {
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined; const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
// Create a panel // If we already have a panel, show it, otherwise create a new panel
const burndownPanel = new KanbnBurndownPanel( if (KanbnBurndownPanel.currentPanel) {
extensionPath, KanbnBurndownPanel.currentPanel._panel.reveal(column);
workspacePath, } else {
column || vscode.ViewColumn.One, KanbnBurndownPanel.currentPanel = new KanbnBurndownPanel(
kanbn extensionPath,
); workspacePath,
KanbnBurndownPanel.panels.push(burndownPanel); column || vscode.ViewColumn.One,
kanbn
);
}
} }
public static async updateAll() { public static async update() {
if (KanbnBurndownPanel.panels.length === 0) { if (KanbnBurndownPanel.currentPanel) {
return; 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( private constructor(
@ -101,8 +127,7 @@ export default class KanbnBurndownPanel {
this.sprint = message.sprint; this.sprint = message.sprint;
this.startDate = message.startDate; this.startDate = message.startDate;
this.endDate = message.endDate; this.endDate = message.endDate;
this.assigned = message.assigned; KanbnBurndownPanel.update();
KanbnBurndownPanel.updateAll();
return; return;
} }
}, },
@ -112,6 +137,9 @@ export default class KanbnBurndownPanel {
} }
public dispose() { public dispose() {
KanbnBurndownPanel.currentPanel = undefined;
// Clean up our resources
this._panel.dispose(); this._panel.dispose();
while (this._disposables.length) { while (this._disposables.length) {
const x = this._disposables.pop(); 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() { private _getHtmlForWebview() {
const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json")); const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json"));
const mainScript = manifest["main.js"]; const mainScript = manifest["main.js"];

View File

@ -110,8 +110,8 @@ export async function activate(context: vscode.ExtensionContext) {
// If kanbn is initialised, view the burndown chart // If kanbn is initialised, view the burndown chart
if (await kanbn.initialised()) { if (await kanbn.initialised()) {
KanbnBurndownPanel.show(context.extensionPath, vscode.workspace.workspaceFolders[0].uri.fsPath, kanbn); KanbnBurndownPanel.createOrShow(context.extensionPath, vscode.workspace.workspaceFolders[0].uri.fsPath, kanbn);
KanbnBurndownPanel.updateAll(); KanbnBurndownPanel.update();
} else { } else {
vscode.window.showErrorMessage("You need to initialise Kanbn before viewing the burndown chart."); 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(() => { fileWatcher.onDidChange(() => {
kanbnStatusBarItem.update(); kanbnStatusBarItem.update();
KanbnBoardPanel.update(); KanbnBoardPanel.update();
KanbnBurndownPanel.updateAll(); KanbnBurndownPanel.update();
}); });
} }

View File

@ -114,7 +114,6 @@ function App() {
type === 'burndown' && type === 'burndown' &&
<Burndown <Burndown
name={name} name={name}
tasks={tasks}
sprints={sprints} sprints={sprints}
burndownData={burndownData} burndownData={burndownData}
dateFormat={dateFormat} dateFormat={dateFormat}