Skip to content
Snippets Groups Projects
Commit 3d4badf9 authored by Leonardo Christino's avatar Leonardo Christino
Browse files

feat(qb): larger handle for mouse events

also fixes qb's pills growing due to large attribute names
parent 76e6978a
No related branches found
Tags v1.115.1
No related merge requests found
Pipeline #131887 passed
...@@ -197,7 +197,6 @@ export class GraphologyForceAtlas2Webworker extends GraphologyLayout { ...@@ -197,7 +197,6 @@ export class GraphologyForceAtlas2Webworker extends GraphologyLayout {
super.layout(graph, boundingBox); super.layout(graph, boundingBox);
const sensibleSettings = forceAtlas2.inferSettings(graph); const sensibleSettings = forceAtlas2.inferSettings(graph);
console.log(sensibleSettings);
const layout = new FA2Layout(graph, { const layout = new FA2Layout(graph, {
settings: { settings: {
......
...@@ -10,9 +10,13 @@ const selector = (s: any) => ({ ...@@ -10,9 +10,13 @@ const selector = (s: any) => ({
export const FilterHandle = ( export const FilterHandle = (
props: { props: {
handle: QueryGraphEdgeHandle; handle: QueryGraphEdgeHandle;
handleTop?: 'auto' | 'fixed';
hidden?: boolean;
} & Omit<HandleProps, 'id'> & } & Omit<HandleProps, 'id'> &
Omit<React.HTMLAttributes<HTMLDivElement>, 'id'> Omit<React.HTMLAttributes<HTMLDivElement>, 'id'>,
) => { ) => {
const outerSize = 8;
const innerSize = 3;
const { nodeInternals, edges } = useStore(selector); const { nodeInternals, edges } = useStore(selector);
const nodeId = useNodeId(); const nodeId = useNodeId();
...@@ -51,8 +55,50 @@ export const FilterHandle = ( ...@@ -51,8 +55,50 @@ export const FilterHandle = (
if (sourceWithLogic === targetHandleOfTypeLogic) return true; if (sourceWithLogic === targetHandleOfTypeLogic) return true;
else return false; else return false;
}, },
[nodeInternals, edges, nodeId, props.handle] [nodeInternals, edges, nodeId, props.handle],
); );
return <Handle id={id} {...props} isValidConnection={isValidConnection}></Handle>; const style: React.CSSProperties = {
width: outerSize * 2,
height: outerSize * 2,
top: props.handleTop === 'auto' ? `auto` : `calc(2rem - ${outerSize}px)`,
};
if (props.position === Position.Left) {
style.left = outerSize / 2;
} else {
style.right = outerSize / 2;
}
const handleStyle: React.CSSProperties = {};
if (props.position === Position.Left) {
handleStyle.left = 0;
} else {
handleStyle.right = 0;
}
const innerStyle: React.CSSProperties = { width: innerSize * 2, height: innerSize * 2 };
innerStyle.top = outerSize / 2 + innerSize / 4;
if (props.position === Position.Left) {
innerStyle.left = outerSize / 2 + innerSize / 4;
} else {
innerStyle.right = outerSize / 2 + innerSize / 4;
}
const innerProps = { ...props };
delete innerProps.className;
delete innerProps.style;
delete innerProps.handleTop;
return (
<div className="absolute " style={style}>
<Handle
id={id}
{...innerProps}
className={'!rounded-none !bg-transparent !w-full !h-full !border-0'}
style={handleStyle}
isValidConnection={isValidConnection}
></Handle>
<div className={'absolute pointer-events-none ' + props.className} style={innerStyle}></div>
</div>
);
}; };
...@@ -18,7 +18,7 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => ...@@ -18,7 +18,7 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) =>
const graph = useQuerybuilderGraph(); const graph = useQuerybuilderGraph();
const attributeEdges = useMemo( const attributeEdges = useMemo(
() => graph.edges.filter((edge) => edge.source === node.id && !!edge?.attributes?.sourceHandleData.attributeType), () => graph.edges.filter((edge) => edge.source === node.id && !!edge?.attributes?.sourceHandleData.attributeType),
[graph] [graph],
); );
const [hovered, setHovered] = useState(false); const [hovered, setHovered] = useState(false);
...@@ -48,19 +48,22 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => ...@@ -48,19 +48,22 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) =>
return ( return (
<div className="p-3 bg-transparent" onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}> <div className="p-3 bg-transparent" onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<div className={`rounded-sm shadow min-w-[8rem] text-[0.8rem] bg-gradient-to-r pt-1 from-[#FFA952] to-[#D66700]`}> <div className={`rounded-sm shadow min-w-[9rem] max-w-[9rem] text-[0.8rem] bg-gradient-to-r pt-1 from-[#FFA952] to-[#D66700]`}>
<div className={`pt-1 ${data.selected ? 'bg-secondary-400' : 'bg-secondary-50'}`}> <div className={`pt-1 ${data.selected ? 'bg-secondary-400' : 'bg-secondary-50'}`}>
<FilterHandle <FilterHandle
handle={data.leftRelationHandleId} handle={data.leftRelationHandleId}
type="target" type="target"
position={Position.Left} position={Position.Left}
className={'!top-8 !left-2 !bg-danger-700 !rounded-none'} // className={'!top-8 !left-2 !bg-danger-700 !rounded-none'}
// outerClassName={'!bg-blue-700 !rounded-none'}
className={'!bg-accent-700'}
/> />
<FilterHandle <FilterHandle
handle={data.rightRelationHandleId} handle={data.rightRelationHandleId}
type="source" type="source"
position={Position.Right} position={Position.Right}
className={'!top-8 !right-2 !bg-accent-700 !rounded-none'} // outerClassName={'!bg-blue-700 !rounded-none'}
className={'!bg-accent-700'}
/> />
<div className="text-center py-1">{data.name}</div> <div className="text-center py-1">{data.name}</div>
{data?.attributes && ( {data?.attributes && (
......
...@@ -26,15 +26,13 @@ export const LeftHandle = (props: Props) => { ...@@ -26,15 +26,13 @@ export const LeftHandle = (props: Props) => {
handle={props.handle} handle={props.handle}
type={props.type} type={props.type}
position={Position.Left} position={Position.Left}
className="!top- !left-2"
// style={{ transform: `translate(${offsetX}px, ${offsetY}px)` }}
onDoubleClickCapture={(e) => { onDoubleClickCapture={(e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
if (props.onDoubleClick) props.onDoubleClick(); if (props.onDoubleClick) props.onDoubleClick();
}} }}
> >
<svg className="pointer-events-none" height={10} style={{ transform: `translate(-2px, -3px)` }}> <svg className="pointer-events-none" height={10} style={{ transform: `translate(3px, 4px)` }}>
<polygon points={getArrow[props.point]} fill={tailwindColors.relation[200]} /> <polygon points={getArrow[props.point]} fill={tailwindColors.relation[200]} />
</svg> </svg>
</FilterHandle> </FilterHandle>
...@@ -47,15 +45,13 @@ export const RightHandle = (props: Props) => { ...@@ -47,15 +45,13 @@ export const RightHandle = (props: Props) => {
handle={props.handle} handle={props.handle}
type={props.type} type={props.type}
position={Position.Right} position={Position.Right}
className="!top-8 !right-2"
// style={{ transform: `translate(${offsetX}px, ${offsetY}px)` }}
onDoubleClickCapture={(e) => { onDoubleClickCapture={(e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
if (props.onDoubleClick) props.onDoubleClick(); if (props.onDoubleClick) props.onDoubleClick();
}} }}
> >
<svg height={10} className="pointer-events-none" style={{ transform: `translate(-2px, -3px)` }}> <svg height={10} className="pointer-events-none" style={{ transform: `translate(6px, 4px)` }}>
<polygon points={getArrow[props.point]} fill={tailwindColors.relation[200]} /> <polygon points={getArrow[props.point]} fill={tailwindColors.relation[200]} />
</svg> </svg>
</FilterHandle> </FilterHandle>
......
...@@ -63,7 +63,7 @@ export const PillDropdown = (props: PillDropdownProps) => { ...@@ -63,7 +63,7 @@ export const PillDropdown = (props: PillDropdownProps) => {
props.onHandleMouseDown(attribute, i, event); props.onHandleMouseDown(attribute, i, event);
}} }}
> >
<p>{attribute.handleData.attributeName}</p> <p className="truncate text-[0.6rem]">{attribute.handleData.attributeName}</p>
{attribute.handleData?.attributeDimension && ( {attribute.handleData?.attributeDimension && (
// <div className="!text-xs text-secondary-500">{IconMap[attribute.handleData.attributeDimension]}</div> // <div className="!text-xs text-secondary-500">{IconMap[attribute.handleData.attributeDimension]}</div>
// <div className="!text-xs text-secondary-500"> // <div className="!text-xs text-secondary-500">
...@@ -74,7 +74,8 @@ export const PillDropdown = (props: PillDropdownProps) => { ...@@ -74,7 +74,8 @@ export const PillDropdown = (props: PillDropdownProps) => {
handle={handleDataFromReactflowToDataId(props.node, attribute)} handle={handleDataFromReactflowToDataId(props.node, attribute)}
type="source" type="source"
position={Position.Right} position={Position.Right}
className={styles.handle + ' ' + '!top-auto mt-2 !right-[0.5rem] bg-secondary-500'} className={styles.handle + ' bg-secondary-500 rounded-full'}
handleTop="auto"
></FilterHandle> ></FilterHandle>
</div> </div>
); );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment