From 3c884fd46e544589859ebbdb145736a083abff40 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Thu, 2 Nov 2023 23:57:44 +0530 Subject: [PATCH] fix: implementing layouts using _app.tsx get layout method. (#2620) * fix: implementing layouts in all pages * fix: layout fixes, implemting using standard nextjs parctice --- web/components/headers/cycles.tsx | 19 +- web/pages/[workspaceSlug]/analytics.tsx | 10 +- web/pages/[workspaceSlug]/index.tsx | 14 +- .../[workspaceSlug]/me/profile/activity.tsx | 299 ++++++----- .../[workspaceSlug]/me/profile/index.tsx | 500 +++++++++--------- .../me/profile/preferences.tsx | 58 +- .../profile/[userId]/assigned.tsx | 45 +- .../profile/[userId]/created.tsx | 40 +- .../profile/[userId]/index.tsx | 37 +- .../profile/[userId]/subscribed.tsx | 16 +- .../archived-issues/[archivedIssueId].tsx | 27 +- .../[projectId]/archived-issues/index.tsx | 43 +- .../projects/[projectId]/cycles/[cycleId].tsx | 17 +- .../projects/[projectId]/cycles/index.tsx | 21 +- .../[projectId]/draft-issues/index.tsx | 41 +- .../projects/[projectId]/inbox/[inboxId].tsx | 31 +- .../projects/[projectId]/issues/[issueId].tsx | 23 +- .../projects/[projectId]/issues/index.tsx | 23 +- .../[projectId]/modules/[moduleId].tsx | 93 ++-- .../projects/[projectId]/modules/index.tsx | 21 +- .../projects/[projectId]/pages/[pageId].tsx | 29 +- .../projects/[projectId]/pages/index.tsx | 22 +- .../[projectId]/settings/automations.tsx | 33 +- .../[projectId]/settings/estimates.tsx | 26 +- .../[projectId]/settings/features.tsx | 42 +- .../projects/[projectId]/settings/index.tsx | 67 +-- .../[projectId]/settings/integrations.tsx | 83 +-- .../projects/[projectId]/settings/labels.tsx | 27 +- .../projects/[projectId]/settings/members.tsx | 27 +- .../projects/[projectId]/settings/states.tsx | 33 +- .../projects/[projectId]/views/[viewId].tsx | 17 +- .../projects/[projectId]/views/index.tsx | 25 +- web/pages/[workspaceSlug]/projects/index.tsx | 16 +- .../[workspaceSlug]/settings/billing.tsx | 52 +- .../[workspaceSlug]/settings/exports.tsx | 16 +- .../[workspaceSlug]/settings/imports.tsx | 33 +- web/pages/[workspaceSlug]/settings/index.tsx | 21 +- .../[workspaceSlug]/settings/integrations.tsx | 50 +- .../[workspaceSlug]/settings/members.tsx | 81 +-- .../workspace-views/[globalViewId].tsx | 30 +- .../workspace-views/all-issues.tsx | 23 +- .../workspace-views/assigned.tsx | 23 +- .../workspace-views/created.tsx | 23 +- .../[workspaceSlug]/workspace-views/index.tsx | 46 +- .../workspace-views/subscribed.tsx | 23 +- web/pages/_app.tsx | 18 +- web/pages/accounts/forgot-password.tsx | 28 +- web/pages/accounts/magic-sign-in.tsx | 101 ++-- web/pages/accounts/reset-password.tsx | 33 +- web/pages/accounts/sign-up.tsx | 31 +- web/pages/create-workspace.tsx | 78 +-- web/pages/index.tsx | 14 +- web/pages/installations/[provider]/index.tsx | 12 +- web/pages/invitations/index.tsx | 214 ++++---- web/pages/onboarding/index.tsx | 146 ++--- web/pages/workspace-invitations/index.tsx | 152 +++--- web/types/app.d.ts | 3 + 57 files changed, 1653 insertions(+), 1423 deletions(-) create mode 100644 web/types/app.d.ts diff --git a/web/components/headers/cycles.tsx b/web/components/headers/cycles.tsx index b2682823a..93aa08aea 100644 --- a/web/components/headers/cycles.tsx +++ b/web/components/headers/cycles.tsx @@ -1,5 +1,4 @@ -import * as React from "react"; - +import { FC } from "react"; import { useRouter } from "next/router"; import Link from "next/link"; import { Plus } from "lucide-react"; @@ -7,16 +6,18 @@ import { Plus } from "lucide-react"; import { Breadcrumbs, BreadcrumbItem, Button } from "@plane/ui"; // helpers import { truncateText } from "helpers/string.helper"; +// hooks +import { useMobxStore } from "lib/mobx/store-provider"; +export interface ICyclesHeader {} -export interface ICyclesHeader { - name: string | undefined; -} - -export const CyclesHeader: React.FC = (props) => { - const { name } = props; +export const CyclesHeader: FC = (props) => { + const {} = props; // router const router = useRouter(); const { workspaceSlug } = router.query; + // store + const { project: projectStore } = useMobxStore(); + const { currentProjectDetails } = projectStore; return (
= (props) => { } /> - +
diff --git a/web/pages/[workspaceSlug]/analytics.tsx b/web/pages/[workspaceSlug]/analytics.tsx index 55870cd06..da65e1291 100644 --- a/web/pages/[workspaceSlug]/analytics.tsx +++ b/web/pages/[workspaceSlug]/analytics.tsx @@ -1,4 +1,4 @@ -import React, { Fragment, useEffect } from "react"; +import React, { Fragment, useEffect, ReactElement } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import { Tab } from "@headlessui/react"; @@ -18,10 +18,12 @@ import { Plus } from "lucide-react"; import emptyAnalytics from "public/empty-state/analytics.svg"; // constants import { ANALYTICS_TABS } from "constants/analytics"; +// type +import { NextPageWithLayout } from "types/app"; const trackEventService = new TrackEventService(); -const AnalyticsPage = observer(() => { +const AnalyticsPage: NextPageWithLayout = observer(() => { // router const router = useRouter(); const { workspaceSlug } = router.query; @@ -110,4 +112,8 @@ const AnalyticsPage = observer(() => { ); }); +AnalyticsPage.getLayout = function getLayout(page: ReactElement) { + return }>{page}; +}; + export default AnalyticsPage; diff --git a/web/pages/[workspaceSlug]/index.tsx b/web/pages/[workspaceSlug]/index.tsx index 362cd5499..703882a23 100644 --- a/web/pages/[workspaceSlug]/index.tsx +++ b/web/pages/[workspaceSlug]/index.tsx @@ -1,14 +1,16 @@ -import type { NextPage } from "next"; +import { ReactElement } from "react"; // layouts import { AppLayout } from "layouts/app-layout"; // components import { WorkspaceDashboardView } from "components/views"; import { WorkspaceDashboardHeader } from "components/headers/workspace-dashboard"; +// types +import { NextPageWithLayout } from "types/app"; -const WorkspacePage: NextPage = () => ( - }> - - -); +const WorkspacePage: NextPageWithLayout = () => ; + +WorkspacePage.getLayout = function getLayout(page: ReactElement) { + return }>{page}; +}; export default WorkspacePage; diff --git a/web/pages/[workspaceSlug]/me/profile/activity.tsx b/web/pages/[workspaceSlug]/me/profile/activity.tsx index cc1809a43..3b5e60f59 100644 --- a/web/pages/[workspaceSlug]/me/profile/activity.tsx +++ b/web/pages/[workspaceSlug]/me/profile/activity.tsx @@ -1,3 +1,4 @@ +import { ReactElement } from "react"; import useSWR from "swr"; import { useRouter } from "next/router"; import Link from "next/link"; @@ -18,10 +19,12 @@ import { ExternalLinkIcon, Loader } from "@plane/ui"; import { USER_ACTIVITY } from "constants/fetch-keys"; // helper import { timeAgo } from "helpers/date-time.helper"; +// type +import { NextPageWithLayout } from "types/app"; const userService = new UserService(); -const ProfileActivity = () => { +const ProfileActivityPage: NextPageWithLayout = () => { const router = useRouter(); const { workspaceSlug } = router.query; @@ -31,165 +34,169 @@ const ProfileActivity = () => { ); return ( - }> - - {userActivity ? ( -
-
-

Activity

-
-
-
    - {userActivity.results.map((activityItem: any) => { - if (activityItem.field === "comment") { - return ( -
    -
    -
    - {activityItem.field ? ( - activityItem.new_value === "restore" && ( - - ) - ) : activityItem.actor_detail.avatar && activityItem.actor_detail.avatar !== "" ? ( - {activityItem.actor_detail.display_name} - ) : ( -
    - {activityItem.actor_detail.display_name?.charAt(0)} -
    - )} + <> + {userActivity ? ( +
    +
    +

    Activity

    +
    +
    +
      + {userActivity.results.map((activityItem: any) => { + if (activityItem.field === "comment") { + return ( +
      +
      +
      + {activityItem.field ? ( + activityItem.new_value === "restore" && ( + + ) + ) : activityItem.actor_detail.avatar && activityItem.actor_detail.avatar !== "" ? ( + {activityItem.actor_detail.display_name} + ) : ( +
      + {activityItem.actor_detail.display_name?.charAt(0)} +
      + )} - - + + +
      +
      +
      +
      + {activityItem.actor_detail.is_bot + ? activityItem.actor_detail.first_name + " Bot" + : activityItem.actor_detail.display_name} +
      +

      + Commented {timeAgo(activityItem.created_at)} +

      -
      -
      -
      - {activityItem.actor_detail.is_bot - ? activityItem.actor_detail.first_name + " Bot" - : activityItem.actor_detail.display_name} -
      -

      - Commented {timeAgo(activityItem.created_at)} -

      -
      -
      - -
      +
      +
      - ); - } +
      + ); + } - const message = - activityItem.verb === "created" && - activityItem.field !== "cycles" && - activityItem.field !== "modules" && - activityItem.field !== "attachment" && - activityItem.field !== "link" && - activityItem.field !== "estimate" ? ( - - created{" "} - - - this issue. - - - - ) : activityItem.field ? ( - - ) : ( - "created the issue." - ); + const message = + activityItem.verb === "created" && + activityItem.field !== "cycles" && + activityItem.field !== "modules" && + activityItem.field !== "attachment" && + activityItem.field !== "link" && + activityItem.field !== "estimate" ? ( + + created{" "} + + + this issue. + + + + ) : activityItem.field ? ( + + ) : ( + "created the issue." + ); - if ("field" in activityItem && activityItem.field !== "updated_by") { - return ( -
    • -
      -
      - <> -
      -
      -
      -
      - {activityItem.field ? ( - activityItem.new_value === "restore" ? ( - - ) : ( - - ) - ) : activityItem.actor_detail.avatar && - activityItem.actor_detail.avatar !== "" ? ( - {activityItem.actor_detail.display_name} + if ("field" in activityItem && activityItem.field !== "updated_by") { + return ( +
    • +
      +
      + <> +
      +
      +
      +
      + {activityItem.field ? ( + activityItem.new_value === "restore" ? ( + ) : ( -
      - {activityItem.actor_detail.display_name?.charAt(0)} -
      - )} -
      + + ) + ) : activityItem.actor_detail.avatar && activityItem.actor_detail.avatar !== "" ? ( + {activityItem.actor_detail.display_name} + ) : ( +
      + {activityItem.actor_detail.display_name?.charAt(0)} +
      + )}
      -
      -
      - {activityItem.field === "archived_at" && activityItem.new_value !== "restore" ? ( - Plane - ) : activityItem.actor_detail.is_bot ? ( - - {activityItem.actor_detail.first_name} Bot - - ) : ( - - {activityItem.actor_detail.display_name} - - )}{" "} - {message}{" "} - {timeAgo(activityItem.created_at)} -
      +
      +
      +
      + {activityItem.field === "archived_at" && activityItem.new_value !== "restore" ? ( + Plane + ) : activityItem.actor_detail.is_bot ? ( + + {activityItem.actor_detail.first_name} Bot + + ) : ( + + {activityItem.actor_detail.display_name} + + )}{" "} + {message} {timeAgo(activityItem.created_at)}
      - -
      +
      +
      -
    • - ); - } - })} -
    -
    -
    - ) : ( - - - - - - - )} - +
    + + ); + } + })} +
+
+
+ ) : ( + + + + + + + )} + + ); +}; + +ProfileActivityPage.getLayout = function getLayout(page: ReactElement) { + return ( + }> + {page} ); }; -export default ProfileActivity; +export default ProfileActivityPage; diff --git a/web/pages/[workspaceSlug]/me/profile/index.tsx b/web/pages/[workspaceSlug]/me/profile/index.tsx index 1cb645cce..33813fa52 100644 --- a/web/pages/[workspaceSlug]/me/profile/index.tsx +++ b/web/pages/[workspaceSlug]/me/profile/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, ReactElement } from "react"; import { useRouter } from "next/router"; import Link from "next/link"; import { Controller, useForm } from "react-hook-form"; @@ -19,8 +19,8 @@ import { Button, CustomSelect, CustomSearchSelect, Input, Spinner } from "@plane // icons import { User2, UserCircle2 } from "lucide-react"; // types -import type { NextPage } from "next"; import type { IUser } from "types"; +import type { NextPageWithLayout } from "types/app"; // constants import { USER_ROLES } from "constants/workspace"; import { TIME_ZONES } from "constants/timezones"; @@ -38,7 +38,7 @@ const defaultValues: Partial = { const fileService = new FileService(); const userService = new UserService(); -const Profile: NextPage = () => { +const ProfilePage: NextPageWithLayout = () => { const [isRemoving, setIsRemoving] = useState(false); const [isImageUploadModalOpen, setIsImageUploadModalOpen] = useState(false); // router @@ -144,255 +144,261 @@ const Profile: NextPage = () => { })); return ( - }> - - setIsImageUploadModalOpen(false)} - isRemoving={isRemoving} - handleDelete={() => handleDelete(myProfile?.avatar, true)} - onSuccess={(url) => { - setValue("avatar", url); - handleSubmit(onSubmit)(); - setIsImageUploadModalOpen(false); - }} - value={watch("avatar") !== "" ? watch("avatar") : undefined} - userImage - /> - {myProfile ? ( -
-
-
- {myProfile?.first_name + setIsImageUploadModalOpen(false)} + isRemoving={isRemoving} + handleDelete={() => handleDelete(myProfile?.avatar, true)} + onSuccess={(url) => { + setValue("avatar", url); + handleSubmit(onSubmit)(); + setIsImageUploadModalOpen(false); + }} + value={watch("avatar") !== "" ? watch("avatar") : undefined} + userImage + /> + {myProfile ? ( + +
+
+ {myProfile?.first_name +
+
+
+ +
+
+
+ +
+ ( + { + setValue("cover_image", imageUrl); + }} + control={control} + value={watch("cover_image") ?? "https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"} + /> + )} /> -
-
-
- -
-
-
- -
- ( - { - setValue("cover_image", imageUrl); - }} - control={control} - value={watch("cover_image") ?? "https://images.unsplash.com/photo-1506383796573-caf02b4a79ab"} - /> - )} - /> -
-
- -
-
-
- {`${watch("first_name")} ${watch("last_name")}`} -
- {watch("email")} -
- - - - - - - View Profile - - -
- -
-
-

