Skip to content

Cancelling the API's on Unmounting phase #1068

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions frontend/src/API/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ const api = axios.create({

export const createDefaultFormData = (userCredentials: UserCredentials) => {
const formData = new FormData();
if (userCredentials?.uri) formData.append('uri', userCredentials?.uri);
if (userCredentials?.database) formData.append('database', userCredentials?.database);
if (userCredentials?.userName) formData.append('userName', userCredentials?.userName);
if (userCredentials?.password) formData.append('password', userCredentials?.password);
if (userCredentials?.email) formData.append('email', userCredentials?.email);
if (userCredentials?.uri) {
formData.append('uri', userCredentials?.uri);
}
if (userCredentials?.database) {
formData.append('database', userCredentials?.database);
}
if (userCredentials?.userName) {
formData.append('userName', userCredentials?.userName);
}
if (userCredentials?.password) {
formData.append('password', userCredentials?.password);
}
if (userCredentials?.email) {
formData.append('email', userCredentials?.email);
}
api.interceptors.request.use(
(config) => {
if (config.data instanceof FormData) {
Expand Down
32 changes: 14 additions & 18 deletions frontend/src/components/ChatBot/ChatInfoModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { ExtendedNode, chatInfoMessage } from '../../types';
import { useEffect, useMemo, useReducer, useRef, useState } from 'react';
import GraphViewButton from '../Graph/GraphViewButton';
import { chunkEntitiesAPI } from '../../services/ChunkEntitiesInfo';
import { useCredentials } from '../../context/UserCredentials';
import { tokens } from '@neo4j-ndl/base';
import ChunkInfo from './ChunkInfo';
import EntitiesInfo from './EntitiesInfo';
Expand Down Expand Up @@ -82,10 +81,10 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
error?.length
? 10
: mode === chatModeLables['global search+vector+fulltext']
? 7
: mode === chatModeLables.graph
? 4
: 3
? 7
: mode === chatModeLables.graph
? 4
: 3
);
const [, copy] = useCopyToClipboard();
const [copiedText, setcopiedText] = useState<boolean>(false);
Expand All @@ -98,17 +97,16 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
multiModelMetrics.length > 0 && Object.keys(multiModelMetrics[0]).length > 4
? true
: multiModelMetrics.length > 0 && Object.keys(multiModelMetrics[0]).length <= 4
? false
: null
? false
: null
);
const [isAdditionalMetricsWithSingleMode, setIsAdditionalMetricsWithSingleMode] = useState<boolean | null>(
metricDetails != undefined && Object.keys(metricDetails).length > 3
? true
: metricDetails != undefined && Object.keys(metricDetails).length <= 3
? false
: null
? false
: null
);

const actions: React.ComponentProps<typeof IconButton<'button'>>[] = useMemo(
() => [
{
Expand All @@ -133,18 +131,15 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
);

useEffect(() => {
const abortcontroller = new AbortController();
if (
(mode != chatModeLables.graph || error?.trim() !== '') &&
(!nodes.length || !infoEntities.length || !chunks.length)
) {
(async () => {
toggleInfoLoading();
try {
const response = await chunkEntitiesAPI(
nodeDetails,
entities_ids,
mode,
);
const response = await chunkEntitiesAPI(nodeDetails, entities_ids, mode, abortcontroller.signal);
if (response.data.status === 'Failure') {
throw new Error(response.data.error);
}
Expand Down Expand Up @@ -196,6 +191,7 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
if (metricsLoading) {
toggleMetricsLoading();
}
abortcontroller.abort();
};
}, [nodeDetails, mode, error, metricsLoading]);

Expand Down Expand Up @@ -353,9 +349,9 @@ const ChatInfoModal: React.FC<chatInfoMessage> = ({
{mode != chatModeLables.graph ? <Tabs.Tab tabId={3}>Sources used</Tabs.Tab> : <></>}
{mode != chatModeLables.graph ? <Tabs.Tab tabId={5}>Chunks</Tabs.Tab> : <></>}
{mode === chatModeLables['graph+vector'] ||
mode === chatModeLables.graph ||
mode === chatModeLables['graph+vector+fulltext'] ||
mode === chatModeLables['entity search+vector'] ? (
mode === chatModeLables.graph ||
mode === chatModeLables['graph+vector+fulltext'] ||
mode === chatModeLables['entity search+vector'] ? (
<Tabs.Tab tabId={4}>Top Entities used</Tabs.Tab>
) : (
<></>
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/ChatBot/ChatOnlyComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ const ChatContent: React.FC<ChatProps> = ({ chatMessages }) => {
} else {
setOpenConnection((prev) => ({ ...prev, openPopUp: true }));
}
}
else {
} else {
const credentialsForAPI: UserCredentials = {
uri,
userName: user,
Expand Down
49 changes: 24 additions & 25 deletions frontend/src/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const Content: React.FC<ContentProps> = ({
const [currentPage, setCurrentPage] = useState<number>(0);
const [totalPageCount, setTotalPageCount] = useState<number | null>(null);
const [textChunks, setTextChunks] = useState<chunkdata[]>([]);
const chunksTextAbortController = useRef<AbortController>();

const [alertStateForRetry, setAlertStateForRetry] = useState<BannerAlertProps>({
showAlert: false,
Expand Down Expand Up @@ -103,9 +104,9 @@ const Content: React.FC<ContentProps> = ({
additionalInstructions,
setAdditionalInstructions,
} = useFileContext();
const [viewPoint, setViewPoint] = useState<'tableView' | 'showGraphView' | 'chatInfoView' | 'neighborView'|'showSchemaView'>(
'tableView'
);
const [viewPoint, setViewPoint] = useState<
'tableView' | 'showGraphView' | 'chatInfoView' | 'neighborView' | 'showSchemaView'
>('tableView');
const [showDeletePopUp, setShowDeletePopUp] = useState<boolean>(false);
const [deleteLoading, setIsDeleteLoading] = useState<boolean>(false);

Expand Down Expand Up @@ -153,10 +154,10 @@ const Content: React.FC<ContentProps> = ({
? postProcessingTasks.filter((task) => task !== 'graph_schema_consolidation')
: postProcessingTasks
: hasSelections
? postProcessingTasks.filter(
? postProcessingTasks.filter(
(task) => task !== 'graph_schema_consolidation' && task !== 'enable_communities'
)
: postProcessingTasks.filter((task) => task !== 'enable_communities');
: postProcessingTasks.filter((task) => task !== 'enable_communities');
if (payload.length) {
const response = await postProcessing(payload);
if (response.data.status === 'Success') {
Expand Down Expand Up @@ -221,8 +222,9 @@ const Content: React.FC<ContentProps> = ({
});
};
const getChunks = async (name: string, pageNo: number) => {
chunksTextAbortController.current = new AbortController();
toggleChunksLoading();
const response = await getChunkText(name, pageNo);
const response = await getChunkText(name, pageNo, chunksTextAbortController.current.signal);
setTextChunks(response.data.data.pageitems);
if (!totalPageCount) {
setTotalPageCount(response.data.data.total_pages);
Expand Down Expand Up @@ -271,11 +273,7 @@ const Content: React.FC<ContentProps> = ({
});
if (fileItem.name != undefined && userCredentials != null) {
const { name } = fileItem;
triggerStatusUpdateAPI(
name as string,
userCredentials,
updateStatusForLargeFiles
);
triggerStatusUpdateAPI(name as string, userCredentials, updateStatusForLargeFiles);
}

const apiResponse = await extractAPI(
Expand Down Expand Up @@ -544,12 +542,14 @@ const Content: React.FC<ContentProps> = ({
let finalUrl = bloomUrl;
if (userCredentials?.database && userCredentials.uri && userCredentials.userName) {
const uriCoded = userCredentials.uri.replace(/:\d+$/, '');
const connectURL = `${uriCoded.split('//')[0]}//${userCredentials.userName}@${uriCoded.split('//')[1]}:${userCredentials.port ?? '7687'}`;
const connectURL = `${uriCoded.split('//')[0]}//${userCredentials.userName}@${uriCoded.split('//')[1]}:${
userCredentials.port ?? '7687'
}`;
const encodedURL = encodeURIComponent(connectURL);
finalUrl = bloomUrl?.replace('{CONNECT_URL}', encodedURL);
}
window.open(finalUrl, '_blank');
};
};

const handleGraphView = () => {
setOpenGraphView(true);
Expand Down Expand Up @@ -611,12 +611,12 @@ const Content: React.FC<ContentProps> = ({
return prev.map((f) => {
return f.name === filename
? {
...f,
status: 'Ready to Reprocess',
processingProgress: isStartFromBegining ? 0 : f.processingProgress,
nodesCount: isStartFromBegining ? 0 : f.nodesCount,
relationshipsCount: isStartFromBegining ? 0 : f.relationshipsCount,
}
...f,
status: 'Ready to Reprocess',
processingProgress: isStartFromBegining ? 0 : f.processingProgress,
nodesCount: isStartFromBegining ? 0 : f.nodesCount,
relationshipsCount: isStartFromBegining ? 0 : f.relationshipsCount,
}
: f;
});
});
Expand Down Expand Up @@ -855,7 +855,10 @@ const Content: React.FC<ContentProps> = ({
{showChunkPopup && (
<ChunkPopUp
chunksLoading={chunksLoading}
onClose={() => toggleChunkPopup()}
onClose={() => {
chunksTextAbortController.current?.abort();
toggleChunkPopup();
}}
showChunkPopup={showChunkPopup}
chunks={textChunks}
incrementPage={incrementPage}
Expand Down Expand Up @@ -885,11 +888,7 @@ const Content: React.FC<ContentProps> = ({
<div className='connectionstatus__container'>
<span className='h6 px-1'>Neo4j connection {isReadOnlyUser ? '(Read only Mode)' : ''}</span>
<Typography variant='body-medium'>
<DatabaseStatusIcon
isConnected={connectionStatus}
isGdsActive={isGdsActive}
uri={userCredentials?.uri}
/>
<DatabaseStatusIcon isConnected={connectionStatus} isGdsActive={isGdsActive} uri={userCredentials?.uri} />
<div className='pt-1 flex gap-1 items-center'>
<div>{!hasSelections ? <StatusIndicator type='danger' /> : <StatusIndicator type='success' />}</div>
<div>
Expand Down
11 changes: 10 additions & 1 deletion frontend/src/components/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { OptionType, ReusableDropdownProps } from '../types';
import { memo, useMemo } from 'react';
import { capitalize, capitalizeWithUnderscore } from '../utils/Utils';
import { prodllms } from '../utils/Constants';
import { InformationCircleIconOutline } from '@neo4j-ndl/react/icons';

const DropdownComponent: React.FC<ReusableDropdownProps> = ({
options,
placeholder,
Expand All @@ -29,7 +31,14 @@ const DropdownComponent: React.FC<ReusableDropdownProps> = ({
<Select
type='select'
label='LLM Models'
helpText={<div className='!w-max'> LLM Model used for Extraction & Chat</div>}
helpText={
<div className='!w-max flex gap-1 items-center'>
<span>
<InformationCircleIconOutline title='info' aria-label='infoicon' className='n-size-token-6' />
</span>
<span>LLM Model used for Extraction & Chat</span>
</div>
}
selectProps={{
onChange: handleChange,
// @ts-ignore
Expand Down
13 changes: 2 additions & 11 deletions frontend/src/components/FileTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -683,20 +683,11 @@ const FileTable: ForwardRefRenderFunction<ChildRef, FileTableProps> = (props, re
};

const handleSmallFile = (item: SourceNode, userCredentials: UserCredentials) => {
subscribe(
item.fileName,
userCredentials,
updatestatus,
updateProgress
).catch(handleFileUploadError);
subscribe(item.fileName, userCredentials, updatestatus, updateProgress).catch(handleFileUploadError);
};

const handleLargeFile = (item: SourceNode, userCredentials: UserCredentials) => {
triggerStatusUpdateAPI(
item.fileName,
userCredentials,
updateStatusForLargeFiles
);
triggerStatusUpdateAPI(item.fileName, userCredentials, updateStatusForLargeFiles);
};
useEffect(() => {
const waitingQueue: CustomFile[] = JSON.parse(
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/components/Graph/GraphViewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
const [disableRefresh, setDisableRefresh] = useState<boolean>(false);
const [selected, setSelected] = useState<{ type: EntityType; id: string } | undefined>(undefined);
const [mode, setMode] = useState<boolean>(false);
const graphQueryAbortControllerRef = useRef<AbortController>();

const graphQuery: string =
graphType.includes('DocumentChunk') && graphType.includes('Entities')
Expand Down Expand Up @@ -109,17 +110,23 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({
}, [allNodes]);

const fetchData = useCallback(async () => {
graphQueryAbortControllerRef.current = new AbortController();
try {
let nodeRelationshipData;
if (viewPoint === graphLabels.showGraphView) {
nodeRelationshipData = await graphQueryAPI(
graphQuery,
selectedRows?.map((f) => f.name)
selectedRows?.map((f) => f.name),
graphQueryAbortControllerRef.current.signal
);
} else if (viewPoint === graphLabels.showSchemaView) {
nodeRelationshipData = await getGraphSchema();
} else {
nodeRelationshipData = await graphQueryAPI(graphQuery, [inspectedName ?? '']);
nodeRelationshipData = await graphQueryAPI(
graphQuery,
[inspectedName ?? ''],
graphQueryAbortControllerRef.current.signal
);
}
return nodeRelationshipData;
} catch (error: any) {
Expand Down Expand Up @@ -310,6 +317,7 @@ const GraphViewModal: React.FunctionComponent<GraphViewModalProps> = ({

// when modal closes reset all states to default
const onClose = () => {
graphQueryAbortControllerRef?.current?.abort();
setStatus('unknown');
setStatusMessage('');
setGraphViewOpen(false);
Expand Down
18 changes: 8 additions & 10 deletions frontend/src/components/Layout/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,22 +115,21 @@ const PageLayout: React.FC = () => {
email: user?.email ?? '',
connection: 'backendApi',
};
//setChunksToBeProces(credentials.chunksTobeProcess);
// setChunksToBeProces(credentials.chunksTobeProcess);
setIsGCSActive(credentials.isGCSActive);
setUserCredentials(credentials);
createDefaultFormData({ uri: credentials.uri, email: credentials.email ?? '' });
setGdsActive(credentials.isgdsActive);
setConnectionStatus(Boolean(connectionData.data.graph_connection));
setIsReadOnlyUser(connectionData.data.isReadonlyUser);
handleDisconnectButtonState(false);
}
else if (!connectionData.data && connectionData.status === 'Success') {
} else if (!connectionData.data && connectionData.status === 'Success') {
const storedCredentials = localStorage.getItem('neo4j.connection');
if (storedCredentials) {
const credentials = JSON.parse(storedCredentials);
setUserCredentials({ ...credentials, password: atob(credentials.password) });
createDefaultFormData({ ...credentials, password: atob(credentials.password) });
//setChunksToBeProces(credentials.chunksTobeProcess);
// setChunksToBeProces(credentials.chunksTobeProcess);
setIsGCSActive(credentials.isGCSActive);
setGdsActive(credentials.isgdsActive);
setConnectionStatus(Boolean(credentials.connection === 'connectAPI'));
Expand All @@ -144,7 +143,7 @@ const PageLayout: React.FC = () => {
setErrorMessage(backendApiResponse?.data?.error);
setOpenConnection((prev) => ({ ...prev, openPopUp: true }));
handleDisconnectButtonState(true);
console.log('from else cndition error is there')
console.log('from else cndition error is there');
}
} catch (error) {
if (error instanceof Error) {
Expand All @@ -160,9 +159,7 @@ const PageLayout: React.FC = () => {
setClearHistoryData(true);
setIsDeleteChatLoading(true);
cancel();
const response = await clearChatAPI(
sessionStorage.getItem('session_id') ?? ''
);
const response = await clearChatAPI(sessionStorage.getItem('session_id') ?? '');
setIsDeleteChatLoading(false);
if (response.data.status === 'Success') {
const date = new Date();
Expand Down Expand Up @@ -216,8 +213,9 @@ const PageLayout: React.FC = () => {
></SchemaFromTextDialog>
{isLargeDesktop ? (
<div
className={`layout-wrapper ${!isLeftExpanded ? 'drawerdropzoneclosed' : ''} ${!isRightExpanded ? 'drawerchatbotclosed' : ''
} ${!isRightExpanded && !isLeftExpanded ? 'drawerclosed' : ''}`}
className={`layout-wrapper ${!isLeftExpanded ? 'drawerdropzoneclosed' : ''} ${
!isRightExpanded ? 'drawerchatbotclosed' : ''
} ${!isRightExpanded && !isLeftExpanded ? 'drawerclosed' : ''}`}
>
<SideNav
toggles3Modal={toggleS3Modal}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export default function ConnectionModal({
isGCSActive,
chunksTobeProcess,
email: user?.email ?? '',
connection:'connectAPI',
connection: 'connectAPI',
})
);
setUserDbVectorIndex(response.data.data.db_vector_dimension);
Expand Down
Loading