Refactor htmx and fetch-action related code (#37186)

This is the first step (the hardest part):

* repo file list last commit message lazy load
* admin server status monitor
* watch/unwatch (normal page, watchers page)
* star/unstar (normal page, watchers page)
* project view, delete column
* workflow dispatch, switch the branch
* commit page: load branches and tags referencing this commit

The legacy "data-redirect" attribute is removed, it only makes the page
reload (sometimes using an incorrect link).

Also did cleanup for some devtest pages.
This commit is contained in:
wxiaoguang
2026-04-14 02:53:55 +08:00
committed by GitHub
parent 6eae04241d
commit 6bcb666a9d
41 changed files with 457 additions and 242 deletions
@@ -4,13 +4,16 @@
</div>
<div id="runWorkflowDispatchModal" class="ui tiny modal">
<div class="content">
<form id="runWorkflowDispatchForm" class="ui form" action="{{$.Link}}/run?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}" method="post">
<form id="runWorkflowDispatchForm" class="ui form ignore-dirty" action="{{$.Link}}/run?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}" method="post">
<div class="ui inline field required tw-flex tw-items-center">
<span class="ui inline required field">
<label>{{ctx.Locale.Tr "actions.workflow.from_ref"}}:</label>
</span>
<div class="ui inline field dropdown button select-branch branch-selector-dropdown ellipsis-text-items">
<input type="hidden" name="ref" hx-sync="this:replace" hx-target="#runWorkflowDispatchModalInputs" hx-swap="innerHTML" hx-get="{{$.Link}}/workflow-dispatch-inputs?workflow={{$.CurWorkflow}}" hx-trigger="change" value="refs/heads/{{index .Branches 0}}">
<input type="hidden" name="ref" value="refs/heads/{{index .Branches 0}}"
data-fetch-trigger="change" data-fetch-sync="$body #runWorkflowDispatchModalInputs"
data-fetch-url="{{$.Link}}/workflow-dispatch-inputs?workflow={{$.CurWorkflow}}"
>
{{svg "octicon-git-branch" 14}}
<div class="default text">{{index .Branches 0}}</div>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
@@ -45,12 +48,8 @@
</div>
</div>
</div>
<div class="divider"></div>
<div id="runWorkflowDispatchModalInputs">
{{template "repo/actions/workflow_dispatch_inputs" .}}
</div>
{{template "repo/actions/workflow_dispatch_inputs" .}}
</form>
</div>
</div>
@@ -1,3 +1,4 @@
<div id="runWorkflowDispatchModalInputs">
{{if not .WorkflowDispatchConfig}}
<div class="ui error message tw-block">{{/* using "ui message" in "ui form" needs to force to display */}}
{{if not .CurWorkflowExists}}
@@ -44,3 +45,4 @@
</div>
{{end}}
{{end}}
</div>
@@ -8,7 +8,7 @@
</div>
{{end}}
<button class="ui button ellipsis-button load-branches-and-tags tw-mt-2" aria-expanded="false"
data-fetch-url="{{.RepoLink}}/commit/{{.CommitID}}/load-branches-and-tags"
data-url="{{.RepoLink}}/commit/{{.CommitID}}/load-branches-and-tags"
data-tooltip-content="{{ctx.Locale.Tr "repo.commit.load_referencing_branches_and_tags"}}"
>...</button>
<div class="branch-and-tag-detail tw-hidden">
@@ -9,7 +9,7 @@
{{if and $.UpdateAllowed $.UpdateByRebaseAllowed}}
<div class="tw-inline-block">
<div id="update-pr-branch-with-base" class="ui buttons">
<button class="ui button" data-do="{{$.Issue.Link}}/update" data-redirect="{{$.Issue.Link}}">
<button class="ui button" data-do="{{$.Issue.Link}}/update">
<span class="button-text">
{{ctx.Locale.Tr "repo.pulls.update_branch"}}
</span>
+1 -1
View File
@@ -6,7 +6,7 @@
<div class="ui right">
<!-- the button is wrapped with a span because the tooltip doesn't show on hover if we put data-tooltip-content directly on the button -->
<span data-tooltip-content="{{if or $isNew .Webhook.IsActive}}{{ctx.Locale.Tr "repo.settings.webhook.test_delivery_desc"}}{{else}}{{ctx.Locale.Tr "repo.settings.webhook.test_delivery_desc_disabled"}}{{end}}">
<button class="ui tiny button{{if not (or $isNew .Webhook.IsActive)}} disabled{{end}}" id="test-delivery" data-link="{{.Link}}/test" data-redirect="{{.Link}}">
<button class="ui tiny button{{if not (or $isNew .Webhook.IsActive)}} disabled{{end}}" id="test-delivery" data-link="{{.Link}}/test">
<span class="text">{{ctx.Locale.Tr "repo.settings.webhook.test_delivery"}}</span>
</button>
</span>
+19 -13
View File
@@ -1,13 +1,19 @@
<form class="flex-text-inline" hx-boost="true" hx-target="this" method="post" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}unstar{{else}}star{{end}}">
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.star_guest_user"}}"{{end}}>
{{$buttonText := ctx.Locale.Tr "repo.star"}}
{{if $.IsStaringRepo}}{{$buttonText = ctx.Locale.Tr "repo.unstar"}}{{end}}
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
{{svg (Iif $.IsStaringRepo "octicon-star-fill" "octicon-star")}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
<a hx-boost="false" class="ui basic label" href="{{$.RepoLink}}/stars">
{{CountFmt .Repository.NumStars}}
</a>
</div>
</form>
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.star_guest_user"}}"{{end}}>
{{$buttonText := ctx.Locale.Tr "repo.star"}}
{{if $.IsStaringRepo}}{{$buttonText = ctx.Locale.Tr "repo.unstar"}}{{end}}
<button type="button" class="ui compact small basic button" aria-label="{{$buttonText}}"
{{if $.IsSigned}}
data-fetch-method="post"
data-fetch-url="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}unstar{{else}}star{{end}}"
data-fetch-sync="$closest(.ui.labeled.button)"
{{else}}
disabled
{{end}}
>
{{svg (Iif $.IsStaringRepo "octicon-star-fill" "octicon-star")}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
<a class="ui basic label" href="{{$.RepoLink}}/stars">
{{CountFmt .Repository.NumStars}}
</a>
</div>
+2 -11
View File
@@ -1,14 +1,5 @@
<!-- Refresh the content if a htmx response contains "HX-Trigger" header.
This usually happens when a user stays on the watchers/stargazers page
when they watched/unwatched/starred/unstarred and the list should be refreshed.
To test go to the watchers page and click the watch button. The user cards should reload.
At the moment, no JS initialization would re-trigger (fortunately there is no JS for this page).
-->
<div class="no-loading-indicator tw-hidden"></div>
<div class="user-cards"
hx-trigger="refreshUserCards from:body" hx-indicator=".no-loading-indicator"
hx-get="" hx-swap="outerHTML" hx-select=".user-cards"
>
{{/* need to reload after "watch/unwatch" or "star/unstar" fetch actions */}}
<div class="user-cards" id="user-cards-container" data-fetch-trigger="fetch-reload">
{{if .CardsTitle}}
<h2 class="ui dividing header">
{{.CardsTitle}}
+9 -3
View File
@@ -1,5 +1,11 @@
{{/* use grid layout, still use the old ID because there are many other CSS styles depending on this ID */}}
<div id="repo-files-table" {{if .HasFilesWithoutLatestCommit}}hx-indicator="#repo-files-table .repo-file-cell.message" hx-trigger="load" hx-swap="morph" hx-post="{{.LastCommitLoaderURL}}"{{end}}>
<div id="repo-files-table"
{{if .HasFilesWithoutLatestCommit}}
data-fetch-url="{{.LastCommitLoaderURL}}"
data-fetch-trigger="load" data-fetch-sync="$morph"
data-fetch-indicator="#repo-files-table .repo-file-cell.notready.message"
{{end}}
>
<div class="repo-file-line repo-file-last-commit">
{{template "repo/latest_commit" .}}
<div>{{if and .LatestCommit .LatestCommit.Committer}}{{DateUtils.TimeSince .LatestCommit.Committer.When}}{{end}}</div>
@@ -15,7 +21,7 @@
{{$entry := $item.Entry}}
{{$commit := $item.Commit}}
{{$submoduleFile := $item.SubmoduleFile}}
<div class="repo-file-cell name muted-links {{if not $commit}}notready{{end}}">
<div class="repo-file-cell name muted-links">
{{index $.FileIcons $entry.Name}}
{{if $entry.IsSubModule}}
{{$submoduleLink := $submoduleFile.SubmoduleWebLinkTree ctx}}
@@ -47,7 +53,7 @@
{{end}}
{{end}}
</div>
<div class="repo-file-cell message commit-summary loading-icon-2px">
<div class="repo-file-cell message commit-summary {{if not $commit}}notready{{end}}">
{{if $commit}}
{{$commitLink := printf "%s/commit/%s" $.RepoLink (PathEscape $commit.ID.String)}}
{{ctx.RenderUtils.RenderCommitMessageLinkSubject $commit.Message $commitLink $.Repository}}
+19 -13
View File
@@ -1,13 +1,19 @@
<form class="flex-text-inline" hx-boost="true" hx-target="this" method="post" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}unwatch{{else}}watch{{end}}">
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.watch_guest_user"}}"{{end}}>
{{$buttonText := ctx.Locale.Tr "repo.watch"}}
{{if $.IsWatchingRepo}}{{$buttonText = ctx.Locale.Tr "repo.unwatch"}}{{end}}
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
{{svg "octicon-eye"}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
<a hx-boost="false" class="ui basic label" href="{{.RepoLink}}/watchers">
{{CountFmt .Repository.NumWatches}}
</a>
</div>
</form>
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.watch_guest_user"}}"{{end}}>
{{$buttonText := ctx.Locale.Tr "repo.watch"}}
{{if $.IsWatchingRepo}}{{$buttonText = ctx.Locale.Tr "repo.unwatch"}}{{end}}
<button type="button" class="ui compact small basic button" aria-label="{{$buttonText}}"
{{if $.IsSigned}}
data-fetch-method="post"
data-fetch-url="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}unwatch{{else}}watch{{end}}"
data-fetch-sync="$closest(.ui.labeled.button)"
{{else}}
disabled
{{end}}
>
{{svg "octicon-eye"}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
<a class="ui basic label" href="{{.RepoLink}}/watchers">
{{CountFmt .Repository.NumWatches}}
</a>
</div>