diff --git a/cmd/frontend/graphqlbackend/insights.go b/cmd/frontend/graphqlbackend/insights.go index fa84e37071b..b5a51e255f1 100644 --- a/cmd/frontend/graphqlbackend/insights.go +++ b/cmd/frontend/graphqlbackend/insights.go @@ -467,6 +467,7 @@ type InsightViewQueryArgs struct { First *int32 After *string Id *graphql.ID + Find *string IsFrozen *bool Filters *InsightViewFiltersInput SeriesDisplayOptions *SeriesDisplayOptionsInput diff --git a/cmd/frontend/graphqlbackend/insights.graphql b/cmd/frontend/graphqlbackend/insights.graphql index 2ede502710d..5ef49438747 100644 --- a/cmd/frontend/graphqlbackend/insights.graphql +++ b/cmd/frontend/graphqlbackend/insights.graphql @@ -187,6 +187,10 @@ extend type Query { first: Int after: String id: ID + """ + Allow you to search insight views by their title or data series labels. + """ + find: String isFrozen: Boolean filters: InsightViewFiltersInput seriesDisplayOptions: SeriesDisplayOptionsInput diff --git a/enterprise/internal/insights/resolvers/insight_view_resolvers.go b/enterprise/internal/insights/resolvers/insight_view_resolvers.go index b154b13ac68..69eade0868b 100644 --- a/enterprise/internal/insights/resolvers/insight_view_resolvers.go +++ b/enterprise/internal/insights/resolvers/insight_view_resolvers.go @@ -1166,6 +1166,10 @@ func (r *InsightViewQueryConnectionResolver) computeViews(ctx context.Context) ( // we might want to not filter on this attribute at all, and `bool` defaults to false. args.IsFrozen = r.args.IsFrozen } + if r.args.Find != nil { + args.Find = *r.args.Find + } + var err error args.UserID, args.OrgID, err = getUserPermissions(ctx, orgStore) if err != nil { diff --git a/enterprise/internal/insights/store/insight_store.go b/enterprise/internal/insights/store/insight_store.go index c153b237e7a..d298c5973f5 100644 --- a/enterprise/internal/insights/store/insight_store.go +++ b/enterprise/internal/insights/store/insight_store.go @@ -54,6 +54,7 @@ type InsightQueryArgs struct { After string Limit int IsFrozen *bool + Find string // This field will disable user level authorization checks on the insight views. This should only be used // when fetching insights from a container that also has authorization checks, such as a dashboard. @@ -120,6 +121,9 @@ func (s *InsightStore) GetAll(ctx context.Context, args InsightQueryArgs) ([]typ preds = append(preds, sqlf.Sprintf("iv.is_frozen = FALSE")) } } + if args.Find != "" { + preds = append(preds, sqlf.Sprintf("(iv.title ILIKE %s OR ivs.label ILIKE %s)", "%"+args.Find+"%", "%"+args.Find+"%")) + } limit := sqlf.Sprintf("") if args.Limit > 0 { diff --git a/enterprise/internal/insights/store/insight_store_test.go b/enterprise/internal/insights/store/insight_store_test.go index 12361849198..3e4f38f6e63 100644 --- a/enterprise/internal/insights/store/insight_store_test.go +++ b/enterprise/internal/insights/store/insight_store_test.go @@ -676,6 +676,125 @@ func TestGetAll(t *testing.T) { t.Errorf("unexpected insight view series want/got: %s", diff) } }) + t.Run("test find by title results ", func(*testing.T) { + store := NewInsightStore(insightsDB) + got, err := store.GetAll(ctx, InsightQueryArgs{Find: "view 3"}) + if err != nil { + t.Fatal(err) + } + series1RepoCriteria := "repo:a" + want := []types.InsightViewSeries{ + { + ViewID: 5, + UniqueID: "b", + InsightSeriesID: 1, + SeriesID: "series-id-1", + Title: "user can view 3", + Description: "", + Query: "query-1", + CreatedAt: now, + OldestHistoricalAt: now, + LastRecordedAt: now, + NextRecordingAfter: now, + LastSnapshotAt: now, + NextSnapshotAfter: now, + Label: "label5-1", + LineColor: "color", + SampleIntervalUnit: "MONTH", + SampleIntervalValue: 1, + PresentationType: types.PresentationType("LINE"), + GenerationMethod: types.GenerationMethod("search"), + SupportsAugmentation: true, + RepositoryCriteria: &series1RepoCriteria, + }, + { + ViewID: 5, + UniqueID: "b", + InsightSeriesID: 2, + SeriesID: "series-id-2", + Title: "user can view 3", + Description: "", + Query: "query-2", + CreatedAt: now, + OldestHistoricalAt: now, + LastRecordedAt: now, + NextRecordingAfter: now, + LastSnapshotAt: now, + NextSnapshotAfter: now, + Label: "label5-2", + LineColor: "color", + SampleIntervalUnit: "MONTH", + SampleIntervalValue: 1, + PresentationType: types.PresentationType("LINE"), + GenerationMethod: types.GenerationMethod("search"), + GroupBy: &groupByRepo, + SupportsAugmentation: true, + }, + } + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected insight view series want/got: %s", diff) + } + }) + + t.Run("test find by series label results ", func(*testing.T) { + store := NewInsightStore(insightsDB) + got, err := store.GetAll(ctx, InsightQueryArgs{Find: "label5-1"}) + if err != nil { + t.Fatal(err) + } + series1RepoCriteria := "repo:a" + want := []types.InsightViewSeries{ + { + ViewID: 5, + UniqueID: "b", + InsightSeriesID: 1, + SeriesID: "series-id-1", + Title: "user can view 3", + Description: "", + Query: "query-1", + CreatedAt: now, + OldestHistoricalAt: now, + LastRecordedAt: now, + NextRecordingAfter: now, + LastSnapshotAt: now, + NextSnapshotAfter: now, + Label: "label5-1", + LineColor: "color", + SampleIntervalUnit: "MONTH", + SampleIntervalValue: 1, + PresentationType: types.PresentationType("LINE"), + GenerationMethod: types.GenerationMethod("search"), + SupportsAugmentation: true, + RepositoryCriteria: &series1RepoCriteria, + }, + { + ViewID: 5, + UniqueID: "b", + InsightSeriesID: 2, + SeriesID: "series-id-2", + Title: "user can view 3", + Description: "", + Query: "query-2", + CreatedAt: now, + OldestHistoricalAt: now, + LastRecordedAt: now, + NextRecordingAfter: now, + LastSnapshotAt: now, + NextSnapshotAfter: now, + Label: "label5-2", + LineColor: "color", + SampleIntervalUnit: "MONTH", + SampleIntervalValue: 1, + PresentationType: types.PresentationType("LINE"), + GenerationMethod: types.GenerationMethod("search"), + GroupBy: &groupByRepo, + SupportsAugmentation: true, + }, + } + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected insight view series want/got: %s", diff) + } + }) } func TestGetAllOnDashboard(t *testing.T) {