chore: project cleanup and bugfixes

This commit is contained in:
Jordan Knott
2020-07-12 02:06:11 -05:00
parent e7e6fdc24c
commit a20ff90106
43 changed files with 3317 additions and 1143 deletions

File diff suppressed because it is too large Load Diff

View File

@ -124,13 +124,15 @@ type DeleteTeam struct {
}
type DeleteTeamMember struct {
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
NewOwnerID *uuid.UUID `json:"newOwnerID"`
}
type DeleteTeamMemberPayload struct {
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
TeamID uuid.UUID `json:"teamID"`
UserID uuid.UUID `json:"userID"`
AffectedProjects []db.Project `json:"affectedProjects"`
}
type DeleteTeamPayload struct {
@ -174,6 +176,7 @@ type Member struct {
FullName string `json:"fullName"`
Username string `json:"username"`
ProfileIcon *ProfileIcon `json:"profileIcon"`
Owned *OwnersList `json:"owned"`
}
type NewProject struct {
@ -229,6 +232,11 @@ type NewUserAccount struct {
RoleCode string `json:"roleCode"`
}
type OwnersList struct {
Projects []uuid.UUID `json:"projects"`
Teams []uuid.UUID `json:"teams"`
}
type ProfileIcon struct {
URL *string `json:"url"`
Initials *string `json:"initials"`
@ -326,11 +334,32 @@ type UpdateProjectName struct {
Name string `json:"name"`
}
type UpdateTaskChecklistItemLocation struct {
ChecklistID uuid.UUID `json:"checklistID"`
ChecklistItemID uuid.UUID `json:"checklistItemID"`
Position float64 `json:"position"`
}
type UpdateTaskChecklistItemLocationPayload struct {
ChecklistID uuid.UUID `json:"checklistID"`
PrevChecklistID uuid.UUID `json:"prevChecklistID"`
ChecklistItem *db.TaskChecklistItem `json:"checklistItem"`
}
type UpdateTaskChecklistItemName struct {
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Name string `json:"name"`
}
type UpdateTaskChecklistLocation struct {
ChecklistID uuid.UUID `json:"checklistID"`
Position float64 `json:"position"`
}
type UpdateTaskChecklistLocationPayload struct {
Checklist *db.TaskChecklist `json:"checklist"`
}
type UpdateTaskChecklistName struct {
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
Name string `json:"name"`
@ -372,6 +401,15 @@ type UpdateTeamMemberRolePayload struct {
Member *Member `json:"member"`
}
type UpdateUserRole struct {
UserID uuid.UUID `json:"userID"`
RoleCode RoleCode `json:"roleCode"`
}
type UpdateUserRolePayload struct {
User *db.UserAccount `json:"user"`
}
type RoleCode string
const (

View File

@ -35,12 +35,18 @@ type ProfileIcon {
bgColor: String
}
type OwnersList {
projects: [UUID!]!
teams: [UUID!]!
}
type Member {
id: ID!
role: Role!
fullName: String!
username: String!
profileIcon: ProfileIcon!
owned: OwnersList
}
type RefreshToken {
@ -361,6 +367,30 @@ extend type Mutation {
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!): UpdateTaskChecklistLocationPayload!
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!): UpdateTaskChecklistItemLocationPayload!
}
input UpdateTaskChecklistItemLocation {
checklistID: UUID!
checklistItemID: UUID!
position: Float!
}
type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID!
prevChecklistID: UUID!
checklistItem: TaskChecklistItem!
}
input UpdateTaskChecklistLocation {
checklistID: UUID!
position: Float!
}
type UpdateTaskChecklistLocationPayload {
checklist: TaskChecklist!
}
input CreateTaskChecklist {
@ -492,11 +522,13 @@ extend type Mutation {
input DeleteTeamMember {
teamID: UUID!
userID: UUID!
newOwnerID: UUID
}
type DeleteTeamMemberPayload {
teamID: UUID!
userID: UUID!
affectedProjects: [Project!]!
}
input CreateTeamMember {
@ -537,6 +569,17 @@ extend type Mutation {
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
logoutUser(input: LogoutUser!): Boolean!
clearProfileAvatar: UserAccount!
updateUserRole(input: UpdateUserRole!): UpdateUserRolePayload!
}
input UpdateUserRole {
userID: UUID!
roleCode: RoleCode!
}
type UpdateUserRolePayload {
user: UserAccount!
}
input NewRefreshToken {

View File

@ -426,6 +426,26 @@ func (r *mutationResolver) DeleteTaskChecklistItem(ctx context.Context, input De
}, err
}
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
}
func (r *mutationResolver) CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*db.TaskGroup, error) {
createdAt := time.Now().UTC()
projectID, err := uuid.Parse(input.ProjectID)
@ -682,7 +702,11 @@ func (r *mutationResolver) UpdateTeamMemberRole(ctx context.Context, input Updat
}
func (r *mutationResolver) DeleteTeamMember(ctx context.Context, input DeleteTeamMember) (*DeleteTeamMemberPayload, error) {
_, err := r.Repository.GetTeamMemberByID(ctx, db.GetTeamMemberByIDParams{TeamID: input.TeamID, UserID: input.UserID})
ownedProjects, err := r.Repository.GetOwnedTeamProjectsForUserID(ctx, db.GetOwnedTeamProjectsForUserIDParams{TeamID: input.TeamID, Owner: input.UserID})
if err != nil {
return &DeleteTeamMemberPayload{}, err
}
_, err = r.Repository.GetTeamMemberByID(ctx, db.GetTeamMemberByIDParams{TeamID: input.TeamID, UserID: input.UserID})
if err != nil {
return &DeleteTeamMemberPayload{}, err
}
@ -690,6 +714,11 @@ func (r *mutationResolver) DeleteTeamMember(ctx context.Context, input DeleteTea
if err != nil {
return &DeleteTeamMemberPayload{}, err
}
if input.NewOwnerID != nil {
for _, projectID := range ownedProjects {
_, err = r.Repository.SetProjectOwner(ctx, db.SetProjectOwnerParams{ProjectID: projectID, Owner: *input.NewOwnerID})
}
}
return &DeleteTeamMemberPayload{TeamID: input.TeamID, UserID: input.UserID}, nil
}
@ -754,6 +783,15 @@ func (r *mutationResolver) ClearProfileAvatar(ctx context.Context) (*db.UserAcco
return &user, nil
}
func (r *mutationResolver) UpdateUserRole(ctx context.Context, input UpdateUserRole) (*UpdateUserRolePayload, error) {
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
}
func (r *organizationResolver) ID(ctx context.Context, obj *db.Organization) (uuid.UUID, error) {
return obj.OrganizationID, nil
}
@ -1095,6 +1133,7 @@ func (r *teamResolver) ID(ctx context.Context, obj *db.Team) (uuid.UUID, error)
func (r *teamResolver) Members(ctx context.Context, obj *db.Team) ([]Member, error) {
user, err := r.Repository.GetUserAccountByID(ctx, obj.Owner)
members := []Member{}
log.WithFields(log.Fields{"teamID": obj.TeamID}).Info("getting members")
if err == sql.ErrNoRows {
return members, nil
}
@ -1102,6 +1141,20 @@ func (r *teamResolver) Members(ctx context.Context, obj *db.Team) ([]Member, err
log.WithError(err).Error("get user account by ID")
return members, err
}
ownedProjects, err := r.Repository.GetOwnedTeamProjectsForUserID(ctx, db.GetOwnedTeamProjectsForUserIDParams{TeamID: obj.TeamID, Owner: user.UserID})
log.WithFields(log.Fields{"projects": ownedProjects}).Info("retrieved owned project list")
if err == sql.ErrNoRows {
ownedProjects = []uuid.UUID{}
} else if err != nil {
log.WithError(err).Error("get owned team projects for user id")
return members, err
}
ownedTeams := []uuid.UUID{}
var ownerList *OwnersList
if len(ownedTeams) != 0 || len(ownedProjects) != 0 {
log.Info("owned list is not empty")
ownerList = &OwnersList{Projects: ownedProjects, Teams: ownedTeams}
}
var url *string
if user.ProfileAvatarUrl.Valid {
url = &user.ProfileAvatarUrl.String
@ -1109,7 +1162,7 @@ func (r *teamResolver) Members(ctx context.Context, obj *db.Team) ([]Member, err
profileIcon := &ProfileIcon{url, &user.Initials, &user.ProfileBgColor}
members = append(members, Member{
ID: obj.Owner, FullName: user.FullName, ProfileIcon: profileIcon, Username: user.Username,
Role: &db.Role{Code: "owner", Name: "Owner"},
Owned: ownerList, Role: &db.Role{Code: "owner", Name: "Owner"},
})
teamMembers, err := r.Repository.GetTeamMembersForTeamID(ctx, obj.TeamID)
if err != nil {
@ -1132,9 +1185,24 @@ func (r *teamResolver) Members(ctx context.Context, obj *db.Team) ([]Member, err
log.WithError(err).Error("get role for projet member by user ID")
return members, err
}
ownedProjects, err := r.Repository.GetOwnedTeamProjectsForUserID(ctx, db.GetOwnedTeamProjectsForUserIDParams{TeamID: obj.TeamID, Owner: user.UserID})
log.WithFields(log.Fields{"projects": ownedProjects}).Info("retrieved owned project list")
if err == sql.ErrNoRows {
ownedProjects = []uuid.UUID{}
} else if err != nil {
log.WithError(err).Error("get owned team projects for user id")
return members, err
}
ownedTeams := []uuid.UUID{}
var ownerList *OwnersList
if len(ownedTeams) != 0 || len(ownedProjects) != 0 {
log.Info("owned list is not empty")
ownerList = &OwnersList{Projects: ownedProjects, Teams: ownedTeams}
}
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},
Username: user.Username, Owned: ownerList, Role: &db.Role{Code: role.Code, Name: role.Name},
})
}
return members, nil

View File

@ -35,12 +35,18 @@ type ProfileIcon {
bgColor: String
}
type OwnersList {
projects: [UUID!]!
teams: [UUID!]!
}
type Member {
id: ID!
role: Role!
fullName: String!
username: String!
profileIcon: ProfileIcon!
owned: OwnersList
}
type RefreshToken {

View File

@ -6,6 +6,30 @@ extend type Mutation {
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!): UpdateTaskChecklistLocationPayload!
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!): UpdateTaskChecklistItemLocationPayload!
}
input UpdateTaskChecklistItemLocation {
checklistID: UUID!
checklistItemID: UUID!
position: Float!
}
type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID!
prevChecklistID: UUID!
checklistItem: TaskChecklistItem!
}
input UpdateTaskChecklistLocation {
checklistID: UUID!
position: Float!
}
type UpdateTaskChecklistLocationPayload {
checklist: TaskChecklist!
}
input CreateTaskChecklist {

View File

@ -8,11 +8,13 @@ extend type Mutation {
input DeleteTeamMember {
teamID: UUID!
userID: UUID!
newOwnerID: UUID
}
type DeleteTeamMemberPayload {
teamID: UUID!
userID: UUID!
affectedProjects: [Project!]!
}
input CreateTeamMember {

View File

@ -4,6 +4,17 @@ extend type Mutation {
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
logoutUser(input: LogoutUser!): Boolean!
clearProfileAvatar: UserAccount!
updateUserRole(input: UpdateUserRole!): UpdateUserRolePayload!
}
input UpdateUserRole {
userID: UUID!
roleCode: RoleCode!
}
type UpdateUserRolePayload {
user: UserAccount!
}
input NewRefreshToken {