feature: add user project count to Admin component

This commit is contained in:
Jordan Knott
2020-07-17 19:40:05 -05:00
parent ccaa97e2bb
commit 68fa7aef94
23 changed files with 1140 additions and 140 deletions

View File

@ -158,6 +158,66 @@ func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) (
return items, nil
}
const getMemberProjectIDsForUserID = `-- name: GetMemberProjectIDsForUserID :many
SELECT project_id FROM project_member WHERE user_id = $1
`
func (q *Queries) GetMemberProjectIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error) {
rows, err := q.db.QueryContext(ctx, getMemberProjectIDsForUserID, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []uuid.UUID
for rows.Next() {
var project_id uuid.UUID
if err := rows.Scan(&project_id); err != nil {
return nil, err
}
items = append(items, project_id)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getOwnedProjectsForUserID = `-- name: GetOwnedProjectsForUserID :many
SELECT project_id, team_id, created_at, name, owner FROM project WHERE owner = $1
`
func (q *Queries) GetOwnedProjectsForUserID(ctx context.Context, owner uuid.UUID) ([]Project, error) {
rows, err := q.db.QueryContext(ctx, getOwnedProjectsForUserID, owner)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Project
for rows.Next() {
var i Project
if err := rows.Scan(
&i.ProjectID,
&i.TeamID,
&i.CreatedAt,
&i.Name,
&i.Owner,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getOwnedTeamProjectsForUserID = `-- name: GetOwnedTeamProjectsForUserID :many
SELECT project_id FROM project WHERE owner = $1 AND team_id = $2
`

View File

@ -52,7 +52,11 @@ type Querier interface {
GetAssignedMembersForTask(ctx context.Context, taskID uuid.UUID) ([]TaskAssigned, error)
GetLabelColorByID(ctx context.Context, labelColorID uuid.UUID) (LabelColor, error)
GetLabelColors(ctx context.Context) ([]LabelColor, error)
GetMemberProjectIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error)
GetMemberTeamIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error)
GetOwnedProjectsForUserID(ctx context.Context, owner uuid.UUID) ([]Project, error)
GetOwnedTeamProjectsForUserID(ctx context.Context, arg GetOwnedTeamProjectsForUserIDParams) ([]uuid.UUID, error)
GetOwnedTeamsForUserID(ctx context.Context, owner uuid.UUID) ([]Team, error)
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)

View File

@ -39,3 +39,9 @@ UPDATE project_member SET role_code = $3 WHERE project_id = $1 AND user_id = $2
-- name: GetOwnedTeamProjectsForUserID :many
SELECT project_id FROM project WHERE owner = $1 AND team_id = $2;
-- name: GetOwnedProjectsForUserID :many
SELECT * FROM project WHERE owner = $1;
-- name: GetMemberProjectIDsForUserID :many
SELECT project_id FROM project_member WHERE user_id = $1;

View File

@ -15,3 +15,9 @@ SELECT * FROM team WHERE organization_id = $1;
-- name: SetTeamOwner :one
UPDATE team SET owner = $2 WHERE team_id = $1 RETURNING *;
-- name: GetOwnedTeamsForUserID :many
SELECT * FROM team WHERE owner = $1;
-- name: GetMemberTeamIDsForUserID :many
SELECT team_id FROM team_member WHERE user_id = $1;

View File

@ -81,6 +81,66 @@ func (q *Queries) GetAllTeams(ctx context.Context) ([]Team, error) {
return items, nil
}
const getMemberTeamIDsForUserID = `-- name: GetMemberTeamIDsForUserID :many
SELECT team_id FROM team_member WHERE user_id = $1
`
func (q *Queries) GetMemberTeamIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error) {
rows, err := q.db.QueryContext(ctx, getMemberTeamIDsForUserID, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []uuid.UUID
for rows.Next() {
var team_id uuid.UUID
if err := rows.Scan(&team_id); err != nil {
return nil, err
}
items = append(items, team_id)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getOwnedTeamsForUserID = `-- name: GetOwnedTeamsForUserID :many
SELECT team_id, created_at, name, organization_id, owner FROM team WHERE owner = $1
`
func (q *Queries) GetOwnedTeamsForUserID(ctx context.Context, owner uuid.UUID) ([]Team, error) {
rows, err := q.db.QueryContext(ctx, getOwnedTeamsForUserID, owner)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Team
for rows.Next() {
var i Team
if err := rows.Scan(
&i.TeamID,
&i.CreatedAt,
&i.Name,
&i.OrganizationID,
&i.Owner,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getTeamByID = `-- name: GetTeamByID :one
SELECT team_id, created_at, name, organization_id, owner FROM team WHERE team_id = $1
`

View File

@ -130,12 +130,18 @@ type ComplexityRoot struct {
Member struct {
FullName func(childComplexity int) int
ID func(childComplexity int) int
Member func(childComplexity int) int
Owned func(childComplexity int) int
ProfileIcon func(childComplexity int) int
Role func(childComplexity int) int
Username func(childComplexity int) int
}
MemberList struct {
Projects func(childComplexity int) int
Teams func(childComplexity int) int
}
Mutation struct {
AddTaskLabel func(childComplexity int, input *AddTaskLabelInput) int
AssignTask func(childComplexity int, input *AssignTaskInput) int
@ -194,6 +200,11 @@ type ComplexityRoot struct {
Name func(childComplexity int) int
}
OwnedList struct {
Projects func(childComplexity int) int
Teams func(childComplexity int) int
}
OwnersList struct {
Projects func(childComplexity int) int
Teams func(childComplexity int) int
@ -363,6 +374,8 @@ type ComplexityRoot struct {
FullName func(childComplexity int) int
ID func(childComplexity int) int
Initials func(childComplexity int) int
Member func(childComplexity int) int
Owned func(childComplexity int) int
ProfileIcon func(childComplexity int) int
Role func(childComplexity int) int
Username func(childComplexity int) int
@ -501,6 +514,8 @@ type UserAccountResolver interface {
Role(ctx context.Context, obj *db.UserAccount) (*db.Role, error)
ProfileIcon(ctx context.Context, obj *db.UserAccount) (*ProfileIcon, error)
Owned(ctx context.Context, obj *db.UserAccount) (*OwnedList, error)
Member(ctx context.Context, obj *db.UserAccount) (*MemberList, error)
}
type executableSchema struct {
@ -749,6 +764,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Member.ID(childComplexity), true
case "Member.member":
if e.complexity.Member.Member == nil {
break
}
return e.complexity.Member.Member(childComplexity), true
case "Member.owned":
if e.complexity.Member.Owned == nil {
break
@ -777,6 +799,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Member.Username(childComplexity), true
case "MemberList.projects":
if e.complexity.MemberList.Projects == nil {
break
}
return e.complexity.MemberList.Projects(childComplexity), true
case "MemberList.teams":
if e.complexity.MemberList.Teams == nil {
break
}
return e.complexity.MemberList.Teams(childComplexity), true
case "Mutation.addTaskLabel":
if e.complexity.Mutation.AddTaskLabel == nil {
break
@ -1386,6 +1422,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Organization.Name(childComplexity), true
case "OwnedList.projects":
if e.complexity.OwnedList.Projects == nil {
break
}
return e.complexity.OwnedList.Projects(childComplexity), true
case "OwnedList.teams":
if e.complexity.OwnedList.Teams == nil {
break
}
return e.complexity.OwnedList.Teams(childComplexity), true
case "OwnersList.projects":
if e.complexity.OwnersList.Projects == nil {
break
@ -2083,6 +2133,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.UserAccount.Initials(childComplexity), true
case "UserAccount.member":
if e.complexity.UserAccount.Member == nil {
break
}
return e.complexity.UserAccount.Member(childComplexity), true
case "UserAccount.owned":
if e.complexity.UserAccount.Owned == nil {
break
}
return e.complexity.UserAccount.Owned(childComplexity), true
case "UserAccount.profileIcon":
if e.complexity.UserAccount.ProfileIcon == nil {
break
@ -2216,7 +2280,8 @@ type Member {
fullName: String!
username: String!
profileIcon: ProfileIcon!
owned: OwnersList
owned: OwnedList!
member: MemberList!
}
type RefreshToken {
@ -2231,6 +2296,16 @@ type Role {
name: String!
}
type OwnedList {
teams: [Team!]!
projects: [Project!]!
}
type MemberList {
teams: [Team!]!
projects: [Project!]!
}
type UserAccount {
id: ID!
email: String!
@ -2240,6 +2315,8 @@ type UserAccount {
role: Role!
username: String!
profileIcon: ProfileIcon!
owned: OwnedList!
member: MemberList!
}
type Team {
@ -4851,11 +4928,116 @@ func (ec *executionContext) _Member_owned(ctx context.Context, field graphql.Col
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*OwnersList)
res := resTmp.(*OwnedList)
fc.Result = res
return ec.marshalOOwnersList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐOwnersList(ctx, field.Selections, res)
return ec.marshalNOwnedList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐOwnedList(ctx, field.Selections, res)
}
func (ec *executionContext) _Member_member(ctx context.Context, field graphql.CollectedField, obj *Member) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Member",
Field: field,
Args: nil,
IsMethod: false,
}
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.Member, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*MemberList)
fc.Result = res
return ec.marshalNMemberList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐMemberList(ctx, field.Selections, res)
}
func (ec *executionContext) _MemberList_teams(ctx context.Context, field graphql.CollectedField, obj *MemberList) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "MemberList",
Field: field,
Args: nil,
IsMethod: false,
}
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.Teams, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]db.Team)
fc.Result = res
return ec.marshalNTeam2ᚕgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋdbᚐTeamᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _MemberList_projects(ctx context.Context, field graphql.CollectedField, obj *MemberList) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "MemberList",
Field: field,
Args: nil,
IsMethod: false,
}
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.Projects, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]db.Project)
fc.Result = res
return ec.marshalNProject2ᚕgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋdbᚐProjectᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _Mutation_createProject(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
@ -6969,6 +7151,74 @@ func (ec *executionContext) _Organization_name(ctx context.Context, field graphq
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) _OwnedList_teams(ctx context.Context, field graphql.CollectedField, obj *OwnedList) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "OwnedList",
Field: field,
Args: nil,
IsMethod: false,
}
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.Teams, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]db.Team)
fc.Result = res
return ec.marshalNTeam2ᚕgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋdbᚐTeamᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _OwnedList_projects(ctx context.Context, field graphql.CollectedField, obj *OwnedList) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "OwnedList",
Field: field,
Args: nil,
IsMethod: false,
}
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.Projects, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.([]db.Project)
fc.Result = res
return ec.marshalNProject2ᚕgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋdbᚐProjectᚄ(ctx, field.Selections, res)
}
func (ec *executionContext) _OwnersList_projects(ctx context.Context, field graphql.CollectedField, obj *OwnersList) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -10418,6 +10668,74 @@ func (ec *executionContext) _UserAccount_profileIcon(ctx context.Context, field
return ec.marshalNProfileIcon2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐProfileIcon(ctx, field.Selections, res)
}
func (ec *executionContext) _UserAccount_owned(ctx context.Context, field graphql.CollectedField, obj *db.UserAccount) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UserAccount",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.UserAccount().Owned(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*OwnedList)
fc.Result = res
return ec.marshalNOwnedList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐOwnedList(ctx, field.Selections, res)
}
func (ec *executionContext) _UserAccount_member(ctx context.Context, field graphql.CollectedField, obj *db.UserAccount) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "UserAccount",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.UserAccount().Member(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*MemberList)
fc.Result = res
return ec.marshalNMemberList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐMemberList(ctx, field.Selections, res)
}
func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
@ -13265,6 +13583,46 @@ func (ec *executionContext) _Member(ctx context.Context, sel ast.SelectionSet, o
}
case "owned":
out.Values[i] = ec._Member_owned(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "member":
out.Values[i] = ec._Member_member(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch()
if invalids > 0 {
return graphql.Null
}
return out
}
var memberListImplementors = []string{"MemberList"}
func (ec *executionContext) _MemberList(ctx context.Context, sel ast.SelectionSet, obj *MemberList) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, memberListImplementors)
out := graphql.NewFieldSet(fields)
var invalids uint32
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("MemberList")
case "teams":
out.Values[i] = ec._MemberList_teams(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "projects":
out.Values[i] = ec._MemberList_projects(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@ -13593,6 +13951,38 @@ func (ec *executionContext) _Organization(ctx context.Context, sel ast.Selection
return out
}
var ownedListImplementors = []string{"OwnedList"}
func (ec *executionContext) _OwnedList(ctx context.Context, sel ast.SelectionSet, obj *OwnedList) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, ownedListImplementors)
out := graphql.NewFieldSet(fields)
var invalids uint32
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("OwnedList")
case "teams":
out.Values[i] = ec._OwnedList_teams(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "projects":
out.Values[i] = ec._OwnedList_projects(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch()
if invalids > 0 {
return graphql.Null
}
return out
}
var ownersListImplementors = []string{"OwnersList"}
func (ec *executionContext) _OwnersList(ctx context.Context, sel ast.SelectionSet, obj *OwnersList) graphql.Marshaler {
@ -15001,6 +15391,34 @@ func (ec *executionContext) _UserAccount(ctx context.Context, sel ast.SelectionS
}
return res
})
case "owned":
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_owned(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
case "member":
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_member(ctx, field, obj)
if res == graphql.Null {
atomic.AddUint32(&invalids, 1)
}
return res
})
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@ -15645,6 +16063,20 @@ func (ec *executionContext) marshalNMember2ᚖgithubᚗcomᚋjordanknottᚋproje
return ec._Member(ctx, sel, v)
}
func (ec *executionContext) marshalNMemberList2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐMemberList(ctx context.Context, sel ast.SelectionSet, v MemberList) graphql.Marshaler {
return ec._MemberList(ctx, sel, &v)
}
func (ec *executionContext) marshalNMemberList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐMemberList(ctx context.Context, sel ast.SelectionSet, v *MemberList) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
return ec._MemberList(ctx, sel, v)
}
func (ec *executionContext) unmarshalNNewProject2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐNewProject(ctx context.Context, v interface{}) (NewProject, error) {
return ec.unmarshalInputNewProject(ctx, v)
}
@ -15722,6 +16154,20 @@ func (ec *executionContext) marshalNOrganization2ᚕgithubᚗcomᚋjordanknott
return ret
}
func (ec *executionContext) marshalNOwnedList2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐOwnedList(ctx context.Context, sel ast.SelectionSet, v OwnedList) graphql.Marshaler {
return ec._OwnedList(ctx, sel, &v)
}
func (ec *executionContext) marshalNOwnedList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐOwnedList(ctx context.Context, sel ast.SelectionSet, v *OwnedList) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
return ec._OwnedList(ctx, sel, v)
}
func (ec *executionContext) marshalNProfileIcon2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐProfileIcon(ctx context.Context, sel ast.SelectionSet, v ProfileIcon) graphql.Marshaler {
return ec._ProfileIcon(ctx, sel, &v)
}
@ -16829,17 +17275,6 @@ func (ec *executionContext) marshalOChecklistBadge2ᚖgithubᚗcomᚋjordanknott
return ec._ChecklistBadge(ctx, sel, v)
}
func (ec *executionContext) marshalOOwnersList2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐOwnersList(ctx context.Context, sel ast.SelectionSet, v OwnersList) graphql.Marshaler {
return ec._OwnersList(ctx, sel, &v)
}
func (ec *executionContext) marshalOOwnersList2ᚖgithubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐOwnersList(ctx context.Context, sel ast.SelectionSet, v *OwnersList) graphql.Marshaler {
if v == nil {
return graphql.Null
}
return ec._OwnersList(ctx, sel, v)
}
func (ec *executionContext) unmarshalOProjectsFilter2githubᚗcomᚋjordanknottᚋprojectᚑcitadelᚋapiᚋinternalᚋgraphᚐProjectsFilter(ctx context.Context, v interface{}) (ProjectsFilter, error) {
return ec.unmarshalInputProjectsFilter(ctx, v)
}

48
internal/graph/helpers.go Normal file
View File

@ -0,0 +1,48 @@
package graph
import (
"context"
"database/sql"
"github.com/jordanknott/project-citadel/api/internal/db"
)
func GetOwnedList(ctx context.Context, r db.Repository, user db.UserAccount) (*OwnedList, error) {
ownedTeams, err := r.GetOwnedTeamsForUserID(ctx, user.UserID)
if err != sql.ErrNoRows && err != nil {
return &OwnedList{}, err
}
ownedProjects, err := r.GetOwnedProjectsForUserID(ctx, user.UserID)
if err != sql.ErrNoRows && err != nil {
return &OwnedList{}, err
}
return &OwnedList{Teams: ownedTeams, Projects: ownedProjects}, nil
}
func GetMemberList(ctx context.Context, r db.Repository, user db.UserAccount) (*MemberList, error) {
projectMemberIDs, err := r.GetMemberProjectIDsForUserID(ctx, user.UserID)
if err != sql.ErrNoRows && err != nil {
return &MemberList{}, err
}
var projects []db.Project
for _, projectID := range projectMemberIDs {
project, err := r.GetProjectByID(ctx, projectID)
if err != nil {
return &MemberList{}, err
}
projects = append(projects, project)
}
teamMemberIDs, err := r.GetMemberTeamIDsForUserID(ctx, user.UserID)
if err != sql.ErrNoRows && err != nil {
return &MemberList{}, err
}
var teams []db.Team
for _, teamID := range teamMemberIDs {
team, err := r.GetTeamByID(ctx, teamID)
if err != nil {
return &MemberList{}, err
}
teams = append(teams, team)
}
return &MemberList{Teams: teams, Projects: projects}, nil
}

