Commit 6f1a38cb by Alex Khomenko Committed by GitHub

Variables: Extend option pickers to accept custom onChange callback (#30913)

* Rename DashboardPicker props

* Extend variable option pickers to allow providing custom onchage callback

* Update public/app/features/variables/pickers/OptionsPicker/actions.ts

Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>

* Update public/app/features/variables/pickers/OptionsPicker/actions.ts

Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>

* Update public/app/features/variables/pickers/OptionsPicker/actions.ts

Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>

* Update public/app/features/variables/textbox/TextBoxVariablePicker.tsx

Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>

* Codeformat

Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
parent 8c35ed40
...@@ -7,8 +7,8 @@ import { DashboardSearchHit } from 'app/features/search/types'; ...@@ -7,8 +7,8 @@ import { DashboardSearchHit } from 'app/features/search/types';
import { DashboardDTO } from 'app/types'; import { DashboardDTO } from 'app/types';
export interface Props { export interface Props {
onSelected: (dashboard: DashboardDTO) => void; onChange: (dashboard: DashboardDTO) => void;
currentDashboard?: SelectableValue; value?: SelectableValue;
width?: number; width?: number;
isClearable?: boolean; isClearable?: boolean;
invalid?: boolean; invalid?: boolean;
...@@ -26,14 +26,7 @@ const getDashboards = (query = '') => { ...@@ -26,14 +26,7 @@ const getDashboards = (query = '') => {
}); });
}; };
export const DashboardPicker: FC<Props> = ({ export const DashboardPicker: FC<Props> = ({ onChange, value, width, isClearable = false, invalid, disabled }) => {
onSelected,
currentDashboard,
width,
isClearable = false,
invalid,
disabled,
}) => {
const debouncedSearch = debounce(getDashboards, 300); const debouncedSearch = debounce(getDashboards, 300);
return ( return (
...@@ -42,10 +35,10 @@ export const DashboardPicker: FC<Props> = ({ ...@@ -42,10 +35,10 @@ export const DashboardPicker: FC<Props> = ({
isClearable={isClearable} isClearable={isClearable}
defaultOptions={true} defaultOptions={true}
loadOptions={debouncedSearch} loadOptions={debouncedSearch}
onChange={onSelected} onChange={onChange}
placeholder="Select dashboard" placeholder="Select dashboard"
noOptionsMessage="No dashboards found" noOptionsMessage="No dashboards found"
value={currentDashboard} value={value}
invalid={invalid} invalid={invalid}
disabled={disabled} disabled={disabled}
/> />
......
...@@ -36,7 +36,7 @@ type Props = OwnProps & ConnectedProps & DispatchProps; ...@@ -36,7 +36,7 @@ type Props = OwnProps & ConnectedProps & DispatchProps;
export class OptionsPickerUnconnected extends PureComponent<Props> { export class OptionsPickerUnconnected extends PureComponent<Props> {
onShowOptions = () => this.props.showOptions(this.props.variable); onShowOptions = () => this.props.showOptions(this.props.variable);
onHideOptions = () => this.props.commitChangesToVariable(); onHideOptions = () => this.props.commitChangesToVariable(this.props.onVariableChange);
onToggleOption = (option: VariableOption, clearOthers: boolean) => { onToggleOption = (option: VariableOption, clearOthers: boolean) => {
const toggleFunc = this.props.variable.multi ? this.onToggleMultiValueVariable : this.onToggleSingleValueVariable; const toggleFunc = this.props.variable.multi ? this.onToggleMultiValueVariable : this.onToggleSingleValueVariable;
......
...@@ -72,7 +72,13 @@ export const filterOrSearchOptions = (searchQuery = ''): ThunkResult<void> => { ...@@ -72,7 +72,13 @@ export const filterOrSearchOptions = (searchQuery = ''): ThunkResult<void> => {
}; };
}; };
export const commitChangesToVariable = (): ThunkResult<void> => { const setVariable = async (updated: VariableWithMultiSupport) => {
const adapter = variableAdapters.get(updated.type);
await adapter.setValue(updated, updated.current, true);
return;
};
export const commitChangesToVariable = (callback?: (updated: VariableWithMultiSupport) => void): ThunkResult<void> => {
return async (dispatch, getState) => { return async (dispatch, getState) => {
const picker = getState().templating.optionsPicker; const picker = getState().templating.optionsPicker;
const existing = getVariable<VariableWithMultiSupport>(picker.id, getState()); const existing = getVariable<VariableWithMultiSupport>(picker.id, getState());
...@@ -88,9 +94,11 @@ export const commitChangesToVariable = (): ThunkResult<void> => { ...@@ -88,9 +94,11 @@ export const commitChangesToVariable = (): ThunkResult<void> => {
return; return;
} }
const adapter = variableAdapters.get(updated.type); if (callback) {
await adapter.setValue(updated, updated.current, true); return callback(updated);
return; }
return setVariable(updated);
}; };
}; };
...@@ -159,7 +167,7 @@ const searchForOptions = async (dispatch: ThunkDispatch, getState: () => StoreSt ...@@ -159,7 +167,7 @@ const searchForOptions = async (dispatch: ThunkDispatch, getState: () => StoreSt
const searchForOptionsWithDebounce = debounce(searchForOptions, 500); const searchForOptionsWithDebounce = debounce(searchForOptions, 500);
function mapToCurrent(picker: OptionsPickerState): VariableOption | undefined { export function mapToCurrent(picker: OptionsPickerState): VariableOption | undefined {
const { options, selectedValues, queryValue: searchQuery, multi } = picker; const { options, selectedValues, queryValue: searchQuery, multi } = picker;
if (options.length === 0 && searchQuery && searchQuery.length > 0) { if (options.length === 0 && searchQuery && searchQuery.length > 0) {
......
...@@ -2,6 +2,7 @@ import { VariableModel } from '../types'; ...@@ -2,6 +2,7 @@ import { VariableModel } from '../types';
export interface VariablePickerProps<Model extends VariableModel = VariableModel> { export interface VariablePickerProps<Model extends VariableModel = VariableModel> {
variable: Model; variable: Model;
onVariableChange?: (variable: Model) => void;
} }
export enum NavigationKey { export enum NavigationKey {
......
...@@ -10,7 +10,7 @@ import { useDispatch } from 'react-redux'; ...@@ -10,7 +10,7 @@ import { useDispatch } from 'react-redux';
export interface Props extends VariablePickerProps<TextBoxVariableModel> {} export interface Props extends VariablePickerProps<TextBoxVariableModel> {}
export function TextBoxVariablePicker({ variable }: Props): ReactElement { export function TextBoxVariablePicker({ variable, onVariableChange }: Props): ReactElement {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [updatedValue, setUpdatedValue] = useState(variable.current.value); const [updatedValue, setUpdatedValue] = useState(variable.current.value);
useEffect(() => { useEffect(() => {
...@@ -27,6 +27,15 @@ export function TextBoxVariablePicker({ variable }: Props): ReactElement { ...@@ -27,6 +27,15 @@ export function TextBoxVariablePicker({ variable }: Props): ReactElement {
toVariablePayload({ id: variable.id, type: variable.type }, { propName: 'query', propValue: updatedValue }) toVariablePayload({ id: variable.id, type: variable.type }, { propName: 'query', propValue: updatedValue })
) )
); );
if (onVariableChange) {
onVariableChange({
...variable,
current: { ...variable.current, value: updatedValue },
});
return;
}
variableAdapters.get(variable.type).updateOptions(variable); variableAdapters.get(variable.type).updateOptions(variable);
}, [dispatch, variable, updatedValue]); }, [dispatch, variable, updatedValue]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment