import memoizeOne from 'memoize-one'; import { memo, useMemo, useState } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; import { FixedSizeList, type ListChildComponentProps, areEqual, } from 'react-window'; import { useShallow } from 'zustand/react/shallow'; import type { ProjectConfig, Unit } from '../../shared/config'; import headerStyles from '../common/Header.module.css'; import { quickPickUnit, setCurrentUnit, useAppStore, useExtensionStore, } from '../state'; import { useFontSize } from '../util/util'; import { type SimpleTreeData, TreeRow, buildSimpleTree } from './TreeView'; import styles from './UnitsView.module.css'; const UnitRow = memo((props: ListChildComponentProps>) => { const setCollapsedUnit = useAppStore((state) => state.setCollapsedUnit); return ( { if ( item.type === 'leaf' && item.data.metadata?.complete !== undefined ) { if (item.data.metadata.complete) { return [styles.complete]; } return [styles.incomplete]; } return []; }} onLeafClick={(item) => { setCurrentUnit(item.data); }} setBranchCollapsed={setCollapsedUnit} render={(item) => { return ( {item.data.label} ); }} /> ); }, areEqual); const createItemData = memoizeOne( ( config: ProjectConfig | null, collapsedUnits: Record, highlightedPath: string | null, setHighlightedPath: (id: string | null) => void, ): SimpleTreeData => { return buildSimpleTree( config?.units ?? [], (unit) => unit.name || '', collapsedUnits, highlightedPath, setHighlightedPath, ); }, ); const UnitsView = () => { const config = useExtensionStore((state) => state.projectConfig); const { collapsedUnits, setCurrentView, setUnitsScrollOffset } = useAppStore( useShallow((state) => ({ collapsedUnits: state.collapsedUnits, setCurrentView: state.setCurrentView, setUnitsScrollOffset: state.setUnitsScrollOffset, })), ); const initialScrollOffset = useMemo( () => useAppStore.getState().unitsScrollOffset, [], ); const itemSize = useFontSize() * 1.33; const [highlightedPath, setHighlightedPath] = useState(null); const itemData = createItemData( config, collapsedUnits, highlightedPath, setHighlightedPath, ); return ( <>
{itemData.leafCount} unit{itemData.leafCount === 1 ? '' : 's'}
{({ height, width }) => ( { setUnitsScrollOffset(e.scrollOffset); }} initialScrollOffset={initialScrollOffset} > {UnitRow} )}
); }; export default UnitsView;