-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Chore/admin semantic table rows #5950
base: main
Are you sure you want to change the base?
Chore/admin semantic table rows #5950
Conversation
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.
Nice! What about using link_to
instead?
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.
Alberto is right, We should use the link_to
helper wherever possible.
Regarding the tr
click event: I consider this a harmful and bad UX pattern and we should remove it completely.
cell = column.data | ||
cell = cell.call(data) if cell.respond_to?(:call) | ||
cell = data.public_send(cell) if cell.is_a?(Symbol) | ||
cell = content_tag :a, data.public_send(cell), href: url if cell.is_a?(Symbol) |
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.
We should use the link_to
helper here if possible and only if url
is present, no?
And why do we still need the cell.is_a?(Symbol)
call in case of an url
present?
cell = content_tag :a, data.public_send(cell), href: url if cell.is_a?(Symbol) | |
cell = link_to(data.public_send(cell), url) if cell.is_a?(Symbol) |
Sorry for my ignorance, but I am new to this part of Solidus and I still need some time to wrap my head around.
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.
I am also learning as I go as I wasn't the original author of this section, but I think if I understand it correctly the cell that is passed can be one of many types, and the Symbol check is needed in order to know whether we should be calling data.public_send(cell)
. This method call results in the string which is now newly wrapped in a link, but we still need that string as that is the data we want to show to the user (eg descriptions, names, etc).
@@ -83,15 +83,21 @@ def columns | |||
}, | |||
{ | |||
header: :order_count, | |||
data: ->(user) { user.order_count }, | |||
data: ->(user) do | |||
content_tag :a, user.order_count, href: row_url(user) |
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.
link_to
seems to be the helper we want here, no?
}, | ||
{ | ||
header: :lifetime_value, | ||
data: -> { _1.display_lifetime_value.to_html }, | ||
data: ->(user) do | ||
content_tag :a, user.display_lifetime_value.to_html, href: row_url(user) |
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.
ditto
}, | ||
{ | ||
header: :last_active, | ||
data: ->(user) { last_login(user) }, | ||
data: ->(user) do | ||
content_tag :a, last_login(user), href: row_url(user) |
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.
ditto
For sure, I can switch out |
Technically we do not need table rows to be clickable in order for the new admin flow to work. Clicking links inside the data cells should open modals or links, not clicking the row itself. It is not possible to wrap a TR in a A in HTML for good reasons. Consider a table row having multiple "actions" inside (let's say the promotions table has a link to edit the promotion itself and a promotion code, if clicked, visits the promotion codes list). How do we make this possible if only one click action is available for a whole row?
Thanks to your work we now have links in all table rows. So we should have the same UX as before, but on the HTML elements that are accessibly and semantically the correct elements. The click events inside the cells should bubble to the handler, so the click handler should still do its work. Ideally the row event handler would only handle modals and nothing else, but this is something to tackle later. Sorry for all the push back. I know that neither you nor I have been involved in designing or developing the new admin. We now have the burden to make it as maintainable as possible while still getting it done. I appreciate all the work you put into it, but please bear with we that I am looking at it from a maintainers prospective. Thanks 🙏🏻 |
No worries, always happy to work through these hurdles in discussion! I agree that the table rows should allow for multiple links/actions inside of each row (as in your promotion codes list example), and currently this is what we have. I also agree that having one overarching link would not be good. Currently the click handler will not fire if the user clicks on any of these elements: We can remove the Will now be dead space that is un-clickable. I think this would make the new admin flow quite janky and confusing for users, as they would need to know which parts to click (some of the However I think that would involve more bad code as we would then need to be checking already rendered component html (in string form) for whether it contains any of these elements: What do you think about the above challenges? Do you see a third option I don't? |
All of these are solvable by using less code and more semantics :)
I think we should not overcomplicate things. The browser, HTML and CSS provide us with simple, semantic, established and accessible tools that all do not require more, but less code. The web can be reduced to two simple UX patterns: links and forms. It's that simple. |
That sounds reasonable @tvdeyen I can take a look at this today. I'll do a pass over all the primary identifiers (most of which should already be links), swap out the content_tag for link_to, and address the spec failures and we should be good. |
392acbd
to
7e96eae
Compare
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.
Thansk @MadelineCollier, I marked some other occurrences of content_tag :a
, let's please fix them, unless there's a reason to keep them as they are.
promotions/lib/components/admin/solidus_promotions/promotion_categories/index/component.rb
Outdated
Show resolved
Hide resolved
promotions/lib/components/admin/solidus_promotions/promotion_categories/index/component.rb
Outdated
Show resolved
Hide resolved
legacy_promotions/lib/components/admin/solidus_admin/promotion_categories/index/component.rb
Outdated
Show resolved
Hide resolved
All over the new admin we use divs or simply text to display the resource and rely on a complex Stimulus click event handler to open the edit route. This is not semantic at all and makes it necessary to use a fully JS enabled browser under all circumstances to test the new admin interface which leads to flaky and slow tests. We should use links instead and probably remove the stimulus click event handler. Also, links are not visually highlighted, which leads to a11y issues. So, this commit adds underlines to links in table rows. solidusio#5944
Previously, when provided a symbol, the admin table component would simply call `data.public_send(cell)` (with cell being the symbol). This would result in a basic string as the content of the table row. We want to stop relying on the additional Stimulus click handlers that captured those plain text clicks and redirected the users to wherever the `row_url` location was. Now, the `render_data_cell` method handles wrapping the plain text in a link, with the href being the `row_url` location. Symbols can still be provided as columns and the component takes care of generating the proper semantic UI elements for us.
7e96eae
to
7e8a645
Compare
Thanks for catching those @kennyadsl, fixed! Still having some trouble with the specs. It seems like now that the rowClicked handler isn't in charge anymore, the links aren't preserving the query params (and many specs assert that they should be preserved even when opening/closing modals). Any ideas on how to fix this behaviour? We won't know what the ransack search params are at time of render as far as I can tell. I can also remove those spec assertions if we think its reasonable that if you open a modal to edit a table row, the query params are allowed to be lost. |
I can't recall exactly what was the need for that requirement. Is there a PR linked to that failing specs that we can reach with a git blame? |
No blames that I found were particularly helpful as the specs were generally just added as part of the development of the new admin. It makes sense that where possible we’d want to retain the filters/searches that users have inputted, but I can’t find a good way of doing that for all of our new links. This largely only comes into play on edit actions triggered by table link clicks. |
Yes, you are right. It was probably because when we search for something, edit an item on the row and close the modal, we want to keep the existing selection of the table. cc'ing @elia and @rainerdema to see if we have more details here. I think we should keep this behavior, as the alternative is a very bad UX where you need to filter again if you want to edit multiple items in the same table after a specific filtering. |
Ok that makes sense as a requirement. My only thought is that this was possible before due to the fact that the |
Ok guys, I have been plugging away at the specs, and while the consistent blocker is the missing query params, another issue has come up that relates to the See it in it's original form:
The deletion of the At this point it feels like 1 step forward, 3 steps back. It would be nice to hear from @elia and @rainerdema to see if this is a path (more semantic UI links instead of stimulus handlers) that has already been explored. This would explain why the |
A tricky problem we faced in Alchemy as well. It has been solved by responding with a proper 422 on errors, so that the modal gets redisplayed and properly closed via a redirect from the server. Query parameters are preserved by passing around the ransack parameters. All that said, I know that this is a tough problem to solve and I was under the impression it can be solved in the new admin. Unfortunately there is much more involved to fix this issue. I can totally understand if you want to table this for now. Maybe I find some time in the future to contribute some of the code we built for Alchemy to Solidus. Sorry for these circumstances |
Summary
This PR is for issue: [Admin] Table component rows do not contain links
This addresses the major concerns of that issue, but does not remove the click handler as it's still required in one case. That is the case of the
<tr>
clicks. I tried inserting an<a>
to wrap the whole row, but that didn't work. The browser refused to render it as it seemingly violates the HTML standard for tables. You can have a link, a td, but not both on the same level within the tr. You can only have both if the link is nested inside the td. We might want to look into inserting it inside of each of the<tr>
's<td>
s, but this seems quite messy since some<td>
s currently have their own behaviour which would be overruled by that link (row checkbox inputs for one example).So to recap, this PR addresses our over reliance on the
rowClicked
stimulus handler for all cases except for the<tr>
itself. Now instead of rendering text or divs, we render semantic UI elements (links) with proper hrefs. Hopefully this makes sense @tvdeyen let me know what you think.Before:
before.mov
After:
after.mov
Checklist
Check out our PR guidelines for more details.
The following are mandatory for all PRs:
The following are not always needed: