Commit Graph

5006 Commits

Author SHA1 Message Date
Javi Martín
58d123ad51 Merge pull request #4552 from consul/table_icons_with_text
Use icons with text in admin table actions
2021-06-30 16:31:18 +02:00
Javi Martín
db4a262a0d Merge pull request #4571 from consul/campaigns_specs
Make campaign specs more robust
2021-06-30 16:16:28 +02:00
Javi Martín
28e720a1ec Make sure we use non-existent IDs in campaign test
Previously, depending on the database status, it could be possible that
the ID of the campaign2 record was exactly 999 and this test could fail.
2021-06-30 16:00:07 +02:00
Javi Martín
855f47f386 Create campaings before running campaigns tests
We were defining campaigns with `let`. That meant they weren't created
until these methods were used in the tests.

For the test "Do not track erroneous track_ids", that meant the line
`expect(page).not_to have_content campaign2.name.to_s` wasn't really
testing anything, since before this line is executed, the campaign2
wasn't in the database at all, and so obviously its name wouldn't be on
the stats page.

For the test "Track email templates", it meant we were creating the
campaign2 record after visiting the campaign1 page with the browser.
Creating records in the tests after starting the browser might be the
reason why this test has recenty failed in our CI [1]:

 1) Email campaigns Track email templates
     Failure/Error: ds.add params[:event].titleize, Ahoy::Event.where(
                    name: params[:event]).group_by_day(:time).count
     ActiveRecord::StatementInvalid:
       PG::ProtocolViolation: ERROR:  bind message supplies 0
       parameters, but prepared statement "" requires 1
     # ./app/controllers/admin/api/stats_controller.rb:13:in `show'

Using `let!` to create the campaings before the browser starts improves
the situation.

[1] https://github.com/consul/consul/runs/2952333023
2021-06-30 16:00:00 +02:00
Javi Martín
5531a0b2bc Simplify action links in budgets table
The word "budget" in the "Preview budget" link is redundant.

On the other hand, the words "Manage", Edit" and "Admin" are not
really necessary in my humble opinion. Just like in the admin
navigation menu we use "Participatory budgets" instead of "Manage
Participatory budgets", the fact that we're going to manage or
admin or edit something can be deduced from the fact that we're in
the admin section.

Besides, it isn't clear to me why we use "Manage" for projects,
"Edit" for heading groups and "Admin" for ballots. The differences
between these three concepts might be too subtle for me.

The previous paragraphs haven't been corroborated with real users,
though, so I might be mistaken and we might need to revisit these
links in the future.

These actions still take quite a lot of space. Maybe in the future we
could remove the "delete" icon, at least on budgets which cannot be
deleted.
2021-06-30 14:33:37 +02:00
Javi Martín
6f04c8f057 Use conventions in page actions texts
We use the words "Manage" and "View" in other places; we don't use the
word "See" as often.
2021-06-30 14:33:37 +02:00
Javi Martín
7d590031f5 Remove redundant words in edit and destroy links
When we see a list of, let's say, banners, and each one has a link to
edit them, the word "banner" in the text "edit banner" is redundant and
adds noise; even for users with cognitive disabilities, it's obvious
that the "edit" link refers to the banner.
2021-06-30 14:33:37 +02:00
Javi Martín
25e9065913 Use icons with text in admin table actions
In commit 9794ffbbf, we replaced "buttons" with icons in order to make
the admin interface consistent with the planned budget investments
redesign.

However, using icons has some issues. For once, icons like a trash for
the "delete" action might be obvious, but other icons like "confirm
moderation" or "send pending" might be a bit confusing.

It's true that we were adding tooltips on hover. We tried two
approaches: using Foundation's tooltips and using CSS tooltips.

Foundation tooltips are not activated on focus (only on hover), while
CSS tooltips always appear below the icon, which might be a problem when
the icons are at the bottom of the screen (one of our milestone tests
was failing because of that and we can now run it with JavaScript
enabled).

Both Foundation and CSS tooltips have other issues:

* They force users to make an extra step and move the mouse over the
  link just to know what the link is about
* They aren't available on touch screens, so these users will have to
  memorize what each icon does
* They are not hoverable, and making them hoverable would cause a
  different issue because the tooltip might cover links below it, making
  it impossible to click these links without moving the mouse away
  first
* They are not dismissable, which is considered an accessibility issue
  and a requirement in the Web Content Accessibility Guidelines [1]

For all these reasons, we're using both texts and icons. As Thomas
Byttebier said "The best icon is a text label [2]". Heydon Pickering
also makes a point towards providing text alongside icons in his book
"Inclusive Components" [3].

Note that, since we're now adding text and some of the colors we use for
actions are hard to read against a white/gray background, we're making a
few colors darker.

With these changes, actions take more space in the admin table compared
to the space they took in version 1.3, but they are more usable and
accessible while they still take less space than they did in version
1.2.

[1] https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus
[2] https://thomasbyttebier.be/blog/the-best-icon-is-a-text-label
[3] https://inclusive-components.design/tooltips-toggletips/
2021-06-30 14:33:37 +02:00
Javi Martín
614e6da92b Use a submit button in budget executions filters
As mentioned in commit 5214d89c8, there are several issues with
submitting a form when a `<select>` tag changes. In particular, keyboard
users might accidentally fire the event while browsing the options, and
screen reader users will find a form with no obvious way to submit it.

In this case, there's an extra problem: in commit be8a0dbe8 we added a
second `<select>` field to this form, which also submitted on change.
Sometimes users changed one of the values and wanted to change the other
value as well before submitting the form. However, it wasn't possible,
because we would submit it before they had a chance to change the second
value.

So now we don't submit the form on change and add a submit button. This
is similar to what we do in the "Advanced filters" we use in several
places.
2021-06-30 14:14:43 +02:00
Javi Martín
ee4ef8d3a5 Use labels to select filters in executions tests
This way we check there's a label associated to these fields.
2021-06-29 20:07:55 +02:00
Javi Martín
d8d5b7f60a Extract budget executions filters to a component 2021-06-29 20:07:55 +02:00
Javi Martín
626af63a42 Merge pull request #4565 from consul/improve-home-cards
Improve home cards
2021-06-29 17:07:07 +02:00
taitus
db23d536dd Do not show link content section when links fields are not defined. 2021-06-29 16:53:37 +02:00
Javi Martín
a2f6e03516 Move advanced search toggle button inside the form
Since forms are landmarks, screen reader users might navigate to the
form. But then they were going to find an empty form with no way to
toggle it.

Moving the button inside the form means screen reader users navigating
to the form will find the button to toggle it.

It also helps us simplifying the code; there's no need to use
data-attributes to communicate whether the form should be visible since
now we can easily use the button `aria-expanded` attribute.

We could further simplify the JavaScript if we used a CSS rule to
show/hide the form fields based on the toggle button `aria-expanded`
attribute. However, implementing the "slide" animation we use when
toggling the form with CSS is difficult and unreliable.
2021-06-29 14:13:54 +02:00
Javi Martín
6a44ca350d Render the advanced search form without JavaScript
We were using the form and then showing it with JavaScript when advanced
search terms were present. Now we hide it with JavaScript when no
advanced search are present. This means users without JavaScript
(including users with JavaScript enabled but bad internet connections
preventing the JavaScript to load) can now access the form.

The other main difference between the two versions is the way the form
flashes while JavaScript is loading.

Previously, the form would always be hidden when no terms had been
introduced. However, when these terms were present, after submitting the
form it would briefly be hidden and then shown again.

Now the opposite happens. When advanced search terms are present, the
form is shown at all times. However, when they aren't, the form is
briefly shown before it disappears.

Here the previous behavior is arguably better because most of the time
these terms will not be present.

So basically we're significantly improving the experience of some users
at the cost of slightly worsen the experience of other users.

We're also hiding the button to show the form when JavaScript is
disabled, since in this scenario it's useless. We're using the `hidden`
attribute so hidden buttons can be detected in CSS.
2021-06-29 14:13:53 +02:00
Javi Martín
6dcdf5c843 Use a button to toggle the advanced search form
Users (particularly, screen reader users) usually identify links with
things that take you somewhere, and buttons with things that either send
forms or change things on the page.

Using a button we can also use the `aria-expanded` attribute, meaning
screen reader users will know that the button has two states ("expanded"
and "collapsed"), the current state of the button, and will get
immediate feedback when clicking the button because the new state of the
button will be announced.

Thanks to this change, we can also slightly simplify the code; we
obviously have to remove the (useless) `href` attribute, and we don't
have to prevent the default event in JavaScript since there's no default
event for buttons with `type="button"`.
2021-06-29 13:58:32 +02:00
taitus
108de86da5 Add link_url validation for cards when are header cards
Add link_url presence validation only when link_text is provided only for header cards.

In this case it makes sense to allow creating a "header card" without link_url, since
we can show the header without link text and without link url and it still does its
function.
2021-06-28 15:59:04 +02:00
taitus
1d47a5c079 Add link_url validation for cards when are not header cards
Currently it is not necessary to include the link_url field.

When we display these cards without link_url, they create an empty link that
redirects to the same page. I understand that this is not a desired behavior, so I
think it is better to add a validation in this case and force administrators to add a
link_url when creating a card.
2021-06-28 15:57:39 +02:00
Javi Martín
bc0f040758 Use order links in legislation proposals admin
As mentioned in the previous commits, a `<select>` field which submits
its form on change causes many accessibility and usability issues, so
we're replacing it with the order links we use everywhere else.

Since the links "Id" and "Title" by themselves don't have enough
information to let users know they're used to sort by ID or title, we
have to update them somehow. We could add a "Sort by:" prefix before the
list of links (and associate it with the `aria-labelledby` attribute);
however, we don't do this anywhere else and might look weird depending
on the screen size.

So we're simply adding "Sort by" before each link.

Now that we don't use the `wide_order_selector` partial anymore, we can
remove it alongside the styles for the `select-order` class.
2021-06-28 01:20:39 +02:00
Javi Martín
14d8bef0d8 Use order links in print proposals management
A `<select>` tag here might make more sense than in other similar places
since there are 5 options to choose among, and using links might take
too much screen space.

However, as mentioned in the previous commits, `<select>` tags which
automatically submit a form have many accessibility and usability
issues.

An alternative would be to create a dropdown menu with a button and a
list of links (similar to what Foundation does). I'm keeping the links
for simplicity and because the interface looks a bit more consistent
with the rest of the sections. Before these changes, we had a heading,
then a `<select>` field to choose the filter, and then a button to print
the page. We never use a similar interface, and some people might think
the "Print" button is related to the same form as the `<select>` field.

Now that we don't use the `order_selector` partial anywhere anymore, we
can remove it.
2021-06-28 00:15:08 +02:00
Javi Martín
227a5868b8 Use order links in moderation section
Using order links in this case causes an unusual interface, where we
show filter links, then information about the number of results, and
then order links.

Whether or not this makes sense needs to be confirmed with usability
tests. In any case, this is still way better than using `<select>`
fields which automatically change to a new page, since they cause
problems to keyboard users, are harder to select for touchscreen users,
might confuse screen reader users who will notice a form but no way to
submit it, and are not elements we generally use to let users choose the
order of the records.

For a more detailed explanation of these issues, check the commit
message in the commit "Use order links to sort comments and topics"
(just a few commits ago).
2021-06-28 00:15:08 +02:00
Javi Martín
55cf502e8f Fix typo in proposal notifications moderation test 2021-06-28 00:15:08 +02:00
Javi Martín
93f3411a30 Use anchors in comments order and pagination links
It was a bit frustrating to click on one of the order elements or the
link to the next page and having to scroll down again until reaching the
comments.
2021-06-28 00:15:06 +02:00
Javi Martín
5214d89c88 Use order links to sort comments and topics
We use order links in many places in the web. However, in the comments
section and the list of community topics, we were displaying a
`<select>` element, and changing the location when users select an
option.

This has several disadvantages.

First, and most important, it's terrible for keyboard users. `<select>`
fields allow using the arrow keys to navigate through their options, and
typing a letter will select the first option starting with that letter.
This will trigger the "change" event and so users will navigate through
a new page while they were probably just checking the available options
[1]. For these reasons, WCAG Success Criterion 3.2.2 [2] states:

> Changing the setting of any user interface component does not
> automatically cause a change of context unless the user has been
> advised of the behavior before using the component.

Second, the form didn't have a submit button. This might confuse screen
reader users, who might not know how that form is supposed to be
submitted.

Finally, dropdowns have usability issues of their own [3], particularly
on mobile phones [4]

The easiest solution is to use the same links we generally use to allow
users select an order, so using them here we make the user experience
more consistent. They offer one disadvantage, though; on small screens
and certain languages, these links might take too much space and not
look that great. This issue affects pretty much every place where we use
order or filter links, so we might revisit it in the future.

Note we're moving the links to order comments after the form to add a
new comment. In my opinion, having an element such as a form to add a
new comment between the element to select the desired order of the
comments and the comments themselves is a bit confusing.

[1] https://webaim.org/techniques/forms/controls#javascript
[2] https://www.w3.org/WAI/WCAG21/Understanding/on-input.html
[3] https://www.youtube.com/watch?v=CUkMCQR4TpY
[4] https://www.lukew.com/ff/entry.asp?1950
2021-06-28 00:08:18 +02:00
taitus
ee66c4182a Return error when the related content already exists
It looks like this bug was introduced in commit 7ca55c4. Before that
commit, a message saying "You added a new related content" was shown,
but (as expected) the related content wasn't added twice.

We now check this case and add a slightly clearer message.
2021-06-25 17:15:34 +02:00
Javi Martín
dae4aae328 Avoid rendenring an empty list in top links
We've had an accessibility error reported by the Spanish "Portal
Administración electrónica" (PAe). While I can't find any accessibility
rule saying empty lists should be avoided, it looks like some screen
readers report finding lists with 0 items, which is annoying.
2021-06-24 13:15:04 +02:00
Javi Martín
da76c848fc Avoid rendering an empty list in footer
We've had an accessibility error reported by the Spanish "Portal
Administración electrónica" (PAe). While I can't find any accessibility
rule saying empty lists should be avoided, it looks like some screen
readers report finding lists with 0 items, which is annoying.

We could also do it with CSS using `ul:empty { display: none}`. However,
at the time of writing no browser supports this rule when the tag
contains whitespace.
2021-06-24 13:15:03 +02:00
Javi Martín
7bc9aea2d1 Merge pull request #4564 from consul/related_content_custom_url
Fix related content with custom URLs
2021-06-24 12:37:20 +02:00
Javi Martín
71b6eda160 Merge pull request #4563 from consul/related_content_accessibility
Improve accessibility in form to add related content
2021-06-24 12:36:30 +02:00
Javi Martín
89a06ea6ef Fix related content with custom URLs
Some CONSUL installations might want to customize their URLs. For
instance, Spanish institutions might want to use "/propuestas" instead
of "/proposals". In that case, it would be impossible to add proposals
as related content because the related contents controller assumed the
name of the model was part of the URL.

Using `recognize_path` instead of manually analyzing the URL solves the
issue.

Now that we don't call the `constantize` method on an empty string as we
previously did, we can be more specific in the `rescue` block and point
out that the only exception we expect is the one where users enter a
route which isn't recognized.
2021-06-23 23:28:35 +02:00
Javi Martín
48dc72cea9 Avoid a brakeman warning in related contents
Although it wasn't a real security concern because we were only calling
a `find_by` method based on the user input, it's a good practice to
avoid using constants based on user parameters.

Since we don't use the `find_by` method anymore but we still need to
check the associated record exists, we're changing the validations in
the `RelatedContent` model to do exactly that.
2021-06-23 23:13:58 +02:00
Javi Martín
8f20ee1a33 Move related content validation to the model
We were manually checking validation rules (like both relationable
objects are present, or they're both the same object) in the controller
and then using the `save!` method.

However, we usually use the `save` method (which checks all validations)
in a condition, and proceed depending on the result.

Now we're taking the same approach here. This means introducing a new
validation rule in the model to check whether both relationable objects
are the same, which is more robust than checking a condition in the
controller.
2021-06-23 23:13:58 +02:00
Javi Martín
f298a308c2 Show actions to score related content to everyone
We were only showing these actions to users with small screens and to
mouse users on hover. Keyboard users or users with a touch screen of a
medium or large size could never find out the actions were there.
2021-06-23 23:06:24 +02:00
Javi Martín
49e0138cd1 Fix label in related content form
It didn't have a `for` attribute and so it wasn't correctly associated
with its input. That means clicking on / touching the label didn't have
the effect of focusing on the field, and screen readers wouldn't
announce the label.
2021-06-23 23:06:24 +02:00
Javi Martín
85215e7e97 Fix aria-expanded value in related content button
The button was announced as expanded when the form was hidden and as
collapsed when the form was shown.

This is because Foundation sets the expanded attribute based on whether
the class to toggle already exists. Since initially the form had the
"hide" class and the button toggled that class, Foundation checked that
the class was already present and so set the button as expanded.

So we're changing the toggler class for a class we don't use at all,
just so Foundation initiall sets `aria-expanded=false` and then changes
it to `aria-expanded=true` after the button is clicked. Then we're
ignoring this class completely and are styling this form with CSS
instead.

We could also use a toggler class like "visible" and write something
like:

```
.add-related-content + form:not(.visible) {
  display: none;
}
```

However, using ARIA attributes is more robust as it guarantees the
styles will always be in sync with what screen reader users experience.

And we could also remove all the Foundation toggler functionality and
use our own JavaScript to handle the button state. We might do so in the
future.
2021-06-23 23:06:24 +02:00
Javi Martín
f1221e9c1c Make relationable test expectations consistent
We're removing the parenthesis after page expectations (as we do almost
everywhere) and we're replacing `have_selector` with `have_css`, since
on that file we were using `have_css` everywhere except in one place.
2021-06-23 23:06:24 +02:00
Javi Martín
1632540984 Remove redundant placeholders in forms
Using placeholders having similar (or identical) text as already present
as a label has a few issues.

First, it's a distraction. Reading the same information twice is
useless, requires an extra effort, and might even frustrate users.

Second, if users start typing before reading the placeholder and see it
disappear, they might think they're missing relevant information,
delete what they typed, and read the placeholder. That will get them
nowhere.

Finally, we display placeholders using a text offering very low contrast
against the background, so users don't think the placeholder is an
actual value entered in the field. Using such low contrast makes the
text hard to read, particularly for users with visual impairments.

So we're removing these placeholders.

This commit only deals with placeholder texts with similar (or
identical) texts as the label text. There might be other places where we
should replace placeholder texts with labels, but that's a different
topic.
2021-06-23 19:52:45 +02:00
Javi Martín
8a697216d1 Fix invalid HTML in related content button
A button cannot be inside an anchor tag, and it might confuse some
browsers or screen readers.

