Task markup and styling

This commit is contained in:
Gordon 2021-04-02 02:30:41 +01:00
parent 7f8d67b551
commit b2fc0be4f2
7 changed files with 278 additions and 103 deletions

View File

@ -1,5 +1,6 @@
import * as path from 'path';
import * as vscode from 'vscode';
import KanbnTaskPanel from './KanbnTaskPanel';
export default class KanbnBoardPanel {
public static currentPanel: KanbnBoardPanel | undefined;
@ -101,7 +102,12 @@ export default class KanbnBoardPanel {
return;
case 'kanbn.task':
// TODO open task panel with task
// KanbnTaskPanel.create(
// this._extensionPath,
// this._workspacePath,
// this._kanbn,
// message.taskId
// );
vscode.window.showInformationMessage(`Opening task ${message.taskId}`);
return;

61
package-lock.json generated
View File

@ -7101,6 +7101,39 @@
"domelementtype": "1"
}
},
"dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"requires": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
},
"dependencies": {
"lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"requires": {
"tslib": "^2.0.3"
}
},
"no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"requires": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"tslib": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
"integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
}
}
},
"dot-prop": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@ -10111,6 +10144,17 @@
"param-case": "2.1.x",
"relateurl": "0.2.x",
"uglify-js": "3.4.x"
},
"dependencies": {
"param-case": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
"integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
"dev": true,
"requires": {
"no-case": "^2.2.0"
}
}
}
},
"html-webpack-plugin": {
@ -13314,12 +13358,19 @@
}
},
"param-case": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
"integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
"dev": true,
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"requires": {
"no-case": "^2.2.0"
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
},
"dependencies": {
"tslib": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
"integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
}
}
},
"parent-module": {

View File

@ -27,6 +27,7 @@
"@basementuniverse/kanbn": "file:~/Projects/kanbn",
"@types/dateformat": "^3.0.1",
"dateformat": "^4.5.1",
"param-case": "^3.0.4",
"react": "^16.3.2",
"react-beautiful-dnd": "12.2.0",
"react-dom": "^16.3.2",

View File

@ -2,6 +2,7 @@ import { DragDropContext, Droppable } from "react-beautiful-dnd";
import React, { useState } from "react";
import Task from './Task';
import VSCodeApi from "./VSCodeApi";
import { paramCase } from 'param-case';
declare var acquireVsCodeApi: Function;
const vscode: VSCodeApi = acquireVsCodeApi();
@ -77,7 +78,10 @@ const Board = ({ columns, startedColumns, completedColumns, dateFormat }: {
{Object.entries(columns).map(([columnName, column]) => {
return (
<div
className="kanbn-column"
className={[
'kanbn-column',
`kanbn-column-${paramCase(columnName)}`
].join(' ')}
style={{
flex: 1
}}
@ -86,11 +90,11 @@ const Board = ({ columns, startedColumns, completedColumns, dateFormat }: {
<h2 className="kanbn-column-name">
{
startedColumns.indexOf(columnName) > -1 &&
<i className="codicon codicon-chevron-right"></i>
<i className="kanbn-column-icon codicon codicon-chevron-right"></i>
}
{
completedColumns.indexOf(columnName) > -1 &&
<i className="codicon codicon-check"></i>
<i className="kanbn-column-icon codicon codicon-check"></i>
}
{columnName}
<span className="kanbn-column-count">{column.length || ''}</span>

1
src/KanbnTask.d.ts vendored
View File

@ -9,6 +9,7 @@ declare type KanbnTask = {
metadata: {
created: Date,
updated?: Date,
started?: Date,
completed?: Date,
assigned?: string,
tags?: string[]

View File

@ -9,6 +9,10 @@ const Task = ({ task, index, dateFormat, vscode }: {
dateFormat: string,
vscode: VSCodeApi
}) => {
const createdDate = 'created' in task.metadata ? formatDate(task.metadata.created, dateFormat) : '';
const updatedDate = 'updated' in task.metadata ? formatDate(task.metadata.updated, dateFormat) : '';
const startedDate = 'started' in task.metadata ? formatDate(task.metadata.started, dateFormat) : '';
const completedDate = 'completed' in task.metadata ? formatDate(task.metadata.completed, dateFormat) : '';
return (
<Draggable
key={task.id}
@ -30,6 +34,7 @@ const Task = ({ task, index, dateFormat, vscode }: {
...provided.draggableProps.style
}}
>
<div className="kanbn-task-row">
<button
type="button"
className="kanbn-task-name"
@ -43,9 +48,11 @@ const Task = ({ task, index, dateFormat, vscode }: {
>
{task.name}
</button>
</div>
<div className="kanbn-task-row">
{
'tags' in task.metadata &&
<div className="kanbn-task-tags">
<div className="kanbn-task-data kanbn-task-tags">
{task.metadata.tags!.map(tag => {
return (
<span className={[
@ -58,38 +65,41 @@ const Task = ({ task, index, dateFormat, vscode }: {
})}
</div>
}
</div>
<div className="kanbn-task-row">
{
'assigned' in task.metadata &&
<div className="kanbn-task-assigned">
<div className="kanbn-task-data kanbn-task-assigned">
<i className="codicon codicon-account"></i>{task.metadata.assigned}
</div>
}
<div className="kanbn-task-date">
{
'updated' in task.metadata
? formatDate(task.metadata.updated, dateFormat)
: formatDate(task.metadata.created, dateFormat)
(createdDate || updatedDate) &&
<div className="kanbn-task-data kanbn-task-date" title={[
createdDate ? `Created ${createdDate}` : null,
updatedDate ? `Updated ${updatedDate}` : null,
startedDate ? `Started ${startedDate}` : null,
completedDate ? `Completed ${completedDate}` : null
].filter(i => i).join('\n')}>
<i className="codicon codicon-clock"></i>{updatedDate || createdDate}
</div>
}
</div>
<div className="kanbn-task-description">
{task.description}
</div>
{
task.comments.length > 0 &&
<div className="kanbn-task-comments">
<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-sub-tasks">
<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-workload">
<div className="kanbn-task-data kanbn-task-workload">
<i className="codicon codicon-run"></i>{task.workload}
</div>
}
@ -101,6 +111,7 @@ const Task = ({ task, index, dateFormat, vscode }: {
}}></div>
}
</div>
</div>
);
}}
</Draggable>

View File

@ -1,17 +1,3 @@
/*
--vscode-editor-background
--vscode-editor-foreground
--vscode-foreground
--vscode-activityBar-background
--vscode-activityBar-foreground
--vscode-activityBar-inactiveForeground
--vscode-button-background
--vscode-button-foreground
--vscode-button-hoverBackground
*/
body {
margin: 0;
padding: 1em;
@ -37,16 +23,35 @@ body {
padding-left: 8px;
}
.kanbn-column-icon {
font-size: 0.8em !important;
margin-right: 0.5em;
}
.kanbn-create-task-button {
position: relative;
top: -2px;
left: -4px;
float: right;
border: none;
outline: none;
color: var(--vscode-foreground);
background-color: transparent;
padding: 2px;
height: 16px;
width: 16px;
margin-right: 8px;
}
.kanbn-create-task-button:focus, .kanbn-create-task-button:hover {
border: none;
outline: none;
color: var(--vscode-editor-background);
background-color: var(--vscode-foreground);
}
.kanbn-create-task-button .codicon {
font-size: 14px;
}
.kanbn-column:first-child .kanbn-column-name {
padding-left: 0;
font-size: 11px !important;
}
.kanbn-column-count {
@ -61,32 +66,62 @@ body {
border-left: 3px var(--vscode-activityBar-inactiveForeground) solid;
}
.kanbn-column:first-child .kanbn-column-task-list {
margin-left: 0;
}
.kanbn-column:last-child .kanbn-column-task-list {
margin-right: 0;
}
.kanbn-column-task-list.drag-over {
border-color: var(--vscode-activityBar-foreground);
}
.kanbn-column-backlog .kanbn-column-task-list {
border-color: #36d;
}
.kanbn-column-backlog .kanbn-column-task-list.drag-over {
border-color: #69f;
}
.kanbn-column-in-progress .kanbn-column-task-list {
border-color: #194;
}
.kanbn-column-in-progress .kanbn-column-task-list.drag-over {
border-color: #3c7;
}
.kanbn-column-todo .kanbn-column-task-list {
border-color: #eb1;
}
.kanbn-column-todo .kanbn-column-task-list.drag-over {
border-color: #fe5;
}
.kanbn-column-done .kanbn-column-task-list {
border-color: #e83;
}
.kanbn-column-done .kanbn-column-task-list.drag-over {
border-color: #fa4;
}
.kanbn-task {
position: relative;
overflow: hidden;
padding: 4px;
margin: 8px;
min-height: 50px;
min-height: 30px;
border: 1px var(--vscode-activityBar-inactiveForeground) solid;
border-radius: 2px;
color: var(--vscode-editor-foreground);
transition: background-color .5s ease-in-out;
}
.kanbn-task.drag {
background-color: var(--vscode-activityBar-inactiveForeground);
border-color: var(--vscode-activityBar-activeBackground);
}
.kanbn-task-name {
margin: 0;
padding: 0;
border: none;
outline: none;
background-color: transparent;
@ -99,3 +134,69 @@ body {
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;
font-size: 0.9em !important;
margin-right: 4px;
}
.kanbn-task-tag {
display: inline-block;
background-color: var(--vscode-activityBar-inactiveForeground);
color: var(--vscode-editor-background);
font-weight: bold;
padding: 2px 4px;
margin: 4px 4px 4px 0;
border-radius: 2px;
}
.kanbn-task-tag-Nothing {
background-color: #aab;
color: #333;
}
.kanbn-task-tag-Tiny {
background-color: #36d;
color: #333;
}
.kanbn-task-tag-Small {
background-color: #194;
color: #333;
}
.kanbn-task-tag-Medium {
background-color: #eb1;
color: #333;
}
.kanbn-task-tag-Large {
background-color: #e83;
color: #333;
}
.kanbn-task-tag-Huge {
background-color: #f42;
color: #333;
}
.kanbn-task-progress {
position: absolute;
bottom: -2px;
left: 0;
height: 4px;
background-color: #3c7;
opacity: 0.7;
}