@andrian.yablonskyy/thub-coordinator 1.1.15 → 1.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -156,7 +156,7 @@ Server-rendered Pug templates styled with Bootstrap 5.3, with a little vanilla J
156
156
  | Page | Content |
157
157
  |---|---|
158
158
  | `/` | Runner cards by status, queue length, jobs in the last 24 h. Click a card for its runner card (below). |
159
- | `/runners` | **Runners** (formerly Resources; `/resources` redirects): Type, Client version, labels, groups, status, busy source/reason, last heartbeat age; admin maintenance/rotate-token actions. Click a row for its resource card (below). |
159
+ | `/runners` | **Runners** (formerly Resources; `/resources` redirects): Type, Client version, labels, groups, status (with the last heartbeat under it), busy source/reason; admin maintenance/rotate-token actions. Click a row for its resource card (below). |
160
160
  | `/groups` | Resource groups — id/name/comment, member count; admin create/rename/delete. Membership itself is set per-resource in the Client's own config. |
161
161
  | `/jobs` | Filterable job list (state, source, resource), with the job's `user` label if set; admin **Reset queue** / **Clean history**. |
162
162
  | `/jobs/:id` | Spec, timeline, live log viewer with stream filter, artifact downloads, cancel button. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andrian.yablonskyy/thub-coordinator",
3
- "version": "1.1.15",
3
+ "version": "1.1.16",
4
4
  "description": "TestHub Coordinator — job queue, resource registry, scheduler, heartbeat monitor, log/artifact store and web dashboard",
5
5
  "main": "src/server.js",
6
6
  "engines": {
@@ -457,3 +457,20 @@ fieldset:disabled .thub-tags-box {
457
457
  white-space: nowrap;
458
458
  }
459
459
  }
460
+
461
+ /* A second, smaller line in a table cell: the version under a name (Runners,
462
+ CI tokens), the last heartbeat under a status (Runners). */
463
+ .thub-subline {
464
+ font-size: 0.7rem;
465
+ margin-top: 0.125rem;
466
+ }
467
+
468
+ .thub-subline .badge {
469
+ font-size: 0.65rem;
470
+ }
471
+
472
+ .thub-subline .btn {
473
+ --bs-btn-padding-y: 0;
474
+ --bs-btn-padding-x: 0.3rem;
475
+ --bs-btn-font-size: 0.7rem;
476
+ }
@@ -31,7 +31,6 @@ block content
31
31
  tr
32
32
  +sortHeader(list, 'name', 'Name')
33
33
  +sortHeader(list, 'group', 'Group')
34
- +sortHeader(list, 'version', 'Version', 'desc')
35
34
  +sortHeader(list, 'created', 'Created', 'desc')
36
35
  +sortHeader(list, 'used', 'Last used', 'desc')
37
36
  +sortHeader(list, 'status', 'Status')
@@ -42,13 +41,14 @@ block content
42
41
  //- The name opens Edit (name and group).
43
42
  td
44
43
  a.fw-medium(href=`#editAgentModal-${a.id}` data-bs-toggle="modal" role="button")= a.name
44
+ //- Its Agent's last reported version and update controls (none for a revoked token).
45
+ .thub-subline.text-body-secondary
46
+ +versionWithUpdate(a.version, updates.latest.agent, a.update_to, `/admin/agents/${a.id}/update`, list.pageUrl(), !a.revoked_at)
45
47
  td
46
48
  if a.group_id && groupsById[a.group_id]
47
49
  span.badge.text-bg-info= groupsById[a.group_id].name
48
50
  else
49
51
  span.text-body-secondary any
50
- //- A revoked token can't pick an update up: no button.
51
- td: +versionWithUpdate(a.version, updates.latest.agent, a.update_to, `/admin/agents/${a.id}/update`, list.pageUrl(), !a.revoked_at)
52
52
  td= fmtDate(a.created_at)
53
53
  td= fmtDate(a.last_used_at, 'never')
54
54
  td= a.revoked_at ? 'revoked' : 'active'
@@ -89,7 +89,7 @@ block content
89
89
 
90
90
  else
91
91
  tr
92
- td.text-body-secondary(colspan="7")
92
+ td.text-body-secondary(colspan="6")
93
93
  if q
94
94
  | No agent matches “#{q}”.
95
95
  a(href=list.urlFor({ q: '' })) Show all agents
@@ -24,21 +24,25 @@ block content
24
24
  tr
25
25
  +sortHeader(list, 'name', 'Name')
26
26
  +sortHeader(list, 'type', 'Type')
27
- +sortHeader(list, 'version', 'Version', 'desc')
28
27
  +sortHeader(list, 'status', 'Status')
29
28
  th Labels
30
29
  th Groups
31
30
  th Busy source / reason
32
- +sortHeader(list, 'heartbeat', 'Last heartbeat', 'desc')
33
31
  if can.operate
34
32
  th Actions
35
33
  tbody(data-live="rows")
36
34
  each r in resources
37
35
  tr(role="button" tabindex="0" data-resource-card=`resource-card-${r.id}`)
38
- td= r.name
36
+ //- Name, and under it the Client's version (with its update controls).
37
+ td
38
+ div= r.name
39
+ .thub-subline.text-body-secondary
40
+ +versionWithUpdate(r.client_version, updates.latest.client, r.update_to, `/runners/${r.id}/update`, list.pageUrl(), true, r.activity && r.activity.state === 'update-hold')
39
41
  td.text-uppercase= r.type
40
- td: +versionWithUpdate(r.client_version, updates.latest.client, r.update_to, `/runners/${r.id}/update`, list.pageUrl(), true, r.activity && r.activity.state === 'update-hold')
41
- td: +resourceBadge(r.status, r.remove_requested_at)
42
+ //- Status, and under it when the Client last heartbeated.
43
+ td
44
+ +resourceBadge(r.status, r.remove_requested_at)
45
+ .thub-subline.text-body-secondary.text-nowrap(title="Last heartbeat")= fmtDate(r.last_heartbeat_at, 'never')
42
46
  //- One label per line.
43
47
  td
44
48
  if r.labels.length
@@ -52,7 +56,6 @@ block content
52
56
  else
53
57
  span.text-body-secondary —
54
58
  td= r.busy_source ? `${r.busy_source}${r.busy_reason ? ' — ' + r.busy_reason : ''}` : '—'
55
- td= fmtDate(r.last_heartbeat_at, 'never')
56
59
  if can.operate
57
60
  td
58
61
  +resourceActions(r, list.pageUrl())