mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Public Dashboards: Add Public Tag to Dashboard Title (#52351)
Adds Public tag to dashboard title when it has an enabled public dashboard
This commit is contained in:
parent
acd85314b3
commit
3bc13e2335
@ -77,6 +77,18 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
if rsp != nil {
|
||||
return rsp
|
||||
}
|
||||
|
||||
var (
|
||||
hasPublicDashboard bool
|
||||
err error
|
||||
)
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) {
|
||||
hasPublicDashboard, err = hs.PublicDashboardsApi.PublicDashboardService.PublicDashboardEnabled(c.Req.Context(), dash.Uid)
|
||||
if err != nil {
|
||||
return response.Error(500, "Error while retrieving public dashboards", err)
|
||||
}
|
||||
}
|
||||
|
||||
// When dash contains only keys id, uid that means dashboard data is not valid and json decode failed.
|
||||
if dash.Data != nil {
|
||||
isEmptyData := true
|
||||
@ -139,6 +151,7 @@ func (hs *HTTPServer) GetDashboard(c *models.ReqContext) response.Response {
|
||||
Url: dash.GetUrl(),
|
||||
FolderTitle: "General",
|
||||
AnnotationsPermissions: annotationPermissions,
|
||||
PublicDashboardEnabled: hasPublicDashboard,
|
||||
}
|
||||
|
||||
// lookup folder title
|
||||
|
@ -261,6 +261,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
AccessControl: accesscontrolmock.New(),
|
||||
DashboardService: dashboardService,
|
||||
dashboardVersionService: fakeDashboardVersionService,
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
|
||||
|
||||
@ -901,6 +902,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
||||
SQLStore: mockSQLStore,
|
||||
AccessControl: accesscontrolmock.New(),
|
||||
DashboardService: dashboardService,
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
|
||||
hs.callGetDashboard(sc)
|
||||
@ -955,6 +957,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
|
||||
folderPermissions, dashboardPermissions, ac,
|
||||
),
|
||||
DashboardService: dashboardService,
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
|
||||
|
||||
@ -1053,6 +1056,7 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
|
||||
LibraryElementService: &mockLibraryElementService{},
|
||||
SQLStore: sqlmock,
|
||||
dashboardVersionService: fakeDashboardVersionService,
|
||||
Features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
hs.CoremodelStaticRegistry, hs.CoremodelRegistry = setupDashboardCoremodel(t)
|
||||
|
||||
|
@ -34,6 +34,7 @@ type DashboardMeta struct {
|
||||
ProvisionedExternalId string `json:"provisionedExternalId"`
|
||||
AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"`
|
||||
PublicDashboardAccessToken string `json:"publicDashboardAccessToken"`
|
||||
PublicDashboardEnabled bool `json:"publicDashboardEnabled"`
|
||||
}
|
||||
type AnnotationPermission struct {
|
||||
Dashboard AnnotationActions `json:"dashboard"`
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.12.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.12.1. DO NOT EDIT.
|
||||
|
||||
package dashboards
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.12.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.12.1. DO NOT EDIT.
|
||||
|
||||
package dashboards
|
||||
|
||||
|
@ -171,3 +171,21 @@ func (d *PublicDashboardStoreImpl) UpdatePublicDashboardConfig(ctx context.Conte
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *PublicDashboardStoreImpl) PublicDashboardEnabled(ctx context.Context, dashboardUid string) (bool, error) {
|
||||
hasPublicDashboard := false
|
||||
err := d.sqlStore.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
|
||||
sql := "SELECT COUNT(*) FROM dashboard_public WHERE dashboard_uid=? AND is_enabled=true"
|
||||
|
||||
result, err := dbSession.SQL(sql, dashboardUid).Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hasPublicDashboard = result > 0
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
return hasPublicDashboard, err
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
dashboards "github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
dashboardsDB "github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||
@ -38,6 +38,54 @@ func TestIntegrationGetPublicDashboard(t *testing.T) {
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
}
|
||||
|
||||
t.Run("PublicDashboardEnabled Will return true when dashboard has at least one enabled public dashboard", func(t *testing.T) {
|
||||
setup()
|
||||
|
||||
_, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
PublicDashboard: PublicDashboard{
|
||||
IsEnabled: true,
|
||||
Uid: "abc123",
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
CreatedAt: time.Now(),
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := publicdashboardStore.PublicDashboardEnabled(context.Background(), savedDashboard.Uid)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, res)
|
||||
})
|
||||
|
||||
t.Run("PublicDashboardEnabled will return false when dashboard has public dashboards but they are not enabled", func(t *testing.T) {
|
||||
setup()
|
||||
|
||||
_, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
PublicDashboard: PublicDashboard{
|
||||
IsEnabled: false,
|
||||
Uid: "abc123",
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
CreatedAt: time.Now(),
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
res, err := publicdashboardStore.PublicDashboardEnabled(context.Background(), savedDashboard.Uid)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.False(t, res)
|
||||
})
|
||||
|
||||
t.Run("returns PublicDashboard and Dashboard", func(t *testing.T) {
|
||||
setup()
|
||||
pubdash, err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.12.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.12.1. DO NOT EDIT.
|
||||
|
||||
package publicdashboards
|
||||
|
||||
@ -110,6 +110,27 @@ func (_m *FakePublicDashboardService) GetPublicDashboardConfig(ctx context.Conte
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// PublicDashboardEnabled provides a mock function with given fields: ctx, dashboardUid
|
||||
func (_m *FakePublicDashboardService) PublicDashboardEnabled(ctx context.Context, dashboardUid string) (bool, error) {
|
||||
ret := _m.Called(ctx, dashboardUid)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) bool); ok {
|
||||
r0 = rf(ctx, dashboardUid)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, dashboardUid)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SavePublicDashboardConfig provides a mock function with given fields: ctx, dto
|
||||
func (_m *FakePublicDashboardService) SavePublicDashboardConfig(ctx context.Context, dto *publicdashboardsmodels.SavePublicDashboardConfigDTO) (*publicdashboardsmodels.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, dto)
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.12.2. DO NOT EDIT.
|
||||
// Code generated by mockery v2.12.1. DO NOT EDIT.
|
||||
|
||||
package publicdashboards
|
||||
|
||||
@ -94,6 +94,27 @@ func (_m *FakePublicDashboardStore) GetPublicDashboardConfig(ctx context.Context
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// PublicDashboardEnabled provides a mock function with given fields: ctx, dashboardUid
|
||||
func (_m *FakePublicDashboardStore) PublicDashboardEnabled(ctx context.Context, dashboardUid string) (bool, error) {
|
||||
ret := _m.Called(ctx, dashboardUid)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) bool); ok {
|
||||
r0 = rf(ctx, dashboardUid)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, dashboardUid)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SavePublicDashboardConfig provides a mock function with given fields: ctx, cmd
|
||||
func (_m *FakePublicDashboardStore) SavePublicDashboardConfig(ctx context.Context, cmd models.SavePublicDashboardConfigCommand) (*models.PublicDashboard, error) {
|
||||
ret := _m.Called(ctx, cmd)
|
||||
|
@ -17,6 +17,7 @@ type Service interface {
|
||||
GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error)
|
||||
SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*PublicDashboard, error)
|
||||
BuildPublicDashboardMetricRequest(ctx context.Context, dashboard *models.Dashboard, publicDashboard *PublicDashboard, panelId int64) (dtos.MetricRequest, error)
|
||||
PublicDashboardEnabled(ctx context.Context, dashboardUid string) (bool, error)
|
||||
}
|
||||
|
||||
//go:generate mockery --name Store --structname FakePublicDashboardStore --inpackage --filename public_dashboard_store_mock.go
|
||||
@ -26,4 +27,5 @@ type Store interface {
|
||||
GenerateNewPublicDashboardUid(ctx context.Context) (string, error)
|
||||
SavePublicDashboardConfig(ctx context.Context, cmd SavePublicDashboardConfigCommand) (*PublicDashboard, error)
|
||||
UpdatePublicDashboardConfig(ctx context.Context, cmd SavePublicDashboardConfigCommand) error
|
||||
PublicDashboardEnabled(ctx context.Context, dashboardUid string) (bool, error)
|
||||
}
|
||||
|
@ -189,6 +189,10 @@ func (pd *PublicDashboardServiceImpl) BuildAnonymousUser(ctx context.Context, da
|
||||
return anonymousUser, nil
|
||||
}
|
||||
|
||||
func (pd *PublicDashboardServiceImpl) PublicDashboardEnabled(ctx context.Context, dashboardUid string) (bool, error) {
|
||||
return pd.store.PublicDashboardEnabled(ctx, dashboardUid)
|
||||
}
|
||||
|
||||
// generates a uuid formatted without dashes to use as access token
|
||||
func GenerateAccessToken() (string, error) {
|
||||
token, err := uuid.NewRandom()
|
||||
|
@ -4,7 +4,7 @@ import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { locationUtil, textUtil } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { ButtonGroup, ModalsController, ToolbarButton, PageToolbar, useForceUpdate } from '@grafana/ui';
|
||||
import { ButtonGroup, ModalsController, ToolbarButton, PageToolbar, useForceUpdate, Tag } from '@grafana/ui';
|
||||
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
|
||||
import { NavToolbarSeparator } from 'app/core/components/AppChrome/NavToolbarSeparator';
|
||||
import config from 'app/core/config';
|
||||
@ -154,6 +154,10 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (dashboard.meta.publicDashboardEnabled) {
|
||||
buttons.push(<Tag name="Public" colorIndex={5}></Tag>);
|
||||
}
|
||||
|
||||
if (dashboard.uid && config.featureToggles.dashboardComments) {
|
||||
buttons.push(
|
||||
<ModalsController key="button-dashboard-comments">
|
||||
|
@ -42,6 +42,7 @@ export interface DashboardMeta {
|
||||
hasUnsavedFolderChange?: boolean;
|
||||
annotationsPermissions?: AnnotationsPermissions;
|
||||
publicDashboardAccessToken?: string;
|
||||
publicDashboardEnabled?: boolean;
|
||||
}
|
||||
|
||||
export interface AnnotationActions {
|
||||
|
Loading…
Reference in New Issue
Block a user