LibraryPanels: Adds panel type filter and sorting (#33425)

* Wip: inital commit

* Chore: updating api

* Refactor: adds description search and sorting

* Refactor: adds panel filtering

* Refactor: limits the height of select

* Tests: updates snapshot

* Refactor: small UI improvements
This commit is contained in:
Hugo Häggmark
2021-04-28 09:18:13 +02:00
committed by GitHub
parent eaf7decf5a
commit 20ee0e9601
16 changed files with 756 additions and 119 deletions
+9 -1
View File
@@ -81,7 +81,15 @@ func (lps *LibraryPanelService) getHandler(c *models.ReqContext) response.Respon
// getAllHandler handles GET /api/library-panels/.
func (lps *LibraryPanelService) getAllHandler(c *models.ReqContext) response.Response {
libraryPanels, err := lps.getAllLibraryPanels(c, c.QueryInt("perPage"), c.QueryInt("page"), c.Query("name"), c.Query("excludeUid"))
query := searchLibraryPanelsQuery{
perPage: c.QueryInt("perPage"),
page: c.QueryInt("page"),
searchString: c.Query("searchString"),
sortDirection: c.Query("sortDirection"),
panelFilter: c.Query("panelFilter"),
excludeUID: c.Query("excludeUid"),
}
libraryPanels, err := lps.getAllLibraryPanels(c, query)
if err != nil {
return toLibraryPanelError(err, "Failed to get library panels")
}
+65 -23
View File
@@ -1,11 +1,14 @@
package librarypanels
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
@@ -15,7 +18,7 @@ import (
var (
sqlStatmentLibrayPanelDTOWithMeta = `
SELECT DISTINCT
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
lp.name, lp.id, lp.org_id, lp.folder_id, lp.uid, 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
@@ -384,42 +387,71 @@ func (lps *LibraryPanelService) getLibraryPanel(c *models.ReqContext, uid string
}
// getAllLibraryPanels gets all library panels.
func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext, perPage int, page int, name string, excludeUID string) (LibraryPanelSearchResult, error) {
func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext, query searchLibraryPanelsQuery) (LibraryPanelSearchResult, error) {
libraryPanels := make([]LibraryPanelWithMeta, 0)
result := LibraryPanelSearchResult{}
if perPage <= 0 {
perPage = 100
if query.perPage <= 0 {
query.perPage = 100
}
if page <= 0 {
page = 1
if query.page <= 0 {
query.page = 1
}
var panelFilter []string
if len(strings.TrimSpace(query.panelFilter)) > 0 {
panelFilter = strings.Split(query.panelFilter, ",")
}
err := lps.SQLStore.WithDbSession(c.Context.Req.Context(), func(session *sqlstore.DBSession) error {
builder := sqlstore.SQLBuilder{}
builder.Write(sqlStatmentLibrayPanelDTOWithMeta)
builder.Write(` WHERE lp.org_id=? AND lp.folder_id=0`, c.SignedInUser.OrgId)
if len(strings.TrimSpace(name)) > 0 {
builder.Write(" AND lp.name "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+name+"%")
if len(strings.TrimSpace(query.searchString)) > 0 {
builder.Write(" AND lp.name "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+query.searchString+"%")
builder.Write(" OR lp.description "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+query.searchString+"%")
}
if len(strings.TrimSpace(excludeUID)) > 0 {
builder.Write(" AND lp.uid <> ?", excludeUID)
if len(strings.TrimSpace(query.excludeUID)) > 0 {
builder.Write(" AND lp.uid <> ?", query.excludeUID)
}
if len(panelFilter) > 0 {
var sql bytes.Buffer
params := make([]interface{}, 0)
sql.WriteString(` AND lp.type IN (?` + strings.Repeat(",?", len(panelFilter)-1) + ")")
for _, v := range panelFilter {
params = append(params, v)
}
builder.Write(sql.String(), params...)
}
builder.Write(" UNION ")
builder.Write(sqlStatmentLibrayPanelDTOWithMeta)
builder.Write(" INNER JOIN dashboard AS dashboard on lp.folder_id = dashboard.id AND lp.folder_id<>0")
builder.Write(` WHERE lp.org_id=?`, c.SignedInUser.OrgId)
if len(strings.TrimSpace(name)) > 0 {
builder.Write(" AND lp.name "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+name+"%")
if len(strings.TrimSpace(query.searchString)) > 0 {
builder.Write(" AND lp.name "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+query.searchString+"%")
builder.Write(" OR lp.description "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+query.searchString+"%")
}
if len(strings.TrimSpace(excludeUID)) > 0 {
builder.Write(" AND lp.uid <> ?", excludeUID)
if len(strings.TrimSpace(query.excludeUID)) > 0 {
builder.Write(" AND lp.uid <> ?", query.excludeUID)
}
if len(panelFilter) > 0 {
var sql bytes.Buffer
params := make([]interface{}, 0)
sql.WriteString(` AND lp.type IN (?` + strings.Repeat(",?", len(panelFilter)-1) + ")")
for _, v := range panelFilter {
params = append(params, v)
}
builder.Write(sql.String(), params...)
}
if c.SignedInUser.OrgRole != models.ROLE_ADMIN {
builder.WriteDashboardPermissionFilter(c.SignedInUser, models.PERMISSION_VIEW)
}
if perPage != 0 {
offset := perPage * (page - 1)
builder.Write(lps.SQLStore.Dialect.LimitOffset(int64(perPage), int64(offset)))
if query.sortDirection == search.SortAlphaDesc.Name {
builder.Write(" ORDER BY 1 DESC")
} else {
builder.Write(" ORDER BY 1 ASC")
}
if query.perPage != 0 {
offset := query.perPage * (query.page - 1)
builder.Write(lps.SQLStore.Dialect.LimitOffset(int64(query.perPage), int64(offset)))
}
if err := session.SQL(builder.GetSQLString(), builder.GetParams()...).Find(&libraryPanels); err != nil {
return err
@@ -460,11 +492,21 @@ func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext, perPag
countBuilder := sqlstore.SQLBuilder{}
countBuilder.Write("SELECT * FROM library_panel")
countBuilder.Write(` WHERE org_id=?`, c.SignedInUser.OrgId)
if len(strings.TrimSpace(name)) > 0 {
countBuilder.Write(" AND name "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+name+"%")
if len(strings.TrimSpace(query.searchString)) > 0 {
countBuilder.Write(" AND name "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+query.searchString+"%")
countBuilder.Write(" OR description "+lps.SQLStore.Dialect.LikeStr()+" ?", "%"+query.searchString+"%")
}
if len(strings.TrimSpace(excludeUID)) > 0 {
countBuilder.Write(" AND uid <> ?", excludeUID)
if len(strings.TrimSpace(query.excludeUID)) > 0 {
countBuilder.Write(" AND uid <> ?", query.excludeUID)
}
if len(panelFilter) > 0 {
var sql bytes.Buffer
params := make([]interface{}, 0)
sql.WriteString(` AND type IN (?` + strings.Repeat(",?", len(panelFilter)-1) + ")")
for _, v := range panelFilter {
params = append(params, v)
}
countBuilder.Write(sql.String(), params...)
}
if err := session.SQL(countBuilder.GetSQLString(), countBuilder.GetParams()...).Find(&panels); err != nil {
return err
@@ -473,8 +515,8 @@ func (lps *LibraryPanelService) getAllLibraryPanels(c *models.ReqContext, perPag
result = LibraryPanelSearchResult{
TotalCount: int64(len(panels)),
LibraryPanels: retDTOs,
Page: page,
PerPage: perPage,
Page: query.page,
PerPage: query.perPage,
}
return nil
@@ -4,6 +4,8 @@ import (
"encoding/json"
"testing"
"github.com/grafana/grafana/pkg/services/search"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
@@ -124,6 +126,252 @@ func TestGetAllLibraryPanels(t *testing.T) {
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and sort desc is set, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommand(sc.folder.Id, "Text - Library Panel2")
resp := sc.service.createHandler(sc.reqContext, command)
require.Equal(t, 200, resp.Status())
err := sc.reqContext.Req.ParseForm()
require.NoError(t, err)
sc.reqContext.Req.Form.Add("sortDirection", search.SortAlphaDesc.Name)
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
var result libraryPanelsSearch
err = json.Unmarshal(resp.Body(), &result)
require.NoError(t, err)
var expected = libraryPanelsSearch{
Result: libraryPanelsSearchResult{
TotalCount: 2,
Page: 1,
PerPage: 100,
LibraryPanels: []libraryPanel{
{
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}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel2",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
Created: result.Result.LibraryPanels[0].Meta.Created,
Updated: result.Result.LibraryPanels[0].Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
},
},
{
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[1].UID,
Name: "Text - Library Panel",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
Created: result.Result.LibraryPanels[1].Meta.Created,
Updated: result.Result.LibraryPanels[1].Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
},
},
},
},
}
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and panelFilter is set to existing types, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommandWithModel(sc.folder.Id, "Gauge - Library Panel", []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Gauge - Library Panel",
"type": "gauge",
"description": "Gauge description"
}
`))
resp := sc.service.createHandler(sc.reqContext, command)
require.Equal(t, 200, resp.Status())
command = getCreateCommandWithModel(sc.folder.Id, "BarGauge - Library Panel", []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "BarGauge - Library Panel",
"type": "bargauge",
"description": "BarGauge description"
}
`))
resp = sc.service.createHandler(sc.reqContext, command)
require.Equal(t, 200, resp.Status())
err := sc.reqContext.Req.ParseForm()
require.NoError(t, err)
sc.reqContext.Req.Form.Add("panelFilter", "bargauge,gauge")
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
var result libraryPanelsSearch
err = json.Unmarshal(resp.Body(), &result)
require.NoError(t, err)
var expected = libraryPanelsSearch{
Result: libraryPanelsSearchResult{
TotalCount: 2,
Page: 1,
PerPage: 100,
LibraryPanels: []libraryPanel{
{
ID: 3,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "BarGauge - Library Panel",
Type: "bargauge",
Description: "BarGauge description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"description": "BarGauge description",
"id": float64(1),
"title": "BarGauge - Library Panel",
"type": "bargauge",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
Created: result.Result.LibraryPanels[0].Meta.Created,
Updated: result.Result.LibraryPanels[0].Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
},
},
{
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[1].UID,
Name: "Gauge - Library Panel",
Type: "gauge",
Description: "Gauge description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"id": float64(1),
"title": "Gauge - Library Panel",
"type": "gauge",
"description": "Gauge description",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
Created: result.Result.LibraryPanels[1].Meta.Created,
Updated: result.Result.LibraryPanels[1].Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
},
},
},
},
}
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and panelFilter is set to non existing type, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommandWithModel(sc.folder.Id, "Gauge - Library Panel", []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Gauge - Library Panel",
"type": "gauge",
"description": "Gauge description"
}
`))
resp := sc.service.createHandler(sc.reqContext, command)
require.Equal(t, 200, resp.Status())
err := sc.reqContext.Req.ParseForm()
require.NoError(t, err)
sc.reqContext.Req.Form.Add("panelFilter", "unknown1,unknown2")
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
var result libraryPanelsSearch
err = json.Unmarshal(resp.Body(), &result)
require.NoError(t, err)
var expected = libraryPanelsSearch{
Result: libraryPanelsSearchResult{
TotalCount: 0,
Page: 1,
PerPage: 100,
LibraryPanels: []libraryPanel{},
},
}
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and excludeUID is set, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommand(sc.folder.Id, "Text - Library Panel2")
@@ -311,7 +559,182 @@ func TestGetAllLibraryPanels(t *testing.T) {
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and perPage is 1 and page is 1 and name is panel2, it should succeed and the result should be correct",
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and searchString exists in the description, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommandWithModel(sc.folder.Id, "Text - Library Panel2", []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Text - Library Panel",
"type": "text",
"description": "Some other d e s c r i p t i o n"
}
`))
resp := sc.service.createHandler(sc.reqContext, command)
require.Equal(t, 200, resp.Status())
err := sc.reqContext.Req.ParseForm()
require.NoError(t, err)
sc.reqContext.Req.Form.Add("perPage", "1")
sc.reqContext.Req.Form.Add("page", "1")
sc.reqContext.Req.Form.Add("searchString", "description")
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
var result libraryPanelsSearch
err = json.Unmarshal(resp.Body(), &result)
require.NoError(t, err)
var expected = libraryPanelsSearch{
Result: libraryPanelsSearchResult{
TotalCount: 1,
Page: 1,
PerPage: 1,
LibraryPanels: []libraryPanel{
{
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}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
Created: result.Result.LibraryPanels[0].Meta.Created,
Updated: result.Result.LibraryPanels[0].Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
},
},
},
},
}
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and searchString exists in both name and description, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommandWithModel(sc.folder.Id, "Some Other", []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
"title": "Text - Library Panel",
"type": "text",
"description": "A Library Panel"
}
`))
resp := sc.service.createHandler(sc.reqContext, command)
require.Equal(t, 200, resp.Status())
err := sc.reqContext.Req.ParseForm()
require.NoError(t, err)
sc.reqContext.Req.Form.Add("searchString", "Library Panel")
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
var result libraryPanelsSearch
err = json.Unmarshal(resp.Body(), &result)
require.NoError(t, err)
var expected = libraryPanelsSearch{
Result: libraryPanelsSearchResult{
TotalCount: 2,
Page: 1,
PerPage: 100,
LibraryPanels: []libraryPanel{
{
ID: 2,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[0].UID,
Name: "Some Other",
Type: "text",
Description: "A Library Panel",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A Library Panel",
"id": float64(1),
"title": "Some Other",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
Created: result.Result.LibraryPanels[0].Meta.Created,
Updated: result.Result.LibraryPanels[0].Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
},
},
{
ID: 1,
OrgID: 1,
FolderID: 1,
UID: result.Result.LibraryPanels[1].UID,
Name: "Text - Library Panel",
Type: "text",
Description: "A description",
Model: map[string]interface{}{
"datasource": "${DS_GDEV-TESTDATA}",
"description": "A description",
"id": float64(1),
"title": "Text - Library Panel",
"type": "text",
},
Version: 1,
Meta: LibraryPanelDTOMeta{
CanEdit: true,
ConnectedDashboards: 0,
Created: result.Result.LibraryPanels[1].Meta.Created,
Updated: result.Result.LibraryPanels[1].Meta.Updated,
CreatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
UpdatedBy: LibraryPanelDTOMetaUser{
ID: 1,
Name: UserInDbName,
AvatarUrl: UserInDbAvatar,
},
},
},
},
},
}
if diff := cmp.Diff(expected, result, getCompareOptions()...); diff != "" {
t.Fatalf("Result mismatch (-want +got):\n%s", diff)
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and perPage is 1 and page is 1 and searchString is panel2, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommand(sc.folder.Id, "Text - Library Panel2")
resp := sc.service.createHandler(sc.reqContext, command)
@@ -321,7 +744,7 @@ func TestGetAllLibraryPanels(t *testing.T) {
require.NoError(t, err)
sc.reqContext.Req.Form.Add("perPage", "1")
sc.reqContext.Req.Form.Add("page", "1")
sc.reqContext.Req.Form.Add("name", "panel2")
sc.reqContext.Req.Form.Add("searchString", "panel2")
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
@@ -375,7 +798,7 @@ func TestGetAllLibraryPanels(t *testing.T) {
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and perPage is 1 and page is 3 and name is panel, it should succeed and the result should be correct",
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and perPage is 1 and page is 3 and searchString is panel, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommand(sc.folder.Id, "Text - Library Panel2")
resp := sc.service.createHandler(sc.reqContext, command)
@@ -385,7 +808,7 @@ func TestGetAllLibraryPanels(t *testing.T) {
require.NoError(t, err)
sc.reqContext.Req.Form.Add("perPage", "1")
sc.reqContext.Req.Form.Add("page", "3")
sc.reqContext.Req.Form.Add("name", "panel")
sc.reqContext.Req.Form.Add("searchString", "panel")
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
@@ -405,7 +828,7 @@ func TestGetAllLibraryPanels(t *testing.T) {
}
})
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and perPage is 1 and page is 3 and name does not exist, it should succeed and the result should be correct",
scenarioWithLibraryPanel(t, "When an admin tries to get all library panels and two exist and perPage is 1 and page is 3 and searchString does not exist, it should succeed and the result should be correct",
func(t *testing.T, sc scenarioContext) {
command := getCreateCommand(sc.folder.Id, "Text - Library Panel2")
resp := sc.service.createHandler(sc.reqContext, command)
@@ -415,7 +838,7 @@ func TestGetAllLibraryPanels(t *testing.T) {
require.NoError(t, err)
sc.reqContext.Req.Form.Add("perPage", "1")
sc.reqContext.Req.Form.Add("page", "3")
sc.reqContext.Req.Form.Add("name", "monkey")
sc.reqContext.Req.Form.Add("searchString", "monkey")
resp = sc.service.getAllHandler(sc.reqContext)
require.Equal(t, 200, resp.Status())
@@ -720,10 +720,7 @@ func overrideLibraryPanelServiceInRegistry(cfg *setting.Cfg) LibraryPanelService
}
func getCreateCommand(folderID int64, name string) createLibraryPanelCommand {
command := createLibraryPanelCommand{
FolderID: folderID,
Name: name,
Model: []byte(`
command := getCreateCommandWithModel(folderID, name, []byte(`
{
"datasource": "${DS_GDEV-TESTDATA}",
"id": 1,
@@ -731,7 +728,16 @@ func getCreateCommand(folderID int64, name string) createLibraryPanelCommand {
"type": "text",
"description": "A description"
}
`),
`))
return command
}
func getCreateCommandWithModel(folderID int64, name string, model []byte) createLibraryPanelCommand {
command := createLibraryPanelCommand{
FolderID: folderID,
Name: name,
Model: model,
}
return command
+10
View File
@@ -137,3 +137,13 @@ type patchLibraryPanelCommand struct {
Model json.RawMessage `json:"model"`
Version int64 `json:"version" binding:"Required"`
}
// searchLibraryPanelsQuery is the query used for searching for LibraryPanels
type searchLibraryPanelsQuery struct {
perPage int
page int
searchString string
sortDirection string
panelFilter string
excludeUID string
}
+2 -2
View File
@@ -60,8 +60,8 @@ type SearchService struct {
func (s *SearchService) Init() error {
s.Bus.AddHandler(s.searchHandler)
s.sortOptions = map[string]SortOption{
sortAlphaAsc.Name: sortAlphaAsc,
sortAlphaDesc.Name: sortAlphaDesc,
SortAlphaAsc.Name: SortAlphaAsc,
SortAlphaDesc.Name: SortAlphaDesc,
}
return nil
+2 -2
View File
@@ -7,7 +7,7 @@ import (
)
var (
sortAlphaAsc = SortOption{
SortAlphaAsc = SortOption{
Name: "alpha-asc",
DisplayName: "Alphabetically (A–Z)",
Description: "Sort results in an alphabetically ascending order",
@@ -16,7 +16,7 @@ var (
searchstore.TitleSorter{},
},
}
sortAlphaDesc = SortOption{
SortAlphaDesc = SortOption{
Name: "alpha-desc",
DisplayName: "Alphabetically (Z–A)",
Description: "Sort results in an alphabetically descending order",