Full-width GE-Enforce pages; asset column no longer echoes the host
This commit is contained in:
@@ -1106,7 +1106,9 @@ def list_reports():
|
|||||||
'machineassetid': known.get('machineassetid'),
|
'machineassetid': known.get('machineassetid'),
|
||||||
'toolassetnumber': known.get('toolassetnumber'),
|
'toolassetnumber': known.get('toolassetnumber'),
|
||||||
'toolassetid': known.get('toolassetid'),
|
'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'),
|
'backupkind': known.get('backupkind'),
|
||||||
'backuplastseen': known.get('backuplastseen'),
|
'backuplastseen': known.get('backuplastseen'),
|
||||||
'scopename': report.scopename,
|
'scopename': report.scopename,
|
||||||
|
|||||||
@@ -73,8 +73,12 @@
|
|||||||
</router-link>
|
</router-link>
|
||||||
<span v-if="report.displayrole" class="asset-chip muted"
|
<span v-if="report.displayrole" class="asset-chip muted"
|
||||||
title="Display role">{{ report.displayrole }}</span>
|
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"
|
<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>
|
<div v-if="report.location" class="asset-location muted">{{ report.location }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ report.scopename }}</td>
|
<td>{{ report.scopename }}</td>
|
||||||
@@ -189,7 +193,11 @@ load()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<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); }
|
.muted { color: var(--text-light); }
|
||||||
.fail-count { color: var(--danger); font-weight: 600; }
|
.fail-count { color: var(--danger); font-weight: 600; }
|
||||||
.empty { color: var(--text-light); text-align: center; padding: 1rem; }
|
.empty { color: var(--text-light); text-align: center; padding: 1rem; }
|
||||||
|
|||||||
@@ -18,7 +18,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<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 { margin-bottom: 0.5rem; }
|
||||||
.section-header h1 { margin: 0; }
|
.section-header h1 { margin: 0; }
|
||||||
.section-sub { color: var(--text-light); margin: 0.25rem 0 0; }
|
.section-sub { color: var(--text-light); margin: 0.25rem 0 0; }
|
||||||
|
|||||||
28
plugins/geenforce/migrations/versions/0003_report_subtype.py
Normal file
28
plugins/geenforce/migrations/versions/0003_report_subtype.py
Normal 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')
|
||||||
@@ -295,6 +295,11 @@ class ManifestEnforcementReport(db.Model):
|
|||||||
# published version to see whether this PC received the latest manifest.
|
# published version to see whether this PC received the latest manifest.
|
||||||
appliedversion = db.Column(db.Integer, nullable=True)
|
appliedversion = db.Column(db.Integer, nullable=True)
|
||||||
enforcerversion = db.Column(db.String(20), 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)
|
installedcount = db.Column(db.Integer, nullable=False, default=0)
|
||||||
skippedcount = 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)
|
failedcount = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ def record_enforcement_report(payload):
|
|||||||
phase=phase,
|
phase=phase,
|
||||||
appliedversion=payload.get('appliedversion'),
|
appliedversion=payload.get('appliedversion'),
|
||||||
enforcerversion=payload.get('enforcerversion'),
|
enforcerversion=payload.get('enforcerversion'),
|
||||||
|
subtype=(payload.get('subtype') or None),
|
||||||
installedcount=installed,
|
installedcount=installed,
|
||||||
skippedcount=int(counts.get('skipped', 0)),
|
skippedcount=int(counts.get('skipped', 0)),
|
||||||
failedcount=failed,
|
failedcount=failed,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ EXPECTED_HEAD_REVISION['measuringtools'] = 'measuringtools0001baseline'
|
|||||||
EXPECTED_HEAD_REVISION['backups'] = 'backups0003clearlastseen'
|
EXPECTED_HEAD_REVISION['backups'] = 'backups0003clearlastseen'
|
||||||
# geenforce adds the content-addressed blob store (manifestblobs) on top of its
|
# geenforce adds the content-addressed blob store (manifestblobs) on top of its
|
||||||
# baseline.
|
# baseline.
|
||||||
EXPECTED_HEAD_REVISION['geenforce'] = 'geenforce0002blobs'
|
EXPECTED_HEAD_REVISION['geenforce'] = 'geenforce0003subtype'
|
||||||
# printers adds the printersupplyalerts crossing-state table on top of its anchor.
|
# printers adds the printersupplyalerts crossing-state table on top of its anchor.
|
||||||
EXPECTED_HEAD_REVISION['printers'] = 'printers0002supplyalerts'
|
EXPECTED_HEAD_REVISION['printers'] = 'printers0002supplyalerts'
|
||||||
# machines (renamed from equipment) keeps its original anchor id and adds the
|
# machines (renamed from equipment) keeps its original anchor id and adds the
|
||||||
|
|||||||
Reference in New Issue
Block a user