mirror of https://github.com/grafana/grafana.git
SaveProvisionedDashboardForm: Reset dashboard dirty state after provisioned dashboard save (#110571)
* SaveProvisionedDashboardForm: Bugfix when changes are saved, save button still enabled
This commit is contained in:
parent
d715bda8af
commit
24107abea3
|
@ -2040,21 +2040,6 @@
|
||||||
"count": 2
|
"count": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingGroupCondition.tsx": {
|
|
||||||
"no-restricted-syntax": {
|
|
||||||
"count": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingGroupVisibility.tsx": {
|
|
||||||
"no-restricted-syntax": {
|
|
||||||
"count": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingTimeRangeSize.tsx": {
|
|
||||||
"no-restricted-syntax": {
|
|
||||||
"count": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"public/app/features/dashboard-scene/edit-pane/DashboardEditPaneRenderer.tsx": {
|
"public/app/features/dashboard-scene/edit-pane/DashboardEditPaneRenderer.tsx": {
|
||||||
"@typescript-eslint/consistent-type-assertions": {
|
"@typescript-eslint/consistent-type-assertions": {
|
||||||
"count": 1
|
"count": 1
|
||||||
|
|
|
@ -1276,9 +1276,10 @@ describe('UnifiedDashboardScenePageStateManager', () => {
|
||||||
await loader.loadDashboard({ uid: 'blah-blah', route: DashboardRoutes.Provisioning });
|
await loader.loadDashboard({ uid: 'blah-blah', route: DashboardRoutes.Provisioning });
|
||||||
|
|
||||||
expect(loader.state.dashboard).toBeDefined();
|
expect(loader.state.dashboard).toBeDefined();
|
||||||
expect(loader.state.dashboard!.serializer.initialSaveModel).toEqual(
|
expect(loader.state.dashboard!.serializer.initialSaveModel).toEqual({
|
||||||
v1ProvisionedDashboardResource.resource.dryRun.spec
|
...v1ProvisionedDashboardResource.resource.dryRun.spec,
|
||||||
);
|
version: v1ProvisionedDashboardResource.resource.dryRun.metadata.generation || 0,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should load a provisioned v2 dashboard', async () => {
|
it('should load a provisioned v2 dashboard', async () => {
|
||||||
|
|
|
@ -230,6 +230,12 @@ abstract class DashboardScenePageStateManagerBase<T>
|
||||||
anno[AnnoKeyManagerIdentity] = repo;
|
anno[AnnoKeyManagerIdentity] = repo;
|
||||||
anno[AnnoKeySourcePath] = provisioningPreview.ref ? path + '#' + provisioningPreview.ref : path;
|
anno[AnnoKeySourcePath] = provisioningPreview.ref ? path + '#' + provisioningPreview.ref : path;
|
||||||
|
|
||||||
|
// Include version information to align with the current dashboard schema
|
||||||
|
const specWithVersion = {
|
||||||
|
...dryRun.spec,
|
||||||
|
version: dryRun.metadata.generation || 0,
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
meta: {
|
meta: {
|
||||||
canStar: false,
|
canStar: false,
|
||||||
|
@ -247,7 +253,7 @@ abstract class DashboardScenePageStateManagerBase<T>
|
||||||
// lookup info
|
// lookup info
|
||||||
provisioning: provisioningPreview,
|
provisioning: provisioningPreview,
|
||||||
},
|
},
|
||||||
dashboard: dryRun.spec,
|
dashboard: specWithVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Trans, t } from '@grafana/i18n';
|
||||||
import { getAppEvents, locationService } from '@grafana/runtime';
|
import { getAppEvents, locationService } from '@grafana/runtime';
|
||||||
import { Dashboard } from '@grafana/schema';
|
import { Dashboard } from '@grafana/schema';
|
||||||
import { Button, Field, Input, Stack, TextArea } from '@grafana/ui';
|
import { Button, Field, Input, Stack, TextArea } from '@grafana/ui';
|
||||||
import { RepositoryView } from 'app/api/clients/provisioning/v0alpha1';
|
import { RepositoryView, Unstructured } from 'app/api/clients/provisioning/v0alpha1';
|
||||||
import kbn from 'app/core/utils/kbn';
|
import kbn from 'app/core/utils/kbn';
|
||||||
import { Resource } from 'app/features/apiserver/types';
|
import { Resource } from 'app/features/apiserver/types';
|
||||||
import { SaveDashboardFormCommonOptions } from 'app/features/dashboard-scene/saving/SaveDashboardForm';
|
import { SaveDashboardFormCommonOptions } from 'app/features/dashboard-scene/saving/SaveDashboardForm';
|
||||||
|
@ -19,6 +19,7 @@ import {
|
||||||
ProvisionedOperationInfo,
|
ProvisionedOperationInfo,
|
||||||
useProvisionedRequestHandler,
|
useProvisionedRequestHandler,
|
||||||
} from 'app/features/provisioning/hooks/useProvisionedRequestHandler';
|
} from 'app/features/provisioning/hooks/useProvisionedRequestHandler';
|
||||||
|
import { SaveDashboardResponseDTO } from 'app/types/dashboard';
|
||||||
|
|
||||||
import { ProvisionedDashboardFormData } from '../../types/form';
|
import { ProvisionedDashboardFormData } from '../../types/form';
|
||||||
import { buildResourceBranchRedirectUrl } from '../../utils/redirect';
|
import { buildResourceBranchRedirectUrl } from '../../utils/redirect';
|
||||||
|
@ -111,8 +112,13 @@ export function SaveProvisionedDashboardForm({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDismiss = () => {
|
const handleDismiss = () => {
|
||||||
dashboard.setState({ isDirty: false });
|
|
||||||
panelEditor?.onDiscard();
|
panelEditor?.onDiscard();
|
||||||
|
|
||||||
|
const model = dashboard.getSaveModel();
|
||||||
|
const resourceData = request?.data?.resource.dryRun;
|
||||||
|
const saveResponse = createSaveResponseFromResource(resourceData);
|
||||||
|
dashboard.saveCompleted(model, saveResponse, defaultValues.folder?.uid);
|
||||||
|
|
||||||
drawer.onClose();
|
drawer.onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -292,3 +298,29 @@ function updateURLParams(param: string, value?: string) {
|
||||||
url.searchParams.set(param, value);
|
url.searchParams.set(param, value);
|
||||||
window.history.replaceState({}, '', url);
|
window.history.replaceState({}, '', url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a SaveDashboardResponseDTO from a provisioning resource response
|
||||||
|
* This allows us to use the standard dashboard save completion flow
|
||||||
|
*/
|
||||||
|
function createSaveResponseFromResource(resource?: Unstructured): SaveDashboardResponseDTO {
|
||||||
|
const uid = resource?.metadata?.name;
|
||||||
|
const title = resource?.spec?.title;
|
||||||
|
const slug = kbn.slugifyForUrl(title);
|
||||||
|
|
||||||
|
return {
|
||||||
|
uid,
|
||||||
|
// Use the current dashboard state version to maintain consistency
|
||||||
|
version: resource?.metadata?.generation,
|
||||||
|
id: resource?.spec?.id || 0,
|
||||||
|
status: 'success',
|
||||||
|
url: locationUtil.assureBaseUrl(
|
||||||
|
getDashboardUrl({
|
||||||
|
uid,
|
||||||
|
slug,
|
||||||
|
currentQueryParams: '',
|
||||||
|
})
|
||||||
|
),
|
||||||
|
slug,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue