bb-plane-fork/web/core/components/analytics/trend-piece.tsx
JayashTripathy c1a078ef3f
[WEB-4246] Analytics minor improvements (#7194)
* chore: updated label for epics

* chore: improved export logic

* refactor: move csvConfig to export.ts and clean up export logic

* refactor: remove unused CSV export logic from WorkItemsInsightTable component

* refactor: streamline data handling in InsightTable component for improved rendering

* feat: add translation for "No. of {entity}" and update priority chart y-axis label to use new translation

* refactor: cleaned up some component and added utilitites

* feat: add "at_risk" translation to multiple languages in translations.json files

* refactor: update TrendPiece component to use new status variants for analytics

* fix: adjust TrendPiece component logic for on-track and off-track status

* refactor: use nullish coalescing operator for yAxis.dx in line and scatter charts

* feat: add "at_risk" translation to various languages in translations.json files

* feat: add "no_of" translation to various languages in translations.json files

* feat: update "at_risk" translation in Ukrainian, Vietnamese, and Chinese locales in translations.json files
2025-06-12 21:15:09 +05:30

80 lines
2 KiB
TypeScript

// plane package imports
import React from "react";
import { TrendingDown, TrendingUp } from "lucide-react";
import { cn } from "@plane/utils";
// plane web components
type Props = {
percentage: number;
className?: string;
size?: "xs" | "sm" | "md" | "lg";
trendIconVisible?: boolean;
variant?: "simple" | "outlined" | "tinted";
};
const sizeConfig = {
xs: {
text: "text-xs",
icon: "w-3 h-3",
},
sm: {
text: "text-sm",
icon: "w-4 h-4",
},
md: {
text: "text-base",
icon: "w-5 h-5",
},
lg: {
text: "text-lg",
icon: "w-6 h-6",
},
} as const;
const variants: Record<NonNullable<Props["variant"]>, Record<"ontrack" | "offtrack" | "atrisk", string>> = {
simple: {
ontrack: "text-green-500",
offtrack: "text-yellow-500",
atrisk: "text-red-500",
},
outlined: {
ontrack: "text-green-500 border border-green-500",
offtrack: "text-yellow-500 border border-yellow-500",
atrisk: "text-red-500 border border-red-500",
},
tinted: {
ontrack: "text-green-500 bg-green-500/10",
offtrack: "text-yellow-500 bg-yellow-500/10",
atrisk: "text-red-500 bg-red-500/10",
},
} as const;
const TrendPiece = (props: Props) => {
const { percentage, className, trendIconVisible = true, size = "sm", variant = "simple" } = props;
const isOnTrack = percentage >= 66;
const isOffTrack = percentage >= 33 && percentage < 66;
const config = sizeConfig[size];
return (
<div
className={cn(
"flex items-center gap-1 p-1 rounded-md",
variants[variant][isOnTrack ? "ontrack" : isOffTrack ? "offtrack" : "atrisk"],
config.text,
className
)}
>
{trendIconVisible &&
(isOnTrack ? (
<TrendingUp className={config.icon} />
) : isOffTrack ? (
<TrendingDown className={config.icon} />
) : (
<TrendingDown className={config.icon} />
))}
{Math.round(Math.abs(percentage))}%
</div>
);
};
export default TrendPiece;