Initial Commit
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
h2 {
|
||||
cursor: pointer;
|
||||
}
|
||||
form:not(.mb-6), .mt-4 {
|
||||
display: none;
|
||||
}
|
||||
.allocated-ips {
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.button-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 1rem;
|
||||
justify-items: center;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
@import "tailwindcss"
|
||||
@@ -0,0 +1,15 @@
|
||||
function validateSubnetForm() {
|
||||
const cidrInput = document.getElementById('cidr-input');
|
||||
const errorSpan = document.getElementById('cidr-error');
|
||||
const cidrPattern = /^(?:\d{1,3}\.){3}\d{1,3}\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
||||
if (!cidrPattern.test(cidrInput.value.trim())) {
|
||||
errorSpan.textContent = 'Please enter a valid CIDR (e.g., 192.168.1.0/24)';
|
||||
errorSpan.classList.remove('hidden');
|
||||
cidrInput.classList.add('border-red-500');
|
||||
return false;
|
||||
}
|
||||
errorSpan.textContent = '';
|
||||
errorSpan.classList.add('hidden');
|
||||
cidrInput.classList.remove('border-red-500');
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const siteSelect = document.getElementById('site-select');
|
||||
const subnetSelect = document.getElementById('subnet-select');
|
||||
const ipSelect = document.getElementById('ip-select');
|
||||
const renameBtn = document.querySelector('.rename-btn');
|
||||
const saveBtn = document.querySelector('.save-btn');
|
||||
const cancelBtn = document.querySelector('.cancel-btn');
|
||||
const nameInput = document.querySelector('input[name="new_name"]');
|
||||
const h1 = document.querySelector('h1');
|
||||
siteSelect.addEventListener('change', function() {
|
||||
const selectedSite = this.value;
|
||||
let firstSubnet = null;
|
||||
Array.from(subnetSelect.options).forEach(option => {
|
||||
if (!option.value) return;
|
||||
if (option.getAttribute('data-site') === selectedSite) {
|
||||
option.style.display = '';
|
||||
if (!firstSubnet) firstSubnet = option.value;
|
||||
} else {
|
||||
option.style.display = 'none';
|
||||
}
|
||||
});
|
||||
subnetSelect.value = firstSubnet || '';
|
||||
const event = new Event('change', { bubbles: true });
|
||||
subnetSelect.dispatchEvent(event);
|
||||
});
|
||||
subnetSelect.addEventListener('change', function() {
|
||||
const subnetId = this.value;
|
||||
if (!subnetId) {
|
||||
ipSelect.innerHTML = '<option value="" disabled selected>Select IP</option>';
|
||||
return;
|
||||
}
|
||||
fetch(`/get_available_ips?subnet_id=${subnetId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
ipSelect.innerHTML = '<option value="" disabled selected>Select IP</option>';
|
||||
data.available_ips.forEach(ip => {
|
||||
const option = document.createElement('option');
|
||||
option.value = ip.id;
|
||||
option.textContent = ip.ip;
|
||||
ipSelect.appendChild(option);
|
||||
});
|
||||
});
|
||||
});
|
||||
if (renameBtn && saveBtn && cancelBtn && nameInput && h1) {
|
||||
renameBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
nameInput.classList.remove('hidden');
|
||||
saveBtn.classList.remove('hidden');
|
||||
cancelBtn.classList.remove('hidden');
|
||||
h1.classList.add('hidden');
|
||||
nameInput.focus();
|
||||
});
|
||||
cancelBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
nameInput.classList.add('hidden');
|
||||
saveBtn.classList.add('hidden');
|
||||
cancelBtn.classList.add('hidden');
|
||||
h1.classList.remove('hidden');
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// Expand/collapse site groups
|
||||
document.querySelectorAll('.site-header').forEach(header => {
|
||||
header.addEventListener('click', function(e) {
|
||||
const deviceList = this.closest('.site-group').querySelector('.device-list');
|
||||
const icon = this.querySelector('.expand-btn i');
|
||||
if (deviceList.classList.contains('hidden')) {
|
||||
deviceList.classList.remove('hidden');
|
||||
icon.classList.remove('fa-chevron-down');
|
||||
icon.classList.add('fa-chevron-up');
|
||||
} else {
|
||||
deviceList.classList.add('hidden');
|
||||
icon.classList.remove('fa-chevron-up');
|
||||
icon.classList.add('fa-chevron-down');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Search functionality
|
||||
const searchInput = document.getElementById('search');
|
||||
searchInput.addEventListener('keypress', function(event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
const query = this.value.toLowerCase();
|
||||
document.querySelectorAll('.site-group').forEach(siteGroup => {
|
||||
let anyVisible = false;
|
||||
siteGroup.querySelectorAll('.device-list li').forEach(li => {
|
||||
const deviceName = li.querySelector('span').textContent.toLowerCase();
|
||||
const ipSpans = li.querySelectorAll('span.inline-block');
|
||||
let match = deviceName.includes(query);
|
||||
if (!match) {
|
||||
ipSpans.forEach(ipSpan => {
|
||||
if (ipSpan.textContent.toLowerCase().includes(query)) {
|
||||
match = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
li.style.display = match ? '' : 'none';
|
||||
const card = li.querySelector('a');
|
||||
if (match) {
|
||||
anyVisible = true;
|
||||
siteGroup.querySelector('.device-list').classList.remove('hidden');
|
||||
const icon = siteGroup.querySelector('.expand-btn i');
|
||||
if (icon && icon.classList.contains('fa-chevron-down')) {
|
||||
icon.classList.remove('fa-chevron-down');
|
||||
icon.classList.add('fa-chevron-up');
|
||||
}
|
||||
if (card) {
|
||||
card.style.transition = 'background-color 0.3s';
|
||||
card.style.backgroundColor = '#2563eb';
|
||||
card.style.color = '#fff';
|
||||
setTimeout(() => {
|
||||
card.style.backgroundColor = '';
|
||||
card.style.color = '';
|
||||
}, 2000);
|
||||
}
|
||||
} else {
|
||||
if (card) {
|
||||
card.style.backgroundColor = '';
|
||||
card.style.color = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
siteGroup.style.display = anyVisible ? '' : 'none';
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Scroll to Top Button
|
||||
const scrollToTopButton = document.createElement('button');
|
||||
scrollToTopButton.innerHTML = '<i class="fas fa-arrow-up"></i>';
|
||||
scrollToTopButton.style.fontSize = '26px';
|
||||
scrollToTopButton.className = 'fixed bottom-5 right-5 bg-gray-800 text-white p-3 rounded-full shadow-lg hidden';
|
||||
scrollToTopButton.style.width = '60px';
|
||||
scrollToTopButton.style.height = '60px';
|
||||
scrollToTopButton.style.borderRadius = '50%';
|
||||
document.body.appendChild(scrollToTopButton);
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@keyframes bob {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
}
|
||||
|
||||
.bobbing {
|
||||
animation: bob 1.5s infinite;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
scrollToTopButton.classList.add('bobbing');
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.scrollY > 200) {
|
||||
scrollToTopButton.classList.remove('hidden');
|
||||
} else {
|
||||
scrollToTopButton.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
scrollToTopButton.addEventListener('click', () => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
document.querySelectorAll('.export-csv-btn').forEach(btn => {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
const subnetId = this.getAttribute('data-subnet-id');
|
||||
window.location.href = `/subnet/${subnetId}/export_csv`;
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const mobileNav = document.getElementById('mobile-nav');
|
||||
navToggle.addEventListener('click', function() {
|
||||
mobileNav.classList.toggle('hidden');
|
||||
});
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!mobileNav.contains(e.target) && !navToggle.contains(e.target)) {
|
||||
mobileNav.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('.site-header').forEach(header => {
|
||||
header.addEventListener('click', function(e) {
|
||||
if (e.target.closest('button')) return;
|
||||
const subnetList = this.closest('.site-group').querySelector('.subnet-list');
|
||||
const icon = this.querySelector('.expand-btn i');
|
||||
if (subnetList.classList.contains('hidden')) {
|
||||
subnetList.classList.remove('hidden');
|
||||
icon.classList.remove('fa-chevron-down');
|
||||
icon.classList.add('fa-chevron-up');
|
||||
} else {
|
||||
subnetList.classList.add('hidden');
|
||||
icon.classList.remove('fa-chevron-up');
|
||||
icon.classList.add('fa-chevron-down');
|
||||
}
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.expand-btn').forEach(btn => {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
const subnetList = this.closest('.site-group').querySelector('.subnet-list');
|
||||
const icon = this.querySelector('i');
|
||||
if (subnetList.classList.contains('hidden')) {
|
||||
subnetList.classList.remove('hidden');
|
||||
icon.classList.remove('fa-chevron-down');
|
||||
icon.classList.add('fa-chevron-up');
|
||||
} else {
|
||||
subnetList.classList.add('hidden');
|
||||
icon.classList.remove('fa-chevron-up');
|
||||
icon.classList.add('fa-chevron-down');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const form = document.querySelector('form');
|
||||
if (form) {
|
||||
form.addEventListener('submit', (event) => {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
const searchInput = document.createElement('input');
|
||||
searchInput.type = 'text';
|
||||
searchInput.placeholder = 'Search by IP or Hostname';
|
||||
searchInput.className = 'p-2 w-full rounded-lg bg-gray-800 text-gray-100 border border-gray-600 focus:outline-none focus:border-blue-400 mb-4 text-center';
|
||||
form.insertAdjacentElement('beforebegin', searchInput);
|
||||
|
||||
searchInput.addEventListener('keypress', (event) => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
const searchTerm = searchInput.value.toLowerCase();
|
||||
const rows = document.querySelectorAll('tbody tr');
|
||||
|
||||
rows.forEach(row => {
|
||||
const ipCell = row.querySelector('td:nth-child(1)').textContent.toLowerCase();
|
||||
const hostnameCell = row.querySelector('td:nth-child(2)').textContent.toLowerCase();
|
||||
|
||||
if (ipCell.includes(searchTerm) || hostnameCell.includes(searchTerm)) {
|
||||
row.style.backgroundColor = 'rgba(59, 130, 246, 0.5)';
|
||||
row.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
|
||||
setTimeout(() => {
|
||||
row.style.backgroundColor = '';
|
||||
}, 3000);
|
||||
} else {
|
||||
row.style.backgroundColor = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Scroll to Top Button
|
||||
const scrollToTopButton = document.createElement('button');
|
||||
scrollToTopButton.innerHTML = '<i class="fas fa-arrow-up"></i>';
|
||||
scrollToTopButton.style.fontSize = '26px';
|
||||
scrollToTopButton.className = 'fixed bottom-5 right-5 bg-gray-800 text-white p-3 rounded-full shadow-lg hidden';
|
||||
scrollToTopButton.style.width = '60px';
|
||||
scrollToTopButton.style.height = '60px';
|
||||
scrollToTopButton.style.borderRadius = '50%';
|
||||
document.body.appendChild(scrollToTopButton);
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@keyframes bob {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
}
|
||||
|
||||
.bobbing {
|
||||
animation: bob 1.5s infinite;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
scrollToTopButton.classList.add('bobbing');
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.scrollY > 200) {
|
||||
scrollToTopButton.classList.remove('hidden');
|
||||
} else {
|
||||
scrollToTopButton.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
scrollToTopButton.addEventListener('click', () => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
});
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Reference in New Issue
Block a user