'use client'; import { AnimatePresence, motion } from 'framer-motion'; import isEmpty from 'lodash/isEmpty'; import React, { useMemo } from 'react'; import { useGetMetric, useGetMetricData } from '@/api/buster_rest/metrics'; import { useUpdateMetricChart } from '@/context/Metrics'; import { useIsMetricReadOnly } from '@/context/Metrics/useIsMetricReadOnly'; import { useMemoizedFn } from '@/hooks'; import { cn } from '@/lib/classMerge'; import { inputHasText } from '@/lib/text'; import { MetricChartEvaluation } from './MetricChartEvaluation'; import { MetricDataTruncatedWarning } from './MetricDataTruncatedWarning'; import { MetricSaveFilePopup } from './MetricSaveFilePopup'; import { MetricViewChartContent } from './MetricViewChartContent'; import { MetricViewChartHeader } from './MetricViewChartHeader'; export const MetricViewChart: React.FC<{ metricId: string; readOnly?: boolean; className?: string; cardClassName?: string; }> = React.memo( ({ metricId, readOnly: readOnlyProp = false, className = '', cardClassName = '' }) => { const { data: metric } = useGetMetric( { id: metricId }, { select: ({ chart_config, name, description, time_frame, permission, evaluation_score, evaluation_summary, version_number, versions }) => ({ name, description, time_frame, permission, evaluation_score, evaluation_summary, chart_config, version_number, versions }) } ); const { data: metricData, isFetched: isFetchedMetricData, error: metricDataError } = useGetMetricData({ id: metricId }, { enabled: false }); const { onUpdateMetricName } = useUpdateMetricChart({ metricId }); const { name, description, time_frame, evaluation_score, evaluation_summary } = metric || {}; const isTable = metric?.chart_config.selectedChartType === 'table'; const { isReadOnly, isVersionHistoryMode, isViewingOldVersion } = useIsMetricReadOnly({ metricId, readOnly: readOnlyProp }); const loadingData = !isFetchedMetricData; const hasData = !loadingData && !isEmpty(metricData?.data); const errorData = !!metricDataError; const showEvaluation = !!evaluation_score && !!evaluation_summary; const onSetTitle = useMemoizedFn((title: string) => { if (inputHasText(title)) { onUpdateMetricName({ name: title }); } }); if (!metric) return null; return (
{!isReadOnly && !isVersionHistoryMode && !isViewingOldVersion && ( )}
); } ); MetricViewChart.displayName = 'MetricViewChart'; const MetricViewChartCard: React.FC<{ children: React.ReactNode; loadingData: boolean; hasData: boolean; errorData: boolean; isTable: boolean; className?: string; }> = React.memo(({ children, loadingData, hasData, errorData, isTable, className }) => { const cardClass = useMemo(() => { if (loadingData || errorData || !hasData) return 'h-full max-h-[600px]'; if (isTable) return ''; return 'h-full max-h-[600px]'; }, [isTable, loadingData, hasData, errorData]); return (
{children}
); }); MetricViewChartCard.displayName = 'MetricViewChartCard'; const animation = { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.4 } }; const AnimatePresenceWrapper: React.FC<{ children: React.ReactNode; show: boolean; }> = ({ children, show }) => { return ( {show && {children}} ); };