Skip to content

Commit

Permalink
feat (frontend): submissions geojson download (#1518)
Browse files Browse the repository at this point in the history
* feat(projectSlice): action and state to track submission download loading

* feat(project): DownloadSubmission geojson service to download geojson

* feat(projectDetailsV2): pass project name to projectOptions component as props

* feat(projectOptions): submission geojson download button & functionality add
  • Loading branch information
NSUWAL123 authored May 15, 2024
1 parent a11ea3b commit aff94b0
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 27 deletions.
30 changes: 30 additions & 0 deletions src/frontend/src/api/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,33 @@ export const GetProjectTaskActivity = (url) => {
await getProjectActivity(url);
};
};

export const DownloadSubmissionGeojson = (url, projectName) => {
return async (dispatch) => {
dispatch(ProjectActions.SetDownloadSubmissionGeojsonLoading(true));

const downloadSubmissionGeojson = async (url) => {
try {
const response = await CoreModules.axios.get(url, { responseType: 'blob' });
const a = document.createElement('a');
a.href = window.URL.createObjectURL(response.data);
a.download = `${projectName}.geojson`;
a.click();
dispatch(ProjectActions.SetDownloadSubmissionGeojsonLoading(false));
} catch (error) {
dispatch(
CommonActions.SetSnackBar({
open: true,
message: 'Failed to download submission geojson.',
variant: 'error',
duration: 2000,
}),
);
dispatch(ProjectActions.SetDownloadSubmissionGeojsonLoading(false));
} finally {
dispatch(ProjectActions.SetDownloadSubmissionGeojsonLoading(false));
}
};
await downloadSubmissionGeojson(url);
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { useLocation } from 'react-router-dom';
import ProjectOptions from '@/components/ProjectDetailsV2/ProjectOptions';
import useOutsideClick from '@/hooks/useOutsideClick';

const MapControlComponent = ({ map }) => {
type mapControlComponentType = {
map: any;
projectName: string;
};

const MapControlComponent = ({ map, projectName }: mapControlComponentType) => {
const btnList = [
{
id: 'add',
Expand Down Expand Up @@ -97,7 +102,7 @@ const MapControlComponent = ({ map }) => {
: '-fmtm-right-[60rem] fmtm-top-0 sm:fmtm-hidden'
}`}
>
<ProjectOptions />
<ProjectOptions projectName={projectName} />
</div>
</div>
</div>
Expand Down
46 changes: 36 additions & 10 deletions src/frontend/src/components/ProjectDetailsV2/ProjectOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import React from 'react';
import CoreModules from '@/shared/CoreModules';
import AssetModules from '@/shared/AssetModules';
import { DownloadDataExtract, DownloadProjectForm } from '@/api/Project';
import { DownloadDataExtract, DownloadProjectForm, DownloadSubmissionGeojson } from '@/api/Project';
import Button from '@/components/common/Button';
import { downloadProjectFormLoadingType } from '@/models/project/projectModel';
import { useAppSelector } from '@/types/reduxTypes';

const ProjectOptions = () => {
type projectOptionPropTypes = {
projectName: string;
};

const ProjectOptions = ({ projectName }: projectOptionPropTypes) => {
const dispatch = CoreModules.useAppDispatch();
const params = CoreModules.useParams();

const downloadProjectFormLoading: downloadProjectFormLoadingType = CoreModules.useAppSelector(
(state) => state.project.downloadProjectFormLoading,
);
const downloadDataExtractLoading: boolean = CoreModules.useAppSelector(
(state) => state.project.downloadDataExtractLoading,
);
const downloadProjectFormLoading = useAppSelector((state) => state.project.downloadProjectFormLoading);
const downloadDataExtractLoading = useAppSelector((state) => state.project.downloadDataExtractLoading);
const downloadSubmissionLoading = useAppSelector((state) => state.project.downloadSubmissionLoading);

const projectId: string = params.id;

Expand All @@ -37,14 +38,25 @@ const ProjectOptions = () => {
);
}
};

const onDataExtractDownload = () => {
dispatch(
DownloadDataExtract(`${import.meta.env.VITE_API_URL}/projects/features/download/?project_id=${projectId}`),
);
};

const onSubmissionDownload = () => {
dispatch(
DownloadSubmissionGeojson(
`${import.meta.env.VITE_API_URL}/submission/download-submission-geojson/${projectId}`,
projectName,
),
);
};

return (
<>
<div className="fmtm-flex fmtm-gap-4 fmtm-flex-col md:fmtm-flex-row">
<div className="fmtm-flex fmtm-gap-4 fmtm-flex-col lg:fmtm-flex-row">
<Button
isLoading={downloadProjectFormLoading.type === 'form' && downloadProjectFormLoading.loading}
loadingText="FORM"
Expand Down Expand Up @@ -91,6 +103,20 @@ const ProjectOptions = () => {
onDataExtractDownload();
}}
/>
<Button
isLoading={downloadSubmissionLoading}
loadingText="SUBMISSIONS"
btnText="SUBMISSIONS"
btnType="other"
className={`${
downloadSubmissionLoading ? '' : 'hover:fmtm-text-red-700'
} fmtm-border-red-700 !fmtm-rounded-md fmtm-truncate`}
icon={<AssetModules.FileDownloadIcon style={{ fontSize: '22px' }} />}
onClick={(e) => {
e.stopPropagation();
onSubmissionDownload();
}}
/>
</div>
</>
);
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/src/store/slices/ProjectSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const initialState: ProjectStateTypes = {
projectOpfsBasemapPath: null,
projectTaskActivity: [],
projectActivityLoading: false,
downloadSubmissionLoading: false,
};

const ProjectSlice = createSlice({
Expand Down Expand Up @@ -141,6 +142,9 @@ const ProjectSlice = createSlice({
UpdateProjectTaskActivity(state, action) {
state.projectTaskActivity = [action.payload, ...state.projectTaskActivity];
},
SetDownloadSubmissionGeojsonLoading(state, action) {
state.downloadSubmissionLoading = action.payload;
},
},
});

Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/store/types/IProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export type ProjectStateTypes = {
projectOpfsBasemapPath: string | null;
projectTaskActivity: projectTaskActivity[];
projectActivityLoading: boolean;
downloadSubmissionLoading: boolean;
};

export type EntityOsmMap = {
Expand Down
19 changes: 4 additions & 15 deletions src/frontend/src/views/ProjectDetailsV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,11 @@ const Home = () => {
<div
className={`fmtm-flex fmtm-gap-4 fmtm-absolute fmtm-duration-200 fmtm-z-[1000] fmtm-bg-[#F5F5F5] fmtm-p-2 fmtm-rounded-md ${
toggle
? 'fmtm-left-0 fmtm-bottom-0 md:fmtm-top-0'
: '-fmtm-left-[60rem] fmtm-bottom-0 md:fmtm-top-0'
? 'fmtm-left-0 fmtm-bottom-0 lg:fmtm-top-0'
: '-fmtm-left-[60rem] fmtm-bottom-0 lg:fmtm-top-0'
}`}
>
<ProjectOptions />
<ProjectOptions projectName={state?.projectInfo?.title} />
</div>
</div>
</div>
Expand Down Expand Up @@ -518,7 +518,7 @@ const Home = () => {
className="!fmtm-text-base !fmtm-pr-2"
/>
</div>
<MapControlComponent map={map} />
<MapControlComponent map={map} projectName={state?.projectInfo?.title} />
</MapComponent>
<div
className="fmtm-absolute fmtm-top-4 fmtm-left-4 fmtm-bg-white fmtm-rounded-full fmtm-p-1 hover:fmtm-bg-red-50 fmtm-duration-300 fmtm-border-[1px] sm:fmtm-hidden fmtm-cursor-pointer"
Expand Down Expand Up @@ -558,17 +558,6 @@ const Home = () => {
onClose={() => dispatch(ProjectActions.SetMobileFooterSelection(''))}
/>
)}
{mobileFooterSelection === 'others' && (
<BottomSheet
body={
<div className="fmtm-mb-[10vh]">
<ProjectOptions />
</div>
}
onClose={() => dispatch(ProjectActions.SetMobileFooterSelection(''))}
/>
)}

<MobileFooter />
</div>
)}
Expand Down

0 comments on commit aff94b0

Please sign in to comment.