homedocs/app/templates/dashboard/server_form.html
2025-04-03 16:58:01 +02:00

290 lines
No EOL
11 KiB
HTML

{% extends "layout.html" %}
{% block content %}
<div class="container-xl">
<div class="page-header d-print-none">
<div class="row align-items-center">
<div class="col">
<h2 class="page-title">
{{ title }}
</h2>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<div class="card">
<div class="card-body">
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="mb-3">
<label for="hostname" class="form-label">Hostname</label>
<input type="text" class="form-control" id="hostname" name="hostname" required
value="{{ server.hostname if server else '' }}">
</div>
<div class="mb-3">
<label for="ip_address" class="form-label">IP Address</label>
<input type="text" class="form-control" id="ip_address" name="ip_address" required
value="{{ server.ip_address if server else '' }}">
</div>
<div class="mb-3">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<label for="subnet_id" class="form-label">Subnet (optional for public IPs)</label>
<select class="form-select" id="subnet_id" name="subnet_id">
<option value="">No subnet (standalone server)</option>
{% for subnet in subnets %}
<option value="{{ subnet.id }}" {% if server and server.subnet_id==subnet.id %}selected{% endif %}>
{{ subnet.cidr }} ({{ subnet.location_ref.name }})
</option>
{% endfor %}
</select>
</div>
<div class="ms-2 pt-4">
<button type="button" class="btn btn-outline-primary btn-icon" data-bs-toggle="modal"
data-bs-target="#add-subnet-modal">
<span class="ti ti-plus"></span>
</button>
</div>
</div>
</div>
<div class="mb-3">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<label for="location_id" class="form-label">Location (required for standalone servers)</label>
<select class="form-select" id="location_id" name="location_id">
<option value="">Select a location</option>
{% for location in locations %}
<option value="{{ location.id }}" {% if server and server.location_id==location.id %}selected{%
endif %}>
{{ location.name }}
</option>
{% endfor %}
</select>
</div>
<div class="ms-2 pt-4">
<button type="button" class="btn btn-outline-primary btn-icon" data-bs-toggle="modal"
data-bs-target="#add-location-modal">
<span class="ti ti-plus"></span>
</button>
</div>
</div>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description (optional)</label>
<textarea class="form-control" id="description" name="description"
rows="3">{{ server.description if server else '' }}</textarea>
</div>
<div class="form-footer">
<button type="submit" class="btn btn-primary">Save</button>
<a href="{{ url_for('dashboard.server_list') }}" class="btn btn-link">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Add Subnet Modal -->
<div class="modal modal-blur fade" id="add-subnet-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add New Subnet</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="add-subnet-form">
<div class="row mb-3">
<div class="col-md-8">
<label class="form-label required">IP Address</label>
<input type="text" class="form-control" id="new-subnet-ip" placeholder="192.168.1.0" required>
</div>
<div class="col-md-4">
<label class="form-label required">Prefix</label>
<select class="form-select" id="new-subnet-prefix" required>
{% for i in range(8, 31) %}
<option value="{{ i }}">{{ i }} ({{ 2**(32-i) }} hosts)</option>
{% endfor %}
</select>
</div>
</div>
<div class="mb-3">
<label class="form-label required">Location</label>
<select class="form-select" id="new-subnet-location" required>
<option value="">Select a location</option>
{% for location in locations %}
<option value="{{ location.id }}">{{ location.name }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="new-subnet-auto-scan">
<label class="form-check-label" for="new-subnet-auto-scan">
Auto-scan for active hosts
</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link link-secondary" data-bs-dismiss="modal">
Cancel
</button>
<button type="button" class="btn btn-primary ms-auto" id="save-subnet-btn">
<span class="ti ti-plus me-2"></span>
Add Subnet
</button>
</div>
</div>
</div>
</div>
<!-- Add Location Modal -->
<div class="modal modal-blur fade" id="add-location-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add New Location</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="add-location-form">
<div class="mb-3">
<label class="form-label required">Name</label>
<input type="text" class="form-control" id="new-location-name" required>
</div>
<div class="mb-3">
<label class="form-label">Description (optional)</label>
<textarea class="form-control" id="new-location-description" rows="3"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link link-secondary" data-bs-dismiss="modal">
Cancel
</button>
<button type="button" class="btn btn-primary ms-auto" id="save-location-btn">
<span class="ti ti-plus me-2"></span>
Add Location
</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const subnetSelect = document.getElementById('subnet_id');
const locationField = document.querySelector('.mb-3:has(#location_id)');
function updateLocationVisibility() {
if (subnetSelect.value === '') {
locationField.style.display = 'block';
document.getElementById('location_id').setAttribute('required', 'required');
} else {
locationField.style.display = 'none';
document.getElementById('location_id').removeAttribute('required');
}
}
// Initial state
if (locationField) {
updateLocationVisibility();
// Update on change
subnetSelect.addEventListener('change', updateLocationVisibility);
}
// Add subnet functionality
const saveSubnetBtn = document.getElementById('save-subnet-btn');
const addSubnetModal = document.getElementById('add-subnet-modal');
if (saveSubnetBtn && addSubnetModal) {
const bsSubnetModal = new bootstrap.Modal(addSubnetModal);
saveSubnetBtn.addEventListener('click', function () {
const ip = document.getElementById('new-subnet-ip').value.trim();
const prefix = document.getElementById('new-subnet-prefix').value;
const locationId = document.getElementById('new-subnet-location').value;
const autoScan = document.getElementById('new-subnet-auto-scan').checked;
const csrfToken = document.querySelector('input[name="csrf_token"]').value;
if (!ip || !prefix || !locationId) {
alert('All fields are required');
return;
}
apiFunctions.createSubnet(`${ip}/${prefix}`, locationId, autoScan, csrfToken)
.then(data => {
// Add new option to select dropdown
const locationName = document.querySelector(`#new-subnet-location option[value="${locationId}"]`).textContent;
const newOption = new Option(`${data.cidr} (${locationName})`, data.id, true, true);
subnetSelect.add(newOption);
// Reset form and close modal
document.getElementById('new-subnet-ip').value = '';
document.getElementById('new-subnet-prefix').value = '24';
document.getElementById('new-subnet-location').value = '';
document.getElementById('new-subnet-auto-scan').checked = false;
bsSubnetModal.hide();
// Trigger the subnet change event to hide location if needed
const event = new Event('change');
subnetSelect.dispatchEvent(event);
})
.catch(error => {
console.error('Error:', error);
alert('Failed to create subnet: ' + error.message);
});
});
}
// Add location functionality
const saveLocationBtn = document.getElementById('save-location-btn');
const locationSelect = document.getElementById('location_id');
const addLocationModal = document.getElementById('add-location-modal');
if (saveLocationBtn && locationSelect && addLocationModal) {
const bsLocationModal = new bootstrap.Modal(addLocationModal);
saveLocationBtn.addEventListener('click', function () {
const name = document.getElementById('new-location-name').value.trim();
const description = document.getElementById('new-location-description').value.trim();
const csrfToken = document.querySelector('input[name="csrf_token"]').value;
if (!name) {
alert('Location name is required');
return;
}
apiFunctions.createLocation(name, description, csrfToken)
.then(data => {
// Add new option to select dropdown
const newOption = new Option(data.name, data.id, true, true);
locationSelect.add(newOption);
// Reset form and close modal
document.getElementById('new-location-name').value = '';
document.getElementById('new-location-description').value = '';
bsLocationModal.hide();
})
.catch(error => {
console.error('Error:', error);
alert('Failed to create location: ' + error.message);
});
});
}
});
</script>
{% endblock %}