Bugfixes
This commit is contained in:
parent
63bf065331
commit
a26d1ba7c0
@ -2,16 +2,69 @@ import * as path from 'path';
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
function transformTaskData(taskData: any) {
|
||||||
|
const result = {
|
||||||
|
id: taskData.id,
|
||||||
|
name: taskData.name,
|
||||||
|
description: taskData.description,
|
||||||
|
metadata: {
|
||||||
|
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
|
||||||
|
} 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
|
||||||
|
}))
|
||||||
|
} as any;
|
||||||
|
|
||||||
|
// Add assigned
|
||||||
|
if (taskData.metadata.assigned) {
|
||||||
|
result.metadata['assigned'] = taskData.metadata.assigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add progress
|
||||||
|
if (taskData.progress > 0) {
|
||||||
|
result.metadata['progress'] = taskData.progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add tags
|
||||||
|
if (taskData.metadata.tags.length) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
if (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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export default class KanbnTaskPanel {
|
export default class KanbnTaskPanel {
|
||||||
private static readonly viewType = 'react';
|
private static readonly viewType = 'react';
|
||||||
private static panels: KanbnTaskPanel[] = [];
|
private static panels: Record<string, KanbnTaskPanel> = {};
|
||||||
|
|
||||||
private readonly _panel: vscode.WebviewPanel;
|
private readonly _panel: vscode.WebviewPanel;
|
||||||
private readonly _extensionPath: string;
|
private readonly _extensionPath: string;
|
||||||
private readonly _workspacePath: string;
|
private readonly _workspacePath: string;
|
||||||
private readonly _kanbn: typeof import('@basementuniverse/kanbn/src/main');
|
private readonly _kanbn: typeof import('@basementuniverse/kanbn/src/main');
|
||||||
private readonly _taskId: string|null;
|
private _taskId: string|null;
|
||||||
private readonly _columnName: string;
|
private _columnName: string|null;
|
||||||
|
private readonly _panelUuid: string;
|
||||||
private _disposables: vscode.Disposable[] = [];
|
private _disposables: vscode.Disposable[] = [];
|
||||||
|
|
||||||
public static async show(
|
public static async show(
|
||||||
@ -22,55 +75,20 @@ export default class KanbnTaskPanel {
|
|||||||
columnName: string|null
|
columnName: string|null
|
||||||
) {
|
) {
|
||||||
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
|
||||||
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 => ({
|
|
||||||
uuid: uuidv4(),
|
|
||||||
...kanbn.hydrateTask(index, task)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let task = null;
|
|
||||||
if (taskId) {
|
|
||||||
task = tasks.find(t => t.id === taskId) ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no columnName is specified, use the first column
|
|
||||||
if (!columnName) {
|
|
||||||
columnName = Object.keys(index.columns)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new panel
|
// Create a new panel
|
||||||
|
const panelUuid = uuidv4();
|
||||||
const taskPanel = new KanbnTaskPanel(
|
const taskPanel = new KanbnTaskPanel(
|
||||||
extensionPath,
|
extensionPath,
|
||||||
workspacePath,
|
workspacePath,
|
||||||
column || vscode.ViewColumn.One,
|
column || vscode.ViewColumn.One,
|
||||||
kanbn,
|
kanbn,
|
||||||
taskId,
|
taskId,
|
||||||
columnName
|
columnName,
|
||||||
|
panelUuid
|
||||||
);
|
);
|
||||||
KanbnTaskPanel.panels.push(taskPanel);
|
KanbnTaskPanel.panels[panelUuid] = taskPanel;
|
||||||
|
taskPanel.update();
|
||||||
// Send task data to the webview
|
|
||||||
taskPanel._panel.webview.postMessage({
|
|
||||||
type: 'task',
|
|
||||||
index,
|
|
||||||
task,
|
|
||||||
columnName: taskPanel._columnName,
|
|
||||||
tasks,
|
|
||||||
dateFormat: kanbn.getDateFormat(index)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(
|
private constructor(
|
||||||
@ -79,13 +97,15 @@ export default class KanbnTaskPanel {
|
|||||||
column: vscode.ViewColumn,
|
column: vscode.ViewColumn,
|
||||||
kanbn: typeof import('@basementuniverse/kanbn/src/main'),
|
kanbn: typeof import('@basementuniverse/kanbn/src/main'),
|
||||||
taskId: string|null,
|
taskId: string|null,
|
||||||
columnName: string
|
columnName: string|null,
|
||||||
|
panelUuid: string
|
||||||
) {
|
) {
|
||||||
this._extensionPath = extensionPath;
|
this._extensionPath = extensionPath;
|
||||||
this._workspacePath = workspacePath;
|
this._workspacePath = workspacePath;
|
||||||
this._kanbn = kanbn;
|
this._kanbn = kanbn;
|
||||||
this._taskId = taskId;
|
this._taskId = taskId;
|
||||||
this._columnName = columnName;
|
this._columnName = columnName;
|
||||||
|
this._panelUuid = panelUuid;
|
||||||
|
|
||||||
// Create and show a new webview panel
|
// 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, {
|
||||||
@ -137,26 +157,31 @@ export default class KanbnTaskPanel {
|
|||||||
|
|
||||||
// Create a task
|
// Create a task
|
||||||
case 'kanbn.create':
|
case 'kanbn.create':
|
||||||
// TODO convert dates
|
await this._kanbn.createTask(transformTaskData(message.taskData), message.taskData.column);
|
||||||
// await this._kanbn.createTask(message.taskData, message.taskData.column);
|
KanbnTaskPanel.panels[message.panelUuid]._taskId = message.taskData.id;
|
||||||
vscode.window.showInformationMessage(`Created task ${message.taskData.name}.`);
|
KanbnTaskPanel.panels[message.panelUuid]._columnName = message.taskData.column;
|
||||||
|
KanbnTaskPanel.panels[message.panelUuid].update();
|
||||||
|
// vscode.window.showInformationMessage(`Created task '${message.taskData.name}'.`);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update a task
|
// Update a task
|
||||||
case 'kanbn.update':
|
case 'kanbn.update':
|
||||||
// TODO convert dates
|
await this._kanbn.updateTask(message.taskId, transformTaskData(message.taskData), message.taskData.column);
|
||||||
// await this._kanbn.updateTask(message.taskData.id, message.taskData, message.taskData.column);
|
KanbnTaskPanel.panels[message.panelUuid]._taskId = message.taskData.id;
|
||||||
vscode.window.showInformationMessage(`Updated task ${message.taskData.name}.`);
|
KanbnTaskPanel.panels[message.panelUuid]._columnName = message.taskData.column;
|
||||||
|
KanbnTaskPanel.panels[message.panelUuid].update();
|
||||||
|
// vscode.window.showInformationMessage(`Updated task '${message.taskData.name}'.`);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Delete a task
|
// Delete a task and close the webview panel
|
||||||
case 'kanbn.delete':
|
case 'kanbn.delete':
|
||||||
vscode.window.showInformationMessage(`Delete task ${message.taskData.name}?`, 'Yes', 'No').then(
|
vscode.window.showInformationMessage(`Delete task '${message.taskData.name}'?`, 'Yes', 'No').then(
|
||||||
async value => {
|
async value => {
|
||||||
if (value === 'Yes') {
|
if (value === 'Yes') {
|
||||||
// await this._kanbn.deleteTask(message.taskId, true);
|
await this._kanbn.deleteTask(message.taskId, true);
|
||||||
vscode.window.showInformationMessage(`Deleted task ${message.taskData.name}.`);
|
KanbnTaskPanel.panels[message.panelUuid].dispose();
|
||||||
// TODO close panel, will need to generate uuid for each panel
|
delete KanbnTaskPanel.panels[message.panelUuid];
|
||||||
|
// vscode.window.showInformationMessage(`Deleted task '${message.taskData.name}'.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -175,6 +200,48 @@ export default class KanbnTaskPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async update() {
|
||||||
|
let index: any;
|
||||||
|
try {
|
||||||
|
index = await this._kanbn.getIndex();
|
||||||
|
} catch (error) {
|
||||||
|
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let tasks: any[];
|
||||||
|
try {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no columnName is specified, use the first column
|
||||||
|
if (!this._columnName) {
|
||||||
|
this._columnName = Object.keys(index.columns)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send task data to the webview
|
||||||
|
this._panel.webview.postMessage({
|
||||||
|
type: 'task',
|
||||||
|
index,
|
||||||
|
task,
|
||||||
|
tasks,
|
||||||
|
columnName: this._columnName,
|
||||||
|
dateFormat: this._kanbn.getDateFormat(index),
|
||||||
|
panelUuid: this._panelUuid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
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'];
|
||||||
|
@ -42,9 +42,9 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||||||
name: newProjectName
|
name: newProjectName
|
||||||
});
|
});
|
||||||
vscode.window.showInformationMessage(`Initialised kanbn project '${newProjectName}'.`);
|
vscode.window.showInformationMessage(`Initialised kanbn project '${newProjectName}'.`);
|
||||||
kanbnStatusBarItem.update();
|
|
||||||
KanbnBoardPanel.update();
|
KanbnBoardPanel.update();
|
||||||
}
|
}
|
||||||
|
kanbnStatusBarItem.update();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Register a command to open the kanbn board. This command will be invoked when the status bar item is clicked
|
// Register a command to open the kanbn board. This command will be invoked when the status bar item is clicked
|
||||||
@ -72,6 +72,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||||||
} else {
|
} else {
|
||||||
vscode.window.showErrorMessage('You need to initialise kanbn before viewing the kanbn board.');
|
vscode.window.showErrorMessage('You need to initialise kanbn before viewing the kanbn board.');
|
||||||
}
|
}
|
||||||
|
kanbnStatusBarItem.update();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Register a command to add a new kanbn task.
|
// Register a command to add a new kanbn task.
|
||||||
|
@ -20,6 +20,7 @@ function App() {
|
|||||||
const [tasks, setTasks] = useState({});
|
const [tasks, setTasks] = useState({});
|
||||||
const [columnName, setColumnName] = useState('');
|
const [columnName, setColumnName] = useState('');
|
||||||
const [columnNames, setColumnNames] = useState([] as string[]);
|
const [columnNames, setColumnNames] = useState([] as string[]);
|
||||||
|
const [panelUuid, setPanelUuid] = useState('');
|
||||||
|
|
||||||
window.addEventListener('message', event => {
|
window.addEventListener('message', event => {
|
||||||
const tasks = Object.fromEntries(event.data.tasks.map(task => [task.id, task]));
|
const tasks = Object.fromEntries(event.data.tasks.map(task => [task.id, task]));
|
||||||
@ -42,6 +43,7 @@ function App() {
|
|||||||
setTasks(tasks);
|
setTasks(tasks);
|
||||||
setColumnName(event.data.columnName);
|
setColumnName(event.data.columnName);
|
||||||
setColumnNames(Object.keys(event.data.index.columns));
|
setColumnNames(Object.keys(event.data.index.columns));
|
||||||
|
setPanelUuid(event.data.panelUuid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setType(event.data.type);
|
setType(event.data.type);
|
||||||
@ -70,6 +72,7 @@ function App() {
|
|||||||
columnName={columnName}
|
columnName={columnName}
|
||||||
columnNames={columnNames}
|
columnNames={columnNames}
|
||||||
dateFormat={dateFormat}
|
dateFormat={dateFormat}
|
||||||
|
panelUuid={panelUuid}
|
||||||
vscode={vscode}
|
vscode={vscode}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -64,6 +64,7 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
|||||||
<div className="kanbn-task-row">
|
<div className="kanbn-task-row">
|
||||||
{
|
{
|
||||||
'tags' in task.metadata &&
|
'tags' in task.metadata &&
|
||||||
|
task.metadata.tags!.length > 0 &&
|
||||||
<div className="kanbn-task-data kanbn-task-tags">
|
<div className="kanbn-task-data kanbn-task-tags">
|
||||||
{task.metadata.tags!.map(tag => {
|
{task.metadata.tags!.map(tag => {
|
||||||
return (
|
return (
|
||||||
@ -81,6 +82,7 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
|||||||
<div className="kanbn-task-row">
|
<div className="kanbn-task-row">
|
||||||
{
|
{
|
||||||
'assigned' in task.metadata &&
|
'assigned' in task.metadata &&
|
||||||
|
!!task.metadata.assigned &&
|
||||||
<div className="kanbn-task-data kanbn-task-assigned">
|
<div className="kanbn-task-data kanbn-task-assigned">
|
||||||
<i className="codicon codicon-account"></i>{task.metadata.assigned}
|
<i className="codicon codicon-account"></i>{task.metadata.assigned}
|
||||||
</div>
|
</div>
|
||||||
|
@ -120,6 +120,7 @@ body {
|
|||||||
.kanbn-column-task-list {
|
.kanbn-column-task-list {
|
||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
border-left: 4px var(--vscode-activityBar-inactiveForeground) solid;
|
border-left: 4px var(--vscode-activityBar-inactiveForeground) solid;
|
||||||
|
min-height: 46px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.kanbn-column-task-list.drag-over {
|
.kanbn-column-task-list.drag-over {
|
||||||
@ -270,6 +271,11 @@ body {
|
|||||||
border-bottom: 1px var(--vscode-activityBar-inactiveForeground) solid;
|
border-bottom: 1px var(--vscode-activityBar-inactiveForeground) solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kanbn-task-editor-dirty {
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #f42;
|
||||||
|
}
|
||||||
|
|
||||||
.kanbn-task-editor-dates {
|
.kanbn-task-editor-dates {
|
||||||
font-size: var(--vscode-font-size);
|
font-size: var(--vscode-font-size);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user