Skip to content
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

Fix: publish button delay #1263

Merged
merged 2 commits into from
May 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 30 additions & 18 deletions src/layouts/ReviewRequest/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,22 @@ export const ReviewRequestDashboard = (): JSX.Element => {
// TODO!
isError: isMergeError,
} = useMergeReviewRequest(siteName, prNumber, false)
const [isApproved, setIsApproved] = useState<boolean | null>(null)

const { onCopy, hasCopied } = useClipboard(data?.reviewUrl || "")

const reviewStatus = data?.status
const isApproved = reviewStatus === ReviewRequestStatus.APPROVED

useEffect(() => {
if (
reviewStatus === ReviewRequestStatus.CLOSED ||
reviewStatus === ReviewRequestStatus.MERGED
) {
setRedirectToPage(`/sites/${siteName}/dashboard`)
}
}, [reviewStatus, setRedirectToPage, siteName])
if (reviewStatus && isApproved === null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey I am confused with this code here :(
why are we setting it to approved when isApproved is null? if the idea to set them when we first run this code, this wouldn't play well well with a flow like approve -> disapprove -> approve? shouldnt this then just be if(reviewStatus) setIsApproved(reviewStatus === ReviewRequestStatus.APPROVED)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea for this code is to set isApproved only on initial load - isApproved is set to null originally, and if reviewStatus has finished loading, we set setIsApproved(reviewStatus === ReviewRequestStatus.APPROVED). From this point onwards, isApproved is only affected by the user's changes, which are immediate (as opposed to the previous behaviour of having to wait for the query from the backend)

Without the check for the first load, it gets stuck on the initial state of the page and has to rely on new information from the backend in order to change state!

setIsApproved(reviewStatus === ReviewRequestStatus.APPROVED)
}
}, [isApproved, reviewStatus, setRedirectToPage, siteName])

useEffect(() => {
updateReviewRequestViewed({ siteName, prNumber })
Expand Down Expand Up @@ -151,9 +154,15 @@ export const ReviewRequestDashboard = (): JSX.Element => {
</HStack>
<Spacer />
{role === "requestor" ? (
<CancelRequestButton isApproved={isApproved} />
<CancelRequestButton
isApproved={isApproved}
setIsApproved={setIsApproved}
/>
) : (
<ApprovalButton isApproved={isApproved} />
<ApprovalButton
isApproved={isApproved}
setIsApproved={setIsApproved}
/>
)}
</Flex>
<Skeleton
Expand Down Expand Up @@ -213,11 +222,13 @@ export const ReviewRequestDashboard = (): JSX.Element => {
}

interface RequestButtonProps {
isApproved: boolean
isApproved: null | boolean
setIsApproved: (state: boolean) => void
}

const CancelRequestButton = ({
isApproved,
setIsApproved,
}: RequestButtonProps): JSX.Element => {
const { onOpen, isOpen, onClose } = useDisclosure()
const { role, isLoading } = useReviewRequestRoleContext()
Expand All @@ -238,20 +249,21 @@ const CancelRequestButton = ({
</Text>
</MenuDropdownItem>
</MenuDropdownButton>
<CancelRequestModal isOpen={isOpen} onClose={onClose} />
<CancelRequestModal
isOpen={isOpen}
onClose={() => {
setIsApproved(false)
onClose()
}}
/>
</>
)
}

// NOTE: Utility component exists to soothe over state management
const ApprovalButton = ({
isApproved: defaultIsApproved,
isApproved,
setIsApproved,
}: RequestButtonProps): JSX.Element => {
const [isApproved, setIsApproved] = useState<boolean | null>(null)
// NOTE: We use a computed approval one because
// the `useState` above captures a stale value.
// This leads to the button not updating when the status is finally fetched.
const computedApproval = isApproved === null ? defaultIsApproved : isApproved
const { role, isLoading } = useReviewRequestRoleContext()
const { onOpen, isOpen, onClose } = useDisclosure()
const errorToast = useErrorToast()
Expand Down Expand Up @@ -298,16 +310,16 @@ const ApprovalButton = ({
return (
<>
<MenuDropdownButton
colorScheme={computedApproval ? "success" : "primary"}
mainButtonText={computedApproval ? "Approved" : "In review"}
colorScheme={isApproved ? "success" : "primary"}
mainButtonText={isApproved ? "Approved" : "In review"}
variant="solid"
isDisabled={role !== "reviewer"}
isLoading={isLoading}
>
<MenuDropdownItem
onClick={async () => {
await unapproveReviewRequest()
setIsApproved(false)
await unapproveReviewRequest()
}}
>
<Text textStyle="body-1" textColor="text.body" w="100%">
Expand All @@ -316,8 +328,8 @@ const ApprovalButton = ({
</MenuDropdownItem>
<MenuDropdownItem
onClick={async () => {
await approveReviewRequest()
setIsApproved(true)
await approveReviewRequest()
onOpen()
}}
>
Expand Down