Skip to content

Commit 851b434

Browse files
Connection modal implementation and dropzone allignment (#21)
* Dropdown Changes * Modified Components placement styling accoroding to figma design --------- Co-authored-by: Prakriti Solankey <156313631+prakriti-solankey@users.noreply.github.com>
1 parent 05b8fea commit 851b434

18 files changed

+737
-139
lines changed

frontend/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@
2828
"@typescript-eslint/eslint-plugin": "^6.0.0",
2929
"@typescript-eslint/parser": "^6.0.0",
3030
"@vitejs/plugin-react": "^4.0.3",
31+
"autoprefixer": "^10.4.17",
3132
"eslint": "^8.45.0",
3233
"eslint-config-prettier": "^8.5.0",
3334
"eslint-plugin-react-hooks": "^4.6.0",
3435
"eslint-plugin-react-refresh": "^0.4.3",
36+
"postcss": "^8.4.33",
3537
"prettier": "^2.7.1",
3638
"react-dropzone": "^14.2.3",
39+
"tailwindcss": "^3.4.1",
3740
"typescript": "^5.0.2",
3841
"vite": "^4.4.5"
3942
}

frontend/postcss.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}

frontend/src/App.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import './App.css';
22
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
3-
43
import ThemeWrapper from './context/ThemeWrapper';
54
import QuickStarter from './components/QuickStarter';
65

frontend/src/components/Content.tsx

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { useEffect, useState } from 'react';
22
import ConnectionModal from './ConnectionModal';
33
import { Button, Label, Typography, Flex } from '@neo4j-ndl/react';
44
import { setDriver, disconnect } from '../utils/Driver';
5-
import DropZone from './DropZone';
5+
import LlmDropdown from './Dropdown';
66
import { useCredentials } from '../context/UserCredentials';
7+
import FileTable from './FileTable';
78

