diff --git a/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx b/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx index d5a38f39505286d682b0aeaab4d19b3a016744ce..26da1edfb41b03e3e960c6d7ee7e1acf8b5028fc 100644 --- a/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx @@ -444,10 +444,23 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { return ( <QueryBuilderDispatcherContext.Provider value={{ - openLogicPillChooser: (node) => { + openLogicPillUpdate: (node) => { editLogicNode.current = node; setToggleSettings('logic'); }, + openLogicPillCreate: (params, position) => { + if (!params?.handleId) return; + + let node = graphologyGraph.getNodeAttributes(params.nodeId); + const handleData = toHandleData(params.handleId); + connectingNodeId.current = { + params, + node, + position: position || { x: 0, y: 0 }, + attribute: { handleData: handleData }, + }; + setToggleSettings('logic'); + }, }} > <div ref={reactFlowWrapper} className="h-full w-full flex flex-col"> diff --git a/libs/shared/lib/querybuilder/panel/QueryBuilderDispatcher.tsx b/libs/shared/lib/querybuilder/panel/QueryBuilderDispatcher.tsx index fd7329e7bea8072a072a9852134bd2a92fe37378..951bfc61e076ae829fc2ccdb1e269d07e06d2b21 100644 --- a/libs/shared/lib/querybuilder/panel/QueryBuilderDispatcher.tsx +++ b/libs/shared/lib/querybuilder/panel/QueryBuilderDispatcher.tsx @@ -1,10 +1,15 @@ import React, { createContext } from 'react'; -import { SchemaReactflowLogicNode } from '../model'; +import { SchemaReactflowEntityNode, SchemaReactflowLogicNode } from '../model'; +import { OnConnectStartParams } from 'reactflow'; export const QueryBuilderDispatcherContext = createContext<{ - openLogicPillChooser: (node: SchemaReactflowLogicNode) => void; + openLogicPillUpdate: (node: SchemaReactflowLogicNode) => void; + openLogicPillCreate: (params: OnConnectStartParams, position?: { x: number; y: number }) => void; }>({ - openLogicPillChooser: (node: SchemaReactflowLogicNode) => { - throw new Error('openLogicPillChooser not implemented'); + openLogicPillUpdate: (node: SchemaReactflowLogicNode) => { + throw new Error('openLogicPillUpdate not implemented'); + }, + openLogicPillCreate: (params: OnConnectStartParams, position?: { x: number; y: number }) => { + throw new Error('openLogicPillCreate not implemented'); }, }); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/QueryLogicPill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/QueryLogicPill.tsx index 032ae41e07cde66bf49a7e01518ee3385f6544f7..f17b0e7058b5e36bf328173b442aa9d3f7ebb617 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/QueryLogicPill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/QueryLogicPill.tsx @@ -14,7 +14,7 @@ export function QueryLogicPill(node: SchemaReactflowLogicNode) { const dispatch = useAppDispatch(); const data = node.data; const logic = data.logic; - const { openLogicPillChooser } = useContext(QueryBuilderDispatcherContext); + const { openLogicPillUpdate: openLogicPillChooser } = useContext(QueryBuilderDispatcherContext); const output = data.logic.output; const inputReference = useRef<HTMLInputElement>(null); diff --git a/libs/shared/lib/querybuilder/pills/pilldropdown/PillDropdown.tsx b/libs/shared/lib/querybuilder/pills/pilldropdown/PillDropdown.tsx index 3b796d784ee2d4288556a0dbe350ddfb6885e915..85c84843a5cfcf552dda97d5bd8d713dbaebd8ef 100644 --- a/libs/shared/lib/querybuilder/pills/pilldropdown/PillDropdown.tsx +++ b/libs/shared/lib/querybuilder/pills/pilldropdown/PillDropdown.tsx @@ -1,4 +1,4 @@ -import { useMemo, ReactElement, useState } from 'react'; +import { useMemo, ReactElement, useState, useContext } from 'react'; import { NodeAttribute, QueryGraphEdges, SchemaReactflowEntityNode, handleDataFromReactflowToDataId, toHandleId } from '../../model'; import { Handle, Position, useUpdateNodeInternals } from 'reactflow'; import { Abc, CalendarToday, Map, Numbers, Place, QuestionMarkOutlined } from '@mui/icons-material'; @@ -8,6 +8,7 @@ import { pillDropdownPadding } from '@graphpolaris/shared/lib/components/pills/p import { Button, TextInput, useAppDispatch, useQuerybuilderAttributesShown } from '../../..'; import { attributeShownToggle } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; import { isEqual } from 'lodash-es'; +import { QueryBuilderDispatcherContext } from '../../panel/QueryBuilderDispatcher'; type PillDropdownProps = { node: SchemaReactflowEntityNode; @@ -35,6 +36,7 @@ export const PillDropdown = (props: PillDropdownProps) => { const [filter, setFilter] = useState<string>(''); const dispatch = useAppDispatch(); const attributesBeingShown = useQuerybuilderAttributesShown(); + const { openLogicPillCreate } = useContext(QueryBuilderDispatcherContext); const attributesOfInterest = useMemo(() => { return props.attributes.map((attribute) => @@ -53,13 +55,36 @@ export const PillDropdown = (props: PillDropdownProps) => { throw new Error('attribute.handleData.attributeName is undefined'); } + const handleId = toHandleId(handleDataFromReactflowToDataId(props.node, attribute)); + const handleType = 'source'; + return ( <div className="px-2 py-1 bg-secondary-100 flex justify-between items-center" key={(attribute.handleData.attributeName || '') + i} > <p className="truncate text-[0.6rem]">{attribute.handleData.attributeName}</p> - {attribute.handleData?.attributeDimension && <Icon component={IconMap[attribute.handleData.attributeDimension]} size={16} />} + <Button + variantType="secondary" + variant="ghost" + size="2xs" + iconComponent={ + attribute.handleData?.attributeDimension ? IconMap[attribute.handleData.attributeDimension] : <QuestionMarkOutlined /> + } + onClick={() => { + openLogicPillCreate( + { + nodeId: props.node.id, + handleId: handleId, + handleType: handleType, + }, + { + x: props.node.xPos + 200, + y: props.node.yPos + 50, + }, + ); + }} + /> <PillHandle mr={-pillDropdownPadding + (props.mr || 0)} handleTop="auto" @@ -68,8 +93,8 @@ export const PillDropdown = (props: PillDropdownProps) => { type="square" > <Handle - id={toHandleId(handleDataFromReactflowToDataId(props.node, attribute))} - type="source" + id={handleId} + type={handleType} position={Position.Right} className={'!rounded-none !bg-transparent !w-full !h-full !right-0 !left-0 !border-0'} ></Handle>