Hide accepted invitations
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -378,13 +378,14 @@ func (s *TenantAuthzService) GetInvitationsByOrganizationID(
|
||||
ctx context.Context,
|
||||
orgID gid.GID,
|
||||
cursor *page.Cursor[coredata.InvitationOrderField],
|
||||
filter *coredata.InvitationFilter,
|
||||
) (*page.Page[*coredata.Invitation, coredata.InvitationOrderField], error) {
|
||||
var invitations coredata.Invitations
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := invitations.LoadByOrganizationID(ctx, conn, s.scope, orgID, cursor); err != nil {
|
||||
if err := invitations.LoadByOrganizationID(ctx, conn, s.scope, orgID, cursor, filter); err != nil {
|
||||
return fmt.Errorf("failed to load organization invitations: %w", err)
|
||||
}
|
||||
|
||||
@@ -401,6 +402,7 @@ func (s *TenantAuthzService) GetInvitationsByOrganizationID(
|
||||
func (s *TenantAuthzService) CountOrganizationInvitations(
|
||||
ctx context.Context,
|
||||
orgID gid.GID,
|
||||
filter *coredata.InvitationFilter,
|
||||
) (int, error) {
|
||||
var count int
|
||||
err := s.pg.WithConn(
|
||||
@@ -408,7 +410,7 @@ func (s *TenantAuthzService) CountOrganizationInvitations(
|
||||
func(conn pg.Conn) error {
|
||||
var invitations coredata.Invitations
|
||||
var err error
|
||||
count, err = invitations.CountByOrganizationID(ctx, conn, s.scope, orgID)
|
||||
count, err = invitations.CountByOrganizationID(ctx, conn, s.scope, orgID, filter)
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
@@ -297,6 +297,7 @@ func (i *Invitations) LoadByOrganizationID(
|
||||
scope Scoper,
|
||||
orgID gid.GID,
|
||||
cursor *page.Cursor[InvitationOrderField],
|
||||
filter *InvitationFilter,
|
||||
) error {
|
||||
query := `
|
||||
SELECT
|
||||
@@ -319,14 +320,16 @@ WHERE
|
||||
organization_id = @organization_id
|
||||
AND %s
|
||||
AND %s
|
||||
AND %s
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment(), cursor.SQLFragment())
|
||||
query = fmt.Sprintf(query, scope.SQLFragment(), filter.SQLFragment(), cursor.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"organization_id": orgID,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
maps.Copy(args, filter.SQLArguments())
|
||||
maps.Copy(args, cursor.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, query, args)
|
||||
@@ -348,6 +351,7 @@ func (i *Invitations) CountByOrganizationID(
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
orgID gid.GID,
|
||||
filter *InvitationFilter,
|
||||
) (int, error) {
|
||||
q := `
|
||||
SELECT
|
||||
@@ -355,15 +359,16 @@ SELECT
|
||||
FROM
|
||||
authz_invitations
|
||||
WHERE
|
||||
organization_id = @organization_id AND %s
|
||||
organization_id = @organization_id AND %s AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), filter.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"organization_id": orgID,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
maps.Copy(args, filter.SQLArguments())
|
||||
|
||||
row := conn.QueryRow(ctx, q, args)
|
||||
|
||||
|
||||
@@ -20,19 +20,19 @@ import (
|
||||
|
||||
type (
|
||||
InvitationFilter struct {
|
||||
status *InvitationStatus
|
||||
statuses InvitationStatuses
|
||||
}
|
||||
)
|
||||
|
||||
func NewInvitationFilter(status *InvitationStatus) *InvitationFilter {
|
||||
func NewInvitationFilter(statuses []InvitationStatus) *InvitationFilter {
|
||||
return &InvitationFilter{
|
||||
status: status,
|
||||
statuses: InvitationStatuses(statuses),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *InvitationFilter) SQLArguments() pgx.NamedArgs {
|
||||
return pgx.NamedArgs{
|
||||
"status": f.status,
|
||||
"statuses": f.statuses,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,12 +40,12 @@ func (f *InvitationFilter) SQLFragment() string {
|
||||
return `
|
||||
(
|
||||
CASE
|
||||
WHEN @status::text IS NOT NULL THEN
|
||||
WHEN @statuses::text[] IS NOT NULL THEN
|
||||
(CASE
|
||||
WHEN accepted_at IS NOT NULL THEN 'ACCEPTED'
|
||||
WHEN expires_at < NOW() THEN 'EXPIRED'
|
||||
ELSE 'PENDING'
|
||||
END) = @status::text
|
||||
END) = ANY(@statuses::text[])
|
||||
ELSE TRUE
|
||||
END
|
||||
)`
|
||||
|
||||
@@ -17,9 +17,13 @@ package coredata
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type InvitationStatus string
|
||||
type (
|
||||
InvitationStatus string
|
||||
InvitationStatuses []InvitationStatus
|
||||
)
|
||||
|
||||
const (
|
||||
InvitationStatusPending InvitationStatus = "PENDING"
|
||||
@@ -58,3 +62,20 @@ func (tcv *InvitationStatus) Scan(value any) error {
|
||||
func (tcv InvitationStatus) Value() (driver.Value, error) {
|
||||
return tcv.String(), nil
|
||||
}
|
||||
|
||||
func (statuses InvitationStatuses) Value() (driver.Value, error) {
|
||||
if len(statuses) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var result strings.Builder
|
||||
result.WriteString("{")
|
||||
for i, status := range statuses {
|
||||
if i > 0 {
|
||||
result.WriteString(",")
|
||||
}
|
||||
result.WriteString(fmt.Sprintf("%q", status.String()))
|
||||
}
|
||||
result.WriteString("}")
|
||||
return result.String(), nil
|
||||
}
|
||||
|
||||
@@ -1508,7 +1508,7 @@ input InvitationOrder {
|
||||
}
|
||||
|
||||
input InvitationFilter {
|
||||
status: InvitationStatus
|
||||
statuses: [InvitationStatus!]
|
||||
}
|
||||
|
||||
input DocumentVersionFilter {
|
||||
@@ -3797,7 +3797,8 @@ input UpdateProcessingActivityInput {
|
||||
recipients: String @goField(omittable: true)
|
||||
location: String @goField(omittable: true)
|
||||
internationalTransfers: Boolean
|
||||
transferSafeguards: ProcessingActivityTransferSafeguards @goField(omittable: true)
|
||||
transferSafeguards: ProcessingActivityTransferSafeguards
|
||||
@goField(omittable: true)
|
||||
retentionPeriod: String @goField(omittable: true)
|
||||
securityMeasures: String @goField(omittable: true)
|
||||
dataProtectionImpactAssessment: ProcessingActivityDataProtectionImpactAssessment
|
||||
|
||||
@@ -10575,7 +10575,7 @@ input InvitationOrder {
|
||||
}
|
||||
|
||||
input InvitationFilter {
|
||||
status: InvitationStatus
|
||||
statuses: [InvitationStatus!]
|
||||
}
|
||||
|
||||
input DocumentVersionFilter {
|
||||
@@ -12864,7 +12864,8 @@ input UpdateProcessingActivityInput {
|
||||
recipients: String @goField(omittable: true)
|
||||
location: String @goField(omittable: true)
|
||||
internationalTransfers: Boolean
|
||||
transferSafeguards: ProcessingActivityTransferSafeguards @goField(omittable: true)
|
||||
transferSafeguards: ProcessingActivityTransferSafeguards
|
||||
@goField(omittable: true)
|
||||
retentionPeriod: String @goField(omittable: true)
|
||||
securityMeasures: String @goField(omittable: true)
|
||||
dataProtectionImpactAssessment: ProcessingActivityDataProtectionImpactAssessment
|
||||
@@ -72331,20 +72332,20 @@ func (ec *executionContext) unmarshalInputInvitationFilter(ctx context.Context,
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"status"}
|
||||
fieldsInOrder := [...]string{"statuses"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
switch k {
|
||||
case "status":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("status"))
|
||||
data, err := ec.unmarshalOInvitationStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus(ctx, v)
|
||||
case "statuses":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("statuses"))
|
||||
data, err := ec.unmarshalOInvitationStatus2ᚕgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatusᚄ(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.Status = data
|
||||
it.Statuses = data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101735,32 +101736,78 @@ func (ec *executionContext) unmarshalOInvitationOrder2ᚖgithubᚗcomᚋgetprobo
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalOInvitationStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus(ctx context.Context, v any) (*coredata.InvitationStatus, error) {
|
||||
func (ec *executionContext) unmarshalOInvitationStatus2ᚕgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatusᚄ(ctx context.Context, v any) ([]coredata.InvitationStatus, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
tmp, err := graphql.UnmarshalString(v)
|
||||
res := unmarshalOInvitationStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus[tmp]
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
var vSlice []any
|
||||
vSlice = graphql.CoerceList(v)
|
||||
var err error
|
||||
res := make([]coredata.InvitationStatus, len(vSlice))
|
||||
for i := range vSlice {
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i))
|
||||
res[i], err = ec.unmarshalNInvitationStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus(ctx, vSlice[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOInvitationStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus(ctx context.Context, sel ast.SelectionSet, v *coredata.InvitationStatus) graphql.Marshaler {
|
||||
func (ec *executionContext) marshalOInvitationStatus2ᚕgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatusᚄ(ctx context.Context, sel ast.SelectionSet, v []coredata.InvitationStatus) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
_ = sel
|
||||
_ = ctx
|
||||
res := graphql.MarshalString(marshalOInvitationStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus[*v])
|
||||
return res
|
||||
ret := make(graphql.Array, len(v))
|
||||
var wg sync.WaitGroup
|
||||
isLen1 := len(v) == 1
|
||||
if !isLen1 {
|
||||
wg.Add(len(v))
|
||||
}
|
||||
for i := range v {
|
||||
i := i
|
||||
fc := &graphql.FieldContext{
|
||||
Index: &i,
|
||||
Result: &v[i],
|
||||
}
|
||||
ctx := graphql.WithFieldContext(ctx, fc)
|
||||
f := func(i int) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = nil
|
||||
}
|
||||
}()
|
||||
if !isLen1 {
|
||||
defer wg.Done()
|
||||
}
|
||||
ret[i] = ec.marshalNInvitationStatus2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus(ctx, sel, v[i])
|
||||
}
|
||||
if isLen1 {
|
||||
f(i)
|
||||
} else {
|
||||
go f(i)
|
||||
}
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
for _, e := range ret {
|
||||
if e == graphql.Null {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
var (
|
||||
unmarshalOInvitationStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus = map[string]coredata.InvitationStatus{
|
||||
unmarshalOInvitationStatus2ᚕgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatusᚄ = map[string]coredata.InvitationStatus{
|
||||
"PENDING": coredata.InvitationStatusPending,
|
||||
"ACCEPTED": coredata.InvitationStatusAccepted,
|
||||
"EXPIRED": coredata.InvitationStatusExpired,
|
||||
}
|
||||
marshalOInvitationStatus2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatus = map[coredata.InvitationStatus]string{
|
||||
marshalOInvitationStatus2ᚕgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐInvitationStatusᚄ = map[coredata.InvitationStatus]string{
|
||||
coredata.InvitationStatusPending: "PENDING",
|
||||
coredata.InvitationStatusAccepted: "ACCEPTED",
|
||||
coredata.InvitationStatusExpired: "EXPIRED",
|
||||
|
||||
@@ -1235,7 +1235,7 @@ type InvitationEdge struct {
|
||||
}
|
||||
|
||||
type InvitationFilter struct {
|
||||
Status *coredata.InvitationStatus `json:"status,omitempty"`
|
||||
Statuses []coredata.InvitationStatus `json:"statuses,omitempty"`
|
||||
}
|
||||
|
||||
type InvitationOrder struct {
|
||||
|
||||
@@ -911,8 +911,13 @@ func (r *invitationResolver) Organization(ctx context.Context, obj *types.Invita
|
||||
func (r *invitationConnectionResolver) TotalCount(ctx context.Context, obj *types.InvitationConnection) (int, error) {
|
||||
switch obj.Resolver.(type) {
|
||||
case *organizationResolver:
|
||||
invitationFilter := coredata.NewInvitationFilter(nil)
|
||||
if obj.Filter != nil {
|
||||
invitationFilter = coredata.NewInvitationFilter(obj.Filter.Statuses)
|
||||
}
|
||||
|
||||
authzSvc := r.AuthzService(ctx, obj.ParentID.TenantID())
|
||||
count, err := authzSvc.CountOrganizationInvitations(ctx, obj.ParentID)
|
||||
count, err := authzSvc.CountOrganizationInvitations(ctx, obj.ParentID, invitationFilter)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to count organization invitations: %w", err))
|
||||
}
|
||||
@@ -925,7 +930,7 @@ func (r *invitationConnectionResolver) TotalCount(ctx context.Context, obj *type
|
||||
|
||||
invitationFilter := coredata.NewInvitationFilter(nil)
|
||||
if obj.Filter != nil {
|
||||
invitationFilter = coredata.NewInvitationFilter(obj.Filter.Status)
|
||||
invitationFilter = coredata.NewInvitationFilter(obj.Filter.Statuses)
|
||||
}
|
||||
|
||||
count, err := r.authzSvc.CountUserInvitations(ctx, user.EmailAddress, invitationFilter)
|
||||
@@ -3647,8 +3652,13 @@ func (r *organizationResolver) Invitations(ctx context.Context, obj *types.Organ
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
invitationFilter := coredata.NewInvitationFilter(nil)
|
||||
if filter != nil {
|
||||
invitationFilter = coredata.NewInvitationFilter(filter.Statuses)
|
||||
}
|
||||
|
||||
authzSvc := r.AuthzService(ctx, obj.ID.TenantID())
|
||||
page, err := authzSvc.GetInvitationsByOrganizationID(ctx, obj.ID, cursor)
|
||||
page, err := authzSvc.GetInvitationsByOrganizationID(ctx, obj.ID, cursor, invitationFilter)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list invitations: %w", err))
|
||||
}
|
||||
@@ -5363,7 +5373,7 @@ func (r *viewerResolver) Invitations(ctx context.Context, obj *types.Viewer, fir
|
||||
|
||||
invitationFilter := coredata.NewInvitationFilter(nil)
|
||||
if filter != nil {
|
||||
invitationFilter = coredata.NewInvitationFilter(filter.Status)
|
||||
invitationFilter = coredata.NewInvitationFilter(filter.Statuses)
|
||||
}
|
||||
|
||||
invitations, err := r.authzSvc.GetUserInvitations(ctx, user.EmailAddress, cursor, invitationFilter)
|
||||
|
||||
Reference in New Issue
Block a user