import { alpha, useTheme } from '@mui/material'; import { useMemoComponent } from '@centreon/ui'; import { equals, prop, slice, sortBy } from 'ramda'; import { type Dispatch, type KeyboardEvent, type MouseEvent, type ReactElement, type ReactNode, type SetStateAction, useMemo } from 'react'; import { formatMetricValue } from '../../common/timeSeries'; import type { Line } from '../../common/timeSeries/models'; import type { LegendModel } from '../models'; import { labelAvg, labelMax, labelMin } from '../translatedLabels'; import LegendContent from './LegendContent'; import LegendHeader from './LegendHeader'; import { type GetMetricValueProps, LegendDisplayMode } from './models'; import useLegend from './useLegend'; interface Props extends Pick { base: number; height: number | null; limitLegend?: false | number; lines: Array; renderExtraComponent?: ReactNode; setLinesGraph: Dispatch | null>>; shouldDisplayLegendInCompactMode: boolean; toggable?: boolean; secondaryClick?: (props: { element: EventTarget | null; metricId: number | string; position: [number, number]; }) => void; graphHeight: number; } const MainLegend = ({ lines, base, toggable = true, limitLegend = false, renderExtraComponent, setLinesGraph, shouldDisplayLegendInCompactMode, placement, mode, showCalculations = { avg: true, max: true, min: true }, secondaryClick, graphHeight }: Props): ReactElement => { const theme = useTheme(); const { selectMetricLine, clearHighlight, highlightLine, toggleMetricLine } = useLegend({ lines, setLinesGraph }); const sortedData = sortBy(prop('metric_id'), lines); const isListMode = useMemo(() => equals(mode, 'list'), [mode]); const displayedLines = limitLegend ? slice(0, limitLegend, sortedData) : sortedData; const getMetricValue = ({ value, unit }: GetMetricValueProps): string => formatMetricValue({ base, unit, value }) || 'N/A'; const contextMenuClick = (metricId: number) => (event: MouseEvent): void => { if (!secondaryClick) { return; } event.preventDefault(); secondaryClick({ element: event.target, metricId, position: [event.pageX, event.pageY] }); }; const selectMetric = ({ event, metric_id }: { event: MouseEvent | KeyboardEvent; metric_id: number; }): void => { if (!toggable) { return; } if (event.ctrlKey || event.metaKey) { toggleMetricLine(metric_id); return; } selectMetricLine(metric_id); }; const itemMode = !isListMode && shouldDisplayLegendInCompactMode ? LegendDisplayMode.Compact : LegendDisplayMode.Normal; return (
    {displayedLines.map((line) => { const { color, display, metric_id, unit } = line; const markerColor = display ? color : alpha(theme.palette.text.disabled, 0.2); const minMaxAvg = [ showCalculations.min && { label: labelMin, value: line.minimum_value }, showCalculations.max && { label: labelMax, value: line.maximum_value }, showCalculations.avg && { label: labelAvg, value: line.average_value } ].filter(Boolean) as Array<{ label: string; value: number | null; }>; return (
  • selectMetric({ event, metric_id })} onContextMenu={contextMenuClick(metric_id)} onKeyUp={(event) => event.key === 'Enter' && selectMetric({ event, metric_id }) } onMouseEnter={(): void => highlightLine(metric_id)} onMouseLeave={(): void => clearHighlight()} >
    {!shouldDisplayLegendInCompactMode && !isListMode && (
    {( minMaxAvg as Array<{ label: string; value: number | null; }> ).map(({ label, value }) => ( ))}
    )}
  • ); })}
{renderExtraComponent}
); }; const Legend = (props: Props): ReactElement => { const { toggable, limitLegend, lines, base, shouldDisplayLegendInCompactMode, placement, height, mode } = props; return useMemoComponent({ Component: , memoProps: [ lines, base, toggable, limitLegend, shouldDisplayLegendInCompactMode, placement, height, mode ] }); }; export default Legend;