Add relations, custom fields and card customisation
This commit is contained in:
parent
95b87052b4
commit
0aa5776af3
@ -1,8 +1,10 @@
|
|||||||
# 0.11.0
|
# 0.11.0
|
||||||
|
|
||||||
* Added KaTeX support to task markdown (description and comments)
|
* Added KaTeX support to task markdown (description and comments) using `$$...$$` for blocks and `$...$` for inline
|
||||||
* Added syntax highlighting to code blocks in task markdown (description and comments)
|
* Added syntax highlighting to code blocks in task markdown (description and comments)
|
||||||
* Added column sorting
|
* Added column sorting
|
||||||
|
* Added relations and custom fields to task cards
|
||||||
|
* Added task card customisation using `board.css`
|
||||||
|
|
||||||
# 0.10.0
|
# 0.10.0
|
||||||
|
|
||||||
|
@ -8,6 +8,62 @@ Visual Studio Code will add `vscode-light`, `vscode-dark` and `vscode-high-contr
|
|||||||
|
|
||||||
Various Codicon icons have been used in this extension. Check [here](https://code.visualstudio.com/api/references/icons-in-labels) for a listing of available icons.
|
Various Codicon icons have been used in this extension. Check [here](https://code.visualstudio.com/api/references/icons-in-labels) for a listing of available icons.
|
||||||
|
|
||||||
|
## Column and tag configuration
|
||||||
|
|
||||||
|
Each column is given a CSS class containing the column name in param-case. You can use this to apply custom styles to specific columns.
|
||||||
|
|
||||||
|
For example, say we have a column called 'In Progress'. We can apply a custom border colour like so:
|
||||||
|
```css
|
||||||
|
.kanbn-column-in-progress .kanbn-column-task-list {
|
||||||
|
border-color: #ff0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Similarly, each tag is given a CSS class containing the tag name in param-case.
|
||||||
|
|
||||||
|
For example, say we have tags called 'QA required' and 'Breaking Change'. We can apply custom styles like so:
|
||||||
|
```css
|
||||||
|
.kanbn-task-tag-qa-required {
|
||||||
|
background-color: #418;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-tag-breaking-change {
|
||||||
|
background-color: #900;
|
||||||
|
color: #eee;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Task card configuration
|
||||||
|
|
||||||
|
The task cards that appear on the Kanbn board can be configured by showing or hiding different elements, or by applying alternative styles to them.
|
||||||
|
|
||||||
|
The following elements are hidden by default (but can be re-enabled by adding a custom board style):
|
||||||
|
- Updated date
|
||||||
|
- Started date
|
||||||
|
- Due date
|
||||||
|
- Completed date
|
||||||
|
- Number of comments
|
||||||
|
- Relations
|
||||||
|
|
||||||
|
Task fields are generally contained within a `.kanbn-task-data` element, most of which have `display: inline-block` by default. Additionally, the outer-container of a task card is given CSS classes containing the task's column name, completed status and overdue status.
|
||||||
|
|
||||||
|
Here's an example of a task card style using some of the above features:
|
||||||
|
```css
|
||||||
|
.kanbn-task-data-relation {
|
||||||
|
display: block; /* this will display task relations, one per line */
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-relation-blocks {
|
||||||
|
color: #900;
|
||||||
|
font-weight: bold; /* this will highlight task relations of type 'blocks' */
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-completed .kanbn-task-data-completed {
|
||||||
|
display: inline-block; /* this will show the completed date only for tasks that have been completed */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## CSS classes
|
## CSS classes
|
||||||
|
|
||||||
### Kanbn board
|
### Kanbn board
|
||||||
@ -24,7 +80,7 @@ Various Codicon icons have been used in this extension. Check [here](https://cod
|
|||||||
- `kanbn-header-description`
|
- `kanbn-header-description`
|
||||||
- `kanbn-board`
|
- `kanbn-board`
|
||||||
- `kanbn-column`
|
- `kanbn-column`
|
||||||
- `kanbn-column-{Column name in snake-case}`
|
- `kanbn-column-{Column name in param-case}`
|
||||||
- `kanbn-column-name`
|
- `kanbn-column-name`
|
||||||
- `kanbn-column-count`
|
- `kanbn-column-count`
|
||||||
- `kanbn-column-button`
|
- `kanbn-column-button`
|
||||||
@ -35,19 +91,30 @@ Various Codicon icons have been used in this extension. Check [here](https://cod
|
|||||||
- `kanbn-column-task-list`
|
- `kanbn-column-task-list`
|
||||||
- `kanbn-column-task-list.drag-over`
|
- `kanbn-column-task-list.drag-over`
|
||||||
- `kanbn-task`
|
- `kanbn-task`
|
||||||
- `kanbn-task-row`
|
- `kanbn-task-{Column name in param-case}`
|
||||||
- `kanbn-task-name`
|
|
||||||
- `kanbn-task-data`
|
|
||||||
- `kanbn-task-tags`
|
|
||||||
- `kanbn-task-tag`
|
|
||||||
- `kanbn-task-tag-{Tag name in snake-case}`
|
|
||||||
- `kanbn-task-assigned`
|
|
||||||
- `kanbn-task-date`
|
|
||||||
- `kanbn-task-workload`
|
|
||||||
- `kanbn-task-progress`
|
|
||||||
- `kanbn-task-overdue`
|
- `kanbn-task-overdue`
|
||||||
- `kanbn-task-comments`
|
- `kanbn-task-completed`
|
||||||
- `kanbn-task-sub-tasks`
|
- `drag`
|
||||||
|
- `kanbn-task-data`
|
||||||
|
- `kanbn-task-data-label`
|
||||||
|
- `kanbn-task-data-name`
|
||||||
|
- `kanbn-task-data-tags`
|
||||||
|
- `kanbn-task-tag`
|
||||||
|
- `kanbn-task-tag-{Tag name in param-case}`
|
||||||
|
- `kanbn-task-data-custom-field`
|
||||||
|
- `kanbn-task-data-{Custom field name in param-case}
|
||||||
|
- `kanbn-task-data-assigned`
|
||||||
|
- `kanbn-task-data-created`
|
||||||
|
- `kanbn-task-data-updated`
|
||||||
|
- `kanbn-task-data-started`
|
||||||
|
- `kanbn-task-data-due`
|
||||||
|
- `kanbn-task-data-completed`
|
||||||
|
- `kanbn-task-data-comments`
|
||||||
|
- `kanbn-task-data-sub-tasks`
|
||||||
|
- `kanbn-task-data-relation`
|
||||||
|
- `kanbn-task-data-relation-{Relation type in param-case}`
|
||||||
|
- `kanbn-task-data-workload`
|
||||||
|
- `kanbn-task-progress`
|
||||||
|
|
||||||
### Task editor
|
### Task editor
|
||||||
|
|
||||||
@ -107,7 +174,7 @@ Various Codicon icons have been used in this extension. Check [here](https://cod
|
|||||||
- `kanbn-task-editor-row-tag`
|
- `kanbn-task-editor-row-tag`
|
||||||
- `kanbn-task-editor-field-tag`
|
- `kanbn-task-editor-field-tag`
|
||||||
- `kanbn-task-editor-tag-highlight`
|
- `kanbn-task-editor-tag-highlight`
|
||||||
- `kanbn-task-tag-{Tag name in snake-case}`
|
- `kanbn-task-tag-{Tag name in param-case}`
|
||||||
|
|
||||||
### Burndown chart
|
### Burndown chart
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ export default class KanbnBoardPanel {
|
|||||||
startedColumns: index.options.startedColumns ?? [],
|
startedColumns: index.options.startedColumns ?? [],
|
||||||
completedColumns: index.options.completedColumns ?? [],
|
completedColumns: index.options.completedColumns ?? [],
|
||||||
columnSorting: index.options.columnSorting ?? {},
|
columnSorting: index.options.columnSorting ?? {},
|
||||||
|
customFields: index.options.customFields ?? [],
|
||||||
dateFormat: KanbnBoardPanel.currentPanel._kanbn.getDateFormat(index),
|
dateFormat: KanbnBoardPanel.currentPanel._kanbn.getDateFormat(index),
|
||||||
showBurndownButton: vscode.workspace.getConfiguration("kanbn").get("showBurndownButton"),
|
showBurndownButton: vscode.workspace.getConfiguration("kanbn").get("showBurndownButton"),
|
||||||
showSprintButton: vscode.workspace.getConfiguration("kanbn").get("showSprintButton"),
|
showSprintButton: vscode.workspace.getConfiguration("kanbn").get("showSprintButton"),
|
||||||
|
24
package-lock.json
generated
24
package-lock.json
generated
@ -1352,9 +1352,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@basementuniverse/kanbn": {
|
"@basementuniverse/kanbn": {
|
||||||
"version": "0.9.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@basementuniverse/kanbn/-/kanbn-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@basementuniverse/kanbn/-/kanbn-0.10.0.tgz",
|
||||||
"integrity": "sha512-LYJlJ6/KLkxqW/ZpPkLsAYTZ6ki5wmP9ZIgLPNW28+KVXhFz78/+3amoynMeOFUOBiKymCJYlKtvly6y0CvdTg==",
|
"integrity": "sha512-inNRbX1ZuiUiub0PbEDJAZGI9m92+AwGWnoByEZEHAq0L8rD1Z8DZVzeyXQDhrNdt8gpkjINR8+l8NJ8Tmqc0Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"asciichart": "^1.5.25",
|
"asciichart": "^1.5.25",
|
||||||
"auto-load": "^3.0.4",
|
"auto-load": "^3.0.4",
|
||||||
@ -4168,9 +4168,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chrono-node": {
|
"chrono-node": {
|
||||||
"version": "2.2.6",
|
"version": "2.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-2.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-2.2.7.tgz",
|
||||||
"integrity": "sha512-ahgxpY4ihg3frV5t7pZYrS0Iap5MErTQ7whVNBxbiLjplc2HhGwj3zgr0dEnJos/FAuZVjrHoky8J9YiNc5ZKQ==",
|
"integrity": "sha512-QQxlQUwebgNJDtUJpRQlhKoJJgSfvNTe6Zk1LgyVHVnbCj6xKygmiviJonS/n5A4xd9qjEl1u+ke2vzD77ty/g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"dayjs": "^1.10.0"
|
"dayjs": "^1.10.0"
|
||||||
}
|
}
|
||||||
@ -10245,9 +10245,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"humanize-duration": {
|
"humanize-duration": {
|
||||||
"version": "3.26.0",
|
"version": "3.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz",
|
||||||
"integrity": "sha512-SddekX3p5ApvPY6bbAYppGKe874jP6iFZXYtrQToDV4R0j2UpTYPqwTFM2QpXpuw9DhS/eXTUnKYTF9TbXAJ6A=="
|
"integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ=="
|
||||||
},
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
@ -13798,9 +13798,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"nextgen-events": {
|
"nextgen-events": {
|
||||||
"version": "1.4.0",
|
"version": "1.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/nextgen-events/-/nextgen-events-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/nextgen-events/-/nextgen-events-1.5.2.tgz",
|
||||||
"integrity": "sha512-bwSpShfuLg/lcRFokZvtUcrn5kumy6uRI6Jc+QWzH+bW6ZRdog7LfwAwhqeTzVfsprZgDGrctr6rO5aJhcdAfg=="
|
"integrity": "sha512-0ZEIRQywH5Oxt2IYYufRltQg/KjXhKM7f7MHve+ZIRaKnIR1PPYEXAl2WBmej5Sf0Qh2GgE/21sMRZVuOyxLzw=="
|
||||||
},
|
},
|
||||||
"nice-try": {
|
"nice-try": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@basementuniverse/kanbn": "^0.9.0",
|
"@basementuniverse/kanbn": "^0.10.0",
|
||||||
"dateformat": "^4.5.1",
|
"dateformat": "^4.5.1",
|
||||||
"formik": "^2.2.6",
|
"formik": "^2.2.6",
|
||||||
"git-user-name": "^2.0.0",
|
"git-user-name": "^2.0.0",
|
||||||
|
@ -18,6 +18,7 @@ function App() {
|
|||||||
const [startedColumns, setStartedColumns] = useState([]);
|
const [startedColumns, setStartedColumns] = useState([]);
|
||||||
const [completedColumns, setCompletedColumns] = useState([]);
|
const [completedColumns, setCompletedColumns] = useState([]);
|
||||||
const [columnSorting, setColumnSorting] = useState({});
|
const [columnSorting, setColumnSorting] = useState({});
|
||||||
|
const [customFields, setCustomFields] = useState([]);
|
||||||
const [dateFormat, setDateFormat] = useState('');
|
const [dateFormat, setDateFormat] = useState('');
|
||||||
const [task, setTask] = useState({});
|
const [task, setTask] = useState({});
|
||||||
const [tasks, setTasks] = useState({});
|
const [tasks, setTasks] = useState({});
|
||||||
@ -48,6 +49,7 @@ function App() {
|
|||||||
setStartedColumns(event.data.startedColumns);
|
setStartedColumns(event.data.startedColumns);
|
||||||
setCompletedColumns(event.data.completedColumns);
|
setCompletedColumns(event.data.completedColumns);
|
||||||
setColumnSorting(event.data.columnSorting);
|
setColumnSorting(event.data.columnSorting);
|
||||||
|
setCustomFields(event.data.customFields);
|
||||||
setShowBurndownButton(event.data.showBurndownButton);
|
setShowBurndownButton(event.data.showBurndownButton);
|
||||||
setShowSprintButton(event.data.showSprintButton);
|
setShowSprintButton(event.data.showSprintButton);
|
||||||
|
|
||||||
@ -101,6 +103,7 @@ function App() {
|
|||||||
startedColumns={startedColumns}
|
startedColumns={startedColumns}
|
||||||
completedColumns={completedColumns}
|
completedColumns={completedColumns}
|
||||||
columnSorting={columnSorting}
|
columnSorting={columnSorting}
|
||||||
|
customFields={customFields}
|
||||||
dateFormat={dateFormat}
|
dateFormat={dateFormat}
|
||||||
showBurndownButton={showBurndownButton}
|
showBurndownButton={showBurndownButton}
|
||||||
showSprintButton={showSprintButton}
|
showSprintButton={showSprintButton}
|
||||||
|
@ -140,6 +140,7 @@ const Board = ({
|
|||||||
startedColumns,
|
startedColumns,
|
||||||
completedColumns,
|
completedColumns,
|
||||||
columnSorting,
|
columnSorting,
|
||||||
|
customFields,
|
||||||
dateFormat,
|
dateFormat,
|
||||||
showBurndownButton,
|
showBurndownButton,
|
||||||
showSprintButton,
|
showSprintButton,
|
||||||
@ -153,6 +154,7 @@ const Board = ({
|
|||||||
startedColumns: string[],
|
startedColumns: string[],
|
||||||
completedColumns: string[],
|
completedColumns: string[],
|
||||||
columnSorting: { [columnName: string]: { field: string, order: 'ascending' | 'descending' }[] },
|
columnSorting: { [columnName: string]: { field: string, order: 'ascending' | 'descending' }[] },
|
||||||
|
customFields: { name: string, type: 'boolean' | 'date' | 'number' | 'string' }[],
|
||||||
dateFormat: string,
|
dateFormat: string,
|
||||||
showBurndownButton: boolean,
|
showBurndownButton: boolean,
|
||||||
showSprintButton: boolean,
|
showSprintButton: boolean,
|
||||||
@ -326,6 +328,8 @@ const Board = ({
|
|||||||
>
|
>
|
||||||
{column.filter(task => filterTask(task, taskFilter)).map((task, position) => <TaskItem
|
{column.filter(task => filterTask(task, taskFilter)).map((task, position) => <TaskItem
|
||||||
task={task}
|
task={task}
|
||||||
|
columnName={columnName}
|
||||||
|
customFields={customFields}
|
||||||
position={position}
|
position={position}
|
||||||
dateFormat={dateFormat}
|
dateFormat={dateFormat}
|
||||||
vscode={vscode}
|
vscode={vscode}
|
||||||
|
203
src/TaskItem.tsx
203
src/TaskItem.tsx
@ -4,8 +4,10 @@ import formatDate from 'dateformat';
|
|||||||
import { paramCase } from '@basementuniverse/kanbn/src/utility';
|
import { paramCase } from '@basementuniverse/kanbn/src/utility';
|
||||||
import VSCodeApi from "./VSCodeApi";
|
import VSCodeApi from "./VSCodeApi";
|
||||||
|
|
||||||
const TaskItem = ({ task, position, dateFormat, vscode }: {
|
const TaskItem = ({ task, columnName, customFields, position, dateFormat, vscode }: {
|
||||||
task: KanbnTask,
|
task: KanbnTask,
|
||||||
|
columnName: string,
|
||||||
|
customFields: { name: string, type: 'boolean' | 'date' | 'number' | 'string' }[],
|
||||||
position: number,
|
position: number,
|
||||||
dateFormat: string,
|
dateFormat: string,
|
||||||
vscode: VSCodeApi
|
vscode: VSCodeApi
|
||||||
@ -38,6 +40,9 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
|||||||
{...provided.dragHandleProps}
|
{...provided.dragHandleProps}
|
||||||
className={[
|
className={[
|
||||||
'kanbn-task',
|
'kanbn-task',
|
||||||
|
`kanbn-task-column-${paramCase(columnName)}`,
|
||||||
|
checkOverdue(task) ? 'kanbn-task-overdue' : null,
|
||||||
|
!!completedDate ? 'kanbn-task-completed' : null,
|
||||||
snapshot.isDragging ? 'drag' : null
|
snapshot.isDragging ? 'drag' : null
|
||||||
].filter(i => i).join(' ')}
|
].filter(i => i).join(' ')}
|
||||||
style={{
|
style={{
|
||||||
@ -45,10 +50,9 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
|||||||
...provided.draggableProps.style
|
...provided.draggableProps.style
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="kanbn-task-row">
|
<div className="kanbn-task-data kanbn-task-data-name">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="kanbn-task-name"
|
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
vscode.postMessage({
|
vscode.postMessage({
|
||||||
command: 'kanbn.task',
|
command: 'kanbn.task',
|
||||||
@ -61,76 +65,131 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
|||||||
{task.name}
|
{task.name}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="kanbn-task-row">
|
{
|
||||||
{
|
'tags' in task.metadata &&
|
||||||
'tags' in task.metadata &&
|
task.metadata.tags!.length > 0 &&
|
||||||
task.metadata.tags!.length > 0 &&
|
<div className="kanbn-task-data kanbn-task-data-tags">
|
||||||
<div className="kanbn-task-data kanbn-task-tags">
|
{task.metadata.tags!.map(tag => {
|
||||||
{task.metadata.tags!.map(tag => {
|
return (
|
||||||
return (
|
<span className={[
|
||||||
<span className={[
|
'kanbn-task-tag',
|
||||||
'kanbn-task-tag',
|
`kanbn-task-tag-${paramCase(tag)}`
|
||||||
`kanbn-task-tag-${paramCase(tag)}`
|
].join(' ')}>
|
||||||
].join(' ')}>
|
{tag}
|
||||||
{tag}
|
</span>
|
||||||
</span>
|
);
|
||||||
);
|
})}
|
||||||
})}
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
customFields.map(customField => {
|
||||||
|
if (customField.name in task.metadata) {
|
||||||
|
return (
|
||||||
|
<div className={[
|
||||||
|
'kanbn-task-data kanbn-task-data-custom-field',
|
||||||
|
`kanbn-task-data-${paramCase(customField.name)}`
|
||||||
|
].join(' ')}>
|
||||||
|
{
|
||||||
|
customField.type === 'boolean'
|
||||||
|
? (
|
||||||
|
<>
|
||||||
|
<i className={`codicon codicon-${task.metadata[customField.name]
|
||||||
|
? 'pass-filled'
|
||||||
|
: 'circle-large-outline'}`}></i>
|
||||||
|
{customField.name}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<i className="codicon codicon-json"></i>
|
||||||
|
<span title={customField.name}>
|
||||||
|
{task.metadata[customField.name]}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (<></>);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
{
|
||||||
|
'assigned' in task.metadata &&
|
||||||
|
!!task.metadata.assigned &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-assigned">
|
||||||
|
<i className="codicon codicon-account"></i>{task.metadata.assigned}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
createdDate &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-created" title={`Created ${createdDate}`}>
|
||||||
|
<i className="codicon codicon-clock"></i>{createdDate}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
updatedDate &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-updated" title={`Updated ${updatedDate}`}>
|
||||||
|
<i className="codicon codicon-clock"></i>{updatedDate}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
startedDate &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-started" title={`Started ${startedDate}`}>
|
||||||
|
<i className="codicon codicon-run"></i>{startedDate}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dueDate &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-due" title={`Due ${dueDate}`}>
|
||||||
|
<i className="codicon codicon-watch"></i>{dueDate}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
completedDate &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-completed" title={`Completed ${completedDate}`}>
|
||||||
|
<i className="codicon codicon-check"></i>{completedDate}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
task.comments.length > 0 &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-comments">
|
||||||
|
<i className="codicon codicon-comment"></i>{task.comments.length}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
task.subTasks.length > 0 &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-sub-tasks">
|
||||||
|
<i className="codicon codicon-tasklist"></i>
|
||||||
|
{task.subTasks.filter(subTask => subTask.completed).length} / {task.subTasks.length}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
task.workload !== undefined &&
|
||||||
|
<div className="kanbn-task-data kanbn-task-data-workload">
|
||||||
|
<i className="codicon codicon-run"></i>{task.workload}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
task.relations.length > 0 &&
|
||||||
|
task.relations.map(relation => (
|
||||||
|
<div className={[
|
||||||
|
'kanbn-task-data kanbn-task-data-relation',
|
||||||
|
relation.type ? `kanbn-task-data-relation-${relation.type}` : null,
|
||||||
|
].join(' ')}>
|
||||||
|
<i className="codicon codicon-link"></i>
|
||||||
|
<span className="kanbn-task-data-label">
|
||||||
|
{relation.type}
|
||||||
|
</span> {relation.task}
|
||||||
</div>
|
</div>
|
||||||
}
|
))
|
||||||
</div>
|
}
|
||||||
<div className="kanbn-task-row">
|
{
|
||||||
{
|
task.workload !== undefined &&
|
||||||
'assigned' in task.metadata &&
|
task.progress !== undefined &&
|
||||||
!!task.metadata.assigned &&
|
<div className="kanbn-task-progress" style={{
|
||||||
<div className="kanbn-task-data kanbn-task-assigned">
|
width: `${Math.min(1, Math.max(0, task.progress)) * 100}%`
|
||||||
<i className="codicon codicon-account"></i>{task.metadata.assigned}
|
}}></div>
|
||||||
</div>
|
}
|
||||||
}
|
|
||||||
{
|
|
||||||
(createdDate || updatedDate) &&
|
|
||||||
<div className="kanbn-task-data kanbn-task-date" title={[
|
|
||||||
createdDate ? `Created ${createdDate}` : null,
|
|
||||||
updatedDate ? `Updated ${updatedDate}` : null,
|
|
||||||
startedDate ? `Started ${startedDate}` : null,
|
|
||||||
dueDate ? `Due ${dueDate}` : null,
|
|
||||||
completedDate ? `Completed ${completedDate}` : null
|
|
||||||
].filter(i => i).join('\n')}>
|
|
||||||
<i
|
|
||||||
className={[
|
|
||||||
'codicon codicon-clock',
|
|
||||||
checkOverdue(task) ? 'kanbn-task-overdue' : null
|
|
||||||
].filter(i => i).join(' ')}
|
|
||||||
></i>{updatedDate || createdDate}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
task.comments.length > 0 &&
|
|
||||||
<div className="kanbn-task-data kanbn-task-comments">
|
|
||||||
<i className="codicon codicon-comment"></i>{task.comments.length}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
task.subTasks.length > 0 &&
|
|
||||||
<div className="kanbn-task-data kanbn-task-sub-tasks">
|
|
||||||
<i className="codicon codicon-tasklist"></i>
|
|
||||||
{task.subTasks.filter(subTask => subTask.completed).length} / {task.subTasks.length}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
task.workload !== undefined &&
|
|
||||||
<div className="kanbn-task-data kanbn-task-workload">
|
|
||||||
<i className="codicon codicon-run"></i>{task.workload}
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
task.workload !== undefined &&
|
|
||||||
task.progress !== undefined &&
|
|
||||||
<div className="kanbn-task-progress" style={{
|
|
||||||
width: `${Math.min(1, Math.max(0, task.progress)) * 100}%`
|
|
||||||
}}></div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -220,7 +220,33 @@ body.vscode-dark .kanbn-task {
|
|||||||
border-color: var(--vscode-activityBar-foreground);
|
border-color: var(--vscode-activityBar-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kanbn-task-name {
|
.kanbn-task-data {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 4px 8px 4px 0;
|
||||||
|
min-width: 30%;
|
||||||
|
opacity: 0.7;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-label {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-name {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-tags {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-relation {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-name button {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
@ -232,22 +258,13 @@ body.vscode-dark .kanbn-task {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.kanbn-task-name:focus, .kanbn-task-name:hover {
|
.kanbn-task-data-name button:focus,
|
||||||
|
.kanbn-task-data-name button:hover {
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.kanbn-task-data {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 4px 8px 4px 0;
|
|
||||||
min-width: 30%;
|
|
||||||
opacity: 0.7;
|
|
||||||
font-size: 0.9em;
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kanbn-task div .codicon {
|
.kanbn-task div .codicon {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 1px;
|
top: 1px;
|
||||||
@ -291,7 +308,7 @@ body.vscode-dark .kanbn-task {
|
|||||||
background-color: #f42;
|
background-color: #f42;
|
||||||
}
|
}
|
||||||
|
|
||||||
.kanbn-task-overdue {
|
.kanbn-task-overdue .kanbn-task-data-due {
|
||||||
color: #f22 !important;
|
color: #f22 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,6 +322,30 @@ body.vscode-dark .kanbn-task {
|
|||||||
transition: width .5s ease-in-out;
|
transition: width .5s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-updated {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-started {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-due {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-completed {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-comments {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kanbn-task-data-relation {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
Task editor styles
|
Task editor styles
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user