LibraryPanels: Fixes connections after dashboard import (#34461)

This commit is contained in:
Hugo Häggmark 2021-05-20 09:40:23 +02:00 committed by GitHub
parent ca416df9d1
commit 740f1ab3e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 129 additions and 3 deletions

View File

@ -1348,6 +1348,10 @@ func (m *mockLibraryPanelService) ConnectLibraryPanelsForDashboard(c *models.Req
return nil return nil
} }
func (m *mockLibraryPanelService) ImportDashboard(c *models.ReqContext, dashboard *simplejson.Json, importedID int64) error {
return nil
}
type mockLibraryElementService struct { type mockLibraryElementService struct {
} }

View File

@ -226,6 +226,11 @@ func (hs *HTTPServer) ImportDashboard(c *models.ReqContext, apiCmd dtos.ImportDa
return hs.dashboardSaveErrorToApiResponse(err) return hs.dashboardSaveErrorToApiResponse(err)
} }
err = hs.LibraryPanelService.ImportDashboard(c, apiCmd.Dashboard, dashInfo.DashboardId)
if err != nil {
return response.Error(500, "Error while connecting library panels", err)
}
return response.JSON(200, dashInfo) return response.JSON(200, dashInfo)
} }

View File

@ -18,6 +18,7 @@ type Service interface {
LoadLibraryPanelsForDashboard(c *models.ReqContext, dash *models.Dashboard) error LoadLibraryPanelsForDashboard(c *models.ReqContext, dash *models.Dashboard) error
CleanLibraryPanelsForDashboard(dash *models.Dashboard) error CleanLibraryPanelsForDashboard(dash *models.Dashboard) error
ConnectLibraryPanelsForDashboard(c *models.ReqContext, dash *models.Dashboard) error ConnectLibraryPanelsForDashboard(c *models.ReqContext, dash *models.Dashboard) error
ImportDashboard(c *models.ReqContext, dashboard *simplejson.Json, importedID int64) error
} }
// LibraryPanelService is the service for the Panel Library feature. // LibraryPanelService is the service for the Panel Library feature.
@ -166,7 +167,7 @@ func (lps *LibraryPanelService) CleanLibraryPanelsForDashboard(dash *models.Dash
// ConnectLibraryPanelsForDashboard loops through all panels in dashboard JSON and connects any library panels to the dashboard. // ConnectLibraryPanelsForDashboard loops through all panels in dashboard JSON and connects any library panels to the dashboard.
func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c *models.ReqContext, dash *models.Dashboard) error { func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c *models.ReqContext, dash *models.Dashboard) error {
panels := dash.Data.Get("panels").MustArray() panels := dash.Data.Get("panels").MustArray()
var libraryPanels []string libraryPanels := make(map[string]string)
for _, panel := range panels { for _, panel := range panels {
panelAsJSON := simplejson.NewFromAny(panel) panelAsJSON := simplejson.NewFromAny(panel)
libraryPanel := panelAsJSON.Get("libraryPanel") libraryPanel := panelAsJSON.Get("libraryPanel")
@ -179,8 +180,24 @@ func (lps *LibraryPanelService) ConnectLibraryPanelsForDashboard(c *models.ReqCo
if len(uid) == 0 { if len(uid) == 0 {
return errLibraryPanelHeaderUIDMissing return errLibraryPanelHeaderUIDMissing
} }
libraryPanels = append(libraryPanels, uid) _, exists := libraryPanels[uid]
if !exists {
libraryPanels[uid] = uid
}
} }
return lps.LibraryElementService.ConnectElementsToDashboard(c, libraryPanels, dash.Id) elementUIDs := make([]string, 0, len(libraryPanels))
for libraryPanel := range libraryPanels {
elementUIDs = append(elementUIDs, libraryPanel)
}
return lps.LibraryElementService.ConnectElementsToDashboard(c, elementUIDs, dash.Id)
}
// ImportDashboard loops through all panels in dashboard JSON and connects any library panels to the dashboard.
func (lps *LibraryPanelService) ImportDashboard(c *models.ReqContext, dashboard *simplejson.Json, importedID int64) error {
dash := models.NewDashboardFromJson(dashboard)
dash.Id = importedID
return lps.ConnectLibraryPanelsForDashboard(c, dash)
} }

View File

@ -572,6 +572,106 @@ func TestConnectLibraryPanelsForDashboard(t *testing.T) {
}) })
} }
func TestImportDashboard(t *testing.T) {
scenarioWithLibraryPanel(t, "When an admin tries to import a dashboard with a library panel, it should connect the two",
func(t *testing.T, sc scenarioContext) {
importedJSON := map[string]interface{}{
"panels": []interface{}{},
}
importedDashboard := models.Dashboard{
Title: "Dummy dash that simulates an imported dash",
Data: simplejson.NewFromAny(importedJSON),
}
importedDashInDB := createDashboard(t, sc.sqlStore, sc.user, &importedDashboard, sc.folder.Id)
elements, err := sc.elementService.GetElementsForDashboard(sc.reqContext, importedDashInDB.Id)
require.NoError(t, err)
require.Len(t, elements, 0)
dashJSON := map[string]interface{}{
"title": "Testing ImportDashboard",
"panels": []interface{}{
map[string]interface{}{
"id": int64(1),
"gridPos": map[string]interface{}{
"h": 6,
"w": 6,
"x": 0,
"y": 0,
},
},
map[string]interface{}{
"id": int64(2),
"gridPos": map[string]interface{}{
"h": 6,
"w": 6,
"x": 6,
"y": 0,
},
"datasource": "${DS_GDEV-TESTDATA}",
"libraryPanel": map[string]interface{}{
"uid": sc.initialResult.Result.UID,
"name": sc.initialResult.Result.Name,
},
"title": "Text - Library Panel",
"type": "text",
},
},
}
dash := simplejson.NewFromAny(dashJSON)
err = sc.service.ImportDashboard(sc.reqContext, dash, importedDashInDB.Id)
require.NoError(t, err)
elements, err = sc.elementService.GetElementsForDashboard(sc.reqContext, importedDashInDB.Id)
require.NoError(t, err)
require.Len(t, elements, 1)
require.Equal(t, sc.initialResult.Result.UID, elements[sc.initialResult.Result.UID].UID)
})
scenarioWithLibraryPanel(t, "When an admin tries to import a dashboard with a library panel without uid, it should fail",
func(t *testing.T, sc scenarioContext) {
importedJSON := map[string]interface{}{
"panels": []interface{}{},
}
importedDashboard := models.Dashboard{
Title: "Dummy dash that simulates an imported dash",
Data: simplejson.NewFromAny(importedJSON),
}
importedDashInDB := createDashboard(t, sc.sqlStore, sc.user, &importedDashboard, sc.folder.Id)
dashJSON := map[string]interface{}{
"panels": []interface{}{
map[string]interface{}{
"id": int64(1),
"gridPos": map[string]interface{}{
"h": 6,
"w": 6,
"x": 0,
"y": 0,
},
},
map[string]interface{}{
"id": int64(2),
"gridPos": map[string]interface{}{
"h": 6,
"w": 6,
"x": 6,
"y": 0,
},
"datasource": "${DS_GDEV-TESTDATA}",
"libraryPanel": map[string]interface{}{
"name": sc.initialResult.Result.Name,
},
"title": "Text - Library Panel",
"type": "text",
},
},
}
dash := simplejson.NewFromAny(dashJSON)
err := sc.service.ImportDashboard(sc.reqContext, dash, importedDashInDB.Id)
require.EqualError(t, err, errLibraryPanelHeaderUIDMissing.Error())
})
}
type libraryPanel struct { type libraryPanel struct {
ID int64 ID int64
OrgID int64 OrgID int64