import {createContext, FC, useCallback, useContext, useMemo} from "react"; import {Group} from "../../src/types"; import {useLocalStorage} from "../../src/hooks/useLocalStorage"; import {ReactNodeLike} from "prop-types"; interface Props { children: ReactNodeLike } interface GroupContextType { doNotSuggest: Set ignoredFactories: string[] setIgnoredFactories(factories: string[]): void baseFactories: string[] setBaseFactories(factories: string[]): void groups: Record addGroup(name: string, exported?: string[], malls?: string[]): void removeGroup(name: string): void renameGroup(name: string, newName: string): void setFactories(name: string, factories: string[], type: 'inputs'|'intermediates'|'exports'|'malls'): void getInputType(uid: string): 'base'|'produced'|'unknown' } const defaultValues: GroupContextType = { doNotSuggest: new Set(), ignoredFactories: [], setIgnoredFactories() {}, baseFactories: [], setBaseFactories() {}, groups: {}, addGroup() {}, removeGroup() {}, renameGroup() {}, setFactories() {}, getInputType() {return 'unknown'} } const GroupContext = createContext(defaultValues); export const useGroups = () => useContext(GroupContext) export const GroupProvider: FC = ({children}) => { const [excludedSuggestions, setExcludedSuggestions] = useLocalStorage('excludedSuggestions', []) const [basicValues, setBasicValues] = useLocalStorage('basicValues', []) const [groups, setGroups] = useLocalStorage>('serviceGroups', {}) const doNotSuggest = useMemo>(() => { return new Set([...Object.values(groups).flatMap(group => [...group.exports, ...group.malls, ...(group.malls.length ? group.intermediates : [])]), ...excludedSuggestions, ...basicValues]) }, [basicValues, groups, excludedSuggestions]) const exportedFactories = useMemo>(() => { return new Set([...Object.values(groups).flatMap(group => [...group.exports])]) }, [groups]) const addGroup = useCallback((name: string, exports: string[] = [], malls: string[] = []) => { if (name in groups) return false setGroups(groups => { groups[name] = { name, inputs: [], intermediates: [], exports, malls } return groups }) return true }, [groups, setGroups]) const removeGroup = useCallback((name: string) => { setGroups(groups => { delete groups[name] return groups }) }, [setGroups]) const renameGroup = useCallback((name: string, newName: string) => { setGroups(groups => { groups[newName] = {...groups[name], name: newName} delete groups[name] return groups }) }, [setGroups]) const setFactories = useCallback((name: string, factories: string[], type: 'inputs'|'intermediates'|'exports'|'malls') => { setGroups(groups => { groups[name] = {...groups[name], [type]: factories} return groups }) }, [setGroups]) const getInputType = useCallback((uid: string) => { if (basicValues.includes(uid)) return 'base' else if (exportedFactories.has(uid)) return 'produced' else return 'unknown' }, [basicValues, exportedFactories]) const value: GroupContextType = useMemo(() => ({ doNotSuggest, ignoredFactories: excludedSuggestions, setIgnoredFactories: setExcludedSuggestions, baseFactories: basicValues, setBaseFactories: setBasicValues, groups, addGroup, removeGroup, renameGroup, setFactories, getInputType }), [addGroup, basicValues, doNotSuggest, excludedSuggestions, getInputType, groups, removeGroup, renameGroup, setBasicValues, setExcludedSuggestions, setFactories]) return {children} }