88 lines
3.0 KiB
TypeScript
88 lines
3.0 KiB
TypeScript
import { useRouter } from 'next/router'
|
|
import { useGroups } from '../contexts/GroupProvider'
|
|
import { FC, useMemo } from 'react'
|
|
import { calculateInputs } from '../../src/calculateInputs'
|
|
import { DetailGraphNode, NodeDetails } from './NodeDetails/NodeDetails'
|
|
import { groupBy, isNonNullable, uniquify } from '../../src/utils'
|
|
import { EnrichedEntity } from '../../src/types'
|
|
import Head from 'next/head'
|
|
import { ScrollContainer } from './ScrollContainer/ScrollContainer'
|
|
import { ProducingGraph } from './ProducingGraph/ProducingGraph'
|
|
import { useFactories } from '../contexts/FactoryProvider'
|
|
import { i18n, I18n } from '../shared/I18n/I18n'
|
|
import { useIntl } from 'react-intl'
|
|
|
|
export const PageDetails: FC = () => {
|
|
const intl = useIntl()
|
|
const {
|
|
query: { name }
|
|
} = useRouter()
|
|
const { exportedFactories, baseFactories, groups } = useGroups()
|
|
const { findFactory } = useFactories()
|
|
|
|
const group = typeof name === 'string' ? groups[name] : undefined
|
|
|
|
const [inputFactories, intermediateFactories] = useMemo<
|
|
ReturnType<typeof calculateInputs>
|
|
>(() => {
|
|
if (!group) return [[], []]
|
|
return calculateInputs(
|
|
[...group.exports, ...group.malls],
|
|
baseFactories,
|
|
exportedFactories,
|
|
findFactory
|
|
)
|
|
}, [baseFactories, exportedFactories, findFactory, group])
|
|
|
|
const producingNodes: DetailGraphNode[] = useMemo(() => {
|
|
if (!group) return []
|
|
const nodes = uniquify([...intermediateFactories, ...group.exports, ...group.malls])
|
|
.map(findFactory)
|
|
.filter(isNonNullable)
|
|
.map(
|
|
(factory: EnrichedEntity) =>
|
|
({
|
|
inputs: Object.keys(factory.recipe?.prerequisites ?? {}).sort((a, b) =>
|
|
a.localeCompare(b)
|
|
),
|
|
outputs: Object.keys(factory.recipe?.output ?? {}).sort((a, b) => a.localeCompare(b)),
|
|
name: factory.name,
|
|
recipes: [factory.recipe]
|
|
} as DetailGraphNode)
|
|
)
|
|
return Object.values(groupBy(nodes, node => node.inputs.join())).map(
|
|
nodesOfInput =>
|
|
({
|
|
inputs: nodesOfInput[0].inputs,
|
|
outputs: uniquify(nodesOfInput.flatMap(node => node.outputs)),
|
|
name: nodesOfInput.map(node => node.name).join(', '),
|
|
recipes: nodesOfInput.flatMap(node => node.recipes)
|
|
} as DetailGraphNode)
|
|
)
|
|
}, [findFactory, group, intermediateFactories])
|
|
|
|
return (
|
|
<>
|
|
<Head>
|
|
<title>
|
|
<I18n id={'page.visualize.details.title'} values={{ name: group?.name ?? '' }} />
|
|
</title>
|
|
<meta name='description' content={i18n(intl, 'page.home.head.meta.description')} />
|
|
</Head>
|
|
<main>
|
|
<ScrollContainer>
|
|
<h1>
|
|
<I18n id={'page.visualize.details.title'} values={{ name: group?.name ?? '' }} />
|
|
</h1>
|
|
<ProducingGraph
|
|
nodes={producingNodes}
|
|
inputs={inputFactories}
|
|
outputs={group?.exports}
|
|
childType={NodeDetails}
|
|
/>
|
|
</ScrollContainer>
|
|
</main>
|
|
</>
|
|
)
|
|
}
|