import React from "react"; import Image from "next/image"; // headless ui import { Tab } from "@headlessui/react"; // hooks import useLocalStorage from "hooks/use-local-storage"; // images import emptyLabel from "public/empty-state/empty_label.svg"; import emptyMembers from "public/empty-state/empty_members.svg"; // components import { SingleProgressStats } from "components/core"; // ui import { Avatar, StateGroupIcon } from "@plane/ui"; // types import { IIssueFilterOptions, IModule, TAssigneesDistribution, TCompletionChartDistribution, TLabelsDistribution, TStateGroups, } from "types"; type Props = { distribution: { assignees: TAssigneesDistribution[]; completion_chart: TCompletionChartDistribution; labels: TLabelsDistribution[]; }; groupedIssues: { [key: string]: number; }; totalIssues: number; module?: IModule; roundedTab?: boolean; noBackground?: boolean; isPeekView?: boolean; isCompleted?: boolean; filters?: IIssueFilterOptions; handleFiltersUpdate: (key: keyof IIssueFilterOptions, value: string | string[]) => void; }; export const SidebarProgressStats: React.FC = ({ distribution, groupedIssues, totalIssues, module, roundedTab, noBackground, isCompleted = false, isPeekView = false, filters, handleFiltersUpdate, }) => { const { storedValue: tab, setValue: setTab } = useLocalStorage("tab", "Assignees"); const currentValue = (tab: string | null) => { switch (tab) { case "Assignees": return 0; case "Labels": return 1; case "States": return 2; default: return 0; } }; return ( { switch (i) { case 0: return setTab("Assignees"); case 1: return setTab("Labels"); case 2: return setTab("States"); default: return setTab("Assignees"); } }} > `w-full ${ roundedTab ? "rounded-3xl border border-custom-border-200" : "rounded" } px-3 py-1 text-custom-text-100 ${ selected ? "bg-custom-background-100 text-custom-text-300 shadow-custom-shadow-2xs" : "text-custom-text-400 hover:text-custom-text-300" }` } > Assignees `w-full ${ roundedTab ? "rounded-3xl border border-custom-border-200" : "rounded" } px-3 py-1 text-custom-text-100 ${ selected ? "bg-custom-background-100 text-custom-text-300 shadow-custom-shadow-2xs" : "text-custom-text-400 hover:text-custom-text-300" }` } > Labels `w-full ${ roundedTab ? "rounded-3xl border border-custom-border-200" : "rounded" } px-3 py-1 text-custom-text-100 ${ selected ? "bg-custom-background-100 text-custom-text-300 shadow-custom-shadow-2xs" : "text-custom-text-400 hover:text-custom-text-300" }` } > States {distribution.assignees.length > 0 ? ( distribution.assignees.map((assignee, index) => { if (assignee.assignee_id) return ( {assignee.display_name} } completed={assignee.completed_issues} total={assignee.total_issues} {...(!isPeekView && !isCompleted && { onClick: () => handleFiltersUpdate("assignees", assignee.assignee_id ?? ""), selected: filters?.assignees?.includes(assignee.assignee_id ?? ""), })} /> ); else return (
User
No assignee } completed={assignee.completed_issues} total={assignee.total_issues} /> ); }) ) : (
empty members
No assignees yet
)}
{distribution.labels.length > 0 ? ( distribution.labels.map((label, index) => ( {label.label_name ?? "No labels"} } completed={label.completed_issues} total={label.total_issues} {...(!isPeekView && !isCompleted && { onClick: () => handleFiltersUpdate("labels", label.label_id ?? ""), selected: filters?.labels?.includes(label.label_id ?? `no-label-${index}`), })} /> )) ) : (
empty label
No labels yet
)}
{Object.keys(groupedIssues).map((group, index) => ( {group} } completed={groupedIssues[group]} total={totalIssues} /> ))}
); };