Commit Graph

9884 Commits

Author SHA1 Message Date
Javi Martín
463112c2ea Use a switch to toggle investment selection
Just like it happened with proposals, the button to select/deselect an
investment wasn't very intuitive; for example, it wasn't obvious that
pressing a button saying "selected" would deselect the investment.

So we're using a switch control, like we do to enable/disable features
since commit fabe97e50.

Note that we're making the text of the switch smaller than in other
places because the text in the investments table it is also smaller
(we're using `font-size: inherit` for that purpose). That made the
button look weird because we were using rems instead of ems for the
width of the button, so we're adjusting that as well.

Also note we're changing the width of the switch to `6em` instead of
`6.25em` (which would be 100px if 1em is 16px). We're doing so because
we used 100 for the minimum width because it's a round number, so
now we're using another round number.
2024-10-28 13:40:27 +01:00
Javi Martín
f72daff71f Simplify JavaScript to toggle investment selection
We don't need to replace the whole row, since the changes only affect
the button. Therefore, we don't need to depend on an `inserted` event to
decide which columns to render in that row.
2024-10-28 13:39:49 +01:00
Javi Martín
9e5566cee4 Use a button to toggle investment selection
As mentioned in commit 5311daadf, using buttons for non-GET requests has
several advantages over using links.
2024-10-28 13:39:49 +01:00
Javi Martín
cf0d8258ed Use abilities to allow toggling investment selection
We were checking it in the view, meaning that it was possible to toggle
the selection by sending a custom request even when the investment
wasn't feasible.
2024-10-28 13:39:49 +01:00
Javi Martín
95f36ed52f Simplify code to toggle investment selection
This way it'll be easier to change the link/button used to toggle the
selection.

Note that the conditions in the view seem to be different because we no
longer include the `selected?` condition when rendering the link/button.
However, an investment can only be selected if it's feasible and its
valuation is finished, so writing something like this would have been
redundant:

```ruby
can?(:toggle_selection, investment) &&
  (selected? || investment.feasible? && investment.valuation_finished?)
```

The reason why the previous code was using the `selected?` condition was
to check whether to render the link/button to select or to deselect an
investment. We're now doing that in the Ruby part of the component.
2024-10-28 13:39:42 +01:00
Javi Martín
c78494c100 Extract method to get toggle selection path
This way we simplify the view code.

Since now we only use the `budget` method in one place, we're removing
it.
2024-10-28 13:37:56 +01:00
Javi Martín
fde24870bc Extract component for investment toggle selection
This way it'll be easier to refactor it.
2024-10-28 13:31:34 +01:00
Javi Martín
b9c3e75930 Fix duplicate HTML IDs in investments selection
Since this cell is shown once per row, there were multiple rows with the
same HTML ID on the page.
2024-10-25 17:24:32 +02:00
Javi Martín
73166e164b Simplify HTML for an investment row
Since we define the `data-field` element, we can style each element
individually with CSS.

I'm not sure whether these styles make sense, though. For instance, why
is "Supports" aligned to the center, since it's a number? For now, we're
leaving it as it was.
2024-10-25 17:24:32 +02:00
Javi Martín
607dabbc8a Move admin investments partial to a component
This way it'll be easier to organize the code related to it.
2024-10-25 17:24:32 +02:00
Javi Martín
e4df6426c2 Remove unused JavaScript view in investments admin
This code isn't used since commit c9f31b8e1.

Since we no longer depend on the content of the `#investments` element
being in a separate partial, we're also moving this element to the
partial itself and adding an HTML class to it, like we usually do.

We're also removing the code that loads all the investments in the
`toggle_selection` action, which wasn't needed since commit 3278b3572,
when we stopped rendering all the investments in this action.
2024-10-25 17:24:29 +02:00
Javi Martín
9330cdb304 Extract methods in investment row component
This way we simplify the code a little bit.
2024-10-25 17:19:52 +02:00
Javi Martín
bb42809168 Move investment partial to a component
This way we'll be able to simplify it a little bit.

Note that the original partial didn't include the whole row and only
the cells. Since, most of the time, we include the whole row in
partials, we're slightly modifying the component.
2024-10-25 17:19:42 +02:00
Javi Martín
02b6302f25 Focus the proposal selection switch after pressing it
Since this button is replaced by a new element in an AJAX call, nothing
was focused after pressing it.

So we're reusing the code we used to enable/disable budget phases, which
already dealt with this issue.
2024-10-25 17:15:40 +02:00
Javi Martín
2acaa14705 Make it possible to select proposals without JavaScript
This way, when JavaScript hasn't loaded (for whatever reason),
administrators can still use this functionality.
2024-10-25 17:12:47 +02:00
Javi Martín
4a2fc50c76 Use separate actions to select/deselect proposals
This is consistent to what we usually do. Also, we're applying the same
criteria mentioned in commit 72704d776:

> We're also making these actions idempotent, so sending many requests
> to the same action will get the same result, which wasn't the case
> with the `toggle` action. Although it's a low probability case, the
> `toggle` action could result in [selecting a proposal] when trying to
> [deselect] it if someone else has [deselected it] it between the time
> the page loaded and the time the admin clicked on the "[Selected]"
> button.
2024-10-25 17:12:47 +02:00
Javi Martín
fec44c146c Use a switch to toggle proposal selection
The button to select/deselect a proposal wasn't very intuitive; for
example, it wasn't obvious that pressing a button saying "selected"
would deselect the proposal.

So we're using a switch control, like we do to enable/disable features
since commit fabe97e50.
2024-10-25 17:12:44 +02:00
Javi Martín
b127bd2f51 Use a button to toggle proposal selection
As mentioned in commit 5311daadf, using buttons for non-GET requests has
several advantages over using links.
2024-10-25 17:10:14 +02:00
Javi Martín
43b6ab00e3 Simplify method to get the toggle selection path 2024-10-25 16:40:34 +02:00
Javi Martín
3febe3f0cc Extract methods in toggle selection component 2024-10-25 16:40:34 +02:00
Javi Martín
3cebce9a29 Extract link to toggle selection to a component 2024-10-25 16:40:32 +02:00
taitus
64e9d28479 Release version 2.2.2 2024-10-15 16:11:09 +02:00
Javi Martín
b870e29170 Disable turbolinks previews in the test environment
When clicking the browser's back button, browsers usually don't reload
the page but show a cached version of the page.

Turbolinks takes this one step further. When clicking on a link to a
page that's already cached, turbolinks displays the cached version of
the page and then it reloads it.

I don't really like this behavior but, since it affects the whole
application and we're about to release a patch version :), for now we're
keeping it this way in the development and production environments.

In the test environment, however, we're disabling these previews because
they might lead to requests leaking between tests.

For example, a test that visits the investments index, then goes to
"check my votes", then clicks on "Go back" and finishes by checking some
content on this page will result in those checks being done against the
cached version of the page. If these checks pass before turbolinks
reloads the page, the "Go back" request will finish during the test that
runs immediately after this one, resulting in unpredictable results.

Disabling the previews solves the issue.
2024-10-15 14:44:26 +02:00
taitus
93189d3ecd Allow use embedded_video_component in legislation proposals
Since the PR "Do not use third-party cookies in embedded videos #5548", the logic from
"embed_videos_helper" was extracted to the "embedded_video_component" and the
"videoable" model concern.

However, during this refactor, the "regex" method, which uses record.class:: to handle
video embeds, was left inaccessible for Legislation Proposals.

This commit fixes the issue by including the concern in the Legislation Proposal model.
2024-10-14 15:24:29 +02:00
Sebastia
d3a039040c Merge pull request #5722 from consuldemocracy/dependabot/bundler/rubocop-rails-2.26.2
Bump rubocop-rails from 2.25.1 to 2.26.2
2024-10-10 15:03:08 +02:00
taitus
29df39b2fa Add an apply Rails/CompactBlank rubocop rule
In rubocop-rails 2.26.0, the Rails/CompactBlank rule was modified to handle
cases where select(&:present?) is used. After identifying three occurrences
in our code, we've decided to apply this rule as it encourages the use of the
more efficient and clearer method, compact_blank.

By using compact_blank, we improve code clarity and performance, as this method performs the same operation but in a more optimized way.
2024-10-10 10:02:22 +02:00
taitus
c50452aec6 Add and apply Rails/EnumHash rubocop rule
In rubocop-rails 2.26.0, support was added for Rails 7 syntax in the
Rails/EnumHash rule. We took this opportunity to ensure consistency
by converting all enums to hash with integer values. This format minimizes
the risk of data consistency issues in the database when adding new values.
2024-10-10 09:56:44 +02:00
taitus
3d4f78a424 Add an apply Rails/EnumSyntax rubocop rule
This rule was added in rubocop-rails 2.26.0. Applying it allows
us to anticipate the deprecation of the current enum syntax
using keyword arguments, which is set to be removed in Rails
8.0, as mentioned in the rule's own documentation:

https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsenumsyntax
2024-10-10 09:55:48 +02:00
taitus
4dcac5bed5 Add and apply Naming/RescuedExceptionsVariableName rubocop rule
This rule was introduced in RuboCop 0.67.2, but now after seeing a fix in version 1.65.1,
we have decided to add it. The reason for adding it is to ensure consistency in how we
reference exceptions throughout the project, by following a standard naming convention
for exception variables.
2024-10-10 09:47:47 +02:00
taitus
6b15a073a2 Add and apply Style/RedundantRegexpArgument RuboCop rule
This rule was introduced in RuboCop 1.53.0. After adding the
Style/RedundantRegexpCharacterClass rule in the previous commit,
RuboCop started detecting redundant regular expression arguments.
Therefore, we apply this rule to remove them and prevent future
occurrences.
2024-10-10 09:47:47 +02:00
taitus
d94eed8628 Add and apply Style/RedundantRegexpCharacterClass rubocop rule
This rule was introduced in RuboCop 0.93.0, but now after seeing a fix in version 1.65,
we have decided to add it. The reason for adding it is to simplify our regular
expressions. This enforcement will help us maintain better regular expression
practices across the project.
2024-10-09 09:33:35 +02:00
taitus
2408caf9da Release version 2.2.1 2024-10-03 20:04:22 +02:00
Javi Martín
5f80a75161 Limit GraphQL queries complexity once again
We accidentally removed the code for maximum complexity in commit
c984e666f. As mentioned in the documentation:

> The main risk factor is multiple collections of resources being
> requested in the same query.

We reject these requests by limiting the complexity.

The `max_complexity` option depends on the page size being set. Without
it, we get an error:

```
Can't calculate complexity for User.public_debates, no `first:`,
`last:`, `max_page_size` or `default_max_page_size`
```

So we're also adding a default max page size.

Note that the documentation mentioned that the default page size was 25.
However, before commit c984e666f, we were using a page size of 50 in
some cases. We're going with the one mentioned in the documentation
since we don't fully understand the old code.
2024-09-30 12:06:42 +02:00
Javi Martín
90bb7484a5 Add max_depth limit to GraphQL queries once again
We accidentally removed this code in commit c984e666f. As mentioned in
our GraphQL documentation, limiting the depth of the queries helps
against DoS attacks.
2024-09-30 11:52:39 +02:00
Javi Martín
b01364d26b Make sure we only return public records in the API
When returning a collection of records in the API, we were making sure
we only returned public ones. However, when returning individual
records, we were not checking that.

In practice, this wasn't a big issue, since most `public_for_api`
methods return all records, but it could affect Consul Democracy
installations which might have customized their `public_for_api` method.
The only exception was the `budget` method, since it was returning
budgets that were still in drafting.
2024-09-30 11:35:15 +02:00
cyrillefr
18323a36c3 Add new GraphQL type for milestones
- added the milestone type to be displayed with investments
- the corresponding spec
2024-09-30 11:14:01 +02:00
cyrillefr
5ec6337d47 Add new GraphQL types for budget investments
- added 2 new types
- modified the models to get data through graphQL
- modified the corresponding spec
- also testing that hidden comments do not show up
- modified comments specs bc now it returns comments on budget
  investments
2024-09-30 11:14:01 +02:00
Javi Martín
ced834200a Update documentation to customize JavaScript
Note that, while it doesn't really affect the way the application
behaves (as long as the JavaScript code doesn't rely on the order it's
loaded) we're requiring `app/assets/javascripts/custom.js` after
requiring any files in the `app/assets/javascripts/custom/` folder. This
is done for consistency, since we load the content of
`app/assets/javascripts/application.js` after requiring everything else.
2024-09-10 14:29:51 +02:00
Javi Martín
8663778245 Add missing folders for custom code
We were loading these folders in `application.rb`, but they didn't exist
by default.
2024-09-02 15:03:24 +02:00
Javi Martín
00c97ad587 Split polls date range validation
It was a bit strange to leave the end date blank and have a message
associated with the start date, so we're using presence validations
instead.

For the range validation, we're using the comparison validator included
in Rails 7.0.
2024-07-22 18:35:35 +02:00
Javi Martín
da86254fe5 Use comparison validation to validate dates
The `validates_comparison_of` method was added in Rails 7.0.

We aren't changing the `date_range` validation in polls yet because it's
a bit complex; we'll do it in the next commit.
2024-07-22 18:35:35 +02:00
Javi Martín
f8f6844ec3 Simplify common HTML attributes using tag.attributes
The `tag.attributes` method was introduced in Rails 7.0.
2024-07-22 18:35:35 +02:00
Javi Martín
1b18151941 Use minimum and maximum in enumerables
While the `minimum` and `maximum` methods have been available for a long
time for ActiveRecord relations, Rails 7.0 has added these methods for
enumerables as well.

This means that the `start_date` and `end_date` methods in the
ShiftsHelper can use `minimum` and `maximum` no matter whether they
receive an ActiveRecord relation or an array of polls (I think the
latter never happens, though, but I'm not 100% sure).
2024-07-22 18:35:35 +02:00
Javi Martín
38ad65605e Use excluding instead of where.not(id:
This method was added in Rails 7.0 and makes the code slihgtly more
readable.

The downside is that it generates two queries instead of one, so it
might generate some confusion when debugging SQL queries. Its impact on
performance is probably negligible.
2024-07-22 18:35:35 +02:00
Javi Martín
9841a9b03a Use in_order_of to sort translations by fallback
This method was introduced in Rails 7.0, and thanks to it we can
simplify the code that gets the translations in order.

We tried to use this method to simplify the `Randomizable` concern as
well. However, we found out that, when ordering tens of thousands of
records, the query could take several minutes, so we aren't using it in
this case. Using it for translation fallbacks is OK, since there's a
good chance we're never going to have tens of thousands of available
locales.

Note that automated security tools reported a false positive related to
SQL Injection due to the way we used `LEFT JOIN`, so now we get one less
false positive in these reports.
2024-07-22 17:50:40 +02:00
Javi Martín
2ccf725815 Add properties-alphabetical-order Stylelint rule
We hadn't added this rule before because there was no such rule in
scss-lint. Instead, we were following it without a linter, and so we
unintentionally broke it sometimes.

But now we're using Stylelint, so we can add the rule and let the linter
check we're still following it.
2024-07-22 17:34:08 +02:00
Javi Martín
16315e14d2 Add and apply Style/SuperArguments rubocop rule
This rule was added in rubocop 1.64.0.

For clarity, in order to make it obvious that we're modifying the object
we received, we're excluding the Ahoy initializer, whose code was copied
from the Ahoy documentation.

We're also changing the `Types::BaseObject` class so we don't use a
variable with the same name as the parameter and we don't get a false
positive for this rule.
2024-07-09 11:23:02 +02:00
Javi Martín
46dc4a3163 Add and apply Style/MapIntoArray rubocop rule
This rule was added in rubocop 1.63.0.
2024-07-09 11:23:02 +02:00
Javi Martín
2abe9f27b5 Use ranges instead of comparisons in SQL queries
These cases aren't covered by the `Rails/WhereRange` rubocop rule, but
IMHO using ranges makes them more consistent. Besides, they generate SQL
which is more consistent with what Rails usually generates. For example,
`Poll.where("starts_at <= :time and ends_at >= :time", time:
Time.current)` generates:

```
SELECT \"polls\".\"id\", (...) WHERE \"polls\".\"hidden_at\" IS NULL AND
(starts_at <= '2024-07-(...)' and ends_at >= '2024-07-(...)')
```

And `Poll.where(starts_at: ..Time.current, ends_at: Time.current..)`
generates:

```
SELECT \"polls\".\"id\", (...) WHERE \"polls\".\"hidden_at\" IS NULL AND
\"polls\".\"starts_at\" <= '2024-07-(...)' AND \"polls\".\"ends_at\" >=
'2024-07-(...)'"
```

Note that the `not_archived` scope in proposals slightly changes, since
we were using `>` and now we use the equivalent of `>=`. However, since
the `created_at` field is a time, this will only mean that a proposal
will be archived about one microsecond later.

For consistency, we're also changing the `archived` scope, so a proposal
is never archived and not archived at the same time (not even for a
microsecond).
2024-07-05 17:24:56 +02:00
Javi Martín
fb0c087f95 Add and apply Rails/WhereRange rubocop rule
This rule was added in rubocop-rails 2.25.0. Applying it allows us to
simplify the code a little bit. For example, now there's no need to
specify the `proposals` table in proposal scopes, which was actually
causing a bug in the `Legislation::Proposal` model, which was using the
`proposals` table instead of the `legislation_proposals` table (but,
since we don't use this scope, it didn't affect the application).
2024-07-05 17:11:29 +02:00