Cursor sync: Apply the settings without saving the dashboard (#44270)

* Cursor sync: Apply the settings without saving the dashboard

* Remove unnecessary code

* Lint god damn
This commit is contained in:
Dominik Prokop 2022-01-20 07:38:10 -08:00 committed by GitHub
parent ab4aa86e67
commit 7bf25f62e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 26 additions and 15 deletions

View File

@ -197,7 +197,7 @@ describe('GraphNG utils', () => {
timeZone: DefaultTimeZone,
getTimeRange: getDefaultTimeRange,
eventBus: new EventBusSrv(),
sync: DashboardCursorSync.Tooltip,
sync: () => DashboardCursorSync.Tooltip,
allFrames: [frame!],
}).getConfig();
expect(result).toMatchSnapshot();

View File

@ -15,7 +15,7 @@ export interface PanelContext {
eventBus: EventBus;
/** Dashboard panels sync */
sync?: DashboardCursorSync;
sync?: () => DashboardCursorSync;
/** Information on what the outer container is */
app?: CoreApp | 'string';

View File

@ -18,7 +18,7 @@ export class UnthemedTimeSeries extends React.Component<TimeSeriesProps> {
panelContext: PanelContext = {} as PanelContext;
prepConfig = (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => {
const { eventBus, sync } = this.context;
const { eventBus, sync } = this.context as PanelContext;
const { theme, timeZone, legend, renderers, tweakAxis, tweakScale } = this.props;
return preparePlotConfigBuilder({

View File

@ -38,7 +38,10 @@ const defaultConfig: GraphFieldConfig = {
axisPlacement: AxisPlacement.Auto,
};
export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursorSync; legend?: VizLegendOptions }> = ({
export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
sync?: () => DashboardCursorSync;
legend?: VizLegendOptions;
}> = ({
frame,
theme,
timeZone,
@ -405,7 +408,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursor
},
};
if (sync !== DashboardCursorSync.Off) {
if (sync && sync() !== DashboardCursorSync.Off) {
const payload: DataHoverPayload = {
point: {
[xScaleKey]: null,
@ -418,6 +421,10 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{ sync: DashboardCursor
key: '__global_',
filters: {
pub: (type: string, src: uPlot, x: number, y: number, w: number, h: number, dataIdx: number) => {
if (sync && sync() === DashboardCursorSync.Off) {
return false;
}
payload.rowIndex = dataIdx;
if (x < 0 && y < 0) {
payload.point[xScaleUnit] = null;

View File

@ -26,7 +26,7 @@ interface TooltipPluginProps {
config: UPlotConfigBuilder;
mode?: TooltipDisplayMode;
sortOrder?: SortOrder;
sync?: DashboardCursorSync;
sync?: () => DashboardCursorSync;
// Allows custom tooltip content rendering. Exposes aligned data frame with relevant indexes for data inspection
// Use field.state.origin indexes from alignedData frame field to get access to original data frame and field index.
renderTooltip?: (alignedFrame: DataFrame, seriesIdx: number | null, datapointIdx: number | null) => React.ReactNode;
@ -95,7 +95,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
u.root.parentElement?.addEventListener('blur', plotLeave);
u.over.addEventListener('mouseleave', plotLeave);
if (sync === DashboardCursorSync.Crosshair) {
if (sync && sync() === DashboardCursorSync.Crosshair) {
u.root.classList.add('shared-crosshair');
}
});
@ -168,7 +168,7 @@ export const TooltipPlugin: React.FC<TooltipPluginProps> = ({
};
}, [config, setCoords, setIsActive, setFocusedPointIdx, setFocusedPointIdxs]);
if (focusedPointIdx === null || (!isActive && sync === DashboardCursorSync.Crosshair)) {
if (focusedPointIdx === null || (!isActive && sync && sync() === DashboardCursorSync.Crosshair)) {
return null;
}

View File

@ -80,8 +80,8 @@ export class PanelChrome extends PureComponent<Props, State> {
refreshWhenInView: false,
context: {
eventBus,
sync: props.isEditing ? DashboardCursorSync.Off : props.dashboard.graphTooltip,
app: this.getPanelContextApp(),
sync: this.getSync,
onSeriesColorChange: this.onSeriesColorChange,
onToggleSeriesVisibility: this.onSeriesVisibilityChange,
onAnnotationCreate: this.onAnnotationCreate,
@ -95,6 +95,9 @@ export class PanelChrome extends PureComponent<Props, State> {
};
}
// Due to a mutable panel model we get the sync settings via function that proactively reads from the model
getSync = () => (this.props.isEditing ? DashboardCursorSync.Off : this.props.dashboard.graphTooltip);
onInstanceStateChange = (value: any) => {
this.props.onInstanceStateChange(value);
@ -218,17 +221,15 @@ export class PanelChrome extends PureComponent<Props, State> {
}
componentDidUpdate(prevProps: Props) {
const { isInView, isEditing, width } = this.props;
const { isInView, width } = this.props;
const { context } = this.state;
const app = this.getPanelContextApp();
const sync = isEditing ? DashboardCursorSync.Off : this.props.dashboard.graphTooltip;
if (context.sync !== sync || context.app !== app) {
if (context.app !== app) {
this.setState({
context: {
...context,
sync,
app,
},
});

View File

@ -17,7 +17,7 @@ export interface TimelineOptions extends OptionsWithLegend, OptionsWithTooltip {
// only used in "changes" mode (state-timeline)
alignValue?: TimelineValueAlignment;
sync?: DashboardCursorSync;
sync?: () => DashboardCursorSync;
}
export type TimelineValueAlignment = 'center' | 'left' | 'right';

View File

@ -236,13 +236,16 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<TimelineOptions> = ({
});
}
if (sync !== DashboardCursorSync.Off) {
if (sync && sync() !== DashboardCursorSync.Off) {
let cursor: Partial<uPlot.Cursor> = {};
cursor.sync = {
key: '__global_',
filters: {
pub: (type: string, src: uPlot, x: number, y: number, w: number, h: number, dataIdx: number) => {
if (sync && sync() === DashboardCursorSync.Off) {
return false;
}
payload.rowIndex = dataIdx;
if (x < 0 && y < 0) {
payload.point[xScaleUnit] = null;