diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 705b76079a0..e4ca209463f 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -59,7 +59,6 @@ Some features are enabled by default. You can disable these feature by setting t | Feature toggle name | Description | | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `trimDefaults` | Use cue schema to remove values that will be applied automatically | | `panelTitleSearch` | Search for dashboards using panel title | | `migrationLocking` | Lock database during migrations | | `correlations` | Correlations page | diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index b99a9573f11..256983e6fda 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -18,7 +18,6 @@ * @public */ export interface FeatureToggles { - trimDefaults?: boolean; disableEnvelopeEncryption?: boolean; ['live-service-web-worker']?: boolean; queryOverLive?: boolean; diff --git a/pkg/api/api.go b/pkg/api/api.go index 15bee759b6d..ee3c5a828a6 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -471,7 +471,6 @@ func (hs *HTTPServer) registerRoutes() { dashboardRoute.Post("/calculate-diff", authorize(ac.EvalPermission(dashboards.ActionDashboardsWrite)), routing.Wrap(hs.CalculateDashboardDiff)) dashboardRoute.Post("/validate", authorize(ac.EvalPermission(dashboards.ActionDashboardsWrite)), routing.Wrap(hs.ValidateDashboard)) - dashboardRoute.Post("/trim", routing.Wrap(hs.TrimDashboard)) dashboardRoute.Post("/db", authorize(ac.EvalAny(ac.EvalPermission(dashboards.ActionDashboardsCreate), ac.EvalPermission(dashboards.ActionDashboardsWrite))), routing.Wrap(hs.PostDashboard)) dashboardRoute.Get("/home", routing.Wrap(hs.GetHomeDashboard)) diff --git a/pkg/api/dashboard.go b/pkg/api/dashboard.go index 008031c85cc..dd70a773dd3 100644 --- a/pkg/api/dashboard.go +++ b/pkg/api/dashboard.go @@ -68,32 +68,6 @@ func dashboardGuardianResponse(err error) response.Response { return response.Error(http.StatusForbidden, "Access denied to this dashboard", nil) } -// swagger:route POST /dashboards/trim dashboards trimDashboard -// -// Trim defaults from dashboard. -// -// Responses: -// 200: trimDashboardResponse -// 401: unauthorisedError -// 500: internalServerError -func (hs *HTTPServer) TrimDashboard(c *contextmodel.ReqContext) response.Response { - cmd := dashboards.TrimDashboardCommand{} - if err := web.Bind(c.Req, &cmd); err != nil { - return response.Error(http.StatusBadRequest, "bad request data", err) - } - dash := cmd.Dashboard - meta := cmd.Meta - - // TODO temporarily just return the input as a no-op while we convert to thema calls - dto := dtos.TrimDashboardFullWithMeta{ - Dashboard: dash, - Meta: meta, - } - - c.TimeRequest(metrics.MApiDashboardGet) - return response.JSON(http.StatusOK, dto) -} - // swagger:route GET /dashboards/uid/{uid} dashboards getDashboardByUID // // Get dashboard by uid. @@ -1233,13 +1207,6 @@ type CalcDashboardDiffParams struct { } } -// swagger:parameters trimDashboard -type TrimDashboardParams struct { - // in:body - // required:true - Body dashboards.TrimDashboardCommand -} - // swagger:response dashboardResponse type DashboardResponse struct { // The response message @@ -1315,12 +1282,6 @@ type CalculateDashboardDiffResponse struct { Body []byte `json:"body"` } -// swagger:response trimDashboardResponse -type TrimDashboardResponse struct { - // in: body - Body dtos.TrimDashboardFullWithMeta `json:"body"` -} - // swagger:response getHomeDashboardResponse type GetHomeDashboardResponse struct { // in: body diff --git a/pkg/api/dtos/dashboard.go b/pkg/api/dtos/dashboard.go index 8e920a20e12..ef4d34864dc 100644 --- a/pkg/api/dtos/dashboard.go +++ b/pkg/api/dtos/dashboard.go @@ -51,11 +51,6 @@ type DashboardFullWithMeta struct { Dashboard *simplejson.Json `json:"dashboard"` } -type TrimDashboardFullWithMeta struct { - Meta *simplejson.Json `json:"meta"` - Dashboard *simplejson.Json `json:"dashboard"` -} - type DashboardRedirect struct { RedirectUri string `json:"redirectUri"` } diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 3db02aff0bf..45267daa23f 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -9,12 +9,6 @@ package featuremgmt var ( // Register each toggle here standardFeatureFlags = []FeatureFlag{ - { - Name: "trimDefaults", - Description: "Use cue schema to remove values that will be applied automatically", - Stage: FeatureStagePublicPreview, - Owner: grafanaAsCodeSquad, - }, { Name: "disableEnvelopeEncryption", Description: "Disable envelope encryption (emergency only)", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 1dfdae95a8d..5b76e116dba 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -1,5 +1,4 @@ Name,Stage,Owner,requiresDevMode,RequiresLicense,RequiresRestart,FrontendOnly -trimDefaults,preview,@grafana/grafana-as-code,false,false,false,false disableEnvelopeEncryption,GA,@grafana/grafana-as-code,false,false,false,false live-service-web-worker,experimental,@grafana/grafana-app-platform-squad,false,false,false,true queryOverLive,experimental,@grafana/grafana-app-platform-squad,false,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 24e183d6ac1..10325675080 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -7,10 +7,6 @@ package featuremgmt const ( - // FlagTrimDefaults - // Use cue schema to remove values that will be applied automatically - FlagTrimDefaults = "trimDefaults" - // FlagDisableEnvelopeEncryption // Disable envelope encryption (emergency only) FlagDisableEnvelopeEncryption = "disableEnvelopeEncryption" diff --git a/pkg/services/featuremgmt/usage_stats_test.go b/pkg/services/featuremgmt/usage_stats_test.go index 1496bb055c4..03c7fe0c2df 100644 --- a/pkg/services/featuremgmt/usage_stats_test.go +++ b/pkg/services/featuremgmt/usage_stats_test.go @@ -9,7 +9,6 @@ import ( func TestFeatureUsageStats(t *testing.T) { featureManagerWithAllFeatures := WithFeatures( - "trimDefaults", "database_metrics", "live-config", "UPPER_SNAKE_CASE", @@ -17,7 +16,6 @@ func TestFeatureUsageStats(t *testing.T) { ) require.Equal(t, map[string]any{ - "stats.features.trim_defaults.count": 1, "stats.features.database_metrics.count": 1, "stats.features.live_config.count": 1, "stats.features.upper_snake_case.count": 1, diff --git a/public/api-merged.json b/public/api-merged.json index b61b4a4aeb0..bf8b1330c52 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -3926,36 +3926,6 @@ } } }, - "/dashboards/trim": { - "post": { - "tags": [ - "dashboards" - ], - "summary": "Trim defaults from dashboard.", - "operationId": "trimDashboard", - "parameters": [ - { - "name": "Body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/TrimDashboardCommand" - } - } - ], - "responses": { - "200": { - "$ref": "#/responses/trimDashboardResponse" - }, - "401": { - "$ref": "#/responses/unauthorisedError" - }, - "500": { - "$ref": "#/responses/internalServerError" - } - } - } - }, "/dashboards/uid/{dashboardUid}/public-dashboards": { "get": { "description": "Get public dashboard by dashboardUid", diff --git a/public/app/features/dashboard-scene/sharing/ShareExportTab.tsx b/public/app/features/dashboard-scene/sharing/ShareExportTab.tsx index e6a9831ca34..352f8438997 100644 --- a/public/app/features/dashboard-scene/sharing/ShareExportTab.tsx +++ b/public/app/features/dashboard-scene/sharing/ShareExportTab.tsx @@ -3,7 +3,6 @@ import React from 'react'; import { useAsync } from 'react-use'; import AutoSizer from 'react-virtualized-auto-sizer'; -import { config, getBackendSrv } from '@grafana/runtime'; import { SceneComponentProps, SceneObjectBase, SceneObjectRef } from '@grafana/scenes'; import { Button, ClipboardButton, CodeEditor, Field, Modal, Switch, VerticalGroup } from '@grafana/ui'; import { t, Trans } from 'app/core/internationalization'; @@ -18,12 +17,10 @@ import { transformSceneToSaveModel } from '../serialization/transformSceneToSave import { SceneShareTabState } from './types'; const exportExternallyTranslation = t('share-modal.export.share-externally-label', `Export for sharing externally`); -const exportDefaultTranslation = t('share-modal.export.share-default-label', `Export with default values removed`); interface ShareExportTabState extends SceneShareTabState { dashboardRef: SceneObjectRef; isSharingExternally?: boolean; - shouldTrimDefaults?: boolean; isViewingJSON?: boolean; } @@ -35,7 +32,6 @@ export class ShareExportTab extends SceneObjectBase { constructor(state: Omit) { super({ isSharingExternally: false, - shouldTrimDefaults: false, isViewingJSON: false, ...state, }); @@ -51,12 +47,6 @@ export class ShareExportTab extends SceneObjectBase { }); }; - public onTrimDefaultsChange = () => { - this.setState({ - shouldTrimDefaults: !this.state.shouldTrimDefaults, - }); - }; - public onViewJSON = () => { this.setState({ isViewingJSON: !this.state.isViewingJSON, @@ -68,19 +58,14 @@ export class ShareExportTab extends SceneObjectBase { } public async getExportableDashboardJson() { - const { dashboardRef, isSharingExternally, shouldTrimDefaults } = this.state; + const { dashboardRef, isSharingExternally } = this.state; const saveModel = transformSceneToSaveModel(dashboardRef.resolve()); const exportable = isSharingExternally ? await this._exporter.makeExportable(new DashboardModel(saveModel)) : saveModel; - if (shouldTrimDefaults) { - const trimmed = await getBackendSrv().post('/api/dashboards/trim', { dashboard: exportable }); - return trimmed.dashboard; - } else { - return exportable; - } + return exportable; } public async onSaveAsFile() { @@ -92,13 +77,17 @@ export class ShareExportTab extends SceneObjectBase { }); const time = new Date().getTime(); - saveAs(blob, `${dashboardJson.title}-${time}.json`); + let title = 'dashboard'; + if ('title' in dashboardJson && dashboardJson.title) { + title = dashboardJson.title; + } + saveAs(blob, `${title}-${time}.json`); trackDashboardSharingActionPerType('save_export', shareDashboardType.export); } } function ShareExportTabRenderer({ model }: SceneComponentProps) { - const { isSharingExternally, shouldTrimDefaults, isViewingJSON, modalRef } = model.useState(); + const { isSharingExternally, isViewingJSON, modalRef } = model.useState(); const dashboardJson = useAsync(async () => { if (isViewingJSON) { @@ -124,12 +113,6 @@ function ShareExportTabRenderer({ model }: SceneComponentProps) onChange={model.onShareExternallyChange} /> - - {config.featureToggles.trimDefaults && ( - - - - )} diff --git a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx index a2fbf2013b4..a33f0bd39ce 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareExport.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareExport.tsx @@ -1,11 +1,9 @@ import { saveAs } from 'file-saver'; import React, { PureComponent } from 'react'; -import { config } from '@grafana/runtime'; import { Button, Field, Modal, Switch } from '@grafana/ui'; import { appEvents } from 'app/core/core'; import { t, Trans } from 'app/core/internationalization'; -import { getBackendSrv } from 'app/core/services/backend_srv'; import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal'; import { ShowModalReactEvent } from 'app/types/events'; @@ -18,7 +16,6 @@ interface Props extends ShareModalTabProps {} interface State { shareExternally: boolean; - trimDefaults: boolean; } export class ShareExport extends PureComponent { @@ -28,7 +25,6 @@ export class ShareExport extends PureComponent { super(props); this.state = { shareExternally: false, - trimDefaults: false, }; this.exporter = new DashboardExporter(); @@ -40,69 +36,29 @@ export class ShareExport extends PureComponent { }); }; - onTrimDefaultsChange = () => { - this.setState({ - trimDefaults: !this.state.trimDefaults, - }); - }; - onSaveAsFile = () => { const { dashboard } = this.props; const { shareExternally } = this.state; - const { trimDefaults } = this.state; if (shareExternally) { this.exporter.makeExportable(dashboard).then((dashboardJson) => { - if (trimDefaults) { - getBackendSrv() - .post('/api/dashboards/trim', { dashboard: dashboardJson }) - .then((resp) => { - this.openSaveAsDialog(resp.dashboard); - }); - } else { - this.openSaveAsDialog(dashboardJson); - } + this.openSaveAsDialog(dashboardJson); }); } else { - if (trimDefaults) { - getBackendSrv() - .post('/api/dashboards/trim', { dashboard: dashboard.getSaveModelClone() }) - .then((resp) => { - this.openSaveAsDialog(resp.dashboard); - }); - } else { - this.openSaveAsDialog(dashboard.getSaveModelClone()); - } + this.openSaveAsDialog(dashboard.getSaveModelClone()); } }; onViewJson = () => { const { dashboard } = this.props; const { shareExternally } = this.state; - const { trimDefaults } = this.state; if (shareExternally) { this.exporter.makeExportable(dashboard).then((dashboardJson) => { - if (trimDefaults) { - getBackendSrv() - .post('/api/dashboards/trim', { dashboard: dashboardJson }) - .then((resp) => { - this.openJsonModal(resp.dashboard); - }); - } else { - this.openJsonModal(dashboardJson); - } + this.openJsonModal(dashboardJson); }); } else { - if (trimDefaults) { - getBackendSrv() - .post('/api/dashboards/trim', { dashboard: dashboard.getSaveModelClone() }) - .then((resp) => { - this.openJsonModal(resp.dashboard); - }); - } else { - this.openJsonModal(dashboard.getSaveModelClone()); - } + this.openJsonModal(dashboard.getSaveModelClone()); } }; @@ -132,12 +88,9 @@ export class ShareExport extends PureComponent { render() { const { onDismiss } = this.props; const { shareExternally } = this.state; - const { trimDefaults } = this.state; const exportExternallyTranslation = t('share-modal.export.share-externally-label', `Export for sharing externally`); - const exportDefaultTranslation = t('share-modal.export.share-default-label', `Export with default values removed`); - return ( <>

@@ -146,11 +99,6 @@ export class ShareExport extends PureComponent { - {config.featureToggles.trimDefaults && ( - - - - )}