Commit c4bdcb41 authored by Andrey Azov's avatar Andrey Azov
Browse files

Add reading from indexedDB

parent 2d2e476f
Pipeline #258824 passed with stages
in 4 minutes and 32 seconds
......@@ -19,6 +19,8 @@ import { useLocation, useRoutes } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import routesConfig from 'src/routes/routesConfig';
import useToolsContext from 'src/content/app/tools/shared/context/useToolsContext';
import analyticsTracking from 'src/services/analytics-service';
import { changeCurrentApp } from 'src/global/globalSlice';
......@@ -28,6 +30,7 @@ import Header from 'src/header/Header';
const AppContainer = () => {
const dispatch = useDispatch();
const location = useLocation();
const { restoreBlastSubmissions } = useToolsContext();
useEffect(() => {
const appName: string = location.pathname.split('/').filter(Boolean)[0];
......@@ -40,6 +43,10 @@ const AppContainer = () => {
};
}, [location.pathname]);
useEffect(() => {
restoreBlastSubmissions();
}, []);
useLocationReporting();
return <App />;
......
......@@ -30,11 +30,19 @@ export const saveBlastSubmission = async (
await IndexedDB.set(STORE_NAME, submissionId, submission);
};
export const getAllBlastSubmissions = async (): Promise<BlastSubmission[]> => {
const submissionIds = await IndexedDB.keys(STORE_NAME);
return Promise.all(
submissionIds.map((id) => getBlastSubmission(id as string))
export const getAllBlastSubmissions = async (): Promise<
Record<string, BlastSubmission>
> => {
const submissionIds = (await IndexedDB.keys(STORE_NAME)) as string[];
const submissions = await Promise.all(
submissionIds.map((id) => getBlastSubmission(id))
);
return submissionIds.reduce((obj, id, index) => {
return {
...obj,
[id]: submissions[index]
};
}, {} as Record<string, BlastSubmission>);
};
export const getBlastSubmission = async (
......
......@@ -53,6 +53,12 @@ const blastResultsSlice = createSlice({
name: 'blast-results',
initialState: {} as BlastResultsState,
reducers: {
restoreSubmissions(
state,
action: PayloadAction<Record<string, BlastSubmission>>
) {
return action.payload;
},
updateJob(
state,
action: PayloadAction<{
......@@ -75,6 +81,6 @@ const blastResultsSlice = createSlice({
}
});
export const { updateJob } = blastResultsSlice.actions;
export const { restoreSubmissions, updateJob } = blastResultsSlice.actions;
export default blastResultsSlice.reducer;
......@@ -21,10 +21,14 @@ import config from 'config';
import { useAppDispatch } from 'src/store';
import { submitBlast } from 'src/content/app/tools/blast/state/blast-api/blastApiSlice';
import { updateJob } from 'src/content/app/tools/blast/state/blast-results/blastResultsSlice';
import {
restoreSubmissions,
updateJob
} from 'src/content/app/tools/blast/state/blast-results/blastResultsSlice';
import {
saveBlastSubmission,
updateSavedBlastJob
updateSavedBlastJob,
getAllBlastSubmissions
} from 'src/content/app/tools/blast/services/blastStorageService';
import type { BlastSubmissionPayload } from 'src/content/app/tools/blast/state/blast-api/blastApiSlice';
......@@ -40,6 +44,7 @@ type ToolsContextType = {
) => Promise<
{ submissionId: string; submission: BlastSubmission } | undefined
>;
restoreBlastSubmissions: () => void;
};
const ToolsContext = createContext<ToolsContextType | undefined>(undefined);
......@@ -80,9 +85,15 @@ const ToolContextContainer = (props: Props) => {
jobId
}));
for await (const job of getFinishedJobs({ jobs: jobIds })) {
await pollJobStatuses(jobIds);
};
const pollJobStatuses = async (
jobs: { submissionId: string; jobId: string }[]
) => {
for await (const job of getFinishedJobs({ jobs })) {
const updatePayload = {
submissionId,
submissionId: job.submissionId,
jobId: job.jobId,
fragment: { status: job.status }
};
......@@ -91,8 +102,31 @@ const ToolContextContainer = (props: Props) => {
}
};
const restoreBlastSubmissions = async () => {
const submissions = await getAllBlastSubmissions();
dispatch(restoreSubmissions(submissions));
// resume polling for non-finished jobs
const jobIds = Object.entries(submissions).flatMap(
([submissionId, submission]) =>
submission.results
.filter((job) => job.status === 'RUNNING')
.map(({ jobId }) => ({
submissionId,
jobId
}))
);
await pollJobStatuses(jobIds);
};
const contextValue = {
submitBlastForm,
restoreBlastSubmissions
};
return (
<ToolsContext.Provider value={{ submitBlastForm }}>
<ToolsContext.Provider value={contextValue}>
{props.children}
</ToolsContext.Provider>
);
......
......@@ -24,7 +24,6 @@ import { BrowserRouter } from 'react-router-dom';
import ensureBrowserSupport from 'src/shared/helpers/browserSupport';
import { Provider as IndexedDBProvider } from 'src/shared/contexts/IndexedDBContext';
import ToolsContextContainer from 'src/content/app/tools/shared/context/ToolsContextContainer';
import configureStore from './store';
import Root from './root/Root';
......@@ -43,11 +42,9 @@ hydrate(
<IndexedDBProvider>
<Provider store={store}>
<BrowserRouter>
<ToolsContextContainer>
<HelmetProvider>
<Root />
</HelmetProvider>
</ToolsContextContainer>
<HelmetProvider>
<Root />
</HelmetProvider>
</BrowserRouter>
</Provider>
</IndexedDBProvider>
......
......@@ -29,6 +29,7 @@ import App from '../content/app/App';
import RootMeta from './RootMeta';
import PrivacyBanner from '../shared/components/privacy-banner/PrivacyBanner';
import ErrorBoundary from 'src/shared/components/error-boundary/ErrorBoundary';
import ToolsContextContainer from 'src/content/app/tools/shared/context/ToolsContextContainer';
import { GeneralErrorScreen } from 'src/shared/components/error-screen';
import styles from './Root.scss';
......@@ -63,9 +64,11 @@ export const Root = () => {
return (
<div className={styles.root}>
<ErrorBoundary fallbackComponent={GeneralErrorScreen}>
<RootMeta />
<App />
{showPrivacyBanner && <PrivacyBanner closeBanner={closeBanner} />}
<ToolsContextContainer>
<RootMeta />
<App />
{showPrivacyBanner && <PrivacyBanner closeBanner={closeBanner} />}
</ToolsContextContainer>
</ErrorBoundary>
</div>
);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment