import { css } from '@emotion/css'; import React, { useState } from 'react'; import { AbsoluteTimeRange, DataQueryError, DataQueryResponse, GrafanaTheme2, LoadingState, SplitOpen, TimeZone, } from '@grafana/data'; import { Alert, Button, Collapse, InlineField, TooltipDisplayMode, useStyles2, useTheme2 } from '@grafana/ui'; import { ExploreGraph } from './ExploreGraph'; type Props = { logsVolumeData: DataQueryResponse | undefined; absoluteRange: AbsoluteTimeRange; logLinesBasedData: DataQueryResponse | undefined; logLinesBasedDataVisibleRange: AbsoluteTimeRange | undefined; timeZone: TimeZone; splitOpen: SplitOpen; width: number; onUpdateTimeRange: (timeRange: AbsoluteTimeRange) => void; onLoadLogsVolume: () => void; onHiddenSeriesChanged: (hiddenSeries: string[]) => void; }; const SHORT_ERROR_MESSAGE_LIMIT = 100; function ErrorAlert(props: { error: DataQueryError }) { const [isOpen, setIsOpen] = useState(false); // generic get-error-message-logic, taken from // /public/app/features/explore/ErrorContainer.tsx const message = props.error.message || props.error.data?.message || ''; const showButton = !isOpen && message.length > SHORT_ERROR_MESSAGE_LIMIT; return ( {showButton ? ( ) : ( message )} ); } function createVisualisationData( logLinesBased: DataQueryResponse | undefined, logLinesBasedVisibleRange: AbsoluteTimeRange | undefined, fullRangeData: DataQueryResponse | undefined, absoluteRange: AbsoluteTimeRange ): | { logsVolumeData: DataQueryResponse; fullRangeData: boolean; range: AbsoluteTimeRange; } | undefined { if (fullRangeData !== undefined) { return { logsVolumeData: fullRangeData, fullRangeData: true, range: absoluteRange, }; } if (logLinesBased !== undefined) { return { logsVolumeData: logLinesBased, fullRangeData: false, range: logLinesBasedVisibleRange || absoluteRange, }; } return undefined; } export function LogsVolumePanel(props: Props) { const { width, timeZone, splitOpen, onUpdateTimeRange, onLoadLogsVolume, onHiddenSeriesChanged } = props; const theme = useTheme2(); const styles = useStyles2(getStyles); const spacing = parseInt(theme.spacing(2).slice(0, -2), 10); const height = 150; const data = createVisualisationData( props.logLinesBasedData, props.logLinesBasedDataVisibleRange, props.logsVolumeData, props.absoluteRange ); if (data === undefined) { return null; } const { logsVolumeData, fullRangeData, range } = data; if (logsVolumeData.error !== undefined) { return ; } let LogsVolumePanelContent; if (logsVolumeData?.state === LoadingState.Loading) { LogsVolumePanelContent = Log volume is loading...; } else if (logsVolumeData?.data) { if (logsVolumeData.data.length > 0) { LogsVolumePanelContent = ( ); } else { LogsVolumePanelContent = No volume data.; } } let extraInfo; if (fullRangeData) { const zoomRatio = logsLevelZoomRatio(logsVolumeData, range); if (zoomRatio !== undefined && zoomRatio < 1) { extraInfo = (