diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.test.tsx
new file mode 100644
index 000000000000..838e9d5da1aa
--- /dev/null
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.test.tsx
@@ -0,0 +1,84 @@
+import { render, screen } from '@testing-library/react';
+import React from 'react';
+
+import createMockDatasource from '../../__mocks__/datasource';
+import createMockQuery from '../../__mocks__/query';
+
+import ArgQueryEditor from './ArgQueryEditor';
+
+jest.mock('@grafana/runtime', () => ({
+ ...(jest.requireActual('@grafana/runtime') as unknown as object),
+ getTemplateSrv: () => ({
+ replace: (val: string) => {
+ return val;
+ },
+ }),
+}));
+
+const variableOptionGroup = {
+ label: 'Template variables',
+ options: [],
+};
+
+const defaultProps = {
+ query: createMockQuery(),
+ datasource: createMockDatasource(),
+ variableOptionGroup: variableOptionGroup,
+ onChange: jest.fn(),
+ setError: jest.fn(),
+};
+
+describe('ArgQueryEditor', () => {
+ it('should render', async () => {
+ render();
+ expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
+ });
+
+ it('should select a subscription from the fetched array', async () => {
+ const datasource = createMockDatasource({
+ getSubscriptions: jest.fn().mockResolvedValue([{ value: 'foo' }]),
+ });
+ const onChange = jest.fn();
+ render();
+ expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
+ expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo'] }));
+ });
+
+ it('should select a subscription from existing query', async () => {
+ const onChange = jest.fn();
+ const query = createMockQuery({
+ subscriptions: ['bar'],
+ });
+ render();
+ expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
+ expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['bar'] }));
+ });
+
+ it('should change the subscription if the selected one is not part of the fetched array', async () => {
+ const onChange = jest.fn();
+ const datasource = createMockDatasource({
+ getSubscriptions: jest.fn().mockResolvedValue([{ value: 'foo' }]),
+ });
+ const query = createMockQuery({
+ subscriptions: ['bar'],
+ });
+ render();
+ expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
+ expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo'] }));
+ expect(onChange).not.toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['bar'] }));
+ });
+
+ it('should keep a subset of subscriptions if the new list does not contain all the query subscriptions', async () => {
+ const onChange = jest.fn();
+ const datasource = createMockDatasource({
+ getSubscriptions: jest.fn().mockResolvedValue([{ value: 'foo' }, { value: 'bar' }]),
+ });
+ const query = createMockQuery({
+ subscriptions: ['foo', 'bar', 'foobar'],
+ });
+ render();
+ expect(await screen.findByTestId('azure-monitor-arg-query-editor-with-experimental-ui')).toBeInTheDocument();
+ expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo', 'bar'] }));
+ expect(onChange).not.toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['foo', 'bar', 'foobar'] }));
+ });
+});
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx
index 7f4b06333525..be3905e0ca5e 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ArgQueryEditor/ArgQueryEditor.tsx
@@ -1,4 +1,5 @@
-import React, { useEffect, useState, useRef } from 'react';
+import { intersection } from 'lodash';
+import React, { useState, useMemo } from 'react';
import { EditorRows, EditorRow, EditorFieldGroup } from '@grafana/experimental';
@@ -18,6 +19,28 @@ interface ArgQueryEditorProps {
}
const ERROR_SOURCE = 'arg-subscriptions';
+
+function selectSubscriptions(
+ fetchedSubscriptions: string[],
+ currentSubscriptions?: string[],
+ currentSubscription?: string
+) {
+ let querySubscriptions = currentSubscriptions || [];
+ if (querySubscriptions.length === 0 && currentSubscription) {
+ querySubscriptions = [currentSubscription];
+ }
+ if (querySubscriptions.length === 0 && fetchedSubscriptions.length) {
+ querySubscriptions = [fetchedSubscriptions[0]];
+ }
+ const commonSubscriptions = intersection(querySubscriptions, fetchedSubscriptions);
+ if (fetchedSubscriptions.length && querySubscriptions.length > commonSubscriptions.length) {
+ // If not all of the query subscriptions are in the list of fetched subscriptions, then
+ // select only the ones present (or the first one if none is present)
+ querySubscriptions = commonSubscriptions.length > 0 ? commonSubscriptions : [fetchedSubscriptions[0]];
+ }
+ return querySubscriptions;
+}
+
const ArgQueryEditor: React.FC = ({
query,
datasource,
@@ -26,15 +49,8 @@ const ArgQueryEditor: React.FC = ({
onChange,
setError,
}) => {
- const fetchedRef = useRef(false);
const [subscriptions, setSubscriptions] = useState([]);
-
- useEffect(() => {
- if (fetchedRef.current) {
- return;
- }
-
- fetchedRef.current = true;
+ useMemo(() => {
datasource
.getSubscriptions()
.then((results) => {
@@ -42,15 +58,19 @@ const ArgQueryEditor: React.FC = ({
setSubscriptions(fetchedSubscriptions);
setError(ERROR_SOURCE, undefined);
- if (!query.subscriptions?.length && fetchedSubscriptions?.length) {
- onChange({
- ...query,
- subscriptions: [query.subscription ?? fetchedSubscriptions[0].value],
- });
- }
+ onChange({
+ ...query,
+ subscriptions: selectSubscriptions(
+ fetchedSubscriptions.map((v) => v.value),
+ query.subscriptions,
+ query.subscription
+ ),
+ });
})
.catch((err) => setError(ERROR_SOURCE, err));
- }, [datasource, onChange, query, setError]);
+ // We are only interested in re-fetching subscriptions if the data source changes
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [datasource]);
return (