[WEB-5358] fix: analytics enhancements (#8150)

* refactor: enhance analytics page tab functionality and UI

- Introduced state management for selected tabs using useState and useEffect hooks.
- Updated tab handling to improve user experience with onValueChange for Tabs component.
- Refactored AnalyticsFilterActions to remove unused duration selection.
- Added Tooltip to project name in ActiveProjectItem for better visibility.
- Minor styling adjustments in Tabs component for improved layout consistency.

* refactor: improve tab layout in analytics page by adding w-fit

* fix: update styling for ActiveProjectItem component

* refactor: simplify analytics page and introduce useAnalyticsTabs hook

- Removed unused imports and optimized the analytics page component.
- Replaced getAnalyticsTabs with a new custom hook useAnalyticsTabs for better modularity.
- Added useAnalyticsTabs hook to manage analytics tab logic.
- Created new files for useAnalyticsTabs and analytics tabs in the 'ce' and 'ee' directories.

* fix: ensure consistent export in use-analytics-tabs file

* style: format code for better readability in AnalyticsPage component

* fix: add missing newline at end of file in use-analytics-tabs

* chore: remove unused analytics tab components

---------

Co-authored-by: sriramveeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
Jayash Tripathy 2025-11-24 21:29:34 +05:30 committed by GitHub
parent 09f4e3d4ae
commit 2804987fe8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 84 additions and 45 deletions

View file

@ -1,14 +1,15 @@
import { useMemo } from "react";
"use client";
import { useState, useEffect } from "react";
import { observer } from "mobx-react";
import { useRouter } from "next/navigation";
// plane package imports
import { EUserPermissions, EUserPermissionsLevel, PROJECT_TRACKER_ELEMENTS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { EmptyStateDetailed } from "@plane/propel/empty-state";
import type { AnalyticsTab } from "@plane/types";
import { Tabs } from "@plane/ui";
import type { TabItem } from "@plane/ui";
import { Tabs } from "@plane/propel/tabs";
// components
import { cn } from "@plane/utils";
import AnalyticsFilterActions from "@/components/analytics/analytics-filter-actions";
import { PageHead } from "@/components/core/page-title";
// hooks
@ -17,7 +18,7 @@ import { useCommandPalette } from "@/hooks/store/use-command-palette";
import { useProject } from "@/hooks/store/use-project";
import { useWorkspace } from "@/hooks/store/use-workspace";
import { useUserPermissions } from "@/hooks/store/user";
import { getAnalyticsTabs } from "@/plane-web/components/analytics/tabs";
import { useAnalyticsTabs } from "@/plane-web/components/analytics/use-analytics-tabs";
import type { Route } from "./+types/page";
function AnalyticsPage({ params }: Route.ComponentProps) {
@ -35,31 +36,32 @@ function AnalyticsPage({ params }: Route.ComponentProps) {
const { currentWorkspace } = useWorkspace();
const { allowPermissions } = useUserPermissions();
const pageTitle = currentWorkspace?.name
? t(`workspace_analytics.page_label`, { workspace: currentWorkspace?.name })
: undefined;
// permissions
const canPerformEmptyStateActions = allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
EUserPermissionsLevel.WORKSPACE
);
// derived values
const pageTitle = currentWorkspace?.name
? t(`workspace_analytics.page_label`, { workspace: currentWorkspace?.name })
: undefined;
const ANALYTICS_TABS = useMemo<AnalyticsTab[]>(() => getAnalyticsTabs(t), [t]);
const tabs: TabItem[] = useMemo(
() =>
ANALYTICS_TABS.map((tab) => ({
key: tab.key,
label: tab.label,
content: <tab.content />,
onClick: () => {
router.push(`/${currentWorkspace?.slug}/analytics/${tab.key}`);
},
disabled: tab.isDisabled,
})),
[ANALYTICS_TABS, router, currentWorkspace?.slug]
);
const defaultTab = tabId;
const workspaceSlug = params.workspaceSlug;
const ANALYTICS_TABS = useAnalyticsTabs(workspaceSlug.toString());
const [selectedTab, setSelectedTab] = useState(tabId || ANALYTICS_TABS[0]?.key);
useEffect(() => {
if (tabId) {
setSelectedTab(tabId);
}
}, [tabId]);
// Handle tab change
const handleTabChange = (value: string) => {
setSelectedTab(value);
router.push(`/${currentWorkspace?.slug}/analytics/${value}`);
};
return (
<>
@ -67,19 +69,43 @@ function AnalyticsPage({ params }: Route.ComponentProps) {
{workspaceProjectIds && (
<>
{workspaceProjectIds.length > 0 || loader === "init-loader" ? (
<div className="flex h-full overflow-hidden bg-custom-background-100 justify-between items-center ">
<Tabs
tabs={tabs}
storageKey={`analytics-page-${currentWorkspace?.id}`}
defaultTab={defaultTab}
size="md"
tabListContainerClassName="px-6 py-2 border-b border-custom-border-200 flex items-center justify-between"
tabListClassName="my-2 w-auto"
tabClassName="px-3"
tabPanelClassName="h-full overflow-hidden overflow-y-auto px-2"
storeInLocalStorage={false}
actions={<AnalyticsFilterActions />}
/>
<div className="flex h-full overflow-hidden bg-custom-background-100 ">
<Tabs value={selectedTab} onValueChange={handleTabChange} className="w-full h-full">
<div className={"flex flex-col w-full h-full"}>
<div
className={cn(
"px-6 py-2 border-b border-custom-border-200 flex items-center gap-4 overflow-hidden w-full justify-between"
)}
>
<Tabs.List className={"my-2 overflow-x-auto flex w-fit"}>
{ANALYTICS_TABS.map((tab) => (
<Tabs.Trigger
key={tab.key}
value={tab.key}
disabled={tab.isDisabled}
size="md"
className="px-3"
>
{tab.label}
</Tabs.Trigger>
))}
</Tabs.List>
<div className="flex-shrink-0">
<AnalyticsFilterActions />
</div>
</div>
{ANALYTICS_TABS.map((tab) => (
<Tabs.Content
key={tab.key}
value={tab.key}
className={"h-full overflow-hidden overflow-y-auto px-2"}
>
<tab.content />
</Tabs.Content>
))}
</div>
</Tabs>
</div>
) : (
<EmptyStateDetailed