diff --git a/packages/app/src/components/Editor/Canvas/Canvas.tsx b/packages/app/src/components/Editor/Canvas/Canvas.tsx index 50f45f1..5249005 100644 --- a/packages/app/src/components/Editor/Canvas/Canvas.tsx +++ b/packages/app/src/components/Editor/Canvas/Canvas.tsx @@ -1,7 +1,7 @@ import {EditorStore} from '#editor-store/editor.store'; import type {WorkflowStructureJob} from '#editor-store/editor.types'; import type {ElkExtendedEdge, ElkNode} from 'elkjs'; -import {batch, createEffect, createSignal, onCleanup, onMount} from 'solid-js'; +import {createResource, onCleanup, onMount, Suspense, untrack} from 'solid-js'; import {provideState} from 'statebuilder'; import {FlowRenderer} from '../Flow/engine/FlowRenderer'; import type {FlowConnection, FlowNodeMap} from '../Flow/engine/types'; @@ -24,6 +24,8 @@ function createNodes(jobs: WorkflowStructureJob[]) { return acc; }, {} as FlowNodeMap); + console.log('my jobs', jobs); + return import('elkjs').then(({default: ELK}) => { const graph: ElkNode = { id: 'root', @@ -77,86 +79,91 @@ function createNodes(jobs: WorkflowStructureJob[]) { return acc; }, [] as ElkExtendedEdge[]), }; - return new ELK().layout(graph).then(layout => { - layout.children?.forEach(child => { - const node = mappedNodes[child.id]; - if (node) { - node.position.x = child.x ?? 0; - node.position.y = child.y ?? 0; - } - }); + return new ELK() + .layout(graph) + .then(layout => { + layout.children?.forEach(child => { + const node = mappedNodes[child.id]; + if (node) { + node.position.x = child.x ?? 0; + node.position.y = child.y ?? 0; + } + }); - const edges = jobs.reduce((acc, job) => { - const jobEdge: FlowConnection[] = (job.needs ?? []).reduce( - (acc, need) => { - const cJob = jobs.find(n => n.id.toString() === need.toString()); - if (!cJob) { - return acc; - } - return [ - ...acc, - { - target: { - nodeId: job.id, - connectorId: `${job.id}-output`, - connectorType: 'output', - }, - source: { - nodeId: need, - connectorId: `${need}-input`, - connectorType: 'input', - }, - } satisfies FlowConnection, - ]; - }, - [] as FlowConnection[], - ); + const edges = jobs.reduce((acc, job) => { + const jobEdge: FlowConnection[] = (job.needs ?? []).reduce( + (acc, need) => { + const cJob = jobs.find(n => n.id.toString() === need.toString()); + if (!cJob) { + return acc; + } + return [ + ...acc, + { + target: { + nodeId: job.id, + connectorId: `${job.id}-output`, + connectorType: 'output', + }, + source: { + nodeId: need, + connectorId: `${need}-input`, + connectorType: 'input', + }, + } satisfies FlowConnection, + ]; + }, + [] as FlowConnection[], + ); + + return [...acc, ...jobEdge]; + }, [] as FlowConnection[]); - return [...acc, ...jobEdge]; - }, [] as FlowConnection[]); + console.log(mappedNodes); - return { - size: { - width: layout.width!, - height: layout.height!, - }, - mappedNodes, - edges, - }; - }); + return { + size: { + width: layout.width!, + height: layout.height!, + }, + mappedNodes, + edges, + }; + }) + .catch(console.error); }); } -export function Canvas() { +export default function Canvas() { const editor = provideState(EditorStore); - const [mappedNodes, setMappedNodes] = createSignal({}); - const [connections, setConnections] = createSignal([]); - const [size, setSize] = createSignal({width: 0, height: 0}); + const [data, {refetch}] = createResource( + () => editor.initialized(), + async () => { + const result = await createNodes( + untrack(() => editor().structure.jobs ?? []), + ); + return result; + }, + ); - function updateNodes() { - createNodes(editor().structure.jobs).then(({size, edges, mappedNodes}) => { - batch(() => { - setSize(size); - setMappedNodes(mappedNodes); - setConnections(edges); - }); - }); - } + const mappedNodes = () => data.latest?.mappedNodes ?? {}; + const connections = () => data.latest?.edges ?? []; + const size = () => data.latest?.size ?? {width: 0, height: 0}; onMount(() => { const {unsubscribe} = editor - .watchCommand([editor.commands.updateJobNeeds]) + .watchCommand([ + editor.commands.updateJobNeeds, + editor.commands.addNewJob, + editor.commands.deleteJob, + ]) .subscribe(() => { - updateNodes(); + refetch(); }); onCleanup(() => unsubscribe()); }); - createEffect(() => { - updateNodes(); - }); - return (
- Promise.all([import('elkjs'), import('./Canvas/Canvas')]).then(([, m]) => ({ - default: m.Canvas, - })), + Promise.all([import('elkjs'), import('./Canvas/Canvas')]).then(([, m]) => m), ); export interface EditorProps { @@ -127,8 +117,11 @@ export function Editor(props: EditorProps) { position={'left'} /> - - + + }> @@ -153,18 +146,20 @@ export function Editor(props: EditorProps) { {rightPanel => ( <> - - - } - when={editor.selectedJob()} + + + - - - - + } + when={editor.selectedJob()} + > + + + + + )} @@ -187,22 +182,24 @@ export function Editor(props: EditorProps) { collapsible class={styles.resizablePanel} > - + + + ); }}
- + + + ); } function YamlEditorFallback() { const editor = useContext(EditorContext); - - createEffect(() => console.log(editor?.source.split('\n'))); return (
; } -export function OverlayLoader() { +export interface OverlayLoaderProps { + relative?: boolean; +} +export function OverlayLoader(props: OverlayLoaderProps) { return ( -
+
);