Commit 4e4242d4 by Sartaj Singh Baveja Committed by GitHub

Variables: Adds support for key/value mapping in Custom variable (#27829)

* Initial work on adding new mapping variable type

* Remove add button

* Update custom variable type to include key/value mapping

* Update custom variable docs

* Try to fix failing build

* Update reducer.ts

* Fix failing build

* Remove expansion of the colon

* Update docs

Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>

Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
parent c028d304
...@@ -26,7 +26,7 @@ For example, if you have server names or region names that never change, then yo ...@@ -26,7 +26,7 @@ For example, if you have server names or region names that never change, then yo
## Enter Custom Options ## Enter Custom Options
1. In the **Values separated by comma** list, enter the values for this variable in a comma-separated list. You can include numbers, strings, or other variables. 1. In the **Values separated by comma** list, enter the values for this variable in a comma-separated list. You can include numbers, strings, other variables or key/value pairs separated by a colon.
1. (optional) Enter [Selection Options]({{< relref "../variable-selection-options.md" >}}). 1. (optional) Enter [Selection Options]({{< relref "../variable-selection-options.md" >}}).
1. In **Preview of values**, Grafana displays a list of the current variable values. Review them to ensure they match what you expect. 1. In **Preview of values**, Grafana displays a list of the current variable values. Review them to ensure they match what you expect.
1. Click **Add** to add the variable to the dashboard. 1. Click **Add** to add the variable to the dashboard.
...@@ -50,7 +50,7 @@ class CustomVariableEditorUnconnected extends PureComponent<Props> { ...@@ -50,7 +50,7 @@ class CustomVariableEditorUnconnected extends PureComponent<Props> {
value={this.props.variable.query} value={this.props.variable.query}
onChange={this.onChange} onChange={this.onChange}
onBlur={this.onBlur} onBlur={this.onBlur}
placeholder="1, 10, 20, myvalue, escaped\,value" placeholder="1, 10, mykey : myvalue, myvalue, escaped\,value"
required required
aria-label="Variable editor Form Custom Query field" aria-label="Variable editor Form Custom Query field"
/> />
......
...@@ -12,7 +12,7 @@ describe('customVariableReducer', () => { ...@@ -12,7 +12,7 @@ describe('customVariableReducer', () => {
describe('when createCustomOptionsFromQuery is dispatched', () => { describe('when createCustomOptionsFromQuery is dispatched', () => {
it('then state should be correct', () => { it('then state should be correct', () => {
const query = 'a,b,c'; const query = 'a,b,c,d:e';
const id = '0'; const id = '0';
const { initialState } = getVariableTestContext(adapter, { id, query }); const { initialState } = getVariableTestContext(adapter, { id, query });
const payload = toVariablePayload({ id: '0', type: 'custom' }); const payload = toVariablePayload({ id: '0', type: 'custom' });
...@@ -39,6 +39,11 @@ describe('customVariableReducer', () => { ...@@ -39,6 +39,11 @@ describe('customVariableReducer', () => {
value: 'c', value: 'c',
selected: false, selected: false,
}, },
{
text: 'd',
value: 'e',
selected: false,
},
], ],
} as CustomVariableModel, } as CustomVariableModel,
}); });
...@@ -47,7 +52,7 @@ describe('customVariableReducer', () => { ...@@ -47,7 +52,7 @@ describe('customVariableReducer', () => {
describe('when createCustomOptionsFromQuery is dispatched and query contains spaces', () => { describe('when createCustomOptionsFromQuery is dispatched and query contains spaces', () => {
it('then state should be correct', () => { it('then state should be correct', () => {
const query = 'a, b, c'; const query = 'a, b, c, d : e';
const id = '0'; const id = '0';
const { initialState } = getVariableTestContext(adapter, { id, query }); const { initialState } = getVariableTestContext(adapter, { id, query });
const payload = toVariablePayload({ id: '0', type: 'constant' }); const payload = toVariablePayload({ id: '0', type: 'constant' });
...@@ -74,6 +79,11 @@ describe('customVariableReducer', () => { ...@@ -74,6 +79,11 @@ describe('customVariableReducer', () => {
value: 'c', value: 'c',
selected: false, selected: false,
}, },
{
text: 'd',
value: 'e',
selected: false,
},
], ],
} as CustomVariableModel, } as CustomVariableModel,
}); });
...@@ -82,7 +92,7 @@ describe('customVariableReducer', () => { ...@@ -82,7 +92,7 @@ describe('customVariableReducer', () => {
describe('when createCustomOptionsFromQuery is dispatched and includeAll is true', () => { describe('when createCustomOptionsFromQuery is dispatched and includeAll is true', () => {
it('then state should be correct', () => { it('then state should be correct', () => {
const query = 'a,b,c'; const query = 'a,b,c,d:e';
const id = '0'; const id = '0';
const { initialState } = getVariableTestContext(adapter, { id, query, includeAll: true }); const { initialState } = getVariableTestContext(adapter, { id, query, includeAll: true });
const payload = toVariablePayload({ id: '0', type: 'constant' }); const payload = toVariablePayload({ id: '0', type: 'constant' });
...@@ -114,6 +124,11 @@ describe('customVariableReducer', () => { ...@@ -114,6 +124,11 @@ describe('customVariableReducer', () => {
value: 'c', value: 'c',
selected: false, selected: false,
}, },
{
text: 'd',
value: 'e',
selected: false,
},
], ],
} as CustomVariableModel, } as CustomVariableModel,
}); });
......
...@@ -36,10 +36,15 @@ export const customVariableSlice = createSlice({ ...@@ -36,10 +36,15 @@ export const customVariableSlice = createSlice({
const instanceState = getInstanceState<CustomVariableModel>(state, action.payload.id); const instanceState = getInstanceState<CustomVariableModel>(state, action.payload.id);
const { includeAll, query } = instanceState; const { includeAll, query } = instanceState;
const match = query.match(/(?:\\,|[^,])+/g) ?? []; const match = query.match(/(?:\\,|[^,])+/g) ?? [];
const options = match.map(text => { const options = match.map(text => {
text = text.replace(/\\,/g, ','); text = text.replace(/\\,/g, ',');
const textMatch = text.match(/(?:\\:|[^:])+/g) ?? [];
if (textMatch.length > 1) {
const [key, value] = textMatch;
return { text: key.trim(), value: value.trim(), selected: false };
} else {
return { text: text.trim(), value: text.trim(), selected: false }; return { text: text.trim(), value: text.trim(), selected: false };
}
}); });
if (includeAll) { if (includeAll) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment