Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • graphpolaris/frontend-v2
  • rijkheere/frontend-v-2-reordering-paoh
2 results
Show changes
Commits on Source (10)
......@@ -246,11 +246,14 @@ export const MenuTrigger = React.forwardRef<HTMLElement, MenuTriggerProps>(
};
delete referenceProps.onMouseDown;
delete referenceProps.onPointerDown;
referenceProps.onClick = (event: React.MouseEvent) => {
event.preventDefault();
console.log('Click event!!!', context.isOpen);
context.setIsOpen(false);
};
delete referenceProps.onClick;
if (context.isOpen) {
referenceProps.onClick = (event: React.MouseEvent) => {
event.preventDefault();
context.setIsOpen(false);
};
}
}
const element = React.cloneElement(children as React.ReactElement<{ ref?: React.Ref<HTMLElement> }>, {
......
import { DropdownItem, DropdownItemContainer, Icon, Input, Popover, PopoverTrigger } from '@/lib/components';
import {
Menu,
MenuCheckboxItem,
MenuContent,
MenuItem,
MenuLabel,
MenuRadioGroup,
MenuRadioItem,
MenuSeparator,
MenuTrigger,
} from '@/lib/components/menu';
import {
attributeShownToggle,
setQuerybuilderGraphology,
......@@ -8,7 +18,7 @@ import {
import { isEqual } from 'lodash-es';
import { useEffect, useMemo, useState } from 'react';
import { Node, ReactFlowInstance } from 'reactflow';
import { defaultGraph, NodeAttribute, QueryRelationDirection, QueryUnionType } from 'ts-common';
import { defaultGraph, NodeAttribute, QueryGraphEdgeHandle, QueryRelationDirection, QueryUnionType } from 'ts-common';
import { useActiveQuery, useAppDispatch, useQuerybuilderHash } from '../..';
import { getDataTypeIcon } from '../../components/DataTypeIcon';
......@@ -20,7 +30,6 @@ export const QueryBuilderContextMenu = (props: {
reactFlow: ReactFlowInstance;
onClose: () => void;
}) => {
const [filter, setFilter] = useState<string>('');
const dispatch = useAppDispatch();
const activeQuery = useActiveQuery();
const qbHash = useQuerybuilderHash();
......@@ -45,7 +54,7 @@ export const QueryBuilderContextMenu = (props: {
return {
open: props.open,
x: position.x - divPosition.x - (initialPosition.x - divPosition.x),
x: position.x - divPosition.x - (initialPosition.x - divPosition.x) + 10,
y: position.y - divPosition.y - (initialPosition.y - divPosition.y) + 10,
};
}, [props.open, props.node, divPosition]);
......@@ -65,29 +74,22 @@ export const QueryBuilderContextMenu = (props: {
};
}, [props.reactFlowWrapper]);
const filteredAttributes = useMemo<NodeAttribute[]>(() => {
if (props.node == null) return [];
if (filter == null || filter.length == 0) return props.node.data.attributes;
return (props.node.data.attributes as NodeAttribute[]).filter(attr => {
return attr.handleData.attributeName?.toLocaleLowerCase().includes(filter.toLocaleLowerCase());
});
}, [filter, props.node]);
function isAttributeAdded(attribute: NodeAttribute): boolean {
return activeQuery?.attributesBeingShown.some(x => isEqual(x, attribute.handleData)) ?? false;
}
function addAttribute(attribute: NodeAttribute) {
function toggleAttribute(attribute: NodeAttribute) {
dispatch(attributeShownToggle(attribute.handleData));
}
function setUnionType(unionType: QueryUnionType) {
function setUnionType(value: string) {
const unionType = value as QueryUnionType;
if (!props.node) return;
dispatch(setQueryUnionType({ nodeId: props.node.id, unionType: unionType }));
}
function setRelationDirection(relationDirection: QueryRelationDirection) {
function setRelationDirection(value: string) {
const relationDirection = value as QueryRelationDirection;
if (!props.node) return;
// @ts-expect-error - graphology types are not up to date
graphologyGraph.setNodeAttribute(props.node.id, 'direction', relationDirection);
......@@ -111,96 +113,56 @@ export const QueryBuilderContextMenu = (props: {
}
return (
<Popover open={props.open && state !== undefined} interactive={true} showArrow={false} placement="bottom-start">
<PopoverTrigger x={state ? state.x : 0} y={state ? state.y : 0} />
<DropdownItemContainer root={props.reactFlowWrapper.current}>
{props.node && props?.node.type !== 'logic' && (
<>
<DropdownItem
value={'Add/remove attribute'}
onClick={e => {}}
submenu={[
<Input
label=""
type={'text'}
placeholder="Filter"
size="xs"
className="mb-1 rounded-sm w-full"
value={filter}
onClick={e => e.stopPropagation()}
onChange={v => setFilter(v)}
/>,
filteredAttributes.map(attr => (
<DropdownItem
key={attr.handleData.attributeName + attr.handleData.nodeId}
value={''}
selected={isAttributeAdded(attr)}
onClick={_ => addAttribute(attr)}
className="w-full"
>
<div className="flex items-center gap-1">
<Icon component={getDataTypeIcon(attr?.handleData?.attributeType)} className="" size={16} />
<span>{attr.handleData.attributeName ?? ''}</span>
</div>
</DropdownItem>
)),
]}
/>
<DropdownItem
value="Union type"
submenu={[
<DropdownItem
value="AND"
onClick={_ => setUnionType(QueryUnionType.AND)}
selected={props.node ? unionType != QueryUnionType.OR : false} // Also selected when null
/>,
<DropdownItem
value="OR"
onClick={_ => setUnionType(QueryUnionType.OR)}
selected={props.node ? unionType == QueryUnionType.OR : false}
/>,
]}
/>
{relationDirection && (
<DropdownItem
value="Direction"
submenu={[
<DropdownItem
value={QueryRelationDirection.BOTH}
onClick={_ => setRelationDirection(QueryRelationDirection.BOTH)}
selected={relationDirection === QueryRelationDirection.BOTH}
/>,
<DropdownItem
value={QueryRelationDirection.RIGHT}
onClick={_ => setRelationDirection(QueryRelationDirection.RIGHT)}
selected={relationDirection === QueryRelationDirection.RIGHT}
/>,
<DropdownItem
value={QueryRelationDirection.LEFT}
onClick={_ => setRelationDirection(QueryRelationDirection.LEFT)}
selected={relationDirection === QueryRelationDirection.LEFT}
/>,
]}
<Menu isOpen={props.open && state !== undefined}>
<MenuTrigger x={state ? state.x : 0} y={state ? state.y : 0}>
<div />
</MenuTrigger>
<MenuContent>
<Menu>
<MenuTrigger label="Add/remove attribute" />
<MenuContent className="max-h-60 overflow-y-auto">
{props.node?.data.attributes.map((attr: { handleData: QueryGraphEdgeHandle }) => (
<MenuCheckboxItem
key={attr.handleData.attributeName + attr.handleData.nodeId}
checked={isAttributeAdded(attr)}
onCheckedChange={_ => toggleAttribute(attr)}
label={attr.handleData.attributeName}
iconRight={getDataTypeIcon(attr?.handleData?.attributeType)}
/>
)}
<DropdownItem
value="Entity statistics"
submenu={[
<DropdownItem value="" disabled className="text-muted pointer-events-none">
<div className="flex items-between text-neutral-400">
<div className="inline-block w-[70px]">Total:</div>
<span>
{activeQuery?.graphCounts.nodeCounts ? activeQuery.graphCounts.nodeCounts[props.node.id + '_count'] : 'unknown'}
</span>
</div>
</DropdownItem>,
]}
/>
</>
))}
</MenuContent>
</Menu>
<Menu>
<MenuTrigger label="Union type" />
<MenuContent>
<MenuRadioGroup value={unionType ?? QueryUnionType.AND} onValueChange={setUnionType}>
<MenuRadioItem label="AND" value={QueryUnionType.AND} />
<MenuRadioItem label="OR" value={QueryUnionType.OR} />
</MenuRadioGroup>
</MenuContent>
</Menu>
{relationDirection && (
<Menu>
<MenuTrigger label="Direction" />
<MenuContent>
<MenuRadioGroup value={relationDirection} onValueChange={setRelationDirection}>
<MenuRadioItem label={QueryRelationDirection.BOTH} value={QueryRelationDirection.BOTH} />
<MenuRadioItem label={QueryRelationDirection.RIGHT} value={QueryRelationDirection.RIGHT} />
<MenuRadioItem label={QueryRelationDirection.LEFT} value={QueryRelationDirection.LEFT} />
</MenuRadioGroup>
</MenuContent>
</Menu>
)}
<DropdownItem value="Remove" className="text-danger" onClick={e => removeNode()} />
</DropdownItemContainer>
</Popover>
<Menu>
<MenuTrigger label="Entity statistics" />
<MenuContent>
<MenuLabel label="Total node count" />
<MenuItem disabled label={String(activeQuery?.graphCounts?.nodeCounts[props.node?.id + '_count'] ?? 'unknown')}></MenuItem>
</MenuContent>
</Menu>
<MenuSeparator />
<MenuItem label="Remove" className="text-danger" onClick={() => removeNode()} />
</MenuContent>
</Menu>
);
};