Skip to content

Commit 97b248c

Browse files
graph
1 parent b6ece75 commit 97b248c

File tree

9 files changed

+115
-44
lines changed

9 files changed

+115
-44
lines changed

frontend/src/HOC/CustomDropdown.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,21 @@ const GraphDropdown: React.FC<DropdownProps> = ({ onSelect, isDisabled }) => {
55
const handleChange = (selectedOption: OptionType | null | void) => {
66
onSelect(selectedOption);
77
};
8-
const allOptions = ['Pure Document','Document and Entities', 'Entities'];
8+
const allOptions = ['Document Structure','Document & Knowledge Graph', 'Knowledge Graph Entities'];
99
return (
1010
<>
11-
<div style={{ width: '150px' }}>
11+
<div style={{ width: '250px' }}>
1212
<Dropdown
1313
type='select'
1414
aria-label='A selection dropdown'
1515
selectProps={{
1616
onChange: handleChange,
1717
options: allOptions.map((option) => ({ label: option, value: option })),
18-
placeholder: 'Select Graph Type',
19-
defaultValue: { label: 'Pure Document', value: 'Pure Document' },
18+
defaultValue: { label: 'Document Structure', value: 'Document Structure' },
2019
menuPlacement: 'auto',
2120
isDisabled,
2221
}}
23-
size='medium'
22+
size='large'
2423
fluid
2524
/>
2625
</div>

frontend/src/components/ConnectionModal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useState } from 'react';
33
import { setDriver } from '../utils/Driver';
44
import { useCredentials } from '../context/UserCredentials';
55
import { ConnectionModalProps } from '../types';
6+
import connectAPI from '../services/ConnectAPI';
67

78
const ConnectionModal: React.FunctionComponent<ConnectionModalProps> = ({
89
open,
@@ -31,7 +32,7 @@ const ConnectionModal: React.FunctionComponent<ConnectionModalProps> = ({
3132
localStorage.setItem('database', database);
3233
localStorage.setItem('selectedProtocol', selectedProtocol);
3334
setLoading(true);
34-
const status = await setDriver(connectionURI, username, password, database);
35+
const status = await connectAPI(connectionURI);
3536
if (status === 'success') {
3637
setOpenConnection(false);
3738
setConnectionStatus(true);

frontend/src/components/Content.tsx

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const Content: React.FC<ContentProps> = ({ isExpanded, showChatBot, openChatBot
2525
const [showAlert, setShowAlert] = useState<boolean>(false);
2626
const [showGraph, setShowGraph] = useState<boolean>(false);
2727
const [selectedValue, setSelectedValue] = useState<string>('');
28+
const [viewPoint, setViewPoint] = useState<string>('tableView');
2829

2930
useEffect(() => {
3031
if (!init) {
@@ -173,33 +174,21 @@ const Content: React.FC<ContentProps> = ({ isExpanded, showChatBot, openChatBot
173174

174175

175176
const handleGraphView = () => {
176-
setOpenGraphView(!openGraphView);
177-
console.log('hello ppl', openGraphView);
178-
}
179-
const handleCloseGraph = () => {
180-
setShowGraph(false);
181-
};
182-
183-
const handleSelectvalue = (value: string) => {
184-
setSelectedValue(value);
177+
setOpenGraphView(true);
178+
setViewPoint('showGraphView');
185179
}
186180

187181
return (
188182
<>
189183
<CustomAlert open={showAlert} handleClose={handleClose} alertMessage={errorMessage} />
184+
190185
<div className={`n-bg-palette-neutral-bg-default ${classNameCheck}`}>
191186
<Flex className='w-full' alignItems='center' justifyContent='space-between' style={{ flexFlow: 'row' }}>
192187
<ConnectionModal
193188
open={openConnection}
194189
setOpenConnection={setOpenConnection}
195190
setConnectionStatus={setConnectionStatus}
196191
/>
197-
<GraphViewModal
198-
inspectedName={inspectedName}
199-
open={openGraphView}
200-
setGraphViewOpen={setOpenGraphView}
201-
viewPoint='tableGraph'
202-
/>
203192
<Typography
204193
variant='body-medium'
205194
style={{ display: 'flex', padding: '20px', alignItems: 'center', justifyContent: 'center' }}
@@ -235,6 +224,7 @@ const Content: React.FC<ContentProps> = ({ isExpanded, showChatBot, openChatBot
235224
onInspect={(name) => {
236225
setInspectedName(name);
237226
setOpenGraphView(true);
227+
setViewPoint('tableView');
238228
}}
239229
></FileTable>
240230
<Flex
@@ -260,14 +250,6 @@ const Content: React.FC<ContentProps> = ({ isExpanded, showChatBot, openChatBot
260250
>
261251
Show Graph
262252
</Button>
263-
{showGraph && (
264-
<GraphViewModal
265-
inspectedName={inspectedName}
266-
open={openGraphView}
267-
setGraphViewOpen={setOpenGraphView}
268-
viewPoint='showGraphView'
269-
/>
270-
)}
271253
<Button href={openGraphUrl} target='_blank' disabled={disableCheckGraph} className='ml-0.5'>
272254
Open Graph
273255
</Button>
@@ -281,6 +263,12 @@ const Content: React.FC<ContentProps> = ({ isExpanded, showChatBot, openChatBot
281263
</Flex>
282264
</Flex>
283265
</div>
266+
<GraphViewModal
267+
inspectedName={inspectedName}
268+
open={openGraphView}
269+
setGraphViewOpen={setOpenGraphView}
270+
viewPoint={viewPoint}
271+
/>
284272
</>
285273
);
286274
};

frontend/src/components/FileTable.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ const FileTable: React.FC<FileTableProps> = ({ isExpanded, connectionStatus, set
129129
try {
130130
setIsLoading(true);
131131
const res: any = await getSourceNodes(userCredentials);
132+
if(!res.data){
133+
throw new Error('Please check backend connection');
134+
}
132135
if (res.data.status !== 'Failed') {
133136
const prefiles: any[] = [];
134137
if (res.data.data.length) {

frontend/src/components/GraphViewModal.tsx

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { Button, Dialog, Flex } from '@neo4j-ndl/react';
1+
import { Button, Dialog, LoadingSpinner } from '@neo4j-ndl/react';
22
import { useEffect, useRef, useState } from 'react';
33
import { GraphViewModalProps } from '../types';
44
import { InteractiveNvlWrapper } from '@neo4j-nvl/react';
55
import NVL, { NvlOptions } from '@neo4j-nvl/core';
66
import { driver } from '../utils/Driver';
77
import GraphDropdown from '../HOC/CustomDropdown';
8-
import { useFileContext } from '../context/UsersFiles';
98

109
const uniqueElementsForDocQuery = `
1110
// Finds a document with chunks & entities. Transforms path objects to return a list of unique nodes and relationships.
@@ -19,6 +18,55 @@ UNWIND rels as rel
1918
WITH nodes, collect(DISTINCT rel) as rels
2019
RETURN nodes, rels`
2120

21+
const pureDocument = `
22+
MATCH (d:Document)
23+
WITH d ORDER BY d.createdAt DESC
24+
MATCH files = (d)<-[part:PART_OF]-(c:Chunk)
25+
WITH nodes(files) as nodes, relationships(files) as rels
26+
UNWIND nodes as node
27+
WITH collect(DISTINCT node) as nodes, collect(rels) as relslist
28+
UNWIND relslist as rels
29+
UNWIND rels as rel
30+
WITH nodes, collect(DISTINCT rel) as rels
31+
RETURN nodes, rels,
32+
collect { MATCH p=(c)-[:NEXT_CHUNK]-() RETURN p } as chain,
33+
collect { MATCH p=(c)-[:SIMILAR]-() RETURN p } as chunks;
34+
`
35+
36+
37+
const docEntitiesGraph = `
38+
MATCH (d:Document)
39+
WITH d ORDER BY d.createdAt DESC
40+
MATCH files = (d)<-[:PART_OF]-(c:Chunk)
41+
OPTIONAL MATCH p=(d)<-[:PART_OF]-(c:Chunk)-[:HAS_ENTITY]->(e)--(:!Chunk)
42+
WITH nodes(p) as nodes, relationships(p) as rels
43+
UNWIND nodes as node
44+
WITH collect(DISTINCT node) as nodes, collect(rels) as relslist
45+
UNWIND relslist as rels
46+
UNWIND rels as rel
47+
WITH nodes, collect(DISTINCT rel) as rels
48+
RETURN nodes, rels,
49+
collect { MATCH p=(c)-[:NEXT_CHUNK]-() RETURN p } as chain,
50+
collect { MATCH p=(c)-[:SIMILAR]-() RETURN p } as chunks,
51+
collect { OPTIONAL MATCH p=(c)-[:HAS_ENTITY]->(e)--(:!Chunk) RETURN p } as entities;`
52+
53+
54+
const knowledgeGraph = `
55+
MATCH (d:Document)
56+
WITH d ORDER BY d.createdAt DESC
57+
LIMIT 50
58+
MATCH files = (d)<-[:PART_OF]-(c:Chunk)
59+
RETURN
60+
collect { OPTIONAL MATCH p=(c)-[:HAS_ENTITY]->(e)--(:!Chunk) RETURN p } as entities`
61+
62+
63+
const queryMap: any = {
64+
'Document Structure': pureDocument,
65+
'Document & Knowledge Graph': docEntitiesGraph,
66+
'Knowledge Graph Entities': knowledgeGraph
67+
};
68+
69+
2270
const colors = [
2371
'#588c7e',
2472
'#f2e394',
@@ -77,7 +125,8 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
77125
const nvlRef = useRef<NVL>(null);
78126
const [nodes, setNodes] = useState([]);
79127
const [relationships, setRelationships] = useState([]);
80-
const {setGraphType } = useFileContext();
128+
const [graphType, setGraphType] = useState<string>('Document Structure');
129+
const [loading, setLoading] = useState<boolean>(false);
81130

82131
const handleDropdownChange = (option: any) => {
83132
setGraphType(option.value);
@@ -87,12 +136,20 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
87136
if (open) {
88137
setNodes([]);
89138
setRelationships([]);
139+
let queryToRun = '';
140+
if (viewPoint === 'tableView') {
141+
queryToRun = uniqueElementsForDocQuery;
142+
}
143+
else {
144+
queryToRun = queryMap[graphType]
145+
}
90146

91147
const session = driver.session();
92-
session.run(uniqueElementsForDocQuery, { 'document_name': inspectedName }).then(
148+
session.run(queryToRun, { 'document_name': inspectedName }).then(
93149
(results) => {
94150
// If this doc exists in the graph, the result length will be one.
95-
if (results.records.length == 1) {
151+
setLoading(true);
152+
if (results.records.length >= 1) {
96153
const neo4jNodes = results.records[0]._fields[0];
97154
const neo4jRels = results.records[0]._fields[1];
98155

@@ -120,13 +177,16 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
120177

121178
setNodes(newNodes);
122179
setRelationships(newRels);
123-
} else {
180+
setLoading(false);
181+
182+
}
183+
else {
124184
console.error("Unable to retrieve document graph for " + inspectedName, results);
125185
}
126186
}
127187
);
128188
}
129-
}, [open]);
189+
}, [open, graphType]);
130190

131191
// If the modal is closed, render nothing
132192
if (!open) {
@@ -152,13 +212,12 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
152212
return (
153213
<>
154214
<Dialog size='unset' open={open} aria-labelledby='form-dialog-title' disableCloseButton>
155-
<Flex className='w-full' alignItems='center' justifyContent='space-between' style={{ flexFlow: 'row' }}>
156-
<Dialog.Header id='form-dialog-title'>Inspect Generated Graph from {inspectedName}. </Dialog.Header>
157-
{true && <GraphDropdown onSelect={handleDropdownChange} isDisabled={false} />}
158-
</Flex>
215+
<Dialog.Header id='form-dialog-title'>Inspect Generated Graph from {inspectedName}. </Dialog.Header>
216+
{viewPoint === 'showGraphView' && <GraphDropdown onSelect={handleDropdownChange} isDisabled={false} />}
159217
<Dialog.Content className='n-flex n-flex-col n-gap-token-4'>
160218
<></>
161-
<div style={{ width: '100%', height: '600px' }}>
219+
<div style={{ width: '100%', height: '600px', border: '1px solid red' }}>
220+
{/* {loading && <LoadingSpinner size="large"/>} */}
162221
<InteractiveNvlWrapper
163222
ref={nvlRef}
164223
nodes={nodes}

frontend/src/components/Layout/DrawerDropzone.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ const DrawerDropzone: React.FC<DrawerProps> = ({ isExpanded }) => {
5454
type='push'
5555
closeable={false}
5656
key={'leftdrawer'}
57-
onExpandedChange={function Ha() {}}
5857
>
5958
<Drawer.Body style={{ overflow: 'hidden', height: 'intial' }}>
6059
<div className='flex h-full flex-col'>

frontend/src/context/UsersFiles.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const FileContextProvider: React.FC<FileContextProviderProps> = ({ children }) =
1919
const [files, setFiles] = useState<File[] | []>([]);
2020
const [filesData, setFilesData] = useState<CustomFile[] | []>([]);
2121
const [model, setModel] = useState<string>('OpenAI GPT 3.5');
22-
const [graphType, setGraphType]= useState<string>('Pure document')
22+
const [graphType, setGraphType]= useState<string>('Knowledge Graph Entities')
2323
const value: FileContextType = {
2424
files,
2525
filesData,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import axios from 'axios';
2+
import { url } from '../utils/Utils';
3+
4+
const connectAPI = async (userCredentials: any) => {
5+
try {
6+
const formData = new FormData();
7+
formData.append('uri', userCredentials?.uri ?? '');
8+
formData.append('database', userCredentials?.database ?? '');
9+
formData.append('userName', userCredentials?.userName ?? '');
10+
formData.append('password', userCredentials?.password ?? '');
11+
const response: any = await axios.post(`${url()}/connect`, formData, {
12+
headers: {
13+
'Content-Type': 'multipart/form-data',
14+
},
15+
});
16+
return response;
17+
} catch (error) {
18+
console.log('Error in connecting to the Neo4j instance :', error);
19+
throw error;
20+
}
21+
};
22+
export default connectAPI;

frontend/src/services/UpdateGraph.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const updateGraphAPI = async (userCredentials: any) => {
1515
});
1616
return response;
1717
} catch (error) {
18-
console.log('Error uploading file:', error);
18+
console.log('Error updating the graph:', error);
1919
throw error;
2020
}
2121
};

0 commit comments

Comments
 (0)