89
export default function Content() {
910
const [init, setInit] = useState<boolean>(false);
@@ -34,25 +35,52 @@ export default function Content() {
3435
className='n-bg-palette-neutral-bg-default'
3536
style={{
3637
width: '100%',
37-
height: 'calc(100dvh - 58px)',
38+
height: 'calc(100dvh - 67px)',
3839
padding: 3,
3940
display: 'flex',
4041
flexDirection: 'column',
4142
alignItems: 'center',
4243
gap: 1,
4344
}}
4445
>
46+
<Flex className='w-full' alignItems='center' justifyContent='space-between' style={{ flexFlow: 'row' }}>
47+
<ConnectionModal
48+
open={openConnection}
49+
setOpenConnection={setOpenConnection}
50+
setConnectionStatus={setConnectionStatus}
51+
/>
52+
<Typography variant='body-medium' style={{ display: 'flex', padding: '20px' }}>
53+
Neo4j connection Status:
54+
<Typography variant='body-medium' style={{ marginLeft: '10px' }}>
55+
{!connectionStatus ? <Label color='danger'>Not connected</Label> : <Label color='success'>Connected</Label>}
56+
</Typography>
57+
</Typography>
58+
{!connectionStatus ? (
59+
<Button className='mr-2.5' onClick={() => setOpenConnection(true)}>
60+
Connect to Neo4j
61+
</Button>
62+
) : (
63+
<Button className='mr-2.5' onClick={() => disconnect().then(() => setConnectionStatus(false))}>
64+
Disconnect
65+
</Button>
66+
)}
67+
</Flex>
4568
<Flex
4669
flexDirection='column'
4770
style={{
4871
padding: '12px',
49-
justifyContent: 'center',
72+
justifyContent: 'space-evenly',
5073
alignItems: 'center',
5174
width: '100%',
5275
marginTop: '10px',
76+
height: '100%',
5377
}}
5478
>
55-
<DropZone />
79+
<FileTable></FileTable>
80+
<div style={{ marginTop: '15px', width: '100%', display: 'flex', justifyContent: 'space-between' }}>
81+
<LlmDropdown />
82+
<Button onClick={() => console.log('hello')}>Generate Graph</Button>
83+
</div>
5684
</Flex>
5785
</div>
5886
);
Lines changed: 42 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { Dropzone, Box, Label, Typography } from '@neo4j-ndl/react';
2-
import { useState, useEffect } from 'react';
3-
import FileTable from './FileTable';
1+
import { Dropzone } from '@neo4j-ndl/react';
2+
import { useState, useEffect, FunctionComponent } from 'react';
43
import Loader from '../utils/Loader';
54
import { uploadAPI } from '../services/Upload';
6-
import { healthStatus } from '../services/HealthStatus';
75
import { v4 as uuidv4 } from 'uuid';
86
import { useCredentials } from '../context/UserCredentials';
7+
import { useFileContext } from '../context/UsersFiles';
98

109
interface CustomFile extends Partial<globalThis.File> {
1110
processing: string;
@@ -15,19 +14,17 @@ interface CustomFile extends Partial<globalThis.File> {
1514
relationshipCount: number;
1615
}
1716

18-
export default function DropZone() {
19-
const [filesdata, setFilesdata] = useState<CustomFile[] | []>([]);
20-
const [files, setFiles] = useState<File[] | []>([]);
17+
const DropZone: FunctionComponent<{ isBackendConnected: Boolean }> = (props) => {
18+
const { files, filesData, setFiles, setFilesData } = useFileContext();
2119
const [isLoading, setIsLoading] = useState<boolean>(false);
22-
const [isBackendConnected, setIsBackendConnected] = useState<boolean>(false);
2320
const { userCredentials } = useCredentials();
2421

2522
const fileUpload = async (file: File, uid: number) => {
26-
if (filesdata[uid].status == 'None') {
23+
if (filesData[uid].status == 'None') {
2724
const apirequests = [];
2825
try {
2926
setIsLoading(true);
30-
setFilesdata((prevfiles) =>
27+
setFilesData((prevfiles) =>
3128
prevfiles.map((curfile, idx) => {
3229
if (idx == uid) {
3330
return {
@@ -46,7 +43,7 @@ export default function DropZone() {
4643
r.forEach((apiRes) => {
4744
if (apiRes.status === 'fulfilled' && apiRes.value) {
4845
if (apiRes?.value?.data != 'Unexpected Error') {
49-
setFilesdata((prevfiles) =>
46+
setFilesData((prevfiles) =>
5047
prevfiles.map((curfile, idx) => {
5148
if (idx == uid) {
5249
return {
@@ -72,7 +69,7 @@ export default function DropZone() {
7269
} catch (err) {
7370
console.log(err);
7471
setIsLoading(false);
75-
setFilesdata((prevfiles) =>
72+
setFilesData((prevfiles) =>
7673
prevfiles.map((curfile, idx) => {
7774
if (idx == uid) {
7875
return {
@@ -88,18 +85,6 @@ export default function DropZone() {
8885
}
8986
};
9087

91-
useEffect(() => {
92-
async function getHealthStatus() {
93-
try {
94-
const response = await healthStatus();
95-
setIsBackendConnected(response.data.healthy);
96-
} catch (error) {
97-
setIsBackendConnected(false);
98-
}
99-
}
100-
getHealthStatus();
101-
}, []);
102-
10388
useEffect(() => {
10489
if (files.length > 0) {
10590
for (let i = 0; i < files.length; i++) {
@@ -110,55 +95,38 @@ export default function DropZone() {
11095

11196
return (
11297
<>
113-
<Box
114-
style={{
115-
width: '100%',
116-
padding: '0.8em',
117-
}}
118-
>
119-
<Typography variant='body-medium' style={{ display: 'flex', marginBlock: '10px', marginLeft: '5px' }}>
120-
Backend connection Status:
121-
<Typography variant='body-medium' style={{ marginLeft: '10px' }}>
122-
{!isBackendConnected ? (
123-
<Label color='danger'>Not connected</Label>
124-
) : (
125-
<Label color='success'>Connected</Label>
126-
)}
127-
</Typography>
128-
</Typography>
129-
{isBackendConnected && (
130-
<Dropzone
131-
loadingComponent={isLoading && <Loader />}
132-
isTesting={true}
133-
dropZoneOptions={{
134-
accept: { 'application/pdf': ['.pdf'] },
135-
onDrop: (f: Partial<globalThis.File>[]) => {
136-
setIsLoading(false);
137-
if (f.length) {
138-
const defaultValues: CustomFile = {
139-
processing: 'None',
140-
status: 'None',
141-
NodesCount: 0,
142-
id: uuidv4(),
143-
relationshipCount: 0,
144-
};
145-
const updatedFiles: CustomFile[] = f.map((file) => ({
146-
name: file.name,
147-
type: file.type,
148-
size: file.size,
149-
...defaultValues,
150-
}));
151-
setFiles((prevfiles) => [...prevfiles, ...(f as File[])]);
152-
setFilesdata((prevfilesdata) => [...prevfilesdata, ...updatedFiles]);
153-
}
154-
},
155-
}}
156-
/>
157-
)}
158-
</Box>
159-
<div style={{ marginTop: '15px', width: '100%' }}>
160-
<div>{filesdata.length > 0 && <FileTable files={filesdata} />}</div>
161-
</div>
98+
{props.isBackendConnected && (
99+
<Dropzone
100+
loadingComponent={isLoading && <Loader />}
101+
isTesting={true}
102+
className='w-full h-full'
103+
dropZoneOptions={{
104+
accept: { 'application/pdf': ['.pdf'] },
105+
onDrop: (f: Partial<globalThis.File>[]) => {
106+
setIsLoading(false);
107+
if (f.length) {
108+
const defaultValues: CustomFile = {
109+
processing: 'None',
110+
status: 'None',
111+
NodesCount: 0,
112+
id: uuidv4(),
113+
relationshipCount: 0,
114+
};
115+
const updatedFiles: CustomFile[] = f.map((file) => ({
116+
name: file.name,
117+
type: file.type,
118+
size: file.size,
119+
...defaultValues,
120+
}));
121+
setFiles((prevfiles) => [...prevfiles, ...(f as File[])]);
122+
setFilesData((prevfilesdata) => [...prevfilesdata, ...updatedFiles]);
123+
}
124+
},
125+
}}
126+
/>
127+
)}
162128
</>
163129
);
164-
}
130+
};
131+
132+
export default DropZone;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Dropdown } from '@neo4j-ndl/react';
2+
import { useState } from 'react';
3+
4+
export default function LlmDropdown() {
5+
const [selectedValue, setSelectedValue] = useState<string>('');
6+
const allOptions = ['Diffbot', 'OpenAI GPT'];
7+
console.log('selctedValue', selectedValue);
8+
return (
9+
<>
10+
<div style={{ width: '150px' }}>
11+
<Dropdown
12+
type='select'
13+
selectProps={{
14+
onChange: (newValue) => newValue && setSelectedValue(newValue.value),
15+
options: allOptions.map((option) => ({ label: option, value: option })),
16+
value: { label: selectedValue, value: selectedValue },
17+
placeholder: 'Your',
18+
}}
19+
size='medium'
20+
fluid
21+
/>
22+
</div>
23+
</>
24+
);
25+
}

frontend/src/components/FileTable.tsx

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { DataGrid } from '@neo4j-ndl/react';
22
import { useState, useEffect } from 'react';
33
import { useReactTable, getCoreRowModel, createColumnHelper } from '@tanstack/react-table';
4+
import { useFileContext } from '../context/UsersFiles';
45

56
interface CustomFile extends Partial<globalThis.File> {
67
processing: string;
@@ -9,13 +10,13 @@ interface CustomFile extends Partial<globalThis.File> {
910
id: string;
1011
relationshipCount: number;
1112
}
12-
export default function FileTable({ files }: { files: CustomFile[] | [] }) {
13-
const [data, setData] = useState([...files]);
13+
export default function FileTable() {
14+
const { filesData } = useFileContext();
15+
const [data, setData] = useState([...filesData]);
1416
const columnHelper = createColumnHelper<CustomFile>();
15-
// console.log('hello ', data);
1617
const columns = [
1718
columnHelper.accessor('name', {
18-
cell: (info) => info.getValue(),
19+
cell: (info) => <div>{info.getValue()?.substring(0, 10) + '...'}</div>,
1920
footer: (info) => info.column.id,
2021
}),
2122
columnHelper.accessor((row) => row.size, {
@@ -57,29 +58,37 @@ export default function FileTable({ files }: { files: CustomFile[] | [] }) {
5758
];
5859

5960
useEffect(() => {
60-
setData([...files]);
61-
}, [files]);
61+
setData([...filesData]);
62+
}, [filesData]);
6263

6364
const table = useReactTable({
6465
data,
6566
columns,
6667
getCoreRowModel: getCoreRowModel(),
68+
initialState: {
69+
pagination: {
70+
pageSize: 5,
71+
},
72+
},
6773
});
6874

6975
return (
7076
<>
7177
{data ? (
72-
<div className='n-w-full n-bg-light-neutral-text-weakest'>
73-
<DataGrid
74-
isResizable={true}
75-
tableInstance={table}
76-
isKeyboardNavigable={true}
77-
styling={{
78-
zebraStriping: false,
79-
borderStyle: 'all-sides',
80-
}}
81-
/>
82-
</div>
78+
<>
79+
<div className='n-w-full'>
80+
<DataGrid
81+
isResizable={true}
82+
tableInstance={table}
83+
isKeyboardNavigable={true}
84+
styling={{
85+
zebraStriping: true,
86+
borderStyle: 'all-sides',
87+
headerStyle: 'clean',
88+
}}
89+
/>
90+
</div>
91+
</>
8392
) : null}
8493
</>
8594
);

0 commit comments

Comments
 (0)