-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Save shape updates #141
Save shape updates #141
Changes from all commits
5a403cb
e0bf015
b5ad762
8d3772f
c824157
2b9520a
551e61d
5c56803
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { | ||
Flex, | ||
Modal, | ||
ModalBody, | ||
ModalContent, | ||
ModalFooter, | ||
ModalHeader, | ||
ModalOverlay, | ||
Spinner, | ||
} from '@chakra-ui/react'; | ||
|
||
export default function LoadingModal({ isOpen, title }) { | ||
return ( | ||
<Modal isOpen={isOpen} isCentered size='xs'> | ||
<ModalOverlay> | ||
<ModalContent> | ||
<ModalHeader alignItems='center'>{title ?? ''}</ModalHeader> | ||
<ModalBody> | ||
<Flex direction='column' alignItems='center'> | ||
<Spinner size='xl' /> | ||
</Flex> | ||
<ModalFooter /> | ||
</ModalBody> | ||
</ModalContent> | ||
</ModalOverlay> | ||
</Modal> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,18 @@ | ||
import { useSelector } from 'react-redux'; | ||
import { useParams } from 'react-router-dom'; | ||
import { Box, Flex, Spinner } from '@chakra-ui/react'; | ||
import { Box, Flex } from '@chakra-ui/react'; | ||
|
||
import NotFound from './NotFound'; | ||
import DrawTools from '../components/DrawTools'; | ||
import Layers from '../components/Layers'; | ||
import Map from '../components/Map'; | ||
import Sidebar from '../components/Sidebar'; | ||
|
||
import { useGetBoundaryDetailsQuery } from '../api/boundaries'; | ||
import { BOUNDARY_STATUS, ROLES } from '../constants'; | ||
|
||
const DRAW_MODES = { | ||
FULLY_EDITABLE: 'fully_editable', | ||
ANNOTATIONS_ONLY: 'annotations_only', | ||
READ_ONLY: 'read_only', | ||
}; | ||
|
||
export default function Draw() { | ||
const user = useSelector(state => state.auth.user); | ||
const { id } = useParams(); | ||
|
||
const { isFetching, data: details, error } = useGetBoundaryDetailsQuery(id); | ||
|
||
if (isFetching) { | ||
return ( | ||
<Box w='100%' h='100vh'> | ||
<Flex direction='column' alignItems='center'> | ||
<Spinner mt={60} /> | ||
</Flex> | ||
</Box> | ||
); | ||
} | ||
|
||
if (error || typeof details !== 'object') { | ||
return <NotFound />; | ||
} | ||
|
||
let mode = DRAW_MODES.READ_ONLY; | ||
|
||
if ( | ||
[BOUNDARY_STATUS.SUBMITTED, BOUNDARY_STATUS.IN_REVIEW].includes( | ||
details.status | ||
) && | ||
user.role === ROLES.VALIDATOR | ||
) { | ||
mode = DRAW_MODES.ANNOTATIONS_ONLY; | ||
} else if ( | ||
details.status === BOUNDARY_STATUS.DRAFT && | ||
user.role === ROLES.CONTRIBUTOR | ||
) { | ||
mode = DRAW_MODES.FULLY_EDITABLE; | ||
} | ||
|
||
return ( | ||
<Flex> | ||
<Sidebar /> | ||
<Box flex={1} position='relative'> | ||
<Map> | ||
<Layers mode={mode} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I like that arrangement. Alternatively, if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yep, but then we would also need to handle the various states of the request (isFetching, error, success) in that component as well. I like to have one parent component handling all this and passing the non-null data to the children. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. |
||
<DrawTools mode={mode} details={details} /> | ||
<Layers /> | ||
<DrawTools /> | ||
</Map> | ||
</Box> | ||
</Flex> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from rest_framework.exceptions import APIException | ||
|
||
|
||
class ForbiddenException(APIException): | ||
status_code = 403 | ||
default_detail = 'You are not allowed to perform this action.' | ||
default_code = 'forbidden' | ||
|
||
|
||
class BadRequestException(APIException): | ||
status_code = 400 | ||
default_detail = 'There was a problem with your request.' | ||
default_code = 'bad_request' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice job adding clear exceptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to be:
I'm thinking that the distinction between
IN_REVIEW
andSUBMITTED
is the presence of a row in the Reviews database table. If a Validator clicks "Review" on a boudary, an entry should be added to the Reviews table before taking them to the/draw
page.Otherwise the Review creation logic would happen the first time a review is saved. This feels more complicated to me, however, it's something that could be handled entirely by the back-end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This understanding is correct.
DRAFT = Row in Submission table, with submitted_at = NULL
SUBMITTED = That row has a value for submitted_at
IN_REVIEW = Row in Review table, with reviewed_at = NULL
NEEDS REVISIONS = That row has a value for reviewed_at
APPROVED = Row in Approval table, with a value for approved_at
I'm not sure how much we'll end up using IN_REVIEW in practice.