mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
User: Support sort query param for user and org user, search endpoints (#75229)
* User: Add sort option to user search * Switch to an approach that uses the dashboard search options * Cable user sort on the org endpoint * Alias user table with u in org store * Add test and cover orgs/:orgID/users/search endpoint * Add test to userimpl store * Simplify the store_test with sortopts.ParseSortQueryParam * Account for PR feedback * Positive check * Update docs * Update docs * Switch to ErrOrFallback Co-authored-by: Karl Persson <kalle.persson@grafana.com> --------- Co-authored-by: Karl Persson <kalle.persson@grafana.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/search/model"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
)
|
||||
|
||||
@@ -61,11 +62,11 @@ func (b *Builder) buildSelect() {
|
||||
folder.title AS folder_title `)
|
||||
|
||||
for _, f := range b.Filters {
|
||||
if f, ok := f.(FilterSelect); ok {
|
||||
if f, ok := f.(model.FilterSelect); ok {
|
||||
b.sql.WriteString(fmt.Sprintf(", %s", f.Select()))
|
||||
}
|
||||
|
||||
if f, ok := f.(FilterWith); ok {
|
||||
if f, ok := f.(model.FilterWith); ok {
|
||||
recQuery, recQueryParams = f.With()
|
||||
}
|
||||
}
|
||||
@@ -98,14 +99,14 @@ func (b *Builder) applyFilters() (ordering string) {
|
||||
orders := []string{}
|
||||
|
||||
for _, f := range b.Filters {
|
||||
if f, ok := f.(FilterLeftJoin); ok {
|
||||
if f, ok := f.(model.FilterLeftJoin); ok {
|
||||
s := f.LeftJoin()
|
||||
if s != "" {
|
||||
joins = append(joins, fmt.Sprintf(" LEFT OUTER JOIN %s ", s))
|
||||
}
|
||||
}
|
||||
|
||||
if f, ok := f.(FilterWhere); ok {
|
||||
if f, ok := f.(model.FilterWhere); ok {
|
||||
sql, params := f.Where()
|
||||
if sql != "" {
|
||||
wheres = append(wheres, sql)
|
||||
@@ -113,7 +114,7 @@ func (b *Builder) applyFilters() (ordering string) {
|
||||
}
|
||||
}
|
||||
|
||||
if f, ok := f.(FilterGroupBy); ok {
|
||||
if f, ok := f.(model.FilterGroupBy); ok {
|
||||
sql, params := f.GroupBy()
|
||||
if sql != "" {
|
||||
groups = append(groups, sql)
|
||||
@@ -121,8 +122,8 @@ func (b *Builder) applyFilters() (ordering string) {
|
||||
}
|
||||
}
|
||||
|
||||
if f, ok := f.(FilterOrderBy); ok {
|
||||
if f, ok := f.(FilterLeftJoin); ok {
|
||||
if f, ok := f.(model.FilterOrderBy); ok {
|
||||
if f, ok := f.(model.FilterLeftJoin); ok {
|
||||
orderJoins = append(orderJoins, fmt.Sprintf(" LEFT OUTER JOIN %s ", f.LeftJoin()))
|
||||
}
|
||||
orders = append(orders, f.OrderBy())
|
||||
|
||||
@@ -5,45 +5,10 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/search/model"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
)
|
||||
|
||||
// FilterWhere limits the set of dashboard IDs to the dashboards for
|
||||
// which the filter is applicable. Results where the first value is
|
||||
// an empty string are discarded.
|
||||
type FilterWhere interface {
|
||||
Where() (string, []any)
|
||||
}
|
||||
|
||||
// FilterWith returns any recursive CTE queries (if supported)
|
||||
// and their parameters
|
||||
type FilterWith interface {
|
||||
With() (string, []any)
|
||||
}
|
||||
|
||||
// FilterGroupBy should be used after performing an outer join on the
|
||||
// search result to ensure there is only one of each ID in the results.
|
||||
// The id column must be present in the result.
|
||||
type FilterGroupBy interface {
|
||||
GroupBy() (string, []any)
|
||||
}
|
||||
|
||||
// FilterOrderBy provides an ordering for the search result.
|
||||
type FilterOrderBy interface {
|
||||
OrderBy() string
|
||||
}
|
||||
|
||||
// FilterLeftJoin adds the returned string as a "LEFT OUTER JOIN" to
|
||||
// allow for fetching extra columns from a table outside of the
|
||||
// dashboard column.
|
||||
type FilterLeftJoin interface {
|
||||
LeftJoin() string
|
||||
}
|
||||
|
||||
type FilterSelect interface {
|
||||
Select() string
|
||||
}
|
||||
|
||||
const (
|
||||
TypeFolder = "dash-folder"
|
||||
TypeDashboard = "dash-db"
|
||||
@@ -220,7 +185,7 @@ func sqlUIDin(column string, uids []string) (string, []any) {
|
||||
type FolderWithAlertsFilter struct {
|
||||
}
|
||||
|
||||
var _ FilterWhere = &FolderWithAlertsFilter{}
|
||||
var _ model.FilterWhere = &FolderWithAlertsFilter{}
|
||||
|
||||
func (f FolderWithAlertsFilter) Where() (string, []any) {
|
||||
return "EXISTS (SELECT 1 FROM alert_rule WHERE alert_rule.namespace_uid = dashboard.uid)", nil
|
||||
|
||||
Reference in New Issue
Block a user