Files
grafana/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx
Torkel Ödegaard b01cbc7aef Dashboard: Fixes save drawer always comparing changes against first loaded version (#76506)
* Dashboard: Fixes save changes diff after first save

* Lots of type issues

* better fix

* Update some more places to use new function

* Fix

* Update

* Update

* remove console.log

* Update
2023-10-13 16:23:23 +02:00

113 lines
3.8 KiB
TypeScript

import { useAsyncFn } from 'react-use';
import { locationUtil } from '@grafana/data';
import { locationService, reportInteraction } from '@grafana/runtime';
import { Dashboard } from '@grafana/schema';
import appEvents from 'app/core/app_events';
import { useAppNotification } from 'app/core/copy/appNotification';
import { contextSrv } from 'app/core/core';
import { updateDashboardName } from 'app/core/reducers/navBarTree';
import { useSaveDashboardMutation } from 'app/features/browse-dashboards/api/browseDashboardsAPI';
import { newBrowseDashboardsEnabled } from 'app/features/browse-dashboards/featureFlag';
import { DashboardModel } from 'app/features/dashboard/state';
import { saveDashboard as saveDashboardApiCall } from 'app/features/manage-dashboards/state/actions';
import { useDispatch } from 'app/types';
import { DashboardSavedEvent } from 'app/types/events';
import { updateDashboardUidLastUsedDatasource } from '../../utils/dashboard';
import { SaveDashboardOptions } from './types';
const saveDashboard = async (
saveModel: any,
options: SaveDashboardOptions,
dashboard: DashboardModel,
saveDashboardRtkQuery: ReturnType<typeof useSaveDashboardMutation>[0]
) => {
if (newBrowseDashboardsEnabled()) {
const query = await saveDashboardRtkQuery({
dashboard: saveModel,
folderUid: options.folderUid ?? dashboard.meta.folderUid ?? saveModel.meta.folderUid,
message: options.message,
overwrite: options.overwrite,
});
if ('error' in query) {
throw query.error;
}
return query.data;
} else {
let folderUid = options.folderUid;
if (folderUid === undefined) {
folderUid = dashboard.meta.folderUid ?? saveModel.folderUid;
}
const result = await saveDashboardApiCall({ ...options, folderUid, dashboard: saveModel });
// fetch updated access control permissions
await contextSrv.fetchUserPermissions();
return result;
}
};
export const useDashboardSave = (isCopy = false) => {
const dispatch = useDispatch();
const notifyApp = useAppNotification();
const [saveDashboardRtkQuery] = useSaveDashboardMutation();
const [state, onDashboardSave] = useAsyncFn(
async (clone: Dashboard, options: SaveDashboardOptions, dashboard: DashboardModel) => {
try {
const result = await saveDashboard(clone, options, dashboard, saveDashboardRtkQuery);
dashboard.version = result.version;
clone.version = result.version;
dashboard.clearUnsavedChanges(clone, options);
// important that these happen before location redirect below
appEvents.publish(new DashboardSavedEvent());
notifyApp.success('Dashboard saved');
//Update local storage dashboard to handle things like last used datasource
updateDashboardUidLastUsedDatasource(result.uid);
if (isCopy) {
reportInteraction('grafana_dashboard_copied', {
name: dashboard.title,
url: result.url,
});
} else {
reportInteraction(`grafana_dashboard_${dashboard.id ? 'saved' : 'created'}`, {
name: dashboard.title,
url: result.url,
});
}
const currentPath = locationService.getLocation().pathname;
const newUrl = locationUtil.stripBaseFromUrl(result.url);
if (newUrl !== currentPath) {
setTimeout(() => locationService.replace(newUrl));
}
if (dashboard.meta.isStarred) {
dispatch(
updateDashboardName({
id: dashboard.uid,
title: dashboard.title,
url: newUrl,
})
);
}
return result;
} catch (error) {
if (error instanceof Error) {
notifyApp.error(error.message ?? 'Error saving dashboard');
}
throw error;
}
},
[dispatch, notifyApp]
);
return { state, onDashboardSave };
};