- Strip emojis from 47 markdown files across docs/, sql/, and root - Add docs/DOCS_CONSOLIDATION_PLAN.md with plan to reduce 45 docs to 8 - Establish no-emoji rule for documentation going forward 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
25 KiB
Network Devices - Unified Page Design
Date: 2025-10-23 Approach: Single "Network Devices" page showing all infrastructure with filtering Files Required: 4 files total
Concept: One Page to Rule Them All
Instead of separate pages per device type, create a unified Network Devices page that shows:
- Servers
- Switches
- 📹 Cameras
- Access Points (if you add them later)
- IDFs (Intermediate Distribution Frames)
User Experience:
- Click "Network Devices" → See ALL devices in one table
- Filter by type using tabs/dropdown
- Click any device → Detail page (works for all types)
- "Add Device" button → Select type, then add
Page Architecture
Main Pages (4 files)
network_devices.asp → List all devices with type filter
network_device_detail.asp?type=server&id=5 → View/edit any device
add_network_device.asp?type=server → Add new device (any type)
save_network_device.asp → Universal save endpoint
Navigation
Main Menu:
└─ Network Devices (single menu item)
└─ Opens network_devices.asp with tabs for filtering
File 1: network_devices.asp (Main List View)
Features
- Tabs/Filter: All | Servers | Switches | Cameras | Access Points | IDFs
- Unified Table: Shows all device types in one view
- Device Type Badge: Visual indicator (Server, Switch, Camera, etc.)
- Search: Filter by vendor, model, IP, serial number
- Actions: View/Edit/Delete per device
UI Mockup
┌─────────────────────────────────────────────────────────────┐
│ Network Devices [+ Add Device] │
├─────────────────────────────────────────────────────────────┤
│ [ All ] [ Servers ] [ Switches ] [ Cameras ] [ More ▼ ] │
├─────────────────────────────────────────────────────────────┤
│ Type | Vendor | Model | Serial | IP │
├─────────────────────────────────────────────────────────────┤
│ [Server] | Dell | PowerEdge | ABC123 | 10.0.1.5 │
│ [Switch] | Cisco | Catalyst 2960| XYZ789 | 10.0.1.1 │
│ [Camera] | Hikvision | DS-2CD2142FWD| CAM001 | 10.0.2.10 │
│ [Server] | HP | ProLiant | SRV456 | 10.0.1.6 │
└─────────────────────────────────────────────────────────────┘
Code Structure
<%
' Get filter parameter (default = all)
Dim filterType
filterType = Request.QueryString("filter")
If filterType = "" Then filterType = "all"
' Build query using vw_network_devices view
Dim strSQL
If filterType = "all" Then
strSQL = "SELECT * FROM vw_network_devices WHERE isactive = 1 ORDER BY device_type, device_id DESC"
Else
' Filter by specific type (server, switch, camera)
strSQL = "SELECT * FROM vw_network_devices WHERE device_type = '" & filterType & "' AND isactive = 1 ORDER BY device_id DESC"
End If
Set rs = objConn.Execute(strSQL)
%>
<!-- Tabs -->
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link <%If filterType="all" Then Response.Write("active")%>"
href="network_devices.asp?filter=all">All Devices</a>
</li>
<li class="nav-item">
<a class="nav-link <%If filterType="Server" Then Response.Write("active")%>"
href="network_devices.asp?filter=Server">Servers</a>
</li>
<li class="nav-item">
<a class="nav-link <%If filterType="Switch" Then Response.Write("active")%>"
href="network_devices.asp?filter=Switch">Switches</a>
</li>
<li class="nav-item">
<a class="nav-link <%If filterType="Camera" Then Response.Write("active")%>"
href="network_devices.asp?filter=Camera">Cameras</a>
</li>
</ul>
<!-- Table -->
<table class="table table-hover">
<thead>
<tr>
<th>Type</th>
<th>Vendor</th>
<th>Model</th>
<th>Serial Number</th>
<th>IP Address</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% Do While Not rs.EOF %>
<tr>
<td>
<%
' Device type badge with icon
Dim badgeClass, iconClass
Select Case rs("device_type")
Case "Server"
badgeClass = "badge-primary"
iconClass = "zmdi-storage"
Case "Switch"
badgeClass = "badge-success"
iconClass = "zmdi-device-hub"
Case "Camera"
badgeClass = "badge-info"
iconClass = "zmdi-videocam"
End Select
%>
<span class="badge <%=badgeClass%>">
<i class="zmdi <%=iconClass%>"></i> <%=rs("device_type")%>
</span>
</td>
<td><%=Server.HTMLEncode(rs("vendor") & "")%></td>
<td><%=Server.HTMLEncode(rs("modelnumber") & "")%></td>
<td><%=Server.HTMLEncode(rs("serialnumber") & "")%></td>
<td><%=Server.HTMLEncode(rs("ipaddress") & "")%></td>
<td><%=Server.HTMLEncode(rs("description") & "")%></td>
<td>
<a href="network_device_detail.asp?type=<%=LCase(rs("device_type"))%>&id=<%=rs("device_id")%>">
<i class="zmdi zmdi-edit"></i> View
</a>
</td>
</tr>
<%
rs.MoveNext
Loop
%>
</tbody>
</table>
File 2: network_device_detail.asp (Detail/Edit View)
Features
- Shows device details with vendor/model
- Inline edit form (click Edit button)
- Works for ANY device type
- Map coordinates (if provided)
- Link back to network_devices.asp
Code Structure
<%
' Get type and ID from URL
Dim deviceType, deviceId
deviceType = Request.QueryString("type") ' server, switch, camera
deviceId = Request.QueryString("id")
' Validate type
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
Response.Redirect("network_devices.asp")
Response.End
End If
' Map type to table/field names
Dim tableName, idField, displayName
Select Case deviceType
Case "server"
tableName = "servers"
idField = "serverid"
displayName = "Server"
Case "switch"
tableName = "switches"
idField = "switchid"
displayName = "Switch"
Case "camera"
tableName = "cameras"
idField = "cameraid"
displayName = "Camera"
End Select
' Fetch device with model/vendor
strSQL = "SELECT d.*, m.modelnumber, m.modelnumberid, v.vendor, v.vendorid " & _
"FROM " & tableName & " d " & _
"LEFT JOIN models m ON d.modelid = m.modelnumberid " & _
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE d." & idField & " = " & deviceId
Set rs = objConn.Execute(strSQL)
If rs.EOF Then
Response.Write("Device not found")
Response.End
End If
%>
<div class="content-wrapper">
<a href="network_devices.asp" class="btn btn-secondary">
<i class="zmdi zmdi-arrow-left"></i> Back to Network Devices
</a>
<h2><%=displayName%> #<%=deviceId%></h2>
<!-- Display Mode -->
<div id="displayMode">
<table class="table table-bordered">
<tr>
<th>Vendor</th>
<td><%=Server.HTMLEncode(rs("vendor") & "N/A")%></td>
</tr>
<tr>
<th>Model</th>
<td><%=Server.HTMLEncode(rs("modelnumber") & "N/A")%></td>
</tr>
<tr>
<th>Serial Number</th>
<td><%=Server.HTMLEncode(rs("serialnumber") & "")%></td>
</tr>
<tr>
<th>IP Address</th>
<td><%=Server.HTMLEncode(rs("ipaddress") & "")%></td>
</tr>
<tr>
<th>Description</th>
<td><%=Server.HTMLEncode(rs("description") & "")%></td>
</tr>
<tr>
<th>Map Position</th>
<td>
<% If Not IsNull(rs("maptop")) And Not IsNull(rs("mapleft")) Then %>
Top: <%=rs("maptop")%>, Left: <%=rs("mapleft")%>
<a href="network_map.asp?highlight=<%=deviceType%>_<%=deviceId%>" target="_blank">
<i class="zmdi zmdi-map"></i> View on Map
</a>
<% Else %>
Not mapped
<% End If %>
</td>
</tr>
</table>
<button class="btn btn-primary" onclick="showEditMode()">
<i class="zmdi zmdi-edit"></i> Edit <%=displayName%>
</button>
</div>
<!-- Edit Mode (hidden by default) -->
<div id="editMode" style="display:none;">
<form method="post" action="save_network_device.asp">
<input type="hidden" name="type" value="<%=deviceType%>">
<input type="hidden" name="id" value="<%=deviceId%>">
<div class="form-group">
<label>Model</label>
<select name="modelid" class="form-control">
<option value="">-- No Model --</option>
<%
Dim strSQL2, rsModels
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF
Dim selected
If Not IsNull(rs("modelnumberid")) Then
If rsModels("modelnumberid") = rs("modelnumberid") Then
selected = "selected"
Else
selected = ""
End If
End If
%>
<option value="<%=rsModels("modelnumberid")%>" <%=selected%>>
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
</option>
<%
rsModels.MoveNext
Loop
rsModels.Close
Set rsModels = Nothing
%>
</select>
</div>
<div class="form-group">
<label>Serial Number</label>
<input type="text" name="serialnumber" class="form-control"
value="<%=Server.HTMLEncode(rs("serialnumber") & "")%>" maxlength="100">
</div>
<div class="form-group">
<label>IP Address</label>
<input type="text" name="ipaddress" class="form-control"
value="<%=Server.HTMLEncode(rs("ipaddress") & "")%>"
maxlength="15" pattern="^[0-9\.]+$">
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" class="form-control" rows="3"><%=Server.HTMLEncode(rs("description") & "")%></textarea>
</div>
<div class="form-group">
<label>Map Position (Optional)</label>
<div class="row">
<div class="col-md-6">
<input type="number" name="maptop" class="form-control"
placeholder="Top (Y)" value="<%=rs("maptop") & ""%>">
</div>
<div class="col-md-6">
<input type="number" name="mapleft" class="form-control"
placeholder="Left (X)" value="<%=rs("mapleft") & ""%>">
</div>
</div>
</div>
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i> Save Changes
</button>
<button type="button" class="btn btn-secondary" onclick="showDisplayMode()">
Cancel
</button>
</form>
</div>
</div>
<script>
function showEditMode() {
document.getElementById('displayMode').style.display = 'none';
document.getElementById('editMode').style.display = 'block';
}
function showDisplayMode() {
document.getElementById('displayMode').style.display = 'block';
document.getElementById('editMode').style.display = 'none';
}
</script>
File 3: add_network_device.asp (Add Form)
Features
- First: Select device type (Server, Switch, Camera, etc.)
- Then: Show form with fields
- Model/vendor dropdown
- All standard fields
- Optional map coordinates
Code Structure
<%
' Get device type (from URL or form)
Dim deviceType
deviceType = Request.QueryString("type")
' If no type selected, show type selector
If deviceType = "" OR (deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera") Then
%>
<div class="content-wrapper">
<h2>Add Network Device</h2>
<p>Select the type of device you want to add:</p>
<div class="row">
<div class="col-md-4">
<div class="card text-center">
<div class="card-body">
<i class="zmdi zmdi-storage" style="font-size:48px;"></i>
<h5>Server</h5>
<a href="add_network_device.asp?type=server" class="btn btn-primary">
Add Server
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center">
<div class="card-body">
<i class="zmdi zmdi-device-hub" style="font-size:48px;"></i>
<h5>Switch</h5>
<a href="add_network_device.asp?type=switch" class="btn btn-success">
Add Switch
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card text-center">
<div class="card-body">
<i class="zmdi zmdi-videocam" style="font-size:48px;"></i>
<h5>Camera</h5>
<a href="add_network_device.asp?type=camera" class="btn btn-info">
Add Camera
</a>
</div>
</div>
</div>
</div>
<a href="network_devices.asp" class="btn btn-secondary">Cancel</a>
</div>
<%
Response.End
End If
' Type is selected, show form
Dim displayName
Select Case deviceType
Case "server": displayName = "Server"
Case "switch": displayName = "Switch"
Case "camera": displayName = "Camera"
End Select
%>
<div class="content-wrapper">
<h2>Add <%=displayName%></h2>
<form method="post" action="save_network_device.asp">
<input type="hidden" name="type" value="<%=deviceType%>">
<div class="form-group">
<label>Model <span class="text-danger">*</span></label>
<select name="modelid" required class="form-control">
<option value="">-- Select Model --</option>
<%
strSQL = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL)
Do While Not rsModels.EOF
%>
<option value="<%=rsModels("modelnumberid")%>">
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
</option>
<%
rsModels.MoveNext
Loop
rsModels.Close
Set rsModels = Nothing
%>
</select>
<small class="form-text text-muted">
Don't see your model? <a href="addmodel.asp" target="_blank">Add a new model first</a>
</small>
</div>
<div class="form-group">
<label>Serial Number</label>
<input type="text" name="serialnumber" class="form-control" maxlength="100">
</div>
<div class="form-group">
<label>IP Address</label>
<input type="text" name="ipaddress" class="form-control"
maxlength="15" pattern="^[0-9\.]+$" placeholder="192.168.1.100">
</div>
<div class="form-group">
<label>Description</label>
<textarea name="description" class="form-control" rows="3"
placeholder="Location, purpose, notes..."></textarea>
</div>
<div class="form-group">
<label>Map Position (Optional)</label>
<div class="row">
<div class="col-md-6">
<input type="number" name="maptop" class="form-control"
placeholder="Top (Y coordinate)">
</div>
<div class="col-md-6">
<input type="number" name="mapleft" class="form-control"
placeholder="Left (X coordinate)">
</div>
</div>
<small class="form-text text-muted">
Used for network map visualization. Leave blank if unknown.
</small>
</div>
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i> Add <%=displayName%>
</button>
<a href="network_devices.asp" class="btn btn-secondary">Cancel</a>
</form>
</div>
File 4: save_network_device.asp (Universal Save)
Features
- Handles INSERT and UPDATE for all device types
- Validates all inputs
- Redirects back to appropriate page
Code Structure
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/db_helpers.asp"-->
<%
' Get device type
Dim deviceType
deviceType = Request.Form("type")
' Validate type
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
Response.Write("Error: Invalid device type")
Response.End
End If
' Map to table/field names
Dim tableName, idField
Select Case deviceType
Case "server"
tableName = "servers"
idField = "serverid"
Case "switch"
tableName = "switches"
idField = "switchid"
Case "camera"
tableName = "cameras"
idField = "cameraid"
End Select
' Get and validate form data
Dim deviceId, modelid, serialnumber, ipaddress, description, maptop, mapleft
deviceId = GetSafeInteger("FORM", "id", 0, 0, 999999)
modelid = GetSafeInteger("FORM", "modelid", 0, 0, 999999)
serialnumber = GetSafeString("FORM", "serialnumber", "", 0, 100, "^[A-Za-z0-9\-\s]*$")
ipaddress = GetSafeString("FORM", "ipaddress", "", 0, 15, "^[0-9\.]*$")
description = GetSafeString("FORM", "description", "", 0, 255, "")
maptop = GetSafeInteger("FORM", "maptop", 0, 0, 999999)
mapleft = GetSafeInteger("FORM", "mapleft", 0, 0, 999999)
' Convert 0 to NULL for optional fields
If modelid = 0 Then modelid = Null
If maptop = 0 Then maptop = Null
If mapleft = 0 Then mapleft = Null
' Validate required fields
If IsNull(modelid) Then
Response.Write("Error: Model is required")
Response.End
End If
' Build query
Dim strSQL
If deviceId = 0 Then
' INSERT - New device
strSQL = "INSERT INTO " & tableName & " " & _
"(modelid, serialnumber, ipaddress, description, maptop, mapleft, isactive) " & _
"VALUES (?, ?, ?, ?, ?, ?, 1)"
Set rs = ExecuteParameterizedQuery(objConn, strSQL, _
Array(modelid, serialnumber, ipaddress, description, maptop, mapleft))
' Get new ID for redirect
deviceId = objConn.Execute("SELECT LAST_INSERT_ID() as newid")(0)
Else
' UPDATE - Existing device
strSQL = "UPDATE " & tableName & " " & _
"SET modelid = ?, serialnumber = ?, ipaddress = ?, description = ?, " & _
" maptop = ?, mapleft = ? " & _
"WHERE " & idField & " = ?"
Set rs = ExecuteParameterizedQuery(objConn, strSQL, _
Array(modelid, serialnumber, ipaddress, description, maptop, mapleft, deviceId))
End If
Call CleanupResources()
' Redirect to detail page
Response.Redirect("network_device_detail.asp?type=" & deviceType & "&id=" & deviceId)
%>
Navigation Update
leftsidebar.asp
<!-- Network Section -->
<li class="nav-header">NETWORK</li>
<li>
<a href="network_devices.asp">
<i class="zmdi zmdi-devices"></i> Network Devices
</a>
</li>
<li>
<a href="network_map.asp">
<i class="zmdi zmdi-map"></i> Network Map
</a>
</li>
<li>
<a href="displaysubnets.asp">
<i class="zmdi zmdi-network"></i> Subnets
</a>
</li>
Database View: vw_network_devices
The migration script already creates this! It unifies all infrastructure:
CREATE VIEW vw_network_devices AS
SELECT
'Server' AS device_type,
serverid AS device_id,
modelid, modelnumber, vendor,
serialnumber, ipaddress, description,
maptop, mapleft, isactive
FROM servers
LEFT JOIN models ON servers.modelid = models.modelnumberid
LEFT JOIN vendors ON models.vendorid = vendors.vendorid
UNION ALL
SELECT
'Switch' AS device_type,
switchid AS device_id,
modelid, modelnumber, vendor,
serialnumber, ipaddress, description,
maptop, mapleft, isactive
FROM switches
LEFT JOIN models ON switches.modelid = models.modelnumberid
LEFT JOIN vendors ON models.vendorid = vendors.vendorid
UNION ALL
SELECT
'Camera' AS device_type,
cameraid AS device_id,
modelid, modelnumber, vendor,
serialnumber, ipaddress, description,
maptop, mapleft, isactive
FROM cameras
LEFT JOIN models ON cameras.modelid = models.modelnumberid
LEFT JOIN vendors ON models.vendorid = vendors.vendorid
Future: Adding More Device Types
To add Access Points or IDFs later:
-
Database:
CREATE TABLE accesspoints ( accesspointid INT(11) PRIMARY KEY AUTO_INCREMENT, modelid INT(11), serialnumber VARCHAR(100), ipaddress VARCHAR(15), description VARCHAR(255), maptop INT(11), mapleft INT(11), isactive BIT(1) DEFAULT b'1', FOREIGN KEY (modelid) REFERENCES models(modelnumberid) ); -- Add to view ALTER VIEW vw_network_devices AS -- ... existing unions ... UNION ALL SELECT 'Access Point' AS device_type, accesspointid AS device_id, ... FROM accesspoints ... -
Code: Just add new case to Select statements!
Case "accesspoint" tableName = "accesspoints" idField = "accesspointid" displayName = "Access Point" -
UI: Add new tab to network_devices.asp
That's it! The unified design makes it trivial to extend.
Summary: Why This Is Better
Single source of truth - One page for all infrastructure
Easy filtering - Tabs to view by type or see all
Consistent UX - Same interface for all device types
Uses existing view - vw_network_devices already unifies them
Only 4 files - vs 12 separate files
Easy to extend - Add new device types without file duplication
Matches mental model - "Network Devices" is how users think
Search/filter across all - Find any device in one place
Ready to build? This is the cleanest approach!