From f6614d2ef39046b0783cf55dcf459b3efed89d70 Mon Sep 17 00:00:00 2001
From: Hsu Zhong Jun <27919917+dcshzj@users.noreply.github.com>
Date: Mon, 16 Oct 2023 17:11:19 +0800
Subject: [PATCH] feat(homepage): allow user to override changes when there is
a conflict (#1588)
---
.../OverwriteChangesModal.tsx | 4 +-
.../homepageHooks/useUpdateHomepageHook.ts | 35 +++++++---
src/layouts/EditHomepage/EditHomepage.jsx | 69 +++++++++++++++----
.../components/OverrideWarningModal.tsx | 4 +-
4 files changed, 85 insertions(+), 27 deletions(-)
diff --git a/src/components/OverwriteChangesModal/OverwriteChangesModal.tsx b/src/components/OverwriteChangesModal/OverwriteChangesModal.tsx
index f084e6783..2704fb151 100644
--- a/src/components/OverwriteChangesModal/OverwriteChangesModal.tsx
+++ b/src/components/OverwriteChangesModal/OverwriteChangesModal.tsx
@@ -27,8 +27,8 @@ export const OverwriteChangesModal = ({
edits now, their changes will be lost.
- We recommend you to make a copy of your changes elsewhere and come
- back later.
+ We recommend you to make a copy of your changes elsewhere, and
+ come back later to reconcile your changes.
diff --git a/src/hooks/homepageHooks/useUpdateHomepageHook.ts b/src/hooks/homepageHooks/useUpdateHomepageHook.ts
index 886dbfee6..31b7a2b5e 100644
--- a/src/hooks/homepageHooks/useUpdateHomepageHook.ts
+++ b/src/hooks/homepageHooks/useUpdateHomepageHook.ts
@@ -1,5 +1,10 @@
import { AxiosError } from "axios"
-import { UseMutationResult, useQueryClient, useMutation } from "react-query"
+import {
+ UseMutationResult,
+ useQueryClient,
+ useMutation,
+ UseMutationOptions,
+} from "react-query"
import { GET_HOMEPAGE_KEY } from "constants/queryKeys"
@@ -9,27 +14,41 @@ import { HomepageDto } from "types/homepage"
import { useSuccessToast, useErrorToast, DEFAULT_RETRY_MSG } from "utils"
export const useUpdateHomepageHook = (
- siteName: string
+ siteName: string,
+ mutationOptions?: Omit<
+ UseMutationOptions, HomepageDto>,
+ "mutationFn" | "mutationKey"
+ >
): UseMutationResult, HomepageDto> => {
const queryClient = useQueryClient()
const successToast = useSuccessToast()
const errorToast = useErrorToast()
+
return useMutation(
(homepageData: HomepageDto) =>
HomepageService.updateHomepage(siteName, homepageData),
{
- onSuccess: () => {
+ ...mutationOptions,
+ onSettled: () => {
queryClient.invalidateQueries([GET_HOMEPAGE_KEY, siteName])
+ },
+ onSuccess: (data, variables, context) => {
successToast({
id: "update-homepage-success",
description: "Homepage updated successfully",
})
+ if (mutationOptions?.onSuccess)
+ mutationOptions.onSuccess(data, variables, context)
},
- onError: (err: AxiosError) => {
- errorToast({
- id: "update-homepage-error",
- description: `Could not update homepage. ${DEFAULT_RETRY_MSG}. Error: ${err.response?.data.error.message}`,
- })
+ onError: (err, variables, context) => {
+ if (err.response?.status !== 409) {
+ errorToast({
+ id: "update-homepage-error",
+ description: `Could not update homepage. ${DEFAULT_RETRY_MSG}. Error: ${err.response?.data?.message}`,
+ })
+ }
+ if (mutationOptions?.onError)
+ mutationOptions.onError(err, variables, context)
},
}
)
diff --git a/src/layouts/EditHomepage/EditHomepage.jsx b/src/layouts/EditHomepage/EditHomepage.jsx
index bdd138dbe..42565e7bb 100644
--- a/src/layouts/EditHomepage/EditHomepage.jsx
+++ b/src/layouts/EditHomepage/EditHomepage.jsx
@@ -20,6 +20,7 @@ import { Footer } from "components/Footer"
import { Greyscale } from "components/Greyscale"
import Header from "components/Header"
import { LoadingButton } from "components/LoadingButton"
+import { OverwriteChangesModal } from "components/OverwriteChangesModal"
import { WarningModal } from "components/WarningModal"
import { FEATURE_FLAGS } from "constants/featureFlags"
@@ -207,11 +208,27 @@ const EditHomepage = ({ match }) => {
id: "",
type: "",
})
- const { isOpen, onOpen, onClose } = useDisclosure()
+ const {
+ isOpen: isSectionDeleteOpen,
+ onOpen: onSectionDeleteOpen,
+ onClose: onSectionDeleteClose,
+ } = useDisclosure()
+ const {
+ isOpen: isOverwriteOpen,
+ onOpen: onOverwriteOpen,
+ onClose: onOverwriteClose,
+ } = useDisclosure()
const [savedHeroElems, setSavedHeroElems] = useState("")
const [savedHeroErrors, setSavedHeroErrors] = useState("")
const { data: homepageData } = useGetHomepageHook(siteName)
- const { mutateAsync: updateHomepageHandler } = useUpdateHomepageHook(siteName)
+ const { mutateAsync: updateHomepageHandler } = useUpdateHomepageHook(
+ siteName,
+ {
+ onError: (err) => {
+ if (err.response.status === 409) onOverwriteOpen()
+ },
+ }
+ )
const homepageState = {
frontMatter,
errors,
@@ -237,6 +254,8 @@ const EditHomepage = ({ match }) => {
setDisplayAnnouncementItems(displayAnnouncementItems)
}
const heroSection = frontMatter.sections.filter((section) => !!section.hero)
+ const hasChanges =
+ JSON.stringify(originalFrontMatter) !== JSON.stringify(frontMatter)
const errorToast = useErrorToast()
@@ -244,6 +263,14 @@ const EditHomepage = ({ match }) => {
// TODO: Shift this into react query + custom hook
useEffect(() => {
if (!homepageData) return
+ if (!!homepageData && hasChanges) {
+ // We do not want to override changes made by the user but we want the
+ // user to be able to save using the latest sha if they choose to override
+ const { sha } = homepageData
+ setSha(sha)
+ return
+ }
+
const loadPageDetails = async () => {
// Set page colors
try {
@@ -907,7 +934,7 @@ const EditHomepage = ({ match }) => {
}
const onDeleteClick = (id, name) => {
- onOpen()
+ onSectionDeleteOpen()
setItemPendingForDelete({ id, type: name })
}
@@ -1163,11 +1190,13 @@ const EditHomepage = ({ match }) => {
resetFirstLoad()
await updateHomepageHandler(params)
} catch (err) {
- errorToast({
- id: "update-homepage-error",
- description: `There was a problem trying to save your homepage. ${DEFAULT_RETRY_MSG}`,
- })
- console.log(err)
+ if (err.response.status !== 409) {
+ errorToast({
+ id: "update-homepage-error",
+ description: `There was a problem trying to save your homepage. ${DEFAULT_RETRY_MSG}`,
+ })
+ console.log(err)
+ }
}
}
@@ -1184,11 +1213,12 @@ const EditHomepage = ({ match }) => {
const showNewLayouts = useFeatureIsOn(FEATURE_FLAGS.HOMEPAGE_TEMPLATES)
return (
<>
+ {/* Section deletion warning modal */}
{
setItemPendingForDelete({ id: null, type: "" })
- onClose()
+ onSectionDeleteClose()
}}
displayTitle={`Delete ${itemPendingForDelete.type}`}
displayText={
@@ -1202,7 +1232,7 @@ const EditHomepage = ({ match }) => {
colorScheme="secondary"
onClick={() => {
setItemPendingForDelete({ id: null, type: "" })
- onClose()
+ onSectionDeleteClose()
}}
>
Cancel
@@ -1212,18 +1242,27 @@ const EditHomepage = ({ match }) => {
onClick={() => {
deleteHandler(itemPendingForDelete.id)
setItemPendingForDelete({ id: null, type: "" })
- onClose()
+ onSectionDeleteClose()
}}
>
Yes, delete
+
+ {/* Override changes warning modal */}
+ {
+ onOverwriteClose()
+ savePage()
+ }}
+ />
+
- We recommend you to make a copy of your changes elsewhere and come
- back later.
+ We recommend you to make a copy of your changes elsewhere, and
+ come back later to reconcile your changes.