Azure Monitor: Add info about multiple resource selection (#62327)

This commit is contained in:
Andres Martinez Gotor 2023-01-30 10:49:57 +01:00 committed by GitHub
parent bed1bb1a73
commit be7b90bbd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 1 deletions

View File

@ -118,4 +118,37 @@ describe('LogsQueryEdiutor', () => {
expect(await screen.findByLabelText('web-server_DataDisk')).toBeDisabled(); expect(await screen.findByLabelText('web-server_DataDisk')).toBeDisabled();
}); });
it('should show info about multiple selection', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const query = createMockQuery();
delete query?.subscription;
delete query?.azureLogAnalytics?.resources;
const onChange = jest.fn();
render(
<LogsQueryEditor
query={query}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
resourcePickerButton.click();
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
subscriptionButton.click();
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
resourceGroupButton.click();
const checkbox = await screen.findByLabelText('web-server');
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(await screen.findByText('You may only choose items of the same resource type.')).toBeInTheDocument();
});
}); });

View File

@ -82,6 +82,11 @@ const LogsQueryEditor: React.FC<LogsQueryEditorProps> = ({
// eslint-disable-next-line // eslint-disable-next-line
<AdvancedResourcePicker resources={resources as string[]} onChange={onChange} /> <AdvancedResourcePicker resources={resources as string[]} onChange={onChange} />
)} )}
selectionNotice={() =>
config.featureToggles.azureMultipleResourcePicker
? 'You may only choose items of the same resource type.'
: ''
}
/> />
</EditorFieldGroup> </EditorFieldGroup>
</EditorRow> </EditorRow>

View File

