Add relations, custom fields and card customisation
This commit is contained in:
parent
95b87052b4
commit
0aa5776af3
@ -1,8 +1,10 @@
|
||||
# 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 column sorting
|
||||
* Added relations and custom fields to task cards
|
||||
* Added task card customisation using `board.css`
|
||||
|
||||
# 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.
|
||||
|
||||
## 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
|
||||
|
||||
### Kanbn board
|
||||
@ -24,7 +80,7 @@ Various Codicon icons have been used in this extension. Check [here](https://cod
|
||||
- `kanbn-header-description`
|
||||
- `kanbn-board`
|
||||
- `kanbn-column`
|
||||
- `kanbn-column-{Column name in snake-case}`
|
||||
- `kanbn-column-{Column name in param-case}`
|
||||
- `kanbn-column-name`
|
||||
- `kanbn-column-count`
|
||||
- `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.drag-over`
|
||||
- `kanbn-task`
|
||||
- `kanbn-task-row`
|
||||
- `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-{Column name in param-case}`
|
||||
- `kanbn-task-overdue`
|
||||
- `kanbn-task-comments`
|
||||
- `kanbn-task-sub-tasks`
|
||||
- `kanbn-task-completed`
|
||||
- `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
|
||||
|
||||
@ -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-field-tag`
|
||||
- `kanbn-task-editor-tag-highlight`
|
||||
- `kanbn-task-tag-{Tag name in snake-case}`
|
||||
- `kanbn-task-tag-{Tag name in param-case}`
|
||||
|
||||
### Burndown chart
|
||||
|
||||
|
@ -79,6 +79,7 @@ export default class KanbnBoardPanel {
|
||||
startedColumns: index.options.startedColumns ?? [],
|
||||
completedColumns: index.options.completedColumns ?? [],
|
||||
columnSorting: index.options.columnSorting ?? {},
|
||||
customFields: index.options.customFields ?? [],
|
||||
dateFormat: KanbnBoardPanel.currentPanel._kanbn.getDateFormat(index),
|
||||
showBurndownButton: vscode.workspace.getConfiguration("kanbn").get("showBurndownButton"),
|
||||
showSprintButton: vscode.workspace.getConfiguration("kanbn").get("showSprintButton"),
|
||||
|
24
package-lock.json
generated
24
package-lock.json
generated
@ -1352,9 +1352,9 @@
|
||||
}
|
||||
},
|
||||
"@basementuniverse/kanbn": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@basementuniverse/kanbn/-/kanbn-0.9.0.tgz",
|
||||
"integrity": "sha512-LYJlJ6/KLkxqW/ZpPkLsAYTZ6ki5wmP9ZIgLPNW28+KVXhFz78/+3amoynMeOFUOBiKymCJYlKtvly6y0CvdTg==",
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@basementuniverse/kanbn/-/kanbn-0.10.0.tgz",
|
||||
"integrity": "sha512-inNRbX1ZuiUiub0PbEDJAZGI9m92+AwGWnoByEZEHAq0L8rD1Z8DZVzeyXQDhrNdt8gpkjINR8+l8NJ8Tmqc0Q==",
|
||||
"requires": {
|
||||
"asciichart": "^1.5.25",
|
||||
"auto-load": "^3.0.4",
|
||||
@ -4168,9 +4168,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"chrono-node": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-2.2.6.tgz",
|
||||
"integrity": "sha512-ahgxpY4ihg3frV5t7pZYrS0Iap5MErTQ7whVNBxbiLjplc2HhGwj3zgr0dEnJos/FAuZVjrHoky8J9YiNc5ZKQ==",
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-2.2.7.tgz",
|
||||
"integrity": "sha512-QQxlQUwebgNJDtUJpRQlhKoJJgSfvNTe6Zk1LgyVHVnbCj6xKygmiviJonS/n5A4xd9qjEl1u+ke2vzD77ty/g==",
|
||||
"requires": {
|
||||
"dayjs": "^1.10.0"
|
||||
}
|
||||
@ -10245,9 +10245,9 @@
|
||||
}
|
||||
},
|
||||
"humanize-duration": {
|
||||
"version": "3.26.0",
|
||||
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.26.0.tgz",
|
||||
"integrity": "sha512-SddekX3p5ApvPY6bbAYppGKe874jP6iFZXYtrQToDV4R0j2UpTYPqwTFM2QpXpuw9DhS/eXTUnKYTF9TbXAJ6A=="
|
||||
"version": "3.27.0",
|
||||
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.0.tgz",
|
||||
"integrity": "sha512-qLo/08cNc3Tb0uD7jK0jAcU5cnqCM0n568918E7R2XhMr/+7F37p4EY062W/stg7tmzvknNn9b/1+UhVRzsYrQ=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
@ -13798,9 +13798,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"nextgen-events": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/nextgen-events/-/nextgen-events-1.4.0.tgz",
|
||||
"integrity": "sha512-bwSpShfuLg/lcRFokZvtUcrn5kumy6uRI6Jc+QWzH+bW6ZRdog7LfwAwhqeTzVfsprZgDGrctr6rO5aJhcdAfg=="
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/nextgen-events/-/nextgen-events-1.5.2.tgz",
|
||||
"integrity": "sha512-0ZEIRQywH5Oxt2IYYufRltQg/KjXhKM7f7MHve+ZIRaKnIR1PPYEXAl2WBmej5Sf0Qh2GgE/21sMRZVuOyxLzw=="
|
||||
},
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
|
@ -98,7 +98,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@basementuniverse/kanbn": "^0.9.0",
|
||||
"@basementuniverse/kanbn": "^0.10.0",
|
||||
"dateformat": "^4.5.1",
|
||||
"formik": "^2.2.6",
|
||||
"git-user-name": "^2.0.0",
|
||||
|
@ -18,6 +18,7 @@ function App() {
|
||||
const [startedColumns, setStartedColumns] = useState([]);
|
||||
const [completedColumns, setCompletedColumns] = useState([]);
|
||||
const [columnSorting, setColumnSorting] = useState({});
|
||||
const [customFields, setCustomFields] = useState([]);
|
||||
const [dateFormat, setDateFormat] = useState('');
|
||||
const [task, setTask] = useState({});
|
||||
const [tasks, setTasks] = useState({});
|
||||
@ -48,6 +49,7 @@ function App() {
|
||||
setStartedColumns(event.data.startedColumns);
|
||||
setCompletedColumns(event.data.completedColumns);
|
||||
setColumnSorting(event.data.columnSorting);
|
||||
setCustomFields(event.data.customFields);
|
||||
setShowBurndownButton(event.data.showBurndownButton);
|
||||
setShowSprintButton(event.data.showSprintButton);
|
||||
|
||||
@ -101,6 +103,7 @@ function App() {
|
||||
startedColumns={startedColumns}
|
||||
completedColumns={completedColumns}
|
||||
columnSorting={columnSorting}
|
||||
customFields={customFields}
|
||||
dateFormat={dateFormat}
|
||||
showBurndownButton={showBurndownButton}
|
||||
showSprintButton={showSprintButton}
|
||||
|
@ -140,6 +140,7 @@ const Board = ({
|
||||
startedColumns,
|
||||
completedColumns,
|
||||
columnSorting,
|
||||
customFields,
|
||||
dateFormat,
|
||||
showBurndownButton,
|
||||
showSprintButton,
|
||||
@ -153,6 +154,7 @@ const Board = ({
|
||||
startedColumns: string[],
|
||||
completedColumns: string[],
|
||||
columnSorting: { [columnName: string]: { field: string, order: 'ascending' | 'descending' }[] },
|
||||
customFields: { name: string, type: 'boolean' | 'date' | 'number' | 'string' }[],
|
||||
dateFormat: string,
|
||||
showBurndownButton: boolean,
|
||||
showSprintButton: boolean,
|
||||
@ -326,6 +328,8 @@ const Board = ({
|
||||
>
|
||||
{column.filter(task => filterTask(task, taskFilter)).map((task, position) => <TaskItem
|
||||
task={task}
|
||||
columnName={columnName}
|
||||
customFields={customFields}
|
||||
position={position}
|
||||
dateFormat={dateFormat}
|
||||
vscode={vscode}
|
||||
|
109
src/TaskItem.tsx
109
src/TaskItem.tsx
@ -4,8 +4,10 @@ import formatDate from 'dateformat';
|
||||
import { paramCase } from '@basementuniverse/kanbn/src/utility';
|
||||
import VSCodeApi from "./VSCodeApi";
|
||||
|
||||
const TaskItem = ({ task, position, dateFormat, vscode }: {
|
||||
const TaskItem = ({ task, columnName, customFields, position, dateFormat, vscode }: {
|
||||
task: KanbnTask,
|
||||
columnName: string,
|
||||
customFields: { name: string, type: 'boolean' | 'date' | 'number' | 'string' }[],
|
||||
position: number,
|
||||
dateFormat: string,
|
||||
vscode: VSCodeApi
|
||||
@ -38,6 +40,9 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
||||
{...provided.dragHandleProps}
|
||||
className={[
|
||||
'kanbn-task',
|
||||
`kanbn-task-column-${paramCase(columnName)}`,
|
||||
checkOverdue(task) ? 'kanbn-task-overdue' : null,
|
||||
!!completedDate ? 'kanbn-task-completed' : null,
|
||||
snapshot.isDragging ? 'drag' : null
|
||||
].filter(i => i).join(' ')}
|
||||
style={{
|
||||
@ -45,10 +50,9 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
||||
...provided.draggableProps.style
|
||||
}}
|
||||
>
|
||||
<div className="kanbn-task-row">
|
||||
<div className="kanbn-task-data kanbn-task-data-name">
|
||||
<button
|
||||
type="button"
|
||||
className="kanbn-task-name"
|
||||
onClick={() => {
|
||||
vscode.postMessage({
|
||||
command: 'kanbn.task',
|
||||
@ -61,11 +65,10 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
||||
{task.name}
|
||||
</button>
|
||||
</div>
|
||||
<div className="kanbn-task-row">
|
||||
{
|
||||
'tags' in task.metadata &&
|
||||
task.metadata.tags!.length > 0 &&
|
||||
<div className="kanbn-task-data kanbn-task-tags">
|
||||
<div className="kanbn-task-data kanbn-task-data-tags">
|
||||
{task.metadata.tags!.map(tag => {
|
||||
return (
|
||||
<span className={[
|
||||
@ -78,51 +81,108 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
||||
})}
|
||||
</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>
|
||||
<div className="kanbn-task-row">
|
||||
);
|
||||
}
|
||||
return (<></>);
|
||||
})
|
||||
}
|
||||
{
|
||||
'assigned' in task.metadata &&
|
||||
!!task.metadata.assigned &&
|
||||
<div className="kanbn-task-data kanbn-task-assigned">
|
||||
<div className="kanbn-task-data kanbn-task-data-assigned">
|
||||
<i className="codicon codicon-account"></i>{task.metadata.assigned}
|
||||
</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}
|
||||
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-comments">
|
||||
<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-sub-tasks">
|
||||
<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-workload">
|
||||
<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>
|
||||
))
|
||||
}
|
||||
{
|
||||
task.workload !== undefined &&
|
||||
task.progress !== undefined &&
|
||||
@ -131,7 +191,6 @@ const TaskItem = ({ task, position, dateFormat, vscode }: {
|
||||
}}></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Draggable>
|
||||
|
@ -220,7 +220,33 @@ body.vscode-dark .kanbn-task {
|
||||
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;
|
||||
padding: 0;
|
||||
border: none;
|
||||
@ -232,22 +258,13 @@ body.vscode-dark .kanbn-task {
|
||||
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;
|
||||
outline: none;
|
||||
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 {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
@ -291,7 +308,7 @@ body.vscode-dark .kanbn-task {
|
||||
background-color: #f42;
|
||||
}
|
||||
|
||||
.kanbn-task-overdue {
|
||||
.kanbn-task-overdue .kanbn-task-data-due {
|
||||
color: #f22 !important;
|
||||
}
|
||||
|
||||
@ -305,6 +322,30 @@ body.vscode-dark .kanbn-task {
|
||||
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
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user