First Name

- ( - - )} - /> -
- -
-

Last Name

- - ( - - )} - /> -
- -
-

Email

- ( - - )} - /> -
- -
-

Role

- ( - - {USER_ROLES.map((item) => ( - - {item.label} - - ))} - - )} - /> - {errors.role && Please select a role} -
- -
-

Display name

- { - if (value.trim().length < 1) return "Display name can't be empty."; - - if (value.split(" ").length > 1) return "Display name can't have two consecutive spaces."; - - if (value.replace(/\s/g, "").length < 1) - return "Display name must be at least 1 characters long."; - - if (value.replace(/\s/g, "").length > 20) - return "Display name must be less than 20 characters long."; - - return true; - }, - }} - render={({ field: { value, onChange, ref } }) => ( - - )} - /> -
- -
-

Timezone

- - ( - t.value === value)?.label ?? value : "Select a timezone"} - options={timeZoneOptions} - onChange={onChange} - optionsClassName="w-full" - input - /> - )} - /> - {errors.role && Please select a role} -
- -
- -
- - ) : ( -
- + +
+
+
+ {`${watch("first_name")} ${watch("last_name")}`} +
+ {watch("email")} +
+ + + + + + + View Profile + + +
+ +
+
+

First Name

+ ( + + )} + /> +
+ +
+

