Add project Schedule page with interactive Gantt chart

Adds a Schedule tab (Kitsu-style production schedule) under each
project: tasks grouped by type with drag-to-reschedule bars, Day/Week/
Month zoom, manual date-range control, weekend shading, a frozen task
column, and a two-tier month/date axis header. Requires a new
start_date field on Task (start_date was previously missing; only
deadline existed) and shadcn DatePicker inputs replace native date
inputs on the Schedule toolbar and TaskDetailPanel's Start Date/
Deadline fields.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 04:10:43 +08:00
parent 981808b901
commit f547d05478
11 changed files with 967 additions and 19 deletions
+6
View File
@@ -248,6 +248,7 @@ async def get_tasks(
"name": task.name,
"task_type": task.task_type,
"status": task.status,
"start_date": task.start_date,
"deadline": task.deadline,
"project_id": task.project_id,
"project_name": task.project.name if task.project else None,
@@ -329,6 +330,7 @@ async def get_my_tasks(
name=task.name,
task_type=task.task_type,
status=task.status,
start_date=task.start_date,
deadline=task.deadline,
project_id=task.project_id,
project_name=task.project.name if task.project else "Unknown",
@@ -718,6 +720,7 @@ async def get_task(
"description": task.description,
"task_type": task.task_type,
"status": task.status,
"start_date": task.start_date,
"deadline": task.deadline,
"project_id": task.project_id,
"episode_id": task.episode_id,
@@ -843,6 +846,7 @@ async def update_task(
"description": task.description,
"task_type": task.task_type,
"status": task.status,
"start_date": task.start_date,
"deadline": task.deadline,
"project_id": task.project_id,
"episode_id": task.episode_id,
@@ -934,6 +938,7 @@ async def update_task_status(
"description": task.description,
"task_type": task.task_type,
"status": task.status,
"start_date": task.start_date,
"deadline": task.deadline,
"project_id": task.project_id,
"episode_id": task.episode_id,
@@ -1039,6 +1044,7 @@ async def assign_task(
"description": task.description,
"task_type": task.task_type,
"status": task.status,
"start_date": task.start_date,
"deadline": task.deadline,
"project_id": task.project_id,
"episode_id": task.episode_id,