import React, { useState, useMemo } from "react"; import { TextField, Autocomplete, Chip, Box } from "@mui/material"; import DoneIcon from "@mui/icons-material/Done"; import type { FieldConfig } from "../../../types"; interface Props { field: FieldConfig; value: any; onChange: (value: any) => void; fkOptions?: { value: any; label: string }[]; fkLoading?: boolean; onOpen?: () => void; } export function FkMultiSelectField({ field, value, onChange, fkOptions, fkLoading, onOpen }: Props) { const [open, setOpen] = useState(false); const [frozenValue, setFrozenValue] = useState([]); const handleOpen = () => { onOpen?.(); setFrozenValue(value ?? []); setOpen(true); }; const handleClose = () => { setOpen(false); }; const sortedOptions = useMemo(() => { const sel = new Set(frozenValue); const picked: { value: any; label: string }[] = []; const rest: { value: any; label: string }[] = []; for (const opt of fkOptions ?? []) { (sel.has(opt.value) ? picked : rest).push(opt); } return [...picked, ...rest]; }, [fkOptions, frozenValue]); return ( o.label} value={fkOptions?.filter((o) => (value ?? []).includes(o.value)) ?? []} onChange={(_, newVal) => onChange(newVal.map((v) => v.value))} loading={fkLoading} renderOption={(props, option, { selected }) => (
  • {selected ? ( ) : ( )} {option.label}
  • )} renderTags={(tagValue, getTagProps) => { const maxChips = 1; return ( <> {tagValue.slice(0, maxChips).map((tag, index) => { const { key, ...tagProps } = getTagProps({ index }); return ( 10 ? `${tag.label.slice(0, 8)}..` : tag.label} size="small" onClick={open ? handleClose : handleOpen} sx={{ cursor: "pointer" }} /> ); })} {tagValue.length > maxChips && ( )} ); }} renderInput={(params) => ( )} size="small" sx={{ "& .MuiAutocomplete-popupIndicator, & .MuiAutocomplete-clearIndicator": { width: 20, height: 20, fontSize: 16 }, }} disabled={field.readOnly} /> ); }