From 3a14f19c993933415f79e98648877dbf995cd098 Mon Sep 17 00:00:00 2001 From: Ramesh Kumar Chandra <31303617+rameshkumarchandra@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:52:25 +0530 Subject: [PATCH] style: responsive analytics (#3604) --- .../custom-analytics/custom-analytics.tsx | 28 +++++++---- .../analytics/custom-analytics/select-bar.tsx | 5 +- .../sidebar/projects-list.tsx | 4 +- .../sidebar/sidebar-header.tsx | 6 +-- .../custom-analytics/sidebar/sidebar.tsx | 46 +++++++++---------- .../analytics/project-modal/main-content.tsx | 7 ++- web/components/headers/user-profile.tsx | 2 +- .../headers/workspace-analytics.tsx | 35 ++++++++++++-- web/components/profile/sidebar.tsx | 16 +++---- web/pages/[workspaceSlug]/analytics.tsx | 15 ++++-- web/store/application/theme.store.ts | 18 ++++++++ 11 files changed, 118 insertions(+), 64 deletions(-) diff --git a/web/components/analytics/custom-analytics/custom-analytics.tsx b/web/components/analytics/custom-analytics/custom-analytics.tsx index a3c083b02..0c3ec8925 100644 --- a/web/components/analytics/custom-analytics/custom-analytics.tsx +++ b/web/components/analytics/custom-analytics/custom-analytics.tsx @@ -10,6 +10,8 @@ import { CustomAnalyticsSelectBar, CustomAnalyticsMainContent, CustomAnalyticsSi import { IAnalyticsParams } from "@plane/types"; // fetch-keys import { ANALYTICS } from "constants/fetch-keys"; +import { cn } from "helpers/common.helper"; +import { useApplication } from "hooks/store"; type Props = { additionalParams?: Partial; @@ -46,11 +48,13 @@ export const CustomAnalytics: React.FC = observer((props) => { workspaceSlug ? () => analyticsService.getAnalytics(workspaceSlug.toString(), params) : null ); + const { theme: themeStore } = useApplication(); + const isProjectLevel = projectId ? true : false; return ( -
-
+
+
= observer((props) => {
- + +
+ +
); }); diff --git a/web/components/analytics/custom-analytics/select-bar.tsx b/web/components/analytics/custom-analytics/select-bar.tsx index 19f83e40b..31acb8471 100644 --- a/web/components/analytics/custom-analytics/select-bar.tsx +++ b/web/components/analytics/custom-analytics/select-bar.tsx @@ -22,9 +22,8 @@ export const CustomAnalyticsSelectBar: React.FC = observer((props) => { return (
{!isProjectLevel && (
diff --git a/web/components/analytics/custom-analytics/sidebar/projects-list.tsx b/web/components/analytics/custom-analytics/sidebar/projects-list.tsx index d09e8def4..f7ba07b75 100644 --- a/web/components/analytics/custom-analytics/sidebar/projects-list.tsx +++ b/web/components/analytics/custom-analytics/sidebar/projects-list.tsx @@ -17,9 +17,9 @@ export const CustomAnalyticsSidebarProjectsList: React.FC = observer((pro const { getProjectById } = useProject(); return ( -
+

Selected Projects

-
+
{projectIds.map((projectId) => { const project = getProjectById(projectId); diff --git a/web/components/analytics/custom-analytics/sidebar/sidebar-header.tsx b/web/components/analytics/custom-analytics/sidebar/sidebar-header.tsx index 4a18011d1..ee677fe91 100644 --- a/web/components/analytics/custom-analytics/sidebar/sidebar-header.tsx +++ b/web/components/analytics/custom-analytics/sidebar/sidebar-header.tsx @@ -26,7 +26,7 @@ export const CustomAnalyticsSidebarHeader = observer(() => { <> {projectId ? ( cycleDetails ? ( -
+

Analytics for {cycleDetails.name}

@@ -52,7 +52,7 @@ export const CustomAnalyticsSidebarHeader = observer(() => {
) : moduleDetails ? ( -
+

Analytics for {moduleDetails.name}

@@ -78,7 +78,7 @@ export const CustomAnalyticsSidebarHeader = observer(() => {
) : ( -
+
{projectDetails?.emoji ? (
{renderEmoji(projectDetails.emoji)}
diff --git a/web/components/analytics/custom-analytics/sidebar/sidebar.tsx b/web/components/analytics/custom-analytics/sidebar/sidebar.tsx index 59013a3e3..c2e12dc3c 100644 --- a/web/components/analytics/custom-analytics/sidebar/sidebar.tsx +++ b/web/components/analytics/custom-analytics/sidebar/sidebar.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import { mutate } from "swr"; @@ -19,18 +19,18 @@ import { renderFormattedDate } from "helpers/date-time.helper"; import { IAnalyticsParams, IAnalyticsResponse, IExportAnalyticsFormData, IWorkspace } from "@plane/types"; // fetch-keys import { ANALYTICS } from "constants/fetch-keys"; +import { cn } from "helpers/common.helper"; type Props = { analytics: IAnalyticsResponse | undefined; params: IAnalyticsParams; - fullScreen: boolean; isProjectLevel: boolean; }; const analyticsService = new AnalyticsService(); export const CustomAnalyticsSidebar: React.FC = observer((props) => { - const { analytics, params, fullScreen, isProjectLevel = false } = props; + const { analytics, params, isProjectLevel = false } = props; // router const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId } = router.query; @@ -138,18 +138,14 @@ export const CustomAnalyticsSidebar: React.FC = observer((props) => { const selectedProjects = params.project && params.project.length > 0 ? params.project : workspaceProjectIds; + return ( -
- {analytics ? analytics.total : "..."} Issues + {analytics ? analytics.total : "..."}
Issues
{isProjectLevel && (
@@ -158,36 +154,36 @@ export const CustomAnalyticsSidebar: React.FC = observer((props) => { (cycleId ? cycleDetails?.created_at : moduleId - ? moduleDetails?.created_at - : projectDetails?.created_at) ?? "" + ? moduleDetails?.created_at + : projectDetails?.created_at) ?? "" )}
)}
-
- {fullScreen ? ( - <> - {!isProjectLevel && selectedProjects && selectedProjects.length > 0 && ( - - )} - - - ) : null} + +
+ <> + {!isProjectLevel && selectedProjects && selectedProjects.length > 0 && ( + + )} + +
-
+ +
diff --git a/web/components/analytics/project-modal/main-content.tsx b/web/components/analytics/project-modal/main-content.tsx index 09423e6dd..a04a43260 100644 --- a/web/components/analytics/project-modal/main-content.tsx +++ b/web/components/analytics/project-modal/main-content.tsx @@ -20,16 +20,15 @@ export const ProjectAnalyticsModalMainContent: React.FC = observer((props return ( - + {ANALYTICS_TABS.map((tab) => ( - `rounded-3xl border border-custom-border-200 px-4 py-2 text-xs hover:bg-custom-background-80 ${ - selected ? "bg-custom-background-80" : "" + `rounded-0 w-full md:w-max md:rounded-3xl border-b md:border border-custom-border-200 focus:outline-none px-0 md:px-4 py-2 text-xs hover:bg-custom-background-80 ${selected ? "border-custom-primary-100 text-custom-primary-100 md:bg-custom-background-80 md:text-custom-text-200 md:border-custom-border-200" : "border-transparent" }` } - onClick={() => {}} + onClick={() => { }} > {tab.title} diff --git a/web/components/headers/user-profile.tsx b/web/components/headers/user-profile.tsx index f933d4dfa..30bc5b2a9 100644 --- a/web/components/headers/user-profile.tsx +++ b/web/components/headers/user-profile.tsx @@ -64,7 +64,7 @@ export const UserProfileHeader: FC = observer((props) => { ))} - + }
); -}; +}); diff --git a/web/components/profile/sidebar.tsx b/web/components/profile/sidebar.tsx index b356b5adb..107c1f528 100644 --- a/web/components/profile/sidebar.tsx +++ b/web/components/profile/sidebar.tsx @@ -30,7 +30,7 @@ export const ProfileSidebar = observer(() => { const { workspaceSlug, userId } = router.query; // store hooks const { currentUser } = useUser(); - const { theme: themStore } = useApplication(); + const { theme: themeStore } = useApplication(); const ref = useRef(null); const { data: userProjectsData } = useSWR( @@ -41,9 +41,9 @@ export const ProfileSidebar = observer(() => { ); useOutsideClickDetector(ref, () => { - if (themStore.profileSidebarCollapsed === false) { + if (themeStore.profileSidebarCollapsed === false) { if (window.innerWidth < 768) { - themStore.toggleProfileSidebar(); + themeStore.toggleProfileSidebar(); } } }); @@ -62,22 +62,22 @@ export const ProfileSidebar = observer(() => { useEffect(() => { const handleToggleProfileSidebar = () => { if (window && window.innerWidth < 768) { - themStore.toggleProfileSidebar(true); + themeStore.toggleProfileSidebar(true); } - if (window && themStore.profileSidebarCollapsed && window.innerWidth >= 768) { - themStore.toggleProfileSidebar(false); + if (window && themeStore.profileSidebarCollapsed && window.innerWidth >= 768) { + themeStore.toggleProfileSidebar(false); } }; window.addEventListener("resize", handleToggleProfileSidebar); handleToggleProfileSidebar(); return () => window.removeEventListener("resize", handleToggleProfileSidebar); - }, [themStore]); + }, [themeStore]); return (
{userProjectsData ? ( <> diff --git a/web/pages/[workspaceSlug]/analytics.tsx b/web/pages/[workspaceSlug]/analytics.tsx index 71173c2c2..d4cb28e6f 100644 --- a/web/pages/[workspaceSlug]/analytics.tsx +++ b/web/pages/[workspaceSlug]/analytics.tsx @@ -15,8 +15,11 @@ import { ANALYTICS_TABS } from "constants/analytics"; import { EUserWorkspaceRoles } from "constants/workspace"; // type import { NextPageWithLayout } from "lib/types"; +import { useRouter } from "next/router"; const AnalyticsPage: NextPageWithLayout = observer(() => { + const router = useRouter() + const { analytics_tab } = router.query // theme const { resolvedTheme } = useTheme(); // store hooks @@ -38,17 +41,19 @@ const AnalyticsPage: NextPageWithLayout = observer(() => { <> {workspaceProjectIds && workspaceProjectIds.length > 0 ? (
- - + + {ANALYTICS_TABS.map((tab) => ( - `rounded-3xl border border-custom-border-200 px-4 py-2 text-xs hover:bg-custom-background-80 ${ - selected ? "bg-custom-background-80" : "" + `rounded-0 w-full md:w-max md:rounded-3xl border-b md:border border-custom-border-200 focus:outline-none px-0 md:px-4 py-2 text-xs hover:bg-custom-background-80 ${selected ? "border-custom-primary-100 text-custom-primary-100 md:bg-custom-background-80 md:text-custom-text-200 md:border-custom-border-200" : "border-transparent" }` } - onClick={() => {}} + onClick={() => { + router.query.analytics_tab = tab.key + router.push(router) + }} > {tab.title} diff --git a/web/store/application/theme.store.ts b/web/store/application/theme.store.ts index 7ecc0e770..f264c175d 100644 --- a/web/store/application/theme.store.ts +++ b/web/store/application/theme.store.ts @@ -8,10 +8,12 @@ export interface IThemeStore { theme: string | null; sidebarCollapsed: boolean | undefined; profileSidebarCollapsed: boolean | undefined; + workspaceAnalyticsSidebarCollapsed: boolean | undefined; // actions toggleSidebar: (collapsed?: boolean) => void; setTheme: (theme: any) => void; toggleProfileSidebar: (collapsed?: boolean) => void; + toggleWorkspaceAnalyticsSidebar: (collapsed?: boolean) => void; } export class ThemeStore implements IThemeStore { @@ -19,6 +21,7 @@ export class ThemeStore implements IThemeStore { sidebarCollapsed: boolean | undefined = undefined; theme: string | null = null; profileSidebarCollapsed: boolean | undefined = undefined; + workspaceAnalyticsSidebarCollapsed: boolean | undefined = undefined; // root store rootStore; @@ -28,10 +31,12 @@ export class ThemeStore implements IThemeStore { sidebarCollapsed: observable.ref, theme: observable.ref, profileSidebarCollapsed: observable.ref, + workspaceAnalyticsSidebarCollapsed: observable.ref, // action toggleSidebar: action, setTheme: action, toggleProfileSidebar: action, + toggleWorkspaceAnalyticsSidebar: action // computed }); // root store @@ -64,6 +69,19 @@ export class ThemeStore implements IThemeStore { localStorage.setItem("profile_sidebar_collapsed", this.profileSidebarCollapsed.toString()); }; + /** + * Toggle the profile sidebar collapsed state + * @param collapsed + */ + toggleWorkspaceAnalyticsSidebar = (collapsed?: boolean) => { + if (collapsed === undefined) { + this.workspaceAnalyticsSidebarCollapsed = !this.workspaceAnalyticsSidebarCollapsed; + } else { + this.workspaceAnalyticsSidebarCollapsed = collapsed; + } + localStorage.setItem("workspace_analytics_sidebar_collapsed", this.workspaceAnalyticsSidebarCollapsed.toString()); + }; + /** * Sets the user theme and applies it to the platform * @param _theme