diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ea29212..2325b266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Load boundary details in draw page [#139](https://github.com/azavea/iow-boundary-tool/pull/139) - Let users select utility at login [#142](https://github.com/azavea/iow-boundary-tool/pull/142) - Add Activity Log Serializer [#140](https://github.com/azavea/iow-boundary-tool/pull/140) +- Save shape updates on draw page [#141](https://github.com/azavea/iow-boundary-tool/pull/141) ### Changed diff --git a/src/app/src/App.js b/src/app/src/App.js index 548fbd5e..a092aa16 100644 --- a/src/app/src/App.js +++ b/src/app/src/App.js @@ -28,7 +28,7 @@ const privateRoutes = ( } /> } /> - } /> + } /> } /> } /> diff --git a/src/app/src/api/boundaries.js b/src/app/src/api/boundaries.js index c362afdc..0e54cefa 100644 --- a/src/app/src/api/boundaries.js +++ b/src/app/src/api/boundaries.js @@ -28,11 +28,19 @@ const boundaryApi = api.injectEndpoints({ query: newBoundary => ({ url: '/boundaries/', method: 'POST', - body: newBoundary, + data: newBoundary, }), invalidatesTags: getNewItemTagInvalidator(TAGS.BOUNDARY), }), + updateBoundaryShape: build.mutation({ + query: ({ id, shape }) => ({ + url: `/boundaries/${id}/shape/`, + method: 'PUT', + data: shape, + }), + }), + submitBoundary: build.mutation({ query: id => ({ url: `/boundaries/${id}/submit/`, @@ -47,5 +55,6 @@ export const { useGetBoundariesQuery, useGetBoundaryDetailsQuery, useStartNewBoundaryMutation, + useUpdateBoundaryShapeMutation, useSubmitBoundaryMutation, } = boundaryApi; diff --git a/src/app/src/components/DrawTools/DrawTools.js b/src/app/src/components/DrawTools/DrawTools.js index eff2f84e..ead6ee54 100644 --- a/src/app/src/components/DrawTools/DrawTools.js +++ b/src/app/src/components/DrawTools/DrawTools.js @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; import { Button, Icon } from '@chakra-ui/react'; import { ArrowRightIcon } from '@heroicons/react/outline'; @@ -7,14 +7,45 @@ import { ArrowRightIcon } from '@heroicons/react/outline'; import EditToolbar from './EditToolbar'; import MapControlButtons from './MapControlButtons'; +import { useGetBoundaryDetailsQuery } from '../../api/boundaries'; +import { useBoundaryId, useEndpointToastError } from '../../hooks'; + import useAddPolygonCursor from './useAddPolygonCursor'; import useEditingPolygon from './useEditingPolygon'; import useGeocoderResult from './useGeocoderResult'; import useTrackMapZoom from './useTrackMapZoom'; import { setPolygon } from '../../store/mapSlice'; +import { BOUNDARY_STATUS, ROLES } from '../../constants'; +import LoadingModal from '../LoadingModal'; + +const DRAW_MODES = { + FULLY_EDITABLE: 'fully_editable', + ANNOTATIONS_ONLY: 'annotations_only', + READ_ONLY: 'read_only', +}; + +export default function LoadBoundaryDetails() { + const user = useSelector(state => state.auth.user); + const id = useBoundaryId(); + + const { isFetching, data: details, error } = useGetBoundaryDetailsQuery(id); + useEndpointToastError(error); + + if (isFetching) { + return ; + } + + if (error || typeof details !== 'object') { + return null; + } + + const mode = getDrawMode({ status: details.status, userRole: user.role }); -export default function DrawTools({ details }) { + return ; +} + +function DrawTools({ mode, details }) { const dispatch = useDispatch(); // Add the polygon indicated by `details` to the state @@ -22,11 +53,7 @@ export default function DrawTools({ details }) { if (details) { dispatch( setPolygon({ - // endpoint returns lngLat, leaflet needs latLng - points: details.submission.shape.coordinates[0].map(p => [ - p[1], - p[0], - ]), + points: details.submission.shape.coordinates[0], visible: true, label: details.utility.name, }) @@ -49,6 +76,18 @@ export default function DrawTools({ details }) { ); } +function getDrawMode({ status, userRole }) { + if (userRole === ROLES.VALIDATOR && status === BOUNDARY_STATUS.IN_REVIEW) { + return DRAW_MODES.ANNOTATIONS_ONLY; + } + + if (status === BOUNDARY_STATUS.DRAFT && userRole === ROLES.CONTRIBUTOR) { + return DRAW_MODES.FULLY_EDITABLE; + } + + return DRAW_MODES.READ_ONLY; +} + function SaveAndBackButton() { return (