LibraryPanels: Adds Type and Description to DB (#32258)

* Refactor: adds description to getCreateCommand

* Refactor: Adds type and description fields

* Chore: Updates FrontEnd

* Update pkg/services/librarypanels/database.go

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>

* Update pkg/services/librarypanels/database.go

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>

* Chore: fixes backend linting error

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Hugo Häggmark 2021-03-24 13:43:51 +01:00 committed by GitHub
parent 05fa9d6ad9
commit 7f5487a461
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 325 additions and 198 deletions

View File

@ -15,7 +15,7 @@ import (
var (
sqlStatmentLibrayPanelDTOWithMeta = `
SELECT DISTINCT
lp.id, lp.org_id, lp.folder_id, lp.uid, lp.name, lp.model, lp.created, lp.created_by, lp.updated, lp.updated_by, lp.version
lp.id, lp.org_id, lp.folder_id, lp.uid, lp.name, lp.type, lp.description, lp.model, lp.created, lp.created_by, lp.updated, lp.updated_by, lp.version
, 0 AS can_edit
, u1.login AS created_by_name
, u1.email AS created_by_email
@ -28,13 +28,23 @@ FROM library_panel AS lp
`
)
func syncTitleWithName(libraryPanel *LibraryPanel) error {
func syncFieldsWithModel(libraryPanel *LibraryPanel) error {
var model map[string]interface{}
if err := json.Unmarshal(libraryPanel.Model, &model); err != nil {
return err
}
model["title"] = libraryPanel.Name
if model["type"] != nil {
libraryPanel.Type = model["type"].(string)
} else {
model["type"] = libraryPanel.Type
}
if model["description"] != nil {
libraryPanel.Description = model["description"].(string)
} else {
model["description"] = libraryPanel.Description
}
syncedModel, err := json.Marshal(&model)
if err != nil {
return err
@ -62,7 +72,7 @@ func (lps *LibraryPanelService) createLibraryPanel(c *models.ReqContext, cmd cre
UpdatedBy: c.SignedInUser.UserId,
}
if err := syncTitleWithName(&libraryPanel); err != nil {
if err := syncFieldsWithModel(&libraryPanel); err != nil {
return LibraryPanelDTO{}, err
}
@ -80,13 +90,15 @@ func (lps *LibraryPanelService) createLibraryPanel(c *models.ReqContext, cmd cre
})
dto := LibraryPanelDTO{
ID: libraryPanel.ID,
OrgID: libraryPanel.OrgID,
FolderID: libraryPanel.FolderID,
UID: libraryPanel.UID,
Name: libraryPanel.Name,
Model: libraryPanel.Model,
Version: libraryPanel.Version,
ID: libraryPanel.ID,
OrgID: libraryPanel.OrgID,
FolderID: libraryPanel.FolderID,
UID: libraryPanel.UID,
Name: libraryPanel.Name,
Type: libraryPanel.Type,
Description: libraryPanel.Description,
Model: libraryPanel.Model,
Version: libraryPanel.Version,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
@ -111,13 +123,13 @@ func (lps *LibraryPanelService) createLibraryPanel(c *models.ReqContext, cmd cre
// connectDashboard adds a connection between a Library Panel and a Dashboard.
func (lps *LibraryPanelService) connectDashboard(c *models.ReqContext, uid string, dashboardID int64) error {
err := lps.SQLStore.WithTransactionalDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
return lps.implConnectDashboard(session, c.SignedInUser, uid, dashboardID)
return lps.internalConnectDashboard(session, c.SignedInUser, uid, dashboardID)
})
return err
}
func (lps *LibraryPanelService) implConnectDashboard(session *sqlstore.DBSession, user *models.SignedInUser,
func (lps *LibraryPanelService) internalConnectDashboard(session *sqlstore.DBSession, user *models.SignedInUser,
uid string, dashboardID int64) error {
panel, err := getLibraryPanel(session, uid, user.OrgId)
if err != nil {
@ -127,8 +139,6 @@ func (lps *LibraryPanelService) implConnectDashboard(session *sqlstore.DBSession
return err
}
// TODO add check that dashboard exists
libraryPanelDashboard := libraryPanelDashboard{
DashboardID: dashboardID,
LibraryPanelID: panel.ID,
@ -152,7 +162,7 @@ func (lps *LibraryPanelService) connectLibraryPanelsForDashboard(c *models.ReqCo
return err
}
for _, uid := range uids {
err := lps.implConnectDashboard(session, c.SignedInUser, uid, dashboardID)
err := lps.internalConnectDashboard(session, c.SignedInUser, uid, dashboardID)
if err != nil {
return err
}
@ -343,13 +353,15 @@ func (lps *LibraryPanelService) getLibraryPanel(c *models.ReqContext, uid string
})
dto := LibraryPanelDTO{
ID: libraryPanel.ID,
OrgID: libraryPanel.OrgID,
FolderID: libraryPanel.FolderID,
UID: libraryPanel.UID,
Name: libraryPanel.Name,
Model: libraryPanel.Model,
Version: libraryPanel.Version,
ID: libraryPanel.ID,
OrgID: libraryPanel.OrgID,
FolderID: libraryPanel.FolderID,
UID: libraryPanel.UID,
Name: libraryPanel.Name,
Type: libraryPanel.Type,
Description: libraryPanel.Description,
Model: libraryPanel.Model,
Version: libraryPanel.Version,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: libraryPanel.ConnectedDashboards,
@ -416,13 +428,15 @@ func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext, perPag
retDTOs := make([]LibraryPanelDTO, 0)
for _, panel := range libraryPanels {
retDTOs = append(retDTOs, LibraryPanelDTO{
ID: panel.ID,
OrgID: panel.OrgID,
FolderID: panel.FolderID,
UID: panel.UID,
Name: panel.Name,
Model: panel.Model,
Version: panel.Version,
ID: panel.ID,
OrgID: panel.OrgID,
FolderID: panel.FolderID,
UID: panel.UID,
Name: panel.Name,
Type: panel.Type,
Description: panel.Description,
Model: panel.Model,
Version: panel.Version,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: panel.ConnectedDashboards,
@ -512,13 +526,15 @@ func (lps *LibraryPanelService) getLibraryPanelsForDashboardID(c *models.ReqCont
for _, panel := range libraryPanels {
libraryPanelMap[panel.UID] = LibraryPanelDTO{
ID: panel.ID,
OrgID: panel.OrgID,
FolderID: panel.FolderID,
UID: panel.UID,
Name: panel.Name,
Model: panel.Model,
Version: panel.Version,
ID: panel.ID,
OrgID: panel.OrgID,
FolderID: panel.FolderID,
UID: panel.UID,
Name: panel.Name,
Type: panel.Type,
Description: panel.Description,
Model: panel.Model,
Version: panel.Version,
Meta: LibraryPanelDTOMeta{
CanEdit: panel.CanEdit,
ConnectedDashboards: panel.ConnectedDashboards,
@ -581,17 +597,19 @@ func (lps *LibraryPanelService) patchLibraryPanel(c *models.ReqContext, cmd patc
}
var libraryPanel = LibraryPanel{
ID: panelInDB.ID,
OrgID: c.SignedInUser.OrgId,
FolderID: cmd.FolderID,
UID: uid,
Name: cmd.Name,
Model: cmd.Model,
Version: panelInDB.Version + 1,
Created: panelInDB.Created,
CreatedBy: panelInDB.CreatedBy,
Updated: time.Now(),
UpdatedBy: c.SignedInUser.UserId,
ID: panelInDB.ID,
OrgID: c.SignedInUser.OrgId,
FolderID: cmd.FolderID,
UID: uid,
Name: cmd.Name,
Type: panelInDB.Type,
Description: panelInDB.Description,
Model: cmd.Model,
Version: panelInDB.Version + 1,
Created: panelInDB.Created,
CreatedBy: panelInDB.CreatedBy,
Updated: time.Now(),
UpdatedBy: c.SignedInUser.UserId,
}
if cmd.Name == "" {
@ -603,7 +621,7 @@ func (lps *LibraryPanelService) patchLibraryPanel(c *models.ReqContext, cmd patc
if err := lps.handleFolderIDPatches(&libraryPanel, panelInDB.FolderID, cmd.FolderID, c.SignedInUser); err != nil {
return err
}
if err := syncTitleWithName(&libraryPanel); err != nil {
if err := syncFieldsWithModel(&libraryPanel); err != nil {
return err
}
if rowsAffected, err := session.ID(panelInDB.ID).Update(&libraryPanel); err != nil {
@ -616,13 +634,15 @@ func (lps *LibraryPanelService) patchLibraryPanel(c *models.ReqContext, cmd patc
}
dto = LibraryPanelDTO{
ID: libraryPanel.ID,
OrgID: libraryPanel.OrgID,
FolderID: libraryPanel.FolderID,
UID: libraryPanel.UID,
Name: libraryPanel.Name,
Model: libraryPanel.Model,
Version: libraryPanel.Version,
ID: libraryPanel.ID,
OrgID: libraryPanel.OrgID,
FolderID: libraryPanel.FolderID,
UID: libraryPanel.UID,
Name: libraryPanel.Name,
Type: libraryPanel.Type,
Description: libraryPanel.Description,
Model: libraryPanel.Model,
Version: libraryPanel.Version,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: panelInDB.ConnectedDashboards,

View File

@ -102,9 +102,11 @@ func (lps *LibraryPanelService) LoadLibraryPanelsForDashboard(c *models.ReqConte
elem.Set("gridPos", panelAsJSON.Get("gridPos").MustMap())
elem.Set("id", panelAsJSON.Get("id").MustInt64())
elem.Set("libraryPanel", map[string]interface{}{
"uid": libraryPanelInDB.UID,
"name": libraryPanelInDB.Name,
"version": libraryPanelInDB.Version,
"uid": libraryPanelInDB.UID,
"name": libraryPanelInDB.Name,
"type": libraryPanelInDB.Type,
"description": libraryPanelInDB.Description,
"version": libraryPanelInDB.Version,
"meta": map[string]interface{}{
"canEdit": libraryPanelInDB.Meta.CanEdit,
"connectedDashboards": libraryPanelInDB.Meta.ConnectedDashboards,
@ -242,6 +244,8 @@ func (lps *LibraryPanelService) AddMigration(mg *migrator.Migrator) {
{Name: "folder_id", Type: migrator.DB_BigInt, Nullable: false},
{Name: "uid", Type: migrator.DB_NVarchar, Length: 40, Nullable: false},
{Name: "name", Type: migrator.DB_NVarchar, Length: 255, Nullable: false},
{Name: "type", Type: migrator.DB_NVarchar, Length: 40, Nullable: false},
{Name: "description", Type: migrator.DB_NVarchar, Length: 255, Nullable: false},
{Name: "model", Type: migrator.DB_Text, Nullable: false},
{Name: "created", Type: migrator.DB_DateTime, Nullable: false},
{Name: "created_by", Type: migrator.DB_BigInt, Nullable: false},

View File

@ -19,16 +19,19 @@ func TestCreateLibraryPanel(t *testing.T) {
func(t *testing.T, sc scenarioContext) {
var expected = libraryPanelResult{
Result: libraryPanel{
ID: 1,
OrgID: 1,
FolderID: 1,
UID: sc.initialResult.Result.UID,
Name: "Text - Library Panel",
ID: 1,
OrgID: 1,
FolderID: 1,
UID: sc.initialResult.Result.UID,
Name: "Text - Library Panel",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
@ -61,16 +64,19 @@ func TestCreateLibraryPanel(t *testing.T) {
var result = validateAndUnMarshalResponse(t, resp)
var expected = libraryPanelResult{
Result: libraryPanel{
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.UID,
Name: "Library Panel Name",
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.UID,
Name: "Library Panel Name",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Library Panel Name",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Library Panel Name",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{

View File

@ -51,16 +51,19 @@ func TestGetAllLibraryPanels(t *testing.T) {
PerPage: 100,
LibraryPanels: []libraryPanel{
{
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel",
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
@ -81,16 +84,19 @@ func TestGetAllLibraryPanels(t *testing.T) {
},
},
{
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[1].UID,
Name: "Text - Library Panel2",
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[1].UID,
Name: "Text - Library Panel2",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
@ -140,16 +146,19 @@ func TestGetAllLibraryPanels(t *testing.T) {
PerPage: 100,
LibraryPanels: []libraryPanel{
{
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel2",
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel2",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
@ -199,16 +208,19 @@ func TestGetAllLibraryPanels(t *testing.T) {
PerPage: 1,
LibraryPanels: []libraryPanel{
{
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel",
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
@ -259,16 +271,19 @@ func TestGetAllLibraryPanels(t *testing.T) {
PerPage: 1,
LibraryPanels: []libraryPanel{
{
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel2",
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel2",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
@ -320,16 +335,19 @@ func TestGetAllLibraryPanels(t *testing.T) {
PerPage: 1,
LibraryPanels: []libraryPanel{
{
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel2",
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Text - Library Panel2",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{

View File

@ -24,16 +24,19 @@ func TestGetLibraryPanel(t *testing.T) {
var result = validateAndUnMarshalResponse(t, resp)
var expected = libraryPanelResult{
Result: libraryPanel{
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.UID,
Name: "Text - Library Panel",
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.UID,
Name: "Text - Library Panel",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{

View File

@ -32,9 +32,10 @@ func TestPatchLibraryPanel(t *testing.T) {
Model: []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"description": "An updated description",
"id": 1,
"title": "Model - New name",
"type": "text"
"type": "graph"
}
`),
Version: 1,
@ -45,16 +46,19 @@ func TestPatchLibraryPanel(t *testing.T) {
var result = validateAndUnMarshalResponse(t, resp)
var expected = libraryPanelResult{
Result: libraryPanel{
ID: 1,
OrgID: 1,
FolderID: newFolder.Id,
UID: sc.initialResult.Result.UID,
Name: "Panel - New name",
ID: 1,
OrgID: 1,
FolderID: newFolder.Id,
UID: sc.initialResult.Result.UID,
Name: "Panel - New name",
Type: "graph",
Description: "An updated description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Panel - New name",
"type": "text",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "An updated description",
"id": float64(1),
"title": "Panel - New name",
"type": "graph",
},
Version: 2,
Meta: LibraryPanelDTOMeta{
@ -64,8 +68,8 @@ func TestPatchLibraryPanel(t *testing.T) {
Updated: result.Result.Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: "user_in_db",
AvatarUrl: "/avatar/402d08de060496d6b6874495fe20f5ad",
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
@ -92,8 +96,8 @@ func TestPatchLibraryPanel(t *testing.T) {
require.Equal(t, 200, resp.Status())
var result = validateAndUnMarshalResponse(t, resp)
sc.initialResult.Result.FolderID = newFolder.Id
sc.initialResult.Result.Meta.CreatedBy.Name = "user_in_db"
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
sc.initialResult.Result.Meta.CreatedBy.Name = UserInDbName
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
sc.initialResult.Result.Version = 2
if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
@ -111,8 +115,8 @@ func TestPatchLibraryPanel(t *testing.T) {
resp := sc.service.patchHandler(sc.reqContext, cmd)
var result = validateAndUnMarshalResponse(t, resp)
sc.initialResult.Result.Name = "New Name"
sc.initialResult.Result.Meta.CreatedBy.Name = "user_in_db"
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
sc.initialResult.Result.Meta.CreatedBy.Name = UserInDbName
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
sc.initialResult.Result.Model["title"] = "New Name"
sc.initialResult.Result.Version = 2
if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" {
@ -120,22 +124,76 @@ func TestPatchLibraryPanel(t *testing.T) {
}
})
scenarioWithLibraryPanel(t, "When an admin tries to patch a library panel with model only, it should change model successfully and return correct result",
scenarioWithLibraryPanel(t, "When an admin tries to patch a library panel with model only, it should change model successfully, sync name, type and description fields and return correct result",
func(t *testing.T, sc scenarioContext) {
cmd := patchLibraryPanelCommand{
FolderID: -1,
Model: []byte(`{ "title": "New Model Title", "name": "New Model Name" }`),
Model: []byte(`{ "title": "New Model Title", "name": "New Model Name", "type":"graph", "description": "New description" }`),
Version: 1,
}
sc.reqContext.ReplaceAllParams(map[string]string{":uid": sc.initialResult.Result.UID})
resp := sc.service.patchHandler(sc.reqContext, cmd)
var result = validateAndUnMarshalResponse(t, resp)
sc.initialResult.Result.Type = "graph"
sc.initialResult.Result.Description = "New description"
sc.initialResult.Result.Model = map[string]interface{}{
"title": "Text - Library Panel",
"name": "New Model Name",
"title": "Text - Library Panel",
"name": "New Model Name",
"type": "graph",
"description": "New description",
}
sc.initialResult.Result.Meta.CreatedBy.Name = "user_in_db"
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
sc.initialResult.Result.Meta.CreatedBy.Name = UserInDbName
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
sc.initialResult.Result.Version = 2
if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
scenarioWithLibraryPanel(t, "When an admin tries to patch a library panel with model.description only, it should change model successfully, sync name, type and description fields and return correct result",
func(t *testing.T, sc scenarioContext) {
cmd := patchLibraryPanelCommand{
FolderID: -1,
Model: []byte(`{ "description": "New description" }`),
Version: 1,
}
sc.reqContext.ReplaceAllParams(map[string]string{":uid": sc.initialResult.Result.UID})
resp := sc.service.patchHandler(sc.reqContext, cmd)
var result = validateAndUnMarshalResponse(t, resp)
sc.initialResult.Result.Type = "text"
sc.initialResult.Result.Description = "New description"
sc.initialResult.Result.Model = map[string]interface{}{
"title": "Text - Library Panel",
"type": "text",
"description": "New description",
}
sc.initialResult.Result.Meta.CreatedBy.Name = UserInDbName
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
sc.initialResult.Result.Version = 2
if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
scenarioWithLibraryPanel(t, "When an admin tries to patch a library panel with model.type only, it should change model successfully, sync name, type and description fields and return correct result",
func(t *testing.T, sc scenarioContext) {
cmd := patchLibraryPanelCommand{
FolderID: -1,
Model: []byte(`{ "type": "graph" }`),
Version: 1,
}
sc.reqContext.ReplaceAllParams(map[string]string{":uid": sc.initialResult.Result.UID})
resp := sc.service.patchHandler(sc.reqContext, cmd)
var result = validateAndUnMarshalResponse(t, resp)
sc.initialResult.Result.Type = "graph"
sc.initialResult.Result.Description = "A description"
sc.initialResult.Result.Model = map[string]interface{}{
"title": "Text - Library Panel",
"type": "graph",
"description": "A description",
}
sc.initialResult.Result.Meta.CreatedBy.Name = UserInDbName
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
sc.initialResult.Result.Version = 2
if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
@ -150,8 +208,8 @@ func TestPatchLibraryPanel(t *testing.T) {
resp := sc.service.patchHandler(sc.reqContext, cmd)
var result = validateAndUnMarshalResponse(t, resp)
sc.initialResult.Result.Meta.UpdatedBy.ID = int64(2)
sc.initialResult.Result.Meta.CreatedBy.Name = "user_in_db"
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = "/avatar/402d08de060496d6b6874495fe20f5ad"
sc.initialResult.Result.Meta.CreatedBy.Name = UserInDbName
sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = UserInDbAvatar
sc.initialResult.Result.Version = 2
if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)

View File

@ -84,11 +84,14 @@ func TestLoadLibraryPanelsForDashboard(t *testing.T) {
"x": 6,
"y": 0,
},
"datasource": "${DS_GDEV-TESTDATA}",
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"libraryPanel": map[string]interface{}{
"uid": sc.initialResult.Result.UID,
"name": sc.initialResult.Result.Name,
"version": sc.initialResult.Result.Version,
"uid": sc.initialResult.Result.UID,
"name": sc.initialResult.Result.Name,
"type": sc.initialResult.Result.Type,
"description": sc.initialResult.Result.Description,
"version": sc.initialResult.Result.Version,
"meta": map[string]interface{}{
"canEdit": false,
"connectedDashboards": int64(1),
@ -664,14 +667,16 @@ func TestDeleteLibraryPanelsInFolder(t *testing.T) {
}
type libraryPanel struct {
ID int64 `json:"id"`
OrgID int64 `json:"orgId"`
FolderID int64 `json:"folderId"`
UID string `json:"uid"`
Name string `json:"name"`
Model map[string]interface{} `json:"model"`
Version int64 `json:"version"`
Meta LibraryPanelDTOMeta `json:"meta"`
ID int64 `json:"id"`
OrgID int64 `json:"orgId"`
FolderID int64 `json:"folderId"`
UID string `json:"uid"`
Name string `json:"name"`
Type string
Description string
Model map[string]interface{} `json:"model"`
Version int64 `json:"version"`
Meta LibraryPanelDTOMeta `json:"meta"`
}
type libraryPanelResult struct {
@ -723,7 +728,8 @@ func getCreateCommand(folderID int64, name string) createLibraryPanelCommand {
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Text - Library Panel",
"type": "text"
"type": "text",
"description": "A description"
}
`),
}

View File

@ -8,13 +8,15 @@ import (
// LibraryPanel is the model for library panel definitions.
type LibraryPanel struct {
ID int64 `xorm:"pk autoincr 'id'"`
OrgID int64 `xorm:"org_id"`
FolderID int64 `xorm:"folder_id"`
UID string `xorm:"uid"`
Name string
Model json.RawMessage
Version int64
ID int64 `xorm:"pk autoincr 'id'"`
OrgID int64 `xorm:"org_id"`
FolderID int64 `xorm:"folder_id"`
UID string `xorm:"uid"`
Name string
Type string
Description string
Model json.RawMessage
Version int64
Created time.Time
Updated time.Time
@ -25,13 +27,15 @@ type LibraryPanel struct {
// LibraryPanelWithMeta is the model used to retrieve library panels with additional meta information.
type LibraryPanelWithMeta struct {
ID int64 `xorm:"pk autoincr 'id'"`
OrgID int64 `xorm:"org_id"`
FolderID int64 `xorm:"folder_id"`
UID string `xorm:"uid"`
Name string
Model json.RawMessage
Version int64
ID int64 `xorm:"pk autoincr 'id'"`
OrgID int64 `xorm:"org_id"`
FolderID int64 `xorm:"folder_id"`
UID string `xorm:"uid"`
Name string
Type string
Description string
Model json.RawMessage
Version int64
Created time.Time
Updated time.Time
@ -48,14 +52,16 @@ type LibraryPanelWithMeta struct {
// LibraryPanelDTO is the frontend DTO for library panels.
type LibraryPanelDTO struct {
ID int64 `json:"id"`
OrgID int64 `json:"orgId"`
FolderID int64 `json:"folderId"`
UID string `json:"uid"`
Name string `json:"name"`
Model json.RawMessage `json:"model"`
Version int64 `json:"version"`
Meta LibraryPanelDTOMeta `json:"meta"`
ID int64 `json:"id"`
OrgID int64 `json:"orgId"`
FolderID int64 `json:"folderId"`
UID string `json:"uid"`
Name string `json:"name"`
Type string `json:"type"`
Description string `json:"description"`
Model json.RawMessage `json:"model"`
Version int64 `json:"version"`
Meta LibraryPanelDTOMeta `json:"meta"`
}
// LibraryPanelSearchResult is the search result for library panels.

View File

@ -130,6 +130,8 @@ function mockLibraryPanel({
updatedBy: { id: 2, name: 'User Y', avatarUrl: '/avatar/xyz' },
},
version = 1,
description = 'a description',
type = 'text',
}: Partial<LibraryPanelDTO> = {}): LibraryPanelDTO {
return {
uid,
@ -140,5 +142,7 @@ function mockLibraryPanel({
model,
version,
meta,
description,
type,
};
}

View File

@ -15,6 +15,8 @@ export interface LibraryPanelDTO {
folderId: number;
uid: string;
name: string;
type: string;
description: string;
model: any;
version: number;
meta: LibraryPanelDTOMeta;