добавил фильтр по вендорам

This commit is contained in:
Novikova.Yelena 2026-08-19 06:58:43 +00:00
parent c0ac1154d3
commit 7939b5cc05
3 changed files with 64 additions and 7 deletions

View File

@ -26,3 +26,7 @@ up to date in 362ms
up to date in 437ms
Сервер запущен на порту 3000
--- run Wed Aug 19 06:55:48 AM UTC 2026 :: npm start --silent
up to date in 346ms
Сервер запущен на порту 3000

View File

@ -1 +1 @@
2218
2598

View File

@ -49,6 +49,28 @@
background: #fff;
}
.filters input { flex: 1; min-width: 200px; }
.vendor-filter {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
}
.vendor-chip {
padding: 6px 14px;
border-radius: 20px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
background: #f0f0f0;
color: #555;
border: 2px solid transparent;
transition: all 0.2s;
}
.vendor-chip.active {
background: #e3f2fd;
border-color: #1e3c72;
color: #1e3c72;
}
.chip {
display: inline-block;
padding: 6px 14px;
@ -159,7 +181,11 @@
<select id="filter-city"><option value="">Все</option></select>
<label>Уровень:</label>
<div id="filter-levels"></div>
<button class="export-btn" onclick="exportCsv()">📥 Выгрузить в Excel</button>
</div>
<div class="filters" style="padding-top: 10px; padding-bottom: 10px;">
<label>🏷️ Вендоры:</label>
<div class="vendor-filter" id="filter-vendors"></div>
<button class="export-btn" onclick="exportCsv()" style="margin-left: auto;">📥 Выгрузить в Excel</button>
</div>
<div class="charts-row">
@ -199,7 +225,12 @@
</div>
<script>
const allData = [
let allData = [];
let filteredData = [];
let selectedLevels = new Set();
let selectedVendors = new Set();
const allDataRaw = [
{"id": 1, "city": "Астана", "name": "Әжібек Айбек Тұрғанбекұлы", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астана", "vendor": "Cisco", "certificate": "Cisco Certified Network Associate (CCNA)", "level": "Специалист"},
{"id": 2, "city": "Астана", "name": "Абдрахманова Гаухар Нигметовна", "position": "Ведущий инженер службы оперативного контроля 1 уровня г.Астана", "vendor": "Juniper", "certificate": "Juniper Networks Certified Internetwork Associate (JNCIA)", "level": "Специалист"},
{"id": 3, "city": "Алматы", "name": "АБДУГАППАРОВ МАКСАТ КАЛДЫБЕКОВИЧ", "position": "Гл. менеджер СТПСР 3 уровня г.Алматы", "vendor": "Red Hat", "certificate": "Red Hat Certified System Administrator", "level": "Профессионал"},
@ -328,10 +359,10 @@
{"id": 129, "city": "Алматы", "name": "Касымжанов Жарас Жастарович", "position": "Главный менеджер СТПСР 3 г.Алматы", "vendor": "Juniper", "certificate": "Juniper Networks Certified Professional Data Center (JNCIP-DC)", "level": "Профессионал"},
{"id": 130, "city": "Алматы", "name": "Ыдыят Бауыржан Нзамдинұлы", "position": "Старший аналитик службы оперативного контроля 1 уровня г.Алматы", "vendor": "Juniper", "certificate": "Junos, Associate (JNCIA-Junos)", "level": "Специалист"}
];
let filteredData = [...allData];
let selectedLevels = new Set();
function load() {
allData = allDataRaw;
filteredData = [...allData];
initFilters();
render();
}
@ -357,6 +388,16 @@
chip.onclick = () => toggleLevel(l, chip);
levelsContainer.appendChild(chip);
});
const vendors = [...new Set(allData.map(d => d.vendor))].filter(v => v).sort();
const vendorsContainer = document.getElementById('filter-vendors');
vendors.forEach(v => {
const chip = document.createElement('span');
chip.className = 'vendor-chip';
chip.textContent = v;
chip.onclick = () => toggleVendor(v, chip);
vendorsContainer.appendChild(chip);
});
}
function toggleLevel(level, chip) {
@ -370,6 +411,17 @@
applyFilters();
}
function toggleVendor(vendor, chip) {
if (selectedVendors.has(vendor)) {
selectedVendors.delete(vendor);
chip.classList.remove('active');
} else {
selectedVendors.add(vendor);
chip.classList.add('active');
}
applyFilters();
}
function applyFilters() {
const search = document.getElementById('search').value.toLowerCase();
const city = document.getElementById('filter-city').value;
@ -382,7 +434,8 @@
(d.vendor && d.vendor.toLowerCase().includes(search));
const matchCity = !city || d.city === city;
const matchLevel = selectedLevels.size === 0 || selectedLevels.has(d.level);
return matchSearch && matchCity && matchLevel;
const matchVendor = selectedVendors.size === 0 || selectedVendors.has(d.vendor);
return matchSearch && matchCity && matchLevel && matchVendor;
});
render();
}