This repository has been archived on 2026-11-14. You can view files and clone it, but cannot push or open issues or pull requests.
aa/index.html
Askarova A dee9899242 feat: per-function time overrides (no xlsx changes)
Adds a UI block "Ручные правки времени" that lets a user override the
parsed time of a specific function by number, without modifying the xlsx
file. The override propagates through every KPI, chart, simulator, and
FTE scenario via filtered().

The table marks overridden rows with ✏️ and shows the original raw value
struck through. Overrides appear as removable chips below the form.

Also seeds a default override for function №39 ("Контроль табелей") to
60 minutes, because the raw "5до 7 дней" string parses to ~2880 min
(48 h) which is unrealistic for a one-off check and skews every
aggregate. The user can change or remove it from the UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 14:19:29 +05:00

175 lines
7.6 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" data-theme="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Дашборд функций рекрутинга — telecom.quest</title>
<link rel="stylesheet" href="./styles.css">
<script src="https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"></script>
<script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
</head>
<body>
<header>
<img src="./assets/logo.svg" alt="telecom.quest" class="logo">
<h1>Дашборд функций рекрутинга</h1>
<button id="theme-toggle" aria-label="Тема">🌙</button>
</header>
<section class="toolbar">
<label class="btn-primary">
📁 Загрузить .xlsx
<input type="file" id="file-input" accept=".xlsx" hidden>
</label>
<select id="group-filter" multiple size="3" hidden></select>
<input type="search" id="search-input" placeholder="🔍 Поиск функции..." hidden>
</section>
<section class="hero">
<div class="hero-text">
<h2>Аналитика рекрутинга</h2>
<p>Время функций → KPI, нагрузка, узкие места, симулятор «что если». Без сервера: данные парсятся прямо в браузере.</p>
</div>
<img src="./assets/hero.svg" alt="" class="hero-img" loading="lazy">
</section>
<main id="dashboard" hidden>
<section class="block">
<h2>Базовые показатели</h2>
<div id="kpi" class="kpi-grid"></div>
</section>
<section class="block">
<h2>📊 Стратегические KPI</h2>
<div class="inputs">
<label>Вакансий/мес <input type="number" id="inp-vacancies" value="15" min="0"></label>
<label>Ставка ₸/мес <input type="number" id="inp-salary" value="500000" min="0" step="10000"></label>
<label title="Время функций, помеченных 🏢, умножается на это число">
Структурных подразделений (СП)
<input type="number" id="inp-units" value="1" min="1" step="1">
</label>
</div>
<div id="strategic-kpi" class="kpi-grid"></div>
</section>
<section class="block">
<h2>👤 Нагрузка на сотрудника (дни и недели)</h2>
<div id="workload-kpi" class="kpi-grid"></div>
</section>
<section class="block">
<h2>✏️ Ручные правки времени (без изменения xlsx)</h2>
<p class="hint">Заменить минуты конкретной функции по №. Влияет на все KPI и графики. Пусто = убрать правку.</p>
<div class="ovr-form">
<label>№ функции <input type="number" id="ovr-num" min="1" placeholder="например 39"></label>
<label>Время, мин <input type="number" id="ovr-min" min="0" placeholder="например 60"></label>
<button type="button" id="ovr-apply">Применить</button>
<button type="button" id="ovr-clear" class="secondary">Очистить все</button>
</div>
<div id="ovr-list" class="ovr-list"></div>
</section>
<section class="block">
<h2>🧪 Симулятор «что если»</h2>
<p class="hint">Не меняет исходные данные. Покажет, как изменятся KPI при заданных условиях.</p>
<label class="sim-toggle"><input type="checkbox" id="sim-toggle"> Включить симулятор</label>
<div id="sim-controls" class="sim-controls" hidden>
<div class="sim-row">
<label>Оптимизация всех функций: <span id="sim-optimize-val">0%</span>
<input type="range" id="sim-optimize" min="0" max="80" step="5" value="0">
</label>
</div>
<div class="sim-row">
<label>Исключить топ-N длинных функций: <span id="sim-exclude-top-val">0</span>
<input type="range" id="sim-exclude-top" min="0" max="10" step="1" value="0">
</label>
</div>
<div class="sim-row">
<label>Исключить этап (авто-классификатор):
<select id="sim-stage"></select>
</label>
</div>
<div class="sim-row">
<label>Рекрутеров (FTE): <span id="sim-recruiters-val">1</span>
<input type="range" id="sim-recruiters" min="1" max="10" step="1" value="1">
</label>
<label>Вакансий/мес: <span id="sim-vacancies-val">15</span>
<input type="range" id="sim-vacancies" min="0" max="50" step="1" value="15">
</label>
</div>
<button id="sim-reset" type="button">↺ Сбросить</button>
</div>
<div id="sim-output" hidden></div>
</section>
<section class="block">
<h2>📈 Сценарий: FTE % vs число вакансий</h2>
<p class="hint">Зелёный — норма (≤100%), жёлтый — перегруз ≤150%, красный — критично. Пунктир — 100% FTE.</p>
<div id="chart-fte-scenario"></div>
</section>
<section class="charts-row">
<div class="block">
<h2>Топ-10 самых долгих функций</h2>
<div id="chart-top10"></div>
</div>
<div class="block">
<h2>Распределение по группам</h2>
<div id="chart-groups"></div>
</div>
</section>
<section class="block">
<h2>📉 Pareto: накопительный % времени</h2>
<p class="hint">Какие функции дают 80% всей нагрузки. Жёлтая линия — порог 80%.</p>
<div id="chart-pareto"></div>
</section>
<section class="charts-row">
<div class="block">
<h2>📊 Гистограмма длительности</h2>
<div id="chart-histogram"></div>
</div>
<div class="block">
<h2>⏱ Категории функций</h2>
<div id="chart-duration"></div>
</div>
</section>
<section class="block">
<h2>🧭 Авто-этапы (по ключевым словам в названии)</h2>
<p class="hint">Эвристика — не правит данные. Привлечение / Скрининг / Интервью / Оффер / Адаптация / Документы-СПП / Коммуникация.</p>
<div id="chart-stages"></div>
</section>
<section class="block">
<h2>🗺 Treemap: группа → функция (площадь = время)</h2>
<div id="chart-treemap"></div>
</section>
<section class="block">
<h2>Все функции <span class="hint">(клик по заголовку — сортировка)</span></h2>
<table id="table">
<thead><tr>
<th data-col="num">№</th>
<th data-col="name">Функция</th>
<th data-col="rawTime">Исх. время</th>
<th data-col="minutes">Мин</th>
<th data-col="stage">Этап</th>
<th data-col="group">Группа</th>
</tr></thead>
<tbody></tbody>
</table>
</section>
</main>
<div id="placeholder">
<img src="./assets/empty.svg" alt="" loading="lazy">
<p>Загрузка данных… Если дашборд не появился — нажмите «📁 Загрузить .xlsx».</p>
</div>
<script src="./app.js?v=9"></script>
</body>
</html>