Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ui: DestinationSearchSelect component #3593

Merged
merged 9 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,274 changes: 949 additions & 325 deletions graphql2/generated.go

Large diffs are not rendered by default.

23 changes: 20 additions & 3 deletions graphql2/graph/destinations.graphqls
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
extend type Query {

# destinationTypes returns a list of destination types that can be used for
# notifications.
destinationTypes: [DestinationTypeInfo!]! @experimental(flagName: "dest-types")

# destinationFieldValidate validates a destination field value as valid or invalid.
#
# It does not guarantee that the value is valid for the destination type, only
# that it is valid for the field (i.e., syntax/formatting).
destinationFieldValidate(input: DestinationFieldValidateInput!): Boolean! @experimental(flagName: "dest-types")

destinationFieldSearch(input: DestinationFieldSearchInput!): FieldValueConnection!
destinationFieldValueName(input: DestinationFieldValidateInput!): String!

# destinationDisplayInfo returns the display information for a destination.
destinationDisplayInfo(input: DestinationInput!): DestinationDisplayInfo! @experimental(flagName: "dest-types")
}

# FieldValueConnection is a connection to a list of FieldValuePairs.
type FieldValueConnection {
nodes: [FieldValuePair!]!
pageInfo: PageInfo!
}

input DestinationFieldValidateInput {
destType: DestinationType! # the type of destination to validate
fieldID: ID! # the ID of the input field to validate
Expand All @@ -25,6 +30,15 @@ input DestinationFieldValidateInput {
# notifications.
scalar DestinationType

input DestinationFieldSearchInput {
destType: DestinationType! # the type of destination to search for
fieldID: ID! # the ID of the input field to search for
search: String # search string to match against
omit: [String!] # values/ids to omit from results
after: String # cursor to start search from
first: Int = 15 # number of results to return
}

# Destination represents a destination that can be used for notifications.
type Destination {
type: DestinationType!
Expand All @@ -45,6 +59,9 @@ type FieldValuePair {
fieldID: ID! # The ID of the input field that this value is for.

value: String! # The value of the input field.
label: String! @goField(forceResolver: true) # The user-friendly text for this value of the input field (e.g., if the value is a user ID, label would be the user's name).

isFavorite: Boolean! # if true, this value is a favorite for the user, only set for search results
}

input DestinationInput {
Expand Down
124 changes: 124 additions & 0 deletions graphql2/graphqlapp/destinationtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,130 @@ const (
fieldScheduleID = "schedule-id"
)

type FieldValuePair App
type DestinationDisplayInfo App

func (a *App) FieldValuePair() graphql2.FieldValuePairResolver { return (*FieldValuePair)(a) }

func (a *FieldValuePair) Label(ctx context.Context, fvp *graphql2.FieldValuePair) (string, error) {
if fvp.Label != "" {
return fvp.Label, nil
}

app := (*App)(a)
switch fvp.FieldID {
case fieldSlackChanID:
ch, err := app.SlackStore.Channel(ctx, fvp.Value)
if err != nil {
return "", err
}
return ch.Name, nil
case fieldSlackUGID:
ug, err := app.SlackStore.UserGroup(ctx, fvp.Value)
if err != nil {
return "", err
}

return ug.Handle, nil
case fieldUserID:
u, err := app.FindOneUser(ctx, fvp.Value)
if err != nil {
return "", err
}
return u.Name, nil
case fieldRotationID:
r, err := app.FindOneRotation(ctx, fvp.Value)
if err != nil {
return "", err
}
return r.Name, nil
case fieldScheduleID:
s, err := app.FindOneSchedule(ctx, fvp.Value)
if err != nil {
return "", err
}
return s.Name, nil
}

return "", validation.NewGenericError("unsupported fieldID")
}

func (q *Query) DestinationFieldValueName(ctx context.Context, input graphql2.DestinationFieldValidateInput) (string, error) {
switch input.FieldID {
case fieldSlackChanID:
ch, err := q.SlackChannel(ctx, input.Value)
if err != nil {
return "", err
}

return ch.Name, nil
case fieldSlackUGID:
ug, err := q.SlackUserGroup(ctx, input.Value)
if err != nil {
return "", err
}

return ug.Handle, nil
}

return "", validation.NewGenericError("unsupported fieldID")
}

func (q *Query) DestinationFieldSearch(ctx context.Context, input graphql2.DestinationFieldSearchInput) (*graphql2.FieldValueConnection, error) {
switch input.FieldID {
case fieldSlackChanID:
res, err := q.SlackChannels(ctx, &graphql2.SlackChannelSearchOptions{
Omit: input.Omit,
First: input.First,
Search: input.Search,
After: input.After,
})
if err != nil {
return nil, err
}

var nodes []graphql2.FieldValuePair
for _, c := range res.Nodes {
nodes = append(nodes, graphql2.FieldValuePair{
FieldID: input.FieldID,
Value: c.ID,
Label: c.Name,
})
}

return &graphql2.FieldValueConnection{
Nodes: nodes,
PageInfo: res.PageInfo,
}, nil
case fieldSlackUGID:
res, err := q.SlackUserGroups(ctx, &graphql2.SlackUserGroupSearchOptions{
Omit: input.Omit,
First: input.First,
Search: input.Search,
After: input.After,
})
if err != nil {
return nil, err
}

var nodes []graphql2.FieldValuePair
for _, ug := range res.Nodes {
nodes = append(nodes, graphql2.FieldValuePair{
FieldID: input.FieldID,
Value: ug.ID,
Label: ug.Handle,
})
}

return &graphql2.FieldValueConnection{
Nodes: nodes,
PageInfo: res.PageInfo,
}, nil
}

return nil, validation.NewGenericError("unsupported fieldID")
}

func (q *Query) DestinationFieldValidate(ctx context.Context, input graphql2.DestinationFieldValidateInput) (bool, error) {
switch input.DestType {
case destTwilioSMS, destTwilioVoice:
Expand Down
20 changes: 18 additions & 2 deletions graphql2/models_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading