diff --git a/web/src/components/tables/sample-table.tsx b/web/src/components/tables/sample-table.tsx index adc0015f..f4b4747e 100644 --- a/web/src/components/tables/sample-table.tsx +++ b/web/src/components/tables/sample-table.tsx @@ -148,6 +148,7 @@ export const SampleTable = (props: Props) => { onChange(arraysToSampleList(rows)); } }} + outsideClickDeselects={false} /> ); }; diff --git a/web/src/contexts/project-page-context.tsx b/web/src/contexts/project-page-context.tsx index bd8a949d..5213eb17 100644 --- a/web/src/contexts/project-page-context.tsx +++ b/web/src/contexts/project-page-context.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useContext, useEffect, useState } from 'react'; +import React, { createContext, useContext, useEffect, useMemo, useState } from 'react'; import { useParams, useSearchParams } from 'react-router-dom'; import { useProjectAllHistory } from '../hooks/queries/useProjectAllHistory'; @@ -56,8 +56,19 @@ export const ProjectPageProvider = ({ children }: ProviderProps) => { // GENERAL STATE const [pageView, setPageView] = useState('samples'); + const pageViewStateMemoized = useMemo(() => { + return { pageView, setPageView }; + }, [pageView]); + const [forceTraditionalInterface, setForceTraditionalInterface] = useState(false); + const forceTraditionalInterfaceMemoized = useMemo(() => { + return { forceTraditionalInterface, setForceTraditionalInterface }; + }, [forceTraditionalInterface]); + const [currentHistoryId, setCurrentHistoryId] = useState(null); + const currentHistoryIdMemoized = useMemo(() => { + return { currentHistoryId, setCurrentHistoryId }; + }, [currentHistoryId]); // get state // PROJECT ANNOTATION @@ -112,33 +123,48 @@ export const ProjectPageProvider = ({ children }: ProviderProps) => { } }, [currentHistoryId]); - return ( - - {children} - + const contextValue = useMemo( + () => ({ + namespace, + projectName, + tag, + projectAnnotationQuery, + sampleTableQuery, + subSampleTableQuery, + projectConfigQuery, + projectViewsQuery, + projectValidationQuery, + projectAllHistoryQuery, + projectHistoryQuery, + shouldFetchSampleTable, + pageView, + setPageView, + forceTraditionalInterface, + setForceTraditionalInterface, + MAX_SAMPLE_COUNT, + currentHistoryId, + setCurrentHistoryId, + }), + [ + namespace, + projectName, + tag, + projectAnnotationQuery, + sampleTableQuery, + subSampleTableQuery, + projectConfigQuery, + projectViewsQuery, + projectValidationQuery, + projectAllHistoryQuery, + projectHistoryQuery, + shouldFetchSampleTable, + pageView, + forceTraditionalInterface, + currentHistoryId, + ], ); + + return {children}; }; export const useProjectPage = () => { diff --git a/web/src/pages/Project.tsx b/web/src/pages/Project.tsx index 72b39f5b..f56627dd 100644 --- a/web/src/pages/Project.tsx +++ b/web/src/pages/Project.tsx @@ -1,4 +1,4 @@ -import { Fragment, useCallback, useEffect, useRef, useState } from 'react'; +import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useSearchParams } from 'react-router-dom'; import { useLocalStorage } from 'usehooks-ts'; @@ -48,7 +48,6 @@ export const ProjectPage = () => { shouldFetchSampleTable, pageView, forceTraditionalInterface, - MAX_SAMPLE_COUNT, currentHistoryId, projectHistoryQuery, } = useProjectPage(); @@ -91,6 +90,20 @@ export const ProjectPage = () => { projectValidationQuery.refetch(); }; + const sampleData = useMemo(() => { + if (currentHistoryId !== null) { + return projectHistoryView?._sample_dict || []; + } + return viewData ? viewData._samples || [] : newProjectSamples || []; + }, [currentHistoryId, projectHistoryView?._sample_dict, viewData, newProjectSamples]); + + const subsampleData = useMemo(() => { + if (currentHistoryId !== null) { + return projectHistoryView?._subsample_list || []; + } + return newProjectSubsamples || []; + }, [currentHistoryId, projectHistoryView, newProjectSubsamples]); + // watch for query changes to update newProjectConfig and newProjectSamples useEffect(() => { setNewProjectConfig(projectConfig?.config || ''); @@ -170,34 +183,6 @@ export const ProjectPage = () => { }; }, [currentHistoryId]); - // dedicated functions to get proper data for the project page - // (easier to read and understand the code) - const determineWhichSamplesToShow = () => { - if (currentHistoryId !== null) { - return projectHistoryView?._sample_dict || []; - } else if (view !== undefined) { - return viewData?._samples || []; - } else { - return newProjectSamples; - } - }; - - const determineWhichSubsamplesToShow = () => { - if (currentHistoryId !== null) { - return projectHistoryView?._subsample_list || []; - } else { - return newProjectSubsamples || []; - } - }; - - const determineWhichConfigToShow = () => { - if (currentHistoryId !== null) { - return projectHistoryView?._config || ''; - } else { - return newProjectConfig || ''; - } - }; - if (projectAnnotationQuery.error) { return ( @@ -256,32 +241,20 @@ export const ProjectPage = () => {
- {pageView === 'samples' ? ( + {pageView === 'samples' || pageView === 'subsamples' ? ( - ) : pageView === 'subsamples' ? ( - = MAX_SAMPLE_COUNT || - currentHistoryId !== null - } - data={newProjectSubsamples || []} - onChange={memoizedSetNewProjectSubsamples} + data={pageView === 'samples' ? sampleData : subsampleData} + onChange={pageView === 'samples' ? memoizedSetNewProjectSamples : memoizedSetNewProjectSubsamples} /> ) : (
setNewProjectConfig(value)} />