- Fix dualpath PC propagation direction (Equipment->PC) in api.asp and db_helpers.asp - Fix early exit in CreatePCMachineRelationship preventing propagation - Fix getShopfloorPCs to filter machinetypeid IN (33,34,35) instead of >= 33 - Fix getShopfloorPCs to show equipment numbers via GROUP_CONCAT subquery - Add detailed PropagateDP logging for dualpath debugging - Default "Show on Shopfloor Dashboard" checkbox to checked in addnotification.asp - Add USB label batch printing, single USB labels, and USB history pages - Add printer supplies tracking and toner report enhancements - Add uptime map visualization page - Add dashboard/lobby display SQL migration - Update CLAUDE.md with IIS 401 workaround documentation - Update TODO.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
596 lines
24 KiB
Plaintext
596 lines
24 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<!--#include file="./includes/header.asp"-->
|
|
<!--#include file="./includes/sql.asp"-->
|
|
<link rel="stylesheet" href="./leaflet/leaflet.css">
|
|
<script src="./leaflet/leaflet.js"></script>
|
|
</head>
|
|
|
|
<%
|
|
theme = Request.Cookies("theme")
|
|
IF theme = "" THEN
|
|
theme="bg-theme1"
|
|
END IF
|
|
|
|
' Get minimum uptime filter from query string (default 10 days)
|
|
Dim minUptime
|
|
minUptime = Request.QueryString("minuptime")
|
|
If minUptime = "" Or Not IsNumeric(minUptime) Then
|
|
minUptime = 10
|
|
Else
|
|
minUptime = CInt(minUptime)
|
|
End If
|
|
%>
|
|
<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 -->
|
|
<!-- Start wrapper-->
|
|
<div id="wrapper">
|
|
<!--#include file="./includes/leftsidebar.asp"-->
|
|
<!--Start topbar header-->
|
|
<!--#include file="./includes/topbarheader.asp"-->
|
|
<!--End topbar header-->
|
|
<div class="clearfix"></div>
|
|
<div class="content-wrapper">
|
|
<div class="row">
|
|
<div class="col-lg-9">
|
|
<div class="card">
|
|
<div class="card-body" style="padding:0;">
|
|
<div style="padding:15px; border-bottom:1px solid #444;">
|
|
<h5 class="card-title" style="margin:0; display:inline-block;">
|
|
<i class='zmdi zmdi-time-interval'></i> High Uptime PCs with Machine Relationships
|
|
</h5>
|
|
<div style="float:right;">
|
|
<input type="text" id="pcSearch" class="form-control form-control-sm" placeholder="Search hostname, machine..." style="display:inline-block; width:180px; margin-right:10px;">
|
|
<label style="margin-right:5px; display:inline-block; color:#aaa;">Min Uptime:</label>
|
|
<select id="uptimeFilter" class="form-control form-control-sm" style="display:inline-block; width:100px; margin-right:10px;">
|
|
<option value="10" <%If minUptime = 10 Then Response.Write("selected")%>>10+ days</option>
|
|
<option value="20" <%If minUptime = 20 Then Response.Write("selected")%>>20+ days</option>
|
|
<option value="30" <%If minUptime = 30 Then Response.Write("selected")%>>30+ days</option>
|
|
<option value="60" <%If minUptime = 60 Then Response.Write("selected")%>>60+ days</option>
|
|
<option value="90" <%If minUptime = 90 Then Response.Write("selected")%>>90+ days</option>
|
|
</select>
|
|
<label style="margin-right:5px; display:inline-block; color:#aaa;">BU:</label>
|
|
<select id="businessUnitFilter" class="form-control form-control-sm" style="display:inline-block; width:120px;">
|
|
<option value="all">All</option>
|
|
<%
|
|
' Get business units for dropdown
|
|
Dim rsBU, strBUSQL
|
|
strBUSQL = "SELECT businessunitid, businessunit FROM businessunits WHERE isactive = 1 ORDER BY businessunit"
|
|
Set rsBU = objConn.Execute(strBUSQL)
|
|
Do While Not rsBU.EOF
|
|
Response.Write("<option value='" & rsBU("businessunitid") & "'>" & Server.HTMLEncode(rsBU("businessunit")) & "</option>")
|
|
rsBU.MoveNext
|
|
Loop
|
|
rsBU.Close
|
|
Set rsBU = Nothing
|
|
%>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div id="map"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-3">
|
|
<div class="card">
|
|
<div class="card-header" style="background: linear-gradient(45deg, #ff6b6b, #ee5a24); color: white;">
|
|
<i class="zmdi zmdi-time-interval"></i> Uptime Legend
|
|
</div>
|
|
<div class="card-body">
|
|
<p style="font-size:12px; color:#aaa; margin-bottom:15px;">
|
|
PCs with uptime > <%=minUptime%> days that need to be rebooted.
|
|
</p>
|
|
|
|
<div style="margin-bottom:20px;">
|
|
<div style="margin:8px 0; display:flex; align-items:center;">
|
|
<span style="display:inline-block; width:14px; height:14px; background:#F44336; border-radius:50%; margin-right:10px; border:2px solid #fff; box-shadow:0 1px 3px rgba(0,0,0,0.5);"></span>
|
|
<span style="font-size:13px; color:#fff;">Needs Reboot (<%=minUptime%>+ days)</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="statsPanel" style="margin-top:20px; padding:15px; background:#2a2a2a; border-radius:4px;">
|
|
<strong style="color:#4fc3f7;">Statistics:</strong>
|
|
<div id="pcCount" style="margin-top:10px; font-size:14px; color:#fff;">Loading...</div>
|
|
</div>
|
|
|
|
<div style="margin-top:20px; padding:15px; background:#2a2a2a; border-radius:4px; font-size:12px;">
|
|
<strong style="color:#4fc3f7;">Tips:</strong>
|
|
<ul style="margin:8px 0; padding-left:20px; color:#aaa;">
|
|
<li style="margin:5px 0;">Hover over markers for PC details</li>
|
|
<li style="margin:5px 0;">Markers placed at related machine location</li>
|
|
<li style="margin:5px 0;">Click "View PC" for full information</li>
|
|
<li style="margin:5px 0;">Red markers need attention!</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div><!--End Row-->
|
|
|
|
<!-- PCs without machine relationships (can't be mapped) -->
|
|
<div class="row" style="margin-top:20px;">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header" style="background: linear-gradient(45deg, #6c757d, #495057); color: white; cursor:pointer;" onclick="toggleUnmappedTable()">
|
|
<i class="zmdi zmdi-alert-circle"></i> PCs That Cannot Be Mapped (No Relationship or No Location)
|
|
<span id="unmappedToggle" style="float:right;"><i class="zmdi zmdi-chevron-down"></i></span>
|
|
</div>
|
|
<div id="unmappedTable" class="card-body" style="display:none; padding:0;">
|
|
<p style="padding:15px 15px 0 15px; font-size:12px; color:#aaa;">
|
|
These PCs have high uptime but cannot be placed on the map because they either have no machine relationship,
|
|
or their related machine has no map coordinates. <span style="color:#FFC107;">*</span> = has relationship but machine needs location.
|
|
</p>
|
|
<div class="table-responsive">
|
|
<table class="table table-sm table-hover" style="margin:0;">
|
|
<thead>
|
|
<tr>
|
|
<th>Hostname</th>
|
|
<th>Uptime (Days)</th>
|
|
<th>Last Boot</th>
|
|
<th>Business Unit</th>
|
|
<th>Related Machine</th>
|
|
<th>Serial Number</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<%
|
|
' Query PCs with high uptime that CANNOT be mapped:
|
|
' 1. No machine relationship at all, OR
|
|
' 2. Has relationship but equipment has no map coordinates
|
|
Dim rsUnmapped, strUnmappedSQL
|
|
Dim unmappedDisplayCount
|
|
unmappedDisplayCount = 0
|
|
|
|
strUnmappedSQL = "SELECT " &_
|
|
"pc.machineid, " &_
|
|
"pc.hostname, " &_
|
|
"pc.serialnumber, " &_
|
|
"pc.lastboottime, " &_
|
|
"DATEDIFF(NOW(), pc.lastboottime) as uptime_days, " &_
|
|
"bu.businessunit, " &_
|
|
"eq.machinenumber as related_machine " &_
|
|
"FROM machines pc " &_
|
|
"LEFT JOIN machinerelationships mr ON pc.machineid = mr.related_machineid AND mr.isactive = 1 " &_
|
|
"LEFT JOIN machines eq ON mr.machineid = eq.machineid " &_
|
|
"LEFT JOIN businessunits bu ON pc.businessunitid = bu.businessunitid " &_
|
|
"WHERE pc.pctypeid IS NOT NULL " &_
|
|
"AND pc.isactive = 1 " &_
|
|
"AND pc.lastboottime IS NOT NULL " &_
|
|
"AND DATEDIFF(NOW(), pc.lastboottime) >= " & minUptime & " " &_
|
|
"AND (mr.relationshipid IS NULL OR eq.mapleft IS NULL OR eq.maptop IS NULL) " &_
|
|
"ORDER BY uptime_days DESC"
|
|
|
|
Set rsUnmapped = objConn.Execute(strUnmappedSQL)
|
|
|
|
Do While Not rsUnmapped.EOF
|
|
unmappedDisplayCount = unmappedDisplayCount + 1
|
|
Dim umHostname, umUptime, umLastBoot, umBU, umSerial, umId, umColor
|
|
umId = rsUnmapped("machineid")
|
|
umHostname = rsUnmapped("hostname") & ""
|
|
If IsNull(rsUnmapped("uptime_days")) Then
|
|
umUptime = 0
|
|
Else
|
|
umUptime = CLng(rsUnmapped("uptime_days"))
|
|
End If
|
|
umLastBoot = rsUnmapped("lastboottime")
|
|
umSerial = rsUnmapped("serialnumber") & ""
|
|
If IsNull(rsUnmapped("businessunit")) Then
|
|
umBU = "-"
|
|
Else
|
|
umBU = rsUnmapped("businessunit") & ""
|
|
End If
|
|
Dim umRelatedMachine
|
|
If IsNull(rsUnmapped("related_machine")) Then
|
|
umRelatedMachine = ""
|
|
Else
|
|
umRelatedMachine = rsUnmapped("related_machine") & ""
|
|
End If
|
|
|
|
' Color based on uptime
|
|
If umUptime >= 90 Then
|
|
umColor = "#F44336"
|
|
ElseIf umUptime >= 60 Then
|
|
umColor = "#FF9800"
|
|
ElseIf umUptime >= 30 Then
|
|
umColor = "#FFC107"
|
|
Else
|
|
umColor = "#4CAF50"
|
|
End If
|
|
%>
|
|
<tr>
|
|
<td><a href="./displaypc.asp?machineid=<%=umId%>" target="_blank"><%=Server.HTMLEncode(umHostname)%></a></td>
|
|
<td><span style="color:<%=umColor%>; font-weight:bold;"><%=umUptime%></span></td>
|
|
<td><%=umLastBoot%></td>
|
|
<td><%=Server.HTMLEncode(umBU)%></td>
|
|
<td><%If umRelatedMachine <> "" Then%><span style="color:#FFC107;" title="Has relationship but machine has no map location"><%=Server.HTMLEncode(umRelatedMachine)%> *</span><%Else%><span style="color:#aaa;">None</span><%End If%></td>
|
|
<td><%=Server.HTMLEncode(umSerial)%></td>
|
|
<td><a href="./displaypc.asp?machineid=<%=umId%>" target="_blank" class="btn btn-sm btn-outline-info">View</a></td>
|
|
</tr>
|
|
<%
|
|
rsUnmapped.MoveNext
|
|
Loop
|
|
rsUnmapped.Close
|
|
Set rsUnmapped = Nothing
|
|
%>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div style="padding:10px 15px; background:#2a2a2a; font-size:12px; color:#aaa;">
|
|
Total: <strong style="color:#fff;"><%=unmappedDisplayCount%></strong> PCs without machine relationships
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!--End content-wrapper-->
|
|
<!--Start Back To Top Button-->
|
|
<a href="javaScript:void();" class="back-to-top"><i class="fa fa-angle-double-up"></i> </a>
|
|
<!--End Back To Top Button-->
|
|
|
|
<!--Start footer-->
|
|
<footer class="footer">
|
|
</div>
|
|
</footer>
|
|
<!--End footer-->
|
|
|
|
</div><!--End wrapper-->
|
|
|
|
<!-- Bootstrap core JavaScript-->
|
|
<script src="assets/js/jquery.min.js"></script>
|
|
<script src="assets/js/popper.min.js"></script>
|
|
<script src="assets/js/bootstrap.min.js"></script>
|
|
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
|
|
<script src="assets/js/sidebar-menu.js"></script>
|
|
<script src="assets/js/app-script.js"></script>
|
|
|
|
<style>
|
|
#map {
|
|
width: 100%;
|
|
height: calc(100vh - 250px);
|
|
min-height: 600px;
|
|
background-color: #1a1a1a;
|
|
}
|
|
|
|
.leaflet-control-zoom a {
|
|
background-color: #2a2a2a !important;
|
|
color: #fff !important;
|
|
border-color: #444 !important;
|
|
}
|
|
.leaflet-control-zoom a:hover {
|
|
background-color: #3a3a3a !important;
|
|
}
|
|
.leaflet-bar {
|
|
border: 1px solid #444 !important;
|
|
}
|
|
|
|
.leaflet-popup-content-wrapper {
|
|
background: #1f1f1f !important;
|
|
color: #fff !important;
|
|
box-shadow: 0 3px 14px rgba(0,0,0,0.6) !important;
|
|
border-radius: 4px !important;
|
|
padding: 0 !important;
|
|
}
|
|
.leaflet-popup-content {
|
|
margin: 0 !important;
|
|
}
|
|
.leaflet-popup-tip-container {
|
|
display: none !important;
|
|
}
|
|
.leaflet-popup-close-button {
|
|
color: #fff !important;
|
|
font-size: 24px !important;
|
|
padding: 4px 8px 0 0 !important;
|
|
}
|
|
|
|
.leaflet-control-attribution {
|
|
display: none !important;
|
|
}
|
|
|
|
.uptime-pulse {
|
|
animation: pulse 2s infinite;
|
|
}
|
|
@keyframes pulse {
|
|
0%, 100% { transform: scale(1); opacity: 1; }
|
|
50% { transform: scale(1.2); opacity: 0.8; }
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// Get current theme
|
|
var bodyClass = document.body.className;
|
|
var themeMatch = bodyClass.match(/bg-theme(\d+)/);
|
|
var theme = themeMatch ? 'bg-theme' + themeMatch[1] : 'bg-theme1';
|
|
|
|
var themeConfig = {
|
|
'bg-theme1': { bg: '#2a2a2a', filter: 'brightness(0.7) contrast(1.1)', gradient: 'linear-gradient(45deg, #ff6b6b, #ee5a24)' },
|
|
'bg-theme7': { bg: '#0c675e', filter: 'brightness(0.8) contrast(1.1) hue-rotate(-10deg)', gradient: 'linear-gradient(45deg, #ff6b6b, #ee5a24)' },
|
|
'bg-theme11': { bg: '#1565C0', filter: 'brightness(0.85) contrast(1.05) hue-rotate(-5deg)', gradient: 'linear-gradient(45deg, #ff6b6b, #ee5a24)' }
|
|
};
|
|
|
|
var config = themeConfig[theme] || { bg: '#1a1a1a', filter: 'brightness(0.7) contrast(1.1)', gradient: 'linear-gradient(45deg, #ff6b6b, #ee5a24)' };
|
|
|
|
document.getElementById('map').style.backgroundColor = config.bg;
|
|
|
|
var map = L.map('map', {
|
|
crs: L.CRS.Simple,
|
|
minZoom: -3
|
|
});
|
|
var bounds = [[0,0], [2550,3300]];
|
|
|
|
var lightThemes = ['bg-theme11', 'bg-theme13'];
|
|
var mapImage = lightThemes.includes(theme) ? './images/sitemap2025-light.png' : './images/sitemap2025-dark.png';
|
|
var image = L.imageOverlay(mapImage, bounds);
|
|
|
|
image.on('load', function() {
|
|
var imgElement = this.getElement();
|
|
if (imgElement) {
|
|
imgElement.style.filter = config.filter;
|
|
}
|
|
});
|
|
|
|
image.addTo(map);
|
|
var center = [1275, 1650];
|
|
map.setView(center, -2.3);
|
|
|
|
// Store PC markers
|
|
var pcMarkers = [];
|
|
|
|
// Uptime color function - single color for all (reboot needed)
|
|
function getUptimeColor(days) {
|
|
return '#F44336'; // Red - all PCs need reboot
|
|
}
|
|
|
|
function getUptimeLabel(days) {
|
|
return 'Needs Reboot';
|
|
}
|
|
|
|
<%
|
|
' First, get count of PCs without relationships (for stats display)
|
|
Dim rsUnmappedCount, unmappedCount
|
|
unmappedCount = 0
|
|
Set rsUnmappedCount = objConn.Execute("SELECT COUNT(*) as cnt FROM machines pc " &_
|
|
"LEFT JOIN machinerelationships mr ON pc.machineid = mr.related_machineid AND mr.isactive = 1 " &_
|
|
"LEFT JOIN machines eq ON mr.machineid = eq.machineid " &_
|
|
"WHERE pc.pctypeid IS NOT NULL AND pc.isactive = 1 " &_
|
|
"AND pc.lastboottime IS NOT NULL " &_
|
|
"AND DATEDIFF(NOW(), pc.lastboottime) >= " & minUptime & " " &_
|
|
"AND (mr.relationshipid IS NULL OR eq.mapleft IS NULL OR eq.maptop IS NULL)")
|
|
If Not rsUnmappedCount.EOF Then
|
|
unmappedCount = CLng(rsUnmappedCount("cnt"))
|
|
End If
|
|
rsUnmappedCount.Close
|
|
Set rsUnmappedCount = Nothing
|
|
|
|
' Query PCs with machine relationships and high uptime
|
|
' Use the RELATED MACHINE's map coordinates since PCs don't have their own
|
|
Dim strSQL, rs
|
|
Dim pcId, pcHostname, pcUptime, lastBoot
|
|
Dim eqId, eqNumber, eqMapLeft, eqMapTop, eqType
|
|
Dim businessunitid, businessunit
|
|
|
|
strSQL = "SELECT " &_
|
|
"pc.machineid as pc_id, " &_
|
|
"pc.hostname as pc_hostname, " &_
|
|
"pc.lastboottime, " &_
|
|
"DATEDIFF(NOW(), pc.lastboottime) as uptime_days, " &_
|
|
"eq.machineid as eq_id, " &_
|
|
"eq.machinenumber as eq_number, " &_
|
|
"eq.mapleft as eq_mapleft, " &_
|
|
"eq.maptop as eq_maptop, " &_
|
|
"mt.machinetype as eq_type, " &_
|
|
"pc.businessunitid, " &_
|
|
"bu.businessunit " &_
|
|
"FROM machines pc " &_
|
|
"INNER JOIN machinerelationships mr ON pc.machineid = mr.related_machineid AND mr.isactive = 1 " &_
|
|
"INNER JOIN machines eq ON mr.machineid = eq.machineid " &_
|
|
"LEFT JOIN models mo ON eq.modelnumberid = mo.modelnumberid " &_
|
|
"LEFT JOIN machinetypes mt ON mo.machinetypeid = mt.machinetypeid " &_
|
|
"LEFT JOIN businessunits bu ON pc.businessunitid = bu.businessunitid " &_
|
|
"WHERE pc.pctypeid IS NOT NULL " &_
|
|
"AND pc.isactive = 1 " &_
|
|
"AND pc.lastboottime IS NOT NULL " &_
|
|
"AND DATEDIFF(NOW(), pc.lastboottime) >= " & minUptime & " " &_
|
|
"AND eq.mapleft IS NOT NULL " &_
|
|
"AND eq.maptop IS NOT NULL " &_
|
|
"ORDER BY uptime_days DESC"
|
|
|
|
Set rs = objConn.Execute(strSQL)
|
|
|
|
Dim pcCount
|
|
pcCount = 0
|
|
|
|
Do While Not rs.EOF
|
|
pcCount = pcCount + 1
|
|
|
|
pcId = rs("pc_id")
|
|
pcHostname = rs("pc_hostname") & ""
|
|
pcUptime = rs("uptime_days")
|
|
lastBoot = rs("lastboottime")
|
|
|
|
eqId = rs("eq_id")
|
|
eqNumber = rs("eq_number") & ""
|
|
eqMapLeft = rs("eq_mapleft")
|
|
eqMapTop = 2550 - rs("eq_maptop") ' Flip Y coordinate
|
|
|
|
If Not IsNull(rs("eq_type")) Then
|
|
eqType = rs("eq_type")
|
|
Else
|
|
eqType = "Unknown"
|
|
End If
|
|
|
|
If Not IsNull(rs("businessunitid")) Then
|
|
businessunitid = rs("businessunitid")
|
|
Else
|
|
businessunitid = 0
|
|
End If
|
|
|
|
If Not IsNull(rs("businessunit")) Then
|
|
businessunit = rs("businessunit")
|
|
Else
|
|
businessunit = "N/A"
|
|
End If
|
|
%>
|
|
(function() {
|
|
var pcId = '<%=pcId%>';
|
|
var pcHostname = '<%=Server.HTMLEncode(pcHostname)%>';
|
|
var uptimeDays = <%=pcUptime%>;
|
|
var lastBoot = '<%=lastBoot%>';
|
|
var eqId = '<%=eqId%>';
|
|
var eqNumber = '<%=Server.HTMLEncode(eqNumber)%>';
|
|
var eqType = '<%=Server.HTMLEncode(eqType)%>';
|
|
var businessUnitId = '<%=businessunitid%>';
|
|
var businessUnit = '<%=Server.HTMLEncode(businessunit)%>';
|
|
|
|
var color = getUptimeColor(uptimeDays);
|
|
var uptimeLabel = getUptimeLabel(uptimeDays);
|
|
|
|
// Create custom marker icon
|
|
var icon = L.divIcon({
|
|
html: '<div style="background:' + color + '; width:14px; height:14px; border-radius:50%; border:2px solid #fff; box-shadow:0 2px 5px rgba(0,0,0,0.5);"></div>',
|
|
iconSize: [14, 14],
|
|
iconAnchor: [7, 7],
|
|
popupAnchor: [0, -5],
|
|
className: 'custom-marker'
|
|
});
|
|
|
|
var marker = L.marker([<%=eqMapTop%>, <%=eqMapLeft%>], {
|
|
title: pcHostname + ' (' + uptimeDays + ' days)',
|
|
icon: icon,
|
|
pcId: pcId,
|
|
uptimeDays: uptimeDays
|
|
}).addTo(map);
|
|
|
|
// Store marker with searchable data
|
|
pcMarkers.push({
|
|
marker: marker,
|
|
pcId: pcId,
|
|
uptimeDays: uptimeDays,
|
|
businessUnitId: businessUnitId,
|
|
searchData: {
|
|
hostname: pcHostname.toLowerCase(),
|
|
machine: eqNumber.toLowerCase(),
|
|
bu: businessUnit.toLowerCase()
|
|
}
|
|
});
|
|
|
|
// Popup on hover
|
|
var popupTimeout;
|
|
marker.on('mouseover', function() {
|
|
clearTimeout(popupTimeout);
|
|
this.openPopup();
|
|
});
|
|
marker.on('mouseout', function(e) {
|
|
popupTimeout = setTimeout(function() {
|
|
marker.closePopup();
|
|
}, 800);
|
|
});
|
|
|
|
var pcUrl = './displaypc.asp?machineid=' + pcId;
|
|
var eqUrl = './displaymachine.asp?machineid=' + eqId;
|
|
|
|
var popupContent = '<div style="background:#1f1f1f; color:#fff; min-width:280px; border-radius:4px; overflow:hidden;">' +
|
|
'<div style="background:' + config.gradient + '; padding:10px 15px; border-bottom:1px solid #444;">' +
|
|
'<h6 style="margin:0; color:#fff; font-size:14px;"><i class="zmdi zmdi-desktop-mac"></i> ' + pcHostname + '</h6>' +
|
|
'</div>' +
|
|
'<div style="padding:10px 15px; font-size:12px;">' +
|
|
'<div style="margin:8px 0; padding:10px; background:' + color + '22; border-left:3px solid ' + color + '; border-radius:0 4px 4px 0;">' +
|
|
'<strong style="color:' + color + '; font-size:16px;">' + uptimeDays + ' days uptime</strong>' +
|
|
'<div style="color:#aaa; font-size:11px; margin-top:3px;">Status: ' + uptimeLabel + '</div>' +
|
|
'</div>' +
|
|
'<div style="margin:5px 0;"><strong style="color:#aaa;">Last Boot:</strong> <span style="color:#fff;">' + lastBoot + '</span></div>' +
|
|
'<div style="margin:5px 0;"><strong style="color:#aaa;">Related Machine:</strong> <a href="' + eqUrl + '" target="_blank" style="color:#4fc3f7;">' + eqNumber + '</a> (' + eqType + ')</div>' +
|
|
(businessUnit !== 'N/A' ? '<div style="margin:5px 0;"><strong style="color:#aaa;">Business Unit:</strong> <span style="color:#fff;">' + businessUnit + '</span></div>' : '') +
|
|
'</div>' +
|
|
'<div style="padding:10px 15px; border-top:1px solid #444; text-align:center;">' +
|
|
'<a href="' + pcUrl + '" style="display:inline-block; background:' + config.gradient + '; color:#fff; padding:8px 18px; border-radius:4px; text-decoration:none; font-size:13px; font-weight:500;" target="_blank"><i class="zmdi zmdi-desktop-mac"></i> View PC</a>' +
|
|
'</div>' +
|
|
'</div>';
|
|
|
|
marker.bindPopup(popupContent);
|
|
})();
|
|
<%
|
|
rs.MoveNext
|
|
Loop
|
|
rs.Close
|
|
Set rs = Nothing
|
|
objConn.Close
|
|
%>
|
|
|
|
// Update stats
|
|
document.getElementById('pcCount').innerHTML =
|
|
'<div style="margin:5px 0;"><i class="zmdi zmdi-pin"></i> <strong><%=pcCount%></strong> PCs on map</div>' +
|
|
'<div style="margin:5px 0;"><i class="zmdi zmdi-alert-circle" style="color:#6c757d;"></i> <strong><%=unmappedCount%></strong> PCs without location</div>' +
|
|
'<div style="margin:5px 0; font-size:12px; color:#aaa;">Total: <%=pcCount + unmappedCount%> high-uptime PCs</div>';
|
|
|
|
// Toggle unmapped PCs table
|
|
function toggleUnmappedTable() {
|
|
var table = document.getElementById('unmappedTable');
|
|
var toggle = document.getElementById('unmappedToggle');
|
|
if (table.style.display === 'none') {
|
|
table.style.display = 'block';
|
|
toggle.innerHTML = '<i class="zmdi zmdi-chevron-up"></i>';
|
|
} else {
|
|
table.style.display = 'none';
|
|
toggle.innerHTML = '<i class="zmdi zmdi-chevron-down"></i>';
|
|
}
|
|
}
|
|
|
|
// Filter functionality
|
|
function applyFilters() {
|
|
var selectedBU = document.getElementById('businessUnitFilter').value;
|
|
var searchTerm = document.getElementById('pcSearch').value.toLowerCase().trim();
|
|
var minUptimeVal = parseInt(document.getElementById('uptimeFilter').value);
|
|
|
|
var visibleCount = 0;
|
|
|
|
pcMarkers.forEach(function(item) {
|
|
var buMatch = (selectedBU === 'all' || item.businessUnitId == selectedBU);
|
|
var uptimeMatch = item.uptimeDays >= minUptimeVal;
|
|
var searchMatch = true;
|
|
|
|
if (searchTerm !== '') {
|
|
searchMatch = item.searchData.hostname.indexOf(searchTerm) > -1 ||
|
|
item.searchData.machine.indexOf(searchTerm) > -1 ||
|
|
item.searchData.bu.indexOf(searchTerm) > -1;
|
|
}
|
|
|
|
if (buMatch && uptimeMatch && searchMatch) {
|
|
item.marker.setOpacity(1);
|
|
visibleCount++;
|
|
} else {
|
|
item.marker.setOpacity(0.15);
|
|
}
|
|
});
|
|
|
|
// Update visible count
|
|
document.getElementById('pcCount').innerHTML =
|
|
'<div style="margin:5px 0;"><i class="zmdi zmdi-desktop-mac"></i> <strong>' + visibleCount + '</strong> PCs visible</div>' +
|
|
'<div style="margin:5px 0; font-size:12px; color:#aaa;">Filtered from <%=pcCount%> total</div>';
|
|
}
|
|
|
|
// Uptime filter changes page
|
|
document.getElementById('uptimeFilter').addEventListener('change', function() {
|
|
window.location.href = '?minuptime=' + this.value;
|
|
});
|
|
|
|
// Listen to filter changes
|
|
document.getElementById('businessUnitFilter').addEventListener('change', applyFilters);
|
|
|
|
// Listen to search input with debouncing
|
|
var searchTimeout;
|
|
document.getElementById('pcSearch').addEventListener('input', function() {
|
|
clearTimeout(searchTimeout);
|
|
searchTimeout = setTimeout(applyFilters, 300);
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|