import { useCallback, useState } from 'react'; import { useAsync, useDebounce } from 'react-use'; import { Button, Icon, Input, Modal, useStyles2 } from '@grafana/ui'; import { getConnectedDashboards } from 'app/features/library-panels/state/api'; import { getModalStyles } from 'app/features/library-panels/styles'; import { LibraryPanelBehavior } from '../scene/LibraryPanelBehavior'; interface Props { libraryPanel: LibraryPanelBehavior; isUnsavedPrompt?: boolean; onConfirm: () => void; onDismiss: () => void; onDiscard: () => void; } export const SaveLibraryVizPanelModal = ({ libraryPanel, isUnsavedPrompt, onDismiss, onConfirm, onDiscard }: Props) => { const [searchString, setSearchString] = useState(''); const dashState = useAsync(async () => { const searchHits = await getConnectedDashboards(libraryPanel.state.uid); if (searchHits.length > 0) { return searchHits.map((dash) => dash.title); } return []; }, [libraryPanel.state.uid]); const [filteredDashboards, setFilteredDashboards] = useState([]); useDebounce( () => { if (!dashState.value) { return setFilteredDashboards([]); } return setFilteredDashboards( dashState.value.filter((dashName) => dashName.toLowerCase().includes(searchString.toLowerCase())) ); }, 300, [dashState.value, searchString] ); const styles = useStyles2(getModalStyles); const discardAndClose = useCallback(() => { onDiscard(); }, [onDiscard]); const title = isUnsavedPrompt ? 'Unsaved library panel changes' : 'Save library panel'; return (

{'This update will affect '} {libraryPanel.state._loadedPanel?.meta?.connectedDashboards}{' '} {libraryPanel.state._loadedPanel?.meta?.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}. The following dashboards using the panel will be affected:

} placeholder="Search affected dashboards" value={searchString} onChange={(e) => setSearchString(e.currentTarget.value)} /> {dashState.loading ? (

Loading connected dashboards...

) : ( {filteredDashboards.map((dashName, i) => ( ))}
Dashboard name
{dashName}
)} {isUnsavedPrompt && ( )}
); };