Last Name

+ + ( + + )} + /> +
+ +
+

Email

+ ( + + )} + /> +
+ +
+

Role

+ ( + + {USER_ROLES.map((item) => ( + + {item.label} + + ))} + + )} + /> + {errors.role && Please select a role} +
+ +
+

Display name

+ { + if (value.trim().length < 1) return "Display name can't be empty."; + + if (value.split(" ").length > 1) return "Display name can't have two consecutive spaces."; + + if (value.replace(/\s/g, "").length < 1) + return "Display name must be at least 1 characters long."; + + if (value.replace(/\s/g, "").length > 20) + return "Display name must be less than 20 characters long."; + + return true; + }, + }} + render={({ field: { value, onChange, ref } }) => ( + + )} + /> +
+ +
+

Timezone

+ + ( + t.value === value)?.label ?? value : "Select a timezone"} + options={timeZoneOptions} + onChange={onChange} + optionsClassName="w-full" + input + /> + )} + /> + {errors.role && Please select a role} +
+ +
+ +
+
- )} - + + ) : ( +
+ +
+ )} + + ); +}; + +ProfilePage.getLayout = function getLayout(page: ReactElement) { + return ( + }> + {page} ); }; -export default Profile; +export default ProfilePage; diff --git a/web/pages/[workspaceSlug]/me/profile/preferences.tsx b/web/pages/[workspaceSlug]/me/profile/preferences.tsx index 1e2da7d9c..842740f7a 100644 --- a/web/pages/[workspaceSlug]/me/profile/preferences.tsx +++ b/web/pages/[workspaceSlug]/me/profile/preferences.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useState, ReactElement } from "react"; import { observer } from "mobx-react-lite"; import { useTheme } from "next-themes"; // hooks @@ -14,8 +14,10 @@ import { WorkspaceSettingHeader } from "components/headers"; import { Spinner } from "@plane/ui"; // constants import { I_THEME_OPTION, THEME_OPTIONS } from "constants/themes"; +// type +import { NextPageWithLayout } from "types/app"; -const ProfilePreferencesPage = observer(() => { +const ProfilePreferencesPage: NextPageWithLayout = observer(() => { const { user: userStore } = useMobxStore(); // states const [currentTheme, setCurrentTheme] = useState(null); @@ -45,32 +47,38 @@ const ProfilePreferencesPage = observer(() => { }; return ( - }> - - {userStore.currentUser ? ( -
-
-

