Dashboard: Enable JSON editor for Schema v2 (#102466)
Co-authored-by: Haris Rozajac <haris.rozajac12@gmail.com>
This commit is contained in:
co-authored by
Haris Rozajac
parent
7ae86ee017
commit
3c3e5754b3
@@ -4,11 +4,13 @@ import { useState } from 'react';
|
||||
import { GrafanaTheme2, PageLayoutType } from '@grafana/data';
|
||||
import { SceneComponentProps, SceneObjectBase, sceneUtils } from '@grafana/scenes';
|
||||
import { Dashboard } from '@grafana/schema';
|
||||
import { Spec as DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen';
|
||||
import { Alert, Box, Button, CodeEditor, Stack, useStyles2 } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { getDashboardAPI } from 'app/features/dashboard/api/dashboard_api';
|
||||
import { getPrettyJSON } from 'app/features/inspector/utils/utils';
|
||||
import { DashboardDTO, SaveDashboardResponseDTO } from 'app/types';
|
||||
import { DashboardDataDTO, SaveDashboardResponseDTO } from 'app/types';
|
||||
|
||||
import {
|
||||
NameAlreadyExistsError,
|
||||
@@ -17,10 +19,10 @@ import {
|
||||
isVersionMismatchError,
|
||||
} from '../saving/shared';
|
||||
import { useSaveDashboard } from '../saving/useSaveDashboard';
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { DashboardScene, isV2Dashboard } from '../scene/DashboardScene';
|
||||
import { NavToolbarActions } from '../scene/NavToolbarActions';
|
||||
import { transformSaveModelSchemaV2ToScene } from '../serialization/transformSaveModelSchemaV2ToScene';
|
||||
import { transformSaveModelToScene } from '../serialization/transformSaveModelToScene';
|
||||
import { transformSceneToSaveModel } from '../serialization/transformSceneToSaveModel';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { DashboardEditView, DashboardEditViewState, useDashboardEditPageNav } from './utils';
|
||||
@@ -46,9 +48,8 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
|
||||
return getDashboardSceneFor(this);
|
||||
}
|
||||
|
||||
public getSaveModel(): Dashboard {
|
||||
const dashboard = this.getDashboard();
|
||||
return transformSceneToSaveModel(dashboard);
|
||||
public getSaveModel(): Dashboard | DashboardV2Spec {
|
||||
return this.getDashboard().getSaveModel();
|
||||
}
|
||||
|
||||
public getJsonText(): string {
|
||||
@@ -60,21 +61,34 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
|
||||
this.setState({ jsonText: value });
|
||||
};
|
||||
|
||||
public onSaveSuccess = (result: SaveDashboardResponseDTO) => {
|
||||
const jsonModel = JSON.parse(this.state.jsonText);
|
||||
public onSaveSuccess = async (result: SaveDashboardResponseDTO) => {
|
||||
const jsonModel: DashboardDataDTO | DashboardV2Spec = JSON.parse(this.state.jsonText);
|
||||
const dashboard = this.getDashboard();
|
||||
jsonModel.version = result.version;
|
||||
|
||||
const rsp: DashboardDTO = {
|
||||
dashboard: jsonModel,
|
||||
meta: dashboard.state.meta,
|
||||
};
|
||||
const newDashboardScene = transformSaveModelToScene(rsp);
|
||||
const newState = sceneUtils.cloneSceneObjectState(newDashboardScene.state);
|
||||
const isV2 = isV2Dashboard(jsonModel);
|
||||
let newDashboardScene: DashboardScene;
|
||||
|
||||
dashboard.pauseTrackingChanges();
|
||||
dashboard.setInitialSaveModel(rsp.dashboard);
|
||||
dashboard.setState(newState);
|
||||
if (isV2) {
|
||||
// FIXME: We could avoid this call by storing the entire dashboard DTO as initial dashboard scene instead of only the spec and metadata
|
||||
const dto = await getDashboardAPI('v2').getDashboardDTO(result.uid);
|
||||
newDashboardScene = transformSaveModelSchemaV2ToScene(dto);
|
||||
const newState = sceneUtils.cloneSceneObjectState(newDashboardScene.state);
|
||||
|
||||
dashboard.pauseTrackingChanges();
|
||||
dashboard.setInitialSaveModel(dto.spec, dto.metadata);
|
||||
dashboard.setState(newState);
|
||||
} else {
|
||||
jsonModel.version = result.version;
|
||||
newDashboardScene = transformSaveModelToScene({
|
||||
dashboard: jsonModel,
|
||||
meta: dashboard.state.meta,
|
||||
});
|
||||
const newState = sceneUtils.cloneSceneObjectState(newDashboardScene.state);
|
||||
|
||||
dashboard.pauseTrackingChanges();
|
||||
dashboard.setInitialSaveModel(jsonModel, dashboard.state.meta);
|
||||
dashboard.setState(newState);
|
||||
}
|
||||
|
||||
this.setState({ jsonText: this.getJsonText() });
|
||||
};
|
||||
@@ -94,11 +108,12 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
|
||||
folderUid: dashboard.state.meta.folderUid,
|
||||
overwrite,
|
||||
rawDashboardJSON: JSON.parse(model.state.jsonText),
|
||||
k8s: dashboard.state.meta.k8s,
|
||||
});
|
||||
|
||||
setIsSaving(true);
|
||||
if (result.status === 'success') {
|
||||
model.onSaveSuccess(result);
|
||||
await model.onSaveSuccess(result);
|
||||
setIsSaving(false);
|
||||
} else {
|
||||
setIsSaving(true);
|
||||
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
AnnoKeyFolderId,
|
||||
AnnoKeyFolderTitle,
|
||||
AnnoKeyFolderUrl,
|
||||
AnnoKeyMessage,
|
||||
AnnoKeySavedFromUI,
|
||||
DeprecatedInternalId,
|
||||
} from 'app/features/apiserver/types';
|
||||
|
||||
@@ -58,6 +60,10 @@ jest.mock('@grafana/runtime', () => ({
|
||||
}),
|
||||
config: {
|
||||
...jest.requireActual('@grafana/runtime').config,
|
||||
buildInfo: {
|
||||
...jest.requireActual('@grafana/runtime').config.buildInfo,
|
||||
versionString: '10.0.0',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -138,6 +144,7 @@ describe('v2 dashboard API', () => {
|
||||
|
||||
annotations: {
|
||||
[AnnoKeyFolder]: 'new-folder',
|
||||
[AnnoKeyMessage]: 'test save',
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -205,6 +212,7 @@ describe('v2 dashboard API', () => {
|
||||
name: 'existing-dash',
|
||||
annotations: {
|
||||
[AnnoKeyFolder]: 'folderUidXyz',
|
||||
[AnnoKeySavedFromUI]: '10.0.0',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
|
||||
@@ -148,8 +148,8 @@ export class DashboardLoaderSrv extends DashboardLoaderSrvBase<DashboardDTO> {
|
||||
return result;
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('Failed to load dashboard', e);
|
||||
if (isFetchError(e) && !(e instanceof DashboardVersionError)) {
|
||||
console.error('Failed to load dashboard', e);
|
||||
e.isHandled = true;
|
||||
if (e.status === 404) {
|
||||
appEvents.emit(AppEvents.alertError, ['Dashboard not found']);
|
||||
@@ -216,8 +216,8 @@ export class DashboardLoaderSrvV2 extends DashboardLoaderSrvBase<DashboardWithAc
|
||||
return result;
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('Failed to load dashboard', e);
|
||||
if (isFetchError(e) && !(e instanceof DashboardVersionError)) {
|
||||
console.error('Failed to load dashboard', e);
|
||||
e.isHandled = true;
|
||||
if (e.status === 404) {
|
||||
appEvents.emit(AppEvents.alertError, ['Dashboard not found']);
|
||||
|
||||
@@ -56,6 +56,8 @@ export class DashboardSrv {
|
||||
return getDashboardAPI().saveDashboard({
|
||||
dashboard: parsedJson,
|
||||
folderUid: this.dashboard?.meta.folderUid || parsedJson.folderUid,
|
||||
message: 'Edit Dashboard JSON',
|
||||
k8s: this.dashboard?.meta.k8s,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user