Comments editor

This commit is contained in:
Gordon 2021-04-06 22:00:56 +01:00
parent d889148e56
commit 7ea93c6290
7 changed files with 335 additions and 81 deletions

View File

@ -7,5 +7,6 @@
"out": true // set this to false to include "out" folder in search results "out": true // set this to false to include "out" folder in search results
}, },
"typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version "typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version
"typescript.tsc.autoDetect": "off" // Turn off tsc task auto detection since we have the necessary task as npm scripts "typescript.tsc.autoDetect": "off",
"todo-tree.tree.scanMode": "workspace only" // Turn off tsc task auto detection since we have the necessary task as npm scripts
} }

View File

@ -102,6 +102,10 @@ export default class KanbnTaskPanel {
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.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'))
};
// Set the webview's title to the kanbn task name // Set the webview's title to the kanbn task name
if (this._taskId !== null) { if (this._taskId !== null) {

View File

@ -91,13 +91,13 @@ const Board = ({ columns, startedColumns, completedColumns, dateFormat, vscode }
<button <button
type="button" type="button"
className="kanbn-create-task-button" className="kanbn-create-task-button"
title={`Create task in ${columnName}`}
onClick={() => { onClick={() => {
vscode.postMessage({ vscode.postMessage({
command: 'kanbn.addTask', command: 'kanbn.addTask',
columnName columnName
}) })
}} }}
title={`Create task in ${columnName}`}
> >
<i className="codicon codicon-add"></i> <i className="codicon codicon-add"></i>
</button> </button>

3
src/KanbnTask.d.ts vendored
View File

@ -1,3 +1,4 @@
// Note that Date properties will be converted to strings (ISO) when a task is serialized and passed as a prop
declare type KanbnTask = { declare type KanbnTask = {
uuid?: string, uuid?: string,
id: string, id: string,
@ -8,7 +9,7 @@ declare type KanbnTask = {
remainingWorkload?: number, remainingWorkload?: number,
progress?: number, progress?: number,
metadata: { metadata: {
created: string, created?: string,
updated?: string, updated?: string,
started?: string, started?: string,
due?: string, due?: string,

View File

@ -5,6 +5,24 @@ import VSCodeApi from './VSCodeApi';
import { paramCase } from 'param-case'; import { paramCase } from 'param-case';
import gitUsername from 'git-user-name'; import gitUsername from 'git-user-name';
interface KanbnTaskValidationOutput {
name: string,
metadata: {
tags: string[]
},
subTasks: Array<{
text: string
}>,
comments: Array<{
text: string
}>
}
interface KanbnTaskValidationInput extends KanbnTaskValidationOutput {
uuid: string,
id: string
}
const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }: { const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }: {
task: KanbnTask|null, task: KanbnTask|null,
tasks: Record<string, KanbnTask>, tasks: Record<string, KanbnTask>,
@ -36,35 +54,55 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
}); });
}; };
// TODO progress bar below progress input // Check if a task's due date is in the past
// TODO auto-colour tags while typing const checkOverdue = (values: { metadata: { due?: string } }) => {
// TODO comments if ('due' in values.metadata && values.metadata.due !== undefined) {
// TODO make sure all buttons have title attributes, maybe remove labels from array delete buttons? return Date.parse(values.metadata.due) < (new Date()).getTime();
}
return false;
};
return ( return (
<div className="kanbn-task-editor"> <div className="kanbn-task-editor">
<h1 className="kanbn-task-editor-title">{editing ? 'Update task' : 'Create new task'}</h1> <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 <Formik
initialValues={{ initialValues={{
uuid: task ? task.uuid : '', uuid: task ? (task.uuid || '') : '',
id: task ? task.id : '', id: task ? task.id : '',
name: task ? task.name : '', name: task ? task.name : '',
description: task ? task.description : '', description: task ? task.description : '',
column: columnName, column: columnName,
progress: task ? task.progress : 0, progress: task ? task.progress : 0,
metadata: { metadata: {
due: (task && 'due' in task.metadata) ? formatDate(new Date(task.metadata.due!), 'yyyy-mm-dd') : '', 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() || ''), assigned: (task && 'assigned' in task.metadata) ? task.metadata.assigned : (gitUsername() || ''),
tags: (task && 'tags' in task.metadata) ? task.metadata.tags : [] tags: (task && 'tags' in task.metadata) ? (task.metadata.tags || []) : []
}, },
relations: task ? task.relations : [], relations: task ? task.relations : [],
subTasks: task ? task.subTasks : [], subTasks: task ? task.subTasks : [],
comments: task ? task.comments : [] comments: task ? task.comments : []
}} }}
validate={values => { validate={(values: KanbnTaskValidationInput): KanbnTaskValidationOutput => {
const errors: { name?: string } = {}; const errors: KanbnTaskValidationOutput = {
name: '',
// TODO validation metadata: {
tags: []
},
subTasks: [],
comments: []
};
// Task name cannot be empty // Task name cannot be empty
if (!values.name) { if (!values.name) {
@ -75,6 +113,32 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
if (values.id in tasks && tasks[values.id].uuid !== values.uuid) { if (values.id in tasks && tasks[values.id].uuid !== values.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.';
} }
// 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.';
}
}
// Sub-tasks text cannot be empty
for (let i = 0; i < values.subTasks.length; i++) {
if (!values.subTasks[i].text) {
errors.subTasks[i] = {
text: 'Sub-task text cannot be empty.'
};
}
}
// Comments text cannot be empty
for (let i = 0; i < values.comments.length; i++) {
if (!values.comments[i].text) {
errors.comments[i] = {
text: 'Comment text cannot be empty.'
};
}
}
return errors; return errors;
}} }}
onSubmit={(values, { setSubmitting }) => { onSubmit={(values, { setSubmitting }) => {
@ -134,6 +198,63 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
name="description" name="description"
/> />
</div> </div>
<div className="kanbn-task-editor-field kanbn-task-editor-field-subtasks">
<h2 className="kanbn-task-editor-title">Sub-tasks</h2>
<FieldArray name="subTasks">
{({ insert, remove, push }) => (
<div>
{values.subTasks.length > 0 && values.subTasks.map((subTask, index) => (
<div className="kanbn-task-editor-row kanbn-task-editor-row-subtask" key={index}>
<div className="kanbn-task-editor-column kanbn-task-editor-field-subtask-completed">
<Field
className="kanbn-task-editor-field-checkbox"
type="checkbox"
name={`subTasks.${index}.completed`}
/>
<ErrorMessage
className="kanbn-task-editor-field-errors"
component="div"
name={`subTasks.${index}.completed`}
/>
</div>
<div className="kanbn-task-editor-column kanbn-task-editor-field-subtask-text">
<Field
className="kanbn-task-editor-field-input"
name={`subTasks.${index}.text`}
placeholder="Sub-task text"
/>
<ErrorMessage
className="kanbn-task-editor-field-errors"
component="div"
name={`subTasks.${index}.text`}
/>
</div>
<div className="kanbn-task-editor-column kanbn-task-editor-column-buttons">
<button
type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-delete"
title="Remove sub-task"
onClick={() => remove(index)}
>
<i className="codicon codicon-trash"></i>
</button>
</div>
</div>
))}
<div className="kanbn-task-editor-buttons">
<button
type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-add"
title="Add sub-task"
onClick={() => push({ completed: false, text: '' })}
>
<i className="codicon codicon-tasklist"></i>Add sub-task
</button>
</div>
</div>
)}
</FieldArray>
</div>
<div className="kanbn-task-editor-field kanbn-task-editor-field-relations"> <div className="kanbn-task-editor-field kanbn-task-editor-field-relations">
<h2 className="kanbn-task-editor-title">Relations</h2> <h2 className="kanbn-task-editor-title">Relations</h2>
<FieldArray name="relations"> <FieldArray name="relations">
@ -171,9 +292,10 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
<button <button
type="button" type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-delete" className="kanbn-task-editor-button kanbn-task-editor-button-delete"
title="Remove relation"
onClick={() => remove(index)} onClick={() => remove(index)}
> >
<i className="codicon codicon-trash"></i>Delete <i className="codicon codicon-trash"></i>
</button> </button>
</div> </div>
</div> </div>
@ -182,54 +304,63 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
<button <button
type="button" type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-add" className="kanbn-task-editor-button kanbn-task-editor-button-add"
title="Add relation"
onClick={() => push({ type: '', task: '' })} onClick={() => push({ type: '', task: '' })}
> >
<i className="codicon codicon-plus"></i>Add relation <i className="codicon codicon-link"></i>Add relation
</button> </button>
</div> </div>
</div> </div>
)} )}
</FieldArray> </FieldArray>
</div> </div>
<div className="kanbn-task-editor-field kanbn-task-editor-field-subtasks"> <div className="kanbn-task-editor-field kanbn-task-editor-field-comments">
<h2 className="kanbn-task-editor-title">Sub-tasks</h2> <h2 className="kanbn-task-editor-title">Comments</h2>
<FieldArray name="subTasks"> <FieldArray name="comments">
{({ insert, remove, push }) => ( {({ insert, remove, push }) => (
<div> <div>
{values.subTasks.length > 0 && values.subTasks.map((subTask, index) => ( {values.comments.length > 0 && values.comments.map((comment, index) => (
<div className="kanbn-task-editor-row kanbn-task-editor-row-subtask" key={index}> <div className="kanbn-task-editor-row-comment" key={index}>
<div className="kanbn-task-editor-column kanbn-task-editor-field-subtask-completed"> <div className="kanbn-task-editor-row">
<Field <div className="kanbn-task-editor-column kanbn-task-editor-field-comment-author">
className="kanbn-task-editor-field-checkbox" <Field
type="checkbox" className="kanbn-task-editor-field-input"
name={`subTasks.${index}.completed`} name={`comments.${index}.author`}
/> placeholder="Comment author"
<ErrorMessage />
className="kanbn-task-editor-field-errors" <ErrorMessage
component="div" className="kanbn-task-editor-field-errors"
name={`subTasks.${index}.completed`} component="div"
/> name={`comments.${index}.author`}
/>
</div>
<div className="kanbn-task-editor-column kanbn-task-editor-field-comment-date">
{formatDate(comment.date, dateFormat)}
</div>
<div className="kanbn-task-editor-column kanbn-task-editor-column-buttons">
<button
type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-delete"
title="Remove comment"
onClick={() => remove(index)}
>
<i className="codicon codicon-trash"></i>
</button>
</div>
</div> </div>
<div className="kanbn-task-editor-column kanbn-task-editor-field-subtask-text"> <div className="kanbn-task-editor-row">
<Field <div className="kanbn-task-editor-column kanbn-task-editor-field-comment-text">
className="kanbn-task-editor-field-input" <Field
name={`subTasks.${index}.text`} className="kanbn-task-editor-field-textarea"
placeholder="Sub-task text" as="textarea"
/> name={`comments.${index}.text`}
<ErrorMessage />
className="kanbn-task-editor-field-errors" <ErrorMessage
component="div" className="kanbn-task-editor-field-errors"
name={`subTasks.${index}.text`} component="div"
/> name={`comments.${index}.text`}
</div> />
<div className="kanbn-task-editor-column kanbn-task-editor-column-buttons"> </div>
<button
type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-delete"
onClick={() => remove(index)}
>
<i className="codicon codicon-trash"></i>Delete
</button>
</div> </div>
</div> </div>
))} ))}
@ -237,9 +368,10 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
<button <button
type="button" type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-add" className="kanbn-task-editor-button kanbn-task-editor-button-add"
onClick={() => push({ completed: false, text: '' })} title="Add comment"
onClick={() => push({ text: '', date: new Date(), author: gitUsername() || '' })}
> >
<i className="codicon codicon-plus"></i>Add sub-task <i className="codicon codicon-comment"></i>Add comment
</button> </button>
</div> </div>
</div> </div>
@ -252,7 +384,7 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
{editing && <button {editing && <button
type="button" type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-delete" className="kanbn-task-editor-button kanbn-task-editor-button-delete"
title="Delete" title="Delete task"
onClick={handleRemoveTask} onClick={handleRemoveTask}
> >
<i className="codicon codicon-trash"></i>Delete <i className="codicon codicon-trash"></i>Delete
@ -260,7 +392,7 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
<button <button
type="submit" type="submit"
className="kanbn-task-editor-button kanbn-task-editor-button-submit" className="kanbn-task-editor-button kanbn-task-editor-button-submit"
title="Save" title="Save task"
disabled={isSubmitting} disabled={isSubmitting}
> >
<i className="codicon codicon-save"></i>Save <i className="codicon codicon-save"></i>Save
@ -298,11 +430,29 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
name="metadata.assigned" name="metadata.assigned"
/> />
</div> </div>
<div className="kanbn-task-editor-field kanbn-task-editor-field-started">
<label className="kanbn-task-editor-field-label">
<p>Started date</p>
<Field
className="kanbn-task-editor-field-input"
type="date"
name="metadata.started"
/>
</label>
<ErrorMessage
className="kanbn-task-editor-field-errors"
component="div"
name="metadata.started"
/>
</div>
<div className="kanbn-task-editor-field kanbn-task-editor-field-due"> <div className="kanbn-task-editor-field kanbn-task-editor-field-due">
<label className="kanbn-task-editor-field-label"> <label className="kanbn-task-editor-field-label">
<p>Due date</p> <p>Due date</p>
<Field <Field
className="kanbn-task-editor-field-input" className={[
'kanbn-task-editor-field-input',
checkOverdue(values) ? 'kanbn-task-overdue' : null
].filter(i => i).join(' ')}
type="date" type="date"
name="metadata.due" name="metadata.due"
/> />
@ -313,6 +463,21 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
name="metadata.due" name="metadata.due"
/> />
</div> </div>
<div className="kanbn-task-editor-field kanbn-task-editor-field-completed">
<label className="kanbn-task-editor-field-label">
<p>Completed date</p>
<Field
className="kanbn-task-editor-field-input"
type="date"
name="metadata.completed"
/>
</label>
<ErrorMessage
className="kanbn-task-editor-field-errors"
component="div"
name="metadata.completed"
/>
</div>
<div className="kanbn-task-editor-field kanbn-task-editor-field-progress"> <div className="kanbn-task-editor-field kanbn-task-editor-field-progress">
<label className="kanbn-task-editor-field-label"> <label className="kanbn-task-editor-field-label">
<p>Progress</p> <p>Progress</p>
@ -324,6 +489,9 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
max="1" max="1"
step="0.05" step="0.05"
/> />
<div className="kanbn-task-progress" style={{
width: `${Math.min(1, Math.max(0, values.progress || 0)) * 100}%`
}}></div>
</label> </label>
<ErrorMessage <ErrorMessage
className="kanbn-task-editor-field-errors" className="kanbn-task-editor-field-errors"
@ -347,7 +515,14 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
<Field <Field
className="kanbn-task-editor-field-input" className="kanbn-task-editor-field-input"
name={`metadata.tags.${index}`} name={`metadata.tags.${index}`}
placeholder="Tag name"
/> />
<div
className={[
'kanbn-task-editor-tag-highlight',
`kanbn-task-tag-${paramCase(values.metadata.tags![index])}`
].join(' ')}
></div>
<ErrorMessage <ErrorMessage
className="kanbn-task-editor-field-errors" className="kanbn-task-editor-field-errors"
component="div" component="div"
@ -358,9 +533,10 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
<button <button
type="button" type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-delete" className="kanbn-task-editor-button kanbn-task-editor-button-delete"
title="Remove tag"
onClick={() => remove(index)} onClick={() => remove(index)}
> >
<i className="codicon codicon-trash"></i>Delete <i className="codicon codicon-trash"></i>
</button> </button>
</div> </div>
</div> </div>
@ -369,9 +545,10 @@ const TaskEditor = ({ task, tasks, columnName, columnNames, dateFormat, vscode }
<button <button
type="button" type="button"
className="kanbn-task-editor-button kanbn-task-editor-button-add" className="kanbn-task-editor-button kanbn-task-editor-button-add"
title="Add tag"
onClick={() => push('')} onClick={() => push('')}
> >
<i className="codicon codicon-plus"></i>Add tag <i className="codicon codicon-tag"></i>Add tag
</button> </button>
</div> </div>
</div> </div>

View File

@ -10,11 +10,20 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
dateFormat: string, dateFormat: string,
vscode: VSCodeApi vscode: VSCodeApi
}) => { }) => {
const createdDate = 'created' in task.metadata ? formatDate(task.metadata.created, dateFormat) : ''; const createdDate = 'created' in task.metadata ? formatDate(task.metadata.created, dateFormat) : null;
const updatedDate = 'updated' in task.metadata ? formatDate(task.metadata.updated, dateFormat) : ''; const updatedDate = 'updated' in task.metadata ? formatDate(task.metadata.updated, dateFormat) : null;
const startedDate = 'started' in task.metadata ? formatDate(task.metadata.started, dateFormat) : ''; const startedDate = 'started' in task.metadata ? formatDate(task.metadata.started, dateFormat) : null;
const dueDate = 'due' in task.metadata ? formatDate(task.metadata.due, dateFormat) : ''; const dueDate = 'due' in task.metadata ? formatDate(task.metadata.due, dateFormat) : null;
const completedDate = 'completed' in task.metadata ? formatDate(task.metadata.completed, dateFormat) : ''; const completedDate = 'completed' in task.metadata ? formatDate(task.metadata.completed, dateFormat) : null;
// Check if a task's due date is in the past
const checkOverdue = (task: KanbnTask) => {
if ('due' in task.metadata && task.metadata.due !== undefined) {
return Date.parse(task.metadata.due) < (new Date()).getTime();
}
return false;
};
return ( return (
<Draggable <Draggable
key={task.id} key={task.id}
@ -85,7 +94,12 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
dueDate ? `Due ${dueDate}` : null, dueDate ? `Due ${dueDate}` : null,
completedDate ? `Completed ${completedDate}` : null completedDate ? `Completed ${completedDate}` : null
].filter(i => i).join('\n')}> ].filter(i => i).join('\n')}>
<i className="codicon codicon-clock"></i>{updatedDate || createdDate} <i
className={[
'codicon codicon-clock',
checkOverdue(task) ? 'kanbn-task-overdue' : null
].filter(i => i).join(' ')}
></i>{updatedDate || createdDate}
</div> </div>
} }
{ {
@ -111,7 +125,7 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
task.workload !== undefined && task.workload !== undefined &&
task.progress !== undefined && task.progress !== undefined &&
<div className="kanbn-task-progress" style={{ <div className="kanbn-task-progress" style={{
width: `${task.progress * 100}%` width: `${Math.min(1, Math.max(0, task.progress)) * 100}%`
}}></div> }}></div>
} }
</div> </div>

View File

@ -1,7 +1,8 @@
body { body {
margin: 0; margin: 0;
padding: 1em; padding: 1em;
font-family: sans-serif; font-family: var(--vscode-font-family);
font-size: var(--vscode-font-size);
background-color: var(--vscode-editor-background); background-color: var(--vscode-editor-background);
color: var(--vscode-foreground); color: var(--vscode-foreground);
} }
@ -204,6 +205,10 @@ body {
color: #333; color: #333;
} }
.kanbn-task-overdue {
color: #f42 !important;
}
.kanbn-task-progress { .kanbn-task-progress {
position: absolute; position: absolute;
bottom: -2px; bottom: -2px;
@ -220,14 +225,27 @@ body {
border-bottom: 1px var(--vscode-activityBar-inactiveForeground) solid; border-bottom: 1px var(--vscode-activityBar-inactiveForeground) solid;
} }
.kanbn-task-editor-dates {
font-size: var(--vscode-font-size);
font-style: italic;
font-weight: normal;
opacity: 0.8;
float: right;
}
.kanbn-task-editor-form { .kanbn-task-editor-form {
display: flex; display: flex;
} }
.kanbn-task-editor-field .kanbn-task-editor-title { .kanbn-task-editor-field .kanbn-task-editor-title,
font-size: 1.1em; .kanbn-task-editor-field-label p {
padding: 0.5em 0; color: var(--vscode-editor-foreground);
border-bottom: 1px var(--vscode-activityBar-inactiveForeground) solid; font-size: 0.8em;
letter-spacing: 0.1em;
font-weight: bold;
text-transform: uppercase;
padding: 4px 0;
border-bottom: none;
} }
.kanbn-task-editor-column-left { .kanbn-task-editor-column-left {
@ -243,15 +261,6 @@ body {
margin-bottom: 1em; margin-bottom: 1em;
} }
.kanbn-task-editor-field-label p {
color: var(--vscode-editor-foreground);
font-size: 0.8em;
letter-spacing: 0.1em;
font-weight: bold;
text-transform: uppercase;
padding: 4px 0;
}
body.vscode-dark .kanbn-task-editor-field-input[type="date"]::-webkit-calendar-picker-indicator { body.vscode-dark .kanbn-task-editor-field-input[type="date"]::-webkit-calendar-picker-indicator {
filter: invert(1); filter: invert(1);
} }
@ -270,6 +279,11 @@ body.vscode-dark .kanbn-task-editor-field-input[type="date"]::-webkit-calendar-p
border: 1px transparent solid; border: 1px transparent solid;
} }
.kanbn-task-editor-field-input[type=date] {
font-family: var(--vscode-font-family);
font-size: var(--vscode-font-size);
}
.kanbn-task-editor-field-select { .kanbn-task-editor-field-select {
padding-bottom: 7px; padding-bottom: 7px;
} }
@ -356,3 +370,46 @@ body.vscode-dark .kanbn-task-editor-field-input[type="date"]::-webkit-calendar-p
.kanbn-task-editor-column-buttons .kanbn-task-editor-button { .kanbn-task-editor-column-buttons .kanbn-task-editor-button {
margin: 8px 0; margin: 8px 0;
} }
.kanbn-task-editor-field-progress {
position: relative;
}
.kanbn-task-editor-field-progress .kanbn-task-progress {
bottom: 0;
height: 4px;
opacity: 1;
}
.kanbn-task-editor-column .kanbn-task-editor-button-delete .codicon {
margin-right: 0;
}
.kanbn-task-editor-field-tag {
position: relative;
}
.kanbn-task-editor-tag-highlight {
position: absolute;
bottom: 8px;
left: 0;
height: 4px;
width: 100%;
}
.kanbn-task-editor-row-comment {
padding-bottom: 1em;
border-bottom: 1px var(--vscode-activityBar-inactiveForeground) solid;
margin-bottom: 1em;
}
.kanbn-task-editor-field-comment-date {
padding: 16px 0;
text-align: right;
font-style: italic;
opacity: 0.8;
}
.kanbn-task-editor-field-comment-text .kanbn-task-editor-field-textarea {
min-height: 90px;
}