import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import type { RootState } from './store'; import Graph, { MultiGraph } from 'graphology'; /*************** schema format from the backend *************** */ // TODO: should probably not live here /** Schema type, consist of nodes and edges */ export type SchemaFromBackend = { edges: Edge[]; nodes: Node[]; }; /** Attribute type, consist of a name */ export type Attribute = { name: string; type: 'string' | 'int' | 'bool' | 'float'; }; /** Node type, consist of a name and a list of attributes */ export type Node = { name: string; attributes: Attribute[]; }; /** Edge type, consist of a name, start point, end point and a list of attributes */ export type Edge = { name: string; to: string; from: string; collection: string; attributes: Attribute[]; }; /**************************************************************** */ // Define the initial state using that type export const initialState = { graphologySerialized: new MultiGraph().export(), }; export const schemaSlice = createSlice({ name: 'schema', // `createSlice` will infer the state type from the `initialState` argument initialState, reducers: { setSchema: (state, action: PayloadAction<Graph>) => { console.log('setSchema', action); state.graphologySerialized = action.payload.export(); }, readInSchemaFromBackend: ( state, action: PayloadAction<SchemaFromBackend> ) => { const { nodes, edges } = action.payload; // Instantiate a directed graph that allows self loops and parallel edges const schema = new MultiGraph({ allowSelfLoops: true }); console.log('Updating schema'); // The graph schema needs a node for each node AND edge. These need then be connected // nodes.forEach((node) => { // schema.addNode(node.name, { // name: node.name, // attributes: node.attributes, // x: 0, // y: 0, // }); // }); // // The name of the edge will be name + from + to, since edge names are not unique // edges.forEach((edge) => { // const edgeID = edge.name + edge.from + edge.to; // // This node is the actual edge // schema.addNode(edgeID, { // name: edge.name, // attributes: edge.attributes, // from: edge.from, // to: edge.to, // collection: edge.collection, // x: 0, // y: 0, // }); // // These lines are simply for keeping the schema together // schema.addDirectedEdgeWithKey(edgeID + 'f', edge.from, edgeID); // schema.addDirectedEdgeWithKey(edgeID + 't', edgeID, edge.to); // }); state.graphologySerialized = schema.export(); }, }, }); export const { readInSchemaFromBackend, setSchema } = schemaSlice.actions; // Select the schema and convert it to a graphology object export const selectSchema = (state: RootState) => Graph.from(state.schema.graphologySerialized); export default schemaSlice.reducer;