import { FC, memo, useCallback, useEffect, useMemo } from 'react' import Select, { ActionMeta, CSSObjectWithLabel } from 'react-select' import { isNonNullable } from '../../../src/utils' import styles from './FactorySelect.module.css' import { EntitySpan } from '../EntitySpan/EntitySpan' import { useFactories } from '../../contexts/FactoryProvider' interface Props { id: string factories: string[] onSetFactories: (factories: string[]) => void fixInputs?: boolean } interface Option { label: string value: string isFixed: boolean } const selectStyles: Record< 'multiValue' | 'multiValueLabel' | 'multiValueRemove', (base: CSSObjectWithLabel, state: { data: Option }) => CSSObjectWithLabel > = { multiValue: (base, state) => { return state.data.isFixed ? { ...base, backgroundColor: 'var(--fixed-item-bg) !important' } : base }, multiValueLabel: (base, state) => { return state.data.isFixed ? { ...base, fontWeight: 'bold', paddingRight: '6px' } : base }, multiValueRemove: (base, state) => { return state.data.isFixed ? { ...base, display: 'none' } : base } } const orderOptions = (values: Option[]) => { return values.filter(v => v.isFixed).concat(values.filter(v => !v.isFixed)) } const FactorySelectBase: FC = ({ id, factories, onSetFactories, fixInputs }) => { const { factories: details } = useFactories() const options = useMemo( () => details.map(detail => ({ label: detail.name, value: detail.href, isFixed: !!fixInputs && !detail.recipe })), [details, fixInputs] ) const state = useMemo(() => { return factories .map(factory => options.find(option => option.value === factory)) .filter(isNonNullable) }, [factories, options]) useEffect(() => { if (!fixInputs) return const set = new Set(factories) const addOptions = options .filter(option => option.isFixed && !set.has(option.value)) .map(option => option.value) if (addOptions.length) { onSetFactories([...factories, ...addOptions]) } }, [factories, fixInputs, onSetFactories, options]) const onChange = useCallback( (values: readonly Option[], { action, removedValue }: ActionMeta