diff --git a/internal/lookout/ui/src/components/ActionableValueOnHover.tsx b/internal/lookout/ui/src/components/ActionableValueOnHover.tsx index 1f7ba72b2e9..778f8caeb4b 100644 --- a/internal/lookout/ui/src/components/ActionableValueOnHover.tsx +++ b/internal/lookout/ui/src/components/ActionableValueOnHover.tsx @@ -6,12 +6,17 @@ import { CopyIconButton } from "./CopyIconButton" import { AddFilter } from "./icons" const OuterContainer = styled("div")({ - display: "flex", + display: "inline-flex", + width: "100%", flexDirection: "row", alignItems: "center", gap: "0.5ch", }) +const ContentContainer = styled("div")<{ minWidth: boolean }>(({ minWidth }) => ({ + flexGrow: minWidth ? undefined : 1, +})) + const StyledIconButton = styled(IconButton)(({ hidden }) => ({ visibility: hidden ? "hidden" : "unset", })) @@ -40,7 +45,7 @@ export const ActionableValueOnHover = ({ const [hovering, setHovering] = useState(false) return ( setHovering(true)} onMouseLeave={() => setHovering(false)}> -
{children}
+ {children} {copyAction && (
rowIsGroup: boolean @@ -204,21 +228,16 @@ export interface BodyCellProps { onExpandedChange: () => void onClickRowCheckbox: (row: Row) => void } + export const BodyCell = ({ cell, rowIsGroup, rowIsExpanded, onExpandedChange, onClickRowCheckbox }: BodyCellProps) => { const columnMetadata = getColumnMetadata(cell.column.columnDef) const cellHasValue = cell.renderValue() const isRightAligned = columnMetadata.isRightAligned ?? false - return ( - - {rowIsGroup && cell.column.getIsGrouped() && cellHasValue ? ( - // If it's a grouped cell, add an expander and row count + + const cellContent = ((): ReactNode => { + // If it's a grouped cell, add an expander and row count + if (rowIsGroup && cell.column.getIsGrouped() && cellHasValue) { + return ( - ) : cell.getIsAggregated() ? ( - // If the cell is aggregated, use the Aggregated - // renderer for cell - flexRender(cell.column.columnDef.aggregatedCell ?? cell.column.columnDef.cell, { + ) + } + + // If the cell is aggregated, use the Aggregated renderer for cell + if (cell.getIsAggregated()) { + return flexRender(cell.column.columnDef.aggregatedCell ?? cell.column.columnDef.cell, { + ...cell.getContext(), + onClickRowCheckbox, + }) + } + + return ( + { + cell.column.setFilterValue( + columnMetadata.filterType === FilterType.Enum ? [cell.getValue()] : cell.getValue(), + ) + }, + } + } + > + {flexRender(cell.column.columnDef.cell, { ...cell.getContext(), onClickRowCheckbox, - }) - ) : ( - { - cell.column.setFilterValue( - columnMetadata.filterType === FilterType.Enum ? [cell.getValue()] : cell.getValue(), - ) - }, - } - } - > - {flexRender(cell.column.columnDef.cell, { - ...cell.getContext(), - onClickRowCheckbox, - })} - - )} - + })} + + ) + })() + + return ( + + {cellContent} + ) } diff --git a/internal/lookout/ui/src/containers/lookoutV2/JobsTableContainer.tsx b/internal/lookout/ui/src/containers/lookoutV2/JobsTableContainer.tsx index 569222b1d59..e7b2d7351bb 100644 --- a/internal/lookout/ui/src/containers/lookoutV2/JobsTableContainer.tsx +++ b/internal/lookout/ui/src/containers/lookoutV2/JobsTableContainer.tsx @@ -825,6 +825,7 @@ export const JobsTableContainer = ({ onSetTextFieldRef={(ref) => { setTextFieldRef(header.id, ref) }} + groupedColumns={grouping} /> ))} diff --git a/internal/lookout/ui/src/theme/components/chip.ts b/internal/lookout/ui/src/theme/components/chip.ts new file mode 100644 index 00000000000..718a52352f9 --- /dev/null +++ b/internal/lookout/ui/src/theme/components/chip.ts @@ -0,0 +1,67 @@ +import { alpha, ChipClasses, ChipProps, Components, Theme } from "@mui/material" + +declare module "@mui/material/Chip" { + interface ChipPropsVariantOverrides { + shaded: true + } +} + +type ChipColor = Exclude + +const getShadedChipTextColor = (color: ChipColor, theme: Theme): string => { + switch (theme.palette.mode) { + case "light": + return color === "default" ? theme.palette.grey[400] : theme.palette[color].dark + case "dark": + return color === "default" ? theme.palette.grey[700] : theme.palette[color].light + } +} + +const getShadedChipBackgroundColor = (color: ChipColor, theme: Theme): string | undefined => { + switch (theme.palette.mode) { + case "light": + return color === "default" ? undefined : alpha(theme.palette[color].light, 0.12) + case "dark": + return color === "default" ? undefined : alpha(theme.palette[color].dark, 0.12) + } +} + +const ChipColorClassesKeyMap: Record = { + default: "colorDefault", + primary: "colorPrimary", + secondary: "colorSecondary", + error: "colorError", + info: "colorInfo", + success: "colorSuccess", + warning: "colorWarning", + statusGrey: "colorStatusGrey", + statusBlue: "colorStatusBlue", + statusGreen: "colorStatusGreen", + statusAmber: "colorStatusAmber", + statusRed: "colorStatusRed", +} + +export const MuiChip: Components["MuiChip"] = { + variants: [ + { + props: { variant: "shaded" }, + style: ({ theme }) => [ + { + fontWeight: theme.typography.fontWeightMedium, + + ...Object.entries(ChipColorClassesKeyMap).reduce((acc, [_color, chipClassesKey]) => { + const color = _color as ChipColor + return { + ...acc, + + [`&.MuiChip-${chipClassesKey}`]: { + backgroundColor: getShadedChipBackgroundColor(color, theme), + color: getShadedChipTextColor(color, theme), + }, + } + }, {}), + }, + ], + }, + ], +} diff --git a/internal/lookout/ui/src/theme/components/tooltip.ts b/internal/lookout/ui/src/theme/components/tooltip.ts new file mode 100644 index 00000000000..fe2c07bcf5f --- /dev/null +++ b/internal/lookout/ui/src/theme/components/tooltip.ts @@ -0,0 +1,26 @@ +import { Components, tooltipClasses } from "@mui/material" + +export const MuiTooltip: Components["MuiTooltip"] = { + defaultProps: { + arrow: true, + placement: "top", + slotProps: { + popper: { + sx: { + [`&.${tooltipClasses.popper}[data-popper-placement*="bottom"] .${tooltipClasses.tooltip}`]: { + marginTop: "5px", + }, + [`&.${tooltipClasses.popper}[data-popper-placement*="top"] .${tooltipClasses.tooltip}`]: { + marginBottom: "5px", + }, + [`&.${tooltipClasses.popper}[data-popper-placement*="right"] .${tooltipClasses.tooltip}`]: { + marginLeft: "5px", + }, + [`&.${tooltipClasses.popper}[data-popper-placement*="left"] .${tooltipClasses.tooltip}`]: { + marginRight: "5px", + }, + }, + }, + }, + }, +} diff --git a/internal/lookout/ui/src/theme/palette.ts b/internal/lookout/ui/src/theme/palette.ts index 6e1d354eeb7..23cbef30556 100644 --- a/internal/lookout/ui/src/theme/palette.ts +++ b/internal/lookout/ui/src/theme/palette.ts @@ -82,6 +82,8 @@ declare module "@mui/material/Button" { declare module "@mui/material/Chip" { // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface ChipPropsColorOverrides extends CustomPaletteColorTokensTrueMap {} + // eslint-disable-next-line @typescript-eslint/no-empty-object-type + interface ChipClasses extends Record<`color${Capitalize}`, string> {} } declare module "@mui/material/SvgIcon" { diff --git a/internal/lookout/ui/src/theme/theme.ts b/internal/lookout/ui/src/theme/theme.ts index 7088b8257cb..4eb8a250ed3 100644 --- a/internal/lookout/ui/src/theme/theme.ts +++ b/internal/lookout/ui/src/theme/theme.ts @@ -1,9 +1,12 @@ import { createTheme } from "@mui/material" +import { MuiChip } from "./components/chip" +import { MuiTooltip } from "./components/tooltip" import { darkModePalette, lightModePalette } from "./palette" import { typography } from "./typography" export const theme = createTheme({ colorSchemes: { dark: { palette: darkModePalette }, light: { palette: lightModePalette } }, + components: { MuiChip, MuiTooltip }, typography, }) diff --git a/internal/lookout/ui/src/utils/jobsTableColumns.tsx b/internal/lookout/ui/src/utils/jobsTableColumns.tsx index 80f388e7129..367e4fb46d8 100644 --- a/internal/lookout/ui/src/utils/jobsTableColumns.tsx +++ b/internal/lookout/ui/src/utils/jobsTableColumns.tsx @@ -238,7 +238,12 @@ export const JOB_COLUMNS: JobTableColumn[] = [ cell.row.original.stateCounts && cell.row.original.groupedField !== "state" ) { - return + return ( + + ) } else { return } @@ -251,7 +256,12 @@ export const JOB_COLUMNS: JobTableColumn[] = [ cell.row.original.stateCounts && cell.row.original.groupedField !== "state" ) { - return + return ( + + ) } else { return }