feat: auto-load default xlsx on page open

Dashboard fetches "Функции и вес рекрутинг 2026 (2).xlsx" from the same
directory on load, so opening the page renders the MVP immediately
without requiring a manual upload. Manual upload still works as override.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Askarova A 2026-05-22 13:14:13 +05:00
parent f97af2b749
commit da623a388c
2 changed files with 26 additions and 9 deletions

33
app.js
View File

@ -22,6 +22,8 @@ const state = {
}; };
// === Init === // === Init ===
const DEFAULT_XLSX = './Функции и вес рекрутинг 2026 (2).xlsx';
addEventListener('DOMContentLoaded', () => { addEventListener('DOMContentLoaded', () => {
$('file-input').onchange = onFile; $('file-input').onchange = onFile;
$('group-filter').onchange = e => { state.groupFilter = [...e.target.selectedOptions].map(o => o.value); render(); }; $('group-filter').onchange = e => { state.groupFilter = [...e.target.selectedOptions].map(o => o.value); render(); };
@ -29,22 +31,37 @@ addEventListener('DOMContentLoaded', () => {
$('theme-toggle').onclick = toggleTheme; $('theme-toggle').onclick = toggleTheme;
$('inp-vacancies').oninput = e => { state.vacancies = +e.target.value || 0; render(); }; $('inp-vacancies').oninput = e => { state.vacancies = +e.target.value || 0; render(); };
$('inp-salary').oninput = e => { state.salary = +e.target.value || 0; render(); }; $('inp-salary').oninput = e => { state.salary = +e.target.value || 0; render(); };
autoLoad();
}); });
async function autoLoad() {
try {
const res = await fetch(DEFAULT_XLSX);
if (!res.ok) return;
const buf = await res.arrayBuffer();
loadWorkbook(buf);
} catch (_) { /* fallback: ручная загрузка */ }
}
function loadWorkbook(buf) {
const wb = XLSX.read(buf, { type: 'array' });
const sheet = wb.SheetNames.find(n => n.toLowerCase().includes('функ')) || wb.SheetNames[0];
const rows = XLSX.utils.sheet_to_json(wb.Sheets[sheet], { header: 1, defval: null });
state.items = parseRows(rows);
if (!state.items.length) return;
populateGroups();
showDashboard();
render();
}
// === Excel === // === Excel ===
async function onFile(e) { async function onFile(e) {
const file = e.target.files[0]; const file = e.target.files[0];
if (!file) return; if (!file) return;
try { try {
const buf = await file.arrayBuffer(); const buf = await file.arrayBuffer();
const wb = XLSX.read(buf, { type: 'array' }); loadWorkbook(buf);
const sheet = wb.SheetNames.find(n => n.toLowerCase().includes('функ')) || wb.SheetNames[0]; if (!state.items.length) alert('В файле не найдено функций. Проверьте формат (лист «функции»).');
const rows = XLSX.utils.sheet_to_json(wb.Sheets[sheet], { header: 1, defval: null });
state.items = parseRows(rows);
if (!state.items.length) return alert('В файле не найдено функций. Проверьте формат (лист «функции»).');
populateGroups();
showDashboard();
render();
} catch (err) { } catch (err) {
alert(`Ошибка чтения файла: ${err.message}`); alert(`Ошибка чтения файла: ${err.message}`);
} }

View File

@ -59,7 +59,7 @@
</section> </section>
</main> </main>
<p id="placeholder">Загрузите Excel-файл — дашборд построится автоматически.</p> <p id="placeholder">Загрузка данных… Если дашборд не появился — нажмите «📁 Загрузить .xlsx».</p>
<script src="./app.js"></script> <script src="./app.js"></script>
</body> </body>