diff --git a/app/client/src/actions/evaluationActions.ts b/app/client/src/actions/evaluationActions.ts index 8493ca3fd3..67f5f922d3 100644 --- a/app/client/src/actions/evaluationActions.ts +++ b/app/client/src/actions/evaluationActions.ts @@ -11,14 +11,12 @@ import { QueryActionConfig } from "entities/Action"; export const FIRST_EVAL_REDUX_ACTIONS = [ // Pages - // ReduxActionTypes.FETCH_PAGE_SUCCESS, - // ReduxActionTypes.FETCH_PUBLISHED_PAGE_SUCCESS, ReduxActionTypes.FETCH_ALL_PAGE_ENTITY_COMPLETION, ]; + export const EVALUATE_REDUX_ACTIONS = [ ...FIRST_EVAL_REDUX_ACTIONS, // Actions - ReduxActionTypes.FETCH_PLUGIN_AND_JS_ACTIONS_SUCCESS, ReduxActionTypes.FETCH_PLUGIN_FORM_CONFIGS_SUCCESS, ReduxActionTypes.FETCH_ACTIONS_VIEW_MODE_SUCCESS, ReduxActionErrorTypes.FETCH_ACTIONS_ERROR, diff --git a/app/client/src/actions/initActions.ts b/app/client/src/actions/initActions.ts index a82db2787e..6e2691d733 100644 --- a/app/client/src/actions/initActions.ts +++ b/app/client/src/actions/initActions.ts @@ -1,3 +1,4 @@ +import { APP_MODE } from "entities/App"; import { ReduxActionTypes, ReduxAction, @@ -7,6 +8,7 @@ export type InitializeEditorPayload = { applicationId?: string; pageId?: string; branch?: string; + mode: APP_MODE; }; export const initEditor = ( @@ -16,6 +18,28 @@ export const initEditor = ( payload, }); +export type InitAppViewerPayload = { + branch: string; + applicationId: string; + pageId: string; + mode: APP_MODE; +}; + +export const initAppViewer = ({ + applicationId, + branch, + mode, + pageId, +}: InitAppViewerPayload) => ({ + type: ReduxActionTypes.INITIALIZE_PAGE_VIEWER, + payload: { + branch: branch, + applicationId, + pageId, + mode, + }, +}); + export const resetEditorRequest = () => ({ type: ReduxActionTypes.RESET_EDITOR_REQUEST, }); diff --git a/app/client/src/ce/constants/ReduxActionConstants.tsx b/app/client/src/ce/constants/ReduxActionConstants.tsx index 086fce5cb6..792cdbfe0c 100644 --- a/app/client/src/ce/constants/ReduxActionConstants.tsx +++ b/app/client/src/ce/constants/ReduxActionConstants.tsx @@ -714,7 +714,6 @@ export const ReduxActionTypes = { "GET_SIMILAR_TEMPLATES_SUCCESS" /* This action constants is for identifying the status of the updates of the entities */, ENTITY_UPDATE_STARTED: "ENTITY_UPDATE_STARTED", ENTITY_UPDATE_SUCCESS: "ENTITY_UPDATE_SUCCESS", - FETCH_PLUGIN_AND_JS_ACTIONS_SUCCESS: "FETCH_PLUGIN_AND_JS_ACTIONS_SUCCESS", SET_APP_VIEWER_HEADER_HEIGHT: "SET_APP_VIEWER_HEADER_HEIGHT", UPDATE_BETA_CARD_SHOWN: "UPDATE_BETA_CARD_SHOWN", CLOSE_BETA_CARD_SHOWN: "CLOSE_BETA_CARD_SHOWN", diff --git a/app/client/src/pages/AppViewer/index.tsx b/app/client/src/pages/AppViewer/index.tsx index 7c62e696f5..89a61d9e89 100644 --- a/app/client/src/pages/AppViewer/index.tsx +++ b/app/client/src/pages/AppViewer/index.tsx @@ -8,7 +8,6 @@ import { BuilderRouteParams, GIT_BRANCH_QUERY_KEY, } from "constants/routes"; -import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import { getIsInitialized, getAppViewHeaderHeight, @@ -41,6 +40,11 @@ import { } from "actions/controlActions"; import { setAppViewHeaderHeight } from "actions/appViewActions"; import { showPostCompletionMessage } from "selectors/onboardingSelectors"; +import { fetchPublishedPage } from "actions/pageActions"; +import usePrevious from "utils/hooks/usePrevious"; +import { getIsBranchUpdated } from "../utils"; +import { APP_MODE } from "entities/App"; +import { initAppViewer } from "actions/initActions"; import { getShowBrandingBadge } from "@appsmith/selectors/organizationSelectors"; const AppViewerBody = styled.section<{ @@ -80,7 +84,7 @@ const DEFAULT_FONT_NAME = "System Default"; function AppViewer(props: Props) { const dispatch = useDispatch(); - const { search } = props.location; + const { pathname, search } = props.location; const { applicationId, pageId } = props.match.params; const [registered, setRegistered] = useState(false); const isInitialized = useSelector(getIsInitialized); @@ -91,24 +95,65 @@ function AppViewer(props: Props) { ); const showGuidedTourMessage = useSelector(showPostCompletionMessage); const headerHeight = useSelector(getAppViewHeaderHeight); - const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); const showBrandingBadge = useSelector(getShowBrandingBadge); + const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); + const prevValues = usePrevious({ branch, location: props.location, pageId }); /** * initializes the widgets factory and registers all widgets */ useEffect(() => { - editorInitializer().then(() => setRegistered(true)); + editorInitializer().then(() => { + setRegistered(true); + }); + + // onMount initPage + if (applicationId || pageId) { + dispatch( + initAppViewer({ + applicationId, + branch, + pageId, + mode: APP_MODE.PUBLISHED, + }), + ); + } }, []); /** * initialize the app if branch, pageId or application is changed */ useEffect(() => { - if (applicationId || pageId) { - initializeAppViewerCallback(branch, applicationId, pageId); + const prevBranch = prevValues?.branch; + const prevLocation = prevValues?.location; + const prevPageId = prevValues?.pageId; + let isBranchUpdated = false; + if (prevBranch && prevLocation) { + isBranchUpdated = getIsBranchUpdated(props.location, prevLocation); } - }, [branch, pageId, applicationId]); + + const isPageIdUpdated = pageId !== prevPageId; + + if (prevBranch && isBranchUpdated && (applicationId || pageId)) { + dispatch( + initAppViewer({ + applicationId, + branch, + pageId, + mode: APP_MODE.PUBLISHED, + }), + ); + } else { + /** + * First time load is handled by init sagas + * If we don't check for `prevPageId`: fetch page is retriggered + * when redirected to the default page + */ + if (prevPageId && pageId && isPageIdUpdated) { + dispatch(fetchPublishedPage(pageId, true)); + } + } + }, [branch, pageId, applicationId, pathname]); useEffect(() => { const header = document.querySelector(".js-appviewer-header"); @@ -141,24 +186,6 @@ function AppViewer(props: Props) { document.body.style.fontFamily = appFontFamily; }, [selectedTheme.properties.fontFamily.appFont]); - /** - * callback for initialize app - */ - const initializeAppViewerCallback = ( - branch: string, - applicationId: string, - pageId: string, - ) => { - dispatch({ - type: ReduxActionTypes.INITIALIZE_PAGE_VIEWER, - payload: { - branch: branch, - applicationId, - pageId, - }, - }); - }; - /** * callback for executing an action */ diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index 3348fb4acf..53f4ebd791 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -53,6 +53,9 @@ import GuidedTourModal from "./GuidedTour/DeviationModal"; import { getPageLevelSocketRoomId } from "sagas/WebsocketSagas/utils"; import RepoLimitExceededErrorModal from "./gitSync/RepoLimitExceededErrorModal"; import ImportedApplicationSuccessModal from "./gitSync/ImportedAppSuccessModal"; +import { getIsBranchUpdated } from "../utils"; +import { APP_MODE } from "entities/App"; +import { GIT_BRANCH_QUERY_KEY } from "constants/routes"; type EditorProps = { currentApplicationId?: string; @@ -95,11 +98,16 @@ class Editor extends Component { const { location: { search }, } = this.props; - const branch = getSearchQuery(search, "branch"); + const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); const { applicationId, pageId } = this.props.match.params; - if (applicationId || pageId) - this.props.initEditor({ applicationId, pageId, branch }); + if (pageId) + this.props.initEditor({ + applicationId, + pageId, + branch, + mode: APP_MODE.EDIT, + }); this.props.handlePathUpdated(window.location); this.unlisten = history.listen(this.handleHistoryChange); @@ -110,22 +118,11 @@ class Editor extends Component { } } - getIsBranchUpdated(props1: Props, props2: Props) { - const { - location: { search: search1 }, - } = props1; - const { - location: { search: search2 }, - } = props2; - - const branch1 = getSearchQuery(search1, "branch"); - const branch2 = getSearchQuery(search2, "branch"); - - return branch1 !== branch2; - } - shouldComponentUpdate(nextProps: Props, nextState: { registered: boolean }) { - const isBranchUpdated = this.getIsBranchUpdated(this.props, nextProps); + const isBranchUpdated = getIsBranchUpdated( + this.props.location, + nextProps.location, + ); return ( isBranchUpdated || @@ -148,16 +145,30 @@ class Editor extends Component { componentDidUpdate(prevProps: Props) { const { applicationId, pageId } = this.props.match.params || {}; const { pageId: prevPageId } = prevProps.match.params || {}; - const isBranchUpdated = this.getIsBranchUpdated(this.props, prevProps); + const isBranchUpdated = getIsBranchUpdated( + this.props.location, + prevProps.location, + ); - const branch = getSearchQuery(this.props.location.search, "branch"); - const prevBranch = getSearchQuery(prevProps.location.search, "branch"); + const branch = getSearchQuery( + this.props.location.search, + GIT_BRANCH_QUERY_KEY, + ); + const prevBranch = getSearchQuery( + prevProps.location.search, + GIT_BRANCH_QUERY_KEY, + ); const isPageIdUpdated = pageId !== prevPageId; // to prevent re-init during connect - if (prevBranch && isBranchUpdated && (applicationId || pageId)) { - this.props.initEditor({ pageId, branch, applicationId }); + if (prevBranch && isBranchUpdated && pageId) { + this.props.initEditor({ + applicationId, + pageId, + branch, + mode: APP_MODE.EDIT, + }); } else { /** * First time load is handled by init sagas @@ -182,7 +193,7 @@ class Editor extends Component { const { location: { search }, } = this.props; - const branch = getSearchQuery(search, "branch"); + const branch = getSearchQuery(search, GIT_BRANCH_QUERY_KEY); this.props.resetEditorRequest(); if (typeof this.unlisten === "function") this.unlisten(); this.props.collabStopSharingPointerEvent( diff --git a/app/client/src/pages/utils.ts b/app/client/src/pages/utils.ts new file mode 100644 index 0000000000..80c6935a15 --- /dev/null +++ b/app/client/src/pages/utils.ts @@ -0,0 +1,15 @@ +import { getSearchQuery } from "utils/helpers"; +import { Location } from "history"; + +export const getIsBranchUpdated = ( + prevLocation: Location, + currentLocation: Location, +) => { + const { search: search1 } = prevLocation; + const { search: search2 } = currentLocation; + + const branch1 = getSearchQuery(search1, "branch"); + const branch2 = getSearchQuery(search2, "branch"); + + return branch1 !== branch2; +}; diff --git a/app/client/src/sagas/GitSyncSagas.ts b/app/client/src/sagas/GitSyncSagas.ts index acf1e5168f..722cbb570a 100644 --- a/app/client/src/sagas/GitSyncSagas.ts +++ b/app/client/src/sagas/GitSyncSagas.ts @@ -84,6 +84,7 @@ import { Org } from "constants/orgConstants"; import { log } from "loglevel"; import GIT_ERROR_CODES from "constants/GitErrorCodes"; import { builderURL } from "RouteBuilder"; +import { APP_MODE } from "../entities/App"; export function* handleRepoLimitReachedError(response?: ApiResponse) { const { responseMeta } = response || {}; @@ -547,6 +548,7 @@ function* gitPullSaga( initEditor({ pageId: currentPageId, branch: currentBranch, + mode: APP_MODE.EDIT, }), ); } diff --git a/app/client/src/sagas/InitSagas.ts b/app/client/src/sagas/InitSagas.ts index 8e49e446c8..75c59fe074 100644 --- a/app/client/src/sagas/InitSagas.ts +++ b/app/client/src/sagas/InitSagas.ts @@ -57,17 +57,14 @@ import { restoreRecentEntitiesRequest, } from "actions/globalSearchActions"; import { - InitializeEditorPayload, resetEditorSuccess, + InitializeEditorPayload, + InitAppViewerPayload, } from "actions/initActions"; import PerformanceTracker, { PerformanceTransactionName, } from "utils/PerformanceTracker"; -import { - getCurrentApplicationId, - getIsEditorInitialized, - getPageById, -} from "selectors/editorSelectors"; +import { getIsEditorInitialized, getPageById } from "selectors/editorSelectors"; import { getIsInitialized as getIsViewerInitialized } from "selectors/appViewSelectors"; import { fetchCommentThreadsInit } from "actions/commentActions"; import { fetchJSCollectionsForView } from "actions/jsActionActions"; @@ -127,11 +124,13 @@ export function* failFastApiCalls( * @param initializeEditorAction * @returns */ -function* bootstrapEditor(payload: InitializeEditorPayload) { - const { branch } = payload; - yield put(resetEditorSuccess()); +function* bootstrap(payload: InitializeEditorPayload) { + const { branch, mode } = payload; + if (mode === APP_MODE.EDIT) { + yield put(resetEditorSuccess()); + } yield put(updateBranchLocally(branch || "")); - yield put(setAppMode(APP_MODE.EDIT)); + yield put(setAppMode(mode)); yield put({ type: ReduxActionTypes.START_EVALUATION }); } @@ -200,19 +199,18 @@ function* initiateURLUpdate( } } -function* initiateEditorApplicationAndPages(payload: InitializeEditorPayload) { - const pageId = payload.pageId; - const applicationId = payload.applicationId; +function* initiateApplication(payload: InitializeEditorPayload) { + const { applicationId, mode, pageId } = payload; const applicationCall: boolean = yield failFastApiCalls( - [fetchApplication({ pageId, applicationId, mode: APP_MODE.EDIT })], + [fetchApplication({ pageId, applicationId, mode })], [ ReduxActionTypes.FETCH_APPLICATION_SUCCESS, ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS, ], [ ReduxActionErrorTypes.FETCH_APPLICATION_ERROR, - ReduxActionErrorTypes.FETCH_PAGE_ERROR, + ReduxActionErrorTypes.FETCH_PAGE_LIST_ERROR, ], ); @@ -222,34 +220,73 @@ function* initiateEditorApplicationAndPages(payload: InitializeEditorPayload) { const defaultPageId: string = yield select(getDefaultPageId); toLoadPageId = toLoadPageId || defaultPageId; - yield call(initiateURLUpdate, toLoadPageId, APP_MODE.EDIT, payload.pageId); + yield call(initiateURLUpdate, toLoadPageId, mode, payload.pageId); return toLoadPageId; } -function* initiateEditorActions(toLoadPageId: string, applicationId: string) { - const initActionsCalls = [ - fetchPage(toLoadPageId, true), - fetchActions({ applicationId }, []), - fetchJSCollections({ applicationId }), - fetchSelectedAppThemeAction(applicationId), - fetchAppThemesAction(applicationId), - ]; - - const successActionEffects = [ - ReduxActionTypes.FETCH_JS_ACTIONS_SUCCESS, - ReduxActionTypes.FETCH_ACTIONS_SUCCESS, - ReduxActionTypes.FETCH_APP_THEMES_SUCCESS, - ReduxActionTypes.FETCH_SELECTED_APP_THEME_SUCCESS, - fetchPageSuccess().type, - ]; - const failureActionEffects = [ - ReduxActionErrorTypes.FETCH_JS_ACTIONS_ERROR, - ReduxActionErrorTypes.FETCH_ACTIONS_ERROR, - ReduxActionErrorTypes.FETCH_APP_THEMES_ERROR, - ReduxActionErrorTypes.FETCH_SELECTED_APP_THEME_ERROR, - ReduxActionErrorTypes.FETCH_PAGE_ERROR, - ]; +function* initiatePageAndAllActions( + toLoadPageId: string, + applicationId: string, + mode: APP_MODE, +) { + let initActionsCalls = []; + let successActionEffects = []; + let failureActionEffects = []; + switch (mode) { + case APP_MODE.EDIT: + { + initActionsCalls = [ + fetchPage(toLoadPageId, true), + fetchActions({ applicationId }, []), + fetchJSCollections({ applicationId }), + fetchSelectedAppThemeAction(applicationId), + fetchAppThemesAction(applicationId), + ]; + successActionEffects = [ + ReduxActionTypes.FETCH_JS_ACTIONS_SUCCESS, + ReduxActionTypes.FETCH_ACTIONS_SUCCESS, + ReduxActionTypes.FETCH_SELECTED_APP_THEME_SUCCESS, + fetchPageSuccess().type, + ReduxActionTypes.FETCH_APP_THEMES_SUCCESS, + ]; + failureActionEffects = [ + ReduxActionErrorTypes.FETCH_JS_ACTIONS_ERROR, + ReduxActionErrorTypes.FETCH_ACTIONS_ERROR, + ReduxActionErrorTypes.FETCH_SELECTED_APP_THEME_ERROR, + ReduxActionErrorTypes.FETCH_PAGE_ERROR, + ReduxActionErrorTypes.FETCH_APP_THEMES_ERROR, + ]; + } + break; + case APP_MODE.PUBLISHED: + { + initActionsCalls = [ + fetchPublishedPage(toLoadPageId, true, true), + fetchActionsForView({ applicationId }), + fetchJSCollectionsForView({ applicationId }), + fetchSelectedAppThemeAction(applicationId), + fetchAppThemesAction(applicationId), + ]; + successActionEffects = [ + fetchPublishedPageSuccess().type, + ReduxActionTypes.FETCH_ACTIONS_VIEW_MODE_SUCCESS, + ReduxActionTypes.FETCH_JS_ACTIONS_VIEW_MODE_SUCCESS, + ReduxActionTypes.FETCH_SELECTED_APP_THEME_SUCCESS, + ReduxActionTypes.FETCH_APP_THEMES_SUCCESS, + ]; + failureActionEffects = [ + ReduxActionErrorTypes.FETCH_PUBLISHED_PAGE_ERROR, + ReduxActionErrorTypes.FETCH_ACTIONS_VIEW_MODE_ERROR, + ReduxActionErrorTypes.FETCH_JS_ACTIONS_VIEW_MODE_ERROR, + ReduxActionErrorTypes.FETCH_SELECTED_APP_THEME_ERROR, + ReduxActionErrorTypes.FETCH_APP_THEMES_ERROR, + ]; + } + break; + default: + return false; + } const allActionCalls: boolean = yield failFastApiCalls( initActionsCalls, successActionEffects, @@ -257,15 +294,15 @@ function* initiateEditorActions(toLoadPageId: string, applicationId: string) { ); if (!allActionCalls) { - return; + return false; } else { - yield put({ - type: ReduxActionTypes.FETCH_PLUGIN_AND_JS_ACTIONS_SUCCESS, - }); yield put(fetchAllPageEntityCompletion([executePageLoadActions()])); + + return true; } } +// Editor mode only function* initiatePluginsAndDatasources() { const pluginsAndDatasourcesCalls: boolean = yield failFastApiCalls( [fetchPlugins(), fetchDatasources(), fetchMockDatasources()], @@ -289,7 +326,7 @@ function* initiatePluginsAndDatasources() { ); if (!pluginFormCall) return; } - +// Editor mode only function* initiateGit(applicationId: string) { const branchInStore: string = yield select(getCurrentGitBranch); @@ -316,17 +353,15 @@ function* initializeEditorSaga( initializeEditorAction: ReduxAction, ) { try { - const { payload } = initializeEditorAction; - - const { branch } = payload; - - yield call(bootstrapEditor, payload); - PerformanceTracker.startAsyncTracking( PerformanceTransactionName.INIT_EDIT_APP, ); + const { payload } = initializeEditorAction; + const { branch, mode } = initializeEditorAction.payload; - const toLoadPageId = yield call(initiateEditorApplicationAndPages, payload); + yield call(bootstrap, payload); + + const toLoadPageId = yield call(initiateApplication, payload); if (!toLoadPageId) return; const { id: applicationId, name }: ApplicationPayload = yield select( @@ -338,7 +373,8 @@ function* initializeEditorSaga( ); yield all([ - call(initiateEditorActions, toLoadPageId, applicationId), + call(initiatePageAndAllActions, toLoadPageId, applicationId, mode), + // only in edit mode call(initiatePluginsAndDatasources), call(populatePageDSLsSaga), ]); @@ -348,10 +384,14 @@ function* initializeEditorSaga( appName: name, }); + // only in edit mode yield call(initiateGit, applicationId); yield put(fetchCommentThreadsInit()); + // For omnibar to show all entities search + // only in edit mode + yield put({ type: ReduxActionTypes.INITIALIZE_EDITOR_SUCCESS, }); @@ -373,75 +413,34 @@ function* initializeEditorSaga( } export function* initializeAppViewerSaga( - action: ReduxAction<{ - branch: string; - pageId: string; - applicationId: string; - }>, + action: ReduxAction, ) { - const { branch, pageId } = action.payload; - - let { applicationId } = action.payload; - PerformanceTracker.startAsyncTracking( PerformanceTransactionName.INIT_VIEW_APP, ); + const { payload } = action; + const { branch, mode } = payload; - yield put(updateBranchLocally(branch || "")); + yield call(bootstrap, payload); - yield put(setAppMode(APP_MODE.PUBLISHED)); - - const applicationCall: boolean = yield failFastApiCalls( - [fetchApplication({ applicationId, pageId, mode: APP_MODE.PUBLISHED })], - [ - ReduxActionTypes.FETCH_APPLICATION_SUCCESS, - ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS, - ], - [ - ReduxActionErrorTypes.FETCH_APPLICATION_ERROR, - ReduxActionErrorTypes.FETCH_PAGE_LIST_ERROR, - ], + const toLoadPageId = yield call(initiateApplication, payload); + // only in edit mode + const { id: applicationId }: ApplicationPayload = yield select( + getCurrentApplication, ); - if (!applicationCall) return; - - applicationId = applicationId || (yield select(getCurrentApplicationId)); yield put( updateAppPersistentStore(getPersistentAppStore(applicationId, branch)), ); - yield put({ type: ReduxActionTypes.START_EVALUATION }); - const defaultPageId: string = yield select(getDefaultPageId); - const toLoadPageId: string = pageId || defaultPageId; - - yield call(initiateURLUpdate, toLoadPageId, APP_MODE.PUBLISHED, pageId); - - const resultOfPrimaryCalls: boolean = yield failFastApiCalls( - [ - fetchActionsForView({ applicationId }), - fetchJSCollectionsForView({ applicationId }), - fetchSelectedAppThemeAction(applicationId), - fetchAppThemesAction(applicationId), - fetchPublishedPage(toLoadPageId, true, true), - ], - [ - ReduxActionTypes.FETCH_ACTIONS_VIEW_MODE_SUCCESS, - ReduxActionTypes.FETCH_JS_ACTIONS_VIEW_MODE_SUCCESS, - ReduxActionTypes.FETCH_APP_THEMES_SUCCESS, - ReduxActionTypes.FETCH_SELECTED_APP_THEME_SUCCESS, - fetchPublishedPageSuccess().type, - ], - [ - ReduxActionErrorTypes.FETCH_ACTIONS_VIEW_MODE_ERROR, - ReduxActionErrorTypes.FETCH_JS_ACTIONS_VIEW_MODE_ERROR, - ReduxActionErrorTypes.FETCH_APP_THEMES_ERROR, - ReduxActionErrorTypes.FETCH_SELECTED_APP_THEME_ERROR, - ReduxActionErrorTypes.FETCH_PUBLISHED_PAGE_ERROR, - ], + const pageAndActionsFetch = yield call( + initiatePageAndAllActions, + toLoadPageId, + applicationId, + mode, ); - if (!resultOfPrimaryCalls) return; - + if (!pageAndActionsFetch) return; yield put(fetchAllPageEntityCompletion([executePageLoadActions()])); yield put(fetchCommentThreadsInit()); diff --git a/app/client/src/utils/hooks/usePrevious.tsx b/app/client/src/utils/hooks/usePrevious.tsx new file mode 100644 index 0000000000..a9a52702ea --- /dev/null +++ b/app/client/src/utils/hooks/usePrevious.tsx @@ -0,0 +1,12 @@ +import { useEffect, useRef } from "react"; + +// Make sure to use this hook at the start of functional component +const usePrevious = (value: T): T | undefined => { + const ref = useRef(); + useEffect(() => { + ref.current = value; + }); + return ref.current; +}; + +export default usePrevious; diff --git a/app/client/test/testCommon.ts b/app/client/test/testCommon.ts index 1fb45b98ac..1a5a2be648 100644 --- a/app/client/test/testCommon.ts +++ b/app/client/test/testCommon.ts @@ -98,7 +98,7 @@ export const syntheticTestMouseEvent = ( export function MockApplication({ children }: any) { editorInitializer(); const dispatch = useDispatch(); - dispatch(initEditor({ pageId: "page_id" })); + dispatch(initEditor({ pageId: "page_id", mode: APP_MODE.EDIT })); const mockResp: any = { organizationId: "org_id", pages: [{ id: "page_id", name: "Page1", isDefault: true }],