Skip to content

Commit 4a912a1

Browse files
added backendconfig functionality (#1524)
1 parent bc6432d commit 4a912a1

2 files changed

Lines changed: 77 additions & 14 deletions

File tree

frontend/src/components/ChatBot/ChatOnlyComponent.tsx

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { ChatProps, connectionState, Messages, UserCredentials } from '../../typ
1111
import { getIsLoading } from '../../utils/Utils';
1212
import ThemeWrapper from '../../context/ThemeWrapper';
1313
import { SpotlightProvider } from '@neo4j-ndl/react';
14+
import { envConnectionAPI } from '../../services/ConnectAPI';
15+
import { showErrorToast } from '../../utils/Toasts';
1416

1517
const ChatContent: React.FC<ChatProps> = ({ chatMessages }) => {
1618
const { clearHistoryData, messages, setMessages, setClearHistoryData, setIsDeleteChatLoading, isDeleteChatLoading } =
@@ -23,10 +25,47 @@ const ChatContent: React.FC<ChatProps> = ({ chatMessages }) => {
2325
vectorIndexMisMatch: false,
2426
chunksExistsWithDifferentDimension: false,
2527
});
26-
/**
27-
* Initializes connection settings based on URL parameters.
28-
*/
29-
const initialiseConnection = useCallback(() => {
28+
const resolveConnectionFromBackend = useCallback(async (): Promise<boolean> => {
29+
try {
30+
const backendApiResponse = await envConnectionAPI();
31+
const connectionData = backendApiResponse.data;
32+
if (connectionData.data && connectionData.status === 'Success') {
33+
const credentials: UserCredentials = {
34+
uri: connectionData.data.uri,
35+
connection: 'backendApi',
36+
email: '',
37+
};
38+
setUserCredentials(credentials);
39+
setConnectionStatus(Boolean(connectionData.data.graph_connection));
40+
setShowDisconnectButton(true);
41+
if (chatMessages.length) {
42+
setMessages(chatMessages);
43+
}
44+
return true;
45+
}
46+
if (!connectionData.data && connectionData.status === 'Success') {
47+
const storedCredentials = localStorage.getItem('neo4j.connection');
48+
if (storedCredentials) {
49+
const parsed = JSON.parse(storedCredentials) as UserCredentials;
50+
parsed.password = atob(parsed.password as string);
51+
setUserCredentials(parsed);
52+
setConnectionStatus(Boolean(parsed.connection === 'connectAPI'));
53+
setShowDisconnectButton(true);
54+
if (chatMessages.length) {
55+
setMessages(chatMessages);
56+
}
57+
return true;
58+
}
59+
}
60+
} catch (_err) {
61+
const message =
62+
_err instanceof Error ? _err.message : 'Unable to reach the backend. Please check your connection.';
63+
showErrorToast(message);
64+
}
65+
return false;
66+
}, [chatMessages, setUserCredentials, setConnectionStatus, setShowDisconnectButton, setMessages]);
67+
68+
const initialiseConnection = useCallback(async () => {
3069
const urlParams = new URLSearchParams(window.location.search);
3170
const uri = urlParams.get('uri');
3271
const user = urlParams.get('user');
@@ -40,9 +79,14 @@ const ChatContent: React.FC<ChatProps> = ({ chatMessages }) => {
4079
if (connectionStatus) {
4180
setShowBackButton();
4281
setConnectionStatus(connectionStatus);
43-
setMessages(chatMessages);
82+
if (chatMessages.length) {
83+
setMessages(chatMessages);
84+
}
4485
} else {
45-
setOpenConnection((prev) => ({ ...prev, openPopUp: true }));
86+
const resolved = await resolveConnectionFromBackend();
87+
if (!resolved) {
88+
setOpenConnection((prev) => ({ ...prev, openPopUp: true }));
89+
}
4690
}
4791
} else {
4892
const credentialsForAPI: UserCredentials = {
@@ -56,11 +100,13 @@ const ChatContent: React.FC<ChatProps> = ({ chatMessages }) => {
56100
setShowBackButton();
57101
setUserCredentials(credentialsForAPI);
58102
setConnectionStatus(true);
59-
setMessages(chatMessages);
60-
// Remove query params from URL
103+
setShowDisconnectButton(true);
104+
if (chatMessages.length) {
105+
setMessages(chatMessages);
106+
}
61107
window.history.replaceState({}, document.title, window.location.pathname);
62108
}
63-
}, [chatMessages, setUserCredentials, setConnectionStatus, setMessages]);
109+
}, [chatMessages, setUserCredentials, setConnectionStatus, setMessages, resolveConnectionFromBackend]);
64110

65111
useEffect(() => {
66112
initialiseConnection();
@@ -92,7 +138,7 @@ const ChatContent: React.FC<ChatProps> = ({ chatMessages }) => {
92138
}
93139
} catch (error) {
94140
setIsDeleteChatLoading(false);
95-
console.error('Error clearing chat history:', error);
141+
showErrorToast(error instanceof Error ? error.message : 'Error clearing chat history');
96142
setClearHistoryData(false);
97143
}
98144
};

frontend/src/components/Layout/Header.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,17 @@ const Header: React.FC<HeaderProp> = ({ chatOnly, deleteOnClick, setOpenConnecti
3333
const downloadLinkRef = useRef<HTMLAnchorElement>(null);
3434
const { loginWithRedirect, isAuthenticated } = useAuth0();
3535
const firstTourTarget = useRef<HTMLDivElement>(null);
36-
const { connectionStatus } = useCredentials();
36+
const { connectionStatus, showDisconnectButton, setConnectionStatus, setUserCredentials, setShowDisconnectButton } =
37+
useCredentials();
38+
const chatOnlyDisconnect = useCallback(() => {
39+
setConnectionStatus(false);
40+
setShowDisconnectButton(false);
41+
setUserCredentials({ uri: '', password: '', userName: '', database: '', email: '' });
42+
localStorage.removeItem('neo4j.connection');
43+
if (setOpenConnection) {
44+
setOpenConnection((prev) => ({ ...prev, openPopUp: true }));
45+
}
46+
}, [setConnectionStatus, setUserCredentials, setShowDisconnectButton, setOpenConnection]);
3747
const chatAnchor = useRef<HTMLDivElement>(null);
3848
const { pathname } = useLocation();
3949
const [showChatModeOption, setShowChatModeOption] = useState<boolean>(false);
@@ -167,7 +177,7 @@ const Header: React.FC<HeaderProp> = ({ chatOnly, deleteOnClick, setOpenConnecti
167177
className='inline-flex gap-x-1'
168178
style={{ display: 'flex', flexGrow: 0, alignItems: 'center', gap: '4px' }}
169179
>
170-
{!connectionStatus && (
180+
{!connectionStatus ? (
171181
<Button
172182
size={'medium'}
173183
className={`${chatOnly ? '' : 'mr-2.5'}`}
@@ -179,6 +189,12 @@ const Header: React.FC<HeaderProp> = ({ chatOnly, deleteOnClick, setOpenConnecti
179189
>
180190
{buttonCaptions.connectToNeo4j}
181191
</Button>
192+
) : (
193+
showDisconnectButton && (
194+
<Button size={'medium'} className='mr-2.5' onClick={chatOnlyDisconnect}>
195+
{buttonCaptions.disconnect}
196+
</Button>
197+
)
182198
)}
183199
{showBackButton && (
184200
<IconButtonWithToolTip
@@ -219,6 +235,7 @@ const Header: React.FC<HeaderProp> = ({ chatOnly, deleteOnClick, setOpenConnecti
219235
text='Chat mode'
220236
placement='bottom'
221237
label='Chat mode'
238+
disabled={!connectionStatus}
222239
>
223240
<RiChatSettingsLine />
224241
</IconButtonWithToolTip>
@@ -235,7 +252,7 @@ const Header: React.FC<HeaderProp> = ({ chatOnly, deleteOnClick, setOpenConnecti
235252
'graph-builder-conversation.json'
236253
)
237254
}
238-
disabled={messages.length === 1 || getIsLoading(messages)}
255+
disabled={!connectionStatus || messages.length === 1 || getIsLoading(messages)}
239256
placement={chatOnly ? 'left' : 'bottom'}
240257
label={tooltips.downloadChat}
241258
>
@@ -253,7 +270,7 @@ const Header: React.FC<HeaderProp> = ({ chatOnly, deleteOnClick, setOpenConnecti
253270
aria-label='Remove chat history'
254271
clean
255272
onClick={deleteOnClick}
256-
disabled={messages.length === 1 || getIsLoading(messages)}
273+
disabled={!connectionStatus || messages.length === 1 || getIsLoading(messages)}
257274
placement={chatOnly ? 'left' : 'bottom'}
258275
label={tooltips.clearChat}
259276
>

0 commit comments

Comments
 (0)