Gate endpoint UI refresh on fresh telemetry and land endpoint agent
A command reaching 'succeeded' only proves the agent ran the action, not that it posted a new telemetry snapshot. Reloading panels on command success alone re-rendered stale service/process rows, so a stopped process could still show running right after Refresh Status. Add a lightweight telemetrymeta probe exposing lastreportedat and gate both the header Refresh Status action and inline row Start/Stop on that stamp advancing past a pre-action baseline. Polling is bounded so an offline or idle agent never hangs the button, and messaging distinguishes a confirmed refresh from a queued one. Bring the .NET endpoint agent source (service, tray, installer) into the repo so Cameron can merge and test, with an agent/.gitignore keeping bin/obj/publish out. Includes the DncMain launch-path fix, tray single-file host env scrub, and best-effort file logger.
This commit is contained in:
@@ -72,6 +72,34 @@ describe('list render mapping (warranty)', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('list row filtering (tracked services vs processes)', () => {
|
||||
const feedPanel = {
|
||||
id: 'endpoints-tracked-services', render: 'list',
|
||||
filter: { key: 'kind', equals: 'service' },
|
||||
map: { title: 'name' },
|
||||
_data: [
|
||||
{ name: 'UDC MTConnect Agent', kind: 'service' },
|
||||
{ name: 'DncMain', kind: 'process' },
|
||||
{ name: 'Spooler', kind: 'SERVICE' },
|
||||
],
|
||||
}
|
||||
|
||||
it('keeps only rows whose filter key matches, case-insensitively', () => {
|
||||
const kept = rows(feedPanel).map((r) => r.name)
|
||||
expect(kept).toEqual(['UDC MTConnect Agent', 'Spooler'])
|
||||
})
|
||||
|
||||
it('filters the same feed to processes when equals is process', () => {
|
||||
const kept = rows({ ...feedPanel, filter: { key: 'kind', equals: 'process' } })
|
||||
expect(kept.map((r) => r.name)).toEqual(['DncMain'])
|
||||
})
|
||||
|
||||
it('returns every row when no filter is declared', () => {
|
||||
const kept = rows({ ...feedPanel, filter: undefined })
|
||||
expect(kept).toHaveLength(3)
|
||||
})
|
||||
})
|
||||
|
||||
describe('keyvalue + table + badge', () => {
|
||||
it('keyvalue reads a fields array or a plain object', () => {
|
||||
const fromFields = keyvalueFields({
|
||||
|
||||
Reference in New Issue
Block a user