import { useEffect, useState } from "react"; import Link from "next/link"; import { observer } from "mobx-react-lite"; // hooks import { useDashboard } from "hooks/store"; // components import { MarimekkoGraph } from "components/ui"; import { DurationFilterDropdown, IssuesByPriorityEmptyState, WidgetLoader, WidgetProps, } from "components/dashboard/widgets"; // ui import { PriorityIcon } from "@plane/ui"; // helpers import { getCustomDates } from "helpers/dashboard.helper"; // types import { TIssuesByPriorityWidgetFilters, TIssuesByPriorityWidgetResponse } from "@plane/types"; // constants import { PRIORITY_GRAPH_GRADIENTS } from "constants/dashboard"; import { ISSUE_PRIORITIES } from "constants/issue"; const TEXT_COLORS = { urgent: "#F4A9AA", high: "#AB4800", medium: "#AB6400", low: "#1F2D5C", none: "#60646C", }; const CustomBar = (props: any) => { const { bar, workspaceSlug } = props; // states const [isMouseOver, setIsMouseOver] = useState(false); return ( setIsMouseOver(true)} onMouseLeave={() => setIsMouseOver(false)} > {bar?.id} ); }; const WIDGET_KEY = "issues_by_priority"; export const IssuesByPriorityWidget: React.FC = observer((props) => { const { dashboardId, workspaceSlug } = props; // store hooks const { fetchWidgetStats, getWidgetDetails, getWidgetStats, updateDashboardWidgetFilters } = useDashboard(); const widgetDetails = getWidgetDetails(workspaceSlug, dashboardId, WIDGET_KEY); const widgetStats = getWidgetStats(workspaceSlug, dashboardId, WIDGET_KEY); const handleUpdateFilters = async (filters: Partial) => { if (!widgetDetails) return; await updateDashboardWidgetFilters(workspaceSlug, dashboardId, widgetDetails.id, { widgetKey: WIDGET_KEY, filters, }); fetchWidgetStats(workspaceSlug, dashboardId, { widget_key: WIDGET_KEY, target_date: getCustomDates(filters.target_date ?? widgetDetails.widget_filters.target_date ?? "this_week"), }); }; useEffect(() => { fetchWidgetStats(workspaceSlug, dashboardId, { widget_key: WIDGET_KEY, target_date: getCustomDates(widgetDetails?.widget_filters.target_date ?? "this_week"), }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); if (!widgetDetails || !widgetStats) return ; const totalCount = widgetStats.reduce((acc, item) => acc + item?.count, 0); const chartData = widgetStats .filter((i) => i.count !== 0) .map((item) => ({ priority: item?.priority, percentage: (item?.count / totalCount) * 100, urgent: item?.priority === "urgent" ? 1 : 0, high: item?.priority === "high" ? 1 : 0, medium: item?.priority === "medium" ? 1 : 0, low: item?.priority === "low" ? 1 : 0, none: item?.priority === "none" ? 1 : 0, })); const CustomBarsLayer = (props: any) => { const { bars } = props; return ( {bars ?.filter((b: any) => b?.value === 1) // render only bars with value 1 .map((bar: any) => ( ))} ); }; return (
Assigned by priority

Filtered by{" "} Due date

handleUpdateFilters({ target_date: val, }) } />
{totalCount > 0 ? (
({ id: p.key, value: p.key, }))} axisBottom={null} axisLeft={null} height="119px" margin={{ top: 11, right: 0, bottom: 0, left: 0, }} defs={PRIORITY_GRAPH_GRADIENTS} fill={ISSUE_PRIORITIES.map((p) => ({ match: { id: p.key, }, id: `gradient${p.title}`, }))} tooltip={() => <>} enableGridX={false} enableGridY={false} layers={[CustomBarsLayer]} />
{chartData.map((item) => (

{item.percentage.toFixed(0)}%

))}
) : (
)}
); });