diff --git a/web/components/issues/issue-detail/root.tsx b/web/components/issues/issue-detail/root.tsx
index 92badf4b2..1fab25d96 100644
--- a/web/components/issues/issue-detail/root.tsx
+++ b/web/components/issues/issue-detail/root.tsx
@@ -9,7 +9,7 @@ import { EmptyState } from "components/common";
// images
import emptyIssue from "public/empty-state/issue.svg";
// hooks
-import { useEventTracker, useIssueDetail, useIssues, useUser } from "hooks/store";
+import { useApplication, useEventTracker, useIssueDetail, useIssues, useUser } from "hooks/store";
import useToast from "hooks/use-toast";
// types
import { TIssue } from "@plane/types";
@@ -17,6 +17,7 @@ import { TIssue } from "@plane/types";
import { EUserProjectRoles } from "constants/project";
import { EIssuesStoreType } from "constants/issue";
import { ISSUE_UPDATED, ISSUE_DELETED } from "constants/event-tracker";
+import { observer } from "mobx-react";
export type TIssueOperations = {
fetch: (workspaceSlug: string, projectId: string, issueId: string) => Promise
;
@@ -52,7 +53,7 @@ export type TIssueDetailRoot = {
is_archived?: boolean;
};
-export const IssueDetailRoot: FC = (props) => {
+export const IssueDetailRoot: FC = observer((props) => {
const { workspaceSlug, projectId, issueId, is_archived = false } = props;
// router
const router = useRouter();
@@ -76,6 +77,7 @@ export const IssueDetailRoot: FC = (props) => {
const {
membership: { currentProjectRole },
} = useUser();
+ const { theme: themeStore } = useApplication();
const issueOperations: TIssueOperations = useMemo(
() => ({
@@ -347,8 +349,8 @@ export const IssueDetailRoot: FC = (props) => {
}}
/>
) : (
-
-
+
+
= (props) => {
is_editable={!is_archived && is_editable}
/>
-
+
= (props) => {
>
);
-};
+});
diff --git a/web/components/issues/issue-detail/sidebar.tsx b/web/components/issues/issue-detail/sidebar.tsx
index 668d3538f..c78bbe942 100644
--- a/web/components/issues/issue-detail/sidebar.tsx
+++ b/web/components/issues/issue-detail/sidebar.tsx
@@ -187,9 +187,8 @@ export const IssueDetailsSidebar: React.FC = observer((props) => {
buttonVariant={issue?.assignee_ids?.length > 1 ? "transparent-without-text" : "transparent-with-text"}
className="w-3/5 flex-grow group"
buttonContainerClassName="w-full text-left"
- buttonClassName={`text-sm justify-between ${
- issue?.assignee_ids.length > 0 ? "" : "text-custom-text-400"
- }`}
+ buttonClassName={`text-sm justify-between ${issue?.assignee_ids.length > 0 ? "" : "text-custom-text-400"
+ }`}
hideIcon={issue.assignee_ids?.length === 0}
dropdownArrow
dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline"
@@ -233,8 +232,8 @@ export const IssueDetailsSidebar: React.FC = observer((props) => {
buttonClassName={`text-sm ${issue?.start_date ? "" : "text-custom-text-400"}`}
hideIcon
clearIconClassName="h-3 w-3 hidden group-hover:inline"
- // TODO: add this logic
- // showPlaceholderIcon
+ // TODO: add this logic
+ // showPlaceholderIcon
/>
@@ -259,8 +258,8 @@ export const IssueDetailsSidebar: React.FC
= observer((props) => {
buttonClassName={`text-sm ${issue?.target_date ? "" : "text-custom-text-400"}`}
hideIcon
clearIconClassName="h-3 w-3 hidden group-hover:inline"
- // TODO: add this logic
- // showPlaceholderIcon
+ // TODO: add this logic
+ // showPlaceholderIcon
/>
diff --git a/web/components/issues/issue-detail/subscription.tsx b/web/components/issues/issue-detail/subscription.tsx
index b57e75bed..8d05140b3 100644
--- a/web/components/issues/issue-detail/subscription.tsx
+++ b/web/components/issues/issue-detail/subscription.tsx
@@ -1,5 +1,5 @@
import { FC, useState } from "react";
-import { Bell } from "lucide-react";
+import { Bell, BellOff } from "lucide-react";
import { observer } from "mobx-react-lite";
// UI
import { Button } from "@plane/ui";
@@ -52,12 +52,20 @@ export const IssueSubscription: FC
= observer((props) => {
}
+ prependIcon={subscription?.subscribed ?
:
}
variant="outline-primary"
className="hover:!bg-custom-primary-100/20"
onClick={handleSubscription}
>
- {loading ? "Loading..." : subscription?.subscribed ? "Unsubscribe" : "Subscribe"}
+ {loading ? (
+
+ Loading...
+
+ ) : subscription?.subscribed ? (
+
Unsubscribe
+ ) : (
+
Subscribe
+ )}
);
diff --git a/web/components/issues/issue-layouts/spreadsheet/columns/header-column.tsx b/web/components/issues/issue-layouts/spreadsheet/columns/header-column.tsx
index 73478c6ac..b7f432385 100644
--- a/web/components/issues/issue-layouts/spreadsheet/columns/header-column.tsx
+++ b/web/components/issues/issue-layouts/spreadsheet/columns/header-column.tsx
@@ -66,14 +66,14 @@ export const HeaderColumn = (props: Props) => {
}
onMenuClose={onClose}
placement="bottom-end"
+ closeOnSelect
>
handleOrderBy(propertyDetails.ascendingOrderKey, property)}>
@@ -87,11 +87,10 @@ export const HeaderColumn = (props: Props) => {
handleOrderBy(propertyDetails.descendingOrderKey, property)}>
diff --git a/web/components/pages/create-update-page-modal.tsx b/web/components/pages/create-update-page-modal.tsx
index 31cee45b3..e81a0040b 100644
--- a/web/components/pages/create-update-page-modal.tsx
+++ b/web/components/pages/create-update-page-modal.tsx
@@ -104,7 +104,7 @@ export const CreateUpdatePageModal: FC
= (props) => {
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
-
+
diff --git a/web/components/pages/page-form.tsx b/web/components/pages/page-form.tsx
index 79d378c59..4f5874e5f 100644
--- a/web/components/pages/page-form.tsx
+++ b/web/components/pages/page-form.tsx
@@ -67,7 +67,7 @@ export const PageForm: React.FC = (props) => {
-
+
= (props) => {
)}
/>
-
+
diff --git a/web/components/pages/pages-list/list-item.tsx b/web/components/pages/pages-list/list-item.tsx
index 03133d5df..6b1a4793d 100644
--- a/web/components/pages/pages-list/list-item.tsx
+++ b/web/components/pages/pages-list/list-item.tsx
@@ -155,7 +155,7 @@ export const PagesListItem: FC
= observer(({ pageId, projectId }
setDeletePageModal(false)} pageId={pageId} />
-
+
diff --git a/web/components/pages/pages-list/recent-pages-list.tsx b/web/components/pages/pages-list/recent-pages-list.tsx
index 960d5253b..e998629c6 100644
--- a/web/components/pages/pages-list/recent-pages-list.tsx
+++ b/web/components/pages/pages-list/recent-pages-list.tsx
@@ -52,7 +52,7 @@ export const RecentPagesList: FC = observer(() => {
return (
-
+
{replaceUnderscoreIfSnakeCase(key)}
diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx
index 6be784368..64f43939e 100644
--- a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx
+++ b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx
@@ -1,4 +1,4 @@
-import React, { ReactElement } from "react";
+import React, { ReactElement, useEffect } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
import { observer } from "mobx-react-lite";
@@ -12,7 +12,7 @@ import { Loader } from "@plane/ui";
// types
import { NextPageWithLayout } from "lib/types";
// fetch-keys
-import { useIssueDetail } from "hooks/store";
+import { useApplication, useIssueDetail } from "hooks/store";
const IssueDetailsPage: NextPageWithLayout = observer(() => {
// router
@@ -23,6 +23,7 @@ const IssueDetailsPage: NextPageWithLayout = observer(() => {
fetchIssue,
issue: { getIssueById },
} = useIssueDetail();
+ const { theme: themeStore } = useApplication();
const { isLoading } = useSWR(
workspaceSlug && projectId && issueId ? `ISSUE_DETAIL_${workspaceSlug}_${projectId}_${issueId}` : null,
@@ -34,6 +35,21 @@ const IssueDetailsPage: NextPageWithLayout = observer(() => {
const issue = getIssueById(issueId?.toString() || "") || undefined;
const issueLoader = !issue || isLoading ? true : false;
+ useEffect(() => {
+ const handleToggleIssueDetailSidebar = () => {
+ if (window && window.innerWidth < 768) {
+ themeStore.toggleIssueDetailSidebar(true);
+ }
+ if (window && themeStore.issueDetailSidebarCollapsed && window.innerWidth >= 768) {
+ themeStore.toggleIssueDetailSidebar(false);
+ }
+ };
+
+ window.addEventListener("resize", handleToggleIssueDetailSidebar);
+ handleToggleIssueDetailSidebar();
+ return () => window.removeEventListener("resize", handleToggleIssueDetailSidebar);
+ }, [themeStore]);
+
return (
<>
{issueLoader ? (
diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx
index b0ab29285..1f3204045 100644
--- a/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx
+++ b/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx
@@ -103,6 +103,25 @@ const ProjectPagesPage: NextPageWithLayout = observer(() => {
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER;
+ const mobileTabList = (
+
+
+ {PAGE_TABS_LIST.map((tab) => (
+
+ `text-sm outline-none pb-3 ${
+ selected ? "border-custom-primary-100 text-custom-primary-100 border-b" : ""
+ }`
+ }
+ >
+ {tab.title}
+
+ ))}
+
+
+ );
+
if (loader || archivedPageLoader)
return (
@@ -121,8 +140,8 @@ const ProjectPagesPage: NextPageWithLayout = observer(() => {
projectId={projectId.toString()}
/>
)}
-
-
+
+
Pages
{
}
}}
>
-
+ {mobileTabList}
+
{PAGE_TABS_LIST.map((tab) => (
void;
setTheme: (theme: any) => void;
toggleProfileSidebar: (collapsed?: boolean) => void;
toggleWorkspaceAnalyticsSidebar: (collapsed?: boolean) => void;
+ toggleIssueDetailSidebar: (collapsed?: boolean) => void;
}
export class ThemeStore implements IThemeStore {
@@ -22,6 +24,7 @@ export class ThemeStore implements IThemeStore {
theme: string | null = null;
profileSidebarCollapsed: boolean | undefined = undefined;
workspaceAnalyticsSidebarCollapsed: boolean | undefined = undefined;
+ issueDetailSidebarCollapsed: boolean | undefined = undefined;
// root store
rootStore;
@@ -32,11 +35,13 @@ export class ThemeStore implements IThemeStore {
theme: observable.ref,
profileSidebarCollapsed: observable.ref,
workspaceAnalyticsSidebarCollapsed: observable.ref,
+ issueDetailSidebarCollapsed: observable.ref,
// action
toggleSidebar: action,
setTheme: action,
toggleProfileSidebar: action,
- toggleWorkspaceAnalyticsSidebar: action
+ toggleWorkspaceAnalyticsSidebar: action,
+ toggleIssueDetailSidebar: action,
// computed
});
// root store
@@ -82,6 +87,15 @@ export class ThemeStore implements IThemeStore {
localStorage.setItem("workspace_analytics_sidebar_collapsed", this.workspaceAnalyticsSidebarCollapsed.toString());
};
+ toggleIssueDetailSidebar = (collapsed?: boolean) => {
+ if(collapsed === undefined) {
+ this.issueDetailSidebarCollapsed = !this.issueDetailSidebarCollapsed;
+ } else {
+ this.issueDetailSidebarCollapsed = collapsed;
+ }
+ localStorage.setItem("issue_detail_sidebar_collapsed", this.issueDetailSidebarCollapsed.toString());
+ }
+
/**
* Sets the user theme and applies it to the platform
* @param _theme