import React, { useState } from 'react'; import { Button, HorizontalGroup, Icon, Input, Modal, stylesFactory, useStyles } from '@grafana/ui'; import { GrafanaTheme } from '@grafana/data'; import { css } from 'emotion'; import { useAsync, useDebounce } from 'react-use'; import { getBackendSrv } from 'app/core/services/backend_srv'; import { usePanelSave } from '../../utils/usePanelSave'; import { getLibraryPanelConnectedDashboards } from '../../state/api'; import { PanelModelWithLibraryPanel } from '../../types'; interface Props { panel: PanelModelWithLibraryPanel; folderId: number; isOpen: boolean; onConfirm: () => void; onDismiss: () => void; } export const SaveLibraryPanelModal: React.FC = ({ panel, folderId, isOpen, onDismiss, onConfirm }: Props) => { const [searchString, setSearchString] = useState(''); const connectedDashboardsState = useAsync(async () => { const connectedDashboards = await getLibraryPanelConnectedDashboards(panel.libraryPanel.uid); return connectedDashboards; }, []); const dashState = useAsync(async () => { const connectedDashboards = connectedDashboardsState.value; if (connectedDashboards && connectedDashboards.length > 0) { const dashboardDTOs = await getBackendSrv().search({ dashboardIds: connectedDashboards }); return dashboardDTOs.map((dash) => dash.title); } return []; }, [connectedDashboardsState.value]); 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 { saveLibraryPanel } = usePanelSave(); const styles = useStyles(getModalStyles); return (

{'This update will affect '} {panel.libraryPanel.meta.connectedDashboards}{' '} {panel.libraryPanel.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}
)}
); }; const getModalStyles = stylesFactory((theme: GrafanaTheme) => { return { myTable: css` max-height: 204px; overflow-y: auto; margin-top: 11px; margin-bottom: 28px; border-radius: ${theme.border.radius.sm}; border: 1px solid ${theme.colors.bg3}; background: ${theme.colors.bg1}; color: ${theme.colors.textSemiWeak}; font-size: ${theme.typography.size.md}; width: 100%; thead { color: #538ade; font-size: ${theme.typography.size.sm}; } th, td { padding: 6px 13px; height: ${theme.spacing.xl}; } tbody > tr:nth-child(odd) { background: ${theme.colors.bg2}; } `, noteTextbox: css` margin-bottom: ${theme.spacing.xl}; `, textInfo: css` color: ${theme.colors.textSemiWeak}; font-size: ${theme.typography.size.sm}; `, dashboardSearch: css` margin-top: ${theme.spacing.md}; `, }; });