Added the watch and scheduler systems
This commit is contained in:
@@ -5,6 +5,30 @@ use crate::api;
|
||||
use crate::components::status_badge::StatusBadge;
|
||||
use crate::types::Status;
|
||||
|
||||
/// Format a UTC datetime string as a relative time like "in 2h 15m".
|
||||
fn format_next_run(datetime_str: &str) -> String {
|
||||
let now_ms = js_sys::Date::new_0().get_time();
|
||||
let parsed = js_sys::Date::parse(datetime_str);
|
||||
|
||||
// NaN means parse failed
|
||||
if parsed.is_nan() {
|
||||
return datetime_str.to_string();
|
||||
}
|
||||
|
||||
let delta_ms = parsed - now_ms;
|
||||
if delta_ms <= 0.0 {
|
||||
return "soon".to_string();
|
||||
}
|
||||
let total_mins = (delta_ms / 60_000.0) as u64;
|
||||
let hours = total_mins / 60;
|
||||
let mins = total_mins % 60;
|
||||
if hours > 0 {
|
||||
format!("in {hours}h {mins}m")
|
||||
} else {
|
||||
format!("in {mins}m")
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component(DashboardPage)]
|
||||
pub fn dashboard() -> Html {
|
||||
let status = use_state(|| None::<Status>);
|
||||
@@ -157,6 +181,29 @@ pub fn dashboard() -> Html {
|
||||
})
|
||||
};
|
||||
|
||||
let on_monitor_check = {
|
||||
let message = message.clone();
|
||||
let error = error.clone();
|
||||
let fetch = fetch_status.clone();
|
||||
Callback::from(move |_: MouseEvent| {
|
||||
let message = message.clone();
|
||||
let error = error.clone();
|
||||
let fetch = fetch.clone();
|
||||
wasm_bindgen_futures::spawn_local(async move {
|
||||
match api::trigger_monitor_check().await {
|
||||
Ok(t) => {
|
||||
message.set(Some(format!(
|
||||
"Monitor check started (task: {})",
|
||||
&t.task_id[..8]
|
||||
)));
|
||||
fetch.emit(());
|
||||
}
|
||||
Err(e) => error.set(Some(e.0)),
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
let on_pipeline = {
|
||||
let message = message.clone();
|
||||
let error = error.clone();
|
||||
@@ -193,6 +240,35 @@ pub fn dashboard() -> Html {
|
||||
.iter()
|
||||
.any(|t| t.status == "Pending" || t.status == "Running");
|
||||
|
||||
// Pre-compute scheduled task rows
|
||||
let scheduled_rows = {
|
||||
let mut rows = Vec::new();
|
||||
if let Some(ref sched) = s.scheduled {
|
||||
if let Some(ref next) = sched.next_pipeline {
|
||||
rows.push(html! {
|
||||
<tr>
|
||||
<td>{ "Auto Pipeline" }</td>
|
||||
<td><span class="badge badge-pending">{ "Scheduled" }</span></td>
|
||||
<td></td>
|
||||
<td class="text-sm text-muted">{ format!("Next run: {}", format_next_run(next)) }</td>
|
||||
</tr>
|
||||
});
|
||||
}
|
||||
if let Some(ref next) = sched.next_monitor {
|
||||
rows.push(html! {
|
||||
<tr>
|
||||
<td>{ "Monitor Check" }</td>
|
||||
<td><span class="badge badge-pending">{ "Scheduled" }</span></td>
|
||||
<td></td>
|
||||
<td class="text-sm text-muted">{ format!("Next run: {}", format_next_run(next)) }</td>
|
||||
</tr>
|
||||
});
|
||||
}
|
||||
}
|
||||
rows
|
||||
};
|
||||
let has_scheduled = !scheduled_rows.is_empty();
|
||||
|
||||
html! {
|
||||
<div>
|
||||
<div class="page-header">
|
||||
@@ -247,11 +323,12 @@ pub fn dashboard() -> Html {
|
||||
<button class="btn btn-secondary" onclick={on_index}>{ "Re-index" }</button>
|
||||
<button class="btn btn-secondary" onclick={on_tag}>{ "Auto-tag" }</button>
|
||||
<button class="btn btn-secondary" onclick={on_organize}>{ "Organize" }</button>
|
||||
<button class="btn btn-secondary" onclick={on_monitor_check}>{ "Check Monitored Artists" }</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
// Background Tasks
|
||||
if !s.tasks.is_empty() {
|
||||
// Background Tasks (always show if there are tasks or scheduled items)
|
||||
if !s.tasks.is_empty() || has_scheduled {
|
||||
<div class="card">
|
||||
<h3>{ "Background Tasks" }</h3>
|
||||
<table class="tasks-table">
|
||||
@@ -259,6 +336,7 @@ pub fn dashboard() -> Html {
|
||||
<tr><th>{ "Type" }</th><th>{ "Status" }</th><th>{ "Progress" }</th><th>{ "Result" }</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ for scheduled_rows.into_iter() }
|
||||
{ for s.tasks.iter().map(|t| {
|
||||
let progress_html = if let Some(ref p) = t.progress {
|
||||
if p.total > 0 {
|
||||
|
||||
Reference in New Issue
Block a user