feat(tasks): remember list or Kanban per task list
Each task list (and "Alle Aufgaben") keeps its own view on this device; a single remembered Kanban view from before carries over to its list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c2aff2ced6
commit
886fb2c711
1 file changed
+38
-8
@@ -92,7 +92,15 @@ const kanbanBoardStyle = (wide: boolean, columns: number): React.CSSProperties =
|
||||
};
|
||||
|
||||
type GroupBy = 'none' | 'list' | 'tag' | 'status' | 'priority' | 'due';
|
||||
type TasksSession = { listId: string; viewMode: 'list' | 'kanban'; groupAll: GroupBy; groupList: GroupBy };
|
||||
type ViewMode = 'list' | 'kanban';
|
||||
// viewModes: list or Kanban per task list ("all" for Alle Aufgaben); viewMode is the old single value
|
||||
type TasksSession = {
|
||||
listId: string;
|
||||
viewModes: Record<string, ViewMode>;
|
||||
viewMode?: ViewMode;
|
||||
groupAll: GroupBy;
|
||||
groupList: GroupBy;
|
||||
};
|
||||
|
||||
// "Alle Aufgaben" is grouped by task list unless the user picks something else; a single list has no
|
||||
// grouping by default (grouping it by list would give one group)
|
||||
@@ -123,11 +131,20 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
onInitialTaskShown,
|
||||
openTasksCount,
|
||||
}) => {
|
||||
// Open list, view and grouping are remembered on this device (new tab, restart of the installed app)
|
||||
// Open list, view per list and grouping are remembered on this device (new tab, restart of the
|
||||
// installed app)
|
||||
const remembered = useMemo(() => readViewMemory<TasksSession>('tasks'), []);
|
||||
const [viewMode, setViewMode] = useState<'list' | 'kanban'>(() =>
|
||||
remembered.viewMode === 'kanban' ? 'kanban' : 'list'
|
||||
);
|
||||
const [viewModes, setViewModes] = useState<Record<string, ViewMode>>(() => {
|
||||
const out: Record<string, ViewMode> = {};
|
||||
if (remembered.viewModes && typeof remembered.viewModes === 'object') {
|
||||
for (const [id, mode] of Object.entries(remembered.viewModes)) {
|
||||
if (mode === 'kanban') out[id] = 'kanban';
|
||||
}
|
||||
} else if (remembered.viewMode === 'kanban' && remembered.listId) {
|
||||
out[remembered.listId] = 'kanban'; // stored before views were kept per list
|
||||
}
|
||||
return out;
|
||||
});
|
||||
const [groupAll, setGroupAll] = useState<GroupBy>(() =>
|
||||
remembered.groupAll && remembered.groupAll in GROUP_LABELS ? remembered.groupAll : DEFAULT_GROUP_ALL
|
||||
);
|
||||
@@ -153,13 +170,25 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
// only a convenience
|
||||
}
|
||||
};
|
||||
const isKanbanWide = viewMode === 'kanban' && kanbanWide;
|
||||
const [filter, setFilter] = useState<'open' | 'done' | 'discarded'>('open');
|
||||
const [tasks, setTasks] = useState<Thought[]>([]);
|
||||
const [taskLists, setTaskLists] = useState<TaskList[]>([]);
|
||||
const [selectedListId, setSelectedListId] = useState<string>(
|
||||
() => remembered.listId || 'all'
|
||||
);
|
||||
const viewMode: ViewMode = viewModes[selectedListId] || 'list';
|
||||
// Only Kanban is stored; the list view is the default
|
||||
const setViewMode = useCallback(
|
||||
(mode: ViewMode) =>
|
||||
setViewModes((prev) => {
|
||||
const next = { ...prev };
|
||||
if (mode === 'kanban') next[selectedListId] = 'kanban';
|
||||
else delete next[selectedListId];
|
||||
return next;
|
||||
}),
|
||||
[selectedListId]
|
||||
);
|
||||
const isKanbanWide = viewMode === 'kanban' && kanbanWide;
|
||||
const isAllTasks = selectedListId === 'all';
|
||||
const groupBy: GroupBy = isAllTasks ? groupAll : groupList;
|
||||
const setGroupBy = (g: GroupBy) => (isAllTasks ? setGroupAll(g) : setGroupList(g));
|
||||
@@ -169,8 +198,8 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
.filter((id) => isAllTasks || id !== 'list')
|
||||
.map((id) => ({ id, label: GROUP_LABELS[id] }));
|
||||
useEffect(() => {
|
||||
writeViewMemory<TasksSession>('tasks', { listId: selectedListId, viewMode, groupAll, groupList });
|
||||
}, [selectedListId, viewMode, groupAll, groupList]);
|
||||
writeViewMemory<TasksSession>('tasks', { listId: selectedListId, viewModes, groupAll, groupList });
|
||||
}, [selectedListId, viewModes, groupAll, groupList]);
|
||||
const [teams, setTeams] = useState<Team[]>([]);
|
||||
const [collaborators, setCollaborators] = useState<User[]>([]);
|
||||
// Task trash of the selected list (or all): deleted tasks and cleared or cleaned-up completed ones
|
||||
@@ -1538,6 +1567,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
selectedTag,
|
||||
groupBy,
|
||||
defaultGroupBy,
|
||||
setViewMode,
|
||||
sortBy,
|
||||
openTasks.length,
|
||||
doneTasks.length,
|
||||
|
||||
Reference in new issue
Block a user