feat(web): a home page in two columns, with four figures on top

The home page was two grids of panels side by side, each row as tall as
its tallest panel, which left gaps. Now: four figures of the same size
(my open tickets, waiting for QA, finished by me and by the team this
week), the week, my views, and two columns that stack on their own: my
tickets and the latest on the left; sprints, QA, following, releases,
who is online and «Retomar» on the right. Project cards are as tall as
their row, with the team at the bottom, and a phone only lists the
days of the week that have something.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 21:37:45 +02:00
parent 0564810d36
commit 9044690348
9 changed files with 425 additions and 383 deletions

View File

@@ -51,7 +51,8 @@ import { HomeSprintsComponent } from '../ui/home/home-sprints';
import { OnlineNowComponent } from '../ui/home/online-now';
import { ResumeComponent } from '../ui/home/resume';
import { WeekAgendaComponent } from '../ui/home/week-agenda';
import { WeekStatsComponent } from '../ui/home/week-stats';
import { HomeKpisComponent } from '../ui/home/kpis';
import { MyViewsComponent } from '../ui/my-views';
/** How often the home page refreshes its reading while open. */
const REFRESH_MS = 60_000;
@@ -72,7 +73,8 @@ const REFRESH_MS = 60_000;
OnlineNowComponent,
ResumeComponent,
WeekAgendaComponent,
WeekStatsComponent,
HomeKpisComponent,
MyViewsComponent,
PiActionButtonComponent,
PiEmptyStateComponent,
PiSkeletonComponent,
@@ -106,29 +108,43 @@ const REFRESH_MS = 60_000;
[firstKey]="facade.sorted()[0]?.key ?? null"
(createProject)="openCreate()"
/>
@if (facade.projects().length) {
<ts-week-agenda [items]="h.agenda" />
}
}
@if (facade.projects().length) {
<ts-my-work />
@if (myHome.home(); as h) {
<div class="ts-home">
<ts-activity-feed
[activity]="h.activity"
[projectKeys]="projectKeys()"
/>
<div class="ts-home__side">
<ts-week-stats [me]="h.me" [team]="h.team" />
@if (h.sprints.length) {
<ts-home-sprints [sprints]="h.sprints" />
}
<ts-online-now [online]="h.online" />
<ts-resume />
</div>
</div>
<ts-home-kpis
[mine]="home.mineTotal()"
[dueToday]="dueToday()"
[overdue]="overdue()"
[awaitingQa]="home.awaitingQaTotal()"
[me]="h.me"
[team]="h.team"
/>
<ts-week-agenda [items]="h.agenda" />
}
<ts-my-views />
<!-- Two columns that stack on their own: no gaps between rows. -->
<div class="ts-home">
<div class="ts-home__column">
<ts-my-work />
@if (myHome.home(); as h) {
<ts-activity-feed
[activity]="h.activity"
[projectKeys]="projectKeys()"
/>
}
</div>
<div class="ts-home__column">
@if (myHome.home()?.sprints?.length) {
<ts-home-sprints [sprints]="myHome.home()!.sprints" />
}
<ts-my-work part="side" />
@if (myHome.home(); as h) {
<ts-online-now [online]="h.online" />
}
<ts-resume />
</div>
</div>
<div class="ts-section-header">
<h2>
Proyectos
@@ -245,22 +261,25 @@ const REFRESH_MS = 60_000;
font-size: 0.8125rem;
}
ts-first-steps,
ts-week-agenda {
ts-home-kpis,
ts-week-agenda,
ts-my-views {
margin-bottom: 1.25rem;
}
.ts-home {
display: grid;
grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
gap: 1.25rem;
align-items: start;
margin: 1.25rem 0 2rem;
margin-bottom: 2.5rem;
@media (max-width: 960px) {
grid-template-columns: minmax(0, 1fr);
}
}
.ts-home__side {
.ts-home__column {
display: grid;
gap: 1.25rem;
min-width: 0;
}
.ts-public-check {
p {