Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / src / builder / b-ws-server.c
Author[]Andy Green <andy@warmcat.com> 2026-08-30 07:42 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-08-30 07:42 UTC
Tree12048c620121ba796d5deb03aeec4423ba837fdd   Raw Patch
 
js: tasks pane follows branch selection
js: tasks pane follows branch selection
diff --git a/assets/sai.js b/assets/sai.js index 8dc8b4e..c7e02c4 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -1625,6 +1625,28 @@ function sai_sb_branch_state_class(ref) } /* + * The newest loaded event matching the current sidebar selection (project + * and, if set, branch), or null if we hold no event for it yet. + */ +function sai_sb_newest_matching_event() +{ + if (!loaded_events || !loaded_events.length) + return null; + var ml = loaded_events.filter(function(o) { + return o && o.e && + (!sb_selected_project || + o.e.repo_name === sb_selected_project) && + (!sb_selected_ref || o.e.ref === sb_selected_ref); + }); + if (!ml.length) + return null; + ml.sort(function(a, b) { + return (b.e.created || 0) - (a.e.created || 0); + }); + return ml[0]; +} + +/* * Live-update the selected branch's colour: the server only pushes scoped * events for the current selection, so only sb_selected_ref can have moved. * Recompute the newest matching event's state from loaded_events; if it differs @@ -1633,22 +1655,13 @@ function sai_sb_branch_state_class(ref) function sai_sb_branch_state_livecheck() { if (!sb_selected_ref || !sb_branch_states || - !(sb_selected_ref in sb_branch_states) || - !loaded_events || !loaded_events.length) + !(sb_selected_ref in sb_branch_states)) return; - var ml = loaded_events.filter(function(o) { - return o && o.e && o.e.ref === sb_selected_ref && - (!sb_selected_project || - o.e.repo_name === sb_selected_project); - }); - if (!ml.length) + var newest = sai_sb_newest_matching_event(); + if (!newest) return; - ml.sort(function(a, b) { - return (b.e.created || 0) - (a.e.created || 0); - }); - var nst = ml[0].e.state; - if (sb_branch_states[sb_selected_ref] !== nst) { - sb_branch_states[sb_selected_ref] = nst; + if (sb_branch_states[sb_selected_ref] !== newest.e.state) { + sb_branch_states[sb_selected_ref] = newest.e.state; render_sb_branches(); } } @@ -1771,6 +1784,8 @@ function selectSbProject(name) render_sb_projects(); /* refresh the branch list for this project; auto-selects newest branch */ sai_sb_request_branches(name); + /* move the tasks pane off the old project's event */ + sai_sb_follow_selection(); sai_sb_update_url(); } @@ -1780,20 +1795,55 @@ function selectSbBranch(ref) return; sb_selected_ref = ref; render_sb_branches(); - /* re-scope the event list + tasks pane to the new selection */ - sai_sb_request_overview(0); - /* Clear any prior task selection that no longer applies */ - if (selected_task_uuid) { - var ev = loaded_events.find(function(o) { return o.e.uuid === selected_event_uuid; }); - var has = ev && ev.t && ev.t.some(function(t) { return t.uuid === selected_task_uuid; }); - if (!has) { - selected_task_uuid = null; - window.current_task_run = null; - } - } - render_sb_events(); /* reflect the project + branch selection in the URL */ sai_sb_update_url(); + /* re-scope the event list to the new selection */ + sai_sb_request_overview(0); + /* + * Move the tasks pane to the most recent event on the new branch (or + * clear it until the scoped overview reply auto-selects it), so it + * doesn't keep showing the previous branch's event + */ + sai_sb_follow_selection(); + render_sb_events(); +} + +/* + * The sidebar selection moved to a project / branch we hold no events for: + * drop the stale event + task selection (and their URL params) so the tasks + * pane stops showing an event from the old selection. The scoped overview + * reply auto-selects the newest matching event when it arrives. + */ +function sai_sb_clear_stale_selection() +{ + selected_event_uuid = null; + clear_task_view(); + var c = document.getElementById("sai_event_tasks"); + if (c) + c.innerHTML = "<div class=\"sb-empty\">No events</div>"; + var par = new URLSearchParams(window.location.search); + par.delete("event"); + par.delete("task"); + par.delete("run"); + sai_update_history(par, true); +} + +/* + * Point the tasks pane at the most recent event matching the current sidebar + * selection, so it never keeps showing an event from a different project / + * branch. If we hold no matching event yet, clear the stale selection until + * the scoped overview reply auto-selects the newest one. + */ +function sai_sb_follow_selection() +{ + var newest = sai_sb_newest_matching_event(); + if (newest) { + if (newest.e.uuid !== selected_event_uuid) + selectEvent(newest.e.uuid); + return; + } + if (selected_event_uuid) + sai_sb_clear_stale_selection(); } /* @@ -1983,6 +2033,30 @@ function render_selected_event_tasks(o) { } } +/* + * Drop the selected task and reset the task log view, eg because the + * selected event changed to one that doesn't contain it. + */ +function clear_task_view() +{ + selected_task_uuid = null; + window.current_task_run = null; + var stickyEl = document.getElementById("sai_sticky"); + var overviewEl = document.getElementById("sai_overview"); + if (stickyEl) stickyEl.innerHTML = ""; + if (overviewEl) overviewEl.innerHTML = ""; + + lines = times = logs = ""; + lines_pending = times_pending = logs_pending = ""; + segment_stack = []; + seg_counter = 0; + window.held_start_line = null; + logAnsiState = {}; + tfirst = 0; + lli = 1; + last_log_timestamp = 0; +} + function selectEvent(uuid) { selected_event_uuid = uuid; @@ -1992,24 +2066,8 @@ function selectEvent(uuid) { if (ev_obj && ev_obj.t && selected_task_uuid) { hasTask = ev_obj.t.some(t => t.uuid === selected_task_uuid); } - if (!hasTask) { - selected_task_uuid = null; - window.current_task_run = null; - var stickyEl = document.getElementById("sai_sticky"); - var overviewEl = document.getElementById("sai_overview"); - if (stickyEl) stickyEl.innerHTML = ""; - if (overviewEl) overviewEl.innerHTML = ""; - - lines = times = logs = ""; - lines_pending = times_pending = logs_pending = ""; - segment_stack = []; - seg_counter = 0; - window.held_start_line = null; - logAnsiState = {}; - tfirst = 0; - lli = 1; - last_log_timestamp = 0; - } + if (!hasTask) + clear_task_view(); var par = new URLSearchParams(window.location.search); par.set("event", uuid); @@ -3414,7 +3472,17 @@ function ws_open_sai() if (evUuid) selected_event_uuid = evUuid; } if (!selected_event_uuid) { - selected_event_uuid = loaded_events[loaded_events.length - 1].e.uuid; + /* + * With a sidebar selection, auto-pick the + * newest event matching it (eg after a branch + * switch cleared the selection); without one, + * take the newest event we hold. + */ + var _ne = sai_sb_newest_matching_event(); + if (_ne) + selected_event_uuid = _ne.e.uuid; + else if (!sb_selected_project && !sb_selected_ref) + selected_event_uuid = loaded_events[loaded_events.length - 1].e.uuid; } }
Page fetched 0s ago, creation time: 4ms (vhost etag hits: 0%, cache hits: 0%)