diff --git a/apps/web/package.json b/apps/web/package.json index 44dd9b3ff5a31408bbd823bbe5a37ef709e27f33..71a76d8b0e453eb8d6e6bfbe644ab9669fdc53cf 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -28,13 +28,9 @@ "styled-components": "^5.3.6" }, "devDependencies": { - "@iconify/json": "^2.2.95", - "@iconify/react": "^4.1.1", "@import-meta-env/cli": "^0.6.5", "@import-meta-env/unplugin": "^0.4.9", "@storybook/react": "7.0.0-rc.5", - "@svgr/core": "^8.0.0", - "@svgr/plugin-jsx": "^8.0.1", "@tailwindcss/typography": "^0.5.9", "@testing-library/react": "14.0.0", "@types/react": "^18.0.28", diff --git a/libs/shared/lib/data-access/store/hooks.ts b/libs/shared/lib/data-access/store/hooks.ts index 61710067235cc25b37b14c5aa7336923853eb4c1..224170da3c1371265a4f721f2a073abeff6f0db8 100644 --- a/libs/shared/lib/data-access/store/hooks.ts +++ b/libs/shared/lib/data-access/store/hooks.ts @@ -1,12 +1,11 @@ import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import { selectGraphQueryResult } from './graphQueryResultSlice'; -import { schemaGraph, schemaGraphology, selectSchemaLayout, schemaSettingsState } from './schemaSlice'; +import { schemaGraph, selectSchemaLayout, schemaSettingsState } from './schemaSlice'; import type { RootState, AppDispatch } from './store'; import { configState } from '@graphpolaris/shared/lib/data-access/store/configSlice'; import { queryBuilderSettingsState, selectQuerybuilderGraph, - selectQuerybuilderGraphology, selectQuerybuilderHash, } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; import { sessionCacheState } from './sessionSlice'; @@ -22,13 +21,11 @@ export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; export const useGraphQueryResult = () => useAppSelector(selectGraphQueryResult); // Gives the schema form the store (as a graphology object) -export const useSchemaGraphology = () => useAppSelector(schemaGraphology); export const useSchemaGraph = () => useAppSelector(schemaGraph); export const useSchemaSettings = () => useAppSelector(schemaSettingsState); // Gives the schema form the store (as a graphology object) export const useSchemaLayout = () => useAppSelector(selectSchemaLayout); -export const useQuerybuilderGraphology = () => useAppSelector(selectQuerybuilderGraphology); export const useQuerybuilderGraph = () => useAppSelector(selectQuerybuilderGraph); export const useQuerybuilderHash = () => useAppSelector(selectQuerybuilderHash); export const useQuerybuilderSettings = () => useAppSelector(queryBuilderSettingsState); diff --git a/libs/shared/lib/data-access/store/index.ts b/libs/shared/lib/data-access/store/index.ts index 154aec4d518e733c223f90b20dbea750d072138a..eb2b9cc7a19c31fee9376036a79c5443e19aaac9 100644 --- a/libs/shared/lib/data-access/store/index.ts +++ b/libs/shared/lib/data-access/store/index.ts @@ -2,7 +2,7 @@ export * from './store'; export * from './hooks'; export { setSchema, readInSchemaFromBackend, schemaSlice, selectSchemaLayout } from './schemaSlice'; -export { querybuilderSlice, setQuerybuilderNodes } from './querybuilderSlice'; +export { querybuilderSlice, setQuerybuilderGraph as setQuerybuilderNodes } from './querybuilderSlice'; export { selectGraphQueryResult, selectGraphQueryResultLinks, diff --git a/libs/shared/lib/data-access/store/querybuilderSlice.ts b/libs/shared/lib/data-access/store/querybuilderSlice.ts index ef4208ec551b950cf307ffeefa50e361492b475c..895b0f754d87a18cabf99dcf7ad417ad48071844 100644 --- a/libs/shared/lib/data-access/store/querybuilderSlice.ts +++ b/libs/shared/lib/data-access/store/querybuilderSlice.ts @@ -4,6 +4,8 @@ import Graph, { MultiGraph } from 'graphology'; import { Attributes, SerializedGraph } from 'graphology-types'; import { QueryMultiGraph, QueryMultiGraphology as QueryGraphology } from '../../querybuilder/model/graphology/utils'; +const defaultGraph = () => ({ nodes: [], edges: [], attributes: {}, options: {} }); + export type QueryBuilderSettings = { limit: number; depth: { min: number; max: number }; @@ -11,10 +13,10 @@ export type QueryBuilderSettings = { // Define the initial state using that type export const initialState: { - graphologySerialized: QueryMultiGraph; + graph: QueryMultiGraph; settings: QueryBuilderSettings; } = { - graphologySerialized: new QueryGraphology().export(), + graph: defaultGraph(), settings: { limit: 500, depth: { min: 0, max: 1 }, @@ -24,68 +26,43 @@ export const initialState: { export const querybuilderSlice = createSlice({ name: 'querybuilder', - // `createSlice` will infer the state type from the `initialState` argument initialState, reducers: { - setQuerybuilderNodes: (state, action: PayloadAction<QueryMultiGraph>) => { - // console.log('setQuerybuilderNodes', action.payload); + setQuerybuilderGraph: (state, action: PayloadAction<QueryMultiGraph>) => { // @ts-ignore - state.graphologySerialized = QueryGraphology.from(action.payload).export(); - // state.graphologySerialized = action.payload; + state.graph = action.payload; }, - // updateQBAttributeOperator: (state, action: PayloadAction<{ id: string; operator: string }>) => { - // const graph = QueryMultiGraphology.from(state.graphologySerialized); - // graph.setNodeAttribute(action.payload.id, 'operator', action.payload.operator); - // state.graphologySerialized = graph.export(); - // }, - // updateQBAttributeValue: (state, action: PayloadAction<{ id: string; value: string }>) => { - // const graph = QueryMultiGraphology.from(state.graphologySerialized); - // graph.setNodeAttribute(action.payload.id, 'value', action.payload.value); - // state.graphologySerialized = graph.export(); - // }, clearQB: (state) => { - state.graphologySerialized = new QueryGraphology().export(); + state.graph = defaultGraph(); }, setQuerybuilderSettings: (state, action: PayloadAction<QueryBuilderSettings>) => { state.settings = action.payload; }, - - // addQuerybuilderNode: ( - // state, - // action: PayloadAction<{ id: string; attributes: Attributes }> - // ) => { - // const graph = MultiGraph.from(state.graphologySerialized); - // graph.addNode(action.payload.id, action.payload.attributes); - // state.graphologySerialized = graph.export(); - // }, - // setGraphLayout: (state, action: PayloadAction<AllLayoutAlgorithms>) => { - // state.schemaLayout = action.payload; - // }, }, }); -export const { setQuerybuilderNodes, clearQB, setQuerybuilderSettings } = querybuilderSlice.actions; - export const queryBuilderSettingsState = (state: RootState) => state.querybuilder.settings; -/** Select the querybuilder nodes in serialized fromat */ -export const selectQuerybuilderGraphology = (state: RootState): QueryGraphology => { - // This is really weird but for some reason all the attributes appeared as read-only otherwise +export const setQuerybuilderGraphology = (payload: QueryGraphology) => { + return querybuilderSlice.actions.setQuerybuilderGraph(payload.export()); +}; +/** Select the querybuilder nodes in serialized fromat */ +export const toQuerybuilderGraphology = (graph: QueryMultiGraph): QueryGraphology => { let ret = new QueryGraphology(); - ret.import(Graph.from(state.querybuilder.graphologySerialized).export()); + ret.import(Graph.from(graph).export()); return ret; }; /** Select the querybuilder nodes and convert it to a graphology object */ export const selectQuerybuilderGraph = (state: RootState): QueryMultiGraph => { // This is really weird but for some reason all the attributes appeared as read-only otherwise - return state.querybuilder.graphologySerialized as QueryMultiGraph; + return state.querybuilder.graph as QueryMultiGraph; }; /** Select the querybuilder nodes and convert it to a graphology object */ export const selectQuerybuilderHash = (state: RootState): any => { - const hashedNodes = state.querybuilder.graphologySerialized.nodes.map((n) => { + const hashedNodes = state.querybuilder.graph.nodes.map((n) => { let node = { ...n }; if (n?.attributes) { let newAttributes = { ...n?.attributes }; @@ -100,7 +77,7 @@ export const selectQuerybuilderHash = (state: RootState): any => { return JSON.stringify({ nodes: hashedNodes, - edges: state.querybuilder.graphologySerialized.edges.map((n) => ({ + edges: state.querybuilder.graph.edges.map((n) => ({ key: n.key, source: n.source, target: n.target, @@ -117,3 +94,4 @@ export const selectQuerybuilderHash = (state: RootState): any => { // state.schema.schemaLayout; export default querybuilderSlice.reducer; +export const { setQuerybuilderGraph, clearQB, setQuerybuilderSettings } = querybuilderSlice.actions; diff --git a/libs/shared/lib/data-access/store/schemaSlice.ts b/libs/shared/lib/data-access/store/schemaSlice.ts index 082302c528b1e4583b323b54f2c5e98bdf4a81a5..3fdb6b89d10cacbbaf944b20c612ff1126d71e5f 100644 --- a/libs/shared/lib/data-access/store/schemaSlice.ts +++ b/libs/shared/lib/data-access/store/schemaSlice.ts @@ -11,14 +11,14 @@ export type SchemaSettings = { }; type schemaSliceI = { - graphologySerialized: SchemaGraph; + graph: SchemaGraph; layoutName: AllLayoutAlgorithms; settings: SchemaSettings; }; // Define the initial state using that type export const initialState: schemaSliceI = { - graphologySerialized: new SchemaGraphology().export(), + graph: new SchemaGraphology().export(), // layoutName: 'Cytoscape_fcose', layoutName: CytoscapeLayoutAlgorithms.KLAY as AllLayoutAlgorithms, settings: { @@ -32,7 +32,7 @@ export const schemaSlice = createSlice({ reducers: { setSchema: (state, action: PayloadAction<SchemaGraph>) => { console.log('setSchema', action); - state.graphologySerialized = action.payload; + state.graph = action.payload; }, setSchemaLayout: (state, action: PayloadAction<string>) => { @@ -41,7 +41,7 @@ export const schemaSlice = createSlice({ }, readInSchemaFromBackend: (state, action: PayloadAction<SchemaFromBackend>) => { - state.graphologySerialized = SchemaUtils.schemaBackend2Graphology(action.payload).export(); + state.graph = SchemaUtils.schemaBackend2Graphology(action.payload).export(); // console.log('Updated schema from backend'); // The graph schema needs a node for each node AND edge. These need then be connected @@ -89,10 +89,10 @@ export const schemaSettingsState = (state: RootState) => state.schema.settings; /** * Select the schema and convert it to a graphology object * */ -export const schemaGraphology = (state: RootState) => { +export const toSchemaGraphology = (graph: SchemaGraph): SchemaGraphology => { // This is really weird but for some reason all the attributes appeared as read-only otherwise let ret = new SchemaGraphology(); - ret.import(SchemaGraphology.from(state.schema.graphologySerialized).export()); + ret.import(SchemaGraphology.from(graph).export()); return ret; }; @@ -100,7 +100,7 @@ export const schemaGraphology = (state: RootState) => { * Select the schema * */ export const schemaGraph = (state: RootState): SchemaGraph => { - return state.schema.graphologySerialized; + return state.schema.graph; }; // /** diff --git a/libs/shared/lib/querybuilder/panel/querySettingsDialog.tsx b/libs/shared/lib/querybuilder/panel/querySettingsDialog.tsx index d5ccff8e3107de3f13a0725f3ff6c680fb6476bd..7b8e1891f06cf4e3fefeb1e2e840736781ee3545 100644 --- a/libs/shared/lib/querybuilder/panel/querySettingsDialog.tsx +++ b/libs/shared/lib/querybuilder/panel/querySettingsDialog.tsx @@ -6,8 +6,12 @@ import { useAppDispatch, useQuerybuilderSettings } from '../../data-access'; import { QueryBuilderSettings, setQuerybuilderSettings } from '../../data-access/store/querybuilderSlice'; import { addWarning } from '../../data-access/store/configSlice'; import { FormBody, FormCard, FormDiv, FormHBar, FormTitle } from '../../components/forms'; +import { NodeAttribute, QueryGraphNodes, toHandleData } from '../model'; +import { OnConnectStartParams, XYPosition } from 'reactflow'; -export const QuerySettingsDialog = React.forwardRef<HTMLDivElement, DialogProps>((props, ref) => { +type QuerySettingsDialogProps = DialogProps; + +export const QuerySettingsDialog = React.forwardRef<HTMLDivElement, QuerySettingsDialogProps>((props, ref) => { const qb = useQuerybuilderSettings(); const dispatch = useAppDispatch(); const [state, setState] = React.useState<QueryBuilderSettings>(qb); diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index f0955f7d52db1f6eaf9df13e14afbd0063d20b62..479d9471287a482167e2f2052904935804a6916a 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -1,12 +1,5 @@ import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { - setQuerybuilderNodes, - useConfig, - useQuerybuilderGraph, - useQuerybuilderGraphology, - useQuerybuilderSettings, - useSchemaGraphology, -} from '@graphpolaris/shared/lib/data-access/store'; +import { useConfig, useQuerybuilderGraph, useQuerybuilderSettings, useSchemaGraph } from '@graphpolaris/shared/lib/data-access/store'; import ReactFlow, { Background, Connection, @@ -27,7 +20,7 @@ import ReactFlow, { } from 'reactflow'; import styles from './querybuilder.module.scss'; -import { clearQB } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; +import { clearQB, setQuerybuilderGraphology, toQuerybuilderGraphology } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; import { Cached as CachedIcon, Delete as DeleteIcon, ImportExport as ExportIcon, Settings as SettingsIcon } from '@mui/icons-material'; import { useDispatch } from 'react-redux'; import { @@ -50,6 +43,7 @@ import { QueryBuilderLogicPillsPanel } from './querysidepanel/queryBuilderLogicP import { QueryBuilderMLPanel } from './querysidepanel/queryBuilderMLPanel'; import { Popup } from '../../components/Popup'; import { QuerySettingsDialog } from './querySettingsDialog'; +import { toSchemaGraphology } from '../../data-access/store/schemaSlice'; export type QueryBuilderProps = { onRunQuery?: () => void; @@ -65,19 +59,19 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { const reactFlowWrapper = useRef<HTMLDivElement>(null); const queryBuilderSettings = useQuerybuilderSettings(); - var nodeTypes = { - entity: EntityFlowElement, - relation: RelationPill, - logic: LogicPill, - }; + var nodeTypes = useMemo( + () => ({ + entity: EntityFlowElement, + relation: RelationPill, + logic: LogicPill, + }), + [] + ); - var edgeTypes = { - connection: ConnectionLine, - attribute_connection: ConnectionLine, - }; + var edgeTypes = useMemo(() => ({ connection: ConnectionLine, attribute_connection: ConnectionLine }), []); - const schema = useSchemaGraphology(); - const graphologyGraph = useQuerybuilderGraphology(); + const schemaGraph = useSchemaGraph(); + const schema = useMemo(() => toSchemaGraphology(schemaGraph), [schemaGraph]); const graph = useQuerybuilderGraph(); const config = useConfig(); const dispatch = useDispatch(); @@ -91,13 +85,13 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { const reactFlow = useReactFlow(); const isEdgeUpdating = useRef(false); const isOnConnect = useRef(false); + const graphologyGraph = useMemo(() => toQuerybuilderGraphology(graph), [graph]); + const elements = useMemo(() => createReactFlowElements(graphologyGraph), [graph]); const onInit = (reactFlowInstance: ReactFlowInstance) => { setTimeout(() => reactFlow.fitView(), 0); }; - const elements = useMemo(() => createReactFlowElements(graphologyGraph), [graph]); - /** * Clears all nodes in the graph. */ @@ -115,7 +109,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { }); // Dispatch the new graphology object, so reactflow will get re-rendered - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); } /** @@ -144,7 +138,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { // Call the drag usecase movePillTo(node.id, graphologyGraph, dx, dy, node.position); // Dispatch the new graphology object, so reactflow will get rerendered - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); } }); } @@ -186,7 +180,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { }, schema.getNodeAttribute(dragData.name, 'attributes') ); - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); break; // Creates a relation element and will also create the 2 related entities together with the connections case QueryElementTypes.Relation: @@ -206,7 +200,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { // sendQuery(); } - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); break; default: const logic = AllLogicMap[dragData.value.key]; @@ -221,7 +215,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { logic: logic, }); - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); } }; @@ -247,7 +241,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { sourceHandleData: toHandleData(connection.sourceHandle), targetHandleData: toHandleData(connection.targetHandle), }); - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); } } }, @@ -304,8 +298,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { ); const onNewNodeFromPopup = (value: AllLogicDescriptions) => { - console.log('onNewNodeFromPopup', value); - const logic = AllLogicMap[value.key]; const firstLeftLogicInput = logic.inputs?.[0]; if (!firstLeftLogicInput) return; @@ -347,7 +339,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { ); } - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); setToggleSettings(undefined); connectingNodeId.current = null; }; @@ -371,7 +363,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { sourceHandleData: toHandleData(newConnection.sourceHandle), targetHandleData: toHandleData(newConnection.targetHandle), }); - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); } }, [graph] @@ -387,7 +379,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { if (graphologyGraph.hasEdge(edge.id)) { graphologyGraph.dropEdge(edge.id); } - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); } isEdgeUpdating.current = false; }, @@ -397,7 +389,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { const onNodeContextMenu = (event: React.MouseEvent, node: Node) => { event.preventDefault(); graphologyGraph.dropNode(node.id); - dispatch(setQuerybuilderNodes(graphologyGraph.export())); + dispatch(setQuerybuilderGraphology(graphologyGraph)); }; return ( @@ -415,6 +407,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { title="Logic Pills usable by the node" className="min-h-[75vh] max-h-[75vh]" onDrag={() => {}} + connection={connectingNodeId?.current} /> </Dialog> <Popup open={toggleSettings === 'ml'} hAnchor="right"> diff --git a/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx b/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx index 72a4aab296c666754a50ec1fb71c54d3250ccd15..46c1f9e7aea1c001689d2f9076fac16b4bb27d7c 100644 --- a/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx +++ b/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx @@ -4,15 +4,24 @@ import GridOnIcon from '@mui/icons-material/GridOn'; import NumbersIcon from '@mui/icons-material/Numbers'; import AbcIcon from '@mui/icons-material/Abc'; import { useState } from 'react'; -import { AllLogicDescriptions, AllLogicMap } from '../../model'; +import { AllLogicDescriptions, AllLogicMap, NodeAttribute, QueryGraphNodes, toHandleData } from '../../model'; +import { OnConnectStartParams, XYPosition } from 'reactflow'; export const QueryBuilderLogicPillsPanel = (props: { className?: string; title?: string; - filter?: string; onClick: (item: AllLogicDescriptions) => void; onDrag?: (item: AllLogicDescriptions) => void; + connection?: { + params: OnConnectStartParams; + position: XYPosition; + node: QueryGraphNodes; + attribute: NodeAttribute; + } | null; }) => { + let filterType = (props.connection?.params?.handleId ? toHandleData(props.connection.params.handleId).attributeType : null) as string; + filterType = filterType && filterType === 'float' ? 'number' : filterType; + const dataOps = [ { title: 'aggregation', @@ -41,10 +50,9 @@ export const QueryBuilderLogicPillsPanel = (props: { description: 'Text', icon: <AbcIcon fontSize="small" />, }, - ]; - const filter = props.filter === 'number' ? 'float' : props.filter; - const [selectedOp, setSelectedOp] = useState(dataOps.findIndex((item) => item.title === filter) || -1); - const [selectedType, setSelectedType] = useState(dataTypes.findIndex((item) => item.title === filter) || -1); + ].filter((item) => !filterType || item.title === filterType); + const [selectedOp, setSelectedOp] = useState(-1); + const [selectedType, setSelectedType] = useState(-1); const onDragStart = (event: React.DragEvent, value: AllLogicDescriptions) => { console.log('drag start'); @@ -86,14 +94,14 @@ export const QueryBuilderLogicPillsPanel = (props: { </div> ))} </div> - <div className="overflow-x-hidden bg-base-200 h-full w-full mt-1"> - <ul className="menu bg-base-200 p-0 [&_li>*]:rounded-none w-full pb-10"> + <div className="overflow-x-hidden h-[75rem] w-full mt-1"> + <ul className="menu p-0 [&_li>*]:rounded-none w-full pb-10 h-full"> {Object.values(AllLogicMap) - .filter((item) => !filter || item.key.toLowerCase().includes(filter === 'number' ? 'float' : 'string')) + .filter((item) => !filterType || item.key.toLowerCase().includes(filterType)) .filter((item) => selectedOp === -1 || item.key.toLowerCase().includes(dataOps?.[selectedOp].title)) .filter((item) => selectedType === -1 || item.key.toLowerCase().includes(dataTypes?.[selectedType].title)) .map((item, index) => ( - <li key={item.key + item.description} className="h-fit"> + <li key={item.key + item.description} className="h-fit bg-base-200 "> <span data-tip={item.description} className="flex before:w-[10rem] before:text-center tooltip tooltip-bottom text-start " diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx index f92ddde07e2424c69a4abffd79e8042dae769c8b..b2963dd7b98ca114ef110c5309f208a456ab7783 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx @@ -1,6 +1,6 @@ // import { handles } from '@graphpolaris/shared/lib/querybuilder/usecases'; import { useQuerybuilderGraph } from '@graphpolaris/shared/lib/data-access'; -import React, { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; import { Handle, Position } from 'reactflow'; import { NodeAttribute, SchemaReactflowEntityNode, handleDataFromReactflowToId, toHandleId } from '../../../model'; import { styleHandleMap } from '../../utils'; @@ -22,15 +22,15 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => [graph] ); - const [hovered, setHovered] = React.useState(false); - const [handleBeingDragged, setHandleBeingDragged] = React.useState(-1); + const [hovered, setHovered] = useState(false); + const [handleBeingDragged, setHandleBeingDragged] = useState(-1); const onMouseEnter = (event: React.MouseEvent) => { - setHovered(true); + if (!hovered) setHovered(true); }; const onMouseLeave = (event: React.MouseEvent) => { - setHovered(false); + if (hovered) setHovered(false); }; const onHandleMouseDown = (attribute: NodeAttribute, i: number, event: React.MouseEvent) => { @@ -47,7 +47,10 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => console.log('EntityPill onConnect', params); }; - const showingDropdown = hovered || handleBeingDragged !== -1 || attributeEdges.length > 0 || forceOpen; + const showingDropdown = useMemo( + () => hovered || handleBeingDragged !== -1 || attributeEdges.length > 0 || forceOpen, + [hovered, handleBeingDragged, attributeEdges, forceOpen] + ); const dropDown = useMemo(() => { if (!data?.attributes) return null; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss index d4090da752aa4c8a5b54970c72cabcb153bef568..6a1592bfa3ba7da3ac008f16139ce96c00e0590f 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss @@ -9,27 +9,4 @@ font-size: 13px; display: flex; min-width: 5rem; - - .logicInput { - // float: right; - // background-color: #ee917a; - padding-left: 2px; - padding-right: 2px; - margin-top: 5px; - width: 3rem; - height: 1.2rem; - position: relative; - left: 0.8rem; - bottom: 0.3rem; - border: 1px solid; - border-radius: 0.1rem; - @apply border-logic-600; - } - .logicSpan { - // height: 100%; - padding: 0 1rem; - // display: flex; - // text-align: center; - // align-items: center; - } } diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss.d.ts index 1ed06c620d31f89809aa11045aadeadf0895020a..9fa2784a18c05ec92d88e5bf2147a3b37d389a1d 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss.d.ts +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss.d.ts @@ -20,7 +20,5 @@ declare const classNames: { readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft'; readonly handleFunction: 'handleFunction'; readonly logic: 'logic'; - readonly logicInput: 'logicInput'; - readonly logicSpan: 'logicSpan'; }; export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx index 5e853e044837bea61068d9cf2690e01e36f3096c..2d2c4de5d18dba9aec85c3de63e981c829f819c5 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx @@ -8,19 +8,14 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { - setQuerybuilderNodes, - useAppDispatch, - useQuerybuilderGraph, - useQuerybuilderGraphology, - useQuerybuilderHash, -} from '@graphpolaris/shared/lib/data-access'; +import { useAppDispatch, useQuerybuilderGraph, useQuerybuilderHash } from '@graphpolaris/shared/lib/data-access'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { Handle, HandleType, Position } from 'reactflow'; import { LogicNodeAttributes, SchemaReactflowLogicNode, toHandleId } from '../../../model'; import { InputNode, InputNodeTypeTypes } from '../../../model/logic/general'; import { styleHandleMap } from '../../utils'; import styles from './logicpill.module.scss'; +import { setQuerybuilderGraphology, toQuerybuilderGraphology } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; /** * Component to render an entity flow element @@ -33,12 +28,12 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { const output = data.logic.output; const graph = useQuerybuilderGraph(); - const graphology = useQuerybuilderGraphology(); const graphologyHash = useQuerybuilderHash(); + const graphologyGraph = useMemo(() => toQuerybuilderGraphology(graph), [graph]); const connectionsToLeft = useMemo(() => graph.edges.filter((edge) => edge.target === node.id), [graph]); const connectionsToRight = useMemo(() => graph.edges.filter((edge) => edge.source === node.id), [graph]); const graphologyNodeAttributes = useMemo<LogicNodeAttributes | undefined>( - () => (graphology.hasNode(node.id) ? { ...(graphology.getNodeAttributes(node.id) as LogicNodeAttributes) } : undefined), + () => (graphologyGraph.hasNode(node.id) ? { ...(graphologyGraph.getNodeAttributes(node.id) as LogicNodeAttributes) } : undefined), [node.id] ); const [localInputCache, setLocalInputCache] = useState<Record<string, InputNodeTypeTypes>>({ ...graphologyNodeAttributes?.inputs }); @@ -55,34 +50,34 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { if (!logicNode) throw new Error('LogicPill: logicNode is undefined'); let logicNodeInputs = { ...logicNode.inputs }; - if (logicNodeInputs[input.name] != value) { + if (data.inputs[input.name] !== value) { logicNodeInputs[input.name] = value; logicNode.inputs = logicNodeInputs; - graphology.setNodeAttribute<any>(node.id, 'inputs', logicNodeInputs); // FIXME: I'm not sure why TS requires <any> to work here - dispatch(setQuerybuilderNodes(graphology.export())); - console.log('updated input', input.name, 'to', value); + graphologyGraph.setNodeAttribute<any>(node.id, 'inputs', logicNodeInputs); // FIXME: I'm not sure why TS requires <any> to work here + dispatch(setQuerybuilderGraphology(graphologyGraph)); + // console.log('updated input', input.name, 'from', data.inputs[input.name], 'to', value); } }; - const createLeftHandles = useCallback( - (sideInputs: InputNode[]) => { - return sideInputs.filter((input, i) => { - return !connectionsToLeft.some( - (edge) => edge?.attributes?.targetHandleData.nodeId === data.id && edge?.attributes?.targetHandleData.attributeName === input.name - ); - }).length; - }, - [node] - ); - const leftInputsNumber = createLeftHandles(node.data.logic.inputs); + // const createLeftHandles = useCallback( + // (sideInputs: InputNode[]) => { + // return sideInputs.filter((input, i) => { + // return !connectionsToLeft.some( + // (edge) => edge?.attributes?.targetHandleData.nodeId === data.id && edge?.attributes?.targetHandleData.attributeName === input.name + // ); + // }).length; + // }, + // [node] + // ); + // const leftInputsNumber = createLeftHandles(node.data.logic.inputs); return ( - <div className={styles.logic}> - <span className={styles.logicSpan} style={{ height: `${Math.max(leftInputsNumber * 2.6, 1.5)}rem` }}> + <div className={styles.logic + ' w-fit h-min-[3rem]'}> + <div className="h-fit"> { - <span> + <div className="m-1 mx-2 text-left"> {connectionsToLeft.map((e) => e?.attributes?.sourceHandleData.attributeName)}.{output.name} - </span> + </div> } {node.data.logic.inputs.map((input, i) => { let inputTextBox = null; @@ -94,9 +89,10 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { ) { inputTextBox = ( <input - className={styles.logicInput} + className="px-0.5 m-2 mt-0 h-5 border-logic-600 rounded-sm border-[1px]" + style={{ width: input.type === 'string' ? '9rem' : '4rem' }} + placeholder="empty" value={localInputCache?.[input.name] as string} - style={{ top: -5, transform: `translateY(-${i * 20}%)` }} onChange={(e) => { setLocalInputCache({ ...localInputCache, [input.name]: e.target.value }); }} @@ -108,16 +104,17 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { ); } return ( - <Handle - type={'target'} - position={Position.Left} - id={toHandleId({ ...defaultHandleData, attributeName: input.name, attributeType: input.type })} - key={input.name + input.type} - style={{ top: `${((i + 0.8) / (node.data.logic.inputs.length + 0.6)) * 100}%` }} - className={styleHandleMap[input.type]} - > - {inputTextBox} - </Handle> + <> + <div className="w-full flex">{inputTextBox}</div> + <Handle + type={'target'} + position={Position.Left} + id={toHandleId({ ...defaultHandleData, attributeName: input.name, attributeType: input.type })} + key={input.name + input.type} + style={{ top: `${((i + 0.8) / (node.data.logic.inputs.length + 0.6)) * 100}%` }} + className={styleHandleMap[input.type] + ''} + ></Handle> + </> ); })} {!!node.data.logic.output && ( @@ -128,7 +125,7 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { className={styleHandleMap?.[output.type]} ></Handle> )} - </span> + </div> </div> ); } diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx index 09501947bf5415ebfe28dcd5e7df0f57b41f6a9f..dbda2f433602305b0bc42a70bf0ac74143a1432c 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx @@ -6,10 +6,12 @@ import { setQuerybuilderNodes, useAppDispatch, useConfig, - useQuerybuilderGraphology, + useQuerybuilderGraph, useQuerybuilderSettings, } from '@graphpolaris/shared/lib/data-access'; import { addWarning } from '@graphpolaris/shared/lib/data-access/store/configSlice'; +import { setQuerybuilderGraphology, toQuerybuilderGraphology } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; +import graphology from 'graphology'; /** * Component to render a relation flow element @@ -17,11 +19,12 @@ import { addWarning } from '@graphpolaris/shared/lib/data-access/store/configSli */ export const RelationPill = memo((node: SchemaReactflowRelationNode) => { const data = node.data; - const graphology = useQuerybuilderGraphology(); + const graph = useQuerybuilderGraph(); + const graphologyGraph = useMemo(() => toQuerybuilderGraphology(graph), [graph]); const settings = useQuerybuilderSettings(); const dispatch = useAppDispatch(); const graphologyNodeAttributes = useMemo<RelationNodeAttributes | undefined>( - () => (graphology.hasNode(node.id) ? { ...(graphology.getNodeAttributes(node.id) as RelationNodeAttributes) } : undefined), + () => (graphologyGraph.hasNode(node.id) ? { ...(graphologyGraph.getNodeAttributes(node.id) as RelationNodeAttributes) } : undefined), [node.id] ); const [depth, setDepth] = useState<{ min: number; max: number }>({ @@ -41,8 +44,8 @@ export const RelationPill = memo((node: SchemaReactflowRelationNode) => { } else if (depth.min >= depth.max) { dispatch(addWarning('The minimum depth cannot be larger than the maximum depth')); } else { - graphology.setNodeAttribute<any>(node.id, 'depth', depth); - dispatch(setQuerybuilderNodes(graphology.export())); + graphologyGraph.setNodeAttribute<any>(node.id, 'depth', depth); + dispatch(setQuerybuilderGraphology(graphologyGraph)); } }; diff --git a/libs/shared/lib/querybuilder/query-utils/query2backend.ts b/libs/shared/lib/querybuilder/query-utils/query2backend.ts index 4eb4c47a29f4def87af7614099c4a2b5d5cde1d5..e50c0d2d7b488133dab966eff5ac62df0bbc53ae 100644 --- a/libs/shared/lib/querybuilder/query-utils/query2backend.ts +++ b/libs/shared/lib/querybuilder/query-utils/query2backend.ts @@ -1,10 +1,8 @@ import { EntityNodeAttributes, LogicNodeAttributes, QueryGraphNodes, RelationNodeAttributes } from '../model/graphology/model'; import { QueryMultiGraph } from '../model/graphology/utils'; import { BackendQueryFormat, MachineLearning, NodeStruct, QueryStruct, RelationStruct } from '../model/BackendQueryFormat'; -import { Handles, QueryElementTypes, toHandleData } from '../model'; -import { get } from 'http'; -import { SerializedEdge, SerializedNode } from 'graphology-types'; -import { G } from 'vitest/dist/types-fafda418'; +import { QueryElementTypes, toHandleData } from '../model'; +import { SerializedNode } from 'graphology-types'; import { hasCycle } from 'graphology-dag'; import Graph, { MultiGraph } from 'graphology'; import { allSimplePaths } from 'graphology-simple-path'; @@ -117,10 +115,14 @@ export function calculateQueryLogic( if (!connectionToInputRef) { // Not connected, search for set or default value let val = node.attributes.inputs?.[inputRef.name] || inputRef.default; - if (val && inputRef.type === 'string') { - val = `\"${val}\"`; + if (inputRef.type === 'string') { + if (val) { + val = `\"${val}\"`; + } else { + val = `\".*\"`; // Empty means allow anything + } } - console.log('val', val, inputRef, node); + // console.log('val', val, inputRef, node); return val; } else if (connectionToInputRef.attributes?.sourceHandleData.nodeType === QueryElementTypes.Logic) { // Is connected to another logic node @@ -137,6 +139,7 @@ export function calculateQueryLogic( return l; } }); + return ret as AllLogicStatement; } diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx index a7ea87e3a3b703c581141d1d61534efeaf3c3a17..cd4e02336ae3ba9874d4a371fffd278e9912f517 100644 --- a/libs/shared/lib/schema/panel/schema.tsx +++ b/libs/shared/lib/schema/panel/schema.tsx @@ -1,12 +1,6 @@ import { AlgorithmToLayoutProvider, AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/shared/lib/graph-layout'; import { schemaGraphology2Reactflow, schemaExpandRelation } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { - useSchemaGraph, - useSchemaGraphology, - useSchemaLayout, - useSchemaSettings, - useSessionCache, -} from '@graphpolaris/shared/lib/data-access/store'; +import { useSchemaGraph, useSchemaLayout, useSchemaSettings, useSessionCache } from '@graphpolaris/shared/lib/data-access/store'; import { SmartBezierEdge, SmartStepEdge, SmartStraightEdge } from '@tisoap/react-flow-smart-edge'; import { useEffect, useMemo, useRef, useState } from 'react'; @@ -34,6 +28,7 @@ import NodeEdge from '../pills/edges/node-edge'; import SelfEdge from '../pills/edges/self-edge'; import { useSchemaAPI } from '../../data-access'; import { SchemaDialog } from './schemaDialog'; +import { toSchemaGraphology } from '../../data-access/store/schemaSlice'; interface Props { content?: string; @@ -79,8 +74,8 @@ export const Schema = (props: Props) => { const dialogRef = useRef<HTMLDivElement>(null); // In case the schema is updated - const schemaGraphology = useSchemaGraphology(); const schemaGraph = useSchemaGraph(); + const schemaGraphology = useMemo(() => toSchemaGraphology(schemaGraph), [schemaGraph]); const schemaLayout = useSchemaLayout(); const layout = useRef<AlgorithmToLayoutProvider<AllLayoutAlgorithms>>(); @@ -99,12 +94,10 @@ export const Schema = (props: Props) => { }, [props.auth]); useEffect(() => { - if (schemaGraphology == undefined || schemaGraphology.order == 0) { + if (schemaGraphology === undefined || schemaGraphology.order == 0) { return; } - console.log(schemaGraph); - updateLayout(); const expandedSchema = schemaExpandRelation(schemaGraphology); layout.current?.layout(expandedSchema); diff --git a/libs/shared/lib/schema/schema-utils/schema-usecases.ts b/libs/shared/lib/schema/schema-utils/schema-usecases.ts index 810e2e337d6b0f900298751faffe5fef6fcc0ef8..fcd643a90a1e129b2f41ed86b2c7357954610d57 100644 --- a/libs/shared/lib/schema/schema-utils/schema-usecases.ts +++ b/libs/shared/lib/schema/schema-utils/schema-usecases.ts @@ -4,11 +4,12 @@ import { Attributes } from 'graphology-types'; import { MarkerType, Edge, Node } from 'reactflow'; import { SchemaReactflowEntity } from '../model/reactflow'; import { QueryElementTypes } from '../../querybuilder'; +import { SchemaGraph, SchemaGraphology } from '../model'; //TODO does not belong here; maybe should go into the GraphPolarisThemeProvider const ANIMATEDEDGES = false; -export function schemaExpandRelation(graph: Graph): Graph { +export function schemaExpandRelation(graph: SchemaGraphology): SchemaGraphology { const newGraph = graph.copy(); newGraph.forEachNode((node, attributes) => { @@ -29,6 +30,7 @@ export function schemaExpandRelation(graph: Graph): Graph { // attributes: attributes // }, ...attributes, + attributes: [], x: 0, y: 0, type: QueryElementTypes.Relation, diff --git a/libs/shared/lib/schema/schema-utils/schema-utils.ts b/libs/shared/lib/schema/schema-utils/schema-utils.ts index 86cebcb2807d183385f518cae2193a5201d4a9d3..7d8dfa6992c5c666ce3cf36f966d77ddedbb0a3b 100644 --- a/libs/shared/lib/schema/schema-utils/schema-utils.ts +++ b/libs/shared/lib/schema/schema-utils/schema-utils.ts @@ -11,8 +11,6 @@ export class SchemaUtils { if (!nodes || !edges) return schemaGraphology; nodes.forEach((node) => { - console.log(node); - const attributes: SchemaGraphologyNode = { ...node, name: node.name, @@ -24,7 +22,6 @@ export class SchemaUtils { y: 0, }; schemaGraphology.addNode(node.name, attributes); - // console.log(node, schemaGraph.nodes()); }); // The name of the edge will be name + from + to, since edge names are not unique diff --git a/libs/shared/lib/vis/nodelink/components/NLForce.tsx b/libs/shared/lib/vis/nodelink/components/NLForce.tsx index 567e82cfbe5339967c836df519ff0bf9191cbca3..f6c1d9aa3c39978e3e7f1deb29403fa02633c58b 100644 --- a/libs/shared/lib/vis/nodelink/components/NLForce.tsx +++ b/libs/shared/lib/vis/nodelink/components/NLForce.tsx @@ -1,6 +1,5 @@ import { forceCenter, forceCollide, forceLink, forceManyBody, forceRadial, forceSimulation } from 'd3'; import { GraphType, LinkType, NodeType } from '../Types'; -import { useEffect } from 'react'; export const simulation = forceSimulation<NodeType, LinkType>(); diff --git a/libs/shared/lib/vis/nodelink/components/NLPixi.tsx b/libs/shared/lib/vis/nodelink/components/NLPixi.tsx index 2370370e5a1107d4510c8aef63480ee50dbd65c7..66cb2324d2f3cf9b7e23a014e10fb75ac68f361e 100644 --- a/libs/shared/lib/vis/nodelink/components/NLPixi.tsx +++ b/libs/shared/lib/vis/nodelink/components/NLPixi.tsx @@ -145,7 +145,8 @@ export const NLPixi = (props: Props) => { function toGlobal(node: NodeType): IPointData { if (viewport?.current) { - const rect = ref.current?.getBoundingClientRect(); + // const rect = ref.current?.getBoundingClientRect(); + const rect = { x: 0, y: 0 }; const x = (rect?.x || 0) + (node.x || 0); const y = (rect?.y || 0) + (node.y || 0); return viewport.current.toScreen(x, y); @@ -159,7 +160,7 @@ export const NLPixi = (props: Props) => { function onDragMove(event: FederatedPointerEvent) { event.stopPropagation(); - imperative.current.onDragMove(event.movementX, event.movementY); + if (imperative.current) imperative.current.onDragMove(event.movementX, event.movementY); } function onDragEnd(event: FederatedPointerEvent) { @@ -352,6 +353,7 @@ export const NLPixi = (props: Props) => { }; const update = (forceClear = false) => { + setPopups([]); if (!props.graph || !ref.current) return; if (props.graph) { diff --git a/libs/shared/lib/vis/nodelink/components/NLPopup.tsx b/libs/shared/lib/vis/nodelink/components/NLPopup.tsx index 8500994309622e1aacbeeff1dae7d7b998d41ae7..8ac151f99f56346f43bcf6ac1925e2ee7a1155d5 100644 --- a/libs/shared/lib/vis/nodelink/components/NLPopup.tsx +++ b/libs/shared/lib/vis/nodelink/components/NLPopup.tsx @@ -12,7 +12,8 @@ export const NLPopup = (props: NodelinkPopupProps) => { return ( <div className="absolute card card-bordered bg-white rounded-none text-[0.9rem] min-w-[10rem]" - style={{ top: props.data.pos.y + 10, left: props.data.pos.x + 10 }} + // style={{ top: props.data.pos.y + 10, left: props.data.pos.x + 10 }} + style={{ transform: 'translate(' + (props.data.pos.x + 20) + 'px, ' + (props.data.pos.y + 10) + 'px)' }} > <div className="card-body p-0"> <span className="px-2.5 pt-2"> diff --git a/libs/shared/lib/vis/nodelink/nodelinkvis.tsx b/libs/shared/lib/vis/nodelink/nodelinkvis.tsx index 5b2c7737d05f334f09322fe5293d679a35d71b9e..58f9d6568446f0cbd89193fdc8664205075e40ea 100644 --- a/libs/shared/lib/vis/nodelink/nodelinkvis.tsx +++ b/libs/shared/lib/vis/nodelink/nodelinkvis.tsx @@ -53,7 +53,7 @@ export const NodeLinkVis = React.memo((props: Props) => { useEffect(() => { if (graphQueryResult) { - console.log('graphQueryResult', graphQueryResult); + console.debug('graphQueryResult', graphQueryResult); setGraph( parseQueryResult(graphQueryResult, ml, { diff --git a/libs/shared/package.json b/libs/shared/package.json index 5a7fd734514753c7517c2aaf2d0619870423d771..e87add37344d86afa63c9cf81dc7ea2da39224c6 100644 --- a/libs/shared/package.json +++ b/libs/shared/package.json @@ -34,7 +34,6 @@ "classnames": "^2.3.2", "color": "^4.2.3", "config": "workspace:*", - "core-js": "^3.28.0", "cytoscape": "^3.23.0", "d3": "^6.6", "deck.gl": "^8.9.19", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 05e29cb6f2bfd69e7fb129b9613b2ab713e0fa53..e34849fcbb4d82edfcc1ac5b6865948c500ff0c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 3.0.3 turbo: specifier: latest - version: 1.10.13 + version: 1.10.14 vitest: specifier: ^0.29.2 version: 0.29.4 @@ -112,12 +112,6 @@ importers: specifier: ^5.3.6 version: 5.3.9(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0) devDependencies: - '@iconify/json': - specifier: ^2.2.95 - version: 2.2.95 - '@iconify/react': - specifier: ^4.1.1 - version: 4.1.1(react@18.2.0) '@import-meta-env/cli': specifier: ^0.6.5 version: 0.6.5(@import-meta-env/unplugin@0.4.9)(dotenv@16.3.1) @@ -127,12 +121,6 @@ importers: '@storybook/react': specifier: 7.0.0-rc.5 version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) - '@svgr/core': - specifier: ^8.0.0 - version: 8.0.0 - '@svgr/plugin-jsx': - specifier: ^8.0.1 - version: 8.0.1(@svgr/core@8.0.0) '@tailwindcss/typography': specifier: ^0.5.9 version: 0.5.9(tailwindcss@3.3.1) @@ -265,9 +253,6 @@ importers: config: specifier: workspace:* version: link:../config - core-js: - specifier: ^3.28.0 - version: 3.29.1 cytoscape: specifier: ^3.23.0 version: 3.23.0 @@ -460,7 +445,7 @@ importers: version: 8.7.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.13(eslint@7.32.0) + version: 1.10.14(eslint@7.32.0) eslint-plugin-import: specifier: 2.27.5 version: 2.27.5(@typescript-eslint/parser@5.52.0)(eslint-import-resolver-typescript@2.7.1)(eslint@7.32.0) @@ -668,7 +653,7 @@ importers: version: 8.7.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.13(eslint@7.32.0) + version: 1.10.14(eslint@7.32.0) eslint-plugin-react: specifier: 7.31.8 version: 7.31.8(eslint@7.32.0) @@ -3572,15 +3557,6 @@ packages: pathe: 1.1.0 dev: true - /@iconify/react@4.1.1(react@18.2.0): - resolution: {integrity: sha512-jed14EjvKjee8mc0eoscGxlg7mSQRkwQG3iX3cPBCO7UlOjz0DtlvTqxqEcHUJGh+z1VJ31Yhu5B9PxfO0zbdg==} - peerDependencies: - react: '>=16' - dependencies: - '@iconify/types': 2.0.0 - react: 18.2.0 - dev: true - /@iconify/types@2.0.0: resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} dev: true @@ -7545,113 +7521,41 @@ packages: engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-plugin-remove-jsx-attribute@5.4.0: resolution: {integrity: sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==} engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-plugin-remove-jsx-empty-expression@5.0.1: resolution: {integrity: sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==} engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-plugin-replace-jsx-attribute-value@5.0.1: resolution: {integrity: sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==} engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-plugin-svg-dynamic-title@5.4.0: resolution: {integrity: sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==} engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-plugin-svg-em-dimensions@5.4.0: resolution: {integrity: sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==} engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-plugin-transform-react-native-svg@5.4.0: resolution: {integrity: sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==} engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-transform-react-native-svg@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-UKrY3860AQICgH7g+6h2zkoxeVEPLYwX/uAjmqo4PIq2FIHppwhIqZstIyTz0ZtlwreKR41O3W3BzsBBiJV2Aw==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-plugin-transform-svg-component@5.5.0: resolution: {integrity: sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==} engines: {node: '>=10'} dev: true - /@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} - engines: {node: '>=12'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - dev: true - /@svgr/babel-preset@5.5.0: resolution: {integrity: sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==} engines: {node: '>=10'} @@ -7666,23 +7570,6 @@ packages: '@svgr/babel-plugin-transform-svg-component': 5.5.0 dev: true - /@svgr/babel-preset@8.0.0(@babel/core@7.21.3): - resolution: {integrity: sha512-KLcjiZychInVrhs86OvcYPLTFu9L5XV2vj0XAaE1HwE3J3jLmIzRY8ttdeAg/iFyp8nhavJpafpDZTt+1LIpkQ==} - engines: {node: '>=14'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.3 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.21.3) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.21.3) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.21.3) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.21.3) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.21.3) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.21.3) - '@svgr/babel-plugin-transform-react-native-svg': 8.0.0(@babel/core@7.21.3) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.21.3) - dev: true - /@svgr/core@5.5.0: resolution: {integrity: sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==} engines: {node: '>=10'} @@ -7694,19 +7581,6 @@ packages: - supports-color dev: true - /@svgr/core@8.0.0: - resolution: {integrity: sha512-aJKtc+Pie/rFYsVH/unSkDaZGvEeylNv/s2cP+ta9/rYWxRVvoV/S4Qw65Kmrtah4CBK5PM6ISH9qUH7IJQCng==} - engines: {node: '>=14'} - dependencies: - '@babel/core': 7.21.3 - '@svgr/babel-preset': 8.0.0(@babel/core@7.21.3) - camelcase: 6.3.0 - cosmiconfig: 8.1.3 - snake-case: 3.0.4 - transitivePeerDependencies: - - supports-color - dev: true - /@svgr/hast-util-to-babel-ast@5.5.0: resolution: {integrity: sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==} engines: {node: '>=10'} @@ -7714,14 +7588,6 @@ packages: '@babel/types': 7.22.5 dev: true - /@svgr/hast-util-to-babel-ast@8.0.0: - resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} - engines: {node: '>=14'} - dependencies: - '@babel/types': 7.22.5 - entities: 4.4.0 - dev: true - /@svgr/plugin-jsx@5.5.0: resolution: {integrity: sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==} engines: {node: '>=10'} @@ -7734,21 +7600,6 @@ packages: - supports-color dev: true - /@svgr/plugin-jsx@8.0.1(@svgr/core@8.0.0): - resolution: {integrity: sha512-bfCFb+4ZsM3UuKP2t7KmDwn6YV8qVn9HIQJmau6xeQb/iV65Rpi7NBNBWA2hcCd4GKoCqG8hpaaDk5FDR0eH+g==} - engines: {node: '>=14'} - peerDependencies: - '@svgr/core': '*' - dependencies: - '@babel/core': 7.21.3 - '@svgr/babel-preset': 8.0.0(@babel/core@7.21.3) - '@svgr/core': 8.0.0 - '@svgr/hast-util-to-babel-ast': 8.0.0 - svg-parser: 2.0.4 - transitivePeerDependencies: - - supports-color - dev: true - /@svgr/plugin-prettier@5.5.0: resolution: {integrity: sha512-mVc+u+eKUmy8sW5UnFpes9NqVtizJfnhasF8Srbi3XdxVTWyU5lmhWlQAgHLhcrsZKowQ0b7xBa4qWHI5Ew/VQ==} engines: {node: '>=10'} @@ -11746,6 +11597,7 @@ packages: dependencies: no-case: 3.0.4 tslib: 2.5.0 + dev: false /dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} @@ -12253,13 +12105,13 @@ packages: dependencies: eslint: 7.32.0 - /eslint-config-turbo@1.10.13(eslint@7.32.0): - resolution: {integrity: sha512-Ffa0SxkRCPMtfUX/HDanEqsWoLwZTQTAXO9W4IsOtycb2MzJDrVcLmoFW5sMwCrg7gjqbrC4ZJoD+1SPPzIVqg==} + /eslint-config-turbo@1.10.14(eslint@7.32.0): + resolution: {integrity: sha512-ZeB+IcuFXy1OICkLuAplVa0euoYbhK+bMEQd0nH9+Lns18lgZRm33mVz/iSoH9VdUzl/1ZmFmoK+RpZc+8R80A==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.10.13(eslint@7.32.0) + eslint-plugin-turbo: 1.10.14(eslint@7.32.0) /eslint-import-resolver-node@0.3.7: resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} @@ -12402,8 +12254,8 @@ packages: semver: 6.3.0 string.prototype.matchall: 4.0.8 - /eslint-plugin-turbo@1.10.13(eslint@7.32.0): - resolution: {integrity: sha512-el4AAmn0zXmvHEyp1h0IQMfse10Vy8g5Vbg4IU3+vD9CSj5sDbX07iFVt8sCKg7og9Q5FAa9mXzlCf7t4vYgzg==} + /eslint-plugin-turbo@1.10.14(eslint@7.32.0): + resolution: {integrity: sha512-sBdBDnYr9AjT1g4lR3PBkZDonTrMnR4TvuGv5W0OiF7z9az1rI68yj2UHJZvjkwwcGu5mazWA1AfB0oaagpmfg==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -15045,6 +14897,7 @@ packages: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: tslib: 2.5.0 + dev: false /lru-cache@10.0.0: resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} @@ -15595,6 +15448,7 @@ packages: dependencies: lower-case: 2.0.2 tslib: 2.5.0 + dev: false /node-bitmap@0.0.1: resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==} @@ -16336,7 +16190,7 @@ packages: dependencies: lilconfig: 2.1.0 postcss: 8.4.21 - ts-node: 10.9.1(@types/node@18.13.0)(typescript@4.9.5) + ts-node: 10.9.1(@types/node@17.0.12)(typescript@4.9.5) yaml: 1.10.2 dev: true @@ -18316,13 +18170,6 @@ packages: is-fullwidth-code-point: 4.0.0 dev: true - /snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} - dependencies: - dot-case: 3.0.4 - tslib: 2.5.0 - dev: true - /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -19262,64 +19109,64 @@ packages: safe-buffer: 5.2.1 dev: false - /turbo-darwin-64@1.10.13: - resolution: {integrity: sha512-vmngGfa2dlYvX7UFVncsNDMuT4X2KPyPJ2Jj+xvf5nvQnZR/3IeDEGleGVuMi/hRzdinoxwXqgk9flEmAYp0Xw==} + /turbo-darwin-64@1.10.14: + resolution: {integrity: sha512-I8RtFk1b9UILAExPdG/XRgGQz95nmXPE7OiGb6ytjtNIR5/UZBS/xVX/7HYpCdmfriKdVwBKhalCoV4oDvAGEg==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.13: - resolution: {integrity: sha512-eMoJC+k7gIS4i2qL6rKmrIQGP6Wr9nN4odzzgHFngLTMimok2cGLK3qbJs5O5F/XAtEeRAmuxeRnzQwTl/iuAw==} + /turbo-darwin-arm64@1.10.14: + resolution: {integrity: sha512-KAdUWryJi/XX7OD0alOuOa0aJ5TLyd4DNIYkHPHYcM6/d7YAovYvxRNwmx9iv6Vx6IkzTnLeTiUB8zy69QkG9Q==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.13: - resolution: {integrity: sha512-0CyYmnKTs6kcx7+JRH3nPEqCnzWduM0hj8GP/aodhaIkLNSAGAa+RiYZz6C7IXN+xUVh5rrWTnU2f1SkIy7Gdg==} + /turbo-linux-64@1.10.14: + resolution: {integrity: sha512-BOBzoREC2u4Vgpap/WDxM6wETVqVMRcM8OZw4hWzqCj2bqbQ6L0wxs1LCLWVrghQf93JBQtIGAdFFLyCSBXjWQ==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.13: - resolution: {integrity: sha512-0iBKviSGQQlh2OjZgBsGjkPXoxvRIxrrLLbLObwJo3sOjIH0loGmVIimGS5E323soMfi/o+sidjk2wU1kFfD7Q==} + /turbo-linux-arm64@1.10.14: + resolution: {integrity: sha512-D8T6XxoTdN5D4V5qE2VZG+/lbZX/89BkAEHzXcsSUTRjrwfMepT3d2z8aT6hxv4yu8EDdooZq/2Bn/vjMI32xw==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.13: - resolution: {integrity: sha512-S5XySRfW2AmnTeY1IT+Jdr6Goq7mxWganVFfrmqU+qqq3Om/nr0GkcUX+KTIo9mPrN0D3p5QViBRzulwB5iuUQ==} + /turbo-windows-64@1.10.14: + resolution: {integrity: sha512-zKNS3c1w4i6432N0cexZ20r/aIhV62g69opUn82FLVs/zk3Ie0GVkSB6h0rqIvMalCp7enIR87LkPSDGz9K4UA==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.13: - resolution: {integrity: sha512-nKol6+CyiExJIuoIc3exUQPIBjP9nIq5SkMJgJuxsot2hkgGrafAg/izVDRDrRduQcXj2s8LdtxJHvvnbI8hEQ==} + /turbo-windows-arm64@1.10.14: + resolution: {integrity: sha512-rkBwrTPTxNSOUF7of8eVvvM+BkfkhA2OvpHM94if8tVsU+khrjglilp8MTVPHlyS9byfemPAmFN90oRIPB05BA==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.13: - resolution: {integrity: sha512-vOF5IPytgQPIsgGtT0n2uGZizR2N3kKuPIn4b5p5DdeLoI0BV7uNiydT7eSzdkPRpdXNnO8UwS658VaI4+YSzQ==} + /turbo@1.10.14: + resolution: {integrity: sha512-hr9wDNYcsee+vLkCDIm8qTtwhJ6+UAMJc3nIY6+PNgUTtXcQgHxCq8BGoL7gbABvNWv76CNbK5qL4Lp9G3ZYRA==} hasBin: true optionalDependencies: - turbo-darwin-64: 1.10.13 - turbo-darwin-arm64: 1.10.13 - turbo-linux-64: 1.10.13 - turbo-linux-arm64: 1.10.13 - turbo-windows-64: 1.10.13 - turbo-windows-arm64: 1.10.13 + turbo-darwin-64: 1.10.14 + turbo-darwin-arm64: 1.10.14 + turbo-linux-64: 1.10.14 + turbo-linux-arm64: 1.10.14 + turbo-windows-64: 1.10.14 + turbo-windows-arm64: 1.10.14 dev: true /turf-jsts@1.2.3: @@ -20370,8 +20217,8 @@ packages: tinybench: 2.4.0 tinypool: 0.4.0 tinyspy: 1.1.1 - vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2) - vite-node: 0.29.4(@types/node@17.0.12)(sass@1.59.3) + vite: 4.2.1(@types/node@17.0.12)(sass@1.59.3) + vite-node: 0.29.4(@types/node@17.0.12)(sass@1.64.2) why-is-node-running: 2.2.2 transitivePeerDependencies: - less