Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix elipsis button not working if the last commit loading is deferred #29544

Merged
merged 9 commits into from
Mar 2, 2024

Conversation

yardenshoham
Copy link
Member

@yardenshoham yardenshoham commented Mar 2, 2024

Before this change, if we had more than 200 entries being deferred in loading, the entire table would get replaced thus losing any event listeners attached to the elements within the table, such as the elipsis button and commit list with tippy.

With this change we remove the previous javascript code that replaced the table and use htmx to replace the table.

htmx attributes added:

  • hx-indicator="tr.notready td.message span": attach the loading spinner to the files whose last commit is still being loaded
  • hx-trigger="load" trigger the request-replace behavior as soon as possible
  • hx-swap="morph": use the idiomorph morphing algorithm, this is the thing that makes it so the elipsis button event listener is kept during the replacement, fixing the bug because we don't actually replace the table, only modifying it
  • hx-post="{{.LastCommitLoaderURL}}": make a post request to this url to get the table with all of the commit information

As part of this change I removed the handling of partial replacement in the case we have less than 200 "not ready" files. The first reason is that I couldn't make htmx replace only a subset of returned elements, the second reason is that we have a cache implemented in the backend already so the only cost added is that we query the cache a few times (which is sure to be populated due to the initial request), and the last reason is that since the last refactor of this functionality that removed jQuery we don't properly send the "not ready" entries as the backend expects FormData with f[] and we send a JSON with f so we always query for all rows anyway.

Before

before

After

after

Before this change, if we had more than 200 entries being deferred in loading, the entire table would get replaced thus losing any event listeners attached to the elements within the table, such as the elipsis button and commit list with tippy.

With this change we remove the previous javascript code that replaced the table and use htmx to replace the table.

htmx attributes added:
- `hx-indicator="tr.notready td.message span"`: attach the loading spinner to the files whose last commit is still being loaded
- `hx-trigger="load[this.querySelectorAll('tr.notready').length > 0]"` trigger the request-replace behavior as soon as possible and only if the current table is showing files that haven't had their latest commit info loaded. If this inline javascript doesn't look good I can change it so the backend doesn't render the htmx attributes if it's an htmx request, and the trigger would simply be `load` but I like it as it is now
- `hx-swap="morph"`:  use the idiomorph morphing algorithm, this is the thing that makes it so the elipsis button event listener is kept during the replacement, fixing the bug
- `hx-post="{{.LastCommitLoaderURL}}"`: make a post request to this url to get the table with all of the commit information

As part of this change I removed the handling of partial replacement in the case we have less than 200 "not ready" files. The first reason is that I couldn't make htmx replace only a subset of returned elements, the second reason is that we have a cache implemented in the backend already so the only cost added is that we query the cache a few times (which is sure to be populated due to the initial request), and the last reason is that since the last refactor of this functionality that removed jQuery we don't properly send the "not ready" entries as the backend expects `FormData` with `f[]` and we send a JSON with `f` so we always query for all rows anyway.

Signed-off-by: Yarden Shoham <git@yardenshoham.com>
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Mar 2, 2024
@pull-request-size pull-request-size bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Mar 2, 2024
@yardenshoham yardenshoham added type/bug type/refactoring Existing code has been cleaned up. There should be no new functionality. labels Mar 2, 2024
@yardenshoham
Copy link
Member Author

cc @delvh because of #29230 (comment)

routers/web/repo/view.go Outdated Show resolved Hide resolved
yardenshoham and others added 2 commits March 2, 2024 17:57
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
@wxiaoguang
Copy link
Contributor

ps: does it really fixe "elipsis button not working if the last commit loading is deferred"?

I think it is a longstanding problem, because since the code before #29230, initRepoEllipsisButton is not really called if the last commit loading is deferred?

@yardenshoham
Copy link
Member Author

It fixes the bug as you can see in the GIF. Also, yes this bug existed before #29230. See #29230 (comment)

