Skip to content

Commit 0229725

Browse files
committed
async data islands in dashboard
Signed-off-by: Artiom Diomin <artiom@kubermatic.com>
1 parent 97d3a56 commit 0229725

7 files changed

Lines changed: 412 additions & 347 deletions

File tree

176 KB
Binary file not shown.
131 KB
Binary file not shown.

pkg/dashboard/components.templ

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package dashboard
1616

1717
import "fmt"
1818

19-
templ Layout(data *dashboardData) {
19+
templ Layout() {
2020
<!DOCTYPE html>
2121
<html lang="en" class="h-100">
2222
<head>
@@ -31,7 +31,7 @@ templ Layout(data *dashboardData) {
3131
</style>
3232
<title>KubeOne Dashboard</title>
3333
</head>
34-
<body class="d-flex flex-column h-100" hx-get="/" hx-trigger="every 10s" hx-target="body" hx-swap="outerHTML">
34+
<body class="d-flex flex-column h-100">
3535
<header class="navbar navbar-expand-lg sticky-top bd-navbar border-bottom py-3 bg-body px-4 shadow-sm">
3636
<nav class="container-l bd-gutter d-flex flex-wrap flex-lg-nowrap align-items-center">
3737
<img src="/assets/kubeone-logo.png" alt="logo" style="height: 30px;"/>
@@ -43,19 +43,35 @@ templ Layout(data *dashboardData) {
4343
<div class="card shadow-sm">
4444
<div class="card-body">
4545
<h4 class="card-title pb-2">Control-Plane Nodes</h4>
46-
@NodesTable(data.ControlPlaneNodes)
46+
<div hx-get="/nodes/control-plane" hx-trigger="load, every 30s">
47+
<div class="text-center py-3">
48+
<div class="spinner-border text-secondary" role="status">
49+
<span class="visually-hidden">Loading...</span>
50+
</div>
51+
</div>
52+
</div>
4753
</div>
48-
if len(data.WorkerNodes) > 0 {
54+
<div id="worker-section" hx-get="/nodes/worker" hx-trigger="load, every 30s" hx-swap="outerHTML">
4955
<div class="card-body">
5056
<h4 class="card-title pb-2">Worker Nodes</h4>
51-
@NodesTable(data.WorkerNodes)
57+
<div class="text-center py-3">
58+
<div class="spinner-border text-secondary" role="status">
59+
<span class="visually-hidden">Loading...</span>
60+
</div>
61+
</div>
5262
</div>
53-
}
63+
</div>
5464
</div>
5565
<div class="card shadow-sm">
5666
<div class="card-body">
5767
<h4 class="card-title pb-2">Machine Deployments</h4>
58-
@MachineDeploymentsTable(data.MachineDeployments)
68+
<div id="machine-deployments" hx-get="/machine-deployments" hx-trigger="load, every 30s">
69+
<div class="text-center py-3">
70+
<div class="spinner-border text-secondary" role="status">
71+
<span class="visually-hidden">Loading...</span>
72+
</div>
73+
</div>
74+
</div>
5975
</div>
6076
</div>
6177
</div>
@@ -66,10 +82,6 @@ templ Layout(data *dashboardData) {
6682
</div>
6783
</footer>
6884
<script src="/assets/bootstrap.bundle.min.js"></script>
69-
<script>
70-
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
71-
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
72-
</script>
7385
</body>
7486
</html>
7587
}
@@ -88,6 +100,17 @@ templ StatusBadge(status string) {
88100
<span class={ fmt.Sprintf("badge text-bg-%s rounded-pill", badgeClass(status)) }>{ status }</span>
89101
}
90102

103+
templ WorkerNodesSection(nodes []node) {
104+
if len(nodes) > 0 {
105+
<div id="worker-section" class="card-body" hx-get="/nodes/worker" hx-trigger="every 30s" hx-swap="outerHTML">
106+
<h4 class="card-title pb-2">Worker Nodes</h4>
107+
@NodesTable(nodes)
108+
</div>
109+
} else {
110+
<div id="worker-section" hx-get="/nodes/worker" hx-trigger="every 30s" hx-swap="outerHTML" style="display:none"></div>
111+
}
112+
}
113+
91114
templ NodesTable(nodes []node) {
92115
<div class="row row-cols-1 row-cols-md-4 g-3">
93116
for _, n := range nodes {
@@ -148,7 +171,13 @@ templ NodesTable(nodes []node) {
148171
}
149172

150173
templ RolloutButton(md machineDeployment) {
151-
<form method="POST" action="/rollout" hx-post="/rollout" hx-target="body" hx-swap="outerHTML">
174+
<form
175+
method="POST"
176+
action="/rollout"
177+
hx-post="/rollout"
178+
hx-target="#machine-deployments"
179+
hx-swap="innerHTML"
180+
>
152181
<input type="hidden" name="Namespace" value={ md.Namespace }/>
153182
<input type="hidden" name="Name" value={ md.Name }/>
154183
<button type="submit" class="btn btn-outline-warning btn-sm" title="Force rollout">
@@ -159,7 +188,13 @@ templ RolloutButton(md machineDeployment) {
159188

160189
templ ScaleButtons(md machineDeployment) {
161190
<div class="d-flex align-items-center gap-2">
162-
<form method="POST" action="/scale" hx-post="/scale" hx-target="body" hx-swap="outerHTML">
191+
<form
192+
method="POST"
193+
action="/scale"
194+
hx-post="/scale"
195+
hx-target="#machine-deployments"
196+
hx-swap="innerHTML"
197+
>
163198
<input type="hidden" name="Namespace" value={ md.Namespace }/>
164199
<input type="hidden" name="Name" value={ md.Name }/>
165200
<input type="hidden" name="Direction" value="down"/>
@@ -171,7 +206,13 @@ templ ScaleButtons(md machineDeployment) {
171206
>−</button>
172207
</form>
173208
<span class="fw-semibold">{ fmt.Sprintf("%d", md.Replicas) }</span>
174-
<form method="POST" action="/scale" hx-post="/scale" hx-target="body" hx-swap="outerHTML">
209+
<form
210+
method="POST"
211+
action="/scale"
212+
hx-post="/scale"
213+
hx-target="#machine-deployments"
214+
hx-swap="innerHTML"
215+
>
175216
<input type="hidden" name="Namespace" value={ md.Namespace }/>
176217
<input type="hidden" name="Name" value={ md.Name }/>
177218
<input type="hidden" name="Direction" value="up"/>
@@ -190,7 +231,9 @@ templ MachineDeploymentsTable(machineDeployments []machineDeployment) {
190231
<th scope="col">Namespace</th>
191232
<th scope="col">Replicas</th>
192233
<th scope="col">Available</th>
193-
<th scope="col">Scale</th> <th scope="col">Rollout</th> <th scope="col">Kubelet</th>
234+
<th scope="col">Scale</th>
235+
<th scope="col">Rollout</th>
236+
<th scope="col">Kubelet</th>
194237
<th scope="col">Age</th>
195238
</tr>
196239
</thead>
@@ -206,9 +249,12 @@ templ MachineDeploymentsTable(machineDeployments []machineDeployment) {
206249
<td>{ md.Namespace }</td>
207250
<td>{ fmt.Sprintf("%d", md.Replicas) }</td>
208251
<td>{ fmt.Sprintf("%d", md.AvailableReplicas) }</td>
209-
<td>@ScaleButtons(md)
210-
</td>
211-
<td>@RolloutButton(md)</td>
252+
<td>
253+
@ScaleButtons(md)
254+
</td>
255+
<td>
256+
@RolloutButton(md)
257+
</td>
212258
<td>{ md.Kubelet }</td>
213259
<td>{ md.Age.String() }</td>
214260
</tr>
@@ -257,7 +303,13 @@ templ MachinesTable(machines []machine) {
257303
<td>{ m.Address }</td>
258304
<td>{ m.Age.String() }</td>
259305
<td>
260-
<form method="POST" action="/delete-machine" hx-post="/delete-machine" hx-target="body" hx-swap="outerHTML">
306+
<form
307+
method="POST"
308+
action="/delete-machine"
309+
hx-post="/delete-machine"
310+
hx-target="#machine-deployments"
311+
hx-swap="innerHTML"
312+
>
261313
<input type="hidden" name="Namespace" value={ m.Namespace }/>
262314
<input type="hidden" name="Name" value={ m.Name }/>
263315
<button
@@ -295,7 +347,9 @@ templ NodePodsTable(nodeName string, pods []pod) {
295347
}
296348
for _, p := range pods {
297349
<tr>
298-
<td>@PodStatusBadge(p.Status)</td>
350+
<td>
351+
@PodStatusBadge(p.Status)
352+
</td>
299353
<td>{ p.Name }</td>
300354
<td>{ p.Namespace }</td>
301355
<td>{ p.Ready }</td>

0 commit comments

Comments
 (0)