LibraryPanel: Cleanup service calls (#113277)

* cleanup

* library panel via search

* test cleanup

* merge main

* add FindDashboards mock

* no matching dashbaords should return empty

* do not alllow name and libraryPanel query
This commit is contained in:
Ryan McKinley
2025-11-06 15:31:02 +01:00
committed by GitHub
parent ca5d898120
commit 95ffd1a55a
9 changed files with 62 additions and 51 deletions
@@ -229,12 +229,32 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resourcepb.Reso
return nil, fmt.Errorf("only one repo name is supported")
}
query.ManagerIdentity = vals[0]
case unisearch.DASHBOARD_LIBRARY_PANEL_REFERENCE:
if len(vals) != 1 {
return nil, fmt.Errorf("only one library panel uid is supported")
}
return c.getLibraryPanelConnections(ctx, user, vals[0], req.Options.Key.Namespace)
// Make sure the query does not include incompatible combinations
for _, f := range req.Options.Fields {
switch f.Key {
case resource.SEARCH_FIELD_NAME:
return nil, fmt.Errorf("libraryPanel query must not include explicit names")
}
}
query.DashboardUIDs, err = c.getLibraryPanelConnections(ctx, user, vals[0])
if err != nil {
return nil, err
}
if len(query.DashboardUIDs) == 0 {
// Empty results
return &resourcepb.ResourceSearchResponse{
TotalHits: 0,
Results: &resourcepb.ResourceTable{},
}, nil
}
case resource.SEARCH_FIELD_TITLE_PHRASE:
if len(vals) != 1 {
return nil, fmt.Errorf("only one title supported")
@@ -362,32 +382,18 @@ func getResourceKey(item *dashboards.DashboardSearchProjection, namespace string
}
}
// retrieves all the dashboards that are connected to the given library panel
func (c *DashboardSearchClient) getLibraryPanelConnections(ctx context.Context, user identity.Requester, libraryElementUID, namespace string) (*resourcepb.ResourceSearchResponse, error) {
// retrieves all dashboard UIDs connected to a given library panel
func (c *DashboardSearchClient) getLibraryPanelConnections(ctx context.Context, user identity.Requester, libraryElementUID string) ([]string, error) {
connections, err := c.dashboardStore.GetDashboardsByLibraryPanelUID(ctx, libraryElementUID, user.GetOrgID())
if err != nil {
return nil, err
}
columns := c.getColumns("", &dashboards.FindPersistedDashboardsQuery{})
list := &resourcepb.ResourceSearchResponse{
Results: &resourcepb.ResourceTable{
Columns: columns,
},
uids := make([]string, len(connections))
for i, dashboard := range connections {
uids[i] = dashboard.UID
}
for _, dashboard := range connections {
cells := c.createCommonCells("", dashboard.FolderUID, dashboard.ID, nil) // nolint:staticcheck
list.Results.Rows = append(list.Results.Rows, &resourcepb.ResourceTableRow{
Key: getResourceKey(&dashboards.DashboardSearchProjection{
UID: dashboard.UID,
}, namespace),
Cells: cells,
})
}
list.TotalHits = int64(len(list.Results.Rows))
return list, nil
return uids, nil
}
func (c *DashboardSearchClient) GetStats(ctx context.Context, req *resourcepb.ResourceStatsRequest, _ ...grpc.CallOption) (*resourcepb.ResourceStatsResponse, error) {
@@ -581,6 +581,11 @@ func TestDashboardSearchClient_Search(t *testing.T) {
{UID: "dashboard2", FolderUID: "folder2", ID: 2},
}, nil).Once()
mockStore.On("FindDashboards", mock.Anything, mock.Anything).Return([]dashboards.DashboardSearchProjection{
{UID: "dashboard1", FolderUID: "folder1", ID: 1},
{UID: "dashboard2", FolderUID: "folder2", ID: 2},
}, nil).Once()
req := &resourcepb.ResourceSearchRequest{
Options: &resourcepb.ListOptions{
Key: dashboardKey,
+18
View File
@@ -121,6 +121,15 @@ func (s *SearchHandler) GetAPIRoutes(defs map[string]common.OpenAPIDefinition) *
Schema: spec.ArrayProperty(spec.StringProperty()),
},
},
{
ParameterProps: spec3.ParameterProps{
Name: "libraryPanel",
In: "query",
Description: "find dashboards that reference a given libraryPanel",
Required: false,
Schema: spec.StringProperty(),
},
},
{
ParameterProps: spec3.ParameterProps{
Name: "sort",
@@ -363,6 +372,15 @@ func (s *SearchHandler) DoSearch(w http.ResponseWriter, r *http.Request) {
}}
}
// The libraryPanel filter
if libraryPanel, ok := queryParams["libraryPanel"]; ok {
searchRequest.Options.Fields = []*resourcepb.Requirement{{
Key: search.DASHBOARD_LIBRARY_PANEL_REFERENCE,
Operator: "=",
Values: libraryPanel,
}}
}
// The names filter
names := queryParams["name"]