Files
drupal-figli-compta/web/modules/custom/figli_compta_ledger/css/admin-chrome.css
T
bachir 2f9ad7d52c Rebuild /dashboard with charts, add Grand livre/Dashboard nav
Nav: a small "Grand livre" / "Dashboard" switcher, top-right on both
pages, with the current page highlighted. Needed hook_theme() to
declare current_route as an accepted variable for both theme hooks --
same class of bug as the earlier can_view_history fix: an undeclared
variable passed via the render array is silently dropped rather than
reaching Twig.

Dashboard: replaced the old "solde par compte / par client" tables
(computed client-side from a full unwindowed JSON:API fetch of every
node -- the same performance problem the /lignes sliding window was
built to avoid, just not yet felt at 1500+ lines) with a single
aggregate endpoint (DashboardStatsController, plain SQL GROUP BY) and
five chart panels: CA par année, solde par compte (diverging,
red/green), solde par compte trend (small multiples per compte),
répartition par type, top clients par CA. No charting library --
small dependency-free div/CSS bar charts (HBarChart/ColumnChart/
MiniTrend components in dashboard.js), consistent with this project
vendoring its own JS.

Two data-correctness fixes along the way: (1) the historical stray
mistyped dates (0213-06-15, 2015-08-29 -- preserved as-is per this
module's policy) needed excluding from per-year buckets without
excluding their money from all-time totals, so the filtering happens
per-output-field in PHP rather than as a blanket SQL date range. (2)
PHP silently casts numeric-looking array keys ("2021") to actual
integers, so array_keys() on a year-keyed map produces a mix of ints
and strings -- json_encode emits the int ones as bare JSON numbers in
a list (unlike object keys, which JSON always stringifies), which
broke the frontend's annees[i].slice(2) trend-card labels. Fixed with
an explicit array_map('strval', ...).

Verified: bar widths/colors match the underlying data exactly (e.g.
EXT.'s red bar is proportionally sized against Maud's green one per
their actual solde ratio), all 8 trend cards render correct year
labels, and both nav links correctly highlight on their own page.
2026-09-04 23:30:40 +02:00

121 lines
4.0 KiB
CSS

/* Core Navigation's top bar (`.top-bar`) only shows itself when its
tools/context/actions regions are non-empty -- but with no blocks placed
there, the regions still contain whitespace text nodes from the Twig
loop scaffolding, which defeats the `:not(:empty)` check. Result: an
empty top bar renders anyway, with the page content pushed down to make
room for it. We only use the Gin sidebar (the left icon rail), so force
the phantom bar off and collapse the space it would otherwise reserve. */
.top-bar {
display: none !important;
}
.top-bar ~ .dialog-off-canvas-main-canvas {
margin-block-start: 0 !important;
}
/* Grand livre / Dashboard switcher, top-right of both pages. Only present
on those two custom routes, but attached here (already loaded on every
page for the phantom-top-bar fix above) rather than duplicated between
home.css and dashboard.css -- and defined with its own explicit colors
rather than relying on either page's #figli-*-app-scoped custom
properties, since this <nav> sits outside both of those elements. */
.figli-page-nav {
display: flex;
justify-content: flex-end;
gap: 0.4rem;
padding: 0.5rem 0.25rem 0;
}
.figli-page-nav a {
padding: 0.3rem 0.8rem;
border-radius: 6px;
font-size: 0.82rem;
font-weight: 600;
text-decoration: none;
color: #6b7280;
border: 1px solid transparent;
}
.figli-page-nav a:hover {
border-color: #dcdee2;
}
.figli-page-nav a.is-active {
background: #eef1f6;
color: #1a1a1a;
}
html.gin--dark-mode .figli-page-nav a {
color: #a1a5ab;
}
html.gin--dark-mode .figli-page-nav a:hover {
border-color: #3d3e42;
}
html.gin--dark-mode .figli-page-nav a.is-active {
background: #2c2d30;
color: #e8e9ea;
}
/* Drupal status messages: fixed top-right, out of document flow, so they
never shift the page layout the way the default in-flow placement does
-- and shrunk to a fraction of Gin's default size, which is sized for a
single full-width flash banner on an admin form, not a toast for
frequent background feedback here. Targets both the real region
([data-drupal-messages], present once a message is queued on a normal
page load) and the JS-only fallback container
([data-drupal-messages-fallback], used when Drupal.Message.add() -- our
own MessageCommand-driven AJAX messages included -- has no region to
attach to). Auto-dismiss timing for non-error messages is handled in
admin-chrome.js. */
[data-drupal-messages],
[data-drupal-messages-fallback] {
position: fixed !important;
top: 0.75rem;
right: 0.75rem;
left: auto !important;
width: auto;
max-width: 22rem;
z-index: 1000;
}
[data-drupal-messages] .messages-list__wrapper,
[data-drupal-messages] .messages__wrapper,
[data-drupal-messages-fallback] .messages-list__wrapper,
[data-drupal-messages-fallback] .messages__wrapper {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
[data-drupal-messages] .messages,
[data-drupal-messages-fallback] .messages {
padding: 0.5rem 0.6rem;
font-size: 0.78rem;
line-height: 1.3;
border-radius: 6px;
}
[data-drupal-messages] .messages__header,
[data-drupal-messages-fallback] .messages__header {
margin-block-end: 0.15rem;
margin-inline-end: 1.1em;
}
[data-drupal-messages] .messages__header::before,
[data-drupal-messages-fallback] .messages__header::before {
width: 1rem !important;
height: 1rem !important;
}
[data-drupal-messages] .messages__title,
[data-drupal-messages-fallback] .messages__title {
font-size: 0.78rem;
}
[data-drupal-messages] .messages__title,
[data-drupal-messages] .messages__content,
[data-drupal-messages-fallback] .messages__title,
[data-drupal-messages-fallback] .messages__content {
margin-inline-start: 1.4rem;
}
[data-drupal-messages] .button--dismiss,
[data-drupal-messages-fallback] .button--dismiss {
height: 20px !important;
width: 20px !important;
margin: 0.3rem !important;
}
[data-drupal-messages] .button--dismiss .icon-close,
[data-drupal-messages-fallback] .button--dismiss .icon-close {
mask-size: 11px 11px !important;
}