Styling and tidying up

This commit is contained in:
Gordon 2021-04-19 03:38:57 +01:00
parent d417b6ec7f
commit 5632f35130
3 changed files with 90 additions and 30 deletions

View File

@ -144,6 +144,7 @@ export default class KanbnTaskPanel {
this._panel.webview.onDidReceiveMessage( this._panel.webview.onDidReceiveMessage(
async (message) => { async (message) => {
switch (message.command) { switch (message.command) {
// Display error message // Display error message
case "error": case "error":
vscode.window.showErrorMessage(message.text); vscode.window.showErrorMessage(message.text);

View File

@ -2,11 +2,10 @@ import React, { useState, useEffect } from 'react';
import { ResponsiveContainer, LineChart, Line, CartesianGrid, XAxis, YAxis, Tooltip } from 'recharts'; import { ResponsiveContainer, LineChart, Line, CartesianGrid, XAxis, YAxis, Tooltip } from 'recharts';
import VSCodeApi from "./VSCodeApi"; import VSCodeApi from "./VSCodeApi";
import formatDate from 'dateformat'; import formatDate from 'dateformat';
import dateFormat from 'dateformat'; import { debounce } from 'throttle-debounce';
const Burndown = ({ name, tasks, sprints, burndownData, dateFormat, vscode }: { const Burndown = ({ name, sprints, burndownData, dateFormat, vscode }: {
name: string, name: string,
tasks: Record<string, KanbnTask>,
sprints: KanbnSprint[], sprints: KanbnSprint[],
burndownData: { burndownData: {
series: Array<{ series: Array<{
@ -29,58 +28,94 @@ const Burndown = ({ name, tasks, sprints, burndownData, dateFormat, vscode }: {
}) => { }) => {
const hasSprints = sprints.length > 0; const hasSprints = sprints.length > 0;
const [sprintMode, setSprintMode] = useState(hasSprints); const [sprintMode, setSprintMode] = useState(hasSprints);
const [sprint, setSprint] = useState(sprintMode ? burndownData.series[0].sprint.name : ''); const [sprint, setSprint] = useState((sprintMode && hasSprints) ? sprints[sprints.length - 1].name : '');
const [startDate, setStartDate] = useState(sprintMode ? '' : formatDate(burndownData.series[0].from, 'yyyy-mm-dd')); const [startDate, setStartDate] = useState(
const [endDate, setEndDate] = useState(sprintMode ? '' : formatDate(burndownData.series[0].to, 'yyyy-mm-dd')); (sprintMode && burndownData.series.length > 0)
const [assigned, setAssigned] = useState(''); ? ''
: formatDate(burndownData.series[0].from, 'yyyy-mm-dd')
);
const [endDate, setEndDate] = useState(
(sprintMode && burndownData.series.length > 0)
? ''
: formatDate(burndownData.series[0].to, 'yyyy-mm-dd')
);
const refreshBurndownData = () => { const refreshBurndownData = debounce(500, settings => {
vscode.postMessage({ vscode.postMessage({
command: 'kanbn.refreshBurndownData', command: 'kanbn.refreshBurndownData',
sprintMode, ...Object.assign(
sprint, {
startDate, sprintMode,
endDate, sprint,
assigned startDate,
endDate
},
settings
)
}); });
}; });
const handleChangeSprint = ({ target: { value }}) => { const handleChangeSprint = ({ target: { value }}) => {
setSprint(value); setSprint(value);
refreshBurndownData(); refreshBurndownData({ sprint: value });
}; };
const handleChangeStartDate = ({ target: { value }}) => { const handleChangeStartDate = ({ target: { value }}) => {
setStartDate(value); setStartDate(value);
refreshBurndownData(); refreshBurndownData({ startDate: value });
}; };
const handleChangeEndDate = ({ target: { value }}) => { const handleChangeEndDate = ({ target: { value }}) => {
setEndDate(value); setEndDate(value);
refreshBurndownData(); refreshBurndownData({ endDate: value });
}; };
const handleClickSprintMode = () => { const handleClickSprintMode = () => {
setSprintMode(true); setSprintMode(true);
refreshBurndownData(); refreshBurndownData({ sprintMode: true });
}; };
const handleClickDateMode = () => { const handleClickDateMode = () => {
setSprintMode(false); setSprintMode(false);
refreshBurndownData(); refreshBurndownData({ sprintMode: false });
}; };
const chartMin = Date.parse(burndownData.series[0].from); const chartMin = burndownData.series.length > 0
const chartMax = Date.parse(burndownData.series[0].to); ? Date.parse(burndownData.series[0].from)
const chartData = burndownData.series[0].dataPoints.map(dataPoint => ({ : 'auto';
x: Date.parse(dataPoint.x), const chartMax = burndownData.series.length > 0
y: dataPoint.y, ? Date.parse(burndownData.series[0].to)
'Active tasks': dataPoint.count, : 'auto';
'Activity': dataPoint.tasks.map(task => `${task.eventType} ${task.taskId}`).join('\n') const chartData = burndownData.series.length > 0
})); ? burndownData.series[0].dataPoints.map(dataPoint => ({
x: Date.parse(dataPoint.x),
y: dataPoint.y,
count: dataPoint.count,
tasks: dataPoint.tasks,
}))
: [];
const formatXAxis = date => formatDate(date, dateFormat); const formatXAxis = date => formatDate(date, dateFormat);
const renderTooltip = e => {
if (e.active && e.payload && e.payload.length) {
const data = e.payload[0].payload;
return (
<div className="kanbn-burndown-tooltip">
<p className="kanbn-burndown-tooltip-date">{formatDate(data.x, dateFormat)}</p>
<p className="kanbn-burndown-tooltip-workload">Total workload: {data.y}</p>
<p className="kanbn-burndown-tooltip-count">Active tasks: {data.count}</p>
{data.tasks.map(task => (
<p className="kanbn-burndown-tooltip-task">
{{ started: 'Started', completed: 'Completed' }[task.eventType]} {task.task.name}
</p>
))}
</div>
)
}
return null;
};
return ( return (
<React.Fragment> <React.Fragment>
<div className="kanbn-header"> <div className="kanbn-header">
@ -151,11 +186,17 @@ const Burndown = ({ name, tasks, sprints, burndownData, dateFormat, vscode }: {
<div className="kanbn-burndown"> <div className="kanbn-burndown">
<ResponsiveContainer width="100%" height="100%" className="kanbn-burndown-chart"> <ResponsiveContainer width="100%" height="100%" className="kanbn-burndown-chart">
<LineChart data={chartData}> <LineChart data={chartData}>
<Line className="kanbn-burndown-line" type="monotone" dataKey="y" /> <Line className="kanbn-burndown-line" type="stepAfter" dataKey="y" />
<CartesianGrid className="kanbn-burndown-grid" strokeDasharray="5 5" vertical={false} /> <CartesianGrid className="kanbn-burndown-grid" strokeDasharray="5 5" vertical={false} />
<XAxis dataKey="x" type="number" domain={[chartMin, chartMax]} tickFormatter={formatXAxis} /> <XAxis
dataKey="x"
type="number"
domain={[chartMin, chartMax]}
tickFormatter={formatXAxis}
tickCount={6}
/>
<YAxis /> <YAxis />
<Tooltip /> <Tooltip content={renderTooltip} />
</LineChart> </LineChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>

View File

@ -545,3 +545,21 @@ body.vscode-dark .kanbn-burndown-settings-input[type="date"]::-webkit-calendar-p
.kanbn-burndown-line path { .kanbn-burndown-line path {
stroke: #3c7; stroke: #3c7;
} }
.kanbn-burndown-tooltip {
background-color: var(--vscode-menu-background);
color: var(--vscode-menu-foreground);
padding: 8px;
}
.kanbn-burndown-tooltip p {
margin: 0;
}
.kanbn-burndown-tooltip-date {
font-weight: bold;
}
.kanbn-burndown-tooltip-task {
font-style: italic;
}