import React, { useMemo, useState } from 'react'; import { config, isFetchError } from '@grafana/runtime'; import { Drawer, Tab, TabsBar } from '@grafana/ui'; import { jsonDiff } from '../VersionHistory/utils'; import DashboardValidation from './DashboardValidation'; import { SaveDashboardDiff } from './SaveDashboardDiff'; import { proxyHandlesError, SaveDashboardErrorProxy } from './SaveDashboardErrorProxy'; import { SaveDashboardAsForm } from './forms/SaveDashboardAsForm'; import { SaveDashboardForm } from './forms/SaveDashboardForm'; import { SaveProvisionedDashboardForm } from './forms/SaveProvisionedDashboardForm'; import { SaveDashboardData, SaveDashboardModalProps, SaveDashboardOptions } from './types'; import { useDashboardSave } from './useDashboardSave'; export const SaveDashboardDrawer = ({ dashboard, onDismiss, onSaveSuccess, isCopy }: SaveDashboardModalProps) => { const [options, setOptions] = useState({}); const previous = dashboard.getOriginalDashboard(); const isProvisioned = dashboard.meta.provisioned; const isNew = dashboard.version === 0; const data = useMemo(() => { const clone = dashboard.getSaveModelClone({ saveTimerange: Boolean(options.saveTimerange), saveVariables: Boolean(options.saveVariables), }); if (!previous) { return { clone, diff: {}, diffCount: 0, hasChanges: false }; } const cloneJSON = JSON.stringify(clone, null, 2); const cloneSafe = JSON.parse(cloneJSON); // avoids undefined issues const diff = jsonDiff(previous, cloneSafe); let diffCount = 0; for (const d of Object.values(diff)) { diffCount += d.length; } return { clone, diff, diffCount, hasChanges: diffCount > 0 && !isNew, }; }, [dashboard, previous, options, isNew]); const [showDiff, setShowDiff] = useState(false); const { state, onDashboardSave } = useDashboardSave(dashboard, isCopy); const onSuccess = onSaveSuccess ? () => { onDismiss(); onSaveSuccess(); } : onDismiss; const renderSaveBody = () => { if (showDiff) { return ; } if (isNew || isCopy) { return ( ); } if (isProvisioned) { return ; } return ( ); }; if ( state.error && isFetchError(state.error) && !state.error.isHandled && proxyHandlesError(state.error.data.status) ) { return ( ); } let title = 'Save dashboard'; if (isCopy) { title = 'Save dashboard copy'; } else if (isProvisioned) { title = 'Provisioned dashboard'; } return ( setShowDiff(false)} /> {data.hasChanges && ( setShowDiff(true)} counter={data.diffCount} /> )} } scrollableContent > {renderSaveBody()} {config.featureToggles.showDashboardValidationWarnings && } ); };