Commit Graph

5814 Commits

Author SHA1 Message Date
taitus
e662c704ac Vendor Foundation form builder to remove gem dependency
The "foundation_rails_helper" gem is no longer maintained and is
incompatible with Rails 7.1. To avoid blocking the upgrade, we've vendored
the vendor/foundation_rails_helper/form_builder.rb as a copy of the
original FormBuilder class.

To mantain compatibility with auto_labels and button_class variables, that
are used in the original builder, we are overwriting in the foundation
form builder initializer.

The gem has been removed from the Gemfile and replaced with this vendored
fallback. This workaround is safe to remove once legacy Foundation CSS
support is dropped.

All vendored code retains the original MIT license and attribution.
2025-05-06 17:07:08 +02:00
taitus
b07e429356 Remove monkey patch for connected_to in Rails 7
ros-apartment 3.0.0+ includes official support for connection handling in Rails 7,
so we no longer need to override `ActiveRecord::ConnectionHandling#connected_to`.

References: PR #194 and #243 in ros-apartment
2025-04-11 15:41:59 +02:00
taitus
30da0bc626 Update translations from Crowdin 2025-04-07 15:41:49 +02:00
Javi Martín
962aa388df Remove redundant placeholders in attachment fields
Saying that we're supposed to introduce a descriptive title in a field
labelled as "Title" is redundant. Besides, the text of the placeholder
was barely distinguishable, making it harder to fill in the form.
2025-04-03 15:00:12 +02:00
Javi Martín
4e08f3f147 Add a text to the links to execute dashboard actions
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
```
2025-04-02 16:02:55 +02:00
Javi Martín
a1bdaf6e8f Add a text to the show password link in management area
We were using an icon for this link, but people who can't see the icon
couldn't know what the link was about. 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: .show-password
  HTML: <a href="#" class="show-password">
          <span class="icon-eye"></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
```
2025-04-02 15:57:23 +02:00
Javi Martín
3484c6b7b8 Use a list of links to change group in budgets wizard
The original implementation (which was never merged) had a `<select>`
field for the switch, which offered accessibility issues. So I came up
with a very bad idea, which was emulating the look and feel of a select
field while making it more accessible for keyboard users.

This approach is inconvenient because we were using a bunch of ARIA
roles to do the same thing that can be done with a list of links, going
against the first rule of ARIA, which is:

> "Don’t use ARIA if you can achieve the same semantics with a native
> HTML element or attribute

Not only that, but the control was confusing for people using mobile
phones (select fields don't behave the same way), and we were using
*invalid* ARIA roles in this situation, leading Axe to report a critical
accessibility error:

```
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: ul[data-dropdown-menu="edw1i2-dropdown-menu"]
  HTML: <ul class="dropdown menu" wnenu="edw1i2-dropdown-menu"
            data-disable-hover="true" op="true" role="menubar">
  Fix any of the following:
  - Element has children which are not allowed: button[tabindex]
```

So, at least for now, we're using a simple list of links. We might style
it in the future if we find ways to make usability improvements, but,
for now, it does the job, and it does it better than the custom control
we were using.
2025-04-02 13:40:04 +02:00
Javi Martín
5ba6e7b692 Remove redeemable code
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.
2025-03-26 16:42:04 +01:00
Javi Martín
2239b8fdca Remove obsolete questions index in the admin area
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.
2025-03-26 16:42:04 +01:00
Javi Martín
c5018e4a53 Remove obsolete video_url column in poll_questions table
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.
2025-03-26 16:42:04 +01:00
Javi Martín
d8c866c5e6 Remove initializers no longer in Rails
These initializers either don't contain any code at all or contain code
that we never use. Since this was the case in most Rails applications,
they're no longer generated in new Rails applications [1].

So we're removing them as well.

[1] See pull requests 42538 and 43237 in https://github.com/rails/rails
2025-03-06 12:11:51 +01:00
Javi Martín
dc05ff0fd6 Downgrade Sass to version 1.77.5
In commit 64bcedc8b, we upgraded Sass from version 1.70 to version 1.80.
However, since then we've noticed a couple of inconvenient things.

First, we're getting some deprecation warnings when compiling the
assets, related to a usage of `map-has-key` in Foundation which is
deprecated since Sass 1.80. Even with the `quiet_deps` flag, these
warnings aren't silenced.

Second, version 1.79 changed the way color functions work [1]. In
particular, functions like `color.adjust` or `darken` would now generate
RGB colors that include float numbers [2]. Browser support for float values
in RGB colors is about 98% at the time of writing [3], meaning some
browsers that are at least 5 or 6 years old will not render these
colors, sometimes resulting in white text over a white background, which
is of course impossible to read.

Finally, we get some deprecation warnings in our code when we remove the
`quiet_deps` flag, caused by the breaking change in mixed declaration
[4] from version 1.77.7 [5]. This warning is tricky; consider the following
code:

```
@mixin normal-selection {
  &::selection,
  *::selection {
    @include background-with-text-contrast($brand, brand, $check-invert-selection: false);
  }
}

.button.hollow {
  @include normal-selection;
  border: 1px solid;
}
```

In this scenario, since normal-selection is a mixin that generates a
nested rule, we're doing a declaration after a nested rule, which is now
deprecated.

The situation gets even more complicated when we define mixins that have
both nested rules and rules that apply to the element itself. Currently,
we sometimes include a mixin and then override some of the properties
the mixin defines, but we wouldn't be able to do so if we can't define
properties after including the mixin.

Right now, the solution seems to be adding `& { }` selectors
after including a mixin, like this:

```
.button.hollow {
  @include normal-selection;

  & {
    border: 1px solid;
  }
}
```

Which is incredibly cumbersome.

So, for now, we're downgrading to version 1.77.5 (we would downgrade to
version 1.77.6, but the sass-embedded gem skipped that version). That
version was released in June 2024, so it isn't very old yet. In the
future, we'll see what to do about the issues mentioned above, since
we'll have to upgrade at some point.

Note we're removing the `silence_deprecations` flag because Sass 1.77
doesn't raise warnings about using `import`.

[1] https://sass-lang.com/documentation/breaking-changes/color-functions/
[2] https://sass-lang.com/documentation/modules/color/#adjust
[3] https://caniuse.com/mdn-css_types_color_rgb_float_values
[4] https://sass-lang.com/documentation/breaking-changes/mixed-decls/
[5] https://sass-lang.com/documentation/js-api/interfaces/deprecations/#mixed_decls
2025-03-05 15:40:03 +01:00
Javi Martín
1eb45299e2 Fix missing Spanish translation
When we renamed this internationalization key in d25f2e725, we forgot to
rename it in Spanish as well.
2025-02-28 12:21:43 +01:00
taitus
7750dfa9f6 Update translations from Crowdin 2025-01-28 17:09:36 +01:00
Sebastia
b8460f2065 Merge pull request #5847 from consuldemocracy/i18n_crowdin
Update translations from Crowdin
2025-01-23 18:41:10 +01:00
taitus
c65495af6e Enable Portuguese (Portugal) by default 2025-01-23 18:22:36 +01:00
taitus
4126f03a58 Update translations from Crowdin 2025-01-23 17:49:58 +01:00
taitus
018b00cd6e Allow managing versions of cookies consent
This can be useful when adding a new cookie or making
modifications that require asking the user again.
2025-01-23 17:16:57 +01:00
taitus
7407c386a6 Render third party cookies in the management component
Set cookie duration to 365 days based on the AEPD's cookie usage guidelines.

Note from the document: "Cookies with a duration of up to 24 months are
considered acceptable as long as they are periodically updated."
Reference: https://www.aepd.es/guias/guia-cookies.pdf
2025-01-23 17:16:55 +01:00
taitus
dc54fda71b Allow accepting all cookies in consent banner and management component
Create cookie consent "all" when accept all cookies

Set cookie duration to 365 days based on the AEPD's cookie usage guidelines.

Note from the document: "Cookies with a duration of up to 24 months are
considered acceptable as long as they are periodically updated."
Reference: https://www.aepd.es/guias/guia-cookies.pdf
2025-01-23 17:03:30 +01:00
taitus
6753505e7c Allow administrators to define the cookies vendors the application uses 2025-01-23 17:03:30 +01:00
taitus
390c749d24 Add switch to management component for essentials cookies 2025-01-23 16:48:55 +01:00
taitus
d35455624f Allow accept essential cookies from management modal 2025-01-23 16:48:55 +01:00
taitus
df34853792 Add link to management modal in footer 2025-01-23 16:48:55 +01:00
taitus
119c4202fe Allow accessing to management modal from cookies consent banner 2025-01-23 16:48:55 +01:00
taitus
5d590a0aee Add modal management for show essential cookies information
Note that in order to avoid display duplicated vertical scroll when
render a modal, we are add an `overflow: unset` rule. This rule
overwrite a vendor rule both in the modal we are adding and in the
modal we already have when creating a budget in admin section.
2025-01-23 16:48:55 +01:00
taitus
d7f701cc9a Add an optional setting with the link to the cookies policy page 2025-01-23 16:48:54 +01:00
taitus
1958a77842 Allow accept essential cookies from consent banner
Set cookie duration to 365 days based on the AEPD's cookie usage guidelines.

Note from the document: "Cookies with a duration of up to 24 months are
considered acceptable as long as they are periodically updated."
Reference: https://www.aepd.es/guias/guia-cookies.pdf
2025-01-23 16:48:53 +01:00
taitus
4c0b6455f6 Add cookies consent banner
Allow enabling from settings admin section.

Note that we set the z-index to 20 in order to will be greater than
the others z-index elements in the application like <header> on
mobile devices.
2025-01-23 16:05:40 +01:00
Javi Martín
8d1a848e60 Remove code to rotate non-SHA256 cookies
This code was added in commit b3f570512 in order to rotate existing
cookies used by Consul Democracy 2.1 and earlier. Since the code was
included in Consul Democracy 2.2, existing installation using Consul
Democracy 2.2 will have already rotated the old cookies, which means we
don't need the cookie rotator anymore.
2025-01-08 16:47:57 +01:00
Javi Martín
0eb62f9b9c Merge pull request #5616 from coslajohn/maps
Render Geozone Maps Collections and Multipolygons
2024-12-23 18:01:12 +01:00
CoslaJohn
5dbe2cbf24 Support FeatureCollection and MultiPolygon in geozones
We're reworking the format validation to correctly interpret feature
collection, feature, and geometry, according to RFC 7946 [1].

Since Leaflet interprets GeoJSON format, we're rendering the GeoJSON as
a layer instead of as a set of points. For that, we're normalizing the
GeoJSON to make sure it contains either a Feature or a
FeatureCollection. We're also adding the Leaflet images to the assets
path so the markers used for point geometries are rendered correctly.

Note we no longer allow a GeoJSON containing a geometry but not a
defined type. Since there might be invalid GeoJSON in existing Consul
Democracy databases, we're normalizing these existing geometry objects
to be part of a feature object.

We're also wrapping the outline points in a FeatureCollection object
because most of the large GIS systems eg ArcGIS, QGIS export geojson as
a complete FeatureCollection.

[1] https://datatracker.ietf.org/doc/html/rfc7946

Co-authored-by: Javi Martín <javim@elretirao.net>
2024-12-23 17:35:33 +01:00
Javi Martín
6ab51b0367 Remove the ahoy_events table
We stopped using ahoy events in commit f7e2d724d.
2024-11-13 15:55:20 +01:00
Javi Martín
4102330abc Add labels to investments filters
Note that adding the labels broke the layout because the button was no
longer aligned with the fields, so we're now using a flex layout.

