mapdash/frontend/index.html
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

157 lines
6.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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: scale + appearance + checkboxes (compact stack) -->
<div class="hgroup hgroup-controls">
<div class="field zoom-field">
<label for="zoom-slider">Масштаб: <span id="zoom-label">12 месяцев</span></label>
<div class="zoom-row">
<input type="range" id="zoom-slider" min="0" max="9" step="1" value="3" />
</div>
</div>
<div class="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>
</div>
<!-- Appearance ("+") button, pinned to the header's bottom-right corner -->
<div class="decor-wrap">
<button type="button" class="decor-btn" id="decor-btn" aria-label="Оформление" data-tip="Оформление">+</button>
<div class="decor-menu" id="decor-menu"></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 id="lg-free">свободна</span></span>
<span class="lg-item"><span class="lg-dot lg-busy"></span><span id="lg-busy">занята</span></span>
<span class="lg-item" id="map-counter"></span>
<button type="button" class="lg-nocoords" id="map-nocoords-btn" style="display:none"></button>
</div>
<div id="map-nocoords-panel" style="display:none"></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>