mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-27 18:09:10 +00:00
style(report): draw grouped rows the way the app already draws them
The report had invented its own treatment for a group and its events: a flat surface, a rail drawn as an inset shadow at its own width, and a foot closing the group off. The cuesheet and the sheet import preview had already settled this, and settled it the same way as each other, so the report now follows them rather than adding a third dialect. Both wash a row with a colour mixed from the entry's own colour and rail it down the left, deepening for the group that owns the rows: 4% and 3px for an event, 12% and 4px for the group, over gray-1300. Both read that colour from a --entry-colour custom property, which is what the report now sets too. The import preview is the closer precedent of the two, being a table of grouped entries inside a settings panel, so its exact mix ratios and rail widths are the ones taken here. Groups are separated by space above the heading, as the preview does it, which retires the closing foot. The summary card's surface moves behind a --card-surface variable so the group tier can wash it without a specificity fight, and the neutral default stays the gray-1200 that Info uses. The wash sits on the cells rather than the row so it covers the panel table's own striping, which no longer shows through on some rows and not others. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019nr3FbLbM8gB8Jm771YgTV
This commit is contained in:
+4
-2
@@ -1,7 +1,9 @@
|
||||
// an inset surface within the panel card, matching how Info nests inside one
|
||||
// an inset surface within the panel card, matching how Info nests inside one.
|
||||
// The surface is a variable so a tier with a colour of its own can wash it
|
||||
// without having to out-specify this rule
|
||||
.card {
|
||||
padding: 1.25rem;
|
||||
background-color: $gray-1200;
|
||||
background-color: var(--card-surface, #{$gray-1200});
|
||||
border-radius: 3px;
|
||||
|
||||
display: flex;
|
||||
|
||||
+24
-30
@@ -1,7 +1,12 @@
|
||||
// the rail the whole group hangs off, falling back to a neutral edge when the
|
||||
// user gave the group no colour of its own
|
||||
$rail-width: 3px;
|
||||
$rail-colour: var(--group-colour, #{$gray-500});
|
||||
// Rows follow the treatment the cuesheet and the sheet import preview already
|
||||
// use for entries: a wash of the entry's own colour over the row and a rail of
|
||||
// it down the left, deepening for the group that owns them. --entry-colour is
|
||||
// the variable both of those read.
|
||||
//
|
||||
// The two fall back differently on purpose: a group the user gave no colour
|
||||
// still needs a visible edge to be read as a group, but nothing to wash with.
|
||||
$rail: var(--entry-colour, #{$gray-500});
|
||||
$wash: var(--entry-colour, transparent);
|
||||
|
||||
// event rows carry their values in td, not th: the panel's th styling is meant
|
||||
// for column headings and renders whatever it holds small, bold and upper case
|
||||
@@ -13,44 +18,33 @@ td.under {
|
||||
color: $playback-under;
|
||||
}
|
||||
|
||||
// the group heading is a card rather than a table row treatment, so the cell
|
||||
// only has to give it room and stay out of the table's striping
|
||||
.groupRow {
|
||||
background-color: transparent;
|
||||
|
||||
td {
|
||||
padding: 1.25rem 0 0;
|
||||
}
|
||||
// the surface sits on the cells rather than the row so it paints over the
|
||||
// table's own striping without having to out-specify it
|
||||
.eventRow td {
|
||||
background-color: color-mix(in srgb, #{$gray-1300} 96%, #{$wash} 4%);
|
||||
}
|
||||
|
||||
// a continuous coloured edge down the heading and every event under it, closed
|
||||
// by the cap below. Mirrors how the rundown editor brackets a group, so the
|
||||
// report reads with the same grammar as the rundown it reports on
|
||||
.grouped {
|
||||
box-shadow: inset $rail-width 0 $rail-colour;
|
||||
}
|
||||
|
||||
td.grouped {
|
||||
.groupedRow td:first-child {
|
||||
box-shadow: inset 3px 0 $rail;
|
||||
// clear the rail rather than sitting against it
|
||||
padding-left: 0.75rem;
|
||||
}
|
||||
|
||||
.groupEndRow {
|
||||
// the group heading is a card rather than a row treatment, so the cell only has
|
||||
// to give it room. The space above it is what separates one group from the last
|
||||
.groupRow {
|
||||
background-color: transparent;
|
||||
|
||||
td {
|
||||
padding: 0 0 1.25rem;
|
||||
padding: 0;
|
||||
border-top: 1.25rem solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.groupEnd {
|
||||
display: block;
|
||||
height: 0.5rem;
|
||||
background-color: $rail-colour;
|
||||
border-radius: 0 0 $rail-width $rail-width;
|
||||
// the rail tapering off, not a second element: any wider and the foot reads
|
||||
// as an underline belonging to the last event rather than to the group
|
||||
width: $rail-width;
|
||||
.groupCard {
|
||||
--card-surface: color-mix(in srgb, #{$gray-1300} 88%, #{$rail} 12%);
|
||||
|
||||
box-shadow: inset 4px 0 $rail;
|
||||
}
|
||||
|
||||
.eventCue,
|
||||
|
||||
+10
-21
@@ -44,7 +44,6 @@ export default function ReportTable({ rows, groups }: ReportTableProps) {
|
||||
{section.rows.map((entry) => (
|
||||
<EventRow key={entry.id} entry={entry} colour={section.group?.colour} />
|
||||
))}
|
||||
{section.group && <GroupEndRow colour={section.group.colour} />}
|
||||
</Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
@@ -62,10 +61,10 @@ function GroupRow({ group }: { group: GroupReport }) {
|
||||
const measuredAgainst = group.targetDuration ?? group.scheduledDuration;
|
||||
|
||||
return (
|
||||
<tr className={style.groupRow}>
|
||||
<td colSpan={7} style={groupColour(group.colour)}>
|
||||
<tr className={style.groupRow} style={entryColour(group.colour)}>
|
||||
<td colSpan={7}>
|
||||
<ReportSummaryCard
|
||||
className={style.grouped}
|
||||
className={style.groupCard}
|
||||
title={group.title || 'Untitled group'}
|
||||
subtitle={
|
||||
group.actualStart !== null && group.actualEnd !== null
|
||||
@@ -116,8 +115,8 @@ function EventRow({ entry, colour }: { entry: CombinedReport; colour?: string })
|
||||
const grouped = colour !== undefined;
|
||||
|
||||
return (
|
||||
<tr style={grouped ? groupColour(colour) : undefined}>
|
||||
<td className={cx([style.eventIndex, grouped && style.grouped])}>{entry.index}</td>
|
||||
<tr className={cx([style.eventRow, grouped && style.groupedRow])} style={grouped ? entryColour(colour) : undefined}>
|
||||
<td className={style.eventIndex}>{entry.index}</td>
|
||||
<td className={style.eventCue}>{entry.cue}</td>
|
||||
<td>{entry.title}</td>
|
||||
<td>{formatTime(entry.scheduledStart)}</td>
|
||||
@@ -129,22 +128,12 @@ function EventRow({ entry, colour }: { entry: CombinedReport; colour?: string })
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the group off the way the rundown editor does, so the events between
|
||||
* the heading and this cap read as belonging to it rather than following it.
|
||||
* The entry's own colour, read by the row styling the same way the cuesheet and
|
||||
* the import preview read it. Left unset when the user gave the group none, so
|
||||
* the stylesheet falls back to a neutral edge.
|
||||
*/
|
||||
function GroupEndRow({ colour }: { colour: string }) {
|
||||
return (
|
||||
<tr className={style.groupEndRow} style={groupColour(colour)}>
|
||||
<td colSpan={7}>
|
||||
<span className={style.groupEnd} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
/** The group's own colour, or a neutral rail when the user set none */
|
||||
function groupColour(colour?: string): React.CSSProperties {
|
||||
return { '--group-colour': colour || undefined } as React.CSSProperties;
|
||||
function entryColour(colour?: string): React.CSSProperties {
|
||||
return { '--entry-colour': colour || undefined } as React.CSSProperties;
|
||||
}
|
||||
|
||||
/** Whether an actual time landed before (under) or after (over) its schedule */
|
||||
|
||||
Reference in New Issue
Block a user