Fix network device description/machinenotes display and edit

- Fix ADO cursor issue where reading rs("description") twice caused
  empty values (IsNull check consumed the field value)
- Change all device pages to read description field once using
  `description = rs("description") & ""` pattern
- Add deviceDescription variable in displaydevice.asp
- Fix machinetypeid mapping: IDF=17, Camera=18 (was swapped)
- Add model dropdown fix to include currently assigned model
- Add server application tracking feature
- Various other improvements and fixes

Files affected:
- displaydevice.asp, displaylocationdevice.asp
- deviceaccesspoint.asp, deviceserver.asp, deviceswitch.asp
- devicecamera.asp, deviceidf.asp
- savenetworkdevice.asp, networkdevices.asp

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2025-12-17 13:47:56 -05:00
parent a5b4013949
commit a4096ace94
25 changed files with 1744 additions and 355 deletions

View File

@@ -23,11 +23,11 @@
' If editing, fetch existing data
Dim rs, servername, modelid, serialnumber, ipaddress, fqdn, description, maptop, mapleft, isactive
Dim vendorname, modelnumber
Dim vendorname, modelnumber, logicmonitorurl
If Not isNewRecord Then
Dim strSQL
strSQL = "SELECT mac.machineid, mac.alias AS servername, mac.modelnumberid AS modelid, " & _
"mac.serialnumber, mac.fqdn, mac.machinenotes AS description, mac.maptop, mac.mapleft, mac.isactive, " & _
"mac.serialnumber, mac.fqdn, mac.logicmonitorurl, mac.machinenotes AS description, mac.maptop, mac.mapleft, mac.isactive, " & _
"m.modelnumber, v.vendor, c.address AS ipaddress " & _
"FROM machines mac " & _
"LEFT JOIN models m ON mac.modelnumberid = m.modelnumberid " & _
@@ -47,7 +47,8 @@
If Not IsNull(rs("serialnumber")) Then serialnumber = rs("serialnumber") & "" Else serialnumber = ""
If Not IsNull(rs("ipaddress")) Then ipaddress = rs("ipaddress") & "" Else ipaddress = ""
If Not IsNull(rs("fqdn")) Then fqdn = rs("fqdn") & "" Else fqdn = ""
If Not IsNull(rs("description")) Then description = rs("description") & "" Else description = ""
If Not IsNull(rs("logicmonitorurl")) Then logicmonitorurl = rs("logicmonitorurl") & "" Else logicmonitorurl = ""
description = rs("description") & ""
If Not IsNull(rs("maptop")) Then maptop = rs("maptop") Else maptop = ""
If Not IsNull(rs("mapleft")) Then mapleft = rs("mapleft") Else mapleft = ""
If Not IsNull(rs("isactive")) Then isactive = rs("isactive") Else isactive = 1
@@ -63,6 +64,7 @@
serialnumber = ""
ipaddress = ""
fqdn = ""
logicmonitorurl = ""
description = ""
maptop = ""
mapleft = ""
@@ -135,12 +137,13 @@
<select name="modelid" id="modelid" class="form-control">
<option value="">-- Select Model --</option>
<%
Dim strSQL2, rsModels
' Filter models to only show Server models (machinetypeid = 20)
Dim strSQL2, rsModels, currentModelId
' Show Server models (machinetypeid = 20) plus currently assigned model
If IsNumeric(modelid) Then currentModelId = CLng(modelid) Else currentModelId = 0
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 AND m.machinetypeid = 20 " & _
"WHERE m.isactive = 1 AND (m.machinetypeid = 20 OR m.modelnumberid = " & currentModelId & ") " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF
@@ -301,6 +304,19 @@
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Logic Monitor URL</label>
<div class="col-sm-9">
<input type="url" name="logicmonitorurl" class="form-control"
value="<%=Server.HTMLEncode(logicmonitorurl)%>"
maxlength="512"
placeholder="e.g., https://company.logicmonitor.com/santaba/uiv3/...">
<small class="form-text text-muted">
Link to this device in Logic Monitor (optional)
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Description</label>
<div class="col-sm-9">
@@ -312,6 +328,74 @@
</div>
</div>
<%If Not isNewRecord Then%>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Hosted Applications</label>
<div class="col-sm-9">
<div id="currentApps" style="margin-bottom:10px;">
<%
' Query applications currently assigned to this server
Dim rsCurrentApps, strAppSQL
strAppSQL = "SELECT ia.installedappid, a.appid, a.appname " & _
"FROM installedapps ia " & _
"INNER JOIN applications a ON ia.appid = a.appid " & _
"WHERE ia.machineid = " & CLng(serverid) & " AND ia.isactive = 1 " & _
"ORDER BY a.appname"
Set rsCurrentApps = objConn.Execute(strAppSQL)
If Not rsCurrentApps.EOF Then
Do While Not rsCurrentApps.EOF
%>
<span class="badge badge-primary mr-2 mb-2" style="font-size:14px; padding:8px 12px;">
<%=Server.HTMLEncode(rsCurrentApps("appname") & "")%>
<input type="hidden" name="currentapps[]" value="<%=rsCurrentApps("appid")%>">
<button type="button" class="btn-remove-app" data-appid="<%=rsCurrentApps("appid")%>"
style="background:none; border:none; color:#fff; margin-left:5px; cursor:pointer; font-size:16px;">&times;</button>
</span>
<%
rsCurrentApps.MoveNext
Loop
Else
%>
<span class="text-muted"><em>No applications assigned</em></span>
<%
End If
rsCurrentApps.Close
Set rsCurrentApps = Nothing
%>
</div>
<div class="input-group">
<select id="addAppSelect" class="form-control">
<option value="">-- Add Application --</option>
<%
' Query all available applications
Dim rsAllApps
strAppSQL = "SELECT appid, appname FROM applications WHERE isactive = 1 ORDER BY appname"
Set rsAllApps = objConn.Execute(strAppSQL)
Do While Not rsAllApps.EOF
%>
<option value="<%=rsAllApps("appid")%>"><%=Server.HTMLEncode(rsAllApps("appname") & "")%></option>
<%
rsAllApps.MoveNext
Loop
rsAllApps.Close
Set rsAllApps = Nothing
%>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addAppBtn">
<i class="zmdi zmdi-plus"></i> Add
</button>
</div>
</div>
<small class="form-text text-muted">
Select applications hosted on this server
</small>
<input type="hidden" name="apps" id="appsInput" value="">
<input type="hidden" name="removedapps" id="removedAppsInput" value="">
</div>
</div>
<%End If%>
<div class="form-group row">
<label class="col-sm-3 col-form-label"></label>
<div class="col-sm-9">
@@ -496,6 +580,63 @@ $(document).ready(function() {
}
}
});
// Application management
var addedApps = [];
var removedApps = [];
// Add application
$('#addAppBtn').on('click', function() {
var appId = $('#addAppSelect').val();
var appName = $('#addAppSelect option:selected').text();
if (appId && appId !== '') {
// Check if already added or already exists
if ($('#currentApps').find('[data-appid="' + appId + '"]').length > 0) {
alert('This application is already assigned to this server');
return;
}
if (addedApps.indexOf(appId) >= 0) {
alert('This application has already been added');
return;
}
addedApps.push(appId);
$('#appsInput').val(addedApps.join(','));
// Add badge
var badge = $('<span class="badge badge-success mr-2 mb-2" style="font-size:14px; padding:8px 12px;">' +
appName +
'<button type="button" class="btn-remove-new-app" data-appid="' + appId + '" ' +
'style="background:none; border:none; color:#fff; margin-left:5px; cursor:pointer; font-size:16px;">&times;</button>' +
'</span>');
if ($('#currentApps').find('.text-muted').length > 0) {
$('#currentApps').html('');
}
$('#currentApps').append(badge);
$('#addAppSelect').val('');
}
});
// Remove newly added application
$(document).on('click', '.btn-remove-new-app', function() {
var appId = $(this).data('appid').toString();
addedApps = addedApps.filter(function(id) { return id !== appId; });
$('#appsInput').val(addedApps.join(','));
$(this).parent().remove();
if ($('#currentApps').children().length === 0) {
$('#currentApps').html('<span class="text-muted"><em>No applications assigned</em></span>');
}
});
// Remove existing application
$(document).on('click', '.btn-remove-app', function() {
var appId = $(this).data('appid').toString();
removedApps.push(appId);
$('#removedAppsInput').val(removedApps.join(','));
$(this).parent().remove();
if ($('#currentApps').children().length === 0) {
$('#currentApps').html('<span class="text-muted"><em>No applications assigned</em></span>');
}
});
});
</script>