mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-28 04:01:59 +08:00

* refactor: initial setup for list view logs * feat: done with basic functionality panel view logs * feat: added panel view * fix: discard and edit issue * refactor: removed not required params from uselogdata * feat: trace list view * fix: loader * refactor: traces table component css update * refactor: added open san font and udpated css * fix: full view traces issue and search column css update * refactor: remove consoles * refactor: removed commented code and updated logic * chore: build failure * refactor: icons change for apdd panels * refactor: rebased to develop * refactor: added support for light mode * refactor: fix tsc * fix: query select issue * chore: table column to lower case * refactor: updated styling for both log and traces tables * chore: removed comment code * chore: remove the resizable block from table header traces * refactor: log table header and body stayling updated * fix: query range on every column add * refactor: styling updates * fix: query range log respect global time * refactor: css update log table header * refactor: removed unnecessary code * refactor: log query range respect globaltime * refactor: dropdown support to qb * refactor: remove creating alert for list view * refactor: fix the height of column select dropdown * fix: dropdown suggestion for orderby * refactor: remove the commented code * refactor: full view respect global time * refactor: css updates * refactor: should fire query range on variable change * refactor: css updates for log list view * refactor: removed the unused changes * refactor: handle error state for exploere columns * refactor: handle error state for explorer columns * chore: generate yarn lock file * refactor: pagination for order by timestamp * fix: full text body contain issue * refactor: inverted the operator for next and previous button config * refactor: rename variable handle light mode * fix: no log issue * chore: renamed variables --------- Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
261 lines
7.6 KiB
TypeScript
261 lines
7.6 KiB
TypeScript
import './WidgetFullView.styles.scss';
|
|
|
|
import { SyncOutlined } from '@ant-design/icons';
|
|
import { Button } from 'antd';
|
|
import cx from 'classnames';
|
|
import { ToggleGraphProps } from 'components/Graph/types';
|
|
import Spinner from 'components/Spinner';
|
|
import TimePreference from 'components/TimePreferenceDropDown';
|
|
import { PANEL_TYPES } from 'constants/queryBuilder';
|
|
import GridPanelSwitch from 'container/GridPanelSwitch';
|
|
import {
|
|
timeItems,
|
|
timePreferance,
|
|
} from 'container/NewWidget/RightContainer/timeItems';
|
|
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
|
import { useStepInterval } from 'hooks/queryBuilder/useStepInterval';
|
|
import { useChartMutable } from 'hooks/useChartMutable';
|
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
|
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
|
|
import { getUPlotChartOptions } from 'lib/uPlotLib/getUplotChartOptions';
|
|
import { getUPlotChartData } from 'lib/uPlotLib/utils/getUplotChartData';
|
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
import { useSelector } from 'react-redux';
|
|
import { AppState } from 'store/reducers';
|
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
|
import uPlot from 'uplot';
|
|
import { getTimeRange } from 'utils/getTimeRange';
|
|
|
|
import { getGraphVisibilityStateOnDataChange } from '../utils';
|
|
import { PANEL_TYPES_VS_FULL_VIEW_TABLE } from './contants';
|
|
import GraphManager from './GraphManager';
|
|
// import GraphManager from './GraphManager';
|
|
import { GraphContainer, TimeContainer } from './styles';
|
|
import { FullViewProps } from './types';
|
|
|
|
function FullView({
|
|
widget,
|
|
fullViewOptions = true,
|
|
onClickHandler,
|
|
name,
|
|
originalName,
|
|
yAxisUnit,
|
|
options,
|
|
onDragSelect,
|
|
isDependedDataLoaded = false,
|
|
onToggleModelHandler,
|
|
parentChartRef,
|
|
parentGraphVisibilityState,
|
|
}: FullViewProps): JSX.Element {
|
|
const { selectedTime: globalSelectedTime } = useSelector<
|
|
AppState,
|
|
GlobalReducer
|
|
>((state) => state.globalTime);
|
|
|
|
const fullViewRef = useRef<HTMLDivElement>(null);
|
|
|
|
const [chartOptions, setChartOptions] = useState<uPlot.Options>();
|
|
|
|
const { selectedDashboard, isDashboardLocked } = useDashboard();
|
|
|
|
const { graphVisibilityStates: localStoredVisibilityStates } = useMemo(
|
|
() =>
|
|
getGraphVisibilityStateOnDataChange({
|
|
options,
|
|
isExpandedName: false,
|
|
name: originalName,
|
|
}),
|
|
[options, originalName],
|
|
);
|
|
|
|
const [graphsVisibilityStates, setGraphsVisibilityStates] = useState(
|
|
localStoredVisibilityStates,
|
|
);
|
|
|
|
const getSelectedTime = useCallback(
|
|
() =>
|
|
timeItems.find((e) => e.enum === (widget?.timePreferance || 'GLOBAL_TIME')),
|
|
[widget],
|
|
);
|
|
|
|
const fullViewChartRef = useRef<ToggleGraphProps>();
|
|
|
|
const [selectedTime, setSelectedTime] = useState<timePreferance>({
|
|
name: getSelectedTime()?.name || '',
|
|
enum: widget?.timePreferance || 'GLOBAL_TIME',
|
|
});
|
|
|
|
const updatedQuery = useStepInterval(widget?.query);
|
|
|
|
const response = useGetQueryRange(
|
|
{
|
|
selectedTime: selectedTime.enum,
|
|
graphType: widget.panelTypes,
|
|
query: updatedQuery,
|
|
globalSelectedInterval: globalSelectedTime,
|
|
variables: getDashboardVariables(selectedDashboard?.data.variables),
|
|
},
|
|
{
|
|
queryKey: `FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}-${widget.id}`,
|
|
enabled: !isDependedDataLoaded && widget.panelTypes !== PANEL_TYPES.LIST, // Internally both the list view panel has it's own query range api call, so we don't need to call it again
|
|
},
|
|
);
|
|
|
|
const canModifyChart = useChartMutable({
|
|
panelType: widget.panelTypes,
|
|
panelTypeAndGraphManagerVisibility: PANEL_TYPES_VS_FULL_VIEW_TABLE,
|
|
});
|
|
|
|
const chartData = getUPlotChartData(response?.data?.payload, widget.fillSpans);
|
|
|
|
const isDarkMode = useIsDarkMode();
|
|
|
|
const [minTimeScale, setMinTimeScale] = useState<number>();
|
|
const [maxTimeScale, setMaxTimeScale] = useState<number>();
|
|
|
|
const { minTime, maxTime, selectedTime: globalSelectedInterval } = useSelector<
|
|
AppState,
|
|
GlobalReducer
|
|
>((state) => state.globalTime);
|
|
|
|
useEffect((): void => {
|
|
const { startTime, endTime } = getTimeRange(response);
|
|
|
|
setMinTimeScale(startTime);
|
|
setMaxTimeScale(endTime);
|
|
}, [maxTime, minTime, globalSelectedInterval, response]);
|
|
|
|
useEffect(() => {
|
|
if (!response.isFetching && fullViewRef.current) {
|
|
const width = fullViewRef.current?.clientWidth
|
|
? fullViewRef.current.clientWidth - 45
|
|
: 700;
|
|
|
|
const height = fullViewRef.current?.clientWidth
|
|
? fullViewRef.current.clientHeight
|
|
: 300;
|
|
|
|
const newChartOptions = getUPlotChartOptions({
|
|
yAxisUnit: yAxisUnit || '',
|
|
apiResponse: response.data?.payload,
|
|
dimensions: {
|
|
height,
|
|
width,
|
|
},
|
|
isDarkMode,
|
|
onDragSelect,
|
|
graphsVisibilityStates,
|
|
setGraphsVisibilityStates,
|
|
thresholds: widget.thresholds,
|
|
minTimeScale,
|
|
maxTimeScale,
|
|
softMax: widget.softMax === undefined ? null : widget.softMax,
|
|
softMin: widget.softMin === undefined ? null : widget.softMin,
|
|
});
|
|
|
|
setChartOptions(newChartOptions);
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [response.isFetching, graphsVisibilityStates, fullViewRef.current]);
|
|
|
|
useEffect(() => {
|
|
graphsVisibilityStates?.forEach((e, i) => {
|
|
fullViewChartRef?.current?.toggleGraph(i, e);
|
|
});
|
|
parentGraphVisibilityState(graphsVisibilityStates);
|
|
}, [graphsVisibilityStates, parentGraphVisibilityState]);
|
|
|
|
const isListView = widget.panelTypes === PANEL_TYPES.LIST;
|
|
|
|
if (response.isFetching) {
|
|
return <Spinner height="100%" size="large" tip="Loading..." />;
|
|
}
|
|
|
|
return (
|
|
<div className="full-view-container">
|
|
<div className="full-view-header-container">
|
|
{fullViewOptions && (
|
|
<TimeContainer $panelType={widget.panelTypes}>
|
|
<TimePreference
|
|
selectedTime={selectedTime}
|
|
setSelectedTime={setSelectedTime}
|
|
/>
|
|
<Button
|
|
style={{
|
|
marginLeft: '4px',
|
|
}}
|
|
onClick={(): void => {
|
|
response.refetch();
|
|
}}
|
|
type="primary"
|
|
icon={<SyncOutlined />}
|
|
/>
|
|
</TimeContainer>
|
|
)}
|
|
</div>
|
|
|
|
<div
|
|
className={cx('graph-container', {
|
|
disabled: isDashboardLocked,
|
|
'list-graph-container': isListView,
|
|
})}
|
|
ref={fullViewRef}
|
|
>
|
|
{chartOptions && (
|
|
<GraphContainer
|
|
style={{
|
|
height: isListView ? '100%' : '90%',
|
|
}}
|
|
isGraphLegendToggleAvailable={canModifyChart}
|
|
>
|
|
<GridPanelSwitch
|
|
panelType={widget.panelTypes}
|
|
data={chartData}
|
|
options={chartOptions}
|
|
onClickHandler={onClickHandler}
|
|
name={name}
|
|
yAxisUnit={yAxisUnit}
|
|
onDragSelect={onDragSelect}
|
|
panelData={response.data?.payload.data.newResult.data.result || []}
|
|
query={widget.query}
|
|
ref={fullViewChartRef}
|
|
thresholds={widget.thresholds}
|
|
selectedLogFields={widget.selectedLogFields}
|
|
dataSource={widget.query.builder.queryData[0].dataSource}
|
|
selectedTracesFields={widget.selectedTracesFields}
|
|
selectedTime={selectedTime}
|
|
/>
|
|
</GraphContainer>
|
|
)}
|
|
</div>
|
|
|
|
{canModifyChart && chartOptions && !isDashboardLocked && (
|
|
<GraphManager
|
|
data={chartData}
|
|
name={originalName}
|
|
options={chartOptions}
|
|
yAxisUnit={yAxisUnit}
|
|
onToggleModelHandler={onToggleModelHandler}
|
|
setGraphsVisibilityStates={setGraphsVisibilityStates}
|
|
graphsVisibilityStates={graphsVisibilityStates}
|
|
lineChartRef={fullViewChartRef}
|
|
parentChartRef={parentChartRef}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
FullView.defaultProps = {
|
|
fullViewOptions: undefined,
|
|
onClickHandler: undefined,
|
|
yAxisUnit: undefined,
|
|
onDragSelect: undefined,
|
|
isDependedDataLoaded: undefined,
|
|
};
|
|
|
|
FullView.displayName = 'FullView';
|
|
|
|
export default FullView;
|