Alerting: Remove unused components (#111320)
This commit is contained in:
@@ -1809,11 +1809,6 @@
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"public/app/features/alerting/unified/rule-list/StateView.tsx": {
|
||||
"no-restricted-syntax": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"public/app/features/alerting/unified/types/alerting.ts": {
|
||||
"@typescript-eslint/no-explicit-any": {
|
||||
"count": 5
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Stack, useStyles2 } from '@grafana/ui';
|
||||
|
||||
interface DotStylesProps {
|
||||
color: 'success' | 'error' | 'warning' | 'info';
|
||||
includeState?: boolean;
|
||||
}
|
||||
|
||||
const AlertStateDot = ({ color, includeState }: DotStylesProps) => {
|
||||
const styles = useStyles2(getDotStyles, { color, includeState });
|
||||
|
||||
return (
|
||||
<Stack direction="row" gap={0.5}>
|
||||
<div className={styles.dot} />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
const getDotStyles = (theme: GrafanaTheme2, props: DotStylesProps) => {
|
||||
const size = theme.spacing(1.25);
|
||||
const outlineSize = `calc(${size} / 2.5)`;
|
||||
|
||||
const errorStyle = props.color === 'error';
|
||||
const successStyle = props.color === 'success';
|
||||
const warningStyle = props.color === 'warning';
|
||||
|
||||
return {
|
||||
dot: css(
|
||||
{
|
||||
width: size,
|
||||
height: size,
|
||||
|
||||
borderRadius: theme.shape.radius.circle,
|
||||
|
||||
backgroundColor: theme.colors.secondary.main,
|
||||
outline: `solid ${outlineSize} ${theme.colors.secondary.transparent}`,
|
||||
margin: outlineSize,
|
||||
},
|
||||
successStyle &&
|
||||
css({
|
||||
backgroundColor: theme.colors.success.main,
|
||||
outlineColor: theme.colors.success.transparent,
|
||||
}),
|
||||
warningStyle &&
|
||||
css({
|
||||
backgroundColor: theme.colors.warning.main,
|
||||
outlineColor: theme.colors.warning.transparent,
|
||||
}),
|
||||
errorStyle &&
|
||||
css({
|
||||
backgroundColor: theme.colors.error.main,
|
||||
outlineColor: theme.colors.error.transparent,
|
||||
})
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
export { AlertStateDot };
|
||||
@@ -1,151 +0,0 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Counter, Pagination, Stack, useStyles2 } from '@grafana/ui';
|
||||
import { DEFAULT_PER_PAGE_PAGINATION } from 'app/core/constants';
|
||||
import { CombinedRule, CombinedRuleNamespace } from 'app/types/unified-alerting';
|
||||
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { usePagination } from '..//hooks/usePagination';
|
||||
import { calculateTotalInstances } from '../components/rule-viewer/RuleViewer';
|
||||
import { ListSection } from '../rule-list/components/ListSection';
|
||||
import { groupIdentifier } from '../utils/groupIdentifier';
|
||||
import { createViewLink } from '../utils/misc';
|
||||
import { hashRule } from '../utils/rule-id';
|
||||
import { getRulePluginOrigin, prometheusRuleType, rulerRuleType } from '../utils/rules';
|
||||
|
||||
import { AlertRuleListItem } from './components/AlertRuleListItem';
|
||||
import { RuleActionsButtons } from './components/RuleActionsButtons.V2';
|
||||
import { RuleActionsSkeleton } from './components/RuleActionsSkeleton';
|
||||
|
||||
interface Props {
|
||||
namespaces: CombinedRuleNamespace[];
|
||||
}
|
||||
|
||||
type GroupedRules = Map<PromAlertingRuleState, CombinedRule[]>;
|
||||
|
||||
export const StateView = ({ namespaces }: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const groupedRules = useMemo(() => {
|
||||
const result: GroupedRules = new Map([
|
||||
[PromAlertingRuleState.Firing, []],
|
||||
[PromAlertingRuleState.Pending, []],
|
||||
[PromAlertingRuleState.Recovering, []],
|
||||
[PromAlertingRuleState.Inactive, []],
|
||||
[PromAlertingRuleState.Unknown, []],
|
||||
]);
|
||||
|
||||
namespaces.forEach((namespace) =>
|
||||
namespace.groups.forEach((group) =>
|
||||
group.rules.forEach((rule) => {
|
||||
// We might hit edge cases where there type = alerting, but there is no state.
|
||||
// In this case, we shouldn't try to group these alerts in the state view
|
||||
// Even though we handle this at the API layer, this is a last catch point for any edge cases
|
||||
if (prometheusRuleType.alertingRule(rule.promRule) && rule.promRule.state) {
|
||||
result.get(rule.promRule.state)?.push(rule);
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
result.forEach((rules) => rules.sort((a, b) => a.name.localeCompare(b.name)));
|
||||
|
||||
return result;
|
||||
}, [namespaces]);
|
||||
|
||||
const entries = groupedRules.entries();
|
||||
|
||||
return (
|
||||
<ul className={styles.columnStack} role="tree">
|
||||
{Array.from(entries).map(([state, rules]) => (
|
||||
<RulesByState key={state} state={state} rules={rules} />
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
const STATE_TITLES: Record<PromAlertingRuleState, string> = {
|
||||
[PromAlertingRuleState.Firing]: 'Firing',
|
||||
[PromAlertingRuleState.Pending]: 'Pending',
|
||||
[PromAlertingRuleState.Inactive]: 'Normal',
|
||||
[PromAlertingRuleState.Recovering]: 'Recovering',
|
||||
[PromAlertingRuleState.Unknown]: 'Unknown',
|
||||
};
|
||||
|
||||
const RulesByState = ({ state, rules }: { state: PromAlertingRuleState; rules: CombinedRule[] }) => {
|
||||
const { page, pageItems, numberOfPages, onPageChange } = usePagination(rules, 1, DEFAULT_PER_PAGE_PAGINATION);
|
||||
|
||||
const isFiringState = state !== PromAlertingRuleState.Firing;
|
||||
const hasRulesMatchingState = rules.length > 0;
|
||||
|
||||
return (
|
||||
<ListSection
|
||||
title={
|
||||
<Stack alignItems="center" gap={0}>
|
||||
{STATE_TITLES[state] ?? 'Unknown'}
|
||||
<Counter value={rules.length} />
|
||||
</Stack>
|
||||
}
|
||||
collapsed={isFiringState || hasRulesMatchingState}
|
||||
pagination={
|
||||
<Pagination
|
||||
currentPage={page}
|
||||
numberOfPages={numberOfPages}
|
||||
onNavigate={onPageChange}
|
||||
hideWhenSinglePage={true}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{pageItems.map((rule) => {
|
||||
const { rulerRule, promRule } = rule;
|
||||
|
||||
const isProvisioned = rulerRuleType.grafana.rule(rulerRule) && Boolean(rulerRule.grafana_alert.provenance);
|
||||
const instancesCount = prometheusRuleType.alertingRule(rule.promRule)
|
||||
? calculateTotalInstances(rule.instanceTotals)
|
||||
: undefined;
|
||||
const groupId = groupIdentifier.fromCombinedRule(rule);
|
||||
|
||||
if (!promRule) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const originMeta = getRulePluginOrigin(promRule);
|
||||
|
||||
return (
|
||||
<AlertRuleListItem
|
||||
key={hashRule(promRule)}
|
||||
name={rule.name}
|
||||
href={createViewLink(rule.namespace.rulesSource, rule)}
|
||||
summary={rule.annotations.summary}
|
||||
state={state}
|
||||
health={rule.promRule?.health}
|
||||
error={rule.promRule?.lastError}
|
||||
labels={rule.promRule?.labels}
|
||||
isProvisioned={isProvisioned}
|
||||
instancesCount={instancesCount}
|
||||
namespace={rule.namespace.name}
|
||||
group={rule.group.name}
|
||||
actions={
|
||||
rule.rulerRule ? (
|
||||
<RuleActionsButtons compact rule={rule.rulerRule} promRule={promRule} groupIdentifier={groupId} />
|
||||
) : (
|
||||
<RuleActionsSkeleton />
|
||||
)
|
||||
}
|
||||
origin={originMeta}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ListSection>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
columnStack: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: theme.spacing(1),
|
||||
}),
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Icon } from '@grafana/ui';
|
||||
import lokiIconSvg from 'app/plugins/datasource/loki/img/loki_icon.svg';
|
||||
import mimirLogoSvg from 'app/plugins/datasource/prometheus/img/mimir_logo.svg';
|
||||
import prometheusLogoSvg from 'app/plugins/datasource/prometheus/img/prometheus_logo.svg';
|
||||
import { PromApplication, RulesSourceApplication } from 'app/types/unified-alerting-dto';
|
||||
|
||||
interface DataSourceIconProps {
|
||||
application?: RulesSourceApplication;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export const DataSourceIcon = ({ application, size = 16 }: DataSourceIconProps) => {
|
||||
switch (application) {
|
||||
case PromApplication.Prometheus:
|
||||
return <img width={size} height={size} src={prometheusLogoSvg} alt="Prometheus" />;
|
||||
case PromApplication.Mimir:
|
||||
return <img width={size} height={size} src={mimirLogoSvg} alt="Mimir" />;
|
||||
case 'Loki':
|
||||
return <img width={size} height={size} src={lokiIconSvg} alt="Loki" />;
|
||||
case 'grafana':
|
||||
default:
|
||||
return <Icon name="grafana" />;
|
||||
}
|
||||
};
|
||||
@@ -12,7 +12,7 @@ import { Spacer } from '../../components/Spacer';
|
||||
import { WithReturnButton } from '../../components/WithReturnButton';
|
||||
import { isAdmin, stringifyErrorLike } from '../../utils/misc';
|
||||
|
||||
import { DataSourceIcon } from './Namespace';
|
||||
import { DataSourceIcon } from './DataSourceIcon';
|
||||
import { LoadingIndicator } from './RuleGroup';
|
||||
|
||||
export interface DataSourceSectionProps extends PropsWithChildren {
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { Icon, Stack, TextLink, useStyles2 } from '@grafana/ui';
|
||||
import lokiIconSvg from 'app/plugins/datasource/loki/img/loki_icon.svg';
|
||||
import mimirLogoSvg from 'app/plugins/datasource/prometheus/img/mimir_logo.svg';
|
||||
import prometheusLogoSvg from 'app/plugins/datasource/prometheus/img/prometheus_logo.svg';
|
||||
import { PromApplication, RulesSourceApplication } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { WithReturnButton } from '../../components/WithReturnButton';
|
||||
|
||||
interface NamespaceProps extends PropsWithChildren {
|
||||
name: string;
|
||||
href?: string;
|
||||
application?: RulesSourceApplication;
|
||||
}
|
||||
|
||||
// @TODO add export rules for namespace back in
|
||||
const Namespace = ({ children, name, href, application }: NamespaceProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
<li className={styles.namespaceWrapper} role="treeitem" aria-selected="false">
|
||||
<div className={styles.namespaceTitle}>
|
||||
<Stack alignItems={'center'} gap={1}>
|
||||
<DataSourceIcon application={application} />
|
||||
{href ? (
|
||||
<WithReturnButton
|
||||
title={t('alerting.namespace.title-alert-rules', 'Alert rules')}
|
||||
component={
|
||||
<TextLink href={href} inline={false}>
|
||||
{name}
|
||||
</TextLink>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
name
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
{children && (
|
||||
<ul role="group" className={styles.groupItemsWrapper}>
|
||||
{children}
|
||||
</ul>
|
||||
)}
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
interface NamespaceIconProps {
|
||||
application?: RulesSourceApplication;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export const DataSourceIcon = ({ application, size = 16 }: NamespaceIconProps) => {
|
||||
switch (application) {
|
||||
case PromApplication.Prometheus:
|
||||
return <img width={size} height={size} src={prometheusLogoSvg} alt="Prometheus" />;
|
||||
case PromApplication.Mimir:
|
||||
return <img width={size} height={size} src={mimirLogoSvg} alt="Mimir" />;
|
||||
case 'Loki':
|
||||
return <img width={size} height={size} src={lokiIconSvg} alt="Loki" />;
|
||||
case 'grafana':
|
||||
default:
|
||||
return <Icon name="grafana" />;
|
||||
}
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
groupItemsWrapper: css({
|
||||
position: 'relative',
|
||||
borderRadius: theme.shape.radius.default,
|
||||
border: `solid 1px ${theme.colors.border.weak}`,
|
||||
borderBottom: 'none',
|
||||
|
||||
marginLeft: theme.spacing(3),
|
||||
|
||||
'&:before': {
|
||||
content: "''",
|
||||
position: 'absolute',
|
||||
height: '100%',
|
||||
|
||||
borderLeft: `solid 1px ${theme.colors.border.weak}`,
|
||||
|
||||
marginTop: 0,
|
||||
marginLeft: `-${theme.spacing(2.5)}`,
|
||||
},
|
||||
}),
|
||||
namespaceWrapper: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
gap: theme.spacing(1),
|
||||
}),
|
||||
namespaceTitle: css({
|
||||
padding: `${theme.spacing(1)} ${theme.spacing(1.5)}`,
|
||||
|
||||
// background: theme.colors.background.secondary,
|
||||
|
||||
// border: `solid 1px ${theme.colors.border.weak}`,
|
||||
// borderRadius: theme.shape.radius.default,
|
||||
}),
|
||||
});
|
||||
|
||||
export default Namespace;
|
||||
@@ -2,7 +2,7 @@ import { Icon, Stack, TextLink, Tooltip } from '@grafana/ui';
|
||||
import { RulesSourceIdentifier } from 'app/types/unified-alerting';
|
||||
import { RulesSourceApplication } from 'app/types/unified-alerting-dto';
|
||||
|
||||
import { DataSourceIcon } from './Namespace';
|
||||
import { DataSourceIcon } from './DataSourceIcon';
|
||||
|
||||
interface RuleLocationProps {
|
||||
namespace: string;
|
||||
|
||||
@@ -1919,9 +1919,6 @@
|
||||
"title-remove": "Remove",
|
||||
"tooltip-remove-time-range": "Remove time range"
|
||||
},
|
||||
"namespace": {
|
||||
"title-alert-rules": "Alert rules"
|
||||
},
|
||||
"namespace-and-group-filter": {
|
||||
"select-group": "Select group",
|
||||
"select-namespace": "Select namespace"
|
||||
|
||||
Reference in New Issue
Block a user