diff --git a/public/app/core/angular_wrappers.ts b/public/app/core/angular_wrappers.ts index 9fc4503803a..01a1b238e1c 100644 --- a/public/app/core/angular_wrappers.ts +++ b/public/app/core/angular_wrappers.ts @@ -28,7 +28,7 @@ import { SaveDashboardAsButtonConnected, SaveDashboardButtonConnected, } from '../features/dashboard/components/SaveDashboard/SaveDashboardButton'; -import { VariableEditorContainer } from '../features/templating/editor/VariableEditorContainer'; +import { VariableEditorContainer } from '../features/variables/editor/VariableEditorContainer'; export function registerAngularDirectives() { react2AngularDirective('footer', Footer, []); diff --git a/public/app/core/reducers/root.ts b/public/app/core/reducers/root.ts index 35492dc6d15..3914e14a412 100644 --- a/public/app/core/reducers/root.ts +++ b/public/app/core/reducers/root.ts @@ -13,7 +13,7 @@ import usersReducers from 'app/features/users/state/reducers'; import userReducers from 'app/features/profile/state/reducers'; import organizationReducers from 'app/features/org/state/reducers'; import ldapReducers from 'app/features/admin/state/reducers'; -import templatingReducers from 'app/features/templating/state/reducers'; +import templatingReducers from 'app/features/variables/state/reducers'; const rootReducers = { ...sharedReducers, diff --git a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx index 5fa5c35e8ca..e46c257fefa 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenu.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenu.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { connect, MapStateToProps } from 'react-redux'; import { StoreState } from '../../../../types'; -import { getVariableClones } from '../../../templating/state/selectors'; +import { getVariableClones } from '../../../variables/state/selectors'; import { VariableHide, VariableModel } from '../../../templating/variable'; import { DashboardModel } from '../../state'; import { AngularDashboardLinks } from './AngularDashboardLinks'; diff --git a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx index af1c37f2bcc..78d035cbcd6 100644 --- a/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx +++ b/public/app/features/dashboard/components/SubMenu/SubMenuItems.tsx @@ -1,7 +1,7 @@ import React, { FunctionComponent, useEffect, useState } from 'react'; import { VariableHide, VariableModel } from '../../../templating/variable'; import { e2e } from '@grafana/e2e'; -import { PickerRenderer } from '../../../templating/pickers/PickerRenderer'; +import { PickerRenderer } from '../../../variables/pickers/PickerRenderer'; interface Props { variables: VariableModel[]; diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index 8471375bdbe..04042daa77d 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -15,8 +15,8 @@ import { UrlQueryValue } from '@grafana/runtime'; import { CoreEvents, DashboardMeta, KIOSK_MODE_TV } from 'app/types'; import { VariableModel } from '../../templating/variable'; import { getConfig } from '../../../core/config'; -import { getVariables } from 'app/features/templating/state/selectors'; -import { variableAdapters } from 'app/features/templating/adapters'; +import { getVariables } from 'app/features/variables/state/selectors'; +import { variableAdapters } from 'app/features/variables/adapters'; export interface CloneOptions { saveVariables?: boolean; diff --git a/public/app/features/dashboard/state/initDashboard.ts b/public/app/features/dashboard/state/initDashboard.ts index 8a8fed2d09a..45f59d4c382 100644 --- a/public/app/features/dashboard/state/initDashboard.ts +++ b/public/app/features/dashboard/state/initDashboard.ts @@ -23,8 +23,8 @@ import { DashboardDTO, DashboardRouteInfo, StoreState, ThunkDispatch, ThunkResul import { DashboardModel } from './DashboardModel'; import { DataQuery } from '@grafana/data'; import { getConfig } from '../../../core/config'; -import { initDashboardTemplating, processVariables } from '../../templating/state/actions'; -import { variableAdapters } from '../../templating/adapters'; +import { initDashboardTemplating, processVariables } from '../../variables/state/actions'; +import { variableAdapters } from '../../variables/adapters'; export interface InitDashboardArgs { $injector: any; diff --git a/public/app/features/panel/repeat_option.ts b/public/app/features/panel/repeat_option.ts index 2fab9e695ad..9d847807a93 100644 --- a/public/app/features/panel/repeat_option.ts +++ b/public/app/features/panel/repeat_option.ts @@ -1,7 +1,7 @@ import { coreModule } from 'app/core/core'; import { VariableSrv } from 'app/features/templating/variable_srv'; import { getConfig } from '../../core/config'; -import { getVariables } from '../templating/state/selectors'; +import { getVariables } from '../variables/state/selectors'; const template = `
diff --git a/public/app/features/templating/all.ts b/public/app/features/templating/all.ts index 13f27b9b1e5..50804fe4b61 100644 --- a/public/app/features/templating/all.ts +++ b/public/app/features/templating/all.ts @@ -10,11 +10,12 @@ import { CustomVariable } from './custom_variable'; import { ConstantVariable } from './constant_variable'; import { AdhocVariable } from './adhoc_variable'; import { TextBoxVariable } from './TextBoxVariable'; -import { variableAdapters } from './adapters'; -import { createQueryVariableAdapter } from './query/adapter'; -import { createCustomVariableAdapter } from './custom/adapter'; -import { createTextBoxVariableAdapter } from './textbox/adapter'; -import { createConstantVariableAdapter } from './constant/adapter'; +import { variableAdapters } from '../variables/adapters'; +import { createQueryVariableAdapter } from '../variables/query/adapter'; +import { createCustomVariableAdapter } from '../variables/custom/adapter'; +import { createTextBoxVariableAdapter } from '../variables/textbox/adapter'; +import { createConstantVariableAdapter } from '../variables/constant/adapter'; +import { createDataSourceVariableAdapter } from '../variables/datasource/adapter'; coreModule.factory('templateSrv', () => templateSrv); @@ -33,3 +34,4 @@ variableAdapters.set('query', createQueryVariableAdapter()); variableAdapters.set('custom', createCustomVariableAdapter()); variableAdapters.set('textbox', createTextBoxVariableAdapter()); variableAdapters.set('constant', createConstantVariableAdapter()); +variableAdapters.set('datasource', createDataSourceVariableAdapter()); diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts index 63df7ec7b21..736df956054 100644 --- a/public/app/features/templating/template_srv.ts +++ b/public/app/features/templating/template_srv.ts @@ -3,7 +3,7 @@ import _ from 'lodash'; import { variableRegex } from 'app/features/templating/variable'; import { escapeHtml } from 'app/core/utils/text'; import { ScopedVars, TimeRange } from '@grafana/data'; -import { getVariableWithName } from './state/selectors'; +import { getVariableWithName } from '../variables/state/selectors'; import { getState } from '../../store/store'; import { getConfig } from 'app/core/config'; diff --git a/public/app/features/templating/adapters.ts b/public/app/features/variables/adapters.ts similarity index 96% rename from public/app/features/templating/adapters.ts rename to public/app/features/variables/adapters.ts index 23ab5343de8..926ac37c378 100644 --- a/public/app/features/templating/adapters.ts +++ b/public/app/features/variables/adapters.ts @@ -2,7 +2,7 @@ import { ComponentType } from 'react'; import { Reducer } from 'redux'; import { UrlQueryValue } from '@grafana/runtime'; -import { VariableModel, VariableOption, VariableType } from './variable'; +import { VariableModel, VariableOption, VariableType } from '../templating/variable'; import { VariableEditorProps } from './editor/types'; import { VariablesState } from './state/variablesReducer'; import { VariablePickerProps } from './pickers/types'; diff --git a/public/app/features/templating/constant/ConstantVariableEditor.tsx b/public/app/features/variables/constant/ConstantVariableEditor.tsx similarity index 95% rename from public/app/features/templating/constant/ConstantVariableEditor.tsx rename to public/app/features/variables/constant/ConstantVariableEditor.tsx index c83ba23f2c7..d946f467fab 100644 --- a/public/app/features/templating/constant/ConstantVariableEditor.tsx +++ b/public/app/features/variables/constant/ConstantVariableEditor.tsx @@ -1,7 +1,7 @@ import React, { ChangeEvent, FocusEvent, PureComponent } from 'react'; import { e2e } from '@grafana/e2e'; -import { ConstantVariableModel } from '../variable'; +import { ConstantVariableModel } from '../../templating/variable'; import { VariableEditorProps } from '../editor/types'; export interface Props extends VariableEditorProps {} diff --git a/public/app/features/templating/constant/actions.test.ts b/public/app/features/variables/constant/actions.test.ts similarity index 89% rename from public/app/features/templating/constant/actions.test.ts rename to public/app/features/variables/constant/actions.test.ts index f509c601a8d..84f2e602d55 100644 --- a/public/app/features/templating/constant/actions.test.ts +++ b/public/app/features/variables/constant/actions.test.ts @@ -1,10 +1,10 @@ import { variableAdapters } from '../adapters'; -import { createConstantVariableAdapter } from '../constant/adapter'; +import { createConstantVariableAdapter } from './adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { TemplatingState } from 'app/features/templating/state/reducers'; +import { TemplatingState } from 'app/features/variables/state/reducers'; import { updateConstantVariableOptions } from './actions'; import { getTemplatingRootReducer } from '../state/helpers'; -import { ConstantVariableModel, VariableOption, VariableHide } from '../variable'; +import { ConstantVariableModel, VariableHide, VariableOption } from '../../templating/variable'; import { toVariablePayload } from '../state/types'; import { createConstantOptionsFromQuery } from './reducer'; import { setCurrentVariableValue } from '../state/sharedReducer'; diff --git a/public/app/features/templating/constant/actions.ts b/public/app/features/variables/constant/actions.ts similarity index 100% rename from public/app/features/templating/constant/actions.ts rename to public/app/features/variables/constant/actions.ts diff --git a/public/app/features/templating/constant/adapter.ts b/public/app/features/variables/constant/adapter.ts similarity index 96% rename from public/app/features/templating/constant/adapter.ts rename to public/app/features/variables/constant/adapter.ts index 03ab39d4e63..d930a24dda4 100644 --- a/public/app/features/templating/constant/adapter.ts +++ b/public/app/features/variables/constant/adapter.ts @@ -1,5 +1,5 @@ import cloneDeep from 'lodash/cloneDeep'; -import { ConstantVariableModel } from '../variable'; +import { ConstantVariableModel } from '../../templating/variable'; import { dispatch } from '../../../store/store'; import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; import { VariableAdapter } from '../adapters'; diff --git a/public/app/features/templating/constant/reducer.test.ts b/public/app/features/variables/constant/reducer.test.ts similarity index 97% rename from public/app/features/templating/constant/reducer.test.ts rename to public/app/features/variables/constant/reducer.test.ts index f22e1e0799b..add0528cc4a 100644 --- a/public/app/features/templating/constant/reducer.test.ts +++ b/public/app/features/variables/constant/reducer.test.ts @@ -4,7 +4,7 @@ import { getVariableTestContext } from '../state/helpers'; import { toVariablePayload } from '../state/types'; import { constantVariableReducer, createConstantOptionsFromQuery } from './reducer'; import { VariablesState } from '../state/variablesReducer'; -import { ConstantVariableModel } from '../variable'; +import { ConstantVariableModel } from '../../templating/variable'; import { createConstantVariableAdapter } from './adapter'; describe('constantVariableReducer', () => { diff --git a/public/app/features/templating/constant/reducer.ts b/public/app/features/variables/constant/reducer.ts similarity index 97% rename from public/app/features/templating/constant/reducer.ts rename to public/app/features/variables/constant/reducer.ts index d0c4cfbfa67..9d209982a52 100644 --- a/public/app/features/templating/constant/reducer.ts +++ b/public/app/features/variables/constant/reducer.ts @@ -1,5 +1,5 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { ConstantVariableModel, VariableHide, VariableOption } from '../variable'; +import { ConstantVariableModel, VariableHide, VariableOption } from '../../templating/variable'; import { EMPTY_UUID, getInstanceState, VariablePayload } from '../state/types'; import { initialVariablesState, VariablesState } from '../state/variablesReducer'; diff --git a/public/app/features/templating/custom/CustomVariableEditor.tsx b/public/app/features/variables/custom/CustomVariableEditor.tsx similarity index 98% rename from public/app/features/templating/custom/CustomVariableEditor.tsx rename to public/app/features/variables/custom/CustomVariableEditor.tsx index c89279ab7f4..d895752e809 100644 --- a/public/app/features/templating/custom/CustomVariableEditor.tsx +++ b/public/app/features/variables/custom/CustomVariableEditor.tsx @@ -1,5 +1,5 @@ import React, { ChangeEvent, FocusEvent, PureComponent } from 'react'; -import { CustomVariableModel, VariableWithMultiSupport } from '../variable'; +import { CustomVariableModel, VariableWithMultiSupport } from '../../templating/variable'; import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; diff --git a/public/app/features/templating/custom/actions.test.ts b/public/app/features/variables/custom/actions.test.ts similarity index 96% rename from public/app/features/templating/custom/actions.test.ts rename to public/app/features/variables/custom/actions.test.ts index e363a339797..f182cf8820e 100644 --- a/public/app/features/templating/custom/actions.test.ts +++ b/public/app/features/variables/custom/actions.test.ts @@ -3,7 +3,7 @@ import { updateCustomVariableOptions } from './actions'; import { createCustomVariableAdapter } from './adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; import { getTemplatingRootReducer } from '../state/helpers'; -import { VariableOption, VariableHide, CustomVariableModel } from '../variable'; +import { CustomVariableModel, VariableHide, VariableOption } from '../../templating/variable'; import { toVariablePayload } from '../state/types'; import { setCurrentVariableValue } from '../state/sharedReducer'; import { initDashboardTemplating } from '../state/actions'; diff --git a/public/app/features/templating/custom/actions.ts b/public/app/features/variables/custom/actions.ts similarity index 100% rename from public/app/features/templating/custom/actions.ts rename to public/app/features/variables/custom/actions.ts diff --git a/public/app/features/templating/custom/adapter.ts b/public/app/features/variables/custom/adapter.ts similarity index 96% rename from public/app/features/templating/custom/adapter.ts rename to public/app/features/variables/custom/adapter.ts index d0ecd968457..a4ee7bad3cd 100644 --- a/public/app/features/templating/custom/adapter.ts +++ b/public/app/features/variables/custom/adapter.ts @@ -1,5 +1,5 @@ import cloneDeep from 'lodash/cloneDeep'; -import { CustomVariableModel } from '../variable'; +import { CustomVariableModel } from '../../templating/variable'; import { dispatch } from '../../../store/store'; import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; import { VariableAdapter } from '../adapters'; diff --git a/public/app/features/templating/custom/reducer.test.ts b/public/app/features/variables/custom/reducer.test.ts similarity index 93% rename from public/app/features/templating/custom/reducer.test.ts rename to public/app/features/variables/custom/reducer.test.ts index eb0302a41b2..42108042859 100644 --- a/public/app/features/templating/custom/reducer.test.ts +++ b/public/app/features/variables/custom/reducer.test.ts @@ -1,11 +1,11 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; import cloneDeep from 'lodash/cloneDeep'; import { getVariableTestContext } from '../state/helpers'; -import { toVariablePayload, ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../state/types'; -import { customVariableReducer, createCustomOptionsFromQuery } from './reducer'; -import { createCustomVariableAdapter } from '../custom/adapter'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, toVariablePayload } from '../state/types'; +import { createCustomOptionsFromQuery, customVariableReducer } from './reducer'; +import { createCustomVariableAdapter } from './adapter'; import { VariablesState } from '../state/variablesReducer'; -import { CustomVariableModel } from '../variable'; +import { CustomVariableModel } from '../../templating/variable'; describe('customVariableReducer', () => { const adapter = createCustomVariableAdapter(); diff --git a/public/app/features/templating/custom/reducer.ts b/public/app/features/variables/custom/reducer.ts similarity index 98% rename from public/app/features/templating/custom/reducer.ts rename to public/app/features/variables/custom/reducer.ts index 8ae7de6bf91..cffcd8d089d 100644 --- a/public/app/features/templating/custom/reducer.ts +++ b/public/app/features/variables/custom/reducer.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { CustomVariableModel, VariableHide, VariableOption } from '../variable'; +import { CustomVariableModel, VariableHide, VariableOption } from '../../templating/variable'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, EMPTY_UUID, getInstanceState, VariablePayload } from '../state/types'; import { initialVariablesState, VariablesState } from '../state/variablesReducer'; diff --git a/public/app/features/variables/datasource/DataSourceVariableEditor.tsx b/public/app/features/variables/datasource/DataSourceVariableEditor.tsx new file mode 100644 index 00000000000..fd021e9cd44 --- /dev/null +++ b/public/app/features/variables/datasource/DataSourceVariableEditor.tsx @@ -0,0 +1,131 @@ +import React, { ChangeEvent, FocusEvent, PureComponent } from 'react'; + +import { DataSourceVariableModel, VariableWithMultiSupport } from '../../templating/variable'; +import { OnPropChangeArguments, VariableEditorProps } from '../editor/types'; +import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; +import { FormLabel } from '@grafana/ui'; +import { VariableEditorState } from '../editor/reducer'; +import { DataSourceVariableEditorState } from './reducer'; +import { initDataSourceVariableEditor } from './actions'; +import { MapDispatchToProps, MapStateToProps } from 'react-redux'; +import { StoreState } from '../../../types'; +import { connectWithStore } from '../../../core/utils/connectWithReduxStore'; + +export interface OwnProps extends VariableEditorProps {} + +interface ConnectedProps { + editor: VariableEditorState; +} + +interface DispatchProps { + initDataSourceVariableEditor: typeof initDataSourceVariableEditor; +} + +type Props = OwnProps & ConnectedProps & DispatchProps; + +export class DataSourceVariableEditorUnConnected extends PureComponent { + async componentDidMount() { + await this.props.initDataSourceVariableEditor(); + } + + onRegExChange = (event: ChangeEvent) => { + this.props.onPropChange({ + propName: 'regex', + propValue: event.target.value, + }); + }; + + onRegExBlur = (event: FocusEvent) => { + this.props.onPropChange({ + propName: 'regex', + propValue: event.target.value, + updateOptions: true, + }); + }; + + onSelectionOptionsChange = async ({ propValue, propName }: OnPropChangeArguments) => { + this.props.onPropChange({ propName, propValue, updateOptions: true }); + }; + + getSelectedDataSourceTypeValue = (): string => { + if (!this.props.editor.extended?.dataSourceTypes?.length) { + return ''; + } + const foundItem = this.props.editor.extended?.dataSourceTypes.find(ds => ds.value === this.props.variable.query); + const value = foundItem ? foundItem.value : this.props.editor.extended?.dataSourceTypes[0].value; + return value ?? ''; + }; + + onDataSourceTypeChanged = (event: ChangeEvent) => { + this.props.onPropChange({ propName: 'query', propValue: event.target.value, updateOptions: true }); + }; + + render() { + return ( + <> +
+
Data source options
+ +
+ +
+ +
+
+ +
+ + Regex filter for which data source instances to choose from in the variable value dropdown. Leave + empty for all. +
+
+ Example: /^prod/ +
+ } + > + Instance name filter + + +
+
+ + + + ); + } +} + +const mapStateToProps: MapStateToProps = (state, ownProps) => ({ + editor: state.templating.editor as VariableEditorState, +}); + +const mapDispatchToProps: MapDispatchToProps = { + initDataSourceVariableEditor, +}; + +export const DataSourceVariableEditor = connectWithStore( + DataSourceVariableEditorUnConnected, + mapStateToProps, + mapDispatchToProps +); diff --git a/public/app/features/variables/datasource/actions.test.ts b/public/app/features/variables/datasource/actions.test.ts new file mode 100644 index 00000000000..a2e5ed4e036 --- /dev/null +++ b/public/app/features/variables/datasource/actions.test.ts @@ -0,0 +1,175 @@ +import { reduxTester } from '../../../../test/core/redux/reduxTester'; +import { TemplatingState } from '../state/reducers'; +import { getTemplatingRootReducer, variableMockBuilder } from '../state/helpers'; +import { initDashboardTemplating } from '../state/actions'; +import { toVariableIdentifier, toVariablePayload } from '../state/types'; +import { variableAdapters } from '../adapters'; +import { createDataSourceVariableAdapter } from './adapter'; +import { + DataSourceVariableActionDependencies, + initDataSourceVariableEditor, + updateDataSourceVariableOptions, +} from './actions'; +import { DataSourcePluginMeta, DataSourceSelectItem } from '@grafana/data'; +import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; +import { createDataSourceOptions } from './reducer'; +import { setCurrentVariableValue } from '../state/sharedReducer'; +import { changeVariableEditorExtended } from '../editor/reducer'; + +describe('data source actions', () => { + variableAdapters.set('datasource', createDataSourceVariableAdapter()); + + describe('when updateDataSourceVariableOptions is dispatched', () => { + describe('and there is no regex', () => { + it('then the correct actions are dispatched', async () => { + const sources: DataSourceSelectItem[] = [ + { + name: 'first-name', + value: 'first-value', + meta: getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }), + sort: '', + }, + { + name: 'second-name', + value: 'second-value', + meta: getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }), + sort: '', + }, + ]; + + const getMetricSourcesMock = jest.fn().mockResolvedValue(sources); + const getDatasourceSrvMock = jest.fn().mockReturnValue({ getMetricSources: getMetricSourcesMock }); + const dependencies: DataSourceVariableActionDependencies = { getDatasourceSrv: getDatasourceSrvMock }; + const datasource = variableMockBuilder('datasource') + .withUuid('0') + .withQuery('mock-data-id') + .create(); + const tester = await reduxTester<{ templating: TemplatingState }>() + .givenRootReducer(getTemplatingRootReducer()) + .whenActionIsDispatched(initDashboardTemplating([datasource])) + .whenAsyncActionIsDispatched( + updateDataSourceVariableOptions(toVariableIdentifier(datasource), dependencies), + true + ); + + await tester.thenDispatchedActionShouldEqual( + createDataSourceOptions( + toVariablePayload({ type: 'datasource', uuid: '0' }, { sources, regex: (undefined as unknown) as RegExp }) + ), + setCurrentVariableValue( + toVariablePayload( + { type: 'datasource', uuid: '0' }, + { option: { text: 'first-name', value: 'first-name', selected: false } } + ) + ) + ); + + expect(getMetricSourcesMock).toHaveBeenCalledTimes(1); + expect(getMetricSourcesMock).toHaveBeenCalledWith({ skipVariables: true }); + expect(getDatasourceSrvMock).toHaveBeenCalledTimes(1); + }); + }); + + describe('and there is a regex', () => { + it('then the correct actions are dispatched', async () => { + const sources: DataSourceSelectItem[] = [ + { + name: 'first-name', + value: 'first-value', + meta: getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }), + sort: '', + }, + { + name: 'second-name', + value: 'second-value', + meta: getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }), + sort: '', + }, + ]; + + const getMetricSourcesMock = jest.fn().mockResolvedValue(sources); + const getDatasourceSrvMock = jest.fn().mockReturnValue({ getMetricSources: getMetricSourcesMock }); + const dependencies: DataSourceVariableActionDependencies = { getDatasourceSrv: getDatasourceSrvMock }; + const datasource = variableMockBuilder('datasource') + .withUuid('0') + .withQuery('mock-data-id') + .withRegEx('/.*(second-name).*/') + .create(); + const tester = await reduxTester<{ templating: TemplatingState }>() + .givenRootReducer(getTemplatingRootReducer()) + .whenActionIsDispatched(initDashboardTemplating([datasource])) + .whenAsyncActionIsDispatched( + updateDataSourceVariableOptions(toVariableIdentifier(datasource), dependencies), + true + ); + + await tester.thenDispatchedActionShouldEqual( + createDataSourceOptions( + toVariablePayload({ type: 'datasource', uuid: '0' }, { sources, regex: /.*(second-name).*/ }) + ), + setCurrentVariableValue( + toVariablePayload( + { type: 'datasource', uuid: '0' }, + { option: { text: 'second-name', value: 'second-name', selected: false } } + ) + ) + ); + + expect(getMetricSourcesMock).toHaveBeenCalledTimes(1); + expect(getMetricSourcesMock).toHaveBeenCalledWith({ skipVariables: true }); + expect(getDatasourceSrvMock).toHaveBeenCalledTimes(1); + }); + }); + }); + + describe('when initDataSourceVariableEditor is dispatched', () => { + it('then the correct actions are dispatched', async () => { + const sources: DataSourceSelectItem[] = [ + { + name: 'first-name', + value: 'first-value', + meta: getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }), + sort: '', + }, + { + name: 'second-name', + value: 'second-value', + meta: getMockPlugin({ name: 'mock-data-name', id: 'mock-data-id' }), + sort: '', + }, + { + name: 'mixed-name', + value: 'mixed-value', + meta: getMockPlugin(({ + name: 'mixed-data-name', + id: 'mixed-data-id', + mixed: true, + } as unknown) as DataSourcePluginMeta), + sort: '', + }, + ]; + + const getMetricSourcesMock = jest.fn().mockResolvedValue(sources); + const getDatasourceSrvMock = jest.fn().mockReturnValue({ getMetricSources: getMetricSourcesMock }); + const dependencies: DataSourceVariableActionDependencies = { getDatasourceSrv: getDatasourceSrvMock }; + + const tester = await reduxTester<{ templating: TemplatingState }>() + .givenRootReducer(getTemplatingRootReducer()) + .whenAsyncActionIsDispatched(initDataSourceVariableEditor(dependencies)); + + await tester.thenDispatchedActionShouldEqual( + changeVariableEditorExtended({ + propName: 'dataSourceTypes', + propValue: [ + { text: '', value: '' }, + { text: 'mock-data-name', value: 'mock-data-id' }, + ], + }) + ); + + expect(getMetricSourcesMock).toHaveBeenCalledTimes(1); + expect(getMetricSourcesMock).toHaveBeenCalledWith(); + expect(getDatasourceSrvMock).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/public/app/features/variables/datasource/actions.ts b/public/app/features/variables/datasource/actions.ts new file mode 100644 index 00000000000..27e3534bd52 --- /dev/null +++ b/public/app/features/variables/datasource/actions.ts @@ -0,0 +1,54 @@ +import { toVariablePayload, VariableIdentifier } from '../state/types'; +import { ThunkResult } from '../../../types'; +import { createDataSourceOptions } from './reducer'; +import { validateVariableSelectionState } from '../state/actions'; +import { DataSourceSelectItem, stringToJsRegex } from '@grafana/data'; +import { getDatasourceSrv } from '../../plugins/datasource_srv'; +import { getVariable } from '../state/selectors'; +import { DataSourceVariableModel } from '../../templating/variable'; +import templateSrv from '../../templating/template_srv'; +import _ from 'lodash'; +import { changeVariableEditorExtended } from '../editor/reducer'; + +export interface DataSourceVariableActionDependencies { + getDatasourceSrv: typeof getDatasourceSrv; +} + +export const updateDataSourceVariableOptions = ( + identifier: VariableIdentifier, + dependencies: DataSourceVariableActionDependencies = { getDatasourceSrv: getDatasourceSrv } +): ThunkResult => async (dispatch, getState) => { + const sources = await dependencies.getDatasourceSrv().getMetricSources({ skipVariables: true }); + const variableInState = getVariable(identifier.uuid!, getState()); + let regex; + + if (variableInState.regex) { + regex = templateSrv.replace(variableInState.regex, undefined, 'regex'); + regex = stringToJsRegex(regex); + } + + await dispatch(createDataSourceOptions(toVariablePayload(identifier, { sources, regex }))); + await dispatch(validateVariableSelectionState(identifier)); +}; + +export const initDataSourceVariableEditor = ( + dependencies: DataSourceVariableActionDependencies = { getDatasourceSrv: getDatasourceSrv } +): ThunkResult => async dispatch => { + const dataSources: DataSourceSelectItem[] = await dependencies.getDatasourceSrv().getMetricSources(); + const filtered = dataSources.filter(ds => !ds.meta.mixed && ds.value !== null); + const dataSourceTypes = _(filtered) + .uniqBy('meta.id') + .map((ds: any) => { + return { text: ds.meta.name, value: ds.meta.id }; + }) + .value(); + + dataSourceTypes.unshift({ text: '', value: '' }); + + dispatch( + changeVariableEditorExtended({ + propName: 'dataSourceTypes', + propValue: dataSourceTypes, + }) + ); +}; diff --git a/public/app/features/variables/datasource/adapter.ts b/public/app/features/variables/datasource/adapter.ts new file mode 100644 index 00000000000..2991b137d92 --- /dev/null +++ b/public/app/features/variables/datasource/adapter.ts @@ -0,0 +1,46 @@ +import cloneDeep from 'lodash/cloneDeep'; +import { containsVariable, DataSourceVariableModel } from '../../templating/variable'; +import { dispatch } from '../../../store/store'; +import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; +import { VariableAdapter } from '../adapters'; +import { dataSourceVariableReducer, initialDataSourceVariableModelState } from './reducer'; +import { OptionsPicker } from '../pickers'; +import { ALL_VARIABLE_TEXT, toVariableIdentifier } from '../state/types'; +import { DataSourceVariableEditor } from './DataSourceVariableEditor'; +import { updateDataSourceVariableOptions } from './actions'; + +export const createDataSourceVariableAdapter = (): VariableAdapter => { + return { + description: 'Enabled you to dynamically switch the datasource for multiple panels', + label: 'Datasource', + initialState: initialDataSourceVariableModelState, + reducer: dataSourceVariableReducer, + picker: OptionsPicker, + editor: DataSourceVariableEditor, + dependsOn: (variable, variableToTest) => { + if (variable.regex) { + return containsVariable(variable.regex, variableToTest.name); + } + return false; + }, + setValue: async (variable, option, emitChanges = false) => { + await dispatch(setOptionAsCurrent(toVariableIdentifier(variable), option, emitChanges)); + }, + setValueFromUrl: async (variable, urlValue) => { + await dispatch(setOptionFromUrl(toVariableIdentifier(variable), urlValue)); + }, + updateOptions: async variable => { + await dispatch(updateDataSourceVariableOptions(toVariableIdentifier(variable))); + }, + getSaveModel: variable => { + const { index, uuid, initLock, global, ...rest } = cloneDeep(variable); + return { ...rest, options: [] }; + }, + getValueForUrl: variable => { + if (variable.current.text === ALL_VARIABLE_TEXT) { + return ALL_VARIABLE_TEXT; + } + return variable.current.value; + }, + }; +}; diff --git a/public/app/features/variables/datasource/reducer.test.ts b/public/app/features/variables/datasource/reducer.test.ts new file mode 100644 index 00000000000..f27d3ce3ce5 --- /dev/null +++ b/public/app/features/variables/datasource/reducer.test.ts @@ -0,0 +1,64 @@ +import { reducerTester } from '../../../../test/core/redux/reducerTester'; +import { VariablesState } from '../state/variablesReducer'; +import { createDataSourceOptions, dataSourceVariableReducer } from './reducer'; +import { DataSourceVariableModel } from '../../templating/variable'; +import { getVariableTestContext } from '../state/helpers'; +import cloneDeep from 'lodash/cloneDeep'; +import { createDataSourceVariableAdapter } from './adapter'; +import { DataSourceSelectItem } from '@grafana/data'; +import { toVariablePayload } from '../state/types'; +import { getMockPlugins } from '../../plugins/__mocks__/pluginMocks'; + +describe('dataSourceVariableReducer', () => { + const adapter = createDataSourceVariableAdapter(); + describe('when createDataSourceOptions is dispatched', () => { + const plugins = getMockPlugins(3); + const sources: DataSourceSelectItem[] = plugins.map(p => ({ + name: p.name, + value: `${p.name} value`, + meta: p, + sort: '', + })); + + it.each` + query | regex | includeAll | expected + ${sources[1].meta.id} | ${undefined} | ${false} | ${[{ text: 'pretty cool plugin-1', value: 'pretty cool plugin-1', selected: false }]} + ${'not-found-plugin'} | ${undefined} | ${false} | ${[{ text: 'No data sources found', value: '', selected: false }]} + ${sources[1].meta.id} | ${/.*(pretty cool plugin-1).*/} | ${false} | ${[{ text: 'pretty cool plugin-1', value: 'pretty cool plugin-1', selected: false }]} + ${sources[1].meta.id} | ${/.*(pretty cool plugin-2).*/} | ${false} | ${[{ text: 'No data sources found', value: '', selected: false }]} + ${sources[1].meta.id} | ${undefined} | ${true} | ${[ + { text: 'All', value: '$__all', selected: false }, + { text: 'pretty cool plugin-1', value: 'pretty cool plugin-1', selected: false }, +]} + ${'not-found-plugin'} | ${undefined} | ${true} | ${[ + { text: 'All', value: '$__all', selected: false }, + { text: 'No data sources found', value: '', selected: false }, +]} + ${sources[1].meta.id} | ${/.*(pretty cool plugin-1).*/} | ${true} | ${[ + { text: 'All', value: '$__all', selected: false }, + { text: 'pretty cool plugin-1', value: 'pretty cool plugin-1', selected: false }, +]} + ${sources[1].meta.id} | ${/.*(pretty cool plugin-2).*/} | ${true} | ${[ + { text: 'All', value: '$__all', selected: false }, + { text: 'No data sources found', value: '', selected: false }, +]} + `( + "when called with query: '$query' and regex: '$regex' and includeAll: '$includeAll' then state should be correct", + ({ query, regex, includeAll, expected }) => { + const { initialState } = getVariableTestContext(adapter, { query, includeAll }); + const payload = toVariablePayload({ uuid: '0', type: 'datasource' }, { sources, regex }); + + reducerTester() + .givenReducer(dataSourceVariableReducer, cloneDeep(initialState)) + .whenActionIsDispatched(createDataSourceOptions(payload)) + .thenStateShouldEqual({ + ...initialState, + ['0']: ({ + ...initialState['0'], + options: expected, + } as unknown) as DataSourceVariableModel, + }); + } + ); + }); +}); diff --git a/public/app/features/variables/datasource/reducer.ts b/public/app/features/variables/datasource/reducer.ts new file mode 100644 index 00000000000..2ded552ef40 --- /dev/null +++ b/public/app/features/variables/datasource/reducer.ts @@ -0,0 +1,70 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { DataSourceVariableModel, VariableHide, VariableOption, VariableRefresh } from '../../templating/variable'; +import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, EMPTY_UUID, getInstanceState, VariablePayload } from '../state/types'; +import { initialVariablesState, VariablesState } from '../state/variablesReducer'; +import { DataSourceSelectItem } from '@grafana/data'; + +export interface DataSourceVariableEditorState { + dataSourceTypes: Array<{ text: string; value: string }>; +} + +export const initialDataSourceVariableModelState: DataSourceVariableModel = { + uuid: EMPTY_UUID, + global: false, + type: 'datasource', + name: '', + hide: VariableHide.dontHide, + label: '', + current: {} as VariableOption, + regex: '', + options: [], + query: '', + multi: false, + includeAll: false, + refresh: VariableRefresh.onDashboardLoad, + skipUrlSync: false, + index: -1, + initLock: null, +}; + +export const dataSourceVariableSlice = createSlice({ + name: 'templating/datasource', + initialState: initialVariablesState, + reducers: { + createDataSourceOptions: ( + state: VariablesState, + action: PayloadAction> + ) => { + const { sources, regex } = action.payload.data; + const options: VariableOption[] = []; + const instanceState = getInstanceState(state, action.payload.uuid); + for (let i = 0; i < sources.length; i++) { + const source = sources[i]; + // must match on type + if (source.meta.id !== instanceState.query) { + continue; + } + + if (regex && !regex.exec(source.name)) { + continue; + } + + options.push({ text: source.name, value: source.name, selected: false }); + } + + if (options.length === 0) { + options.push({ text: 'No data sources found', value: '', selected: false }); + } + + if (instanceState.includeAll) { + options.unshift({ text: ALL_VARIABLE_TEXT, value: ALL_VARIABLE_VALUE, selected: false }); + } + + instanceState.options = options; + }, + }, +}); + +export const dataSourceVariableReducer = dataSourceVariableSlice.reducer; + +export const { createDataSourceOptions } = dataSourceVariableSlice.actions; diff --git a/public/app/features/templating/editor/SelectionOptionsEditor.tsx b/public/app/features/variables/editor/SelectionOptionsEditor.tsx similarity index 97% rename from public/app/features/templating/editor/SelectionOptionsEditor.tsx rename to public/app/features/variables/editor/SelectionOptionsEditor.tsx index 9505e320bfc..95d4d074fc1 100644 --- a/public/app/features/templating/editor/SelectionOptionsEditor.tsx +++ b/public/app/features/variables/editor/SelectionOptionsEditor.tsx @@ -2,7 +2,7 @@ import React, { FunctionComponent, useCallback } from 'react'; import { Switch } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; -import { VariableWithMultiSupport } from '../variable'; +import { VariableWithMultiSupport } from '../../templating/variable'; import { VariableEditorProps } from './types'; export interface SelectionOptionsEditorProps diff --git a/public/app/features/templating/editor/VariableEditorContainer.tsx b/public/app/features/variables/editor/VariableEditorContainer.tsx similarity index 96% rename from public/app/features/templating/editor/VariableEditorContainer.tsx rename to public/app/features/variables/editor/VariableEditorContainer.tsx index dcc74f64da8..ca4d37f3e25 100644 --- a/public/app/features/templating/editor/VariableEditorContainer.tsx +++ b/public/app/features/variables/editor/VariableEditorContainer.tsx @@ -7,7 +7,7 @@ import { VariableEditorEditor } from './VariableEditorEditor'; import { MapDispatchToProps, MapStateToProps } from 'react-redux'; import { connectWithStore } from '../../../core/utils/connectWithReduxStore'; import { getVariableClones } from '../state/selectors'; -import { VariableModel } from '../variable'; +import { VariableModel } from '../../templating/variable'; import { switchToEditMode, switchToListMode, switchToNewMode } from './actions'; import { changeVariableOrder, duplicateVariable, removeVariable } from '../state/sharedReducer'; @@ -53,7 +53,7 @@ class VariableEditorContainerUnconnected extends PureComponent { }; onDuplicateVariable = (identifier: VariableIdentifier) => { - this.props.duplicateVariable(toVariablePayload(identifier)); + this.props.duplicateVariable(toVariablePayload(identifier, { newUuid: (undefined as unknown) as string })); }; onRemoveVariable = (identifier: VariableIdentifier) => { diff --git a/public/app/features/templating/editor/VariableEditorEditor.tsx b/public/app/features/variables/editor/VariableEditorEditor.tsx similarity index 99% rename from public/app/features/templating/editor/VariableEditorEditor.tsx rename to public/app/features/variables/editor/VariableEditorEditor.tsx index ad817b24ea8..a03f34a084f 100644 --- a/public/app/features/templating/editor/VariableEditorEditor.tsx +++ b/public/app/features/variables/editor/VariableEditorEditor.tsx @@ -5,7 +5,7 @@ import { FormLabel } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; import { variableAdapters } from '../adapters'; import { EMPTY_UUID, toVariablePayload, VariableIdentifier } from '../state/types'; -import { VariableHide, VariableModel, VariableType } from '../variable'; +import { VariableHide, VariableModel, VariableType } from '../../templating/variable'; import { appEvents } from '../../../core/core'; import { VariableValuesPreview } from './VariableValuesPreview'; import { changeVariableName, onEditorAdd, onEditorUpdate, variableEditorMount, variableEditorUnMount } from './actions'; diff --git a/public/app/features/templating/editor/VariableEditorList.tsx b/public/app/features/variables/editor/VariableEditorList.tsx similarity index 98% rename from public/app/features/templating/editor/VariableEditorList.tsx rename to public/app/features/variables/editor/VariableEditorList.tsx index 9cfb670b358..b6472773956 100644 --- a/public/app/features/templating/editor/VariableEditorList.tsx +++ b/public/app/features/variables/editor/VariableEditorList.tsx @@ -1,7 +1,7 @@ import React, { MouseEvent, PureComponent } from 'react'; import { e2e } from '@grafana/e2e'; import EmptyListCTA from '../../../core/components/EmptyListCTA/EmptyListCTA'; -import { QueryVariableModel, VariableModel } from '../variable'; +import { QueryVariableModel, VariableModel } from '../../templating/variable'; import { toVariableIdentifier, VariableIdentifier } from '../state/types'; export interface Props { diff --git a/public/app/features/templating/editor/VariableValuesPreview.tsx b/public/app/features/variables/editor/VariableValuesPreview.tsx similarity index 98% rename from public/app/features/templating/editor/VariableValuesPreview.tsx rename to public/app/features/variables/editor/VariableValuesPreview.tsx index 945eb8b812d..37fea9ea96d 100644 --- a/public/app/features/templating/editor/VariableValuesPreview.tsx +++ b/public/app/features/variables/editor/VariableValuesPreview.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { VariableModel, VariableOption, VariableWithOptions } from '../variable'; +import { VariableModel, VariableOption, VariableWithOptions } from '../../templating/variable'; import { e2e } from '@grafana/e2e'; export interface VariableValuesPreviewProps { diff --git a/public/app/features/templating/editor/actions.ts b/public/app/features/variables/editor/actions.ts similarity index 98% rename from public/app/features/templating/editor/actions.ts rename to public/app/features/variables/editor/actions.ts index cfa498639d2..7b37fcab9bc 100644 --- a/public/app/features/templating/editor/actions.ts +++ b/public/app/features/variables/editor/actions.ts @@ -12,7 +12,7 @@ import { variableAdapters } from '../adapters'; import { v4 } from 'uuid'; import { AddVariable, EMPTY_UUID, toVariablePayload, VariableIdentifier } from '../state/types'; import cloneDeep from 'lodash/cloneDeep'; -import { VariableType } from '../variable'; +import { VariableType } from '../../templating/variable'; import { addVariable, removeVariable, storeNewVariable } from '../state/sharedReducer'; export const variableEditorMount = (identifier: VariableIdentifier): ThunkResult => { diff --git a/public/app/features/templating/editor/reducer.test.ts b/public/app/features/variables/editor/reducer.test.ts similarity index 100% rename from public/app/features/templating/editor/reducer.test.ts rename to public/app/features/variables/editor/reducer.test.ts diff --git a/public/app/features/templating/editor/reducer.ts b/public/app/features/variables/editor/reducer.ts similarity index 100% rename from public/app/features/templating/editor/reducer.ts rename to public/app/features/variables/editor/reducer.ts diff --git a/public/app/features/templating/editor/types.ts b/public/app/features/variables/editor/types.ts similarity index 84% rename from public/app/features/templating/editor/types.ts rename to public/app/features/variables/editor/types.ts index 73ff373cc47..674926c22f1 100644 --- a/public/app/features/templating/editor/types.ts +++ b/public/app/features/variables/editor/types.ts @@ -1,4 +1,4 @@ -import { VariableModel } from '../variable'; +import { VariableModel } from '../../templating/variable'; export interface OnPropChangeArguments { propName: keyof Model; diff --git a/public/app/features/templating/guard.ts b/public/app/features/variables/guard.ts similarity index 60% rename from public/app/features/templating/guard.ts rename to public/app/features/variables/guard.ts index 8235a6957ac..8b93cc5764e 100644 --- a/public/app/features/templating/guard.ts +++ b/public/app/features/variables/guard.ts @@ -1,4 +1,4 @@ -import { VariableModel, QueryVariableModel } from './variable'; +import { QueryVariableModel, VariableModel } from '../templating/variable'; export const isQuery = (model: VariableModel): model is QueryVariableModel => { return model.type === 'query'; diff --git a/public/app/features/templating/pickers/OptionsPicker/OptionsPicker.tsx b/public/app/features/variables/pickers/OptionsPicker/OptionsPicker.tsx similarity index 97% rename from public/app/features/templating/pickers/OptionsPicker/OptionsPicker.tsx rename to public/app/features/variables/pickers/OptionsPicker/OptionsPicker.tsx index f85b132d656..f44b9fdc26d 100644 --- a/public/app/features/templating/pickers/OptionsPicker/OptionsPicker.tsx +++ b/public/app/features/variables/pickers/OptionsPicker/OptionsPicker.tsx @@ -6,7 +6,12 @@ import { VariableLink } from '../shared/VariableLink'; import { VariableInput } from '../shared/VariableInput'; import { commitChangesToVariable, filterOrSearchOptions, navigateOptions, toggleAndFetchTag } from './actions'; import { OptionsPickerState, showOptions, toggleAllOptions, toggleOption } from './reducer'; -import { VariableOption, VariableTag, VariableWithMultiSupport, VariableWithOptions } from '../../variable'; +import { + VariableOption, + VariableTag, + VariableWithMultiSupport, + VariableWithOptions, +} from '../../../templating/variable'; import { VariableOptions } from '../shared/VariableOptions'; import { isQuery } from '../../guard'; import { VariablePickerProps } from '../types'; diff --git a/public/app/features/templating/pickers/OptionsPicker/actions.test.ts b/public/app/features/variables/pickers/OptionsPicker/actions.test.ts similarity index 98% rename from public/app/features/templating/pickers/OptionsPicker/actions.test.ts rename to public/app/features/variables/pickers/OptionsPicker/actions.test.ts index 3ed63c972ca..ffa8c39567a 100644 --- a/public/app/features/templating/pickers/OptionsPicker/actions.test.ts +++ b/public/app/features/variables/pickers/OptionsPicker/actions.test.ts @@ -2,7 +2,7 @@ import { reduxTester } from '../../../../../test/core/redux/reduxTester'; import { getTemplatingRootReducer } from '../../state/helpers'; import { initDashboardTemplating } from '../../state/actions'; import { TemplatingState } from '../../state/reducers'; -import { QueryVariableModel, VariableHide, VariableRefresh, VariableSort } from '../../variable'; +import { QueryVariableModel, VariableHide, VariableRefresh, VariableSort } from '../../../templating/variable'; import { hideOptions, showOptions, @@ -374,8 +374,7 @@ describe('options picker actions', () => { const variable = createVariable({ options, includeAll: false, tags: [tag] }); datasource.metricFindQuery.mockReset(); - // @ts-ignore couldn't wrap my head around this - // error TS2345: Argument of type '() => Promise<{ value: string; text: string; }[]>' is not assignable to parameter of type '() => Promise'. + // @ts-ignore strict null error TS2345: Argument of type '() => Promise<{ value: string; text: string; }[]>' is not assignable to parameter of type '() => Promise' datasource.metricFindQuery.mockImplementation(() => Promise.resolve(values)); const tester = await reduxTester<{ templating: TemplatingState }>() diff --git a/public/app/features/templating/pickers/OptionsPicker/actions.ts b/public/app/features/variables/pickers/OptionsPicker/actions.ts similarity index 98% rename from public/app/features/templating/pickers/OptionsPicker/actions.ts rename to public/app/features/variables/pickers/OptionsPicker/actions.ts index 2f7e4486181..97346726b90 100644 --- a/public/app/features/templating/pickers/OptionsPicker/actions.ts +++ b/public/app/features/variables/pickers/OptionsPicker/actions.ts @@ -8,7 +8,7 @@ import { VariableTag, VariableWithMultiSupport, VariableWithOptions, -} from '../../variable'; +} from '../../../templating/variable'; import { variableAdapters } from '../../adapters'; import { getVariable } from '../../state/selectors'; import { NavigationKey } from '../types'; @@ -24,7 +24,7 @@ import { } from './reducer'; import { getDataSourceSrv } from '@grafana/runtime'; import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; -import { setCurrentVariableValue, changeVariableProp } from '../../state/sharedReducer'; +import { changeVariableProp, setCurrentVariableValue } from '../../state/sharedReducer'; import { toVariablePayload } from '../../state/types'; export const navigateOptions = (key: NavigationKey, clearOthers: boolean): ThunkResult => { diff --git a/public/app/features/templating/pickers/OptionsPicker/reducer.test.ts b/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts similarity index 99% rename from public/app/features/templating/pickers/OptionsPicker/reducer.test.ts rename to public/app/features/variables/pickers/OptionsPicker/reducer.test.ts index cf39b0bf877..4e4eaeadc89 100644 --- a/public/app/features/templating/pickers/OptionsPicker/reducer.test.ts +++ b/public/app/features/variables/pickers/OptionsPicker/reducer.test.ts @@ -14,7 +14,7 @@ import { updateSearchQuery, } from './reducer'; import { reducerTester } from '../../../../../test/core/redux/reducerTester'; -import { QueryVariableModel, VariableTag } from '../../variable'; +import { QueryVariableModel, VariableTag } from '../../../templating/variable'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../../state/types'; const getVariableTestContext = (extend: Partial) => { diff --git a/public/app/features/templating/pickers/OptionsPicker/reducer.ts b/public/app/features/variables/pickers/OptionsPicker/reducer.ts similarity index 97% rename from public/app/features/templating/pickers/OptionsPicker/reducer.ts rename to public/app/features/variables/pickers/OptionsPicker/reducer.ts index 5a866a5868d..7d99df621fe 100644 --- a/public/app/features/templating/pickers/OptionsPicker/reducer.ts +++ b/public/app/features/variables/pickers/OptionsPicker/reducer.ts @@ -1,6 +1,11 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { cloneDeep } from 'lodash'; -import { containsSearchFilter, VariableOption, VariableTag, VariableWithMultiSupport } from '../../variable'; +import { + containsSearchFilter, + VariableOption, + VariableTag, + VariableWithMultiSupport, +} from '../../../templating/variable'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE } from '../../state/types'; import { isQuery } from '../../guard'; import { applyStateChanges } from '../../../../core/utils/applyStateChanges'; diff --git a/public/app/features/templating/pickers/PickerRenderer.tsx b/public/app/features/variables/pickers/PickerRenderer.tsx similarity index 93% rename from public/app/features/templating/pickers/PickerRenderer.tsx rename to public/app/features/variables/pickers/PickerRenderer.tsx index 6b59a17a5cd..523046a14a5 100644 --- a/public/app/features/templating/pickers/PickerRenderer.tsx +++ b/public/app/features/variables/pickers/PickerRenderer.tsx @@ -1,5 +1,5 @@ import React, { FunctionComponent, useMemo } from 'react'; -import { VariableHide, VariableModel } from '../variable'; +import { VariableHide, VariableModel } from '../../templating/variable'; import { e2e } from '@grafana/e2e'; import { variableAdapters } from '../adapters'; diff --git a/public/app/features/templating/pickers/index.ts b/public/app/features/variables/pickers/index.ts similarity index 100% rename from public/app/features/templating/pickers/index.ts rename to public/app/features/variables/pickers/index.ts diff --git a/public/app/features/templating/pickers/shared/VariableInput.tsx b/public/app/features/variables/pickers/shared/VariableInput.tsx similarity index 100% rename from public/app/features/templating/pickers/shared/VariableInput.tsx rename to public/app/features/variables/pickers/shared/VariableInput.tsx diff --git a/public/app/features/templating/pickers/shared/VariableLink.tsx b/public/app/features/variables/pickers/shared/VariableLink.tsx similarity index 95% rename from public/app/features/templating/pickers/shared/VariableLink.tsx rename to public/app/features/variables/pickers/shared/VariableLink.tsx index a298be8c0fe..313f460754d 100644 --- a/public/app/features/templating/pickers/shared/VariableLink.tsx +++ b/public/app/features/variables/pickers/shared/VariableLink.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { getTagColorsFromName } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; -import { VariableTag } from '../../variable'; +import { VariableTag } from '../../../templating/variable'; interface Props { onClick: () => void; diff --git a/public/app/features/templating/pickers/shared/VariableOptions.tsx b/public/app/features/variables/pickers/shared/VariableOptions.tsx similarity index 98% rename from public/app/features/templating/pickers/shared/VariableOptions.tsx rename to public/app/features/variables/pickers/shared/VariableOptions.tsx index 3bc2bba9af4..3c71d546881 100644 --- a/public/app/features/templating/pickers/shared/VariableOptions.tsx +++ b/public/app/features/variables/pickers/shared/VariableOptions.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { getTagColorsFromName, Tooltip } from '@grafana/ui'; import { e2e } from '@grafana/e2e'; -import { VariableOption, VariableTag } from '../../variable'; +import { VariableOption, VariableTag } from '../../../templating/variable'; export interface Props { multi: boolean; diff --git a/public/app/features/templating/pickers/types.ts b/public/app/features/variables/pickers/types.ts similarity index 79% rename from public/app/features/templating/pickers/types.ts rename to public/app/features/variables/pickers/types.ts index b69546c562f..f3e2e8c7aa7 100644 --- a/public/app/features/templating/pickers/types.ts +++ b/public/app/features/variables/pickers/types.ts @@ -1,4 +1,4 @@ -import { VariableModel } from '../variable'; +import { VariableModel } from '../../templating/variable'; export interface VariablePickerProps { variable: Model; diff --git a/public/app/features/templating/query/QueryVariableEditor.tsx b/public/app/features/variables/query/QueryVariableEditor.tsx similarity index 99% rename from public/app/features/templating/query/QueryVariableEditor.tsx rename to public/app/features/variables/query/QueryVariableEditor.tsx index b1c97d54479..f6ad57d664b 100644 --- a/public/app/features/templating/query/QueryVariableEditor.tsx +++ b/public/app/features/variables/query/QueryVariableEditor.tsx @@ -2,9 +2,9 @@ import React, { ChangeEvent, PureComponent } from 'react'; import { e2e } from '@grafana/e2e'; import { FormLabel, Switch } from '@grafana/ui'; -import templateSrv from '../template_srv'; +import templateSrv from '../../templating/template_srv'; import { SelectionOptionsEditor } from '../editor/SelectionOptionsEditor'; -import { QueryVariableModel, VariableRefresh, VariableSort, VariableWithMultiSupport } from '../variable'; +import { QueryVariableModel, VariableRefresh, VariableSort, VariableWithMultiSupport } from '../../templating/variable'; import { QueryVariableEditorState } from './reducer'; import { changeQueryVariableDataSource, changeQueryVariableQuery, initQueryVariableEditor } from './actions'; import { VariableEditorState } from '../editor/reducer'; diff --git a/public/app/features/templating/query/actions.test.ts b/public/app/features/variables/query/actions.test.ts similarity index 99% rename from public/app/features/templating/query/actions.test.ts rename to public/app/features/variables/query/actions.test.ts index 15af7c73c53..be03b31e955 100644 --- a/public/app/features/templating/query/actions.test.ts +++ b/public/app/features/variables/query/actions.test.ts @@ -2,7 +2,7 @@ import { variableAdapters } from '../adapters'; import { createQueryVariableAdapter } from './adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; import { getTemplatingRootReducer } from '../state/helpers'; -import { QueryVariableModel, VariableHide, VariableRefresh, VariableSort } from '../variable'; +import { QueryVariableModel, VariableHide, VariableRefresh, VariableSort } from '../../templating/variable'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, toVariablePayload } from '../state/types'; import { changeVariableProp, setCurrentVariableValue } from '../state/sharedReducer'; import { initDashboardTemplating } from '../state/actions'; @@ -20,7 +20,7 @@ import { removeVariableEditorError, setIdInEditor, } from '../editor/reducer'; -import DefaultVariableQueryEditor from '../DefaultVariableQueryEditor'; +import DefaultVariableQueryEditor from '../../templating/DefaultVariableQueryEditor'; import { expect } from 'test/lib/common'; const mocks: Record = { diff --git a/public/app/features/templating/query/actions.ts b/public/app/features/variables/query/actions.ts similarity index 96% rename from public/app/features/templating/query/actions.ts rename to public/app/features/variables/query/actions.ts index 3f856ffcf57..3db647700ad 100644 --- a/public/app/features/templating/query/actions.ts +++ b/public/app/features/variables/query/actions.ts @@ -1,13 +1,13 @@ import { AppEvents, DataSourcePluginMeta, DataSourceSelectItem } from '@grafana/data'; import { validateVariableSelectionState } from '../state/actions'; -import { QueryVariableModel, VariableRefresh } from '../variable'; +import { QueryVariableModel, VariableRefresh } from '../../templating/variable'; import { ThunkResult } from '../../../types'; import { getDatasourceSrv } from '../../plugins/datasource_srv'; import { getTimeSrv } from '../../dashboard/services/TimeSrv'; import appEvents from '../../../core/app_events'; import { importDataSourcePlugin } from '../../plugins/plugin_loader'; -import DefaultVariableQueryEditor from '../DefaultVariableQueryEditor'; +import DefaultVariableQueryEditor from '../../templating/DefaultVariableQueryEditor'; import { getVariable } from '../state/selectors'; import { addVariableEditorError, changeVariableEditorExtended, removeVariableEditorError } from '../editor/reducer'; import { variableAdapters } from '../adapters'; diff --git a/public/app/features/templating/query/adapter.ts b/public/app/features/variables/query/adapter.ts similarity index 98% rename from public/app/features/templating/query/adapter.ts rename to public/app/features/variables/query/adapter.ts index d0f5b6078c8..d6f9bf94b89 100644 --- a/public/app/features/templating/query/adapter.ts +++ b/public/app/features/variables/query/adapter.ts @@ -1,6 +1,6 @@ import cloneDeep from 'lodash/cloneDeep'; -import { containsVariable, QueryVariableModel, VariableRefresh } from '../variable'; +import { containsVariable, QueryVariableModel, VariableRefresh } from '../../templating/variable'; import { initialQueryVariableModelState, queryVariableReducer } from './reducer'; import { dispatch } from '../../../store/store'; import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; diff --git a/public/app/features/templating/query/reducer.test.ts b/public/app/features/variables/query/reducer.test.ts similarity index 98% rename from public/app/features/templating/query/reducer.test.ts rename to public/app/features/variables/query/reducer.test.ts index 589f6b65c77..94ba78b5a95 100644 --- a/public/app/features/templating/query/reducer.test.ts +++ b/public/app/features/variables/query/reducer.test.ts @@ -1,6 +1,6 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { queryVariableReducer, updateVariableOptions, updateVariableTags } from './reducer'; -import { QueryVariableModel, VariableOption } from '../variable'; +import { QueryVariableModel, VariableOption } from '../../templating/variable'; import cloneDeep from 'lodash/cloneDeep'; import { VariablesState } from '../state/variablesReducer'; import { getVariableTestContext } from '../state/helpers'; diff --git a/public/app/features/templating/query/reducer.ts b/public/app/features/variables/query/reducer.ts similarity index 98% rename from public/app/features/templating/query/reducer.ts rename to public/app/features/variables/query/reducer.ts index 799e3128257..f8cad8227a7 100644 --- a/public/app/features/templating/query/reducer.ts +++ b/public/app/features/variables/query/reducer.ts @@ -9,8 +9,8 @@ import { VariableRefresh, VariableSort, VariableTag, -} from '../variable'; -import templateSrv from '../template_srv'; +} from '../../templating/variable'; +import templateSrv from '../../templating/template_srv'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, diff --git a/public/app/features/templating/state/actions.test.ts b/public/app/features/variables/state/actions.test.ts similarity index 99% rename from public/app/features/templating/state/actions.test.ts rename to public/app/features/variables/state/actions.test.ts index 5849c44bfe0..8903a5bfdd7 100644 --- a/public/app/features/templating/state/actions.test.ts +++ b/public/app/features/variables/state/actions.test.ts @@ -7,7 +7,7 @@ import { createCustomVariableAdapter } from '../custom/adapter'; import { createTextBoxVariableAdapter } from '../textbox/adapter'; import { createConstantVariableAdapter } from '../constant/adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { TemplatingState } from 'app/features/templating/state/reducers'; +import { TemplatingState } from 'app/features/variables/state/reducers'; import { initDashboardTemplating, processVariables, setOptionFromUrl, validateVariableSelectionState } from './actions'; import { addInitLock, addVariable, removeInitLock, resolveInitLock, setCurrentVariableValue } from './sharedReducer'; import { toVariableIdentifier, toVariablePayload } from './types'; diff --git a/public/app/features/templating/state/actions.ts b/public/app/features/variables/state/actions.ts similarity index 98% rename from public/app/features/templating/state/actions.ts rename to public/app/features/variables/state/actions.ts index c803f44339a..e4babb0ec0c 100644 --- a/public/app/features/templating/state/actions.ts +++ b/public/app/features/variables/state/actions.ts @@ -1,7 +1,13 @@ import castArray from 'lodash/castArray'; import { UrlQueryMap, UrlQueryValue } from '@grafana/runtime'; -import { QueryVariableModel, VariableModel, VariableOption, VariableRefresh, VariableWithOptions } from '../variable'; +import { + QueryVariableModel, + VariableModel, + VariableOption, + VariableRefresh, + VariableWithOptions, +} from '../../templating/variable'; import { StoreState, ThunkResult } from '../../../types'; import { getVariable, getVariables } from './selectors'; import { variableAdapters } from '../adapters'; diff --git a/public/app/features/templating/state/helpers.ts b/public/app/features/variables/state/helpers.ts similarity index 96% rename from public/app/features/templating/state/helpers.ts rename to public/app/features/variables/state/helpers.ts index 52f44fefc23..188b18668d3 100644 --- a/public/app/features/templating/state/helpers.ts +++ b/public/app/features/variables/state/helpers.ts @@ -2,7 +2,7 @@ import { combineReducers } from '@reduxjs/toolkit'; import cloneDeep from 'lodash/cloneDeep'; import { EMPTY_UUID } from './types'; -import { VariableHide, VariableModel, VariableRefresh, VariableType } from '../variable'; +import { VariableHide, VariableModel, VariableRefresh, VariableType } from '../../templating/variable'; import { variablesReducer, VariablesState } from './variablesReducer'; import { optionsPickerReducer } from '../pickers/OptionsPicker/reducer'; import { variableEditorReducer } from '../editor/reducer'; @@ -106,6 +106,11 @@ export const variableMockBuilder = (type: VariableType) => { return instance; }; + const withRegEx = (regex: any) => { + model.regex = regex; + return instance; + }; + const create = () => model; const instance = { @@ -116,6 +121,7 @@ export const variableMockBuilder = (type: VariableType) => { withRefresh, withQuery, withMulti, + withRegEx, create, }; diff --git a/public/app/features/templating/state/processVariable.test.ts b/public/app/features/variables/state/processVariable.test.ts similarity index 99% rename from public/app/features/templating/state/processVariable.test.ts rename to public/app/features/variables/state/processVariable.test.ts index f18dcb62ac7..766d4595342 100644 --- a/public/app/features/templating/state/processVariable.test.ts +++ b/public/app/features/variables/state/processVariable.test.ts @@ -5,11 +5,11 @@ import { variableAdapters } from '../adapters'; import { createQueryVariableAdapter } from '../query/adapter'; import { createCustomVariableAdapter } from '../custom/adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { TemplatingState } from 'app/features/templating/state/reducers'; +import { TemplatingState } from 'app/features/variables/state/reducers'; import { initDashboardTemplating, processVariable } from './actions'; import { resolveInitLock, setCurrentVariableValue } from './sharedReducer'; import { toVariableIdentifier, toVariablePayload } from './types'; -import { VariableRefresh } from '../variable'; +import { VariableRefresh } from '../../templating/variable'; import { updateVariableOptions } from '../query/reducer'; jest.mock('app/features/dashboard/services/TimeSrv', () => ({ diff --git a/public/app/features/templating/state/reducers.test.ts b/public/app/features/variables/state/reducers.test.ts similarity index 98% rename from public/app/features/templating/state/reducers.test.ts rename to public/app/features/variables/state/reducers.test.ts index b387722dc4b..aa9dc686635 100644 --- a/public/app/features/templating/state/reducers.test.ts +++ b/public/app/features/variables/state/reducers.test.ts @@ -1,6 +1,6 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; import { cleanUpDashboard } from 'app/features/dashboard/state/reducers'; -import { VariableHide, VariableModel } from '../variable'; +import { VariableHide, VariableModel } from '../../templating/variable'; import { VariableAdapter, variableAdapters } from '../adapters'; import { createAction } from '@reduxjs/toolkit'; import { variablesReducer, VariablesState } from './variablesReducer'; diff --git a/public/app/features/templating/state/reducers.ts b/public/app/features/variables/state/reducers.ts similarity index 91% rename from public/app/features/templating/state/reducers.ts rename to public/app/features/variables/state/reducers.ts index a89733af8ed..26c439ee8ae 100644 --- a/public/app/features/templating/state/reducers.ts +++ b/public/app/features/variables/state/reducers.ts @@ -2,7 +2,7 @@ import { combineReducers } from '@reduxjs/toolkit'; import { optionsPickerReducer, OptionsPickerState } from '../pickers/OptionsPicker/reducer'; import { variableEditorReducer, VariableEditorState } from '../editor/reducer'; import { variablesReducer } from './variablesReducer'; -import { VariableModel } from '../variable'; +import { VariableModel } from '../../templating/variable'; export interface TemplatingState { variables: Record; diff --git a/public/app/features/templating/state/selectors.ts b/public/app/features/variables/state/selectors.ts similarity index 95% rename from public/app/features/templating/state/selectors.ts rename to public/app/features/variables/state/selectors.ts index e84f54f6af6..2b5e0374d6c 100644 --- a/public/app/features/templating/state/selectors.ts +++ b/public/app/features/variables/state/selectors.ts @@ -1,7 +1,7 @@ import { cloneDeep } from 'lodash'; import { StoreState } from '../../../types'; -import { VariableModel } from '../variable'; +import { VariableModel } from '../../templating/variable'; import { getState } from '../../../store/store'; import { EMPTY_UUID } from './types'; diff --git a/public/app/features/templating/state/sharedReducer.test.ts b/public/app/features/variables/state/sharedReducer.test.ts similarity index 99% rename from public/app/features/templating/state/sharedReducer.test.ts rename to public/app/features/variables/state/sharedReducer.test.ts index 5cd8d6906fc..8e22d5dad21 100644 --- a/public/app/features/templating/state/sharedReducer.test.ts +++ b/public/app/features/variables/state/sharedReducer.test.ts @@ -14,7 +14,7 @@ import { sharedReducer, storeNewVariable, } from './sharedReducer'; -import { QueryVariableModel, VariableHide } from '../variable'; +import { QueryVariableModel, VariableHide } from '../../templating/variable'; import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, EMPTY_UUID, toVariablePayload } from './types'; import { variableAdapters } from '../adapters'; import { createQueryVariableAdapter } from '../query/adapter'; diff --git a/public/app/features/templating/state/sharedReducer.ts b/public/app/features/variables/state/sharedReducer.ts similarity index 98% rename from public/app/features/templating/state/sharedReducer.ts rename to public/app/features/variables/state/sharedReducer.ts index 325e5223e4e..4764d70b00c 100644 --- a/public/app/features/templating/state/sharedReducer.ts +++ b/public/app/features/variables/state/sharedReducer.ts @@ -1,7 +1,7 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import cloneDeep from 'lodash/cloneDeep'; -import { VariableModel, VariableOption, VariableType, VariableWithOptions } from '../variable'; +import { VariableModel, VariableOption, VariableType, VariableWithOptions } from '../../templating/variable'; import { AddVariable, ALL_VARIABLE_VALUE, EMPTY_UUID, getInstanceState, VariablePayload } from './types'; import { variableAdapters } from '../adapters'; import { changeVariableNameSucceeded } from '../editor/reducer'; @@ -100,8 +100,12 @@ const sharedReducerSlice = createSlice({ }, setCurrentVariableValue: ( state: VariablesState, - action: PayloadAction> + action: PayloadAction> ) => { + if (!action.payload.data.option) { + return; + } + const instanceState = getInstanceState(state, action.payload.uuid); const current = { ...action.payload.data.option }; diff --git a/public/app/features/templating/state/types.ts b/public/app/features/variables/state/types.ts similarity index 95% rename from public/app/features/templating/state/types.ts rename to public/app/features/variables/state/types.ts index 4215e8898c2..3bad148b500 100644 --- a/public/app/features/templating/state/types.ts +++ b/public/app/features/variables/state/types.ts @@ -1,4 +1,4 @@ -import { VariableModel, VariableType } from '../variable'; +import { VariableModel, VariableType } from '../../templating/variable'; import { VariablesState } from './variablesReducer'; export const EMPTY_UUID = '00000000-0000-0000-0000-000000000000'; diff --git a/public/app/features/templating/state/variablesReducer.ts b/public/app/features/variables/state/variablesReducer.ts similarity index 96% rename from public/app/features/templating/state/variablesReducer.ts rename to public/app/features/variables/state/variablesReducer.ts index f454b3c8855..d1625ebf4c5 100644 --- a/public/app/features/templating/state/variablesReducer.ts +++ b/public/app/features/variables/state/variablesReducer.ts @@ -2,7 +2,7 @@ import { PayloadAction } from '@reduxjs/toolkit'; import { cleanUpDashboard } from '../../dashboard/state/reducers'; import { variableAdapters } from '../adapters'; import { sharedReducer } from './sharedReducer'; -import { VariableModel } from '../variable'; +import { VariableModel } from '../../templating/variable'; import { VariablePayload } from './types'; export interface VariablesState extends Record {} diff --git a/public/app/features/templating/textbox/TextBoxVariableEditor.tsx b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx similarity index 94% rename from public/app/features/templating/textbox/TextBoxVariableEditor.tsx rename to public/app/features/variables/textbox/TextBoxVariableEditor.tsx index 6a3b773462e..7390e1537de 100644 --- a/public/app/features/templating/textbox/TextBoxVariableEditor.tsx +++ b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx @@ -1,5 +1,5 @@ import React, { ChangeEvent, PureComponent } from 'react'; -import { TextBoxVariableModel } from '../variable'; +import { TextBoxVariableModel } from '../../templating/variable'; import { VariableEditorProps } from '../editor/types'; export interface Props extends VariableEditorProps {} diff --git a/public/app/features/templating/textbox/TextBoxVariablePicker.tsx b/public/app/features/variables/textbox/TextBoxVariablePicker.tsx similarity index 95% rename from public/app/features/templating/textbox/TextBoxVariablePicker.tsx rename to public/app/features/variables/textbox/TextBoxVariablePicker.tsx index fbc0dd1f234..878a9158d25 100644 --- a/public/app/features/templating/textbox/TextBoxVariablePicker.tsx +++ b/public/app/features/variables/textbox/TextBoxVariablePicker.tsx @@ -1,6 +1,6 @@ import React, { ChangeEvent, FocusEvent, KeyboardEvent, PureComponent } from 'react'; -import { TextBoxVariableModel } from '../variable'; +import { TextBoxVariableModel } from '../../templating/variable'; import { toVariablePayload } from '../state/types'; import { dispatch } from '../../../store/store'; import { variableAdapters } from '../adapters'; diff --git a/public/app/features/templating/textbox/actions.test.ts b/public/app/features/variables/textbox/actions.test.ts similarity index 92% rename from public/app/features/templating/textbox/actions.test.ts rename to public/app/features/variables/textbox/actions.test.ts index 47ff72ed0fc..e8eb7adf162 100644 --- a/public/app/features/templating/textbox/actions.test.ts +++ b/public/app/features/variables/textbox/actions.test.ts @@ -1,10 +1,10 @@ import { variableAdapters } from '../adapters'; import { createTextBoxVariableAdapter } from './adapter'; import { reduxTester } from '../../../../test/core/redux/reduxTester'; -import { TemplatingState } from 'app/features/templating/state/reducers'; +import { TemplatingState } from 'app/features/variables/state/reducers'; import { updateTextBoxVariableOptions } from './actions'; import { getTemplatingRootReducer } from '../state/helpers'; -import { VariableOption, VariableHide, TextBoxVariableModel } from '../variable'; +import { TextBoxVariableModel, VariableHide, VariableOption } from '../../templating/variable'; import { toVariablePayload } from '../state/types'; import { createTextBoxOptions } from './reducer'; import { setCurrentVariableValue } from '../state/sharedReducer'; diff --git a/public/app/features/templating/textbox/actions.ts b/public/app/features/variables/textbox/actions.ts similarity index 91% rename from public/app/features/templating/textbox/actions.ts rename to public/app/features/variables/textbox/actions.ts index 58fdc9e73af..b7141f0f803 100644 --- a/public/app/features/templating/textbox/actions.ts +++ b/public/app/features/variables/textbox/actions.ts @@ -1,4 +1,4 @@ -import { TextBoxVariableModel } from '../variable'; +import { TextBoxVariableModel } from '../../templating/variable'; import { ThunkResult } from '../../../types'; import { getVariable } from '../state/selectors'; import { variableAdapters } from '../adapters'; diff --git a/public/app/features/templating/textbox/adapter.ts b/public/app/features/variables/textbox/adapter.ts similarity index 96% rename from public/app/features/templating/textbox/adapter.ts rename to public/app/features/variables/textbox/adapter.ts index 30143f128ea..62388de283f 100644 --- a/public/app/features/templating/textbox/adapter.ts +++ b/public/app/features/variables/textbox/adapter.ts @@ -1,6 +1,6 @@ import cloneDeep from 'lodash/cloneDeep'; -import { TextBoxVariableModel } from '../variable'; +import { TextBoxVariableModel } from '../../templating/variable'; import { initialTextBoxVariableModelState, textBoxVariableReducer } from './reducer'; import { dispatch } from '../../../store/store'; import { setOptionAsCurrent, setOptionFromUrl } from '../state/actions'; diff --git a/public/app/features/templating/textbox/reducer.test.ts b/public/app/features/variables/textbox/reducer.test.ts similarity index 94% rename from public/app/features/templating/textbox/reducer.test.ts rename to public/app/features/variables/textbox/reducer.test.ts index f06b2b52fb4..b253a62e0a4 100644 --- a/public/app/features/templating/textbox/reducer.test.ts +++ b/public/app/features/variables/textbox/reducer.test.ts @@ -2,9 +2,9 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester'; import cloneDeep from 'lodash/cloneDeep'; import { getVariableTestContext } from '../state/helpers'; import { toVariablePayload } from '../state/types'; -import { textBoxVariableReducer, createTextBoxOptions } from './reducer'; +import { createTextBoxOptions, textBoxVariableReducer } from './reducer'; import { VariablesState } from '../state/variablesReducer'; -import { TextBoxVariableModel } from '../variable'; +import { TextBoxVariableModel } from '../../templating/variable'; import { createTextBoxVariableAdapter } from './adapter'; describe('textBoxVariableReducer', () => { diff --git a/public/app/features/templating/textbox/reducer.ts b/public/app/features/variables/textbox/reducer.ts similarity index 97% rename from public/app/features/templating/textbox/reducer.ts rename to public/app/features/variables/textbox/reducer.ts index f5f0d5ff43a..247fa753485 100644 --- a/public/app/features/templating/textbox/reducer.ts +++ b/public/app/features/variables/textbox/reducer.ts @@ -1,6 +1,6 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { TextBoxVariableModel, VariableHide, VariableOption } from '../variable'; +import { TextBoxVariableModel, VariableHide, VariableOption } from '../../templating/variable'; import { EMPTY_UUID, getInstanceState, VariablePayload } from '../state/types'; import { initialVariablesState, VariablesState } from '../state/variablesReducer'; diff --git a/public/app/types/store.ts b/public/app/types/store.ts index 1f8a94841f9..cae98a5405e 100644 --- a/public/app/types/store.ts +++ b/public/app/types/store.ts @@ -18,7 +18,7 @@ import { LdapState } from './ldap'; import { PanelEditorState } from '../features/dashboard/panel_editor/state/reducers'; import { PanelEditorStateNew } from '../features/dashboard/components/PanelEditor/state/reducers'; import { ApiKeysState } from './apiKeys'; -import { TemplatingState } from '../features/templating/state/reducers'; +import { TemplatingState } from '../features/variables/state/reducers'; export interface StoreState { navIndex: NavIndex;