diff --git a/public/app/plugins/datasource/azuremonitor/azure_resource_graph/azure_resource_graph_datasource.ts b/public/app/plugins/datasource/azuremonitor/azure_resource_graph/azure_resource_graph_datasource.ts
index bed9f6cc52c..c1e8c036e69 100644
--- a/public/app/plugins/datasource/azuremonitor/azure_resource_graph/azure_resource_graph_datasource.ts
+++ b/public/app/plugins/datasource/azuremonitor/azure_resource_graph/azure_resource_graph_datasource.ts
@@ -12,7 +12,7 @@ export default class AzureResourceGraphDatasource extends DataSourceWithBackend<
AzureDataSourceJsonData
> {
filterQuery(item: AzureMonitorQuery): boolean {
- return !!item.azureResourceGraph?.query;
+ return !!item.azureResourceGraph?.query && !!item.subscriptions && item.subscriptions.length > 0;
}
applyTemplateVariables(target: AzureMonitorQuery, scopedVars: ScopedVars): AzureMonitorQuery {
diff --git a/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.test.tsx b/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.test.tsx
index 2ec87df7808..3f5f31a1966 100644
--- a/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.test.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.test.tsx
@@ -1,4 +1,5 @@
-import { render, screen } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import createMockDatasource from '../../__mocks__/datasource';
@@ -118,4 +119,67 @@ describe('ArgQueryEditor', () => {
).toHaveTextContent('$test');
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: ['$test'] }));
});
+
+ it('should display an error if no subscription is selected', async () => {
+ const onChange = jest.fn();
+ const datasource = createMockDatasource({
+ getSubscriptions: jest.fn().mockResolvedValue([]),
+ });
+ const query = createMockQuery({
+ subscriptions: [],
+ });
+ render(
+
+ );
+
+ expect(await waitFor(() => screen.getByText('At least one subscription must be chosen.'))).toBeInTheDocument();
+ });
+
+ it('should display an error if subscriptions are cleared', async () => {
+ const onChange = jest.fn();
+ const datasource = createMockDatasource({
+ getSubscriptions: jest.fn().mockResolvedValue([{ text: 'foo', value: 'test-subscription-value' }]),
+ });
+ const query = createMockQuery({
+ subscription: undefined,
+ subscriptions: ['test-subscription-value'],
+ });
+ const { rerender } = render(
+
+ );
+
+ expect(datasource.getSubscriptions).toHaveBeenCalled();
+ expect(await waitFor(() => onChange)).toHaveBeenCalledWith(
+ expect.objectContaining({ subscriptions: ['test-subscription-value'] })
+ );
+ expect(await waitFor(() => screen.findByText('foo'))).toBeInTheDocument();
+
+ const clear = screen.getByLabelText('select-clear-value');
+ await userEvent.click(clear);
+
+ expect(onChange).toHaveBeenCalledWith(expect.objectContaining({ subscriptions: [] }));
+
+ rerender(
+
+ );
+ expect(await waitFor(() => screen.getByText('At least one subscription must be chosen.'))).toBeInTheDocument();
+ });
});
diff --git a/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.tsx b/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.tsx
index 488f1cf1211..78b685d491b 100644
--- a/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/ArgQueryEditor.tsx
@@ -6,9 +6,9 @@ import { EditorFieldGroup, EditorRow, EditorRows } from '@grafana/experimental';
import Datasource from '../../datasource';
import { selectors } from '../../e2e/selectors';
import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types';
-import SubscriptionField from '../SubscriptionField';
import QueryField from './QueryField';
+import SubscriptionField from './SubscriptionField';
interface ArgQueryEditorProps {
query: AzureMonitorQuery;
@@ -81,7 +81,6 @@ const ArgQueryEditor = ({
void;
+ subscriptions: AzureMonitorOption[];
+}
+
+const SubscriptionField = ({ query, subscriptions, variableOptionGroup, onQueryChange }: SubscriptionFieldProps) => {
+ const [error, setError] = useState(false);
+ const [values, setValues] = useState>>([]);
+ const options = useMemo(() => [...subscriptions, variableOptionGroup], [subscriptions, variableOptionGroup]);
+
+ useEffect(() => {
+ if (query.subscriptions && query.subscriptions.length > 0) {
+ setValues(findOptions([...subscriptions, ...variableOptionGroup.options], query.subscriptions));
+ setError(false);
+ } else {
+ setError(true);
+ }
+ }, [query.subscriptions, subscriptions, variableOptionGroup.options]);
+
+ const onChange = (change: Array>) => {
+ if (!change || change.length === 0) {
+ setValues([]);
+ onQueryChange({
+ ...query,
+ subscriptions: [],
+ });
+ setError(true);
+ } else {
+ const newSubs = change.map((c) => c.value ?? '');
+ onQueryChange({
+ ...query,
+ subscriptions: newSubs,
+ });
+ setValues(findOptions([...subscriptions, ...variableOptionGroup.options], newSubs));
+ setError(false);
+ }
+ };
+
+ return (
+
+ <>
+
+ {error ? At least one subscription must be chosen. : null}
+ >
+
+ );
+};
+
+export default SubscriptionField;
diff --git a/public/app/plugins/datasource/azuremonitor/components/SubscriptionField.tsx b/public/app/plugins/datasource/azuremonitor/components/SubscriptionField.tsx
deleted file mode 100644
index 396bed8b410..00000000000
--- a/public/app/plugins/datasource/azuremonitor/components/SubscriptionField.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import React, { useCallback, useMemo } from 'react';
-
-import { SelectableValue } from '@grafana/data';
-import { Select, MultiSelect } from '@grafana/ui';
-
-import { selectors } from '../e2e/selectors';
-import { AzureMonitorQuery, AzureQueryEditorFieldProps, AzureMonitorOption, AzureQueryType } from '../types';
-import { findOptions } from '../utils/common';
-
-import { Field } from './Field';
-
-interface SubscriptionFieldProps extends AzureQueryEditorFieldProps {
- onQueryChange: (newQuery: AzureMonitorQuery) => void;
- subscriptions: AzureMonitorOption[];
- multiSelect?: boolean;
-}
-
-const SubscriptionField = ({
- query,
- subscriptions,
- variableOptionGroup,
- onQueryChange,
- multiSelect = false,
-}: SubscriptionFieldProps) => {
- const handleChange = useCallback(
- (change: SelectableValue) => {
- if (!change.value) {
- return;
- }
-
- let newQuery: AzureMonitorQuery = {
- ...query,
- subscription: change.value,
- };
-
- if (query.queryType === AzureQueryType.AzureMonitor) {
- newQuery.azureMonitor = {
- ...newQuery.azureMonitor,
- resources: undefined,
- metricNamespace: undefined,
- metricName: undefined,
- aggregation: undefined,
- timeGrain: '',
- dimensionFilters: [],
- };
- }
-
- onQueryChange(newQuery);
- },
- [query, onQueryChange]
- );
-
- const onSubscriptionsChange = useCallback(
- (change: Array>) => {
- if (!change) {
- return;
- }
-
- onQueryChange({
- ...query,
- subscriptions: change.map((c) => c.value ?? ''),
- });
- },
- [query, onQueryChange]
- );
-
- const options = useMemo(() => [...subscriptions, variableOptionGroup], [subscriptions, variableOptionGroup]);
-
- return multiSelect ? (
-
-
-
- ) : (
-
-
-
- );
-};
-
-export default SubscriptionField;
diff --git a/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.test.tsx b/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.test.tsx
index 7947503f9b8..de3b4cfd9db 100644
--- a/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.test.tsx
+++ b/public/app/plugins/datasource/azuremonitor/components/VariableEditor/VariableEditor.test.tsx
@@ -100,7 +100,7 @@ describe('VariableEditor:', () => {
it('should render', async () => {
render();
await waitFor(() => screen.queryByTestId('mockeditor'));
- expect(screen.queryByLabelText('Subscriptions')).toBeInTheDocument();
+ await waitFor(() => screen.queryByLabelText('Subscriptions'));
expect(screen.queryByText('Resource Graph')).toBeInTheDocument();
expect(screen.queryByLabelText('Select subscription')).not.toBeInTheDocument();
expect(screen.queryByLabelText('Select query type')).not.toBeInTheDocument();