Library Panels: Update connection generation for V2 (#114504)

* Library Panels: Update connection generation for V2

* add test

---------

Co-authored-by: Haris Rozajac <haris.rozajac12@gmail.com>
This commit is contained in:
Collin Fingar
2025-12-04 12:21:27 -05:00
committed by GitHub
co-authored by Haris Rozajac
parent 59ec85b936
commit c90677831b
2 changed files with 42 additions and 4 deletions
+17 -4
View File
@@ -64,9 +64,19 @@ var _ Service = (*LibraryPanelService)(nil)
// ConnectLibraryPanelsForDashboard loops through all panels in dashboard JSON and connects any library panels to the dashboard.
func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c context.Context, signedInUser identity.Requester, dash *dashboards.Dashboard) error {
panels := dash.Data.Get("panels").MustArray()
var panels []any
isV2 := dash.Data.Get("elements").Interface() != nil
if isV2 {
elementsMap := dash.Data.Get("elements").MustMap()
panels = make([]any, 0, len(elementsMap))
for _, element := range elementsMap {
panels = append(panels, element)
}
} else {
panels = dash.Data.Get("panels").MustArray()
}
libraryPanels := make(map[string]string)
err := connectLibraryPanelsRecursively(c, panels, libraryPanels)
err := connectLibraryPanelsRecursively(c, panels, libraryPanels, isV2)
if err != nil {
return err
}
@@ -83,10 +93,13 @@ func isLibraryPanelOrRow(panel *simplejson.Json, panelType string) bool {
return panel.Interface() != nil || panelType == "row"
}
func connectLibraryPanelsRecursively(c context.Context, panels []any, libraryPanels map[string]string) error {
func connectLibraryPanelsRecursively(c context.Context, panels []any, libraryPanels map[string]string, isV2 bool) error {
for _, panel := range panels {
panelAsJSON := simplejson.NewFromAny(panel)
libraryPanel := panelAsJSON.Get("libraryPanel")
if isV2 {
libraryPanel = panelAsJSON.Get("spec").Get("libraryPanel")
}
panelType := panelAsJSON.Get("type").MustString()
if !isLibraryPanelOrRow(libraryPanel, panelType) {
continue
@@ -95,7 +108,7 @@ func connectLibraryPanelsRecursively(c context.Context, panels []any, libraryPan
// we have a row
if panelType == "row" {
rowPanels := panelAsJSON.Get("panels").MustArray()
err := connectLibraryPanelsRecursively(c, rowPanels, libraryPanels)
err := connectLibraryPanelsRecursively(c, rowPanels, libraryPanels, isV2)
if err != nil {
return err
}
@@ -87,6 +87,31 @@ func TestIntegrationConnectLibraryPanelsForDashboard(t *testing.T) {
require.Equal(t, sc.initialResult.Result.UID, elements[sc.initialResult.Result.UID].UID)
})
scenarioWithLibraryPanel(t, "When an admin tries to store a V2 dashboard with a library panel, it should connect the two",
func(t *testing.T, sc scenarioContext) {
dashJSON := map[string]any{
"elements": []any{
map[string]any{
"kind": "Panel",
"spec": map[string]any{
"datasource": "${DS_GDEV-TESTDATA}",
"libraryPanel": map[string]any{
"uid": sc.initialResult.Result.UID,
},
},
},
},
}
dash := dashboards.Dashboard{
Title: "Testing ConnectLibraryPanelsForDashboard for V2 dashboard",
Data: simplejson.NewFromAny(dashJSON),
}
dashInDB := createDashboard(t, sc, &dash)
err := sc.service.ConnectLibraryPanelsForDashboard(sc.ctx, sc.user, dashInDB)
require.NoError(t, err)
})
scenarioWithLibraryPanel(t, "When an admin tries to store a dashboard with library panels inside and outside of rows, it should connect all",
func(t *testing.T, sc scenarioContext) {
cmd := model.CreateLibraryElementCommand{