feature: add checklist

This commit is contained in:
Jordan Knott
2020-06-18 18:12:15 -05:00
parent b6f0e8b6b2
commit 9d6c67f791
73 changed files with 4582 additions and 390 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,10 +19,36 @@ type AssignTaskInput struct {
UserID uuid.UUID `json:"userID"`
}
type ChecklistBadge struct {
Complete int `json:"complete"`
Total int `json:"total"`
}
type CreateTaskChecklist struct {
TaskID uuid.UUID `json:"taskID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type CreateTaskChecklistItem struct {
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type DeleteProjectLabel struct {
ProjectLabelID uuid.UUID `json:"projectLabelID"`
}
type DeleteTaskChecklistItem struct {
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
}
type DeleteTaskChecklistItemPayload struct {
Ok bool `json:"ok"`
TaskChecklistItem *pg.TaskChecklistItem `json:"taskChecklistItem"`
}
type DeleteTaskGroupInput struct {
TaskGroupID uuid.UUID `json:"taskGroupID"`
}
@ -129,6 +155,20 @@ type RemoveTaskLabelInput struct {
TaskLabelID uuid.UUID `json:"taskLabelID"`
}
type SetTaskChecklistItemComplete struct {
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Complete bool `json:"complete"`
}
type SetTaskComplete struct {
TaskID uuid.UUID `json:"taskID"`
Complete bool `json:"complete"`
}
type TaskBadges struct {
Checklist *ChecklistBadge `json:"checklist"`
}
type ToggleTaskLabelInput struct {
TaskID uuid.UUID `json:"taskID"`
ProjectLabelID uuid.UUID `json:"projectLabelID"`
@ -165,6 +205,11 @@ type UpdateProjectName struct {
Name string `json:"name"`
}
type UpdateTaskChecklistItemName struct {
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Name string `json:"name"`
}
type UpdateTaskDescriptionInput struct {
TaskID uuid.UUID `json:"taskID"`
Description string `json:"description"`

View File

@ -77,6 +77,15 @@ type TaskGroup {
tasks: [Task!]!
}
type ChecklistBadge {
complete: Int!
total: Int!
}
type TaskBadges {
checklist: ChecklistBadge
}
type Task {
id: ID!
taskGroup: TaskGroup!
@ -85,8 +94,11 @@ type Task {
position: Float!
description: String
dueDate: Time
complete: Boolean!
assigned: [ProjectMember!]!
labels: [TaskLabel!]!
checklists: [TaskChecklist!]!
badges: TaskBadges!
}
input ProjectsFilter {
@ -188,6 +200,27 @@ type DeleteTaskGroupPayload {
taskGroup: TaskGroup!
}
type DeleteTaskChecklistItemPayload {
ok: Boolean!
taskChecklistItem: TaskChecklistItem!
}
type TaskChecklistItem {
id: ID!
name: String!
taskChecklistID: UUID!
complete: Boolean!
position: Float!
dueDate: Time!
}
type TaskChecklist {
id: ID!
name: String!
position: Float!
items: [TaskChecklistItem!]!
}
input AssignTaskInput {
taskID: UUID!
userID: UUID!
@ -267,6 +300,36 @@ input UpdateTaskDueDate {
dueDate: Time
}
input SetTaskComplete {
taskID: UUID!
complete: Boolean!
}
input CreateTaskChecklist {
taskID: UUID!
name: String!
position: Float!
}
input CreateTaskChecklistItem {
taskChecklistID: UUID!
name: String!
position: Float!
}
input SetTaskChecklistItemComplete {
taskChecklistItemID: UUID!
complete: Boolean!
}
input DeleteTaskChecklistItem {
taskChecklistItemID: UUID!
}
input UpdateTaskChecklistItemName {
taskChecklistItemID: UUID!
name: String!
}
type Mutation {
createRefreshToken(input: NewRefreshToken!): RefreshToken!
@ -293,10 +356,17 @@ type Mutation {
removeTaskLabel(input: RemoveTaskLabelInput): Task!
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
createTask(input: NewTask!): Task!
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
updateTaskName(input: UpdateTaskName!): Task!
setTaskComplete(input: SetTaskComplete!): Task!
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
assignTask(input: AssignTaskInput): Task!

View File

@ -143,7 +143,11 @@ func (r *mutationResolver) UpdateTaskGroupLocation(ctx context.Context, input Ne
}
func (r *mutationResolver) UpdateTaskGroupName(ctx context.Context, input UpdateTaskGroupName) (*pg.TaskGroup, error) {
panic(fmt.Errorf("not implemented"))
taskGroup, err := r.Repository.SetTaskGroupName(ctx, pg.SetTaskGroupNameParams{TaskGroupID: input.TaskGroupID, Name: input.Name})
if err != nil {
return &pg.TaskGroup{}, err
}
return &taskGroup, nil
}
func (r *mutationResolver) DeleteTaskGroup(ctx context.Context, input DeleteTaskGroupInput) (*DeleteTaskGroupPayload, error) {
@ -225,6 +229,75 @@ func (r *mutationResolver) ToggleTaskLabel(ctx context.Context, input ToggleTask
return &payload, nil
}
func (r *mutationResolver) CreateTaskChecklist(ctx context.Context, input CreateTaskChecklist) (*pg.TaskChecklist, error) {
createdAt := time.Now().UTC()
taskChecklist, err := r.Repository.CreateTaskChecklist(ctx, pg.CreateTaskChecklistParams{
TaskID: input.TaskID,
CreatedAt: createdAt,
Name: input.Name,
Position: input.Position,
})
if err != nil {
return &pg.TaskChecklist{}, err
}
return &taskChecklist, nil
}
func (r *mutationResolver) CreateTaskChecklistItem(ctx context.Context, input CreateTaskChecklistItem) (*pg.TaskChecklistItem, error) {
createdAt := time.Now().UTC()
taskChecklistItem, err := r.Repository.CreateTaskChecklistItem(ctx, pg.CreateTaskChecklistItemParams{
TaskChecklistID: input.TaskChecklistID,
CreatedAt: createdAt,
Name: input.Name,
Position: input.Position,
})
if err != nil {
return &pg.TaskChecklistItem{}, err
}
return &taskChecklistItem, nil
}
func (r *mutationResolver) UpdateTaskChecklistItemName(ctx context.Context, input UpdateTaskChecklistItemName) (*pg.TaskChecklistItem, error) {
task, err := r.Repository.UpdateTaskChecklistItemName(ctx, pg.UpdateTaskChecklistItemNameParams{TaskChecklistItemID: input.TaskChecklistItemID,
Name: input.Name,
})
if err != nil {
return &pg.TaskChecklistItem{}, err
}
return &task, nil
}
func (r *mutationResolver) SetTaskChecklistItemComplete(ctx context.Context, input SetTaskChecklistItemComplete) (*pg.TaskChecklistItem, error) {
item, err := r.Repository.SetTaskChecklistItemComplete(ctx, pg.SetTaskChecklistItemCompleteParams{TaskChecklistItemID: input.TaskChecklistItemID, Complete: input.Complete})
if err != nil {
return &pg.TaskChecklistItem{}, err
}
return &item, nil
}
func (r *mutationResolver) DeleteTaskChecklistItem(ctx context.Context, input DeleteTaskChecklistItem) (*DeleteTaskChecklistItemPayload, error) {
item, err := r.Repository.GetTaskChecklistItemByID(ctx, input.TaskChecklistItemID)
if err != nil {
return &DeleteTaskChecklistItemPayload{
Ok: false,
TaskChecklistItem: &pg.TaskChecklistItem{},
}, err
}
err = r.Repository.DeleteTaskChecklistItem(ctx, input.TaskChecklistItemID)
if err != nil {
return &DeleteTaskChecklistItemPayload{
Ok: false,
TaskChecklistItem: &pg.TaskChecklistItem{},
}, err
}
return &DeleteTaskChecklistItemPayload{
Ok: true,
TaskChecklistItem: &item,
}, err
}
func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*pg.Task, error) {
taskGroupID, err := uuid.Parse(input.TaskGroupID)
createdAt := time.Now().UTC()
@ -260,6 +333,14 @@ func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskN
return &task, err
}
func (r *mutationResolver) SetTaskComplete(ctx context.Context, input SetTaskComplete) (*pg.Task, error) {
task, err := r.Repository.SetTaskComplete(ctx, pg.SetTaskCompleteParams{TaskID: input.TaskID, Complete: input.Complete})
if err != nil {
return &pg.Task{}, err
}
return &task, nil
}
func (r *mutationResolver) UpdateTaskDueDate(ctx context.Context, input UpdateTaskDueDate) (*pg.Task, error) {
var dueDate sql.NullTime
if input.DueDate == nil {
@ -531,6 +612,51 @@ func (r *taskResolver) Labels(ctx context.Context, obj *pg.Task) ([]pg.TaskLabel
return r.Repository.GetTaskLabelsForTaskID(ctx, obj.TaskID)
}
func (r *taskResolver) Checklists(ctx context.Context, obj *pg.Task) ([]pg.TaskChecklist, error) {
return r.Repository.GetTaskChecklistsForTask(ctx, obj.TaskID)
}
func (r *taskResolver) Badges(ctx context.Context, obj *pg.Task) (*TaskBadges, error) {
checklists, err := r.Repository.GetTaskChecklistsForTask(ctx, obj.TaskID)
if err != nil {
return &TaskBadges{}, err
}
if len(checklists) == 0 {
return &TaskBadges{Checklist: nil}, err
}
complete := 0
total := 0
for _, checklist := range checklists {
items, err := r.Repository.GetTaskChecklistItemsForTaskChecklist(ctx, checklist.TaskChecklistID)
if err != nil {
return &TaskBadges{}, err
}
for _, item := range items {
total += 1
if item.Complete {
complete += 1
}
}
}
return &TaskBadges{Checklist: &ChecklistBadge{Total: total, Complete: complete}}, nil
}
func (r *taskChecklistResolver) ID(ctx context.Context, obj *pg.TaskChecklist) (uuid.UUID, error) {
return obj.TaskChecklistID, nil
}
func (r *taskChecklistResolver) Items(ctx context.Context, obj *pg.TaskChecklist) ([]pg.TaskChecklistItem, error) {
return r.Repository.GetTaskChecklistItemsForTaskChecklist(ctx, obj.TaskChecklistID)
}
func (r *taskChecklistItemResolver) ID(ctx context.Context, obj *pg.TaskChecklistItem) (uuid.UUID, error) {
return obj.TaskChecklistItemID, nil
}
func (r *taskChecklistItemResolver) DueDate(ctx context.Context, obj *pg.TaskChecklistItem) (*time.Time, error) {
panic(fmt.Errorf("not implemented"))
}
func (r *taskGroupResolver) ID(ctx context.Context, obj *pg.TaskGroup) (uuid.UUID, error) {
return obj.TaskGroupID, nil
}
@ -591,6 +717,12 @@ func (r *Resolver) RefreshToken() RefreshTokenResolver { return &refreshTokenRes
// Task returns TaskResolver implementation.
func (r *Resolver) Task() TaskResolver { return &taskResolver{r} }
// TaskChecklist returns TaskChecklistResolver implementation.
func (r *Resolver) TaskChecklist() TaskChecklistResolver { return &taskChecklistResolver{r} }
// TaskChecklistItem returns TaskChecklistItemResolver implementation.
func (r *Resolver) TaskChecklistItem() TaskChecklistItemResolver { return &taskChecklistItemResolver{r} }
// TaskGroup returns TaskGroupResolver implementation.
func (r *Resolver) TaskGroup() TaskGroupResolver { return &taskGroupResolver{r} }
@ -610,6 +742,8 @@ type projectLabelResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
type refreshTokenResolver struct{ *Resolver }
type taskResolver struct{ *Resolver }
type taskChecklistResolver struct{ *Resolver }
type taskChecklistItemResolver struct{ *Resolver }
type taskGroupResolver struct{ *Resolver }
type taskLabelResolver struct{ *Resolver }
type teamResolver struct{ *Resolver }