Add filter field, fix validation

This commit is contained in:
Gordon 2021-04-07 00:07:35 +01:00
parent 7ea93c6290
commit 63bf065331
6 changed files with 195 additions and 116 deletions

View File

@ -137,21 +137,29 @@ export default class KanbnTaskPanel {
// Create a task
case 'kanbn.create':
// TODO create task
vscode.window.showInformationMessage('create task');
// TODO convert dates
// await this._kanbn.createTask(message.taskData, message.taskData.column);
vscode.window.showInformationMessage(`Created task ${message.taskData.name}.`);
return;
// Update a task
case 'kanbn.update':
// TODO update task
vscode.window.showInformationMessage('update task');
// TODO convert dates
// await this._kanbn.updateTask(message.taskData.id, message.taskData, message.taskData.column);
vscode.window.showInformationMessage(`Updated task ${message.taskData.name}.`);
return;
// Delete a task
case 'kanbn.delete':
// TODO delete task
// TODO add yes/no confirmation buttons to information message, then delete task and close task panel
vscode.window.showInformationMessage('delete task');
vscode.window.showInformationMessage(`Delete task ${message.taskData.name}?`, 'Yes', 'No').then(
async value => {
if (value === 'Yes') {
// await this._kanbn.deleteTask(message.taskId, true);
vscode.window.showInformationMessage(`Deleted task ${message.taskData.name}.`);
// TODO close panel, will need to generate uuid for each panel
}
}
);
return;
}
}, null, this._disposables);

View File

@ -1,4 +1,3 @@
import Header from './Header';
import Board from './Board';
import TaskEditor from './TaskEditor';
import React, { useState } from "react";
@ -53,19 +52,15 @@ function App() {
<React.Fragment>
{
type === 'index' &&
<React.Fragment>
<Header
<Board
name={name}
description={description}
/>
<Board
columns={columns}
startedColumns={startedColumns}
completedColumns={completedColumns}
dateFormat={dateFormat}
vscode={vscode}
/>
</React.Fragment>
}
{
type === 'task' &&

View File

@ -55,7 +55,9 @@ const onDragEnd = (result, columns, setColumns, vscode: VSCodeApi) => {
});
};
const Board = ({ columns, startedColumns, completedColumns, dateFormat, vscode }: {
const Board = ({ name, description, columns, startedColumns, completedColumns, dateFormat, vscode }: {
name: string,
description: string,
columns: Record<string, KanbnTask[]>,
startedColumns: string[],
completedColumns: string[],
@ -63,7 +65,34 @@ const Board = ({ columns, startedColumns, completedColumns, dateFormat, vscode }
vscode: VSCodeApi
}) => {
const [, setColumns] = useState(columns);
const filterTasks = () => {
console.log();
};
return (
<React.Fragment>
<div className="kanbn-header">
<h1 className="kanbn-header-name">
<p>{name}</p>
<div className="kanbn-filter">
<input
className="kanbn-filter-input"
placeholder="Filter tasks"
/>
<button
type="button"
className="kanbn-filter-button"
onClick={filterTasks}
>
<i className="codicon codicon-filter"></i>
</button>
</div>
</h1>
<p className="kanbn-header-description">
{description}
</p>
</div>
<div className="kanbn-board">
<DragDropContext
onDragEnd={result => onDragEnd(result, columns, setColumns, vscode)}
@ -131,6 +160,7 @@ const Board = ({ columns, startedColumns, completedColumns, dateFormat, vscode }
})}
</DragDropContext>
</div>
</React.Fragment>
);
};

View File

@ -1,14 +0,0 @@
import React from "react";
const Header = ({ name, description }: { name: string, description: string }) => {
return (
<div className="kanbn-header">
<h1 className="kanbn-header-name">{name}</h1>
<p className="kanbn-header-description">
{description}
</p>
</div>
);
}
export default Header;

View File

@ -46,11 +46,27 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
});
};
// Called when the form is submitted
const handleSubmit = values => {
if (editing) {
vscode.postMessage({
command: 'kanbn.update',
taskData: values
});
} else {
vscode.postMessage({
command: 'kanbn.create',
taskData: values
});
}
};
// Called when the delete task button is clicked
const handleRemoveTask = () => {
const handleRemoveTask = values => {
vscode.postMessage({
command: 'kanbn.delete',
taskId: task!.id
taskId: task!.id,
taskData: values
});
};
@ -94,7 +110,8 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
subTasks: task ? task.subTasks : [],
comments: task ? task.comments : []
}}
validate={(values: KanbnTaskValidationInput): KanbnTaskValidationOutput => {
validate={(values: KanbnTaskValidationInput): KanbnTaskValidationOutput|{} => {
let hasErrors = false;
const errors: KanbnTaskValidationOutput = {
name: '',
metadata: {
@ -107,17 +124,20 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
// Task name cannot be empty
if (!values.name) {
errors.name = 'Task name is required.';
hasErrors = true;
}
// Check if the id is already in use
if (values.id in tasks && tasks[values.id].uuid !== values.uuid) {
errors.name = 'There is already a task with the same name or id.';
hasErrors = true;
}
// Tag names cannot be empty
for (let i = 0; i < values.metadata.tags.length; i++) {
if (!values.metadata.tags[i]) {
errors.metadata.tags[i] = 'Tag cannot be empty.';
hasErrors = true;
}
}
@ -127,6 +147,7 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
errors.subTasks[i] = {
text: 'Sub-task text cannot be empty.'
};
hasErrors = true;
}
}
@ -136,22 +157,14 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
errors.comments[i] = {
text: 'Comment text cannot be empty.'
};
hasErrors = true;
}
}
return errors;
return hasErrors ? errors : {};
}}
onSubmit={(values, { setSubmitting }) => {
if (editing) {
vscode.postMessage({
command: 'kanbn.update'
});
} else {
vscode.postMessage({
command: 'kanbn.create'
});
}
console.log(values);
handleSubmit(values);
setSubmitting(false);
}}
>
@ -385,7 +398,9 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-delete"
title="Delete task"
onClick={handleRemoveTask}
onClick={() => {
handleRemoveTask(values);
}}
>
<i className="codicon codicon-trash"></i>Delete
</button>}

View File

@ -12,6 +12,51 @@ body {
margin-top: 0;
padding-bottom: 0.5em;
border-bottom: 1px var(--vscode-activityBar-inactiveForeground) solid;
display: flex;
}
.kanbn-header-name p {
display: inline-block;
flex: 1;
margin: 0;
padding: 4px 0;
}
.kanbn-filter {
flex: 1;
text-align: right;
}
.kanbn-filter-input {
box-sizing: border-box;
width: 80%;
padding: 8px;
background-color: var(--vscode-input-background);
color: var(--vscode-input-foreground);
border: 1px transparent solid;
}
.kanbn-filter-input:hover, .kanbn-filter-input:focus {
border-color: var(--vscode-input-border);
}
.kanbn-filter-button {
outline: none;
border: none;
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
padding: 9px 1em;
margin-left: 8px;
}
.kanbn-filter-button .codicon {
font-size: 11px !important;
position: relative;
top: 1px;
}
.kanbn-filter-button:hover, .kanbn-filter-button:focus {
background-color: var(--vscode-button-hoverBackground);
}
.kanbn-board {