View File

@ -176,7 +176,13 @@ type Member struct {
FullName string `json:"fullName"`
Username string `json:"username"`
ProfileIcon *ProfileIcon `json:"profileIcon"`
Owned *OwnersList `json:"owned"`
Owned *OwnedList `json:"owned"`
Member *MemberList `json:"member"`
}
type MemberList struct {
Teams []db.Team `json:"teams"`
Projects []db.Project `json:"projects"`
}
type NewProject struct {
@ -232,6 +238,11 @@ type NewUserAccount struct {
RoleCode string `json:"roleCode"`
}
type OwnedList struct {
Teams []db.Team `json:"teams"`
Projects []db.Project `json:"projects"`
}
type OwnersList struct {
Projects []uuid.UUID `json:"projects"`
Teams []uuid.UUID `json:"teams"`

View File

@ -46,7 +46,8 @@ type Member {
fullName: String!
username: String!
profileIcon: ProfileIcon!
owned: OwnersList
owned: OwnedList!
member: MemberList!
}
type RefreshToken {
@ -61,6 +62,16 @@ type Role {
name: String!
}
type OwnedList {
teams: [Team!]!
projects: [Project!]!
}
type MemberList {
teams: [Team!]!
projects: [Project!]!
}
type UserAccount {
id: ID!
email: String!
@ -70,6 +81,8 @@ type UserAccount {
role: Role!
username: String!
profileIcon: ProfileIcon!
owned: OwnedList!
member: MemberList!
}
type Team {

View File

@ -113,16 +113,13 @@ func (r *mutationResolver) CreateProjectMember(ctx context.Context, input Create
return &CreateProjectMemberPayload{Ok: true, Member: &Member{
ID: input.UserID,
FullName: user.FullName,
Username: user.Username,
ProfileIcon: profileIcon,
Role: &db.Role{Code: role.Code, Name: role.Name},
}}, nil
}
func (r *mutationResolver) DeleteProjectMember(ctx context.Context, input DeleteProjectMember) (*DeleteProjectMemberPayload, error) {
err := r.Repository.DeleteProjectMember(ctx, db.DeleteProjectMemberParams{UserID: input.UserID, ProjectID: input.ProjectID})
if err != nil {
return &DeleteProjectMemberPayload{Ok: false}, err
}
user, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
if err != nil {
return &DeleteProjectMemberPayload{Ok: false}, err
@ -136,6 +133,10 @@ func (r *mutationResolver) DeleteProjectMember(ctx context.Context, input Delete
if err != nil {
return &DeleteProjectMemberPayload{Ok: false}, err
}
err = r.Repository.DeleteProjectMember(ctx, db.DeleteProjectMemberParams{UserID: input.UserID, ProjectID: input.ProjectID})
if err != nil {
return &DeleteProjectMemberPayload{Ok: false}, err
}
return &DeleteProjectMemberPayload{Ok: true, Member: &Member{
ID: input.UserID,
FullName: user.FullName,
@ -1156,20 +1157,15 @@ 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")
ownedList, err := GetOwnedList(ctx, r.Repository, user)
if err != nil {
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}
memberList, err := GetMemberList(ctx, r.Repository, user)
if err != nil {
return members, err
}
var url *string
if user.ProfileAvatarUrl.Valid {
url = &user.ProfileAvatarUrl.String
@ -1177,7 +1173,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,
Owned: ownerList, Role: &db.Role{Code: "owner", Name: "Owner"},
Owned: ownedList, Member: memberList, Role: &db.Role{Code: "owner", Name: "Owner"},
})
teamMembers, err := r.Repository.GetTeamMembersForTeamID(ctx, obj.TeamID)
if err != nil {
@ -1200,24 +1196,19 @@ 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")
ownedList, err := GetOwnedList(ctx, r.Repository, user)
if err != nil {
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}
memberList, err := GetMemberList(ctx, r.Repository, user)
if err != nil {
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, Owned: ownerList, Role: &db.Role{Code: role.Code, Name: role.Name},
Username: user.Username, Owned: ownedList, Member: memberList, Role: &db.Role{Code: role.Code, Name: role.Name},
})
}
return members, nil
@ -1246,6 +1237,47 @@ func (r *userAccountResolver) ProfileIcon(ctx context.Context, obj *db.UserAccou
return profileIcon, nil
}
func (r *userAccountResolver) Owned(ctx context.Context, obj *db.UserAccount) (*OwnedList, error) {
ownedTeams, err := r.Repository.GetOwnedTeamsForUserID(ctx, obj.UserID)
if err != sql.ErrNoRows && err != nil {
return &OwnedList{}, err
}
ownedProjects, err := r.Repository.GetOwnedProjectsForUserID(ctx, obj.UserID)
if err != sql.ErrNoRows && err != nil {
return &OwnedList{}, err
}
return &OwnedList{Teams: ownedTeams, Projects: ownedProjects}, nil
}
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
}
// LabelColor returns LabelColorResolver implementation.
func (r *Resolver) LabelColor() LabelColorResolver { return &labelColorResolver{r} }
@ -1274,7 +1306,9 @@ func (r *Resolver) Task() TaskResolver { return &taskResolver{r} }
func (r *Resolver) TaskChecklist() TaskChecklistResolver { return &taskChecklistResolver{r} }
// TaskChecklistItem returns TaskChecklistItemResolver implementation.
func (r *Resolver) TaskChecklistItem() TaskChecklistItemResolver { return &taskChecklistItemResolver{r} }
func (r *Resolver) TaskChecklistItem() TaskChecklistItemResolver {
return &taskChecklistItemResolver{r}
}
// TaskGroup returns TaskGroupResolver implementation.
func (r *Resolver) TaskGroup() TaskGroupResolver { return &taskGroupResolver{r} }

View File

@ -46,7 +46,8 @@ type Member {
fullName: String!
username: String!
profileIcon: ProfileIcon!
owned: OwnersList
owned: OwnedList!
member: MemberList!
}
type RefreshToken {
@ -61,6 +62,16 @@ type Role {
name: String!
}
type OwnedList {
teams: [Team!]!
projects: [Project!]!
}
type MemberList {
teams: [Team!]!
projects: [Project!]!
}
type UserAccount {
id: ID!
email: String!
@ -70,6 +81,8 @@ type UserAccount {
role: Role!
username: String!
profileIcon: ProfileIcon!
owned: OwnedList!
member: MemberList!
}
type Team {