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:
@@ -1,12 +1,17 @@
|
||||
<%@ Language=VBScript %>
|
||||
<%
|
||||
Option Explicit
|
||||
%>
|
||||
<!--#include file="./includes/sql.asp"-->
|
||||
<%
|
||||
Dim appid, rs
|
||||
Dim appid, rs, theme, kbClicks, kbDesc, kbClicksNum
|
||||
Dim strSQL, installPath, docPath, appLink, teamUrl
|
||||
Dim rsKB, sqlKB, appName, rsSupportTeams, sqlSupportTeams
|
||||
Dim rsAppOwners, sqlAppOwners
|
||||
|
||||
appid = Request.Querystring("appid")
|
||||
|
||||
' Get highlight parameter for shared links
|
||||
Dim highlightId
|
||||
highlightId = Request.QueryString("highlight")
|
||||
|
||||
' Basic validation - must be numeric and positive
|
||||
If Not IsNumeric(appid) Or CLng(appid) < 1 Then
|
||||
Response.Redirect("displayapplications.asp")
|
||||
@@ -15,14 +20,12 @@ Option Explicit
|
||||
|
||||
appid = CLng(appid) ' Convert to long integer
|
||||
|
||||
Dim theme
|
||||
theme = Request.Cookies("theme")
|
||||
IF theme = "" THEN
|
||||
theme="bg-theme1"
|
||||
END IF
|
||||
|
||||
' Simple query with validated integer
|
||||
Dim strSQL
|
||||
strSQL = "SELECT a.*, s.teamname, s.teamurl, o.appowner, o.sso " & _
|
||||
"FROM applications a " & _
|
||||
"INNER JOIN supportteams s ON a.supportteamid = s.supporteamid " & _
|
||||
@@ -43,11 +46,80 @@ Option Explicit
|
||||
<!--#include file="./includes/header.asp"-->
|
||||
</head>
|
||||
|
||||
<style>
|
||||
.highlighted-result {
|
||||
background: linear-gradient(90deg, rgba(255, 193, 7, 0.3) 0%, rgba(255, 193, 7, 0.1) 100%) !important;
|
||||
border-left: 4px solid #ffc107 !important;
|
||||
animation: highlight-pulse 2s ease-in-out 3;
|
||||
}
|
||||
@keyframes highlight-pulse {
|
||||
0%, 100% { background: linear-gradient(90deg, rgba(255, 193, 7, 0.3) 0%, rgba(255, 193, 7, 0.1) 100%); }
|
||||
50% { background: linear-gradient(90deg, rgba(255, 193, 7, 0.5) 0%, rgba(255, 193, 7, 0.2) 100%); }
|
||||
}
|
||||
.card-img-block img {
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.card-img-block img:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
.lightbox-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
z-index: 9999;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.lightbox-overlay.active {
|
||||
display: flex;
|
||||
}
|
||||
.lightbox-content {
|
||||
position: relative;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
}
|
||||
.lightbox-content img {
|
||||
max-width: 100%;
|
||||
max-height: 85vh;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.lightbox-close {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: -10px;
|
||||
color: #fff;
|
||||
font-size: 32px;
|
||||
cursor: pointer;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.2s;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.lightbox-close:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
<body class="bg-theme <%Response.Write(theme)%>">
|
||||
|
||||
<!-- start loader -->
|
||||
<div id="pageloader-overlay" class="visible incoming"><div class="loader-wrapper-outer"><div class="loader-wrapper-inner" ><div class="loader"></div></div></div></div>
|
||||
<!-- end loader -->
|
||||
|
||||
<!-- Lightbox overlay -->
|
||||
<div id="imageLightbox" class="lightbox-overlay" onclick="closeLightbox(event)">
|
||||
<div class="lightbox-content" onclick="event.stopPropagation()">
|
||||
<button class="lightbox-close" onclick="closeLightbox(event)">×</button>
|
||||
<img src="./images/applications/<%=Server.HTMLEncode(rs("image") & "")%>" alt="<%=Server.HTMLEncode(rs("appname") & "")%>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Start wrapper-->
|
||||
<div id="wrapper">
|
||||
<!--#include file="./includes/leftsidebar.asp"-->
|
||||
@@ -63,7 +135,7 @@ Option Explicit
|
||||
<div class="col-lg-4">
|
||||
<div class="card profile-card-2">
|
||||
<div class="card-img-block">
|
||||
<img class="img-fluid" src="./images/applications/<%=Server.HTMLEncode(rs("image") & "")%>" alt="Card image cap">
|
||||
<img class="img-fluid" src="./images/applications/<%=Server.HTMLEncode(rs("image") & "")%>" alt="<%=Server.HTMLEncode(rs("appname") & "")%>" onclick="openLightbox()" title="Click to enlarge">
|
||||
</div>
|
||||
<div class="card-body pt-5">
|
||||
<img src="./images/applications/<%=Server.HTMLEncode(rs("image") & "")%>" alt="profile-image" class="profile">
|
||||
@@ -90,13 +162,19 @@ Option Explicit
|
||||
<div class="tab-content p-3">
|
||||
<div class="tab-pane active" id="profile">
|
||||
<h5 class="mb-3"><%=Server.HTMLEncode(rs("appname") & "")%></h5>
|
||||
<%
|
||||
Dim appDescription
|
||||
appDescription = rs("appdescription") & ""
|
||||
If appDescription <> "" Then
|
||||
Response.Write("<p class='mb-3'>" & Server.HTMLEncode(appDescription) & "</p>")
|
||||
End If
|
||||
%>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<p class="mb-2"><strong>Support Team:</strong></p>
|
||||
<p class="mb-2"><strong>App Owner:</strong></p>
|
||||
<p class="mb-2"><strong>SSO:</strong></p>
|
||||
<%
|
||||
Dim installPath, docPath, appLink
|
||||
installPath = rs("installpath") & ""
|
||||
appLink = rs("applicationlink") & ""
|
||||
docPath = rs("documentationpath") & ""
|
||||
@@ -113,7 +191,6 @@ Option Explicit
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<%
|
||||
Dim teamUrl
|
||||
teamUrl = rs("teamurl") & ""
|
||||
If teamUrl <> "" Then
|
||||
Response.Write("<p class='mb-2'><a href='" & Server.HTMLEncode(teamUrl) & "' target='_blank' title='Click here for Service Now page'>" & Server.HTMLEncode(rs("teamname")) & "</a></p>")
|
||||
@@ -137,43 +214,30 @@ Option Explicit
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<h5 class="mt-2 mb-3">Application Notes</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<strong><%Response.Write(rs("appname"))%></strong>:
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><%Response.Write(rs("applicationnotes"))%>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-striped" style="font-size: 1rem;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding: 12px;">
|
||||
<strong><%=Server.HTMLEncode(rs("appname") & "")%></strong>:
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 12px;"><%=rs("applicationnotes") & ""%></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<h5 class="mt-4 mb-3"><i class="zmdi zmdi-collection-bookmark"></i> Related Knowledge Base Articles</h5>
|
||||
<%
|
||||
' Query knowledge base articles for this application
|
||||
' Use keyword matching similar to search.asp - match on app name in keywords/description
|
||||
Dim rsKB, sqlKB, appName
|
||||
appName = rs("appname") & ""
|
||||
|
||||
' Search for articles where keywords or shortdescription contain the app name
|
||||
' Also include articles explicitly linked via appid
|
||||
' Sort by clicks (highest first), then prioritize directly linked articles
|
||||
sqlKB = "SELECT linkid, linkurl, shortdescription, COALESCE(clicks, 0) as clicks, " & _
|
||||
"CASE WHEN appid = " & appid & " THEN 1 ELSE 0 END as direct_link, " & _
|
||||
"CAST(COALESCE(clicks, 0) AS SIGNED) as clicks_num " & _
|
||||
' Query knowledge base articles directly linked to this application
|
||||
sqlKB = "SELECT linkid, linkurl, shortdescription, COALESCE(clicks, 0) as clicks " & _
|
||||
"FROM knowledgebase " & _
|
||||
"WHERE isactive = 1 " & _
|
||||
"AND (appid = " & appid & " " & _
|
||||
" OR keywords LIKE '%" & Replace(appName, "'", "''") & "%' " & _
|
||||
" OR shortdescription LIKE '%" & Replace(appName, "'", "''") & "%') " & _
|
||||
"ORDER BY clicks_num DESC, direct_link DESC"
|
||||
"WHERE isactive = 1 AND appid = " & appid & " " & _
|
||||
"ORDER BY clicks DESC"
|
||||
Set rsKB = objConn.Execute(sqlKB)
|
||||
|
||||
If Not rsKB.EOF Then
|
||||
@@ -183,16 +247,12 @@ Option Explicit
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="padding: 12px;">Article</th>
|
||||
<th style="width:100px; text-align:center; padding: 12px;">
|
||||
<i class="zmdi zmdi-eye"></i> Clicks
|
||||
</th>
|
||||
<th style="width:100px; text-align:center; padding: 12px;">Clicks</th>
|
||||
<th style="width:60px; text-align:center; padding: 12px;">Share</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%
|
||||
' Declare loop variables once outside the loop
|
||||
Dim kbClicks, kbDesc, kbClicksNum
|
||||
|
||||
While Not rsKB.EOF
|
||||
' Get click count with proper error handling
|
||||
On Error Resume Next
|
||||
@@ -214,14 +274,22 @@ Option Explicit
|
||||
kbDesc = "[No description]"
|
||||
End If
|
||||
On Error Goto 0
|
||||
|
||||
' Check if this row should be highlighted
|
||||
Dim rowClass, kbLinkId
|
||||
kbLinkId = rsKB("linkid")
|
||||
rowClass = ""
|
||||
If highlightId <> "" And CStr(kbLinkId) = CStr(highlightId) Then
|
||||
rowClass = " class='highlighted-result'"
|
||||
End If
|
||||
%>
|
||||
<tr>
|
||||
<tr id="kb-<%=Server.HTMLEncode(kbLinkId)%>"<%=rowClass%>>
|
||||
<td style="padding: 12px;">
|
||||
<a href="./clickcounter.asp?linkid=<%=Server.HTMLEncode(rsKB("linkid"))%>"
|
||||
<a href="./clickcounter.asp?linkid=<%=Server.HTMLEncode(kbLinkId)%>"
|
||||
target="_blank"
|
||||
title="<%=Server.HTMLEncode(kbDesc)%>"
|
||||
style="font-size: 1rem;">
|
||||
<i class="zmdi zmdi-link" style="font-size: 1.1rem;"></i> <%=Server.HTMLEncode(kbDesc)%>
|
||||
<%=Server.HTMLEncode(kbDesc)%>
|
||||
</a>
|
||||
</td>
|
||||
<td style="text-align:center; padding: 12px;">
|
||||
@@ -238,6 +306,11 @@ Option Explicit
|
||||
End If
|
||||
%>
|
||||
</td>
|
||||
<td style="text-align:center; padding: 12px;">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="shareKBArticle(<%=Server.HTMLEncode(kbLinkId)%>)" title="Copy link to this article">
|
||||
<i class="zmdi zmdi-share"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<%
|
||||
rsKB.MoveNext
|
||||
@@ -288,7 +361,6 @@ Option Explicit
|
||||
<option value='<%response.write(rs("supportteamid"))%>'><%Response.Write(rs("teamname"))%></option>
|
||||
<%
|
||||
' Get all support teams for dropdown (same pattern as displayprinter.asp)
|
||||
Dim rsSupportTeams, sqlSupportTeams
|
||||
sqlSupportTeams = "SELECT supporteamid, teamname FROM supportteams WHERE isactive=1 ORDER BY teamname ASC"
|
||||
Set rsSupportTeams = objconn.Execute(sqlSupportTeams)
|
||||
While Not rsSupportTeams.EOF
|
||||
@@ -332,7 +404,6 @@ Option Explicit
|
||||
<select class="form-control" id="newappownerid" name="newappownerid">
|
||||
<option value="">-- Select App Owner --</option>
|
||||
<%
|
||||
Dim rsAppOwners, sqlAppOwners
|
||||
sqlAppOwners = "SELECT appownerid, appowner FROM appowners WHERE isactive=1 ORDER BY appowner ASC"
|
||||
Set rsAppOwners = objconn.Execute(sqlAppOwners)
|
||||
While Not rsAppOwners.EOF
|
||||
@@ -529,7 +600,61 @@ Option Explicit
|
||||
<script src="assets/js/app-script.js"></script>
|
||||
|
||||
<script>
|
||||
// Lightbox functions
|
||||
function openLightbox() {
|
||||
document.getElementById('imageLightbox').classList.add('active');
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
function closeLightbox(event) {
|
||||
document.getElementById('imageLightbox').classList.remove('active');
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
|
||||
// Close lightbox with Escape key
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
closeLightbox();
|
||||
}
|
||||
});
|
||||
|
||||
// Share KB article link with highlight parameter
|
||||
function shareKBArticle(linkId) {
|
||||
var url = window.location.protocol + '//' + window.location.host + window.location.pathname;
|
||||
url += '?appid=<%=appid%>&highlight=' + linkId;
|
||||
|
||||
// Use fallback method for HTTP (clipboard API requires HTTPS)
|
||||
var temp = document.createElement('textarea');
|
||||
temp.value = url;
|
||||
temp.style.position = 'fixed';
|
||||
temp.style.left = '-9999px';
|
||||
document.body.appendChild(temp);
|
||||
temp.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(temp);
|
||||
|
||||
// Show feedback
|
||||
var btn = event.currentTarget;
|
||||
var originalHTML = btn.innerHTML;
|
||||
btn.innerHTML = '<i class="zmdi zmdi-check"></i>';
|
||||
btn.classList.remove('btn-outline-secondary');
|
||||
btn.classList.add('btn-success');
|
||||
setTimeout(function() {
|
||||
btn.innerHTML = originalHTML;
|
||||
btn.classList.remove('btn-success');
|
||||
btn.classList.add('btn-outline-secondary');
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
// Scroll to highlighted KB article if present
|
||||
var highlightedRow = document.querySelector('.highlighted-result');
|
||||
if (highlightedRow) {
|
||||
setTimeout(function() {
|
||||
highlightedRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// Show/hide new support team section
|
||||
$('#addSupportTeamBtn, #supportteamid').on('change click', function() {
|
||||
if ($('#supportteamid').val() === 'new' || $(this).attr('id') === 'addSupportTeamBtn') {
|
||||
|
||||
Reference in New Issue
Block a user