mirror of
https://github.com/grafana/grafana.git
synced 2025-09-20 22:07:06 +08:00

* WIP * Add instance totals to combined rule. Use totals to display instances stats in the UI * WIP * add global summaries, fix TS errors * fix useCombined test * fix test * use activeAt from rule when available * Fix NaN in global stats * Add no data total to global summary * Add totals recalculation for filtered rules * Fix instances totals, remove instances filtering from alert list view * Update tests * Fetch alerts considering filtering label matchers * WIP - Fetch alerts appending state filter to endpoint * Fix multiple values for state in request being applyied * fix test * Calculate hidden by for grafana managed alerts * Use INSTANCES_DISPLAY_LIMIT constant for limiting alert instances instead of 1 * Rename matchers parameter according to API changes * Fix calculating total number of grafana instances * Rename matcher prop after previous change * Display button to remove max instances limit * Change matcher query param to be an array of strings * Add test for paramsWithMatcherAndState method * Refactor matcher to be an string array to be consistent with state * Use matcher query string as matcher object type (encoded JSON) * Avoind encoding matcher parameters twice * fix tests * Enable toggle for the limit/show all button and restore limit and filters when we come back from custom view * Move getMatcherListFromString method to utils/alertmanager.ts * Fix limit toggle button being shown when it's not necessary * Use filteredTotals from be response to calculate hidden by count * Fix variables not being replaced correctly * Fix total shown to be all the instances filtered without limits * Adress some PR review comments * Move paramsWithMatcherAndState inside prometheusUrlBuilder method --------- Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com> Co-authored-by: Konrad Lalik <konrad.lalik@grafana.com> Co-authored-by: Virginia Cepeda <virginia.cepeda@grafana.com>
90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { useMemo } from 'react';
|
|
|
|
import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data';
|
|
import { Stack } from '@grafana/experimental';
|
|
import { Spinner, useStyles2 } from '@grafana/ui';
|
|
import { CombinedRule } from 'app/types/unified-alerting';
|
|
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';
|
|
|
|
import { isAlertingRule, isRecordingRule, getFirstActiveAt } from '../../utils/rules';
|
|
|
|
import { AlertStateTag } from './AlertStateTag';
|
|
|
|
interface Props {
|
|
rule: CombinedRule;
|
|
isDeleting: boolean;
|
|
isCreating: boolean;
|
|
isPaused?: boolean;
|
|
}
|
|
|
|
export const RuleState = ({ rule, isDeleting, isCreating, isPaused }: Props) => {
|
|
const style = useStyles2(getStyle);
|
|
const { promRule } = rule;
|
|
|
|
// return how long the rule has been in its firing state, if any
|
|
const forTime = useMemo(() => {
|
|
if (
|
|
promRule &&
|
|
isAlertingRule(promRule) &&
|
|
promRule.alerts?.length &&
|
|
promRule.state !== PromAlertingRuleState.Inactive
|
|
) {
|
|
// find earliest alert
|
|
const firstActiveAt = promRule.activeAt ? new Date(promRule.activeAt) : getFirstActiveAt(promRule);
|
|
|
|
// calculate time elapsed from earliest alert
|
|
if (firstActiveAt) {
|
|
return (
|
|
<span title={String(firstActiveAt)} className={style.for}>
|
|
for{' '}
|
|
{intervalToAbbreviatedDurationString(
|
|
{
|
|
start: firstActiveAt,
|
|
end: new Date(),
|
|
},
|
|
false
|
|
)}
|
|
</span>
|
|
);
|
|
}
|
|
}
|
|
return null;
|
|
}, [promRule, style]);
|
|
|
|
if (isDeleting) {
|
|
return (
|
|
<Stack gap={1}>
|
|
<Spinner />
|
|
Deleting
|
|
</Stack>
|
|
);
|
|
} else if (isCreating) {
|
|
return (
|
|
<Stack gap={1}>
|
|
<Spinner />
|
|
Creating
|
|
</Stack>
|
|
);
|
|
} else if (promRule && isAlertingRule(promRule)) {
|
|
return (
|
|
<Stack gap={1}>
|
|
<AlertStateTag state={promRule.state} isPaused={isPaused} />
|
|
{forTime}
|
|
</Stack>
|
|
);
|
|
} else if (promRule && isRecordingRule(promRule)) {
|
|
return <>Recording rule</>;
|
|
}
|
|
return <>n/a</>;
|
|
};
|
|
|
|
const getStyle = (theme: GrafanaTheme2) => ({
|
|
for: css`
|
|
font-size: ${theme.typography.bodySmall.fontSize};
|
|
color: ${theme.colors.text.secondary};
|
|
white-space: nowrap;
|
|
padding-top: 2px;
|
|
`,
|
|
});
|