From 10833dca3274e33ecb29c7850a0fa357607b5326 Mon Sep 17 00:00:00 2001 From: Leonardo <leomilho@gmail.com> Date: Sat, 15 Jun 2024 14:30:35 +0200 Subject: [PATCH] feat(qb): qb attribute icon is a button to add logic pill --- .../lib/querybuilder/panel/QueryBuilder.tsx | 15 ++++++++- .../panel/QueryBuilderDispatcher.tsx | 13 +++++--- .../logicpill/QueryLogicPill.tsx | 2 +- .../pills/pilldropdown/PillDropdown.tsx | 33 ++++++++++++++++--- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx b/libs/shared/lib/querybuilder/panel/QueryBuilder.tsx index d5a38f395..26da1edfb 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 fd7329e7b..951bfc61e 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 032ae41e0..f17b0e705 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 3b796d784..85c84843a 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> -- GitLab