import { cx } from '@emotion/css'; import React, { useEffect, useState } from 'react'; import { FadeTransition, LoadingPlaceholder, useStyles2 } from '@grafana/ui'; import { NestedEntry } from './NestedEntry'; import getStyles from './styles'; import { ResourceRow, ResourceRowGroup, ResourceRowType } from './types'; import { findRow } from './utils'; interface NestedRowProps { row: ResourceRow; level: number; selectedRows: ResourceRowGroup; requestNestedRows: (row: ResourceRow) => Promise; onRowSelectedChange: (row: ResourceRow, selected: boolean) => void; selectableEntryTypes: ResourceRowType[]; scrollIntoView?: boolean; } const NestedRow: React.FC = ({ row, selectedRows, level, requestNestedRows, onRowSelectedChange, selectableEntryTypes, scrollIntoView, }) => { const styles = useStyles2(getStyles); const [rowStatus, setRowStatus] = useState<'open' | 'closed' | 'loading'>('closed'); const isSelected = !!selectedRows.find((v) => v.uri === row.uri); const isDisabled = selectedRows.length > 0 && !isSelected; const isOpen = rowStatus === 'open'; 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 ( <> type === row.type)} scrollIntoView={scrollIntoView} /> {row.typeLabel} {row.location ?? '-'} {isOpen && row.children && Object.keys(row.children).length > 0 && row.children.map((childRow) => ( ))} ); }; export default NestedRow;