# 0.12.0
* First release with the following changes
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
import { join } from "path";
|
||||
import { WebviewPanel, Disposable, window, ViewColumn, workspace, Uri, commands } from "vscode";
|
||||
import getNonce from "./getNonce";
|
||||
import KanbnTaskPanel from "./KanbnTaskPanel";
|
||||
import KanbnBurndownPanel from "./KanbnBurndownPanel";
|
||||
@ -24,12 +24,12 @@ export default class KanbnBoardPanel {
|
||||
|
||||
private static readonly viewType = "react";
|
||||
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _panel: WebviewPanel;
|
||||
private readonly _extensionPath: string;
|
||||
private readonly _workspacePath: string;
|
||||
private readonly _kanbn: typeof import("@basementuniverse/kanbn/src/main");
|
||||
private readonly _kanbnFolderName: string;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
private _disposables: Disposable[] = [];
|
||||
|
||||
public static createOrShow(
|
||||
extensionPath: string,
|
||||
@ -37,7 +37,7 @@ export default class KanbnBoardPanel {
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
kanbnFolderName: string
|
||||
) {
|
||||
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
||||
const column = window.activeTextEditor ? window.activeTextEditor.viewColumn : undefined;
|
||||
|
||||
// If we already have a panel, show it, otherwise create a new panel
|
||||
if (KanbnBoardPanel.currentPanel) {
|
||||
@ -46,7 +46,7 @@ export default class KanbnBoardPanel {
|
||||
KanbnBoardPanel.currentPanel = new KanbnBoardPanel(
|
||||
extensionPath,
|
||||
workspacePath,
|
||||
column || vscode.ViewColumn.One,
|
||||
column || ViewColumn.One,
|
||||
kanbn,
|
||||
kanbnFolderName
|
||||
);
|
||||
@ -59,7 +59,7 @@ export default class KanbnBoardPanel {
|
||||
try {
|
||||
index = await KanbnBoardPanel.currentPanel._kanbn.getIndex();
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
let tasks: any[];
|
||||
@ -68,7 +68,7 @@ export default class KanbnBoardPanel {
|
||||
KanbnBoardPanel.currentPanel!._kanbn.hydrateTask(index, task)
|
||||
);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
KanbnBoardPanel.currentPanel._panel.webview.postMessage({
|
||||
@ -81,8 +81,8 @@ export default class KanbnBoardPanel {
|
||||
columnSorting: index.options.columnSorting ?? {},
|
||||
customFields: index.options.customFields ?? [],
|
||||
dateFormat: KanbnBoardPanel.currentPanel._kanbn.getDateFormat(index),
|
||||
showBurndownButton: vscode.workspace.getConfiguration("kanbn").get("showBurndownButton"),
|
||||
showSprintButton: vscode.workspace.getConfiguration("kanbn").get("showSprintButton"),
|
||||
showBurndownButton: workspace.getConfiguration("kanbn").get("showBurndownButton"),
|
||||
showSprintButton: workspace.getConfiguration("kanbn").get("showSprintButton"),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -90,7 +90,7 @@ export default class KanbnBoardPanel {
|
||||
private constructor(
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
column: vscode.ViewColumn,
|
||||
column: ViewColumn,
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
kanbnFolderName: string
|
||||
) {
|
||||
@ -100,7 +100,7 @@ export default class KanbnBoardPanel {
|
||||
this._kanbnFolderName = kanbnFolderName;
|
||||
|
||||
// Create and show a new webview panel
|
||||
this._panel = vscode.window.createWebviewPanel(KanbnBoardPanel.viewType, "Kanbn Board", column, {
|
||||
this._panel = window.createWebviewPanel(KanbnBoardPanel.viewType, "Kanbn Board", column, {
|
||||
// Enable javascript in the webview
|
||||
enableScripts: true,
|
||||
|
||||
@ -109,14 +109,14 @@ 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._workspacePath, this._kanbnFolderName)),
|
||||
vscode.Uri.file(path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist")),
|
||||
Uri.file(join(this._extensionPath, "build")),
|
||||
Uri.file(join(this._workspacePath, this._kanbnFolderName)),
|
||||
Uri.file(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: Uri.file(join(this._extensionPath, "resources", "project_light.svg")),
|
||||
dark: Uri.file(join(this._extensionPath, "resources", "project_dark.svg")),
|
||||
};
|
||||
|
||||
// Set the webview's title to the kanbn project name
|
||||
@ -138,7 +138,7 @@ export default class KanbnBoardPanel {
|
||||
|
||||
// Display error message
|
||||
case "error":
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
window.showErrorMessage(message.text);
|
||||
return;
|
||||
|
||||
// Open a task in the editor
|
||||
@ -153,12 +153,18 @@ export default class KanbnBoardPanel {
|
||||
);
|
||||
return;
|
||||
|
||||
// Go to raw task in the editor
|
||||
case "kanbn.goToRaw":
|
||||
let uri = Uri.file(join(this._workspacePath, ".kanbn", "tasks", message.taskId + ".md"));
|
||||
await commands.executeCommand('vscode.open', uri);
|
||||
return;
|
||||
|
||||
// Move a task
|
||||
case "kanbn.move":
|
||||
try {
|
||||
await kanbn.moveTask(message.task, message.columnName, message.position);
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(e.message);
|
||||
window.showErrorMessage(e.message);
|
||||
}
|
||||
return;
|
||||
|
||||
@ -185,7 +191,7 @@ export default class KanbnBoardPanel {
|
||||
);
|
||||
}
|
||||
// Prompt for a task property to sort by
|
||||
const sortBy: string = await vscode.window.showQuickPick(
|
||||
const sortBy = await window.showQuickPick(
|
||||
[
|
||||
'None',
|
||||
...Object.keys(sortByFields),
|
||||
@ -204,7 +210,7 @@ export default class KanbnBoardPanel {
|
||||
}
|
||||
|
||||
// Prompt for sort direction and save settings
|
||||
const sortDirection = await vscode.window.showQuickPick(
|
||||
const sortDirection = await window.showQuickPick(
|
||||
[
|
||||
'Ascending',
|
||||
'Descending',
|
||||
@ -215,7 +221,7 @@ export default class KanbnBoardPanel {
|
||||
}
|
||||
);
|
||||
if (sortDirection !== undefined) {
|
||||
const saveSort = await vscode.window.showQuickPick(
|
||||
const saveSort = await window.showQuickPick(
|
||||
[
|
||||
"Yes",
|
||||
"No",
|
||||
@ -256,7 +262,7 @@ export default class KanbnBoardPanel {
|
||||
// Start a new sprint
|
||||
case "kanbn.sprint":
|
||||
// Prompt for a sprint name
|
||||
const newSprintName = await vscode.window.showInputBox({
|
||||
const newSprintName = await window.showInputBox({
|
||||
placeHolder: "The sprint name.",
|
||||
});
|
||||
|
||||
@ -265,7 +271,7 @@ export default class KanbnBoardPanel {
|
||||
try {
|
||||
await kanbn.sprint(newSprintName, "", new Date());
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(e.message);
|
||||
window.showErrorMessage(e.message);
|
||||
}
|
||||
}
|
||||
KanbnBurndownPanel.update();
|
||||
@ -291,20 +297,20 @@ export default class KanbnBoardPanel {
|
||||
}
|
||||
|
||||
private _getHtmlForWebview() {
|
||||
const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json"));
|
||||
const manifest = require(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({
|
||||
const scriptUri = Uri.file(join(this._extensionPath, "build", mainScript)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const styleUri = vscode.Uri.file(path.join(this._extensionPath, "build", mainStyle)).with({
|
||||
const styleUri = Uri.file(join(this._extensionPath, "build", mainStyle)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const customStyleUri = vscode.Uri.file(
|
||||
path.join(this._workspacePath, this._kanbnFolderName, "board.css")
|
||||
const customStyleUri = Uri.file(
|
||||
join(this._workspacePath, this._kanbnFolderName, "board.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
const codiconsUri = vscode.Uri.file(
|
||||
path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
const codiconsUri = Uri.file(
|
||||
join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
|
||||
// Use a nonce to whitelist which scripts can be run
|
||||
@ -321,7 +327,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="${Uri.file(join(this._extensionPath, "build")).with({ scheme: "vscode-resource" })}/">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
import { join } from "path";
|
||||
import { WebviewPanel, Disposable, window, ViewColumn, Uri } from "vscode";
|
||||
import getNonce from "./getNonce";
|
||||
|
||||
export default class KanbnBurndownPanel {
|
||||
@ -7,7 +7,7 @@ export default class KanbnBurndownPanel {
|
||||
|
||||
private static readonly viewType = "react";
|
||||
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _panel: WebviewPanel;
|
||||
private readonly _extensionPath: string;
|
||||
private readonly _workspacePath: string;
|
||||
private readonly _kanbn: typeof import("@basementuniverse/kanbn/src/main");
|
||||
@ -16,7 +16,7 @@ export default class KanbnBurndownPanel {
|
||||
private sprint: string = '';
|
||||
private startDate: string = '';
|
||||
private endDate: string = '';
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
private _disposables: Disposable[] = [];
|
||||
|
||||
public static async createOrShow(
|
||||
extensionPath: string,
|
||||
@ -24,7 +24,7 @@ export default class KanbnBurndownPanel {
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
kanbnFolderName: string
|
||||
) {
|
||||
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
||||
const column = window.activeTextEditor ? window.activeTextEditor.viewColumn : undefined;
|
||||
|
||||
// If we already have a panel, show it, otherwise create a new panel
|
||||
if (KanbnBurndownPanel.currentPanel) {
|
||||
@ -33,7 +33,7 @@ export default class KanbnBurndownPanel {
|
||||
KanbnBurndownPanel.currentPanel = new KanbnBurndownPanel(
|
||||
extensionPath,
|
||||
workspacePath,
|
||||
column || vscode.ViewColumn.One,
|
||||
column || ViewColumn.One,
|
||||
kanbn,
|
||||
kanbnFolderName
|
||||
);
|
||||
@ -46,7 +46,7 @@ export default class KanbnBurndownPanel {
|
||||
try {
|
||||
index = await KanbnBurndownPanel.currentPanel._kanbn.getIndex();
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
KanbnBurndownPanel.currentPanel._panel.webview.postMessage({
|
||||
@ -78,7 +78,7 @@ export default class KanbnBurndownPanel {
|
||||
private constructor(
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
column: vscode.ViewColumn,
|
||||
column: ViewColumn,
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
kanbnFolderName: string
|
||||
) {
|
||||
@ -88,7 +88,7 @@ export default class KanbnBurndownPanel {
|
||||
this._kanbnFolderName = kanbnFolderName;
|
||||
|
||||
// Create and show a new webview panel
|
||||
this._panel = vscode.window.createWebviewPanel(KanbnBurndownPanel.viewType, "Burndown Chart", column, {
|
||||
this._panel = window.createWebviewPanel(KanbnBurndownPanel.viewType, "Burndown Chart", column, {
|
||||
// Enable javascript in the webview
|
||||
enableScripts: true,
|
||||
|
||||
@ -97,14 +97,14 @@ export default class KanbnBurndownPanel {
|
||||
|
||||
// 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._workspacePath, this._kanbnFolderName)),
|
||||
vscode.Uri.file(path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist")),
|
||||
Uri.file(join(this._extensionPath, "build")),
|
||||
Uri.file(join(this._workspacePath, this._kanbnFolderName)),
|
||||
Uri.file(join(this._extensionPath, "node_modules", "vscode-codicons", "dist")),
|
||||
],
|
||||
});
|
||||
(this._panel as any).iconPath = {
|
||||
light: vscode.Uri.file(path.join(this._extensionPath, "resources", "burndown_light.svg")),
|
||||
dark: vscode.Uri.file(path.join(this._extensionPath, "resources", "burndown_dark.svg")),
|
||||
light: Uri.file(join(this._extensionPath, "resources", "burndown_light.svg")),
|
||||
dark: Uri.file(join(this._extensionPath, "resources", "burndown_dark.svg")),
|
||||
};
|
||||
|
||||
// Set the webview's title to the kanbn project name
|
||||
@ -126,7 +126,7 @@ export default class KanbnBurndownPanel {
|
||||
|
||||
// Display error message
|
||||
case "error":
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
window.showErrorMessage(message.text);
|
||||
return;
|
||||
|
||||
// Refresh the kanbn chart
|
||||
@ -158,20 +158,20 @@ export default class KanbnBurndownPanel {
|
||||
}
|
||||
|
||||
private _getHtmlForWebview() {
|
||||
const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json"));
|
||||
const manifest = require(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({
|
||||
const scriptUri = Uri.file(join(this._extensionPath, "build", mainScript)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const styleUri = vscode.Uri.file(path.join(this._extensionPath, "build", mainStyle)).with({
|
||||
const styleUri = Uri.file(join(this._extensionPath, "build", mainStyle)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const customStyleUri = vscode.Uri.file(
|
||||
path.join(this._workspacePath, this._kanbnFolderName, "board.css")
|
||||
const customStyleUri = Uri.file(
|
||||
join(this._workspacePath, this._kanbnFolderName, "board.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
const codiconsUri = vscode.Uri.file(
|
||||
path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
const codiconsUri = Uri.file(
|
||||
join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
|
||||
// Use a nonce to whitelist which scripts can be run
|
||||
@ -188,7 +188,7 @@ export default class KanbnBurndownPanel {
|
||||
<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="${Uri.file(join(this._extensionPath, "build")).with({ scheme: "vscode-resource" })}/">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { status } from '@basementuniverse/kanbn/src/main';
|
||||
import * as vscode from 'vscode';
|
||||
import { StatusBarItem, ExtensionContext, window, StatusBarAlignment, workspace } from 'vscode';
|
||||
|
||||
export default class KanbnStatusBarItem {
|
||||
private readonly _statusBarItem: vscode.StatusBarItem;
|
||||
private readonly _statusBarItem: StatusBarItem;
|
||||
private readonly _kanbn: typeof import('@basementuniverse/kanbn/src/main');
|
||||
|
||||
constructor(
|
||||
context: vscode.ExtensionContext,
|
||||
context: ExtensionContext,
|
||||
kanbn: typeof import('@basementuniverse/kanbn/src/main')
|
||||
) {
|
||||
this._statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 0);
|
||||
this._statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left, 0);
|
||||
context.subscriptions.push(this._statusBarItem);
|
||||
this._kanbn = kanbn;
|
||||
}
|
||||
@ -28,7 +28,7 @@ export default class KanbnStatusBarItem {
|
||||
const text = [
|
||||
`$(project) ${status.tasks}`
|
||||
];
|
||||
let tooltip = [];
|
||||
let tooltip: any = [];
|
||||
if (status.tasks > 0) {
|
||||
tooltip = [
|
||||
`${status.tasks} task${status.tasks === 1 ? '' : 's'}`
|
||||
@ -52,7 +52,7 @@ export default class KanbnStatusBarItem {
|
||||
this._statusBarItem.text = '$(project)';
|
||||
this._statusBarItem.tooltip = 'Initialise Kanbn';
|
||||
this._statusBarItem.command = 'kanbn.init';
|
||||
if (vscode.workspace.getConfiguration('kanbn').get('showUninitialisedStatusBarItem')) {
|
||||
if (workspace.getConfiguration('kanbn').get('showUninitialisedStatusBarItem')) {
|
||||
this._statusBarItem.show();
|
||||
} else {
|
||||
this._statusBarItem.hide();
|
||||
|
@ -1,11 +1,11 @@
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
import { join } from "path";
|
||||
import { WebviewPanel, Disposable, window, ViewColumn, Uri, workspace, commands } from "vscode";
|
||||
import getNonce from "./getNonce";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
function transformTaskData(
|
||||
taskData: any,
|
||||
customFields: { name: string, type: 'boolean' | 'date' | 'number' | 'string'}[]
|
||||
customFields: { name: string, type: 'boolean' | 'date' | 'number' | 'string' }[]
|
||||
) {
|
||||
const result = {
|
||||
id: taskData.id,
|
||||
@ -71,7 +71,7 @@ export default class KanbnTaskPanel {
|
||||
private static readonly viewType = "react";
|
||||
private static panels: Record<string, KanbnTaskPanel> = {};
|
||||
|
||||
private readonly _panel: vscode.WebviewPanel;
|
||||
private readonly _panel: WebviewPanel;
|
||||
private readonly _extensionPath: string;
|
||||
private readonly _workspacePath: string;
|
||||
private readonly _kanbn: typeof import("@basementuniverse/kanbn/src/main");
|
||||
@ -79,7 +79,7 @@ export default class KanbnTaskPanel {
|
||||
private readonly _panelUuid: string;
|
||||
private _taskId: string | null;
|
||||
private _columnName: string | null;
|
||||
private _disposables: vscode.Disposable[] = [];
|
||||
private _disposables: Disposable[] = [];
|
||||
|
||||
public static async show(
|
||||
extensionPath: string,
|
||||
@ -89,14 +89,14 @@ export default class KanbnTaskPanel {
|
||||
taskId: string | null,
|
||||
columnName: string | null
|
||||
) {
|
||||
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
||||
const column = window.activeTextEditor ? window.activeTextEditor.viewColumn : undefined;
|
||||
|
||||
// Create a new panel
|
||||
const panelUuid = uuidv4();
|
||||
const taskPanel = new KanbnTaskPanel(
|
||||
extensionPath,
|
||||
workspacePath,
|
||||
column || vscode.ViewColumn.One,
|
||||
column || ViewColumn.One,
|
||||
kanbn,
|
||||
kanbnFolderName,
|
||||
taskId,
|
||||
@ -110,7 +110,7 @@ export default class KanbnTaskPanel {
|
||||
private constructor(
|
||||
extensionPath: string,
|
||||
workspacePath: string,
|
||||
column: vscode.ViewColumn,
|
||||
column: ViewColumn,
|
||||
kanbn: typeof import("@basementuniverse/kanbn/src/main"),
|
||||
kanbnFolderName: string,
|
||||
taskId: string | null,
|
||||
@ -126,7 +126,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 = window.createWebviewPanel(KanbnTaskPanel.viewType, "New task", column, {
|
||||
// Enable javascript in the webview
|
||||
enableScripts: true,
|
||||
|
||||
@ -135,14 +135,14 @@ 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._workspacePath, this._kanbnFolderName)),
|
||||
vscode.Uri.file(path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist")),
|
||||
Uri.file(join(this._extensionPath, "build")),
|
||||
Uri.file(join(this._workspacePath, this._kanbnFolderName)),
|
||||
Uri.file(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: Uri.file(join(this._extensionPath, "resources", "task_light.svg")),
|
||||
dark: Uri.file(join(this._extensionPath, "resources", "task_dark.svg")),
|
||||
};
|
||||
|
||||
// Set the webview's title to the kanbn task name
|
||||
@ -166,7 +166,7 @@ export default class KanbnTaskPanel {
|
||||
|
||||
// Display error message
|
||||
case "error":
|
||||
vscode.window.showErrorMessage(message.text);
|
||||
window.showErrorMessage(message.text);
|
||||
return;
|
||||
|
||||
// Update the task webview panel title
|
||||
@ -183,8 +183,8 @@ export default class KanbnTaskPanel {
|
||||
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}'.`);
|
||||
if (workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
window.showInformationMessage(`Created task '${message.taskData.name}'.`);
|
||||
}
|
||||
return;
|
||||
|
||||
@ -198,34 +198,42 @@ export default class KanbnTaskPanel {
|
||||
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}'.`);
|
||||
if (workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
window.showInformationMessage(`Updated task '${message.taskData.name}'.`);
|
||||
}
|
||||
return;
|
||||
|
||||
// Delete a task and close the webview panel
|
||||
case "kanbn.delete":
|
||||
vscode.window
|
||||
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}'.`);
|
||||
if (workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
window.showInformationMessage(`Deleted task '${message.taskData.name}'.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
|
||||
// Go to raw task and close the webview panel
|
||||
case "kanbn.goToRaw":
|
||||
KanbnTaskPanel.panels[message.panelUuid].dispose();
|
||||
delete KanbnTaskPanel.panels[message.panelUuid];
|
||||
let uri = Uri.file(join(this._workspacePath, ".kanbn", "tasks", message.taskId + ".md"));
|
||||
await commands.executeCommand('vscode.open', uri);
|
||||
return;
|
||||
|
||||
// Archive a task and close the webview panel
|
||||
case 'kanbn.archive':
|
||||
await this._kanbn.archiveTask(message.taskId);
|
||||
KanbnTaskPanel.panels[message.panelUuid].dispose();
|
||||
delete KanbnTaskPanel.panels[message.panelUuid];
|
||||
if (vscode.workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
vscode.window.showInformationMessage(`Archived task '${message.taskData.name}'.`);
|
||||
if (workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
window.showInformationMessage(`Archived task '${message.taskData.name}'.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -250,7 +258,7 @@ export default class KanbnTaskPanel {
|
||||
try {
|
||||
index = await this._kanbn.getIndex();
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
let tasks: any[];
|
||||
@ -260,7 +268,7 @@ export default class KanbnTaskPanel {
|
||||
...this._kanbn.hydrateTask(index, task),
|
||||
}));
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||
return;
|
||||
}
|
||||
let task = null;
|
||||
@ -287,20 +295,20 @@ export default class KanbnTaskPanel {
|
||||
}
|
||||
|
||||
private _getHtmlForWebview() {
|
||||
const manifest = require(path.join(this._extensionPath, "build", "asset-manifest.json"));
|
||||
const manifest = require(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({
|
||||
const scriptUri = Uri.file(join(this._extensionPath, "build", mainScript)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const styleUri = vscode.Uri.file(path.join(this._extensionPath, "build", mainStyle)).with({
|
||||
const styleUri = Uri.file(join(this._extensionPath, "build", mainStyle)).with({
|
||||
scheme: "vscode-resource",
|
||||
});
|
||||
const customStyleUri = vscode.Uri.file(
|
||||
path.join(this._workspacePath, this._kanbnFolderName, "board.css")
|
||||
const customStyleUri = Uri.file(
|
||||
join(this._workspacePath, this._kanbnFolderName, "board.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
const codiconsUri = vscode.Uri.file(
|
||||
path.join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
const codiconsUri = Uri.file(
|
||||
join(this._extensionPath, "node_modules", "vscode-codicons", "dist", "codicon.css")
|
||||
).with({ scheme: "vscode-resource" });
|
||||
|
||||
// Use a nonce to whitelist which scripts can be run
|
||||
@ -317,7 +325,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="${Uri.file(join(this._extensionPath, "build")).with({ scheme: "vscode-resource" })}/">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as vscode from "vscode";
|
||||
import { ExtensionContext, commands, workspace, window, RelativePattern } from "vscode";
|
||||
import KanbnStatusBarItem from "./KanbnStatusBarItem";
|
||||
import KanbnBoardPanel from "./KanbnBoardPanel";
|
||||
import KanbnBurndownPanel from "./KanbnBurndownPanel";
|
||||
@ -6,19 +6,19 @@ import KanbnTaskPanel from "./KanbnTaskPanel";
|
||||
|
||||
let kanbnStatusBarItem: KanbnStatusBarItem;
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
export async function activate(context: 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 () => {
|
||||
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.");
|
||||
if (workspace.workspaceFolders === undefined) {
|
||||
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);
|
||||
process.chdir(workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// If kanbn is already initialised, get the project name
|
||||
@ -28,7 +28,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
// Prompt for a new project name
|
||||
const newProjectName = await vscode.window.showInputBox({
|
||||
const newProjectName = await window.showInputBox({
|
||||
value: projectName,
|
||||
placeHolder: "The project name.",
|
||||
validateInput: (text) => {
|
||||
@ -41,7 +41,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
await kanbn.initialise({
|
||||
name: newProjectName,
|
||||
});
|
||||
vscode.window.showInformationMessage(`Initialised Kanbn project '${newProjectName}'.`);
|
||||
window.showInformationMessage(`Initialised Kanbn project '${newProjectName}'.`);
|
||||
KanbnBoardPanel.update();
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
@ -51,28 +51,28 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
// 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 () => {
|
||||
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.");
|
||||
if (workspace.workspaceFolders === undefined) {
|
||||
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);
|
||||
process.chdir(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,
|
||||
workspace.workspaceFolders[0].uri.fsPath,
|
||||
kanbn,
|
||||
await kanbn.getFolderName()
|
||||
);
|
||||
KanbnBoardPanel.update();
|
||||
} else {
|
||||
vscode.window.showErrorMessage("You need to initialise Kanbn before viewing the Kanbn board.");
|
||||
window.showErrorMessage("You need to initialise Kanbn before viewing the Kanbn board.");
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
})
|
||||
@ -80,57 +80,57 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
// Register a command to add a new kanbn task.
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kanbn.addTask", async () => {
|
||||
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.");
|
||||
if (workspace.workspaceFolders === undefined) {
|
||||
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);
|
||||
process.chdir(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,
|
||||
workspace.workspaceFolders[0].uri.fsPath,
|
||||
kanbn,
|
||||
await kanbn.getFolderName(),
|
||||
null,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
vscode.window.showErrorMessage("You need to initialise Kanbn before adding a new task.");
|
||||
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 () => {
|
||||
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.");
|
||||
if (workspace.workspaceFolders === undefined) {
|
||||
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);
|
||||
process.chdir(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,
|
||||
workspace.workspaceFolders[0].uri.fsPath,
|
||||
kanbn,
|
||||
await kanbn.getFolderName()
|
||||
);
|
||||
KanbnBurndownPanel.update();
|
||||
} else {
|
||||
vscode.window.showErrorMessage("You need to initialise Kanbn before viewing the burndown chart.");
|
||||
window.showErrorMessage("You need to initialise Kanbn before viewing the burndown chart.");
|
||||
}
|
||||
kanbnStatusBarItem.update();
|
||||
})
|
||||
@ -138,15 +138,15 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
// Register a command to archive tasks.
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kanbn.archiveTasks", async () => {
|
||||
commands.registerCommand("kanbn.archiveTasks", async () => {
|
||||
// If no workspace folder is opened, we can't archive tasks
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage("You need to open a workspace before sending tasks to the archive.");
|
||||
if (workspace.workspaceFolders === undefined) {
|
||||
window.showErrorMessage("You need to open a workspace before sending tasks to the archive.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
process.chdir(workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// Get a list of tracked tasks
|
||||
@ -155,12 +155,12 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
tasks = [...(await kanbn.findTrackedTasks())];
|
||||
} catch (e) {}
|
||||
if (tasks.length === 0) {
|
||||
vscode.window.showInformationMessage("There are no tasks to archive.");
|
||||
window.showInformationMessage("There are no tasks to archive.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Prompt for a selection of tasks to archive
|
||||
const archiveTaskIds = await vscode.window.showQuickPick(
|
||||
const archiveTaskIds = await window.showQuickPick(
|
||||
tasks,
|
||||
{
|
||||
placeHolder: 'Select tasks to archive...',
|
||||
@ -173,8 +173,8 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
KanbnBoardPanel.update();
|
||||
kanbnStatusBarItem.update();
|
||||
if (vscode.workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
vscode.window.showInformationMessage(
|
||||
if (workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
window.showInformationMessage(
|
||||
`Archived ${archiveTaskIds.length} task${archiveTaskIds.length === 1 ? '' : 's'}.`
|
||||
);
|
||||
}
|
||||
@ -184,15 +184,15 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
// Register a command to restore a task from the archive.
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kanbn.restoreTasks", async () => {
|
||||
commands.registerCommand("kanbn.restoreTasks", async () => {
|
||||
// If no workspace folder is opened, we can't restore tasks from the archive
|
||||
if (vscode.workspace.workspaceFolders === undefined) {
|
||||
vscode.window.showErrorMessage("You need to open a workspace before restoring tasks from the archive.");
|
||||
if (workspace.workspaceFolders === undefined) {
|
||||
window.showErrorMessage("You need to open a workspace before restoring tasks from the archive.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
process.chdir(workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// Get a list of archived tasks
|
||||
@ -201,12 +201,12 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
archivedTasks = await kanbn.listArchivedTasks();
|
||||
} catch (e) {}
|
||||
if (archivedTasks.length === 0) {
|
||||
vscode.window.showInformationMessage("There are no archived tasks to restore.");
|
||||
window.showInformationMessage("There are no archived tasks to restore.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Prompt for a selection of tasks to restore
|
||||
const restoreTaskIds = await vscode.window.showQuickPick(
|
||||
const restoreTaskIds = await window.showQuickPick(
|
||||
archivedTasks,
|
||||
{
|
||||
placeHolder: 'Select tasks to restore...',
|
||||
@ -219,7 +219,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
const index = await kanbn.getIndex();
|
||||
|
||||
// Prompt for a column to restore the tasks into
|
||||
const restoreColumn = await vscode.window.showQuickPick(
|
||||
const restoreColumn = await window.showQuickPick(
|
||||
[
|
||||
'None (use original)',
|
||||
...Object.keys(index.columns)
|
||||
@ -234,8 +234,8 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
KanbnBoardPanel.update();
|
||||
kanbnStatusBarItem.update();
|
||||
if (vscode.workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
vscode.window.showInformationMessage(
|
||||
if (workspace.getConfiguration("kanbn").get("showTaskNotifications")) {
|
||||
window.showInformationMessage(
|
||||
`Restored ${restoreTaskIds.length} task${restoreTaskIds.length === 1 ? '' : 's'}.`
|
||||
);
|
||||
}
|
||||
@ -245,9 +245,9 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
);
|
||||
|
||||
// If a workspace folder is open, add a status bar item and start watching for file changes
|
||||
if (vscode.workspace.workspaceFolders !== undefined) {
|
||||
if (workspace.workspaceFolders !== undefined) {
|
||||
// Set the node process directory and import kanbn
|
||||
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
|
||||
process.chdir(workspace.workspaceFolders[0].uri.fsPath);
|
||||
const kanbn = await import("@basementuniverse/kanbn/src/main");
|
||||
|
||||
// Create status bar item
|
||||
@ -256,10 +256,10 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
KanbnBoardPanel.update();
|
||||
|
||||
// Initialise file watcher
|
||||
const uri = vscode.workspace.workspaceFolders[0].uri.fsPath;
|
||||
const uri = workspace.workspaceFolders[0].uri.fsPath;
|
||||
const kanbnFolderName = await kanbn.getFolderName();
|
||||
const fileWatcher = vscode.workspace.createFileSystemWatcher(
|
||||
new vscode.RelativePattern(uri, `${kanbnFolderName}/**.*`)
|
||||
const fileWatcher = workspace.createFileSystemWatcher(
|
||||
new RelativePattern(uri, `${kanbnFolderName}/**/*.md`)
|
||||
);
|
||||
fileWatcher.onDidChange(() => {
|
||||
kanbnStatusBarItem.update();
|
||||
@ -269,7 +269,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
// Handle configuration changes
|
||||
vscode.workspace.onDidChangeConfiguration((e) => {
|
||||
workspace.onDidChangeConfiguration((e) => {
|
||||
kanbnStatusBarItem.update();
|
||||
KanbnBoardPanel.update();
|
||||
});
|
||||
|
Reference in New Issue
Block a user