Since we're using labels, we no longer need a placeholder (which wasn't
very informative, by the way) in the text field.
2024-11-11 15:04:40 +01:00
Javi Martín
1cefc040a7 Add labels to the search form in the management area
The text for the unfeasible checkbox wasn't correctly defined as a
label, while the fields to search investments and select the heading
weren't intuitive since their purpose wasn't obvious.
2024-11-11 15:04:35 +01:00
Javi Martín
8213f23629 Use I18n texts for image dimensions
This way it'll be possible to customize the text in languages not using
parenthesis or not using an "x" to define dimensions.
2024-11-08 15:03:55 +01:00
Javi Martín
16fc9998c4 Use labels in controls to add and select languages
The absence of labels in these controls made them hard to use,
particularly for people who use screen readers.

Note we're removing the "Choose language" prompt, since we always
automatically choose a language and not choosing a language doesn't
really make sense. The only scenario where the prompt was used took
place when all languages had been removed but, in that case, the "Choose
language" prompt was misleading because there were no languages to
choose from.
2024-11-08 14:22:44 +01:00
Javi Martín
2fb8eaf6c7 Add aria-labels to user investment actions
This way it'll be easier for people using screen readers to know which
link/button they're about to click.

Note that, at least for now, we aren't reusing the code en
`Admin::ActionComponent`. We might do so in the future if we implement
similar code in more parts of the public area.
2024-11-08 12:29:37 +01:00
Javi Martín
6e5ef9795e Track ahoy visits on the server side
In commit 96ae69fe9, we stopped using cookies to track Ahoy visits and
started using a combination of the IP and the browser agent instead.

However, since we're still using the legacy logic from Ahoy 1.x to track
visits (which we had to add in commit b5220effd), this way of tracking
visits doesn't work and counts every page visited by a user as an
independent visit.

Maybe we could migrate existing data, which uses the `visitor_id` column
so it uses the new `visit_token` and `visitor_token` columns, but
there's no mention in the Ahoy documentation regarding how to do so.

While deciding what to do about this, we found something interesting.

For two years, we've been seeing random failures in the
`system/admin/tenants_spec.rb` tests, with messages like:

```
1) Tenants Create Tenant with subdomain
     Failure/Error:
       raise TenantNotFound, <<~EXCEPTION_MESSAGE
         Could not set search path to schemas, they may be invalid:
           "#{tenant}" #{full_search_path}.
         Original error: #{exception.class}: #{exception}
       EXCEPTION_MESSAGE

     Apartment::TenantNotFound:
       Could not set search path to schemas, they may be invalid:
         "earth" "public", "shared_extensions".
       Original error:
         ActiveRecord::StatementInvalid: Could not find schema earth
```

And we've found one of the causes: the AJAX requests done by Ahoy to
track visits. Sometimes a test that creates or updates a tenant finishes
but the Ahoy AJAX request to, say, `earth.lvh.me/ahoy/visits`, is
handled by the next test, when the `earth` schema no longer exists, thus
raising an `Apartment::TenantNotFound` exception.

So by disabling these AJAX requests and tracking the visits in the
server instead, we're killing two birds in one stone: we're fixing the
bug regarding the visits count and we're reducing the flakiness in our
test suite. It looks like we're also removing the "phantom ahoy cookie"
we were getting since the mentioned commit b5220effd: an ahoy cookie was
quickly set and unset in the browser.

