2020-04-11 04:22:22 +02:00
|
|
|
package graph
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
// This file will be automatically regenerated based on the schema, any resolver implementations
|
|
|
|
// will be copied through when generating and any unknown code will be moved to the end.
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"database/sql"
|
2020-07-05 01:02:57 +02:00
|
|
|
"errors"
|
2020-04-20 05:02:55 +02:00
|
|
|
"fmt"
|
2020-04-10 04:40:22 +02:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
2020-08-01 03:01:14 +02:00
|
|
|
"github.com/jordanknott/taskcafe/internal/auth"
|
2020-08-07 03:50:35 +02:00
|
|
|
"github.com/jordanknott/taskcafe/internal/db"
|
2020-04-10 04:40:22 +02:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/vektah/gqlparser/v2/gqlerror"
|
2020-06-23 22:20:53 +02:00
|
|
|
"golang.org/x/crypto/bcrypt"
|
2020-04-10 04:40:22 +02:00
|
|
|
)
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *labelColorResolver) ID(ctx context.Context, obj *db.LabelColor) (uuid.UUID, error) {
|
2020-05-27 23:18:50 +02:00
|
|
|
return obj.LabelColorID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateProject(ctx context.Context, input NewProject) (*db.Project, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
createdAt := time.Now().UTC()
|
2020-08-01 03:01:14 +02:00
|
|
|
log.WithFields(log.Fields{"userID": input.UserID, "name": input.Name, "teamID": input.TeamID}).Info("creating new project")
|
|
|
|
project, err := r.Repository.CreateProject(ctx, db.CreateProjectParams{input.TeamID, createdAt, input.Name})
|
2020-04-10 04:40:22 +02:00
|
|
|
return &project, err
|
|
|
|
}
|
|
|
|
|
2020-06-21 00:49:11 +02:00
|
|
|
func (r *mutationResolver) DeleteProject(ctx context.Context, input DeleteProject) (*DeleteProjectPayload, error) {
|
|
|
|
project, err := r.Repository.GetProjectByID(ctx, input.ProjectID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteProjectPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
err = r.Repository.DeleteProjectByID(ctx, input.ProjectID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteProjectPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
return &DeleteProjectPayload{Project: &project, Ok: true}, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateProjectName(ctx context.Context, input *UpdateProjectName) (*db.Project, error) {
|
|
|
|
project, err := r.Repository.UpdateProjectNameByID(ctx, db.UpdateProjectNameByIDParams{ProjectID: input.ProjectID, Name: input.Name})
|
2020-05-31 06:11:19 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.Project{}, err
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
|
|
|
return &project, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateProjectLabel(ctx context.Context, input NewProjectLabel) (*db.ProjectLabel, error) {
|
2020-05-27 23:18:50 +02:00
|
|
|
createdAt := time.Now().UTC()
|
|
|
|
|
|
|
|
var name sql.NullString
|
|
|
|
if input.Name != nil {
|
|
|
|
name = sql.NullString{
|
|
|
|
*input.Name,
|
|
|
|
true,
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
name = sql.NullString{
|
|
|
|
"",
|
|
|
|
false,
|
|
|
|
}
|
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
projectLabel, err := r.Repository.CreateProjectLabel(ctx, db.CreateProjectLabelParams{input.ProjectID, input.LabelColorID, createdAt, name})
|
2020-05-27 23:18:50 +02:00
|
|
|
return &projectLabel, err
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) DeleteProjectLabel(ctx context.Context, input DeleteProjectLabel) (*db.ProjectLabel, error) {
|
2020-05-28 03:12:50 +02:00
|
|
|
label, err := r.Repository.GetProjectLabelByID(ctx, input.ProjectLabelID)
|
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.ProjectLabel{}, err
|
2020-05-28 03:12:50 +02:00
|
|
|
}
|
|
|
|
err = r.Repository.DeleteProjectLabelByID(ctx, input.ProjectLabelID)
|
|
|
|
return &label, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateProjectLabel(ctx context.Context, input UpdateProjectLabel) (*db.ProjectLabel, error) {
|
|
|
|
label, err := r.Repository.UpdateProjectLabel(ctx, db.UpdateProjectLabelParams{ProjectLabelID: input.ProjectLabelID, LabelColorID: input.LabelColorID, Name: sql.NullString{String: input.Name, Valid: true}})
|
2020-05-28 03:12:50 +02:00
|
|
|
return &label, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateProjectLabelName(ctx context.Context, input UpdateProjectLabelName) (*db.ProjectLabel, error) {
|
|
|
|
label, err := r.Repository.UpdateProjectLabelName(ctx, db.UpdateProjectLabelNameParams{ProjectLabelID: input.ProjectLabelID, Name: sql.NullString{String: input.Name, Valid: true}})
|
2020-05-28 03:12:50 +02:00
|
|
|
return &label, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateProjectLabelColor(ctx context.Context, input UpdateProjectLabelColor) (*db.ProjectLabel, error) {
|
|
|
|
label, err := r.Repository.UpdateProjectLabelColor(ctx, db.UpdateProjectLabelColorParams{ProjectLabelID: input.ProjectLabelID, LabelColorID: input.LabelColorID})
|
2020-05-28 03:12:50 +02:00
|
|
|
return &label, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateProjectMember(ctx context.Context, input CreateProjectMember) (*CreateProjectMemberPayload, error) {
|
|
|
|
addedAt := time.Now().UTC()
|
|
|
|
_, err := r.Repository.CreateProjectMember(ctx, db.CreateProjectMemberParams{ProjectID: input.ProjectID, UserID: input.UserID, AddedAt: addedAt, RoleCode: "member"})
|
2020-04-10 04:40:22 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &CreateProjectMemberPayload{Ok: false}, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
|
|
|
|
if err != nil {
|
|
|
|
return &CreateProjectMemberPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
|
|
|
|
|
|
|
role, err := r.Repository.GetRoleForProjectMemberByUserID(ctx, db.GetRoleForProjectMemberByUserIDParams{UserID: input.UserID, ProjectID: input.ProjectID})
|
|
|
|
if err != nil {
|
|
|
|
return &CreateProjectMemberPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
return &CreateProjectMemberPayload{Ok: true, Member: &Member{
|
|
|
|
ID: input.UserID,
|
|
|
|
FullName: user.FullName,
|
2020-07-18 02:40:05 +02:00
|
|
|
Username: user.Username,
|
2020-07-05 01:02:57 +02:00
|
|
|
ProfileIcon: profileIcon,
|
|
|
|
Role: &db.Role{Code: role.Code, Name: role.Name},
|
|
|
|
}}, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) DeleteProjectMember(ctx context.Context, input DeleteProjectMember) (*DeleteProjectMemberPayload, error) {
|
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteProjectMemberPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
|
|
|
role, err := r.Repository.GetRoleForProjectMemberByUserID(ctx, db.GetRoleForProjectMemberByUserIDParams{UserID: input.UserID, ProjectID: input.ProjectID})
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteProjectMemberPayload{Ok: false}, err
|
|
|
|
}
|
2020-07-18 02:40:05 +02:00
|
|
|
err = r.Repository.DeleteProjectMember(ctx, db.DeleteProjectMemberParams{UserID: input.UserID, ProjectID: input.ProjectID})
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteProjectMemberPayload{Ok: false}, err
|
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
return &DeleteProjectMemberPayload{Ok: true, Member: &Member{
|
|
|
|
ID: input.UserID,
|
|
|
|
FullName: user.FullName,
|
|
|
|
ProfileIcon: profileIcon,
|
|
|
|
Role: &db.Role{Code: role.Code, Name: role.Name},
|
|
|
|
}, ProjectID: input.ProjectID}, nil
|
2020-04-11 04:47:43 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateProjectMemberRole(ctx context.Context, input UpdateProjectMemberRole) (*UpdateProjectMemberRolePayload, error) {
|
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
|
2020-06-19 01:12:15 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
log.WithError(err).Error("get user account")
|
|
|
|
return &UpdateProjectMemberRolePayload{Ok: false}, err
|
2020-06-19 01:12:15 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
_, err = r.Repository.UpdateProjectMemberRole(ctx, db.UpdateProjectMemberRoleParams{ProjectID: input.ProjectID,
|
|
|
|
UserID: input.UserID, RoleCode: input.RoleCode.String()})
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("update project member role")
|
|
|
|
return &UpdateProjectMemberRolePayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
role, err := r.Repository.GetRoleForProjectMemberByUserID(ctx, db.GetRoleForProjectMemberByUserIDParams{UserID: user.UserID, ProjectID: input.ProjectID})
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("get role for project member")
|
|
|
|
return &UpdateProjectMemberRolePayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
member := Member{ID: user.UserID, FullName: user.FullName, ProfileIcon: profileIcon,
|
|
|
|
Role: &db.Role{Code: role.Code, Name: role.Name},
|
|
|
|
}
|
|
|
|
return &UpdateProjectMemberRolePayload{Ok: true, Member: &member}, err
|
2020-06-13 00:21:58 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.Task, error) {
|
|
|
|
taskGroupID, err := uuid.Parse(input.TaskGroupID)
|
|
|
|
createdAt := time.Now().UTC()
|
2020-04-20 05:02:55 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.Task{}, err
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
|
|
|
|
task, err := r.Repository.CreateTask(ctx, db.CreateTaskParams{taskGroupID, createdAt, input.Name, input.Position})
|
|
|
|
return &task, err
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) DeleteTask(ctx context.Context, input DeleteTaskInput) (*DeleteTaskPayload, error) {
|
|
|
|
taskID, err := uuid.Parse(input.TaskID)
|
2020-05-31 06:11:19 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &DeleteTaskPayload{}, err
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
|
|
|
|
log.WithFields(log.Fields{
|
|
|
|
"taskID": taskID.String(),
|
|
|
|
}).Info("deleting task")
|
|
|
|
err = r.Repository.DeleteTaskByID(ctx, taskID)
|
2020-05-31 06:11:19 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &DeleteTaskPayload{}, err
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
return &DeleteTaskPayload{taskID.String()}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*db.Task, error) {
|
|
|
|
task, err := r.Repository.UpdateTaskDescription(ctx, db.UpdateTaskDescriptionParams{input.TaskID, sql.NullString{String: input.Description, Valid: true}})
|
2020-05-31 06:11:19 +02:00
|
|
|
return &task, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskLocation(ctx context.Context, input NewTaskLocation) (*UpdateTaskLocationPayload, error) {
|
|
|
|
previousTask, err := r.Repository.GetTaskByID(ctx, input.TaskID)
|
2020-05-31 06:11:19 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &UpdateTaskLocationPayload{}, err
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
task, err := r.Repository.UpdateTaskLocation(ctx, db.UpdateTaskLocationParams{input.TaskID, input.TaskGroupID, input.Position})
|
2020-05-31 06:11:19 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
return &UpdateTaskLocationPayload{Task: &task, PreviousTaskGroupID: previousTask.TaskGroupID}, err
|
|
|
|
}
|
2020-05-31 06:11:19 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskName) (*db.Task, error) {
|
|
|
|
taskID, err := uuid.Parse(input.TaskID)
|
|
|
|
if err != nil {
|
|
|
|
return &db.Task{}, err
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
task, err := r.Repository.UpdateTaskName(ctx, db.UpdateTaskNameParams{taskID, input.Name})
|
|
|
|
return &task, err
|
|
|
|
}
|
2020-05-31 06:11:19 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
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})
|
2020-05-31 06:11:19 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.Task{}, err
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
return &task, nil
|
|
|
|
}
|
2020-05-31 06:11:19 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskDueDate(ctx context.Context, input UpdateTaskDueDate) (*db.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, db.UpdateTaskDueDateParams{
|
|
|
|
TaskID: input.TaskID,
|
|
|
|
DueDate: dueDate,
|
2020-05-31 06:11:19 +02:00
|
|
|
})
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
return &task, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) AssignTask(ctx context.Context, input *AssignTaskInput) (*db.Task, error) {
|
|
|
|
assignedDate := time.Now().UTC()
|
|
|
|
assignedTask, err := r.Repository.CreateTaskAssigned(ctx, db.CreateTaskAssignedParams{input.TaskID, input.UserID, assignedDate})
|
|
|
|
log.WithFields(log.Fields{
|
|
|
|
"userID": assignedTask.UserID,
|
|
|
|
"taskID": assignedTask.TaskID,
|
|
|
|
"assignedTaskID": assignedTask.TaskAssignedID,
|
|
|
|
}).Info("assigned task")
|
2020-05-31 06:11:19 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.Task{}, err
|
2020-05-31 06:11:19 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
|
|
|
|
return &task, err
|
|
|
|
}
|
2020-05-31 06:11:19 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UnassignTask(ctx context.Context, input *UnassignTaskInput) (*db.Task, error) {
|
|
|
|
task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
|
|
|
|
if err != nil {
|
|
|
|
return &db.Task{}, err
|
|
|
|
}
|
|
|
|
_, err = r.Repository.DeleteTaskAssignedByID(ctx, db.DeleteTaskAssignedByIDParams{input.TaskID, input.UserID})
|
|
|
|
if err != nil {
|
|
|
|
return &db.Task{}, err
|
|
|
|
}
|
|
|
|
return &task, nil
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateTaskChecklist(ctx context.Context, input CreateTaskChecklist) (*db.TaskChecklist, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
createdAt := time.Now().UTC()
|
2020-07-05 01:02:57 +02:00
|
|
|
taskChecklist, err := r.Repository.CreateTaskChecklist(ctx, db.CreateTaskChecklistParams{
|
2020-06-19 01:12:15 +02:00
|
|
|
TaskID: input.TaskID,
|
|
|
|
CreatedAt: createdAt,
|
|
|
|
Name: input.Name,
|
|
|
|
Position: input.Position,
|
|
|
|
})
|
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.TaskChecklist{}, err
|
2020-06-19 01:12:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return &taskChecklist, nil
|
|
|
|
}
|
|
|
|
|
2020-06-23 22:20:53 +02:00
|
|
|
func (r *mutationResolver) DeleteTaskChecklist(ctx context.Context, input DeleteTaskChecklist) (*DeleteTaskChecklistPayload, error) {
|
|
|
|
taskChecklist, err := r.Repository.GetTaskChecklistByID(ctx, input.TaskChecklistID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteTaskChecklistPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
err = r.Repository.DeleteTaskChecklistByID(ctx, input.TaskChecklistID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteTaskChecklistPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
return &DeleteTaskChecklistPayload{Ok: true, TaskChecklist: &taskChecklist}, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskChecklistName(ctx context.Context, input UpdateTaskChecklistName) (*db.TaskChecklist, error) {
|
|
|
|
checklist, err := r.Repository.UpdateTaskChecklistName(ctx, db.UpdateTaskChecklistNameParams{TaskChecklistID: input.TaskChecklistID, Name: input.Name})
|
2020-06-23 22:20:53 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.TaskChecklist{}, err
|
2020-06-23 22:20:53 +02:00
|
|
|
}
|
|
|
|
return &checklist, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateTaskChecklistItem(ctx context.Context, input CreateTaskChecklistItem) (*db.TaskChecklistItem, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
createdAt := time.Now().UTC()
|
2020-07-05 01:02:57 +02:00
|
|
|
taskChecklistItem, err := r.Repository.CreateTaskChecklistItem(ctx, db.CreateTaskChecklistItemParams{
|
2020-06-19 01:12:15 +02:00
|
|
|
TaskChecklistID: input.TaskChecklistID,
|
|
|
|
CreatedAt: createdAt,
|
|
|
|
Name: input.Name,
|
|
|
|
Position: input.Position,
|
|
|
|
})
|
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.TaskChecklistItem{}, err
|
2020-06-19 01:12:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return &taskChecklistItem, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskChecklistItemName(ctx context.Context, input UpdateTaskChecklistItemName) (*db.TaskChecklistItem, error) {
|
|
|
|
task, err := r.Repository.UpdateTaskChecklistItemName(ctx, db.UpdateTaskChecklistItemNameParams{TaskChecklistItemID: input.TaskChecklistItemID,
|
2020-06-19 01:12:15 +02:00
|
|
|
Name: input.Name,
|
|
|
|
})
|
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.TaskChecklistItem{}, err
|
2020-06-19 01:12:15 +02:00
|
|
|
}
|
|
|
|
return &task, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) SetTaskChecklistItemComplete(ctx context.Context, input SetTaskChecklistItemComplete) (*db.TaskChecklistItem, error) {
|
|
|
|
item, err := r.Repository.SetTaskChecklistItemComplete(ctx, db.SetTaskChecklistItemCompleteParams{TaskChecklistItemID: input.TaskChecklistItemID, Complete: input.Complete})
|
2020-06-19 01:12:15 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.TaskChecklistItem{}, err
|
2020-06-19 01:12:15 +02:00
|
|
|
}
|
|
|
|
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,
|
2020-07-05 01:02:57 +02:00
|
|
|
TaskChecklistItem: &db.TaskChecklistItem{},
|
2020-06-19 01:12:15 +02:00
|
|
|
}, err
|
|
|
|
}
|
|
|
|
err = r.Repository.DeleteTaskChecklistItem(ctx, input.TaskChecklistItemID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteTaskChecklistItemPayload{
|
|
|
|
Ok: false,
|
2020-07-05 01:02:57 +02:00
|
|
|
TaskChecklistItem: &db.TaskChecklistItem{},
|
2020-06-19 01:12:15 +02:00
|
|
|
}, err
|
|
|
|
}
|
|
|
|
return &DeleteTaskChecklistItemPayload{
|
|
|
|
Ok: true,
|
|
|
|
TaskChecklistItem: &item,
|
|
|
|
}, err
|
|
|
|
}
|
|
|
|
|
2020-07-12 09:06:11 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskChecklistLocation(ctx context.Context, input UpdateTaskChecklistLocation) (*UpdateTaskChecklistLocationPayload, error) {
|
|
|
|
checklist, err := r.Repository.UpdateTaskChecklistPosition(ctx, db.UpdateTaskChecklistPositionParams{Position: input.Position, TaskChecklistID: input.ChecklistID})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return &UpdateTaskChecklistLocationPayload{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &UpdateTaskChecklistLocationPayload{Checklist: &checklist}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) UpdateTaskChecklistItemLocation(ctx context.Context, input UpdateTaskChecklistItemLocation) (*UpdateTaskChecklistItemLocationPayload, error) {
|
|
|
|
currentChecklistItem, err := r.Repository.GetTaskChecklistItemByID(ctx, input.ChecklistItemID)
|
|
|
|
|
|
|
|
checklistItem, err := r.Repository.UpdateTaskChecklistItemLocation(ctx, db.UpdateTaskChecklistItemLocationParams{TaskChecklistID: input.ChecklistID, TaskChecklistItemID: input.ChecklistItemID, Position: input.Position})
|
|
|
|
if err != nil {
|
|
|
|
return &UpdateTaskChecklistItemLocationPayload{}, err
|
|
|
|
}
|
|
|
|
return &UpdateTaskChecklistItemLocationPayload{PrevChecklistID: currentChecklistItem.TaskChecklistID, ChecklistID: input.ChecklistID, ChecklistItem: &checklistItem}, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*db.TaskGroup, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
createdAt := time.Now().UTC()
|
2020-07-05 01:02:57 +02:00
|
|
|
projectID, err := uuid.Parse(input.ProjectID)
|
2020-04-10 04:40:22 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.TaskGroup{}, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
project, err := r.Repository.CreateTaskGroup(ctx,
|
|
|
|
db.CreateTaskGroupParams{projectID, createdAt, input.Name, input.Position})
|
|
|
|
return &project, err
|
|
|
|
}
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskGroupLocation(ctx context.Context, input NewTaskGroupLocation) (*db.TaskGroup, error) {
|
|
|
|
taskGroup, err := r.Repository.UpdateTaskGroupLocation(ctx, db.UpdateTaskGroupLocationParams{
|
|
|
|
input.TaskGroupID,
|
|
|
|
input.Position,
|
|
|
|
})
|
|
|
|
return &taskGroup, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTaskGroupName(ctx context.Context, input UpdateTaskGroupName) (*db.TaskGroup, error) {
|
|
|
|
taskGroup, err := r.Repository.SetTaskGroupName(ctx, db.SetTaskGroupNameParams{TaskGroupID: input.TaskGroupID, Name: input.Name})
|
|
|
|
if err != nil {
|
|
|
|
return &db.TaskGroup{}, err
|
|
|
|
}
|
|
|
|
return &taskGroup, nil
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) DeleteTaskGroup(ctx context.Context, input DeleteTaskGroupInput) (*DeleteTaskGroupPayload, error) {
|
|
|
|
deletedTasks, err := r.Repository.DeleteTasksByTaskGroupID(ctx, input.TaskGroupID)
|
2020-04-10 04:40:22 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &DeleteTaskGroupPayload{}, err
|
|
|
|
}
|
|
|
|
taskGroup, err := r.Repository.GetTaskGroupByID(ctx, input.TaskGroupID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteTaskGroupPayload{}, err
|
|
|
|
}
|
|
|
|
deletedTaskGroups, err := r.Repository.DeleteTaskGroupByID(ctx, input.TaskGroupID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteTaskGroupPayload{}, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
return &DeleteTaskGroupPayload{true, int(deletedTasks + deletedTaskGroups), &taskGroup}, nil
|
|
|
|
}
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) AddTaskLabel(ctx context.Context, input *AddTaskLabelInput) (*db.Task, error) {
|
|
|
|
assignedDate := time.Now().UTC()
|
|
|
|
_, err := r.Repository.CreateTaskLabelForTask(ctx, db.CreateTaskLabelForTaskParams{input.TaskID, input.ProjectLabelID, assignedDate})
|
|
|
|
if err != nil {
|
|
|
|
return &db.Task{}, err
|
|
|
|
}
|
|
|
|
task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
|
|
|
|
return &task, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) RemoveTaskLabel(ctx context.Context, input *RemoveTaskLabelInput) (*db.Task, error) {
|
|
|
|
taskLabel, err := r.Repository.GetTaskLabelByID(ctx, input.TaskLabelID)
|
2020-04-10 04:40:22 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.Task{}, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
task, err := r.Repository.GetTaskByID(ctx, taskLabel.TaskID)
|
|
|
|
if err != nil {
|
|
|
|
return &db.Task{}, err
|
|
|
|
}
|
|
|
|
err = r.Repository.DeleteTaskLabelByID(ctx, input.TaskLabelID)
|
2020-04-10 04:40:22 +02:00
|
|
|
return &task, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) ToggleTaskLabel(ctx context.Context, input ToggleTaskLabelInput) (*ToggleTaskLabelPayload, error) {
|
|
|
|
task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
|
2020-06-19 01:12:15 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &ToggleTaskLabelPayload{}, err
|
2020-06-19 01:12:15 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
_, err = r.Repository.GetTaskLabelForTaskByProjectLabelID(ctx, db.GetTaskLabelForTaskByProjectLabelIDParams{TaskID: input.TaskID, ProjectLabelID: input.ProjectLabelID})
|
|
|
|
createdAt := time.Now().UTC()
|
|
|
|
|
|
|
|
if err == sql.ErrNoRows {
|
|
|
|
log.WithFields(log.Fields{"err": err}).Warning("no rows")
|
|
|
|
_, err := r.Repository.CreateTaskLabelForTask(ctx, db.CreateTaskLabelForTaskParams{
|
|
|
|
TaskID: input.TaskID,
|
|
|
|
ProjectLabelID: input.ProjectLabelID,
|
|
|
|
AssignedDate: createdAt,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return &ToggleTaskLabelPayload{}, err
|
|
|
|
}
|
|
|
|
payload := ToggleTaskLabelPayload{Active: true, Task: &task}
|
|
|
|
return &payload, nil
|
2020-06-16 00:36:59 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return &ToggleTaskLabelPayload{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = r.Repository.DeleteTaskLabelForTaskByProjectLabelID(ctx, db.DeleteTaskLabelForTaskByProjectLabelIDParams{
|
|
|
|
TaskID: input.TaskID,
|
|
|
|
ProjectLabelID: input.ProjectLabelID,
|
2020-06-16 00:36:59 +02:00
|
|
|
})
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
if err != nil {
|
|
|
|
return &ToggleTaskLabelPayload{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
payload := ToggleTaskLabelPayload{Active: false, Task: &task}
|
|
|
|
return &payload, nil
|
2020-06-16 00:36:59 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) DeleteTeam(ctx context.Context, input DeleteTeam) (*DeleteTeamPayload, error) {
|
|
|
|
team, err := r.Repository.GetTeamByID(ctx, input.TeamID)
|
2020-04-10 04:40:22 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
log.Error(err)
|
|
|
|
return &DeleteTeamPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
projects, err := r.Repository.GetAllProjectsForTeam(ctx, input.TeamID)
|
|
|
|
if err != nil {
|
|
|
|
log.Error(err)
|
|
|
|
return &DeleteTeamPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
err = r.Repository.DeleteTeamByID(ctx, input.TeamID)
|
|
|
|
if err != nil {
|
|
|
|
log.Error(err)
|
|
|
|
return &DeleteTeamPayload{Ok: false}, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
return &DeleteTeamPayload{Ok: true, Team: &team, Projects: projects}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) CreateTeam(ctx context.Context, input NewTeam) (*db.Team, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
_, role, ok := GetUser(ctx)
|
2020-07-05 01:02:57 +02:00
|
|
|
if !ok {
|
2020-08-01 03:01:14 +02:00
|
|
|
return &db.Team{}, nil
|
2020-07-05 01:02:57 +02:00
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
if role == auth.RoleAdmin {
|
|
|
|
createdAt := time.Now().UTC()
|
|
|
|
team, err := r.Repository.CreateTeam(ctx, db.CreateTeamParams{OrganizationID: input.OrganizationID, CreatedAt: createdAt, Name: input.Name})
|
|
|
|
return &team, err
|
2020-07-05 01:02:57 +02:00
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
return &db.Team{}, &gqlerror.Error{
|
|
|
|
Message: "You must be an organization admin to create new teams",
|
|
|
|
Extensions: map[string]interface{}{
|
|
|
|
"code": "1-400",
|
|
|
|
},
|
2020-07-05 01:02:57 +02:00
|
|
|
}
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) CreateTeamMember(ctx context.Context, input CreateTeamMember) (*CreateTeamMemberPayload, error) {
|
|
|
|
addedDate := time.Now().UTC()
|
|
|
|
team, err := r.Repository.GetTeamByID(ctx, input.TeamID)
|
2020-04-20 05:02:55 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &CreateTeamMemberPayload{}, err
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
_, err = r.Repository.CreateTeamMember(ctx, db.CreateTeamMemberParams{TeamID: input.TeamID, UserID: input.UserID, Addeddate: addedDate, RoleCode: RoleCodeMember.String()})
|
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
|
|
|
|
if err != nil {
|
|
|
|
return &CreateTeamMemberPayload{}, err
|
|
|
|
}
|
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
|
|
|
return &CreateTeamMemberPayload{
|
|
|
|
Team: &team,
|
|
|
|
TeamMember: &Member{
|
|
|
|
ID: user.UserID,
|
|
|
|
Username: user.Username,
|
|
|
|
FullName: user.FullName,
|
|
|
|
ProfileIcon: profileIcon,
|
|
|
|
Role: &db.Role{Code: "member", Name: "Member"},
|
|
|
|
}}, nil
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) UpdateTeamMemberRole(ctx context.Context, input UpdateTeamMemberRole) (*UpdateTeamMemberRolePayload, error) {
|
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
|
2020-04-21 01:04:27 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
log.WithError(err).Error("get user account")
|
|
|
|
return &UpdateTeamMemberRolePayload{Ok: false}, err
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
_, err = r.Repository.UpdateTeamMemberRole(ctx, db.UpdateTeamMemberRoleParams{TeamID: input.TeamID,
|
|
|
|
UserID: input.UserID, RoleCode: input.RoleCode.String()})
|
2020-04-21 01:04:27 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
log.WithError(err).Error("update project member role")
|
|
|
|
return &UpdateTeamMemberRolePayload{Ok: false}, err
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
role, err := r.Repository.GetRoleForTeamMember(ctx, db.GetRoleForTeamMemberParams{UserID: user.UserID, TeamID: input.TeamID})
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("get role for project member")
|
|
|
|
return &UpdateTeamMemberRolePayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
member := Member{ID: user.UserID, FullName: user.FullName, ProfileIcon: profileIcon,
|
|
|
|
Role: &db.Role{Code: role.Code, Name: role.Name},
|
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
return &UpdateTeamMemberRolePayload{Ok: true, Member: &member, TeamID: input.TeamID}, err
|
2020-07-05 01:02:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) DeleteTeamMember(ctx context.Context, input DeleteTeamMember) (*DeleteTeamMemberPayload, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
err := r.Repository.DeleteTeamMember(ctx, db.DeleteTeamMemberParams{TeamID: input.TeamID, UserID: input.UserID})
|
|
|
|
return &DeleteTeamMemberPayload{TeamID: input.TeamID, UserID: input.UserID}, err
|
2020-07-05 01:02:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) CreateRefreshToken(ctx context.Context, input NewRefreshToken) (*db.RefreshToken, error) {
|
|
|
|
userID := uuid.MustParse("0183d9ab-d0ed-4c9b-a3df-77a0cdd93dca")
|
|
|
|
refreshCreatedAt := time.Now().UTC()
|
|
|
|
refreshExpiresAt := refreshCreatedAt.AddDate(0, 0, 1)
|
|
|
|
refreshToken, err := r.Repository.CreateRefreshToken(ctx, db.CreateRefreshTokenParams{userID, refreshCreatedAt, refreshExpiresAt})
|
|
|
|
return &refreshToken, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) CreateUserAccount(ctx context.Context, input NewUserAccount) (*db.UserAccount, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
_, role, ok := GetUser(ctx)
|
|
|
|
if !ok {
|
|
|
|
return &db.UserAccount{}, nil
|
|
|
|
}
|
|
|
|
if role != auth.RoleAdmin {
|
|
|
|
return &db.UserAccount{}, &gqlerror.Error{
|
|
|
|
Message: "Must be an organization admin",
|
|
|
|
Extensions: map[string]interface{}{
|
|
|
|
"code": "0-400",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
createdAt := time.Now().UTC()
|
|
|
|
hashedPwd, err := bcrypt.GenerateFromPassword([]byte(input.Password), 14)
|
|
|
|
if err != nil {
|
|
|
|
return &db.UserAccount{}, err
|
|
|
|
}
|
|
|
|
userAccount, err := r.Repository.CreateUserAccount(ctx, db.CreateUserAccountParams{
|
|
|
|
FullName: input.FullName,
|
|
|
|
RoleCode: input.RoleCode,
|
|
|
|
Initials: input.Initials,
|
|
|
|
Email: input.Email,
|
|
|
|
Username: input.Username,
|
|
|
|
CreatedAt: createdAt,
|
|
|
|
PasswordHash: string(hashedPwd),
|
|
|
|
})
|
|
|
|
return &userAccount, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *mutationResolver) DeleteUserAccount(ctx context.Context, input DeleteUserAccount) (*DeleteUserAccountPayload, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
_, role, ok := GetUser(ctx)
|
|
|
|
if !ok {
|
|
|
|
return &DeleteUserAccountPayload{Ok: false}, nil
|
2020-07-05 01:02:57 +02:00
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
if role != auth.RoleAdmin {
|
|
|
|
return &DeleteUserAccountPayload{Ok: false}, &gqlerror.Error{
|
|
|
|
Message: "User not found",
|
|
|
|
Extensions: map[string]interface{}{
|
|
|
|
"code": "0-401",
|
|
|
|
},
|
2020-07-18 04:55:38 +02:00
|
|
|
}
|
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
|
|
|
|
if err != nil {
|
2020-07-18 04:55:38 +02:00
|
|
|
return &DeleteUserAccountPayload{Ok: false}, err
|
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
|
|
|
|
// TODO(jordanknott) migrate admin ownership
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
err = r.Repository.DeleteUserAccountByID(ctx, input.UserID)
|
|
|
|
if err != nil {
|
|
|
|
return &DeleteUserAccountPayload{Ok: false}, err
|
|
|
|
}
|
|
|
|
return &DeleteUserAccountPayload{UserAccount: &user, Ok: true}, nil
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
|
|
|
|
2020-04-11 21:24:45 +02:00
|
|
|
func (r *mutationResolver) LogoutUser(ctx context.Context, input LogoutUser) (bool, error) {
|
|
|
|
userID, err := uuid.Parse(input.UserID)
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = r.Repository.DeleteRefreshTokenByUserID(ctx, userID)
|
|
|
|
return true, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *mutationResolver) ClearProfileAvatar(ctx context.Context) (*db.UserAccount, error) {
|
|
|
|
userID, ok := GetUserID(ctx)
|
|
|
|
if !ok {
|
|
|
|
return &db.UserAccount{}, fmt.Errorf("internal server error")
|
|
|
|
}
|
|
|
|
user, err := r.Repository.UpdateUserAccountProfileAvatarURL(ctx, db.UpdateUserAccountProfileAvatarURLParams{UserID: userID, ProfileAvatarUrl: sql.NullString{Valid: false, String: ""}})
|
|
|
|
if err != nil {
|
|
|
|
return &db.UserAccount{}, err
|
|
|
|
}
|
|
|
|
return &user, nil
|
|
|
|
}
|
|
|
|
|
2020-07-16 01:20:08 +02:00
|
|
|
func (r *mutationResolver) UpdateUserPassword(ctx context.Context, input UpdateUserPassword) (*UpdateUserPasswordPayload, error) {
|
|
|
|
hashedPwd, err := bcrypt.GenerateFromPassword([]byte(input.Password), 14)
|
|
|
|
if err != nil {
|
|
|
|
return &UpdateUserPasswordPayload{}, err
|
|
|
|
}
|
|
|
|
user, err := r.Repository.SetUserPassword(ctx, db.SetUserPasswordParams{UserID: input.UserID, PasswordHash: string(hashedPwd)})
|
|
|
|
if err != nil {
|
|
|
|
return &UpdateUserPasswordPayload{}, err
|
|
|
|
}
|
|
|
|
return &UpdateUserPasswordPayload{Ok: true, User: &user}, err
|
|
|
|
}
|
|
|
|
|
2020-07-12 09:06:11 +02:00
|
|
|
func (r *mutationResolver) UpdateUserRole(ctx context.Context, input UpdateUserRole) (*UpdateUserRolePayload, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
_, role, ok := GetUser(ctx)
|
|
|
|
if !ok {
|
|
|
|
return &UpdateUserRolePayload{}, nil
|
|
|
|
}
|
|
|
|
if role != auth.RoleAdmin {
|
|
|
|
return &UpdateUserRolePayload{}, &gqlerror.Error{
|
|
|
|
Message: "User not found",
|
|
|
|
Extensions: map[string]interface{}{
|
|
|
|
"code": "0-401",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2020-07-12 09:06:11 +02:00
|
|
|
user, err := r.Repository.UpdateUserRole(ctx, db.UpdateUserRoleParams{RoleCode: input.RoleCode.String(), UserID: input.UserID})
|
|
|
|
if err != nil {
|
|
|
|
return &UpdateUserRolePayload{}, err
|
|
|
|
}
|
|
|
|
return &UpdateUserRolePayload{User: &user}, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *organizationResolver) ID(ctx context.Context, obj *db.Organization) (uuid.UUID, error) {
|
2020-06-21 00:49:11 +02:00
|
|
|
return obj.OrganizationID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectResolver) ID(ctx context.Context, obj *db.Project) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.ProjectID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectResolver) Team(ctx context.Context, obj *db.Project) (*db.Team, error) {
|
2020-04-20 05:02:55 +02:00
|
|
|
team, err := r.Repository.GetTeamByID(ctx, obj.TeamID)
|
|
|
|
if err != nil {
|
2020-08-01 03:01:14 +02:00
|
|
|
log.WithFields(log.Fields{"teamID": obj.TeamID, "projectID": obj.ProjectID}).WithError(err).Error("issue while getting team for project")
|
|
|
|
return &team, err
|
2020-06-13 00:21:58 +02:00
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
return &team, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectResolver) TaskGroups(ctx context.Context, obj *db.Project) ([]db.TaskGroup, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
return r.Repository.GetTaskGroupsForProject(ctx, obj.ProjectID)
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectResolver) Members(ctx context.Context, obj *db.Project) ([]Member, error) {
|
|
|
|
members := []Member{}
|
|
|
|
projectMembers, err := r.Repository.GetProjectMembersForProjectID(ctx, obj.ProjectID)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("get project members for project id")
|
|
|
|
return members, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, projectMember := range projectMembers {
|
2020-08-01 03:01:14 +02:00
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, projectMember.UserID)
|
2020-07-05 01:02:57 +02:00
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("get user account by ID")
|
|
|
|
return members, err
|
|
|
|
}
|
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
role, err := r.Repository.GetRoleForProjectMemberByUserID(ctx, db.GetRoleForProjectMemberByUserIDParams{UserID: user.UserID, ProjectID: obj.ProjectID})
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("get role for projet member by user ID")
|
|
|
|
return members, err
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
|
|
|
members = append(members, Member{ID: user.UserID, FullName: user.FullName, ProfileIcon: profileIcon,
|
|
|
|
Username: user.Username, Role: &db.Role{Code: role.Code, Name: role.Name},
|
|
|
|
})
|
|
|
|
}
|
2020-04-20 05:02:55 +02:00
|
|
|
return members, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectResolver) Labels(ctx context.Context, obj *db.Project) ([]db.ProjectLabel, error) {
|
2020-04-21 01:04:27 +02:00
|
|
|
labels, err := r.Repository.GetProjectLabelsForProject(ctx, obj.ProjectID)
|
|
|
|
return labels, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectLabelResolver) ID(ctx context.Context, obj *db.ProjectLabel) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.ProjectLabelID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectLabelResolver) LabelColor(ctx context.Context, obj *db.ProjectLabel) (*db.LabelColor, error) {
|
2020-04-21 01:04:27 +02:00
|
|
|
labelColor, err := r.Repository.GetLabelColorByID(ctx, obj.LabelColorID)
|
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.LabelColor{}, err
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
2020-05-27 23:18:50 +02:00
|
|
|
return &labelColor, nil
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *projectLabelResolver) Name(ctx context.Context, obj *db.ProjectLabel) (*string, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
var name *string
|
|
|
|
if obj.Name.Valid {
|
|
|
|
name = &obj.Name.String
|
|
|
|
}
|
|
|
|
return name, nil
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) Organizations(ctx context.Context) ([]db.Organization, error) {
|
2020-06-21 00:49:11 +02:00
|
|
|
return r.Repository.GetAllOrganizations(ctx)
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) Users(ctx context.Context) ([]db.UserAccount, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
return r.Repository.GetAllUserAccounts(ctx)
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserAccount, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
userId, err := uuid.Parse(input.UserID)
|
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.UserAccount{}, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
account, err := r.Repository.GetUserAccountByID(ctx, userId)
|
|
|
|
if err == sql.ErrNoRows {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.UserAccount{}, &gqlerror.Error{
|
2020-04-10 04:40:22 +02:00
|
|
|
Message: "User not found",
|
|
|
|
Extensions: map[string]interface{}{
|
|
|
|
"code": "10-404",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &account, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) FindProject(ctx context.Context, input FindProject) (*db.Project, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
userID, role, ok := GetUser(ctx)
|
|
|
|
log.WithFields(log.Fields{"userID": userID, "role": role}).Info("find project user")
|
|
|
|
if !ok {
|
|
|
|
return &db.Project{}, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
project, err := r.Repository.GetProjectByID(ctx, input.ProjectID)
|
2020-04-10 04:40:22 +02:00
|
|
|
if err == sql.ErrNoRows {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.Project{}, &gqlerror.Error{
|
2020-04-10 04:40:22 +02:00
|
|
|
Message: "Project not found",
|
|
|
|
Extensions: map[string]interface{}{
|
|
|
|
"code": "11-404",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
if role == auth.RoleAdmin {
|
|
|
|
return &project, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
projectRoles, err := GetProjectRoles(ctx, r.Repository, input.ProjectID)
|
|
|
|
log.WithFields(log.Fields{"projectID": input.ProjectID, "teamRole": projectRoles.TeamRole, "projectRole": projectRoles.ProjectRole}).Info("get project roles ")
|
|
|
|
if err != nil {
|
|
|
|
return &project, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if projectRoles.TeamRole == "" && projectRoles.ProjectRole == "" {
|
|
|
|
return &db.Project{}, &gqlerror.Error{
|
|
|
|
Message: "project not accessible",
|
|
|
|
Extensions: map[string]interface{}{
|
|
|
|
"code": "11-400",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &project, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) FindTask(ctx context.Context, input FindTask) (*db.Task, error) {
|
2020-04-20 05:02:55 +02:00
|
|
|
task, err := r.Repository.GetTaskByID(ctx, input.TaskID)
|
|
|
|
return &task, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) Projects(ctx context.Context, input *ProjectsFilter) ([]db.Project, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
userID, orgRole, ok := GetUser(ctx)
|
|
|
|
if !ok {
|
|
|
|
log.Info("user id was not found from middleware")
|
|
|
|
return []db.Project{}, nil
|
|
|
|
}
|
|
|
|
log.WithFields(log.Fields{"userID": userID}).Info("fetching projects")
|
|
|
|
|
2020-04-10 04:40:22 +02:00
|
|
|
if input != nil {
|
2020-06-23 22:20:53 +02:00
|
|
|
return r.Repository.GetAllProjectsForTeam(ctx, *input.TeamID)
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
|
|
|
|
if orgRole == "admin" {
|
|
|
|
log.Info("showing all projects for admin")
|
|
|
|
return r.Repository.GetAllProjects(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
teams, err := r.Repository.GetTeamsForUserIDWhereAdmin(ctx, userID)
|
|
|
|
projects := make(map[string]db.Project)
|
|
|
|
for _, team := range teams {
|
|
|
|
log.WithFields(log.Fields{"teamID": team.TeamID}).Info("found team")
|
|
|
|
teamProjects, err := r.Repository.GetAllProjectsForTeam(ctx, team.TeamID)
|
|
|
|
if err != sql.ErrNoRows && err != nil {
|
|
|
|
log.Info("issue getting team projects")
|
|
|
|
return []db.Project{}, nil
|
|
|
|
}
|
|
|
|
for _, project := range teamProjects {
|
|
|
|
log.WithFields(log.Fields{"projectID": project.ProjectID.String()}).Info("adding team project")
|
|
|
|
projects[project.ProjectID.String()] = project
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
visibleProjects, err := r.Repository.GetAllVisibleProjectsForUserID(ctx, userID)
|
|
|
|
if err != nil {
|
|
|
|
log.Info("user id was not found from middleware")
|
|
|
|
return []db.Project{}, nil
|
|
|
|
}
|
|
|
|
for _, project := range visibleProjects {
|
|
|
|
log.WithFields(log.Fields{"projectID": project.ProjectID.String()}).Info("found visible project")
|
|
|
|
if _, ok := projects[project.ProjectID.String()]; !ok {
|
|
|
|
log.WithFields(log.Fields{"projectID": project.ProjectID.String()}).Info("adding visible project")
|
|
|
|
projects[project.ProjectID.String()] = project
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.WithFields(log.Fields{"projectLength": len(projects)}).Info("making projects")
|
|
|
|
allProjects := make([]db.Project, 0, len(projects))
|
|
|
|
for _, project := range projects {
|
|
|
|
log.WithFields(log.Fields{"projectID": project.ProjectID.String()}).Info("add project to final list")
|
|
|
|
allProjects = append(allProjects, project)
|
|
|
|
}
|
|
|
|
log.Info(allProjects)
|
|
|
|
return allProjects, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) FindTeam(ctx context.Context, input FindTeam) (*db.Team, error) {
|
2020-06-23 22:20:53 +02:00
|
|
|
team, err := r.Repository.GetTeamByID(ctx, input.TeamID)
|
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
return &db.Team{}, err
|
2020-06-23 22:20:53 +02:00
|
|
|
}
|
|
|
|
return &team, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) Teams(ctx context.Context) ([]db.Team, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
userID, orgRole, ok := GetUser(ctx)
|
|
|
|
if !ok {
|
|
|
|
log.Error("userID or orgRole does not exist!")
|
|
|
|
return []db.Team{}, errors.New("internal error")
|
|
|
|
}
|
|
|
|
if orgRole == "admin" {
|
|
|
|
return r.Repository.GetAllTeams(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
teams := make(map[string]db.Team)
|
|
|
|
adminTeams, err := r.Repository.GetTeamsForUserIDWhereAdmin(ctx, userID)
|
|
|
|
if err != nil {
|
|
|
|
return []db.Team{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, team := range adminTeams {
|
|
|
|
teams[team.TeamID.String()] = team
|
|
|
|
}
|
|
|
|
|
|
|
|
visibleProjects, err := r.Repository.GetAllVisibleProjectsForUserID(ctx, userID)
|
|
|
|
if err != nil {
|
|
|
|
log.Info("user id was not found from middleware")
|
|
|
|
return []db.Team{}, err
|
|
|
|
}
|
|
|
|
for _, project := range visibleProjects {
|
|
|
|
log.WithFields(log.Fields{"projectID": project.ProjectID.String()}).Info("found visible project")
|
|
|
|
if _, ok := teams[project.ProjectID.String()]; !ok {
|
|
|
|
log.WithFields(log.Fields{"projectID": project.ProjectID.String()}).Info("adding visible project")
|
|
|
|
team, err := r.Repository.GetTeamByID(ctx, project.TeamID)
|
|
|
|
if err != nil {
|
|
|
|
log.Info("user id was not found from middleware")
|
|
|
|
return []db.Team{}, err
|
|
|
|
}
|
|
|
|
teams[project.TeamID.String()] = team
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foundTeams := make([]db.Team, 0, len(teams))
|
|
|
|
for _, team := range teams {
|
|
|
|
foundTeams = append(foundTeams, team)
|
|
|
|
}
|
|
|
|
return foundTeams, nil
|
2020-06-01 04:20:03 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) LabelColors(ctx context.Context) ([]db.LabelColor, error) {
|
2020-05-27 23:18:50 +02:00
|
|
|
return r.Repository.GetLabelColors(ctx)
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *queryResolver) TaskGroups(ctx context.Context) ([]db.TaskGroup, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
return r.Repository.GetAllTaskGroups(ctx)
|
|
|
|
}
|
|
|
|
|
2020-08-01 03:01:14 +02:00
|
|
|
func (r *queryResolver) Me(ctx context.Context) (*MePayload, error) {
|
2020-04-20 05:02:55 +02:00
|
|
|
userID, ok := GetUserID(ctx)
|
|
|
|
if !ok {
|
2020-08-01 03:01:14 +02:00
|
|
|
return &MePayload{}, fmt.Errorf("internal server error")
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, userID)
|
2020-07-17 02:40:23 +02:00
|
|
|
if err == sql.ErrNoRows {
|
|
|
|
log.WithFields(log.Fields{"userID": userID}).Warning("can not find user for me query")
|
2020-08-01 03:01:14 +02:00
|
|
|
return &MePayload{}, nil
|
2020-07-17 02:40:23 +02:00
|
|
|
} else if err != nil {
|
2020-08-01 03:01:14 +02:00
|
|
|
return &MePayload{}, err
|
|
|
|
}
|
|
|
|
var projectRoles []ProjectRole
|
|
|
|
projects, err := r.Repository.GetProjectRolesForUserID(ctx, userID)
|
|
|
|
if err != nil {
|
|
|
|
return &MePayload{}, err
|
|
|
|
}
|
|
|
|
for _, project := range projects {
|
|
|
|
projectRoles = append(projectRoles, ProjectRole{ProjectID: project.ProjectID, RoleCode: ConvertToRoleCode("admin")})
|
|
|
|
// projectRoles = append(projectRoles, ProjectRole{ProjectID: project.ProjectID, RoleCode: ConvertToRoleCode(project.RoleCode)})
|
|
|
|
}
|
|
|
|
var teamRoles []TeamRole
|
|
|
|
teams, err := r.Repository.GetTeamRolesForUserID(ctx, userID)
|
|
|
|
if err != nil {
|
|
|
|
return &MePayload{}, err
|
|
|
|
}
|
|
|
|
for _, team := range teams {
|
|
|
|
// teamRoles = append(teamRoles, TeamRole{TeamID: team.TeamID, RoleCode: ConvertToRoleCode(team.RoleCode)})
|
|
|
|
teamRoles = append(teamRoles, TeamRole{TeamID: team.TeamID, RoleCode: ConvertToRoleCode("admin")})
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
2020-08-01 03:01:14 +02:00
|
|
|
return &MePayload{User: &user, TeamRoles: teamRoles, ProjectRoles: projectRoles}, err
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *refreshTokenResolver) ID(ctx context.Context, obj *db.RefreshToken) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.TokenID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) ID(ctx context.Context, obj *db.Task) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.TaskID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) TaskGroup(ctx context.Context, obj *db.Task) (*db.TaskGroup, error) {
|
2020-04-11 04:22:22 +02:00
|
|
|
taskGroup, err := r.Repository.GetTaskGroupByID(ctx, obj.TaskGroupID)
|
|
|
|
return &taskGroup, err
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) Description(ctx context.Context, obj *db.Task) (*string, error) {
|
2020-04-20 05:02:55 +02:00
|
|
|
task, err := r.Repository.GetTaskByID(ctx, obj.TaskID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if !task.Description.Valid {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
return &task.Description.String, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) DueDate(ctx context.Context, obj *db.Task) (*time.Time, error) {
|
2020-06-16 00:36:59 +02:00
|
|
|
if obj.DueDate.Valid {
|
|
|
|
return &obj.DueDate.Time, nil
|
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) Assigned(ctx context.Context, obj *db.Task) ([]Member, error) {
|
2020-04-20 05:02:55 +02:00
|
|
|
taskMemberLinks, err := r.Repository.GetAssignedMembersForTask(ctx, obj.TaskID)
|
2020-07-05 01:02:57 +02:00
|
|
|
taskMembers := []Member{}
|
2020-04-20 05:02:55 +02:00
|
|
|
if err != nil {
|
|
|
|
return taskMembers, err
|
|
|
|
}
|
|
|
|
for _, taskMemberLink := range taskMemberLinks {
|
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, taskMemberLink.UserID)
|
|
|
|
if err != nil {
|
|
|
|
return taskMembers, err
|
|
|
|
}
|
2020-06-13 00:21:58 +02:00
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
2020-07-05 01:02:57 +02:00
|
|
|
projectID, err := r.Repository.GetProjectIDForTask(ctx, obj.TaskID)
|
|
|
|
if err != nil {
|
|
|
|
return taskMembers, err
|
|
|
|
}
|
|
|
|
role, err := r.Repository.GetRoleForProjectMemberByUserID(ctx, db.GetRoleForProjectMemberByUserIDParams{UserID: user.UserID, ProjectID: projectID})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if err == sql.ErrNoRows {
|
|
|
|
role = db.Role{Code: "owner", Name: "Owner"}
|
|
|
|
} else {
|
|
|
|
log.WithFields(log.Fields{"userID": user.UserID}).WithError(err).Error("get role for project member")
|
|
|
|
return taskMembers, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
taskMembers = append(taskMembers, Member{ID: taskMemberLink.UserID, FullName: user.FullName, ProfileIcon: profileIcon,
|
|
|
|
Role: &role,
|
|
|
|
})
|
2020-04-20 05:02:55 +02:00
|
|
|
}
|
|
|
|
return taskMembers, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) Labels(ctx context.Context, obj *db.Task) ([]db.TaskLabel, error) {
|
2020-04-20 05:02:55 +02:00
|
|
|
return r.Repository.GetTaskLabelsForTaskID(ctx, obj.TaskID)
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) Checklists(ctx context.Context, obj *db.Task) ([]db.TaskChecklist, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
return r.Repository.GetTaskChecklistsForTask(ctx, obj.TaskID)
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskResolver) Badges(ctx context.Context, obj *db.Task) (*TaskBadges, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-13 23:33:01 +02:00
|
|
|
if complete == 0 && total == 0 {
|
|
|
|
return &TaskBadges{Checklist: nil}, nil
|
|
|
|
}
|
2020-06-19 01:12:15 +02:00
|
|
|
return &TaskBadges{Checklist: &ChecklistBadge{Total: total, Complete: complete}}, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskChecklistResolver) ID(ctx context.Context, obj *db.TaskChecklist) (uuid.UUID, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
return obj.TaskChecklistID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskChecklistResolver) Items(ctx context.Context, obj *db.TaskChecklist) ([]db.TaskChecklistItem, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
return r.Repository.GetTaskChecklistItemsForTaskChecklist(ctx, obj.TaskChecklistID)
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskChecklistItemResolver) ID(ctx context.Context, obj *db.TaskChecklistItem) (uuid.UUID, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
return obj.TaskChecklistItemID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskChecklistItemResolver) DueDate(ctx context.Context, obj *db.TaskChecklistItem) (*time.Time, error) {
|
2020-06-19 01:12:15 +02:00
|
|
|
panic(fmt.Errorf("not implemented"))
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskGroupResolver) ID(ctx context.Context, obj *db.TaskGroup) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.TaskGroupID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskGroupResolver) ProjectID(ctx context.Context, obj *db.TaskGroup) (string, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
return obj.ProjectID.String(), nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskGroupResolver) Tasks(ctx context.Context, obj *db.TaskGroup) ([]db.Task, error) {
|
2020-04-10 04:40:22 +02:00
|
|
|
tasks, err := r.Repository.GetTasksForTaskGroupID(ctx, obj.TaskGroupID)
|
|
|
|
return tasks, err
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskLabelResolver) ID(ctx context.Context, obj *db.TaskLabel) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.TaskLabelID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *taskLabelResolver) ProjectLabel(ctx context.Context, obj *db.TaskLabel) (*db.ProjectLabel, error) {
|
2020-04-21 01:04:27 +02:00
|
|
|
projectLabel, err := r.Repository.GetProjectLabelByID(ctx, obj.ProjectLabelID)
|
2020-05-31 06:11:19 +02:00
|
|
|
return &projectLabel, err
|
2020-04-21 01:04:27 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *teamResolver) ID(ctx context.Context, obj *db.Team) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.TeamID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *teamResolver) Members(ctx context.Context, obj *db.Team) ([]Member, error) {
|
|
|
|
members := []Member{}
|
2020-07-18 02:40:05 +02:00
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
teamMembers, err := r.Repository.GetTeamMembersForTeamID(ctx, obj.TeamID)
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("get project members for project id")
|
|
|
|
return members, err
|
|
|
|
}
|
|
|
|
|
2020-06-21 00:49:11 +02:00
|
|
|
for _, teamMember := range teamMembers {
|
2020-08-01 03:01:14 +02:00
|
|
|
user, err := r.Repository.GetUserAccountByID(ctx, teamMember.UserID)
|
2020-06-21 00:49:11 +02:00
|
|
|
if err != nil {
|
2020-07-05 01:02:57 +02:00
|
|
|
log.WithError(err).Error("get user account by ID")
|
|
|
|
return members, err
|
2020-06-21 00:49:11 +02:00
|
|
|
}
|
|
|
|
var url *string
|
|
|
|
if user.ProfileAvatarUrl.Valid {
|
|
|
|
url = &user.ProfileAvatarUrl.String
|
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
role, err := r.Repository.GetRoleForTeamMember(ctx, db.GetRoleForTeamMemberParams{UserID: user.UserID, TeamID: obj.TeamID})
|
|
|
|
if err != nil {
|
|
|
|
log.WithError(err).Error("get role for projet member by user ID")
|
|
|
|
return members, err
|
|
|
|
}
|
2020-07-18 02:40:05 +02:00
|
|
|
|
|
|
|
ownedList, err := GetOwnedList(ctx, r.Repository, user)
|
|
|
|
if err != nil {
|
2020-07-12 09:06:11 +02:00
|
|
|
return members, err
|
|
|
|
}
|
2020-07-18 02:40:05 +02:00
|
|
|
memberList, err := GetMemberList(ctx, r.Repository, user)
|
|
|
|
if err != nil {
|
|
|
|
return members, err
|
2020-07-12 09:06:11 +02:00
|
|
|
}
|
|
|
|
|
2020-06-21 00:49:11 +02:00
|
|
|
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
|
2020-07-05 01:02:57 +02:00
|
|
|
members = append(members, Member{ID: user.UserID, FullName: user.FullName, ProfileIcon: profileIcon,
|
2020-07-18 02:40:05 +02:00
|
|
|
Username: user.Username, Owned: ownedList, Member: memberList, Role: &db.Role{Code: role.Code, Name: role.Name},
|
2020-06-21 00:49:11 +02:00
|
|
|
})
|
|
|
|
}
|
2020-07-05 01:02:57 +02:00
|
|
|
return members, nil
|
2020-06-21 00:49:11 +02:00
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *userAccountResolver) ID(ctx context.Context, obj *db.UserAccount) (uuid.UUID, error) {
|
2020-05-27 02:53:31 +02:00
|
|
|
return obj.UserID, nil
|
|
|
|
}
|
|
|
|
|
2020-07-05 01:02:57 +02:00
|
|
|
func (r *userAccountResolver) Role(ctx context.Context, obj *db.UserAccount) (*db.Role, error) {
|
|
|
|
role, err := r.Repository.GetRoleForUserID(ctx, obj.UserID)
|
|
|
|
if err != nil {
|
|
|
|
log.Info("beep!")
|
|
|
|
log.WithError(err).Error("get role for user id")
|
|
|
|
return &db.Role{}, err
|
|
|
|
}
|
|
|
|
return &db.Role{Code: role.Code, Name: role.Name}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *userAccountResolver) ProfileIcon(ctx context.Context, obj *db.UserAccount) (*ProfileIcon, error) {
|
2020-06-13 00:21:58 +02:00
|
|
|
var url *string
|
|
|
|
if obj.ProfileAvatarUrl.Valid {
|
|
|
|
url = &obj.ProfileAvatarUrl.String
|
|
|
|
}
|
|
|
|
profileIcon := &ProfileIcon{url, &obj.Initials, &obj.ProfileBgColor}
|
2020-04-20 05:02:55 +02:00
|
|
|
return profileIcon, nil
|
2020-04-10 04:40:22 +02:00
|
|
|
}
|
|
|
|
|
2020-07-18 02:40:05 +02:00
|
|
|
func (r *userAccountResolver) Owned(ctx context.Context, obj *db.UserAccount) (*OwnedList, error) {
|
2020-08-01 03:01:14 +02:00
|
|
|
return &OwnedList{}, nil // TODO(jordanknott)
|
2020-07-18 02:40:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *userAccountResolver) Member(ctx context.Context, obj *db.UserAccount) (*MemberList, error) {
|
|
|
|
projectMemberIDs, err := r.Repository.GetMemberProjectIDsForUserID(ctx, obj.UserID)
|
|
|
|
if err != sql.ErrNoRows && err != nil {
|
|
|
|
return &MemberList{}, err
|
|
|
|
}
|
|
|
|
var projects []db.Project
|
|
|
|
for _, projectID := range projectMemberIDs {
|
|
|
|
project, err := r.Repository.GetProjectByID(ctx, projectID)
|
|
|
|
if err != nil {
|
|
|
|
return &MemberList{}, err
|
|
|
|
}
|
|
|
|
projects = append(projects, project)
|
|
|
|
}
|
|
|
|
teamMemberIDs, err := r.Repository.GetMemberTeamIDsForUserID(ctx, obj.UserID)
|
|
|
|
if err != sql.ErrNoRows && err != nil {
|
|
|
|
return &MemberList{}, err
|
|
|
|
}
|
|
|
|
var teams []db.Team
|
|
|
|
for _, teamID := range teamMemberIDs {
|
|
|
|
team, err := r.Repository.GetTeamByID(ctx, teamID)
|
|
|
|
if err != nil {
|
|
|
|
return &MemberList{}, err
|
|
|
|
}
|
|
|
|
teams = append(teams, team)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &MemberList{Teams: teams, Projects: projects}, err
|
|
|
|
}
|
|
|
|
|
2020-05-27 23:18:50 +02:00
|
|
|
// LabelColor returns LabelColorResolver implementation.
|
|
|
|
func (r *Resolver) LabelColor() LabelColorResolver { return &labelColorResolver{r} }
|
|
|
|
|
2020-04-11 04:22:22 +02:00
|
|
|
// Mutation returns MutationResolver implementation.
|
|
|
|
func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} }
|
|
|
|
|
2020-06-21 00:49:11 +02:00
|
|
|
// Organization returns OrganizationResolver implementation.
|
|
|
|
func (r *Resolver) Organization() OrganizationResolver { return &organizationResolver{r} }
|
|
|
|
|
2020-04-11 04:22:22 +02:00
|
|
|
// Project returns ProjectResolver implementation.
|
|
|
|
func (r *Resolver) Project() ProjectResolver { return &projectResolver{r} }
|
|
|
|
|
2020-04-21 01:04:27 +02:00
|
|
|
// ProjectLabel returns ProjectLabelResolver implementation.
|
|
|
|
func (r *Resolver) ProjectLabel() ProjectLabelResolver { return &projectLabelResolver{r} }
|
|
|
|
|
2020-04-11 04:22:22 +02:00
|
|
|
// Query returns QueryResolver implementation.
|
|
|
|
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
|
|
|
|
|
2020-05-27 02:53:31 +02:00
|
|
|
// RefreshToken returns RefreshTokenResolver implementation.
|
|
|
|
func (r *Resolver) RefreshToken() RefreshTokenResolver { return &refreshTokenResolver{r} }
|
|
|
|
|
2020-04-11 04:22:22 +02:00
|
|
|
// Task returns TaskResolver implementation.
|
|
|
|
func (r *Resolver) Task() TaskResolver { return &taskResolver{r} }
|
|
|
|
|
2020-06-19 01:12:15 +02:00
|
|
|
// TaskChecklist returns TaskChecklistResolver implementation.
|
|
|
|
func (r *Resolver) TaskChecklist() TaskChecklistResolver { return &taskChecklistResolver{r} }
|
|
|
|
|
|
|
|
// TaskChecklistItem returns TaskChecklistItemResolver implementation.
|
2020-08-01 03:01:14 +02:00
|
|
|
func (r *Resolver) TaskChecklistItem() TaskChecklistItemResolver {
|
|
|
|
return &taskChecklistItemResolver{r}
|
|
|
|
}
|
2020-06-19 01:12:15 +02:00
|
|
|
|
2020-04-11 04:22:22 +02:00
|
|
|
// TaskGroup returns TaskGroupResolver implementation.
|
|
|
|
func (r *Resolver) TaskGroup() TaskGroupResolver { return &taskGroupResolver{r} }
|
|
|
|
|
2020-04-20 05:02:55 +02:00
|
|
|
// TaskLabel returns TaskLabelResolver implementation.
|
|
|
|
func (r *Resolver) TaskLabel() TaskLabelResolver { return &taskLabelResolver{r} }
|
|
|
|
|
2020-05-27 02:53:31 +02:00
|
|
|
// Team returns TeamResolver implementation.
|
|
|
|
func (r *Resolver) Team() TeamResolver { return &teamResolver{r} }
|
|
|
|
|
2020-04-20 05:02:55 +02:00
|
|
|
// UserAccount returns UserAccountResolver implementation.
|
|
|
|
func (r *Resolver) UserAccount() UserAccountResolver { return &userAccountResolver{r} }
|
2020-04-10 04:40:22 +02:00
|
|
|
|
2020-05-27 23:18:50 +02:00
|
|
|
type labelColorResolver struct{ *Resolver }
|
2020-04-10 04:40:22 +02:00
|
|
|
type mutationResolver struct{ *Resolver }
|
2020-06-21 00:49:11 +02:00
|
|
|
type organizationResolver struct{ *Resolver }
|
2020-04-10 04:40:22 +02:00
|
|
|
type projectResolver struct{ *Resolver }
|
2020-04-21 01:04:27 +02:00
|
|
|
type projectLabelResolver struct{ *Resolver }
|
2020-04-10 04:40:22 +02:00
|
|
|
type queryResolver struct{ *Resolver }
|
2020-05-27 02:53:31 +02:00
|
|
|
type refreshTokenResolver struct{ *Resolver }
|
2020-04-10 04:40:22 +02:00
|
|
|
type taskResolver struct{ *Resolver }
|
2020-06-19 01:12:15 +02:00
|
|
|
type taskChecklistResolver struct{ *Resolver }
|
|
|
|
type taskChecklistItemResolver struct{ *Resolver }
|
2020-04-10 04:40:22 +02:00
|
|
|
type taskGroupResolver struct{ *Resolver }
|
2020-04-20 05:02:55 +02:00
|
|
|
type taskLabelResolver struct{ *Resolver }
|
2020-05-27 02:53:31 +02:00
|
|
|
type teamResolver struct{ *Resolver }
|
2020-04-20 05:02:55 +02:00
|
|
|
type userAccountResolver struct{ *Resolver }
|