Alerting: Reduce number of buildinfo calls (#59319)

This commit is contained in:
Gilles De Mey 2022-12-01 17:05:28 +01:00 committed by GitHub
parent 94c5be8dfb
commit c3a8590fe5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 9 deletions

View File

@ -1,4 +1,4 @@
import { render } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
@ -24,5 +24,12 @@ describe('DataSourcePicker', () => {
select.getByLabelText('select-clear-value');
}).toThrowError();
});
it('should pass disabled prop', async () => {
render(<DataSourcePicker disabled={true} />);
const input = screen.getByLabelText('Select a data source');
expect(input).toHaveProperty('disabled', true);
});
});
});

View File

@ -47,6 +47,8 @@ export interface DataSourcePickerProps {
filter?: (dataSource: DataSourceInstanceSettings) => boolean;
onClear?: () => void;
invalid?: boolean;
disabled?: boolean;
isLoading?: boolean;
}
/**
@ -162,7 +164,17 @@ export class DataSourcePicker extends PureComponent<DataSourcePickerProps, DataS
}
render() {
const { autoFocus, onBlur, onClear, openMenuOnFocus, placeholder, width, inputId } = this.props;
const {
autoFocus,
onBlur,
onClear,
openMenuOnFocus,
placeholder,
width,
inputId,
disabled = false,
isLoading = false,
} = this.props;
const { error } = this.state;
const options = this.getDataSourceOptions();
const value = this.getCurrentValue();
@ -171,6 +183,8 @@ export class DataSourcePicker extends PureComponent<DataSourcePickerProps, DataS
return (
<div aria-label={selectors.components.DataSourcePicker.container}>
<Select
isLoading={isLoading}
disabled={disabled}
aria-label={selectors.components.DataSourcePicker.inputV2}
inputId={inputId || 'data-source-picker'}
className="ds-picker select-container"

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useCallback } from 'react';
import { useAsync } from 'react-use';
import { NavModelItem } from '@grafana/data';
@ -12,7 +12,7 @@ import { ExistingRuleEditor } from './ExistingRuleEditor';
import { AlertingPageWrapper } from './components/AlertingPageWrapper';
import { AlertRuleForm } from './components/rule-editor/AlertRuleForm';
import { useURLSearchParams } from './hooks/useURLSearchParams';
import { fetchAllPromBuildInfoAction } from './state/actions';
import { fetchRulesSourceBuildInfoAction } from './state/actions';
import { useRulesAccess } from './utils/accessControlHooks';
import * as ruleId from './utils/rule-id';
@ -44,12 +44,14 @@ const RuleEditor = ({ match }: RuleEditorProps) => {
const copyFromIdentifier = ruleId.tryParse(copyFromId);
const { loading = true } = useAsync(async () => {
await dispatch(fetchAllPromBuildInfoAction());
if (identifier) {
await dispatch(fetchRulesSourceBuildInfoAction({ rulesSourceName: identifier.ruleSourceName }));
}
}, [dispatch]);
const { canCreateGrafanaRules, canCreateCloudRules, canEditRules } = useRulesAccess();
const getContent = () => {
const getContent = useCallback(() => {
if (loading) {
return;
}
@ -71,7 +73,7 @@ const RuleEditor = ({ match }: RuleEditorProps) => {
}
return <AlertRuleForm />;
};
}, [canCreateCloudRules, canCreateGrafanaRules, canEditRules, copyFromIdentifier, id, identifier, loading]);
return (
<AlertingPageWrapper isLoading={loading} pageId="alert-list" pageNav={getPageNav(identifier ? 'edit' : 'add')}>

View File

@ -1,9 +1,12 @@
import React, { useCallback } from 'react';
import { useAsync } from 'react-use';
import { DataSourceInstanceSettings } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { dispatch } from 'app/store/store';
import { useRulesSourcesWithRuler } from '../../hooks/useRuleSourcesWithRuler';
import { fetchAllPromBuildInfoAction } from '../../state/actions';
interface Props {
onChange: (ds: DataSourceInstanceSettings) => void;
@ -15,6 +18,8 @@ interface Props {
export function CloudRulesSourcePicker({ value, ...props }: Props): JSX.Element {
const rulesSourcesWithRuler = useRulesSourcesWithRuler();
const { loading = true } = useAsync(() => dispatch(fetchAllPromBuildInfoAction()), [dispatch]);
const dataSourceFilter = useCallback(
(ds: DataSourceInstanceSettings): boolean => {
return !!rulesSourcesWithRuler.find(({ id }) => id === ds.id);
@ -22,5 +27,15 @@ export function CloudRulesSourcePicker({ value, ...props }: Props): JSX.Element
[rulesSourcesWithRuler]
);
return <DataSourcePicker noDefault alerting filter={dataSourceFilter} current={value} {...props} />;
return (
<DataSourcePicker
disabled={loading}
isLoading={loading}
noDefault
alerting
filter={dataSourceFilter}
current={value}
{...props}
/>
);
}

View File

@ -1,12 +1,14 @@
import { css } from '@emotion/css';
import { isEmpty } from 'lodash';
import React, { FC } from 'react';
import React, { FC, useEffect } from 'react';
import { GrafanaTheme2 } from '@grafana/data/src';
import { Stack } from '@grafana/experimental';
import { useStyles2 } from '@grafana/ui';
import { dispatch } from 'app/store/store';
import { useRulesSourcesWithRuler } from '../../../hooks/useRuleSourcesWithRuler';
import { fetchAllPromBuildInfoAction } from '../../../state/actions';
import { RuleFormType } from '../../../types/rule-form';
import { GrafanaManagedRuleType } from './GrafanaManagedAlert';
@ -23,6 +25,10 @@ const RuleTypePicker: FC<RuleTypePickerProps> = ({ selected, onChange, enabledTy
const rulesSourcesWithRuler = useRulesSourcesWithRuler();
const hasLotexDatasources = !isEmpty(rulesSourcesWithRuler);
useEffect(() => {
dispatch(fetchAllPromBuildInfoAction());
}, []);
const styles = useStyles2(getStyles);
return (

View File

@ -263,6 +263,7 @@ export function fetchRulerRulesIfNotFetchedYet(rulesSourceName: string): ThunkRe
};
}
// TODO: memoize this or move to RTK Query so we can cache results!
export function fetchAllPromBuildInfoAction(): ThunkResult<Promise<void>> {
return async (dispatch) => {
const allRequests = getAllRulesSourceNames().map((rulesSourceName) =>