mirror of
https://github.com/SigNoz/signoz.git
synced 2026-03-15 01:22:14 +00:00
Compare commits
4 Commits
debug_time
...
feat/cross
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e85395acbf | ||
|
|
401d55b5a1 | ||
|
|
dbe7fcea00 | ||
|
|
11b8fd1d8b |
@@ -1,6 +1,7 @@
|
|||||||
.overview-content {
|
.overview-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
|
||||||
.overview-settings {
|
.overview-settings {
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
@@ -55,6 +56,35 @@
|
|||||||
border: 1px solid var(--bg-slate-400);
|
border: 1px solid var(--bg-slate-400);
|
||||||
background: var(--bg-ink-300);
|
background: var(--bg-ink-300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cross-panel-sync-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.cross-panel-sync-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 200px;
|
||||||
|
|
||||||
|
.cross-panel-sync-title {
|
||||||
|
color: var(--bg-vanilla-400);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross-panel-sync-description {
|
||||||
|
color: var(--bg-vanilla-400);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-radio-group {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.overview-settings-footer {
|
.overview-settings-footer {
|
||||||
@@ -168,6 +198,15 @@
|
|||||||
border: 1px solid var(--bg-vanilla-300);
|
border: 1px solid var(--bg-vanilla-300);
|
||||||
background: var(--bg-vanilla-300);
|
background: var(--bg-vanilla-300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cross-panel-sync-section {
|
||||||
|
.cross-panel-sync-title {
|
||||||
|
color: var(--bg-ink-400);
|
||||||
|
}
|
||||||
|
.cross-panel-sync-description {
|
||||||
|
color: var(--bg-ink-300);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.overview-settings-footer {
|
.overview-settings-footer {
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Col, Input, Select, Space, Typography } from 'antd';
|
import { Col, Input, Radio, Select, Space, Typography } from 'antd';
|
||||||
import AddTags from 'container/DashboardContainer/DashboardSettings/General/AddTags';
|
import AddTags from 'container/DashboardContainer/DashboardSettings/General/AddTags';
|
||||||
import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
|
import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import { Check, X } from 'lucide-react';
|
import { Check, X } from 'lucide-react';
|
||||||
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
import { useDashboard } from 'providers/Dashboard/Dashboard';
|
||||||
|
import {
|
||||||
|
CROSS_PANEL_SYNC_OPTIONS,
|
||||||
|
CrossPanelSync,
|
||||||
|
} from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
import { Button } from './styles';
|
import { Button } from './styles';
|
||||||
import { Base64Icons } from './utils';
|
import { Base64Icons } from './utils';
|
||||||
@@ -21,8 +25,13 @@ function GeneralDashboardSettings(): JSX.Element {
|
|||||||
|
|
||||||
const selectedData = selectedDashboard?.data;
|
const selectedData = selectedDashboard?.data;
|
||||||
|
|
||||||
const { title = '', tags = [], description = '', image = Base64Icons[0] } =
|
const {
|
||||||
selectedData || {};
|
title = '',
|
||||||
|
tags = [],
|
||||||
|
description = '',
|
||||||
|
image = Base64Icons[0],
|
||||||
|
crossPanelSync = 'NONE',
|
||||||
|
} = selectedData || {};
|
||||||
|
|
||||||
const [updatedTitle, setUpdatedTitle] = useState<string>(title);
|
const [updatedTitle, setUpdatedTitle] = useState<string>(title);
|
||||||
const [updatedTags, setUpdatedTags] = useState<string[]>(tags || []);
|
const [updatedTags, setUpdatedTags] = useState<string[]>(tags || []);
|
||||||
@@ -30,6 +39,10 @@ function GeneralDashboardSettings(): JSX.Element {
|
|||||||
description || '',
|
description || '',
|
||||||
);
|
);
|
||||||
const [updatedImage, setUpdatedImage] = useState<string>(image);
|
const [updatedImage, setUpdatedImage] = useState<string>(image);
|
||||||
|
const [
|
||||||
|
updatedCrossPanelSync,
|
||||||
|
setUpdatedCrossPanelSync,
|
||||||
|
] = useState<CrossPanelSync>(crossPanelSync);
|
||||||
const [numberOfUnsavedChanges, setNumberOfUnsavedChanges] = useState<number>(
|
const [numberOfUnsavedChanges, setNumberOfUnsavedChanges] = useState<number>(
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
@@ -50,6 +63,7 @@ function GeneralDashboardSettings(): JSX.Element {
|
|||||||
tags: updatedTags,
|
tags: updatedTags,
|
||||||
title: updatedTitle,
|
title: updatedTitle,
|
||||||
image: updatedImage,
|
image: updatedImage,
|
||||||
|
crossPanelSync: updatedCrossPanelSync,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -65,12 +79,13 @@ function GeneralDashboardSettings(): JSX.Element {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let numberOfUnsavedChanges = 0;
|
let numberOfUnsavedChanges = 0;
|
||||||
const initialValues = [title, description, tags, image];
|
const initialValues = [title, description, tags, image, crossPanelSync];
|
||||||
const updatedValues = [
|
const updatedValues = [
|
||||||
updatedTitle,
|
updatedTitle,
|
||||||
updatedDescription,
|
updatedDescription,
|
||||||
updatedTags,
|
updatedTags,
|
||||||
updatedImage,
|
updatedImage,
|
||||||
|
updatedCrossPanelSync,
|
||||||
];
|
];
|
||||||
initialValues.forEach((val, index) => {
|
initialValues.forEach((val, index) => {
|
||||||
if (!isEqual(val, updatedValues[index])) {
|
if (!isEqual(val, updatedValues[index])) {
|
||||||
@@ -79,21 +94,38 @@ function GeneralDashboardSettings(): JSX.Element {
|
|||||||
});
|
});
|
||||||
setNumberOfUnsavedChanges(numberOfUnsavedChanges);
|
setNumberOfUnsavedChanges(numberOfUnsavedChanges);
|
||||||
}, [
|
}, [
|
||||||
|
crossPanelSync,
|
||||||
description,
|
description,
|
||||||
image,
|
image,
|
||||||
tags,
|
tags,
|
||||||
title,
|
title,
|
||||||
|
updatedCrossPanelSync,
|
||||||
updatedDescription,
|
updatedDescription,
|
||||||
updatedImage,
|
updatedImage,
|
||||||
updatedTags,
|
updatedTags,
|
||||||
updatedTitle,
|
updatedTitle,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const crossPanelSyncOptions = useMemo(() => {
|
||||||
|
return CROSS_PANEL_SYNC_OPTIONS.map((value) => {
|
||||||
|
const sanitizedValue = value.toLowerCase();
|
||||||
|
const label =
|
||||||
|
sanitizedValue === 'none'
|
||||||
|
? 'No Sync'
|
||||||
|
: sanitizedValue.charAt(0).toUpperCase() + sanitizedValue.slice(1);
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const discardHandler = (): void => {
|
const discardHandler = (): void => {
|
||||||
setUpdatedTitle(title);
|
setUpdatedTitle(title);
|
||||||
setUpdatedImage(image);
|
setUpdatedImage(image);
|
||||||
setUpdatedTags(tags);
|
setUpdatedTags(tags);
|
||||||
setUpdatedDescription(description);
|
setUpdatedDescription(description);
|
||||||
|
setUpdatedCrossPanelSync(crossPanelSync);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -156,6 +188,28 @@ function GeneralDashboardSettings(): JSX.Element {
|
|||||||
</div>
|
</div>
|
||||||
</Space>
|
</Space>
|
||||||
</Col>
|
</Col>
|
||||||
|
<Col className="overview-settings">
|
||||||
|
<div className="cross-panel-sync-section">
|
||||||
|
<div className="cross-panel-sync-info">
|
||||||
|
<Typography className="cross-panel-sync-title">
|
||||||
|
Cross-Panel Sync
|
||||||
|
</Typography>
|
||||||
|
<Typography.Text className="cross-panel-sync-description">
|
||||||
|
Sync crosshair and tooltip across all the dashboard panels
|
||||||
|
</Typography.Text>
|
||||||
|
</div>
|
||||||
|
<Radio.Group
|
||||||
|
value={updatedCrossPanelSync}
|
||||||
|
onChange={(e): void =>
|
||||||
|
setUpdatedCrossPanelSync(e.target.value as CrossPanelSync)
|
||||||
|
}
|
||||||
|
optionType="button"
|
||||||
|
buttonStyle="solid"
|
||||||
|
options={crossPanelSyncOptions}
|
||||||
|
data-testid="cross-panel-sync"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
{numberOfUnsavedChanges > 0 && (
|
{numberOfUnsavedChanges > 0 && (
|
||||||
<div className="overview-settings-footer">
|
<div className="overview-settings-footer">
|
||||||
<div className="unsaved">
|
<div className="unsaved">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { PrecisionOption } from 'components/Graph/types';
|
import { PrecisionOption } from 'components/Graph/types';
|
||||||
import { LegendConfig, TooltipRenderArgs } from 'lib/uPlotV2/components/types';
|
import { LegendConfig, TooltipRenderArgs } from 'lib/uPlotV2/components/types';
|
||||||
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
import { UPlotConfigBuilder } from 'lib/uPlotV2/config/UPlotConfigBuilder';
|
||||||
import { DashboardCursorSync } from 'lib/uPlotV2/plugins/TooltipPlugin/types';
|
import { CrossPanelSync } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
interface BaseChartProps {
|
interface BaseChartProps {
|
||||||
width: number;
|
width: number;
|
||||||
@@ -17,7 +17,7 @@ interface BaseChartProps {
|
|||||||
interface UPlotBasedChartProps {
|
interface UPlotBasedChartProps {
|
||||||
config: UPlotConfigBuilder;
|
config: UPlotConfigBuilder;
|
||||||
data: uPlot.AlignedData;
|
data: uPlot.AlignedData;
|
||||||
syncMode?: DashboardCursorSync;
|
syncMode?: CrossPanelSync;
|
||||||
syncKey?: string;
|
syncKey?: string;
|
||||||
plotRef?: (plot: uPlot | null) => void;
|
plotRef?: (plot: uPlot | null) => void;
|
||||||
onDestroy?: (plot: uPlot) => void;
|
onDestroy?: (plot: uPlot) => void;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { getTimeRange } from 'utils/getTimeRange';
|
|||||||
import BarChart from '../../charts/BarChart/BarChart';
|
import BarChart from '../../charts/BarChart/BarChart';
|
||||||
import ChartManager from '../../components/ChartManager/ChartManager';
|
import ChartManager from '../../components/ChartManager/ChartManager';
|
||||||
import { usePanelContextMenu } from '../../hooks/usePanelContextMenu';
|
import { usePanelContextMenu } from '../../hooks/usePanelContextMenu';
|
||||||
|
import { PanelMode } from '../types';
|
||||||
import { prepareBarPanelConfig, prepareBarPanelData } from './utils';
|
import { prepareBarPanelConfig, prepareBarPanelData } from './utils';
|
||||||
|
|
||||||
import '../Panel.styles.scss';
|
import '../Panel.styles.scss';
|
||||||
@@ -27,7 +28,11 @@ function BarPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
onToggleModelHandler,
|
onToggleModelHandler,
|
||||||
} = props;
|
} = props;
|
||||||
const uPlotRef = useRef<uPlot | null>(null);
|
const uPlotRef = useRef<uPlot | null>(null);
|
||||||
const { toScrollWidgetId, setToScrollWidgetId } = useDashboard();
|
const {
|
||||||
|
toScrollWidgetId,
|
||||||
|
setToScrollWidgetId,
|
||||||
|
selectedDashboard,
|
||||||
|
} = useDashboard();
|
||||||
const graphRef = useRef<HTMLDivElement>(null);
|
const graphRef = useRef<HTMLDivElement>(null);
|
||||||
const [minTimeScale, setMinTimeScale] = useState<number>();
|
const [minTimeScale, setMinTimeScale] = useState<number>();
|
||||||
const [maxTimeScale, setMaxTimeScale] = useState<number>();
|
const [maxTimeScale, setMaxTimeScale] = useState<number>();
|
||||||
@@ -117,6 +122,15 @@ function BarPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
onToggleModelHandler,
|
onToggleModelHandler,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const crossPanelSync = selectedDashboard?.data?.crossPanelSync ?? 'NONE';
|
||||||
|
|
||||||
|
const cursorSyncMode = useMemo(() => {
|
||||||
|
if (panelMode !== PanelMode.DASHBOARD_VIEW) {
|
||||||
|
return 'NONE';
|
||||||
|
}
|
||||||
|
return crossPanelSync;
|
||||||
|
}, [panelMode, crossPanelSync]);
|
||||||
|
|
||||||
const onPlotDestroy = useCallback(() => {
|
const onPlotDestroy = useCallback(() => {
|
||||||
uPlotRef.current = null;
|
uPlotRef.current = null;
|
||||||
}, []);
|
}, []);
|
||||||
@@ -137,6 +151,7 @@ function BarPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
onDestroy={onPlotDestroy}
|
onDestroy={onPlotDestroy}
|
||||||
yAxisUnit={widget.yAxisUnit}
|
yAxisUnit={widget.yAxisUnit}
|
||||||
decimalPrecision={widget.decimalPrecision}
|
decimalPrecision={widget.decimalPrecision}
|
||||||
|
syncMode={cursorSyncMode}
|
||||||
timezone={timezone.value}
|
timezone={timezone.value}
|
||||||
data={chartData as uPlot.AlignedData}
|
data={chartData as uPlot.AlignedData}
|
||||||
width={containerDimensions.width}
|
width={containerDimensions.width}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import uPlot from 'uplot';
|
|||||||
import { getTimeRange } from 'utils/getTimeRange';
|
import { getTimeRange } from 'utils/getTimeRange';
|
||||||
|
|
||||||
import { prepareChartData, prepareUPlotConfig } from '../TimeSeriesPanel/utils';
|
import { prepareChartData, prepareUPlotConfig } from '../TimeSeriesPanel/utils';
|
||||||
|
import { PanelMode } from '../types';
|
||||||
|
|
||||||
import '../Panel.styles.scss';
|
import '../Panel.styles.scss';
|
||||||
|
|
||||||
@@ -26,7 +27,11 @@ function TimeSeriesPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
isFullViewMode,
|
isFullViewMode,
|
||||||
onToggleModelHandler,
|
onToggleModelHandler,
|
||||||
} = props;
|
} = props;
|
||||||
const { toScrollWidgetId, setToScrollWidgetId } = useDashboard();
|
const {
|
||||||
|
toScrollWidgetId,
|
||||||
|
setToScrollWidgetId,
|
||||||
|
selectedDashboard,
|
||||||
|
} = useDashboard();
|
||||||
const graphRef = useRef<HTMLDivElement>(null);
|
const graphRef = useRef<HTMLDivElement>(null);
|
||||||
const [minTimeScale, setMinTimeScale] = useState<number>();
|
const [minTimeScale, setMinTimeScale] = useState<number>();
|
||||||
const [maxTimeScale, setMaxTimeScale] = useState<number>();
|
const [maxTimeScale, setMaxTimeScale] = useState<number>();
|
||||||
@@ -96,6 +101,15 @@ function TimeSeriesPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
timezone,
|
timezone,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const crossPanelSync = selectedDashboard?.data?.crossPanelSync ?? 'NONE';
|
||||||
|
|
||||||
|
const cursorSyncMode = useMemo(() => {
|
||||||
|
if (panelMode !== PanelMode.DASHBOARD_VIEW) {
|
||||||
|
return 'NONE';
|
||||||
|
}
|
||||||
|
return crossPanelSync;
|
||||||
|
}, [panelMode, crossPanelSync]);
|
||||||
|
|
||||||
const layoutChildren = useMemo(() => {
|
const layoutChildren = useMemo(() => {
|
||||||
if (!isFullViewMode) {
|
if (!isFullViewMode) {
|
||||||
return null;
|
return null;
|
||||||
@@ -126,6 +140,7 @@ function TimeSeriesPanel(props: PanelWrapperProps): JSX.Element {
|
|||||||
}}
|
}}
|
||||||
yAxisUnit={widget.yAxisUnit}
|
yAxisUnit={widget.yAxisUnit}
|
||||||
decimalPrecision={widget.decimalPrecision}
|
decimalPrecision={widget.decimalPrecision}
|
||||||
|
syncMode={cursorSyncMode}
|
||||||
timezone={timezone.value}
|
timezone={timezone.value}
|
||||||
data={chartData as uPlot.AlignedData}
|
data={chartData as uPlot.AlignedData}
|
||||||
width={containerDimensions.width}
|
width={containerDimensions.width}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
updateWindowSize,
|
updateWindowSize,
|
||||||
} from './tooltipController';
|
} from './tooltipController';
|
||||||
import {
|
import {
|
||||||
DashboardCursorSync,
|
|
||||||
TooltipControllerContext,
|
TooltipControllerContext,
|
||||||
TooltipControllerState,
|
TooltipControllerState,
|
||||||
TooltipLayoutInfo,
|
TooltipLayoutInfo,
|
||||||
@@ -35,7 +34,7 @@ export default function TooltipPlugin({
|
|||||||
render,
|
render,
|
||||||
maxWidth = 300,
|
maxWidth = 300,
|
||||||
maxHeight = 400,
|
maxHeight = 400,
|
||||||
syncMode = DashboardCursorSync.None,
|
syncMode = 'NONE',
|
||||||
syncKey = '_tooltip_sync_global_',
|
syncKey = '_tooltip_sync_global_',
|
||||||
canPinTooltip = false,
|
canPinTooltip = false,
|
||||||
}: TooltipPluginProps): JSX.Element | null {
|
}: TooltipPluginProps): JSX.Element | null {
|
||||||
@@ -78,11 +77,11 @@ export default function TooltipPlugin({
|
|||||||
// render on every mouse move.
|
// render on every mouse move.
|
||||||
const controller: TooltipControllerState = createInitialControllerState();
|
const controller: TooltipControllerState = createInitialControllerState();
|
||||||
|
|
||||||
const syncTooltipWithDashboard = syncMode === DashboardCursorSync.Tooltip;
|
const syncTooltipWithDashboard = syncMode === 'TOOLTIP';
|
||||||
|
|
||||||
// Enable uPlot's built-in cursor sync when requested so that
|
// Enable uPlot's built-in cursor sync when requested so that
|
||||||
// crosshair / tooltip can follow the dashboard-wide cursor.
|
// crosshair / tooltip can follow the dashboard-wide cursor.
|
||||||
if (syncMode !== DashboardCursorSync.None && config.scales[0]?.props.time) {
|
if (syncMode !== 'NONE' && config.scales[0]?.props.time) {
|
||||||
config.setCursor({
|
config.setCursor({
|
||||||
sync: { key: syncKey, scales: ['x', null] },
|
sync: { key: syncKey, scales: ['x', null] },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type {
|
|||||||
ReactNode,
|
ReactNode,
|
||||||
RefObject,
|
RefObject,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
|
import { CrossPanelSync } from 'types/api/dashboard/getAll';
|
||||||
import type uPlot from 'uplot';
|
import type uPlot from 'uplot';
|
||||||
|
|
||||||
import type { TooltipRenderArgs } from '../../components/types';
|
import type { TooltipRenderArgs } from '../../components/types';
|
||||||
@@ -11,12 +12,6 @@ import type { UPlotConfigBuilder } from '../../config/UPlotConfigBuilder';
|
|||||||
|
|
||||||
export const TOOLTIP_OFFSET = 10;
|
export const TOOLTIP_OFFSET = 10;
|
||||||
|
|
||||||
export enum DashboardCursorSync {
|
|
||||||
Crosshair,
|
|
||||||
None,
|
|
||||||
Tooltip,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TooltipViewState {
|
export interface TooltipViewState {
|
||||||
plot?: uPlot | null;
|
plot?: uPlot | null;
|
||||||
style: Partial<CSSProperties>;
|
style: Partial<CSSProperties>;
|
||||||
@@ -35,7 +30,7 @@ export interface TooltipLayoutInfo {
|
|||||||
export interface TooltipPluginProps {
|
export interface TooltipPluginProps {
|
||||||
config: UPlotConfigBuilder;
|
config: UPlotConfigBuilder;
|
||||||
canPinTooltip?: boolean;
|
canPinTooltip?: boolean;
|
||||||
syncMode?: DashboardCursorSync;
|
syncMode?: CrossPanelSync;
|
||||||
syncKey?: string;
|
syncKey?: string;
|
||||||
render: (args: TooltipRenderArgs) => ReactNode;
|
render: (args: TooltipRenderArgs) => ReactNode;
|
||||||
maxWidth?: number;
|
maxWidth?: number;
|
||||||
@@ -86,7 +81,7 @@ export interface TooltipControllerContext {
|
|||||||
rafId: MutableRefObject<number | null>;
|
rafId: MutableRefObject<number | null>;
|
||||||
updateState: (updates: Partial<TooltipViewState>) => void;
|
updateState: (updates: Partial<TooltipViewState>) => void;
|
||||||
renderRef: MutableRefObject<(args: TooltipRenderArgs) => ReactNode>;
|
renderRef: MutableRefObject<(args: TooltipRenderArgs) => ReactNode>;
|
||||||
syncMode: DashboardCursorSync;
|
syncMode: CrossPanelSync;
|
||||||
syncKey: string;
|
syncKey: string;
|
||||||
canPinTooltip: boolean;
|
canPinTooltip: boolean;
|
||||||
createTooltipContents: () => React.ReactNode;
|
createTooltipContents: () => React.ReactNode;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import type uPlot from 'uplot';
|
|||||||
import { TooltipRenderArgs } from '../../components/types';
|
import { TooltipRenderArgs } from '../../components/types';
|
||||||
import { UPlotConfigBuilder } from '../../config/UPlotConfigBuilder';
|
import { UPlotConfigBuilder } from '../../config/UPlotConfigBuilder';
|
||||||
import TooltipPlugin from '../TooltipPlugin/TooltipPlugin';
|
import TooltipPlugin from '../TooltipPlugin/TooltipPlugin';
|
||||||
import { DashboardCursorSync } from '../TooltipPlugin/types';
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Mock helpers
|
// Mock helpers
|
||||||
@@ -100,7 +99,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: renderFn,
|
render: renderFn,
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
...extraProps,
|
...extraProps,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -127,7 +126,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => React.createElement('div', null, 'tooltip-body'),
|
render: () => React.createElement('div', null, 'tooltip-body'),
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -141,7 +140,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => null,
|
render: () => null,
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -217,7 +216,7 @@ describe('TooltipPlugin', () => {
|
|||||||
{ type: 'button', onClick: args.dismiss },
|
{ type: 'button', onClick: args.dismiss },
|
||||||
'Dismiss',
|
'Dismiss',
|
||||||
),
|
),
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
canPinTooltip: true,
|
canPinTooltip: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -261,7 +260,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config: config,
|
config: config,
|
||||||
render: () => React.createElement('div', null, 'tooltip-body'),
|
render: () => React.createElement('div', null, 'tooltip-body'),
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
canPinTooltip: true,
|
canPinTooltip: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -305,7 +304,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => React.createElement('div', null, 'pinned content'),
|
render: () => React.createElement('div', null, 'pinned content'),
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
canPinTooltip: true,
|
canPinTooltip: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -348,7 +347,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => React.createElement('div', null, 'pinned content'),
|
render: () => React.createElement('div', null, 'pinned content'),
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
canPinTooltip: true,
|
canPinTooltip: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -398,7 +397,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => null,
|
render: () => null,
|
||||||
syncMode: DashboardCursorSync.Tooltip,
|
syncMode: 'TOOLTIP',
|
||||||
syncKey: 'dashboard-sync',
|
syncKey: 'dashboard-sync',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -417,7 +416,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => null,
|
render: () => null,
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -433,7 +432,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => null,
|
render: () => null,
|
||||||
syncMode: DashboardCursorSync.Tooltip,
|
syncMode: 'TOOLTIP',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -453,7 +452,7 @@ describe('TooltipPlugin', () => {
|
|||||||
React.createElement(TooltipPlugin, {
|
React.createElement(TooltipPlugin, {
|
||||||
config,
|
config,
|
||||||
render: () => null,
|
render: () => null,
|
||||||
syncMode: DashboardCursorSync.None,
|
syncMode: 'NONE',
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,13 @@ export interface DashboardTemplate {
|
|||||||
previewImage: string;
|
previewImage: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const CROSS_PANEL_SYNC_OPTIONS = [
|
||||||
|
'NONE',
|
||||||
|
'CROSSHAIR',
|
||||||
|
'TOOLTIP',
|
||||||
|
] as const;
|
||||||
|
export type CrossPanelSync = typeof CROSS_PANEL_SYNC_OPTIONS[number];
|
||||||
|
|
||||||
export interface DashboardData {
|
export interface DashboardData {
|
||||||
// uuid?: string;
|
// uuid?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -93,6 +100,7 @@ export interface DashboardData {
|
|||||||
variables: Record<string, IDashboardVariable>;
|
variables: Record<string, IDashboardVariable>;
|
||||||
version?: string;
|
version?: string;
|
||||||
image?: string;
|
image?: string;
|
||||||
|
crossPanelSync?: CrossPanelSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WidgetRow {
|
export interface WidgetRow {
|
||||||
|
|||||||
Reference in New Issue
Block a user