[PR #2294] [CLOSED] Feature/gantt ux duplicate tasks template tasks autogenerate task chain tasks #9885

Closed
opened 2026-04-23 09:15:55 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/go-vikunja/vikunja/pull/2294
Author: @trbom5c
Created: 2/25/2026
Status: Closed

Base: mainHead: feature/ganttUX-duplicateTasks-templateTasks-autogenerateTask-chainTasks


📝 Commits (10+)

  • 044f2f3 fix(task): require explicit confirmation before saving reminders
  • a200b5e test(task): add e2e tests for reminder confirm-before-save behavior
  • afe449c fix(test): update existing reminder tests to click Confirm after date selection
  • 1e446b5 fix(task): disable Confirm button when no date is selected in absolute reminder picker
  • b8cd3af fix: prevent cursor reset when typing in filter input (#2287)
  • 1cf0b62 fix: wait for router before dismissing loading screen
  • 0fbe708 fix: replace tx.Sync() with explicit ALTER TABLE in webhooks migration
  • bdaa627 fix: make teams oidc_id rename migration idempotent
  • d579e58 fix: add comprehensive catchup for bucket and filter format migrations
  • 9adb1f9 fix: cast bucket_configuration to text in postgres catchup query

📊 Changes

184 files changed (+51852 additions, -8149 deletions)

View changed files

📝 CHANGELOG.md (+106 -6612)
deploy-config.json (+7 -0)
docs/AUTO_TASKS.md (+153 -0)
docs/PATCH_MANIFEST.md (+87 -0)
files.zip (+0 -0)
frontend/src/components/gantt/GanttArrowSettings.vue (+506 -0)
📝 frontend/src/components/gantt/GanttChart.vue (+61 -5)
frontend/src/components/gantt/GanttDependencyArrows.vue (+340 -0)
📝 frontend/src/components/gantt/GanttRowBars.vue (+89 -8)
📝 frontend/src/components/gantt/GanttTimelineHeader.vue (+19 -0)
📝 frontend/src/components/gantt/GanttVerticalGridLines.vue (+330 -2)
📝 frontend/src/components/home/Navigation.vue (+10 -0)
📝 frontend/src/components/home/PoweredByLink.vue (+55 -10)
📝 frontend/src/components/project/partials/ProjectCard.vue (+25 -0)
frontend/src/components/project/partials/SubprojectFilter.vue (+346 -0)
📝 frontend/src/components/project/views/ProjectGantt.vue (+119 -21)
📝 frontend/src/components/project/views/ProjectKanban.vue (+70 -0)
📝 frontend/src/components/project/views/ProjectList.vue (+70 -0)
📝 frontend/src/components/project/views/ProjectTable.vue (+73 -2)
frontend/src/components/tasks/partials/AutoTaskEditor.vue (+1176 -0)

...and 80 more files

📄 Description

image <html> <html><head></head>

Feature: Gantt UX, Task Templates, Auto-Generated Tasks & Chain Workflows

Summary

This PR adds a comprehensive task automation and Gantt visualization overhaul to Vikunja. It introduces task templates with duplication, chain workflows for sequenced task creation, auto-generated recurring tasks, and significant Gantt chart UX improvements including configurable dependency arrows, interactive filters, and bar tooltips.

The changes span both Go backend (models, handlers, migrations, routes) and Vue 3 frontend (components, composables, stores, i18n).


Features

1. Task Templates & Duplication (Phase 1)

Reusable task templates that can be saved from any existing task and used to quickly create new tasks across projects.

  • Save any task as a reusable template (title, description, priority, labels, assignees)
  • Create new tasks from templates with project selection via modal
  • Template management page at /templates with card-based UI
  • Duplicate tasks within the same project (one-click)

2. Task Chain Workflows (Phase 2b–2d)

Define sequences of dependent tasks with relative timing offsets, then instantiate all tasks at once from an anchor date.

  • Chain Editor (ChainEditor.vue) — Define ordered steps with title, offset, duration, description, and file attachments
  • Selectable time units — Each step's offset and duration supports hours, days, weeks, and months via dropdown selectors
  • Rich text descriptions per chain step with collapsible UI
  • File attachments per chain step with upload/delete via chain_step_attachment.go
  • Drag-to-reorder chain steps via useDragReorder.ts composable
  • Default time unit preference — Persisted in localStorage via useStorage('chainDefaultTimeUnit', 'days')
  • Create from chain modal (CreateFromChainModal.vue) — Set anchor date, select target project, generate all tasks linked via precedes/follows relations
  • Send to project buttons on both chain templates and auto-task templates with mandatory auto-prefix format: ProjectName_YYMMDD-HHmm_
  • Backend: task_chain.go (model), task_from_chain.go (creation with unit-aware date math)
  • Migration 20260224050000.gotask_chain_step_attachments table
  • Migration 20260224060000.gooffset_unit, duration_unit columns on task_chain_steps

3. Auto-Generated Recurring Tasks (Phase 2g)

Task templates that automatically materialize task instances only when they become due — no board clutter from future tasks.

Core behavior:

  • Only one open (undone) instance per template at any time — no pile-up
  • If the previous task isn't completed, it simply goes overdue naturally
  • next_due_at recalculates from completion time, not creation time (prevents cascading backlog)
  • Pause/resume individual templates without deleting them
  • Manual "Send to project now" button for immediate creation
  • Generation log tracks every creation with trigger type (system vs manual) and user attribution
  • "Completed by" user trackingdone_by_id column on tasks table records who marked a task done; displayed in generation log with username resolution
  • Backend cron goroutine — Checks all users' active templates every minute and creates due instances automatically, no frontend trigger required
  • Automatic completion hookOnAutoTaskCompleted fires when a task with auto_template_id is marked done, advancing the template's next_due_at immediately
  • Attachment copying — File attachments on auto-task templates are duplicated onto each generated task instance
  • Auto-gen indicator — Tasks created from auto-task templates display a bolt icon in list/table views

Backend:

  • auto_task_template.go — Model, CRUD, permissions (owner-only), log enrichment with task_done_by_name
  • auto_task_create.go — Check logic, trigger, completion handler, attachment copying
  • auto_task_cron.go — Background cron goroutine registered in pkg/initialize/init.go
  • auto_task_handler.go — API handlers for trigger and check endpoints (echo v5)
  • tasks.godone_by_id field added to Task struct, set on task completion, cleared on undo; auto_template_id field exposed in API JSON; OnAutoTaskCompleted hook in updateSingleTask
  • Migration 20260224070000.goauto_task_templates, auto_task_log, auto_task_template_attachments tables + tasks.auto_template_id column
  • Migration 20260224080000.gotasks.done_by_id column
  • Migration 20260224090000.go — Log truncation support

API Endpoints:

Method Path Description
GET /api/v1/autotasks List user's templates (with generation log)
GET /api/v1/autotasks/:id Get one template
PUT /api/v1/autotasks Create template
POST /api/v1/autotasks/:id Update template
DELETE /api/v1/autotasks/:id Delete template + log
POST /api/v1/autotasks/:id/trigger Manually create task now
POST /api/v1/autotasks/check Check and create all due tasks

4. Gantt Chart UX Improvements

  • Dependency arrows — SVG overlay with configurable bezier, stepped, and rounded path modes
  • Arrow settings panel — Full configurator with path mode, line style, exit/entry edge selection, bezier control points, corner radius, colors, dots, shadows — fully i18n-localized (60+ keys)
  • Bar tooltips — Rich hover tooltips showing task name, date range, overdue status, completion state
  • Sub-project filter — Color-coded legend with per-project checkboxes, reactive color cascade
  • Today highlight — Configurable vertical line with teleported color picker

Build Compatibility

All new handler files are compatible with Vikunja's current stack:

  • Echo v5 — Handler signatures use c *echo.Context (pointer style)
  • echo.NewHTTPError — Always called with two args (statusCode, message)
  • Auth — Retrieved via auth2.GetAuthFromClaims(c) from pkg/modules/auth
  • Task creationcreateTask called with correct 5-arg signature (s, task, auth, false, false)
  • SpellingTaskAssginee matches Vikunja's upstream spelling
  • CObject interfaceReadAll returns (interface{}, int, int64, error)
  • Permissions — Uses PermissionAdmin (not web.RightAdmin)

Previously Known TODOs — All Resolved

  • [x] Backend cron goroutine for auto-task reliability without frontend trigger — auto_task_cron.go registered in init.go, runs every minute, checks all users
  • [x] Hook OnAutoTaskCompleted into task update path when done field changes — Added to updateSingleTask in tasks.go, fires when updateDoneAt && t.Done
  • [x] Attachment copying from template to generated task — copyAutoTaskTemplateAttachments() in auto_task_create.go, uses same pattern as project_duplicate.go
  • [x] Auto-gen indicator icon on task list items — bolt icon in SingleTaskInProject.vue when task.autoTemplateId > 0, backed by AutoTemplateID field on Task struct
  • [x] i18n for arrow settings panel — All hardcoded strings in GanttArrowSettings.vue replaced with $t() calls via useI18n, 60+ gantt.arrows.* keys added to en.json

Testing

All features have been tested on a self-hosted Vikunja instance with:

  • Custom Docker build via patch-phase2.ps1
  • MariaDB backend
  • Frontend served via nginx reverse proxy
  • Multi-user scenario validation for permissions and done_by tracking

Screenshots

Screenshots available upon request for: Gantt arrow configurator, auto-task editor, chain editor with time units, generation log modal, template tabs, modernized layout pages.

</html> </html><html> <html><head></head>

Feature: Gantt UX, Task Templates, Auto-Generated Tasks & Chain Workflows

Summary

This PR adds a comprehensive task automation and Gantt visualization overhaul to Vikunja. It introduces task templates with duplication, chain workflows for sequenced task creation, auto-generated recurring tasks, and significant Gantt chart UX improvements including configurable dependency arrows, interactive filters, and bar tooltips.

The changes span both Go backend (models, handlers, migrations, routes) and Vue 3 frontend (components, composables, stores, i18n).


Features

1. Task Templates & Duplication (Phase 1)

Reusable task templates that can be saved from any existing task and used to quickly create new tasks across projects.

  • Save any task as a reusable template (title, description, priority, labels, assignees)
  • Create new tasks from templates with project selection via modal
  • Template management page at /templates with card-based UI
  • Duplicate tasks within the same project (one-click)

2. Task Chain Workflows (Phase 2b–2d)

Define sequences of dependent tasks with relative timing offsets, then instantiate all tasks at once from an anchor date.

  • Chain Editor (ChainEditor.vue) — Define ordered steps with title, offset, duration, description, and file attachments
  • Selectable time units — Each step's offset and duration supports hours, days, weeks, and months via dropdown selectors
  • Rich text descriptions per chain step with collapsible UI
  • File attachments per chain step with upload/delete via chain_step_attachment.go
  • Drag-to-reorder chain steps via useDragReorder.ts composable
  • Default time unit preference — Persisted in localStorage via useStorage('chainDefaultTimeUnit', 'days')
  • Create from chain modal (CreateFromChainModal.vue) — Set anchor date, select target project, generate all tasks linked via precedes/follows relations
  • Send to project buttons on both chain templates and auto-task templates with mandatory auto-prefix format: ProjectName_YYMMDD-HHmm_
  • Backend: task_chain.go (model), task_from_chain.go (creation with unit-aware date math)
  • Migration 20260224050000.gotask_chain_step_attachments table
  • Migration 20260224060000.gooffset_unit, duration_unit columns on task_chain_steps

3. Auto-Generated Recurring Tasks (Phase 2g)

Task templates that automatically materialize task instances only when they become due — no board clutter from future tasks.

Core behavior:

  • Only one open (undone) instance per template at any time — no pile-up
  • If the previous task isn't completed, it simply goes overdue naturally
  • next_due_at recalculates from completion time, not creation time (prevents cascading backlog)
  • Pause/resume individual templates without deleting them
  • Manual "Send to project now" button for immediate creation
  • Generation log tracks every creation with trigger type (system vs manual) and user attribution
  • "Completed by" user trackingdone_by_id column on tasks table records who marked a task done; displayed in generation log with username resolution
  • Backend cron goroutine — Checks all users' active templates every minute and creates due instances automatically, no frontend trigger required
  • Automatic completion hookOnAutoTaskCompleted fires when a task with auto_template_id is marked done, advancing the template's next_due_at immediately
  • Attachment copying — File attachments on auto-task templates are duplicated onto each generated task instance
  • Auto-gen indicator — Tasks created from auto-task templates display a bolt icon in list/table views

Backend:

  • auto_task_template.go — Model, CRUD, permissions (owner-only), log enrichment with task_done_by_name
  • auto_task_create.go — Check logic, trigger, completion handler, attachment copying
  • auto_task_cron.go — Background cron goroutine registered in pkg/initialize/init.go
  • auto_task_handler.go — API handlers for trigger and check endpoints (echo v5)
  • tasks.godone_by_id field added to Task struct, set on task completion, cleared on undo; auto_template_id field exposed in API JSON; OnAutoTaskCompleted hook in updateSingleTask
  • Migration 20260224070000.goauto_task_templates, auto_task_log, auto_task_template_attachments tables + tasks.auto_template_id column
  • Migration 20260224080000.gotasks.done_by_id column
  • Migration 20260224090000.go — Log truncation support

API Endpoints:

Method Path Description
GET /api/v1/autotasks List user's templates (with generation log)
GET /api/v1/autotasks/:id Get one template
PUT /api/v1/autotasks Create template
POST /api/v1/autotasks/:id Update template
DELETE /api/v1/autotasks/:id Delete template + log
POST /api/v1/autotasks/:id/trigger Manually create task now
POST /api/v1/autotasks/check Check and create all due tasks

4. Gantt Chart UX Improvements

  • Dependency arrows — SVG overlay with configurable bezier, stepped, and rounded path modes
  • Arrow settings panel — Full configurator with path mode, line style, exit/entry edge selection, bezier control points, corner radius, colors, dots, shadows — fully i18n-localized (60+ keys)
  • Bar tooltips — Rich hover tooltips showing task name, date range, overdue status, completion state
  • Sub-project filter — Color-coded legend with per-project checkboxes, reactive color cascade
  • Today highlight — Configurable vertical line with teleported color picker

Build Compatibility

All new handler files are compatible with Vikunja's current stack:

  • Echo v5 — Handler signatures use c *echo.Context (pointer style)
  • echo.NewHTTPError — Always called with two args (statusCode, message)
  • Auth — Retrieved via auth2.GetAuthFromClaims(c) from pkg/modules/auth
  • Task creationcreateTask called with correct 5-arg signature (s, task, auth, false, false)
  • SpellingTaskAssginee matches Vikunja's upstream spelling
  • CObject interfaceReadAll returns (interface{}, int, int64, error)
  • Permissions — Uses PermissionAdmin (not web.RightAdmin)

Previously Known TODOs — All Resolved

  • [x] Backend cron goroutine for auto-task reliability without frontend trigger — auto_task_cron.go registered in init.go, runs every minute, checks all users
  • [x] Hook OnAutoTaskCompleted into task update path when done field changes — Added to updateSingleTask in tasks.go, fires when updateDoneAt && t.Done
  • [x] Attachment copying from template to generated task — copyAutoTaskTemplateAttachments() in auto_task_create.go, uses same pattern as project_duplicate.go
  • [x] Auto-gen indicator icon on task list items — bolt icon in SingleTaskInProject.vue when task.autoTemplateId > 0, backed by AutoTemplateID field on Task struct
  • [x] i18n for arrow settings panel — All hardcoded strings in GanttArrowSettings.vue replaced with $t() calls via useI18n, 60+ gantt.arrows.* keys added to en.json

Testing

All features have been tested on a self-hosted Vikunja instance with:

  • Custom Docker build via patch-phase2.ps1
  • MariaDB backend
  • Frontend served via nginx reverse proxy
  • Multi-user scenario validation for permissions and done_by tracking

Screenshots

Screenshots available upon request for: Gantt arrow configurator, auto-task editor, chain editor with time units, generation log modal, template tabs, modernized layout pages.

</html> </html> image image image image image image image image image image image image

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/go-vikunja/vikunja/pull/2294 **Author:** [@trbom5c](https://github.com/trbom5c) **Created:** 2/25/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `feature/ganttUX-duplicateTasks-templateTasks-autogenerateTask-chainTasks` --- ### 📝 Commits (10+) - [`044f2f3`](https://github.com/go-vikunja/vikunja/commit/044f2f3a3dab4c1257b992028053c2aa07bcb39a) fix(task): require explicit confirmation before saving reminders - [`a200b5e`](https://github.com/go-vikunja/vikunja/commit/a200b5ee777fe31c3e25332eda6396654bcfe0c0) test(task): add e2e tests for reminder confirm-before-save behavior - [`afe449c`](https://github.com/go-vikunja/vikunja/commit/afe449cb57ea3338b36c5d97e353eb3f9e7e8336) fix(test): update existing reminder tests to click Confirm after date selection - [`1e446b5`](https://github.com/go-vikunja/vikunja/commit/1e446b569d4af162c7b7e5dc1d88c2852ee23e12) fix(task): disable Confirm button when no date is selected in absolute reminder picker - [`b8cd3af`](https://github.com/go-vikunja/vikunja/commit/b8cd3afa5c3cf9b47a07db3643c25268abf21fdf) fix: prevent cursor reset when typing in filter input (#2287) - [`1cf0b62`](https://github.com/go-vikunja/vikunja/commit/1cf0b6266fafe26e1e4567ca35937116f483cbfd) fix: wait for router before dismissing loading screen - [`0fbe708`](https://github.com/go-vikunja/vikunja/commit/0fbe708de5ef621ce6902121b99e91d5093cbee5) fix: replace tx.Sync() with explicit ALTER TABLE in webhooks migration - [`bdaa627`](https://github.com/go-vikunja/vikunja/commit/bdaa627db171c18ac0d3e8d08dec5f02a3b12700) fix: make teams oidc_id rename migration idempotent - [`d579e58`](https://github.com/go-vikunja/vikunja/commit/d579e585d7fdb9f62939e679f309b42bb6ad2647) fix: add comprehensive catchup for bucket and filter format migrations - [`9adb1f9`](https://github.com/go-vikunja/vikunja/commit/9adb1f91be1c10410f095a7a8524155f85aa0696) fix: cast bucket_configuration to text in postgres catchup query ### 📊 Changes **184 files changed** (+51852 additions, -8149 deletions) <details> <summary>View changed files</summary> 📝 `CHANGELOG.md` (+106 -6612) ➕ `deploy-config.json` (+7 -0) ➕ `docs/AUTO_TASKS.md` (+153 -0) ➕ `docs/PATCH_MANIFEST.md` (+87 -0) ➕ `files.zip` (+0 -0) ➕ `frontend/src/components/gantt/GanttArrowSettings.vue` (+506 -0) 📝 `frontend/src/components/gantt/GanttChart.vue` (+61 -5) ➕ `frontend/src/components/gantt/GanttDependencyArrows.vue` (+340 -0) 📝 `frontend/src/components/gantt/GanttRowBars.vue` (+89 -8) 📝 `frontend/src/components/gantt/GanttTimelineHeader.vue` (+19 -0) 📝 `frontend/src/components/gantt/GanttVerticalGridLines.vue` (+330 -2) 📝 `frontend/src/components/home/Navigation.vue` (+10 -0) 📝 `frontend/src/components/home/PoweredByLink.vue` (+55 -10) 📝 `frontend/src/components/project/partials/ProjectCard.vue` (+25 -0) ➕ `frontend/src/components/project/partials/SubprojectFilter.vue` (+346 -0) 📝 `frontend/src/components/project/views/ProjectGantt.vue` (+119 -21) 📝 `frontend/src/components/project/views/ProjectKanban.vue` (+70 -0) 📝 `frontend/src/components/project/views/ProjectList.vue` (+70 -0) 📝 `frontend/src/components/project/views/ProjectTable.vue` (+73 -2) ➕ `frontend/src/components/tasks/partials/AutoTaskEditor.vue` (+1176 -0) _...and 80 more files_ </details> ### 📄 Description <img width="2879" height="1609" alt="image" src="https://github.com/user-attachments/assets/e24ec233-61cf-449a-a213-5bfdab2c0a6d" /> <html> <body> <!--StartFragment--><html><head></head><body><h1>Feature: Gantt UX, Task Templates, Auto-Generated Tasks &amp; Chain Workflows</h1> <h2>Summary</h2> <p>This PR adds a comprehensive task automation and Gantt visualization overhaul to Vikunja. It introduces <strong>task templates</strong> with duplication, <strong>chain workflows</strong> for sequenced task creation, <strong>auto-generated recurring tasks</strong>, and significant <strong>Gantt chart UX improvements</strong> including configurable dependency arrows, interactive filters, and bar tooltips.</p> <p>The changes span both <strong>Go backend</strong> (models, handlers, migrations, routes) and <strong>Vue 3 frontend</strong> (components, composables, stores, i18n).</p> <hr> <h2>Features</h2> <h3>1. Task Templates &amp; Duplication (Phase 1)</h3> <p>Reusable task templates that can be saved from any existing task and used to quickly create new tasks across projects.</p> <ul> <li>Save any task as a reusable template (title, description, priority, labels, assignees)</li> <li>Create new tasks from templates with project selection via modal</li> <li>Template management page at <code>/templates</code> with card-based UI</li> <li>Duplicate tasks within the same project (one-click)</li> </ul> <h3>2. Task Chain Workflows (Phase 2b–2d)</h3> <p>Define sequences of dependent tasks with relative timing offsets, then instantiate all tasks at once from an anchor date.</p> <ul> <li><strong>Chain Editor</strong> (<code>ChainEditor.vue</code>) — Define ordered steps with title, offset, duration, description, and file attachments</li> <li><strong>Selectable time units</strong> — Each step's offset and duration supports hours, days, weeks, and months via dropdown selectors</li> <li><strong>Rich text descriptions</strong> per chain step with collapsible UI</li> <li><strong>File attachments</strong> per chain step with upload/delete via <code>chain_step_attachment.go</code></li> <li><strong>Drag-to-reorder</strong> chain steps via <code>useDragReorder.ts</code> composable</li> <li><strong>Default time unit preference</strong> — Persisted in <code>localStorage</code> via <code>useStorage('chainDefaultTimeUnit', 'days')</code></li> <li><strong>Create from chain modal</strong> (<code>CreateFromChainModal.vue</code>) — Set anchor date, select target project, generate all tasks linked via precedes/follows relations</li> <li><strong>Send to project</strong> buttons on both chain templates and auto-task templates with mandatory auto-prefix format: <code>ProjectName_YYMMDD-HHmm_</code></li> <li>Backend: <code>task_chain.go</code> (model), <code>task_from_chain.go</code> (creation with unit-aware date math)</li> <li>Migration <code>20260224050000.go</code> — <code>task_chain_step_attachments</code> table</li> <li>Migration <code>20260224060000.go</code> — <code>offset_unit</code>, <code>duration_unit</code> columns on <code>task_chain_steps</code></li> </ul> <h3>3. Auto-Generated Recurring Tasks (Phase 2g)</h3> <p>Task templates that automatically materialize task instances only when they become due — no board clutter from future tasks.</p> <p><strong>Core behavior:</strong></p> <ul> <li>Only <strong>one open (undone) instance</strong> per template at any time — no pile-up</li> <li>If the previous task isn't completed, it simply goes overdue naturally</li> <li><code>next_due_at</code> recalculates from <strong>completion time</strong>, not creation time (prevents cascading backlog)</li> <li>Pause/resume individual templates without deleting them</li> <li>Manual "Send to project now" button for immediate creation</li> <li>Generation log tracks every creation with trigger type (system vs manual) and user attribution</li> <li><strong>"Completed by" user tracking</strong> — <code>done_by_id</code> column on tasks table records who marked a task done; displayed in generation log with username resolution</li> <li><strong>Backend cron goroutine</strong> — Checks all users' active templates every minute and creates due instances automatically, no frontend trigger required</li> <li><strong>Automatic completion hook</strong> — <code>OnAutoTaskCompleted</code> fires when a task with <code>auto_template_id</code> is marked done, advancing the template's <code>next_due_at</code> immediately</li> <li><strong>Attachment copying</strong> — File attachments on auto-task templates are duplicated onto each generated task instance</li> <li><strong>Auto-gen indicator</strong> — Tasks created from auto-task templates display a ⚡ bolt icon in list/table views</li> </ul> <p><strong>Backend:</strong></p> <ul> <li><code>auto_task_template.go</code> — Model, CRUD, permissions (owner-only), log enrichment with <code>task_done_by_name</code></li> <li><code>auto_task_create.go</code> — Check logic, trigger, completion handler, attachment copying</li> <li><code>auto_task_cron.go</code> — Background cron goroutine registered in <code>pkg/initialize/init.go</code></li> <li><code>auto_task_handler.go</code> — API handlers for trigger and check endpoints (echo v5)</li> <li><code>tasks.go</code> — <code>done_by_id</code> field added to Task struct, set on task completion, cleared on undo; <code>auto_template_id</code> field exposed in API JSON; <code>OnAutoTaskCompleted</code> hook in <code>updateSingleTask</code></li> <li>Migration <code>20260224070000.go</code> — <code>auto_task_templates</code>, <code>auto_task_log</code>, <code>auto_task_template_attachments</code> tables + <code>tasks.auto_template_id</code> column</li> <li>Migration <code>20260224080000.go</code> — <code>tasks.done_by_id</code> column</li> <li>Migration <code>20260224090000.go</code> — Log truncation support</li> </ul> <p><strong>API Endpoints:</strong></p> Method | Path | Description -- | -- | -- GET | /api/v1/autotasks | List user's templates (with generation log) GET | /api/v1/autotasks/:id | Get one template PUT | /api/v1/autotasks | Create template POST | /api/v1/autotasks/:id | Update template DELETE | /api/v1/autotasks/:id | Delete template + log POST | /api/v1/autotasks/:id/trigger | Manually create task now POST | /api/v1/autotasks/check | Check and create all due tasks <h3>4. Gantt Chart UX Improvements</h3> <ul> <li><strong>Dependency arrows</strong> — SVG overlay with configurable bezier, stepped, and rounded path modes</li> <li><strong>Arrow settings panel</strong> — Full configurator with path mode, line style, exit/entry edge selection, bezier control points, corner radius, colors, dots, shadows — <strong>fully i18n-localized</strong> (60+ keys)</li> <li><strong>Bar tooltips</strong> — Rich hover tooltips showing task name, date range, overdue status, completion state</li> <li><strong>Sub-project filter</strong> — Color-coded legend with per-project checkboxes, reactive color cascade</li> <li><strong>Today highlight</strong> — Configurable vertical line with teleported color picker</li> </ul> <hr> <h2>Build Compatibility</h2> <p>All new handler files are compatible with Vikunja's current stack:</p> <ul> <li><strong>Echo v5</strong> — Handler signatures use <code>c *echo.Context</code> (pointer style)</li> <li><strong>echo.NewHTTPError</strong> — Always called with two args <code>(statusCode, message)</code></li> <li><strong>Auth</strong> — Retrieved via <code>auth2.GetAuthFromClaims(c)</code> from <code>pkg/modules/auth</code></li> <li><strong>Task creation</strong> — <code>createTask</code> called with correct 5-arg signature <code>(s, task, auth, false, false)</code></li> <li><strong>Spelling</strong> — <code>TaskAssginee</code> matches Vikunja's upstream spelling</li> <li><strong>CObject interface</strong> — <code>ReadAll</code> returns <code>(interface{}, int, int64, error)</code></li> <li><strong>Permissions</strong> — Uses <code>PermissionAdmin</code> (not <code>web.RightAdmin</code>)</li> </ul> <hr> <h2>Previously Known TODOs — All Resolved ✅</h2> <ul> <li>[x] <strong>Backend cron goroutine</strong> for auto-task reliability without frontend trigger — <code>auto_task_cron.go</code> registered in <code>init.go</code>, runs every minute, checks all users</li> <li>[x] <strong>Hook <code>OnAutoTaskCompleted</code></strong> into task update path when <code>done</code> field changes — Added to <code>updateSingleTask</code> in <code>tasks.go</code>, fires when <code>updateDoneAt &amp;&amp; t.Done</code></li> <li>[x] <strong>Attachment copying</strong> from template to generated task — <code>copyAutoTaskTemplateAttachments()</code> in <code>auto_task_create.go</code>, uses same pattern as <code>project_duplicate.go</code></li> <li>[x] <strong>Auto-gen indicator icon</strong> on task list items — ⚡ bolt icon in <code>SingleTaskInProject.vue</code> when <code>task.autoTemplateId &gt; 0</code>, backed by <code>AutoTemplateID</code> field on Task struct</li> <li>[x] <strong>i18n for arrow settings panel</strong> — All hardcoded strings in <code>GanttArrowSettings.vue</code> replaced with <code>$t()</code> calls via <code>useI18n</code>, 60+ <code>gantt.arrows.*</code> keys added to <code>en.json</code></li> </ul> <hr> <h2>Testing</h2> <p>All features have been tested on a self-hosted Vikunja instance with:</p> <ul> <li>Custom Docker build via <code>patch-phase2.ps1</code></li> <li>MariaDB backend</li> <li>Frontend served via nginx reverse proxy</li> <li>Multi-user scenario validation for permissions and done_by tracking</li> </ul> <hr> <h2>Screenshots</h2> <p><em>Screenshots available upon request for: Gantt arrow configurator, auto-task editor, chain editor with time units, generation log modal, template tabs, modernized layout pages.</em></p></body></html><!--EndFragment--> </body> </html><html> <body> <!--StartFragment--><html><head></head><body><h1>Feature: Gantt UX, Task Templates, Auto-Generated Tasks &amp; Chain Workflows</h1> <h2>Summary</h2> <p>This PR adds a comprehensive task automation and Gantt visualization overhaul to Vikunja. It introduces <strong>task templates</strong> with duplication, <strong>chain workflows</strong> for sequenced task creation, <strong>auto-generated recurring tasks</strong>, and significant <strong>Gantt chart UX improvements</strong> including configurable dependency arrows, interactive filters, and bar tooltips.</p> <p>The changes span both <strong>Go backend</strong> (models, handlers, migrations, routes) and <strong>Vue 3 frontend</strong> (components, composables, stores, i18n).</p> <hr> <h2>Features</h2> <h3>1. Task Templates &amp; Duplication (Phase 1)</h3> <p>Reusable task templates that can be saved from any existing task and used to quickly create new tasks across projects.</p> <ul> <li>Save any task as a reusable template (title, description, priority, labels, assignees)</li> <li>Create new tasks from templates with project selection via modal</li> <li>Template management page at <code>/templates</code> with card-based UI</li> <li>Duplicate tasks within the same project (one-click)</li> </ul> <h3>2. Task Chain Workflows (Phase 2b–2d)</h3> <p>Define sequences of dependent tasks with relative timing offsets, then instantiate all tasks at once from an anchor date.</p> <ul> <li><strong>Chain Editor</strong> (<code>ChainEditor.vue</code>) — Define ordered steps with title, offset, duration, description, and file attachments</li> <li><strong>Selectable time units</strong> — Each step's offset and duration supports hours, days, weeks, and months via dropdown selectors</li> <li><strong>Rich text descriptions</strong> per chain step with collapsible UI</li> <li><strong>File attachments</strong> per chain step with upload/delete via <code>chain_step_attachment.go</code></li> <li><strong>Drag-to-reorder</strong> chain steps via <code>useDragReorder.ts</code> composable</li> <li><strong>Default time unit preference</strong> — Persisted in <code>localStorage</code> via <code>useStorage('chainDefaultTimeUnit', 'days')</code></li> <li><strong>Create from chain modal</strong> (<code>CreateFromChainModal.vue</code>) — Set anchor date, select target project, generate all tasks linked via precedes/follows relations</li> <li><strong>Send to project</strong> buttons on both chain templates and auto-task templates with mandatory auto-prefix format: <code>ProjectName_YYMMDD-HHmm_</code></li> <li>Backend: <code>task_chain.go</code> (model), <code>task_from_chain.go</code> (creation with unit-aware date math)</li> <li>Migration <code>20260224050000.go</code> — <code>task_chain_step_attachments</code> table</li> <li>Migration <code>20260224060000.go</code> — <code>offset_unit</code>, <code>duration_unit</code> columns on <code>task_chain_steps</code></li> </ul> <h3>3. Auto-Generated Recurring Tasks (Phase 2g)</h3> <p>Task templates that automatically materialize task instances only when they become due — no board clutter from future tasks.</p> <p><strong>Core behavior:</strong></p> <ul> <li>Only <strong>one open (undone) instance</strong> per template at any time — no pile-up</li> <li>If the previous task isn't completed, it simply goes overdue naturally</li> <li><code>next_due_at</code> recalculates from <strong>completion time</strong>, not creation time (prevents cascading backlog)</li> <li>Pause/resume individual templates without deleting them</li> <li>Manual "Send to project now" button for immediate creation</li> <li>Generation log tracks every creation with trigger type (system vs manual) and user attribution</li> <li><strong>"Completed by" user tracking</strong> — <code>done_by_id</code> column on tasks table records who marked a task done; displayed in generation log with username resolution</li> <li><strong>Backend cron goroutine</strong> — Checks all users' active templates every minute and creates due instances automatically, no frontend trigger required</li> <li><strong>Automatic completion hook</strong> — <code>OnAutoTaskCompleted</code> fires when a task with <code>auto_template_id</code> is marked done, advancing the template's <code>next_due_at</code> immediately</li> <li><strong>Attachment copying</strong> — File attachments on auto-task templates are duplicated onto each generated task instance</li> <li><strong>Auto-gen indicator</strong> — Tasks created from auto-task templates display a ⚡ bolt icon in list/table views</li> </ul> <p><strong>Backend:</strong></p> <ul> <li><code>auto_task_template.go</code> — Model, CRUD, permissions (owner-only), log enrichment with <code>task_done_by_name</code></li> <li><code>auto_task_create.go</code> — Check logic, trigger, completion handler, attachment copying</li> <li><code>auto_task_cron.go</code> — Background cron goroutine registered in <code>pkg/initialize/init.go</code></li> <li><code>auto_task_handler.go</code> — API handlers for trigger and check endpoints (echo v5)</li> <li><code>tasks.go</code> — <code>done_by_id</code> field added to Task struct, set on task completion, cleared on undo; <code>auto_template_id</code> field exposed in API JSON; <code>OnAutoTaskCompleted</code> hook in <code>updateSingleTask</code></li> <li>Migration <code>20260224070000.go</code> — <code>auto_task_templates</code>, <code>auto_task_log</code>, <code>auto_task_template_attachments</code> tables + <code>tasks.auto_template_id</code> column</li> <li>Migration <code>20260224080000.go</code> — <code>tasks.done_by_id</code> column</li> <li>Migration <code>20260224090000.go</code> — Log truncation support</li> </ul> <p><strong>API Endpoints:</strong></p> Method | Path | Description -- | -- | -- GET | /api/v1/autotasks | List user's templates (with generation log) GET | /api/v1/autotasks/:id | Get one template PUT | /api/v1/autotasks | Create template POST | /api/v1/autotasks/:id | Update template DELETE | /api/v1/autotasks/:id | Delete template + log POST | /api/v1/autotasks/:id/trigger | Manually create task now POST | /api/v1/autotasks/check | Check and create all due tasks <h3>4. Gantt Chart UX Improvements</h3> <ul> <li><strong>Dependency arrows</strong> — SVG overlay with configurable bezier, stepped, and rounded path modes</li> <li><strong>Arrow settings panel</strong> — Full configurator with path mode, line style, exit/entry edge selection, bezier control points, corner radius, colors, dots, shadows — <strong>fully i18n-localized</strong> (60+ keys)</li> <li><strong>Bar tooltips</strong> — Rich hover tooltips showing task name, date range, overdue status, completion state</li> <li><strong>Sub-project filter</strong> — Color-coded legend with per-project checkboxes, reactive color cascade</li> <li><strong>Today highlight</strong> — Configurable vertical line with teleported color picker</li> </ul> <hr> <h2>Build Compatibility</h2> <p>All new handler files are compatible with Vikunja's current stack:</p> <ul> <li><strong>Echo v5</strong> — Handler signatures use <code>c *echo.Context</code> (pointer style)</li> <li><strong>echo.NewHTTPError</strong> — Always called with two args <code>(statusCode, message)</code></li> <li><strong>Auth</strong> — Retrieved via <code>auth2.GetAuthFromClaims(c)</code> from <code>pkg/modules/auth</code></li> <li><strong>Task creation</strong> — <code>createTask</code> called with correct 5-arg signature <code>(s, task, auth, false, false)</code></li> <li><strong>Spelling</strong> — <code>TaskAssginee</code> matches Vikunja's upstream spelling</li> <li><strong>CObject interface</strong> — <code>ReadAll</code> returns <code>(interface{}, int, int64, error)</code></li> <li><strong>Permissions</strong> — Uses <code>PermissionAdmin</code> (not <code>web.RightAdmin</code>)</li> </ul> <hr> <h2>Previously Known TODOs — All Resolved ✅</h2> <ul> <li>[x] <strong>Backend cron goroutine</strong> for auto-task reliability without frontend trigger — <code>auto_task_cron.go</code> registered in <code>init.go</code>, runs every minute, checks all users</li> <li>[x] <strong>Hook <code>OnAutoTaskCompleted</code></strong> into task update path when <code>done</code> field changes — Added to <code>updateSingleTask</code> in <code>tasks.go</code>, fires when <code>updateDoneAt &amp;&amp; t.Done</code></li> <li>[x] <strong>Attachment copying</strong> from template to generated task — <code>copyAutoTaskTemplateAttachments()</code> in <code>auto_task_create.go</code>, uses same pattern as <code>project_duplicate.go</code></li> <li>[x] <strong>Auto-gen indicator icon</strong> on task list items — ⚡ bolt icon in <code>SingleTaskInProject.vue</code> when <code>task.autoTemplateId &gt; 0</code>, backed by <code>AutoTemplateID</code> field on Task struct</li> <li>[x] <strong>i18n for arrow settings panel</strong> — All hardcoded strings in <code>GanttArrowSettings.vue</code> replaced with <code>$t()</code> calls via <code>useI18n</code>, 60+ <code>gantt.arrows.*</code> keys added to <code>en.json</code></li> </ul> <hr> <h2>Testing</h2> <p>All features have been tested on a self-hosted Vikunja instance with:</p> <ul> <li>Custom Docker build via <code>patch-phase2.ps1</code></li> <li>MariaDB backend</li> <li>Frontend served via nginx reverse proxy</li> <li>Multi-user scenario validation for permissions and done_by tracking</li> </ul> <hr> <h2>Screenshots</h2> <p><em>Screenshots available upon request for: Gantt arrow configurator, auto-task editor, chain editor with time units, generation log modal, template tabs, modernized layout pages.</em></p></body></html><!--EndFragment--> </body> </html> <img width="2879" height="1621" alt="image" src="https://github.com/user-attachments/assets/a581bb19-522b-4b3b-b0b1-2c3166af9c9d" /> <img width="2879" height="1609" alt="image" src="https://github.com/user-attachments/assets/f588d04a-c55b-45b5-aa3f-343a760a3f12" /> <img width="2879" height="1608" alt="image" src="https://github.com/user-attachments/assets/a3e7ef92-4c82-41f6-a1db-aa2b45ed3bbd" /> <img width="1565" height="1630" alt="image" src="https://github.com/user-attachments/assets/c9ae071a-829d-44d5-97e2-5efa0623a587" /> <img width="1003" height="1324" alt="image" src="https://github.com/user-attachments/assets/6d3ca3b1-6245-4095-bf9f-e4979c084dc4" /> <img width="954" height="1089" alt="image" src="https://github.com/user-attachments/assets/70457d30-af46-4c68-ab45-c658d53d8111" /> <img width="990" height="1099" alt="image" src="https://github.com/user-attachments/assets/d9fbd7c3-b370-4689-8549-0b7cfe0a97cd" /> <img width="2879" height="1610" alt="image" src="https://github.com/user-attachments/assets/93d2fb3f-2ba8-4a80-ad96-c11cf53c107e" /> <img width="2879" height="1620" alt="image" src="https://github.com/user-attachments/assets/20315339-75ad-4250-ac9e-324a9e796c01" /> <img width="2879" height="1611" alt="image" src="https://github.com/user-attachments/assets/a77a6c09-d79d-4313-bc65-ea4d8343b7e3" /> <img width="2879" height="1604" alt="image" src="https://github.com/user-attachments/assets/94704799-9969-48c5-a0cc-f98dfa0b4dc3" /> <img width="2879" height="1607" alt="image" src="https://github.com/user-attachments/assets/c2d30fc5-06c7-452e-86de-46dc0f37890d" /> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-23 09:15:55 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/vikunja#9885