From 66a087edb5942c4347b406cc7f383861660e9ad4 Mon Sep 17 00:00:00 2001 From: kwajiehao Date: Wed, 24 Mar 2021 10:26:16 +0100 Subject: [PATCH 01/19] fix: turn off refetching on window focus for useQuery This commit sets the `refetchOnWindowFocus` flag for the useQuery on the following layouts/components to be `false`: - PageSettingsModal - EditNavBar - EditPage The reason we turn off this flag is because these pages involve user changes - with this flag on, any unsaved changes by the user would be overwritten by the refetched data. This commit also sets the - `refetchOnReconnect` - `refetchInterval` - `refetchIntervalInBackground` flags to be false for the same reasons explained above. --- src/components/PageSettingsModal.jsx | 26 ++++++++++++++++++++++++++ src/layouts/EditNavBar.jsx | 6 +++++- src/layouts/EditPage.jsx | 18 +++++++++++++++--- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index 49c8d9c013..f3bc8e80b2 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -67,6 +67,32 @@ const PageSettingsModal = ({ permalink: setPermalink, } + const {} = useQuery( + 'page', + async () => await getPage(pageType, siteName, folderName, originalPageName), + { + enabled: !isNewPage, + retry: false, + onSuccess: ({ content, sha }) => { + const { frontMatter, mdBody } = frontMatterParser(content) + setTitle(deslugifyPage(originalPageName)) + setPermalink(frontMatter.permalink) + setOriginalPermalink(frontMatter.permalink) + setSha(sha) + setMdBody(mdBody) + }, + onError: () => { + setSelectedPage('') + setIsPageSettingsActive(false) + errorToast(`The page data could not be retrieved. ${DEFAULT_RETRY_MSG}`) + }, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: false, + refetchIntervalInBackground: false, + } + ) + const { mutateAsync: saveHandler } = useMutation( () => { const frontMatter = subfolderName diff --git a/src/layouts/EditNavBar.jsx b/src/layouts/EditNavBar.jsx index 550d023b7f..62cb2291df 100644 --- a/src/layouts/EditNavBar.jsx +++ b/src/layouts/EditNavBar.jsx @@ -123,7 +123,11 @@ const EditNavBar = ({ match }) => { } else { errorToast(`There was a problem trying to load your data. ${DEFAULT_RETRY_MSG}`) } - } + }, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: false, + refetchIntervalInBackground: false, }, ); diff --git a/src/layouts/EditPage.jsx b/src/layouts/EditPage.jsx index 5e5456ce1d..7e690b3b1b 100644 --- a/src/layouts/EditPage.jsx +++ b/src/layouts/EditPage.jsx @@ -136,7 +136,11 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => } else { errorToast(`There was a problem trying to load your page. ${DEFAULT_RETRY_MSG}`) } - } + }, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: false, + refetchIntervalInBackground: false, }, ); @@ -152,7 +156,11 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => } else { errorToast(`There was a problem trying to load your page. ${DEFAULT_RETRY_MSG}`) } - } + }, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: false, + refetchIntervalInBackground: false, }, ); @@ -168,7 +176,11 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => } else { errorToast(`There was a problem trying to load your page. ${DEFAULT_RETRY_MSG}`) } - } + }, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchInterval: false, + refetchIntervalInBackground: false, }, ); From 7e817d8ce5a55327fcaf46b6d6d2c2844f3c7f3a Mon Sep 17 00:00:00 2001 From: kwajiehao Date: Thu, 25 Mar 2021 04:26:45 +0100 Subject: [PATCH 02/19] fix: invalidate queries after mutation This commit adds cache invalidation of all our GET queries (the useQuery invocations) after we perform a mutation. This allows us to reset our cache in a more granular manner, as opposed to simply setting the cache time for our GET queries to be 0. Additionally, this commit also adds a PAGE_SETTINGS_KEY constant to replace the string literal that was being used as the query key for the PageSettingsModal. Refer to the following documentation for more details: - https://react-query.tanstack.com/guides/query-invalidation - https://react-query.tanstack.com/guides/invalidations-from-mutations --- src/components/PageSettingsModal.jsx | 18 ++++++++++++++---- src/constants.js | 1 + src/layouts/EditNavBar.jsx | 10 ++++++++-- src/layouts/EditPage.jsx | 10 ++++++++-- src/layouts/Folders.jsx | 11 +++++++++-- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index f3bc8e80b2..038cbdf7d4 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; -import { useMutation } from 'react-query'; import PropTypes from 'prop-types'; +import { useQuery, useMutation, useQueryClient } from 'react-query'; import axios from 'axios'; import * as _ from 'lodash'; @@ -13,7 +13,8 @@ import { deslugifyDirectory, } from '../utils'; -import { createPageData, updatePageData, renamePageData } from '../api' +import { getPage, createPageData, updatePageData, renamePageData } from '../api' +import { PAGE_SETTINGS_KEY } from '../constants' import elementStyles from '../styles/isomer-cms/Elements.module.scss'; @@ -41,6 +42,9 @@ const PageSettingsModal = ({ setSelectedPage, setIsPageSettingsActive, }) => { + // Instantiate queryClient + const queryClient = useQueryClient() + // Errors const [errors, setErrors] = useState({ title: '', @@ -68,7 +72,7 @@ const PageSettingsModal = ({ } const {} = useQuery( - 'page', + [PAGE_SETTINGS_KEY, originalPageName], async () => await getPage(pageType, siteName, folderName, originalPageName), { enabled: !isNewPage, @@ -86,6 +90,7 @@ const PageSettingsModal = ({ setIsPageSettingsActive(false) errorToast(`The page data could not be retrieved. ${DEFAULT_RETRY_MSG}`) }, + cacheTime: 0, refetchOnWindowFocus: false, refetchOnReconnect: false, refetchInterval: false, @@ -105,7 +110,12 @@ const PageSettingsModal = ({ }, { onSettled: () => {setSelectedPage(''); setIsPageSettingsActive(false)}, - onSuccess: (redirectUrl) => redirectUrl ? setRedirectToPage(redirectUrl) : window.location.reload(), + onSuccess: (redirectUrl) => { + queryClient.invalidateQueries([PAGE_SETTINGS_KEY, originalPageName]) + + if (redirectUrl) setRedirectToPage(redirectUrl) + else window.location.reload() + }, onError: () => errorToast(`${isNewPage ? 'A new page could not be created.' : 'Your page settings could not be saved.'} ${DEFAULT_RETRY_MSG}`) } ) diff --git a/src/constants.js b/src/constants.js index 3565f94231..e337e83258 100644 --- a/src/constants.js +++ b/src/constants.js @@ -9,3 +9,4 @@ export const RESOURCE_CATEGORY_CONTENT_KEY = 'resource-category-contents' export const RESOURCE_ROOM_CONTENT_KEY = 'resource-room-contents' export const FOLDERS_CONTENT_KEY = 'folders-contents' export const LAST_UPDATED_KEY = 'last-updated' +export const PAGE_SETTINGS_KEY = 'page-settings'; diff --git a/src/layouts/EditNavBar.jsx b/src/layouts/EditNavBar.jsx index 62cb2291df..3042a20b04 100644 --- a/src/layouts/EditNavBar.jsx +++ b/src/layouts/EditNavBar.jsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import _ from 'lodash'; import PropTypes from 'prop-types'; import update from 'immutability-helper'; -import { useQuery, useMutation } from 'react-query'; +import { useQuery, useMutation, useQueryClient } from 'react-query'; import { ReactQueryDevtools } from 'react-query/devtools'; import { DragDropContext } from 'react-beautiful-dnd'; @@ -31,6 +31,9 @@ import { getEditNavBarData, updateNavBarData } from '../api'; const RADIX_PARSE_INT = 10 const EditNavBar = ({ match }) => { + // Instantiate queryClient + const queryClient = useQueryClient() + const { siteName } = match.params const { setRedirectToNotFound } = useRedirectHook() @@ -136,7 +139,10 @@ const EditNavBar = ({ match }) => { () => updateNavBarData(siteName, originalNav, links, sha), { onError: () => errorToast(`There was a problem trying to save your nav bar. ${DEFAULT_RETRY_MSG}`), - onSuccess: () => window.location.reload(), + onSuccess: () => { + queryClient.invalidateQueries([NAVIGATION_CONTENT_KEY, siteName]) + window.location.reload() + }, }, ) diff --git a/src/layouts/EditPage.jsx b/src/layouts/EditPage.jsx index 7e690b3b1b..9fc0c5b3fb 100644 --- a/src/layouts/EditPage.jsx +++ b/src/layouts/EditPage.jsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef, useState } from 'react'; import axios from 'axios'; import _ from 'lodash'; -import { useQuery, useMutation } from 'react-query'; +import { useQuery, useMutation, useQueryClient } from 'react-query'; import PropTypes from 'prop-types'; import SimpleMDE from 'react-simplemde-editor'; import marked from 'marked'; @@ -96,6 +96,9 @@ const getBackButtonInfo = (resourceCategory, folderName, siteName, subfolderName } const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => { + // Instantiate queryClient + const queryClient = useQueryClient() + const { retrieveSiteColors, generatePageStyleSheet } = useSiteColorsHook() const { setRedirectToNotFound } = useRedirectHook() @@ -189,7 +192,10 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => () => updatePageData(match.params, concatFrontMatterMdBody(frontMatter, editorValue), sha), { onError: () => errorToast(`There was a problem saving your page. ${DEFAULT_RETRY_MSG}`), - onSuccess: () => window.location.reload(), + onSuccess: () => { + queryClient.invalidateQueries([PAGE_CONTENT_KEY, match.params]) + window.location.reload() + }, }, ) diff --git a/src/layouts/Folders.jsx b/src/layouts/Folders.jsx index cf34150ad5..3560f10d6b 100644 --- a/src/layouts/Folders.jsx +++ b/src/layouts/Folders.jsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; -import { useQuery, useMutation } from 'react-query'; +import { useQuery, useMutation, useQueryClient } from 'react-query'; import { ReactQueryDevtools } from 'react-query/devtools'; import { Link } from 'react-router-dom'; import _ from 'lodash'; @@ -41,6 +41,8 @@ import elementStyles from '../styles/isomer-cms/Elements.module.scss'; import contentStyles from '../styles/isomer-cms/pages/Content.module.scss'; const Folders = ({ match, location }) => { + // Instantiate queryClient + const queryClient = useQueryClient() const { siteName, folderName, subfolderName } = match.params; // set Move-To dropdown to start from current location of file @@ -78,7 +80,7 @@ const Folders = ({ match, location }) => { } else { errorToast() } - } + }, }, ) @@ -128,6 +130,11 @@ const Folders = ({ match, location }) => { setSelectedPage('') errorToast(`The page data could not be retrieved. ${DEFAULT_RETRY_MSG}`) }, + onSuccess: () => { + successToast('Successfully updated page order') + queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderName]) + refetchFolderContents() + }, }, ) From 01347fc263c77035c2eafe15c6e9ce7e5e821c8c Mon Sep 17 00:00:00 2001 From: kwajiehao Date: Fri, 26 Mar 2021 04:27:39 +0100 Subject: [PATCH 03/19] feat: standardize output of GET API calls to return resp.data This commit standardizes the output of our GET API functions to return resp.data instead of just the response from the api call. resp.data is a better choice as we are able to use that in dependency arrays, whereas the resp object pointer always changes, which will trigger the useEffect every time even if the object data hasn't actually changed. --- src/api.js | 6 ++++-- src/layouts/EditPage.jsx | 5 +++-- src/layouts/Folders.jsx | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/api.js b/src/api.js index 83ba952bba..6c60bddcb4 100644 --- a/src/api.js +++ b/src/api.js @@ -9,7 +9,8 @@ const BACKEND_URL = process.env.REACT_APP_BACKEND_URL const getDirectoryFile = async (siteName, folderName) => { if (!folderName) return - return await axios.get(`${BACKEND_URL}/sites/${siteName}/collections/${folderName}/pages/collection.yml`); + const resp = await axios.get(`${BACKEND_URL}/sites/${siteName}/collections/${folderName}/pages/collection.yml`); + return resp.data } const setDirectoryFile = async (siteName, folderName, payload) => { @@ -80,7 +81,8 @@ const getEditPageData = async ({folderName, subfolderName, fileName, siteName, r const getCsp = async (siteName) => { // retrieve CSP - return await axios.get(`${process.env.REACT_APP_BACKEND_URL}/sites/${siteName}/netlify-toml`); + const resp = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/sites/${siteName}/netlify-toml`) + return resp.data } const createPageData = async ({folderName, subfolderName, newFileName, siteName, resourceName}, content) => { diff --git a/src/layouts/EditPage.jsx b/src/layouts/EditPage.jsx index 9fc0c5b3fb..983a9d0a3e 100644 --- a/src/layouts/EditPage.jsx +++ b/src/layouts/EditPage.jsx @@ -241,7 +241,7 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => } = pageData const { netlifyTomlHeaderValues - } = cspData.data + } = cspData if (!pageContent) return const { frontMatter: retrievedFrontMatter, mdBody: retrievedMdBody } = frontMatterParser(pageContent); @@ -251,8 +251,9 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => if (isCollectionPage) { const { content: dirContent, - } = dirData.data + } = dirData const { order: parsedFolderContents } = parseDirectoryFile(dirContent) + const parsedFolderContents = parseDirectoryFile(dirContent) // Filter out placeholder files const filteredFolderContents = parsedFolderContents.filter(name => !name.includes('.keep')) generatedLeftNavPages = filteredFolderContents.map((name) => diff --git a/src/layouts/Folders.jsx b/src/layouts/Folders.jsx index 3560f10d6b..bcce0c7cb9 100644 --- a/src/layouts/Folders.jsx +++ b/src/layouts/Folders.jsx @@ -224,6 +224,44 @@ const Folders = ({ match, location }) => { setMoveDropdownQuery({ ...initialMoveDropdownQueryState }); }; + // REORDERING + // save file-reordering + const { mutate: rearrangeFolder } = useMutation( + payload => setDirectoryFile(siteName, folderName, payload), + { + onError: () => errorToast(`Your file reordering could not be saved. ${DEFAULT_RETRY_MSG}`), + onSuccess: () => successToast('Successfully updated page order'), + onSettled: () => setIsRearrangeActive((prevState) => !prevState), + } + ) + + // REORDERING utils + const toggleRearrange = () => { + if (isRearrangeActive) { + // drag and drop complete, save new order + let newFolderOrder + if (subfolderName) { + newFolderOrder = convertSubfolderArray(folderOrderArray, parsedFolderContents, subfolderName) + } else { + newFolderOrder = convertArrayToFolderOrder(folderOrderArray) + } + if (JSON.stringify(newFolderOrder) === JSON.stringify(parsedFolderContents)) { + // no change in file order + setIsRearrangeActive((prevState) => !prevState) + return + } + const updatedDirectoryFile = updateDirectoryFile(folderContents.content, newFolderOrder) + + const payload = { + content: updatedDirectoryFile, + sha: directoryFileSha, + } + rearrangeFolder(payload) // setIsRearrangeActive(false) handled by mutate + } else { + setIsRearrangeActive((prevState) => !prevState) + } + } + return ( <> { From 2d85034b768a7a4f8438172080c063e58fc967c0 Mon Sep 17 00:00:00 2001 From: kwajiehao Date: Fri, 26 Mar 2021 04:35:14 +0100 Subject: [PATCH 04/19] fix: load yaml content when reading directory file --- src/utils.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/utils.js b/src/utils.js index ca6e5ff1dc..7b65f344a4 100644 --- a/src/utils.js +++ b/src/utils.js @@ -611,6 +611,12 @@ export const getObjectDiff = (obj1, obj2) => { } export const parseDirectoryFile = (folderContent) => { + const decodedContent = yaml.safeLoad(folderContent) + const collectionKey = Object.keys(decodedContent.collections)[0] + return decodedContent.collections[collectionKey].order +} + +export const updateDirectoryFile = (folderContent, folderOrder) => { const decodedContent = yaml.parse(folderContent) const collectionKey = Object.keys(decodedContent.collections)[0] return decodedContent.collections[collectionKey] From c9777ecdc90321239535c7a3c25bb86151c12246 Mon Sep 17 00:00:00 2001 From: kwajiehao Date: Fri, 26 Mar 2021 07:10:32 +0100 Subject: [PATCH 05/19] feat: disable useQuery if component tracks local state As per our discussion (refer to meeting minutes here: https://docs.google.com/document/d/1br6T6wVX0KrcA3nwQEo7OhUrcT4veLnaz0vByEXjVvo/edit#heading=h.hyx8t36v9z3n) we will be discussing our `useQuery` functions if there are changes to the local state that are being tracked, to avoid refetching behavior from overwriting local changes. --- src/components/PageSettingsModal.jsx | 15 ++++++--------- src/layouts/EditNavBar.jsx | 23 +++++++++++------------ src/layouts/EditPage.jsx | 23 ++++++++++------------- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index 038cbdf7d4..e9c6a7c086 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -60,8 +60,8 @@ const PageSettingsModal = ({ const [originalFrontMatter, setOriginalFrontMatter] = useState({}) const [sha, setSha] = useState('') const [mdBody, setMdBody] = useState('') - const [siteUrl, setSiteUrl] = useState('https://abc.com.sg') + const [hasChanges, setHasChanges] = useState(false) const { setRedirectToPage } = useRedirectHook() const { retrieveSiteUrl } = useSiteUrlHook() @@ -75,7 +75,7 @@ const PageSettingsModal = ({ [PAGE_SETTINGS_KEY, originalPageName], async () => await getPage(pageType, siteName, folderName, originalPageName), { - enabled: !isNewPage, + enabled: !(isNewPage || hasChanges), // disable if new page or if there are changes retry: false, onSuccess: ({ content, sha }) => { const { frontMatter, mdBody } = frontMatterParser(content) @@ -90,11 +90,6 @@ const PageSettingsModal = ({ setIsPageSettingsActive(false) errorToast(`The page data could not be retrieved. ${DEFAULT_RETRY_MSG}`) }, - cacheTime: 0, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - refetchInterval: false, - refetchIntervalInBackground: false, } ) @@ -170,8 +165,10 @@ const PageSettingsModal = ({ }, [errors]) useEffect(() => { - setHasChanges(!isNewPage && !(originalPageName === generatePageFileName(title) && originalPermalink === permalink)) - }, [title, permalink]) + if (title && permalink) { + setHasChanges(!isNewPage && !(title === deslugifyPage(originalPageName) && permalink === originalPermalink)) + } + }, [originalPageName, originalPermalink, title, permalink]) const changeHandler = (event) => { const { id, value } = event.target; diff --git a/src/layouts/EditNavBar.jsx b/src/layouts/EditNavBar.jsx index 3042a20b04..f201cb9bfc 100644 --- a/src/layouts/EditNavBar.jsx +++ b/src/layouts/EditNavBar.jsx @@ -63,6 +63,8 @@ const EditNavBar = ({ match }) => { const [showDeletedText, setShowDeletedText] = useState(true) const [deletedLinks, setDeletedLinks] = useState('') + const [hasChanges, setHasChanges] = useState(false) + const LinkCollectionSectionConstructor = () => ({ title: 'Menu Title', collection: collections[0], @@ -118,6 +120,7 @@ const EditNavBar = ({ match }) => { [NAVIGATION_CONTENT_KEY, siteName], () => getEditNavBarData(siteName), { + enabled: !hasChanges, retry: false, cacheTime: 0, // We want to refetch data on every page load because file order may have changed onError: (err) => { @@ -127,10 +130,6 @@ const EditNavBar = ({ match }) => { errorToast(`There was a problem trying to load your data. ${DEFAULT_RETRY_MSG}`) } }, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - refetchInterval: false, - refetchIntervalInBackground: false, }, ); @@ -219,6 +218,13 @@ const EditNavBar = ({ match }) => { } }, [navigationContents]) + useEffect(() => { + setHasChanges(JSON.stringify(originalNav) !== JSON.stringify({ + ...originalNav, + links: links + })) + }, [originalNav, links]) + const onFieldChange = async (event) => { try { const { id, value } = event.target; @@ -580,13 +586,6 @@ const EditNavBar = ({ match }) => { } } - const hasChanges = () => { - return JSON.stringify(originalNav) !== JSON.stringify({ - ...originalNav, - links: links - }) - } - const hasErrors = () => { return !isEmpty(errors.links) || !isEmpty(errors.sublinks) } @@ -615,7 +614,7 @@ const EditNavBar = ({ match }) => {
const [isCspViolation, setIsCspViolation] = useState(false) const [chunk, setChunk] = useState('') + const [hasChanges, setHasChanges] = useState(false) + const mdeRef = useRef() // get page data @@ -132,6 +134,7 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => [PAGE_CONTENT_KEY, match.params], () => getEditPageData(match.params), { + enabled: !hasChanges, retry: false, onError: (err) => { if (err.response && err.response.status === 404) { @@ -140,10 +143,6 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => errorToast(`There was a problem trying to load your page. ${DEFAULT_RETRY_MSG}`) } }, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - refetchInterval: false, - refetchIntervalInBackground: false, }, ); @@ -152,6 +151,7 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => [DIR_CONTENT_KEY, siteName, folderName, subfolderName], () => getDirectoryFile(siteName, folderName), { + enabled: !hasChanges, retry: false, onError: (err) => { if (err.response && err.response.status === 404) { @@ -160,10 +160,6 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => errorToast(`There was a problem trying to load your page. ${DEFAULT_RETRY_MSG}`) } }, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - refetchInterval: false, - refetchIntervalInBackground: false, }, ); @@ -172,6 +168,7 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => [CSP_CONTENT_KEY, siteName], () => getCsp(siteName), { + enabled: !hasChanges, retry: false, onError: (err) => { if (err.response && err.response.status === 404) { @@ -180,10 +177,6 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => errorToast(`There was a problem trying to load your page. ${DEFAULT_RETRY_MSG}`) } }, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - refetchInterval: false, - refetchIntervalInBackground: false, }, ); @@ -290,6 +283,10 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => setChunk(processedChunk) }, [editorValue]) + useEffect(() => { + setHasChanges(originalMdValue === editorValue) + }, [originalMdValue, editorValue]) + const onEditorChange = (value) => { setEditorValue(value); } @@ -370,7 +367,7 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) =>
Date: Thu, 1 Apr 2021 11:29:56 +0800 Subject: [PATCH 06/19] fix: rebase errors --- src/components/PageSettingsModal.jsx | 25 +------------------------ src/layouts/Folders.jsx | 10 +++++----- src/utils.js | 2 +- 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index e9c6a7c086..13eba219ce 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -13,7 +13,7 @@ import { deslugifyDirectory, } from '../utils'; -import { getPage, createPageData, updatePageData, renamePageData } from '../api' +import { createPageData, updatePageData, renamePageData } from '../api' import { PAGE_SETTINGS_KEY } from '../constants' import elementStyles from '../styles/isomer-cms/Elements.module.scss'; @@ -62,7 +62,6 @@ const PageSettingsModal = ({ const [mdBody, setMdBody] = useState('') const [siteUrl, setSiteUrl] = useState('https://abc.com.sg') const [hasChanges, setHasChanges] = useState(false) - const { setRedirectToPage } = useRedirectHook() const { retrieveSiteUrl } = useSiteUrlHook() @@ -71,28 +70,6 @@ const PageSettingsModal = ({ permalink: setPermalink, } - const {} = useQuery( - [PAGE_SETTINGS_KEY, originalPageName], - async () => await getPage(pageType, siteName, folderName, originalPageName), - { - enabled: !(isNewPage || hasChanges), // disable if new page or if there are changes - retry: false, - onSuccess: ({ content, sha }) => { - const { frontMatter, mdBody } = frontMatterParser(content) - setTitle(deslugifyPage(originalPageName)) - setPermalink(frontMatter.permalink) - setOriginalPermalink(frontMatter.permalink) - setSha(sha) - setMdBody(mdBody) - }, - onError: () => { - setSelectedPage('') - setIsPageSettingsActive(false) - errorToast(`The page data could not be retrieved. ${DEFAULT_RETRY_MSG}`) - }, - } - ) - const { mutateAsync: saveHandler } = useMutation( () => { const frontMatter = subfolderName diff --git a/src/layouts/Folders.jsx b/src/layouts/Folders.jsx index bcce0c7cb9..3859d8f8ac 100644 --- a/src/layouts/Folders.jsx +++ b/src/layouts/Folders.jsx @@ -91,10 +91,10 @@ const Folders = ({ match, location }) => { // parse contents of current folder directory useEffect(() => { - if (folderContents && folderContents.data) { - const { order: directoryFileOrder, output: directoryFileOutput } = parseDirectoryFile(folderContents.data.content) - setDirectoryFileSha(folderContents.data.sha) - setParsedFolderContents(directoryFileOrder) + if (folderContents && folderContents.sha) { + const parsedFolderContents = parseDirectoryFile(folderContents.content) + setDirectoryFileSha(folderContents.sha) + setParsedFolderContents(parsedFolderContents) setIsFolderLive(directoryFileOutput) if (subfolderName) { @@ -109,6 +109,7 @@ const Folders = ({ match, location }) => { setFolderOrderArray(convertFolderOrderToArray(directoryFileOrder)) } } + }, [folderContents, subfolderName]) // set selected item type @@ -131,7 +132,6 @@ const Folders = ({ match, location }) => { errorToast(`The page data could not be retrieved. ${DEFAULT_RETRY_MSG}`) }, onSuccess: () => { - successToast('Successfully updated page order') queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderName]) refetchFolderContents() }, diff --git a/src/utils.js b/src/utils.js index 7b65f344a4..9fe25f7c77 100644 --- a/src/utils.js +++ b/src/utils.js @@ -611,7 +611,7 @@ export const getObjectDiff = (obj1, obj2) => { } export const parseDirectoryFile = (folderContent) => { - const decodedContent = yaml.safeLoad(folderContent) + const decodedContent = yaml.parse(folderContent) const collectionKey = Object.keys(decodedContent.collections)[0] return decodedContent.collections[collectionKey].order } From 21bb7f45cf8bd4168a1e826825a767e61010097d Mon Sep 17 00:00:00 2001 From: kwajiehao Date: Thu, 1 Apr 2021 11:39:38 +0800 Subject: [PATCH 07/19] fix: invocation of LoginContext --- src/components/Header.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 719970531c..7ee9891a47 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -17,6 +17,7 @@ const Header = ({ }) => { const { setRedirectToLogout, setRedirectToPage } = useRedirectHook() const { retrieveStagingUrl } = useSiteUrlHook() + const { setLogoutState } = useContext(LoginContext) const [showBackNavWarningModal, setShowBackNavWarningModal] = useState(false) const [showStagingWarningModal, setShowStagingWarningModal] = useState(false) From 4893f59f276b3ffc70910ea25b4148cb4618d778 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 28 Apr 2021 17:49:24 +0800 Subject: [PATCH 08/19] Fix: rebase errors --- src/components/CollectionPagesSection.jsx | 2 +- src/components/Header.jsx | 1 - src/components/PageSettingsModal.jsx | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/CollectionPagesSection.jsx b/src/components/CollectionPagesSection.jsx index d03b5b51d9..960696b4bd 100644 --- a/src/components/CollectionPagesSection.jsx +++ b/src/components/CollectionPagesSection.jsx @@ -95,7 +95,7 @@ const CollectionPagesSection = ({ collectionName, pages, siteName, isResource, r return [] } if (folderName !== '' && querySubfolders) { // inside folder, show all subfolders - const { order: parsedFolderContents } = parseDirectoryFile(querySubfolders.data.content) + const { order: parsedFolderContents } = parseDirectoryFile(querySubfolders.content) const parsedFolderArray = convertFolderOrderToArray(parsedFolderContents) return parsedFolderArray.filter(file => file.type === 'dir').map(file => file.fileName) } diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 7ee9891a47..719970531c 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -17,7 +17,6 @@ const Header = ({ }) => { const { setRedirectToLogout, setRedirectToPage } = useRedirectHook() const { retrieveStagingUrl } = useSiteUrlHook() - const { setLogoutState } = useContext(LoginContext) const [showBackNavWarningModal, setShowBackNavWarningModal] = useState(false) const [showStagingWarningModal, setShowStagingWarningModal] = useState(false) diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index 13eba219ce..c6808a9a99 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -61,7 +61,6 @@ const PageSettingsModal = ({ const [sha, setSha] = useState('') const [mdBody, setMdBody] = useState('') const [siteUrl, setSiteUrl] = useState('https://abc.com.sg') - const [hasChanges, setHasChanges] = useState(false) const { setRedirectToPage } = useRedirectHook() const { retrieveSiteUrl } = useSiteUrlHook() From 78655619b2d3bb75fc2febe77921d515e5c6f4e1 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 28 Apr 2021 17:55:07 +0800 Subject: [PATCH 09/19] Fix: update resource category and resource page get calls to return data directly --- src/api.js | 8 ++++++-- src/layouts/CategoryPages.jsx | 2 +- src/layouts/Resources.jsx | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/api.js b/src/api.js index 6c60bddcb4..a884c7cb12 100644 --- a/src/api.js +++ b/src/api.js @@ -163,7 +163,9 @@ const getAllCategories = async ({siteName, isResource}) => { } const getAllResourceCategories = async (siteName) => { - return await axios.get(`${BACKEND_URL}/sites/${siteName}/resources`); + const apiEndpoint = `${BACKEND_URL}/sites/${siteName}/resources` + const resp = await axios.get(apiEndpoint) + return resp.data; } const addResourceCategory = async (siteName, resourceName) => { @@ -179,7 +181,9 @@ const getPages = async ({ siteName }) => { const getResourcePages = async (siteName, resourceName) => { if (!resourceName) return - return await axios.get(`${BACKEND_URL}/sites/${siteName}/resources/${resourceName}`); + const apiEndpoint = `${BACKEND_URL}/sites/${siteName}/resources/${resourceName}` + const resp = await axios.get(apiEndpoint) + return resp.data; } // EditNavBar diff --git a/src/layouts/CategoryPages.jsx b/src/layouts/CategoryPages.jsx index 288d0bd859..2caf1da789 100644 --- a/src/layouts/CategoryPages.jsx +++ b/src/layouts/CategoryPages.jsx @@ -64,7 +64,7 @@ const CategoryPages = ({ match, location, isResource }) => { const fetchData = async () => { if (isResource) { if (!resourcePagesResp) return - const { resourcePages } = resourcePagesResp.data; + const { resourcePages } = resourcePagesResp; if (resourcePages.length > 0) { const retrievedResourcePages = resourcePages.map((resourcePage) => { diff --git a/src/layouts/Resources.jsx b/src/layouts/Resources.jsx index 747bc63af6..f5063e042f 100644 --- a/src/layouts/Resources.jsx +++ b/src/layouts/Resources.jsx @@ -71,7 +71,7 @@ const Resources = ({ match, location }) => { try { // Get the categories in the resource room if (!resourcesResp) return - const { resourceRoomName, resources: resourceCategories } = resourcesResp.data; + const { resourceRoomName, resources: resourceCategories } = resourcesResp; if (resourceRoomName) { const uniqueResourceFolderNames = resourceCategories ? _.uniq(resourceCategories.map((file) => file.dirName)) : [] if (_isMounted) { From 8a7b14b21fb2d3db54b1e8f1867bf270a8a0404d Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 28 Apr 2021 18:08:26 +0800 Subject: [PATCH 10/19] Refactor: use invalidateQueries instead of passing refetch function for CollectionPagesSection --- src/components/CollectionPagesSection.jsx | 19 +++++++++++++------ src/layouts/CategoryPages.jsx | 3 +-- src/layouts/Workspace.jsx | 1 - 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/components/CollectionPagesSection.jsx b/src/components/CollectionPagesSection.jsx index 960696b4bd..faf7058214 100644 --- a/src/components/CollectionPagesSection.jsx +++ b/src/components/CollectionPagesSection.jsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import axios from 'axios'; -import { useQuery, useMutation } from 'react-query'; +import { useQuery, useMutation, useQueryClient } from 'react-query'; import PropTypes from 'prop-types'; import _ from 'lodash'; @@ -8,6 +8,7 @@ import { PAGE_CONTENT_KEY, FOLDERS_CONTENT_KEY, DIR_CONTENT_KEY, + RESOURCE_CATEGORY_CONTENT_KEY, } from '../constants' import { getEditPageData, deletePageData, getAllCategories, moveFile, getDirectoryFile } from '../api' @@ -31,8 +32,8 @@ import contentStyles from '../styles/isomer-cms/pages/Content.module.scss'; axios.defaults.withCredentials = true // Clean up note: Should be renamed, only used for resource pages and unlinked pages sections -const CollectionPagesSection = ({ collectionName, pages, siteName, isResource, refetchPages }) => { - +const CollectionPagesSection = ({ collectionName, pages, siteName, isResource }) => { + const queryClient = useQueryClient() const initialMoveDropdownQueryState = { folderName: '', subfolderName: '', @@ -114,7 +115,12 @@ const CollectionPagesSection = ({ collectionName, pages, siteName, isResource, r async () => await deletePageData({ siteName, fileName: selectedFile, resourceName: collectionName }, pageData.pageSha), { onError: () => errorToast(`Your file could not be deleted successfully. ${DEFAULT_RETRY_MSG}`), - onSuccess: () => {successToast('Successfully deleted file'); refetchPages();}, + onSuccess: () => { + setSelectedFile('') + if (isResource) queryClient.invalidateQueries([RESOURCE_CATEGORY_CONTENT_KEY, siteName, collectionName, true]) + else queryClient.invalidateQueries([PAGE_CONTENT_KEY, { siteName }]) + successToast('Successfully deleted file') + }, onSettled: () => setCanShowDeleteWarningModal((prevState) => !prevState), } ) @@ -128,8 +134,10 @@ const CollectionPagesSection = ({ collectionName, pages, siteName, isResource, r onError: () => errorToast(`Your file could not be moved successfully. ${DEFAULT_RETRY_MSG}`), onSuccess: (samePage) => { if (samePage) return successToast('Page is already in this folder') + setSelectedFile('') + if (isResource) queryClient.invalidateQueries([RESOURCE_CATEGORY_CONTENT_KEY, siteName, collectionName, true]) + else queryClient.invalidateQueries([PAGE_CONTENT_KEY, { siteName }]) successToast('Successfully moved file') - refetchPages() }, onSettled: () => setCanShowMoveModal(prevState => !prevState), } @@ -246,5 +254,4 @@ CollectionPagesSection.propTypes = { ), siteName: PropTypes.string.isRequired, isResource: PropTypes.bool, - refetchPages: PropTypes.func.isRequired, }; diff --git a/src/layouts/CategoryPages.jsx b/src/layouts/CategoryPages.jsx index 2caf1da789..949d59ac27 100644 --- a/src/layouts/CategoryPages.jsx +++ b/src/layouts/CategoryPages.jsx @@ -43,7 +43,7 @@ const CategoryPages = ({ match, location, isResource }) => { const [categoryPages, setCategoryPages] = useState() - const { data: resourcePagesResp, refetch: refetchPages } = useQuery( + const { data: resourcePagesResp } = useQuery( [RESOURCE_CATEGORY_CONTENT_KEY, siteName, collectionName, isResource], () => getResourcePages(siteName, collectionName), { @@ -123,7 +123,6 @@ const CategoryPages = ({ match, location, isResource }) => { pages={categoryPages} siteName={siteName} isResource={isResource} - refetchPages={refetchPages} /> {/* main section ends here */} diff --git a/src/layouts/Workspace.jsx b/src/layouts/Workspace.jsx index b7e2d1c0a0..08e7141e46 100644 --- a/src/layouts/Workspace.jsx +++ b/src/layouts/Workspace.jsx @@ -209,7 +209,6 @@ const Workspace = ({ match, location }) => { {/* main section ends here */} From d58c7288a7481f8de5e67c9403d46fd20051116a Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 15:21:48 +0800 Subject: [PATCH 11/19] Fix: error when retrieving page settings --- src/layouts/Folders.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/Folders.jsx b/src/layouts/Folders.jsx index 3859d8f8ac..aee0990f50 100644 --- a/src/layouts/Folders.jsx +++ b/src/layouts/Folders.jsx @@ -209,7 +209,7 @@ const Folders = ({ match, location }) => { return [] } if (folderName !== '' && querySubfolders) { // inside folder, show all subfolders - const { order: parsedFolderContents } = parseDirectoryFile(querySubfolders.data.content) + const { order: parsedFolderContents } = parseDirectoryFile(querySubfolders.content) const parsedFolderArray = convertFolderOrderToArray(parsedFolderContents) return parsedFolderArray.filter(file => file.type === 'dir').map(file => file.fileName) } From 61ea02768be10bef1e283974893db4988c509331 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 15:47:09 +0800 Subject: [PATCH 12/19] Fix: rebase errors --- src/layouts/EditPage.jsx | 1 - src/layouts/Folders.jsx | 42 ++-------------------------------------- src/utils.js | 6 ------ 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/src/layouts/EditPage.jsx b/src/layouts/EditPage.jsx index f2adb1beb1..75288ea525 100644 --- a/src/layouts/EditPage.jsx +++ b/src/layouts/EditPage.jsx @@ -246,7 +246,6 @@ const EditPage = ({ match, isResourcePage, isCollectionPage, history, type }) => content: dirContent, } = dirData const { order: parsedFolderContents } = parseDirectoryFile(dirContent) - const parsedFolderContents = parseDirectoryFile(dirContent) // Filter out placeholder files const filteredFolderContents = parsedFolderContents.filter(name => !name.includes('.keep')) generatedLeftNavPages = filteredFolderContents.map((name) => diff --git a/src/layouts/Folders.jsx b/src/layouts/Folders.jsx index aee0990f50..080bfb668e 100644 --- a/src/layouts/Folders.jsx +++ b/src/layouts/Folders.jsx @@ -92,9 +92,9 @@ const Folders = ({ match, location }) => { // parse contents of current folder directory useEffect(() => { if (folderContents && folderContents.sha) { - const parsedFolderContents = parseDirectoryFile(folderContents.content) + const { order: directoryFileOrder, output: directoryFileOutput } = parseDirectoryFile(folderContents.content) setDirectoryFileSha(folderContents.sha) - setParsedFolderContents(parsedFolderContents) + setParsedFolderContents(directoryFileOrder) setIsFolderLive(directoryFileOutput) if (subfolderName) { @@ -224,44 +224,6 @@ const Folders = ({ match, location }) => { setMoveDropdownQuery({ ...initialMoveDropdownQueryState }); }; - // REORDERING - // save file-reordering - const { mutate: rearrangeFolder } = useMutation( - payload => setDirectoryFile(siteName, folderName, payload), - { - onError: () => errorToast(`Your file reordering could not be saved. ${DEFAULT_RETRY_MSG}`), - onSuccess: () => successToast('Successfully updated page order'), - onSettled: () => setIsRearrangeActive((prevState) => !prevState), - } - ) - - // REORDERING utils - const toggleRearrange = () => { - if (isRearrangeActive) { - // drag and drop complete, save new order - let newFolderOrder - if (subfolderName) { - newFolderOrder = convertSubfolderArray(folderOrderArray, parsedFolderContents, subfolderName) - } else { - newFolderOrder = convertArrayToFolderOrder(folderOrderArray) - } - if (JSON.stringify(newFolderOrder) === JSON.stringify(parsedFolderContents)) { - // no change in file order - setIsRearrangeActive((prevState) => !prevState) - return - } - const updatedDirectoryFile = updateDirectoryFile(folderContents.content, newFolderOrder) - - const payload = { - content: updatedDirectoryFile, - sha: directoryFileSha, - } - rearrangeFolder(payload) // setIsRearrangeActive(false) handled by mutate - } else { - setIsRearrangeActive((prevState) => !prevState) - } - } - return ( <> { diff --git a/src/utils.js b/src/utils.js index 9fe25f7c77..ca6e5ff1dc 100644 --- a/src/utils.js +++ b/src/utils.js @@ -611,12 +611,6 @@ export const getObjectDiff = (obj1, obj2) => { } export const parseDirectoryFile = (folderContent) => { - const decodedContent = yaml.parse(folderContent) - const collectionKey = Object.keys(decodedContent.collections)[0] - return decodedContent.collections[collectionKey].order -} - -export const updateDirectoryFile = (folderContent, folderOrder) => { const decodedContent = yaml.parse(folderContent) const collectionKey = Object.keys(decodedContent.collections)[0] return decodedContent.collections[collectionKey] From 08e74210d3924b2285cbd144295af2742ca36275 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 16:21:26 +0800 Subject: [PATCH 13/19] Fix: invalidate query instead of reload when changing page settings --- src/components/ComponentSettingsModal.jsx | 15 +++++++++------ src/components/PageSettingsModal.jsx | 7 +++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/components/ComponentSettingsModal.jsx b/src/components/ComponentSettingsModal.jsx index 2ac6ec68d2..dcf04b54db 100644 --- a/src/components/ComponentSettingsModal.jsx +++ b/src/components/ComponentSettingsModal.jsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { useMutation } from 'react-query'; +import { useMutation, useQueryClient } from 'react-query'; import axios from 'axios'; import PropTypes from 'prop-types'; import * as _ from 'lodash'; @@ -8,6 +8,7 @@ import FormField from './FormField'; import FormFieldHorizontal from './FormFieldHorizontal'; import ResourceFormFields from './ResourceFormFields'; import SaveDeleteButtons from './SaveDeleteButtons'; +import { RESOURCE_CATEGORY_CONTENT_KEY } from '../constants' import useSiteUrlHook from '../hooks/useSiteUrlHook'; import useRedirectHook from '../hooks/useRedirectHook'; @@ -41,6 +42,9 @@ const ComponentSettingsModal = ({ setSelectedFile, setIsComponentSettingsActive, }) => { + // Instantiate queryClient + const queryClient = useQueryClient() + const { setRedirectToPage } = useRedirectHook() const { retrieveSiteUrl } = useSiteUrlHook() @@ -54,7 +58,6 @@ const ComponentSettingsModal = ({ const [hasErrors, setHasErrors] = useState(false) // Base hooks - const [baseApiUrl, setBaseApiUrl] = useState(''); const [title, setTitle] = useState('') const [permalink, setPermalink] = useState('') const [mdBody, setMdBody] = useState('') @@ -72,9 +75,6 @@ const ComponentSettingsModal = ({ const [siteUrl, setSiteUrl] = useState('https://abc.com.sg') - // Page redirection modals - const [canShowDeleteWarningModal, setCanShowDeleteWarningModal] = useState(false) - // Map element ID to setter functions const idToSetterFuncMap = { title: setTitle, @@ -176,7 +176,10 @@ const ComponentSettingsModal = ({ }, { onSettled: () => {setSelectedFile(''); setIsComponentSettingsActive(false)}, - onSuccess: (redirectUrl) => redirectUrl && isPost ? setRedirectToPage(redirectUrl) : window.location.reload(), + onSuccess: (redirectUrl) => { + queryClient.invalidateQueries([RESOURCE_CATEGORY_CONTENT_KEY, siteName, category, true]) + if (redirectUrl && isPost) setRedirectToPage(redirectUrl) + }, onError: () => errorToast(`${isNewFile ? 'A new resource page could not be created.' : 'Your resource page settings could not be saved.'} ${DEFAULT_RETRY_MSG}`) } ) diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index c6808a9a99..f8de22698a 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; -import { useQuery, useMutation, useQueryClient } from 'react-query'; +import { useMutation, useQueryClient } from 'react-query'; import axios from 'axios'; import * as _ from 'lodash'; @@ -14,7 +14,7 @@ import { } from '../utils'; import { createPageData, updatePageData, renamePageData } from '../api' -import { PAGE_SETTINGS_KEY } from '../constants' +import { PAGE_SETTINGS_KEY, DIR_CONTENT_KEY } from '../constants' import elementStyles from '../styles/isomer-cms/Elements.module.scss'; @@ -83,9 +83,8 @@ const PageSettingsModal = ({ onSettled: () => {setSelectedPage(''); setIsPageSettingsActive(false)}, onSuccess: (redirectUrl) => { queryClient.invalidateQueries([PAGE_SETTINGS_KEY, originalPageName]) - + queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderName, subfolderName]) if (redirectUrl) setRedirectToPage(redirectUrl) - else window.location.reload() }, onError: () => errorToast(`${isNewPage ? 'A new page could not be created.' : 'Your page settings could not be saved.'} ${DEFAULT_RETRY_MSG}`) } From 2ad447a7f0478a20fa29eca0dcf1214ca9c6dc35 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 16:48:45 +0800 Subject: [PATCH 14/19] Feat: add success toast when changing settings --- src/components/ComponentSettingsModal.jsx | 3 ++- src/components/PageSettingsModal.jsx | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/ComponentSettingsModal.jsx b/src/components/ComponentSettingsModal.jsx index dcf04b54db..7870f8dcda 100644 --- a/src/components/ComponentSettingsModal.jsx +++ b/src/components/ComponentSettingsModal.jsx @@ -25,7 +25,7 @@ import { import { createPageData, updatePageData, renamePageData } from '../api' import { validateResourceSettings } from '../utils/validators'; -import { errorToast } from '../utils/toasts'; +import { errorToast, successToast } from '../utils/toasts'; import elementStyles from '../styles/isomer-cms/Elements.module.scss'; @@ -179,6 +179,7 @@ const ComponentSettingsModal = ({ onSuccess: (redirectUrl) => { queryClient.invalidateQueries([RESOURCE_CATEGORY_CONTENT_KEY, siteName, category, true]) if (redirectUrl && isPost) setRedirectToPage(redirectUrl) + else successToast(`Successfully updated ${title.toLowerCase()}!`) }, onError: () => errorToast(`${isNewFile ? 'A new resource page could not be created.' : 'Your resource page settings could not be saved.'} ${DEFAULT_RETRY_MSG}`) } diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index f8de22698a..d1db61bd0f 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -14,12 +14,12 @@ import { } from '../utils'; import { createPageData, updatePageData, renamePageData } from '../api' -import { PAGE_SETTINGS_KEY, DIR_CONTENT_KEY } from '../constants' +import { PAGE_SETTINGS_KEY, DIR_CONTENT_KEY, PAGE_CONTENT_KEY } from '../constants' import elementStyles from '../styles/isomer-cms/Elements.module.scss'; import { validatePageSettings } from '../utils/validators'; -import { errorToast } from '../utils/toasts'; +import { errorToast, successToast } from '../utils/toasts'; import FormField from './FormField'; import FormFieldHorizontal from './FormFieldHorizontal'; @@ -83,8 +83,12 @@ const PageSettingsModal = ({ onSettled: () => {setSelectedPage(''); setIsPageSettingsActive(false)}, onSuccess: (redirectUrl) => { queryClient.invalidateQueries([PAGE_SETTINGS_KEY, originalPageName]) - queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderName, subfolderName]) if (redirectUrl) setRedirectToPage(redirectUrl) + else { + if (folderName) queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderName, subfolderName]) + else queryClient.invalidateQueries([PAGE_CONTENT_KEY, { siteName }]) + successToast(`Successfully updated ${title.toLowerCase()}!`) + } }, onError: () => errorToast(`${isNewPage ? 'A new page could not be created.' : 'Your page settings could not be saved.'} ${DEFAULT_RETRY_MSG}`) } From b38a98ebaee0aaea60089b093d6fdf7aec44f936 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 16:49:03 +0800 Subject: [PATCH 15/19] Fix: change folder naming to use invalidation instead of reload --- src/components/FolderModal.jsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/FolderModal.jsx b/src/components/FolderModal.jsx index e143f6015a..e3800fd157 100644 --- a/src/components/FolderModal.jsx +++ b/src/components/FolderModal.jsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import axios from 'axios'; import PropTypes from 'prop-types'; -import { useMutation } from 'react-query'; +import { useMutation, useQueryClient } from 'react-query'; import elementStyles from '../styles/isomer-cms/Elements.module.scss'; import SaveDeleteButtons from './SaveDeleteButtons'; import FormField from './FormField'; @@ -20,6 +20,7 @@ import { import { validateCategoryName } from '../utils/validators' import { errorToast } from '../utils/toasts'; +import { DIR_CONTENT_KEY, FOLDERS_CONTENT_KEY, RESOURCE_CATEGORY_CONTENT_KEY } from '../constants'; // axios settings axios.defaults.withCredentials = true @@ -54,6 +55,8 @@ const selectRenameApiCall = (isCollection, siteName, folderOrCategoryName, subfo } const FolderModal = ({ displayTitle, displayText, onClose, folderOrCategoryName, subfolderName, siteName, isCollection, existingFolders }) => { + // Instantiate queryClient + const queryClient = useQueryClient() const [newDirectoryName, setNewDirectoryName] = useState(deslugifyDirectory(subfolderName || folderOrCategoryName)) const [errors, setErrors] = useState('') @@ -62,7 +65,18 @@ const FolderModal = ({ displayTitle, displayText, onClose, folderOrCategoryName, () => selectRenameApiCall(isCollection, siteName, folderOrCategoryName, subfolderName, newDirectoryName), { onError: () => errorToast(`There was a problem trying to rename this folder. ${DEFAULT_RETRY_MSG}`), - onSuccess: () => window.location.reload(), + onSuccess: () => { + if (!isCollection) { + // Resource folder + queryClient.invalidateQueries([RESOURCE_CATEGORY_CONTENT_KEY, siteName]) + } else if (subfolderName) { + // Collection subfolder + queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderOrCategoryName, undefined]) + } else { + queryClient.invalidateQueries([FOLDERS_CONTENT_KEY, { siteName, isResource: false }]) + } + onClose() + }, }, ) From f34f7639edbd1ddfc0f8a70cfb577d54db89af0f Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 17:09:02 +0800 Subject: [PATCH 16/19] Fix: invalidate correct resource folder key --- src/components/FolderModal.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/FolderModal.jsx b/src/components/FolderModal.jsx index e3800fd157..df7fe91a26 100644 --- a/src/components/FolderModal.jsx +++ b/src/components/FolderModal.jsx @@ -19,8 +19,8 @@ import { } from '../utils' import { validateCategoryName } from '../utils/validators' -import { errorToast } from '../utils/toasts'; -import { DIR_CONTENT_KEY, FOLDERS_CONTENT_KEY, RESOURCE_CATEGORY_CONTENT_KEY } from '../constants'; +import { errorToast, successToast } from '../utils/toasts'; +import { DIR_CONTENT_KEY, FOLDERS_CONTENT_KEY, RESOURCE_ROOM_CONTENT_KEY } from '../constants'; // axios settings axios.defaults.withCredentials = true From 2a1852f158cd9420d1f300482ce57220487bd9ba Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 17:09:46 +0800 Subject: [PATCH 17/19] Fix: update success toast messages --- src/components/ComponentSettingsModal.jsx | 2 +- src/components/FolderModal.jsx | 4 +++- src/components/PageSettingsModal.jsx | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/ComponentSettingsModal.jsx b/src/components/ComponentSettingsModal.jsx index 7870f8dcda..fbc13403e2 100644 --- a/src/components/ComponentSettingsModal.jsx +++ b/src/components/ComponentSettingsModal.jsx @@ -179,7 +179,7 @@ const ComponentSettingsModal = ({ onSuccess: (redirectUrl) => { queryClient.invalidateQueries([RESOURCE_CATEGORY_CONTENT_KEY, siteName, category, true]) if (redirectUrl && isPost) setRedirectToPage(redirectUrl) - else successToast(`Successfully updated ${title.toLowerCase()}!`) + else successToast(`Successfully updated file settings!`) }, onError: () => errorToast(`${isNewFile ? 'A new resource page could not be created.' : 'Your resource page settings could not be saved.'} ${DEFAULT_RETRY_MSG}`) } diff --git a/src/components/FolderModal.jsx b/src/components/FolderModal.jsx index df7fe91a26..53b43bb856 100644 --- a/src/components/FolderModal.jsx +++ b/src/components/FolderModal.jsx @@ -68,7 +68,8 @@ const FolderModal = ({ displayTitle, displayText, onClose, folderOrCategoryName, onSuccess: () => { if (!isCollection) { // Resource folder - queryClient.invalidateQueries([RESOURCE_CATEGORY_CONTENT_KEY, siteName]) + console.log('hey') + queryClient.invalidateQueries([RESOURCE_ROOM_CONTENT_KEY, siteName]) } else if (subfolderName) { // Collection subfolder queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderOrCategoryName, undefined]) @@ -76,6 +77,7 @@ const FolderModal = ({ displayTitle, displayText, onClose, folderOrCategoryName, queryClient.invalidateQueries([FOLDERS_CONTENT_KEY, { siteName, isResource: false }]) } onClose() + successToast(`Successfully renamed folder!`) }, }, ) diff --git a/src/components/PageSettingsModal.jsx b/src/components/PageSettingsModal.jsx index d1db61bd0f..687c98b238 100644 --- a/src/components/PageSettingsModal.jsx +++ b/src/components/PageSettingsModal.jsx @@ -87,7 +87,7 @@ const PageSettingsModal = ({ else { if (folderName) queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderName, subfolderName]) else queryClient.invalidateQueries([PAGE_CONTENT_KEY, { siteName }]) - successToast(`Successfully updated ${title.toLowerCase()}!`) + successToast(`Successfully updated page settings!`) } }, onError: () => errorToast(`${isNewPage ? 'A new page could not be created.' : 'Your page settings could not be saved.'} ${DEFAULT_RETRY_MSG}`) From 6ad1ba36be8bd15f142a8b692895dc71c0794648 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 17:25:02 +0800 Subject: [PATCH 18/19] Fix: remove log statement --- src/components/FolderModal.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/FolderModal.jsx b/src/components/FolderModal.jsx index 53b43bb856..b116ad4d76 100644 --- a/src/components/FolderModal.jsx +++ b/src/components/FolderModal.jsx @@ -68,7 +68,6 @@ const FolderModal = ({ displayTitle, displayText, onClose, folderOrCategoryName, onSuccess: () => { if (!isCollection) { // Resource folder - console.log('hey') queryClient.invalidateQueries([RESOURCE_ROOM_CONTENT_KEY, siteName]) } else if (subfolderName) { // Collection subfolder From ba2f9301912e5c3822abd339f977d6301fae7f0e Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 29 Apr 2021 17:26:49 +0800 Subject: [PATCH 19/19] Fix: add successtoast --- src/layouts/Folders.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layouts/Folders.jsx b/src/layouts/Folders.jsx index 080bfb668e..44b5af1d5b 100644 --- a/src/layouts/Folders.jsx +++ b/src/layouts/Folders.jsx @@ -132,6 +132,7 @@ const Folders = ({ match, location }) => { errorToast(`The page data could not be retrieved. ${DEFAULT_RETRY_MSG}`) }, onSuccess: () => { + successToast(`Successfully updated ${isSelectedItemPage ? 'file' : 'subfolder'}`) queryClient.invalidateQueries([DIR_CONTENT_KEY, siteName, folderName]) refetchFolderContents() },