feat: add versioned multi-component assessment registry

This commit is contained in:
Luftmensch
2026-09-04 10:33:36 +07:00
parent 4f4c7df4ed
commit 9f34cf8afd
9 changed files with 906 additions and 38 deletions
+59 -2
View File
@@ -1309,6 +1309,29 @@
</p>
</div>
<div class="form-group">
<label for="profile_category">2. Loại thành phần đánh giá</label>
<select id="profile_category">
<option value="">Tất cả loại thành phần</option>
</select>
</div>
<div class="form-group">
<label for="profile_component">3. Thành phần</label>
<select id="profile_component">
<option value="">Tất cả thành phần</option>
</select>
</div>
<div class="form-group">
<label for="profile_id">4. Assessment Profile (tùy chọn)</label>
<select id="profile_id" name="profile_id">
<option value="">Dùng profile đang active theo OS tự động</option>
{% for profile in active_profiles %}
<option value="{{ profile.id }}" data-category="{{ profile.category_id }}" data-component="{{ profile.component_id }}">{{ profile.category }} → {{ profile.component }} → {{ profile.name }} ({{ profile.version }})</option>
{% endfor %}
</select>
<p class="hint">Chọn profile cho OS, Database, Web Server, Network Device...; để trống vẫn giữ auto-detect OS tương thích cũ.</p>
</div>
<button type="button" class="btn-submit" id="submitBtn" onclick="handleUploadClick()">
⚡ Xử lý File
</button>
@@ -1453,11 +1476,45 @@
const form = document.getElementById('uploadForm');
const loadingOverlay = document.getElementById('loadingOverlay');
const osSelect = document.getElementById('os_type');
const profileSelect = document.getElementById('profile_id');
const categorySelect = document.getElementById('profile_category');
const componentSelect = document.getElementById('profile_component');
const fileInput = document.getElementById('encrypted_files');
const autoDetectInfo = document.getElementById('autoDetectInfo');
const autoDetectIcon = document.getElementById('autoDetectIcon');
const autoDetectMessage = document.getElementById('autoDetectMessage');
const profileOptions = [...profileSelect.options].filter(option => option.value).map(option => ({
value: option.value,
label: option.textContent,
category: option.dataset.category,
component: option.dataset.component
}));
const categories = [...new Set(profileOptions.map(option => option.category))];
categories.forEach(category => categorySelect.add(new Option(category, category)));
function refreshComponents() {
componentSelect.innerHTML = '<option value="">Tất cả thành phần</option>';
const components = [...new Set(profileOptions
.filter(option => !categorySelect.value || option.category === categorySelect.value)
.map(option => option.component))];
components.forEach(component => componentSelect.add(new Option(component, component)));
refreshProfiles();
}
function refreshProfiles() {
const selected = profileSelect.value;
profileSelect.innerHTML = '<option value="">Dùng profile đang active theo OS tự động</option>';
profileOptions.filter(option =>
(!categorySelect.value || option.category === categorySelect.value) &&
(!componentSelect.value || option.component === componentSelect.value)
).forEach(option => profileSelect.add(new Option(option.label, option.value)));
if ([...profileSelect.options].some(option => option.value === selected)) profileSelect.value = selected;
}
categorySelect.addEventListener('change', refreshComponents);
componentSelect.addEventListener('change', refreshProfiles);
refreshComponents();
// OS name display map (mirrors OS_CONFIG)
const osNames = {
'centos': 'CentOS',
@@ -1522,7 +1579,7 @@
}
// Nếu người dùng đã chọn thủ công một OS trên form chính (không phải auto)
if (osSelect.value !== 'auto') {
if (profileSelect.value || osSelect.value !== 'auto') {
// Trang trung gian 2 luôn (Xử lý ngay)
startGeneratingReport();
return;
@@ -1656,4 +1713,4 @@
</script>
</body>
</html>
</html>