mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Search: Fix empty folder details for nested folder items (#76504)
* Introduce dashboard.folder_uid column * Add data migration * Search: Fix empty folder details for nested folders * Set `dashboard.folder_uid` and update tests * Add unique index * lint Ignore cyclomatic complexity of func `(*DashboardServiceImpl).BuildSaveDashboardCommand * Fix search by folder UID
This commit is contained in:
committed by
GitHub
parent
442e533803
commit
03a626f1d6
@@ -1,6 +1,7 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
dashboardFolderMigrations "github.com/grafana/grafana/pkg/services/dashboards/database/migrations"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrations/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrations/anonservice"
|
||||
@@ -103,6 +104,8 @@ func (*OSSMigrations) AddMigration(mg *Migrator) {
|
||||
|
||||
ualert.MigrationServiceMigration(mg)
|
||||
ualert.CreatedFoldersMigration(mg)
|
||||
|
||||
dashboardFolderMigrations.AddDashboardFolderMigrations(mg)
|
||||
}
|
||||
|
||||
func addStarMigrations(mg *Migrator) {
|
||||
|
||||
@@ -815,8 +815,9 @@ func setupNestedTest(t *testing.T, usr *user.SignedInUser, perms []accesscontrol
|
||||
|
||||
// create dashboard under parent folder
|
||||
_, err = dashStore.SaveDashboard(context.Background(), dashboards.SaveDashboardCommand{
|
||||
OrgID: orgID,
|
||||
FolderID: parent.ID,
|
||||
OrgID: orgID,
|
||||
FolderID: parent.ID,
|
||||
FolderUID: parent.UID,
|
||||
Dashboard: simplejson.NewFromAny(map[string]any{
|
||||
"title": "dashboard under parent folder",
|
||||
}),
|
||||
@@ -825,8 +826,9 @@ func setupNestedTest(t *testing.T, usr *user.SignedInUser, perms []accesscontrol
|
||||
|
||||
// create dashboard under subfolder
|
||||
_, err = dashStore.SaveDashboard(context.Background(), dashboards.SaveDashboardCommand{
|
||||
OrgID: orgID,
|
||||
FolderID: subfolder.ID,
|
||||
OrgID: orgID,
|
||||
FolderID: subfolder.ID,
|
||||
FolderUID: subfolder.UID,
|
||||
Dashboard: simplejson.NewFromAny(map[string]any{
|
||||
"title": "dashboard under subfolder",
|
||||
}),
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/search/model"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
)
|
||||
@@ -14,8 +15,9 @@ import (
|
||||
type Builder struct {
|
||||
// List of FilterWhere/FilterGroupBy/FilterOrderBy/FilterLeftJoin
|
||||
// to modify the query.
|
||||
Filters []any
|
||||
Dialect migrator.Dialect
|
||||
Filters []any
|
||||
Dialect migrator.Dialect
|
||||
Features featuremgmt.FeatureToggles
|
||||
|
||||
params []any
|
||||
sql bytes.Buffer
|
||||
@@ -35,9 +37,15 @@ func (b *Builder) ToSQL(limit, page int64) (string, []any) {
|
||||
INNER JOIN dashboard ON ids.id = dashboard.id`)
|
||||
b.sql.WriteString("\n")
|
||||
|
||||
b.sql.WriteString(
|
||||
`LEFT OUTER JOIN dashboard AS folder ON folder.id = dashboard.folder_id
|
||||
LEFT OUTER JOIN dashboard_tag ON dashboard.id = dashboard_tag.dashboard_id`)
|
||||
if b.Features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
b.sql.WriteString(
|
||||
`LEFT OUTER JOIN folder ON folder.uid = dashboard.folder_uid AND folder.org_id = dashboard.org_id`)
|
||||
} else {
|
||||
b.sql.WriteString(`
|
||||
LEFT OUTER JOIN dashboard AS folder ON folder.id = dashboard.folder_id`)
|
||||
}
|
||||
b.sql.WriteString(`
|
||||
LEFT OUTER JOIN dashboard_tag ON dashboard.id = dashboard_tag.dashboard_id`)
|
||||
b.sql.WriteString("\n")
|
||||
b.sql.WriteString(orderQuery)
|
||||
|
||||
@@ -58,7 +66,15 @@ func (b *Builder) buildSelect() {
|
||||
dashboard.is_folder,
|
||||
dashboard.folder_id,
|
||||
folder.uid AS folder_uid,
|
||||
folder.slug AS folder_slug,
|
||||
`)
|
||||
if b.Features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
b.sql.WriteString(`
|
||||
folder.title AS folder_slug,`)
|
||||
} else {
|
||||
b.sql.WriteString(`
|
||||
folder.slug AS folder_slug,`)
|
||||
}
|
||||
b.sql.WriteString(`
|
||||
folder.title AS folder_title `)
|
||||
|
||||
for _, f := range b.Filters {
|
||||
|
||||
@@ -58,9 +58,10 @@ func (f FolderFilter) Where() (string, []any) {
|
||||
}
|
||||
|
||||
type FolderUIDFilter struct {
|
||||
Dialect migrator.Dialect
|
||||
OrgID int64
|
||||
UIDs []string
|
||||
Dialect migrator.Dialect
|
||||
OrgID int64
|
||||
UIDs []string
|
||||
NestedFoldersEnabled bool
|
||||
}
|
||||
|
||||
func (f FolderUIDFilter) Where() (string, []any) {
|
||||
@@ -84,10 +85,16 @@ func (f FolderUIDFilter) Where() (string, []any) {
|
||||
// do nothing
|
||||
case len(params) == 1:
|
||||
q = "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid = ?)"
|
||||
if f.NestedFoldersEnabled {
|
||||
q = "dashboard.org_id = ? AND dashboard.folder_uid = ?"
|
||||
}
|
||||
params = append([]any{f.OrgID}, params...)
|
||||
default:
|
||||
sqlArray := "(?" + strings.Repeat(",?", len(params)-1) + ")"
|
||||
q = "dashboard.folder_id IN (SELECT id FROM dashboard WHERE org_id = ? AND uid IN " + sqlArray + ")"
|
||||
if f.NestedFoldersEnabled {
|
||||
q = "dashboard.org_id = ? AND dashboard.folder_uid IN " + sqlArray
|
||||
}
|
||||
params = append([]any{f.OrgID}, params...)
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ func TestBuilder_EqualResults_Basic(t *testing.T) {
|
||||
searchstore.OrgFilter{OrgId: user.OrgID},
|
||||
searchstore.TitleSorter{},
|
||||
},
|
||||
Dialect: store.GetDialect(),
|
||||
Dialect: store.GetDialect(),
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
res := []dashboards.DashboardSearchProjection{}
|
||||
@@ -83,7 +84,8 @@ func TestBuilder_Pagination(t *testing.T) {
|
||||
searchstore.OrgFilter{OrgId: user.OrgID},
|
||||
searchstore.TitleSorter{},
|
||||
},
|
||||
Dialect: store.GetDialect(),
|
||||
Dialect: store.GetDialect(),
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
resPg1 := []dashboards.DashboardSearchProjection{}
|
||||
@@ -243,7 +245,8 @@ func TestBuilder_RBAC(t *testing.T) {
|
||||
recursiveQueriesAreSupported,
|
||||
),
|
||||
},
|
||||
Dialect: store.GetDialect(),
|
||||
Dialect: store.GetDialect(),
|
||||
Features: features,
|
||||
}
|
||||
|
||||
res := []dashboards.DashboardSearchProjection{}
|
||||
|
||||
Reference in New Issue
Block a user