/usr/share/grafana/public/app/plugins/datasource/azuremonitor/components/ResourcePicker
import { cx } from '@emotion/css'; import { useEffect, useState } from 'react'; import { t } from '@grafana/i18n'; import { FadeTransition, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; import { NestedEntry } from './NestedEntry'; import getStyles from './styles'; import { ResourceRow, ResourceRowGroup, ResourceRowType } from './types'; import { findRow, parseResourceURI } from './utils'; interface NestedRowProps { row: ResourceRow; level: number; selectedRows: ResourceRowGroup; requestNestedRows: (row: ResourceRow) => Promise<void>; onRowSelectedChange: (row: ResourceRow, selected: boolean) => void; selectableEntryTypes: ResourceRowType[]; disableRow: (row: ResourceRow, selectedRows: ResourceRowGroup) => boolean; scrollIntoView?: boolean; } const NestedRow = ({ row, selectedRows, level, requestNestedRows, onRowSelectedChange, selectableEntryTypes, scrollIntoView, disableRow, }: NestedRowProps) => { const styles = useStyles2(getStyles); const [rowStatus, setRowStatus] = useState<'open' | 'closed' | 'loading'>('closed'); const isSelected = !!selectedRows.find((v) => v.uri.toLowerCase() === row.uri.toLowerCase()); const isDisabled = !isSelected && disableRow(row, selectedRows); const isOpen = rowStatus === 'open'; const parsedURI = parseResourceURI(row.uri); const onRowToggleCollapse = async () => { if (rowStatus === 'open') { setRowStatus('closed'); return; } setRowStatus('loading'); requestNestedRows(row) .then(() => setRowStatus('open')) .catch(() => setRowStatus('closed')); }; // opens the resource group on load of component if there was a previously saved selection useEffect(() => { // Assuming we don't have multi-select yet const selectedRow = selectedRows[0]; const containsChild = selectedRow && !!findRow(row.children ?? [], selectedRow.uri); if (containsChild) { setRowStatus('open'); } }, [selectedRows, row]); return ( <> <tr className={cx(styles.row, isDisabled && styles.disabledRow)} key={row.id}> <td className={styles.cell} title={row.name}> <NestedEntry level={level} isSelected={isSelected} isDisabled={isDisabled} isOpen={isOpen} entry={row} onToggleCollapse={onRowToggleCollapse} onSelectedChange={onRowSelectedChange} isSelectable={selectableEntryTypes.some((type) => type === row.type)} scrollIntoView={scrollIntoView} /> </td> <td className={styles.cell} // eslint-disable-next-line @grafana/i18n/no-untranslated-strings title={parsedURI.resourceGroup && row.type === ResourceRowType.Resource ? parsedURI.resourceGroup : '-'} > { // eslint-disable-next-line @grafana/i18n/no-untranslated-strings parsedURI.resourceGroup && row.type === ResourceRowType.Resource ? parsedURI.resourceGroup : '-' } </td> <td className={styles.cell} title={row.typeLabel}> {row.typeLabel} </td> <td className={styles.cell} title={row.location ?? '-'}> {row.location ?? '-'} </td> </tr> {isOpen && row.children && Object.keys(row.children).length > 0 && row.children.map((childRow) => ( <NestedRow key={childRow.uri} row={childRow} selectedRows={selectedRows} level={level + 1} requestNestedRows={requestNestedRows} onRowSelectedChange={onRowSelectedChange} selectableEntryTypes={selectableEntryTypes} scrollIntoView={scrollIntoView} disableRow={disableRow} /> ))} <FadeTransition visible={rowStatus === 'loading'}> <tr> <td className={cx(styles.cell, styles.loadingCell)} colSpan={3}> <LoadingPlaceholder text={t('components.nested-row.text-loading', 'Loading...')} className={styles.spinner} /> </td> </tr> </FadeTransition> </> ); }; export default NestedRow;
.
Edit
..
Edit
AdvancedMulti.test.tsx
Edit
AdvancedMulti.tsx
Edit
EntryIcon.tsx
Edit
NestedEntry.test.tsx
Edit
NestedEntry.tsx
Edit
NestedRow.test.tsx
Edit
NestedRow.tsx
Edit
ResourcePicker.test.tsx
Edit
ResourcePicker.tsx
Edit
Search.tsx
Edit
styles.ts
Edit
types.ts
Edit
utils.test.ts
Edit
utils.ts
Edit