feat: clean some stuff up + total reducer logic

pull/102284/head
Alex Spencer 3 months ago
parent 790a418895
commit d33584b473
  1. 68
      packages/grafana-ui/src/components/Table/TableNG/Cells/summaryCell.tsx
  2. 4
      packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx
  3. 32
      packages/grafana-ui/src/components/Table/TableNG/utils.ts

@ -1,32 +1,74 @@
import { css, cx } from '@emotion/css';
import { GrafanaTheme2, Field } from '@grafana/data';
import { useStyles2 } from '../../../../themes';
import { TableRow } from '../types';
import { getFooterItemNG, getFooterStyles } from '../utils';
import { getFooterItemNG } from '../utils';
interface SummaryCellProps {
sortedRows: TableRow[];
field: Field;
fieldIndex: number;
theme: GrafanaTheme2;
}
export const SummaryCell = ({ sortedRows, field, fieldIndex, theme }: SummaryCellProps) => {
const footerStyles = getFooterStyles(theme);
export const SummaryCell = ({ sortedRows, field }: SummaryCellProps) => {
const styles = useStyles2(getStyles);
const footerItem = getFooterItemNG(sortedRows, field);
if (!footerItem) {
return null;
return <div className={styles.footerCell} />;
}
// Render each reducer in the footer
return (
<div className={footerStyles.footerCell}>
{Object.entries(footerItem).map(([reducerId, { reducerName, formattedValue }]) => (
<div key={reducerId} className={footerStyles.footerItem}>
<div className={footerStyles.footerItemLabel}>{reducerName}</div>
<div className={footerStyles.footerItemValue}>{formattedValue}</div>
</div>
))}
<div className={styles.footerCell}>
{Object.entries(footerItem).map(([reducerId, { reducerName, formattedValue }]) => {
const allSumReducers = Object.keys(footerItem).every((item) => item === 'sum');
return (
<div key={reducerId} className={cx(styles.footerItem, allSumReducers && styles.sumReducer)}>
{!allSumReducers && <div className={styles.footerItemLabel}>{reducerName}</div>}
<div className={styles.footerItemValue}>{formattedValue}</div>
</div>
);
})}
</div>
);
};
const getStyles = (theme: GrafanaTheme2) => ({
footerCell: css({
borderRight: `1px solid ${theme.colors.border.strong}`,
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
height: '100%',
paddingRight: theme.spacing(1),
paddingLeft: theme.spacing(1),
width: '100%',
}),
footerItem: css({
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
}),
footerItemLabel: css({
color: theme.colors.text.secondary,
fontSize: theme.typography.bodySmall.fontSize,
fontWeight: theme.typography.fontWeightLight,
marginRight: theme.spacing(1),
textTransform: 'uppercase',
}),
footerItemValue: css({
fontWeight: theme.typography.fontWeightMedium,
}),
sumReducer: css({
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'end',
width: '100%',
}),
});

@ -622,9 +622,7 @@ export function mapFrameToDataGrid({
/>
);
},
renderSummaryCell: () => (
<SummaryCell sortedRows={sortedRows} field={field} fieldIndex={fieldIndex} theme={theme} />
),
renderSummaryCell: () => <SummaryCell sortedRows={sortedRows} field={field} />,
renderHeaderCell: ({ column, sortDirection }): JSX.Element => (
<HeaderCell
column={column}

@ -1,4 +1,3 @@
import { css } from '@emotion/css';
import { Property } from 'csstype';
import React from 'react';
import { SortColumn, SortDirection } from 'react-data-grid';
@ -324,35 +323,6 @@ export function getFooterItemNG(rows: TableRow[], field: Field): FooterItem | nu
return Object.keys(footerItem).length > 0 ? footerItem : null;
}
export const getFooterStyles = (theme: GrafanaTheme2) => ({
footerCell: css({
border: `1px solid ${theme.colors.border.medium}`,
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
height: '100%',
padding: theme.spacing(1),
width: '100%',
}),
footerItem: css({
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
}),
footerItemLabel: css({
color: theme.colors.text.secondary,
fontSize: theme.typography.bodySmall.fontSize,
fontWeight: theme.typography.fontWeightLight,
marginRight: theme.spacing(1),
textTransform: 'uppercase',
}),
footerItemValue: css({
fontWeight: theme.typography.fontWeightMedium,
}),
});
/* ------------------------- Cell color calculation ------------------------- */
const CELL_COLOR_DARKENING_MULTIPLIER = 10;
const CELL_GRADIENT_DARKENING_MULTIPLIER = 15;
@ -655,6 +625,6 @@ const getMaxReducerCount = (dataFrame: DataFrame, fieldConfig: TableNGProps['fie
export const calculateFooterHeight = (dataFrame: DataFrame, fieldConfig: TableNGProps['fieldConfig']) => {
const maxReducerCount = getMaxReducerCount(dataFrame, fieldConfig);
// Base height (+ padding) + height per reducer
const dynamicHeight = 36 + maxReducerCount * 22;
const dynamicHeight = 22 + maxReducerCount * 22;
return Math.max(dynamicHeight, 36); // Ensure minimum height of 36px
};

Loading…
Cancel
Save