From 0b8fb543fcb32aa3c3a62403e46676c4088d5076 Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Fri, 21 Oct 2022 13:42:14 -0600 Subject: [PATCH] Public Dashboards: Can toggle annotations in modal (#57312) adds toggle for pubdash annotations --- .../dashboards/dashboard-public/index.md | 3 +- .../src/selectors/pages.ts | 1 + .../publicdashboards/database/database.go | 3 +- .../database/database_test.go | 81 ++++++++++--------- .../publicdashboards/models/models.go | 13 +-- .../publicdashboards/service/query.go | 6 +- .../publicdashboards/service/query_test.go | 53 +++++++++--- .../publicdashboards/service/service.go | 28 ++++--- .../publicdashboards/service/service_test.go | 23 +++--- .../migrations/dashboard_public_mig.go | 9 +++ .../SharePublicDashboard/Configuration.tsx | 17 ++++ .../SharePublicDashboard.test.tsx | 15 +++- .../SharePublicDashboard.tsx | 6 +- .../SharePublicDashboardUtils.ts | 1 + 14 files changed, 176 insertions(+), 83 deletions(-) diff --git a/docs/sources/dashboards/dashboard-public/index.md b/docs/sources/dashboards/dashboard-public/index.md index d23f206b1a5..63a49a758dd 100644 --- a/docs/sources/dashboards/dashboard-public/index.md +++ b/docs/sources/dashboards/dashboard-public/index.md @@ -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. diff --git a/packages/grafana-e2e-selectors/src/selectors/pages.ts b/packages/grafana-e2e-selectors/src/selectors/pages.ts index e8fe2aa09bf..ef80af69a29 100644 --- a/packages/grafana-e2e-selectors/src/selectors/pages.ts +++ b/packages/grafana-e2e-selectors/src/selectors/pages.ts @@ -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', diff --git a/pkg/services/publicdashboards/database/database.go b/pkg/services/publicdashboards/database/database.go index f6ef44a7009..9d1a7f7fc79 100644 --- a/pkg/services/publicdashboards/database/database.go +++ b/pkg/services/publicdashboards/database/database.go @@ -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"), diff --git a/pkg/services/publicdashboards/database/database_test.go b/pkg/services/publicdashboards/database/database_test.go index 17d8590551a..17706a5d929 100644 --- a/pkg/services/publicdashboards/database/database_test.go +++ b/pkg/services/publicdashboards/database/database_test.go @@ -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) }) } diff --git a/pkg/services/publicdashboards/models/models.go b/pkg/services/publicdashboards/models/models.go index 0827ed0ef68..5051599df82 100644 --- a/pkg/services/publicdashboards/models/models.go +++ b/pkg/services/publicdashboards/models/models.go @@ -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"` diff --git a/pkg/services/publicdashboards/service/query.go b/pkg/services/publicdashboards/service/query.go index a5de8394925..d06e73911c6 100644 --- a/pkg/services/publicdashboards/service/query.go +++ b/pkg/services/publicdashboards/service/query.go @@ -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 diff --git a/pkg/services/publicdashboards/service/query_test.go b/pkg/services/publicdashboards/service/query_test.go index 1ce038cb37f..1adb772c508 100644 --- a/pkg/services/publicdashboards/service/query_test.go +++ b/pkg/services/publicdashboards/service/query_test.go @@ -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() diff --git a/pkg/services/publicdashboards/service/service.go b/pkg/services/publicdashboards/service/service.go index 636e14489a2..61923f83b15 100644 --- a/pkg/services/publicdashboards/service/service.go +++ b/pkg/services/publicdashboards/service/service.go @@ -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(), }, } diff --git a/pkg/services/publicdashboards/service/service_test.go b/pkg/services/publicdashboards/service/service_test.go index 3535323d239..b39a14811e1 100644 --- a/pkg/services/publicdashboards/service/service_test.go +++ b/pkg/services/publicdashboards/service/service_test.go @@ -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) diff --git a/pkg/services/sqlstore/migrations/dashboard_public_mig.go b/pkg/services/sqlstore/migrations/dashboard_public_mig.go index b3722b621e7..1dfc3512018 100644 --- a/pkg/services/sqlstore/migrations/dashboard_public_mig.go +++ b/pkg/services/sqlstore/migrations/dashboard_public_mig.go @@ -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", + })) } diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/Configuration.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/Configuration.tsx index e09f0564954..41691fd3a35 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/Configuration.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/Configuration.tsx @@ -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 = ({ {}} /> + + + { + reportInteraction('grafana_dashboards_annotations_clicked', { + action: isAnnotationsEnabled ? 'disable' : 'enable', + }); + onToggleAnnotations(); + }} + /> + { 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: () => {} }); diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx index bd17032e58c..36c801ea48a 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx @@ -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) => {
setEnabledSwitch((prevState) => ({ isEnabled: !prevState.isEnabled, wasTouched: true })) } + onToggleAnnotations={() => setAnnotationsEnabled((prevState) => !prevState)} /> {publicDashboardPersisted(publicDashboard) && enabledSwitch.isEnabled && ( diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils.ts b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils.ts index 1cbfc9f50c5..f2409cb4624 100644 --- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils.ts +++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils.ts @@ -4,6 +4,7 @@ import { DashboardDataDTO, DashboardMeta } from 'app/types/dashboard'; export interface PublicDashboard { accessToken?: string; + annotationsEnabled: boolean; isEnabled: boolean; uid: string; dashboardUid: string;