feature: add due dates to tasks

This commit is contained in:
Jordan Knott
2020-06-15 17:36:59 -05:00
parent a12e9c1e50
commit b6f0e8b6b2
32 changed files with 816 additions and 222 deletions

View File

@ -94,6 +94,7 @@ type ComplexityRoot struct {
UpdateProjectLabelName func(childComplexity int, input UpdateProjectLabelName) int
UpdateProjectName func(childComplexity int, input *UpdateProjectName) int
UpdateTaskDescription func(childComplexity int, input UpdateTaskDescriptionInput) int
UpdateTaskDueDate func(childComplexity int, input UpdateTaskDueDate) int
UpdateTaskGroupLocation func(childComplexity int, input NewTaskGroupLocation) int
UpdateTaskGroupName func(childComplexity int, input UpdateTaskGroupName) int
UpdateTaskLocation func(childComplexity int, input NewTaskLocation) int
@ -153,6 +154,7 @@ type ComplexityRoot struct {
Assigned func(childComplexity int) int
CreatedAt func(childComplexity int) int
Description func(childComplexity int) int
DueDate func(childComplexity int) int
ID func(childComplexity int) int
Labels func(childComplexity int) int
Name func(childComplexity int) int
@ -228,6 +230,7 @@ type MutationResolver interface {
UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*pg.Task, error)
UpdateTaskLocation(ctx context.Context, input NewTaskLocation) (*UpdateTaskLocationPayload, error)
UpdateTaskName(ctx context.Context, input UpdateTaskName) (*pg.Task, error)
UpdateTaskDueDate(ctx context.Context, input UpdateTaskDueDate) (*pg.Task, error)
DeleteTask(ctx context.Context, input DeleteTaskInput) (*DeleteTaskPayload, error)
AssignTask(ctx context.Context, input *AssignTaskInput) (*pg.Task, error)
UnassignTask(ctx context.Context, input *UnassignTaskInput) (*pg.Task, error)
@ -267,6 +270,7 @@ type TaskResolver interface {
TaskGroup(ctx context.Context, obj *pg.Task) (*pg.TaskGroup, error)
Description(ctx context.Context, obj *pg.Task) (*string, error)
DueDate(ctx context.Context, obj *pg.Task) (*time.Time, error)
Assigned(ctx context.Context, obj *pg.Task) ([]ProjectMember, error)
Labels(ctx context.Context, obj *pg.Task) ([]pg.TaskLabel, error)
}
@ -619,6 +623,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.UpdateTaskDescription(childComplexity, args["input"].(UpdateTaskDescriptionInput)), true
case "Mutation.updateTaskDueDate":
if e.complexity.Mutation.UpdateTaskDueDate == nil {
break
}
args, err := ec.field_Mutation_updateTaskDueDate_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Mutation.UpdateTaskDueDate(childComplexity, args["input"].(UpdateTaskDueDate)), true
case "Mutation.updateTaskGroupLocation":
if e.complexity.Mutation.UpdateTaskGroupLocation == nil {
break
@ -925,6 +941,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Task.Description(childComplexity), true
case "Task.dueDate":
if e.complexity.Task.DueDate == nil {
break
}
return e.complexity.Task.DueDate(childComplexity), true
case "Task.id":
if e.complexity.Task.ID == nil {
break
@ -1271,6 +1294,7 @@ type Task {
name: String!
position: Float!
description: String
dueDate: Time
assigned: [ProjectMember!]!
labels: [TaskLabel!]!
}
@ -1448,6 +1472,11 @@ input UpdateTaskGroupName {
name: String!
}
input UpdateTaskDueDate {
taskID: UUID!
dueDate: Time
}
type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
@ -1478,6 +1507,7 @@ type Mutation {
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
updateTaskName(input: UpdateTaskName!): Task!
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
assignTask(input: AssignTaskInput): Task!
unassignTask(input: UnassignTaskInput): Task!
@ -1786,6 +1816,20 @@ func (ec *executionContext) field_Mutation_updateTaskDescription_args(ctx contex
return args, nil
}
func (ec *executionContext) field_Mutation_updateTaskDueDate_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 UpdateTaskDueDate
if tmp, ok := rawArgs["input"]; ok {
arg0, err = ec.unmarshalNUpdateTaskDueDate2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateTaskDueDate(ctx, tmp)
if err != nil {
return nil, err
}
}
args["input"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_updateTaskGroupLocation_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@ -3115,6 +3159,47 @@ func (ec *executionContext) _Mutation_updateTaskName(ctx context.Context, field
return ec.marshalNTask2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTask(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_updateTaskDueDate(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Mutation",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Mutation_updateTaskDueDate_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().UpdateTaskDueDate(rctx, args["input"].(UpdateTaskDueDate))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*pg.Task)
fc.Result = res
return ec.marshalNTask2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTask(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_deleteTask(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -4619,6 +4704,37 @@ func (ec *executionContext) _Task_description(ctx context.Context, field graphql
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) _Task_dueDate(ctx context.Context, field graphql.CollectedField, obj *pg.Task) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Task",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Task().DueDate(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*time.Time)
fc.Result = res
return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) _Task_assigned(ctx context.Context, field graphql.CollectedField, obj *pg.Task) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -7166,6 +7282,30 @@ func (ec *executionContext) unmarshalInputUpdateTaskDescriptionInput(ctx context
return it, nil
}
func (ec *executionContext) unmarshalInputUpdateTaskDueDate(ctx context.Context, obj interface{}) (UpdateTaskDueDate, error) {
var it UpdateTaskDueDate
var asMap = obj.(map[string]interface{})
for k, v := range asMap {
switch k {
case "taskID":
var err error
it.TaskID, err = ec.unmarshalNUUID2githubᚗcomᚋgoogleᚋuuidᚐUUID(ctx, v)
if err != nil {
return it, err
}
case "dueDate":
var err error
it.DueDate, err = ec.unmarshalOTime2ᚖtimeᚐTime(ctx, v)
if err != nil {
return it, err
}
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputUpdateTaskGroupName(ctx context.Context, obj interface{}) (UpdateTaskGroupName, error) {
var it UpdateTaskGroupName
var asMap = obj.(map[string]interface{})
@ -7462,6 +7602,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
if out.Values[i] == graphql.Null {
invalids++
}
case "updateTaskDueDate":
out.Values[i] = ec._Mutation_updateTaskDueDate(ctx, field)
if out.Values[i] == graphql.Null {
invalids++
}
case "deleteTask":
out.Values[i] = ec._Mutation_deleteTask(ctx, field)
if out.Values[i] == graphql.Null {
@ -8012,6 +8157,17 @@ func (ec *executionContext) _Task(ctx context.Context, sel ast.SelectionSet, obj
res = ec._Task_description(ctx, field, obj)
return res
})
case "dueDate":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Task_dueDate(ctx, field, obj)
return res
})
case "assigned":
field := field
out.Concurrently(i, func() (res graphql.Marshaler) {
@ -9265,6 +9421,10 @@ func (ec *executionContext) unmarshalNUpdateTaskDescriptionInput2githubᚗcomᚋ
return ec.unmarshalInputUpdateTaskDescriptionInput(ctx, v)
}
func (ec *executionContext) unmarshalNUpdateTaskDueDate2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateTaskDueDate(ctx context.Context, v interface{}) (UpdateTaskDueDate, error) {
return ec.unmarshalInputUpdateTaskDueDate(ctx, v)
}
func (ec *executionContext) unmarshalNUpdateTaskGroupName2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUpdateTaskGroupName(ctx context.Context, v interface{}) (UpdateTaskGroupName, error) {
return ec.unmarshalInputUpdateTaskGroupName(ctx, v)
}
@ -9658,6 +9818,29 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as
return ec.marshalOString2string(ctx, sel, *v)
}
func (ec *executionContext) unmarshalOTime2timeᚐTime(ctx context.Context, v interface{}) (time.Time, error) {
return graphql.UnmarshalTime(v)
}
func (ec *executionContext) marshalOTime2timeᚐTime(ctx context.Context, sel ast.SelectionSet, v time.Time) graphql.Marshaler {
return graphql.MarshalTime(v)
}
func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) {
if v == nil {
return nil, nil
}
res, err := ec.unmarshalOTime2timeᚐTime(ctx, v)
return &res, err
}
func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel ast.SelectionSet, v *time.Time) graphql.Marshaler {
if v == nil {
return graphql.Null
}
return ec.marshalOTime2timeᚐTime(ctx, sel, *v)
}
func (ec *executionContext) unmarshalOUnassignTaskInput2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋgraphᚐUnassignTaskInput(ctx context.Context, v interface{}) (UnassignTaskInput, error) {
return ec.unmarshalInputUnassignTaskInput(ctx, v)
}

View File

@ -3,6 +3,8 @@
package graph
import (
"time"
"github.com/google/uuid"
"github.com/jordanknott/project-citadel/api/pg"
)
@ -168,6 +170,11 @@ type UpdateTaskDescriptionInput struct {
Description string `json:"description"`
}
type UpdateTaskDueDate struct {
TaskID uuid.UUID `json:"taskID"`
DueDate *time.Time `json:"dueDate"`
}
type UpdateTaskGroupName struct {
TaskGroupID uuid.UUID `json:"taskGroupID"`
Name string `json:"name"`

View File

@ -84,6 +84,7 @@ type Task {
name: String!
position: Float!
description: String
dueDate: Time
assigned: [ProjectMember!]!
labels: [TaskLabel!]!
}
@ -261,6 +262,11 @@ input UpdateTaskGroupName {
name: String!
}
input UpdateTaskDueDate {
taskID: UUID!
dueDate: Time
}
type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
@ -291,6 +297,7 @@ type Mutation {
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
updateTaskName(input: UpdateTaskName!): Task!
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
assignTask(input: AssignTaskInput): Task!
unassignTask(input: UnassignTaskInput): Task!

View File

@ -260,6 +260,21 @@ func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskN
return &task, err
}
func (r *mutationResolver) UpdateTaskDueDate(ctx context.Context, input UpdateTaskDueDate) (*pg.Task, error) {
var dueDate sql.NullTime
if input.DueDate == nil {
dueDate = sql.NullTime{Valid: false, Time: time.Now()}
} else {
dueDate = sql.NullTime{Valid: true, Time: *input.DueDate}
}
task, err := r.Repository.UpdateTaskDueDate(ctx, pg.UpdateTaskDueDateParams{
TaskID: input.TaskID,
DueDate: dueDate,
})
return &task, err
}
func (r *mutationResolver) DeleteTask(ctx context.Context, input DeleteTaskInput) (*DeleteTaskPayload, error) {
taskID, err := uuid.Parse(input.TaskID)
if err != nil {
@ -484,6 +499,13 @@ func (r *taskResolver) Description(ctx context.Context, obj *pg.Task) (*string,
return &task.Description.String, nil
}
func (r *taskResolver) DueDate(ctx context.Context, obj *pg.Task) (*time.Time, error) {
if obj.DueDate.Valid {
return &obj.DueDate.Time, nil
}
return nil, nil
}
func (r *taskResolver) Assigned(ctx context.Context, obj *pg.Task) ([]ProjectMember, error) {
taskMemberLinks, err := r.Repository.GetAssignedMembersForTask(ctx, obj.TaskID)
taskMembers := []ProjectMember{}

View File

@ -30,6 +30,7 @@ type Repository interface {
UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error)
DeleteTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) error
UpdateTaskDueDate(ctx context.Context, arg UpdateTaskDueDateParams) (Task, error)
CreateProjectLabel(ctx context.Context, arg CreateProjectLabelParams) (ProjectLabel, error)
GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)

View File

@ -56,11 +56,13 @@ type Querier interface {
GetTeamsForOrganization(ctx context.Context, organizationID uuid.UUID) ([]Team, error)
GetUserAccountByID(ctx context.Context, userID uuid.UUID) (UserAccount, error)
GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error)
SetTaskGroupName(ctx context.Context, arg SetTaskGroupNameParams) (TaskGroup, error)
UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error)
UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error)
UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error)
UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error)
UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescriptionParams) (Task, error)
UpdateTaskDueDate(ctx context.Context, arg UpdateTaskDueDateParams) (Task, error)
UpdateTaskGroupLocation(ctx context.Context, arg UpdateTaskGroupLocationParams) (TaskGroup, error)
UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocationParams) (Task, error)
UpdateTaskName(ctx context.Context, arg UpdateTaskNameParams) (Task, error)

View File

@ -177,6 +177,30 @@ func (q *Queries) UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescr
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
`
type UpdateTaskDueDateParams struct {
TaskID uuid.UUID `json:"task_id"`
DueDate sql.NullTime `json:"due_date"`
}
func (q *Queries) UpdateTaskDueDate(ctx context.Context, arg UpdateTaskDueDateParams) (Task, error) {
row := q.db.QueryRowContext(ctx, updateTaskDueDate, arg.TaskID, arg.DueDate)
var i Task
err := row.Scan(
&i.TaskID,
&i.TaskGroupID,
&i.CreatedAt,
&i.Name,
&i.Position,
&i.Description,
&i.DueDate,
)
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
`

View File

@ -135,6 +135,28 @@ func (q *Queries) GetTaskGroupsForProject(ctx context.Context, projectID uuid.UU
return items, nil
}
const setTaskGroupName = `-- name: SetTaskGroupName :one
UPDATE task_group SET name = $2 WHERE task_group_id = $1 RETURNING task_group_id, project_id, created_at, name, position
`
type SetTaskGroupNameParams struct {
TaskGroupID uuid.UUID `json:"task_group_id"`
Name string `json:"name"`
}
func (q *Queries) SetTaskGroupName(ctx context.Context, arg SetTaskGroupNameParams) (TaskGroup, error) {
row := q.db.QueryRowContext(ctx, setTaskGroupName, arg.TaskGroupID, arg.Name)
var i TaskGroup
err := row.Scan(
&i.TaskGroupID,
&i.ProjectID,
&i.CreatedAt,
&i.Name,
&i.Position,
)
return i, err
}
const updateTaskGroupLocation = `-- name: UpdateTaskGroupLocation :one
UPDATE task_group SET position = $2 WHERE task_group_id = $1 RETURNING task_group_id, project_id, created_at, name, position
`

View File

@ -25,3 +25,6 @@ UPDATE task SET name = $2 WHERE task_id = $1 RETURNING *;
-- name: DeleteTasksByTaskGroupID :execrows
DELETE FROM task where task_group_id = $1;
-- name: UpdateTaskDueDate :one
UPDATE task SET due_date = $2 WHERE task_id = $1 RETURNING *;