Commit Graph

24 Commits

Author SHA1 Message Date
aaverbitskiy
3939dbf8f5 Плашка масштаба графика — сворачиваемая с анимацией
По умолчанию плашка свёрнута (65×35) — белая плашка с фиолетовым пилюлем текущего
масштаба («12М» и т.п.). При наведении разворачивается (145×80) в полный контрол
(лейбл + слайдер + баббл) с плавной анимацией размеров (overflow:hidden + фикс.
размеры) и кросс-фейдом содержимого. Сворачивается обратно через 1с после ухода
курсора (JS-таймер в main.ts, класс .expanded; повторное наведение отменяет). В
развёрнутом виде содержимое смещено на 4px вниз для вертикальной центровки.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-17 12:34:51 +00:00
aaverbitskiy
5ba5a77f97 UI-доработки: выравнивание тогглов, датапикер с «Применить», степперы 80px, поле поиска, автозакрытие балуна карты
- Тогглы: Бренд+Компания в одну строку, блок выровнен ровно по полосе контролов (верх = верх полей, низ = низ «Поиска»), равномерные зазоры
- Датапикер: выбор диапазона больше не применяется автоматически по второму клику — только кнопкой «Применить» (+ «Сбросить» для незавершённого выбора)
- Степперы «Оформления»: ровно 80px по ширине
- Поле поиска в дропдаунах: равномерная рамка 1px по всем сторонам вместо разноцветных краёв
- Балун на карте: клик по пустой карте закрывает балун (guard от самозакрытия по «своему» клику, клик по другому кластеру открывает новый)
- Полоса фильтров: поля сужены на 10px, «Период» до 333px

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 20:39:12 +00:00
aaverbitskiy
e9eee60dab ui: toasts, icon segmented mode switch, steppers, date-range picker (v0.2.13)
Second modernization batch (reference: easystudy ui_elements):
- Toast/snackbar notifications (dark, green check) for actions — copy link.
- Mode switch: icons (horizontal bars / pin / columns) + a sliding active
  indicator; fixed width so the bold active label never resizes the block.
- Appearance number fields became steppers: an editable field with centred −/+
  buttons, ~20% narrower.
- Date filter: the two native date inputs are replaced by a custom range picker
  — one field "Период (даты)" + a calendar popup with month nav and range
  selection (circle endpoints, light band between). The native inputs stay hidden
  as the source of truth so all filter/URL/chip wiring is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 19:02:45 +00:00
aaverbitskiy
f5166b888a ui: toggles, stat tiles, dropdown search, bubble scale slider (v0.2.12)
Modernised several controls (reference: easystudy ui_elements catalogue):
- Display checkboxes (Бренд/Компания/Коллизии/Все поверхности) are now toggle
  switches; the option checkboxes inside filter dropdowns stay normal.
- Counters became stat tiles: header "Поверхности N" (accent) and the map
  legend (свободно/занято/всего + dashed "без координат").
- Filter dropdowns gained an in-panel search that filters the option list
  (shown for lists >7, auto-focused on open).
- Timeline scale control restyled as a filled slider with a value bubble, moved
  out of the header to float over the top-right of the chart just below the time
  axis (5px gap), bubble pointing up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 14:46:04 +00:00
aaverbitskiy
d7c1ce7b77 ui: fresh panel per cluster click, 5-step scale, unified column resizer (v0.2.11)
- Map panel: every marker/cluster click reopens a fresh panel repositioned next
  to the just-clicked cluster (with a pop-in), instead of leaving it in place and
  only swapping the content.
- Timeline scale slider: 5 fixed stops — 6/12/18/24/30 months; label is now
  "Масштаб графика: <6М|12М|18М|24М|30М>" (default 12М).
- Address-column resizer now matches the timeline/map splitter: a 6px solid bar
  that turns accent on hover/drag, so both dividers look identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-15 13:40:10 +00:00
