Extends the bar-label overflow handling: an oversized label defaults to the
right of the bar, but if it would collide with the next bar on the same row it
is placed to the left instead (whichever side has room; larger gap wins when
neither fits). Also make the trigger a debounce (was a throttle) so the layout
runs after a zoom/redraw burst settles, once bar widths are final.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- appearance menu opens 20px below the header/chips and 58px from the right edge
- map "no coordinates" badge is manager-only (hidden for anonymous visitors)
- timeline bar label that is wider than its bar now renders just past the bar's
right edge as dark text on the track, instead of being clipped; labels that
fit still sit inside the bar in white. Applied post-render (measure overflow),
re-run on changed/rangechanged with a double rAF so bar widths are settled.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Counter snippet at the top of <body> (webvisor, clickmap, trackLinks).
Lives in index.html only — no change to the JS/CSS bundle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- appearance menu drops below the active-filter chips row when it is shown,
and sits 10px further from the right edge
- "Скопировать ссылку" moved to the left of the chips, separated by a divider
- enlarge "Green Media" title so it is flush with the "Адресная программа"
line below it
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Appearance ("Оформление") menu:
- add missing status "РК. Предварительное бронирование" (8 statuses total)
- strip the systemic "РК. " prefix from status names in the UI (menu,
tooltip, status filter dropdown, active-filter chips); raw values stay
intact for filtering/URLs
- fixed-position menu: opens 25px below the header, ends >=30px above the
window bottom, scrolls inside — never overflows the viewport
- drop the "Прочие статусы" row
- per-status grey reset glyph (circular arrows) restoring its default colour
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Timeline can now list the entire inventory (occupied + free + never
booked), not just booked surfaces. New manager-only "Все поверхности"
checkbox (on by default; forced on and hidden for anonymous visitors so
they can spot what is currently free with no future bookings).
/api/boards gains all_surfaces: sources rows from board_info and unions
pf_board so a just-booked surface not yet in the inventory snapshot still
gets a row. Surface facets (city/dimension/search) narrow rows; booking
facets (brand/manager/status) narrow to booked surfaces; dates are a
window that narrows bars, not the surface set.
UI polish:
- timeline tooltip flips up/left near viewport edges
- anonymous "Войти" button filled accent, inverts to white-on-accent hover
- appearance button uses a gear icon instead of "+"
- header counter shows only "Поверхности: N"
- map "всего" counter includes surfaces without coordinates
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend (main.py + auth.py):
- Validate Bearer JWT against the intense-sale realm JWKS (RS256, issuer
checked, aud skipped). Missing/invalid token = anonymous, never an error,
so the public map keeps working when Keycloak is down.
- Anonymous truncation: /api/meta hides brand/manager/status facets;
/api/bookings blanks brand/company_name/manager/task_id/task_status
(bars stay, one neutral colour); /api/map keeps occupied_now but empties
booking details. Hidden facet filters are ignored for anonymous callers.
- boards stay visible to all (physical inventory: address/city/dimension).
Frontend (keycloak-js):
- Silent SSO (check-sso) — anonymous by default, Войти/Выйти button.
- Bearer token attached + refreshed on every API call.
- Anonymous UI hides Brand/Manager/Status filters, Brand/Company toggles,
appearance menu, collisions and labels; board detail panel (Planfix
deep-links) gated to managers.
Test manager: user / 1234567890 (realm role `manager`).
- Add Open Props as the token foundation (@import "open-props/style"). Our
semantic tokens (--bg/--surface/--border/--text/--shadow-*/--transition) are
now backed by its gray ramp, shadows and easing; the rest of the CSS is
untouched since it already references var(--…).
- Accent → indigo #4f46e5 (--accent + derived rings / month-hover), and the
timeline bar default colours (appearance.ts) move to the same indigo so the
content and UI share one palette.
- Font → IBM Plex Sans, self-hosted via @fontsource (latin + cyrillic, weights
400/500/600/700) so there is no runtime Google Fonts dependency. Backed into
--font-sans (overrides Open Props' :where() default). Tabular figures on the
counters and map legend.
- Collision default colour → warm amber-orange #e8590c: distinct from the indigo
bars and from the green/red map status, reads as a conflict warning.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>