This commit is contained in:
pika 2025-04-03 16:58:01 +02:00
parent 2b36992be1
commit 25087d055c
16 changed files with 1394 additions and 816 deletions

View file

@ -52,9 +52,26 @@
<input type="hidden" name="cidr" id="cidr-value" value="{% if subnet %}{{ subnet.cidr }}{% endif %}">
<div class="mb-3">
<label class="form-label required">Location</label>
<input type="text" class="form-control" name="location" required
value="{% if subnet %}{{ subnet.location }}{% endif %}">
<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">
@ -77,48 +94,154 @@
</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 cidrValueInput = document.getElementById('cidr-value');
const cidrValue = document.getElementById('cidr-value');
// Function to update the hidden CIDR field
function updateCidrValue() {
function updateCIDR() {
const ip = ipAddressInput.value.trim();
const prefix = prefixSelect.value;
if (ip) {
cidrValueInput.value = `${ip}/${prefix}`;
cidrValue.value = `${ip}/${prefix}`;
}
}
// Add event listeners
ipAddressInput.addEventListener('input', updateCidrValue);
prefixSelect.addEventListener('change', updateCidrValue);
if (ipAddressInput && prefixSelect && cidrValue) {
ipAddressInput.addEventListener('input', updateCIDR);
prefixSelect.addEventListener('change', updateCIDR);
}
// Initialize CIDR value if editing
if (cidrValueInput.value) {
const parts = cidrValueInput.value.split('/');
if (parts.length === 2) {
ipAddressInput.value = parts[0];
const prefix = parseInt(parts[1]);
if (!isNaN(prefix) && prefix >= 8 && prefix <= 30) {
prefixSelect.value = prefix;
// 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}`;
}
}
// Ensure form submission updates the CIDR value
document.querySelector('form').addEventListener('submit', function (e) {
updateCidrValue();
if (ipAddressInput && prefixSelect && cidrValue) {
ipAddressInput.addEventListener('input', updateCIDR);
prefixSelect.addEventListener('change', updateCIDR);
}
// Basic validation
if (!cidrValueInput.value) {
e.preventDefault();
alert('Please enter a valid IP address and prefix');
}
});
// 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 %}