-
Notifications
You must be signed in to change notification settings - Fork 10
Open
Description
- StatusFilter component, to filter tasks by status
- Should be analogous to a Gmail-style check list, with all boxes checked by default
-
AssignerFiltercomponent, which filters task by assignee (task.assigned_to)- Should be a multi-select with no boxes checked by default
By default, show all tasks with all statuses and assignees (or no assignee).
Potential special case: if no username is specified in its filter/search component, include all tasks, not just tasks assigned to usernames in an empty array, which would show no tasks rather than all of them :-).
Should be able to tweak then reuse the filtering logic from the RightPanel TaskDetails:
effective/src/components/Content/RightPanel/TaskList/TaskList.js
Lines 120 to 224 in f1b18c1
| taskMatches = (tasks) => { | |
| const { taskListFilter } = this.props.rightPanel; | |
| const taskListFilterTrimmed = taskListFilter.trim(); | |
| const filters = this.parseTaskListFilter(); | |
| const matches = {}; | |
| let task; | |
| let status; | |
| let statusNot; | |
| let assigned_to; | |
| let dueBefore; | |
| let due_date; | |
| let dueAfter; | |
| gidInTasks: | |
| for (let gid in tasks) { | |
| if (taskListFilterTrimmed === '') { | |
| matches[gid] = true; | |
| continue; | |
| } | |
| task = tasks[gid]; | |
| let matchStatus = false; | |
| let matchAssignedTo = false; | |
| let matchDueDate = false; | |
| let matchTitle = false; | |
| const taskStatusLower = task.status.toLowerCase(); | |
| for (let i in filters.status) { | |
| status = filters.status[i]; | |
| if (taskStatusLower.startsWith(status.toLowerCase())) { | |
| matchStatus = true; | |
| break; | |
| } | |
| } | |
| if (!matchStatus && filters.status.length > 0) { | |
| // Status didn't match && filtering on status => Not an overall match | |
| continue; | |
| } | |
| for (let i in filters.statusNot) { | |
| statusNot = filters.statusNot[i]; | |
| if (taskStatusLower.startsWith(statusNot.toLowerCase())) { | |
| // Not all anti-statuses matched && filtering on not-status | |
| // => Not an overall match | |
| continue gidInTasks; | |
| } | |
| } | |
| for (let i in filters.assigned_to) { | |
| assigned_to = filters.assigned_to[i]; | |
| if (task.assigned_to_pursuance_id === null | |
| && | |
| ((task.assigned_to || '').startsWith(assigned_to) | |
| || | |
| (task.assigned_to === null && | |
| assigned_to === '-'))) { | |
| matchAssignedTo = true; | |
| break; | |
| } | |
| } | |
| if (!matchAssignedTo && filters.assigned_to.length > 0) { | |
| // Assignee didn't match && filtering on assignee => Not an overall match | |
| continue; | |
| } | |
| for (let i in filters.due_date) { | |
| due_date = filters.due_date[i]; | |
| if ((task.due_date || '').startsWith(due_date) || | |
| (task.due_date === null && due_date === '-')) { | |
| matchDueDate = true; | |
| break; | |
| } | |
| } | |
| if (!matchDueDate && filters.due_date.length > 0) { | |
| // Due date didn't match && filtering on due date => Not an overall match | |
| continue; | |
| } | |
| for (let i in filters.dueBefore) { | |
| dueBefore = filters.dueBefore[i]; | |
| // Treating null as neither before nor after any date | |
| if (!task.due_date || task.due_date.localeCompare(dueBefore) >= 0) { | |
| continue gidInTasks; | |
| } | |
| } | |
| for (let i in filters.dueAfter) { | |
| dueAfter = filters.dueAfter[i]; | |
| // Treating null as after all dates | |
| if (task.due_date && task.due_date.localeCompare(dueAfter) < 0) { | |
| continue gidInTasks; | |
| } | |
| } | |
| if (task.title.toLowerCase().indexOf(filters.title.toLowerCase()) !== -1) { | |
| matchTitle = true; | |
| } | |
| if (!matchTitle && filters.title.length > 0) { | |
| // Title didn't match && filtering on title => Not an overall match | |
| continue; | |
| } | |
| matches[gid] = true; | |
| } | |
| return matches; | |
| } |
@Iancam Here you go!
Metadata
Metadata
Assignees
Labels
No labels