Note that, even though we aren't migrating any data, we're still adding
the new fields, because some tests started to fail because, when
tracking visits in the server without cookies, Ahoy expects the Visit
model to have a `visit_token` field.
2024-11-07 12:04:46 +01:00
Sebastia
d242170771 Merge pull request #5057 from consuldemocracy/only_manage_tenants
Add an option to enable the "Multitenancy management mode"
2024-11-06 14:59:50 +01:00
Sebastia
1c684c3daf Merge pull request #5752 from consuldemocracy/dependabot/bundler/sassc-embedded-1.80.1
Bump sassc-embedded from 1.70.1 to 1.80.1
2024-11-06 13:16:42 +01:00
dependabot[bot]
64bcedc8b2 Bump sassc-embedded from 1.70.1 to 1.80.1
Note: Since we update to 1.80.1 deprecation warnings are appear when execute the assets:precompile command.
In order to silence this deprecation, we add silence_deprecation option in sass.rb initializer.

The code has also been updated to remove the deprecation warnings that appeared related to the function
darken(), lighten() and "Using / for division" instead of the function calc().

Bumps [sassc-embedded](https://github.com/sass-contrib/sassc-embedded-shim-ruby) from 1.70.1 to 1.80.1.
- [Commits](https://github.com/sass-contrib/sassc-embedded-shim-ruby/compare/v1.70.1...v1.80.1)

---
updated-dependencies:
- dependency-name: sassc-embedded
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-06 13:01:58 +01:00
taitus
93b35fcecc Redirect root path requests to the tenants administration
When the `multitenancy_management_mode` is enabled.

In order to avoid infinite redirects when regular users try to access
the admin section, we're redirecting to the account page in this case.
Otherwise, the admin section would redirect to the root path, which
would redirect to the admin section, which would redirect to the root
path, and so on.
2024-11-06 11:17:58 +01:00
taitus
a5911f5c6a Modify admin layout to only manage tenants and admins
We only want to render the account link and login items in the header.
And we want only render the Multitenancy and Administrators sections in
the admin sidebar.

We include the administrators management so it's possible to give
permissions to other users to manage tenants.

In order to restrict access to other sections by typing the URL or
following a link, we're only enabling the rest of the routes when we
aren't in the multitenancy management mode.
2024-11-06 11:17:53 +01:00
taitus
1a8676f2d4 Add secret to allow the default tenant only be used to manage other tenants
Co-Authored-By: Senén Rodero <senenrodero@gmail.com>
2024-11-06 11:07:00 +01:00
Javi Martín
60dbda600d Move resolve clauses to the main routes file
We're going to add some constraints in the routes file, and if we add a
`resolve` clause inside a constraints block, we get an error saying that
"The resolve method can't be used inside a routes scope block" when
starting the application.
2024-11-06 11:07:00 +01:00
CoslaJohn
424cedc0c8 Restrict access to admin functions by IP
There are many possible ways to implement this feature:

* Adding a custom middleware
* Using rack-attack with a blocklist
* Using routes constraints

We're choosing to use a controller concern with a redirect because it's
what we do to handle unauthorized cancancan exceptions.
2024-10-30 15:59:50 +01:00
Javi Martín
07202fea10 Add and apply Style/RedundantBegin rubocop rule
We're about to add code which might fall into the `RedundantBegin`
category, so we're adding the rule in order to prevent that.
2024-10-30 15:57:44 +01:00
Javi Martín
fc5103881d Use a switch to toggle visibility to valuators
Using a checkbox wasn't very intuitive because checkboxes are
checked/unchecked when clicked on even if there's an error in the
request. Usually, when checkboxes appear on a form, they don't send any
information to the server unless we click a button to send the form.

So we're using a switch instead of a checkbox, like we did to
enable/disable phases in commit 46d8bc4f0.

Note that, since we've got two switches that match the default
`dom_id(record) .toggle-switch` selector, we need to find a way to
differentiate them. We're adding the `form_class` option for that.

Also note that we're now using a separate action and removing the
JavaScript in the `update` action which assumed that AJAX requests to
this action were always related to updating the `visible_to_valuators`
attribute.
2024-10-28 13:41:55 +01:00
Javi Martín
54a48d63e1 Use separate actions to select/deselect investments
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 an investment] 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-28 13:41:50 +01:00