Dashboards: Remove dummy trim dashboard api (#77249)

Co-authored-by: nikimanoledaki <niki.manoledaki@grafana.com>
This commit is contained in:
Ryan McKinley 2023-11-02 08:35:14 -07:00 committed by GitHub
parent e714c9303e
commit 45d59cf31b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 12 additions and 208 deletions

View File

@ -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 |

View File

@ -18,7 +18,6 @@
* @public
*/
export interface FeatureToggles {
trimDefaults?: boolean;
disableEnvelopeEncryption?: boolean;
['live-service-web-worker']?: boolean;
queryOverLive?: boolean;

View File

@ -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))

View File

@ -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

View File

@ -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"`
}

View File

@ -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)",

View File

@ -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

1 Name Stage Owner requiresDevMode RequiresLicense RequiresRestart FrontendOnly
trimDefaults preview @grafana/grafana-as-code false false false false
2 disableEnvelopeEncryption GA @grafana/grafana-as-code false false false false
3 live-service-web-worker experimental @grafana/grafana-app-platform-squad false false false true
4 queryOverLive experimental @grafana/grafana-app-platform-squad false false false true

View File

@ -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"

View File

@ -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,

View File

@ -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",

View File

@ -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<DashboardScene>;
isSharingExternally?: boolean;
shouldTrimDefaults?: boolean;
isViewingJSON?: boolean;
}
@ -35,7 +32,6 @@ export class ShareExportTab extends SceneObjectBase<ShareExportTabState> {
constructor(state: Omit<ShareExportTabState, 'panelRef'>) {
super({
isSharingExternally: false,
shouldTrimDefaults: false,
isViewingJSON: false,
...state,
});
@ -51,12 +47,6 @@ export class ShareExportTab extends SceneObjectBase<ShareExportTabState> {
});
};
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<ShareExportTabState> {
}
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<ShareExportTabState> {
});
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<ShareExportTab>) {
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<ShareExportTab>)
onChange={model.onShareExternallyChange}
/>
</Field>
{config.featureToggles.trimDefaults && (
<Field label={exportDefaultTranslation}>
<Switch id="trim-defaults-toggle" value={shouldTrimDefaults} onChange={model.onTrimDefaultsChange} />
</Field>
)}
</VerticalGroup>
<Modal.ButtonRow>

View File

@ -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<Props, State> {
@ -28,7 +25,6 @@ export class ShareExport extends PureComponent<Props, State> {
super(props);
this.state = {
shareExternally: false,
trimDefaults: false,
};
this.exporter = new DashboardExporter();
@ -40,69 +36,29 @@ export class ShareExport extends PureComponent<Props, State> {
});
};
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<Props, State> {
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 (
<>
<p className="share-modal-info-text">
@ -146,11 +99,6 @@ export class ShareExport extends PureComponent<Props, State> {
<Field label={exportExternallyTranslation}>
<Switch id="share-externally-toggle" value={shareExternally} onChange={this.onShareExternallyChange} />
</Field>
{config.featureToggles.trimDefaults && (
<Field label={exportDefaultTranslation}>
<Switch id="trim-defaults-toggle" value={trimDefaults} onChange={this.onTrimDefaultsChange} />
</Field>
)}
<Modal.ButtonRow>
<Button variant="secondary" onClick={onDismiss} fill="outline">
<Trans i18nKey="share-modal.export.cancel-button">Cancel</Trans>

View File

@ -1044,7 +1044,6 @@
"cancel-button": "Abbrechen",
"info-text": "Dieses Dashboard exportieren.",
"save-button": "In Datei speichern …",
"share-default-label": "Export mit entfernten Standardwerten",
"share-externally-label": "Export für externe Freigabe",
"view-button": "JSON anzeigen"
},

View File

@ -1044,7 +1044,6 @@
"cancel-button": "Cancel",
"info-text": "Export this dashboard.",
"save-button": "Save to file",
"share-default-label": "Export with default values removed",
"share-externally-label": "Export for sharing externally",
"view-button": "View JSON"
},

View File

@ -1050,7 +1050,6 @@
"cancel-button": "Cancelar",
"info-text": "Exporte este panel de control.",
"save-button": "Guardar en archivo",
"share-default-label": "Exportar con los valores predeterminados eliminados",
"share-externally-label": "Exportar para compartir externamente",
"view-button": "Ver JSON"
},

View File

@ -1050,7 +1050,6 @@
"cancel-button": "Annuler",
"info-text": "Exporter ce tableau de bord.",
"save-button": "Enregistrer dans un fichier",
"share-default-label": "Exporter avec les valeurs par défaut supprimées",
"share-externally-label": "Exporter pour un partage externe",
"view-button": "Afficher au format JSON"
},

View File

@ -1044,7 +1044,6 @@
"cancel-button": "Cäʼnčęľ",
"info-text": "Ēχpőřŧ ŧĥįş đäşĥþőäřđ.",
"save-button": "Ŝävę ŧő ƒįľę",
"share-default-label": "Ēχpőřŧ ŵįŧĥ đęƒäūľŧ väľūęş řęmővęđ",
"share-externally-label": "Ēχpőřŧ ƒőř şĥäřįʼnģ ęχŧęřʼnäľľy",
"view-button": "Vįęŵ ĴŜØŃ"
},

View File

@ -1038,7 +1038,6 @@
"cancel-button": "取消",
"info-text": "导出此仪表板。",
"save-button": "保存至文件",
"share-default-label": "导出时清除默认值",
"share-externally-label": "导出以供外部分享",
"view-button": "查看 JSON"
},

View File

@ -16569,37 +16569,6 @@
]
}
},
"/dashboards/trim": {
"post": {
"operationId": "trimDashboard",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrimDashboardCommand"
}
}
},
"required": true,
"x-originalParamName": "Body"
},
"responses": {
"200": {
"$ref": "#/components/responses/trimDashboardResponse"
},
"401": {
"$ref": "#/components/responses/unauthorisedError"
},
"500": {
"$ref": "#/components/responses/internalServerError"
}
},
"summary": "Trim defaults from dashboard.",
"tags": [
"dashboards"
]
}
},
"/dashboards/uid/{dashboardUid}/public-dashboards": {
"get": {
"description": "Get public dashboard by dashboardUid",