Rename Metrics to Monitors and move it second

This commit is contained in:
2026-08-31 15:21:48 -04:00
parent b21503e250
commit f087a7a5b0
6 changed files with 29 additions and 24 deletions

View File

@@ -200,8 +200,9 @@ const panels = ref([])
// has since been renamed or removed silently disappears. That is what happened
// to tracked services when it moved out of 'actions' - the backend still said
// 'actions', this build had no such tab, and the card was simply gone with
// nothing logged. Fall back the same way the server does rather than drop it.
const RENDERED_GROUPS = ['details', 'software', 'metrics', 'activity']
// nothing logged. The same applies to the 'metrics' to 'monitors' rename.
// Fall back the same way the server does rather than drop it.
const RENDERED_GROUPS = ['details', 'monitors', 'software', 'activity']
function groupOf(panel) {
return RENDERED_GROUPS.includes(panel.group) ? panel.group : 'details'
}

View File

@@ -302,13 +302,14 @@
</div>
</div>
<!-- Metrics and Activity are entirely plugin-contributed: the telemetry,
the service state and its controls, and the event feed all belong to
the endpoints plugin, and core knows nothing about them.
<!-- Monitors and Activity are entirely plugin-contributed: what is being
watched on the box, the service state and its controls, and the event
feed all belong to the endpoints plugin, and core knows nothing about
them.
Metrics keeps the two-column flow because it is short cards. -->
<div v-show="activegroup === 'metrics'" class="content-grid">
<PluginAssetPanels :assetid="computer.assetid" group="metrics" />
Monitors keeps the two-column flow because it is short cards. -->
<div v-show="activegroup === 'monitors'" class="content-grid">
<PluginAssetPanels :assetid="computer.assetid" group="monitors" />
</div>
<div v-show="activegroup === 'activity'" class="detail-full">
<PluginAssetPanels :assetid="computer.assetid" group="activity" />
@@ -384,10 +385,12 @@ const detailtabs = computed(() => {
const filled = assetPanels.value?.populatedGroups ?? new Set()
const has = (key) => filled.has ? filled.has(key) : false
const tabs = [{ key: 'details', label: 'Details' }]
// Monitors sits second: what is being watched on this box is the question
// asked right after "what is it", and well before its software inventory.
if (has('monitors')) tabs.push({ key: 'monitors', label: 'Monitors' })
if (has('software') || installedApps.value.length > 0) {
tabs.push({ key: 'software', label: 'Software', count: installedApps.value.length || null })
}
if (has('metrics')) tabs.push({ key: 'metrics', label: 'Metrics' })
if (has('activity')) tabs.push({ key: 'activity', label: 'Activity' })
return tabs
})

View File

@@ -351,9 +351,9 @@ class EndpointsPlugin(BasePlugin):
'permission': 'endpoints.command',
'empty': 'No monitored services reported.',
'position': 12,
# Service state is telemetry first; the Start/Stop controls
# belong beside it rather than in a tab of their own.
'group': 'metrics',
# Service state is what is being watched; the Start/Stop
# controls belong beside it, not in a tab of their own.
'group': 'monitors',
},
{
'id': 'endpoints-tracked-processes',
@@ -393,7 +393,7 @@ class EndpointsPlugin(BasePlugin):
'empty': 'No monitored processes reported.',
'position': 13,
# observed process state, not something you act on here
'group': 'metrics',
'group': 'monitors',
},
{
# One feed instead of two cards. Events and commands answer the
@@ -458,8 +458,8 @@ class EndpointsPlugin(BasePlugin):
],
'empty': 'No network interfaces reported.',
'position': 16,
# adapter state is telemetry, not something you act on
'group': 'metrics',
# adapter state is watched, not something you act on
'group': 'monitors',
},
{
# Installed-software (SBOM) inventory. Raw discovered list for

View File

@@ -25,7 +25,7 @@ pluginui_bp = Blueprint('pluginui', __name__)
#
# 'details' is first and is the fallback: it holds what an asset IS, which is
# what a panel declaring nothing almost always contributes.
ASSET_PANEL_GROUPS = ('details', 'software', 'metrics', 'activity')
ASSET_PANEL_GROUPS = ('details', 'monitors', 'software', 'activity')
def _collect(hookname):

View File

@@ -371,7 +371,7 @@ class BasePlugin(ABC):
# keys, rendered generically - see warranty)
'position': int, # order among panels
'group': str, # OPTIONAL. Which tab on the detail page:
# 'details' | 'software' | 'metrics'
# 'details' | 'monitors' | 'software'
# | 'activity'. Omitted means 'details'.
}
@@ -383,12 +383,13 @@ class BasePlugin(ABC):
existing plugin working untouched: an unknown or absent group resolves
to 'details', which is the tab that holds what an asset IS. Reach for
another group only when the panel is the thing that tab exists for -
an inventory listing, live telemetry, or a history feed.
what is being watched on the box, an inventory listing, or a history
feed.
There is deliberately no group for controls. A panel that acts on the
machine belongs beside the state it acts on: tracked services read as
telemetry first and a Start/Stop second, so they live in 'metrics' with
the rest of what the endpoint reports. Splitting the buttons away from
state first and a Start/Stop second, so they live in 'monitors' with
the rest of what is being watched. Splitting the buttons away from
the state they change made a tab that held one card and answered no
question on its own.

View File

@@ -198,7 +198,7 @@ def test_a_group_nobody_defined_falls_back_rather_than_disappearing(
monkeypatch.setattr(plugin, 'get_asset_panels', lambda: [{
'id': 'typo', 'title': 'Typo', 'assettypes': ['*'],
'endpoint': '/api/whatever', 'render': 'keyvalue', 'position': 1,
'group': 'metrcis',
'group': 'montiors',
}])
assetid = _make_asset(db)
@@ -210,18 +210,18 @@ def test_a_group_nobody_defined_falls_back_rather_than_disappearing(
def test_group_matching_is_not_case_or_space_sensitive(app, client, db,
auth_headers, monkeypatch):
"""'Metrics ' is obviously meant to be metrics; do not send it to details."""
"""'Monitors ' is obviously meant to be monitors; do not send it to details."""
pm = app.extensions['plugin_manager']
monkeypatch.setattr(pm.registry, 'is_enabled', lambda name: True)
plugin = next(iter(pm.get_all_plugins().values()))
monkeypatch.setattr(plugin, 'get_asset_panels', lambda: [{
'id': 'shouty', 'title': 'Shouty', 'assettypes': ['*'],
'endpoint': '/api/whatever', 'render': 'keyvalue', 'position': 1,
'group': ' Metrics ',
'group': ' Monitors ',
}])
assetid = _make_asset(db)
panels = _data(client, '/api/pluginui/asset-panels?assetid=%d' % assetid,
auth_headers)
panel = next(p for p in panels if p['id'] == 'shouty')
assert panel['group'] == 'metrics'
assert panel['group'] == 'monitors'