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>
This commit is contained in:
Alex Khomenko 2021-02-12 16:00:12 +02:00 committed by GitHub
parent 8c35ed4014
commit 6f1a38cbe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 19 deletions

View File

@ -7,8 +7,8 @@ import { DashboardSearchHit } from 'app/features/search/types';
import { DashboardDTO } from 'app/types';
export interface Props {
onSelected: (dashboard: DashboardDTO) => void;
currentDashboard?: SelectableValue;
onChange: (dashboard: DashboardDTO) => void;
value?: SelectableValue;
width?: number;
isClearable?: boolean;
invalid?: boolean;
@ -26,14 +26,7 @@ const getDashboards = (query = '') => {
});
};
export const DashboardPicker: FC<Props> = ({
onSelected,
currentDashboard,
width,
isClearable = false,
invalid,
disabled,
}) => {
export const DashboardPicker: FC<Props> = ({ onChange, value, width, isClearable = false, invalid, disabled }) => {
const debouncedSearch = debounce(getDashboards, 300);
return (
@ -42,10 +35,10 @@ export const DashboardPicker: FC<Props> = ({
isClearable={isClearable}
defaultOptions={true}
loadOptions={debouncedSearch}
onChange={onSelected}
onChange={onChange}
placeholder="Select dashboard"
noOptionsMessage="No dashboards found"
value={currentDashboard}
value={value}
invalid={invalid}
disabled={disabled}
/>

View File

@ -36,7 +36,7 @@ type Props = OwnProps & ConnectedProps & DispatchProps;
export class OptionsPickerUnconnected extends PureComponent<Props> {
onShowOptions = () => this.props.showOptions(this.props.variable);
onHideOptions = () => this.props.commitChangesToVariable();
onHideOptions = () => this.props.commitChangesToVariable(this.props.onVariableChange);
onToggleOption = (option: VariableOption, clearOthers: boolean) => {
const toggleFunc = this.props.variable.multi ? this.onToggleMultiValueVariable : this.onToggleSingleValueVariable;

View File

@ -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) => {
const picker = getState().templating.optionsPicker;
const existing = getVariable<VariableWithMultiSupport>(picker.id, getState());
@ -88,9 +94,11 @@ export const commitChangesToVariable = (): ThunkResult<void> => {
return;
}
const adapter = variableAdapters.get(updated.type);
await adapter.setValue(updated, updated.current, true);
return;
if (callback) {
return callback(updated);
}
return setVariable(updated);
};
};
@ -159,7 +167,7 @@ const searchForOptions = async (dispatch: ThunkDispatch, getState: () => StoreSt
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;
if (options.length === 0 && searchQuery && searchQuery.length > 0) {

View File

@ -2,6 +2,7 @@ import { VariableModel } from '../types';
export interface VariablePickerProps<Model extends VariableModel = VariableModel> {
variable: Model;
onVariableChange?: (variable: Model) => void;
}
export enum NavigationKey {

View File

@ -10,7 +10,7 @@ import { useDispatch } from 'react-redux';
export interface Props extends VariablePickerProps<TextBoxVariableModel> {}
export function TextBoxVariablePicker({ variable }: Props): ReactElement {
export function TextBoxVariablePicker({ variable, onVariableChange }: Props): ReactElement {
const dispatch = useDispatch();
const [updatedValue, setUpdatedValue] = useState(variable.current.value);
useEffect(() => {
@ -27,6 +27,15 @@ export function TextBoxVariablePicker({ variable }: Props): ReactElement {
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);
}, [dispatch, variable, updatedValue]);