Commit Graph

137 Commits

Author SHA1 Message Date
Javi Martín
7154228fbb Move budget map icon tests back to system specs
These tests don't work without JavaScript. They were passing because the
`within` method always passes in component tests.

This reverts most of commit 822140a14.
2021-10-18 13:51:32 +02:00
Javi Martín
d7f26f012d Fix test checking link in budget header
The test was passing because we were using `within`, but actually the
`have_css` method doesn't support the `href:` argument.
2021-10-18 13:51:32 +02:00
Javi Martín
57fcdc402d Use page.find instead of within in component tests
In component tests, the `within` method is actually an alias to RSpec's
`be_within` matcher, which is used to test numeric ranges. That meant
the tests always passed, even when there were bugs on the page.

In order to use `within` in component tests, we have to use
`page.within`. However, that also fails, since there's no such method
for `Capybara::Node::Simple'` objects, which are used in component
tests.

So we're using `page.find` instead.

See also pull request 945 in https://github.com/github/view_component
2021-10-18 13:51:32 +02:00
Javi Martín
b35c8bda4b Move form field partial to a component
This way it's easier to test; changing it will also be easier.

During my experiments I made a mistake which wasn't covered by the test
suite. We're adding a test for this case.

Note we're using `i18n_content` in the component instead of `content`
because there's already a `content` method provided by ViewComponent.
2021-10-11 20:03:07 +02:00
Javi Martín
5c1a7044cd Hide comments when features are disabled
We were already doing so for debates and investments.

We probably never noticed because this is an edge case that requires
enabling a feature, people adding comments, and then disabling the
feature.
2021-10-05 14:43:47 +02:00
Javi Martín
3cd4f3827e Hide what users are following unless they allow it
It could be argued that seeing which proposals a user follows is a good
indicator of which proposals a user has supported, since we're
automatically creating follows for supported proposals since commit
74fbde09f. So now, we're extending the `public_interests` funcionality,
so it only shows elements users are following if they've enabled it.

This is an improvement over using the `public_activity` attribute in two
ways:

* The `public_interests` attribute is disabled by default, so by default
  other users won't be able to see what a user is following
* Who has created proposals/debates/investments/comments is public
  information, while who is following which elements is not; so enabling
  `public_activity` shouldn't imply potentially private information should
  be displayed as well

We've considered removing the `public_interests` attribute completely
and just hiding the "following" page for everyone except its owner, but
keeping it provides more compatibility with existing installations.
2021-10-05 14:43:09 +02:00
Javi Martín
adaa9c021f Merge pull request #4683 from consul/empty_sdg_tags
Don't render empty SDG tag list div
2021-10-04 16:07:28 +02:00
Javi Martín
c025fef50b Add short titles to SDG targets
Since targets didn't have a title but only a long description, every
form allowing to select targets was pretty much unusable: we either
displayed just the code or the whole description.

Now, with a concise title, it's easier to find and select the desired
target.

The titles have been copied from The Global Goals page [1].

Note we're using the `short_title` I18n key for the `title` method and
the `long_title` I18n key for the `long_title` method. We can't use
`title` as I18n key instead of `short_title` because it would affect
existing translations.

[1] https://www.globalgoals.org/
2021-10-01 16:19:10 +02:00
Javi Martín
391d1083e4 Don't render empty SDG tag list div
The same way we don't render empty regular tags since commit 4d27bbeba.

This way we avoid adding an empty `<div class="sdg-tag-list">` tag,
which might have associated styles (in custom CONSUL installation
styles, for instance) and thus break the layout
2021-10-01 13:54:30 +02:00
Javi Martín
8f2150d9db Add SDG Spanish icons in SVG format
Based on an EPS file downloaded from The Global Goals page [1].

Although in that page there are icons for other languages we support and
that we've only got in PNG format, the Spanish ones are the only ones
which are similar to the official PNG ones provided by the UN or
UN-related organizations like UNRIC. Icons in other languages (like
Chinese, French or Russian) are not that similar to the official PNG
icons and their quality is (in my humble opinion) lower.

Since SVG icons are smaller and can be compressed, users browsing the
page in Spanish will have to download about 80KB for the SDG icons,
instead of the 240KB they needed to download when using PNGs.

[1] https://www.globalgoals.org/resources
2021-09-30 15:06:50 +02:00
Javi Martín
3a2fb1a668 Add SDG English icons in SVG format
These icons have been downloaded from The Global Goals page [1]. English
is the official language of this page and the only one containing all
the information.

Since SVG icons are smaller and can be compressed, users browsing the
page in English will have to download about 45KB for the SDG icons,
instead of the 250KB they needed to download when using PNGs.

[1] https://globalgoals.org
2021-09-30 15:06:50 +02:00
Javi Martín
7b8e892f9c Use a switch to enable/disable homepage features
So it's consistent with the way we enable/disable other features.
2021-09-23 13:25:22 +02:00
Javi Martín
fabe97e506 Use a switch control to enable/disable features
We were using buttons with the "Enable" and "Disable" texts to
enable/disable settings. However, when machine learning settings were
introduced in commit 4d27bbeba, a switch control was introduced to
enable/disable them.

In order to keep the interface consistent, we're now using switch
controls in other sections where settings are enabled/disabled. We can
even use the same code in the machine learning settings as well.

We're also removing the confirmation dialog to enable/disable a setting,
since the dialog is really annoying when changing several settings and
this action can be undone immediately. The only setting which might need
a confirmation is the "Skip user verification" one; we might add it in
the future. Removing the confirmation here doesn't make things worse,
though; the "Are you sure?" confirmation dialog was also pretty useless
and users would most likely blindly accept it.

Note Capybara doesn't support finding a button by its `aria-labelledby`
atrribute. Ideally we'd write `click_button "Participatory budgeting"`
instead of `click_button "Yes"`, since from the user's point of view the
"Yes" or "No" texts aren't button labels but indicators of the status of
the setting. This makes the code a little brittle since tests would pass
even if the element referenced by `aria-labelledby` didn't exist.
2021-09-23 13:25:20 +02:00
Javi Martín
aaa5f6c285 Disable buttons in table actions when pressed
By default, Rails disables submit inputs (<input type="submit">) when
they're pressed so we avoid a double-submission when users click the
button twice.

However, Rails does not disable submit buttons (<button type="submit">)
when they're pressed. This means there's a chance users might press the
button several times. Even if most our table actions are idempotent, it
might cause certain issues. For instance, pressing the "Delete" button
twice means the second request might raise an
`ActiveRecord::RecordNotFound` exception.

Disabling the button also gives feedback to users, letting them know
they've correctly clicked the button.
2021-09-20 20:27:37 +02:00
Javi Martín
5311daadfe Use a button for non-GET table actions
Links acting like buttons have a few disadvantages.

First, screen readers will announce them as "links". Screen reader users
usually associate links with "things that get you somewhere" and buttons
with "things that perform an action". So when something like "Delete,
link" is announced, they'll probably think this is a link which will
take them to another page where they can delete a record.

Furthermore, the URL of the link for the "destroy" action might be the
same as the URL for the "show" action (only one is accessed with a
DELETE request and the other one with a GET request). That means screen
readers could announce the link like "Delete, visited link", which is
very confusing.

They also won't work when opening links in a new tab, since opening
links in a new tab always results in a GET request to the URL the link
points to.

Finally, submit buttons work without JavaScript enabled, so they'll work
even if the JavaScript in the page hasn't loaded (for whatever reason).

For all these reasons (and probably many more), using a button to send
forms is IMHO superior to using links.

There's one disadvantage, though. Using `button_to` we create a <form>
tag, which means we'll generate invalid HTML if the table is inside
another form. If we run into this issue, we need to use `button_tag`
with a `form` attribute and then generate a form somewhere else inside
the HTML (with `content_for`).

Note we're using `button_to` with a block so it generates a <button>
tag. Using it in a different way the text would result in an <input />
tag, and input elements can't have pseudocontent added via CSS.

The following code could be a starting point to use the `button_tag`
with a `form` attribute. One advantage of this approach is screen
readers wouldn't announce "leaving form" while navigating through these
buttons. However, it doesn't work in Internet Explorer.

```
ERB:

<% content_for(:hidden_content, form_tag(path, form_options) {}) %>
<%= button_tag text, button_options %>

Ruby:

def form_id
  path.gsub("/", "_")
end

def form_options
  { id: form_id, method: options[:method] }
end

def button_options
  html_options.except(:method).merge(form: form_id)
end

Layout:

<%= content_for :hidden_content %> # Right before the `</body>`
```
2021-09-20 20:27:37 +02:00
Javi Martín
6510cb9615 Add a more detailed confirmation message
The message "Are you sure?" is usually followed by blindly clicking
"Yes" without really thinking about what one is doing. So we're
including a bit more information about what's about to happen. That way
it's more likely users will notice it when they accidentally click the
wrong button.

Ideally we would offer the option to undo every common action and then
we wouldn't have to ask for confirmation. But since that isn't the case,
for now we're adding a better confirmation message.

