Full-width GE-Enforce pages; asset column no longer echoes the host

This commit is contained in:
2026-08-12 17:01:10 -04:00
parent 2c822e462d
commit 50578f33bd
7 changed files with 52 additions and 5 deletions

View File

@@ -1106,7 +1106,9 @@ def list_reports():
'machineassetid': known.get('machineassetid'),
'toolassetnumber': known.get('toolassetnumber'),
'toolassetid': known.get('toolassetid'),
'displayrole': known.get('displayrole'),
# Reported by the device wins; the DashboardDefault mapping is a
# fallback for hosts on an older client that does not send it.
'displayrole': report.subtype or known.get('displayrole'),
'backupkind': known.get('backupkind'),
'backuplastseen': known.get('backuplastseen'),
'scopename': report.scopename,

View File

@@ -73,8 +73,12 @@
</router-link>
<span v-if="report.displayrole" class="asset-chip muted"
title="Display role">{{ report.displayrole }}</span>
<!-- Deliberately NOT the PC's own asset number: the collector
stores a PC's hostname AS its assetnumber, so echoing it
here would just repeat the Host column. Blank means this PC
drives nothing and is not a display. -->
<span v-if="!report.machineassetid && !report.toolassetid && !report.displayrole"
class="muted">{{ report.assetnumber || '-' }}</span>
class="muted">-</span>
<div v-if="report.location" class="asset-location muted">{{ report.location }}</div>
</td>
<td>{{ report.scopename }}</td>
@@ -189,7 +193,11 @@ load()
</script>
<style scoped>
.enforcement-reports { max-width: 1100px; }
/* No max-width. This is a fleet table - twelve columns now that a row carries
the asset it drives, its location and its backup state - and capping the page
at 1100px squeezed them into a box narrower than the window while empty space
sat to the right. The route already gives this view a full-width shell. */
.enforcement-reports { width: 100%; }
.muted { color: var(--text-light); }
.fail-count { color: var(--danger); font-weight: 600; }
.empty { color: var(--text-light); text-align: center; padding: 1rem; }

View File

@@ -18,7 +18,10 @@
</script>
<style scoped>
.geenforce-section { max-width: 1400px; }
/* No cap on the shell. The reports tab is a wide fleet table and was being
squeezed into 1400px with empty page beside it; views that read better
narrow (the manifest editor) cap themselves instead. */
.geenforce-section { width: 100%; }
.section-header { margin-bottom: 0.5rem; }
.section-header h1 { margin: 0; }
.section-sub { color: var(--text-light); margin: 0.25rem 0 0; }

View File

@@ -0,0 +1,28 @@
"""Record the display subtype a PC reports for itself.
A kiosk knows whether it is a Dashboard, Lobby or 3DPrintRoom - the dispatcher
reads C:\\Enrollment\\display-type.txt to pick its target - but it never told
ShopDB, so the reports table had to infer it from the DashboardDefault
fqdn/ip mapping, which is blank unless someone added a row per kiosk. Reported
by the device beats inferred from a mapping table, the same way enforcerversion
already works.
Revision ID: geenforce0003subtype
Revises: geenforce0002blobs
"""
from alembic import op
import sqlalchemy as sa
revision = 'geenforce0003subtype'
down_revision = 'geenforce0002blobs'
branch_labels = None
depends_on = None
def upgrade():
op.add_column('manifestenforcementreports',
sa.Column('subtype', sa.String(length=50), nullable=True))
def downgrade():
op.drop_column('manifestenforcementreports', 'subtype')

View File

@@ -295,6 +295,11 @@ class ManifestEnforcementReport(db.Model):
# published version to see whether this PC received the latest manifest.
appliedversion = db.Column(db.Integer, nullable=True)
enforcerversion = db.Column(db.String(20), nullable=True)
# What the PC says it IS within its scope (a display's Dashboard / Lobby /
# 3DPrintRoom). Reported by the device, which reads it from its own
# enrollment file - not inferred from a mapping table that may have no row
# for this host.
subtype = db.Column(db.String(50), nullable=True)
installedcount = db.Column(db.Integer, nullable=False, default=0)
skippedcount = db.Column(db.Integer, nullable=False, default=0)
failedcount = db.Column(db.Integer, nullable=False, default=0)

View File

@@ -263,6 +263,7 @@ def record_enforcement_report(payload):
phase=phase,
appliedversion=payload.get('appliedversion'),
enforcerversion=payload.get('enforcerversion'),
subtype=(payload.get('subtype') or None),
installedcount=installed,
skippedcount=int(counts.get('skipped', 0)),
failedcount=failed,

View File

@@ -52,7 +52,7 @@ EXPECTED_HEAD_REVISION['measuringtools'] = 'measuringtools0001baseline'
EXPECTED_HEAD_REVISION['backups'] = 'backups0003clearlastseen'
# geenforce adds the content-addressed blob store (manifestblobs) on top of its
# baseline.
EXPECTED_HEAD_REVISION['geenforce'] = 'geenforce0002blobs'
EXPECTED_HEAD_REVISION['geenforce'] = 'geenforce0003subtype'
# printers adds the printersupplyalerts crossing-state table on top of its anchor.
EXPECTED_HEAD_REVISION['printers'] = 'printers0002supplyalerts'
# machines (renamed from equipment) keeps its original anchor id and adds the