- New displaylocations.asp (production location listing) - 3 new SQL migrations: inspection machine type, location relationship types, pctype inspection update - displaymachine.asp / printbadge.asp substantial rework - editmachine/editpc/savemachineedit: ~50 line additions each - Dashboard index.html + tv-dashboard tweaks - .gitignore: block database-backup-*.sql, *.bak, *.pdf Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
354 lines
14 KiB
Plaintext
354 lines
14 KiB
Plaintext
<%@ Language=VBScript %>
|
|
<%
|
|
Option Explicit
|
|
Dim theme, strSQL, rs, objConn, rsRel
|
|
%>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<!--#include file="./includes/header.asp"-->
|
|
<!--#include file="./includes/sql.asp"-->
|
|
</head>
|
|
|
|
<%
|
|
theme = Request.Cookies("theme")
|
|
IF theme = "" THEN
|
|
theme="bg-theme1"
|
|
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="container-fluid">
|
|
<div class="row">
|
|
<div class="col-xl-auto">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px;">
|
|
<h5 class="card-title" style="margin:0;">
|
|
<i class="zmdi zmdi-pin"></i> Locations
|
|
</h5>
|
|
</div>
|
|
|
|
<%
|
|
' Get all active locations with PC counts and relationship counts
|
|
strSQL = "SELECT m.machineid, m.machinenumber, m.alias, m.machinenotes, m.mapleft, m.maptop, " & _
|
|
" (SELECT COUNT(*) FROM machinerelationships mr " & _
|
|
" JOIN machines pc ON mr.related_machineid = pc.machineid " & _
|
|
" WHERE mr.machineid = m.machineid AND mr.isactive = 1 AND pc.pctypeid IS NOT NULL AND pc.isactive = 1) AS pc_count, " & _
|
|
" (SELECT COUNT(*) FROM machinerelationships mr " & _
|
|
" JOIN machines child ON mr.related_machineid = child.machineid " & _
|
|
" WHERE mr.machineid = m.machineid AND mr.isactive = 1 AND child.islocationonly = 1 AND child.isactive = 1) AS sublocation_count " & _
|
|
"FROM machines m " & _
|
|
"WHERE m.islocationonly = 1 AND m.isactive = 1 AND m.machinenumber <> 'TBD' " & _
|
|
"ORDER BY m.machinenumber"
|
|
Set rs = objConn.Execute(strSQL)
|
|
|
|
' Build a dictionary of all relationships for location machines
|
|
' Key = machineid, Value = array of relationship info
|
|
Dim relDict, relSQL
|
|
Set relDict = Server.CreateObject("Scripting.Dictionary")
|
|
|
|
relSQL = "SELECT mr.machineid AS loc_id, child.machineid AS child_id, child.machinenumber AS child_name, " & _
|
|
" child.hostname AS child_hostname, child.alias AS child_alias, " & _
|
|
" child.pctypeid, child.islocationonly, " & _
|
|
" rt.relationshiptype, rt.relationshiptypeid, " & _
|
|
" GROUP_CONCAT(DISTINCT c.address ORDER BY c.address SEPARATOR ', ') AS child_ip " & _
|
|
"FROM machinerelationships mr " & _
|
|
"JOIN machines loc ON mr.machineid = loc.machineid " & _
|
|
"JOIN machines child ON mr.related_machineid = child.machineid " & _
|
|
"JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid " & _
|
|
"LEFT JOIN communications c ON child.machineid = c.machineid AND c.comstypeid IN (1, 3) AND c.isactive = 1 " & _
|
|
"WHERE loc.islocationonly = 1 AND loc.isactive = 1 AND mr.isactive = 1 AND child.isactive = 1 " & _
|
|
"GROUP BY mr.machineid, child.machineid, child.machinenumber, child.hostname, child.alias, " & _
|
|
" child.pctypeid, child.islocationonly, rt.relationshiptype, rt.relationshiptypeid " & _
|
|
"ORDER BY mr.machineid, rt.relationshiptypeid, child.machinenumber"
|
|
Set rsRel = objConn.Execute(relSQL)
|
|
|
|
Dim curLocId
|
|
Do While Not rsRel.EOF
|
|
curLocId = CStr(rsRel("loc_id"))
|
|
If Not relDict.Exists(curLocId) Then
|
|
relDict.Add curLocId, ""
|
|
End If
|
|
' Build pipe-delimited entries: child_id|child_name|child_hostname|child_alias|child_ip|pctypeid|islocationonly|relationshiptype
|
|
Dim entry
|
|
entry = rsRel("child_id") & "|" & (rsRel("child_name") & "") & "|" & (rsRel("child_hostname") & "") & "|" & _
|
|
(rsRel("child_alias") & "") & "|" & (rsRel("child_ip") & "") & "|" & _
|
|
(rsRel("pctypeid") & "") & "|" & (rsRel("islocationonly") & "") & "|" & (rsRel("relationshiptype") & "")
|
|
If relDict(curLocId) <> "" Then
|
|
relDict(curLocId) = relDict(curLocId) & "~" & entry
|
|
Else
|
|
relDict(curLocId) = entry
|
|
End If
|
|
rsRel.MoveNext
|
|
Loop
|
|
rsRel.Close
|
|
Set rsRel = Nothing
|
|
%>
|
|
|
|
<div class="table-responsive">
|
|
<table id="locationsTable" class="table table-striped table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th>Location</th>
|
|
<th>Alias</th>
|
|
<th>PCs</th>
|
|
<th>Sub-locations</th>
|
|
<th>Map</th>
|
|
<th>Notes</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<%
|
|
Do While Not rs.EOF
|
|
Dim locName, locAlias, locNotes, pcCount, subCount, hasMap, mid, totalRels
|
|
mid = rs("machineid")
|
|
locName = rs("machinenumber") & ""
|
|
locAlias = rs("alias") & ""
|
|
locNotes = rs("machinenotes") & ""
|
|
pcCount = CLng(rs("pc_count") & "")
|
|
subCount = CLng(rs("sublocation_count") & "")
|
|
hasMap = Not (IsNull(rs("mapleft")) Or IsNull(rs("maptop")))
|
|
totalRels = pcCount + subCount
|
|
|
|
' Check if this location has any relationships in our dict
|
|
Dim hasRels, midStr
|
|
midStr = CStr(mid)
|
|
hasRels = relDict.Exists(midStr) And relDict(midStr) <> ""
|
|
%>
|
|
<tr<% If hasRels Then %> class="loc-parent" data-mid="<%=mid%>" style="cursor:pointer;"<% End If %>>
|
|
<td style="width:30px;">
|
|
<% If hasRels Then %>
|
|
<i class="zmdi zmdi-chevron-right loc-toggle" data-mid="<%=mid%>" style="transition:transform 0.2s;"></i>
|
|
<% End If %>
|
|
</td>
|
|
<td>
|
|
<a href="displaymachine.asp?machineid=<%=mid%>">
|
|
<i class="zmdi zmdi-pin" style="margin-right:5px;"></i><%=Server.HTMLEncode(locName)%>
|
|
</a>
|
|
</td>
|
|
<td><%=Server.HTMLEncode(locAlias)%></td>
|
|
<td>
|
|
<% If pcCount > 0 Then %>
|
|
<span class="badge badge-primary"><%=pcCount%></span>
|
|
<% Else %>
|
|
<span class="text-muted">0</span>
|
|
<% End If %>
|
|
</td>
|
|
<td>
|
|
<% If subCount > 0 Then %>
|
|
<span class="badge badge-info"><%=subCount%></span>
|
|
<% Else %>
|
|
<span class="text-muted">0</span>
|
|
<% End If %>
|
|
</td>
|
|
<td>
|
|
<% If hasMap Then %>
|
|
<i class="zmdi zmdi-pin text-success" title="Location set"></i>
|
|
<% Else %>
|
|
<i class="zmdi zmdi-pin-off text-muted" title="No location set"></i>
|
|
<% End If %>
|
|
</td>
|
|
<td><span title="<%=Server.HTMLEncode(locNotes)%>"><%
|
|
If Len(locNotes) > 40 Then
|
|
Response.Write(Server.HTMLEncode(Left(locNotes, 40)) & "...")
|
|
Else
|
|
Response.Write(Server.HTMLEncode(locNotes))
|
|
End If
|
|
%></span></td>
|
|
<td>
|
|
<a href="displaymachine.asp?machineid=<%=mid%>" class="btn btn-sm btn-outline-info" title="View">
|
|
<i class="zmdi zmdi-eye"></i>
|
|
</a>
|
|
<a href="printbadge.asp?machineid=<%=mid%>" class="btn btn-sm btn-outline-secondary" title="Print Label" target="_blank">
|
|
<i class="zmdi zmdi-label"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<%
|
|
' Render hidden detail rows for this location's relationships
|
|
If hasRels Then
|
|
Dim entries, i, parts
|
|
entries = Split(relDict(midStr), "~")
|
|
For i = 0 To UBound(entries)
|
|
parts = Split(entries(i), "|")
|
|
' parts: 0=child_id, 1=child_name, 2=child_hostname, 3=child_alias, 4=child_ip, 5=pctypeid, 6=islocationonly, 7=relationshiptype
|
|
Dim cId, cName, cHost, cAlias, cIp, cIsPC, cIsLoc, cRelType, cBadgeClass, cIcon, cLink
|
|
cId = parts(0)
|
|
cName = parts(1)
|
|
cHost = parts(2)
|
|
cAlias = parts(3)
|
|
cIp = parts(4)
|
|
cIsPC = (parts(5) <> "")
|
|
cIsLoc = (parts(6) = "1" Or parts(6) = "True")
|
|
cRelType = parts(7)
|
|
|
|
' Determine icon and badge
|
|
If cIsLoc Then
|
|
cIcon = "zmdi zmdi-pin text-info"
|
|
cBadgeClass = "badge-info"
|
|
cLink = "displaymachine.asp?machineid=" & cId
|
|
ElseIf cIsPC Then
|
|
cIcon = "zmdi zmdi-desktop-windows text-primary"
|
|
cBadgeClass = "badge-primary"
|
|
cLink = "displaypc.asp?machineid=" & cId
|
|
Else
|
|
cIcon = "zmdi zmdi-memory text-warning"
|
|
cBadgeClass = "badge-warning"
|
|
cLink = "displaymachine.asp?machineid=" & cId
|
|
End If
|
|
|
|
' Display name: use hostname for PCs if available, else machinenumber
|
|
Dim displayName
|
|
If cIsPC And cHost <> "" Then
|
|
displayName = cHost
|
|
Else
|
|
displayName = cName
|
|
End If
|
|
%>
|
|
<tr class="loc-detail loc-detail-<%=mid%>" style="display:none;">
|
|
<td></td>
|
|
<td style="padding-left:30px;">
|
|
<i class="<%=cIcon%>" style="margin-right:5px;"></i>
|
|
<a href="<%=cLink%>"><%=Server.HTMLEncode(displayName)%></a>
|
|
<% If cAlias <> "" Then %>
|
|
<small class="text-muted"> (<%=Server.HTMLEncode(cAlias)%>)</small>
|
|
<% End If %>
|
|
</td>
|
|
<td>
|
|
<% If cIp <> "" Then %>
|
|
<small><%=Server.HTMLEncode(cIp)%></small>
|
|
<% End If %>
|
|
</td>
|
|
<td colspan="2">
|
|
<span class="badge <%=cBadgeClass%>"><%=Server.HTMLEncode(cRelType)%></span>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
<td>
|
|
<a href="<%=cLink%>" class="btn btn-sm btn-outline-info" title="View">
|
|
<i class="zmdi zmdi-eye"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<%
|
|
Next
|
|
End If
|
|
|
|
rs.MoveNext
|
|
Loop
|
|
rs.Close
|
|
Set rs = Nothing
|
|
Set relDict = Nothing
|
|
%>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</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 class="container">
|
|
<div class="text-center">
|
|
</div>
|
|
</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>
|
|
|
|
<!-- simplebar js -->
|
|
<script src="assets/plugins/simplebar/js/simplebar.js"></script>
|
|
<!-- sidebar-menu js -->
|
|
<script src="assets/js/sidebar-menu.js"></script>
|
|
|
|
<!-- DataTables -->
|
|
<link rel="stylesheet" href="assets/plugins/datatables/dataTables.bootstrap4.min.css">
|
|
<script src="assets/plugins/datatables/jquery.dataTables.min.js"></script>
|
|
<script src="assets/plugins/datatables/dataTables.bootstrap4.min.js"></script>
|
|
|
|
<!-- Custom scripts -->
|
|
<script src="assets/js/app-script.js"></script>
|
|
|
|
<style>
|
|
.loc-detail td {
|
|
border-top: none !important;
|
|
padding-top: 2px !important;
|
|
padding-bottom: 2px !important;
|
|
background: rgba(0,0,0,0.05) !important;
|
|
}
|
|
.loc-toggle.open {
|
|
transform: rotate(90deg);
|
|
}
|
|
.loc-parent:hover {
|
|
background: rgba(255,255,255,0.03);
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
$(document).ready(function() {
|
|
var dt = $('#locationsTable').DataTable({
|
|
"order": [[1, "asc"]],
|
|
"pageLength": 25,
|
|
"language": {
|
|
"emptyTable": "No locations found",
|
|
"search": "Filter:"
|
|
},
|
|
"columnDefs": [
|
|
{ "orderable": false, "targets": 0 },
|
|
{ "searchable": false, "targets": 0 }
|
|
]
|
|
});
|
|
|
|
// Toggle detail rows
|
|
$('#locationsTable').on('click', '.loc-parent', function(e) {
|
|
// Don't toggle if clicking a link or button
|
|
if ($(e.target).closest('a, button').length) return;
|
|
|
|
var mid = $(this).data('mid');
|
|
var toggle = $(this).find('.loc-toggle');
|
|
var details = $('.loc-detail-' + mid);
|
|
|
|
if (details.first().is(':visible')) {
|
|
details.hide();
|
|
toggle.removeClass('open');
|
|
} else {
|
|
details.show();
|
|
toggle.addClass('open');
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|
|
<%
|
|
objConn.Close
|
|
%>
|