diff --git a/package.json b/package.json index 78ea268..0e5c991 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.55.1", + "version": "1.55.2", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/app/globals.css b/src/app/globals.css index b7e7484..6029a7f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1952,6 +1952,73 @@ h3 { } /* Kanban stage color indicator on weekly tasks */ +.kanban-card-subtask-toggle { + margin-top: 4px; +} +.kanban-card-subtask-btn { + display: flex; + align-items: center; + gap: 6px; + background: none; + border: none; + cursor: pointer; + padding: 3px 0; + color: var(--weekly-text-muted, #9ca3af); + font-size: 0.7rem; + font-weight: 600; + width: 100%; +} +.kanban-card-subtask-btn:hover { + color: var(--weekly-text, #666); +} +.kanban-card-subtask-bar { + flex: 1; + height: 4px; + border-radius: 2px; + background: var(--weekly-border, #e5e7eb); + position: relative; + overflow: hidden; + max-width: 60px; +} +.kanban-card-subtask-bar-fill { + position: absolute; + left: 0; + top: 0; + height: 100%; + border-radius: 2px; + transition: width 0.3s ease; +} +.kanban-card-subtask-count { + font-size: 0.7rem; + opacity: 0.8; +} +.kanban-card-subtask-list { + display: flex; + flex-direction: column; + gap: 2px; + padding: 4px 0 2px 2px; +} +.kanban-card-subtask-item { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.75rem; + color: var(--weekly-text, #333); + padding: 1px 0; +} +.kanban-card-subtask-item input[type="checkbox"] { + width: 13px; + height: 13px; + cursor: pointer; + flex-shrink: 0; +} +.kanban-card-subtask-item.completed { + opacity: 0.5; +} +.kanban-card-subtask-done { + text-decoration: line-through; +} + .kanban-stage-indicator { width: 4px; border-radius: 2px; diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index df07317..da371c6 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -2078,6 +2078,7 @@ export default function WeeklyView() { const [kanbanAddingStageId, setKanbanAddingStageId] = useState(null); const [kanbanNewTaskTitle, setKanbanNewTaskTitle] = useState(""); const [kanbanDetailTask, setKanbanDetailTask] = useState(null); + const [kanbanExpandedCards, setKanbanExpandedCards] = useState>(new Set()); const [protectEventTimes, setProtectEventTimes] = useState(false); const [unlockedEvents, setUnlockedEvents] = useState>(new Set()); @@ -6447,7 +6448,15 @@ export default function WeeklyView() { return true; }); - const renderKanbanCard = (task: Task) => ( + const renderKanbanCard = (task: Task) => { + const subTasks = task.subTasks || []; + const subCompleted = subTasks.filter(s => s.completed).length; + const subTotal = subTasks.length; + const subPct = subTotal > 0 ? (subCompleted / subTotal) * 100 : 0; + const allSubDone = subTotal > 0 && subCompleted === subTotal; + const isExpanded = kanbanExpandedCards.has(task.id); + + return (
{ - // Don't open detail if clicking checkbox, contentEditable, or buttons const target = e.target as HTMLElement; - if (target.tagName === "INPUT" || target.contentEditable === "true" || target.closest("button")) return; + if (target.tagName === "INPUT" || target.contentEditable === "true" || target.closest("button") || target.closest(".kanban-card-subtask-list")) return; setKanbanDetailTask(task); }} style={{ cursor: "pointer" }} @@ -6488,9 +6496,42 @@ export default function WeeklyView() { {task.title}
- {task.subTasks && task.subTasks.length > 0 && ( -
- {task.subTasks.filter(st => st.completed).length}/{task.subTasks.length} {language === "de" ? "Unteraufgaben" : "subtasks"} + {subTotal > 0 && ( +
e.stopPropagation()}> + + {isExpanded && ( +
+ {subTasks.map(sub => ( +
+ toggleSubTask(sub.id)} + style={{ accentColor: "var(--weekly-accent, #6366f1)" }} + /> + {sub.title} +
+ ))} +
+ )}
)} {task.markdownContent && ( @@ -6514,7 +6555,8 @@ export default function WeeklyView() { return list ?
{list.title}
: null; })()}
- ); + ); + }; const kanbanColumnDrop = (stageId: string | null) => ({ onDragOver: (e: React.DragEvent) => { @@ -9710,9 +9752,9 @@ function TaskItem({ display: "inline-flex", alignItems: "center", gap: "4px", - padding: "2px 8px 2px 6px", + padding: "2px 8px 2px 4px", borderRadius: "12px", - background: "transparent", + background: expanded ? "rgba(99,102,241,0.08)" : "transparent", color: allDone ? "var(--weekly-teal, #0d9488)" : "var(--weekly-text-light, #9ca3af)", border: "none", cursor: "pointer", @@ -9721,17 +9763,14 @@ function TaskItem({ lineHeight: 1, flexShrink: 0, whiteSpace: "nowrap", - transition: "color 0.15s", + transition: "all 0.15s", }} > - - - - {/* Mini progress bar */} +