sort task groups reverse alphabetically by their status (#6886)

This PR Solves #6830 

## Issue Summary
The tasks are grouped by their respective statuses and displayed on the
ui. The grouping is performed by `lodash.groupBy` which doesn't maintain
explicit ordering of the keys.

## Fix
Sort the tasks groups array by their status on the basis of
reverse-alphabetical order before generating task component for each
task data.

#### Why reverse alphabetical?
It implicitly sorts the statuses as per the order `TODO` ->
`IN_PROGRESS` -> `DONE`
Caveats:
1. Changing the name of one or more status might result in a different
unwanted order.
2. `null` is unhandled, although the original code doesn't allow for
nulls as status while displaying

### Alternative Fix
Maintain an explicit ordering of the statuses and sort the tasks
accordingly.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Avinash Bhardwaj
2024-09-09 19:26:52 +05:30
committed by GitHub
parent b01745dba7
commit 1ff31a90f4
2 changed files with 23 additions and 14 deletions

View File

@ -91,22 +91,24 @@ export const TaskGroups = ({
); );
} }
const sortedTasksByStatus = Object.entries(
groupBy(tasks, ({ status }) => status),
).toSorted(([statusA], [statusB]) => statusB.localeCompare(statusA));
return ( return (
<StyledContainer> <StyledContainer>
{Object.entries(groupBy(tasks, ({ status }) => status)).map( {sortedTasksByStatus.map(([status, tasksByStatus]: [string, Task[]]) => (
([status, tasksByStatus]: [string, Task[]]) => ( <TaskList
<TaskList key={status}
key={status} title={status}
title={status} tasks={tasksByStatus}
tasks={tasksByStatus} button={
button={ showAddButton && (
showAddButton && ( <AddTaskButton activityTargetableObjects={targetableObjects} />
<AddTaskButton activityTargetableObjects={targetableObjects} /> )
) }
} />
/> ))}
),
)}
</StyledContainer> </StyledContainer>
); );
}; };

View File

@ -36,6 +36,8 @@ const StyledTaskBody = styled.div`
max-width: 100%; max-width: 100%;
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
padding-bottom: ${({ theme }) => theme.spacing(0.25)};
`; `;
const StyledTaskTitle = styled.div<{ const StyledTaskTitle = styled.div<{
@ -44,10 +46,13 @@ const StyledTaskTitle = styled.div<{
color: ${({ theme }) => theme.font.color.primary}; color: ${({ theme }) => theme.font.color.primary};
font-weight: ${({ theme }) => theme.font.weight.medium}; font-weight: ${({ theme }) => theme.font.weight.medium};
padding: 0 ${({ theme }) => theme.spacing(2)}; padding: 0 ${({ theme }) => theme.spacing(2)};
padding-bottom: ${({ theme }) => theme.spacing(0.25)};
text-decoration: ${({ completed }) => (completed ? 'line-through' : 'none')}; text-decoration: ${({ completed }) => (completed ? 'line-through' : 'none')};
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
align-items: center;
`; `;
const StyledDueDate = styled.div<{ const StyledDueDate = styled.div<{
@ -71,8 +76,10 @@ const StyledPlaceholder = styled.div`
`; `;
const StyledLeftSideContainer = styled.div` const StyledLeftSideContainer = styled.div`
align-items: center;
display: flex; display: flex;
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
`; `;