- Add value attribute to 5 text input fields (it_provider_name, it_contact_name, it_contact_email, azure_tenant_name, ad_domain_name) - Add content to collaboration_notes textarea - Add JavaScript initialization for 23 select dropdowns in initializeForm() This ensures that when editing an existing IT Audit, all previously entered values are displayed in the form instead of showing empty fields with placeholders. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2708 lines
127 KiB
HTML
2708 lines
127 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Audyt IT - {{ company.name }} - Norda Biznes Hub{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.audit-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
margin-bottom: var(--spacing-xl);
|
|
flex-wrap: wrap;
|
|
gap: var(--spacing-md);
|
|
}
|
|
|
|
.audit-header-info h1 {
|
|
font-size: var(--font-size-2xl);
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
|
|
.audit-header-info p {
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.data-source-info {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
margin-top: var(--spacing-sm);
|
|
padding: var(--spacing-xs) var(--spacing-sm);
|
|
background: var(--info-light, #e0f2fe);
|
|
border-radius: var(--radius);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--info, #0284c7);
|
|
}
|
|
|
|
.data-source-info svg {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.header-actions {
|
|
display: flex;
|
|
gap: var(--spacing-sm);
|
|
align-items: center;
|
|
}
|
|
|
|
/* Progress Bar */
|
|
.progress-container {
|
|
background: var(--surface);
|
|
padding: var(--spacing-md);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-sm);
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.progress-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: var(--spacing-sm);
|
|
}
|
|
|
|
.progress-title {
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.progress-percentage {
|
|
font-size: var(--font-size-lg);
|
|
font-weight: 700;
|
|
color: var(--primary);
|
|
}
|
|
|
|
.progress-bar {
|
|
height: 8px;
|
|
background: var(--border);
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.progress-fill {
|
|
height: 100%;
|
|
background: var(--primary);
|
|
border-radius: 4px;
|
|
transition: width 0.3s ease;
|
|
}
|
|
|
|
.progress-sections {
|
|
display: flex;
|
|
gap: var(--spacing-xs);
|
|
margin-top: var(--spacing-sm);
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.progress-section-dot {
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 50%;
|
|
background: var(--border);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: var(--font-size-xs);
|
|
font-weight: 600;
|
|
color: var(--text-tertiary);
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.progress-section-dot.active {
|
|
background: var(--primary);
|
|
color: white;
|
|
}
|
|
|
|
.progress-section-dot.complete {
|
|
background: var(--success);
|
|
color: white;
|
|
}
|
|
|
|
.progress-section-dot:hover {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
/* Form Sections */
|
|
.form-section {
|
|
background: var(--surface);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
margin-bottom: var(--spacing-xl);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.section-header {
|
|
background: var(--bg-secondary);
|
|
padding: var(--spacing-md) var(--spacing-lg);
|
|
border-bottom: 1px solid var(--border);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-md);
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.section-header:hover {
|
|
background: var(--bg-tertiary);
|
|
}
|
|
|
|
.section-number {
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
background: var(--primary);
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: 700;
|
|
font-size: var(--font-size-sm);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.section-number.complete {
|
|
background: var(--success);
|
|
}
|
|
|
|
.section-title-group {
|
|
flex: 1;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: var(--font-size-lg);
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
|
|
.section-subtitle {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.section-toggle {
|
|
width: 24px;
|
|
height: 24px;
|
|
color: var(--text-secondary);
|
|
transition: transform 0.2s ease;
|
|
}
|
|
|
|
.section-header.collapsed .section-toggle {
|
|
transform: rotate(-90deg);
|
|
}
|
|
|
|
.section-content {
|
|
padding: var(--spacing-lg);
|
|
}
|
|
|
|
.section-content.collapsed {
|
|
display: none;
|
|
}
|
|
|
|
/* Form Fields */
|
|
.form-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
gap: var(--spacing-lg);
|
|
}
|
|
|
|
.form-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-xs);
|
|
}
|
|
|
|
.form-group.full-width {
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
.form-label {
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
font-size: var(--font-size-sm);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
}
|
|
|
|
.form-label .required {
|
|
color: var(--error);
|
|
}
|
|
|
|
.form-label .help-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
color: var(--text-tertiary);
|
|
cursor: help;
|
|
}
|
|
|
|
.form-input,
|
|
.form-select,
|
|
.form-textarea {
|
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-primary);
|
|
background: var(--surface);
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.form-input:focus,
|
|
.form-select:focus,
|
|
.form-textarea:focus {
|
|
outline: none;
|
|
border-color: var(--primary);
|
|
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
|
|
}
|
|
|
|
.form-select {
|
|
cursor: pointer;
|
|
appearance: none;
|
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
|
|
background-position: right 0.5rem center;
|
|
background-repeat: no-repeat;
|
|
background-size: 1.5em 1.5em;
|
|
padding-right: 2.5rem;
|
|
}
|
|
|
|
.form-hint {
|
|
font-size: var(--font-size-xs);
|
|
color: var(--text-tertiary);
|
|
}
|
|
|
|
/* Checkbox and Toggle */
|
|
.form-checkbox-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
|
|
.form-checkbox {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.form-checkbox input[type="checkbox"] {
|
|
width: 18px;
|
|
height: 18px;
|
|
accent-color: var(--primary);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.form-checkbox-label {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.form-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-md);
|
|
padding: var(--spacing-sm);
|
|
background: var(--bg-secondary);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
.toggle-switch {
|
|
position: relative;
|
|
width: 48px;
|
|
height: 24px;
|
|
background: var(--border);
|
|
border-radius: 12px;
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.toggle-switch.active {
|
|
background: var(--success);
|
|
}
|
|
|
|
.toggle-switch::after {
|
|
content: '';
|
|
position: absolute;
|
|
width: 20px;
|
|
height: 20px;
|
|
background: white;
|
|
border-radius: 50%;
|
|
top: 2px;
|
|
left: 2px;
|
|
transition: var(--transition);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
|
|
.toggle-switch.active::after {
|
|
left: 26px;
|
|
}
|
|
|
|
.toggle-label {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
/* Conditional Fields */
|
|
.conditional-fields {
|
|
margin-top: var(--spacing-md);
|
|
padding: var(--spacing-md);
|
|
background: var(--bg-secondary);
|
|
border-radius: var(--radius);
|
|
border-left: 3px solid var(--primary);
|
|
}
|
|
|
|
.conditional-fields.hidden {
|
|
display: none;
|
|
}
|
|
|
|
/* Multi-select chips */
|
|
.chip-select {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
|
|
.chip-option {
|
|
padding: var(--spacing-xs) var(--spacing-md);
|
|
background: var(--bg-secondary);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-full);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.chip-option:hover {
|
|
border-color: var(--primary);
|
|
color: var(--primary);
|
|
}
|
|
|
|
.chip-option.selected {
|
|
background: var(--primary);
|
|
border-color: var(--primary);
|
|
color: white;
|
|
}
|
|
|
|
/* Form Actions */
|
|
.form-actions {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: var(--spacing-lg);
|
|
background: var(--surface);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
margin-top: var(--spacing-xl);
|
|
flex-wrap: wrap;
|
|
gap: var(--spacing-md);
|
|
}
|
|
|
|
.form-actions-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.form-actions-right {
|
|
display: flex;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
|
|
/* Breadcrumb */
|
|
.breadcrumb {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
margin-bottom: var(--spacing-md);
|
|
}
|
|
|
|
.breadcrumb a {
|
|
color: var(--primary);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.breadcrumb a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.breadcrumb-separator {
|
|
color: var(--border);
|
|
}
|
|
|
|
/* Loading Overlay */
|
|
.loading-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(255, 255, 255, 0.95);
|
|
z-index: 1000;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
gap: var(--spacing-lg);
|
|
}
|
|
|
|
.loading-overlay.active {
|
|
display: flex;
|
|
}
|
|
|
|
.loading-content {
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-lg);
|
|
max-width: 400px;
|
|
width: 90%;
|
|
text-align: center;
|
|
}
|
|
|
|
.loading-spinner {
|
|
width: 48px;
|
|
height: 48px;
|
|
border: 4px solid var(--border);
|
|
border-top-color: var(--primary);
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
margin: 0 auto var(--spacing-md);
|
|
}
|
|
|
|
@keyframes spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* Modal */
|
|
.modal {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
z-index: 1000;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.modal.active {
|
|
display: flex;
|
|
}
|
|
|
|
.modal-content {
|
|
background: var(--surface);
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
max-width: 480px;
|
|
width: 90%;
|
|
box-shadow: var(--shadow-lg);
|
|
animation: modalSlideIn 0.2s ease-out;
|
|
}
|
|
|
|
@keyframes modalSlideIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.modal-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-md);
|
|
margin-bottom: var(--spacing-md);
|
|
}
|
|
|
|
.modal-icon {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.modal-icon.success { background: #dcfce7; color: #16a34a; }
|
|
.modal-icon.info { background: #dbeafe; color: #2563eb; }
|
|
.modal-icon.warning { background: #fef3c7; color: #d97706; }
|
|
.modal-icon.error { background: #fee2e2; color: #dc2626; }
|
|
|
|
.modal-title {
|
|
font-size: var(--font-size-xl);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.modal-body {
|
|
color: var(--text-secondary);
|
|
margin-bottom: var(--spacing-lg);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.modal-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
|
|
/* Section icons */
|
|
.section-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 768px) {
|
|
.audit-header {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.header-actions {
|
|
width: 100%;
|
|
justify-content: center;
|
|
}
|
|
|
|
.form-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.form-actions {
|
|
flex-direction: column;
|
|
text-align: center;
|
|
}
|
|
|
|
.form-actions-left,
|
|
.form-actions-right {
|
|
width: 100%;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- Breadcrumb -->
|
|
<div class="breadcrumb">
|
|
<a href="{{ url_for('index') }}">Firmy</a>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<a href="{{ url_for('company_detail', company_id=company.id) }}">{{ company.name }}</a>
|
|
<span class="breadcrumb-separator">/</span>
|
|
<span>Audyt IT</span>
|
|
</div>
|
|
|
|
<div class="audit-header">
|
|
<div class="audit-header-info">
|
|
<h1>Audyt Infrastruktury IT</h1>
|
|
<p>{{ company.name }}</p>
|
|
<div class="data-source-info">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"/>
|
|
</svg>
|
|
<span>Formularz oceny infrastruktury IT i gotowosci do wspolpracy</span>
|
|
</div>
|
|
</div>
|
|
<div class="header-actions">
|
|
<a href="{{ url_for('company_detail', company_id=company.id) }}" class="btn btn-outline btn-sm">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
|
|
</svg>
|
|
Profil firmy
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Bar -->
|
|
<div class="progress-container">
|
|
<div class="progress-header">
|
|
<span class="progress-title">Postep wypelniania formularza</span>
|
|
<span class="progress-percentage" id="progressPercentage">0%</span>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div class="progress-fill" id="progressFill" style="width: 0%;"></div>
|
|
</div>
|
|
<div class="progress-sections">
|
|
<div class="progress-section-dot active" data-section="1" title="Kontakt IT">1</div>
|
|
<div class="progress-section-dot" data-section="2" title="Chmura i Tozsamosc">2</div>
|
|
<div class="progress-section-dot" data-section="3" title="Infrastruktura Serwerowa">3</div>
|
|
<div class="progress-section-dot" data-section="4" title="Stacje Robocze">4</div>
|
|
<div class="progress-section-dot" data-section="5" title="Bezpieczenstwo">5</div>
|
|
<div class="progress-section-dot" data-section="6" title="Backup i DR">6</div>
|
|
<div class="progress-section-dot" data-section="7" title="Monitoring">7</div>
|
|
<div class="progress-section-dot" data-section="8" title="Aplikacje Biznesowe">8</div>
|
|
<div class="progress-section-dot" data-section="9" title="Wspolpraca">9</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="itAuditForm" method="POST" action="{{ url_for('it_audit_save') }}">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" name="company_id" value="{{ company.id }}">
|
|
|
|
<!-- Section 1: IT Contact -->
|
|
<div class="form-section" data-section="1">
|
|
<div class="section-header" onclick="toggleSection(1)">
|
|
<div class="section-number" id="sectionNumber1">1</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
|
</svg>
|
|
Kontakt IT
|
|
</div>
|
|
<div class="section-subtitle">Informacje o osobie odpowiedzialnej za IT w firmie</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content" id="sectionContent1">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma wewnetrznego menedzera IT?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasItManager" onclick="toggleSwitch('hasItManager')"></div>
|
|
<span class="toggle-label" id="labelHasItManager">Nie</span>
|
|
<input type="hidden" name="has_it_manager" id="hasItManager" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy IT jest outsourcowane?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleItOutsourced" onclick="toggleSwitch('itOutsourced')"></div>
|
|
<span class="toggle-label" id="labelItOutsourced">Nie</span>
|
|
<input type="hidden" name="it_outsourced" id="itOutsourced" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields" id="itProviderFields">
|
|
<label class="form-label">
|
|
Nazwa dostawcy uslug IT
|
|
</label>
|
|
<input type="text" class="form-input" name="it_provider_name" id="itProviderName" value="{{ audit.it_provider_name if audit and audit.it_provider_name else '' }}" placeholder="np. INPI, Comarch, IT Partner">
|
|
<span class="form-hint">Nazwa firmy zewnetrznej obslugujaca IT</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Imie i nazwisko osoby kontaktowej ds. IT
|
|
</label>
|
|
<input type="text" class="form-input" name="it_contact_name" id="itContactName" value="{{ audit.it_contact_name if audit and audit.it_contact_name else '' }}" placeholder="np. Jan Kowalski">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Email kontaktowy IT
|
|
</label>
|
|
<input type="email" class="form-input" name="it_contact_email" id="itContactEmail" value="{{ audit.it_contact_email if audit and audit.it_contact_email else '' }}" placeholder="it@firma.pl">
|
|
<span class="form-hint">Adres email do spraw technicznych</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 2: Cloud & Identity -->
|
|
<div class="form-section" data-section="2">
|
|
<div class="section-header" onclick="toggleSection(2)">
|
|
<div class="section-number" id="sectionNumber2">2</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z"/>
|
|
</svg>
|
|
Chmura i Tozsamosc
|
|
</div>
|
|
<div class="section-subtitle">Uslugi chmurowe, Azure AD, Microsoft 365, Google Workspace</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent2">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z Azure Active Directory (Entra ID)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasAzureAd" onclick="toggleSwitch('hasAzureAd')"></div>
|
|
<span class="toggle-label" id="labelHasAzureAd">Nie</span>
|
|
<input type="hidden" name="has_azure_ad" id="hasAzureAd" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="azureAdFields">
|
|
<label class="form-label">
|
|
Nazwa tenanta Azure (domena)
|
|
</label>
|
|
<input type="text" class="form-input" name="azure_tenant_name" id="azureTenantName" value="{{ audit.azure_tenant_name if audit and audit.azure_tenant_name else '' }}" placeholder="np. firma.onmicrosoft.com">
|
|
<span class="form-hint">Domena glowna lub .onmicrosoft.com</span>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="azureUserCountField">
|
|
<label class="form-label">
|
|
Liczba uzytkownikow w Azure AD
|
|
</label>
|
|
<select class="form-select" name="azure_user_count" id="azureUserCount">
|
|
<option value="">Wybierz przedzial</option>
|
|
<option value="1-10">1-10 uzytkownikow</option>
|
|
<option value="11-25">11-25 uzytkownikow</option>
|
|
<option value="26-50">26-50 uzytkownikow</option>
|
|
<option value="51-100">51-100 uzytkownikow</option>
|
|
<option value="101-250">101-250 uzytkownikow</option>
|
|
<option value="250+">Ponad 250 uzytkownikow</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z Microsoft 365?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasM365" onclick="toggleSwitch('hasM365')"></div>
|
|
<span class="toggle-label" id="labelHasM365">Nie</span>
|
|
<input type="hidden" name="has_m365" id="hasM365" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group full-width conditional-fields hidden" id="m365PlansField">
|
|
<label class="form-label">
|
|
Posiadane plany Microsoft 365 (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="m365PlansChips">
|
|
<div class="chip-option" data-value="basic" onclick="toggleChip(this, 'm365Plans')">Microsoft 365 Basic</div>
|
|
<div class="chip-option" data-value="standard" onclick="toggleChip(this, 'm365Plans')">Microsoft 365 Business Standard</div>
|
|
<div class="chip-option" data-value="premium" onclick="toggleChip(this, 'm365Plans')">Microsoft 365 Business Premium</div>
|
|
<div class="chip-option" data-value="e3" onclick="toggleChip(this, 'm365Plans')">Microsoft 365 E3</div>
|
|
<div class="chip-option" data-value="e5" onclick="toggleChip(this, 'm365Plans')">Microsoft 365 E5</div>
|
|
<div class="chip-option" data-value="exchange" onclick="toggleChip(this, 'm365Plans')">Exchange Online</div>
|
|
<div class="chip-option" data-value="sharepoint" onclick="toggleChip(this, 'm365Plans')">SharePoint Online</div>
|
|
</div>
|
|
<input type="hidden" name="m365_plans" id="m365Plans" value="">
|
|
</div>
|
|
|
|
<div class="form-group full-width conditional-fields hidden" id="teamsUsageField">
|
|
<label class="form-label">
|
|
Wykorzystanie Microsoft Teams (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="teamsUsageChips">
|
|
<div class="chip-option" data-value="chat" onclick="toggleChip(this, 'teamsUsage')">Chat</div>
|
|
<div class="chip-option" data-value="calls" onclick="toggleChip(this, 'teamsUsage')">Polaczenia glosowe</div>
|
|
<div class="chip-option" data-value="meetings" onclick="toggleChip(this, 'teamsUsage')">Spotkania video</div>
|
|
<div class="chip-option" data-value="channels" onclick="toggleChip(this, 'teamsUsage')">Kanaly zespolow</div>
|
|
<div class="chip-option" data-value="files" onclick="toggleChip(this, 'teamsUsage')">Udostepnianie plikow</div>
|
|
<div class="chip-option" data-value="apps" onclick="toggleChip(this, 'teamsUsage')">Aplikacje i integracje</div>
|
|
</div>
|
|
<input type="hidden" name="teams_usage" id="teamsUsage" value="">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z Google Workspace?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasGoogleWorkspace" onclick="toggleSwitch('hasGoogleWorkspace')"></div>
|
|
<span class="toggle-label" id="labelHasGoogleWorkspace">Nie</span>
|
|
<input type="hidden" name="has_google_workspace" id="hasGoogleWorkspace" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma lokalna Active Directory (on-premises)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasLocalAd" onclick="toggleSwitch('hasLocalAd')"></div>
|
|
<span class="toggle-label" id="labelHasLocalAd">Nie</span>
|
|
<input type="hidden" name="has_local_ad" id="hasLocalAd" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="localAdFields">
|
|
<label class="form-label">
|
|
Nazwa domeny AD
|
|
</label>
|
|
<input type="text" class="form-input" name="ad_domain_name" id="adDomainName" value="{{ audit.ad_domain_name if audit and audit.ad_domain_name else '' }}" placeholder="np. firma.local">
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="adSyncField">
|
|
<label class="form-label">
|
|
Czy AD jest zsynchronizowane z Azure AD?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasAdAzureSync" onclick="toggleSwitch('hasAdAzureSync')"></div>
|
|
<span class="toggle-label" id="labelHasAdAzureSync">Nie</span>
|
|
<input type="hidden" name="has_ad_azure_sync" id="hasAdAzureSync" value="false">
|
|
</div>
|
|
<span class="form-hint">Azure AD Connect / Cloud Sync</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 3: Server Infrastructure -->
|
|
<div class="form-section" data-section="3">
|
|
<div class="section-header" onclick="toggleSection(3)">
|
|
<div class="section-number" id="sectionNumber3">3</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"/>
|
|
</svg>
|
|
Infrastruktura Serwerowa
|
|
</div>
|
|
<div class="section-subtitle">Serwery fizyczne i wirtualne, platformy wirtualizacji, systemy operacyjne</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent3">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Liczba serwerow (fizycznych + wirtualnych)
|
|
</label>
|
|
<select class="form-select" name="server_count" id="serverCount">
|
|
<option value="">Wybierz przedzial</option>
|
|
<option value="0">Brak serwerow</option>
|
|
<option value="1-3">1-3 serwerow</option>
|
|
<option value="4-10">4-10 serwerow</option>
|
|
<option value="11-25">11-25 serwerow</option>
|
|
<option value="26-50">26-50 serwerow</option>
|
|
<option value="50+">Ponad 50 serwerow</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Typy serwerow (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="serverTypesChips">
|
|
<div class="chip-option" data-value="physical_onprem" onclick="toggleChip(this, 'serverTypes')">Fizyczne (on-premises)</div>
|
|
<div class="chip-option" data-value="virtual_onprem" onclick="toggleChip(this, 'serverTypes')">Wirtualne (on-premises)</div>
|
|
<div class="chip-option" data-value="vps" onclick="toggleChip(this, 'serverTypes')">VPS (hosting zewnetrzny)</div>
|
|
<div class="chip-option" data-value="azure_vm" onclick="toggleChip(this, 'serverTypes')">Azure VM</div>
|
|
<div class="chip-option" data-value="aws_ec2" onclick="toggleChip(this, 'serverTypes')">AWS EC2</div>
|
|
<div class="chip-option" data-value="gcp_compute" onclick="toggleChip(this, 'serverTypes')">Google Cloud Compute</div>
|
|
<div class="chip-option" data-value="dedicated" onclick="toggleChip(this, 'serverTypes')">Serwery dedykowane (kolokacja)</div>
|
|
</div>
|
|
<input type="hidden" name="server_types" id="serverTypes" value="">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Platforma wirtualizacji (glowna)
|
|
</label>
|
|
<select class="form-select" name="virtualization_platform" id="virtualizationPlatform">
|
|
<option value="">Wybierz platforme</option>
|
|
<option value="none">Brak wirtualizacji</option>
|
|
<option value="proxmox">Proxmox VE</option>
|
|
<option value="vmware_esxi">VMware ESXi / vSphere</option>
|
|
<option value="hyperv">Microsoft Hyper-V</option>
|
|
<option value="xcp-ng">XCP-ng</option>
|
|
<option value="kvm">KVM / QEMU</option>
|
|
<option value="nutanix">Nutanix AHV</option>
|
|
<option value="other">Inna</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Systemy operacyjne serwerow (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="serverOsChips">
|
|
<div class="chip-option" data-value="windows_2022" onclick="toggleChip(this, 'serverOs')">Windows Server 2022</div>
|
|
<div class="chip-option" data-value="windows_2019" onclick="toggleChip(this, 'serverOs')">Windows Server 2019</div>
|
|
<div class="chip-option" data-value="windows_2016" onclick="toggleChip(this, 'serverOs')">Windows Server 2016</div>
|
|
<div class="chip-option" data-value="windows_older" onclick="toggleChip(this, 'serverOs')">Windows Server (starszy)</div>
|
|
<div class="chip-option" data-value="ubuntu" onclick="toggleChip(this, 'serverOs')">Ubuntu Server</div>
|
|
<div class="chip-option" data-value="debian" onclick="toggleChip(this, 'serverOs')">Debian</div>
|
|
<div class="chip-option" data-value="rhel" onclick="toggleChip(this, 'serverOs')">RHEL / CentOS / Rocky</div>
|
|
<div class="chip-option" data-value="suse" onclick="toggleChip(this, 'serverOs')">SUSE Linux</div>
|
|
<div class="chip-option" data-value="freebsd" onclick="toggleChip(this, 'serverOs')">FreeBSD / TrueNAS</div>
|
|
</div>
|
|
<input type="hidden" name="server_os" id="serverOs" value="">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Marka firewalla / UTM sieciowego
|
|
</label>
|
|
<select class="form-select" name="network_firewall_brand" id="networkFirewallBrand">
|
|
<option value="">Wybierz marke</option>
|
|
<option value="none">Brak dedykowanego firewalla</option>
|
|
<option value="fortigate">Fortinet FortiGate</option>
|
|
<option value="pfsense">pfSense / OPNsense</option>
|
|
<option value="sophos">Sophos XG / XGS</option>
|
|
<option value="cisco">Cisco ASA / Meraki</option>
|
|
<option value="paloalto">Palo Alto Networks</option>
|
|
<option value="watchguard">WatchGuard</option>
|
|
<option value="mikrotik">MikroTik</option>
|
|
<option value="ubiquiti">Ubiquiti UDM / USG</option>
|
|
<option value="checkpoint">Check Point</option>
|
|
<option value="other">Inny</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 4: Endpoints (Workstations) -->
|
|
<div class="form-section" data-section="4">
|
|
<div class="section-header collapsed" onclick="toggleSection(4)">
|
|
<div class="section-number" id="sectionNumber4">4</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
|
|
</svg>
|
|
Stacje Robocze
|
|
</div>
|
|
<div class="section-subtitle">Komputery pracownikow, systemy operacyjne, MDM</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent4">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Liczba stacji roboczych (komputerow)
|
|
</label>
|
|
<select class="form-select" name="endpoint_count" id="endpointCount">
|
|
<option value="">Wybierz przedzial</option>
|
|
<option value="1-10">1-10 komputerow</option>
|
|
<option value="11-25">11-25 komputerow</option>
|
|
<option value="26-50">26-50 komputerow</option>
|
|
<option value="51-100">51-100 komputerow</option>
|
|
<option value="101-250">101-250 komputerow</option>
|
|
<option value="250+">Ponad 250 komputerow</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Typy urzadzen koncowych (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="endpointTypesChips">
|
|
<div class="chip-option" data-value="desktop_pc" onclick="toggleChip(this, 'endpointTypes')">Komputery stacjonarne (PC)</div>
|
|
<div class="chip-option" data-value="laptop" onclick="toggleChip(this, 'endpointTypes')">Laptopy</div>
|
|
<div class="chip-option" data-value="workstation" onclick="toggleChip(this, 'endpointTypes')">Stacje robocze (CAD/grafika)</div>
|
|
<div class="chip-option" data-value="thin_client" onclick="toggleChip(this, 'endpointTypes')">Thin clienty / terminale</div>
|
|
<div class="chip-option" data-value="mac" onclick="toggleChip(this, 'endpointTypes')">Komputery Mac</div>
|
|
<div class="chip-option" data-value="tablet" onclick="toggleChip(this, 'endpointTypes')">Tablety</div>
|
|
<div class="chip-option" data-value="mobile" onclick="toggleChip(this, 'endpointTypes')">Smartfony sluzbowe</div>
|
|
</div>
|
|
<input type="hidden" name="endpoint_types" id="endpointTypes" value="">
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Systemy operacyjne stacji roboczych (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="endpointOsChips">
|
|
<div class="chip-option" data-value="windows_11" onclick="toggleChip(this, 'endpointOs')">Windows 11</div>
|
|
<div class="chip-option" data-value="windows_10" onclick="toggleChip(this, 'endpointOs')">Windows 10</div>
|
|
<div class="chip-option" data-value="windows_older" onclick="toggleChip(this, 'endpointOs')">Windows 7/8 (starszy)</div>
|
|
<div class="chip-option" data-value="macos" onclick="toggleChip(this, 'endpointOs')">macOS</div>
|
|
<div class="chip-option" data-value="linux" onclick="toggleChip(this, 'endpointOs')">Linux (Ubuntu/inny)</div>
|
|
<div class="chip-option" data-value="chromeos" onclick="toggleChip(this, 'endpointOs')">Chrome OS</div>
|
|
<div class="chip-option" data-value="ios" onclick="toggleChip(this, 'endpointOs')">iOS/iPadOS</div>
|
|
<div class="chip-option" data-value="android" onclick="toggleChip(this, 'endpointOs')">Android</div>
|
|
</div>
|
|
<input type="hidden" name="endpoint_os" id="endpointOs" value="">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z MDM (Mobile Device Management)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasMdm" onclick="toggleSwitch('hasMdm')"></div>
|
|
<span class="toggle-label" id="labelHasMdm">Nie</span>
|
|
<input type="hidden" name="has_mdm" id="hasMdm" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="mdmSolutionField">
|
|
<label class="form-label">
|
|
Rozwiazanie MDM
|
|
</label>
|
|
<select class="form-select" name="mdm_solution" id="mdmSolution">
|
|
<option value="">Wybierz rozwiazanie</option>
|
|
<option value="intune">Microsoft Intune</option>
|
|
<option value="jamf">Jamf (dla macOS/iOS)</option>
|
|
<option value="workspace_one">VMware Workspace ONE</option>
|
|
<option value="mobileiron">MobileIron / Ivanti</option>
|
|
<option value="kandji">Kandji</option>
|
|
<option value="hexnode">Hexnode</option>
|
|
<option value="other">Inne rozwiazanie</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy urzadzenia sa centralne zarzadzane (GPO/Intune)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasCentralManagement" onclick="toggleSwitch('hasCentralManagement')"></div>
|
|
<span class="toggle-label" id="labelHasCentralManagement">Nie</span>
|
|
<input type="hidden" name="has_central_management" id="hasCentralManagement" value="false">
|
|
</div>
|
|
<span class="form-hint">Group Policy, Intune, SCCM, inne narzedzia do zarzadzania konfiguracjami</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy dyski twarde sa szyfrowane?
|
|
</label>
|
|
<select class="form-select" name="disk_encryption" id="diskEncryption">
|
|
<option value="">Wybierz opcje</option>
|
|
<option value="none">Brak szyfrowania</option>
|
|
<option value="partial">Czesciowo (niektore urzadzenia)</option>
|
|
<option value="bitlocker">BitLocker (Windows)</option>
|
|
<option value="filevault">FileVault (macOS)</option>
|
|
<option value="veracrypt">VeraCrypt</option>
|
|
<option value="other">Inne rozwiazanie</option>
|
|
</select>
|
|
<span class="form-hint">Szyfrowanie chroni dane w przypadku kradziezy urzadzenia</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 5: Security -->
|
|
<div class="form-section" data-section="5">
|
|
<div class="section-header collapsed" onclick="toggleSection(5)">
|
|
<div class="section-number" id="sectionNumber5">5</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
|
|
</svg>
|
|
Bezpieczenstwo
|
|
</div>
|
|
<div class="section-subtitle">Antywirus, EDR, VPN, MFA, firewall</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent5">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Rozwiazanie antywirusowe / EDR
|
|
</label>
|
|
<select class="form-select" name="antivirus_solution" id="antivirusSolution">
|
|
<option value="">Wybierz rozwiazanie</option>
|
|
<option value="none">Brak (tylko Windows Defender)</option>
|
|
<option value="defender_atp">Microsoft Defender for Endpoint (ATP)</option>
|
|
<option value="crowdstrike">CrowdStrike Falcon</option>
|
|
<option value="sentinelone">SentinelOne</option>
|
|
<option value="eset">ESET Endpoint Security</option>
|
|
<option value="kaspersky">Kaspersky</option>
|
|
<option value="sophos">Sophos Endpoint</option>
|
|
<option value="bitdefender">Bitdefender GravityZone</option>
|
|
<option value="trendmicro">Trend Micro</option>
|
|
<option value="norton">Norton / Symantec</option>
|
|
<option value="malwarebytes">Malwarebytes</option>
|
|
<option value="other">Inne rozwiazanie</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z VPN dla pracownikow zdalnych?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasVpn" onclick="toggleSwitch('hasVpn')"></div>
|
|
<span class="toggle-label" id="labelHasVpn">Nie</span>
|
|
<input type="hidden" name="has_vpn" id="hasVpn" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="vpnSolutionField">
|
|
<label class="form-label">
|
|
Rozwiazanie VPN
|
|
</label>
|
|
<select class="form-select" name="vpn_solution" id="vpnSolution">
|
|
<option value="">Wybierz rozwiazanie</option>
|
|
<option value="forticlient">FortiClient VPN</option>
|
|
<option value="cisco_anyconnect">Cisco AnyConnect</option>
|
|
<option value="globalprotect">Palo Alto GlobalProtect</option>
|
|
<option value="openvpn">OpenVPN</option>
|
|
<option value="wireguard">WireGuard</option>
|
|
<option value="azure_vpn">Azure VPN Gateway</option>
|
|
<option value="sophos_vpn">Sophos VPN</option>
|
|
<option value="pulse">Pulse Secure / Ivanti</option>
|
|
<option value="mikrotik_vpn">MikroTik VPN</option>
|
|
<option value="other">Inne rozwiazanie</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z MFA (uwierzytelnianie wieloskladnikowe)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasMfa" onclick="toggleSwitch('hasMfa')"></div>
|
|
<span class="toggle-label" id="labelHasMfa">Nie</span>
|
|
<input type="hidden" name="has_mfa" id="hasMfa" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group full-width conditional-fields hidden" id="mfaMethodsField">
|
|
<label class="form-label">
|
|
Metody MFA (wybierz wszystkie stosowane)
|
|
</label>
|
|
<div class="chip-select" id="mfaMethodsChips">
|
|
<div class="chip-option" data-value="authenticator_app" onclick="toggleChip(this, 'mfaMethods')">Aplikacja Authenticator (TOTP)</div>
|
|
<div class="chip-option" data-value="sms" onclick="toggleChip(this, 'mfaMethods')">SMS</div>
|
|
<div class="chip-option" data-value="phone_call" onclick="toggleChip(this, 'mfaMethods')">Polaczenie telefoniczne</div>
|
|
<div class="chip-option" data-value="hardware_key" onclick="toggleChip(this, 'mfaMethods')">Klucz sprzetowy (YubiKey, FIDO2)</div>
|
|
<div class="chip-option" data-value="push" onclick="toggleChip(this, 'mfaMethods')">Powiadomienia push</div>
|
|
<div class="chip-option" data-value="biometric" onclick="toggleChip(this, 'mfaMethods')">Biometria (Windows Hello)</div>
|
|
<div class="chip-option" data-value="email" onclick="toggleChip(this, 'mfaMethods')">Kod email</div>
|
|
</div>
|
|
<input type="hidden" name="mfa_methods" id="mfaMethods" value="">
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Zakres stosowania MFA (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="mfaScopeChips">
|
|
<div class="chip-option" data-value="cloud_apps" onclick="toggleChip(this, 'mfaScope')">Aplikacje chmurowe (M365, Google)</div>
|
|
<div class="chip-option" data-value="vpn" onclick="toggleChip(this, 'mfaScope')">VPN</div>
|
|
<div class="chip-option" data-value="windows_login" onclick="toggleChip(this, 'mfaScope')">Logowanie do Windows</div>
|
|
<div class="chip-option" data-value="privileged" onclick="toggleChip(this, 'mfaScope')">Konta uprzywilejowane (admin)</div>
|
|
<div class="chip-option" data-value="all_users" onclick="toggleChip(this, 'mfaScope')">Wszyscy uzytkownicy</div>
|
|
<div class="chip-option" data-value="external" onclick="toggleChip(this, 'mfaScope')">Dostep zewnetrzny</div>
|
|
</div>
|
|
<input type="hidden" name="mfa_scope" id="mfaScope" value="">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma polityki haseł (password policy)?
|
|
</label>
|
|
<select class="form-select" name="password_policy" id="passwordPolicy">
|
|
<option value="">Wybierz opcje</option>
|
|
<option value="none">Brak formalnej polityki</option>
|
|
<option value="basic">Podstawowa (min. dlugosc, zlozonosc)</option>
|
|
<option value="advanced">Zaawansowana (rotacja, historia, blokada)</option>
|
|
<option value="passwordless">Passwordless (bez hasel)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy przeprowadzane sa szkolenia z cyberbezpieczenstwa?
|
|
</label>
|
|
<select class="form-select" name="security_training" id="securityTraining">
|
|
<option value="">Wybierz opcje</option>
|
|
<option value="none">Brak szkolen</option>
|
|
<option value="onboarding">Tylko przy zatrudnieniu</option>
|
|
<option value="annual">Raz w roku</option>
|
|
<option value="quarterly">Kwartalnie</option>
|
|
<option value="continuous">Ciagle (platforma e-learning)</option>
|
|
</select>
|
|
<span class="form-hint">Szkolenia dot. phishingu, bezpieczenstwa hasel, etc.</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma posiada ubezpieczenie cyber (cyber insurance)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasCyberInsurance" onclick="toggleSwitch('hasCyberInsurance')"></div>
|
|
<span class="toggle-label" id="labelHasCyberInsurance">Nie</span>
|
|
<input type="hidden" name="has_cyber_insurance" id="hasCyberInsurance" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Dodatkowe srodki bezpieczenstwa (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="securityMeasuresChips">
|
|
<div class="chip-option" data-value="siem" onclick="toggleChip(this, 'securityMeasures')">SIEM / centralne logi</div>
|
|
<div class="chip-option" data-value="dlp" onclick="toggleChip(this, 'securityMeasures')">DLP (Data Loss Prevention)</div>
|
|
<div class="chip-option" data-value="email_security" onclick="toggleChip(this, 'securityMeasures')">Zabezpieczenia poczty (anti-phishing)</div>
|
|
<div class="chip-option" data-value="web_filter" onclick="toggleChip(this, 'securityMeasures')">Filtrowanie WWW</div>
|
|
<div class="chip-option" data-value="pam" onclick="toggleChip(this, 'securityMeasures')">PAM (Privileged Access Management)</div>
|
|
<div class="chip-option" data-value="vulnerability_scan" onclick="toggleChip(this, 'securityMeasures')">Skanowanie podatnosci</div>
|
|
<div class="chip-option" data-value="pentest" onclick="toggleChip(this, 'securityMeasures')">Testy penetracyjne</div>
|
|
<div class="chip-option" data-value="soc" onclick="toggleChip(this, 'securityMeasures')">SOC (zewnetrzny lub wewnetrzny)</div>
|
|
</div>
|
|
<input type="hidden" name="security_measures" id="securityMeasures" value="">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 6: Backup & Disaster Recovery -->
|
|
<div class="form-section" data-section="6">
|
|
<div class="section-header collapsed" onclick="toggleSection(6)">
|
|
<div class="section-number" id="sectionNumber6">6</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"/>
|
|
</svg>
|
|
Backup i Disaster Recovery
|
|
</div>
|
|
<div class="section-subtitle">Rozwiazania backupowe, cele, czestotliwosc, plan DR</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent6">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma wdrozony backup?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasBackup" onclick="toggleSwitch('hasBackup')"></div>
|
|
<span class="toggle-label" id="labelHasBackup">Nie</span>
|
|
<input type="hidden" name="has_backup" id="hasBackup" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="backupSolutionField">
|
|
<label class="form-label">
|
|
Glowne rozwiazanie backupowe
|
|
</label>
|
|
<select class="form-select" name="backup_solution" id="backupSolution">
|
|
<option value="">Wybierz rozwiazanie</option>
|
|
<option value="veeam">Veeam Backup & Replication</option>
|
|
<option value="acronis">Acronis Cyber Protect</option>
|
|
<option value="commvault">Commvault</option>
|
|
<option value="veritas">Veritas NetBackup / Backup Exec</option>
|
|
<option value="nakivo">NAKIVO</option>
|
|
<option value="azure_backup">Azure Backup</option>
|
|
<option value="aws_backup">AWS Backup</option>
|
|
<option value="proxmox_backup">Proxmox Backup Server</option>
|
|
<option value="synology">Synology Hyper Backup</option>
|
|
<option value="qnap">QNAP Backup</option>
|
|
<option value="windows_backup">Windows Server Backup</option>
|
|
<option value="bacula">Bacula / Bareos</option>
|
|
<option value="restic">Restic / BorgBackup</option>
|
|
<option value="other">Inne rozwiazanie</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group full-width conditional-fields hidden" id="backupTargetsField">
|
|
<label class="form-label">
|
|
Co jest backupowane? (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="backupTargetsChips">
|
|
<div class="chip-option" data-value="servers" onclick="toggleChip(this, 'backupTargets')">Serwery (VM/fizyczne)</div>
|
|
<div class="chip-option" data-value="databases" onclick="toggleChip(this, 'backupTargets')">Bazy danych</div>
|
|
<div class="chip-option" data-value="file_shares" onclick="toggleChip(this, 'backupTargets')">Udzialy plikowe</div>
|
|
<div class="chip-option" data-value="endpoints" onclick="toggleChip(this, 'backupTargets')">Stacje robocze</div>
|
|
<div class="chip-option" data-value="m365" onclick="toggleChip(this, 'backupTargets')">Microsoft 365 (mail, OneDrive, SharePoint)</div>
|
|
<div class="chip-option" data-value="google_workspace" onclick="toggleChip(this, 'backupTargets')">Google Workspace</div>
|
|
<div class="chip-option" data-value="applications" onclick="toggleChip(this, 'backupTargets')">Aplikacje biznesowe (ERP, CRM)</div>
|
|
<div class="chip-option" data-value="config" onclick="toggleChip(this, 'backupTargets')">Konfiguracje (sieci, firewalle)</div>
|
|
</div>
|
|
<input type="hidden" name="backup_targets" id="backupTargets" value="">
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="backupFrequencyField">
|
|
<label class="form-label">
|
|
Czestotliwosc backupu
|
|
</label>
|
|
<select class="form-select" name="backup_frequency" id="backupFrequency">
|
|
<option value="">Wybierz czestotliwosc</option>
|
|
<option value="continuous">Ciagle (CDP)</option>
|
|
<option value="hourly">Co godzine</option>
|
|
<option value="daily">Codziennie</option>
|
|
<option value="weekly">Co tydzien</option>
|
|
<option value="monthly">Co miesiac</option>
|
|
<option value="irregular">Nieregularnie / reczne</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group full-width conditional-fields hidden" id="backupStorageField">
|
|
<label class="form-label">
|
|
Gdzie przechowywane sa kopie backupowe? (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="backupStorageChips">
|
|
<div class="chip-option" data-value="local_nas" onclick="toggleChip(this, 'backupStorage')">Lokalny NAS / storage</div>
|
|
<div class="chip-option" data-value="local_tape" onclick="toggleChip(this, 'backupStorage')">Tasmy LTO (local)</div>
|
|
<div class="chip-option" data-value="offsite_nas" onclick="toggleChip(this, 'backupStorage')">NAS w innej lokalizacji</div>
|
|
<div class="chip-option" data-value="cloud_azure" onclick="toggleChip(this, 'backupStorage')">Azure Blob Storage</div>
|
|
<div class="chip-option" data-value="cloud_aws" onclick="toggleChip(this, 'backupStorage')">AWS S3 / Glacier</div>
|
|
<div class="chip-option" data-value="cloud_gcp" onclick="toggleChip(this, 'backupStorage')">Google Cloud Storage</div>
|
|
<div class="chip-option" data-value="cloud_backblaze" onclick="toggleChip(this, 'backupStorage')">Backblaze B2</div>
|
|
<div class="chip-option" data-value="cloud_wasabi" onclick="toggleChip(this, 'backupStorage')">Wasabi</div>
|
|
<div class="chip-option" data-value="datacenter" onclick="toggleChip(this, 'backupStorage')">Zewnetrzne data center</div>
|
|
</div>
|
|
<input type="hidden" name="backup_storage" id="backupStorage" value="">
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="backupRetentionField">
|
|
<label class="form-label">
|
|
Retencja backupow (jak dlugo przechowywane)
|
|
</label>
|
|
<select class="form-select" name="backup_retention" id="backupRetention">
|
|
<option value="">Wybierz okres</option>
|
|
<option value="7days">7 dni</option>
|
|
<option value="14days">14 dni</option>
|
|
<option value="30days">30 dni</option>
|
|
<option value="90days">90 dni</option>
|
|
<option value="1year">1 rok</option>
|
|
<option value="3years">3 lata</option>
|
|
<option value="7years">7 lat (wymagania prawne)</option>
|
|
<option value="gfs">GFS (Grandfather-Father-Son)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy testy odzyskiwania backupow sa przeprowadzane regularnie?
|
|
</label>
|
|
<select class="form-select" name="backup_test_frequency" id="backupTestFrequency">
|
|
<option value="">Wybierz opcje</option>
|
|
<option value="never">Nigdy nie testowane</option>
|
|
<option value="yearly">Raz w roku</option>
|
|
<option value="quarterly">Kwartalnie</option>
|
|
<option value="monthly">Miesiecznie</option>
|
|
<option value="automated">Automatyczne testy</option>
|
|
</select>
|
|
<span class="form-hint">Testowanie odzyskiwania to klucz do pewnosci, ze backup dziala</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma plan Disaster Recovery (DR)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasDrPlan" onclick="toggleSwitch('hasDrPlan')"></div>
|
|
<span class="toggle-label" id="labelHasDrPlan">Nie</span>
|
|
<input type="hidden" name="has_dr_plan" id="hasDrPlan" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="rtoField">
|
|
<label class="form-label">
|
|
RTO (Recovery Time Objective)
|
|
</label>
|
|
<select class="form-select" name="rto" id="rto">
|
|
<option value="">Wybierz docelowy czas odzyskiwania</option>
|
|
<option value="1hour">Do 1 godziny</option>
|
|
<option value="4hours">Do 4 godzin</option>
|
|
<option value="8hours">Do 8 godzin (1 dzien roboczy)</option>
|
|
<option value="24hours">Do 24 godzin</option>
|
|
<option value="48hours">Do 48 godzin</option>
|
|
<option value="1week">Do 1 tygodnia</option>
|
|
<option value="undefined">Nie zdefiniowany</option>
|
|
</select>
|
|
<span class="form-hint">Maksymalny akceptowalny czas niedostepnosci systemow</span>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="rpoField">
|
|
<label class="form-label">
|
|
RPO (Recovery Point Objective)
|
|
</label>
|
|
<select class="form-select" name="rpo" id="rpo">
|
|
<option value="">Wybierz akceptowalna utrate danych</option>
|
|
<option value="0">Zero (bez utraty danych)</option>
|
|
<option value="1hour">Do 1 godziny</option>
|
|
<option value="4hours">Do 4 godzin</option>
|
|
<option value="24hours">Do 24 godzin</option>
|
|
<option value="48hours">Do 48 godzin</option>
|
|
<option value="1week">Do 1 tygodnia</option>
|
|
<option value="undefined">Nie zdefiniowany</option>
|
|
</select>
|
|
<span class="form-hint">Maksymalna akceptowalna ilosc utraconych danych (od ostatniego backupu)</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma zapasowa lokalizacje (DR site)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasDrSite" onclick="toggleSwitch('hasDrSite')"></div>
|
|
<span class="toggle-label" id="labelHasDrSite">Nie</span>
|
|
<input type="hidden" name="has_dr_site" id="hasDrSite" value="false">
|
|
</div>
|
|
<span class="form-hint">Druga lokalizacja, gdzie mozna przeniesc operacje w razie awarii</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 7: Monitoring -->
|
|
<div class="form-section" data-section="7">
|
|
<div class="section-header collapsed" onclick="toggleSection(7)">
|
|
<div class="section-number" id="sectionNumber7">7</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
|
</svg>
|
|
Monitoring
|
|
</div>
|
|
<div class="section-subtitle">Rozwiazania monitoringu infrastruktury, Zabbix, logi, alerty</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent7">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma wdrozony monitoring infrastruktury?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasMonitoring" onclick="toggleSwitch('hasMonitoring')"></div>
|
|
<span class="toggle-label" id="labelHasMonitoring">Nie</span>
|
|
<input type="hidden" name="has_monitoring" id="hasMonitoring" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="monitoringSolutionField">
|
|
<label class="form-label">
|
|
Glowne rozwiazanie monitoringu
|
|
</label>
|
|
<select class="form-select" name="monitoring_solution" id="monitoringSolution">
|
|
<option value="">Wybierz rozwiazanie</option>
|
|
<option value="zabbix">Zabbix</option>
|
|
<option value="prometheus">Prometheus + Grafana</option>
|
|
<option value="prtg">PRTG Network Monitor</option>
|
|
<option value="nagios">Nagios / Icinga</option>
|
|
<option value="datadog">Datadog</option>
|
|
<option value="new_relic">New Relic</option>
|
|
<option value="azure_monitor">Azure Monitor</option>
|
|
<option value="aws_cloudwatch">AWS CloudWatch</option>
|
|
<option value="splunk">Splunk</option>
|
|
<option value="solarwinds">SolarWinds</option>
|
|
<option value="checkmk">Checkmk</option>
|
|
<option value="opsgenie">OpsGenie / PagerDuty</option>
|
|
<option value="other">Inne rozwiazanie</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group full-width conditional-fields hidden" id="monitoringTargetsField">
|
|
<label class="form-label">
|
|
Co jest monitorowane? (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="monitoringTargetsChips">
|
|
<div class="chip-option" data-value="servers" onclick="toggleChip(this, 'monitoringTargets')">Serwery (CPU, RAM, dyski)</div>
|
|
<div class="chip-option" data-value="network" onclick="toggleChip(this, 'monitoringTargets')">Siec (bandwidth, latency)</div>
|
|
<div class="chip-option" data-value="applications" onclick="toggleChip(this, 'monitoringTargets')">Aplikacje (dostepnosc, wydajnosc)</div>
|
|
<div class="chip-option" data-value="databases" onclick="toggleChip(this, 'monitoringTargets')">Bazy danych</div>
|
|
<div class="chip-option" data-value="endpoints" onclick="toggleChip(this, 'monitoringTargets')">Stacje robocze</div>
|
|
<div class="chip-option" data-value="cloud" onclick="toggleChip(this, 'monitoringTargets')">Uslugi chmurowe</div>
|
|
<div class="chip-option" data-value="security" onclick="toggleChip(this, 'monitoringTargets')">Zdarzenia bezpieczenstwa</div>
|
|
<div class="chip-option" data-value="backup" onclick="toggleChip(this, 'monitoringTargets')">Zadania backupowe</div>
|
|
</div>
|
|
<input type="hidden" name="monitoring_targets" id="monitoringTargets" value="">
|
|
</div>
|
|
|
|
<div class="form-group full-width conditional-fields hidden" id="alertingMethodsField">
|
|
<label class="form-label">
|
|
Metody powiadamiania o alertach (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="alertingMethodsChips">
|
|
<div class="chip-option" data-value="email" onclick="toggleChip(this, 'alertingMethods')">Email</div>
|
|
<div class="chip-option" data-value="sms" onclick="toggleChip(this, 'alertingMethods')">SMS</div>
|
|
<div class="chip-option" data-value="teams" onclick="toggleChip(this, 'alertingMethods')">Microsoft Teams</div>
|
|
<div class="chip-option" data-value="slack" onclick="toggleChip(this, 'alertingMethods')">Slack</div>
|
|
<div class="chip-option" data-value="webhook" onclick="toggleChip(this, 'alertingMethods')">Webhook / API</div>
|
|
<div class="chip-option" data-value="mobile_app" onclick="toggleChip(this, 'alertingMethods')">Aplikacja mobilna</div>
|
|
<div class="chip-option" data-value="phone_call" onclick="toggleChip(this, 'alertingMethods')">Polaczenie telefoniczne</div>
|
|
</div>
|
|
<input type="hidden" name="alerting_methods" id="alertingMethods" value="">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma centralne logowanie (SIEM/Log Management)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasCentralLogging" onclick="toggleSwitch('hasCentralLogging')"></div>
|
|
<span class="toggle-label" id="labelHasCentralLogging">Nie</span>
|
|
<input type="hidden" name="has_central_logging" id="hasCentralLogging" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="loggingSolutionField">
|
|
<label class="form-label">
|
|
Rozwiazanie do logow
|
|
</label>
|
|
<select class="form-select" name="logging_solution" id="loggingSolution">
|
|
<option value="">Wybierz rozwiazanie</option>
|
|
<option value="elastic">Elastic Stack (ELK)</option>
|
|
<option value="splunk">Splunk</option>
|
|
<option value="graylog">Graylog</option>
|
|
<option value="loki">Grafana Loki</option>
|
|
<option value="azure_sentinel">Microsoft Sentinel</option>
|
|
<option value="azure_log_analytics">Azure Log Analytics</option>
|
|
<option value="aws_cloudwatch_logs">AWS CloudWatch Logs</option>
|
|
<option value="datadog_logs">Datadog Logs</option>
|
|
<option value="sumo_logic">Sumo Logic</option>
|
|
<option value="syslog_server">Syslog Server</option>
|
|
<option value="other">Inne rozwiazanie</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Jak dlugo przechowywane sa logi?
|
|
</label>
|
|
<select class="form-select" name="log_retention" id="logRetention">
|
|
<option value="">Wybierz okres</option>
|
|
<option value="none">Brak centralnego przechowywania</option>
|
|
<option value="7days">7 dni</option>
|
|
<option value="30days">30 dni</option>
|
|
<option value="90days">90 dni</option>
|
|
<option value="1year">1 rok</option>
|
|
<option value="3years">3 lata</option>
|
|
<option value="7years">7 lat (wymagania prawne)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z Zabbix?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasZabbix" onclick="toggleSwitch('hasZabbix')"></div>
|
|
<span class="toggle-label" id="labelHasZabbix">Nie</span>
|
|
<input type="hidden" name="has_zabbix" id="hasZabbix" value="false">
|
|
</div>
|
|
<span class="form-hint">Zabbix jest popularnym rozwiazaniem w Norda Biznes - mozliwa wspolpraca</span>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma korzysta z Proxmox Backup Server (PBS)?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasProxmoxPbs" onclick="toggleSwitch('hasProxmoxPbs')"></div>
|
|
<span class="toggle-label" id="labelHasProxmoxPbs">Nie</span>
|
|
<input type="hidden" name="has_proxmox_pbs" id="hasProxmoxPbs" value="false">
|
|
</div>
|
|
<span class="form-hint">PBS umozliwia wspolna replikacje backupow miedzy firmami</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 8: Business Applications -->
|
|
<div class="form-section" data-section="8">
|
|
<div class="section-header collapsed" onclick="toggleSection(8)">
|
|
<div class="section-number" id="sectionNumber8">8</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"/>
|
|
</svg>
|
|
Aplikacje Biznesowe
|
|
</div>
|
|
<div class="section-subtitle">System ERP, CRM, ticketowy, zarzadzanie dokumentami</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent8">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
System ERP / FK
|
|
</label>
|
|
<select class="form-select" name="erp_system" id="erpSystem">
|
|
<option value="">Wybierz system</option>
|
|
<option value="none">Brak systemu ERP</option>
|
|
<option value="sap">SAP (S/4HANA, Business One)</option>
|
|
<option value="dynamics365">Microsoft Dynamics 365</option>
|
|
<option value="dynamics_nav">Microsoft Dynamics NAV</option>
|
|
<option value="enova">Enova365</option>
|
|
<option value="optima">Comarch ERP Optima</option>
|
|
<option value="xl">Comarch ERP XL</option>
|
|
<option value="altum">Comarch ERP Altum</option>
|
|
<option value="sage">Sage (Symfonia)</option>
|
|
<option value="wapro">Asseco WAPRO</option>
|
|
<option value="cdn">CDN Klasyka / XL</option>
|
|
<option value="subiekt">Insert Subiekt GT/nexo</option>
|
|
<option value="oracle">Oracle ERP Cloud</option>
|
|
<option value="odoo">Odoo</option>
|
|
<option value="other">Inny system</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
System CRM
|
|
</label>
|
|
<select class="form-select" name="crm_system" id="crmSystem">
|
|
<option value="">Wybierz system</option>
|
|
<option value="none">Brak systemu CRM</option>
|
|
<option value="dynamics365_crm">Microsoft Dynamics 365 CRM</option>
|
|
<option value="salesforce">Salesforce</option>
|
|
<option value="hubspot">HubSpot</option>
|
|
<option value="pipedrive">Pipedrive</option>
|
|
<option value="zoho">Zoho CRM</option>
|
|
<option value="livespace">Livespace</option>
|
|
<option value="freshsales">Freshsales</option>
|
|
<option value="bitrix24">Bitrix24</option>
|
|
<option value="sugar">SugarCRM</option>
|
|
<option value="erp_integrated">Zintegrowany z ERP</option>
|
|
<option value="excel">Excel / arkusze</option>
|
|
<option value="other">Inny system</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
Czy firma ma system ticketowy / helpdesk?
|
|
</label>
|
|
<div class="form-toggle">
|
|
<div class="toggle-switch" id="toggleHasTicketSystem" onclick="toggleSwitch('hasTicketSystem')"></div>
|
|
<span class="toggle-label" id="labelHasTicketSystem">Nie</span>
|
|
<input type="hidden" name="has_ticket_system" id="hasTicketSystem" value="false">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group conditional-fields hidden" id="ticketSystemField">
|
|
<label class="form-label">
|
|
System ticketowy
|
|
</label>
|
|
<select class="form-select" name="ticket_system" id="ticketSystem">
|
|
<option value="">Wybierz system</option>
|
|
<option value="freshdesk">Freshdesk</option>
|
|
<option value="zendesk">Zendesk</option>
|
|
<option value="jira">Jira Service Management</option>
|
|
<option value="servicenow">ServiceNow</option>
|
|
<option value="osticket">osTicket</option>
|
|
<option value="zammad">Zammad</option>
|
|
<option value="glpi">GLPI</option>
|
|
<option value="otrs">OTRS</option>
|
|
<option value="freshservice">Freshservice</option>
|
|
<option value="teams_ticketing">Rozwiazanie w Teams</option>
|
|
<option value="email_only">Tylko email</option>
|
|
<option value="other">Inny system</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">
|
|
System do zarzadzania dokumentami (DMS)
|
|
</label>
|
|
<select class="form-select" name="document_system" id="documentSystem">
|
|
<option value="">Wybierz system</option>
|
|
<option value="none">Brak dedykowanego DMS</option>
|
|
<option value="sharepoint">SharePoint</option>
|
|
<option value="google_drive">Google Drive</option>
|
|
<option value="onedrive">OneDrive for Business</option>
|
|
<option value="dropbox">Dropbox Business</option>
|
|
<option value="nextcloud">Nextcloud</option>
|
|
<option value="owncloud">ownCloud</option>
|
|
<option value="m_files">M-Files</option>
|
|
<option value="docuware">DocuWare</option>
|
|
<option value="alfresco">Alfresco</option>
|
|
<option value="network_shares">Udzialy sieciowe (SMB)</option>
|
|
<option value="other">Inny system</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Inne kluczowe aplikacje biznesowe (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="otherBusinessAppsChips">
|
|
<div class="chip-option" data-value="project_management" onclick="toggleChip(this, 'otherBusinessApps')">Zarzadzanie projektami (Asana, Monday, Trello)</div>
|
|
<div class="chip-option" data-value="hr_system" onclick="toggleChip(this, 'otherBusinessApps')">System HR / kadry-place</div>
|
|
<div class="chip-option" data-value="bi_analytics" onclick="toggleChip(this, 'otherBusinessApps')">BI / analityka (Power BI, Tableau)</div>
|
|
<div class="chip-option" data-value="ecommerce" onclick="toggleChip(this, 'otherBusinessApps')">E-commerce / sklep online</div>
|
|
<div class="chip-option" data-value="manufacturing" onclick="toggleChip(this, 'otherBusinessApps')">MES / produkcja</div>
|
|
<div class="chip-option" data-value="warehouse" onclick="toggleChip(this, 'otherBusinessApps')">WMS / magazyn</div>
|
|
<div class="chip-option" data-value="cad" onclick="toggleChip(this, 'otherBusinessApps')">CAD / projektowanie</div>
|
|
<div class="chip-option" data-value="accounting" onclick="toggleChip(this, 'otherBusinessApps')">Fakturowanie / ksiegowosc online</div>
|
|
<div class="chip-option" data-value="communication" onclick="toggleChip(this, 'otherBusinessApps')">Komunikatory (Teams, Slack)</div>
|
|
</div>
|
|
<input type="hidden" name="other_business_apps" id="otherBusinessApps" value="">
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Metody integracji miedzy systemami (wybierz wszystkie)
|
|
</label>
|
|
<div class="chip-select" id="integrationMethodsChips">
|
|
<div class="chip-option" data-value="api_rest" onclick="toggleChip(this, 'integrationMethods')">API REST</div>
|
|
<div class="chip-option" data-value="api_soap" onclick="toggleChip(this, 'integrationMethods')">API SOAP</div>
|
|
<div class="chip-option" data-value="file_exchange" onclick="toggleChip(this, 'integrationMethods')">Wymiana plikow (CSV, XML)</div>
|
|
<div class="chip-option" data-value="database_direct" onclick="toggleChip(this, 'integrationMethods')">Bezposredni dostep do bazy</div>
|
|
<div class="chip-option" data-value="middleware" onclick="toggleChip(this, 'integrationMethods')">Middleware / iPaaS</div>
|
|
<div class="chip-option" data-value="power_automate" onclick="toggleChip(this, 'integrationMethods')">Power Automate / Zapier</div>
|
|
<div class="chip-option" data-value="manual" onclick="toggleChip(this, 'integrationMethods')">Reczne przepisywanie</div>
|
|
<div class="chip-option" data-value="none" onclick="toggleChip(this, 'integrationMethods')">Brak integracji</div>
|
|
</div>
|
|
<input type="hidden" name="integration_methods" id="integrationMethods" value="">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section 9: Collaboration -->
|
|
<div class="form-section" data-section="9">
|
|
<div class="section-header collapsed" onclick="toggleSection(9)">
|
|
<div class="section-number" id="sectionNumber9">9</div>
|
|
<div class="section-title-group">
|
|
<div class="section-title">
|
|
<svg class="section-icon" style="display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
|
|
</svg>
|
|
Gotowosc do Wspolpracy
|
|
</div>
|
|
<div class="section-subtitle">Mozliwosci wspolpracy IT z innymi firmami Norda Biznes</div>
|
|
</div>
|
|
<svg class="section-toggle" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="section-content collapsed" id="sectionContent9">
|
|
<div class="form-grid">
|
|
<div class="form-group full-width">
|
|
<div style="background: var(--info-light, #e0f2fe); padding: var(--spacing-md); border-radius: var(--radius); margin-bottom: var(--spacing-lg);">
|
|
<p style="color: var(--info, #0284c7); font-size: var(--font-size-sm); margin: 0;">
|
|
<svg style="width: 16px; height: 16px; display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
Zaznacz obszary, w ktorych Twoja firma jest otwarta na wspolprace z innymi firmami Norda Biznes. System automatycznie dopasuje firmy o podobnych potrzebach i mozliwosciach.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label" style="font-size: var(--font-size-md); margin-bottom: var(--spacing-md);">
|
|
Obszary gotowosci do wspolpracy IT
|
|
</label>
|
|
|
|
<div class="form-checkbox-group" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--spacing-md);">
|
|
<div style="background: var(--bg-secondary); padding: var(--spacing-md); border-radius: var(--radius); border: 1px solid var(--border);">
|
|
<label class="form-checkbox">
|
|
<input type="checkbox" name="open_to_shared_licensing" id="openToSharedLicensing" value="true">
|
|
<span class="form-checkbox-label" style="font-weight: 500;">Wspolne licencje M365</span>
|
|
</label>
|
|
<p style="font-size: var(--font-size-xs); color: var(--text-tertiary); margin: var(--spacing-xs) 0 0 26px;">
|
|
Zainteresowanie wspolnym zakupem licencji Microsoft 365 w ramach umowy CSP dla uzyskania lepszych cen
|
|
</p>
|
|
</div>
|
|
|
|
<div style="background: var(--bg-secondary); padding: var(--spacing-md); border-radius: var(--radius); border: 1px solid var(--border);">
|
|
<label class="form-checkbox">
|
|
<input type="checkbox" name="open_to_backup_replication" id="openToBackupReplication" value="true">
|
|
<span class="form-checkbox-label" style="font-weight: 500;">Replikacja backupow</span>
|
|
</label>
|
|
<p style="font-size: var(--font-size-xs); color: var(--text-tertiary); margin: var(--spacing-xs) 0 0 26px;">
|
|
Mozliwosc wzajemnej replikacji backupow (np. Proxmox PBS) do innej lokalizacji w ramach wspolpracy DR
|
|
</p>
|
|
</div>
|
|
|
|
<div style="background: var(--bg-secondary); padding: var(--spacing-md); border-radius: var(--radius); border: 1px solid var(--border);">
|
|
<label class="form-checkbox">
|
|
<input type="checkbox" name="open_to_teams_federation" id="openToTeamsFederation" value="true">
|
|
<span class="form-checkbox-label" style="font-weight: 500;">Federacja Teams / Azure AD</span>
|
|
</label>
|
|
<p style="font-size: var(--font-size-xs); color: var(--text-tertiary); margin: var(--spacing-xs) 0 0 26px;">
|
|
Umozliwienie bezposredniej komunikacji Teams i udostepniania zasobow miedzy tenantami Azure AD
|
|
</p>
|
|
</div>
|
|
|
|
<div style="background: var(--bg-secondary); padding: var(--spacing-md); border-radius: var(--radius); border: 1px solid var(--border);">
|
|
<label class="form-checkbox">
|
|
<input type="checkbox" name="open_to_shared_monitoring" id="openToSharedMonitoring" value="true">
|
|
<span class="form-checkbox-label" style="font-weight: 500;">Wspolny monitoring</span>
|
|
</label>
|
|
<p style="font-size: var(--font-size-xs); color: var(--text-tertiary); margin: var(--spacing-xs) 0 0 26px;">
|
|
Wspoldzielenie infrastruktury monitoringu (np. Zabbix proxy) lub wymiana szablonow i wiedzy o monitoringu
|
|
</p>
|
|
</div>
|
|
|
|
<div style="background: var(--bg-secondary); padding: var(--spacing-md); border-radius: var(--radius); border: 1px solid var(--border);">
|
|
<label class="form-checkbox">
|
|
<input type="checkbox" name="open_to_collective_purchasing" id="openToCollectivePurchasing" value="true">
|
|
<span class="form-checkbox-label" style="font-weight: 500;">Wspolne zakupy IT</span>
|
|
</label>
|
|
<p style="font-size: var(--font-size-xs); color: var(--text-tertiary); margin: var(--spacing-xs) 0 0 26px;">
|
|
Zainteresowanie grupowymi zakupami sprzetu IT, oprogramowania lub uslug w celu negocjacji lepszych cen
|
|
</p>
|
|
</div>
|
|
|
|
<div style="background: var(--bg-secondary); padding: var(--spacing-md); border-radius: var(--radius); border: 1px solid var(--border);">
|
|
<label class="form-checkbox">
|
|
<input type="checkbox" name="open_to_knowledge_sharing" id="openToKnowledgeSharing" value="true">
|
|
<span class="form-checkbox-label" style="font-weight: 500;">Wymiana wiedzy IT</span>
|
|
</label>
|
|
<p style="font-size: var(--font-size-xs); color: var(--text-tertiary); margin: var(--spacing-xs) 0 0 26px;">
|
|
Chetna wymiana doswiadczen, uczestnictwo w spotkaniach IT Norda Biznes, wspolne rozwiazywanie problemow
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group full-width">
|
|
<label class="form-label">
|
|
Dodatkowe uwagi dotyczace wspolpracy IT
|
|
</label>
|
|
<textarea class="form-textarea" name="collaboration_notes" id="collaborationNotes" rows="3"
|
|
placeholder="Opisz inne obszary wspolpracy IT, ktore Cie interesuja, lub dodatkowe informacje o mozliwosciach Twojej firmy..."
|
|
style="width: 100%; resize: vertical;">{{ audit.collaboration_notes if audit and audit.collaboration_notes else '' }}</textarea>
|
|
<span class="form-hint">Opcjonalne - mozesz opisac szczegolowe potrzeby lub oferte wspolpracy</span>
|
|
</div>
|
|
|
|
<div class="form-group full-width" style="margin-top: var(--spacing-lg);">
|
|
<div style="background: linear-gradient(135deg, var(--primary-light, #dbeafe) 0%, var(--surface) 100%); padding: var(--spacing-lg); border-radius: var(--radius-lg); border: 1px solid var(--primary);">
|
|
<h4 style="color: var(--primary); margin: 0 0 var(--spacing-sm) 0; font-size: var(--font-size-md);">
|
|
<svg style="width: 20px; height: 20px; display: inline; vertical-align: middle; margin-right: 8px;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
|
</svg>
|
|
Jak dziala dopasowanie?
|
|
</h4>
|
|
<p style="color: var(--text-secondary); font-size: var(--font-size-sm); margin: 0; line-height: 1.6;">
|
|
Po zapisaniu audytu system automatycznie przeanalizuje Twoje odpowiedzi i dopasuje firmy o podobnych technologiach oraz komplementarnych potrzebach wspolpracy.
|
|
Wyniki dopasowania beda widoczne w panelu administratora, a w przyszlosci rowniez na Twoim profilu firmy.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="form-actions">
|
|
<div class="form-actions-left">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
</svg>
|
|
<span>Formularz mozna zapisac w dowolnym momencie. Postep zostanie zachowany.</span>
|
|
</div>
|
|
<div class="form-actions-right">
|
|
<button type="button" class="btn btn-outline" onclick="saveDraft()">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"/>
|
|
</svg>
|
|
Zapisz wersje robocza
|
|
</button>
|
|
<button type="submit" class="btn btn-primary" id="submitBtn">
|
|
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
</svg>
|
|
Zapisz audyt
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Loading Overlay -->
|
|
<div class="loading-overlay" id="loadingOverlay">
|
|
<div class="loading-content">
|
|
<div class="loading-spinner"></div>
|
|
<h3>Zapisywanie audytu...</h3>
|
|
<p>Prosze czekac, dane sa przetwarzane.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Info Modal -->
|
|
<div class="modal" id="infoModal">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<div class="modal-icon success" id="modalIcon">
|
|
<svg width="24" height="24" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
</svg>
|
|
</div>
|
|
<div class="modal-title" id="modalTitle">Informacja</div>
|
|
</div>
|
|
<div class="modal-body" id="modalBody">
|
|
Tresc informacji.
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn btn-primary" onclick="closeInfoModal()">OK</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% 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 %}
|