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

247 lines
No EOL
9.2 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">
{% if subnet %}Edit Subnet{% else %}New Subnet{% endif %}
</h2>
</div>
</div>
</div>
<div class="card mt-3">
<div class="card-body">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST"
action="{% if subnet %}{{ url_for('ipam.subnet_edit', subnet_id=subnet.id) }}{% else %}{{ url_for('ipam.subnet_new') }}{% endif %}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<!-- IP Address and Prefix Selection -->
<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="ip-address" placeholder="192.168.1.0" required
value="{% if subnet %}{{ subnet.cidr.split('/')[0] }}{% endif %}">
</div>
<div class="col-md-4">
<label class="form-label required">Prefix</label>
<select class="form-select" id="prefix" required>
{% for i in range(8, 31) %}
<option value="{{ i }}" {% if subnet and subnet.cidr.split('/')[1]|int==i %}selected{% endif %}>
{{ i }} ({{ 2**(32-i) }} hosts)
</option>
{% endfor %}
</select>
</div>
</div>
<!-- Hidden CIDR field to submit combined value -->
<input type="hidden" name="cidr" id="cidr-value" value="{% if subnet %}{{ subnet.cidr }}{% endif %}">
<div class="mb-3">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<label for="location_id" class="form-label required">Location</label>
<select class="form-select" id="location_id" name="location_id" required>
<option value="">Select a location</option>
{% for location in locations %}
<option value="{{ location.id }}" {% if subnet and subnet.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">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="auto_scan" id="auto_scan" {% if subnet and
subnet.auto_scan %}checked{% endif %}>
<label class="form-check-label" for="auto_scan">
Auto-scan for active hosts
</label>
</div>
</div>
<div class="form-footer">
<button type="submit" class="btn btn-primary">Save</button>
<a href="{% if subnet %}{{ url_for('ipam.subnet_view', subnet_id=subnet.id) }}{% else %}{{ url_for('ipam.ipam_home') }}{% endif %}"
class="btn btn-outline-secondary ms-2">Cancel</a>
</div>
</form>
</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">Location Name</label>
<input type="text" class="form-control" id="new-location-name" required>
</div>
<div class="mb-3">
<label class="form-label">Description</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 () {
// Handle CIDR combination
const ipAddressInput = document.getElementById('ip-address');
const prefixSelect = document.getElementById('prefix');
const cidrValue = document.getElementById('cidr-value');
function updateCIDR() {
const ip = ipAddressInput.value.trim();
const prefix = prefixSelect.value;
if (ip) {
cidrValue.value = `${ip}/${prefix}`;
}
}
if (ipAddressInput && prefixSelect && cidrValue) {
ipAddressInput.addEventListener('input', updateCIDR);
prefixSelect.addEventListener('change', updateCIDR);
}
// 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 bsModal = 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 = '';
bsModal.hide();
})
.catch(error => {
console.error('Error:', error);
alert('Failed to create location: ' + error.message);
});
});
}
});
</script>
{% endblock %}
{% block scripts %}
<script>
document.addEventListener('DOMContentLoaded', function () {
// Handle CIDR combination
const ipAddressInput = document.getElementById('ip-address');
const prefixSelect = document.getElementById('prefix');
const cidrValue = document.getElementById('cidr-value');
function updateCIDR() {
const ip = ipAddressInput.value.trim();
const prefix = prefixSelect.value;
if (ip) {
cidrValue.value = `${ip}/${prefix}`;
}
}
if (ipAddressInput && prefixSelect && cidrValue) {
ipAddressInput.addEventListener('input', updateCIDR);
prefixSelect.addEventListener('change', updateCIDR);
}
// 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 bsModal = 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 = '';
bsModal.hide();
})
.catch(error => {
console.error('Error:', error);
alert('Failed to create location: ' + error.message);
});
});
}
});
</script>
{% endblock %}