Some of the code was in its own component, while some of the code
remained in the polls/show view.
Note that we're re-structuring the code a little bit, so it's clear that
the "already voted" messages are only shown when users can vote. Also
note that now the `can?` condition involves the existence of a
`current_user` and that the poll is not expired, so we can simplify the
`voted_in_web` condition.
This way it'll be easier to refactor it.
Note there was a system test which tested both the callout and the form
when unverified users visit a poll. We've split this system test in two
component tests.
Our original interface to vote in a poll had a few issues:
* Since there was no button to send the form, it wasn't clear that
selecting an option would automatically store it in the database.
* The interface was almost identical for single-choice questions and
multiple-choice questions, which made it hard to know which type of
question we were answering.
* Adding other type of questions, like open answers, was hard since we
would have to add a different submit button for each answer.
So we're now using radio buttons for single-choice questions and
checkboxes for multiple-choice questions, which are the native controls
designed for these purposes, and a button to send the whole form.
Since we don't have a database table for poll ballots like we have for
budget ballots, we're adding a new `Poll::WebVote` model to manage poll
ballots. We're using WebVote instead of Ballot or Vote because they
could be mistaken with other vote classes.
Note that browsers don't allow removing answers with radio buttons, so
once somebody has voted in a single-choice question, they can't remove
the vote unless they manually edit their HTML. This is the same behavior
we had before commit 7df0e9a96.
As mentioned in c2010f975, we're now adding the `ChangeByZero` rubocop
rule, since we've removed the test that used `and change`.
This way changing it will be easier.
Note we're moving the `legislation-draft-versions-form` class into the
form component itself, which is wat we usually do in components.
This way changing it will be easier.
Note we're changing the name of the HTML class to follow our naming
conventions; the `edit_page` class wasn't used anywhere, so we don't
need to change anything else.
This rule was introduced in RuboCop 1.76.0 to ensure methods ending
in '?' return boolean.
This commit applies suggested renames and code cleanup:
- Renames 'is_active?' to 'active_class' since it returns a string
- Renames 'parsed_value' to 'in_favor?' and 'is_request_active' to end with '?'
for boolean semantics
- Skips false positives like 'save', 'auto_labels' or 'save_requiring_finish_signup',
which are not predicate methods.
Since commit c5103d3025, the styles from application.scss no longer apply
to app/views/dashboard/poster/index.pdf.erb.
To recover the text-center alignment, we add the rule in dashboard.scss.
Note that we also remove text-center from the h2, since it wasn't applied
and there's no need to recover it because it doesn't exist in the preview
either.
We were using a placeholder, which is way less accessible than a label.
One issue here (which also happened before, but is now more obvious) is
that, when adding several options, there will be many fields with the
same label.
Another issue is that, for some languages, we're using texts like "Add a
closed answer", which might be confusing because we might be editing an
existing answer. The proper solution would probably be using the text
"Option 1", "Option 2", ... I'm not doing so right now because I'm not
sure that's a good option and because changing the text would mean
losing the existing translations.
The link to the comments page was an "expand" icon, which was confusing
because it wasn't really expanding the contents of the sidebar but going
to an entirely different page. Furthermore, it didn't have any text for
people using screen readers, which is why Axe was reporting the
following accessibility error:
```
link-name: Links must have discernible text (serious)
https://dequeuniversity.com/rules/axe/4.10/link-name?application=axeAPI
The following 1 node violate this rule:
Selector: #annotation-link > a
HTML: <a href="/legislation/processes/75/draft_versions/30/annotations/8?sub_annotation_ids=">
<span class="icon-expand" aria-hidden="true"></span>
</a>
Fix all of the following:
- Element is in tab order and does not have accessible text
Fix any of the following:
- Element does not have text that is visible to screen readers
- aria-label attribute does not exist or is empty
- aria-labelledby attribute does not exist, references elements that
do not exist or references elements that are empty
- Element has no title attribute
```
So we're removing the icon and turning the "N comments" text into a
link, so it's easier to guess that the link takes us to the page showing
all the comments for this annotation.
This way we simplify the CSS and, in the case of the "check" icon, using
an SVG icon instead of an icon font offers several advantages, as
mentioned in commit 925f04e3f.
People using screen readers had no idea what these links were about (not
that the icons are very usable for people seeing them either... but
that's a different topic). Axe was reporting this error:
```
link-name: Links must have discernible text (serious)
https://dequeuniversity.com/rules/axe/4.10/link-name?application=axeAPI
The following 1 node violate this rule:
Selector: #dashboard_action_2_execute
HTML: <a id="dashboard_action_2_execute" class="unchecked-link"
rel="nofollow" data-method="post"
href="/proposals/16-proposal-6-title/dashboard/actions/2/execute">
<span class="unchecked"></span>
</a>
Fix all of the following:
- Element is in tab order and does not have accessible text
Fix any of the following:
- Element does not have text that is visible to screen readers
- aria-label attribute does not exist or is empty
- aria-labelledby attribute does not exist, references elements that
do not exist or references elements that are empty
- Element has no title attribute
```
People using screen readers might have a hard time knowing what a
progressbar is about unless we provide a label for it. Axe was reporting
failures like:
```
aria-progressbar-name: ARIA progressbar nodes must have an accessible
name (serious)
https://dequeuniversity.com/rules/axe/4.10/aria-progressbar-name?application=axeAPI
The following 1 node violate this rule:
Selector: .progress
HTML: <div class="progress" role="progressbar" tabindex="0"
aria-valuenow="0.0" aria-valuemin="0" aria-valuemax="100">
<div class="progress-meter" style="width: 0.0%"></div>
</div>
Fix any of the following:
- aria-label attribute does not exist or is empty
- aria-labelledby attribute does not exist, references
elements that do not exist or references elements that are empty
- Element has no title attribute
```
Note that, in the case of the ballot progressbar, it's easier to use
`aria-labelledby`, while in other place it's easier to use `aria-label`,
so we using the easier solution in each scenario.
Just like we do everywhere else. We're also removing the wrong ARIA
attributes that we added in commit c18479e3a, which caused an
accessibility issue reported by Axe:
```
aria-required-children: Certain ARIA roles must contain particular
children (critical)
https://dequeuniversity.com/rules/axe/4.10/aria-required-children?application=axeAPI
The following 1 node violate this rule:
Selector: .tabs-content
HTML: <div class="tabs-content"
data-tabs-content="information-texts-tabs" role="tablist">
Fix any of the following:
- Element has children which are not allowed: ul[tabindex]
```
Although, in this case, it would probably be better to have different
pages instead of tabs, so loading the page doesn't take too long.
Using a `data-toggle` attribute, which we do since commit 07fd5084f,
made Foundation generate an `aria-expanded` attribute to a radio button,
but this attribute can't be present in radio buttons. This makes sense,
since the main purpose of a radio button in a form is to choose an
option, not to show/hide content.
This resulted in the following error when checking the page with Axe:
```
Found 1 accessibility violation:
aria-allowed-attr: Elements must only use supported ARIA attributes
(critical)
https://dequeuniversity.com/rules/axe/4.10/aria-allowed-attr?application=axeAPI
The following 2 nodes violate this rule:
Selector: #dashboard_action_action_type_proposed_action
HTML: <input data-toggle="request_to_administrators short_description"
type="radio" value="proposed_action" checked="checked"
name="dashboard_action[action_type]"
id="dashboard_action_action_type_proposed_action"
aria-expanded="true"
aria-controls="request_to_administrators">
Fix all of the following:
- ARIA attribute is not allowed: aria-expanded="true"
Selector: #dashboard_action_action_type_resource
HTML: <input data-toggle="request_to_administrators short_description"
type="radio" value="resource"
name="dashboard_action[action_type]"
id="dashboard_action_action_type_resource"
aria-expanded="true"
aria-controls="request_to_administrators">
Fix all of the following:
- ARIA attribute is not allowed: aria-expanded="true"
```
So we're using custom JavaScript instead. We're also making the
`short_description` field act as intended; since the changes in commit
07fd5084f it was never shown because it had the `hide` HTML class and it
didn't have a `data-toggler` attribute.
This way we can move some system tests to component tests and stop
creating records after starting the browser with a `visit`.
We could also split the system test in two, but since these tests
aren't checking any user interactions, moving the to component tests we
check the same things while making the tests faster.
Since the partial was using an instance variable, we're passing it to
the component. We're naming it `voter_user` instead of `user` because
passing something named `user` could make us think that we're passing
the `current_user`. I wasn't sure about naming it `voter` because it's a
`User` record and not a `Poll::Voter` record, but naming it `voter`
would definitely be an option.
I don't think this feature it was ever used. It was introduced in commit
49dec6061 as part of a feature that was removed in commits 1cd47da9d and
c45a0bd8ac.
We removed the link to this page in commit 83e8d6035 because poll
questions don't really make sense without a poll.
However, this page also contained information about successful
proposals, which might be interesting so administrators don't have to
navigate to the public area in order to find and create questions based
on successful proposals.
So we're keeping the part about successful proposals and linking it from
the proposals part of the admin area.
Note we're using translation keys like `successful_proposals_tab`, which
don't make sense anymore, for the successful proposals. We're doing so
because we've already got translations for these keys and, if we renamed
them, we'd lose the existing translations and our translators would have
to add them again.
Also note we're changing one poll question test a little bit so we
create the question from a successful proposal using the new page. There
are other tests checking how to create a question from the
admin/proposals#show action and other tests checking what happens when
accessing a successful proposal in the admin section, so we don't lose
any test coverage by changing an existing test instead of adding a new
one.
Finally, note that we've removing the `search` method in poll question
because we no longer use it. This currently makes the
`author_visible_name` database column useless; we aren't removing it
right now because we don't want to risk a possible data loss in a patch
release (we're about to release version 2.3.1), but we might remove it
in the future.
This column isn't used since commit 4c0deb0ec because administrators can
associate videos to the answers since commit 5862eea51. The value of
this attribute isn't used in the public area since commit 8277e3cc2.
This parameter isn't used since commit b4a6f664b.
Note we're changing the tests to use proposals instead of debates
because proposals may have images attached, while debates may not.
This way we're also checking mistakes like closing tags that don't match
their opening element, which we detected by manually running HTML
Beautifier with the `-e` option, and fixed two commits ago.
Note there was a false positive in the mailer layout. We don't know the
cause. Maybe closing the ERB tag right before the HTML opening tag and
the lack of other attributes on the tag made HTML Beautifier think the
tag wasn't correctly open, but on the other hand, we have the exact same
line in other layouts where HTML Beautifier works fine. We're fixing it
by adding an HTML id attribute to the element.
We had inconsistent indentation in many places. Now we're fixing them
and adding a linter to our CI so we don't accidentally introduce
inconsistent indentations again.
In some places, we accidentally opened the same tag twice instead of
closing it, while in some other places we closed a tag without opening
it in the first place.
We've detected these issues thanks to the HTML Beautifier gem, which
we're about to start using for indentation purposes.
Using an `if..else` block made the code harder to follow since the
opening tag was inside the block but the closing tag was outside it.
Moreover, it didn't work well with HTML Beautifier (a gem we're going to
introduce to manage ERB indentations).
This way we simplify the HTML, which had some `if...else` blocks that
were hard to follow because there were opening tags inside these blocks
while the closing tags were outside these blocks.
We're also making the CSS container-dependent instead of
window-dependent. Since there are between one and three elements inside
the panel, we accomplish this by making the element with the content
take its own line if the width of the panel is smaller than 35rem.
Note we're trying to keep the layout similar to what it was; since we're
no longer using negative margins (like the ones in the `.row` selector),
the votes element now gets a width of 22.5% instead of 25%.
Also note we're using the column-gap property for flexbox because the
`flex-with-gap` mixin doesn't work so well with elements that have
borders. Since the column-gap property for flexbox is now supperted by
more than 98% of the browsers (which wasn't the case when we started
using the `flex-with-gap` mixin), the `flex-with-gap` mixin has become
obsolete.
Finally, note we're removing the `max-width: 12rem` rule in the images.
I'm not sure why we introduced this rule in the first place, and it
didn't play so well to the new layout. I considered using code like
`max-width: min(100%, 12rem)`, but, since I'm not sure why `12rem` was
there in the first place, I'm not sure whether this approach was better,
and it sure made things more complex.
Not doing so made it trickier to define a flex layout, since the
icon-successful element is given a `position: absolute`, but only for
successful proposals, while for unsuccessful proposals it was taking
the standard `position: static` value.
We're also reusing the `successful?` method instead of rewriting it in
the view, and fixing a small issue where the icon wasn't displayed for
proposals having the exact needed votes (we were using `>` instead of
`>=` in the condition).
Note that legislation proposals use the method
`Proposal.votes_needed_for_success`, which is probaby a mistake caused
by copying the code from the proposal view. Fixing this issue is out of
the scope of this commit (and pull request), though.