{% extends "base.html" %} {% block title %}Audyt IT - {{ company.name }} - Norda Biznes Partner{% endblock %} {% block extra_css %} {% endblock %} {% block content %}

Audyt Infrastruktury IT

{{ company.name }}

Formularz oceny infrastruktury IT i gotowosci do wspolpracy
Profil firmy
Postep wypelniania formularza 0%
1
2
3
4
5
6
7
8
9
1
Kontakt IT
Informacje o osobie odpowiedzialnej za IT w firmie
Nie
Nie
Nazwa firmy zewnetrznej obslugujaca IT
Adres email do spraw technicznych
2
Chmura i Tozsamosc
Uslugi chmurowe, Azure AD, Microsoft 365, Google Workspace
3
Infrastruktura Serwerowa
Serwery fizyczne i wirtualne, platformy wirtualizacji, systemy operacyjne
Formularz mozna zapisac w dowolnym momencie. Postep zostanie zachowany.

Zapisywanie audytu...

Prosze czekac, dane sa przetwarzane.

{% endblock %} {% block extra_js %} const csrfToken = '{{ csrf_token() }}'; const companyId = {{ company.id }}; // Track selected values for chip selects const chipSelections = { m365Plans: [], teamsUsage: [], serverTypes: [], serverOs: [], endpointTypes: [], endpointOs: [], mfaMethods: [], mfaScope: [], securityMeasures: [], backupTargets: [], backupStorage: [], monitoringTargets: [], alertingMethods: [], otherBusinessApps: [], integrationMethods: [] }; // Toggle switch functionality function toggleSwitch(fieldId) { const toggle = document.getElementById('toggle' + fieldId.charAt(0).toUpperCase() + fieldId.slice(1)); const input = document.getElementById(fieldId); const label = document.getElementById('label' + fieldId.charAt(0).toUpperCase() + fieldId.slice(1)); const isActive = toggle.classList.toggle('active'); input.value = isActive ? 'true' : 'false'; label.textContent = isActive ? 'Tak' : 'Nie'; // Handle conditional fields visibility handleConditionalFields(fieldId, isActive); updateProgress(); } // Handle conditional fields visibility function handleConditionalFields(fieldId, isActive) { const conditionalMappings = { 'itOutsourced': ['itProviderFields'], 'hasAzureAd': ['azureAdFields', 'azureUserCountField'], 'hasM365': ['m365PlansField', 'teamsUsageField'], 'hasLocalAd': ['localAdFields', 'adSyncField'], 'hasMdm': ['mdmSolutionField'], 'hasVpn': ['vpnSolutionField'], 'hasMfa': ['mfaMethodsField'], 'hasBackup': ['backupSolutionField', 'backupTargetsField', 'backupFrequencyField', 'backupStorageField', 'backupRetentionField'], 'hasDrPlan': ['rtoField', 'rpoField'], 'hasMonitoring': ['monitoringSolutionField', 'monitoringTargetsField', 'alertingMethodsField'], 'hasCentralLogging': ['loggingSolutionField'], 'hasTicketSystem': ['ticketSystemField'] }; const fieldsToToggle = conditionalMappings[fieldId]; if (fieldsToToggle) { fieldsToToggle.forEach(fieldGroupId => { const fieldGroup = document.getElementById(fieldGroupId); if (fieldGroup) { if (isActive) { fieldGroup.classList.remove('hidden'); } else { fieldGroup.classList.add('hidden'); } } }); } } // Toggle chip selection function toggleChip(element, fieldId) { const value = element.dataset.value; const isSelected = element.classList.toggle('selected'); if (isSelected) { if (!chipSelections[fieldId].includes(value)) { chipSelections[fieldId].push(value); } } else { chipSelections[fieldId] = chipSelections[fieldId].filter(v => v !== value); } // Update hidden input document.getElementById(fieldId).value = chipSelections[fieldId].join(','); updateProgress(); } // Toggle section visibility function toggleSection(sectionNum) { const header = document.querySelector(`.form-section[data-section="${sectionNum}"] .section-header`); const content = document.getElementById('sectionContent' + sectionNum); if (content) { header.classList.toggle('collapsed'); content.classList.toggle('collapsed'); } // Update progress dots updateProgressDots(sectionNum); } // Update progress dots when navigating sections function updateProgressDots(activeSectionNum) { document.querySelectorAll('.progress-section-dot').forEach(dot => { const section = parseInt(dot.dataset.section); if (section === activeSectionNum) { dot.classList.add('active'); } }); } // Calculate and update form progress function updateProgress() { const totalSections = 9; let completedSections = 0; let totalFields = 0; let filledFields = 0; // Calculate completion for each section for (let sectionNum = 1; sectionNum <= totalSections; sectionNum++) { const section = document.querySelector(`.form-section[data-section="${sectionNum}"]`); if (!section) continue; const sectionContent = document.getElementById('sectionContent' + sectionNum); if (!sectionContent) continue; const sectionResult = calculateSectionCompletion(sectionContent, sectionNum); totalFields += sectionResult.total; filledFields += sectionResult.filled; // Update section number badge and progress dot const sectionNumber = document.getElementById('sectionNumber' + sectionNum); const progressDot = document.querySelector(`.progress-section-dot[data-section="${sectionNum}"]`); if (sectionResult.isComplete) { completedSections++; if (sectionNumber) sectionNumber.classList.add('complete'); if (progressDot) { progressDot.classList.add('complete'); } } else { if (sectionNumber) sectionNumber.classList.remove('complete'); if (progressDot) { progressDot.classList.remove('complete'); } } } // Calculate overall percentage const percentage = totalFields > 0 ? Math.round((filledFields / totalFields) * 100) : 0; // Update progress bar const progressPercentage = document.getElementById('progressPercentage'); const progressFill = document.getElementById('progressFill'); if (progressPercentage) progressPercentage.textContent = percentage + '%'; if (progressFill) progressFill.style.width = percentage + '%'; // Update progress bar color based on completion if (progressFill) { if (percentage >= 80) { progressFill.style.background = 'var(--success)'; } else if (percentage >= 50) { progressFill.style.background = 'var(--warning)'; } else { progressFill.style.background = 'var(--primary)'; } } } // Calculate completion for a single section function calculateSectionCompletion(sectionContent, sectionNum) { let totalFields = 0; let filledFields = 0; // Count visible toggle switches in this section const toggles = sectionContent.querySelectorAll('.toggle-switch'); toggles.forEach(toggle => { const parent = toggle.closest('.form-group'); if (parent && !parent.classList.contains('hidden')) { totalFields++; if (toggle.classList.contains('active')) { filledFields++; } } }); // Count visible select fields const selects = sectionContent.querySelectorAll('select'); selects.forEach(select => { const parent = select.closest('.form-group'); const conditionalParent = select.closest('.conditional-fields'); // Check if field is visible (not in hidden conditional fields) if (conditionalParent && conditionalParent.classList.contains('hidden')) { return; } if (parent && parent.classList.contains('hidden')) { return; } totalFields++; if (select.value && select.value.trim() !== '') { filledFields++; } }); // Count visible text/email inputs const textInputs = sectionContent.querySelectorAll('input[type="text"], input[type="email"]'); textInputs.forEach(input => { const parent = input.closest('.form-group'); const conditionalParent = input.closest('.conditional-fields'); // Check if field is visible if (conditionalParent && conditionalParent.classList.contains('hidden')) { return; } if (parent && parent.classList.contains('hidden')) { return; } totalFields++; if (input.value && input.value.trim() !== '') { filledFields++; } }); // Count visible checkbox groups const checkboxes = sectionContent.querySelectorAll('input[type="checkbox"]'); checkboxes.forEach(checkbox => { const parent = checkbox.closest('.form-group'); if (parent && !parent.classList.contains('hidden')) { totalFields++; if (checkbox.checked) { filledFields++; } } }); // Count chip selections for this section const chipSelects = sectionContent.querySelectorAll('.chip-select'); chipSelects.forEach(chipSelect => { const parent = chipSelect.closest('.form-group'); const conditionalParent = chipSelect.closest('.conditional-fields'); // Check if chip select is visible if (conditionalParent && conditionalParent.classList.contains('hidden')) { return; } if (parent && parent.classList.contains('hidden')) { return; } totalFields++; const selectedChips = chipSelect.querySelectorAll('.chip-option.selected'); if (selectedChips.length > 0) { filledFields++; } }); // Count textareas const textareas = sectionContent.querySelectorAll('textarea'); textareas.forEach(textarea => { const parent = textarea.closest('.form-group'); const conditionalParent = textarea.closest('.conditional-fields'); if (conditionalParent && conditionalParent.classList.contains('hidden')) { return; } if (parent && parent.classList.contains('hidden')) { return; } totalFields++; if (textarea.value && textarea.value.trim() !== '') { filledFields++; } }); // Section is complete if at least 70% of visible fields are filled // or all fields are filled, whichever makes more sense const isComplete = totalFields > 0 && filledFields >= Math.ceil(totalFields * 0.7); return { total: totalFields, filled: filledFields, isComplete: isComplete }; } // Update section progress indicator when navigating function updateSectionProgress(sectionNum) { const sectionContent = document.getElementById('sectionContent' + sectionNum); if (!sectionContent) return; const result = calculateSectionCompletion(sectionContent, sectionNum); const progressDot = document.querySelector(`.progress-section-dot[data-section="${sectionNum}"]`); const sectionNumber = document.getElementById('sectionNumber' + sectionNum); if (result.isComplete) { if (progressDot) progressDot.classList.add('complete'); if (sectionNumber) sectionNumber.classList.add('complete'); } else { if (progressDot) progressDot.classList.remove('complete'); if (sectionNumber) sectionNumber.classList.remove('complete'); } } // Save draft function saveDraft() { const form = document.getElementById('itAuditForm'); const formData = new FormData(form); formData.append('is_draft', 'true'); showLoading(); fetch(form.action, { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { hideLoading(); if (data.success) { showInfoModal('Zapisano', 'Wersja robocza audytu zostala zapisana.', true); } else { showInfoModal('Blad', data.error || 'Nie udalo sie zapisac wersji roboczej.', false); } }) .catch(error => { hideLoading(); showInfoModal('Blad polaczenia', 'Nie udalo sie polaczyc z serwerem: ' + error.message, false); }); } // Form submission document.getElementById('itAuditForm').addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); showLoading(); fetch(this.action, { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { hideLoading(); if (data.success) { showInfoModal('Audyt zapisany', 'Audyt IT zostal zapisany pomyslnie. Za chwile zostaniesz przekierowany.', true); setTimeout(() => { window.location.href = data.redirect_url || '/company/' + companyId; }, 1500); } else { showInfoModal('Blad', data.error || 'Nie udalo sie zapisac audytu.', false); } }) .catch(error => { hideLoading(); showInfoModal('Blad polaczenia', 'Nie udalo sie polaczyc z serwerem: ' + error.message, false); }); }); // Loading overlay function showLoading() { document.getElementById('loadingOverlay').classList.add('active'); } function hideLoading() { document.getElementById('loadingOverlay').classList.remove('active'); } // Info modal function showInfoModal(title, body, isSuccess) { document.getElementById('modalTitle').textContent = title; document.getElementById('modalBody').textContent = body; const icon = document.getElementById('modalIcon'); icon.className = 'modal-icon ' + (isSuccess ? 'success' : 'error'); document.getElementById('infoModal').classList.add('active'); } function closeInfoModal() { document.getElementById('infoModal').classList.remove('active'); } // Close modal on outside click document.getElementById('infoModal')?.addEventListener('click', (e) => { if (e.target.id === 'infoModal') closeInfoModal(); }); // Initialize form with existing data if editing {% if audit %} function initializeForm() { // Initialize toggle switches - Section 1 (IT Contact) {% if audit.has_it_manager %} toggleSwitch('hasItManager'); {% endif %} {% if audit.it_outsourced %} toggleSwitch('itOutsourced'); {% endif %} // Section 2 (Cloud & Identity) {% if audit.has_azure_ad %} toggleSwitch('hasAzureAd'); {% endif %} {% if audit.has_m365 %} toggleSwitch('hasM365'); {% endif %} {% if audit.has_google_workspace %} toggleSwitch('hasGoogleWorkspace'); {% endif %} {% if audit.has_local_ad %} toggleSwitch('hasLocalAd'); {% endif %} {% if audit.has_ad_azure_sync %} toggleSwitch('hasAdAzureSync'); {% endif %} // Section 4 (Endpoints) {% if audit.has_mdm %} toggleSwitch('hasMdm'); {% endif %} {% if audit.has_central_management %} toggleSwitch('hasCentralManagement'); {% endif %} // Section 5 (Security) {% if audit.has_vpn %} toggleSwitch('hasVpn'); {% endif %} {% if audit.has_mfa %} toggleSwitch('hasMfa'); {% endif %} {% if audit.has_cyber_insurance %} toggleSwitch('hasCyberInsurance'); {% endif %} // Section 6 (Backup & DR) {% if audit.has_backup %} toggleSwitch('hasBackup'); {% endif %} {% if audit.has_dr_plan %} toggleSwitch('hasDrPlan'); {% endif %} {% if audit.has_dr_site %} toggleSwitch('hasDrSite'); {% endif %} // Section 7 (Monitoring) {% if audit.has_monitoring %} toggleSwitch('hasMonitoring'); {% endif %} {% if audit.has_central_logging %} toggleSwitch('hasCentralLogging'); {% endif %} {% if audit.has_zabbix %} toggleSwitch('hasZabbix'); {% endif %} {% if audit.has_proxmox_pbs %} toggleSwitch('hasProxmoxPbs'); {% endif %} // Section 8 (Business Apps) {% if audit.has_ticket_system %} toggleSwitch('hasTicketSystem'); {% endif %} // Section 9 (Collaboration) - checkboxes {% if audit.open_to_shared_licensing %} document.getElementById('openToSharedLicensing').checked = true; {% endif %} {% if audit.open_to_backup_replication %} document.getElementById('openToBackupReplication').checked = true; {% endif %} {% if audit.open_to_teams_federation %} document.getElementById('openToTeamsFederation').checked = true; {% endif %} {% if audit.open_to_shared_monitoring %} document.getElementById('openToSharedMonitoring').checked = true; {% endif %} {% if audit.open_to_collective_purchasing %} document.getElementById('openToCollectivePurchasing').checked = true; {% endif %} {% if audit.open_to_knowledge_sharing %} document.getElementById('openToKnowledgeSharing').checked = true; {% endif %} // Initialize chip selections - Section 2 {% if audit.m365_plans %} '{{ audit.m365_plans | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#m365PlansChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'm365Plans'); }); {% endif %} {% if audit.teams_usage %} '{{ audit.teams_usage | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#teamsUsageChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'teamsUsage'); }); {% endif %} // Section 3 (Servers) {% if audit.server_types %} '{{ audit.server_types | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#serverTypesChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'serverTypes'); }); {% endif %} {% if audit.server_os %} '{{ audit.server_os | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#serverOsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'serverOs'); }); {% endif %} // Section 4 (Endpoints) {% if audit.endpoint_types %} '{{ audit.endpoint_types | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#endpointTypesChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'endpointTypes'); }); {% endif %} {% if audit.endpoint_os %} '{{ audit.endpoint_os | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#endpointOsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'endpointOs'); }); {% endif %} // Section 5 (Security) {% if audit.mfa_methods %} '{{ audit.mfa_methods | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#mfaMethodsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'mfaMethods'); }); {% endif %} {% if audit.mfa_scope %} '{{ audit.mfa_scope | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#mfaScopeChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'mfaScope'); }); {% endif %} {% if audit.security_measures %} '{{ audit.security_measures | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#securityMeasuresChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'securityMeasures'); }); {% endif %} // Section 6 (Backup & DR) {% if audit.backup_targets %} '{{ audit.backup_targets | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#backupTargetsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'backupTargets'); }); {% endif %} {% if audit.backup_storage %} '{{ audit.backup_storage | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#backupStorageChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'backupStorage'); }); {% endif %} // Section 7 (Monitoring) {% if audit.monitoring_targets %} '{{ audit.monitoring_targets | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#monitoringTargetsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'monitoringTargets'); }); {% endif %} {% if audit.alerting_methods %} '{{ audit.alerting_methods | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#alertingMethodsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'alertingMethods'); }); {% endif %} // Section 8 (Business Apps) {% if audit.other_business_apps %} '{{ audit.other_business_apps | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#otherBusinessAppsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'otherBusinessApps'); }); {% endif %} {% if audit.integration_methods %} '{{ audit.integration_methods | join(",") }}'.split(',').forEach(value => { const chip = document.querySelector('#integrationMethodsChips .chip-option[data-value="' + value + '"]'); if (chip) toggleChip(chip, 'integrationMethods'); }); {% endif %} // Initialize select dropdowns with existing audit values {% if audit.azure_user_count %} document.getElementById('azureUserCount').value = '{{ audit.azure_user_count }}'; {% endif %} {% if audit.server_count %} document.getElementById('serverCount').value = '{{ audit.server_count }}'; {% endif %} {% if audit.virtualization_platform %} document.getElementById('virtualizationPlatform').value = '{{ audit.virtualization_platform }}'; {% endif %} {% if audit.server_os %} document.getElementById('serverOs').value = '{{ audit.server_os }}'; {% endif %} {% if audit.workstation_count %} document.getElementById('workstationCount').value = '{{ audit.workstation_count }}'; {% endif %} {% if audit.workstation_os %} document.getElementById('workstationOs').value = '{{ audit.workstation_os }}'; {% endif %} {% if audit.security_tools %} document.getElementById('securityTools').value = '{{ audit.security_tools }}'; {% endif %} {% if audit.backup_schedule %} document.getElementById('backupSchedule').value = '{{ audit.backup_schedule }}'; {% endif %} {% if audit.backup_retention %} document.getElementById('backupRetention').value = '{{ audit.backup_retention }}'; {% endif %} {% if audit.backup_location %} document.getElementById('backupLocation').value = '{{ audit.backup_location }}'; {% endif %} {% if audit.disaster_recovery %} document.getElementById('disasterRecovery').value = '{{ audit.disaster_recovery }}'; {% endif %} {% if audit.internet_connection %} document.getElementById('internetConnection').value = '{{ audit.internet_connection }}'; {% endif %} {% if audit.network_type %} document.getElementById('networkType').value = '{{ audit.network_type }}'; {% endif %} {% if audit.vpn_type %} document.getElementById('vpnType').value = '{{ audit.vpn_type }}'; {% endif %} {% if audit.firewall_type %} document.getElementById('firewallType').value = '{{ audit.firewall_type }}'; {% endif %} {% if audit.email_provider %} document.getElementById('emailProvider').value = '{{ audit.email_provider }}'; {% endif %} {% if audit.email_security %} document.getElementById('emailSecurity').value = '{{ audit.email_security }}'; {% endif %} {% if audit.collab_platform %} document.getElementById('collabPlatform').value = '{{ audit.collab_platform }}'; {% endif %} {% if audit.video_conferencing %} document.getElementById('videoConferencing').value = '{{ audit.video_conferencing }}'; {% endif %} {% if audit.crm_system %} document.getElementById('crmSystem').value = '{{ audit.crm_system }}'; {% endif %} {% if audit.erp_system %} document.getElementById('erpSystem').value = '{{ audit.erp_system }}'; {% endif %} {% if audit.accounting_software %} document.getElementById('accountingSoftware').value = '{{ audit.accounting_software }}'; {% endif %} {% if audit.dms_system %} document.getElementById('dmsSystem').value = '{{ audit.dms_system }}'; {% endif %} updateProgress(); } document.addEventListener('DOMContentLoaded', initializeForm); {% else %} document.addEventListener('DOMContentLoaded', updateProgress); {% endif %} // Navigation via progress dots document.querySelectorAll('.progress-section-dot').forEach(dot => { dot.addEventListener('click', () => { const sectionNum = parseInt(dot.dataset.section); // Close all sections document.querySelectorAll('.section-content').forEach(content => { content.classList.add('collapsed'); }); document.querySelectorAll('.section-header').forEach(header => { header.classList.add('collapsed'); }); // Open target section const targetContent = document.getElementById('sectionContent' + sectionNum); const targetHeader = document.querySelector(`.form-section[data-section="${sectionNum}"] .section-header`); if (targetContent) { targetContent.classList.remove('collapsed'); targetHeader?.classList.remove('collapsed'); // Scroll to section document.querySelector(`.form-section[data-section="${sectionNum}"]`).scrollIntoView({ behavior: 'smooth', block: 'start' }); } // Update active dot document.querySelectorAll('.progress-section-dot').forEach(d => d.classList.remove('active')); dot.classList.add('active'); }); }); // Real-time progress tracking for form inputs document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('itAuditForm'); if (!form) return; // Add change listeners for select elements form.querySelectorAll('select').forEach(select => { select.addEventListener('change', updateProgress); }); // Add input listeners for text and email fields with debounce let debounceTimer; form.querySelectorAll('input[type="text"], input[type="email"]').forEach(input => { input.addEventListener('input', () => { clearTimeout(debounceTimer); debounceTimer = setTimeout(updateProgress, 300); }); }); // Add change listeners for checkboxes form.querySelectorAll('input[type="checkbox"]').forEach(checkbox => { checkbox.addEventListener('change', updateProgress); }); // Add input listeners for textareas with debounce form.querySelectorAll('textarea').forEach(textarea => { textarea.addEventListener('input', () => { clearTimeout(debounceTimer); debounceTimer = setTimeout(updateProgress, 300); }); }); }); // Keyboard navigation support for progress dots document.querySelectorAll('.progress-section-dot').forEach(dot => { dot.setAttribute('tabindex', '0'); dot.setAttribute('role', 'button'); dot.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); dot.click(); } }); }); {% endblock %}