mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Azure Monitor: Add info about multiple resource selection (#62327)
This commit is contained in:
parent
bed1bb1a73
commit
be7b90bbd1
@ -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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -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>
|
||||||
|
@ -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();
|
||||||
|
@ -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}
|
||||||
|
@ -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}>
|
||||||
|
@ -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}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user