diff --git a/web/app/[workspaceSlug]/(projects)/notifications/page.tsx b/web/app/[workspaceSlug]/(projects)/notifications/page.tsx index 8afe768d80c..f1b0ccf8dfc 100644 --- a/web/app/[workspaceSlug]/(projects)/notifications/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/notifications/page.tsx @@ -2,6 +2,7 @@ import { useCallback, useEffect } from "react"; import { observer } from "mobx-react"; +import dynamic from "next/dynamic"; import { useParams } from "next/navigation"; import useSWR from "swr"; // plane imports @@ -12,12 +13,19 @@ import { LogoSpinner } from "@/components/common"; import { PageHead } from "@/components/core"; import { SimpleEmptyState } from "@/components/empty-state"; import { InboxContentRoot } from "@/components/inbox"; -import { IssuePeekOverview } from "@/components/issues"; // hooks import { useIssueDetail, useUserPermissions, useWorkspace, useWorkspaceNotifications } from "@/hooks/store"; import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path"; import { useWorkspaceIssueProperties } from "@/hooks/use-workspace-issue-properties"; +const IssuePeekOverview = dynamic( + () => import("@/components/issues/peek-overview/root").then((m) => m.IssuePeekOverview), + { + ssr: false, + loading: () => null, + } +); + const WorkspaceDashboardPage = observer(() => { const { workspaceSlug } = useParams(); // plane hooks diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/page.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/page.tsx index 6b83f367b1e..96ba593c16b 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/issues/(list)/page.tsx @@ -7,7 +7,7 @@ import { useParams } from "next/navigation"; import { useTranslation } from "@plane/i18n"; // components import { PageHead } from "@/components/core"; -import { ProjectLayoutRoot } from "@/components/issues"; +import { ProjectLayoutRoot } from "@/components/issues/issue-layouts"; // hooks import { useProject } from "@/hooks/store"; diff --git a/web/ce/hooks/use-editor-flagging.ts b/web/ce/hooks/use-editor-flagging.ts index 05fdff91fa5..7f05564de80 100644 --- a/web/ce/hooks/use-editor-flagging.ts +++ b/web/ce/hooks/use-editor-flagging.ts @@ -1,5 +1,5 @@ // editor -import { TExtensions } from "@plane/editor"; +import type { TExtensions } from "@plane/editor"; /** * @description extensions disabled in various editors diff --git a/web/core/components/analytics/project-modal/modal.tsx b/web/core/components/analytics/project-modal/modal.tsx index fb45d6aa9dd..39d609dbc38 100644 --- a/web/core/components/analytics/project-modal/modal.tsx +++ b/web/core/components/analytics/project-modal/modal.tsx @@ -1,10 +1,10 @@ import React, { useState } from "react"; import { observer } from "mobx-react"; +import dynamic from "next/dynamic"; import { Dialog, Transition } from "@headlessui/react"; import { ICycle, IModule, IProject } from "@plane/types"; // components -import { ProjectAnalyticsModalHeader, ProjectAnalyticsModalMainContent } from "@/components/analytics"; // types type Props = { @@ -15,6 +15,22 @@ type Props = { projectDetails?: IProject | undefined; }; +const ProjectAnalyticsModalHeader = dynamic( + () => import("@/components/analytics").then((m) => m.ProjectAnalyticsModalHeader), + { + ssr: false, + loading: () => null, + } +); + +const ProjectAnalyticsModalMainContent = dynamic( + () => import("@/components/analytics").then((m) => m.ProjectAnalyticsModalMainContent), + { + ssr: false, + loading: () => null, + } +); + export const ProjectAnalyticsModal: React.FC = observer((props) => { const { isOpen, onClose, cycleDetails, moduleDetails, projectDetails } = props; diff --git a/web/core/components/cycles/cycles-view.tsx b/web/core/components/cycles/cycles-view.tsx index ef6c9d136a2..3ae74f93009 100644 --- a/web/core/components/cycles/cycles-view.tsx +++ b/web/core/components/cycles/cycles-view.tsx @@ -1,9 +1,9 @@ import { FC } from "react"; import { observer } from "mobx-react"; +import dynamic from "next/dynamic"; import Image from "next/image"; // components import { useTranslation } from "@plane/i18n"; -import { CyclesList } from "@/components/cycles"; // ui import { CycleModuleListLayout } from "@/components/ui"; // hooks @@ -16,7 +16,10 @@ export interface ICyclesView { workspaceSlug: string; projectId: string; } - +const CyclesList = dynamic(() => import("@/components/cycles/list/root").then((m) => m.CyclesList), { + ssr: false, + loading: () => , +}); export const CyclesView: FC = observer((props) => { const { workspaceSlug, projectId } = props; // store hooks diff --git a/web/core/components/inbox/content/root.tsx b/web/core/components/inbox/content/root.tsx index 81be3d0e78a..8a84dad063c 100644 --- a/web/core/components/inbox/content/root.tsx +++ b/web/core/components/inbox/content/root.tsx @@ -1,15 +1,32 @@ import { FC, useEffect, useState } from "react"; import { observer } from "mobx-react"; +import dynamic from "next/dynamic"; import useSWR from "swr"; import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { TNameDescriptionLoader } from "@plane/types"; // components import { ContentWrapper } from "@plane/ui"; -import { InboxIssueActionsHeader, InboxIssueMainContent } from "@/components/inbox"; // hooks +import { IssuePeekOverviewLoader } from "@/components/issues/peek-overview/loader"; import { useProjectInbox, useUser, useUserPermissions } from "@/hooks/store"; import { useAppRouter } from "@/hooks/use-app-router"; +const InboxIssueActionsHeader = dynamic( + () => import("@/components/inbox/content/inbox-issue-header").then((m) => m.InboxIssueActionsHeader), + { + ssr: false, + loading: () => null, + } +); + +const InboxIssueMainContent = dynamic( + () => import("@/components/inbox/content/issue-root").then((m) => m.InboxIssueMainContent), + { + ssr: false, + loading: () => null} />, + } +); + type TInboxContentRoot = { workspaceSlug: string; projectId: string; diff --git a/web/core/components/issues/filters.tsx b/web/core/components/issues/filters.tsx index 346c960b769..e85100461b6 100644 --- a/web/core/components/issues/filters.tsx +++ b/web/core/components/issues/filters.tsx @@ -10,6 +10,7 @@ import { useTranslation } from "@plane/i18n"; import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; import { Button } from "@plane/ui"; // components +import { ProjectAnalyticsModal } from "@/components/analytics"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues"; // helpers import { isIssueFilterActive } from "@/helpers/filter.helper"; @@ -17,7 +18,7 @@ import { isIssueFilterActive } from "@/helpers/filter.helper"; import { useLabel, useProjectState, useMember, useIssues } from "@/hooks/store"; // plane web types import { TProject } from "@/plane-web/types"; -import { ProjectAnalyticsModal } from "../analytics"; +// local components type Props = { currentProjectDetails: TProject | undefined; diff --git a/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx index 4007468dc20..ad6467a3da9 100644 --- a/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/project-layout-root.tsx @@ -2,6 +2,7 @@ import { FC, Fragment } from "react"; import { observer } from "mobx-react"; +import dynamic from "next/dynamic"; import { useParams } from "next/navigation"; import useSWR from "swr"; // plane constants @@ -9,19 +10,67 @@ import { EIssueLayoutTypes, EIssuesStoreType } from "@plane/constants"; // components import { Spinner } from "@plane/ui"; import { LogoSpinner } from "@/components/common"; + +// constants import { - ListLayout, - CalendarLayout, - BaseGanttRoot, - KanBanLayout, - ProjectAppliedFiltersRoot, - ProjectSpreadsheetLayout, - IssuePeekOverview, -} from "@/components/issues"; + CalendarLayoutLoader, + GanttLayoutLoader, + KanbanLayoutLoader, + ListLayoutLoader, + SpreadsheetLayoutLoader, +} from "@/components/ui"; + // hooks import { useIssues } from "@/hooks/store"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; +const ProjectAppliedFiltersRoot = dynamic( + () => + import("@/components/issues/issue-layouts/filters/applied-filters/roots/project-root").then( + (m) => m.ProjectAppliedFiltersRoot + ), + { + ssr: false, + loading: () => null, + } +); +const ListLayout = dynamic( + () => import("@/components/issues/issue-layouts/list/roots/project-root").then((m) => m.ListLayout), + { + ssr: false, + loading: () => , + } +); +const KanBanLayout = dynamic( + () => import("@/components/issues/issue-layouts/kanban/roots/project-root").then((m) => m.KanBanLayout), + { + ssr: false, + loading: () => , + } +); +const CalendarLayout = dynamic( + () => import("@/components/issues/issue-layouts/calendar/roots/project-root").then((m) => m.CalendarLayout), + { + ssr: false, + loading: () => , + } +); +const BaseGanttRoot = dynamic( + () => import("@/components/issues/issue-layouts/gantt/base-gantt-root").then((m) => m.BaseGanttRoot), + { + ssr: false, + loading: () => , + } +); +const ProjectSpreadsheetLayout = dynamic( + () => + import("@/components/issues/issue-layouts/spreadsheet/roots/project-root").then((m) => m.ProjectSpreadsheetLayout), + { + ssr: false, + loading: () => , + } +); + const ProjectIssueLayout = (props: { activeLayout: EIssueLayoutTypes | undefined }) => { switch (props.activeLayout) { case EIssueLayoutTypes.LIST: @@ -38,6 +87,13 @@ const ProjectIssueLayout = (props: { activeLayout: EIssueLayoutTypes | undefined return null; } }; +const IssuePeekOverview = dynamic( + () => import("@/components/issues/peek-overview/root").then((m) => m.IssuePeekOverview), + { + ssr: false, + loading: () => null, + } +); export const ProjectLayoutRoot: FC = observer(() => { // router diff --git a/web/core/components/page-views/workspace-dashboard.tsx b/web/core/components/page-views/workspace-dashboard.tsx index 19d3590b07f..91d924c1cb2 100644 --- a/web/core/components/page-views/workspace-dashboard.tsx +++ b/web/core/components/page-views/workspace-dashboard.tsx @@ -1,17 +1,16 @@ import { useEffect } from "react"; import { observer } from "mobx-react"; +import dynamic from "next/dynamic"; import { useParams } from "next/navigation"; // plane imports import { EUserPermissionsLevel, PRODUCT_TOUR_COMPLETED, EUserPermissions } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; import { ContentWrapper } from "@plane/ui"; // components -import { DashboardWidgets } from "@/components/dashboard"; +import { LogoSpinner } from "@/components/common"; import { ComicBoxButton, DetailedEmptyState } from "@/components/empty-state"; -import { IssuePeekOverview } from "@/components/issues"; import { TourRoot } from "@/components/onboarding"; import { UserGreetingsView } from "@/components/user"; -// constants // helpers import { cn } from "@/helpers/common.helper"; // hooks @@ -27,6 +26,26 @@ import { import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path"; import useSize from "@/hooks/use-window-size"; +//@to-do Add loader matching the layout +const DashboardWidgets = dynamic( + () => import("@/components/dashboard/home-dashboard-widgets").then((m) => m.DashboardWidgets), + { + ssr: false, + loading: () => ( +
+ +
+ ), + } +); +const IssuePeekOverview = dynamic( + () => import("@/components/issues/peek-overview/root").then((m) => m.IssuePeekOverview), + { + ssr: false, + loading: () => null, + } +); + export const WorkspaceDashboardView = observer(() => { // plane hooks const { t } = useTranslation(); diff --git a/web/core/components/pages/editor/header/options-dropdown.tsx b/web/core/components/pages/editor/header/options-dropdown.tsx index e1807bcc9c6..255a9be90ca 100644 --- a/web/core/components/pages/editor/header/options-dropdown.tsx +++ b/web/core/components/pages/editor/header/options-dropdown.tsx @@ -2,6 +2,7 @@ import { useMemo, useState } from "react"; import { observer } from "mobx-react"; +import dynamic from "next/dynamic"; import { useRouter } from "next/navigation"; import { ArrowUpToLine, Clipboard, History } from "lucide-react"; // document editor @@ -9,7 +10,7 @@ import { EditorRefApi } from "@plane/editor"; // ui import { TContextMenuItem, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui"; // components -import { ExportPageModal, PageActions, TPageActions } from "@/components/pages"; +import { PageActions, TPageActions } from "@/components/pages"; // helpers import { copyTextToClipboard } from "@/helpers/string.helper"; // hooks @@ -23,6 +24,13 @@ type Props = { page: TPageInstance; }; +const ExportPageModal = dynamic( + () => import("@/components/pages/modals/export-page-modal").then((m) => m.ExportPageModal), + { + ssr: false, + loading: () => null, + } +); export const PageOptionsDropdown: React.FC = observer((props) => { const { editorRef, page } = props; // states diff --git a/web/core/components/profile/profile-setting-content-wrapper.tsx b/web/core/components/profile/profile-setting-content-wrapper.tsx index c9741ca5d3d..d12e16cd08d 100644 --- a/web/core/components/profile/profile-setting-content-wrapper.tsx +++ b/web/core/components/profile/profile-setting-content-wrapper.tsx @@ -1,8 +1,8 @@ "use client"; import React, { FC } from "react"; // helpers +import { SidebarHamburgerToggle } from "@/components/core"; import { cn } from "@/helpers/common.helper"; -import { SidebarHamburgerToggle } from "../core"; type Props = { children: React.ReactNode; diff --git a/web/core/hooks/use-workspace-issue-properties.ts b/web/core/hooks/use-workspace-issue-properties.ts index a3da0295995..a60b477735a 100644 --- a/web/core/hooks/use-workspace-issue-properties.ts +++ b/web/core/hooks/use-workspace-issue-properties.ts @@ -1,5 +1,5 @@ +import { useCycle, useLabel, useModule, useProjectEstimates, useProjectState } from "@/hooks/store"; import useSWR from "swr"; -import { useCycle, useProjectEstimates, useLabel, useModule, useProjectState } from "./store"; export const useWorkspaceIssueProperties = (workspaceSlug: string | string[] | undefined) => { const { fetchWorkspaceLabels } = useLabel(); diff --git a/web/next.config.js b/web/next.config.js index 672d9151b5f..2a398f2a404 100644 --- a/web/next.config.js +++ b/web/next.config.js @@ -75,6 +75,68 @@ const nextConfig = { } return rewrites; }, + + experimental: { + optimizePackageImports: [ + // Components + "@/components/account", + "@/components/analytics", + "@/components/api-token", + "@/components/archives", + "@/components/auth-screens", + "@/components/automation", + "@/components/command-palette", + "@/components/common", + "@/components/core", + "@/components/cycles", + "@/components/dashboard", + "@/components/dropdowns", + "@/components/editor", + "@/components/empty-state", + "@/components/estimates", + "@/components/exporter", + "@/components/gantt-chart", + "@/components/gantt-chart/contexts", + "@/components/global", + "@/components/graphs", + "@/components/icons", + "@/components/inbox", + "@/components/instance", + "@/components/integration", + "@/components/issues", + "@/components/issues/issue-layouts", + "@/components/labels", + "@/components/modules", + "@/components/onboarding", + "@/components/page-views", + "@/components/pages", + "@/components/profile", + "@/components/project", + "@/components/project-states", + "@/components/sidebar", + "@/components/ui", + "@/components/user", + "@/components/views", + "@/components/web-hooks", + "@/components/workspace", + "@/components/workspace-notifications", + + // lib + "@/lib/store-context", + "@/lib/wrappers", + "@/lib/n-progress", + "@/lib/local-storage", + + // Services + "@/plane-web/services", + + // + "@headlessui/react", + "axios", + + "@/hooks/store", + ], + }, }; module.exports = nextConfig;