From 3fee542a8fd347648dabde2cbc7565c354d55ef2 Mon Sep 17 00:00:00 2001 From: Gordon Date: Wed, 7 Apr 2021 23:30:48 +0100 Subject: [PATCH] Implement task filters --- src/Board.tsx | 106 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 14 deletions(-) diff --git a/src/Board.tsx b/src/Board.tsx index 90b5c08..f775ea7 100644 --- a/src/Board.tsx +++ b/src/Board.tsx @@ -4,6 +4,7 @@ import TaskItem from './TaskItem'; import { paramCase } from 'param-case'; import VSCodeApi from "./VSCodeApi"; +// Called when a task item has finished being dragged const onDragEnd = (result, columns, setColumns, vscode: VSCodeApi) => { // No destination means the item was dragged to an invalid location @@ -55,6 +56,78 @@ const onDragEnd = (result, columns, setColumns, vscode: VSCodeApi) => { }); }; +// 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; +}; + +// A list of property names that can be filtered +const filterProperties = [ + 'description', + 'assigned', + 'tag', + 'relation' +]; + +// Filter tasks according to the filter string +const filterTask = (task: KanbnTask, taskFilter: string) => { + let result = true; + taskFilter.split(' ').forEach(f => { + const parts = f.split(':').map(p => p.toLowerCase()); + + // This filter section doesn't contain a property name + if (parts.length === 1) { + + // Filter for overdue tasks + if (parts[0] === 'overdue') { + if (!checkOverdue(task)) { + result = false; + } + return; + } + + // Filter task id or name + if ( + !task.id.toLowerCase().includes(parts[0]) && + !task.name.toLowerCase().includes(parts[0]) + ) { + result = false; + } + return; + } + + // If this filter section contains a property name and value, check the value against the property + if (parts.length === 2 && filterProperties.indexOf(parts[0]) !== -1) { + + // Filter by property value + let propertyValue = ''; + switch (parts[0]) { + case 'description': + propertyValue = task.description; + break; + case 'assigned': + propertyValue = task.metadata.assigned || ''; + break; + case 'tag': + propertyValue = (task.metadata.tags || []).join(' '); + break; + case 'relation': + propertyValue = task.relations.map(relation => `${relation.type} ${relation.task}`).join(' '); + break; + default: break; + } + if (!propertyValue.toLowerCase().includes(parts[1])) { + result = false; + } + return; + } + }); + return result; +}; + const Board = ({ name, description, columns, startedColumns, completedColumns, dateFormat, vscode }: { name: string, description: string, @@ -65,9 +138,12 @@ const Board = ({ name, description, columns, startedColumns, completedColumns, d vscode: VSCodeApi }) => { const [, setColumns] = useState(columns); + const [taskFilter, setTaskFilter] = useState(''); - const filterTasks = () => { - console.log(); + // Called when the filter form is submitted + const filterTasks = e => { + e.preventDefault(); + setTaskFilter((document.querySelector('.kanbn-filter-input') as HTMLInputElement).value); }; return ( @@ -76,17 +152,19 @@ const Board = ({ name, description, columns, startedColumns, completedColumns, d

{name}

- - +
+ + +

@@ -143,7 +221,7 @@ const Board = ({ name, description, columns, startedColumns, completedColumns, d snapshot.isDraggingOver ? 'drag-over' : null ].filter(i => i).join(' ')} > - {column.map((task, position) => filterTask(task, taskFilter)).map((task, position) =>