feat: add task sorting & filtering
adds filtering by task status (completion date, incomplete, completion) adds filtering by task metadata (task name, labels, members, due date) adds sorting by task name, labels, members, and due date
This commit is contained in:
committed by
Jordan Knott
parent
47782d6d86
commit
66583bb4fb
@ -72,6 +72,7 @@ type Task struct {
|
||||
Description sql.NullString `json:"description"`
|
||||
DueDate sql.NullTime `json:"due_date"`
|
||||
Complete bool `json:"complete"`
|
||||
CompletedAt sql.NullTime `json:"completed_at"`
|
||||
}
|
||||
|
||||
type TaskAssigned struct {
|
||||
|
@ -30,7 +30,7 @@ DELETE FROM task where task_group_id = $1;
|
||||
UPDATE task SET due_date = $2 WHERE task_id = $1 RETURNING *;
|
||||
|
||||
-- name: SetTaskComplete :one
|
||||
UPDATE task SET complete = $2 WHERE task_id = $1 RETURNING *;
|
||||
UPDATE task SET complete = $2, completed_at = $3 WHERE task_id = $1 RETURNING *;
|
||||
|
||||
-- name: GetProjectIDForTask :one
|
||||
SELECT project_id FROM task
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
|
||||
const createTask = `-- name: CreateTask :one
|
||||
INSERT INTO task (task_group_id, created_at, name, position)
|
||||
VALUES($1, $2, $3, $4) RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete
|
||||
VALUES($1, $2, $3, $4) RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at
|
||||
`
|
||||
|
||||
type CreateTaskParams struct {
|
||||
@ -40,6 +40,7 @@ func (q *Queries) CreateTask(ctx context.Context, arg CreateTaskParams) (Task, e
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -66,7 +67,7 @@ func (q *Queries) DeleteTasksByTaskGroupID(ctx context.Context, taskGroupID uuid
|
||||
}
|
||||
|
||||
const getAllTasks = `-- name: GetAllTasks :many
|
||||
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete FROM task
|
||||
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at FROM task
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllTasks(ctx context.Context) ([]Task, error) {
|
||||
@ -87,6 +88,7 @@ func (q *Queries) GetAllTasks(ctx context.Context) ([]Task, error) {
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -115,7 +117,7 @@ func (q *Queries) GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uu
|
||||
}
|
||||
|
||||
const getTaskByID = `-- name: GetTaskByID :one
|
||||
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete FROM task WHERE task_id = $1
|
||||
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at FROM task WHERE task_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, error) {
|
||||
@ -130,12 +132,13 @@ func (q *Queries) GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, erro
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getTasksForTaskGroupID = `-- name: GetTasksForTaskGroupID :many
|
||||
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete FROM task WHERE task_group_id = $1
|
||||
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at FROM task WHERE task_group_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) ([]Task, error) {
|
||||
@ -156,6 +159,7 @@ func (q *Queries) GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.U
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -171,16 +175,17 @@ func (q *Queries) GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.U
|
||||
}
|
||||
|
||||
const setTaskComplete = `-- name: SetTaskComplete :one
|
||||
UPDATE task SET complete = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete
|
||||
UPDATE task SET complete = $2, completed_at = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at
|
||||
`
|
||||
|
||||
type SetTaskCompleteParams struct {
|
||||
TaskID uuid.UUID `json:"task_id"`
|
||||
Complete bool `json:"complete"`
|
||||
TaskID uuid.UUID `json:"task_id"`
|
||||
Complete bool `json:"complete"`
|
||||
CompletedAt sql.NullTime `json:"completed_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetTaskComplete(ctx context.Context, arg SetTaskCompleteParams) (Task, error) {
|
||||
row := q.db.QueryRowContext(ctx, setTaskComplete, arg.TaskID, arg.Complete)
|
||||
row := q.db.QueryRowContext(ctx, setTaskComplete, arg.TaskID, arg.Complete, arg.CompletedAt)
|
||||
var i Task
|
||||
err := row.Scan(
|
||||
&i.TaskID,
|
||||
@ -191,12 +196,13 @@ func (q *Queries) SetTaskComplete(ctx context.Context, arg SetTaskCompleteParams
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateTaskDescription = `-- name: UpdateTaskDescription :one
|
||||
UPDATE task SET description = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete
|
||||
UPDATE task SET description = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at
|
||||
`
|
||||
|
||||
type UpdateTaskDescriptionParams struct {
|
||||
@ -216,12 +222,13 @@ func (q *Queries) UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescr
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateTaskDueDate = `-- name: UpdateTaskDueDate :one
|
||||
UPDATE task SET due_date = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete
|
||||
UPDATE task SET due_date = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at
|
||||
`
|
||||
|
||||
type UpdateTaskDueDateParams struct {
|
||||
@ -241,12 +248,13 @@ func (q *Queries) UpdateTaskDueDate(ctx context.Context, arg UpdateTaskDueDatePa
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateTaskLocation = `-- name: UpdateTaskLocation :one
|
||||
UPDATE task SET task_group_id = $2, position = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete
|
||||
UPDATE task SET task_group_id = $2, position = $3 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at
|
||||
`
|
||||
|
||||
type UpdateTaskLocationParams struct {
|
||||
@ -267,12 +275,13 @@ func (q *Queries) UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocation
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateTaskName = `-- name: UpdateTaskName :one
|
||||
UPDATE task SET name = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete
|
||||
UPDATE task SET name = $2 WHERE task_id = $1 RETURNING task_id, task_group_id, created_at, name, position, description, due_date, complete, completed_at
|
||||
`
|
||||
|
||||
type UpdateTaskNameParams struct {
|
||||
@ -292,6 +301,7 @@ func (q *Queries) UpdateTaskName(ctx context.Context, arg UpdateTaskNameParams)
|
||||
&i.Description,
|
||||
&i.DueDate,
|
||||
&i.Complete,
|
||||
&i.CompletedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -129,6 +129,7 @@ type Task {
|
||||
description: String
|
||||
dueDate: Time
|
||||
complete: Boolean!
|
||||
completedAt: Time
|
||||
assigned: [Member!]!
|
||||
labels: [TaskLabel!]!
|
||||
checklists: [TaskChecklist!]!
|
||||
@ -256,7 +257,6 @@ type DeleteProjectPayload {
|
||||
project: Project!
|
||||
}
|
||||
|
||||
|
||||
extend type Mutation {
|
||||
createProjectLabel(input: NewProjectLabel!):
|
||||
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
@ -338,17 +338,26 @@ type UpdateProjectMemberRolePayload {
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createTask(input: NewTask!): Task!
|
||||
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
|
||||
createTask(input: NewTask!):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
deleteTask(input: DeleteTaskInput!):
|
||||
DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
|
||||
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
|
||||
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
|
||||
updateTaskName(input: UpdateTaskName!): Task!
|
||||
setTaskComplete(input: SetTaskComplete!): Task!
|
||||
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
|
||||
updateTaskDescription(input: UpdateTaskDescriptionInput!):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskLocation(input: NewTaskLocation!):
|
||||
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskName(input: UpdateTaskName!):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
setTaskComplete(input: SetTaskComplete!):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskDueDate(input: UpdateTaskDueDate!):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
|
||||
assignTask(input: AssignTaskInput): Task!
|
||||
unassignTask(input: UnassignTaskInput): Task!
|
||||
assignTask(input: AssignTaskInput):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
unassignTask(input: UnassignTaskInput):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input NewTask {
|
||||
@ -407,16 +416,25 @@ input UpdateTaskName {
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
|
||||
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
|
||||
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
|
||||
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
|
||||
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
|
||||
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
|
||||
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
|
||||
createTaskChecklist(input: CreateTaskChecklist!):
|
||||
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
deleteTaskChecklist(input: DeleteTaskChecklist!):
|
||||
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskChecklistName(input: UpdateTaskChecklistName!):
|
||||
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
createTaskChecklistItem(input: CreateTaskChecklistItem!):
|
||||
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
|
||||
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
|
||||
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
|
||||
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!):
|
||||
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!):
|
||||
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
|
||||
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!): UpdateTaskChecklistLocationPayload!
|
||||
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!): UpdateTaskChecklistItemLocationPayload!
|
||||
}
|
||||
|
||||
input UpdateTaskChecklistItemLocation {
|
||||
@ -484,10 +502,14 @@ type DeleteTaskChecklistPayload {
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createTaskGroup(input: NewTaskGroup!): TaskGroup!
|
||||
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
|
||||
updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup!
|
||||
deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload!
|
||||
createTaskGroup(input: NewTaskGroup!):
|
||||
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskGroupLocation(input: NewTaskGroupLocation!):
|
||||
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
updateTaskGroupName(input: UpdateTaskGroupName!):
|
||||
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
deleteTaskGroup(input: DeleteTaskGroupInput!):
|
||||
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
}
|
||||
|
||||
input NewTaskGroupLocation {
|
||||
@ -534,9 +556,13 @@ type ToggleTaskLabelPayload {
|
||||
task: Task!
|
||||
}
|
||||
extend type Mutation {
|
||||
addTaskLabel(input: AddTaskLabelInput): Task!
|
||||
removeTaskLabel(input: RemoveTaskLabelInput): Task!
|
||||
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
|
||||
addTaskLabel(input: AddTaskLabelInput):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
removeTaskLabel(input: RemoveTaskLabelInput):
|
||||
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
toggleTaskLabel(input: ToggleTaskLabelInput!):
|
||||
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
|
||||
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
@ -562,10 +588,12 @@ type DeleteTeamPayload {
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
|
||||
createTeamMember(input: CreateTeamMember!):
|
||||
CreateTeamMemberPayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
|
||||
updateTeamMemberRole(input: UpdateTeamMemberRole!):
|
||||
UpdateTeamMemberRolePayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
|
||||
deleteTeamMember(input: DeleteTeamMember!): DeleteTeamMemberPayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
|
||||
deleteTeamMember(input: DeleteTeamMember!):
|
||||
DeleteTeamMemberPayload! @hasRole(roles: [ADMIN], level: TEAM, type: TEAM)
|
||||
|
||||
}
|
||||
|
||||
|
@ -235,7 +235,8 @@ func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskN
|
||||
}
|
||||
|
||||
func (r *mutationResolver) SetTaskComplete(ctx context.Context, input SetTaskComplete) (*db.Task, error) {
|
||||
task, err := r.Repository.SetTaskComplete(ctx, db.SetTaskCompleteParams{TaskID: input.TaskID, Complete: input.Complete})
|
||||
completedAt := time.Now().UTC()
|
||||
task, err := r.Repository.SetTaskComplete(ctx, db.SetTaskCompleteParams{TaskID: input.TaskID, Complete: input.Complete, CompletedAt: sql.NullTime{Time: completedAt, Valid: true}})
|
||||
if err != nil {
|
||||
return &db.Task{}, err
|
||||
}
|
||||
@ -1041,6 +1042,13 @@ func (r *taskResolver) DueDate(ctx context.Context, obj *db.Task) (*time.Time, e
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *taskResolver) CompletedAt(ctx context.Context, obj *db.Task) (*time.Time, error) {
|
||||
if obj.CompletedAt.Valid {
|
||||
return &obj.CompletedAt.Time, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *taskResolver) Assigned(ctx context.Context, obj *db.Task) ([]Member, error) {
|
||||
taskMemberLinks, err := r.Repository.GetAssignedMembersForTask(ctx, obj.TaskID)
|
||||
taskMembers := []Member{}
|
||||
|
@ -129,6 +129,7 @@ type Task {
|
||||
description: String
|
||||
dueDate: Time
|
||||
complete: Boolean!
|
||||
completedAt: Time
|
||||
assigned: [Member!]!
|
||||
labels: [TaskLabel!]!
|
||||
checklists: [TaskChecklist!]!
|
||||
|
Reference in New Issue
Block a user