Last active
August 2, 2025 06:58
-
-
Save akansha-oi/a773698931d144a2eefafd50627a6a14 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| async function showVlanPortConfig() { | |
| showContent('<p>Loading VLAN Port Configuration...</p>'); | |
| try { | |
| const response = await fetch(`${BASE_URL}/get-vlan-information`); | |
| if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); | |
| await response.json(); // Optional: response not used | |
| const portOptions = Array.from({ length: 10 }, (_, i) => `<option value="${i + 1}">${i + 1}</option>`).join(''); | |
| showContent(` | |
| <h2>VLAN Port Configuration</h2> | |
| <p>(p=default VLAN member, t=tagged member, u=untagged member)</p> | |
| <div id="vlan-config" style="display: flex; gap: 30px; align-items: flex-start;"> | |
| <div class="column"> | |
| <strong>Port</strong><br/> | |
| <select style="width:100px;" id="portSelect" size="10">${portOptions}</select> | |
| </div> | |
| <div class="column"> | |
| <strong>Mode</strong><br/> | |
| <select style="width:100px;" id="modeSelect"> | |
| <option value="access">Access</option> | |
| <option value="Hybrid">Hybrid</option> | |
| <option value="trunk">Trunk</option> | |
| </select> | |
| </div> | |
| <div class="column"> | |
| <label>Current VLAN</label><br/> | |
| <select style="width:100px;" size="10" id="vlanSelect" multiple></select> | |
| </div> | |
| <div> | |
| <button id="btnDefault">Default VLAN =></button><br/> | |
| <button id="btnTagged">Tagged =></button><br/> | |
| <button id="btnUntagged">Untagged =></button><br/> | |
| <button id="btnUnmember">UnMember <=</button> | |
| </div> | |
| <div class="column"> | |
| <label>Port Members</label><br/> | |
| <select style="width:100px;" size="10" id="portMembers" multiple></select> | |
| </div> | |
| </div> | |
| <button id="btnRefresh">Refresh</button> | |
| <button onclick="alert('Help: Choose port, mode and VLAN. Then use buttons to apply.')">Help</button> | |
| `); | |
| // Local state encapsulated | |
| let currentVlanPort = ''; | |
| let membershipVlanMap = {}; | |
| const portSelect = document.getElementById('portSelect'); | |
| const modeSelect = document.getElementById('modeSelect'); | |
| const vlanSelect = document.getElementById('vlanSelect'); | |
| const portMembers = document.getElementById('portMembers'); | |
| const btnMap = { | |
| default: document.getElementById('btnDefault'), | |
| tag: document.getElementById('btnTagged'), | |
| untag: document.getElementById('btnUntagged'), | |
| unmember: document.getElementById('btnUnmember'), | |
| }; | |
| // Event listeners | |
| portSelect.addEventListener('change', async () => { | |
| currentVlanPort = portSelect.value; | |
| if (currentVlanPort) await updatePortMembers(); | |
| }); | |
| modeSelect.addEventListener('change', updateButtonStates); | |
| document.getElementById('btnRefresh').addEventListener('click', loadVlans); | |
| Object.entries(btnMap).forEach(([action, button]) => { | |
| button.addEventListener('click', async () => { | |
| const selectedVLANs = Array.from(vlanSelect.selectedOptions).map(opt => opt.value); | |
| const mode = modeSelect.value; | |
| const currentVLANs = Object.keys(membershipVlanMap); | |
| if (!selectedVLANs.length) { | |
| alert("Select at least one VLAN."); | |
| return; | |
| } | |
| if (mode === 'access') { | |
| selectedVLANs.splice(1); | |
| } else if (mode === 'Hybrid') { | |
| const newVLANs = selectedVLANs.filter(v => !currentVLANs.includes(v)); | |
| const total = currentVLANs.length + newVLANs.length; | |
| if (total > 2) { | |
| const vlansToRemove = currentVLANs.slice(0, total - 2); | |
| for (const vlan of vlansToRemove) { | |
| await sendVLANUpdate(vlan, 'unmember'); | |
| delete membershipVlanMap[vlan]; | |
| } | |
| } | |
| } | |
| for (const vlan of selectedVLANs) { | |
| await sendVLANUpdate(vlan, action); | |
| } | |
| await updatePortMembers(); | |
| }); | |
| }); | |
| // Internal helpers | |
| async function loadVlans() { | |
| const res = await fetch(`${BASE_URL}/vlans`); | |
| const vlans = await res.json(); | |
| vlanSelect.innerHTML = ''; | |
| vlans.forEach(v => { | |
| const opt = document.createElement('option'); | |
| opt.value = v.vid; | |
| opt.text = v.vid; | |
| vlanSelect.appendChild(opt); | |
| }); | |
| } | |
| async function updatePortMembers() { | |
| const res = await fetch(`${BASE_URL}/get_vlan_ports/${currentVlanPort}`); | |
| membershipVlanMap = await res.json(); | |
| portMembers.innerHTML = ''; | |
| Object.entries(membershipVlanMap).forEach(([vlan, type]) => { | |
| const opt = document.createElement('option'); | |
| opt.value = vlan; | |
| opt.textContent = `[${type}] ${vlan}`; | |
| portMembers.appendChild(opt); | |
| }); | |
| updateButtonStates(); | |
| } | |
| function updateButtonStates() { | |
| const isAccess = modeSelect.value === 'access'; | |
| btnMap.tag.disabled = isAccess; | |
| btnMap.untag.disabled = isAccess; | |
| btnMap.unmember.disabled = isAccess; | |
| } | |
| async function sendVLANUpdate(vlan, action) { | |
| const res = await fetch(`${BASE_URL}/set_vlan_port`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ | |
| port: currentVlanPort, | |
| vlan, | |
| mode: modeSelect.value, | |
| action | |
| }) | |
| }); | |
| if (!res.ok) { | |
| console.error(`Failed to update VLAN ${vlan}: ${res.status}`); | |
| return; | |
| } | |
| const result = await res.json(); | |
| membershipVlanMap = result.members || membershipVlanMap; | |
| } | |
| // Initial load | |
| await loadVlans(); | |
| portSelect.value = ''; | |
| } catch (err) { | |
| console.error("Error loading VLAN config:", err); | |
| alert("Failed to load VLAN Port Configuration."); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment