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>
153 lines
5.9 KiB
HTML
153 lines
5.9 KiB
HTML
<!doctype html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>Адресная программа</title>
|
||
<script>
|
||
// Theme is set before first paint (no flash). Dark theme is temporarily
|
||
// hidden — force light regardless of stored/OS preference. To re-enable,
|
||
// restore the localStorage/prefers-color-scheme logic and unhide the toggle.
|
||
document.documentElement.setAttribute('data-theme', 'light');
|
||
</script>
|
||
</head>
|
||
<body>
|
||
|
||
<header>
|
||
<!-- Group 1: brand + counters -->
|
||
<div class="hgroup hgroup-brand">
|
||
<div class="brand">
|
||
<div class="brand-name">Green Media</div>
|
||
<div class="brand-sub">Адресная программа</div>
|
||
<div id="status"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Group 1b: view mode switch -->
|
||
<div class="hgroup hgroup-modes">
|
||
<div class="mode-switch">
|
||
<button type="button" class="mode-btn active" id="mode-timeline">График</button>
|
||
<button type="button" class="mode-btn" id="mode-map">Карта</button>
|
||
<button type="button" class="mode-btn" id="mode-split">Карта и график</button>
|
||
</div>
|
||
<button type="button" class="theme-toggle" id="theme-toggle" title="Переключить тему" aria-label="Переключить тему"></button>
|
||
</div>
|
||
|
||
<!-- Group 2: fields (4-column grid; dates + search on the 2nd row) -->
|
||
<div class="hgroup hgroup-fields">
|
||
<div class="field">
|
||
<label>Город</label>
|
||
<div class="dropdown" id="city-dropdown">
|
||
<button type="button" class="dropdown-btn" id="city-btn">
|
||
<span id="city-btn-text">Все города</span>
|
||
<span class="caret">▾</span>
|
||
</button>
|
||
<div class="dropdown-panel" id="city-panel"></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label>Бренд</label>
|
||
<div class="dropdown" id="brand-dropdown">
|
||
<button type="button" class="dropdown-btn" id="brand-btn">
|
||
<span id="brand-btn-text">Все бренды</span>
|
||
<span class="caret">▾</span>
|
||
</button>
|
||
<div class="dropdown-panel" id="brand-panel"></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label>Размер</label>
|
||
<div class="dropdown" id="dimension-dropdown">
|
||
<button type="button" class="dropdown-btn" id="dimension-btn">
|
||
<span id="dimension-btn-text">Все размеры</span>
|
||
<span class="caret">▾</span>
|
||
</button>
|
||
<div class="dropdown-panel" id="dimension-panel"></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label>Менеджер</label>
|
||
<div class="dropdown" id="manager-dropdown">
|
||
<button type="button" class="dropdown-btn" id="manager-btn">
|
||
<span id="manager-btn-text">Все менеджеры</span>
|
||
<span class="caret">▾</span>
|
||
</button>
|
||
<div class="dropdown-panel" id="manager-panel"></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label for="date-start">Дата начала (от)</label>
|
||
<input type="date" id="date-start" />
|
||
</div>
|
||
<div class="field">
|
||
<label for="date-end">Дата окончания (до)</label>
|
||
<input type="date" id="date-end" />
|
||
</div>
|
||
<div class="field">
|
||
<label>Статус</label>
|
||
<div class="dropdown" id="status-dropdown">
|
||
<button type="button" class="dropdown-btn" id="status-btn">
|
||
<span id="status-btn-text">Все статусы</span>
|
||
<span class="caret">▾</span>
|
||
</button>
|
||
<div class="dropdown-panel" id="status-panel"></div>
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label for="search">Поиск (адрес / код)</label>
|
||
<input type="text" id="search" placeholder="например, Азина" />
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Group 3: checkboxes -->
|
||
<div class="hgroup hgroup-checks">
|
||
<div class="field checkbox-field">
|
||
<label for="show-brand"><input type="checkbox" id="show-brand" checked /> Бренд</label>
|
||
</div>
|
||
<div class="field checkbox-field">
|
||
<label for="show-collisions"><input type="checkbox" id="show-collisions" checked /> Коллизии размещения</label>
|
||
</div>
|
||
<div class="field checkbox-field">
|
||
<label for="show-company"><input type="checkbox" id="show-company" /> Компания</label>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Group 4: appearance settings -->
|
||
<div class="hgroup hgroup-scale">
|
||
<div class="field zoom-field">
|
||
<label for="zoom-slider">Масштаб: <span id="zoom-label">12 месяцев</span></label>
|
||
<input type="range" id="zoom-slider" min="0" max="9" step="1" value="3" />
|
||
</div>
|
||
<div class="decor-wrap">
|
||
<button type="button" class="decor-btn" id="decor-btn">Оформление ▾</button>
|
||
<div class="decor-menu" id="decor-menu"></div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div id="view" class="mode-timeline">
|
||
<div id="pane-timeline">
|
||
<div id="chart-wrap">
|
||
<div id="timeline"></div>
|
||
<div id="col-resizer" title="Потяните, чтобы изменить ширину колонки"></div>
|
||
<div id="empty" style="display:none">Нет данных по выбранным фильтрам</div>
|
||
</div>
|
||
</div>
|
||
<div id="split-resizer" title="Потяните, чтобы изменить пропорции"></div>
|
||
<div id="pane-map">
|
||
<div id="map"></div>
|
||
<div id="map-legend">
|
||
<span class="lg-item"><span class="lg-dot lg-free"></span>свободна сейчас</span>
|
||
<span class="lg-item"><span class="lg-dot lg-busy"></span>занята сейчас</span>
|
||
<span class="lg-item" id="map-counter"></span>
|
||
</div>
|
||
<div id="map-empty" style="display:none">Нет поверхностей с координатами</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="tooltip"></div>
|
||
|
||
<script type="module" src="/src/main.ts"></script>
|
||
</body>
|
||
</html>
|