Add in-progress state to tasks

Introduce IN_PROGRESS as a new task state between TODO and DONE across
the full stack: database enum, Go backend, GraphQL, MCP, and frontend.

The task state icon now cycles forward on click (TODO → IN_PROGRESS →
DONE → TODO), and the action dropdown provides explicit "Move to"
options for any state transition. The "All" tab supports drag-and-drop
between state sections to change a task's state.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-04-02 15:50:20 +02:00
parent 5c71575ade
commit 8adf26ad20
9 changed files with 340 additions and 169 deletions

View File

@@ -0,0 +1,15 @@
-- Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
--
-- Permission to use, copy, modify, and/or distribute this software for any
-- purpose with or without fee is hereby granted, provided that the above
-- copyright notice and this permission notice appear in all copies.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-- PERFORMANCE OF THIS SOFTWARE.
ALTER TYPE task_state ADD VALUE 'IN_PROGRESS' BEFORE 'DONE';

View File

@@ -20,17 +20,19 @@ import (
)
type (
TaskState uint8
TaskState string
)
const (
TaskStateTodo TaskState = iota
TaskStateDone
TaskStateTodo TaskState = "TODO"
TaskStateInProgress TaskState = "IN_PROGRESS"
TaskStateDone TaskState = "DONE"
)
func TaskStates() []TaskState {
return []TaskState{
TaskStateTodo,
TaskStateInProgress,
TaskStateDone,
}
}
@@ -40,13 +42,11 @@ func (ts TaskState) MarshalText() ([]byte, error) {
}
func (ts *TaskState) UnmarshalText(data []byte) error {
val := string(data)
val := TaskState(data)
switch val {
case TaskStateTodo.String():
*ts = TaskStateTodo
case TaskStateDone.String():
*ts = TaskStateDone
case TaskStateTodo, TaskStateInProgress, TaskStateDone:
*ts = val
default:
return fmt.Errorf("invalid TaskState value: %q", val)
}
@@ -55,16 +55,7 @@ func (ts *TaskState) UnmarshalText(data []byte) error {
}
func (ts TaskState) String() string {
var val string
switch ts {
case TaskStateTodo:
val = "TODO"
case TaskStateDone:
val = "DONE"
}
return val
return string(ts)
}
func (ts *TaskState) Scan(value any) error {

View File

@@ -66,6 +66,7 @@ enum MeasureState
enum TaskState @goModel(model: "go.probo.inc/probo/pkg/coredata.TaskState") {
TODO @goEnum(value: "go.probo.inc/probo/pkg/coredata.TaskStateTodo")
IN_PROGRESS @goEnum(value: "go.probo.inc/probo/pkg/coredata.TaskStateInProgress")
DONE @goEnum(value: "go.probo.inc/probo/pkg/coredata.TaskStateDone")
}

View File

@@ -4615,6 +4615,7 @@ components:
type: string
enum:
- TODO
- IN_PROGRESS
- DONE
go.probo.inc/mcpgen/type: go.probo.inc/probo/pkg/coredata.TaskState