Skip to content

Commit

Permalink
Merge pull request #746 from hms-dbmi-cellenics/lazyload-samples
Browse files Browse the repository at this point in the history
Load samples lazily to improve ui performance.
  • Loading branch information
Kristian-A authored Jun 21, 2022
2 parents 735ceda + 8820db3 commit d9d93d4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/__test__/components/data-management/SamplesTable.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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));
});
Expand Down
27 changes: 26 additions & 1 deletion src/components/data-management/SamplesTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -404,7 +406,24 @@ const SamplesTable = forwardRef((props, ref) => {
return <SortableRow index={index} {...otherProps} />;
};

return (
const renderLoader = () => (
<>
<Row justify='center'>
<ClipLoader
size={50}
color='#8f0b10'
/>
</Row>

<Row justify='center'>
<Text>
We&apos;re getting your samples ...
</Text>
</Row>
</>
);

const renderSamplesTable = () => (
<Row>
<Col>
<Table
Expand All @@ -429,6 +448,12 @@ const SamplesTable = forwardRef((props, ref) => {
</Col>
</Row>
);

return (
<>
{areSamplesLoading ? renderLoader() : renderSamplesTable()}
</>
);
});

export default React.memo(SamplesTable);
7 changes: 7 additions & 0 deletions src/pages/data-management/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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
Expand All @@ -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;

Expand All @@ -58,6 +63,8 @@ const DataManagementPage = () => {

dispatch(loadProcessingSettings(activeExperimentId));

if (!areSamplesLoaded()) dispatch(loadSamples(activeProjectUuid));

if (!experimentsAreLoaded) {
dispatch(loadExperiments(activeProjectUuid)).then(() => updateRunStatus(activeExperimentId));
}
Expand Down
4 changes: 0 additions & 4 deletions src/redux/actions/projects/loadProjects.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit d9d93d4

Please sign in to comment.