[PE-182] refactor: pages' components and store for scalability (#6283)
* refactor: created a generic base page instance * refactor: project store hooks * chore: add missing prop declaration * refactor: editor page root and body * refactor: issue embed hook * chore: update search entity types * fix: version editor component * fix: add page to favorites action --------- Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
This commit is contained in:
parent
211d5e1cd0
commit
8d7425a3b7
34 changed files with 553 additions and 521 deletions
|
|
@ -1,29 +1,58 @@
|
|||
"use client";
|
||||
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
import useSWR from "swr";
|
||||
// ui
|
||||
// plane types
|
||||
import { TSearchEntityRequestPayload } from "@plane/types";
|
||||
import { EFileAssetType } from "@plane/types/src/enums";
|
||||
// plane ui
|
||||
import { getButtonStyling } from "@plane/ui";
|
||||
// plane utils
|
||||
import { cn } from "@plane/utils";
|
||||
// components
|
||||
import { LogoSpinner } from "@/components/common";
|
||||
import { PageHead } from "@/components/core";
|
||||
import { IssuePeekOverview } from "@/components/issues";
|
||||
import { PageRoot } from "@/components/pages";
|
||||
import { PageRoot, TPageRootConfig, TPageRootHandlers } from "@/components/pages";
|
||||
// helpers
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
import { getEditorFileHandlers } from "@/helpers/editor.helper";
|
||||
// hooks
|
||||
import { usePage, useProjectPages } from "@/hooks/store";
|
||||
import { useProjectPage, useProjectPages, useWorkspace } from "@/hooks/store";
|
||||
// plane web hooks
|
||||
import { useFileSize } from "@/plane-web/hooks/use-file-size";
|
||||
// plane web services
|
||||
import { WorkspaceService } from "@/plane-web/services";
|
||||
// services
|
||||
import { FileService } from "@/services/file.service";
|
||||
import { ProjectPageService, ProjectPageVersionService } from "@/services/page";
|
||||
const workspaceService = new WorkspaceService();
|
||||
const fileService = new FileService();
|
||||
const projectPageService = new ProjectPageService();
|
||||
const projectPageVersionService = new ProjectPageVersionService();
|
||||
|
||||
const PageDetailsPage = observer(() => {
|
||||
const { workspaceSlug, projectId, pageId } = useParams();
|
||||
|
||||
// store hooks
|
||||
const { getPageById } = useProjectPages();
|
||||
const page = usePage(pageId?.toString() ?? "");
|
||||
const { id, name } = page;
|
||||
|
||||
const { createPage, getPageById } = useProjectPages();
|
||||
const page = useProjectPage(pageId?.toString() ?? "");
|
||||
const { getWorkspaceBySlug } = useWorkspace();
|
||||
// derived values
|
||||
const workspaceId = workspaceSlug ? (getWorkspaceBySlug(workspaceSlug.toString())?.id ?? "") : "";
|
||||
const { id, name, updateDescription } = page;
|
||||
// entity search handler
|
||||
const fetchEntityCallback = useCallback(
|
||||
async (payload: TSearchEntityRequestPayload) =>
|
||||
await workspaceService.searchEntity(workspaceSlug?.toString() ?? "", {
|
||||
...payload,
|
||||
project_id: projectId?.toString() ?? "",
|
||||
}),
|
||||
[projectId, workspaceSlug]
|
||||
);
|
||||
// file size
|
||||
const { maxFileSize } = useFileSize();
|
||||
// fetch page details
|
||||
const { error: pageDetailsError } = useSWR(
|
||||
workspaceSlug && projectId && pageId ? `PAGE_DETAILS_${pageId}` : null,
|
||||
|
|
@ -36,6 +65,62 @@ const PageDetailsPage = observer(() => {
|
|||
revalidateOnReconnect: true,
|
||||
}
|
||||
);
|
||||
// page root handlers
|
||||
const pageRootHandlers: TPageRootHandlers = useMemo(
|
||||
() => ({
|
||||
create: createPage,
|
||||
fetchAllVersions: async (pageId) => {
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
return await projectPageVersionService.fetchAllVersions(workspaceSlug.toString(), projectId.toString(), pageId);
|
||||
},
|
||||
fetchDescriptionBinary: async () => {
|
||||
if (!workspaceSlug || !projectId || !page.id) return;
|
||||
return await projectPageService.fetchDescriptionBinary(workspaceSlug.toString(), projectId.toString(), page.id);
|
||||
},
|
||||
fetchEntity: fetchEntityCallback,
|
||||
fetchVersionDetails: async (pageId, versionId) => {
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
return await projectPageVersionService.fetchVersionById(
|
||||
workspaceSlug.toString(),
|
||||
projectId.toString(),
|
||||
pageId,
|
||||
versionId
|
||||
);
|
||||
},
|
||||
getRedirectionLink: (pageId) => `/${workspaceSlug}/projects/${projectId}/pages/${pageId}`,
|
||||
updateDescription,
|
||||
}),
|
||||
[createPage, fetchEntityCallback, page.id, projectId, updateDescription, workspaceSlug]
|
||||
);
|
||||
// page root config
|
||||
const pageRootConfig: TPageRootConfig = useMemo(
|
||||
() => ({
|
||||
fileHandler: getEditorFileHandlers({
|
||||
maxFileSize,
|
||||
projectId: projectId?.toString() ?? "",
|
||||
uploadFile: async (file) => {
|
||||
const { asset_id } = await fileService.uploadProjectAsset(
|
||||
workspaceSlug?.toString() ?? "",
|
||||
projectId?.toString() ?? "",
|
||||
{
|
||||
entity_identifier: id ?? "",
|
||||
entity_type: EFileAssetType.PAGE_DESCRIPTION,
|
||||
},
|
||||
file
|
||||
);
|
||||
return asset_id;
|
||||
},
|
||||
workspaceId,
|
||||
workspaceSlug: workspaceSlug?.toString() ?? "",
|
||||
}),
|
||||
webhookConnectionParams: {
|
||||
documentType: "project_page",
|
||||
projectId: projectId?.toString() ?? "",
|
||||
workspaceSlug: workspaceSlug?.toString() ?? "",
|
||||
},
|
||||
}),
|
||||
[id, maxFileSize, projectId, workspaceId, workspaceSlug]
|
||||
);
|
||||
|
||||
if ((!page || !id) && !pageDetailsError)
|
||||
return (
|
||||
|
|
@ -65,7 +150,12 @@ const PageDetailsPage = observer(() => {
|
|||
<PageHead title={name} />
|
||||
<div className="flex h-full flex-col justify-between">
|
||||
<div className="relative h-full w-full flex-shrink-0 flex flex-col overflow-hidden">
|
||||
<PageRoot page={page} projectId={projectId.toString()} workspaceSlug={workspaceSlug.toString()} />
|
||||
<PageRoot
|
||||
config={pageRootConfig}
|
||||
handlers={pageRootHandlers}
|
||||
page={page}
|
||||
workspaceSlug={workspaceSlug?.toString() ?? ""}
|
||||
/>
|
||||
<IssuePeekOverview />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { PageEditInformationPopover } from "@/components/pages";
|
|||
import { convertHexEmojiToDecimal } from "@/helpers/emoji.helper";
|
||||
import { getPageName } from "@/helpers/page.helper";
|
||||
// hooks
|
||||
import { usePage, useProject, useUser, useUserPermissions } from "@/hooks/store";
|
||||
import { useProjectPage, useProject, useUser, useUserPermissions } from "@/hooks/store";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// plane web components
|
||||
import { PageDetailsHeaderExtraActions } from "@/plane-web/components/pages";
|
||||
|
|
@ -32,7 +32,7 @@ export const PageDetailsHeader = observer(() => {
|
|||
const [isOpen, setIsOpen] = useState(false);
|
||||
// store hooks
|
||||
const { currentProjectDetails, loader } = useProject();
|
||||
const page = usePage(pageId?.toString() ?? "");
|
||||
const page = useProjectPage(pageId?.toString() ?? "");
|
||||
const { name, logo_props, updatePageLogo, owned_by } = page;
|
||||
const { allowPermissions } = useUserPermissions();
|
||||
const { data: currentUser } = useUser();
|
||||
|
|
@ -169,7 +169,7 @@ export const PageDetailsHeader = observer(() => {
|
|||
</Header.LeftItem>
|
||||
<Header.RightItem>
|
||||
<PageEditInformationPopover page={page} />
|
||||
<PageDetailsHeaderExtraActions />
|
||||
<PageDetailsHeaderExtraActions page={page} />
|
||||
</Header.RightItem>
|
||||
</Header>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -51,11 +51,7 @@ const ProjectPagesPage = observer(() => {
|
|||
projectId={projectId.toString()}
|
||||
pageType={currentPageType()}
|
||||
>
|
||||
<PagesListRoot
|
||||
pageType={currentPageType()}
|
||||
workspaceSlug={workspaceSlug.toString()}
|
||||
projectId={projectId.toString()}
|
||||
/>
|
||||
<PagesListRoot pageType={currentPageType()} />
|
||||
</PagesListView>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue