From 0358e9b9654d67cfe575c842f74fd0c9ae6084d1 Mon Sep 17 00:00:00 2001 From: Vipin Chaudhary Date: Mon, 1 Sep 2025 16:43:07 +0530 Subject: [PATCH] [WIKI-589] fix: update project page creation flow (#7685) * fix : update project page creation flow * chore: update translations * chore: remove unused changes --- .../pages/pages-list-main-content.tsx | 81 +++++++++++++++---- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/apps/web/core/components/pages/pages-list-main-content.tsx b/apps/web/core/components/pages/pages-list-main-content.tsx index ca7c085b6..502c29ba9 100644 --- a/apps/web/core/components/pages/pages-list-main-content.tsx +++ b/apps/web/core/components/pages/pages-list-main-content.tsx @@ -1,14 +1,23 @@ +"use client"; +import { useState } from "react"; import { observer } from "mobx-react"; import Image from "next/image"; // plane imports -import { EUserPermissionsLevel, EPageAccess, PROJECT_PAGE_TRACKER_ELEMENTS } from "@plane/constants"; +import { useParams, useRouter } from "next/navigation"; +import { + EUserPermissionsLevel, + EPageAccess, + PROJECT_PAGE_TRACKER_ELEMENTS, + PROJECT_PAGE_TRACKER_EVENTS, +} from "@plane/constants"; import { useTranslation } from "@plane/i18n"; -import { EUserProjectRoles, TPageNavigationTabs } from "@plane/types"; +import { EUserProjectRoles, TPage, TPageNavigationTabs } from "@plane/types"; // components +import { setToast, TOAST_TYPE } from "@plane/ui"; import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root"; import { PageLoader } from "@/components/pages/loaders/page-loader"; -import { captureClick } from "@/helpers/event-tracker.helper"; -import { useCommandPalette } from "@/hooks/store/use-command-palette"; +import { captureClick, captureError, captureSuccess } from "@/helpers/event-tracker.helper"; +import { useProject } from "@/hooks/store/use-project"; import { useUserPermissions } from "@/hooks/store/user"; import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path"; // plane web hooks @@ -25,10 +34,16 @@ export const PagesListMainContent: React.FC = observer((props) => { // plane hooks const { t } = useTranslation(); // store hooks - const { loader, isAnyPageAvailable, getCurrentProjectFilteredPageIdsByTab, getCurrentProjectPageIdsByTab, filters } = + const { currentProjectDetails, loader } = useProject(); + const { isAnyPageAvailable, getCurrentProjectFilteredPageIdsByTab, getCurrentProjectPageIdsByTab, filters } = usePageStore(storeType); - const { toggleCreatePageModal } = useCommandPalette(); const { allowPermissions } = useUserPermissions(); + const { createPage } = usePageStore(EPageStoreType.PROJECT); + // states + const [isCreatingPage, setIsCreatingPage] = useState(false); + // router + const router = useRouter(); + const { workspaceSlug } = useParams(); // derived values const pageIds = getCurrentProjectPageIdsByTab(pageType); const filteredPageIds = getCurrentProjectFilteredPageIdsByTab(pageType); @@ -54,6 +69,42 @@ export const PagesListMainContent: React.FC = observer((props) => { extension: "svg", }); + // handle page create + const handleCreatePage = async () => { + setIsCreatingPage(true); + + const payload: Partial = { + access: pageType === "private" ? EPageAccess.PRIVATE : EPageAccess.PUBLIC, + }; + + await createPage(payload) + .then((res) => { + captureSuccess({ + eventName: PROJECT_PAGE_TRACKER_EVENTS.create, + payload: { + id: res?.id, + state: "SUCCESS", + }, + }); + const pageId = `/${workspaceSlug}/projects/${currentProjectDetails?.id}/pages/${res?.id}`; + router.push(pageId); + }) + .catch((err) => { + captureError({ + eventName: PROJECT_PAGE_TRACKER_EVENTS.create, + payload: { + state: "ERROR", + }, + }); + setToast({ + type: TOAST_TYPE.ERROR, + title: "Error!", + message: err?.data?.error || "Page could not be created. Please try again.", + }); + }) + .finally(() => setIsCreatingPage(false)); + }; + if (loader === "init-loader") return ; // if no pages exist in the active page type if (!isAnyPageAvailable || pageIds?.length === 0) { @@ -64,12 +115,12 @@ export const PagesListMainContent: React.FC = observer((props) => { description={t("project_page.empty_state.general.description")} assetPath={generalPageResolvedPath} primaryButton={{ - text: t("project_page.empty_state.general.primary_button.text"), + text: isCreatingPage ? t("creating") : t("project_page.empty_state.general.primary_button.text"), onClick: () => { - toggleCreatePageModal({ isOpen: true }); + handleCreatePage(); captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON }); }, - disabled: !canPerformEmptyStateActions, + disabled: !canPerformEmptyStateActions || isCreatingPage, }} /> ); @@ -81,12 +132,12 @@ export const PagesListMainContent: React.FC = observer((props) => { description={t("project_page.empty_state.public.description")} assetPath={publicPageResolvedPath} primaryButton={{ - text: t("project_page.empty_state.public.primary_button.text"), + text: isCreatingPage ? t("creating") : t("project_page.empty_state.public.primary_button.text"), onClick: () => { - toggleCreatePageModal({ isOpen: true, pageAccess: EPageAccess.PUBLIC }); + handleCreatePage(); captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON }); }, - disabled: !canPerformEmptyStateActions, + disabled: !canPerformEmptyStateActions || isCreatingPage, }} /> ); @@ -97,12 +148,12 @@ export const PagesListMainContent: React.FC = observer((props) => { description={t("project_page.empty_state.private.description")} assetPath={privatePageResolvedPath} primaryButton={{ - text: t("project_page.empty_state.private.primary_button.text"), + text: isCreatingPage ? t("creating") : t("project_page.empty_state.private.primary_button.text"), onClick: () => { - toggleCreatePageModal({ isOpen: true, pageAccess: EPageAccess.PRIVATE }); + handleCreatePage(); captureClick({ elementName: PROJECT_PAGE_TRACKER_ELEMENTS.EMPTY_STATE_CREATE_BUTTON }); }, - disabled: !canPerformEmptyStateActions, + disabled: !canPerformEmptyStateActions || isCreatingPage, }} /> );