mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 00:08:10 -05:00
Alerting: mute timing improvements (#43940)
* mute timing table ui fixes * add options for CTA to use link * fix validation for time range
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import React, { ButtonHTMLAttributes, FC } from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { Button, ButtonVariant, IconName, useStyles } from '@grafana/ui';
|
||||
import { Button, ButtonVariant, IconName, LinkButton, useStyles } from '@grafana/ui';
|
||||
import { EmptyArea } from './EmptyArea';
|
||||
|
||||
export interface EmptyAreaWithCTAProps {
|
||||
buttonLabel: string;
|
||||
onButtonClick: ButtonHTMLAttributes<HTMLButtonElement>['onClick'];
|
||||
href?: string;
|
||||
onButtonClick?: ButtonHTMLAttributes<HTMLButtonElement>['onClick'];
|
||||
text: string;
|
||||
|
||||
buttonIcon?: IconName;
|
||||
@@ -21,23 +22,30 @@ export const EmptyAreaWithCTA: FC<EmptyAreaWithCTAProps> = ({
|
||||
buttonVariant = 'primary',
|
||||
onButtonClick,
|
||||
text,
|
||||
href,
|
||||
}) => {
|
||||
const styles = useStyles(getStyles);
|
||||
|
||||
const commonProps = {
|
||||
className: styles.button,
|
||||
icon: buttonIcon,
|
||||
size: buttonSize,
|
||||
variant: buttonVariant,
|
||||
};
|
||||
|
||||
return (
|
||||
<EmptyArea>
|
||||
<>
|
||||
<p className={styles.text}>{text}</p>
|
||||
<Button
|
||||
className={styles.button}
|
||||
icon={buttonIcon}
|
||||
onClick={onButtonClick}
|
||||
size={buttonSize}
|
||||
type="button"
|
||||
variant={buttonVariant}
|
||||
>
|
||||
{buttonLabel}
|
||||
</Button>
|
||||
{href ? (
|
||||
<LinkButton href={href} type="button" {...commonProps}>
|
||||
{buttonLabel}
|
||||
</LinkButton>
|
||||
) : (
|
||||
<Button onClick={onButtonClick} type="button" {...commonProps}>
|
||||
{buttonLabel}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
</EmptyArea>
|
||||
);
|
||||
|
||||
@@ -56,6 +56,12 @@ export const AmRoutesTable: FC<AmRoutesTableProps> = ({
|
||||
renderCell: (item) => item.data.receiver || '-',
|
||||
size: 5,
|
||||
},
|
||||
{
|
||||
id: 'muteTimings',
|
||||
label: 'Mute timings',
|
||||
renderCell: (item) => item.data.muteTimeIntervals.join(', ') || '-',
|
||||
size: 5,
|
||||
},
|
||||
...(readOnly
|
||||
? []
|
||||
: [
|
||||
|
||||
@@ -22,7 +22,7 @@ export const MuteTimingTimeRange: FC<Props> = ({ intervalIndex }) => {
|
||||
return true;
|
||||
}
|
||||
const [hour, minutes] = timeString.split(':').map((x) => parseInt(x, 10));
|
||||
const isHourValid = hour > 0 && hour < 25;
|
||||
const isHourValid = hour >= 0 && hour < 25;
|
||||
const isMinuteValid = minutes > -1 && minutes < 60;
|
||||
const isTimeValid = hour === 24 ? minutes === 0 : isHourValid && isMinuteValid;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
getMonthsString,
|
||||
getYearsString,
|
||||
} from '../../utils/alertmanager';
|
||||
import { EmptyAreaWithCTA } from '../EmptyAreaWithCTA';
|
||||
|
||||
interface Props {
|
||||
alertManagerSourceName: string;
|
||||
@@ -46,7 +47,7 @@ export const MuteTimingsTable: FC<Props> = ({ alertManagerSourceName, muteTiming
|
||||
const columns = useColumns(alertManagerSourceName, hideActions, setMuteTimingName);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.container}>
|
||||
{!hideActions && <h5>Mute timings</h5>}
|
||||
{!hideActions && (
|
||||
<p>
|
||||
@@ -54,7 +55,29 @@ export const MuteTimingsTable: FC<Props> = ({ alertManagerSourceName, muteTiming
|
||||
particular notification policies for specific times of the day.
|
||||
</p>
|
||||
)}
|
||||
{items.length > 0 ? <DynamicTable items={items} cols={columns} /> : <p>No mute timings configured</p>}
|
||||
{!hideActions && items.length > 0 && (
|
||||
<LinkButton
|
||||
className={styles.addMuteButton}
|
||||
icon="plus"
|
||||
variant="primary"
|
||||
href={makeAMLink('alerting/routes/mute-timing/new', alertManagerSourceName)}
|
||||
>
|
||||
New mute timing
|
||||
</LinkButton>
|
||||
)}
|
||||
{items.length > 0 ? (
|
||||
<DynamicTable items={items} cols={columns} />
|
||||
) : !hideActions ? (
|
||||
<EmptyAreaWithCTA
|
||||
text="You haven't created any mute timings yet"
|
||||
buttonLabel="Add mute timing"
|
||||
buttonIcon="plus"
|
||||
buttonSize="lg"
|
||||
href={makeAMLink('alerting/routes/mute-timing/new', alertManagerSourceName)}
|
||||
/>
|
||||
) : (
|
||||
<p>No mute timings configured</p>
|
||||
)}
|
||||
{!hideActions && (
|
||||
<ConfirmModal
|
||||
isOpen={!!muteTimingName}
|
||||
@@ -65,15 +88,6 @@ export const MuteTimingsTable: FC<Props> = ({ alertManagerSourceName, muteTiming
|
||||
onDismiss={() => setMuteTimingName('')}
|
||||
/>
|
||||
)}
|
||||
{!hideActions && (
|
||||
<LinkButton
|
||||
className={styles.addMuteButton}
|
||||
variant="secondary"
|
||||
href={makeAMLink('alerting/routes/mute-timing/new', alertManagerSourceName)}
|
||||
>
|
||||
Add mute timing
|
||||
</LinkButton>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -139,7 +153,12 @@ function renderTimeIntervals(timeIntervals: TimeInterval[]) {
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
container: css`
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
`,
|
||||
addMuteButton: css`
|
||||
margin-top: ${theme.spacing(1)};
|
||||
margin-bottom: ${theme.spacing(2)};
|
||||
align-self: flex-end;
|
||||
`,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user