import { useStateWithRef } from "@probo/hooks"; import { useTranslate } from "@probo/i18n"; import { EditableCell, SelectValue, Spinner, selectCell } from "@probo/ui"; import { useEditableCellRef } from "@probo/ui/src/Molecules/Table/EditableCell.tsx"; import { useEditableRowContext } from "@probo/ui/src/Molecules/Table/EditableRow.tsx"; import { getKey } from "@probo/ui/src/Molecules/Table/utils.ts"; import { Command } from "cmdk"; import { Suspense, type ReactNode } from "react"; import { useLazyLoadQuery } from "react-relay"; import type { GraphQLTaggedNode, OperationType, VariablesOf, } from "relay-runtime"; type Props = { name: string; query: GraphQLTaggedNode; variables: VariablesOf; items: (v: ReturnType>) => T[]; itemRenderer: (v: { item: T; onRemove?: (item: T) => void }) => ReactNode; } & ( | { defaultValue?: T; multiple?: undefined } | { defaultValue: T[]; multiple: true } ); export function GraphQLCell>(props: Props) { const [value, setValue, valueRef] = useStateWithRef( props.defaultValue, ); const cellRef = useEditableCellRef(); const { __ } = useTranslate(); const filteredValue = Array.isArray(value) ? value.filter(Boolean) : value ? [value] : []; const usedKeys = new Set(filteredValue.map(getKey).filter(Boolean) as string[]); const { onUpdate } = useEditableRowContext(); const onSelect = (item: T) => { if (props.multiple) { setValue([...((valueRef.current as T[]) ?? []), item]); return; } setValue(item); cellRef.current?.close(); }; const onClose = () => { if (valueRef.current === props.defaultValue) { return; } // Only send ids when updating the value onUpdate( props.name, Array.isArray(valueRef.current) ? valueRef.current.map(getKey) : getKey(valueRef.current), ); }; const classNames = selectCell(); return ( } onClose={onClose} ref={cellRef} >
{" "}
{" "} {props.multiple && ( )} )} >
); } function ItemList( props: Props & { className: string; onSelect: (item: T) => void; usedKeys: Set; }, ) { const data = useLazyLoadQuery(props.query, props.variables, { fetchPolicy: "network-only", }); const items = props.items(data); return ( <> {items .filter(item => !props.usedKeys.has(getKey(item) ?? "")) .map(item => ( props.onSelect(item)} > {props.itemRenderer({ item })} ))} ); }