diff --git a/src/js/components/BentoAppRouter.tsx b/src/js/components/BentoAppRouter.tsx
index 6665a077..8a2e313d 100644
--- a/src/js/components/BentoAppRouter.tsx
+++ b/src/js/components/BentoAppRouter.tsx
@@ -18,6 +18,7 @@ import { getGenomes } from '@/features/reference/reference.store';
import Loader from '@/components/Loader';
import DefaultLayout from '@/components/Util/DefaultLayout';
import { BEACON_NETWORK_ENABLED } from '@/config';
+import { WAITING_STATES } from '@/constants/requests';
import { RequestStatus } from '@/types/requests';
import { BentoRoute } from '@/types/routes';
import { scopeEqual, validProjectDataset } from '@/utils/router';
@@ -35,7 +36,7 @@ const ScopedRoute = () => {
const { selectedScope, projects, projectsStatus } = useMetadata();
useEffect(() => {
- if ([RequestStatus.Idle, RequestStatus.Pending].includes(projectsStatus)) return; // Wait for projects to load first
+ if (WAITING_STATES.includes(projectsStatus)) return; // Wait for projects to load first
// Update selectedScope based on URL parameters
const valid = validProjectDataset(projects, { project: projectId, dataset: datasetId });
diff --git a/src/js/components/Overview/Counts.tsx b/src/js/components/Overview/Counts.tsx
index 3ac2789b..425da8bf 100644
--- a/src/js/components/Overview/Counts.tsx
+++ b/src/js/components/Overview/Counts.tsx
@@ -5,6 +5,7 @@ import { BiDna } from 'react-icons/bi';
import CountsTitleWithHelp from '@/components/Util/CountsTitleWithHelp';
import { BOX_SHADOW, COUNTS_FILL } from '@/constants/overviewConstants';
+import { WAITING_STATES } from '@/constants/requests';
import { NO_RESULTS_DASHES } from '@/constants/searchConstants';
import { useAppSelector, useTranslationFn } from '@/hooks';
import { useCanSeeUncensoredCounts } from '@/hooks/censorship';
@@ -23,7 +24,7 @@ type CountEntry = { entity: BentoEntity; icon: ReactNode; count: number };
const Counts = () => {
const t = useTranslationFn();
- const { counts, isFetchingData } = useAppSelector((state) => state.data);
+ const { counts, status } = useAppSelector((state) => state.data);
const uncensoredCounts = useCanSeeUncensoredCounts();
@@ -46,18 +47,20 @@ const Counts = () => {
},
];
+ const waitingForData = WAITING_STATES.includes(status);
+
return (
<>
{t('Counts')}
{data.map(({ entity, icon, count }, i) => (
-
+
}
value={count || (uncensoredCounts ? count : NO_RESULTS_DASHES)}
valueStyle={{ color: COUNTS_FILL }}
prefix={icon}
- loading={isFetchingData}
+ loading={waitingForData}
/>
))}
diff --git a/src/js/components/Overview/Drawer/ManageChartsDrawer.tsx b/src/js/components/Overview/Drawer/ManageChartsDrawer.tsx
index 3711aef4..f50f2854 100644
--- a/src/js/components/Overview/Drawer/ManageChartsDrawer.tsx
+++ b/src/js/components/Overview/Drawer/ManageChartsDrawer.tsx
@@ -13,7 +13,7 @@ const ManageChartsDrawer = ({ onManageDrawerClose, manageDrawerVisible }: Manage
const dispatch = useAppDispatch();
- const sections = useAppSelector((state) => state.data.sections);
+ const { sections } = useAppSelector((state) => state.data);
return (
{
const [drawerVisible, setDrawerVisible] = useState(false);
const [aboutContent, setAboutContent] = useState('');
- const { isFetchingData: isFetchingOverviewData, sections } = useAppSelector((state) => state.data);
+ const { status: overviewDataStatus, sections } = useAppSelector((state) => state.data);
const { status: aboutStatus, about } = useAppSelector((state) => state.content);
const selectedProject = useSelectedProject();
@@ -37,9 +38,9 @@ const PublicOverview = () => {
useEffect(() => {
// Save sections to localStorage when they change
- if (isFetchingOverviewData) return;
+ if (overviewDataStatus != RequestStatus.Fulfilled) return;
saveToLocalStorage(sections);
- }, [isFetchingOverviewData, sections]);
+ }, [overviewDataStatus, sections]);
useEffect(() => {
const activeLanguage = i18n.language;
@@ -58,7 +59,7 @@ const PublicOverview = () => {
const searchableFields = useSearchableFields();
- return isFetchingOverviewData ? (
+ return WAITING_STATES.includes(overviewDataStatus) ? (
) : (
<>
diff --git a/src/js/constants/requests.ts b/src/js/constants/requests.ts
new file mode 100644
index 00000000..aedca9b5
--- /dev/null
+++ b/src/js/constants/requests.ts
@@ -0,0 +1,3 @@
+import { RequestStatus } from '@/types/requests';
+
+export const WAITING_STATES = [RequestStatus.Idle, RequestStatus.Pending];
diff --git a/src/js/features/data/data.store.ts b/src/js/features/data/data.store.ts
index a7c1fec1..4b285949 100644
--- a/src/js/features/data/data.store.ts
+++ b/src/js/features/data/data.store.ts
@@ -4,16 +4,17 @@ import { createSlice } from '@reduxjs/toolkit';
import { makeGetDataRequestThunk } from './makeGetDataRequest.thunk';
import type { Sections } from '@/types/data';
import type { Counts } from '@/types/overviewResponse';
+import { RequestStatus } from '@/types/requests';
interface DataState {
- isFetchingData: boolean;
+ status: RequestStatus;
defaultLayout: Sections;
sections: Sections;
counts: Counts;
}
const initialState: DataState = {
- isFetchingData: true,
+ status: RequestStatus.Idle,
defaultLayout: [],
sections: [],
counts: {
@@ -79,16 +80,16 @@ const data = createSlice({
extraReducers: (builder) => {
builder
.addCase(makeGetDataRequestThunk.pending, (state) => {
- state.isFetchingData = true;
+ state.status = RequestStatus.Pending;
})
.addCase(makeGetDataRequestThunk.fulfilled, (state, { payload }) => {
state.sections = payload.sectionData;
state.defaultLayout = payload.defaultData;
state.counts = payload.counts;
- state.isFetchingData = false;
+ state.status = RequestStatus.Fulfilled;
})
.addCase(makeGetDataRequestThunk.rejected, (state) => {
- state.isFetchingData = false;
+ state.status = RequestStatus.Rejected;
});
},
});