Add print badges, pagination, route splitting, JWT auth fixes, and list page alignment

- Fix equipment badge barcode not rendering (loading race condition)
- Fix printer QR code not rendering on initial load (same race condition)
- Add model image to equipment badge via imageurl from Model table
- Fix white-on-white machine number text on badge, tighten barcode spacing
- Add PaginationBar component used across all list pages
- Split monolithic router into per-plugin route modules
- Fix 25 GET API endpoints returning 401 (jwt_required -> optional=True)
- Align list page columns across Equipment, PCs, and Network pages
- Add print views: EquipmentBadge, PrinterQRSingle, PrinterQRBatch, USBLabelBatch
- Add PC Relationships report, migration docs, and CLAUDE.md project guide
- Various plugin model, API, and frontend refinements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-02-04 07:32:44 -05:00
parent fe7a00b260
commit 83caaa7b7c
89 changed files with 3951 additions and 1138 deletions

View File

@@ -20,22 +20,22 @@
</div>
<div class="hero-meta">
<span class="badge badge-lg badge-info">Computer</span>
<span class="badge badge-lg" :class="getStatusClass(computer.status_name)">
{{ computer.status_name || 'Unknown' }}
<span class="badge badge-lg" :class="getStatusClass(computer.statusname)">
{{ computer.statusname || 'Unknown' }}
</span>
</div>
<div class="hero-details">
<div class="hero-detail" v-if="computer.computer?.computertype_name">
<div class="hero-detail" v-if="computer.computer?.computertypename">
<span class="hero-detail-label">Type</span>
<span class="hero-detail-value">{{ computer.computer.computertype_name }}</span>
<span class="hero-detail-value">{{ computer.computer.computertypename }}</span>
</div>
<div class="hero-detail" v-if="computer.computer?.os_name">
<div class="hero-detail" v-if="computer.computer?.osname">
<span class="hero-detail-label">OS</span>
<span class="hero-detail-value">{{ computer.computer.os_name }}</span>
<span class="hero-detail-value">{{ computer.computer.osname }}</span>
</div>
<div class="hero-detail" v-if="computer.location_name">
<div class="hero-detail" v-if="computer.locationname">
<span class="hero-detail-label">Location</span>
<span class="hero-detail-value">{{ computer.location_name }}</span>
<span class="hero-detail-value">{{ computer.locationname }}</span>
</div>
</div>
</div>
@@ -74,11 +74,11 @@
<div class="info-list">
<div class="info-row">
<span class="info-label">Computer Type</span>
<span class="info-value">{{ computer.computer?.computertype_name || '-' }}</span>
<span class="info-value">{{ computer.computer?.computertypename || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">Operating System</span>
<span class="info-value">{{ computer.computer?.os_name || '-' }}</span>
<span class="info-value">{{ computer.computer?.osname || '-' }}</span>
</div>
</div>
</div>
@@ -126,14 +126,14 @@
:top="computer.maptop"
:machineName="computer.assetnumber"
>
<span class="location-link">{{ computer.location_name || 'On Map' }}</span>
<span class="location-link">{{ computer.locationname || 'On Map' }}</span>
</LocationMapTooltip>
<span v-else>{{ computer.location_name || '-' }}</span>
<span v-else>{{ computer.locationname || '-' }}</span>
</span>
</div>
<div class="info-row">
<span class="info-label">Business Unit</span>
<span class="info-value">{{ computer.businessunit_name || '-' }}</span>
<span class="info-value">{{ computer.businessunitname || '-' }}</span>
</div>
</div>
</div>
@@ -145,7 +145,7 @@
<router-link
v-for="item in controlledEquipment"
:key="item.relationshipid"
:to="`/machines/${item.plugin_id || item.assetid}`"
:to="`/machines/${item.pluginid || item.assetid}`"
class="equipment-item"
>
<div class="equipment-info">
@@ -153,7 +153,7 @@
<span class="equipment-alias" v-if="item.name">{{ item.name }}</span>
</div>
<div class="equipment-meta">
<span class="category-tag">{{ item.assettype_name }}</span>
<span class="category-tag">{{ item.assettypename }}</span>
<span class="connection-tag">{{ item.relationshipType }}</span>
</div>
</router-link>
@@ -221,22 +221,22 @@ const controlledEquipment = computed(() => {
// Check outgoing - computer controls equipment
for (const rel of relationships.value.outgoing || []) {
if (rel.target_asset?.assettype_name === 'equipment' && rel.relationship_type_name === 'Controls') {
if (rel.targetasset?.assettypename === 'equipment' && rel.relationshiptypename === 'Controls') {
items.push({
...rel.target_asset,
...rel.targetasset,
relationshipid: rel.relationshipid,
relationshipType: rel.relationship_type_name
relationshipType: rel.relationshiptypename
})
}
}
// Also check incoming - legacy data may have equipment -> computer Controls relationships
for (const rel of relationships.value.incoming || []) {
if (rel.source_asset?.assettype_name === 'equipment' && rel.relationship_type_name === 'Controls') {
if (rel.sourceasset?.assettypename === 'equipment' && rel.relationshiptypename === 'Controls') {
items.push({
...rel.source_asset,
...rel.sourceasset,
relationshipid: rel.relationshipid,
relationshipType: rel.relationship_type_name
relationshipType: rel.relationshiptypename
})
}
}