AlertRules: Update design to align it with recent changes to lists and tables (#66461)

* AlertRules: Update design to be less boxy

* tag alignment fix

* Minor tweak
This commit is contained in:
Torkel Ödegaard 2023-04-13 16:00:03 +02:00 committed by GitHub
parent 0d06aef5f7
commit 7d1b61e033
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 98 additions and 86 deletions

View File

@ -49,6 +49,9 @@ export interface ThemeComponents {
horizontalDrawer: { horizontalDrawer: {
defaultHeight: number; defaultHeight: number;
}; };
table: {
rowHoverBackground: string;
};
} }
export function createComponents(colors: ThemeColors, shadows: ThemeShadows): ThemeComponents { export function createComponents(colors: ThemeColors, shadows: ThemeShadows): ThemeComponents {
@ -102,5 +105,8 @@ export function createComponents(colors: ThemeColors, shadows: ThemeShadows): Th
horizontalDrawer: { horizontalDrawer: {
defaultHeight: 400, defaultHeight: 400,
}, },
table: {
rowHoverBackground: colors.emphasize(colors.background.primary, 0.03),
},
}; };
} }

View File

@ -10,7 +10,6 @@ export function useTableStyles(theme: GrafanaTheme2, cellHeightOption: TableCell
const cellHeight = getCellHeight(theme, cellHeightOption, cellPadding); const cellHeight = getCellHeight(theme, cellHeightOption, cellPadding);
const rowHeight = cellHeight + 2; const rowHeight = cellHeight + 2;
const headerHeight = 28; const headerHeight = 28;
const rowHoverBg = theme.colors.emphasize(theme.colors.background.primary, 0.03);
const buildCellContainerStyle = (color?: string, background?: string, overflowOnHover?: boolean) => { const buildCellContainerStyle = (color?: string, background?: string, overflowOnHover?: boolean) => {
const cellActionsOverflow: CSSObject = { const cellActionsOverflow: CSSObject = {
@ -28,7 +27,7 @@ export function useTableStyles(theme: GrafanaTheme2, cellHeightOption: TableCell
overflow: 'visible', overflow: 'visible',
width: 'auto !important', width: 'auto !important',
boxShadow: `0 0 2px ${theme.colors.primary.main}`, boxShadow: `0 0 2px ${theme.colors.primary.main}`,
background: background ?? rowHoverBg, background: background ?? theme.components.table.rowHoverBackground,
zIndex: 1, zIndex: 1,
}; };
@ -231,7 +230,7 @@ export function useTableStyles(theme: GrafanaTheme2, cellHeightOption: TableCell
border-bottom: 1px solid ${borderColor}; border-bottom: 1px solid ${borderColor};
&:hover { &:hover {
background-color: ${rowHoverBg}; background-color: ${theme.components.table.rowHoverBackground};
} }
&:last-child { &:last-child {

View File

@ -122,7 +122,7 @@ export const DynamicTable = <T extends object>({
<div className={cx(styles.cell, styles.expandCell)}> <div className={cx(styles.cell, styles.expandCell)}>
<IconButton <IconButton
aria-label={`${isItemExpanded ? 'Collapse' : 'Expand'} row`} aria-label={`${isItemExpanded ? 'Collapse' : 'Expand'} row`}
size="xl" size="lg"
data-testid="collapse-toggle" data-testid="collapse-toggle"
className={styles.expandButton} className={styles.expandButton}
name={isItemExpanded ? 'angle-down' : 'angle-right'} name={isItemExpanded ? 'angle-down' : 'angle-right'}
@ -186,7 +186,7 @@ const getStyles = <T extends unknown>(
return (theme: GrafanaTheme2) => ({ return (theme: GrafanaTheme2) => ({
container: css` container: css`
border: 1px solid ${theme.colors.border.strong}; border: 1px solid ${theme.colors.border.weak};
border-radius: ${theme.shape.borderRadius()}; border-radius: ${theme.shape.borderRadius()};
color: ${theme.colors.text.secondary}; color: ${theme.colors.text.secondary};
`, `,
@ -226,6 +226,7 @@ const getStyles = <T extends unknown>(
padding: ${theme.spacing(1)}; padding: ${theme.spacing(1)};
`, `,
cell: css` cell: css`
display: flex;
align-items: center; align-items: center;
padding: ${theme.spacing(1)}; padding: ${theme.spacing(1)};

View File

@ -49,7 +49,7 @@ export const getStyles = (theme: GrafanaTheme2) => ({
`, `,
guideline: css` guideline: css`
left: -19px; left: -19px;
border-left: 1px solid ${theme.colors.border.medium}; border-left: 1px solid ${theme.colors.border.weak};
position: absolute; position: absolute;
${theme.breakpoints.down('md')} { ${theme.breakpoints.down('md')} {
@ -72,7 +72,7 @@ export const getStyles = (theme: GrafanaTheme2) => ({
left: -49px !important; left: -49px !important;
`, `,
headerGuideline: css` headerGuideline: css`
top: -25px; top: -17px;
bottom: 0; bottom: 0;
`, `,
}); });

View File

@ -81,6 +81,7 @@ const getStyles = (theme: GrafanaTheme2) => ({
sectionHeader: css` sectionHeader: css`
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-bottom: ${theme.spacing(1)};
`, `,
wrapper: css` wrapper: css`
margin-bottom: ${theme.spacing(4)}; margin-bottom: ${theme.spacing(4)};

View File

@ -2,7 +2,8 @@ import { css } from '@emotion/css';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data'; import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data';
import { HorizontalGroup, Spinner, useStyles2 } from '@grafana/ui'; import { Stack } from '@grafana/experimental';
import { Spinner, useStyles2 } from '@grafana/ui';
import { CombinedRule } from 'app/types/unified-alerting'; import { CombinedRule } from 'app/types/unified-alerting';
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto'; import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';
@ -53,25 +54,24 @@ export const RuleState = ({ rule, isDeleting, isCreating, isPaused }: Props) =>
if (isDeleting) { if (isDeleting) {
return ( return (
<HorizontalGroup align="flex-start"> <Stack gap={1}>
<Spinner /> <Spinner />
deleting Deleting
</HorizontalGroup> </Stack>
); );
} else if (isCreating) { } else if (isCreating) {
return ( return (
<HorizontalGroup align="flex-start"> <Stack gap={1}>
{' '}
<Spinner /> <Spinner />
creating Creating
</HorizontalGroup> </Stack>
); );
} else if (promRule && isAlertingRule(promRule)) { } else if (promRule && isAlertingRule(promRule)) {
return ( return (
<HorizontalGroup align="flex-start"> <Stack gap={1}>
<AlertStateTag state={promRule.state} isPaused={isPaused} /> <AlertStateTag state={promRule.state} isPaused={isPaused} />
{forTime} {forTime}
</HorizontalGroup> </Stack>
); );
} else if (promRule && isRecordingRule(promRule)) { } else if (promRule && isRecordingRule(promRule)) {
return <>Recording rule</>; return <>Recording rule</>;

View File

@ -209,9 +209,12 @@ export const RulesGroup = React.memo(({ group, namespace, expandAll, viewMode }:
/> />
</Tooltip> </Tooltip>
)} )}
<h6 className={styles.heading}> {
{isFederated && <Badge color="purple" text="Federated" />} {groupName} // eslint-disable-next-line
</h6> <div className={styles.groupName} onClick={() => setIsCollapsed(!isCollapsed)}>
{isFederated && <Badge color="purple" text="Federated" />} {groupName}
</div>
}
<div className={styles.spacer} /> <div className={styles.spacer} />
<div className={styles.headerStats}> <div className={styles.headerStats}>
<RuleStats group={group} /> <RuleStats group={group} />
@ -275,68 +278,70 @@ export const RulesGroup = React.memo(({ group, namespace, expandAll, viewMode }:
RulesGroup.displayName = 'RulesGroup'; RulesGroup.displayName = 'RulesGroup';
export const getStyles = (theme: GrafanaTheme2) => ({ export const getStyles = (theme: GrafanaTheme2) => {
wrapper: css` return {
& + & { wrapper: css``,
margin-top: ${theme.spacing(2)}; header: css`
} display: flex;
`, flex-direction: row;
header: css` align-items: center;
display: flex; padding: ${theme.spacing(1)} ${theme.spacing(1)} ${theme.spacing(1)} 0;
flex-direction: row; flex-wrap: wrap;
align-items: center; border-bottom: 1px solid ${theme.colors.border.weak};
padding: ${theme.spacing(1)} ${theme.spacing(1)} ${theme.spacing(1)} 0; &:hover {
background-color: ${theme.colors.background.secondary}; background-color: ${theme.components.table.rowHoverBackground};
flex-wrap: wrap; }
`, `,
headerStats: css` headerStats: css`
span { span {
vertical-align: middle; vertical-align: middle;
} }
${theme.breakpoints.down('sm')} { ${theme.breakpoints.down('sm')} {
order: 2; order: 2;
width: 100%; width: 100%;
padding-left: ${theme.spacing(1)}; padding-left: ${theme.spacing(1)};
} }
`, `,
heading: css` groupName: css`
margin-left: ${theme.spacing(1)}; margin-left: ${theme.spacing(1)};
margin-bottom: 0;
`,
spacer: css`
flex: 1;
`,
collapseToggle: css`
background: none;
border: none;
margin-top: -${theme.spacing(1)};
margin-bottom: -${theme.spacing(1)};
svg {
margin-bottom: 0; margin-bottom: 0;
} cursor: pointer;
`, `,
dataSourceIcon: css` spacer: css`
width: ${theme.spacing(2)}; flex: 1;
height: ${theme.spacing(2)}; `,
margin-left: ${theme.spacing(2)}; collapseToggle: css`
`, background: none;
dataSourceOrigin: css` border: none;
margin-right: 1em; margin-top: -${theme.spacing(1)};
color: ${theme.colors.text.disabled}; margin-bottom: -${theme.spacing(1)};
`,
actionsSeparator: css` svg {
margin: 0 ${theme.spacing(2)}; margin-bottom: 0;
`, }
actionIcons: css` `,
width: 80px; dataSourceIcon: css`
align-items: center; width: ${theme.spacing(2)};
`, height: ${theme.spacing(2)};
rulesTable: css` margin-left: ${theme.spacing(2)};
margin-top: ${theme.spacing(3)}; `,
`, dataSourceOrigin: css`
rotate90: css` margin-right: 1em;
transform: rotate(90deg); color: ${theme.colors.text.disabled};
`, `,
}); actionsSeparator: css`
margin: 0 ${theme.spacing(2)};
`,
actionIcons: css`
width: 80px;
align-items: center;
`,
rulesTable: css`
margin: ${theme.spacing(2, 0)};
`,
rotate90: css`
transform: rotate(90deg);
`,
};
};

View File

@ -106,9 +106,9 @@ export const getStyles = (theme: GrafanaTheme2) => ({
padding-top: ${theme.spacing(1)}; padding-top: ${theme.spacing(1)};
padding-bottom: ${theme.spacing(0.25)}; padding-bottom: ${theme.spacing(0.25)};
justify-content: center; justify-content: center;
border-left: 1px solid ${theme.colors.border.strong}; border-left: 1px solid ${theme.colors.border.medium};
border-right: 1px solid ${theme.colors.border.strong}; border-right: 1px solid ${theme.colors.border.medium};
border-bottom: 1px solid ${theme.colors.border.strong}; border-bottom: 1px solid ${theme.colors.border.medium};
`, `,
}); });