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}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Formik, Form, Field, ErrorMessage, FieldArray } from 'formik';
|
import { Formik, Form, Field, ErrorMessage, FieldArray } from 'formik';
|
||||||
import formatDate from 'dateformat';
|
import formatDate from 'dateformat';
|
||||||
import VSCodeApi from './VSCodeApi';
|
import VSCodeApi from './VSCodeApi';
|
||||||
@ -19,19 +19,38 @@ interface KanbnTaskValidationOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface KanbnTaskValidationInput extends KanbnTaskValidationOutput {
|
interface KanbnTaskValidationInput extends KanbnTaskValidationOutput {
|
||||||
uuid: string,
|
|
||||||
id: string
|
id: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }: {
|
const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, panelUuid, vscode }: {
|
||||||
task: KanbnTask|null,
|
task: KanbnTask|null,
|
||||||
tasks: Record<string, KanbnTask>,
|
tasks: Record<string, KanbnTask>,
|
||||||
columnName: string,
|
columnName: string,
|
||||||
columnNames: string[],
|
columnNames: string[],
|
||||||
dateFormat: string,
|
dateFormat: string,
|
||||||
|
panelUuid: string,
|
||||||
vscode: VSCodeApi
|
vscode: VSCodeApi
|
||||||
}) => {
|
}) => {
|
||||||
const editing = task !== null;
|
const editing = task !== null;
|
||||||
|
const [taskData, setTaskData] = useState({
|
||||||
|
id: task ? task.id : '',
|
||||||
|
name: task ? task.name : '',
|
||||||
|
description: task ? task.description : '',
|
||||||
|
column: columnName,
|
||||||
|
progress: task ? task.progress : 0,
|
||||||
|
metadata: {
|
||||||
|
created: (task && 'created' in task.metadata) ? task.metadata.created : new Date(),
|
||||||
|
updated: (task && 'updated' in task.metadata) ? task.metadata.updated : null,
|
||||||
|
started: (task && 'started' in task.metadata) ? formatDate(task.metadata.started!, 'yyyy-mm-dd') : '',
|
||||||
|
due: (task && 'due' in task.metadata) ? formatDate(task.metadata.due!, 'yyyy-mm-dd') : '',
|
||||||
|
completed: (task && 'completed' in task.metadata) ? formatDate(task.metadata.completed!, 'yyyy-mm-dd') : '',
|
||||||
|
assigned: (task && 'assigned' in task.metadata) ? task.metadata.assigned : (gitUsername() || ''),
|
||||||
|
tags: (task && 'tags' in task.metadata) ? (task.metadata.tags || []) : []
|
||||||
|
},
|
||||||
|
relations: task ? task.relations : [],
|
||||||
|
subTasks: task ? task.subTasks : [],
|
||||||
|
comments: task ? task.comments : []
|
||||||
|
});
|
||||||
|
|
||||||
// Called when the name field is changed
|
// Called when the name field is changed
|
||||||
const handleUpdateName = ({ target: { value }}, values) => {
|
const handleUpdateName = ({ target: { value }}, values) => {
|
||||||
@ -47,18 +66,24 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Called when the form is submitted
|
// Called when the form is submitted
|
||||||
const handleSubmit = values => {
|
const handleSubmit = (values, setSubmitting, resetForm) => {
|
||||||
if (editing) {
|
if (editing) {
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
command: 'kanbn.update',
|
command: 'kanbn.update',
|
||||||
taskData: values
|
taskId: task!.id,
|
||||||
|
taskData: values,
|
||||||
|
panelUuid
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
command: 'kanbn.create',
|
command: 'kanbn.create',
|
||||||
taskData: values
|
taskData: values,
|
||||||
|
panelUuid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
setTaskData(values);
|
||||||
|
resetForm({ values });
|
||||||
|
setSubmitting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Called when the delete task button is clicked
|
// Called when the delete task button is clicked
|
||||||
@ -66,7 +91,8 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
|
|||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
command: 'kanbn.delete',
|
command: 'kanbn.delete',
|
||||||
taskId: task!.id,
|
taskId: task!.id,
|
||||||
taskData: values
|
taskData: values,
|
||||||
|
panelUuid
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,39 +104,8 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
// Validate form data
|
||||||
<div className="kanbn-task-editor">
|
const validate = (values: KanbnTaskValidationInput): KanbnTaskValidationOutput|{} => {
|
||||||
<h1 className="kanbn-task-editor-title">
|
|
||||||
{editing ? 'Update task' : 'Create new task'}
|
|
||||||
{editing && <span className="kanbn-task-editor-dates">
|
|
||||||
{
|
|
||||||
[
|
|
||||||
'created' in task!.metadata ? `Created ${formatDate(task!.metadata.created, dateFormat)}` : null,
|
|
||||||
'updated' in task!.metadata ? `Updated ${formatDate(task!.metadata.updated, dateFormat)}` : null
|
|
||||||
].filter(i => i).join(', ')
|
|
||||||
}
|
|
||||||
</span>}
|
|
||||||
</h1>
|
|
||||||
<Formik
|
|
||||||
initialValues={{
|
|
||||||
uuid: task ? (task.uuid || '') : '',
|
|
||||||
id: task ? task.id : '',
|
|
||||||
name: task ? task.name : '',
|
|
||||||
description: task ? task.description : '',
|
|
||||||
column: columnName,
|
|
||||||
progress: task ? task.progress : 0,
|
|
||||||
metadata: {
|
|
||||||
started: (task && 'started' in task.metadata) ? formatDate(task.metadata.started!, 'yyyy-mm-dd') : '',
|
|
||||||
due: (task && 'due' in task.metadata) ? formatDate(task.metadata.due!, 'yyyy-mm-dd') : '',
|
|
||||||
completed: (task && 'completed' in task.metadata) ? formatDate(task.metadata.completed!, 'yyyy-mm-dd') : '',
|
|
||||||
assigned: (task && 'assigned' in task.metadata) ? task.metadata.assigned : (gitUsername() || ''),
|
|
||||||
tags: (task && 'tags' in task.metadata) ? (task.metadata.tags || []) : []
|
|
||||||
},
|
|
||||||
relations: task ? task.relations : [],
|
|
||||||
subTasks: task ? task.subTasks : [],
|
|
||||||
comments: task ? task.comments : []
|
|
||||||
}}
|
|
||||||
validate={(values: KanbnTaskValidationInput): KanbnTaskValidationOutput|{} => {
|
|
||||||
let hasErrors = false;
|
let hasErrors = false;
|
||||||
const errors: KanbnTaskValidationOutput = {
|
const errors: KanbnTaskValidationOutput = {
|
||||||
name: '',
|
name: '',
|
||||||
@ -128,7 +123,7 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the id is already in use
|
// Check if the id is already in use
|
||||||
if (values.id in tasks && tasks[values.id].uuid !== values.uuid) {
|
if (values.id in tasks && tasks[values.id].uuid !== (task ? task.uuid : '')) {
|
||||||
errors.name = 'There is already a task with the same name or id.';
|
errors.name = 'There is already a task with the same name or id.';
|
||||||
hasErrors = true;
|
hasErrors = true;
|
||||||
}
|
}
|
||||||
@ -162,17 +157,36 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
|
|||||||
}
|
}
|
||||||
|
|
||||||
return hasErrors ? errors : {};
|
return hasErrors ? errors : {};
|
||||||
}}
|
};
|
||||||
onSubmit={(values, { setSubmitting }) => {
|
|
||||||
handleSubmit(values);
|
return (
|
||||||
setSubmitting(false);
|
<div className="kanbn-task-editor">
|
||||||
|
<Formik
|
||||||
|
initialValues={taskData}
|
||||||
|
validate={validate}
|
||||||
|
onSubmit={(values, { setSubmitting, resetForm }) => {
|
||||||
|
handleSubmit(values, setSubmitting, resetForm);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({
|
{({
|
||||||
|
dirty,
|
||||||
values,
|
values,
|
||||||
handleChange,
|
handleChange,
|
||||||
isSubmitting
|
isSubmitting
|
||||||
}) => (
|
}) => (
|
||||||
|
<React.Fragment>
|
||||||
|
<h1 className="kanbn-task-editor-title">
|
||||||
|
{editing ? 'Update task' : 'Create new task'}
|
||||||
|
{dirty && <span className="kanbn-task-editor-dirty">*</span>}
|
||||||
|
{editing && <span className="kanbn-task-editor-dates">
|
||||||
|
{
|
||||||
|
[
|
||||||
|
'created' in task!.metadata ? `Created ${formatDate(task!.metadata.created, dateFormat)}` : null,
|
||||||
|
'updated' in task!.metadata ? `Updated ${formatDate(task!.metadata.updated, dateFormat)}` : null
|
||||||
|
].filter(i => i).join(', ')
|
||||||
|
}
|
||||||
|
</span>}
|
||||||
|
</h1>
|
||||||
<Form>
|
<Form>
|
||||||
<div className="kanbn-task-editor-form">
|
<div className="kanbn-task-editor-form">
|
||||||
<div className="kanbn-task-editor-column-left">
|
<div className="kanbn-task-editor-column-left">
|
||||||
@ -573,6 +587,7 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
</Formik>
|
</Formik>
|
||||||
</div>
|
</div>
|
||||||
|
@ -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