Files
node-factorio-recipes/components/visualize/PageDetails.tsx
2022-08-19 19:33:38 +02:00

81 lines
2.7 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'
export const PageDetails: FC = () => {
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>Factorio Microservices</title>
<meta name='description' content='Create Factorio microservices' />
</Head>
<main>
<ScrollContainer>
<h1>{name}</h1>
<ProducingGraph
nodes={producingNodes}
inputs={inputFactories}
outputs={group?.exports}
childType={NodeDetails}
/>
</ScrollContainer>
</main>
</>
)
}