diff --git a/api/graph/generated.go b/api/graph/generated.go index f4e8755..cfac87a 100644 --- a/api/graph/generated.go +++ b/api/graph/generated.go @@ -41,9 +41,11 @@ type ResolverRoot interface { Project() ProjectResolver ProjectLabel() ProjectLabelResolver Query() QueryResolver + RefreshToken() RefreshTokenResolver Task() TaskResolver TaskGroup() TaskGroupResolver TaskLabel() TaskLabelResolver + Team() TeamResolver UserAccount() UserAccountResolver } @@ -90,27 +92,27 @@ type ComplexityRoot struct { Project struct { CreatedAt func(childComplexity int) int + ID func(childComplexity int) int Labels func(childComplexity int) int Members func(childComplexity int) int Name func(childComplexity int) int Owner func(childComplexity int) int - ProjectID func(childComplexity int) int TaskGroups func(childComplexity int) int Team func(childComplexity int) int } ProjectLabel struct { - ColorHex func(childComplexity int) int - CreatedDate func(childComplexity int) int - Name func(childComplexity int) int - ProjectLabelID func(childComplexity int) int + ColorHex func(childComplexity int) int + CreatedDate func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int } ProjectMember struct { FirstName func(childComplexity int) int + ID func(childComplexity int) int LastName func(childComplexity int) int ProfileIcon func(childComplexity int) int - UserID func(childComplexity int) int } Query struct { @@ -126,7 +128,7 @@ type ComplexityRoot struct { RefreshToken struct { CreatedAt func(childComplexity int) int ExpiresAt func(childComplexity int) int - TokenID func(childComplexity int) int + ID func(childComplexity int) int UserID func(childComplexity int) int } @@ -134,43 +136,43 @@ type ComplexityRoot struct { Assigned func(childComplexity int) int CreatedAt func(childComplexity int) int Description func(childComplexity int) int + ID func(childComplexity int) int Labels func(childComplexity int) int Name func(childComplexity int) int Position func(childComplexity int) int TaskGroup func(childComplexity int) int - TaskID func(childComplexity int) int } TaskGroup struct { - CreatedAt func(childComplexity int) int - Name func(childComplexity int) int - Position func(childComplexity int) int - ProjectID func(childComplexity int) int - TaskGroupID func(childComplexity int) int - Tasks func(childComplexity int) int + CreatedAt func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Position func(childComplexity int) int + ProjectID func(childComplexity int) int + Tasks func(childComplexity int) int } TaskLabel struct { AssignedDate func(childComplexity int) int ColorHex func(childComplexity int) int + ID func(childComplexity int) int Name func(childComplexity int) int ProjectLabelID func(childComplexity int) int - TaskLabelID func(childComplexity int) int } Team struct { CreatedAt func(childComplexity int) int + ID func(childComplexity int) int Name func(childComplexity int) int - TeamID func(childComplexity int) int } UserAccount struct { CreatedAt func(childComplexity int) int Email func(childComplexity int) int FirstName func(childComplexity int) int + ID func(childComplexity int) int LastName func(childComplexity int) int ProfileIcon func(childComplexity int) int - UserID func(childComplexity int) int Username func(childComplexity int) int } } @@ -196,6 +198,8 @@ type MutationResolver interface { LogoutUser(ctx context.Context, input LogoutUser) (bool, error) } type ProjectResolver interface { + ID(ctx context.Context, obj *pg.Project) (uuid.UUID, error) + Team(ctx context.Context, obj *pg.Project) (*pg.Team, error) Owner(ctx context.Context, obj *pg.Project) (*ProjectMember, error) TaskGroups(ctx context.Context, obj *pg.Project) ([]pg.TaskGroup, error) @@ -203,6 +207,8 @@ type ProjectResolver interface { Labels(ctx context.Context, obj *pg.Project) ([]pg.ProjectLabel, error) } type ProjectLabelResolver interface { + ID(ctx context.Context, obj *pg.ProjectLabel) (uuid.UUID, error) + ColorHex(ctx context.Context, obj *pg.ProjectLabel) (string, error) Name(ctx context.Context, obj *pg.ProjectLabel) (*string, error) } @@ -215,7 +221,11 @@ type QueryResolver interface { TaskGroups(ctx context.Context) ([]pg.TaskGroup, error) Me(ctx context.Context) (*pg.UserAccount, error) } +type RefreshTokenResolver interface { + ID(ctx context.Context, obj *pg.RefreshToken) (uuid.UUID, error) +} type TaskResolver interface { + ID(ctx context.Context, obj *pg.Task) (uuid.UUID, error) TaskGroup(ctx context.Context, obj *pg.Task) (*pg.TaskGroup, error) Description(ctx context.Context, obj *pg.Task) (*string, error) @@ -223,15 +233,23 @@ type TaskResolver interface { Labels(ctx context.Context, obj *pg.Task) ([]pg.TaskLabel, error) } type TaskGroupResolver interface { + ID(ctx context.Context, obj *pg.TaskGroup) (uuid.UUID, error) ProjectID(ctx context.Context, obj *pg.TaskGroup) (string, error) Tasks(ctx context.Context, obj *pg.TaskGroup) ([]pg.Task, error) } type TaskLabelResolver interface { + ID(ctx context.Context, obj *pg.TaskLabel) (uuid.UUID, error) + ColorHex(ctx context.Context, obj *pg.TaskLabel) (string, error) Name(ctx context.Context, obj *pg.TaskLabel) (*string, error) } +type TeamResolver interface { + ID(ctx context.Context, obj *pg.Team) (uuid.UUID, error) +} type UserAccountResolver interface { + ID(ctx context.Context, obj *pg.UserAccount) (uuid.UUID, error) + ProfileIcon(ctx context.Context, obj *pg.UserAccount) (*ProfileIcon, error) } @@ -522,6 +540,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Project.CreatedAt(childComplexity), true + case "Project.id": + if e.complexity.Project.ID == nil { + break + } + + return e.complexity.Project.ID(childComplexity), true + case "Project.labels": if e.complexity.Project.Labels == nil { break @@ -550,13 +575,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Project.Owner(childComplexity), true - case "Project.projectID": - if e.complexity.Project.ProjectID == nil { - break - } - - return e.complexity.Project.ProjectID(childComplexity), true - case "Project.taskGroups": if e.complexity.Project.TaskGroups == nil { break @@ -585,6 +603,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ProjectLabel.CreatedDate(childComplexity), true + case "ProjectLabel.id": + if e.complexity.ProjectLabel.ID == nil { + break + } + + return e.complexity.ProjectLabel.ID(childComplexity), true + case "ProjectLabel.name": if e.complexity.ProjectLabel.Name == nil { break @@ -592,13 +617,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ProjectLabel.Name(childComplexity), true - case "ProjectLabel.projectLabelID": - if e.complexity.ProjectLabel.ProjectLabelID == nil { - break - } - - return e.complexity.ProjectLabel.ProjectLabelID(childComplexity), true - case "ProjectMember.firstName": if e.complexity.ProjectMember.FirstName == nil { break @@ -606,6 +624,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ProjectMember.FirstName(childComplexity), true + case "ProjectMember.id": + if e.complexity.ProjectMember.ID == nil { + break + } + + return e.complexity.ProjectMember.ID(childComplexity), true + case "ProjectMember.lastName": if e.complexity.ProjectMember.LastName == nil { break @@ -620,13 +645,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ProjectMember.ProfileIcon(childComplexity), true - case "ProjectMember.userID": - if e.complexity.ProjectMember.UserID == nil { - break - } - - return e.complexity.ProjectMember.UserID(childComplexity), true - case "Query.findProject": if e.complexity.Query.FindProject == nil { break @@ -710,12 +728,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.RefreshToken.ExpiresAt(childComplexity), true - case "RefreshToken.tokenId": - if e.complexity.RefreshToken.TokenID == nil { + case "RefreshToken.id": + if e.complexity.RefreshToken.ID == nil { break } - return e.complexity.RefreshToken.TokenID(childComplexity), true + return e.complexity.RefreshToken.ID(childComplexity), true case "RefreshToken.userId": if e.complexity.RefreshToken.UserID == nil { @@ -745,6 +763,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Task.Description(childComplexity), true + case "Task.id": + if e.complexity.Task.ID == nil { + break + } + + return e.complexity.Task.ID(childComplexity), true + case "Task.labels": if e.complexity.Task.Labels == nil { break @@ -773,13 +798,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Task.TaskGroup(childComplexity), true - case "Task.taskID": - if e.complexity.Task.TaskID == nil { - break - } - - return e.complexity.Task.TaskID(childComplexity), true - case "TaskGroup.createdAt": if e.complexity.TaskGroup.CreatedAt == nil { break @@ -787,6 +805,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.TaskGroup.CreatedAt(childComplexity), true + case "TaskGroup.id": + if e.complexity.TaskGroup.ID == nil { + break + } + + return e.complexity.TaskGroup.ID(childComplexity), true + case "TaskGroup.name": if e.complexity.TaskGroup.Name == nil { break @@ -808,13 +833,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.TaskGroup.ProjectID(childComplexity), true - case "TaskGroup.taskGroupID": - if e.complexity.TaskGroup.TaskGroupID == nil { - break - } - - return e.complexity.TaskGroup.TaskGroupID(childComplexity), true - case "TaskGroup.tasks": if e.complexity.TaskGroup.Tasks == nil { break @@ -836,6 +854,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.TaskLabel.ColorHex(childComplexity), true + case "TaskLabel.id": + if e.complexity.TaskLabel.ID == nil { + break + } + + return e.complexity.TaskLabel.ID(childComplexity), true + case "TaskLabel.name": if e.complexity.TaskLabel.Name == nil { break @@ -850,13 +875,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.TaskLabel.ProjectLabelID(childComplexity), true - case "TaskLabel.taskLabelID": - if e.complexity.TaskLabel.TaskLabelID == nil { - break - } - - return e.complexity.TaskLabel.TaskLabelID(childComplexity), true - case "Team.createdAt": if e.complexity.Team.CreatedAt == nil { break @@ -864,6 +882,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Team.CreatedAt(childComplexity), true + case "Team.id": + if e.complexity.Team.ID == nil { + break + } + + return e.complexity.Team.ID(childComplexity), true + case "Team.name": if e.complexity.Team.Name == nil { break @@ -871,13 +896,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Team.Name(childComplexity), true - case "Team.teamID": - if e.complexity.Team.TeamID == nil { - break - } - - return e.complexity.Team.TeamID(childComplexity), true - case "UserAccount.createdAt": if e.complexity.UserAccount.CreatedAt == nil { break @@ -899,6 +917,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.UserAccount.FirstName(childComplexity), true + case "UserAccount.id": + if e.complexity.UserAccount.ID == nil { + break + } + + return e.complexity.UserAccount.ID(childComplexity), true + case "UserAccount.lastName": if e.complexity.UserAccount.LastName == nil { break @@ -913,13 +938,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.UserAccount.ProfileIcon(childComplexity), true - case "UserAccount.userID": - if e.complexity.UserAccount.UserID == nil { - break - } - - return e.complexity.UserAccount.UserID(childComplexity), true - case "UserAccount.username": if e.complexity.UserAccount.Username == nil { break @@ -995,14 +1013,14 @@ var sources = []*ast.Source{ scalar UUID type ProjectLabel { - projectLabelID: ID! + id: ID! createdDate: Time! colorHex: String! name: String } type TaskLabel { - taskLabelID: ID! + id: ID! projectLabelID: UUID! assignedDate: Time! colorHex: String! @@ -1016,21 +1034,21 @@ type ProfileIcon { } type ProjectMember { - userID: ID! + id: ID! firstName: String! lastName: String! profileIcon: ProfileIcon! } type RefreshToken { - tokenId: ID! + id: ID! userId: UUID! expiresAt: Time! createdAt: Time! } type UserAccount { - userID: ID! + id: ID! email: String! createdAt: Time! firstName: String! @@ -1040,13 +1058,13 @@ type UserAccount { } type Team { - teamID: ID! + id: ID! createdAt: Time! name: String! } type Project { - projectID: ID! + id: ID! createdAt: Time! name: String! team: Team! @@ -1057,7 +1075,7 @@ type Project { } type TaskGroup { - taskGroupID: ID! + id: ID! projectID: String! createdAt: Time! name: String! @@ -1066,7 +1084,7 @@ type TaskGroup { } type Task { - taskID: ID! + id: ID! taskGroup: TaskGroup! createdAt: Time! name: String! @@ -2563,7 +2581,7 @@ func (ec *executionContext) _ProfileIcon_bgColor(ctx context.Context, field grap return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) _Project_projectID(ctx context.Context, field graphql.CollectedField, obj *pg.Project) (ret graphql.Marshaler) { +func (ec *executionContext) _Project_id(ctx context.Context, field graphql.CollectedField, obj *pg.Project) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2574,13 +2592,13 @@ func (ec *executionContext) _Project_projectID(ctx context.Context, field graphq Object: "Project", Field: field, Args: nil, - IsMethod: false, + 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 obj.ProjectID, nil + return ec.resolvers.Project().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -2835,7 +2853,7 @@ func (ec *executionContext) _Project_labels(ctx context.Context, field graphql.C return ec.marshalNProjectLabel2ᚕgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐProjectLabelᚄ(ctx, field.Selections, res) } -func (ec *executionContext) _ProjectLabel_projectLabelID(ctx context.Context, field graphql.CollectedField, obj *pg.ProjectLabel) (ret graphql.Marshaler) { +func (ec *executionContext) _ProjectLabel_id(ctx context.Context, field graphql.CollectedField, obj *pg.ProjectLabel) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2846,13 +2864,13 @@ func (ec *executionContext) _ProjectLabel_projectLabelID(ctx context.Context, fi Object: "ProjectLabel", Field: field, Args: nil, - IsMethod: false, + 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 obj.ProjectLabelID, nil + return ec.resolvers.ProjectLabel().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -2968,7 +2986,7 @@ func (ec *executionContext) _ProjectLabel_name(ctx context.Context, field graphq return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) _ProjectMember_userID(ctx context.Context, field graphql.CollectedField, obj *ProjectMember) (ret graphql.Marshaler) { +func (ec *executionContext) _ProjectMember_id(ctx context.Context, field graphql.CollectedField, obj *ProjectMember) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2985,7 +3003,7 @@ func (ec *executionContext) _ProjectMember_userID(ctx context.Context, field gra 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 obj.UserID, nil + return obj.ID, nil }) if err != nil { ec.Error(ctx, err) @@ -3439,7 +3457,7 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) } -func (ec *executionContext) _RefreshToken_tokenId(ctx context.Context, field graphql.CollectedField, obj *pg.RefreshToken) (ret graphql.Marshaler) { +func (ec *executionContext) _RefreshToken_id(ctx context.Context, field graphql.CollectedField, obj *pg.RefreshToken) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3450,13 +3468,13 @@ func (ec *executionContext) _RefreshToken_tokenId(ctx context.Context, field gra Object: "RefreshToken", Field: field, Args: nil, - IsMethod: false, + 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 obj.TokenID, nil + return ec.resolvers.RefreshToken().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -3575,7 +3593,7 @@ func (ec *executionContext) _RefreshToken_createdAt(ctx context.Context, field g return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } -func (ec *executionContext) _Task_taskID(ctx context.Context, field graphql.CollectedField, obj *pg.Task) (ret graphql.Marshaler) { +func (ec *executionContext) _Task_id(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)) @@ -3586,13 +3604,13 @@ func (ec *executionContext) _Task_taskID(ctx context.Context, field graphql.Coll Object: "Task", Field: field, Args: nil, - IsMethod: false, + 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 obj.TaskID, nil + return ec.resolvers.Task().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -3844,7 +3862,7 @@ func (ec *executionContext) _Task_labels(ctx context.Context, field graphql.Coll return ec.marshalNTaskLabel2ᚕgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTaskLabelᚄ(ctx, field.Selections, res) } -func (ec *executionContext) _TaskGroup_taskGroupID(ctx context.Context, field graphql.CollectedField, obj *pg.TaskGroup) (ret graphql.Marshaler) { +func (ec *executionContext) _TaskGroup_id(ctx context.Context, field graphql.CollectedField, obj *pg.TaskGroup) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3855,13 +3873,13 @@ func (ec *executionContext) _TaskGroup_taskGroupID(ctx context.Context, field gr Object: "TaskGroup", Field: field, Args: nil, - IsMethod: false, + 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 obj.TaskGroupID, nil + return ec.resolvers.TaskGroup().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -4048,7 +4066,7 @@ func (ec *executionContext) _TaskGroup_tasks(ctx context.Context, field graphql. return ec.marshalNTask2ᚕgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋpgᚐTaskᚄ(ctx, field.Selections, res) } -func (ec *executionContext) _TaskLabel_taskLabelID(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) { +func (ec *executionContext) _TaskLabel_id(ctx context.Context, field graphql.CollectedField, obj *pg.TaskLabel) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -4059,13 +4077,13 @@ func (ec *executionContext) _TaskLabel_taskLabelID(ctx context.Context, field gr Object: "TaskLabel", Field: field, Args: nil, - IsMethod: false, + 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 obj.TaskLabelID, nil + return ec.resolvers.TaskLabel().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -4215,7 +4233,7 @@ func (ec *executionContext) _TaskLabel_name(ctx context.Context, field graphql.C return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) _Team_teamID(ctx context.Context, field graphql.CollectedField, obj *pg.Team) (ret graphql.Marshaler) { +func (ec *executionContext) _Team_id(ctx context.Context, field graphql.CollectedField, obj *pg.Team) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -4226,13 +4244,13 @@ func (ec *executionContext) _Team_teamID(ctx context.Context, field graphql.Coll Object: "Team", Field: field, Args: nil, - IsMethod: false, + 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 obj.TeamID, nil + return ec.resolvers.Team().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -4317,7 +4335,7 @@ func (ec *executionContext) _Team_name(ctx context.Context, field graphql.Collec return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) _UserAccount_userID(ctx context.Context, field graphql.CollectedField, obj *pg.UserAccount) (ret graphql.Marshaler) { +func (ec *executionContext) _UserAccount_id(ctx context.Context, field graphql.CollectedField, obj *pg.UserAccount) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -4328,13 +4346,13 @@ func (ec *executionContext) _UserAccount_userID(ctx context.Context, field graph Object: "UserAccount", Field: field, Args: nil, - IsMethod: false, + 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 obj.UserID, nil + return ec.resolvers.UserAccount().ID(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -6365,11 +6383,20 @@ func (ec *executionContext) _Project(ctx context.Context, sel ast.SelectionSet, switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Project") - case "projectID": - out.Values[i] = ec._Project_projectID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } + case "id": + 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._Project_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "createdAt": out.Values[i] = ec._Project_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6472,11 +6499,20 @@ func (ec *executionContext) _ProjectLabel(ctx context.Context, sel ast.Selection switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("ProjectLabel") - case "projectLabelID": - out.Values[i] = ec._ProjectLabel_projectLabelID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } + case "id": + 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._ProjectLabel_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "createdDate": out.Values[i] = ec._ProjectLabel_createdDate(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6529,8 +6565,8 @@ func (ec *executionContext) _ProjectMember(ctx context.Context, sel ast.Selectio switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("ProjectMember") - case "userID": - out.Values[i] = ec._ProjectMember_userID(ctx, field, obj) + case "id": + out.Values[i] = ec._ProjectMember_id(ctx, field, obj) if out.Values[i] == graphql.Null { invalids++ } @@ -6699,25 +6735,34 @@ func (ec *executionContext) _RefreshToken(ctx context.Context, sel ast.Selection switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("RefreshToken") - case "tokenId": - out.Values[i] = ec._RefreshToken_tokenId(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ - } + case "id": + 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._RefreshToken_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "userId": out.Values[i] = ec._RefreshToken_userId(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "expiresAt": out.Values[i] = ec._RefreshToken_expiresAt(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "createdAt": out.Values[i] = ec._RefreshToken_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } default: panic("unknown field " + strconv.Quote(field.Name)) @@ -6741,11 +6786,20 @@ func (ec *executionContext) _Task(ctx context.Context, sel ast.SelectionSet, obj switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Task") - case "taskID": - out.Values[i] = ec._Task_taskID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } + case "id": + 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_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "taskGroup": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -6836,11 +6890,20 @@ func (ec *executionContext) _TaskGroup(ctx context.Context, sel ast.SelectionSet switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("TaskGroup") - case "taskGroupID": - out.Values[i] = ec._TaskGroup_taskGroupID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } + case "id": + 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._TaskGroup_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "projectID": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -6906,11 +6969,20 @@ func (ec *executionContext) _TaskLabel(ctx context.Context, sel ast.SelectionSet switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("TaskLabel") - case "taskLabelID": - out.Values[i] = ec._TaskLabel_taskLabelID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } + case "id": + 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._TaskLabel_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "projectLabelID": out.Values[i] = ec._TaskLabel_projectLabelID(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6968,20 +7040,29 @@ func (ec *executionContext) _Team(ctx context.Context, sel ast.SelectionSet, obj switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Team") - case "teamID": - out.Values[i] = ec._Team_teamID(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ - } + case "id": + 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._Team_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "createdAt": out.Values[i] = ec._Team_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "name": out.Values[i] = ec._Team_name(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } default: panic("unknown field " + strconv.Quote(field.Name)) @@ -7005,11 +7086,20 @@ func (ec *executionContext) _UserAccount(ctx context.Context, sel ast.SelectionS switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("UserAccount") - case "userID": - out.Values[i] = ec._UserAccount_userID(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) - } + case "id": + 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._UserAccount_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "email": out.Values[i] = ec._UserAccount_email(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/api/graph/models_gen.go b/api/graph/models_gen.go index 9db2f97..709bce8 100644 --- a/api/graph/models_gen.go +++ b/api/graph/models_gen.go @@ -110,7 +110,7 @@ type ProfileIcon struct { } type ProjectMember struct { - UserID uuid.UUID `json:"userID"` + ID uuid.UUID `json:"id"` FirstName string `json:"firstName"` LastName string `json:"lastName"` ProfileIcon *ProfileIcon `json:"profileIcon"` diff --git a/api/graph/schema.graphqls b/api/graph/schema.graphqls index 2131599..42ca110 100644 --- a/api/graph/schema.graphqls +++ b/api/graph/schema.graphqls @@ -2,14 +2,14 @@ scalar Time scalar UUID type ProjectLabel { - projectLabelID: ID! + id: ID! createdDate: Time! colorHex: String! name: String } type TaskLabel { - taskLabelID: ID! + id: ID! projectLabelID: UUID! assignedDate: Time! colorHex: String! @@ -23,21 +23,21 @@ type ProfileIcon { } type ProjectMember { - userID: ID! + id: ID! firstName: String! lastName: String! profileIcon: ProfileIcon! } type RefreshToken { - tokenId: ID! + id: ID! userId: UUID! expiresAt: Time! createdAt: Time! } type UserAccount { - userID: ID! + id: ID! email: String! createdAt: Time! firstName: String! @@ -47,13 +47,13 @@ type UserAccount { } type Team { - teamID: ID! + id: ID! createdAt: Time! name: String! } type Project { - projectID: ID! + id: ID! createdAt: Time! name: String! team: Team! @@ -64,7 +64,7 @@ type Project { } type TaskGroup { - taskGroupID: ID! + id: ID! projectID: String! createdAt: Time! name: String! @@ -73,7 +73,7 @@ type TaskGroup { } type Task { - taskID: ID! + id: ID! taskGroup: TaskGroup! createdAt: Time! name: String! diff --git a/api/graph/schema.resolvers.go b/api/graph/schema.resolvers.go index 3f73773..e857b79 100644 --- a/api/graph/schema.resolvers.go +++ b/api/graph/schema.resolvers.go @@ -190,6 +190,10 @@ func (r *mutationResolver) LogoutUser(ctx context.Context, input LogoutUser) (bo return true, err } +func (r *projectResolver) ID(ctx context.Context, obj *pg.Project) (uuid.UUID, error) { + return obj.ProjectID, nil +} + func (r *projectResolver) Team(ctx context.Context, obj *pg.Project) (*pg.Team, error) { team, err := r.Repository.GetTeamByID(ctx, obj.TeamID) return &team, err @@ -226,6 +230,10 @@ func (r *projectResolver) Labels(ctx context.Context, obj *pg.Project) ([]pg.Pro return labels, err } +func (r *projectLabelResolver) ID(ctx context.Context, obj *pg.ProjectLabel) (uuid.UUID, error) { + return obj.ProjectLabelID, nil +} + func (r *projectLabelResolver) ColorHex(ctx context.Context, obj *pg.ProjectLabel) (string, error) { labelColor, err := r.Repository.GetLabelColorByID(ctx, obj.LabelColorID) if err != nil { @@ -235,7 +243,11 @@ func (r *projectLabelResolver) ColorHex(ctx context.Context, obj *pg.ProjectLabe } func (r *projectLabelResolver) Name(ctx context.Context, obj *pg.ProjectLabel) (*string, error) { - panic(fmt.Errorf("not implemented")) + var name *string + if obj.Name.Valid { + name = &obj.Name.String + } + return name, nil } func (r *queryResolver) Users(ctx context.Context) ([]pg.UserAccount, error) { @@ -311,6 +323,14 @@ func (r *queryResolver) Me(ctx context.Context) (*pg.UserAccount, error) { return &user, err } +func (r *refreshTokenResolver) ID(ctx context.Context, obj *pg.RefreshToken) (uuid.UUID, error) { + return obj.TokenID, nil +} + +func (r *taskResolver) ID(ctx context.Context, obj *pg.Task) (uuid.UUID, error) { + return obj.TaskID, nil +} + func (r *taskResolver) TaskGroup(ctx context.Context, obj *pg.Task) (*pg.TaskGroup, error) { taskGroup, err := r.Repository.GetTaskGroupByID(ctx, obj.TaskGroupID) return &taskGroup, err @@ -349,6 +369,10 @@ func (r *taskResolver) Labels(ctx context.Context, obj *pg.Task) ([]pg.TaskLabel return r.Repository.GetTaskLabelsForTaskID(ctx, obj.TaskID) } +func (r *taskGroupResolver) ID(ctx context.Context, obj *pg.TaskGroup) (uuid.UUID, error) { + return obj.TaskGroupID, nil +} + func (r *taskGroupResolver) ProjectID(ctx context.Context, obj *pg.TaskGroup) (string, error) { return obj.ProjectID.String(), nil } @@ -358,6 +382,10 @@ func (r *taskGroupResolver) Tasks(ctx context.Context, obj *pg.TaskGroup) ([]pg. return tasks, err } +func (r *taskLabelResolver) ID(ctx context.Context, obj *pg.TaskLabel) (uuid.UUID, error) { + return obj.TaskLabelID, nil +} + func (r *taskLabelResolver) ColorHex(ctx context.Context, obj *pg.TaskLabel) (string, error) { projectLabel, err := r.Repository.GetProjectLabelByID(ctx, obj.ProjectLabelID) if err != nil { @@ -382,6 +410,14 @@ func (r *taskLabelResolver) Name(ctx context.Context, obj *pg.TaskLabel) (*strin return &name.String, err } +func (r *teamResolver) ID(ctx context.Context, obj *pg.Team) (uuid.UUID, error) { + return obj.TeamID, nil +} + +func (r *userAccountResolver) ID(ctx context.Context, obj *pg.UserAccount) (uuid.UUID, error) { + return obj.UserID, nil +} + func (r *userAccountResolver) ProfileIcon(ctx context.Context, obj *pg.UserAccount) (*ProfileIcon, error) { initials := string([]rune(obj.FirstName)[0]) + string([]rune(obj.LastName)[0]) profileIcon := &ProfileIcon{nil, &initials, &obj.ProfileBgColor} @@ -400,6 +436,9 @@ func (r *Resolver) ProjectLabel() ProjectLabelResolver { return &projectLabelRes // Query returns QueryResolver implementation. func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } +// RefreshToken returns RefreshTokenResolver implementation. +func (r *Resolver) RefreshToken() RefreshTokenResolver { return &refreshTokenResolver{r} } + // Task returns TaskResolver implementation. func (r *Resolver) Task() TaskResolver { return &taskResolver{r} } @@ -409,6 +448,9 @@ func (r *Resolver) TaskGroup() TaskGroupResolver { return &taskGroupResolver{r} // TaskLabel returns TaskLabelResolver implementation. func (r *Resolver) TaskLabel() TaskLabelResolver { return &taskLabelResolver{r} } +// Team returns TeamResolver implementation. +func (r *Resolver) Team() TeamResolver { return &teamResolver{r} } + // UserAccount returns UserAccountResolver implementation. func (r *Resolver) UserAccount() UserAccountResolver { return &userAccountResolver{r} } @@ -416,20 +458,9 @@ type mutationResolver struct{ *Resolver } type projectResolver struct{ *Resolver } type projectLabelResolver struct{ *Resolver } type queryResolver struct{ *Resolver } +type refreshTokenResolver struct{ *Resolver } type taskResolver struct{ *Resolver } type taskGroupResolver struct{ *Resolver } type taskLabelResolver struct{ *Resolver } +type teamResolver struct{ *Resolver } type userAccountResolver struct{ *Resolver } - -// !!! WARNING !!! -// The code below was going to be deleted when updating resolvers. It has been copied here so you have -// one last chance to move it out of harms way if you want. There are two reasons this happens: -// - When renaming or deleting a resolver the old code will be put in here. You can safely delete -// it when you're done. -// - You have helper methods in this file. Move them out to keep these resolver files clean. -func (r *taskLabelResolver) ProjectLabelID(ctx context.Context, obj *pg.TaskLabel) (uuid.UUID, error) { - panic(fmt.Errorf("not implemented")) -} -func (r *userAccountResolver) DisplayName(ctx context.Context, obj *pg.UserAccount) (string, error) { - return obj.FirstName + " " + obj.LastName, nil -} diff --git a/api/migrations/0017_add-profile-bg-delete-cascade.up.sql b/api/migrations/0017_add-profile-bg-delete-cascade.up.sql new file mode 100644 index 0000000..b25f027 --- /dev/null +++ b/api/migrations/0017_add-profile-bg-delete-cascade.up.sql @@ -0,0 +1,7 @@ +ALTER TABLE task_assigned + DROP CONSTRAINT task_assigned_task_id_fkey, + ADD CONSTRAINT task_assigned_task_id_fkey + FOREIGN KEY (task_id) + REFERENCES task(task_id) + ON DELETE CASCADE; + diff --git a/assets/favicon.svg b/assets/favicon.svg new file mode 100644 index 0000000..04348ba --- /dev/null +++ b/assets/favicon.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/web/public/favicon.ico b/web/public/favicon.ico index bcd5dfd..467a6f6 100644 Binary files a/web/public/favicon.ico and b/web/public/favicon.ico differ diff --git a/web/public/index.html b/web/public/index.html index aa069f2..4176852 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + Citadel diff --git a/web/src/App/TopNavbar.tsx b/web/src/App/TopNavbar.tsx index 4919d2f..ab34bd9 100644 --- a/web/src/App/TopNavbar.tsx +++ b/web/src/App/TopNavbar.tsx @@ -5,7 +5,10 @@ import { useHistory } from 'react-router'; import UserIDContext from 'App/context'; import { useMeQuery } from 'shared/generated/graphql'; -const GlobalTopNavbar: React.FC = () => { +type GlobalTopNavbarProps = { + name: string; +}; +const GlobalTopNavbar: React.FC = ({ name }) => { const { loading, data } = useMeQuery(); const history = useHistory(); const { userID, setUserID } = useContext(UserIDContext); @@ -41,6 +44,7 @@ const GlobalTopNavbar: React.FC = () => { return ( <> { return ( <> - - - - {loading ? ( -
loading
- ) : ( - <> - - - - - - - )} -
+ + + + + {loading ? ( +
loading
+ ) : ( + <> + + + + + + )} +
+
); diff --git a/web/src/Projects/Project/Details/index.tsx b/web/src/Projects/Project/Details/index.tsx index 270ed8a..a47c196 100644 --- a/web/src/Projects/Project/Details/index.tsx +++ b/web/src/Projects/Project/Details/index.tsx @@ -1,11 +1,12 @@ import React, { useState, useContext } from 'react'; import Modal from 'shared/components/Modal'; import TaskDetails from 'shared/components/TaskDetails'; -import PopupMenu from 'shared/components/PopupMenu'; +import PopupMenu, { Popup, usePopup } from 'shared/components/PopupMenu'; import MemberManager from 'shared/components/MemberManager'; import { useRouteMatch, useHistory } from 'react-router'; import { useFindTaskQuery, useAssignTaskMutation, useUnassignTaskMutation } from 'shared/generated/graphql'; import UserIDContext from 'App/context'; +import MiniProfile from 'shared/components/MiniProfile'; type DetailsProps = { taskID: string; @@ -13,7 +14,7 @@ type DetailsProps = { onTaskNameChange: (task: Task, newName: string) => void; onTaskDescriptionChange: (task: Task, newDescription: string) => void; onDeleteTask: (task: Task) => void; - onOpenAddLabelPopup: (task: Task, bounds: ElementBounds) => void; + onOpenAddLabelPopup: (task: Task, $targetRef: React.RefObject) => void; availableMembers: Array; refreshCache: () => void; }; @@ -31,8 +32,10 @@ const Details: React.FC = ({ refreshCache, }) => { const { userID } = useContext(UserIDContext); + const { showPopup } = usePopup(); const history = useHistory(); const match = useRouteMatch(); + const [currentMemberTask, setCurrentMemberTask] = useState(''); const [memberPopupData, setMemberPopupData] = useState(initialMemberPopupState); const { loading, data, refetch } = useFindTaskQuery({ variables: { taskID } }); const [assignTask] = useAssignTaskMutation({ @@ -55,7 +58,7 @@ const Details: React.FC = ({ } const taskMembers = data.findTask.assigned.map(assigned => { return { - userID: assigned.userID, + userID: assigned.id, displayName: `${assigned.firstName} ${assigned.lastName}`, profileIcon: { url: null, @@ -76,6 +79,8 @@ const Details: React.FC = ({ = ({ onTaskDescriptionChange={onTaskDescriptionChange} onDeleteTask={onDeleteTask} onCloseModal={() => history.push(projectURL)} - onOpenAddMemberPopup={(task, bounds) => { - console.log(task, bounds); - setMemberPopupData({ - isOpen: true, - taskID: task.taskID, - top: bounds.position.top + bounds.size.height + 10, - left: bounds.position.left, - }); + onMemberProfile={($targetRef, memberID) => { + showPopup( + $targetRef, + {}} tab={0}> + { + unassignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } }); + }} + /> + , + ); + }} + onOpenAddMemberPopup={(task, $targetRef) => { + console.log(`task: ${task.taskID}`); + showPopup( + $targetRef, + {}}> + { + console.log(`is active ${member.userID} - ${isActive}`); + if (isActive) { + assignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } }); + } else { + unassignTask({ variables: { taskID: data.findTask.id, userID: userID ?? '' } }); + } + console.log(member, isActive); + }} + /> + , + ); }} onOpenAddLabelPopup={onOpenAddLabelPopup} /> ); }} /> - {memberPopupData.isOpen && ( - setMemberPopupData(initialMemberPopupState)} - left={memberPopupData.left} - > - { - console.log(`is active ${member.userID} - ${isActive}`); - if (isActive) { - assignTask({ variables: { taskID: data.findTask.taskID, userID: userID ?? '' } }); - } else { - unassignTask({ variables: { taskID: data.findTask.taskID, userID: userID ?? '' } }); - } - console.log(member, isActive); - }} - /> - - )} ); }; diff --git a/web/src/Projects/Project/KanbanBoard/index.tsx b/web/src/Projects/Project/KanbanBoard/index.tsx index f8126c3..10660ee 100644 --- a/web/src/Projects/Project/KanbanBoard/index.tsx +++ b/web/src/Projects/Project/KanbanBoard/index.tsx @@ -6,7 +6,7 @@ import { Board } from './Styles'; type KanbanBoardProps = { listsData: BoardState; - onOpenListActionsPopup: (isOpen: boolean, left: number, top: number, taskGroupID: string) => void; + onOpenListActionsPopup: ($targetRef: React.RefObject, taskGroupID: string) => void; onCardDrop: (task: Task) => void; onListDrop: (taskGroup: TaskGroup) => void; onCardCreate: (taskGroupID: string, name: string) => void; @@ -31,8 +31,8 @@ const KanbanBoard: React.FC = ({ onCardClick={task => { history.push(`${match.url}/c/${task.taskID}`); }} - onExtraMenuOpen={(taskGroupID, pos, size) => { - onOpenListActionsPopup(true, pos.left, pos.top + size.height + 5, taskGroupID); + onExtraMenuOpen={(taskGroupID, $targetRef) => { + onOpenListActionsPopup($targetRef, taskGroupID); }} onQuickEditorOpen={onQuickEditorOpen} onCardCreate={onCardCreate} diff --git a/web/src/Projects/Project/index.tsx b/web/src/Projects/Project/index.tsx index 479eb60..48a27d7 100644 --- a/web/src/Projects/Project/index.tsx +++ b/web/src/Projects/Project/index.tsx @@ -1,6 +1,9 @@ -import React, { useState } from 'react'; +import React, { useState, useRef } from 'react'; import * as BoardStateUtils from 'shared/utils/boardState'; +import GlobalTopNavbar from 'App/TopNavbar'; import styled from 'styled-components/macro'; +import { Bolt, ToggleOn, Tags } from 'shared/icons'; +import { usePopup, Popup } from 'shared/components/PopupMenu'; import { useParams, Route, useRouteMatch, useHistory, RouteComponentProps } from 'react-router-dom'; import { useFindProjectQuery, @@ -13,14 +16,19 @@ import { useDeleteTaskGroupMutation, useUpdateTaskDescriptionMutation, useAssignTaskMutation, + DeleteTaskDocument, + FindProjectDocument, } from 'shared/generated/graphql'; import QuickCardEditor from 'shared/components/QuickCardEditor'; -import PopupMenu from 'shared/components/PopupMenu'; import ListActions from 'shared/components/ListActions'; import MemberManager from 'shared/components/MemberManager'; import { LabelsPopup } from 'shared/components/PopupMenu/PopupMenu.stories'; import KanbanBoard from 'Projects/Project/KanbanBoard'; +import { mixin } from 'shared/utils/styles'; +import LabelManager from 'shared/components/PopupMenu/LabelManager'; +import LabelEditor from 'shared/components/PopupMenu/LabelEditor'; +import produce from 'immer'; import Details from './Details'; type TaskRouteProps = { @@ -45,6 +53,67 @@ const Title = styled.span` color: #fff; `; +type LabelManagerEditorProps = { + labels: Array