-
Notifications
You must be signed in to change notification settings - Fork 375
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
feat: add p/avl/pager #2584
feat: add p/avl/pager #2584
Conversation
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #2584 +/- ##
==========================================
- Coverage 63.33% 62.99% -0.35%
==========================================
Files 548 548
Lines 78646 81238 +2592
==========================================
+ Hits 49809 51173 +1364
- Misses 25476 26627 +1151
- Partials 3361 3438 +77
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Signed-off-by: moul <94029+moul@users.noreply.github.com>
I tried the pagination with the following:
Edit examples/gno.land/r/demo/users/users.gno. On line 331 in
In a browser, go to http://127.0.0.1:8888/r/demo/users . It shows:
When I click "2", it doesn't change. |
return doc | ||
} | ||
|
||
func splitPathAndQuery(fullPath string) (string, string) { | ||
parts := strings.SplitN(fullPath, "?", 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I click on page "2", the URL becomes "http://127.0.0.1:8888/r/demo/users?page=2". But I don't think that the query string with the "?" is passed to Render
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, they are not being passed:
https://gno.land/r/g1hy6zry03hg5d8le9s2w4fxme6236hkgd928dun/echorender:foo/bar?baz=bar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created #2876 in case is helpful
items := []Item{} | ||
p.Tree.ReverseIterateByOffset(startIndex, endIndex-startIndex, func(key string, value interface{}) bool { | ||
items = append(items, Item{Key: key, Value: value}) | ||
return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
offtopic: a bit misleading. Normally, if you want to continue, you return true, but it is what it is. Example from standard library: https://pkg.go.dev/sync#Map.Range
return &Page{ | ||
Items: items, | ||
PageNumber: pageNumber, | ||
PageSize: pageSize, | ||
TotalItems: totalItems, | ||
TotalPages: totalPages, | ||
HasPrev: pageNumber > 1, | ||
HasNext: pageNumber < totalPages, | ||
Pager: p, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here, you can add items to previously created page instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done 79ffd7d
Co-authored-by: Antonio Navarro Perez <antnavper@gmail.com>
Signed-off-by: moul <94029+moul@users.noreply.github.com>
pageNumber := 1 | ||
pageSize := p.DefaultPageSize | ||
|
||
if p.PageQueryParam != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: given the current situation, this parameter will not be empty, so the check can be omitted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be made empty. The question is whether we let the if
condition so that the subsequent line doesn't produce something strange, or if we switch to a panic because it's nonsensical to use a pager without a way to change the query string.
return pageNumber, pageSize, nil | ||
} | ||
|
||
func min(a, b int) int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems not used in any place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: moul <94029+moul@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't try all of the functionality; just the stuff I needed for HOF.
It seems that the pagination is not working as @jefft0 & @jeronimoalbi noticed Could we fix this?
Other than that, I found it a bit difficult to get around with the API until I saw an actual usage example (r/demo/users).
Another consideration is that we could maybe create a ReversePager
, similar to how you have Iterate
& ReverseIterate
for the AVL. Or maybe it could be a flag for NewPager()
} | ||
|
||
// UI generates the Markdown UI for the page selector. | ||
func (p *Page) Selector() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
func (p *Page) Selector() string { | |
func (p *Page) Picker() string { |
I think this is a more intuitive name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, Picker sounds better. @alexiscolin, do you have an opinion on the name of this part, "1 2 3 4 5"?
func renderHome(path string) string { | ||
doc := "" | ||
name2User.Iterate("", "", func(key string, value interface{}) bool { | ||
user := value.(*users.User) | ||
|
||
page := pager.NewPager(&name2User, 50).MustGetPageByPath(path) | ||
|
||
for _, item := range page.Items { | ||
user := item.Value.(*users.User) | ||
doc += " * [" + user.Name + "](/r/demo/users:" + user.Name + ")\n" | ||
return false | ||
}) | ||
} | ||
|
||
doc += page.Selector() | ||
return doc | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work actually; if you try to make a pager with page size, say, 4, to check to pagination funcntionality, you get this;
but then clicking on 2
, or 3
doesn't take you anywhere, just changes the link, as @jefft0 said. A click on 3 takes you here: /r/demo/users?page=3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this won't be fixed until we figure out what to do with the links here #2876
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, to have a working example, we depend on the other PR.
One option is to merge without using it everywhere, which means some contracts won't function fully for now. This is probably acceptable since we expect the other PR to be merged. We might consider disabling it on r/demo/users if people find the top-level listing too important on gnodev and portal loop (I don't share this opinion).
Alternatively, we need to ensure that someone works on #2876. This could be a core team member if the current contributor doesn't have time to finish.
Co-authored-by: Leon Hudak <33522493+leohhhn@users.noreply.github.com>
Thank you, @leohhhn, for your feedback. Do you have any suggestions on how to improve this part? |
// page number provided is outside the range of total pages | ||
if pageNumber > totalPages { | ||
page.PageNumber = pageNumber | ||
page.HasPrev = pageNumber > 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
page.HasPrev = pageNumber > 0 | |
page.HasPrev = true |
pageNumber > 0
will always be true in this if
, because totalPages
cannot be less than 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, but actually i'm considering if in this case it should maybe be totalPages > 0
.
### Description This PR introduces a change for _gnoweb_ to also pass the URL query string as part of the render path. Passing the URL query string is required to support arguments when rendering realms, which is the case of the AVL pager implementation in #2584 that uses "page" and "size". The PR changes the behavior of realm rendering calls by adding URL query arguments as suffix of the `path` argument, so URLs like `https://gno.land/r/demo/foo:bar?baz=42` would call `Render(path)` with "bar?baz=42" as value of `path`. It also changes how special _gnoweb_ arguments like `help` of `func` are specified which now must be done by using the `$` character, for example: - `https://gno.land/r/demo/foo$help&func=Bar&name=Baz` - `https://gno.land/r/demo/foo:example$tz=Europe/Paris` - `https://gno.land/r/demo/foo:example?value=42$tz=Europe/Paris` Note that `__func` is now `func`, without the underscore prefix. ### Possible Issues The change could potentially affect realm or package implementations that rely on the render path in cases where the `?` is not expected, for example when parsing or splitting it. Because of that there might be changes required to handle the case where a caller sends query string arguments. Realms and packages should be able to handle render paths which could look like `render/path?arg=1&arg=N`. Links that still use `?`, `help` and `__func` won't work as expected, they must be changed to use `$` instead of `?`, and `func` instead of `__func`. Packages `gno.land/p/moul/txlink` and `gno.land/p/moul/helplink` has to be refactored to properly generate links. --------- Co-authored-by: Leon Hudak <33522493+leohhhn@users.noreply.github.com> Co-authored-by: leohhhn <hudakleon@gmail.com> Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com>
Can you check the tests & formatting and we can merge this? |
Signed-off-by: moul <94029+moul@users.noreply.github.com>
should be good |
## Description Depends on #2584 for `avlpager` Introduces the `r/demo/hof` realm. The Hall of Fame is an exhibition that holds items. Users can add their realms to the Hall of Fame by importing the Hall of Fame realm and calling `hof.Register()` from their `init` function. The realm is moderated and the registrations be paused at will. ![Screenshot 2024-10-07 at 20 09 43](https://github.com/user-attachments/assets/9beeefc6-d22a-4e81-aa2d-e336d0e6edf8) <details><summary>Contributors' checklist...</summary> - [x] Added new tests, or not needed, or not feasible - [x] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory - [x] Updated the official documentation or not needed - [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message was included in the description - [x] Added references to related issues and PRs - [x] Provided any useful hints for running manual tests - [x] Added new benchmarks to [generated graphs](https://gnoland.github.io/benchmarks), if any. More info [here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md). </details> --------- Signed-off-by: moul <94029+moul@users.noreply.github.com> Co-authored-by: moul <94029+moul@users.noreply.github.com> Co-authored-by: Antonio Navarro Perez <antnavper@gmail.com>
p/demo/avl/pager
r/demo/users
Hey reviewers, in addition to what you wanted to review, I'm specifically curious if you have any better API/usage ideas.
Example: https://github.com/gnolang/gno/pull/2584/files#diff-8d5cbbe072737a7f288f74adcaaace11cacc3d31264e6a001515fcae824394e2R33
Related with #447, #599, #868