mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
* Fix variable editor name-input bug You couldn't delete an invalid character after typing it into the name-input field. While investigating the issue turned out to be bigger, as there was a problem with valid characters too. (See test scenarios below) The fix seems to be, to remove an unnecessary check in the `changeVariableName` action. There is theoretically now the possibility, that the `changeVariableName` action is called with the same name, as the variable is already, but practically there seems no possibility, that this could happen. A test, which checks that, had to be removed too. Test scenarios: * 1st Scenario 1. Type "@" 2. Try deleting it * 2nd Scenario 1. Type "w" 2. delete "w" 3. Try typing "w" again Fixes #26562 * Fix bug when updating existing variable
135 lines
5.0 KiB
TypeScript
135 lines
5.0 KiB
TypeScript
import { ThunkResult } from '../../../types';
|
|
import { getNewVariabelIndex, getVariable, getVariables } from '../state/selectors';
|
|
import {
|
|
changeVariableNameFailed,
|
|
changeVariableNameSucceeded,
|
|
clearIdInEditor,
|
|
setIdInEditor,
|
|
variableEditorMounted,
|
|
variableEditorUnMounted,
|
|
} from './reducer';
|
|
import { variableAdapters } from '../adapters';
|
|
import {
|
|
AddVariable,
|
|
NEW_VARIABLE_ID,
|
|
toVariableIdentifier,
|
|
toVariablePayload,
|
|
VariableIdentifier,
|
|
} from '../state/types';
|
|
import cloneDeep from 'lodash/cloneDeep';
|
|
import { VariableType } from '@grafana/data';
|
|
import { addVariable, removeVariable, storeNewVariable } from '../state/sharedReducer';
|
|
|
|
export const variableEditorMount = (identifier: VariableIdentifier): ThunkResult<void> => {
|
|
return async dispatch => {
|
|
dispatch(variableEditorMounted({ name: getVariable(identifier.id).name }));
|
|
};
|
|
};
|
|
|
|
export const variableEditorUnMount = (identifier: VariableIdentifier): ThunkResult<void> => {
|
|
return async (dispatch, getState) => {
|
|
dispatch(variableEditorUnMounted(toVariablePayload(identifier)));
|
|
if (getState().templating.variables[NEW_VARIABLE_ID]) {
|
|
dispatch(removeVariable(toVariablePayload({ type: identifier.type, id: NEW_VARIABLE_ID }, { reIndex: false })));
|
|
}
|
|
};
|
|
};
|
|
|
|
export const onEditorUpdate = (identifier: VariableIdentifier): ThunkResult<void> => {
|
|
return async (dispatch, getState) => {
|
|
const variableInState = getVariable(identifier.id, getState());
|
|
await variableAdapters.get(variableInState.type).updateOptions(variableInState);
|
|
dispatch(switchToListMode());
|
|
};
|
|
};
|
|
|
|
export const onEditorAdd = (identifier: VariableIdentifier): ThunkResult<void> => {
|
|
return async (dispatch, getState) => {
|
|
const newVariableInState = getVariable(NEW_VARIABLE_ID, getState());
|
|
const id = newVariableInState.name;
|
|
dispatch(storeNewVariable(toVariablePayload({ type: identifier.type, id })));
|
|
const variableInState = getVariable(id, getState());
|
|
await variableAdapters.get(variableInState.type).updateOptions(variableInState);
|
|
dispatch(switchToListMode());
|
|
dispatch(removeVariable(toVariablePayload({ type: identifier.type, id: NEW_VARIABLE_ID }, { reIndex: false })));
|
|
};
|
|
};
|
|
|
|
export const changeVariableName = (identifier: VariableIdentifier, newName: string): ThunkResult<void> => {
|
|
return (dispatch, getState) => {
|
|
let errorText = null;
|
|
if (!newName.match(/^(?!__).*$/)) {
|
|
errorText = "Template names cannot begin with '__', that's reserved for Grafana's global variables";
|
|
}
|
|
|
|
if (!newName.match(/^\w+$/)) {
|
|
errorText = 'Only word and digit characters are allowed in variable names';
|
|
}
|
|
|
|
const variables = getVariables(getState());
|
|
const foundVariables = variables.filter(v => v.name === newName && v.id !== identifier.id);
|
|
|
|
if (foundVariables.length) {
|
|
errorText = 'Variable with the same name already exists';
|
|
}
|
|
|
|
if (errorText) {
|
|
dispatch(changeVariableNameFailed({ newName, errorText }));
|
|
return;
|
|
}
|
|
|
|
const thunkToCall = identifier.id === NEW_VARIABLE_ID ? completeChangeNewVariableName : completeChangeVariableName;
|
|
dispatch(thunkToCall(identifier, newName));
|
|
};
|
|
};
|
|
|
|
export const completeChangeNewVariableName = (
|
|
identifier: VariableIdentifier,
|
|
newName: string
|
|
): ThunkResult<void> => dispatch => {
|
|
dispatch(changeVariableNameSucceeded(toVariablePayload(identifier, { newName })));
|
|
};
|
|
|
|
export const completeChangeVariableName = (identifier: VariableIdentifier, newName: string): ThunkResult<void> => (
|
|
dispatch,
|
|
getState
|
|
) => {
|
|
const originalVariable = getVariable(identifier.id, getState());
|
|
if (originalVariable.name === newName) {
|
|
dispatch(changeVariableNameSucceeded(toVariablePayload(identifier, { newName })));
|
|
return;
|
|
}
|
|
const model = { ...cloneDeep(originalVariable), name: newName, id: newName };
|
|
const global = originalVariable.global;
|
|
const index = originalVariable.index;
|
|
const renamedIdentifier = toVariableIdentifier(model);
|
|
|
|
dispatch(addVariable(toVariablePayload(renamedIdentifier, { global, index, model })));
|
|
dispatch(changeVariableNameSucceeded(toVariablePayload(renamedIdentifier, { newName })));
|
|
dispatch(switchToEditMode(renamedIdentifier));
|
|
dispatch(removeVariable(toVariablePayload(identifier, { reIndex: false })));
|
|
};
|
|
|
|
export const switchToNewMode = (): ThunkResult<void> => (dispatch, getState) => {
|
|
const type: VariableType = 'query';
|
|
const id = NEW_VARIABLE_ID;
|
|
const global = false;
|
|
const model = cloneDeep(variableAdapters.get(type).initialState);
|
|
const index = getNewVariabelIndex(getState());
|
|
const identifier = { type, id };
|
|
dispatch(
|
|
addVariable(
|
|
toVariablePayload<AddVariable>(identifier, { global, model, index })
|
|
)
|
|
);
|
|
dispatch(setIdInEditor({ id: identifier.id }));
|
|
};
|
|
|
|
export const switchToEditMode = (identifier: VariableIdentifier): ThunkResult<void> => dispatch => {
|
|
dispatch(setIdInEditor({ id: identifier.id }));
|
|
};
|
|
|
|
export const switchToListMode = (): ThunkResult<void> => dispatch => {
|
|
dispatch(clearIdInEditor());
|
|
};
|