import { css } from '@emotion/css'; import { debounce } from 'lodash'; import React, { MouseEvent, useCallback, useEffect, useMemo, useState } from 'react'; import { GrafanaTheme2, SelectableValue, urlUtil } from '@grafana/data'; import { locationService } from '@grafana/runtime'; import { AsyncSelect, Button, Modal, useStyles2 } from '@grafana/ui'; import { DashboardSearchHit } from '../../../search/types'; import { getConnectedDashboards, getLibraryPanelConnectedDashboards } from '../../state/api'; import { LibraryElementDTO } from '../../types'; export interface OpenLibraryPanelModalProps { onDismiss: () => void; libraryPanel: LibraryElementDTO; } export function OpenLibraryPanelModal({ libraryPanel, onDismiss }: OpenLibraryPanelModalProps): JSX.Element { const styles = useStyles2(getStyles); const [loading, setLoading] = useState(false); const [connected, setConnected] = useState(0); const [option, setOption] = useState | undefined>(undefined); useEffect(() => { const getConnected = async () => { const connectedDashboards = await getLibraryPanelConnectedDashboards(libraryPanel.uid); setConnected(connectedDashboards.length); }; getConnected(); }, [libraryPanel.uid]); const loadOptions = useCallback( (searchString: string) => loadOptionsAsync(libraryPanel.uid, searchString, setLoading), [libraryPanel.uid] ); const debouncedLoadOptions = useMemo( () => debounce(loadOptions, 300, { leading: true, trailing: true }), [loadOptions] ); const onViewPanel = (e: MouseEvent) => { e.preventDefault(); locationService.push(urlUtil.renderUrl(`/d/${option?.value?.uid}`, {})); }; return (
{connected === 0 ? ( Panel is not linked to a dashboard. Add the panel to a dashboard and retry. ) : null} {connected > 0 ? ( <>

This panel is being used in{' '} {connected} {connected > 1 ? 'dashboards' : 'dashboard'} .Please choose which dashboard to view the panel in:

) : null}
); } async function loadOptionsAsync(uid: string, searchString: string, setLoading: (loading: boolean) => void) { setLoading(true); const searchHits = await getConnectedDashboards(uid); const options = searchHits .filter((d) => d.title.toLowerCase().includes(searchString.toLowerCase())) .map((d) => ({ label: d.title, value: d })); setLoading(false); return options; } function getStyles(theme: GrafanaTheme2) { return { container: css``, }; }