forgejo/templates/repo/actions/list.tmpl
Mathieu Fenniak 6ad706aa88 feat(ui): Automatically refresh workflows in the "Actions" list (#7361)
- Make the "Actions" list (for example, https://codeberg.org/forgejo/forgejo/actions) dynamically refresh using htmx and partial page reloading. This addresses a pet peeve of mine, I find it common to end up on this page and have workflows in-progress, but not be able to monitor the workflows to success or failure from the page as it currently doesn't do any data refreshing.
- There are a few major risks involves with this change.
  - Increased server-side load & network utilization.  In order to mitigate this risk, I have configured the refresh to occur every 30 seconds **only** when the Page Visibility API indicates that the web page is currently visible to the end-user. It is still reasonable to assume this change will increase server-side load though.
  - UI interactions on the page, such as the "Actor" and "Status" dropdown and the workflow dispatch form, would be replaced from the server with non-expanded UI during the refresh. This problem is prevented by stopping the refresh while these UIs are in their expanded states.
- E2E tests added.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7361
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-04-04 14:38:54 +00:00

41 lines
1.7 KiB
Go HTML Template

{{template "base/head" .}}
<div class="page-content repository actions">
{{template "repo/header" .}}
<div class="ui container">
{{template "base/alert" .}}
{{/* Refresh the list every interval (30s) unless the document isn't visible or a dropdown is open; refresh
if visibility changes as well. simulate-polling-interval is a custom event used for e2e tests to mimic
the polling interval and should be defined identically to the `every` clause for accurate testing. */}}
<div
hx-get="?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{$.CurStatus}}&page={{$.Page.Paginater.Current}}&list_inner=true"
hx-swap="morph:innerHTML"
hx-trigger="every 30s [pollingOk()], visibilitychange[document.visibilityState === 'visible'] from:document, simulate-polling-interval[pollingOk()] from:document"
hx-indicator="#reloading-indicator">
{{template "repo/actions/list_inner" .}}
</div>
</div>
</div>
<script type="text/javascript">
function pollingOk() {
return document.visibilityState === 'visible' && noActiveDropdowns();
}
// Intent: If the "Actor" or "Status" dropdowns are currently open and being navigated, or the workflow dispatch
// dropdown form is open, the htmx refresh would replace them with closed dropdowns. Instead this prevents the list
// refresh from occurring while those dropdowns are open.
//
// Can't inline this into the `hx-trigger` above because using a left-brace ('[') breaks htmx's trigger parsing.
function noActiveDropdowns() {
if (document.querySelector('[aria-expanded=true]') !== null)
return false;
const dropdownForm = document.querySelector('#branch-dropdown-form');
if (dropdownForm !== null && dropdownForm.checkVisibility())
return false;
return true;
}
</script>
{{template "base/footer" .}}