* chore: analytics endpoint * added anlytics v2 * updated status icons * added area chart in workitems and en translations * active projects * chore: created analytics chart * chore: validation errors * improved radar-chart , added empty states , added projects summary * chore: added a new graph in advance analytics * integrated priority chart * chore: added csv exporter * added priority dropdown * integrated created vs resolved chart * custom x and y axis label in bar and area chart * added wrapper styles to legends * added filter components * fixed temp data imports * integrated filters in priority charts * added label to priority chart and updated duration filter * refactor * reverted to void onchange * fixed some contant exports * fixed type issues * fixed some type and build issues * chore: updated the filtering logic for analytics * updated default value to last_30_days * percentage value whole number and added some rules for axis options * fixed some translations * added - custom tick for radar, calc of insight cards, filter labels * chore: opitmised the analytics endpoint * replace old analytics path with new , updated labels of insight card, done some store fixes * chore: updated the export request * Enhanced ProjectSelect to support multi-select, improved state management, and optimized data fetching and component structure. * fix: round completion percentage calculation in ActiveProjectItem * added empty states in project insights * Added loader and empty state in created/resolved chart * added loaders * added icons in filters * added custom colors in customised charts * cleaned up some code * added some responsiveness * updated translations * updated serrchbar for the table * added work item modal in project analytics * fixed some of the layput issues in the peek view * chore: updated the base function for viewsets * synced tab to url * code cleanup * chore: updated the export logic * fixed project_ids filter * added icon in projectdropdown * updated export button position * export csv and emptystates icons * refactor * code refactor * updated loaders, moved color pallete to contants, added nullish collasece operator in neccessary places * removed uneccessary cn * fixed formatting issues * fixed empty project_ids in payload * improved null checks * optimized charts * modified relevant variables to observable.ref * fixed the duration type * optimized some code * updated query key in project-insight * updated query key in project-insight * updated formatting * chore: replaced analytics route with new one and done some optimizations * removed the old analytics --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
105 lines
2.7 KiB
TypeScript
105 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { observer } from "mobx-react";
|
|
import Image from "next/image";
|
|
// ui
|
|
import { Button } from "@plane/ui/src/button";
|
|
// utils
|
|
import { cn } from "@plane/utils";
|
|
|
|
type EmptyStateSize = "sm" | "md" | "lg";
|
|
|
|
type ButtonConfig = {
|
|
text: string;
|
|
prependIcon?: React.ReactNode;
|
|
appendIcon?: React.ReactNode;
|
|
onClick?: () => void;
|
|
disabled?: boolean;
|
|
};
|
|
|
|
type Props = {
|
|
title: string;
|
|
description?: string;
|
|
assetPath?: string;
|
|
size?: EmptyStateSize;
|
|
primaryButton?: ButtonConfig;
|
|
secondaryButton?: ButtonConfig;
|
|
customPrimaryButton?: React.ReactNode;
|
|
customSecondaryButton?: React.ReactNode;
|
|
className?: string;
|
|
};
|
|
|
|
const sizeClasses = {
|
|
sm: "md:min-w-[24rem] max-w-[45rem]",
|
|
md: "md:min-w-[28rem] max-w-[50rem]",
|
|
lg: "md:min-w-[30rem] max-w-[60rem]",
|
|
} as const;
|
|
|
|
const CustomButton = ({
|
|
config,
|
|
variant,
|
|
size,
|
|
}: {
|
|
config: ButtonConfig;
|
|
variant: "primary" | "neutral-primary";
|
|
size: EmptyStateSize;
|
|
}) => (
|
|
<Button
|
|
variant={variant}
|
|
size={size}
|
|
onClick={config.onClick}
|
|
prependIcon={config.prependIcon}
|
|
appendIcon={config.appendIcon}
|
|
disabled={config.disabled}
|
|
>
|
|
{config.text}
|
|
</Button>
|
|
);
|
|
|
|
export const DetailedEmptyState: React.FC<Props> = observer((props) => {
|
|
const {
|
|
title,
|
|
description,
|
|
size = "lg",
|
|
primaryButton,
|
|
secondaryButton,
|
|
customPrimaryButton,
|
|
customSecondaryButton,
|
|
assetPath,
|
|
className,
|
|
} = props;
|
|
|
|
const hasButtons = primaryButton || secondaryButton || customPrimaryButton || customSecondaryButton;
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"flex items-center justify-center min-h-full min-w-full overflow-y-auto py-10 md:px-20 px-5",
|
|
className
|
|
)}
|
|
>
|
|
<div className={cn("flex flex-col gap-5", sizeClasses[size])}>
|
|
<div className="flex flex-col gap-1.5 flex-shrink">
|
|
<h3 className={cn("text-xl font-semibold", { "font-medium": !description })}>{title}</h3>
|
|
{description && <p className="text-sm">{description}</p>}
|
|
</div>
|
|
|
|
{assetPath && <Image src={assetPath} alt={title} width={384} height={250} lazyBoundary="100%" />}
|
|
|
|
{hasButtons && (
|
|
<div className="relative flex items-center justify-center gap-2 flex-shrink-0 w-full">
|
|
{/* primary button */}
|
|
{customPrimaryButton ??
|
|
(primaryButton?.text && <CustomButton config={primaryButton} variant="primary" size={size} />)}
|
|
{/* secondary button */}
|
|
{customSecondaryButton ??
|
|
(secondaryButton?.text && (
|
|
<CustomButton config={secondaryButton} variant="neutral-primary" size={size} />
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
});
|