Preferences

-
-
-
-

Theme

-

Select or customize your interface color scheme.

-
-
- -
-
- {userTheme?.theme === "custom" && } + <> + {userStore.currentUser ? ( +
+
+

Preferences

- ) : ( -
- +
+
+

Theme

+

Select or customize your interface color scheme.

+
+
+ +
- )} - - + {userTheme?.theme === "custom" && } +
+ ) : ( +
+ +
+ )} + ); }); +ProfilePreferencesPage.getLayout = function getLayout(page: ReactElement) { + return ( + }> + {page} + + ); +}; + export default ProfilePreferencesPage; diff --git a/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx b/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx index 36d5b47e6..0b1c3cba4 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/assigned.tsx @@ -1,5 +1,4 @@ -import React from "react"; -import type { NextPage } from "next"; +import React, { ReactElement } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; import { observer } from "mobx-react-lite"; @@ -13,10 +12,10 @@ import { ProfileIssuesKanBanLayout } from "components/issues/issue-layouts/kanba // hooks import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; - // types +import { NextPageWithLayout } from "types/app"; -const ProfileAssignedIssues: NextPage = observer(() => { +const ProfileAssignedIssuesPage: NextPageWithLayout = observer(() => { const { workspace: workspaceStore, project: projectStore, @@ -45,22 +44,28 @@ const ProfileAssignedIssues: NextPage = observer(() => { const activeLayout = profileIssueFiltersStore.userDisplayFilters.layout; return ( - }> - - {isLoading ? ( -
Loading...
- ) : ( -
- {activeLayout === "list" ? ( - - ) : activeLayout === "kanban" ? ( - - ) : null} -
- )} -
-
+ <> + {isLoading ? ( +
Loading...
+ ) : ( +
+ {activeLayout === "list" ? ( + + ) : activeLayout === "kanban" ? ( + + ) : null} +
+ )} + ); }); -export default ProfileAssignedIssues; +ProfileAssignedIssuesPage.getLayout = function getLayout(page: ReactElement) { + return ( + }> + {page} + + ); +}; + +export default ProfileAssignedIssuesPage; diff --git a/web/pages/[workspaceSlug]/profile/[userId]/created.tsx b/web/pages/[workspaceSlug]/profile/[userId]/created.tsx index 4d171e7d4..e9a90f6a1 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/created.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/created.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import { ReactElement } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; // store @@ -12,9 +12,9 @@ import { UserProfileHeader } from "components/headers"; import { ProfileIssuesListLayout } from "components/issues/issue-layouts/list/roots/profile-issues-root"; import { ProfileIssuesKanBanLayout } from "components/issues/issue-layouts/kanban/roots/profile-issues-root"; // types -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; -const ProfileCreatedIssues: NextPage = () => { +const ProfileCreatedIssuesPage: NextPageWithLayout = () => { const { workspace: workspaceStore, project: projectStore, @@ -39,23 +39,29 @@ const ProfileCreatedIssues: NextPage = () => { const activeLayout = profileIssueFiltersStore.userDisplayFilters.layout; + return ( + <> + {isLoading ? ( +
Loading...
+ ) : ( +
+ {activeLayout === "list" ? ( + + ) : activeLayout === "kanban" ? ( + + ) : null} +
+ )} + + ); +}; + +ProfileCreatedIssuesPage.getLayout = function getLayout(page: ReactElement) { return ( }> - - {isLoading ? ( -
Loading...
- ) : ( -
- {activeLayout === "list" ? ( - - ) : activeLayout === "kanban" ? ( - - ) : null} -
- )} -
+ {page}
); }; -export default observer(ProfileCreatedIssues); +export default observer(ProfileCreatedIssuesPage); diff --git a/web/pages/[workspaceSlug]/profile/[userId]/index.tsx b/web/pages/[workspaceSlug]/profile/[userId]/index.tsx index eb175b631..9f55f1cd9 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/index.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/index.tsx @@ -1,9 +1,6 @@ -import React from "react"; - +import { ReactElement } from "react"; import { useRouter } from "next/router"; - import useSWR from "swr"; - // services import { UserService } from "services/user.service"; // layouts @@ -19,8 +16,8 @@ import { ProfileWorkload, } from "components/profile"; // types -import type { NextPage } from "next"; import { IUserStateDistribution, TStateGroups } from "types"; +import { NextPageWithLayout } from "types/app"; // constants import { USER_PROFILE_DATA } from "constants/fetch-keys"; import { GROUP_CHOICES } from "constants/project"; @@ -28,7 +25,7 @@ import { GROUP_CHOICES } from "constants/project"; // services const userService = new UserService(); -const ProfileOverview: NextPage = () => { +const ProfileOverviewPage: NextPageWithLayout = () => { const router = useRouter(); const { workspaceSlug, userId } = router.query; @@ -44,21 +41,25 @@ const ProfileOverview: NextPage = () => { else return { state_group: key as TStateGroups, state_count: 0 }; }); + return ( +
+ + +
+ + +
+ +
+ ); +}; + +ProfileOverviewPage.getLayout = function getLayout(page: ReactElement) { return ( }> - -
- - -
- - -
- -
-
+ {page}
); }; -export default ProfileOverview; +export default ProfileOverviewPage; diff --git a/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx b/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx index 4efded65b..95efcab90 100644 --- a/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx +++ b/web/pages/[workspaceSlug]/profile/[userId]/subscribed.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import { ReactElement } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; // store @@ -12,9 +12,9 @@ import { UserProfileHeader } from "components/headers"; import { ProfileIssuesListLayout } from "components/issues/issue-layouts/list/roots/profile-issues-root"; import { ProfileIssuesKanBanLayout } from "components/issues/issue-layouts/kanban/roots/profile-issues-root"; // types -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; -const ProfileSubscribedIssues: NextPage = () => { +const ProfileSubscribedIssuesPage: NextPageWithLayout = () => { const { workspace: workspaceStore, project: projectStore, @@ -58,4 +58,12 @@ const ProfileSubscribedIssues: NextPage = () => { ); }; -export default observer(ProfileSubscribedIssues); +ProfileSubscribedIssuesPage.getLayout = function getLayout(page: ReactElement) { + return ( + }> + {page} + + ); +}; + +export default observer(ProfileSubscribedIssuesPage); diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx index d6d0c6859..cf0987edb 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/[archivedIssueId].tsx @@ -1,10 +1,6 @@ -import React, { useCallback, useEffect, useState } from "react"; - +import { useCallback, useEffect, useState, ReactElement } from "react"; import { useRouter } from "next/router"; - import useSWR, { mutate } from "swr"; - -// react-hook-form import { useForm } from "react-hook-form"; // services import { IssueService, IssueArchiveService } from "services/issue"; @@ -22,7 +18,7 @@ import { ArchiveIcon, Loader } from "@plane/ui"; import { History } from "lucide-react"; // types import { IIssue } from "types"; -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; // fetch-keys import { PROJECT_ISSUES_ACTIVITY, ISSUE_DETAILS } from "constants/fetch-keys"; @@ -42,12 +38,13 @@ const defaultValues: Partial = { const issueService = new IssueService(); const issueArchiveService = new IssueArchiveService(); -const ArchivedIssueDetailsPage: NextPage = () => { - const [isRestoring, setIsRestoring] = useState(false); - +const ArchivedIssueDetailsPage: NextPageWithLayout = () => { + // router const router = useRouter(); const { workspaceSlug, projectId, archivedIssueId } = router.query; - + // states + const [isRestoring, setIsRestoring] = useState(false); + // hooks const { user } = useUserAuth(); const { setToastAlert } = useToast(); @@ -136,7 +133,7 @@ const ArchivedIssueDetailsPage: NextPage = () => { }; return ( - } withProjectWrapper> + <> {issueDetails && projectId ? (
@@ -187,6 +184,14 @@ const ArchivedIssueDetailsPage: NextPage = () => {
)} + + ); +}; + +ArchivedIssueDetailsPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} ); }; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx index 75e92448e..cb0db2f78 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/archived-issues/index.tsx @@ -1,5 +1,5 @@ +import { ReactElement } from "react"; import { useRouter } from "next/router"; - // layouts import { AppLayout } from "layouts/app-layout"; // contexts @@ -10,33 +10,38 @@ import { ProjectArchivedIssuesHeader } from "components/headers"; // icons import { X } from "lucide-react"; // types -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; -const ProjectArchivedIssues: NextPage = () => { +const ProjectArchivedIssuesPage: NextPageWithLayout = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; + return ( +
+
+ +
+ {/* */} +
+ ); +}; + +ProjectArchivedIssuesPage.getLayout = function getLayout(page: ReactElement) { return ( } withProjectWrapper> -
-
- -
- {/* */} -
+ {page}
); }; -export default ProjectArchivedIssues; +export default ProjectArchivedIssuesPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx index a5a0e922b..775cfcd11 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/[cycleId].tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import { useState, ReactElement } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; // mobx store @@ -22,10 +22,11 @@ import { EmptyState } from "components/common"; import emptyCycle from "public/empty-state/cycle.svg"; // types import { ISearchIssueResponse } from "types"; +import { NextPageWithLayout } from "types/app"; const issueService = new IssueService(); -const SingleCycle: React.FC = () => { +const CycleDetailPage: NextPageWithLayout = () => { const [cycleIssuesListModal, setCycleIssuesListModal] = useState(false); const router = useRouter(); @@ -75,7 +76,7 @@ const SingleCycle: React.FC = () => { }; return ( - } withProjectWrapper> + <> {/* TODO: Update logic to bulk add issues to a cycle */} {
)} + + ); +}; + +CycleDetailPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} ); }; -export default SingleCycle; +export default CycleDetailPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx index 4366841ca..095cad0e7 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx @@ -1,4 +1,4 @@ -import { Fragment, useCallback, useEffect, useState } from "react"; +import { Fragment, useCallback, useEffect, useState, ReactElement } from "react"; import { useRouter } from "next/router"; import { Tab } from "@headlessui/react"; import useSWR from "swr"; @@ -13,19 +13,20 @@ import { CyclesHeader } from "components/headers"; import { CyclesView, ActiveCycleDetails, CycleCreateUpdateModal } from "components/cycles"; // ui import { EmptyState } from "components/common"; +import { Tooltip } from "@plane/ui"; // images import emptyCycle from "public/empty-state/cycle.svg"; // types import { TCycleView, TCycleLayout } from "types"; -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; // constants import { CYCLE_TAB_LIST, CYCLE_VIEWS } from "constants/cycle"; // lib cookie import { setLocalStorage, getLocalStorage } from "lib/local-storage"; -import { Tooltip } from "@plane/ui"; +// helpers import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper"; -const ProjectCyclesPage: NextPage = observer(() => { +const ProjectCyclesPage: NextPageWithLayout = observer(() => { const [createModal, setCreateModal] = useState(false); // store const { project: projectStore, cycle: cycleStore } = useMobxStore(); @@ -85,7 +86,7 @@ const ProjectCyclesPage: NextPage = observer(() => { const cycleLayout = cycleStore?.cycleLayout; return ( - } withProjectWrapper> + <> { )} - + ); }); +ProjectCyclesPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} + + ); +}; + export default ProjectCyclesPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx index feaeea20c..fcde49524 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/draft-issues/index.tsx @@ -1,3 +1,4 @@ +import { ReactElement } from "react"; import { useRouter } from "next/router"; // layouts import { AppLayout } from "layouts/app-layout"; @@ -8,32 +9,38 @@ import { ProjectDraftIssueHeader } from "components/headers"; // icons import { X, PenSquare } from "lucide-react"; // types -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; -const ProjectDraftIssues: NextPage = () => { +const ProjectDraftIssuesPage: NextPageWithLayout = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; + return ( +
+
+ +
+
+ ); +}; + +ProjectDraftIssuesPage.getLayout = function getLayout(page: ReactElement) { return ( } withProjectWrapper> -
-
- -
-
+ {page}
); }; -export default ProjectDraftIssues; +export default ProjectDraftIssuesPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx index f1c6e2e4c..e10f76c48 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/inbox/[inboxId].tsx @@ -1,6 +1,5 @@ +import { ReactElement } from "react"; import { useRouter } from "next/router"; - -import { NextPage } from "next"; import useSWR from "swr"; // hooks import { useMobxStore } from "lib/mobx/store-provider"; @@ -9,8 +8,10 @@ import { AppLayout } from "layouts/app-layout"; // components import { InboxActionsHeader, InboxMainContent, InboxIssuesListSidebar } from "components/inbox"; import { ProjectInboxHeader } from "components/headers"; +// types +import { NextPageWithLayout } from "types/app"; -const ProjectInbox: NextPage = () => { +const ProjectInboxPage: NextPageWithLayout = () => { const router = useRouter(); const { workspaceSlug, projectId, inboxId } = router.query; @@ -24,18 +25,24 @@ const ProjectInbox: NextPage = () => { ); return ( - } withProjectWrapper> -
- -
- -
- -
+
+ +
+ +
+
+
+ ); +}; + +ProjectInboxPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} ); }; -export default ProjectInbox; +export default ProjectInboxPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx index c8e70bdb7..32c11345e 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx @@ -1,9 +1,6 @@ -import React, { useCallback, useEffect } from "react"; - +import React, { useCallback, useEffect, ReactElement } from "react"; import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; - -// react-hook-form import { useForm } from "react-hook-form"; // services import { IssueService } from "services/issue"; @@ -21,10 +18,9 @@ import { Loader } from "@plane/ui"; import emptyIssue from "public/empty-state/issue.svg"; // types import { IIssue } from "types"; -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; // fetch-keys import { PROJECT_ISSUES_ACTIVITY, ISSUE_DETAILS } from "constants/fetch-keys"; -// helper const defaultValues: Partial = { description: "", @@ -42,10 +38,10 @@ const defaultValues: Partial = { // services const issueService = new IssueService(); -const IssueDetailsPage: NextPage = () => { +const IssueDetailsPage: NextPageWithLayout = () => { + // router const router = useRouter(); const { workspaceSlug, projectId, issueId } = router.query; - // console.log(workspaceSlug, "workspaceSlug") const { user } = useUserAuth(); @@ -111,7 +107,8 @@ const IssueDetailsPage: NextPage = () => { }, [issueDetails, reset, issueId]); return ( - } withProjectWrapper> + <> + {" "} {error ? ( {
)} + + ); +}; + +IssueDetailsPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} ); }; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx index 0e1f673ad..ceb75b43c 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/issues/index.tsx @@ -1,17 +1,24 @@ +import { ReactElement } from "react"; // components import { ProjectLayoutRoot } from "components/issues"; import { ProjectIssuesHeader } from "components/headers"; // types -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; // layouts import { AppLayout } from "layouts/app-layout"; -const ProjectIssues: NextPage = () => ( - } withProjectWrapper> -
- -
-
+const ProjectIssuesPage: NextPageWithLayout = () => ( +
+ +
); -export default ProjectIssues; +ProjectIssuesPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} + + ); +}; + +export default ProjectIssuesPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx index 8bc78f512..a7fd7307a 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/modules/[moduleId].tsx @@ -1,9 +1,8 @@ -import React, { useState } from "react"; +import { useState, ReactElement } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; // mobx store import { useMobxStore } from "lib/mobx/store-provider"; - // services import { ModuleService } from "services/module.service"; // hooks @@ -22,23 +21,23 @@ import { EmptyState } from "components/common"; // assets import emptyModule from "public/empty-state/module.svg"; // types -import { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; import { ISearchIssueResponse } from "types"; const moduleService = new ModuleService(); -const ModuleIssuesPage: NextPage = () => { +const ModuleIssuesPage: NextPageWithLayout = () => { + // states const [moduleIssuesListModal, setModuleIssuesListModal] = useState(false); - + // router const router = useRouter(); const { workspaceSlug, projectId, moduleId } = router.query; - + // store const { module: moduleStore } = useMobxStore(); - + // hooks const { user } = useUser(); - const { setToastAlert } = useToast(); - + // local storage const { setValue, storedValue } = useLocalStorage("module_sidebar_collapsed", "false"); const isSidebarCollapsed = storedValue ? (storedValue === "true" ? true : false) : false; @@ -78,45 +77,51 @@ const ModuleIssuesPage: NextPage = () => { return ( <> - } withProjectWrapper> - {/* TODO: Update logic to bulk add issues to a cycle */} - setModuleIssuesListModal(false)} - searchParams={{ module: true }} - handleOnSubmit={handleAddIssuesToModule} + {/* TODO: Update logic to bulk add issues to a cycle */} + setModuleIssuesListModal(false)} + searchParams={{ module: true }} + handleOnSubmit={handleAddIssuesToModule} + /> + {error ? ( + router.push(`/${workspaceSlug}/projects/${projectId}/modules`), + }} /> - {error ? ( - router.push(`/${workspaceSlug}/projects/${projectId}/modules`), - }} - /> - ) : ( -
-
- -
- {moduleId && !isSidebarCollapsed && ( -
- -
- )} + ) : ( +
+
+
- )} - + {moduleId && !isSidebarCollapsed && ( +
+ +
+ )} +
+ )} ); }; +ModuleIssuesPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} + + ); +}; + export default ModuleIssuesPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx index 9ef9b13c4..3ec3bf7f6 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/modules/index.tsx @@ -1,15 +1,20 @@ -import React from "react"; -import { NextPage } from "next"; +import { ReactElement } from "react"; // layouts import { AppLayout } from "layouts/app-layout"; // components import { ModulesListView } from "components/modules"; import { ModulesListHeader } from "components/headers"; +// types +import { NextPageWithLayout } from "types/app"; -const ProjectModules: NextPage = () => ( - } withProjectWrapper> - - -); +const ProjectModulesPage: NextPageWithLayout = () => ; -export default ProjectModules; +ProjectModulesPage.getLayout = function getLayout(page: ReactElement) { + return ( + } withProjectWrapper> + {page} + + ); +}; + +export default ProjectModulesPage; diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx index cacdc7319..d8bd19275 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/pages/[pageId].tsx @@ -1,18 +1,10 @@ -import React, { useEffect, useRef, useState } from "react"; - +import React, { useEffect, useRef, useState, ReactElement } from "react"; import { useRouter } from "next/router"; - import useSWR, { mutate } from "swr"; - -// react-hook-form import { Controller, useForm } from "react-hook-form"; -// headless ui import { Popover, Transition } from "@headlessui/react"; -// react-color import { TwitterPicker } from "react-color"; -// react-beautiful-dnd import { DragDropContext, DropResult } from "react-beautiful-dnd"; -import StrictModeDroppable from "components/dnd/StrictModeDroppable"; // services import { ProjectService } from "services/project"; import { PageService } from "services/page.service"; @@ -23,6 +15,7 @@ import useUser from "hooks/use-user"; // layouts import { AppLayout } from "layouts/app-layout"; // components +import StrictModeDroppable from "components/dnd/StrictModeDroppable"; import { CreateUpdateBlockInline, SinglePageBlock } from "components/pages"; import { CreateLabelModal } from "components/labels"; import { CreateBlock } from "components/pages/create-block"; @@ -39,7 +32,7 @@ import { render24HourFormatTime, renderShortDate } from "helpers/date-time.helpe import { copyTextToClipboard } from "helpers/string.helper"; import { orderArrayBy } from "helpers/array.helper"; // types -import type { NextPage } from "next"; +import { NextPageWithLayout } from "types/app"; import { IIssueLabels, IPage, IPageBlock, IProjectMember } from "types"; // fetch-keys import { @@ -55,7 +48,7 @@ const projectService = new ProjectService(); const pageService = new PageService(); const issueLabelService = new IssueLabelService(); -const SinglePage: NextPage = () => { +const PageDetailsPage: NextPageWithLayout = () => { const [createBlockForm, setCreateBlockForm] = useState(false); const [labelModal, setLabelModal] = useState(false); const [showBlock, setShowBlock] = useState(false); @@ -302,7 +295,7 @@ const SinglePage: NextPage = () => { }, [memberDetails]); return ( - } withProjectWrapper> + <> {error ? ( { ( + render={() => (