@ -270,6 +270,45 @@ describe('MetricsQueryEditor', () => {
expect(await screen.findByLabelText('web-server_DataDisk')).toBeDisabled(); expect(await screen.findByLabelText('web-server_DataDisk')).toBeDisabled();
}); });
it('should show info about multiple selection', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const query = createMockQuery();
delete query?.subscription;
delete query?.azureMonitor?.resources;
delete query?.azureMonitor?.metricNamespace;
const onChange = jest.fn();
render(
<MetricsQueryEditor
data={mockPanelData}
query={query}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={onChange}
setError={() => {}}
/>
);
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
resourcePickerButton.click();
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
subscriptionButton.click();
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
resourceGroupButton.click();
const checkbox = await screen.findByLabelText('web-server');
await userEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(
await screen.findByText(
'You can select items of the same resource type and location. To select resources of a different resource type or location, please first uncheck your current selection.'
)
).toBeInTheDocument();
});
it('should change the metric name when selected', async () => { it('should change the metric name when selected', async () => {
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() }); const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
const onChange = jest.fn(); const onChange = jest.fn();

View File

@ -49,6 +49,11 @@ const MetricsQueryEditor: React.FC<MetricsQueryEditorProps> = ({
resourceName: r.resourceName, resourceName: r.resourceName,
region: query.azureMonitor?.region, region: query.azureMonitor?.region,
})) ?? []; })) ?? [];
const supportMultipleResource = (namespace?: string) => {
return multiResourceCompatibleTypes[namespace?.toLocaleLowerCase() ?? ''] ?? false;
};
const disableRow = (row: ResourceRow, selectedRows: ResourceRowGroup) => { const disableRow = (row: ResourceRow, selectedRows: ResourceRowGroup) => {
if (selectedRows.length === 0) { if (selectedRows.length === 0) {
// Only if there is some resource(s) selected we should disable rows // Only if there is some resource(s) selected we should disable rows
@ -70,10 +75,20 @@ const MetricsQueryEditor: React.FC<MetricsQueryEditorProps> = ({
rowResource.subscription !== selectedRowSample.subscription || rowResource.subscription !== selectedRowSample.subscription ||
rowResource.region !== selectedRowSample.region || rowResource.region !== selectedRowSample.region ||
rowResource.metricNamespace?.toLocaleLowerCase() !== selectedRowSample.metricNamespace?.toLocaleLowerCase() || rowResource.metricNamespace?.toLocaleLowerCase() !== selectedRowSample.metricNamespace?.toLocaleLowerCase() ||
!multiResourceCompatibleTypes[rowResource.metricNamespace?.toLocaleLowerCase() ?? ''] !supportMultipleResource(rowResource.metricNamespace)
); );
}; };
const selectionNotice = (selectedRows: ResourceRowGroup) => {
if (selectedRows.length === 0 || !config.featureToggles.azureMultipleResourcePicker) {
return '';
}
const selectedRowSample = parseResourceDetails(selectedRows[0].uri, selectedRows[0].location);
return supportMultipleResource(selectedRowSample.metricNamespace)
? 'You can select items of the same resource type and location. To select resources of a different resource type or location, please first uncheck your current selection.'
: '';
};
return ( return (
<span data-testid="azure-monitor-metrics-query-editor-with-experimental-ui"> <span data-testid="azure-monitor-metrics-query-editor-with-experimental-ui">
<EditorRows> <EditorRows>
@ -95,6 +110,7 @@ const MetricsQueryEditor: React.FC<MetricsQueryEditorProps> = ({
// eslint-disable-next-line // eslint-disable-next-line
<AdvancedResourcePicker resources={resources as AzureMetricResource[]} onChange={onChange} /> <AdvancedResourcePicker resources={resources as AzureMetricResource[]} onChange={onChange} />
)} )}
selectionNotice={selectionNotice}
/> />
<MetricNamespaceField <MetricNamespaceField
metricNamespaces={metricNamespaces} metricNamespaces={metricNamespaces}

View File

@ -21,6 +21,7 @@ interface ResourceFieldProps<T> extends AzureQueryEditorFieldProps {
labelWidth?: number; labelWidth?: number;
disableRow: (row: ResourceRow, selectedRows: ResourceRowGroup) => boolean; disableRow: (row: ResourceRow, selectedRows: ResourceRowGroup) => boolean;
renderAdvanced: (resources: T[], onChange: (resources: T[]) => void) => React.ReactNode; renderAdvanced: (resources: T[], onChange: (resources: T[]) => void) => React.ReactNode;
selectionNotice?: (selectedRows: ResourceRowGroup) => string;
} }
const ResourceField: React.FC<ResourceFieldProps<string | AzureMetricResource>> = ({ const ResourceField: React.FC<ResourceFieldProps<string | AzureMetricResource>> = ({
@ -34,6 +35,7 @@ const ResourceField: React.FC<ResourceFieldProps<string | AzureMetricResource>>
labelWidth, labelWidth,
disableRow, disableRow,
renderAdvanced, renderAdvanced,
selectionNotice,
}) => { }) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const [pickerIsOpen, setPickerIsOpen] = useState(false); const [pickerIsOpen, setPickerIsOpen] = useState(false);
@ -74,6 +76,7 @@ const ResourceField: React.FC<ResourceFieldProps<string | AzureMetricResource>>
queryType={queryType} queryType={queryType}
disableRow={disableRow} disableRow={disableRow}
renderAdvanced={renderAdvanced} renderAdvanced={renderAdvanced}
selectionNotice={selectionNotice}
/> />
</Modal> </Modal>
<Field label="Resource" inlineField={inlineField} labelWidth={labelWidth}> <Field label="Resource" inlineField={inlineField} labelWidth={labelWidth}>

View File

@ -29,6 +29,7 @@ interface ResourcePickerProps<T> {
onCancel: () => void; onCancel: () => void;
disableRow: (row: ResourceRow, selectedRows: ResourceRowGroup) => boolean; disableRow: (row: ResourceRow, selectedRows: ResourceRowGroup) => boolean;
renderAdvanced: (resources: T[], onChange: (resources: T[]) => void) => React.ReactNode; renderAdvanced: (resources: T[], onChange: (resources: T[]) => void) => React.ReactNode;
selectionNotice?: (selectedRows: ResourceRowGroup) => string;
} }
const ResourcePicker = ({ const ResourcePicker = ({
@ -40,6 +41,7 @@ const ResourcePicker = ({
queryType, queryType,
disableRow, disableRow,
renderAdvanced, renderAdvanced,
selectionNotice,
}: ResourcePickerProps<string | AzureMetricResource>) => { }: ResourcePickerProps<string | AzureMetricResource>) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
@ -49,6 +51,7 @@ const ResourcePicker = ({
const [internalSelected, setInternalSelected] = useState(resources); const [internalSelected, setInternalSelected] = useState(resources);
const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined); const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined);
const [shouldShowLimitFlag, setShouldShowLimitFlag] = useState(false); const [shouldShowLimitFlag, setShouldShowLimitFlag] = useState(false);
const selectionNoticeText = selectionNotice?.(selectedRows);
// Sync the resourceURI prop to internal state // Sync the resourceURI prop to internal state
useEffect(() => { useEffect(() => {
@ -241,6 +244,11 @@ const ResourcePicker = ({
</table> </table>
</div> </div>
<Space v={2} /> <Space v={2} />
{selectionNoticeText?.length ? (
<Alert title="" severity="info">
{selectionNoticeText}
</Alert>
) : null}
</> </>
)} )}