import {createContext, FC, useContext, useMemo, useState} from "react"; import {Group, NewGroup} from "../../src/types"; import {useLocalStorage} from "../../src/hooks/useLocalStorage"; import {sortByProperty} from "../../src/utils"; 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: NewGroup[] addGroup(name: string, exported?: string[], malls?: string[]): void removeGroup(idx: number): void renameGroup(idx: number, newName: string): void getGroup(idx: number): NewGroup setFactories(idx: number, 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() {}, getGroup() {return {name: 'Lorem', inputs: [], intermediates: [], exports: [], malls: []}}, 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 [oldGroups, setGroups] = useLocalStorage('serviceGroups', []) const groups = useMemo(() => { return oldGroups.map(groupToNewGroup) }, [oldGroups]) const doNotSuggest = useMemo>(() => { return new Set([...groups.flatMap(group => [...group.exports, ...group.malls, ...(group.malls.length ? group.intermediates : [])]), ...excludedSuggestions, ...basicValues]) }, [basicValues, groups, excludedSuggestions]) const exportedFactories = useMemo>(() => { return new Set([...groups.flatMap(group => [...group.exports])]) }, [groups]) const value: GroupContextType = { doNotSuggest, ignoredFactories: excludedSuggestions, setIgnoredFactories: setExcludedSuggestions, baseFactories: basicValues, setBaseFactories: setBasicValues, groups, addGroup(name: string, exports: string[] = [], malls: string[] = []) { setGroups(groups => { groups.push({ name, inputs: [], intermediates: [], exports, malls }) return groups.sort(sortByProperty(group => group.name)) }) }, removeGroup(idx: number) { setGroups(groups => { groups.splice(idx, 1) return groups }) }, renameGroup(idx: number, newName: string) { setGroups(groups => { groups[idx].name = newName return groups.sort(sortByProperty(group => group.name)) }) }, getGroup(idx: number) { return groups[idx] }, setFactories(idx: number, factories: string[], type: 'inputs'|'intermediates'|'exports'|'malls') { setGroups(groups => { const group = groupToNewGroup(groups[idx]) group[type] = factories groups[idx] = group return groups }) }, getInputType(uid: string) { if (basicValues.includes(uid)) return 'base' else if (exportedFactories.has(uid)) return 'produced' else return 'unknown' } } return {children} } function groupToNewGroup(group: Group): NewGroup { return 'malls' in group ? group : { name: group.name, inputs: group.inputs, intermediates: group.intermediates, exports: group.isExported ? group.factories : [], malls: !group.isExported ? group.factories : [] } }