import { Messenger } from '@estruyf/vscode/dist/client'; import { EventData } from '@estruyf/vscode/dist/models'; import { ChevronDownIcon, DatabaseIcon } from '@heroicons/react/outline'; import * as React from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { Command } from '../../Command'; import { CommandToCode } from '../../CommandToCode'; import { VsLabel } from '../VscodeComponents'; import Downshift from 'downshift'; import { ChoiceButton } from './ChoiceButton'; export interface IDataFileFieldProps { label: string; dataFileId?: string; dataFileKey?: string; dataFileValue?: string; selected: string | string[]; multiSelect?: boolean; onChange: (value: string | string[]) => void; } export const DataFileField: React.FunctionComponent = ({ label, dataFileId, dataFileKey, dataFileValue, selected, multiSelect, onChange }: React.PropsWithChildren) => { const [ dataEntries, setDataEntries ] = useState(null); const [ crntSelected, setCrntSelected ] = React.useState(); const dsRef = React.useRef | null>(null); const messageListener = (message: MessageEvent>) => { const { command, data } = message.data; if (command === Command.dataFileEntries) { setDataEntries(data || null); } }; const onValueChange = useCallback((txtValue: string) => { if (multiSelect) { const newValue = [...(crntSelected || []) as string[], txtValue]; setCrntSelected(newValue); onChange(newValue); } else { setCrntSelected(txtValue); onChange(txtValue); } }, [crntSelected, multiSelect, onChange]); const removeSelected = useCallback((txtValue: string) => { if (multiSelect) { const newValue = [...(crntSelected || [])].filter(v => v !== txtValue); setCrntSelected(newValue); onChange(newValue); } else { setCrntSelected(""); onChange(""); } }, [crntSelected, multiSelect, onChange]); const allChoices = useMemo(() => { if (dataEntries && dataFileKey) { return dataEntries.map((r: any) => ({ id: r[dataFileKey], title: r[dataFileValue || dataFileKey] || r[dataFileKey] })).filter(r => r.id); } return []; }, [crntSelected, dataEntries, dataFileKey, dataFileValue]); const availableChoices = useMemo(() => { if (allChoices) { return allChoices.filter(choice => { if (choice) { if (typeof crntSelected === 'string') { return crntSelected !== choice.id; } else if (crntSelected instanceof Array) { return crntSelected.indexOf(choice.id) === -1; } return true; } return false; }); } return []; }, [allChoices]); const getChoiceValue = useCallback((id: string) => { const choice = allChoices.find(r => r.id === id); if (choice) { return choice.title; } return ""; }, [allChoices]); useEffect(() => { if (selected) { if (multiSelect) { setCrntSelected(typeof selected === 'string' ? [selected] : selected); return; } else { setCrntSelected(selected instanceof Array ? selected[0] : selected); return; } } setCrntSelected(multiSelect ? [] : ""); }, [selected, multiSelect]); useEffect(() => { if (dataFileId) { Messenger.send(CommandToCode.getDataEntries, dataFileId); } }, [dataFileId]); useEffect(() => { Messenger.listen(messageListener); return () => { Messenger.unlisten(messageListener); } }, []); return (
{label}
onValueChange(selected || "")} itemToString={item => (item ? item : '')}> {({ getToggleButtonProps, getItemProps, getMenuProps, isOpen, getRootProps }) => (
    { isOpen ? availableChoices.map((choice, index) => (
  • { choice.title || Clear value }
  • )) : null }
)}
{ crntSelected instanceof Array ? crntSelected.map((value: string) => ( )) : ( crntSelected && ( ) ) }
); };