Skip to content

Commit e575df8

Browse files
Graph enhancements (#795)
* graph changes * graph properties changes * graph communities changes * graph type selection * checkbox check changes
1 parent 8de117b commit e575df8

10 files changed

+646
-406
lines changed

frontend/src/components/Graph/CheckboxSelection.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const CheckboxSelection: React.FC<CheckboxSectionProps> = ({
77
graphType,
88
loading,
99
handleChange,
10-
isgds,
10+
isCommunity,
1111
isDocChunk,
1212
isEntity,
1313
}) => (
@@ -29,7 +29,7 @@ const CheckboxSelection: React.FC<CheckboxSectionProps> = ({
2929
onChange={() => handleChange('Entities')}
3030
/>
3131
)}
32-
{isgds && (
32+
{isCommunity && (
3333
<Checkbox
3434
checked={graphType.includes('Communities')}
3535
label={graphLabels.community}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { useMemo } from 'react';
2+
import { ResizePanelDetails } from './ResizePanel';
3+
import { BasicNode, BasicRelationship, GraphPropertiesPanelProps } from '../../types';
4+
import { LegendsChip } from './LegendsChip';
5+
import GraphPropertiesTable from './GraphPropertiesTable';
6+
7+
8+
const sortAlphabetically = (a: string, b: string) => a.toLowerCase().localeCompare(b.toLowerCase());
9+
10+
const isNode = (item: BasicNode | BasicRelationship): item is BasicNode => {
11+
return 'labels' in item && !('from' in item) && !('to' in item);
12+
};
13+
14+
const GraphPropertiesPanel = ({ inspectedItem, newScheme }: GraphPropertiesPanelProps) => {
15+
const inspectedItemType = isNode(inspectedItem) ? 'node' : 'relationship';
16+
const properties = inspectedItemType === 'node'
17+
? [
18+
{
19+
key: '<id>',
20+
value: `${(inspectedItem as BasicNode).id}`,
21+
type: 'String',
22+
},
23+
...Object.keys((inspectedItem as BasicNode).properties).map((key) => {
24+
const value = (inspectedItem as BasicNode).properties[key];
25+
return { key: key, value: value ?? '' };
26+
}),
27+
]
28+
: [
29+
{
30+
key: '<element_id>',
31+
value: `${(inspectedItem as BasicRelationship).id}`,
32+
type: 'String',
33+
},
34+
{
35+
key: '<from>',
36+
value: `${(inspectedItem as BasicRelationship).from}`,
37+
type: 'String',
38+
},
39+
{
40+
key: '<to>',
41+
value: `${(inspectedItem as BasicRelationship).to}`,
42+
type: 'String',
43+
},
44+
{
45+
key: '<caption>',
46+
value: `${(inspectedItem as BasicRelationship).caption ?? ''}`,
47+
type: 'String',
48+
},
49+
];
50+
const labelsSorted = useMemo(() => {
51+
if (isNode(inspectedItem)) {
52+
return [...inspectedItem.labels].sort(sortAlphabetically);
53+
}
54+
return [];
55+
}, [inspectedItem]);
56+
57+
return (
58+
<>
59+
<ResizePanelDetails.Title>
60+
<h6 className="mr-auto">
61+
{inspectedItemType === 'node' ? 'Node details' : 'Relationship details'}
62+
</h6>
63+
</ResizePanelDetails.Title>
64+
<ResizePanelDetails.Content>
65+
<div className="mx-4 flex flex-row flex-wrap gap-2">
66+
{isNode(inspectedItem) ? (
67+
labelsSorted.map((label) => (
68+
<LegendsChip
69+
type="node"
70+
key={`node ${label}`}
71+
label={label}
72+
scheme={newScheme}
73+
/>
74+
))
75+
) : (
76+
<LegendsChip
77+
type="relationship"
78+
label={(inspectedItem as BasicRelationship).caption ?? ''}
79+
key={`relationship ${(inspectedItem as BasicRelationship).id}`}
80+
scheme={{}}
81+
/>
82+
)}
83+
</div>
84+
<div className="bg-palette-neutral-border-weak my-3 h-px w-full" />
85+
<GraphPropertiesTable propertiesWithTypes={properties} />
86+
</ResizePanelDetails.Content>
87+
</>
88+
);
89+
}
90+
91+
export default GraphPropertiesPanel;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { GraphLabel, Typography } from '@neo4j-ndl/react';
2+
import { GraphPropertiesTableProps } from '../../types';
3+
4+
const GraphPropertiesTable = ({ propertiesWithTypes }: GraphPropertiesTableProps): JSX.Element => {
5+
console.log('props', propertiesWithTypes);
6+
return (
7+
<div className="flex w-full flex-col break-all px-4 text-sm" data-testid="viz-details-pane-properties-table">
8+
<div className="mb-1 flex flex-row pl-2">
9+
<Typography variant="body-medium" className="basis-1/3">
10+
Key
11+
</Typography>
12+
<Typography variant="body-medium">Value</Typography>
13+
</div>
14+
{propertiesWithTypes.map(({ key, value }, _) => {
15+
return (
16+
<div
17+
key={key}
18+
className="border-palette-neutral-border-weak flex border-t py-1 pl-2 first:border-none"
19+
>
20+
<div className="shrink basis-1/3 overflow-hidden whitespace-nowrap">
21+
<GraphLabel
22+
type="propertyKey"
23+
tabIndex={-1}
24+
className="pointer-events-none !max-w-full overflow-ellipsis"
25+
>
26+
{key}
27+
</GraphLabel>
28+
</div>
29+
<div className={`ml-2 flex-1 whitespace-pre-wrap`}>
30+
{value}
31+
</div>
32+
</div>
33+
);
34+
})}
35+
</div>
36+
);
37+
};
38+
39+
export default GraphPropertiesTable;

0 commit comments

Comments
 (0)