import { FC, memo, useCallback, useMemo, useState } from 'react' import { FactorySelect } from '../FactorySelect/FactorySelect' import { EnrichedEntity, Group } from '../../../src/types' import styles from './GroupBox.module.css' import { EntitySpan } from '../EntitySpan/EntitySpan' import { useGroups } from '../../contexts/GroupProvider' import { calculateInputs } from '../../../src/calculateInputs' import { uniquify } from '../../../src/utils' import { useFactories } from '../../contexts/FactoryProvider' import { i18n, I18n } from '../../shared/I18n/I18n' import { useIntl } from 'react-intl' import { ButtonVisualize } from '../../shared/ButtonVisualize/ButtonVisualize' import { Heading } from '../../shared/Heading' import typography from '../../../styles/typography.module.css' import cx from 'classnames' interface Props { group: Group } const GroupBoxBase: FC = ({ group }) => { const intl = useIntl() const { factories, findFactory } = useFactories() const { doNotSuggest, setFactories, baseFactories, exportedFactories, ignoredFactories, setIgnoredFactories, renameGroup, removeGroup, getInputType } = useGroups() const { name, exports, malls } = group const nameForId = useMemo(() => name.replace(/[^a-z\d_-]/gi, ''), [name]) const [isDeleteConfirm, setDeleteConfirm] = useState(false) const [inputs, intermediates] = useMemo(() => { const allProducingFactories = [...exports, ...malls] return calculateInputs(allProducingFactories, baseFactories, exportedFactories, findFactory) }, [exports, malls, baseFactories, findFactory, exportedFactories]) const [suggestionsExport, suggestionMall] = useMemo<[EnrichedEntity[], EnrichedEntity[]]>(() => { const selectedValues = uniquify([...exports, ...malls]) const availableIngredients = uniquify([...selectedValues, ...intermediates, ...inputs]) return factories .filter(factory => { if (!factory.recipe) return false if (selectedValues.includes(factory.href)) return false if (doNotSuggest.has(factory.href)) return false const prerequisites = Object.keys(factory.recipe.prerequisites ?? {}) return prerequisites.every(pre => availableIngredients.includes(pre)) }) .reduce( (acc, factory) => (factory.usedBy?.length ?? 0) >= 3 ? [[...acc[0], factory], acc[1]] : [acc[0], [...acc[1], factory]], [[], []] as [EnrichedEntity[], EnrichedEntity[]] ) }, [exports, malls, intermediates, inputs, factories, doNotSuggest]) const addFactory = useCallback( (uid: string, type: Parameters[2]) => { setFactories(name, [...group[type], uid], type) }, [group, name, setFactories] ) const setExportFactories = useCallback( (exportFactories: string[]) => setFactories(name, exportFactories, 'exports'), [setFactories, name] ) const setMallFactories = useCallback( (mallFactories: string[]) => setFactories(name, mallFactories, 'malls'), [setFactories, name] ) return (
{ event.currentTarget.innerText = event.currentTarget.innerText.trim() renameGroup(name, event.currentTarget.innerText) }} onKeyDown={event => { if (event.key === 'Enter') { event.preventDefault() event.currentTarget.blur() } if (event.key === 'Escape') { event.preventDefault() event.currentTarget.innerText = name event.currentTarget.blur() } }} > {name} {inputs.length ? ( <>
{inputs.map(input => ( { event.preventDefault() setIgnoredFactories([...ignoredFactories, input]) }} rightClickText={i18n(intl, 'page.home.tooltip.action.exclude_suggestion')} /> ))}
) : null} {intermediates.length ? ( <>
{intermediates.map(intermediate => ( ))}
) : null} {suggestionsExport.length ? ( <>
{suggestionsExport.map(suggestion => ( addFactory(suggestion.href, 'exports')} onContextMenu={event => { event.preventDefault() setIgnoredFactories([...ignoredFactories, suggestion.href]) }} leftClickText={i18n(intl, 'page.home.tooltip.action.add_to_export')} rightClickText={i18n(intl, 'page.home.tooltip.action.exclude_suggestion')} /> ))}
) : null} {suggestionMall.length ? ( <>
{suggestionMall.map(suggestion => ( addFactory(suggestion.href, 'malls')} onContextMenu={event => { event.preventDefault() setIgnoredFactories([...ignoredFactories, suggestion.href]) }} leftClickText={i18n(intl, 'page.home.tooltip.action.add_to_mall')} rightClickText={i18n(intl, 'page.home.tooltip.action.exclude_suggestion')} /> ))}
) : null}
) } export const GroupBox = memo(GroupBoxBase)