In Rails 6.1 and earlier, `button_to` generated a <button> tag when it
received the content as a block, but an <input> tag when receiving
the content as the first parameter.
That's why we were using blocks with `button_to` most of the time; for
starters, <button> tags accept pseudocontent and so are easier to style.
In Rails 7.0, `button_to` always generates a <button> tag [1], so we're
simplifying the code what uses `button_to`, passing the content as a
first parameter instead of passing it as a block.
[1] https://guides.rubyonrails.org/v7.1/configuring.html#config-action-view-button-to-generates-button-tag
Many pages had this tag, but many other didn't, which made navigation
inconsistent for people using screen readers.
Note that there are slight changes in two pages:
* The homepage now includes the banner and the content of the
`shared/header` element inside the <main> tag
* The budgets index now includes the banner inside the <main> tag
I see both potential advantages and disadvantages of this approach,
since banners aren't necessarily related to the main content of a page
but on the other hand they aren't the same across pages and people using
screen readers might accidentally skip them if they jump to the <main>
tag.
So I'm choosing the option that is easier to implement.
Note we're adding a `public-content` class to the <main> element in the
application layout. This might be redundat because the element could
already be accessed through the `.public main` selector, but this is
consistent with the `admin-content` class used in the admin section, and
without it the <main> element would sometimes have an empty class
attribute and we'd have to use `if content_for?(:main_class)` or
`tag.main` which IMHO makes the code less consistent.
The Capybara::DSL monkey-patch is only done on the `visit` method
because it's the only reliable one. Other methods like `click_link`
generate AJAX requests, so `expect(page).to have_css "main", count: 1`
might be executed before the AJAX request is finished, meaning it
wouldn't properly test anything.
The `use_helpers` method was added in ViewComponent 3.8.0, and it's
included by default in all components since version 3.11.0.
Note we sometimes delegated the `can?` method to the controller instead
of the helpers, for no particularly reason. We're unifying that code as
well.
IMHO the best solution would be to completely remove this checkbox on
forms that require registration. Other than the fact that people have
already agreed with these terms when registering (although I guess these
terms might have changed since then) and that approximately 0% of the
population will read the conditions every time they agree with them,
there's the fact that these links are inside a label and people might
accidentally click on them while trying to click on the label in order
to check the checkbox.
I guess the idea is that these conditions might have changed since the
moment people registered. In a fair world, checking "I agree" would have
no legal meaning because it's unreasonable to expect that people will
read these conditions every time they fill in a form, so whatever we're
trying to do here would be pointless.
But, since I'm not sure about the legal implications of removing this
field in a world where you have to inform people that websites requiring
identification use cookies, for now the field will stay where it is.
In some places, we were using `blank` instead of `_blank`. Most browsers
treat `blank` like `_blank`, though, so most people didn't experience
any difference.
In another place, we were incorrectly passing the `target` option inside
an `options:` hash, resulting in invalid HTML.
We were adding <div> tags with the `images` or `documents` HTML class
prettly much every time we rendered a NestedComponent. We're now
including the HTML class inside the component, as we usually do.
We're also rendering the nested components directly, since it's been a
while since the partials were changed to simply render the components.
In some cases, like SDG icons and the proposals map, the image was
bigger than the link containing it, resulting in a funny-looking outline
on focus.
For reasons I don't understand, using `&:active,&:focus:active` didn't
compile to the CSS I was expecting, so I'm repeating the same code for
these two separate cases.
For the HashAlignment rule, we're using the default `key` style (keys
are aligned and values aren't) instead of the `table` style (both keys
and values are aligned) because, even if we used both in the
application, we used the `key` style a lot more. Furthermore, the
`table` style looks strange in places where there are both very long and
very short keys and sometimes we weren't even consistent with the
`table` style, aligning some keys without aligning other keys.
Ideally we could align hashes to "either key or table", so developers
can decide whether keeping the symmetry of the code is worth it in a
case-per-case basis, but Rubocop doesn't allow this option.
We had two different keys with the same text and were passing it as a
parameter. Since the text is the same in any case, we don't need a
parameter for it.
Note we are using the `proposals` i18n key instead of creating a new one
in a `shared` namespace one because creating a new key would mean that
we'd lose the already existing translations in Crowdin.
We were manually generating the IDs in order to pass them as data
attributes in the HTML in a component where we don't have access to the
form which has the inputs.
However, these data attributes only make sense when there's a form
present, so we can pass the form as a parameter and use it to get the
IDs.
We can now define a map as editable when there's an associated form,
which makes sense IMHO.
Defining a behavior on hover means making it different for people using
a keyboard or a touchscreen (most of the population, nowadays).
In this case, we had an accessibility issue where the message wouldn't
disappear once it appeared. That meant that, after tabbing through all
the links and buttons in, for instance, the debates index, the page
would be filled with "participation not allowed" messages, and in order
to see the information about how many people have voted, reloading the
page was required.
For touchscreen users the behavior was similar to what we get on hover,
although we've found some inconsistencies when trying to support several
elements on the same page.
We think in proposals it makes sense to hide the "support" button when
users click on it, and the same applies to the buttonsto support and
vote investment projects. However, we aren't hiding the buttons to
agree/disagree with a debate in order to keep the information about the
current number of people agreeing and disagreeing visible.
Note we're removing some support spec methods because after these
changes the duplication isn't as obvious as it was in the past.
We were using the same logic six times regarding when we should show a
"participation not allowed" message. Since we're going to change the
current behavior, we're unifying the logic in one place so the changes
will be easier.
This way blind screen reader users will know which proposal they're
supporting. In a list of proposals, context might not be clear when a
link saying "Support" or "Support this proposal" is announced, but a
link saying "Support Create a monthly transport ticket" is less
ambiguous.
Just like we did with investments in commit de436e33a, we're keeping the
title attribute because when visiting a proposal page, the connection
between the "Support" link and the proposal is not as clear as it is in
the proposals index page, so it might not be clear what you're
supporting.
This way we can make the view code a bit easier to read.
We're also changing the order of the conditions a little bit so we only
check for the presence of a current user once.
To make sure we aren't breaking anything with these changes, we're
adding some tests. We're also replacing one system test checking content
with a component test, since component tests are much faster.
The action and the views were almost identical, with the supports
progress and the HTML classes of the success message element being the
only exceptions; we can use CSS for the styles instead.
Just like we did in commit 0214184b2d for investments, we're removing
some possible optimizations (we don't have any benchmarks proving they
affect performance at all) in order to simplify the code.
The investement votes component `delegate` code was accidentally left
but isn't used since commit 0214184b2, so we're removing it now that
we're removing the `voted_for?` helper method.
The imageable/documentable object is always the object the form builder
is based on; since we're already passing the form builder, we don't have
to pass the object as well.
The only exception are the poll answers. In this case, we're passing a
new answer as the object. That's OK; the same hack that we're using to
send the data to the answer URL without displaying existing attachments
causes the form to keep working the same way.
We don't need any row classes anymore because the <body> already has a
maximum width. As for columns, we only have one column in this form, so
we don't need them either. Besides, the form's parent element already
has a padding.
Since now categories are loaded in both the investment form component
and proposal form component, and their controllers are the only
"commentable" controllers using the `@categories` instance variable, we
can remove the `load_categories` call in `CommentableActions` affecting
the create and update actions.