We're also making it clear in the tests that the intention is to use a
button there by using `click_button` instead of `click_on` since the
latter also clicks on links.
2021-06-22 22:32:08 +02:00
Javi Martín
918276ec70 Merge pull request #4555 from consul/flaky_recount_spec
Fix flaky poll recount spec
2021-06-22 18:30:14 +02:00
Javi Martín
c6a459c115 Merge pull request #4558 from consul/featured_disabled
Respond with 403 when features are disabled
2021-06-17 15:39:12 +02:00
Javi Martín
59518846a8 Merge pull request #4554 from consul/flaky_hidden_spec
Fix flaky hidden budget investments spec
2021-06-17 15:34:22 +02:00
Javi Martín
5f747122c5 Don't assign IDs to user records in tests
This test will fail if the ID of the created record is the same as the
ID of the first user we create in the test. The chance is very low due
to the `rand(9999999)` which causes the test to fail just once every ten
million times. However, why assigning the ID in the first place? Without
it, the test will never fail due to conflicting IDs.
2021-06-17 01:46:48 +02:00
Javi Martín
433b465ec7 Don't assign IDs to assignment records in tests
The test "updates officer_assignment_id_log if amount changes" failed
when the ID we assigned when creating the records was the same as the ID
of the first officer assignment created during that test. It's recently
happened while running our test suite [1] with the following error:

```
1) Poll::Recount logging changes updates officer_assignment_id_log if
amount changes
  Failure/Error: poll_recount.officer_assignment =
                  create(:poll_officer_assignment, id: 101)

     ActiveRecord::RecordNotUnique:
       PG::UniqueViolation: ERROR:  duplicate key value violates unique
       constraint "poll_officer_assignments_pkey"
       DETAIL:  Key (id)=(101) already exists.
```

We're also removing the IDs in the "updates officer_assignment_id_log if
amount changes" test to avoid any possible issues, even if in this test
I think no other officer assignments are created and so there can't be
another record with the same ID.

[1] https://github.com/consul/consul/runs/2818889296
2021-06-17 01:46:48 +02:00
Javi Martín
7bb7548d00 Respond with 403 when features are disabled
When administrators disabled features and users tried to access them
with the browser, we were responding with a 500 "Internal Server Error"
page, which in my humble opinion was incorrect. There was no error at
all; the server worked exactly as expected.

I think a 403 "Forbidden" code is better; since that feature is
disabled, we're refusing to let users access it.

We could also respond with a 404 "Not found", although I wonder whether
that'll be confusing when administrators temporarily or accidentally
disable a feature.

A similar thing might happen if we responded with a 410 "Gone" code.
Actually this case might be more confusing since users aren't that
familiar with this code.

In any case, all these options are better than the 500 error.
2021-06-16 20:45:15 +02:00
decabeza
a851048d56 Allow users to remove their support on investments
Note we don't cast negative votes when users remove their support. That
way we provide compatibility for institutions who have implemented real
negative votes (in case there are / will be any), and we also keep the
database meaningful: it's not that users downvoted something; they
simply removed their upvote.

Co-Authored-By: Javi Martín <javim@elretirao.net>
Co-Authored-By: Julian Nicolas Herrero <microweb10@gmail.com>
2021-06-14 14:46:54 +02:00
Javi Martín
758cdaf8d7 Extract controllers to support investments
Since we're going to add an action to remove supports, having a separate
controller makes things easier.

Note there was a strange piece of code which assumed users were not
verified if they couldn't vote investments. Now the code is also
strange, since it assumes users are not verified if they can't create
votes. We might need to revisit these conditions if our logic changes in
the future.
2021-06-14 14:42:03 +02:00
Javi Martín
071da81be6 Add notice when supporting an investment
It was hard to notice what was going on when supporting one investment
which was at the bottom of the investment index page.

I wonder whether we should add the title of the investment to this text;
I'm not doing so because we don't do that anywhere else.
2021-06-14 14:42:03 +02:00
Javi Martín
5fab843184 Simplify managing investment votes
If I'm right, the `investment_votes` instance variable only exists to
avoid several database queries to get whether the current user has
supported each of the investments.

However, that doesn't make much sense when only one investment is shown.
In this case, the number of queries stays the same, and so we can
simplify the code by rendering the component with an optional parameter.
2021-06-14 14:41:51 +02:00
Javi Martín
d5f4313f59 Simplify getting URL to support an investment
We're also changing the method name to `vote_path` in order to be
consistent with the way Rails uses `_path` for relative URLs.
2021-06-14 14:38:34 +02:00
decabeza
b23fe300f5 Add supports info section on budgets index page 2021-06-14 13:48:44 +02:00