fix(client): one bar thickness, and every dashboard card half-width
Bars came in two weights — 4px for the plain proportional bar and 8px for the segmented one — so the lines in Monitors by type, Slowest monitors and Lowest uptime were visibly thinner than the one in Monitor status. They sit side by side across cards, so the difference read as an inconsistency rather than as emphasis. There is now a single BAR_HEIGHT of 8 for both. Monitor status and Team members drop to half-width, which makes every card half-width. The grid is now uniform in both dimensions. That also removes the last reason for the stretch rule. A trailing card on an odd-numbered dashboard keeps its declared width instead of being promoted to full: widening one card to fill its row makes it look more important than it is, and an odd count is a property of the selection, not something the layout should paper over. layoutCards is now a straight pass-through, and HALF_WIDTH is gone with the logic that needed it. Verified across the full catalogue, the non-admin subset, the defaults and a single card: no card renders full-width in any configuration. Claude-Session: https://claude.ai/code/session_01AbYLvwpEaZFXktHVcqrFRd
This commit is contained in:
1 parent
74d859b877
commit
8398a0300d
4 files changed
+24
-43
No files matched your search
@@ -10,10 +10,12 @@ import { typographyLevels } from "@/Utils/Theme/Palette";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
/** Thin enough to read as a proportion indicator, not a progress bar. */
|
||||
const BAR_HEIGHT = 4;
|
||||
/** The segmented bar carries more meaning, so it gets a little more presence. */
|
||||
const SEGMENTED_BAR_HEIGHT = 8;
|
||||
/**
|
||||
* One thickness for every bar on the dashboard. Plain and segmented bars sit
|
||||
* side by side across cards, so differing weights read as an inconsistency
|
||||
* rather than as emphasis.
|
||||
*/
|
||||
const BAR_HEIGHT = 8;
|
||||
|
||||
export interface BarSegment {
|
||||
key: string;
|
||||
@@ -73,7 +75,7 @@ export const CardSegmentedBar = ({ segments }: { segments: BarSegment[] }) => {
|
||||
<Stack
|
||||
direction="row"
|
||||
width="100%"
|
||||
height={SEGMENTED_BAR_HEIGHT}
|
||||
height={BAR_HEIGHT}
|
||||
borderRadius={theme.shape.borderRadius}
|
||||
bgcolor={theme.palette.action.hover}
|
||||
gap="1px"
|
||||
|
||||
@@ -2,16 +2,14 @@ import type { ComponentType } from "react";
|
||||
|
||||
// The 12-column grid the dashboard lays cards out on.
|
||||
//
|
||||
// Only two widths exist. Cards are half-width by default and pair up down the
|
||||
// page; a card is full-width only when its content genuinely needs the room,
|
||||
// which makes the wide cards read as a deliberate signal rather than as an
|
||||
// inconsistent grid. Width is declared per card type in code and is never a
|
||||
// user setting.
|
||||
// Every card is currently half-width, so they pair up down the page and the
|
||||
// grid reads as one system. Full width stays in the type for a card whose
|
||||
// content genuinely needs it. Width is declared per card type in code and is
|
||||
// never a user setting.
|
||||
export const CardWidths = [6, 12] as const;
|
||||
export type CardWidth = (typeof CardWidths)[number];
|
||||
|
||||
export const GRID_COLUMNS = 12;
|
||||
export const HALF_WIDTH: CardWidth = 6;
|
||||
|
||||
// Picker groups mirror the sidebar sections: you look for a card where you
|
||||
// look for the feature it belongs to.
|
||||
|
||||
@@ -1,40 +1,21 @@
|
||||
import { GRID_COLUMNS, HALF_WIDTH, type CardDefinition } from "./cards";
|
||||
import type { CardDefinition } from "./cards";
|
||||
|
||||
export interface PlacedCard {
|
||||
card: CardDefinition;
|
||||
/** Columns rendered. Equal to the declared width except for a lone half. */
|
||||
/** Columns rendered — currently always the declared width. */
|
||||
renderedWidth: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs cards into rows of GRID_COLUMNS.
|
||||
*
|
||||
* With only two widths this is nearly trivial: two halves fill a row exactly
|
||||
* and a full-width card fills its own, so no card is ever stretched to close a
|
||||
* gap. The one case needing a decision is a half-width card left alone at the
|
||||
* end of the page — it is promoted to full width so the page does not end on a
|
||||
* ragged half.
|
||||
* With a single body width this is a straight pass-through: two halves fill a
|
||||
* row exactly, so no card is ever stretched to close a gap.
|
||||
*
|
||||
* `grid-auto-flow: dense` was tried and does not help: with a single body width
|
||||
* there is never a smaller card available to backfill.
|
||||
* An odd number of cards leaves the last one alone on its row. It keeps its
|
||||
* declared width rather than being promoted to full: widening one card to fill
|
||||
* the row makes it look more important than it is, and an odd count is a
|
||||
* property of the selection, not something the layout should hide.
|
||||
*/
|
||||
export const layoutCards = (cards: CardDefinition[]): PlacedCard[] => {
|
||||
const placed: PlacedCard[] = cards.map((card) => ({
|
||||
card,
|
||||
renderedWidth: card.width,
|
||||
}));
|
||||
|
||||
// Columns occupied in the row still open once every card is placed. A
|
||||
// trailing half-width card leaves exactly HALF_WIDTH here.
|
||||
const trailing = placed.reduce(
|
||||
(used, entry) => (used + entry.renderedWidth) % GRID_COLUMNS,
|
||||
0
|
||||
);
|
||||
|
||||
const last = placed[placed.length - 1];
|
||||
if (last && trailing === HALF_WIDTH) {
|
||||
last.renderedWidth = GRID_COLUMNS;
|
||||
}
|
||||
|
||||
return placed;
|
||||
};
|
||||
export const layoutCards = (cards: CardDefinition[]): PlacedCard[] =>
|
||||
cards.map((card) => ({ card, renderedWidth: card.width }));
|
||||
@@ -26,14 +26,14 @@ import type { CardDefinition, CardId } from "./cards";
|
||||
//
|
||||
// Order is the render order, and the order the picker lists them in.
|
||||
//
|
||||
// Full width is reserved for Monitor status alone, which lays six counts across
|
||||
// a single row. Every other card is half-width and pairs up down the page.
|
||||
// Every card is half-width and pairs up down the page. The grid promotes a
|
||||
// lone trailing card to full width so the page does not end on a ragged half.
|
||||
export const CARD_REGISTRY: CardDefinition[] = [
|
||||
{
|
||||
id: "monitorStatus",
|
||||
key: "monitorStatus",
|
||||
group: "uptime",
|
||||
width: 12,
|
||||
width: 6,
|
||||
component: MonitorStatusCard,
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user