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, toVariableIdentifier, toVariablePayload, VariableIdentifier } from '../state/types'; import cloneDeep from 'lodash/cloneDeep'; import { VariableType } from '@grafana/data'; import { addVariable, removeVariable } from '../state/sharedReducer'; import { updateOptions } from '../state/actions'; import { VariableModel } from '../types'; export const variableEditorMount = (identifier: VariableIdentifier): ThunkResult => { return async (dispatch) => { dispatch(variableEditorMounted({ name: getVariable(identifier.id).name })); }; }; export const variableEditorUnMount = (identifier: VariableIdentifier): ThunkResult => { return async (dispatch, getState) => { dispatch(variableEditorUnMounted(toVariablePayload(identifier))); }; }; export const onEditorUpdate = (identifier: VariableIdentifier): ThunkResult => { return async (dispatch) => { await dispatch(updateOptions(identifier)); dispatch(switchToListMode()); }; }; export const changeVariableName = (identifier: VariableIdentifier, newName: string): ThunkResult => { 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; } dispatch(completeChangeVariableName(identifier, newName)); }; }; export const completeChangeVariableName = (identifier: VariableIdentifier, newName: string): ThunkResult => ( 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 = (type: VariableType = 'query'): ThunkResult => (dispatch, getState) => { const id = getNextAvailableId(type, getVariables(getState())); const identifier = { type, id }; const global = false; const index = getNewVariabelIndex(getState()); const model = cloneDeep(variableAdapters.get(type).initialState); model.id = id; model.name = id; dispatch( addVariable( toVariablePayload(identifier, { global, model, index }) ) ); dispatch(setIdInEditor({ id: identifier.id })); }; export const switchToEditMode = (identifier: VariableIdentifier): ThunkResult => (dispatch) => { dispatch(setIdInEditor({ id: identifier.id })); }; export const switchToListMode = (): ThunkResult => (dispatch) => { dispatch(clearIdInEditor()); }; export function getNextAvailableId(type: VariableType, variables: VariableModel[]): string { let counter = 0; let nextId = `${type}${counter}`; while (variables.find((variable) => variable.id === nextId)) { nextId = `${type}${++counter}`; } return nextId; }