1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use leptos::prelude::*;
use crate::wasm::api::RefreshSignals;
use crate::wasm::components::JobRow;
use crate::wasm::types::{ListedJob, Modal};
#[component]
pub(super) fn JobsTable(
refresh: RefreshSignals,
filtered_jobs: Memo<Vec<ListedJob>>,
all_visible_selected: Memo<bool>,
modal: RwSignal<Option<Modal>>,
) -> impl IntoView {
let selected_jobs = refresh.selected_jobs;
let toast = refresh.toast;
view! {
<div class="max-h-[58vh] overflow-auto">
<table class="gw-table">
<thead>
<tr>
<th>
<input
id="select-all-jobs"
name="select_all_jobs"
type="checkbox"
class="h-4 w-4"
prop:checked=move || all_visible_selected.get()
on:change=move |event| {
let visible_ids = filtered_jobs.get_untracked().into_iter().map(|job| job.id).collect::<Vec<_>>();
selected_jobs.update(|selected| {
if event_target_checked(&event) {
for id in visible_ids {
if !selected.contains(&id) {
selected.push(id);
}
}
} else {
selected.retain(|id| !visible_ids.contains(id));
}
});
}
/>
</th>
<th>"ID"</th><th>"Task"</th><th>"Queue"</th><th>"State"</th><th>"Run at"</th><th>"Attempts"</th><th>"Priority"</th><th>"Key"</th><th>"Payload"</th><th>"Error"</th><th>"Actions"</th>
</tr>
</thead>
<tbody>
{move || if filtered_jobs.get().is_empty() {
view! { <tr><td colspan="12" class="py-8 text-center gw-muted">"No jobs match the current filters."</td></tr> }.into_any()
} else {
().into_any()
}}
<For
each=move || filtered_jobs.get()
key=|job| job.id
children=move |job| {
view! {
<JobRow
job=job
selected_jobs=selected_jobs
modal=modal
toast=toast
/>
}
}
/>
</tbody>
</table>
</div>
}
}