@andrian.yablonskyy/thub-coordinator 1.0.17 → 1.0.19

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.
@@ -32,6 +32,82 @@ mixin resourceActions(r, returnTo)
32
32
  )
33
33
  i.bi.bi-arrow-repeat
34
34
  +updateButton(`/resources/${r.id}/update`, r.update_to, returnTo)
35
+ +removeResourceButton(r, returnTo)
36
+
37
+ //- Remove: a plain confirm when the resource is idle; with a running job,
38
+ //- the shared warning modal (+removeResourceModal) instead, which stops the
39
+ //- job first (stopJob=1). Disabled once a removal is already pending.
40
+ mixin removeResourceButton(r, returnTo)
41
+ if r.remove_requested_at
42
+ span.d-inline-block.ms-1(tabindex="0" data-bs-toggle="tooltip" data-bs-title="Removal pending — waiting for the Client to confirm its job stopped")
43
+ button.btn.btn-sm.btn-outline-danger(type="button" disabled style="pointer-events: none;" aria-label="Remove")
44
+ i.bi.bi-hourglass-split
45
+ else if r.activeJob
46
+ button.btn.btn-sm.btn-outline-danger.ms-1(
47
+ type="button"
48
+ aria-label="Remove"
49
+ data-bs-toggle="tooltip"
50
+ data-bs-title="Remove this resource from the list — it's running a job"
51
+ data-remove-resource=r.id
52
+ data-remove-name=r.name
53
+ data-remove-job=r.activeJob.id
54
+ data-remove-return=returnTo
55
+ )
56
+ i.bi.bi-trash
57
+ else
58
+ form.d-inline.ms-1(
59
+ method="post"
60
+ action=`/resources/${r.id}/remove`
61
+ data-confirm=`Remove ${r.name} from the list? Its job history is kept. A Client that's still running shows up again when it restarts and re-registers.`
62
+ onsubmit="return confirm(this.dataset.confirm)"
63
+ )
64
+ input(type="hidden" name="returnTo" value=returnTo)
65
+ button.btn.btn-sm.btn-outline-danger(
66
+ type="submit"
67
+ aria-label="Remove"
68
+ data-bs-toggle="tooltip"
69
+ data-bs-title="Remove this resource from the list"
70
+ )
71
+ i.bi.bi-trash
72
+
73
+ //- One per page (admins): filled in by public/js/remove-resource.js from
74
+ //- the clicked Remove button's data-remove-* attributes.
75
+ mixin removeResourceModal()
76
+ .modal.fade#remove-resource-modal(tabindex="-1" aria-labelledby="remove-resource-title" aria-hidden="true")
77
+ .modal-dialog.modal-dialog-centered
78
+ .modal-content
79
+ .modal-header.text-bg-warning
80
+ h5.modal-title#remove-resource-title
81
+ i.bi.bi-exclamation-triangle-fill.me-2
82
+ | Client is running a job
83
+ button.btn-close(type="button" data-bs-dismiss="modal" aria-label="Close")
84
+ .modal-body
85
+ p
86
+ strong(data-field="name")
87
+ | is running job
88
+ |
89
+ a(data-field="job")
90
+ | .
91
+ p.mb-2 Removing it will:
92
+ ul.mb-2
93
+ li
94
+ | stop job
95
+ |
96
+ strong(data-field="job-text")
97
+ | immediately (it ends as
98
+ |
99
+ code CANCELED
100
+ | ), then
101
+ li remove the resource as soon as its Client confirms the job stopped (at most about a minute if the Client doesn't answer).
102
+ p.small.text-body-secondary.mb-0 Its job history is kept. A Client that's still running shows up again when it restarts and re-registers.
103
+ .modal-footer
104
+ button.btn.btn-secondary(type="button" data-bs-dismiss="modal") Keep it
105
+ form(method="post" data-field="form")
106
+ input(type="hidden" name="stopJob" value="1")
107
+ input(type="hidden" name="returnTo" data-field="return")
108
+ button.btn.btn-danger(type="submit")
109
+ i.bi.bi-stop-circle.me-1
110
+ | Stop job and remove
35
111
 
36
112
  //- One udev device line: path (or udev index / ST-Link serial), extra
37
113
  //- detail, and whether the node was present when the Client registered.
@@ -156,7 +232,7 @@ mixin resourceCard(r, groupsById, returnTo)
156
232
  dt.col-sm-4 Type
157
233
  dd.col-sm-8.text-uppercase= r.type
158
234
  dt.col-sm-4 Status
159
- dd.col-sm-8: +resourceBadge(r.status)
235
+ dd.col-sm-8: +resourceBadge(r.status, r.remove_requested_at)
160
236
  +uptimeRows(r)
161
237
  dt.col-sm-4 Client version
162
238
  dd.col-sm-8: +versionCell(r.client_version, updates.latest.client, r.update_to)
@@ -1,6 +1,13 @@
1
- mixin resourceBadge(status)
1
+ //- `removing`: the resource's remove_requested_at — removal is pending
2
+ //- until its Client confirms its stopped job ended (jobs.removeResource).
3
+ mixin resourceBadge(status, removing)
2
4
  - const map = { IDLE: 'success', BUSY: 'primary', OUT_OF_SERVICE: 'danger', MAINTENANCE: 'secondary', REGISTERED: 'secondary' }
3
5
  span.badge(class=`text-bg-${map[status] || 'secondary'}`)= status
6
+ if removing
7
+ span.badge.text-bg-warning.ms-1(
8
+ data-bs-toggle="tooltip"
9
+ data-bs-title="Its job was stopped; removed as soon as the Client confirms"
10
+ ) REMOVING
4
11
 
5
12
  mixin jobBadge(state)
6
13
  - const map = { QUEUED: 'secondary', ASSIGNED: 'info', PREPARING: 'info', RUNNING: 'primary', PASSED: 'success', FAILED: 'danger', ERROR: 'danger', TIMEOUT: 'warning', CANCELED: 'secondary', LOST: 'danger' }
@@ -2,26 +2,31 @@ extends ../layout
2
2
  include ../mixins/status-badge
3
3
  include ../mixins/resource
4
4
  include ../mixins/updates
5
+ include ../mixins/list-controls
5
6
 
6
7
  block content
7
8
  h1.h4.mb-3 Resources
8
9
  p.text-body-secondary.small.
9
10
  Resources register themselves — start a Client with the shared join key and it appears here. Click a resource for its details, including IP addresses.
10
11
 
11
- .mb-3
12
+ .d-flex.flex-wrap.align-items-center.gap-2.mb-3
12
13
  +updatesToolbar('client', 'clients', '/resources')
14
+ .ms-auto
15
+ +pageSizePicker(list)
16
+
17
+ +listToolbar(list, 'resources')
13
18
 
14
19
  table.table.table-hover.align-middle
15
20
  thead
16
21
  tr
17
- th Name
18
- th Type
19
- th Version
20
- th Status
22
+ +sortHeader(list, 'name', 'Name')
23
+ +sortHeader(list, 'type', 'Type')
24
+ +sortHeader(list, 'version', 'Version', 'desc')
25
+ +sortHeader(list, 'status', 'Status')
21
26
  th Labels
22
27
  th Groups
23
28
  th Busy source / reason
24
- th Last heartbeat
29
+ +sortHeader(list, 'heartbeat', 'Last heartbeat', 'desc')
25
30
  if user.role === 'admin'
26
31
  th Actions
27
32
  tbody
@@ -30,7 +35,7 @@ block content
30
35
  td= r.name
31
36
  td.text-uppercase= r.type
32
37
  td: +versionCell(r.client_version, updates.latest.client, r.update_to)
33
- td: +resourceBadge(r.status)
38
+ td: +resourceBadge(r.status, r.remove_requested_at)
34
39
  td
35
40
  each l in r.labels
36
41
  span.badge.text-bg-light.border.me-1= l
@@ -44,10 +49,14 @@ block content
44
49
  td= fmtDate(r.last_heartbeat_at, 'never')
45
50
  if user.role === 'admin'
46
51
  td
47
- +resourceActions(r, '/resources')
52
+ +resourceActions(r, list.pageUrl())
48
53
 
49
54
  each r in resources
50
- +resourceCard(r, groupsById, '/resources')
55
+ +resourceCard(r, groupsById, list.pageUrl())
56
+
57
+ if user && user.role === 'admin'
58
+ +removeResourceModal()
51
59
 
52
60
  block scripts
53
61
  script(src="/js/resource-card.js")
62
+ script(src="/js/remove-resource.js")