mirror of https://github.com/grafana/grafana.git
93 lines
2.9 KiB
TypeScript
93 lines
2.9 KiB
TypeScript
import React from 'react';
|
|
|
|
import { NavModelItem } from '@grafana/data';
|
|
import { config, isFetchError } from '@grafana/runtime';
|
|
import { Alert, withErrorBoundary } from '@grafana/ui';
|
|
import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport';
|
|
import { EntityNotFound } from 'app/core/components/PageNotFound/EntityNotFound';
|
|
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
|
|
|
import { AlertingPageWrapper } from './components/AlertingPageWrapper';
|
|
import { AlertRuleProvider } from './components/rule-viewer/v2/RuleContext';
|
|
import { useCombinedRule } from './hooks/useCombinedRule';
|
|
import { stringifyErrorLike } from './utils/misc';
|
|
import { getRuleIdFromPathname, parse as parseRuleId } from './utils/rule-id';
|
|
|
|
const DetailViewV1 = SafeDynamicImport(() => import('./components/rule-viewer/RuleViewer.v1'));
|
|
const DetailViewV2 = React.lazy(() => import('./components/rule-viewer/v2/RuleViewer.v2'));
|
|
|
|
type RuleViewerProps = GrafanaRouteComponentProps<{
|
|
id: string;
|
|
sourceName: string;
|
|
}>;
|
|
|
|
const newAlertDetailView = Boolean(config.featureToggles?.alertingDetailsViewV2) === true;
|
|
|
|
const RuleViewer = (props: RuleViewerProps): JSX.Element => {
|
|
return newAlertDetailView ? <RuleViewerV2Wrapper {...props} /> : <RuleViewerV1Wrapper {...props} />;
|
|
};
|
|
|
|
export const defaultPageNav: NavModelItem = {
|
|
id: 'alert-rule-view',
|
|
text: '',
|
|
};
|
|
|
|
const RuleViewerV1Wrapper = (props: RuleViewerProps) => <DetailViewV1 {...props} />;
|
|
|
|
const RuleViewerV2Wrapper = (props: RuleViewerProps) => {
|
|
const id = getRuleIdFromPathname(props.match.params);
|
|
|
|
// we convert the stringified ID to a rule identifier object which contains additional
|
|
// type and source information
|
|
const identifier = React.useMemo(() => {
|
|
if (!id) {
|
|
throw new Error('Rule ID is required');
|
|
}
|
|
|
|
return parseRuleId(id, true);
|
|
}, [id]);
|
|
|
|
// we then fetch the rule from the correct API endpoint(s)
|
|
const { loading, error, result: rule } = useCombinedRule({ ruleIdentifier: identifier });
|
|
|
|
if (error) {
|
|
return (
|
|
<AlertingPageWrapper pageNav={defaultPageNav} navId="alert-list">
|
|
<ErrorMessage error={error} />
|
|
</AlertingPageWrapper>
|
|
);
|
|
}
|
|
|
|
if (loading) {
|
|
return (
|
|
<AlertingPageWrapper pageNav={defaultPageNav} navId="alert-list" isLoading={true}>
|
|
<></>
|
|
</AlertingPageWrapper>
|
|
);
|
|
}
|
|
|
|
if (rule) {
|
|
return (
|
|
<AlertRuleProvider identifier={identifier} rule={rule}>
|
|
<DetailViewV2 />
|
|
</AlertRuleProvider>
|
|
);
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
interface ErrorMessageProps {
|
|
error: unknown;
|
|
}
|
|
|
|
function ErrorMessage({ error }: ErrorMessageProps) {
|
|
if (isFetchError(error) && error.status === 404) {
|
|
return <EntityNotFound entity="Rule" />;
|
|
}
|
|
|
|
return <Alert title={'Something went wrong loading the rule'}>{stringifyErrorLike(error)}</Alert>;
|
|
}
|
|
|
|
export default withErrorBoundary(RuleViewer, { style: 'page' });
|