mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Public Dashboards: Can toggle annotations in modal (#57312)
adds toggle for pubdash annotations
This commit is contained in:
parent
7f3b567657
commit
0b8fb543fc
@ -58,7 +58,8 @@ publicDashboards = true
|
||||
- Template variables are currently not supported, but are planned to be in the future.
|
||||
- The time range is permanently set to the default time range on the dashboard. If you update the default time range for a dashboard, it will be reflected in the public dashboard.
|
||||
- Exemplars will be omitted from the panel.
|
||||
- Annotations will not be displayed in public dashboards.
|
||||
- Only annotations that query the `-- Grafana --` datasource are supported.
|
||||
- Organization annotations are not supported.
|
||||
- Grafana Live and real-time event streams are not supported.
|
||||
- Library panels are currently not supported, but are planned to be in the future.
|
||||
- Datasources using Reverse Proxy functionality are not supported.
|
||||
|
@ -186,6 +186,7 @@ export const Pages = {
|
||||
LimitedDSCheckbox: 'data-testid public dashboard limited datasources checkbox',
|
||||
CostIncreaseCheckbox: 'data-testid public dashboard cost may increase checkbox',
|
||||
EnableSwitch: 'data-testid public dashboard on off switch',
|
||||
EnableAnnotationsSwitch: 'data-testid public dashboard on off switch for annotations',
|
||||
SaveConfigButton: 'data-testid public dashboard save config button',
|
||||
CopyUrlInput: 'data-testid public dashboard copy url input',
|
||||
CopyUrlButton: 'data-testid public dashboard copy url button',
|
||||
|
@ -241,8 +241,9 @@ func (d *PublicDashboardStoreImpl) UpdatePublicDashboardConfig(ctx context.Conte
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = sess.Exec("UPDATE dashboard_public SET is_enabled = ?, time_settings = ?, updated_by = ?, updated_at = ? WHERE uid = ?",
|
||||
_, err = sess.Exec("UPDATE dashboard_public SET is_enabled = ?, annotations_enabled = ?, time_settings = ?, updated_by = ?, updated_at = ? WHERE uid = ?",
|
||||
cmd.PublicDashboard.IsEnabled,
|
||||
cmd.PublicDashboard.AnnotationsEnabled,
|
||||
string(timeSettingsJSON),
|
||||
cmd.PublicDashboard.UpdatedBy,
|
||||
cmd.PublicDashboard.UpdatedAt.UTC().Format("2006-01-02 15:04:05"),
|
||||
|
@ -233,14 +233,15 @@ func TestIntegrationGetPublicDashboard(t *testing.T) {
|
||||
setup()
|
||||
cmd := SavePublicDashboardConfigCommand{
|
||||
PublicDashboard: PublicDashboard{
|
||||
IsEnabled: true,
|
||||
Uid: "abc1234",
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
TimeSettings: DefaultTimeSettings,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: true,
|
||||
Uid: "abc1234",
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
TimeSettings: DefaultTimeSettings,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
},
|
||||
}
|
||||
|
||||
@ -359,14 +360,15 @@ func TestIntegrationSavePublicDashboardConfig(t *testing.T) {
|
||||
setup()
|
||||
err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
||||
PublicDashboard: PublicDashboard{
|
||||
IsEnabled: true,
|
||||
Uid: "pubdash-uid",
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
TimeSettings: DefaultTimeSettings,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: true,
|
||||
Uid: "pubdash-uid",
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
TimeSettings: DefaultTimeSettings,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@ -424,13 +426,14 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
|
||||
pdUid := "asdf1234"
|
||||
err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
||||
PublicDashboard: PublicDashboard{
|
||||
Uid: pdUid,
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
IsEnabled: true,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
Uid: pdUid,
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
IsEnabled: false,
|
||||
AnnotationsEnabled: true,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@ -439,25 +442,27 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
|
||||
anotherPdUid := "anotherUid"
|
||||
err = publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
||||
PublicDashboard: PublicDashboard{
|
||||
Uid: anotherPdUid,
|
||||
DashboardUid: anotherSavedDashboard.Uid,
|
||||
OrgId: anotherSavedDashboard.OrgId,
|
||||
IsEnabled: true,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "fakeaccesstoken",
|
||||
Uid: anotherPdUid,
|
||||
DashboardUid: anotherSavedDashboard.Uid,
|
||||
OrgId: anotherSavedDashboard.OrgId,
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: false,
|
||||
CreatedAt: DefaultTime,
|
||||
CreatedBy: 7,
|
||||
AccessToken: "fakeaccesstoken",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
updatedPublicDashboard := PublicDashboard{
|
||||
Uid: pdUid,
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
IsEnabled: false,
|
||||
TimeSettings: &TimeSettings{From: "now-8", To: "now"},
|
||||
UpdatedAt: time.Now().UTC().Round(time.Second),
|
||||
UpdatedBy: 8,
|
||||
Uid: pdUid,
|
||||
DashboardUid: savedDashboard.Uid,
|
||||
OrgId: savedDashboard.OrgId,
|
||||
IsEnabled: false,
|
||||
AnnotationsEnabled: true,
|
||||
TimeSettings: &TimeSettings{From: "now-8", To: "now"},
|
||||
UpdatedAt: time.Now().UTC().Round(time.Second),
|
||||
UpdatedBy: 8,
|
||||
}
|
||||
// update initial record
|
||||
err = publicdashboardStore.UpdatePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
|
||||
@ -473,12 +478,14 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
|
||||
// make sure we're correctly updated IsEnabled because we have to call
|
||||
// UseBool with xorm
|
||||
assert.Equal(t, updatedPublicDashboard.IsEnabled, pdRetrieved.IsEnabled)
|
||||
assert.Equal(t, updatedPublicDashboard.AnnotationsEnabled, pdRetrieved.AnnotationsEnabled)
|
||||
|
||||
// not updated dashboard shouldn't have changed
|
||||
pdNotUpdatedRetrieved, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), anotherSavedDashboard.OrgId, anotherSavedDashboard.Uid)
|
||||
require.NoError(t, err)
|
||||
assert.NotEqual(t, updatedPublicDashboard.UpdatedAt, pdNotUpdatedRetrieved.UpdatedAt)
|
||||
assert.NotEqual(t, updatedPublicDashboard.IsEnabled, pdNotUpdatedRetrieved.IsEnabled)
|
||||
assert.NotEqual(t, updatedPublicDashboard.AnnotationsEnabled, pdNotUpdatedRetrieved.AnnotationsEnabled)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -64,12 +64,13 @@ var (
|
||||
)
|
||||
|
||||
type PublicDashboard struct {
|
||||
Uid string `json:"uid" xorm:"pk uid"`
|
||||
DashboardUid string `json:"dashboardUid" xorm:"dashboard_uid"`
|
||||
OrgId int64 `json:"-" xorm:"org_id"` // Don't ever marshal orgId to Json
|
||||
TimeSettings *TimeSettings `json:"timeSettings" xorm:"time_settings"`
|
||||
IsEnabled bool `json:"isEnabled" xorm:"is_enabled"`
|
||||
AccessToken string `json:"accessToken" xorm:"access_token"`
|
||||
Uid string `json:"uid" xorm:"pk uid"`
|
||||
DashboardUid string `json:"dashboardUid" xorm:"dashboard_uid"`
|
||||
OrgId int64 `json:"-" xorm:"org_id"` // Don't ever marshal orgId to Json
|
||||
TimeSettings *TimeSettings `json:"timeSettings" xorm:"time_settings"`
|
||||
IsEnabled bool `json:"isEnabled" xorm:"is_enabled"`
|
||||
AccessToken string `json:"accessToken" xorm:"access_token"`
|
||||
AnnotationsEnabled bool `json:"annotationsEnabled" xorm:"annotations_enabled"`
|
||||
|
||||
CreatedBy int64 `json:"createdBy" xorm:"created_by"`
|
||||
UpdatedBy int64 `json:"updatedBy" xorm:"updated_by"`
|
||||
|
@ -19,11 +19,15 @@ import (
|
||||
|
||||
// GetAnnotations returns annotations for a public dashboard
|
||||
func (pd *PublicDashboardServiceImpl) GetAnnotations(ctx context.Context, reqDTO models.AnnotationsQueryDTO, accessToken string) ([]models.AnnotationEvent, error) {
|
||||
_, dash, err := pd.GetPublicDashboard(ctx, accessToken)
|
||||
pub, dash, err := pd.GetPublicDashboard(ctx, accessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !pub.AnnotationsEnabled {
|
||||
return []models.AnnotationEvent{}, nil
|
||||
}
|
||||
|
||||
annoDto, err := UnmarshalDashboardAnnotations(dash.Data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -408,6 +408,8 @@ func TestGetQueryDataResponse(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetAnnotations(t *testing.T) {
|
||||
color := "red"
|
||||
name := "annoName"
|
||||
t.Run("will build anonymous user with correct permissions to get annotations", func(t *testing.T) {
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
config := setting.NewCfg()
|
||||
@ -436,8 +438,6 @@ func TestGetAnnotations(t *testing.T) {
|
||||
|
||||
t.Run("Test events from tag queries overwrite built-in annotation queries and duplicate events are not returned", func(t *testing.T) {
|
||||
dash := grafanamodels.NewDashboard("test")
|
||||
color := "red"
|
||||
name := "annoName"
|
||||
grafanaAnnotation := DashAnnotation{
|
||||
Datasource: CreateDatasource("grafana", "grafana"),
|
||||
Enable: true,
|
||||
@ -473,7 +473,7 @@ func TestGetAnnotations(t *testing.T) {
|
||||
store: &fakeStore,
|
||||
AnnotationsRepo: &annotationsRepo,
|
||||
}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
|
||||
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
|
||||
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{
|
||||
{
|
||||
@ -508,8 +508,6 @@ func TestGetAnnotations(t *testing.T) {
|
||||
|
||||
t.Run("Test panelId set to zero when annotation event is for a tags query", func(t *testing.T) {
|
||||
dash := grafanamodels.NewDashboard("test")
|
||||
color := "red"
|
||||
name := "annoName"
|
||||
grafanaAnnotation := DashAnnotation{
|
||||
Datasource: CreateDatasource("grafana", "grafana"),
|
||||
Enable: true,
|
||||
@ -532,7 +530,7 @@ func TestGetAnnotations(t *testing.T) {
|
||||
store: &fakeStore,
|
||||
AnnotationsRepo: &annotationsRepo,
|
||||
}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
|
||||
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
|
||||
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{
|
||||
{
|
||||
@ -567,8 +565,6 @@ func TestGetAnnotations(t *testing.T) {
|
||||
|
||||
t.Run("Test can get grafana annotations and will skip annotation queries and disabled annotations", func(t *testing.T) {
|
||||
dash := grafanamodels.NewDashboard("test")
|
||||
color := "red"
|
||||
name := "annoName"
|
||||
disabledGrafanaAnnotation := DashAnnotation{
|
||||
Datasource: CreateDatasource("grafana", "grafana"),
|
||||
Enable: false,
|
||||
@ -603,7 +599,7 @@ func TestGetAnnotations(t *testing.T) {
|
||||
store: &fakeStore,
|
||||
AnnotationsRepo: &annotationsRepo,
|
||||
}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
|
||||
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
|
||||
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{
|
||||
{
|
||||
@ -645,7 +641,40 @@ func TestGetAnnotations(t *testing.T) {
|
||||
AnnotationsRepo: &annotationsRepo,
|
||||
}
|
||||
dashboard := grafanamodels.NewDashboard("dashWithNoAnnotations")
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
|
||||
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
|
||||
|
||||
items, err := service.GetAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123")
|
||||
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, items)
|
||||
})
|
||||
|
||||
t.Run("test will return nothing when pubdash annotations are disabled", func(t *testing.T) {
|
||||
annotationsRepo := annotations.FakeAnnotationsRepo{}
|
||||
fakeStore := FakePublicDashboardStore{}
|
||||
service := &PublicDashboardServiceImpl{
|
||||
log: log.New("test.logger"),
|
||||
store: &fakeStore,
|
||||
AnnotationsRepo: &annotationsRepo,
|
||||
}
|
||||
dash := grafanamodels.NewDashboard("test")
|
||||
grafanaAnnotation := DashAnnotation{
|
||||
Datasource: CreateDatasource("grafana", "grafana"),
|
||||
Enable: true,
|
||||
Name: &name,
|
||||
IconColor: &color,
|
||||
Target: &dashboard2.AnnotationTarget{
|
||||
Limit: 100,
|
||||
MatchAny: false,
|
||||
Tags: nil,
|
||||
Type: "dashboard",
|
||||
},
|
||||
Type: "dashboard",
|
||||
}
|
||||
annos := []DashAnnotation{grafanaAnnotation}
|
||||
dashboard := AddAnnotationsToDashboard(t, dash, annos)
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: false}
|
||||
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
|
||||
|
||||
items, err := service.GetAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123")
|
||||
@ -663,8 +692,6 @@ func TestGetAnnotations(t *testing.T) {
|
||||
AnnotationsRepo: &annotationsRepo,
|
||||
}
|
||||
dash := grafanamodels.NewDashboard("test")
|
||||
color := "red"
|
||||
name := "annoName"
|
||||
grafanaAnnotation := DashAnnotation{
|
||||
Datasource: CreateDatasource("grafana", "grafana"),
|
||||
Enable: true,
|
||||
@ -679,7 +706,7 @@ func TestGetAnnotations(t *testing.T) {
|
||||
}
|
||||
annos := []DashAnnotation{grafanaAnnotation}
|
||||
dash = AddAnnotationsToDashboard(t, dash, annos)
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dash.Uid}
|
||||
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dash.Uid, AnnotationsEnabled: true}
|
||||
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dash, nil)
|
||||
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return(nil, errors.New("failed")).Maybe()
|
||||
|
||||
|
@ -168,14 +168,15 @@ func (pd *PublicDashboardServiceImpl) savePublicDashboardConfig(ctx context.Cont
|
||||
|
||||
cmd := SavePublicDashboardConfigCommand{
|
||||
PublicDashboard: PublicDashboard{
|
||||
Uid: uid,
|
||||
DashboardUid: dto.DashboardUid,
|
||||
OrgId: dto.OrgId,
|
||||
IsEnabled: dto.PublicDashboard.IsEnabled,
|
||||
TimeSettings: dto.PublicDashboard.TimeSettings,
|
||||
CreatedBy: dto.UserId,
|
||||
CreatedAt: time.Now(),
|
||||
AccessToken: accessToken,
|
||||
Uid: uid,
|
||||
DashboardUid: dto.DashboardUid,
|
||||
OrgId: dto.OrgId,
|
||||
IsEnabled: dto.PublicDashboard.IsEnabled,
|
||||
AnnotationsEnabled: dto.PublicDashboard.AnnotationsEnabled,
|
||||
TimeSettings: dto.PublicDashboard.TimeSettings,
|
||||
CreatedBy: dto.UserId,
|
||||
CreatedAt: time.Now(),
|
||||
AccessToken: accessToken,
|
||||
},
|
||||
}
|
||||
|
||||
@ -192,11 +193,12 @@ func (pd *PublicDashboardServiceImpl) savePublicDashboardConfig(ctx context.Cont
|
||||
func (pd *PublicDashboardServiceImpl) updatePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (string, error) {
|
||||
cmd := SavePublicDashboardConfigCommand{
|
||||
PublicDashboard: PublicDashboard{
|
||||
Uid: dto.PublicDashboard.Uid,
|
||||
IsEnabled: dto.PublicDashboard.IsEnabled,
|
||||
TimeSettings: dto.PublicDashboard.TimeSettings,
|
||||
UpdatedBy: dto.UserId,
|
||||
UpdatedAt: time.Now(),
|
||||
Uid: dto.PublicDashboard.Uid,
|
||||
IsEnabled: dto.PublicDashboard.IsEnabled,
|
||||
AnnotationsEnabled: dto.PublicDashboard.AnnotationsEnabled,
|
||||
TimeSettings: dto.PublicDashboard.TimeSettings,
|
||||
UpdatedBy: dto.UserId,
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -135,10 +135,11 @@ func TestSavePublicDashboard(t *testing.T) {
|
||||
OrgId: dashboard.OrgId,
|
||||
UserId: 7,
|
||||
PublicDashboard: &PublicDashboard{
|
||||
IsEnabled: true,
|
||||
DashboardUid: "NOTTHESAME",
|
||||
OrgId: 9999999,
|
||||
TimeSettings: timeSettings,
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: false,
|
||||
DashboardUid: "NOTTHESAME",
|
||||
OrgId: 9999999,
|
||||
TimeSettings: timeSettings,
|
||||
},
|
||||
}
|
||||
|
||||
@ -152,6 +153,7 @@ func TestSavePublicDashboard(t *testing.T) {
|
||||
assert.Equal(t, dashboard.Uid, pubdash.DashboardUid)
|
||||
assert.Equal(t, dashboard.OrgId, pubdash.OrgId)
|
||||
assert.Equal(t, dto.UserId, pubdash.CreatedBy)
|
||||
assert.Equal(t, dto.PublicDashboard.AnnotationsEnabled, pubdash.AnnotationsEnabled)
|
||||
// IsEnabled set by parameters
|
||||
assert.Equal(t, dto.PublicDashboard.IsEnabled, pubdash.IsEnabled)
|
||||
// CreatedAt set to non-zero time
|
||||
@ -270,8 +272,9 @@ func TestUpdatePublicDashboard(t *testing.T) {
|
||||
OrgId: dashboard.OrgId,
|
||||
UserId: 7,
|
||||
PublicDashboard: &PublicDashboard{
|
||||
IsEnabled: true,
|
||||
TimeSettings: timeSettings,
|
||||
AnnotationsEnabled: false,
|
||||
IsEnabled: true,
|
||||
TimeSettings: timeSettings,
|
||||
},
|
||||
}
|
||||
|
||||
@ -290,9 +293,10 @@ func TestUpdatePublicDashboard(t *testing.T) {
|
||||
CreatedBy: 9,
|
||||
CreatedAt: time.Time{},
|
||||
|
||||
IsEnabled: true,
|
||||
TimeSettings: timeSettings,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
IsEnabled: true,
|
||||
AnnotationsEnabled: true,
|
||||
TimeSettings: timeSettings,
|
||||
AccessToken: "NOTAREALUUID",
|
||||
},
|
||||
}
|
||||
|
||||
@ -310,6 +314,7 @@ func TestUpdatePublicDashboard(t *testing.T) {
|
||||
|
||||
// gets updated
|
||||
assert.Equal(t, dto.PublicDashboard.IsEnabled, updatedPubdash.IsEnabled)
|
||||
assert.Equal(t, dto.PublicDashboard.AnnotationsEnabled, updatedPubdash.AnnotationsEnabled)
|
||||
assert.Equal(t, dto.PublicDashboard.TimeSettings, updatedPubdash.TimeSettings)
|
||||
assert.Equal(t, dto.UserId, updatedPubdash.UpdatedBy)
|
||||
assert.NotEqual(t, &time.Time{}, updatedPubdash.UpdatedAt)
|
||||
|
@ -65,4 +65,13 @@ func addPublicDashboardMigration(mg *Migrator) {
|
||||
|
||||
// rename table
|
||||
addTableRenameMigration(mg, "dashboard_public_config", "dashboard_public", "v2")
|
||||
// some migrations (like AddColumn) need the table object to be passed in. So we need to make sure its updated.
|
||||
dashboardPublicCfgV2.Name = "dashboard_public"
|
||||
|
||||
mg.AddMigration("add annotations_enabled column", NewAddColumnMigration(dashboardPublicCfgV2, &Column{
|
||||
Name: "annotations_enabled",
|
||||
Type: DB_Bool,
|
||||
Nullable: false,
|
||||
Default: "0",
|
||||
}))
|
||||
}
|
||||
|
@ -11,14 +11,18 @@ import { useIsDesktop } from 'app/features/dashboard/utils/screen';
|
||||
import { getTimeRange } from 'app/features/dashboard/utils/timeRange';
|
||||
|
||||
export const Configuration = ({
|
||||
isAnnotationsEnabled,
|
||||
disabled,
|
||||
isPubDashEnabled,
|
||||
onToggleEnabled,
|
||||
onToggleAnnotations,
|
||||
dashboard,
|
||||
}: {
|
||||
isAnnotationsEnabled: boolean;
|
||||
disabled: boolean;
|
||||
isPubDashEnabled?: boolean;
|
||||
onToggleEnabled: () => void;
|
||||
onToggleAnnotations: () => void;
|
||||
dashboard: DashboardModel;
|
||||
}) => {
|
||||
const selectors = e2eSelectors.pages.ShareDashboardModal.PublicDashboard;
|
||||
@ -36,6 +40,19 @@ export const Configuration = ({
|
||||
<Label description="The public dashboard uses the default time settings of the dashboard">Time range</Label>
|
||||
<TimeRangeInput value={timeRange} disabled onChange={() => {}} />
|
||||
</Layout>
|
||||
<Layout orientation={isDesktop ? 0 : 1} spacing="xs" justify="space-between">
|
||||
<Label description="Show annotations on public dashboard">Show annotations</Label>
|
||||
<Switch
|
||||
data-testid={selectors.EnableAnnotationsSwitch}
|
||||
value={isAnnotationsEnabled}
|
||||
onChange={() => {
|
||||
reportInteraction('grafana_dashboards_annotations_clicked', {
|
||||
action: isAnnotationsEnabled ? 'disable' : 'enable',
|
||||
});
|
||||
onToggleAnnotations();
|
||||
}}
|
||||
/>
|
||||
</Layout>
|
||||
<Layout orientation={isDesktop ? 0 : 1} spacing="xs" justify="space-between">
|
||||
<Label description="Configures whether current dashboard can be available publicly">Enabled</Label>
|
||||
<Switch
|
||||
|
@ -23,6 +23,7 @@ const server = setupServer(
|
||||
ctx.status(200),
|
||||
ctx.json({
|
||||
isEnabled: false,
|
||||
annotationsEnabled: false,
|
||||
uid: undefined,
|
||||
dashboardUid: undefined,
|
||||
accessToken: 'an-access-token',
|
||||
@ -170,6 +171,7 @@ describe('SharePublic', () => {
|
||||
expect(screen.getByTestId(selectors.LimitedDSCheckbox)).toBeDisabled();
|
||||
expect(screen.getByTestId(selectors.CostIncreaseCheckbox)).toBeDisabled();
|
||||
expect(screen.getByTestId(selectors.EnableSwitch)).toBeDisabled();
|
||||
expect(screen.getByTestId(selectors.EnableAnnotationsSwitch)).toBeDisabled();
|
||||
expect(screen.getByTestId(selectors.SaveConfigButton)).toBeDisabled();
|
||||
});
|
||||
// test checking if current version of dashboard in state is persisted to db
|
||||
@ -188,6 +190,7 @@ describe('SharePublic - New config setup', () => {
|
||||
expect(screen.getByTestId(selectors.LimitedDSCheckbox)).toBeEnabled();
|
||||
expect(screen.getByTestId(selectors.CostIncreaseCheckbox)).toBeEnabled();
|
||||
expect(screen.getByTestId(selectors.EnableSwitch)).toBeEnabled();
|
||||
expect(screen.getByTestId(selectors.EnableAnnotationsSwitch)).toBeEnabled();
|
||||
|
||||
expect(screen.getByTestId(selectors.SaveConfigButton)).toBeDisabled();
|
||||
});
|
||||
@ -222,6 +225,7 @@ describe('SharePublic - Already persisted', () => {
|
||||
ctx.status(200),
|
||||
ctx.json({
|
||||
isEnabled: true,
|
||||
annotationsEnabled: true,
|
||||
uid: 'a-uid',
|
||||
dashboardUid: req.params.uId,
|
||||
accessToken: 'an-access-token',
|
||||
@ -237,6 +241,13 @@ describe('SharePublic - Already persisted', () => {
|
||||
|
||||
expect(screen.getByTestId(selectors.SaveConfigButton)).toBeEnabled();
|
||||
});
|
||||
it('when modal is opened, then annotations toggle is enabled and checked when its enabled in the db', async () => {
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
|
||||
expect(screen.getByTestId(selectors.EnableAnnotationsSwitch)).toBeEnabled();
|
||||
expect(screen.getByTestId(selectors.EnableAnnotationsSwitch)).toBeChecked();
|
||||
});
|
||||
it('when fetch is done, then loader spinner is gone, inputs are disabled and save button is enabled', async () => {
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
@ -253,13 +264,14 @@ describe('SharePublic - Already persisted', () => {
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
expect(screen.getByTestId(selectors.CopyUrlInput)).toBeInTheDocument();
|
||||
});
|
||||
it('when pubdash is disabled in the db, then link url is not available', async () => {
|
||||
it('when pubdash is disabled in the db, then link url is not available and annotations toggle is disabled', async () => {
|
||||
server.use(
|
||||
rest.get('/api/dashboards/uid/:uId/public-config', (req, res, ctx) => {
|
||||
return res(
|
||||
ctx.status(200),
|
||||
ctx.json({
|
||||
isEnabled: false,
|
||||
annotationsEnabled: false,
|
||||
uid: 'a-uid',
|
||||
dashboardUid: req.params.uId,
|
||||
accessToken: 'an-access-token',
|
||||
@ -272,6 +284,7 @@ describe('SharePublic - Already persisted', () => {
|
||||
await waitForElementToBeRemoved(screen.getByTestId('Spinner'));
|
||||
|
||||
expect(screen.queryByTestId(selectors.CopyUrlInput)).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId(selectors.EnableAnnotationsSwitch)).not.toBeChecked();
|
||||
});
|
||||
it('when pubdash is disabled by the user, then link url is not available', async () => {
|
||||
await renderSharePublicDashboard({ panel: mockPanel, dashboard: mockDashboard, onDismiss: () => {} });
|
||||
|
@ -44,6 +44,7 @@ export const SharePublicDashboard = (props: Props) => {
|
||||
isEnabled: false,
|
||||
wasTouched: false,
|
||||
});
|
||||
const [annotationsEnabled, setAnnotationsEnabled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
reportInteraction('grafana_dashboards_public_share_viewed');
|
||||
@ -56,6 +57,7 @@ export const SharePublicDashboard = (props: Props) => {
|
||||
datasources: true,
|
||||
usage: true,
|
||||
});
|
||||
setAnnotationsEnabled(!!publicDashboard?.annotationsEnabled);
|
||||
}
|
||||
|
||||
setEnabledSwitch((prevState) => ({ ...prevState, isEnabled: !!publicDashboard?.isEnabled }));
|
||||
@ -80,7 +82,7 @@ export const SharePublicDashboard = (props: Props) => {
|
||||
|
||||
saveConfig({
|
||||
dashboard: props.dashboard,
|
||||
payload: { ...publicDashboard!, isEnabled: enabledSwitch.isEnabled },
|
||||
payload: { ...publicDashboard!, isEnabled: enabledSwitch.isEnabled, annotationsEnabled },
|
||||
});
|
||||
};
|
||||
|
||||
@ -124,12 +126,14 @@ export const SharePublicDashboard = (props: Props) => {
|
||||
</div>
|
||||
<hr />
|
||||
<Configuration
|
||||
isAnnotationsEnabled={annotationsEnabled}
|
||||
dashboard={props.dashboard}
|
||||
disabled={!hasWritePermissions || isLoading || isFetchingError}
|
||||
isPubDashEnabled={enabledSwitch.isEnabled}
|
||||
onToggleEnabled={() =>
|
||||
setEnabledSwitch((prevState) => ({ isEnabled: !prevState.isEnabled, wasTouched: true }))
|
||||
}
|
||||
onToggleAnnotations={() => setAnnotationsEnabled((prevState) => !prevState)}
|
||||
/>
|
||||
{publicDashboardPersisted(publicDashboard) && enabledSwitch.isEnabled && (
|
||||
<Field label="Link URL" className={styles.publicUrl}>
|
||||
|
@ -4,6 +4,7 @@ import { DashboardDataDTO, DashboardMeta } from 'app/types/dashboard';
|
||||
|
||||
export interface PublicDashboard {
|
||||
accessToken?: string;
|
||||
annotationsEnabled: boolean;
|
||||
isEnabled: boolean;
|
||||
uid: string;
|
||||
dashboardUid: string;
|
||||
|
Loading…
Reference in New Issue
Block a user