aaverbitskiy
dec639581b ui: green "Размещено" default + green circle favicon (v0.2.6)
- default colour for status "РК. Размещено" is now green #26c04c (was indigo)
- add a #26c04c circle favicon (inline SVG data URI) for the browser tab

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-14 20:14:01 +00:00
aaverbitskiy
159590d62e analytics: add Yandex.Metrika counter 111613184 (v0.2.3)
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>
2026-08-14 18:32:11 +00:00
aaverbitskiy
5cabad9c33 feat: all-surfaces timeline + UI polish (v0.2.0)
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>
2026-08-14 14:48:25 +00:00
aaverbitskiy
341bc42778 auth ui: prevent flash of manager-only controls on load
Anonymous visitors briefly saw the manager-only filters (Brand/Manager/Status),
checkboxes and appearance menu on refresh, because applyRoleUi() hides them only
after the async Keycloak check-sso resolves.

Fix: mark those elements .manager-only and hide them pre-paint via a .role-pending
class set on <html> by the inline head script, gated by a render-blocking CSS rule
(html.role-pending .manager-only { display:none }). applyRoleUi() drops
.role-pending once the role is known and then applies the final per-element state.
Default is now fail-closed (hidden until confirmed manager), so anonymous never
flashes them; managers see the controls appear a moment after load.
2026-08-14 11:29:51 +00:00
aaverbitskiy
1eda6c1e9d auth ui: anon tooltip = dates only; move login button to header top-right
- timeline: RenderFlags.managerView drives the tooltip. Anonymous tier shows
  a minimal tooltip (date range + duration only) — no title, task №, status,
  manager or Planfix hint. Manager tier keeps the rich tooltip.
- header: login/logout button pinned to the top-right corner (.auth-wrap,
  absolute) instead of sitting next to the view-mode switch.

Keycloak: register bare origin in post.logout.redirect.uris so keycloak-js
logout (redirectUri without trailing path) is accepted.
2026-08-14 11:22:16 +00:00
aaverbitskiy
b6b9c27cb0 auth: Keycloak OIDC — anonymous (truncated) vs manager (full) tiers
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`).
2026-08-14 11:05:47 +00:00
aaverbitskiy
4425bd394c features: shareable filter links, board detail panel, spacing rhythm on tokens
- Shareable filter links: current filters sync to the URL query
  (?city=&brand=&dimension=&manager=&status=&q=&from=&to=, repeated params for
  multi-selects) and are restored on load; a "Скопировать ссылку" action in the
  chips row copies the current URL.
- Board detail panel: clicking a timeline row label opens a right-side panel with
  the surface's code, city · size, address and the full list of its bookings
  (brand/company, dates, status dot, manager, Planfix link). Close via ✕ /
  backdrop / Esc. Bars still open the Planfix task. Dropdown gains a public
  setOnBoardClick on the timeline view.
- Fix: the panel showed empty on load because .board-panel{display:flex}
  overrode the UA [hidden] rule — added an explicit [hidden]{display:none}.
- Spacing: tokenised the secondary chrome (header groups, fields, dropdown panel,
  appearance menu, legend, map tooltip) onto the Open Props --size-* scale;
  structural density of the header/fields/inputs deliberately kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-10 18:08:45 +00:00
aaverbitskiy
52a1a7cb2d ui: active-filter chips, empty/loading states, focus/animation polish
- Active-filter chips row under the header: one chip per selected city / brand /
  dimension / manager / status plus search and date bounds, each removable; a
  "Сбросить всё" clears everything. Dropdown gains setSelected()/clear().
- Empty states for the timeline and map: icon + title + subtitle + "Сбросить
  фильтры" button (wired to the same reset). (empty toggled to display:flex.)
- Delayed indeterminate loading bar (250ms threshold so fast loads don't flash),
  covering both the data and the map fetches via an in-flight counter.
- Polish: pop-in animation for dropdown/appearance menus, :focus-visible accent
  rings, :active press on buttons, thin themed scrollbars in panels, tabular
  figures on the timeline date axis and tooltips. New components use the Open
  Props --size-* spacing scale.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-10 16:28:51 +00:00
aaverbitskiy
a68cac80d1 map: donut clusters, occupancy legend/search/no-coords, styled balloon; header polish
Map (map.ts, styles.css, index.html):
- Cluster icons are now donut charts split green (free) / red (busy) by the
  occupancy of the surfaces they contain, count in the centre. Custom
  clusterIconLayout with a hit-area shape; hover/click preserved.
- gridSize 64 -> 112 so nearby clusters stop overlapping at the overview zoom.
- Live legend: "свободна: X · занята: Y · поверхностей: N", reacts to filters.
- "Без координат" is now a clickable badge opening a compact codes-only panel
  (header "Без координат") so the missing-coordinate surfaces can be fixed.
- Search-to-locate: when a filter narrows to one surface the map flies in and
  opens its balloon.
- Balloon restyled to match the timeline tooltip; muted map tiles (ground-pane
  filter) so the markers stand out.
- Cluster hover tooltip shows the brand for occupied surfaces; legend plate
  raised above the Yandex controls.

Header (index.html, styles.css, main.ts):
- Scale + appearance + checkboxes recomposed into one compact block; shorter
  slider; the "Масштаб" label uses the shared field-label style again.
- "Оформление" is now a round "+" button pinned to the header's bottom-right
  corner with a hover tooltip; opens the same appearance menu.
- Counters relabelled "Поверхности" / "Брони"; the counters plate and the
  view-mode switch now share one borderless grey fill; mode buttons sit on a
  more visible grey frame.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 09:39:11 +00:00
aaverbitskiy
557522afcf ui: visual refresh, richer bar tooltip (+manager), header alignment fixes
Frontend (styles.css, index.html, main.ts):
- Design tokens: single accent/border/radius/shadow/spacing system; flat header
  (dropped the boxed groups) with a subtle bottom divider.
- Unified controls: 36px height, consistent focus ring; search field gets a
  magnifier icon; view-mode switch is now a compact vertical segmented control.
- Fixed the dropdown option font: `.field label` styles were leaking into the
  option <label>s (they're inside .field), forcing uppercase + bold; options are
  now normal weight / normal case.
- Header alignment: mode switch fills the row so its bottom lines up with the
  date fields; the counters block is pinned to the same bottom line.
- Dropdown lists no longer show the column-resizer line bleeding through: the
  header now establishes a stacking context (position:relative + z-index) so its
  panels sit above the timeline.
- Dark theme is implemented (tokens + no-flash) but hidden for now (toggle
  display:none, forced light) until it's polished — easy to re-enable.

Timeline tooltip (timeline.ts, types.ts):
- Replaced the plain multi-line text tooltip with a structured card: bold brand
  title + task №, company subtitle, localized dates + duration, status as a
  coloured dot, manager, a distinct collision section, and a "click to open in
  Planfix" hint. Left accent stripe in the bar colour; matches the map tooltip.
- Values are escaped (escapeHtml) before going into innerHTML.

Backend (main.py):
- /api/bookings now returns `manager` (Array(String)), canonicalized to the
  "Фамилия Имя" form (see canon_manager) so the tooltip can show it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 04:39:55 +00:00
aaverbitskiy
c7eae87660 filters: add faceted Status (task_status) filter — meta.statuses, boards/bookings/map filtering (map marker visibility), UI dropdown under Size in filter grid 2026-07-27 19:40:26 +00:00
aaverbitskiy
053bf2587d header: move counters into brand block, compact 4-col filter grid (dates + search on row 2), unify all block backgrounds 2026-07-26 08:52:36 +00:00
aaverbitskiy
68417bf45e map: Yandex map section (3 modes + resizable split), green/red markers, hover tooltips for markers+clusters; fix map init race; header keeps counters inline (fields shrink first); add Manager (Менеджер) faceted filter 2026-07-26 05:05:04 +00:00
aaverbitskiy
23f5ce8b1a header layout: checkbox column (3 rows), Оформление under scale slider, counters as inline gray block 2026-07-21 10:24:07 +00:00
aaverbitskiy
66e501ef59 date filters: independent Дата начала (start_date>=) / Дата окончания (end_date<=), header fields under Город/Бренд; qualify pf_board.start_date/end_date to avoid alias shadowing 2026-07-21 10:07:39 +00:00
aaverbitskiy
5db77b7a06 brand filter (backend+frontend), compact checkbox grid, two-line counter 2026-07-18 11:15:43 +00:00
aaverbitskiy
b393562c3a frontend UI: header 4 groups, Оформление menu (colors/sizes/fonts), centered bars via inner div, clickable Planfix links 2026-07-17 19:27:22 +00:00
aaverbitskiy
6704a50b33 frontend: full modular migration (collisions/dropdown/timeline/styles), staged at /next/, prod unchanged 2026-07-17 16:17:00 +00:00
aaverbitskiy
c6363cd8cf frontend: Vite+TypeScript scaffold (types, api) — not wired to static yet 2026-07-17 15:41:13 +00:00