backups panels show only when the asset has data

This commit is contained in:
2026-08-07 14:53:54 -04:00
parent 64f30f7c9f
commit 2487981d91
3 changed files with 56 additions and 8 deletions

View File

@@ -91,7 +91,7 @@ class BackupsPlugin(BasePlugin):
panels = [kind.infopanel() for kind in REGISTRY.values()
if kind.infopanel()]
for position, kind in enumerate(REGISTRY.values()):
panels.append({
panel = {
'id': 'backups-{}'.format(kind.key),
'title': kind.displayname,
'assettypes': list(kind.assettypes),
@@ -105,7 +105,6 @@ class BackupsPlugin(BasePlugin):
{'key': 'shorthash', 'label': 'Hash', 'mono': True},
],
},
'empty': kind.emptytext,
# The generic renderer has no per-item actions, and downloading
# a .reg needs a per-revision control plus a dialect choice, so
# the panel links to the plugin's own history view instead.
@@ -115,7 +114,16 @@ class BackupsPlugin(BasePlugin):
'emptylabel': 'View history',
},
'position': 40 + position,
})
}
# OMIT 'empty' entirely unless the kind sets it. The list renderer
# shows a panel when it has rows OR declares empty text, so a
# present-but-null 'empty' would still render the panel on every
# asset of the type. Most machines are not part markers and never
# will be, so that panel must disappear rather than announce it has
# nothing.
if kind.emptytext:
panel['empty'] = kind.emptytext
panels.append(panel)
return panels
def get_settings_defaults(self) -> List[Dict]:

View File

@@ -59,8 +59,13 @@ class BackupKind:
displayname = None
storagebackend = 'shopdb'
assettypes = ['*']
# Human note shown on the panel when there is nothing yet.
emptytext = 'No backups on record.'
# Text shown when the kind has no revisions for an asset. None means the
# panel HIDES entirely instead (the generic list renderer shows a panel
# only when it has rows or declares empty text). Default to hiding: a kind
# applies to an asset TYPE, but whether a given asset ever has this kind of
# backup is a property of the individual machine. A part marker panel on
# every one of 144 machines is noise, not information.
emptytext = None
def parse(self, raw):
"""Opaque kinds return None; parseable kinds return the projection."""
@@ -118,7 +123,6 @@ class NtlarsKind(BackupKind):
displayname = 'NTLARS / DNC Settings'
storagebackend = 'shopdb'
assettypes = ['machine']
emptytext = 'No NTLARS settings captured yet.'
@staticmethod
def embeddedmachineno(projection):
@@ -176,8 +180,10 @@ class NtlarsKind(BackupKind):
'title': 'DNC Info',
'assettypes': ['machine'],
'endpoint': '/api/backups/asset/{assetid}/info?kind=ntlars',
# No 'empty' key: the keyvalue renderer decides visibility purely on
# field count and never displays empty text, so a machine with no
# NTLARS revision simply has no DNC Info card at all.
'render': 'keyvalue',
'empty': 'No NTLARS settings captured for this machine yet.',
# Above the history panels: this answers the question a tech
# arrives with, while history is for the rarer restore case.
'position': 38,
@@ -214,7 +220,6 @@ class PartMarkerKind(BackupKind):
displayname = 'Part Marker Configuration'
storagebackend = 'share'
assettypes = ['machine', 'measuring_tool']
emptytext = 'No part marker backups on record.'
def resolveassetid(self, payload):
from shopdb.api import db, Asset