Allow opening multiple burndown panels
This commit is contained in:
@ -1,23 +1,24 @@
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import KanbnTaskPanel from './KanbnTaskPanel';
|
||||
import KanbnBurndownPanel from './KanbnBurndownPanel';
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
import getNonce from "./getNonce";
|
||||
import KanbnTaskPanel from "./KanbnTaskPanel";
|
||||
import KanbnBurndownPanel from "./KanbnBurndownPanel";
|
||||
|
||||
export default class KanbnBoardPanel {
|
||||
public static currentPanel: KanbnBoardPanel | undefined;
|
||||
|
||||
private static readonly viewType = 'react';
|
||||
private static readonly viewType = "react";
|
||||
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _extensionPath: string;
|
||||
private readonly _workspacePath: string;
|
||||
private readonly _kanbn: typeof import('@basementuniverse/kanbn/src/main');
|
||||
private readonly _kanbn: typeof import("@basementuniverse/kanbn/src/main");
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public static createOrShow(
|
||||
extensionPath: 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;
|
||||
|
||||
@ -45,23 +46,23 @@ export default class KanbnBoardPanel {
|
||||
}
|
||||
let tasks: any[];
|
||||
try {
|
||||
tasks = (await KanbnBoardPanel.currentPanel._kanbn.loadAllTrackedTasks(index)).map(
|
||||
task => KanbnBoardPanel.currentPanel!._kanbn.hydrateTask(index, task)
|
||||
tasks = (await KanbnBoardPanel.currentPanel._kanbn.loadAllTrackedTasks(index)).map((task) =>
|
||||
KanbnBoardPanel.currentPanel!._kanbn.hydrateTask(index, task)
|
||||
);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
KanbnBoardPanel.currentPanel._panel.webview.postMessage({
|
||||
type: 'index',
|
||||
type: "index",
|
||||
index,
|
||||
tasks,
|
||||
hiddenColumns: index.options.hiddenColumns ?? [],
|
||||
startedColumns: index.options.startedColumns ?? [],
|
||||
completedColumns: index.options.completedColumns ?? [],
|
||||
dateFormat: KanbnBoardPanel.currentPanel._kanbn.getDateFormat(index),
|
||||
showBurndownButton: vscode.workspace.getConfiguration('kanbn').get('showBurndownButton'),
|
||||
showSprintButton: vscode.workspace.getConfiguration('kanbn').get('showSprintButton')
|
||||
showBurndownButton: vscode.workspace.getConfiguration("kanbn").get("showBurndownButton"),
|
||||
showSprintButton: vscode.workspace.getConfiguration("kanbn").get("showSprintButton"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -70,14 +71,14 @@ export default class KanbnBoardPanel {
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
column: vscode.ViewColumn,
|
||||
kanbn: typeof import('@basementuniverse/kanbn/src/main')
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main")
|
||||
) {
|
||||
this._extensionPath = extensionPath;
|
||||
this._workspacePath = workspacePath;
|
||||
this._kanbn = kanbn;
|
||||
|
||||
// Create and show a new webview panel
|
||||
this._panel = vscode.window.createWebviewPanel(KanbnBoardPanel.viewType, 'Kanbn Board', column, {
|
||||
this._panel = vscode.window.createWebviewPanel(KanbnBoardPanel.viewType, "Kanbn Board", column, {
|
||||
// Enable javascript in the webview
|
||||
enableScripts: true,
|
||||
|
||||
@ -86,18 +87,18 @@ export default class KanbnBoardPanel {
|
||||
|
||||
// Restrict the webview to only loading content from allowed paths
|
||||
localResourceRoots: [
|
||||
vscode.Uri.file(path.join(this._extensionPath, 'build')),
|
||||
vscode.Uri.file(path.join(this._extensionPath, "build")),
|
||||
vscode.Uri.file(path.join(this._workspacePath, this._kanbn.getFolderName())),
|
||||
vscode.Uri.file(path.join(this._extensionPath, 'node_modules', 'vscode-codicons', 'dist'))
|
||||
]
|
||||
vscode.Uri.file(path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist")),
|
||||
],
|
||||
});
|
||||
(this._panel as any).iconPath = {
|
||||
light: vscode.Uri.file(path.join(this._extensionPath, 'resources', 'project_light.svg')),
|
||||
dark: vscode.Uri.file(path.join(this._extensionPath, 'resources', 'project_dark.svg'))
|
||||
light: vscode.Uri.file(path.join(this._extensionPath, "resources", "project_light.svg")),
|
||||
dark: vscode.Uri.file(path.join(this._extensionPath, "resources", "project_dark.svg")),
|
||||
};
|
||||
|
||||
// Set the webview's title to the kanbn project name
|
||||
this._kanbn.getIndex().then(index => {
|
||||
this._kanbn.getIndex().then((index) => {
|
||||
this._panel.title = index.name;
|
||||
});
|
||||
|
||||
@ -109,73 +110,65 @@ export default class KanbnBoardPanel {
|
||||
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
|
||||
|
||||
// Handle messages from the webview
|
||||
this._panel.webview.onDidReceiveMessage(async message => {
|
||||
switch (message.command) {
|
||||
this._panel.webview.onDidReceiveMessage(
|
||||
async (message) => {
|
||||
switch (message.command) {
|
||||
// Display error message
|
||||
case "error":
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
return;
|
||||
|
||||
// Display error message
|
||||
case 'error':
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
return;
|
||||
case "kanbn.task":
|
||||
KanbnTaskPanel.show(
|
||||
this._extensionPath,
|
||||
this._workspacePath,
|
||||
this._kanbn,
|
||||
message.taskId,
|
||||
message.columnName
|
||||
);
|
||||
return;
|
||||
|
||||
case 'kanbn.task':
|
||||
KanbnTaskPanel.show(
|
||||
this._extensionPath,
|
||||
this._workspacePath,
|
||||
this._kanbn,
|
||||
message.taskId,
|
||||
message.columnName
|
||||
);
|
||||
return;
|
||||
|
||||
// Move a task
|
||||
case 'kanbn.move':
|
||||
try {
|
||||
await kanbn.moveTask(message.task, message.columnName, message.position);
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(e.message);
|
||||
}
|
||||
return;
|
||||
|
||||
// Create a task
|
||||
case 'kanbn.addTask':
|
||||
KanbnTaskPanel.show(
|
||||
this._extensionPath,
|
||||
this._workspacePath,
|
||||
this._kanbn,
|
||||
null,
|
||||
message.columnName
|
||||
);
|
||||
return;
|
||||
|
||||
// Open a burndown chart
|
||||
case 'kanbn.burndown':
|
||||
KanbnBurndownPanel.createOrShow(
|
||||
this._extensionPath,
|
||||
this._workspacePath,
|
||||
this._kanbn
|
||||
);
|
||||
KanbnBurndownPanel.update();
|
||||
return;
|
||||
|
||||
// Start a new sprint
|
||||
case 'kanbn.sprint':
|
||||
|
||||
// Prompt for a sprint name
|
||||
const newSprintName = await vscode.window.showInputBox({
|
||||
placeHolder: 'The sprint name.'
|
||||
});
|
||||
|
||||
// If the input prompt wasn't cancelled, start a new sprint
|
||||
if (newSprintName !== undefined) {
|
||||
// Move a task
|
||||
case "kanbn.move":
|
||||
try {
|
||||
await kanbn.sprint(newSprintName, '', new Date());
|
||||
await kanbn.moveTask(message.task, message.columnName, message.position);
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(e.message);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}, null, this._disposables);
|
||||
return;
|
||||
|
||||
// Create a task
|
||||
case "kanbn.addTask":
|
||||
KanbnTaskPanel.show(this._extensionPath, this._workspacePath, this._kanbn, null, message.columnName);
|
||||
return;
|
||||
|
||||
// Open a burndown chart
|
||||
case "kanbn.burndown":
|
||||
KanbnBurndownPanel.show(this._extensionPath, this._workspacePath, this._kanbn);
|
||||
KanbnBurndownPanel.updateAll();
|
||||
return;
|
||||
|
||||
// Start a new sprint
|
||||
case "kanbn.sprint":
|
||||
// Prompt for a sprint name
|
||||
const newSprintName = await vscode.window.showInputBox({
|
||||
placeHolder: "The sprint name.",
|
||||
});
|
||||
|
||||
// If the input prompt wasn't cancelled, start a new sprint
|
||||
if (newSprintName !== undefined) {
|
||||
try {
|
||||
await kanbn.sprint(newSprintName, "", new Date());
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(e.message);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
},
|
||||
null,
|
||||
this._disposables
|
||||
);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
@ -192,21 +185,21 @@ export default class KanbnBoardPanel {
|
||||
}
|
||||
|
||||
private _getHtmlForWebview() {
|
||||
const manifest = require(path.join(this._extensionPath, 'build', 'asset-manifest.json'));
|
||||
const mainScript = manifest['main.js'];
|
||||
const mainStyle = manifest['main.css'];
|
||||
const scriptUri = vscode.Uri
|
||||
.file(path.join(this._extensionPath, 'build', mainScript))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const styleUri = vscode.Uri
|
||||
.file(path.join(this._extensionPath, 'build', mainStyle))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const customStyleUri = vscode.Uri
|
||||
.file(path.join(this._workspacePath, this._kanbn.getFolderName(), 'board.css'))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const codiconsUri = vscode.Uri
|
||||
.file(path.join(this._extensionPath, 'node_modules', 'vscode-codicons', 'dist', 'codicon.css'))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json"));
|
||||
const mainScript = manifest["main.js"];
|
||||
const mainStyle = manifest["main.css"];
|
||||
const scriptUri = vscode.Uri.file(path.join(this._extensionPath, "build", mainScript)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const styleUri = vscode.Uri.file(path.join(this._extensionPath, "build", mainStyle)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const customStyleUri = vscode.Uri.file(
|
||||
path.join(this._workspacePath, this._kanbn.getFolderName(), "board.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
const codiconsUri = vscode.Uri.file(
|
||||
path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
|
||||
// Use a nonce to whitelist which scripts can be run
|
||||
const nonce = getNonce();
|
||||
@ -222,7 +215,7 @@ export default class KanbnBoardPanel {
|
||||
<link rel="stylesheet" type="text/css" href="${customStyleUri}">
|
||||
<link rel="stylesheet" type="text/css" href="${codiconsUri}">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https:; script-src 'nonce-${nonce}'; font-src vscode-resource:; style-src vscode-resource: 'unsafe-inline' http: https: data:;">
|
||||
<base href="${vscode.Uri.file(path.join(this._extensionPath, 'build')).with({ scheme: 'vscode-resource' })}/">
|
||||
<base href="${vscode.Uri.file(path.join(this._extensionPath, "build")).with({ scheme: "vscode-resource" })}/">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
@ -232,12 +225,3 @@ export default class KanbnBoardPanel {
|
||||
</html>`;
|
||||
}
|
||||
}
|
||||
|
||||
function getNonce() {
|
||||
let text = "";
|
||||
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
@ -1,73 +1,72 @@
|
||||
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: Record<string, KanbnBurndownPanel> = {};
|
||||
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _extensionPath: string;
|
||||
private readonly _workspacePath: string;
|
||||
private readonly _kanbn: typeof import("@basementuniverse/kanbn/src/main");
|
||||
private readonly _panelUuid: string;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public static createOrShow(
|
||||
public static async show(
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main")
|
||||
) {
|
||||
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
||||
|
||||
// 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
|
||||
);
|
||||
}
|
||||
// Create a panel
|
||||
const panelUuid = uuidv4();
|
||||
const burndownPanel = new KanbnBurndownPanel(
|
||||
extensionPath,
|
||||
workspacePath,
|
||||
column || vscode.ViewColumn.One,
|
||||
kanbn,
|
||||
panelUuid
|
||||
);
|
||||
KanbnBurndownPanel.panels[panelUuid] = burndownPanel;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
let tasks: any[];
|
||||
try {
|
||||
tasks = (await KanbnBurndownPanel.currentPanel._kanbn.loadAllTrackedTasks(index)).map(
|
||||
task => KanbnBurndownPanel.currentPanel!._kanbn.hydrateTask(index, task)
|
||||
);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
KanbnBurndownPanel.currentPanel._panel.webview.postMessage({
|
||||
type: "burndown",
|
||||
index,
|
||||
tasks,
|
||||
dateFormat: KanbnBurndownPanel.currentPanel._kanbn.getDateFormat(index),
|
||||
});
|
||||
public static async updateAll() {
|
||||
const panels = Object.values(KanbnBurndownPanel.panels);
|
||||
if (panels.length === 0) {
|
||||
return;
|
||||
}
|
||||
const kanbn = panels[0]._kanbn;
|
||||
let index: any;
|
||||
try {
|
||||
index = await kanbn.getIndex();
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
let tasks: any[];
|
||||
try {
|
||||
tasks = (await kanbn.loadAllTrackedTasks(index)).map((task) => kanbn.hydrateTask(index, task));
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
panels.forEach((panel) => panel._update(index, tasks));
|
||||
}
|
||||
|
||||
private constructor(
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
column: vscode.ViewColumn,
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main")
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
panelUuid: string
|
||||
) {
|
||||
this._extensionPath = extensionPath;
|
||||
this._workspacePath = workspacePath;
|
||||
this._kanbn = kanbn;
|
||||
this._panelUuid = panelUuid;
|
||||
|
||||
// Create and show a new webview panel
|
||||
this._panel = vscode.window.createWebviewPanel(KanbnBurndownPanel.viewType, "Burndown Chart", column, {
|
||||
@ -117,9 +116,6 @@ 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();
|
||||
@ -129,6 +125,15 @@ export default class KanbnBurndownPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private async _update(index: any, tasks: any[]) {
|
||||
this._panel.webview.postMessage({
|
||||
type: "burndown",
|
||||
index,
|
||||
tasks,
|
||||
dateFormat: this._kanbn.getDateFormat(index),
|
||||
});
|
||||
}
|
||||
|
||||
private _getHtmlForWebview() {
|
||||
const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json"));
|
||||
const mainScript = manifest["main.js"];
|
||||
@ -170,12 +175,3 @@ export default class KanbnBurndownPanel {
|
||||
</html>`;
|
||||
}
|
||||
}
|
||||
|
||||
function getNonce() {
|
||||
let text = "";
|
||||
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
import getNonce from "./getNonce";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
function transformTaskData(taskData: any) {
|
||||
const result = {
|
||||
@ -8,71 +9,69 @@ function transformTaskData(taskData: any) {
|
||||
name: taskData.name,
|
||||
description: taskData.description,
|
||||
metadata: {
|
||||
created: taskData.metadata.created
|
||||
? new Date(taskData.metadata.created)
|
||||
: new Date(),
|
||||
created: taskData.metadata.created ? new Date(taskData.metadata.created) : new Date(),
|
||||
updated: new Date(),
|
||||
assigned: taskData.metadata.assigned,
|
||||
progress: taskData.progress,
|
||||
tags: taskData.metadata.tags
|
||||
tags: taskData.metadata.tags,
|
||||
} as any,
|
||||
relations: taskData.relations,
|
||||
subTasks: taskData.subTasks,
|
||||
comments: taskData.comments.map((comment: any) => ({
|
||||
author: comment.author,
|
||||
date: new Date(Date.parse(comment.date)),
|
||||
text: comment.text
|
||||
}))
|
||||
text: comment.text,
|
||||
})),
|
||||
} as any;
|
||||
|
||||
// Add assigned
|
||||
if (taskData.metadata.assigned) {
|
||||
result.metadata['assigned'] = taskData.metadata.assigned;
|
||||
result.metadata["assigned"] = taskData.metadata.assigned;
|
||||
}
|
||||
|
||||
// Add progress
|
||||
if (taskData.progress > 0) {
|
||||
result.metadata['progress'] = taskData.progress;
|
||||
result.metadata["progress"] = taskData.progress;
|
||||
}
|
||||
|
||||
// Add tags
|
||||
if (taskData.metadata.tags.length) {
|
||||
result.metadata['tags'] = taskData.metadata.tags;
|
||||
result.metadata["tags"] = taskData.metadata.tags;
|
||||
}
|
||||
|
||||
// Add due, started and completed dates if present
|
||||
if (taskData.metadata.due) {
|
||||
result.metadata['due'] = new Date(Date.parse(taskData.metadata.due));
|
||||
result.metadata["due"] = new Date(Date.parse(taskData.metadata.due));
|
||||
}
|
||||
if (taskData.metadata.started) {
|
||||
result.metadata['started'] = new Date(Date.parse(taskData.metadata.started));
|
||||
result.metadata["started"] = new Date(Date.parse(taskData.metadata.started));
|
||||
}
|
||||
if (taskData.metadata.completed) {
|
||||
result.metadata['completed'] = new Date(Date.parse(taskData.metadata.completed));
|
||||
result.metadata["completed"] = new Date(Date.parse(taskData.metadata.completed));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export default class KanbnTaskPanel {
|
||||
private static readonly viewType = 'react';
|
||||
private static readonly viewType = "react";
|
||||
private static panels: Record<string, KanbnTaskPanel> = {};
|
||||
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _extensionPath: string;
|
||||
private readonly _workspacePath: string;
|
||||
private readonly _kanbn: typeof import('@basementuniverse/kanbn/src/main');
|
||||
private _taskId: string|null;
|
||||
private _columnName: string|null;
|
||||
private readonly _kanbn: typeof import("@basementuniverse/kanbn/src/main");
|
||||
private readonly _panelUuid: string;
|
||||
private _taskId: string | null;
|
||||
private _columnName: string | null;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public static async show(
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
kanbn: typeof import('@basementuniverse/kanbn/src/main'),
|
||||
taskId: string|null,
|
||||
columnName: string|null
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
taskId: string | null,
|
||||
columnName: string | null
|
||||
) {
|
||||
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
||||
|
||||
@ -95,9 +94,9 @@ export default class KanbnTaskPanel {
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
column: vscode.ViewColumn,
|
||||
kanbn: typeof import('@basementuniverse/kanbn/src/main'),
|
||||
taskId: string|null,
|
||||
columnName: string|null,
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
taskId: string | null,
|
||||
columnName: string | null,
|
||||
panelUuid: string
|
||||
) {
|
||||
this._extensionPath = extensionPath;
|
||||
@ -108,7 +107,7 @@ export default class KanbnTaskPanel {
|
||||
this._panelUuid = panelUuid;
|
||||
|
||||
// Create and show a new webview panel
|
||||
this._panel = vscode.window.createWebviewPanel(KanbnTaskPanel.viewType, 'New task', column, {
|
||||
this._panel = vscode.window.createWebviewPanel(KanbnTaskPanel.viewType, "New task", column, {
|
||||
// Enable javascript in the webview
|
||||
enableScripts: true,
|
||||
|
||||
@ -117,19 +116,19 @@ export default class KanbnTaskPanel {
|
||||
|
||||
// Restrict the webview to only loading content from allowed paths
|
||||
localResourceRoots: [
|
||||
vscode.Uri.file(path.join(this._extensionPath, 'build')),
|
||||
vscode.Uri.file(path.join(this._extensionPath, "build")),
|
||||
vscode.Uri.file(path.join(this._workspacePath, this._kanbn.getFolderName())),
|
||||
vscode.Uri.file(path.join(this._extensionPath, 'node_modules', 'vscode-codicons', 'dist'))
|
||||
]
|
||||
vscode.Uri.file(path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist")),
|
||||
],
|
||||
});
|
||||
(this._panel as any).iconPath = {
|
||||
light: vscode.Uri.file(path.join(this._extensionPath, 'resources', 'task_light.svg')),
|
||||
dark: vscode.Uri.file(path.join(this._extensionPath, 'resources', 'task_dark.svg'))
|
||||
light: vscode.Uri.file(path.join(this._extensionPath, "resources", "task_light.svg")),
|
||||
dark: vscode.Uri.file(path.join(this._extensionPath, "resources", "task_dark.svg")),
|
||||
};
|
||||
|
||||
// Set the webview's title to the kanbn task name
|
||||
if (this._taskId !== null) {
|
||||
this._kanbn.getTask(this._taskId).then(task => {
|
||||
this._kanbn.getTask(this._taskId).then((task) => {
|
||||
this._panel.title = task.name;
|
||||
});
|
||||
}
|
||||
@ -142,58 +141,61 @@ export default class KanbnTaskPanel {
|
||||
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
|
||||
|
||||
// Handle messages from the webview
|
||||
this._panel.webview.onDidReceiveMessage(async message => {
|
||||
switch (message.command) {
|
||||
this._panel.webview.onDidReceiveMessage(
|
||||
async (message) => {
|
||||
switch (message.command) {
|
||||
// Display error message
|
||||
case "error":
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
return;
|
||||
|
||||
// Display error message
|
||||
case 'error':
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
return;
|
||||
// Update the task webview panel title
|
||||
case "kanbn.updatePanelTitle":
|
||||
this._panel.title = message.title;
|
||||
return;
|
||||
|
||||
// Update the task webview panel title
|
||||
case 'kanbn.updatePanelTitle':
|
||||
this._panel.title = message.title;
|
||||
return;
|
||||
|
||||
// Create a task
|
||||
case 'kanbn.create':
|
||||
await this._kanbn.createTask(transformTaskData(message.taskData), message.taskData.column);
|
||||
KanbnTaskPanel.panels[message.panelUuid]._taskId = message.taskData.id;
|
||||
KanbnTaskPanel.panels[message.panelUuid]._columnName = message.taskData.column;
|
||||
KanbnTaskPanel.panels[message.panelUuid].update();
|
||||
if (vscode.workspace.getConfiguration('kanbn').get('showTaskNotifications')) {
|
||||
vscode.window.showInformationMessage(`Created task '${message.taskData.name}'.`);
|
||||
}
|
||||
return;
|
||||
|
||||
// Update a task
|
||||
case 'kanbn.update':
|
||||
await this._kanbn.updateTask(message.taskId, transformTaskData(message.taskData), message.taskData.column);
|
||||
KanbnTaskPanel.panels[message.panelUuid]._taskId = message.taskData.id;
|
||||
KanbnTaskPanel.panels[message.panelUuid]._columnName = message.taskData.column;
|
||||
KanbnTaskPanel.panels[message.panelUuid].update();
|
||||
if (vscode.workspace.getConfiguration('kanbn').get('showTaskNotifications')) {
|
||||
vscode.window.showInformationMessage(`Updated task '${message.taskData.name}'.`);
|
||||
}
|
||||
return;
|
||||
|
||||
// Delete a task and close the webview panel
|
||||
case 'kanbn.delete':
|
||||
vscode.window.showInformationMessage(`Delete task '${message.taskData.name}'?`, 'Yes', 'No').then(
|
||||
async value => {
|
||||
if (value === 'Yes') {
|
||||
await this._kanbn.deleteTask(message.taskId, true);
|
||||
KanbnTaskPanel.panels[message.panelUuid].dispose();
|
||||
delete KanbnTaskPanel.panels[message.panelUuid];
|
||||
if (vscode.workspace.getConfiguration('kanbn').get('showTaskNotifications')) {
|
||||
vscode.window.showInformationMessage(`Deleted task '${message.taskData.name}'.`);
|
||||
}
|
||||
}
|
||||
// Create a task
|
||||
case "kanbn.create":
|
||||
await this._kanbn.createTask(transformTaskData(message.taskData), message.taskData.column);
|
||||
KanbnTaskPanel.panels[message.panelUuid]._taskId = message.taskData.id;
|
||||
KanbnTaskPanel.panels[message.panelUuid]._columnName = message.taskData.column;
|
||||
KanbnTaskPanel.panels[message.panelUuid].update();
|
||||
if (vscode.workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
vscode.window.showInformationMessage(`Created task '${message.taskData.name}'.`);
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
}, null, this._disposables);
|
||||
return;
|
||||
|
||||
// Update a task
|
||||
case "kanbn.update":
|
||||
await this._kanbn.updateTask(message.taskId, transformTaskData(message.taskData), message.taskData.column);
|
||||
KanbnTaskPanel.panels[message.panelUuid]._taskId = message.taskData.id;
|
||||
KanbnTaskPanel.panels[message.panelUuid]._columnName = message.taskData.column;
|
||||
KanbnTaskPanel.panels[message.panelUuid].update();
|
||||
if (vscode.workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
vscode.window.showInformationMessage(`Updated task '${message.taskData.name}'.`);
|
||||
}
|
||||
return;
|
||||
|
||||
// Delete a task and close the webview panel
|
||||
case "kanbn.delete":
|
||||
vscode.window
|
||||
.showInformationMessage(`Delete task '${message.taskData.name}'?`, "Yes", "No")
|
||||
.then(async (value) => {
|
||||
if (value === "Yes") {
|
||||
await this._kanbn.deleteTask(message.taskId, true);
|
||||
KanbnTaskPanel.panels[message.panelUuid].dispose();
|
||||
delete KanbnTaskPanel.panels[message.panelUuid];
|
||||
if (vscode.workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
vscode.window.showInformationMessage(`Deleted task '${message.taskData.name}'.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
},
|
||||
null,
|
||||
this._disposables
|
||||
);
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
@ -216,19 +218,17 @@ export default class KanbnTaskPanel {
|
||||
}
|
||||
let tasks: any[];
|
||||
try {
|
||||
tasks = (await this._kanbn.loadAllTrackedTasks(index)).map(
|
||||
task => ({
|
||||
uuid: uuidv4(),
|
||||
...this._kanbn.hydrateTask(index, task)
|
||||
})
|
||||
);
|
||||
tasks = (await this._kanbn.loadAllTrackedTasks(index)).map((task) => ({
|
||||
uuid: uuidv4(),
|
||||
...this._kanbn.hydrateTask(index, task),
|
||||
}));
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
let task = null;
|
||||
if (this._taskId) {
|
||||
task = tasks.find(t => t.id === this._taskId) ?? null;
|
||||
task = tasks.find((t) => t.id === this._taskId) ?? null;
|
||||
}
|
||||
|
||||
// If no columnName is specified, use the first column
|
||||
@ -238,32 +238,32 @@ export default class KanbnTaskPanel {
|
||||
|
||||
// Send task data to the webview
|
||||
this._panel.webview.postMessage({
|
||||
type: 'task',
|
||||
type: "task",
|
||||
index,
|
||||
task,
|
||||
tasks,
|
||||
columnName: this._columnName,
|
||||
dateFormat: this._kanbn.getDateFormat(index),
|
||||
panelUuid: this._panelUuid
|
||||
panelUuid: this._panelUuid,
|
||||
});
|
||||
}
|
||||
|
||||
private _getHtmlForWebview() {
|
||||
const manifest = require(path.join(this._extensionPath, 'build', 'asset-manifest.json'));
|
||||
const mainScript = manifest['main.js'];
|
||||
const mainStyle = manifest['main.css'];
|
||||
const scriptUri = vscode.Uri
|
||||
.file(path.join(this._extensionPath, 'build', mainScript))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const styleUri = vscode.Uri
|
||||
.file(path.join(this._extensionPath, 'build', mainStyle))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const customStyleUri = vscode.Uri
|
||||
.file(path.join(this._workspacePath, this._kanbn.getFolderName(), 'board.css'))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const codiconsUri = vscode.Uri
|
||||
.file(path.join(this._extensionPath, 'node_modules', 'vscode-codicons', 'dist', 'codicon.css'))
|
||||
.with({ scheme: 'vscode-resource' });
|
||||
const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json"));
|
||||
const mainScript = manifest["main.js"];
|
||||
const mainStyle = manifest["main.css"];
|
||||
const scriptUri = vscode.Uri.file(path.join(this._extensionPath, "build", mainScript)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const styleUri = vscode.Uri.file(path.join(this._extensionPath, "build", mainStyle)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const customStyleUri = vscode.Uri.file(
|
||||
path.join(this._workspacePath, this._kanbn.getFolderName(), "board.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
const codiconsUri = vscode.Uri.file(
|
||||
path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
|
||||
// Use a nonce to whitelist which scripts can be run
|
||||
const nonce = getNonce();
|
||||
@ -279,7 +279,7 @@ export default class KanbnTaskPanel {
|
||||
<link rel="stylesheet" type="text/css" href="${customStyleUri}">
|
||||
<link rel="stylesheet" type="text/css" href="${codiconsUri}">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src vscode-resource: https:; script-src 'nonce-${nonce}'; font-src vscode-resource:; style-src vscode-resource: 'unsafe-inline' http: https: data:;">
|
||||
<base href="${vscode.Uri.file(path.join(this._extensionPath, 'build')).with({ scheme: 'vscode-resource' })}/">
|
||||
<base href="${vscode.Uri.file(path.join(this._extensionPath, "build")).with({ scheme: "vscode-resource" })}/">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
@ -289,12 +289,3 @@ export default class KanbnTaskPanel {
|
||||
</html>`;
|
||||
}
|
||||
}
|
||||
|
||||
function getNonce() {
|
||||
let text = "";
|
||||
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
@ -1,141 +1,129 @@
|
||||
import * as vscode from 'vscode';
|
||||
import KanbnStatusBarItem from './KanbnStatusBarItem';
|
||||
import KanbnBoardPanel from './KanbnBoardPanel';
|
||||
import KanbnBurndownPanel from './KanbnBurndownPanel';
|
||||
import KanbnTaskPanel from './KanbnTaskPanel';
|
||||
import * as vscode from "vscode";
|
||||
import KanbnStatusBarItem from "./KanbnStatusBarItem";
|
||||
import KanbnBoardPanel from "./KanbnBoardPanel";
|
||||
import KanbnBurndownPanel from "./KanbnBurndownPanel";
|
||||
import KanbnTaskPanel from "./KanbnTaskPanel";
|
||||
|
||||
let kanbnStatusBarItem: KanbnStatusBarItem;
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
// Register a command to initialise Kanbn in the current workspace. This command will be invoked when the status
|
||||
// bar item is clicked in a workspace where Kanbn isn't already initialised.
|
||||
context.subscriptions.push(vscode.commands.registerCommand('kanbn.init', async () => {
|
||||
|
||||
// If no workspace folder is opened, we can't initialise kanbn
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage('You need to open a workspace before initialising Kanbn.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import('@basementuniverse/kanbn/src/main');
|
||||
|
||||
// If kanbn is already initialised, get the project name
|
||||
let projectName = '';
|
||||
if (await kanbn.initialised()) {
|
||||
projectName = (await kanbn.getIndex()).name;
|
||||
}
|
||||
|
||||
// Prompt for a new project name
|
||||
const newProjectName = await vscode.window.showInputBox({
|
||||
value: projectName,
|
||||
placeHolder: 'The project name.',
|
||||
validateInput: text => {
|
||||
return text.length < 1 ? 'The project name cannot be empty.' : null;
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kanbn.init", async () => {
|
||||
// If no workspace folder is opened, we can't initialise kanbn
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage("You need to open a workspace before initialising Kanbn.");
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// If the input prompt wasn't cancelled, initialise kanbn
|
||||
if (newProjectName !== undefined) {
|
||||
await kanbn.initialise({
|
||||
name: newProjectName
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// If kanbn is already initialised, get the project name
|
||||
let projectName = "";
|
||||
if (await kanbn.initialised()) {
|
||||
projectName = (await kanbn.getIndex()).name;
|
||||
}
|
||||
|
||||
// Prompt for a new project name
|
||||
const newProjectName = await vscode.window.showInputBox({
|
||||
value: projectName,
|
||||
placeHolder: "The project name.",
|
||||
validateInput: (text) => {
|
||||
return text.length < 1 ? "The project name cannot be empty." : null;
|
||||
},
|
||||
});
|
||||
vscode.window.showInformationMessage(`Initialised Kanbn project '${newProjectName}'.`);
|
||||
KanbnBoardPanel.update();
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
}));
|
||||
|
||||
// If the input prompt wasn't cancelled, initialise kanbn
|
||||
if (newProjectName !== undefined) {
|
||||
await kanbn.initialise({
|
||||
name: newProjectName,
|
||||
});
|
||||
vscode.window.showInformationMessage(`Initialised Kanbn project '${newProjectName}'.`);
|
||||
KanbnBoardPanel.update();
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
})
|
||||
);
|
||||
|
||||
// Register a command to open the kanbn board. This command will be invoked when the status bar item is clicked
|
||||
// in a workspace where kanbn has already been initialised.
|
||||
context.subscriptions.push(vscode.commands.registerCommand('kanbn.board', async () => {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kanbn.board", async () => {
|
||||
// If no workspace folder is opened, we can't open the kanbn board
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage("You need to open a workspace before viewing the Kanbn board.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If no workspace folder is opened, we can't open the kanbn board
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage('You need to open a workspace before viewing the Kanbn board.');
|
||||
return;
|
||||
}
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import('@basementuniverse/kanbn/src/main');
|
||||
|
||||
// If kanbn is initialised, view the kanbn board
|
||||
if (await kanbn.initialised()) {
|
||||
KanbnBoardPanel.createOrShow(
|
||||
context.extensionPath,
|
||||
vscode.workspace.workspaceFolders[0].uri.fsPath,
|
||||
kanbn
|
||||
);
|
||||
KanbnBoardPanel.update();
|
||||
} else {
|
||||
vscode.window.showErrorMessage('You need to initialise Kanbn before viewing the Kanbn board.');
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
}));
|
||||
// If kanbn is initialised, view the kanbn board
|
||||
if (await kanbn.initialised()) {
|
||||
KanbnBoardPanel.createOrShow(context.extensionPath, vscode.workspace.workspaceFolders[0].uri.fsPath, kanbn);
|
||||
KanbnBoardPanel.update();
|
||||
} else {
|
||||
vscode.window.showErrorMessage("You need to initialise Kanbn before viewing the Kanbn board.");
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
})
|
||||
);
|
||||
|
||||
// Register a command to add a new kanbn task.
|
||||
context.subscriptions.push(vscode.commands.registerCommand('kanbn.addTask', async () => {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kanbn.addTask", async () => {
|
||||
// If no workspace folder is opened, we can't add a new task
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage("You need to open a workspace before adding a new task.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If no workspace folder is opened, we can't add a new task
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage('You need to open a workspace before adding a new task.');
|
||||
return;
|
||||
}
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import('@basementuniverse/kanbn/src/main');
|
||||
|
||||
// If kanbn is initialised, open the task webview
|
||||
if (await kanbn.initialised()) {
|
||||
KanbnTaskPanel.show(
|
||||
context.extensionPath,
|
||||
vscode.workspace.workspaceFolders[0].uri.fsPath,
|
||||
kanbn,
|
||||
null,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
vscode.window.showErrorMessage('You need to initialise Kanbn before adding a new task.');
|
||||
}
|
||||
}));
|
||||
// If kanbn is initialised, open the task webview
|
||||
if (await kanbn.initialised()) {
|
||||
KanbnTaskPanel.show(context.extensionPath, vscode.workspace.workspaceFolders[0].uri.fsPath, kanbn, null, null);
|
||||
} else {
|
||||
vscode.window.showErrorMessage("You need to initialise Kanbn before adding a new task.");
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// Register a command to open a burndown chart.
|
||||
context.subscriptions.push(vscode.commands.registerCommand('kanbn.burndown', async () => {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kanbn.burndown", async () => {
|
||||
// If no workspace folder is opened, we can't open the burndown chart
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage("You need to open a workspace before viewing the burndown chart.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If no workspace folder is opened, we can't open the burndown chart
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage('You need to open a workspace before viewing the burndown chart.');
|
||||
return;
|
||||
}
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import('@basementuniverse/kanbn/src/main');
|
||||
|
||||
// If kanbn is initialised, view the burndown chart
|
||||
if (await kanbn.initialised()) {
|
||||
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.');
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
}));
|
||||
// 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();
|
||||
} else {
|
||||
vscode.window.showErrorMessage("You need to initialise Kanbn before viewing the burndown chart.");
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
})
|
||||
);
|
||||
|
||||
// If a workspace folder is open, add a status bar item and start watching for file changes
|
||||
if (vscode.workspace.workspaceFolders !== undefined) {
|
||||
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import('@basementuniverse/kanbn/src/main');
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// Create status bar item
|
||||
kanbnStatusBarItem = new KanbnStatusBarItem(context, kanbn);
|
||||
@ -144,18 +132,18 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
// Initialise file watcher
|
||||
const uri = vscode.workspace.workspaceFolders[0].uri.fsPath;
|
||||
const fileWatcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(
|
||||
uri,
|
||||
`${kanbn.getFolderName()}/**.*`
|
||||
));
|
||||
const fileWatcher = vscode.workspace.createFileSystemWatcher(
|
||||
new vscode.RelativePattern(uri, `${kanbn.getFolderName()}/**.*`)
|
||||
);
|
||||
fileWatcher.onDidChange(() => {
|
||||
kanbnStatusBarItem.update();
|
||||
KanbnBoardPanel.update();
|
||||
KanbnBurndownPanel.updateAll();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle configuration changes
|
||||
vscode.workspace.onDidChangeConfiguration(e => {
|
||||
vscode.workspace.onDidChangeConfiguration((e) => {
|
||||
kanbnStatusBarItem.update();
|
||||
KanbnBoardPanel.update();
|
||||
});
|
||||
|
8
ext-src/getNonce.ts
Normal file
8
ext-src/getNonce.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export default function getNonce() {
|
||||
let text = "";
|
||||
const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
Reference in New Issue
Block a user