From 17bb27f2ecbc3682e3904ccb2d04c3b71fa4f2cd Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Mon, 23 Sep 2024 15:17:15 +0545 Subject: [PATCH 1/9] fix(selectForm): debug param add --- src/frontend/src/components/createnewproject/SelectForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/createnewproject/SelectForm.tsx b/src/frontend/src/components/createnewproject/SelectForm.tsx index 225b91d265..e3e74faa6a 100644 --- a/src/frontend/src/components/createnewproject/SelectForm.tsx +++ b/src/frontend/src/components/createnewproject/SelectForm.tsx @@ -80,7 +80,7 @@ const SelectForm = ({ flag, geojsonFile, customFormFile, setCustomFormFile }) => }; useEffect(() => { if (customFormFile && !customFileValidity) { - dispatch(ValidateCustomForm(`${import.meta.env.VITE_API_URL}/projects/validate-form`, customFormFile)); + dispatch(ValidateCustomForm(`${import.meta.env.VITE_API_URL}/projects/validate-form?debug=true`, customFormFile)); } }, [customFormFile]); From bd62c6dc1ce683b20c26e478ff1ad371afa9055b Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Mon, 23 Sep 2024 17:41:53 +0545 Subject: [PATCH 2/9] feat(createProjectService): post additionalFeature if additionalFeature uploaded --- src/frontend/src/api/CreateProjectService.ts | 52 +++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/api/CreateProjectService.ts b/src/frontend/src/api/CreateProjectService.ts index dd3ce11ee4..115348f54f 100755 --- a/src/frontend/src/api/CreateProjectService.ts +++ b/src/frontend/src/api/CreateProjectService.ts @@ -7,7 +7,6 @@ import { OrganisationListModel, } from '@/models/createproject/createProjectModel'; import { CommonActions } from '@/store/slices/CommonSlice'; -import { ValidateCustomFormResponse } from '@/store/types/ICreateProject'; import { isStatusSuccess } from '@/utilfunctions/commonUtils'; const CreateProjectService = ( @@ -17,6 +16,7 @@ const CreateProjectService = ( formUpload: any, dataExtractFile: any, isOsmExtract: boolean, + additionalFeature: any, ) => { return async (dispatch) => { dispatch(CreateProjectActions.CreateProjectLoading(true)); @@ -74,11 +74,26 @@ const CreateProjectService = ( throw new Error(`Request failed with status ${extractResponse.status}`); } + // post additional feature if available + const postAdditionalFeature = await dispatch( + PostAdditionalFeatureService( + `${import.meta.env.VITE_API_URL}/projects/${projectId}/additional-entity`, + additionalFeature, + ), + ); + + hasAPISuccess = postAdditionalFeature; + if (!hasAPISuccess) { + throw new Error(`Request failed`); + } + // Generate project files const generateProjectFile = await dispatch( GenerateProjectFilesService( `${import.meta.env.VITE_API_URL}/projects/${projectId}/generate-project-data`, - projectData, + additionalFeature + ? { ...projectData, additional_entities: [additionalFeature?.name?.split('.')?.[0]] } + : projectData, formUpload, ), ); @@ -221,6 +236,39 @@ const GenerateProjectFilesService = (url: string, projectData: any, formUpload: }; }; +const PostAdditionalFeatureService = (url: string, file: File) => { + return async (dispatch) => { + const PostAdditionalFeature = async (url, file) => { + let isAPISuccess = true; + + try { + const additionalFeatureFormData = new FormData(); + additionalFeatureFormData.append('geojson', file); + + const response = await axios.post(url, additionalFeatureFormData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }); + + isAPISuccess = isStatusSuccess(response.status); + } catch (error: any) { + isAPISuccess = false; + dispatch( + CommonActions.SetSnackBar({ + open: true, + message: JSON.stringify(error?.response?.data?.detail), + variant: 'error', + duration: 2000, + }), + ); + } + return isAPISuccess; + }; + return await PostAdditionalFeature(url, file); + }; +}; + const OrganisationService = (url: string) => { return async (dispatch) => { dispatch(CreateProjectActions.GetOrganisationListLoading(true)); From 85757694c5178989e9f1ca5fcfe5d1556fc99634 Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Mon, 23 Sep 2024 17:44:56 +0545 Subject: [PATCH 3/9] feat(dataExtract): fileUpload component add to upload additional features --- .../createnewproject/DataExtract.tsx | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/components/createnewproject/DataExtract.tsx b/src/frontend/src/components/createnewproject/DataExtract.tsx index 9e95fdf5a7..9b675cd528 100644 --- a/src/frontend/src/components/createnewproject/DataExtract.tsx +++ b/src/frontend/src/components/createnewproject/DataExtract.tsx @@ -1,6 +1,6 @@ +import React, { useEffect, useState } from 'react'; import axios from 'axios'; import { geojson as fgbGeojson } from 'flatgeobuf'; -import React, { useEffect, useState } from 'react'; import Button from '@/components/common/Button'; import { useDispatch } from 'react-redux'; import { CommonActions } from '@/store/slices/CommonSlice'; @@ -14,16 +14,22 @@ import FileInputComponent from '@/components/common/FileInputComponent'; import DataExtractValidation from '@/components/createnewproject/validation/DataExtractValidation'; import NewDefineAreaMap from '@/views/NewDefineAreaMap'; import useDocumentTitle from '@/utilfunctions/useDocumentTitle'; -import { checkGeomTypeInGeojson } from '@/utilfunctions/checkGeomTypeInGeojson'; import { task_split_type } from '@/types/enums'; import { dataExtractGeojsonType } from '@/store/types/ICreateProject'; +import { CustomCheckbox } from '@/components/common/Checkbox'; const dataExtractOptions = [ { name: 'data_extract', value: 'osm_data_extract', label: 'Use OSM map features' }, { name: 'data_extract', value: 'custom_data_extract', label: 'Upload custom map features' }, ]; -const DataExtract = ({ flag, customDataExtractUpload, setCustomDataExtractUpload }) => { +const DataExtract = ({ + flag, + customDataExtractUpload, + setCustomDataExtractUpload, + additionalFeature, + setAdditionalFeature, +}) => { useDocumentTitle('Create Project: Map Features'); const dispatch = useDispatch(); const navigate = useNavigate(); @@ -32,6 +38,7 @@ const DataExtract = ({ flag, customDataExtractUpload, setCustomDataExtractUpload const projectAoiGeojson = useAppSelector((state) => state.createproject.drawnGeojson); const dataExtractGeojson = useAppSelector((state) => state.createproject.dataExtractGeojson); const isFgbFetching = useAppSelector((state) => state.createproject.isFgbFetching); + const additionalFeatureGeojson = useAppSelector((state) => state.createproject.additionalFeatureGeojson); const submission = () => { dispatch(CreateProjectActions.SetIndividualProjectDetailsData(formValues)); @@ -247,7 +254,7 @@ const DataExtract = ({ flag, customDataExtractUpload, setCustomDataExtractUpload resetFile(setCustomDataExtractUpload); generateDataExtract(); }} - className="fmtm-mt-6" + className="fmtm-mt-6 fmtm-text-base" isLoading={isFgbFetching} loadingText="Generating Map Features..." disabled={dataExtractGeojson && customDataExtractUpload ? true : false} @@ -272,6 +279,42 @@ const DataExtract = ({ flag, customDataExtractUpload, setCustomDataExtractUpload /> )} +
+ { + handleCustomChange('hasAdditionalFeature', status); + setAdditionalFeature(null); + }} + className="fmtm-text-black" + labelClickable + /> + {formValues?.hasAdditionalFeature && ( + <> + { + if (e?.target?.files) { + const uploadedFile = e?.target?.files[0]; + setAdditionalFeature(uploadedFile); + const additionalFeatureGeojson = await convertFileToFeatureCol(uploadedFile); + dispatch(CreateProjectActions.SetAdditionalFeatureGeojson(additionalFeatureGeojson)); + } + }} + onResetFile={() => { + resetFile(setAdditionalFeature); + dispatch(CreateProjectActions.SetAdditionalFeatureGeojson(null)); + }} + customFile={additionalFeature} + btnText="Upload Additional Features" + accept=".geojson" + fileDescription="*The supported file formats are .geojson" + errorMsg={errors.additionalFeature} + /> + + )} +
From 78fc711642aede4844db7554dfd79cab0996b68a Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Mon, 23 Sep 2024 17:46:48 +0545 Subject: [PATCH 4/9] fix(createNewProject): add additionalFeature state --- src/frontend/src/components/createnewproject/SplitTasks.tsx | 5 ++++- src/frontend/src/views/CreateNewProject.tsx | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/components/createnewproject/SplitTasks.tsx b/src/frontend/src/components/createnewproject/SplitTasks.tsx index df9753f9e1..b1a8f66102 100644 --- a/src/frontend/src/components/createnewproject/SplitTasks.tsx +++ b/src/frontend/src/components/createnewproject/SplitTasks.tsx @@ -19,7 +19,7 @@ import { task_split_type } from '@/types/enums'; import useDocumentTitle from '@/utilfunctions/useDocumentTitle'; import { taskSplitOptionsType } from '@/store/types/ICreateProject'; -const SplitTasks = ({ flag, setGeojsonFile, customDataExtractUpload }) => { +const SplitTasks = ({ flag, setGeojsonFile, customDataExtractUpload, additionalFeature }) => { useDocumentTitle('Create Project: Split Tasks'); const dispatch = useDispatch(); const navigate = useNavigate(); @@ -41,6 +41,7 @@ const SplitTasks = ({ flag, setGeojsonFile, customDataExtractUpload }) => { const isTasksGenerated = useAppSelector((state) => state.createproject.isTasksGenerated); const isFgbFetching = useAppSelector((state) => state.createproject.isFgbFetching); const toggleSplittedGeojsonEdit = useAppSelector((state) => state.createproject.toggleSplittedGeojsonEdit); + const additionalFeatureGeojson = useAppSelector((state) => state.createproject.additionalFeatureGeojson); const taskSplitOptions: taskSplitOptionsType[] = [ { @@ -133,6 +134,7 @@ const SplitTasks = ({ flag, setGeojsonFile, customDataExtractUpload }) => { projectDetails.customFormUpload, customDataExtractUpload, projectDetails.dataExtractWays === 'osm_data_extract', + additionalFeature, ), ); dispatch(CreateProjectActions.SetIndividualProjectDetailsData({ ...projectDetails, ...formValues })); @@ -373,6 +375,7 @@ const SplitTasks = ({ flag, setGeojsonFile, customDataExtractUpload }) => { } // toggleSplittedGeojsonEdit hasEditUndo + additionalFeatureGeojson={additionalFeatureGeojson} /> diff --git a/src/frontend/src/views/CreateNewProject.tsx b/src/frontend/src/views/CreateNewProject.tsx index 02e8359894..6594a8d874 100644 --- a/src/frontend/src/views/CreateNewProject.tsx +++ b/src/frontend/src/views/CreateNewProject.tsx @@ -24,6 +24,7 @@ const CreateNewProject = () => { const [geojsonFile, setGeojsonFile] = useState(null); const [customDataExtractUpload, setCustomDataExtractUpload] = useState(null); const [customFormFile, setCustomFormFile] = useState(null); + const [additionalFeature, setAdditionalFeature] = useState(null); useEffect(() => { if (location.pathname !== '/create-project' && !projectDetails.name && !projectDetails.odk_central_url) { @@ -83,6 +84,8 @@ const CreateNewProject = () => { flag="create_project" customDataExtractUpload={customDataExtractUpload} setCustomDataExtractUpload={setCustomDataExtractUpload} + additionalFeature={additionalFeature} + setAdditionalFeature={setAdditionalFeature} /> ); case '/split-tasks': @@ -91,6 +94,7 @@ const CreateNewProject = () => { flag="create_project" setGeojsonFile={setGeojsonFile} customDataExtractUpload={customDataExtractUpload} + additionalFeature={additionalFeature} /> ); default: From 9bbd965adc7a07a79ea33fbc820e43a9e7d363c4 Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Mon, 23 Sep 2024 17:47:56 +0545 Subject: [PATCH 5/9] fix(createProject): additionalFeatureGeojson state add --- src/frontend/src/store/slices/CreateProjectSlice.ts | 4 ++++ src/frontend/src/store/types/ICreateProject.ts | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/frontend/src/store/slices/CreateProjectSlice.ts b/src/frontend/src/store/slices/CreateProjectSlice.ts index d7ebe9fd63..975f304555 100755 --- a/src/frontend/src/store/slices/CreateProjectSlice.ts +++ b/src/frontend/src/store/slices/CreateProjectSlice.ts @@ -54,6 +54,7 @@ export const initialState: CreateProjectStateTypes = { toggleSplittedGeojsonEdit: false, customFileValidity: false, validatedCustomForm: null, + additionalFeatureGeojson: null, }; const CreateProject = createSlice({ @@ -225,6 +226,9 @@ const CreateProject = createSlice({ SetValidatedCustomFile(state, action) { state.validatedCustomForm = action.payload; }, + SetAdditionalFeatureGeojson(state, action) { + state.additionalFeatureGeojson = action.payload; + }, }, }); diff --git a/src/frontend/src/store/types/ICreateProject.ts b/src/frontend/src/store/types/ICreateProject.ts index dd7c3d6281..b938389fb1 100644 --- a/src/frontend/src/store/types/ICreateProject.ts +++ b/src/frontend/src/store/types/ICreateProject.ts @@ -38,6 +38,7 @@ export type CreateProjectStateTypes = { toggleSplittedGeojsonEdit: boolean; customFileValidity: boolean; validatedCustomForm: any; + additionalFeatureGeojson: GeoJSONFeatureTypes | null; }; export type ValidateCustomFormResponse = { detail: { message: string; possible_reason: string }; @@ -114,6 +115,7 @@ export type ProjectDetailsTypes = { custom_tms_url: string; hasCustomTMS: boolean; customFormUpload: any; + hasAdditionalFeature: boolean; }; export type ProjectAreaTypes = { From 764201369d86f02368698dde02736273225a9c4c Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Mon, 23 Sep 2024 17:48:24 +0545 Subject: [PATCH 6/9] fix(fileInputComponent): style fix --- src/frontend/src/components/common/FileInputComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/common/FileInputComponent.tsx b/src/frontend/src/components/common/FileInputComponent.tsx index 7e6a965175..d06243188b 100644 --- a/src/frontend/src/components/common/FileInputComponent.tsx +++ b/src/frontend/src/components/common/FileInputComponent.tsx @@ -57,7 +57,7 @@ const FileInputComponent = ({

{customFile?.name}

)} -

{fileDescription}

+

{fileDescription}

); }; From 0be3495a35ed6abd295bd6082f21a6cfa870eb4a Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Mon, 23 Sep 2024 17:49:16 +0545 Subject: [PATCH 7/9] feat(newDefineAreaMap): show additional features on map if uploaded --- src/frontend/src/views/NewDefineAreaMap.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/frontend/src/views/NewDefineAreaMap.tsx b/src/frontend/src/views/NewDefineAreaMap.tsx index 0d1c81e674..aca5f86059 100644 --- a/src/frontend/src/views/NewDefineAreaMap.tsx +++ b/src/frontend/src/views/NewDefineAreaMap.tsx @@ -17,6 +17,7 @@ type NewDefineAreaMapProps = { onModify?: ((geojson: any, area?: number) => void) | null; hasEditUndo?: boolean; getAOIArea?: ((area?: number) => void) | null; + additionalFeatureGeojson?: GeoJSONFeatureTypes | null; }; const NewDefineAreaMap = ({ @@ -29,6 +30,7 @@ const NewDefineAreaMap = ({ onModify, hasEditUndo, getAOIArea, + additionalFeatureGeojson, }: NewDefineAreaMapProps) => { const { mapRef, map }: { mapRef: any; map: any } = useOLMap({ center: [0, 0], @@ -81,6 +83,18 @@ const NewDefineAreaMap = ({ /> )} + {additionalFeatureGeojson && ( + + )} {buildingExtractedGeojson && ( Date: Tue, 24 Sep 2024 09:53:53 +0545 Subject: [PATCH 8/9] feat(dataExtractValidation): additionalFeature add validation --- .../createnewproject/validation/DataExtractValidation.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/frontend/src/components/createnewproject/validation/DataExtractValidation.tsx b/src/frontend/src/components/createnewproject/validation/DataExtractValidation.tsx index dbe413971e..d35afb6736 100644 --- a/src/frontend/src/components/createnewproject/validation/DataExtractValidation.tsx +++ b/src/frontend/src/components/createnewproject/validation/DataExtractValidation.tsx @@ -4,6 +4,8 @@ interface ProjectValues { data_extractFile: object; data_extract_options: string; customDataExtractUpload: string; + hasAdditionalFeature: boolean; + additionalFeature: File; } interface ValidationErrors { form_ways?: string; @@ -11,6 +13,7 @@ interface ValidationErrors { data_extractFile?: string; data_extract_options?: string; customDataExtractUpload?: string; + additionalFeature?: string; } function DataExtractValidation(values: ProjectValues) { @@ -24,6 +27,10 @@ function DataExtractValidation(values: ProjectValues) { errors.customDataExtractUpload = 'A GeoJSON file is required.'; } + if (values.hasAdditionalFeature && !values.additionalFeature) { + errors.additionalFeature = 'Additional Feature is Required.'; + } + return errors; } From a85ce7fed183b50dbbc499a66bd7cec38d3844fe Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Tue, 24 Sep 2024 09:54:35 +0545 Subject: [PATCH 9/9] fix(dataExtract): additionalFeature add to formValue for validation --- .../createnewproject/DataExtract.tsx | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/frontend/src/components/createnewproject/DataExtract.tsx b/src/frontend/src/components/createnewproject/DataExtract.tsx index 9b675cd528..4deab4412a 100644 --- a/src/frontend/src/components/createnewproject/DataExtract.tsx +++ b/src/frontend/src/components/createnewproject/DataExtract.tsx @@ -254,7 +254,7 @@ const DataExtract = ({ resetFile(setCustomDataExtractUpload); generateDataExtract(); }} - className="fmtm-mt-6 fmtm-text-base" + className="fmtm-mt-4 !fmtm-mb-8 fmtm-text-base" isLoading={isFgbFetching} loadingText="Generating Map Features..." disabled={dataExtractGeojson && customDataExtractUpload ? true : false} @@ -279,42 +279,48 @@ const DataExtract = ({ /> )} -
- { - handleCustomChange('hasAdditionalFeature', status); - setAdditionalFeature(null); - }} - className="fmtm-text-black" - labelClickable - /> - {formValues?.hasAdditionalFeature && ( - <> - { - if (e?.target?.files) { - const uploadedFile = e?.target?.files[0]; - setAdditionalFeature(uploadedFile); - const additionalFeatureGeojson = await convertFileToFeatureCol(uploadedFile); - dispatch(CreateProjectActions.SetAdditionalFeatureGeojson(additionalFeatureGeojson)); - } - }} - onResetFile={() => { - resetFile(setAdditionalFeature); - dispatch(CreateProjectActions.SetAdditionalFeatureGeojson(null)); - }} - customFile={additionalFeature} - btnText="Upload Additional Features" - accept=".geojson" - fileDescription="*The supported file formats are .geojson" - errorMsg={errors.additionalFeature} - /> - - )} -
+ {extractWays && ( +
+ { + handleCustomChange('hasAdditionalFeature', status); + handleCustomChange('additionalFeature', null); + dispatch(CreateProjectActions.SetAdditionalFeatureGeojson(null)); + setAdditionalFeature(null); + }} + className="fmtm-text-black" + labelClickable + /> + {formValues?.hasAdditionalFeature && ( + <> + { + if (e?.target?.files) { + const uploadedFile = e?.target?.files[0]; + setAdditionalFeature(uploadedFile); + handleCustomChange('additionalFeature', uploadedFile); + const additionalFeatureGeojson = await convertFileToFeatureCol(uploadedFile); + dispatch(CreateProjectActions.SetAdditionalFeatureGeojson(additionalFeatureGeojson)); + } + }} + onResetFile={() => { + resetFile(setAdditionalFeature); + dispatch(CreateProjectActions.SetAdditionalFeatureGeojson(null)); + handleCustomChange('additionalFeature', null); + }} + customFile={additionalFeature} + btnText="Upload Additional Features" + accept=".geojson" + fileDescription="*The supported file formats are .geojson" + errorMsg={errors.additionalFeature} + /> + + )} +
+ )}