mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PanelEditor: Fixed issue changing a panel from transparent back to normal (#24483)
* PanelModel: Fixed issues with persisting some changes * Fixed other issues
This commit is contained in:
@@ -106,7 +106,6 @@ export const OptionsPaneContent: React.FC<Props> = ({
|
||||
dashboard={dashboard}
|
||||
data={currentData}
|
||||
onPanelConfigChange={onPanelConfigChange}
|
||||
onFieldConfigsChange={onFieldConfigsChange}
|
||||
onPanelOptionsChanged={onPanelOptionsChanged}
|
||||
/>
|
||||
) : (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { FC, useMemo, useRef } from 'react';
|
||||
import { DashboardModel, PanelModel } from '../../state';
|
||||
import { FieldConfigSource, PanelData, PanelPlugin, SelectableValue } from '@grafana/data';
|
||||
import { PanelData, PanelPlugin, SelectableValue } from '@grafana/data';
|
||||
import { Counter, DataLinksInlineEditor, Field, Input, RadioButtonGroup, Select, Switch, TextArea } from '@grafana/ui';
|
||||
import { getPanelLinksVariableSuggestions } from '../../../panel/panellinks/link_srv';
|
||||
import { getVariables } from '../../../variables/state/selectors';
|
||||
@@ -16,7 +16,6 @@ interface Props {
|
||||
dashboard: DashboardModel;
|
||||
onPanelConfigChange: (configKey: string, value: any) => void;
|
||||
onPanelOptionsChanged: (options: any) => void;
|
||||
onFieldConfigsChange: (config: FieldConfigSource) => void;
|
||||
}
|
||||
|
||||
export const PanelOptionsTab: FC<Props> = ({
|
||||
@@ -26,7 +25,6 @@ export const PanelOptionsTab: FC<Props> = ({
|
||||
dashboard,
|
||||
onPanelConfigChange,
|
||||
onPanelOptionsChanged,
|
||||
onFieldConfigsChange,
|
||||
}) => {
|
||||
const visTabInputRef = useRef<HTMLInputElement>();
|
||||
const linkVariablesSuggestions = useMemo(() => getPanelLinksVariableSuggestions(), []);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Libraries
|
||||
import React, { PureComponent, ChangeEvent, FocusEvent, ReactText } from 'react';
|
||||
import React, { PureComponent, ChangeEvent, FocusEvent } from 'react';
|
||||
|
||||
// Utils
|
||||
import { rangeUtil, PanelData, DataSourceApi } from '@grafana/data';
|
||||
@@ -49,7 +49,7 @@ interface State {
|
||||
relativeTime: string;
|
||||
timeShift: string;
|
||||
cacheTimeout: string;
|
||||
maxDataPoints: string | ReactText;
|
||||
maxDataPoints: number | string;
|
||||
interval: string;
|
||||
hideTimeOverride: boolean;
|
||||
isOpen: boolean;
|
||||
@@ -63,7 +63,7 @@ export class QueryOptions extends PureComponent<Props, State> {
|
||||
relativeTime: props.panel.timeFrom || '',
|
||||
timeShift: props.panel.timeShift || '',
|
||||
cacheTimeout: props.panel.cacheTimeout || '',
|
||||
maxDataPoints: props.panel.maxDataPoints || '',
|
||||
maxDataPoints: props.panel.maxDataPoints ?? '',
|
||||
interval: props.panel.interval || '',
|
||||
hideTimeOverride: props.panel.hideTimeOverride || false,
|
||||
isOpen: false,
|
||||
@@ -124,6 +124,20 @@ export class QueryOptions extends PureComponent<Props, State> {
|
||||
this.setState({ ...this.state, [panelKey]: event.target.value });
|
||||
};
|
||||
|
||||
onMaxDataPointsBlur = () => {
|
||||
const { panel } = this.props;
|
||||
|
||||
const maxDataPoints = parseInt(this.state.maxDataPoints as string, 10);
|
||||
|
||||
if (isNaN(maxDataPoints)) {
|
||||
delete panel.maxDataPoints;
|
||||
} else {
|
||||
panel.maxDataPoints = maxDataPoints;
|
||||
}
|
||||
|
||||
panel.refresh();
|
||||
};
|
||||
|
||||
renderCacheTimeoutOption() {
|
||||
const { dataSource } = this.props;
|
||||
const { cacheTimeout } = this.state;
|
||||
@@ -176,12 +190,12 @@ export class QueryOptions extends PureComponent<Props, State> {
|
||||
Max data points
|
||||
</InlineFormLabel>
|
||||
<Input
|
||||
type="text"
|
||||
type="number"
|
||||
className="width-6"
|
||||
placeholder={`${realMd}`}
|
||||
name={name}
|
||||
spellCheck={false}
|
||||
onBlur={this.onDataSourceOptionBlur('maxDataPoints')}
|
||||
onBlur={this.onMaxDataPointsBlur}
|
||||
onChange={this.onDataSourceOptionChange('maxDataPoints')}
|
||||
value={maxDataPoints}
|
||||
/>
|
||||
|
||||
@@ -86,6 +86,8 @@ describe('PanelModel', () => {
|
||||
|
||||
modelJson = {
|
||||
type: 'table',
|
||||
maxDataPoints: 100,
|
||||
interval: '5m',
|
||||
showColumns: true,
|
||||
targets: [{ refId: 'A' }, { noRefId: true }],
|
||||
options: persistedOptionsMock,
|
||||
@@ -225,6 +227,14 @@ describe('PanelModel', () => {
|
||||
expect(model.editSourceId).toBe(1001);
|
||||
});
|
||||
|
||||
it('should keep maxDataPoints', () => {
|
||||
expect(model.maxDataPoints).toBe(100);
|
||||
});
|
||||
|
||||
it('should keep interval', () => {
|
||||
expect(model.interval).toBe('5m');
|
||||
});
|
||||
|
||||
it('should apply next panel option defaults', () => {
|
||||
expect(model.getOptions().showThresholdLabels).toBeFalsy();
|
||||
expect(model.getOptions().showThresholds).toBeUndefined();
|
||||
@@ -313,18 +323,6 @@ describe('PanelModel', () => {
|
||||
expect(model.someProperty).toBeUndefined();
|
||||
});
|
||||
|
||||
it('Should preserve must keep properties', () => {
|
||||
model.id = 10;
|
||||
model.gridPos = { x: 0, y: 0, h: 10, w: 10 };
|
||||
model.restoreModel({
|
||||
title: 'New title',
|
||||
options: {},
|
||||
});
|
||||
|
||||
expect(model.id).toBe(10);
|
||||
expect(model.gridPos.h).toBe(10);
|
||||
});
|
||||
|
||||
it('Should remove old angular panel specfic props', () => {
|
||||
model.axes = [{ prop: 1 }];
|
||||
model.thresholds = [];
|
||||
@@ -337,6 +335,13 @@ describe('PanelModel', () => {
|
||||
expect(model.axes).toBeUndefined();
|
||||
expect(model.thresholds).toBeUndefined();
|
||||
});
|
||||
|
||||
it('Should be able to set defaults back to default', () => {
|
||||
model.transparent = true;
|
||||
|
||||
model.restoreModel({});
|
||||
expect(model.transparent).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroy', () => {
|
||||
|
||||
@@ -82,6 +82,8 @@ const mustKeepProps: { [str: string]: boolean } = {
|
||||
transformations: true,
|
||||
fieldConfig: true,
|
||||
editSourceId: true,
|
||||
maxDataPoints: true,
|
||||
interval: true,
|
||||
};
|
||||
|
||||
const defaults: any = {
|
||||
@@ -90,6 +92,7 @@ const defaults: any = {
|
||||
cachedPluginOptions: {},
|
||||
transparent: false,
|
||||
options: {},
|
||||
datasource: null,
|
||||
};
|
||||
|
||||
export class PanelModel implements DataConfigSource {
|
||||
@@ -146,9 +149,6 @@ export class PanelModel implements DataConfigSource {
|
||||
|
||||
constructor(model: any) {
|
||||
this.events = new Emitter();
|
||||
// should not be part of defaults as defaults are removed in save model and
|
||||
// this should not be removed in save model as exporter needs to templatize it
|
||||
this.datasource = null;
|
||||
this.restoreModel(model);
|
||||
this.replaceVariables = this.replaceVariables.bind(this);
|
||||
}
|
||||
@@ -156,12 +156,8 @@ export class PanelModel implements DataConfigSource {
|
||||
/** Given a persistened PanelModel restores property values */
|
||||
restoreModel(model: any) {
|
||||
// Start with clean-up
|
||||
for (const property of Object.keys(this)) {
|
||||
if (notPersistedProperties[property]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mustKeepProps[property]) {
|
||||
for (const property in this) {
|
||||
if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -169,10 +165,6 @@ export class PanelModel implements DataConfigSource {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!this.hasOwnProperty(property)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof (this as any)[property] === 'function') {
|
||||
continue;
|
||||
}
|
||||
@@ -215,7 +207,6 @@ export class PanelModel implements DataConfigSource {
|
||||
|
||||
updateOptions(options: object) {
|
||||
this.options = options;
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
@@ -228,6 +219,7 @@ export class PanelModel implements DataConfigSource {
|
||||
|
||||
getSaveModel() {
|
||||
const model: any = {};
|
||||
|
||||
for (const property in this) {
|
||||
if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
|
||||
continue;
|
||||
@@ -239,6 +231,13 @@ export class PanelModel implements DataConfigSource {
|
||||
|
||||
model[property] = _.cloneDeep(this[property]);
|
||||
}
|
||||
|
||||
if (model.datasource === undefined) {
|
||||
// This is part of defaults as defaults are removed in save model and
|
||||
// this should not be removed in save model as exporter needs to templatize it
|
||||
model.datasource = null;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user