@wxiaoguang
Copy link
Contributor

It fixes the bug as you can see in the GIF. Also, yes this bug existed before #29230. See #29230 (comment)

Which line/block of code of this PR fixes "elipsis button not working if the last commit loading is deferred" ? I don't see when/where the initRepoEllipsisButton is called differently.

@yardenshoham
Copy link
Member Author

hx-swap="morph": use the idiomorph morphing algorithm, this is the thing that makes it so the elipsis button event listener is kept during the replacement, fixing the bug because we don't actually replace the table, only modifying it

@wxiaoguang

This comment was marked as off-topic.

@wxiaoguang
Copy link
Contributor

wxiaoguang commented Mar 2, 2024

Well, the question is: "if the last commit loading is deferred" (The code: {{if .LatestCommit}}), is there any "ellipsis button" on the UI? If no, then the button would be loaded by htmx, then how could it gets its event listener?

I guess it is a longstanding problem and is not in this PR's scope. I am just curious about the details. So feel free to ignore these comments.

@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Mar 2, 2024
@yardenshoham
Copy link
Member Author

I understand you now, using hx-on::load could help but the guidelines forbid it. So this PR doesn't fix the bug in all cases. The edge case where we have a multi-line message in a deferred commit is not covered. This PR does cover all other cases.

After this PR gets merged I see 2 ways forward:

  1. MutationObserver
  2. hx-on::load

I can send a PR with hx-on::load and we will continue the discussion there

@wxiaoguang
Copy link
Contributor

wxiaoguang commented Mar 2, 2024

After more thoughts, I guess we could just do nothing.

By reading the code, I think maybe the "LatestCommit" couldn't be nil .... if I understand correctly, GetCommitsInfo always returns LatestCommit

  • if it is so, then so far so good, nothing need to do. The old template code for handling LatestCommit==nil is just a no-op
  • if it is not so .... then if LatestCommit is nil, then it is a new problem. I guess it shouldn't be this case.

So I'd like to keep it simple, until some problems really happen one day .......

@yardenshoham
Copy link
Member Author

Agreed

@silverwind
Copy link
Member

Remove the "..." from the loading states? One indicator is enough imho.

@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Mar 2, 2024
@yardenshoham yardenshoham added the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Mar 2, 2024
@silverwind silverwind enabled auto-merge (squash) March 2, 2024 19:19
@silverwind silverwind merged commit 937e8b5 into go-gitea:main Mar 2, 2024
26 checks passed
@GiteaBot GiteaBot added this to the 1.22.0 milestone Mar 2, 2024
@GiteaBot GiteaBot removed the reviewed/wait-merge This pull request is part of the merge queue. It will be merged soon. label Mar 2, 2024
@yardenshoham yardenshoham deleted the morph-elipsis branch March 2, 2024 21:17
zjjhot added a commit to zjjhot/gitea that referenced this pull request Mar 3, 2024
* upstream/main:
  Breaking summary for template refactoring (go-gitea#29395)
  [skip ci] Updated translations via Crowdin
  Fix incorrect cookie path for AppSubURL (go-gitea#29534)
  gitea.service: Remove syslog.target (go-gitea#29550)
  Add option to set language in admin user view (go-gitea#28449)
  Fix elipsis button not working if the last commit loading is deferred (go-gitea#29544)
  Fix incorrect relative/absolute URL usages (go-gitea#29531)
  Add support for API blob upload of release attachments (go-gitea#29507)
  Fix queue worker incorrectly stopped when there are still more items in the queue (go-gitea#29532)
  remove util.OptionalBool and related functions (go-gitea#29513)
  Rename Action.GetDisplayName to GetActDisplayName (go-gitea#29540)
  Make PR form use toast to show error message (go-gitea#29545)
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. type/bug type/refactoring Existing code has been cleaned up. There should be no new functionality.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants