Skip to content

Commit

Permalink
DataLinks: Fix url field not releasing focus (grafana#19804)
Browse files Browse the repository at this point in the history
  • Loading branch information
aocenas authored Oct 16, 2019
1 parent 7f702f8 commit 09a5999
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useMemo, useContext, useRef, RefObject } from 'react';
import React, { useState, useMemo, useContext, useRef, RefObject, memo } from 'react';
import { VariableSuggestion, VariableOrigin, DataLinkSuggestions } from './DataLinkSuggestions';
import { ThemeContext, DataLinkBuiltInVars, makeValue } from '../../index';
import { SelectionReference } from './SelectionReference';
Expand Down Expand Up @@ -41,7 +41,9 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => ({
`,
}));

export const DataLinkInput: React.FC<DataLinkInputProps> = ({ value, onChange, suggestions }) => {
// This memoised also because rerendering the slate editor grabs focus which created problem in some cases this
// was used and changes to different state were propagated here.
export const DataLinkInput: React.FC<DataLinkInputProps> = memo(({ value, onChange, suggestions }) => {
const editorRef = useRef<Editor>() as RefObject<Editor>;
const theme = useContext(ThemeContext);
const styles = getStyles(theme);
Expand Down Expand Up @@ -91,6 +93,7 @@ export const DataLinkInput: React.FC<DataLinkInputProps> = ({ value, onChange, s
const onUrlBlur = React.useCallback((event: Event, editor: CoreEditor, next: () => any) => {
// Callback needed for blur to work correctly
stateRef.current.onChange(Plain.serialize(stateRef.current.linkUrl), () => {
// This needs to be called after state is updated.
editorRef.current!.blur();
});
}, []);
Expand Down Expand Up @@ -161,6 +164,6 @@ export const DataLinkInput: React.FC<DataLinkInputProps> = ({ value, onChange, s
</div>
</div>
);
};
});

DataLinkInput.displayName = 'DataLinkInput';
6 changes: 5 additions & 1 deletion packages/grafana-ui/src/types/panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ export interface PanelProps<T = any> {

export interface PanelEditorProps<T = any> {
options: T;
onOptionsChange: (options: T) => void;
onOptionsChange: (
options: T,
// callback can be used to run something right after update.
callback?: () => void
) => void;
data: PanelData;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ export class VisualizationTab extends PureComponent<Props, State> {
this.setState({ searchQuery: '' });
};

onPanelOptionsChanged = (options: any) => {
onPanelOptionsChanged = (options: any, callback?: () => void) => {
this.props.panel.updateOptions(options);
this.forceUpdate();
this.forceUpdate(callback);
};

onOpenVizPicker = () => {
Expand Down
45 changes: 30 additions & 15 deletions public/app/plugins/panel/gauge/GaugePanelEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,39 @@ export class GaugePanelEditor extends PureComponent<PanelEditorProps<GaugeOption
});
};

onDisplayOptionsChanged = (fieldOptions: FieldDisplayOptions) =>
this.props.onOptionsChange({
...this.props.options,
fieldOptions,
});
onDisplayOptionsChanged = (
fieldOptions: FieldDisplayOptions,
event?: React.SyntheticEvent<HTMLElement>,
callback?: () => void
) =>
this.props.onOptionsChange(
{
...this.props.options,
fieldOptions,
},
callback
);

onDefaultsChange = (field: FieldConfig) => {
this.onDisplayOptionsChanged({
...this.props.options.fieldOptions,
defaults: field,
});
onDefaultsChange = (field: FieldConfig, event?: React.SyntheticEvent<HTMLElement>, callback?: () => void) => {
this.onDisplayOptionsChanged(
{
...this.props.options.fieldOptions,
defaults: field,
},
event,
callback
);
};

onDataLinksChanged = (links: DataLink[]) => {
this.onDefaultsChange({
...this.props.options.fieldOptions.defaults,
links,
});
onDataLinksChanged = (links: DataLink[], callback?: () => void) => {
this.onDefaultsChange(
{
...this.props.options.fieldOptions.defaults,
links,
},
undefined,
callback
);
};

render() {
Expand Down

0 comments on commit 09a5999

Please sign in to comment.