From bc87fd6714486567577e48725298d365de3e1a23 Mon Sep 17 00:00:00 2001 From: Nishit Suwal <81785002+NSUWAL123@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:09:25 +0545 Subject: [PATCH] Fix/event driven tasks continuation (#1839) * build: add migrations to update task_history --> task_events * refactor(backend): wip update to use TaskEvent / State enums * refactor(frontend): wip update to use TaskEvent / State enums * build: add trigger to set task_event.state automatically from event * refactor: continued wip to use task events * refactor: fixes to task state/event distinction * fix: additional fixes to backend usage action --> event * build: fix migration conflict if task_history does not exist * build: add conflate to enums in case for future * refactor: further wip updates for task events * fix(taskSelectionPopup): project task index display on task popup * fix(submissionsInfographics): handle undefined task_history * fix(dialogTaskActions): remove taskBoundary from args, pass geojsonStyles to as args * fix(taskEvent): use response state to track and update current task state color * fix(featureSelectionPopup): page crash on taskStateEnum undefined fix * fix(getTaskStatusStyle): update feature style key based on entiy_state enums * fix(projectInfo): change card title accessor key * fix(taskSubmissionsMap): fix taskGeojson schema * fix(submissionDetails): update get comments api * fix(updateReviewStatusModal): update reviewList id, update post submission comments api --------- Co-authored-by: spwoodcock --- src/backend/tests/conftest.py | 1 - src/frontend/src/api/TaskEvent.ts | 4 +- .../src/components/DialogTaskActions.tsx | 6 +-- .../FeatureSelectionPopup.tsx | 2 +- .../ProjectDetailsV2/TaskSelectionPopup.tsx | 2 +- .../ProjectSubmissions/ProjectInfo.tsx | 4 +- .../SubmissionsInfographics.tsx | 2 +- .../ProjectSubmissions/TaskSubmissionsMap.tsx | 10 +++- .../UpdateReviewStatusModal.tsx | 9 ++-- .../src/utilfunctions/getTaskStatusStyle.ts | 49 ++++++++++--------- src/frontend/src/views/SubmissionDetails.tsx | 2 +- 11 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/backend/tests/conftest.py b/src/backend/tests/conftest.py index 981d13189a..c8d3ecf3ad 100644 --- a/src/backend/tests/conftest.py +++ b/src/backend/tests/conftest.py @@ -230,7 +230,6 @@ async def task_event(db, project, tasks, admin_user): comment="We added a comment!", ) db_task_event = await DbTaskEvent.create(db, new_event) - return db_task_event diff --git a/src/frontend/src/api/TaskEvent.ts b/src/frontend/src/api/TaskEvent.ts index 769979a565..e225f442d8 100755 --- a/src/frontend/src/api/TaskEvent.ts +++ b/src/frontend/src/api/TaskEvent.ts @@ -49,9 +49,9 @@ export const CreateTaskEvent = ( }; const response = await CoreModules.axios.post(url, body, { params }); dispatch(ProjectActions.UpdateProjectTaskActivity(response.data)); - if (feature && style) { - await feature.setStyle(style); + // update task color based on current state + await feature.setStyle(style[response?.data?.state]); // assign userId to actioned_by_uid if state is locked_for_mapping or locked_for_validation const prevProperties = feature.getProperties(); diff --git a/src/frontend/src/components/DialogTaskActions.tsx b/src/frontend/src/components/DialogTaskActions.tsx index 27302136cb..97da9b9bb5 100755 --- a/src/frontend/src/components/DialogTaskActions.tsx +++ b/src/frontend/src/components/DialogTaskActions.tsx @@ -70,6 +70,7 @@ export default function Dialog({ taskId, feature }: dialogPropType) { } }, [taskId, taskInfo]); + // TODO need to set the TaskEvent here, not MappingStatus? useEffect(() => { if (projectIndex != -1) { // Get current state of task @@ -91,7 +92,7 @@ export default function Dialog({ taskId, feature }: dialogPropType) { if (!btnId) return; const selectedAction = taskEventEnum[btnId]; const authDetailsCopy = authDetails != null ? { ...authDetails } : {}; - const geoStyle = geojsonStyles[btnId]; + if (btnId != undefined) { if (authDetailsCopy.hasOwnProperty('id')) { // if (btnId === 'MERGE_WITH_OSM') { @@ -106,8 +107,7 @@ export default function Dialog({ taskId, feature }: dialogPropType) { taskId.toString(), authDetailsCopy, { project_id: currentProjectId }, - geoStyle, - taskBoundaryData, + geojsonStyles, feature, ), ); diff --git a/src/frontend/src/components/ProjectDetailsV2/FeatureSelectionPopup.tsx b/src/frontend/src/components/ProjectDetailsV2/FeatureSelectionPopup.tsx index ea49712473..e25cf24703 100644 --- a/src/frontend/src/components/ProjectDetailsV2/FeatureSelectionPopup.tsx +++ b/src/frontend/src/components/ProjectDetailsV2/FeatureSelectionPopup.tsx @@ -12,7 +12,7 @@ import { UpdateEntityState } from '@/api/Project'; import { TaskFeatureSelectionProperties } from '@/store/types/ITask'; import { CreateTaskEvent } from '@/api/TaskEvent'; import MapStyles from '@/hooks/MapStyles'; -import { task_event } from '@/types/enums'; +import { task_event, task_state as taskStateEnum } from '@/types/enums'; type TaskFeatureSelectionPopupPropType = { taskId: number; diff --git a/src/frontend/src/components/ProjectDetailsV2/TaskSelectionPopup.tsx b/src/frontend/src/components/ProjectDetailsV2/TaskSelectionPopup.tsx index 3cfe70afd7..ba0587f1eb 100644 --- a/src/frontend/src/components/ProjectDetailsV2/TaskSelectionPopup.tsx +++ b/src/frontend/src/components/ProjectDetailsV2/TaskSelectionPopup.tsx @@ -27,7 +27,7 @@ const TaskSelectionPopup = ({ taskId, body, feature }: TaskSelectionPopupPropTyp const authDetails = CoreModules.useAppSelector((state) => state.login.authDetails); const selectedTask = { ...projectData?.[projectIndex]?.taskBoundries?.filter((indTask, i) => { - return indTask?.index == taskId; + return indTask?.id == taskId; })?.[0], }; const checkIfTaskAssignedOrNot = diff --git a/src/frontend/src/components/ProjectSubmissions/ProjectInfo.tsx b/src/frontend/src/components/ProjectSubmissions/ProjectInfo.tsx index fc2b8a1f6f..d46e9525a3 100644 --- a/src/frontend/src/components/ProjectSubmissions/ProjectInfo.tsx +++ b/src/frontend/src/components/ProjectSubmissions/ProjectInfo.tsx @@ -48,7 +48,9 @@ const ProjectInfo = ({ entities }) => {
{data.icon}
-

{data.name}

+

+ {data.title} +

{data.count}

diff --git a/src/frontend/src/components/ProjectSubmissions/SubmissionsInfographics.tsx b/src/frontend/src/components/ProjectSubmissions/SubmissionsInfographics.tsx index 6928b12ea4..ece8ba84f4 100644 --- a/src/frontend/src/components/ProjectSubmissions/SubmissionsInfographics.tsx +++ b/src/frontend/src/components/ProjectSubmissions/SubmissionsInfographics.tsx @@ -41,7 +41,7 @@ const SubmissionsInfographics = ({ toggleView, entities }) => { const projectIndex = projectTaskList.findIndex((project) => project.id == +projectId); // task activities history list const taskActivities = projectTaskList?.[projectIndex]?.taskBoundries?.reduce((acc: taskHistoryTypes[], task) => { - return [...acc, ...task?.task_history]; + return [...acc, ...(task?.task_history ?? [])]; }, []); // filter activities for last 30 days diff --git a/src/frontend/src/components/ProjectSubmissions/TaskSubmissionsMap.tsx b/src/frontend/src/components/ProjectSubmissions/TaskSubmissionsMap.tsx index 2bdc607833..e65240be7b 100644 --- a/src/frontend/src/components/ProjectSubmissions/TaskSubmissionsMap.tsx +++ b/src/frontend/src/components/ProjectSubmissions/TaskSubmissionsMap.tsx @@ -111,8 +111,12 @@ const TaskSubmissionsMap = () => { ...basicGeojsonTemplate, features: [ ...projectTaskBoundries?.[0]?.taskBoundries?.map((task) => ({ - ...task.outline, - id: task?.outline?.properties?.fid, + type: 'Feature', + geometry: { ...task.outline, id: task?.outline?.properties?.fid }, + properties: { + fid: task?.index, + uid: task?.id, + }, })), ], }; @@ -121,6 +125,7 @@ const TaskSubmissionsMap = () => { useEffect(() => { if (!taskBoundaries) return; + if (!selectedTask) return; const filteredSelectedTaskGeojson = { ...basicGeojsonTemplate, features: taskBoundaries?.features?.filter((task) => task?.properties?.fid === selectedTask), @@ -142,6 +147,7 @@ const TaskSubmissionsMap = () => { constrainResolution: true, duration: 2000, }); + dispatch(CoreModules.TaskActions.SetSelectedTask(null)); }, [selectedTask]); const taskOnSelect = (properties, feature) => { diff --git a/src/frontend/src/components/ProjectSubmissions/UpdateReviewStatusModal.tsx b/src/frontend/src/components/ProjectSubmissions/UpdateReviewStatusModal.tsx index e8c93d51a0..b0f109d647 100644 --- a/src/frontend/src/components/ProjectSubmissions/UpdateReviewStatusModal.tsx +++ b/src/frontend/src/components/ProjectSubmissions/UpdateReviewStatusModal.tsx @@ -11,19 +11,19 @@ import { PostProjectComments } from '@/api/Project'; const reviewList: reviewListType[] = [ { - id: 'approved', + id: 'APPROVED', title: 'Approved', className: 'fmtm-bg-[#E7F3E8] fmtm-text-[#40B449] fmtm-border-[#40B449]', hoverClass: 'hover:fmtm-text-[#40B449] hover:fmtm-border-[#40B449]', }, { - id: 'hasIssues', + id: 'HASISSUES', title: 'Has Issue', className: 'fmtm-bg-[#E9DFCF] fmtm-text-[#D99F00] fmtm-border-[#D99F00]', hoverClass: 'hover:fmtm-text-[#D99F00] hover:fmtm-border-[#D99F00]', }, { - id: 'rejected', + id: 'REJECTED', title: 'Rejected', className: 'fmtm-bg-[#E8D5D5] fmtm-text-[#D73F37] fmtm-border-[#D73F37]', hoverClass: 'hover:fmtm-text-[#D73F37] hover:fmtm-border-[#D73F37]', @@ -60,10 +60,11 @@ const UpdateReviewStatusModal = () => { if (noteComments.trim().length > 0) { dispatch( PostProjectComments( - `${import.meta.env.VITE_API_URL}/tasks/${updateReviewStatusModal?.taskUId}/comment/?project_id=${updateReviewStatusModal?.projectId}`, + `${import.meta.env.VITE_API_URL}/tasks/${updateReviewStatusModal?.taskUId}/event/?project_id=${updateReviewStatusModal?.projectId}`, { task_id: updateReviewStatusModal?.taskUId, comment: `${updateReviewStatusModal?.instanceId}-SUBMISSION_INST-${noteComments}`, + event: 'COMMENT', }, ), ); diff --git a/src/frontend/src/utilfunctions/getTaskStatusStyle.ts b/src/frontend/src/utilfunctions/getTaskStatusStyle.ts index efed48d590..d7f5bb4c1f 100644 --- a/src/frontend/src/utilfunctions/getTaskStatusStyle.ts +++ b/src/frontend/src/utilfunctions/getTaskStatusStyle.ts @@ -2,7 +2,7 @@ import { Fill, Icon, Stroke, Style } from 'ol/style'; import { getCenter } from 'ol/extent'; import { Point } from 'ol/geom'; import AssetModules from '@/shared/AssetModules'; -import { task_state } from '@/types/enums'; +import { entity_state } from '@/types/enums'; import { EntityOsmMap } from '@/store/types/IProject'; function createPolygonStyle(fillColor: string, strokeColor: string) { @@ -108,7 +108,8 @@ const getTaskStatusStyle = (feature: Record, mapTheme: Record, entityOsmMap: EntityOsmMap[]) => { const entity = entityOsmMap?.find((entity) => entity?.osm_id === osmId) as EntityOsmMap; - let status = task_state[entity?.status]; + + let status = entity_state[entity?.status]; const borderStrokeColor = '#FF0000'; @@ -124,7 +125,7 @@ export const getFeatureStatusStyle = (osmId: string, mapTheme: Record { if (!taskUId) return; dispatch( GetProjectComments( - `${import.meta.env.VITE_API_URL}/tasks/${parseInt(taskUId)}/history/?project_id=${projectId}&comment=true`, + `${import.meta.env.VITE_API_URL}/tasks/${parseInt(taskUId)}/history/?project_id=${projectId}&comments=true`, ), ); }, [taskUId]);