diff --git a/src/__test__/components/data-management/SamplesTable.test.jsx b/src/__test__/components/data-management/SamplesTable.test.jsx index eda7d7faca..d0c1de285c 100644 --- a/src/__test__/components/data-management/SamplesTable.test.jsx +++ b/src/__test__/components/data-management/SamplesTable.test.jsx @@ -25,6 +25,7 @@ import downloadFromUrl from 'utils/data-management/downloadFromUrl'; import loadEnvironment from 'redux/actions/networkResources/loadEnvironment'; import { loadExperiments } from 'redux/actions/experiments'; +import { loadSamples } from 'redux/actions/samples'; jest.mock('config'); @@ -107,6 +108,7 @@ describe('Samples table', () => { // Loading experiment is usually called in Data Management, so we have to load them manually await storeState.dispatch(loadExperiments(experimentWithSamplesId)); await storeState.dispatch(loadExperiments(experimentWithoutSamplesId)); + await storeState.dispatch(loadSamples(experimentWithSamplesId)); // Defaults to project with samples await storeState.dispatch(setActiveProject(experimentWithSamplesId)); diff --git a/src/__test__/redux/actions/experiments/switchExperiment.test.js b/src/__test__/redux/actions/experiments/switchExperiment.test.js index 7b9ab95a38..17272f91d5 100644 --- a/src/__test__/redux/actions/experiments/switchExperiment.test.js +++ b/src/__test__/redux/actions/experiments/switchExperiment.test.js @@ -8,6 +8,7 @@ import { makeStore } from 'redux/store'; import { loadProjects, setActiveProject } from 'redux/actions/projects'; import { responseData } from '__test__/test-utils/mockData'; import fetchMock, { enableFetchMocks } from 'jest-fetch-mock'; +import { loadSamples } from 'redux/actions/samples'; let store = null; @@ -37,6 +38,7 @@ describe('switch experiment ', () => { store = makeStore(); await store.dispatch(loadProjects()); await store.dispatch(loadExperiments(experimentWithSamplesId)); + await store.dispatch(loadSamples(experimentWithSamplesId)); await store.dispatch(loadExperiments(experimentWithoutSamplesId)); await store.dispatch(setActiveProject(experimentWithoutSamplesId)); }); diff --git a/src/components/data-management/SamplesTable.jsx b/src/components/data-management/SamplesTable.jsx index d48f57e7f2..2ca6c00b88 100644 --- a/src/components/data-management/SamplesTable.jsx +++ b/src/components/data-management/SamplesTable.jsx @@ -38,6 +38,7 @@ import { metadataNameToKey, metadataKeyToName, temporaryMetadataKey } from 'util import integrationTestConstants from 'utils/integrationTestConstants'; import getAccountId from 'utils/getAccountId'; import 'utils/css/data-management.css'; +import { ClipLoader } from 'react-spinners'; const { Paragraph, Text } = Typography; @@ -48,6 +49,7 @@ const SamplesTable = forwardRef((props, ref) => { const projects = useSelector((state) => state.projects); const samples = useSelector((state) => state.samples); + const areSamplesLoading = useSelector((state) => state.samples.meta.loading); const { activeProjectUuid } = useSelector((state) => state.projects.meta) || false; const activeProject = useSelector((state) => state.projects[activeProjectUuid]) || false; @@ -404,7 +406,24 @@ const SamplesTable = forwardRef((props, ref) => { return ; }; - return ( + const renderLoader = () => ( + <> + + + + + + + We're getting your samples ... + + + + ); + + const renderSamplesTable = () => ( { ); + + return ( + <> + {areSamplesLoading ? renderLoader() : renderSamplesTable()} + + ); }); export default React.memo(SamplesTable); diff --git a/src/pages/data-management/index.jsx b/src/pages/data-management/index.jsx index 62a6cbbc79..4d8f8a274e 100644 --- a/src/pages/data-management/index.jsx +++ b/src/pages/data-management/index.jsx @@ -16,6 +16,7 @@ import ProjectsListContainer from 'components/data-management/ProjectsListContai import ProjectDetails from 'components/data-management/ProjectDetails'; import { loadProcessingSettings } from 'redux/actions/experimentSettings'; import loadBackendStatus from 'redux/actions/backendStatus/loadBackendStatus'; +import { loadSamples } from 'redux/actions/samples'; const DataManagementPage = () => { const dispatch = useDispatch(); @@ -36,6 +37,7 @@ const DataManagementPage = () => { const [newProjectModalVisible, setNewProjectModalVisible] = useState(false); const [justLoggedIn, setJustLoggedIn] = useState(true); const activeProject = projectsList[activeProjectUuid]; + const loadedSamples = useSelector((state) => state.samples); const experimentIds = new Set(experiments.ids); const experimentsAreLoaded = activeProject?.experiments @@ -49,6 +51,9 @@ const DataManagementPage = () => { dispatch(loadBackendStatus(experimentId)); }; + const areSamplesLoaded = () => !activeProject.samples.length + || activeProject.samples.every((sample) => Object.keys(loadedSamples).includes(sample)); + useEffect(() => { if (!activeProjectUuid) return; @@ -58,6 +63,8 @@ const DataManagementPage = () => { dispatch(loadProcessingSettings(activeExperimentId)); + if (!areSamplesLoaded()) dispatch(loadSamples(activeProjectUuid)); + if (!experimentsAreLoaded) { dispatch(loadExperiments(activeProjectUuid)).then(() => updateRunStatus(activeExperimentId)); } diff --git a/src/redux/actions/projects/loadProjects.js b/src/redux/actions/projects/loadProjects.js index a2741ab53c..c4e7ecb8d4 100644 --- a/src/redux/actions/projects/loadProjects.js +++ b/src/redux/actions/projects/loadProjects.js @@ -59,10 +59,6 @@ const loadProjects = () => async (dispatch) => { data = await fetchAPI(url); data = toApiV1(data); - - await Promise.all(data - .filter((entry) => entry.samples.length) - .map((entry) => dispatch(loadSamples(null, entry.uuid)))); } const ids = data.map((project) => project.uuid);