From b2e83901520cde90416a3bd7776bf80fb7b3c2a7 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Thu, 29 Jun 2023 12:38:36 -0700 Subject: [PATCH] note -> noiseReason --- alert/feedback.go | 4 +- alert/store.go | 16 +- graphql2/generated.go | 315 ++++++------------ graphql2/graphqlapp/alert.go | 10 +- graphql2/models_gen.go | 14 +- graphql2/schema.graphql | 12 +- .../20230616110941-add-alerts-feedback.sql | 2 +- .../app/alerts/components/AlertDetails.tsx | 18 +- .../app/alerts/components/AlertFeedback.tsx | 34 +- web/src/app/alerts/pages/AlertDetailPage.tsx | 4 +- web/src/cypress/e2e/alerts.cy.ts | 6 +- web/src/schema.d.ts | 12 +- 12 files changed, 165 insertions(+), 282 deletions(-) diff --git a/alert/feedback.go b/alert/feedback.go index b2a0daf48a..b1aac279c9 100644 --- a/alert/feedback.go +++ b/alert/feedback.go @@ -2,6 +2,6 @@ package alert // Feedback represents user provided information about a given alert type Feedback struct { - AlertID int - Note string + AlertID int + NoiseReason string } diff --git a/alert/store.go b/alert/store.go index 21cb7f25c5..9778b64d46 100644 --- a/alert/store.go +++ b/alert/store.go @@ -208,16 +208,16 @@ func NewStore(ctx context.Context, db *sql.DB, logDB *alertlog.Store) (*Store, e feedback: p(` SELECT - alert_id, note + alert_id, noise_reason FROM alert_feedback WHERE alert_id = $1 `), updateFeedback: p(` - INSERT INTO alert_feedback (alert_id, note) + INSERT INTO alert_feedback (alert_id, noise_reason) VALUES ($1, $2) ON CONFLICT (alert_id) DO UPDATE - SET note = $2 + SET noise_reason = $2 WHERE alert_feedback.alert_id = $1 `), }, prep.Err @@ -812,11 +812,11 @@ func (s *Store) State(ctx context.Context, alertIDs []int) ([]State, error) { func (s *Store) Feedback(ctx context.Context, alertID int) (f Feedback, err error) { row := s.feedback.QueryRowContext(ctx, alertID) - err = row.Scan(&f.AlertID, &f.Note) + err = row.Scan(&f.AlertID, &f.NoiseReason) if errors.Is(err, sql.ErrNoRows) { return Feedback{ - AlertID: alertID, - Note: "", + AlertID: alertID, + NoiseReason: "", }, nil } return f, err @@ -832,9 +832,9 @@ func (s Store) UpdateFeedback(ctx context.Context, feedback *Feedback) error { if err != nil { return err } - f.Note = feedback.Note + f.NoiseReason = feedback.NoiseReason - _, err = s.updateFeedback.ExecContext(ctx, feedback.AlertID, f.Note) + _, err = s.updateFeedback.ExecContext(ctx, feedback.AlertID, f.NoiseReason) if err != nil { return err } diff --git a/graphql2/generated.go b/graphql2/generated.go index 3535d404b5..215d983e30 100644 --- a/graphql2/generated.go +++ b/graphql2/generated.go @@ -96,9 +96,9 @@ type ComplexityRoot struct { AlertID func(childComplexity int) int CreatedAt func(childComplexity int) int Details func(childComplexity int) int - Feedback func(childComplexity int) int ID func(childComplexity int) int Metrics func(childComplexity int) int + NoiseReason func(childComplexity int) int PendingNotifications func(childComplexity int) int RecentEvents func(childComplexity int, input *AlertRecentEventsOptions) int Service func(childComplexity int) int @@ -118,10 +118,6 @@ type ComplexityRoot struct { Timestamp func(childComplexity int) int } - AlertFeedback struct { - Note func(childComplexity int) int - } - AlertLogEntry struct { ID func(childComplexity int) int Message func(childComplexity int) int @@ -309,6 +305,7 @@ type ComplexityRoot struct { EscalateAlerts func(childComplexity int, input []int) int LinkAccount func(childComplexity int, token string) int SendContactMethodVerification func(childComplexity int, input SendContactMethodVerificationInput) int + SetAlertNoiseReason func(childComplexity int, input SetAlertNoiseReasonInput) int SetConfig func(childComplexity int, input []ConfigValueInput) int SetFavorite func(childComplexity int, input SetFavoriteInput) int SetLabel func(childComplexity int, input SetLabelInput) int @@ -317,7 +314,6 @@ type ComplexityRoot struct { SetTemporarySchedule func(childComplexity int, input SetTemporaryScheduleInput) int SwoAction func(childComplexity int, action SWOAction) int TestContactMethod func(childComplexity int, id string) int - UpdateAlertFeedback func(childComplexity int, input UpdateAlertFeedbackInput) int UpdateAlerts func(childComplexity int, input UpdateAlertsInput) int UpdateAlertsByService func(childComplexity int, input UpdateAlertsByServiceInput) int UpdateBasicAuth func(childComplexity int, input UpdateBasicAuthInput) int @@ -672,7 +668,7 @@ type AlertResolver interface { RecentEvents(ctx context.Context, obj *alert.Alert, input *AlertRecentEventsOptions) (*AlertLogEntryConnection, error) PendingNotifications(ctx context.Context, obj *alert.Alert) ([]AlertPendingNotification, error) Metrics(ctx context.Context, obj *alert.Alert) (*alertmetrics.Metric, error) - Feedback(ctx context.Context, obj *alert.Alert) (*AlertFeedback, error) + NoiseReason(ctx context.Context, obj *alert.Alert) (*string, error) } type AlertLogEntryResolver interface { Message(ctx context.Context, obj *alertlog.Entry) (string, error) @@ -727,7 +723,7 @@ type MutationResolver interface { UpdateEscalationPolicyStep(ctx context.Context, input UpdateEscalationPolicyStepInput) (bool, error) DeleteAll(ctx context.Context, input []assignment.RawTarget) (bool, error) CreateAlert(ctx context.Context, input CreateAlertInput) (*alert.Alert, error) - UpdateAlertFeedback(ctx context.Context, input UpdateAlertFeedbackInput) (bool, error) + SetAlertNoiseReason(ctx context.Context, input SetAlertNoiseReasonInput) (bool, error) CreateService(ctx context.Context, input CreateServiceInput) (*service.Service, error) CreateEscalationPolicy(ctx context.Context, input CreateEscalationPolicyInput) (*escalation.Policy, error) CreateEscalationPolicyStep(ctx context.Context, input CreateEscalationPolicyStepInput) (*escalation.Step, error) @@ -917,13 +913,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Alert.Details(childComplexity), true - case "Alert.feedback": - if e.complexity.Alert.Feedback == nil { - break - } - - return e.complexity.Alert.Feedback(childComplexity), true - case "Alert.id": if e.complexity.Alert.ID == nil { break @@ -938,6 +927,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Alert.Metrics(childComplexity), true + case "Alert.noiseReason": + if e.complexity.Alert.NoiseReason == nil { + break + } + + return e.complexity.Alert.NoiseReason(childComplexity), true + case "Alert.pendingNotifications": if e.complexity.Alert.PendingNotifications == nil { break @@ -1020,13 +1016,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.AlertDataPoint.Timestamp(childComplexity), true - case "AlertFeedback.note": - if e.complexity.AlertFeedback.Note == nil { - break - } - - return e.complexity.AlertFeedback.Note(childComplexity), true - case "AlertLogEntry.id": if e.complexity.AlertLogEntry.ID == nil { break @@ -1945,6 +1934,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.SendContactMethodVerification(childComplexity, args["input"].(SendContactMethodVerificationInput)), true + case "Mutation.setAlertNoiseReason": + if e.complexity.Mutation.SetAlertNoiseReason == nil { + break + } + + args, err := ec.field_Mutation_setAlertNoiseReason_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.SetAlertNoiseReason(childComplexity, args["input"].(SetAlertNoiseReasonInput)), true + case "Mutation.setConfig": if e.complexity.Mutation.SetConfig == nil { break @@ -2041,18 +2042,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.TestContactMethod(childComplexity, args["id"].(string)), true - case "Mutation.updateAlertFeedback": - if e.complexity.Mutation.UpdateAlertFeedback == nil { - break - } - - args, err := ec.field_Mutation_updateAlertFeedback_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Mutation.UpdateAlertFeedback(childComplexity, args["input"].(UpdateAlertFeedbackInput)), true - case "Mutation.updateAlerts": if e.complexity.Mutation.UpdateAlerts == nil { break @@ -3953,6 +3942,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputScheduleTargetInput, ec.unmarshalInputSendContactMethodVerificationInput, ec.unmarshalInputServiceSearchOptions, + ec.unmarshalInputSetAlertNoiseReasonInput, ec.unmarshalInputSetFavoriteInput, ec.unmarshalInputSetLabelInput, ec.unmarshalInputSetScheduleOnCallNotificationRulesInput, @@ -3964,7 +3954,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputTargetInput, ec.unmarshalInputTimeSeriesOptions, ec.unmarshalInputTimeZoneSearchOptions, - ec.unmarshalInputUpdateAlertFeedbackInput, ec.unmarshalInputUpdateAlertsByServiceInput, ec.unmarshalInputUpdateAlertsInput, ec.unmarshalInputUpdateBasicAuthInput, @@ -4472,6 +4461,21 @@ func (ec *executionContext) field_Mutation_sendContactMethodVerification_args(ct return args, nil } +func (ec *executionContext) field_Mutation_setAlertNoiseReason_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 SetAlertNoiseReasonInput + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalNSetAlertNoiseReasonInput2githubᚗcomᚋtargetᚋgoalertᚋgraphql2ᚐSetAlertNoiseReasonInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_setConfig_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -4592,21 +4596,6 @@ func (ec *executionContext) field_Mutation_testContactMethod_args(ctx context.Co return args, nil } -func (ec *executionContext) field_Mutation_updateAlertFeedback_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 UpdateAlertFeedbackInput - if tmp, ok := rawArgs["input"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalNUpdateAlertFeedbackInput2githubᚗcomᚋtargetᚋgoalertᚋgraphql2ᚐUpdateAlertFeedbackInput(ctx, tmp) - if err != nil { - return nil, err - } - } - args["input"] = arg0 - return args, nil -} - func (ec *executionContext) field_Mutation_updateAlertsByService_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -6093,8 +6082,8 @@ func (ec *executionContext) fieldContext_Alert_metrics(ctx context.Context, fiel return fc, nil } -func (ec *executionContext) _Alert_feedback(ctx context.Context, field graphql.CollectedField, obj *alert.Alert) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Alert_feedback(ctx, field) +func (ec *executionContext) _Alert_noiseReason(ctx context.Context, field graphql.CollectedField, obj *alert.Alert) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Alert_noiseReason(ctx, field) if err != nil { return graphql.Null } @@ -6107,7 +6096,7 @@ func (ec *executionContext) _Alert_feedback(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Alert().Feedback(rctx, obj) + return ec.resolvers.Alert().NoiseReason(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -6116,23 +6105,19 @@ func (ec *executionContext) _Alert_feedback(ctx context.Context, field graphql.C if resTmp == nil { return graphql.Null } - res := resTmp.(*AlertFeedback) + res := resTmp.(*string) fc.Result = res - return ec.marshalOAlertFeedback2ᚖgithub.comᚋtargetᚋgoalertᚋgraphql2ᚐAlertFeedback(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Alert_feedback(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Alert_noiseReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Alert", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "note": - return ec.fieldContext_AlertFeedback_note(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type AlertFeedback", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil @@ -6201,8 +6186,8 @@ func (ec *executionContext) fieldContext_AlertConnection_nodes(ctx context.Conte return ec.fieldContext_Alert_pendingNotifications(ctx, field) case "metrics": return ec.fieldContext_Alert_metrics(ctx, field) - case "feedback": - return ec.fieldContext_Alert_feedback(ctx, field) + case "noiseReason": + return ec.fieldContext_Alert_noiseReason(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Alert", field.Name) }, @@ -6348,47 +6333,6 @@ func (ec *executionContext) fieldContext_AlertDataPoint_alertCount(ctx context.C return fc, nil } -func (ec *executionContext) _AlertFeedback_note(ctx context.Context, field graphql.CollectedField, obj *AlertFeedback) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_AlertFeedback_note(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Note, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_AlertFeedback_note(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "AlertFeedback", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - func (ec *executionContext) _AlertLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *alertlog.Entry) (ret graphql.Marshaler) { fc, err := ec.fieldContext_AlertLogEntry_id(ctx, field) if err != nil { @@ -11249,8 +11193,8 @@ func (ec *executionContext) fieldContext_Mutation_updateAlerts(ctx context.Conte return ec.fieldContext_Alert_pendingNotifications(ctx, field) case "metrics": return ec.fieldContext_Alert_metrics(ctx, field) - case "feedback": - return ec.fieldContext_Alert_feedback(ctx, field) + case "noiseReason": + return ec.fieldContext_Alert_noiseReason(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Alert", field.Name) }, @@ -11384,8 +11328,8 @@ func (ec *executionContext) fieldContext_Mutation_escalateAlerts(ctx context.Con return ec.fieldContext_Alert_pendingNotifications(ctx, field) case "metrics": return ec.fieldContext_Alert_metrics(ctx, field) - case "feedback": - return ec.fieldContext_Alert_feedback(ctx, field) + case "noiseReason": + return ec.fieldContext_Alert_noiseReason(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Alert", field.Name) }, @@ -11739,8 +11683,8 @@ func (ec *executionContext) fieldContext_Mutation_createAlert(ctx context.Contex return ec.fieldContext_Alert_pendingNotifications(ctx, field) case "metrics": return ec.fieldContext_Alert_metrics(ctx, field) - case "feedback": - return ec.fieldContext_Alert_feedback(ctx, field) + case "noiseReason": + return ec.fieldContext_Alert_noiseReason(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Alert", field.Name) }, @@ -11759,8 +11703,8 @@ func (ec *executionContext) fieldContext_Mutation_createAlert(ctx context.Contex return fc, nil } -func (ec *executionContext) _Mutation_updateAlertFeedback(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Mutation_updateAlertFeedback(ctx, field) +func (ec *executionContext) _Mutation_setAlertNoiseReason(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_setAlertNoiseReason(ctx, field) if err != nil { return graphql.Null } @@ -11773,7 +11717,7 @@ func (ec *executionContext) _Mutation_updateAlertFeedback(ctx context.Context, f }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().UpdateAlertFeedback(rctx, fc.Args["input"].(UpdateAlertFeedbackInput)) + return ec.resolvers.Mutation().SetAlertNoiseReason(rctx, fc.Args["input"].(SetAlertNoiseReasonInput)) }) if err != nil { ec.Error(ctx, err) @@ -11790,7 +11734,7 @@ func (ec *executionContext) _Mutation_updateAlertFeedback(ctx context.Context, f return ec.marshalNBoolean2bool(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Mutation_updateAlertFeedback(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Mutation_setAlertNoiseReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Mutation", Field: field, @@ -11807,7 +11751,7 @@ func (ec *executionContext) fieldContext_Mutation_updateAlertFeedback(ctx contex } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_updateAlertFeedback_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Mutation_setAlertNoiseReason_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -14931,8 +14875,8 @@ func (ec *executionContext) fieldContext_Query_alert(ctx context.Context, field return ec.fieldContext_Alert_pendingNotifications(ctx, field) case "metrics": return ec.fieldContext_Alert_metrics(ctx, field) - case "feedback": - return ec.fieldContext_Alert_feedback(ctx, field) + case "noiseReason": + return ec.fieldContext_Alert_noiseReason(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Alert", field.Name) }, @@ -28514,6 +28458,44 @@ func (ec *executionContext) unmarshalInputServiceSearchOptions(ctx context.Conte return it, nil } +func (ec *executionContext) unmarshalInputSetAlertNoiseReasonInput(ctx context.Context, obj interface{}) (SetAlertNoiseReasonInput, error) { + var it SetAlertNoiseReasonInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"alertID", "noiseReason"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "alertID": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("alertID")) + data, err := ec.unmarshalNInt2int(ctx, v) + if err != nil { + return it, err + } + it.AlertID = data + case "noiseReason": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("noiseReason")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.NoiseReason = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputSetFavoriteInput(ctx context.Context, obj interface{}) (SetFavoriteInput, error) { var it SetFavoriteInput asMap := map[string]interface{}{} @@ -29070,44 +29052,6 @@ func (ec *executionContext) unmarshalInputTimeZoneSearchOptions(ctx context.Cont return it, nil } -func (ec *executionContext) unmarshalInputUpdateAlertFeedbackInput(ctx context.Context, obj interface{}) (UpdateAlertFeedbackInput, error) { - var it UpdateAlertFeedbackInput - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v - } - - fieldsInOrder := [...]string{"alertID", "note"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "alertID": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("alertID")) - data, err := ec.unmarshalNInt2int(ctx, v) - if err != nil { - return it, err - } - it.AlertID = data - case "note": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("note")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.Note = data - } - } - - return it, nil -} - func (ec *executionContext) unmarshalInputUpdateAlertsByServiceInput(ctx context.Context, obj interface{}) (UpdateAlertsByServiceInput, error) { var it UpdateAlertsByServiceInput asMap := map[string]interface{}{} @@ -30429,7 +30373,7 @@ func (ec *executionContext) _Alert(ctx context.Context, sel ast.SelectionSet, ob } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "feedback": + case "noiseReason": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -30438,7 +30382,7 @@ func (ec *executionContext) _Alert(ctx context.Context, sel ast.SelectionSet, ob ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Alert_feedback(ctx, field, obj) + res = ec._Alert_noiseReason(ctx, field, obj) return res } @@ -30573,42 +30517,6 @@ func (ec *executionContext) _AlertDataPoint(ctx context.Context, sel ast.Selecti return out } -var alertFeedbackImplementors = []string{"AlertFeedback"} - -func (ec *executionContext) _AlertFeedback(ctx context.Context, sel ast.SelectionSet, obj *AlertFeedback) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, alertFeedbackImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("AlertFeedback") - case "note": - out.Values[i] = ec._AlertFeedback_note(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - var alertLogEntryImplementors = []string{"AlertLogEntry"} func (ec *executionContext) _AlertLogEntry(ctx context.Context, sel ast.SelectionSet, obj *alertlog.Entry) graphql.Marshaler { @@ -32455,9 +32363,9 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_createAlert(ctx, field) }) - case "updateAlertFeedback": + case "setAlertNoiseReason": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_updateAlertFeedback(ctx, field) + return ec._Mutation_setAlertNoiseReason(ctx, field) }) if out.Values[i] == graphql.Null { out.Invalids++ @@ -39105,6 +39013,11 @@ func (ec *executionContext) marshalNServiceOnCallUser2ᚕgithub.comᚋtarget return ret } +func (ec *executionContext) unmarshalNSetAlertNoiseReasonInput2githubᚗcomᚋtargetᚋgoalertᚋgraphql2ᚐSetAlertNoiseReasonInput(ctx context.Context, v interface{}) (SetAlertNoiseReasonInput, error) { + res, err := ec.unmarshalInputSetAlertNoiseReasonInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalNSetFavoriteInput2githubᚗcomᚋtargetᚋgoalertᚋgraphql2ᚐSetFavoriteInput(ctx context.Context, v interface{}) (SetFavoriteInput, error) { res, err := ec.unmarshalInputSetFavoriteInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -39669,11 +39582,6 @@ func (ec *executionContext) marshalNTimeZoneConnection2ᚖgithub.comᚋtarget return ec._TimeZoneConnection(ctx, sel, v) } -func (ec *executionContext) unmarshalNUpdateAlertFeedbackInput2githubᚗcomᚋtargetᚋgoalertᚋgraphql2ᚐUpdateAlertFeedbackInput(ctx context.Context, v interface{}) (UpdateAlertFeedbackInput, error) { - res, err := ec.unmarshalInputUpdateAlertFeedbackInput(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalNUpdateAlertsByServiceInput2githubᚗcomᚋtargetᚋgoalertᚋgraphql2ᚐUpdateAlertsByServiceInput(ctx context.Context, v interface{}) (UpdateAlertsByServiceInput, error) { res, err := ec.unmarshalInputUpdateAlertsByServiceInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -40397,13 +40305,6 @@ func (ec *executionContext) marshalOAlert2ᚖgithub.comᚋtargetᚋgoalertᚋa return ec._Alert(ctx, sel, v) } -func (ec *executionContext) marshalOAlertFeedback2ᚖgithub.comᚋtargetᚋgoalertᚋgraphql2ᚐAlertFeedback(ctx context.Context, sel ast.SelectionSet, v *AlertFeedback) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._AlertFeedback(ctx, sel, v) -} - func (ec *executionContext) marshalOAlertMetric2ᚖgithub.comᚋtargetᚋgoalertᚋalertᚋalertmetricsᚐMetric(ctx context.Context, sel ast.SelectionSet, v *alertmetrics.Metric) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/graphql2/graphqlapp/alert.go b/graphql2/graphqlapp/alert.go index db8f107ea5..9e3dadcbb4 100644 --- a/graphql2/graphqlapp/alert.go +++ b/graphql2/graphqlapp/alert.go @@ -360,22 +360,20 @@ func (m *Mutation) CreateAlert(ctx context.Context, input graphql2.CreateAlertIn return m.AlertStore.Create(ctx, a) } -func (a *Alert) Feedback(ctx context.Context, raw *alert.Alert) (*graphql2.AlertFeedback, error) { +func (a *Alert) NoiseReason(ctx context.Context, raw *alert.Alert) (*string, error) { am, err := a.AlertStore.Feedback(ctx, raw.ID) if err != nil { return nil, err } - return &graphql2.AlertFeedback{ - Note: &am.Note, - }, nil + return &am.NoiseReason, nil } -func (m *Mutation) UpdateAlertFeedback(ctx context.Context, input graphql2.UpdateAlertFeedbackInput) (bool, error) { +func (m *Mutation) SetAlertNoiseReason(ctx context.Context, input graphql2.SetAlertNoiseReasonInput) (bool, error) { f := &alert.Feedback{ AlertID: input.AlertID, } - f.Note = input.Note + f.NoiseReason = input.NoiseReason err := m.AlertStore.UpdateFeedback(ctx, f) if err != nil { diff --git a/graphql2/models_gen.go b/graphql2/models_gen.go index e9be0a92a2..c7fec2d5c3 100644 --- a/graphql2/models_gen.go +++ b/graphql2/models_gen.go @@ -37,10 +37,6 @@ type AlertDataPoint struct { AlertCount int `json:"alertCount"` } -type AlertFeedback struct { - Note *string `json:"note,omitempty"` -} - type AlertLogEntryConnection struct { Nodes []alertlog.Entry `json:"nodes"` PageInfo *PageInfo `json:"pageInfo"` @@ -460,6 +456,11 @@ type ServiceSearchOptions struct { FavoritesFirst *bool `json:"favoritesFirst,omitempty"` } +type SetAlertNoiseReasonInput struct { + AlertID int `json:"alertID"` + NoiseReason string `json:"noiseReason"` +} + type SetFavoriteInput struct { Target *assignment.RawTarget `json:"target"` Favorite bool `json:"favorite"` @@ -552,11 +553,6 @@ type TimeZoneSearchOptions struct { Omit []string `json:"omit,omitempty"` } -type UpdateAlertFeedbackInput struct { - AlertID int `json:"alertID"` - Note string `json:"note"` -} - type UpdateAlertsByServiceInput struct { ServiceID string `json:"serviceID"` NewStatus AlertStatus `json:"newStatus"` diff --git a/graphql2/schema.graphql b/graphql2/schema.graphql index 7cdca022c6..b150c0fc59 100644 --- a/graphql2/schema.graphql +++ b/graphql2/schema.graphql @@ -514,7 +514,7 @@ type Mutation { deleteAll(input: [TargetInput!]): Boolean! createAlert(input: CreateAlertInput!): Alert - updateAlertFeedback(input: UpdateAlertFeedbackInput!): Boolean! + setAlertNoiseReason(input: SetAlertNoiseReasonInput!): Boolean! createService(input: CreateServiceInput!): Service createEscalationPolicy(input: CreateEscalationPolicyInput!): EscalationPolicy @@ -592,9 +592,9 @@ input CreateAlertInput { sanitize: Boolean } -input UpdateAlertFeedbackInput { +input SetAlertNoiseReasonInput { alertID: Int! - note: String! + noiseReason: String! } input CreateUserInput { @@ -1074,7 +1074,7 @@ type Alert { # metrics are only available for closed alerts metrics: AlertMetric - feedback: AlertFeedback + noiseReason: String } type AlertMetric { @@ -1124,10 +1124,6 @@ type AlertState { repeatCount: Int! } -type AlertFeedback { - note: String -} - type Service { id: ID! name: String! diff --git a/migrate/migrations/20230616110941-add-alerts-feedback.sql b/migrate/migrations/20230616110941-add-alerts-feedback.sql index f197dfc36c..a9aaf9b5d7 100644 --- a/migrate/migrations/20230616110941-add-alerts-feedback.sql +++ b/migrate/migrations/20230616110941-add-alerts-feedback.sql @@ -2,7 +2,7 @@ CREATE TABLE alert_feedback ( alert_id BIGINT PRIMARY KEY REFERENCES alerts (id) ON DELETE CASCADE, - note TEXT + noise_reason TEXT ); -- +migrate Down diff --git a/web/src/app/alerts/components/AlertDetails.tsx b/web/src/app/alerts/components/AlertDetails.tsx index b50a14d3b5..e2f8d06a59 100644 --- a/web/src/app/alerts/components/AlertDetails.tsx +++ b/web/src/app/alerts/components/AlertDetails.tsx @@ -93,7 +93,7 @@ export default function AlertDetails(props: AlertDetailsProps): JSX.Element { variables: { input: { alertID: props.data.id, - note: '', + noiseReason: '', }, }, }) @@ -374,20 +374,20 @@ export default function AlertDetails(props: AlertDetailsProps): JSX.Element { 'This could be due to rate-limiting, processing, or network delays.', })) - const note = alert?.feedback?.note ?? '' - if (note !== '') { - const notesArr = note.split('|') - const reasons = notesArr.join(', ') + const noiseReason = alert?.noiseReason ?? '' + if (noiseReason !== '') { + const nrArr = noiseReason.split('|') + const reasons = nrArr.join(', ') extraNotices = [ ...extraNotices, { type: 'INFO', message: 'This alert has been marked as noise', - details: `Reason${notesArr.length > 1 ? 's' : ''}: ${reasons}`, + details: `Reason${nrArr.length > 1 ? 's' : ''}: ${reasons}`, action: ( undoFeedback()} @@ -407,7 +407,7 @@ export default function AlertDetails(props: AlertDetailsProps): JSX.Element { {/* Main Alert Info */} - {!note && ( + {!noiseReason && ( diff --git a/web/src/app/alerts/components/AlertFeedback.tsx b/web/src/app/alerts/components/AlertFeedback.tsx index 73e771031f..0fb1fc8014 100644 --- a/web/src/app/alerts/components/AlertFeedback.tsx +++ b/web/src/app/alerts/components/AlertFeedback.tsx @@ -12,16 +12,14 @@ const query = gql` query AlertFeedbackQuery($id: Int!) { alert(id: $id) { id - feedback { - note - } + noiseReason } } ` export const mutation = gql` - mutation UpdateFeedbackMutation($input: UpdateAlertFeedbackInput!) { - updateAlertFeedback(input: $input) + mutation SetAlertNoiseReasonMutation($input: SetAlertNoiseReasonInput!) { + setAlertNoiseReason(input: $input) } ` @@ -41,10 +39,10 @@ export default function AlertFeedback(props: AlertFeedbackProps): JSX.Element { const options = ['False positive', 'Not actionable', 'Poor details'] - const dataNotes = data?.alert?.feedback?.note ?? '' + const dataNoiseReason = data?.alert?.noiseReason ?? '' const getDefaults = (): [Array, string] => { - const vals = dataNotes !== '' ? dataNotes.split('|') : [] + const vals = dataNoiseReason !== '' ? dataNoiseReason.split('|') : [] let defaultValue: Array = [] let defaultOther = '' vals.forEach((val: string) => { @@ -59,7 +57,7 @@ export default function AlertFeedback(props: AlertFeedbackProps): JSX.Element { } const defaults = getDefaults() - const [notes, setNotes] = useState>(defaults[0]) + const [noiseReasons, setNoiseReasons] = useState>(defaults[0]) const [other, setOther] = useState(defaults[1]) const [otherChecked, setOtherChecked] = useState(Boolean(defaults[1])) const [mutationStatus, commit] = useMutation(mutation) @@ -67,30 +65,30 @@ export default function AlertFeedback(props: AlertFeedbackProps): JSX.Element { useEffect(() => { const v = getDefaults() - setNotes(v[0]) + setNoiseReasons(v[0]) setOther(v[1]) setOtherChecked(Boolean(v[1])) - }, [dataNotes]) + }, [dataNoiseReason]) function handleSubmit(): void { - let n = notes.slice() + let n = noiseReasons.slice() if (other !== '' && otherChecked) n = [...n, other] commit({ input: { alertID, - note: n.join('|'), + noiseReason: n.join('|'), }, }) } function handleCheck( e: React.ChangeEvent, - note: string, + noiseReason: string, ): void { if (e.target.checked) { - setNotes([...notes, note]) + setNoiseReasons([...noiseReasons, noiseReason]) } else { - setNotes(notes.filter((n) => n !== note)) + setNoiseReasons(noiseReasons.filter((n) => n !== noiseReason)) } } @@ -106,7 +104,7 @@ export default function AlertFeedback(props: AlertFeedbackProps): JSX.Element { control={ handleCheck(e, option)} /> } @@ -150,11 +148,11 @@ export default function AlertFeedback(props: AlertFeedbackProps): JSX.Element { Submit , diff --git a/web/src/app/alerts/pages/AlertDetailPage.tsx b/web/src/app/alerts/pages/AlertDetailPage.tsx index aa4f50839f..ef81d2ce45 100644 --- a/web/src/app/alerts/pages/AlertDetailPage.tsx +++ b/web/src/app/alerts/pages/AlertDetailPage.tsx @@ -13,6 +13,7 @@ const query = gql` summary details createdAt + noiseReason service { id name @@ -38,9 +39,6 @@ const query = gql` pendingNotifications { destination } - feedback { - note - } } } ` diff --git a/web/src/cypress/e2e/alerts.cy.ts b/web/src/cypress/e2e/alerts.cy.ts index 7555121372..eeb7830b00 100644 --- a/web/src/cypress/e2e/alerts.cy.ts +++ b/web/src/cypress/e2e/alerts.cy.ts @@ -412,10 +412,10 @@ function testAlerts(screen: ScreenFormat): void { cy.get('[placeholder="Other (please specify)"]').type('Test') // submit - cy.get('button[aria-label="Submit alert notes"]').should( + cy.get('button[aria-label="Submit noise reasons"]').should( 'not.be.disabled', ) - cy.get('button[aria-label="Submit alert notes"]').click() + cy.get('button[aria-label="Submit noise reasons"]').click() cy.get('label').contains('False positive').should('not.exist') // see notice @@ -427,7 +427,7 @@ function testAlerts(screen: ScreenFormat): void { ) // undo - cy.get('button[aria-label="Reset alert notes"]').click() + cy.get('button[aria-label="Reset noise reasons"]').click() cy.get('body').should('not.contain.text', noticeTitle) cy.get('[data-cy="False positive"] input[type="checkbox"]').should( 'not.be.checked', diff --git a/web/src/schema.d.ts b/web/src/schema.d.ts index a6e14212ee..5acb3e80dc 100644 --- a/web/src/schema.d.ts +++ b/web/src/schema.d.ts @@ -389,7 +389,7 @@ export interface Mutation { updateEscalationPolicyStep: boolean deleteAll: boolean createAlert?: null | Alert - updateAlertFeedback: boolean + setAlertNoiseReason: boolean createService?: null | Service createEscalationPolicy?: null | EscalationPolicy createEscalationPolicyStep?: null | EscalationPolicyStep @@ -442,9 +442,9 @@ export interface CreateAlertInput { sanitize?: null | boolean } -export interface UpdateAlertFeedbackInput { +export interface SetAlertNoiseReasonInput { alertID: number - note: string + noiseReason: string } export interface CreateUserInput { @@ -841,7 +841,7 @@ export interface Alert { recentEvents: AlertLogEntryConnection pendingNotifications: AlertPendingNotification[] metrics?: null | AlertMetric - feedback?: null | AlertFeedback + noiseReason?: null | string } export interface AlertMetric { @@ -886,10 +886,6 @@ export interface AlertState { repeatCount: number } -export interface AlertFeedback { - note?: null | string -} - export interface Service { id: string name: string