Note we're removing the `resource_name` parameter from the translation
to confirm the action of deleting a record. The reason is, in many
languages it only makes sense to add the model name when it's got an
associated article, and, unlike in English (where "the" is used for
every word), that article is different depending on the noun it's
related to. So we'd have to provide a translation like "name with
article, when singular" for every model.

The complexity of these translations could scalate quickly. And, given
the context, IMHO it isn't essential to add the resouce name. When we're
in the proposals index and there's a proposal named "Improve XYZ", and
we click on "Delete" and see a message saying "This action will delete
XYZ", it is implied that XYZ is a proposal.

So instead we're changing the message so it works for every record with
no need of noun-dependent articles.
2021-09-20 20:27:37 +02:00
Javi Martín
2b4b2f3442 Use aria-label in admin table actions
This way screen reader users will know which record they're going to
access when focusing on a link to a certain action. Otherwise they'd
hear something like "Edit, link", and they wouldn't know which record
they'll end up editing if they follow the link.
2021-09-20 20:27:37 +02:00
Javi Martín
6a2c01b119 Extract method to render an admin table action
This way it will be easier to change the behavior of all table actions,
like adding ARIA attributes. In the past, when we changed the behavior
of the `link_to` method, we had to change all table action classes.
2021-09-20 20:27:37 +02:00
Javi Martín
81c836fb9f Remove unneeded sign in tag list component
We don't need to sign in as administrator in order to see the tags;
anyone can see them.
2021-09-08 12:39:36 +02:00
Javi Martín
9247a31e85 Stub current_user in all component tests
The `sign_in(nil)` method was a bit hard to understand IMHO. After all,
in controller and system tests we don't have to specify no user is
signed in; that's the default behavior.

So we're making it the default behavior for component tests as well.
2021-09-08 12:39:36 +02:00
Javi Martín
e97c375063 Add method to stub current_user in component tests
We're choosing `sign_in` instead of `login_as` because IMHO component
tests are more similar to controller tests than they are to system
tests.
2021-09-08 12:39:36 +02:00
Javi Martín
4cbf945228 Infer type for component specs automatically 2021-09-08 12:39:36 +02:00
Javi Martín
65c9786db7 Apply Layout/RedundantLineBreak rule to short lines
We're not adding the rule because it would apply the current line length
rule of 110 characters per line. We still haven't decided whether we'll
keep that rule or make lines shorter so they're easier to read,
particularly when vertically splitting the editor window.

So, for now, I'm applying the rule to lines which are about 90
characters long.
2021-09-03 11:49:53 +02:00
Machine Learning
4d27bbebad Add experimental machine learning 2021-08-16 16:31:04 +02:00
Javi Martín
a9095d1b6a Simplify component test stubbing controller path
This is possible due to the changes in commit 6df7f7d05.
2021-08-12 23:00:02 +02:00
Javi Martín
5f19d73b40 Use with_request_url in component specs
This method is available since view component 2.31.0, and greatly
simplifies tests depending on the current URL.
2021-08-12 22:58:29 +02:00
Javi Martín
6df7f7d052 Simplify changing controllers in component tests 2021-08-10 15:00:26 +02:00
decabeza
4a9aae9806 Add groups index page
When render the investment list component with the link "see all
investments", now we redirect to groups index page when a budget has
multiple headings.
2021-08-09 21:45:29 +02:00
taitus
c6b23bb6fa Render investments list in all budgets types
We make this change to unify the index/show budget pages.

This way both single and multiple budgets will render the investments
list component.
2021-08-09 20:07:51 +02:00
Javi Martín
f92796c7fa Move list of investments tests to component tests
In general, slow system tests requiring no interaction from the user are
good candidates to be moved to component tests because component tests
are much faster.

In this case, the system tests were also updating the database after
starting the browser, which might cause concurrency issues. We could
split the test and have one system test per phase, but IMHO there's no
need.

We're still having a couple of system tests for the happy path, in order
to make sure users actually see the list of investments.
2021-08-09 20:07:50 +02:00
Javi Martín
d39c46468a Fix typo in investments list spec 2021-08-09 19:46:40 +02:00
Javi Martín
62ca762587 Only show terms acceptance on new investment form
No need to accept the terms when updating the investment.
2021-07-09 14:25:18 +02:00
Javi Martín
1f10afac64 Simplify language selection with a few languages
As mentioned in commit 5214d89c8, using the `change` event of a `select`
field to automatically change location is really annoying for keyboard
users, since the event will trigger when pressing the down key to
navigate through the options or when typing a key to start searching for
an option. This might cause a lot of frustration.

Most multilanguage CONSUL sites enable between 2 and 4 languages. In
these cases, it's easier to just display the list of languages to
simplify the selection.

This way in this situation we also make it clear which languages are
available. If we use a `<select>` tag, users will have to open it in
order to check whether the site is available in their preferred
language.

This is also useful when the current language uses characters users
don't recognize; users will recognize their own language in the list of
available languages, while it might be harder to recognize the language
selector allows them to switch to a different language.

In this case, we're also hiding the label because a list of links with
language names is usually self explanatory for sighted users. We're
still providing it for screen reader users so they immediately know the
list allows them to change the language and if they don't need to do so
they can quickly skip it.
2021-07-05 22:27:39 +02:00
Javi Martín
ff0f2215ea Extract component for locale switcher
Note that in order to simplify the component tests (which for some
reason seem to be whitespace-sensitive), we have to omit whitespace
characters inside the `<option>` tags.

Also note we're simplifying the test with a missing language name; since
a component test doesn't involve a whole request, we don't need a
complex setup (I'm not sure we even need it in system tests).
2021-07-05 22:27:39 +02:00
Javi Martín
7abca09e03 Extract methods in link list component
Since we're simplifying the main method, we can use a view file instead
of the `call` method. This way we make the code more consistent with the
rest of our components, since we always use a separate file.

Doing so generates an extra newline at the end of the generated HTML, so
we need to change a couple of tests a little bit.
2021-07-05 22:27:39 +02:00
Javi Martín
d0243764a2 Extract component to render a list of links
This way it's easier to refactor it and/or change it.

Back in commit c156621a4 I wrote:

> Generally speaking, I'm not a big fan of helpers, but there are
> methods which IMHO qualify as helpers when (...) many Rails helpers,
> like `tag`, follow these principles.

It's time to modify these criteria a little bit. In some situations,
it's great to have a helper method so it can be easily used in view
(like `link_to`). However, from the maintenance point of view, helper
methods are usually messy because extracting methods requires making
sure there isn't another helper method with that name.

So we can use the best part of these worlds and provide a helper so it
can be easily called from the view, but internally make that helper
render a component and enjoy the advantages associated with using an
isolated Ruby class.
2021-07-05 22:27:39 +02:00
Javi Martín
e4f8f702c7 Use a submit button in admin poll question filters
As mentioned in commit 5214d89c8, using a `<select>` tag which
automatically submits a form on change has a few accessibility issues,
particularly for keyboard users who might accidentally submit the form
while browsing the options.

So we're adding a submit button and removing the "submit on change"
behavior.

Note that, while `<select>` tags have their own usability issues,
alternatives in this case are not obvious because the number of existing
polls could be very low (zero, for instance) or very high (dozens, if
the application has been used for years).

I thought of using a `<datalist>` tag with a regular text input. The
problem here is we don't want to send the name of the poll to the server
(as we would with a `<datalist>` tag); we want to send the ID of the
poll.

Maybe we could add an automplete field instead, providing a similar
funcionality. However, for now we're keeping it simple. This poll
questions page isn't even accessible through the admin menu since commit
83e8d603, so right now anything we change here will be pretty much
useless.
2021-06-30 17:56:47 +02:00
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
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
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
d8d5b7f60a Extract budget executions filters to a component 2021-06-29 20:07:55 +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
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
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
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
Javi Martín
bb958daf05 Replace support investment link with a button
Using links combined with JavaScript to generate POST requests to the
browser has a few issues.

An obvious one is that it doesn't work for users without JavaScript
enabled (which lately I've noticed are more common than I thought, even
though I've been one of them for years). These users will reach a 404
page.

Since CONSUL isn't currently designed to work without JavaScript
enabled, let's ignore this one for now.

A not so obvious issue is screen reader users might expect the link to
take them somewhere instead of performing an action (in this case,
sending a form to the server).

There might be more issues I'm unaware of. Quoting DHH [1]:

"Turning ahrefs into POSTs is a bit of an anti-pattern, especially for
a11y reasons. Better to use button_to with a styling."

So we're using a button instead. This way we can also simplify the code
and make the button disabled for unidentified users, which automatically
makes it impossible to focus it using the keyboard.

A possible disadvantage of using `button_to` is it will create a form
tag which will be announced to screen readers as a form landmark. I've
tested it with my screen reader and everything worked fine for me, but
some screen reader users might interact with these forms in a different
way and find it confusing, particularly in the case where the button is
disabled.

With this change, we're only changing links for buttons in one place.
There are other places where we should do similar changes.

[1] See issue 33 in https://github.com/hotwired/turbo-rails/
2021-06-14 12:51:41 +02:00