The interface was a bit confusing, since after clicking on "See
unfeasible investments" (or similar), we were on a page where no
investments were shown.
Besides, since commit 7e3dd47d5, the group page is only linked from the
"my ballot" page, through a link inviting the user to vote in that
group, and it's only possible to vote selected investments (which is the
default filter during the final voting phase).
The only reason we had these links here was these links weren't present
in the investments page. But they're present there since commit
04605d5d5, so we don't need them in the group page anymore.
As mentioned in commit bc0f04075, a <select> field which submits its
form on change causes many accessibility and usability issues. In this
case there was also an incompatibility with the advanced search filter
which caused a bug solved in commit 541a5fa89.
So the question is where to position the filters and how to display
them. One factor to take into the account is how relevant these filters
are, particularly compared to the links to select the prefered order,
since we don't usually give users the choice of both filters and orders.
Our filters don't really make sense until the valuation phase starts,
since before that phase investments aren't selected nor their
feasibility is decided.
After that phase, the only phase where citizens are really involved
is the final voting; the rest of the phases are done by valuators and
administrators. In the final voting, citizens can only vote on selected
projects, and that's the default filter during that phase.
So these filters are mainly there for information purposes, and not to
help citizens in the phases where they're actually involved (accepting
projects, selecting projects and balloting).
Orders, on the other hand, play a crucial role during the final voting
phase. Since citizens might have already voted for a few projects and
have, let's say, 100,000€ left, ordering by price allows them to find
which projects are within their remaining budget.
In conclusion, orders are more important than filters, and so they
should have a more prominent place.
For consistency with the proposals section, where we've got some links
in the sidebar (bottom part of the page on small screens) providing a
similar funcionality, like accessing selected proposals or archived or
retired proposals, we're moving the investments filters to the sidebar
(bottom part of the page on small screens) as well.
Before, users needed to navigate to the list of groups in order to
add, edit or delete a group.
Also, they need to navigate to the list of groups first, and then to
the list of headings for that group in order to add, edit or delete a
heading.
Now, it's possible to do all these actions for any group or heading
from the participatory budget view to bring simplicity and to reduce
the number of clicks from a user perspective.
Co-Authored-By: Javi Martín <javim@elretirao.net>
In the past it would have been confusing to add a way to directly
enable/disable a phase in the phases table because it was in the middle
of the form. So we would have had next to each other controls that don't
do anything until the form is sent and controls which modify the
database immediately. That's why we couldn't add the checkboxes we used
when using the wizard.
Now the phases aren't on the same page as the budget form, so we can
edit them independently. We're using a switch, so it's consistent with
the way we enable/disable features. We could have used checkboxes, but
with checkboxes, users expect they aren't changing anything until they
click on a button to send the form, so we'd have to add a button, and it
might be missed since we're going to add "buttons" for headings and
groups to this page which won't send a form but will be links.
Since we're changing the element with JavaScript after an AJAX call, we
need a way to find the button we're changing. The easiest way is adding
an ID attribute to all admin actions buttons/links.
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.
Note we're keeping this section's original design (which had one button
to add a new group which after being pressed was replaced by a button to
cancel) but we aren't using Foundation's `data-toggle` because there
were a couple of usability and accessibility issues.
First, using `data-toggle` multiple times and applying it to multiple
elements led to the "cancel" button not being available after submitting
a form with errors. Fixing it made the code more complicated.
Second, the "Add new group" button always had the `aria-expanded`
attribute set to "true", so my screen reader was announcing the button
as expanded even when it wasn't. I didn't manage to fix it using
`data-toggle`.
Finally, after pressing either the "Add new group" and "Cancel" buttons,
the keyboard focus was lost since the elements disappeared.
So we're simplifying the HTML and adding some custom JavaScript to be
able to handle the focus and manually setting the `aria-expanded`
attribute.
Co-Authored-By: Javi Martín <javim@elretirao.net>
Co-Authored-By: Julian Herrero <microweb10@gmail.com>
We weren't using the "Feasible" filter anywhere in the
application, and it's hard for users to know the difference between
"Feasible" and "Not unfeasible".
Apart from 'balloting', there are more phases between
'publishing_prices' and 'finished'. So, it doesn't make sense that the
filter 'selected' is only applied to those two. With this change the
filter will be applied as follow:
'not_unfeasible' for phases:
- informing
- accepting
- reviewing
- selecting
- valuating
selected for phases:
- publishing_prices
- balloting
- reviewing_ballots
winners for phases:
- finished
We were defining the same filters in three different controllers. We
were also adding a method in the ApplicationController which only made
sense in the same three controllers.
Now the banner component accepts either a banner or a section and loads
the banner if it's a section, so we don't have to add the `@banners`
variable in several controllers.
We use a different logic to load the card depending on the controller
we're using, and then share the rest of the code. This way we simplify
the code a bit, since we don't have to check for the page_id parameter.
Ruby 2.6 introduces `Enumerable#filter` as an alias to
`Enumerable#select`, and so our Filterable.filter method will not work
with Ruby 2.6.
So we're renaming the method to `filter_by`, which is similar to
`find_by`. We could also change the `filter` method so if a block is
given it delegates to `Enumerable#filter`, the same way ActiveRecord
handles the `select` method, but IMHO this is easier to follow.
We were treating legislation proposals as if they were proposals,
omitting the "legislation" namespace, and so we were flagging/unflagging
proposals when we wanted to flag/unflag a legislation proposal.
The `respond_with` method is no longer part of Rails (it's now part of
the responders gem) and we barely use it. Using a template forced us to
use different criteria for different controllers.
This change will also make it easier to fix the flag/unflag actions for
legislation proposals. With the old code, we would have to add another
condition for the legislation/proposals controller.
This filter was added in commit 4285ba4b, it was changed in commit
002d8688, and most of the code from the original commit has disappeared
without a trace (maybe due to a merge conflict?).
This filter could actually be useful if we started using it when users
click on a tag. Since we don't, I'm removing it. We might add it back if
we decide to actually use it.
Legislation::Proposal is not Globalize model but use CommentableActions and try
detect remote translations. Add new condition to discard Non Globalize models.
This fix is necessary since the following commit was included: c1f3a4ad.
Creating more than 25 records isn't necessary to test pagination; we can
stub the number of records per page in a test.
On my machine we save about one second per test with these changes.
The new CSV report was more configurable and could work on proposals,
processes and comments. However, it had several issues.
In the public area, by default it generated a blank file.
In the admin section, the report was hard to configure and it generated
a file with less quality than the old system.
So until we improve this system, we're bringing back the old investment
CSV exporter.
This commit reverts most of commit 9d1ca3bf.
We were inconsistent on this one. I consider it particularly useful when
a method starts with a `return` statement.
In other cases, we probably shouldn't have a guard rule in the middle of
a method in any case, but that's a different refactoring.
We were very inconsistent regarding these rules.
Personally I prefer no empty lines around blocks, clases, etc... as
recommended by the Ruby style guide [1], and they're the default values
in rubocop, so those are the settings I'm applying.
The exception is the `private` access modifier, since we were leaving
empty lines around it most of the time. That's the default rubocop rule
as well. Personally I don't have a strong preference about this one.
[1] https://rubystyle.guide/#empty-lines-around-bodies
In general, we always use relative URLs (using `_path`), but sometimes
we were accidentally using absolute URLs (using `_url`). It's been
reported i might cause some isuses if accepting both HTTP and HTTPS
connections, although we've never seen the case.
In any case, this change makes the code more consistent and makes the
generated HTML cleaner.
Moderate legislation proposals
- added a controller for moderation/legislation
- updated view to appropriate link + added route
- added a spec
- Feature test
- test for faded
- javascripts for visual effects
The code `where(id: ids)` is equivalent to `where(id: ids.uniq)`.
Since Rails 5 uses `distinct` instead of `uniq` and in most cases where
we use `uniq` with `pluck` we should simply remove the `uniq` call (as
done in this commit), we're also removing the `Rails/UniqBeforePluck`
rubocop rule.
The statement executed the method twice if the `present?` condition was
true. If the condition was false, it executed it once anyway.
It's probably a typo and originally we probably meant we wanted to
execute the method if the method existed.