Commit Graph

19054 Commits

Author SHA1 Message Date
Javi Martín
d9662164b8 Remove unused code to display polls with no dates
When this code was added, in commit 1a20a3ce4, we had no validation
rules checking the presence of the start and end dates of a poll. Now we
do, so we don't have to check this condition in the view.
2024-06-07 16:19:29 +02:00
Javi Martín
438fe7bd25 Fix inner borders in polls administration tables
The rows in these tables were using the styles from the `.poll`
selector, and the `position: relative` property defined there caused the
inner borders to disappear in some browsers (like Firefox).

So we're adding the `public` class to the selector; this way, it doesn't
affect elements in the admin section.

Even though it's only necessary to add the `.public` prefix to the
`.poll` selector in one place in order to fix this issue, we're doing it
everywhere for consistency.
2024-06-07 16:19:04 +02:00
Javi Martín
7b3b41386e Fix styles for poll dates
We accidentally introduced a typo in commit f497227e3 which caused the
dates to be rendered outside the element where the dates styles are
applied.
2024-06-07 15:52:02 +02:00
Javi Martín
08ca920819 Simplify conditions to render poll status icons
We were using a redundant `elsif` instead of an `else`. We were also
using a negative condition in the main `if`, which made the code a bit
harder to read.

Since we usually use `current_user` instead of `user_signed_in?`, we're
also changing that for consistency.Extract component to render the status of a poll
2024-06-07 15:52:02 +02:00
Javi Martín
765ab758dc Extract component to render a poll in the poll index
This is consistent with the way we've got partials to render debates,
proposals and legislation processes on their index pages.

Note that, while adding the tests for the status icon, we're keeping one
system test because it also tests the process of voting. We're adding a
new, similar component test, where the voter is created in the database,
so all possible statuses are tested in the component.
2024-06-07 15:52:02 +02:00
Javi Martín
2b03e3ebc4 Remove unused CSS to display poll status icons
This code isn't used since commit 5fdbc7b8a.
2024-06-07 15:52:02 +02:00
Javi Martín
9bef791d01 Merge pull request #5548 from consuldemocracy/video_cookies
Do not use third-party cookies in embedded videos
2024-06-07 15:42:25 +02:00
Javi Martín
ee64efe659 Use the Do Not Track parameter in vimeo videos
With this parameter, Vimeo no longer uses cookies that identifies users
browsing our site.

They do still store some cookies, though; quoting from Vimeo player
parameters overview:

> When DNT is enabled, Vimeo deploys one essential cookie via the
> embeddable player:
> The __cf_bm cookie, which is part of Cloudflare's Bot Management
> service and helps mitigate risk associated with spam and bot traffic.

Not sure whether this counts as essential cookies in our case; they're
essential for Vimeo, but for us, they're third-party cookies, after all.

[1] https://help.vimeo.com/hc/en-us/articles/12426260232977-Player-parameters-overview
2024-06-07 15:28:42 +02:00
Javi Martín
442156b1cc Don't use cookies when embedding youtube videos
When embedding a video in our site YouTube stores cookies in the user's
computer that aren't necessary to watch the video, so we'd have to make
people accept those cookies before letting them watch the video.

Using a URL that doesn't use cookies, like mentioned in YouTube Help
[1], is easier, though, and respects people's privacy without affecting
the user experience.

That I've found some references saying that youtube does store cookies
once you hit the "play" button even when using the nocookie server [2].
Not sure whether that's an old behavior or I'm doing something wrong,
but I don't see this is the case; even after playing the video, cookies
aren't stored on my browser.

[1] https://support.google.com/youtube/answer/171780#zippy=%2Cturn-on-privacy-enhanced-mode
[2] https://www.cnet.com/news/privacy/youtubes-new-nocookie-feature-continues-to-serve-cookies/
2024-06-06 17:35:27 +02:00
Javi Martín
738314e685 Add basic tests for embedded video component 2024-06-06 17:35:27 +02:00
Javi Martín
48178ffd43 Make embedded video tests more precise
Now we're also testing that there's an iframe with the URL; before this
change, the test would pass even if the JavaScript generating the iframe
wouldn't work.
2024-06-06 17:35:27 +02:00
Javi Martín
cc8acdcc87 Make method name consistent in embedded video component
We were using `reg_exp` as the method name, when it returned
`VIMEO_REGEX` or `YOUTUBE_REGEX`.

So using `regex` as the method name is less confusing.
2024-06-06 17:35:27 +02:00
Javi Martín
fee5b8a13c Remove redundant code in embedded video component
When using `<%= `, `nil` is converted to an empty string, so there's no
need to explicitely return an empty string.
2024-06-06 17:35:27 +02:00
Javi Martín
b07132d8d4 Extract methods in embedded video component
No that it's no longer a helper, we can extract method without fearing
they will have the same name as other helper methods.
2024-06-06 17:35:27 +02:00
Javi Martín
579e332cf8 Extract component to render an embedded video 2024-06-06 17:35:27 +02:00
Javi Martín
236b58ab01 Remove duplication in code to validate video URL
We were using the same code, and the same regular expressions, in two
places. To do so, we were including a helper inside a model, which is
something we don't usually do.
2024-06-06 17:35:27 +02:00
Javi Martín
250fdd2335 Merge pull request #5488 from consuldemocracy/check_all_none
Add buttons to check/uncheck all locales
2024-06-06 17:28:51 +02:00
Javi Martín
8272b7e9c3 Move shared component stylesheets to shared folder
We had an inconsistency where most stylesheets associated to a component
would have the same relative path as their component, so if we had a
component in `app/components/admin/whatever`, its associated stylesheet
would be in `app/assets/stylesheets/admin/whatever`.

There was one exception to this rule: stylesheets for components in
`app/components/shared/` were placed in `app/assets/stylesheets/`. The
reason was that we thought "well... if they're in the root folder,
they're shared". However, this is confusing because in the root folder
there are also stylesheets that aren't associated to a component.

So we're creating the `app/assets/stylesheets/shared/` folder. This also
means we don't have to manually add every stylesheet in this folder the
the `application.scss` file.

We aren't the same for JavaScript files because with JavaScript we still
don't have a clear association between JavaScript files and components.
Only a couple of them (`advanced_search.js` and `check_all_none.js`)
would be good candidates, and the one for the advanced search form
doesn't even use the `.advanced-search-form` selector that we use in the
CSS file.
2024-06-06 16:28:19 +02:00
Javi Martín
c367f21705 Add buttons to check all/none available languages
Although most Consul Democracy installations will only have a few
available languages using `config.i18n.available_locales`, there's a
chance some installation will keep every language as available and will
enable the desired ones using the admin interface. In these cases,
enabling (or disabling) every language would be tedious, particularly
when casually experimenting in a staging environment or while using the
official Consul Democracy demo.

So we're adding buttons to simplify the process. Since some
installations might have only a couple of available languages, and in
this case these buttons would be pretty much useless, we're only showing
them when there are many languages available.
2024-06-06 16:28:19 +02:00
Javi Martín
a911b0dec7 Extract function in "check all/none" JavaScript file 2024-06-06 16:28:19 +02:00
Javi Martín
15ca47caed Hide "check all/none" buttons when JavaScript isn't available
These buttons only work without JavaScript, so we shouldn't show them in
this case.

I was wondering whether we should use the `hidden` HTML attribute so
these buttons don't show up when stylesheets haven't loaded either. Not
doing so because we already have a stylesheet for the <noscript>
scenario. We might change our minds regarding how to handle these styles
in the future.
2024-06-06 16:28:19 +02:00
Javi Martín
63eacf4579 Move noscript styles to their own stylesheet
This way we can use SCSS syntax here, like we do everywhere else.
2024-06-06 16:28:19 +02:00
Javi Martín
ce1ee861f1 Simplify "check all/none" buttons layout
The float property was removed in commit b71c61e40, but then it was
added again in commit 4a6313fed.

It might have been necessary to do so back then because we had a
`select` field instead of the links to set the order, but now, instead
of making them float on the left and then make the next element clear
the floats, we can do nothing and obtain the same results.
2024-06-06 16:28:19 +02:00
Javi Martín
673eb1358a Group buttons to check all/none elements
Since they're related, we're making them part of the same list. Instead
of finding a way to have the `Select` prefix they had as a label for the
list, we're including the "prefix" they had inside their texts, so the
text of a button doesn't need any additional context.
2024-06-06 16:28:19 +02:00
Javi Martín
2dab8682d9 Remove unused CSS in legislation
This code using the legislation-categories HTML class was removed in
commits d679c1eb7 and ff66909cd. We've noticed is while dealing with the
`.menu.simple` selectors in the previous commit.
2024-06-06 16:27:56 +02:00
Javi Martín
f47179ff68 Use buttons to check/uncheck all options
People using screen readers usually expect links to take them somewhere
else in the page on to a different page, while they expect buttons to
change something on the page.

Since we're in the latter scenario, using a button is more accessible.
It's also more natural; with a button, we don't need to provide `#` as
the URL or stop the default event when the button is clicked. And,
unlike links, buttons can be activated with either the space or the
enter key. Finally, clicking a link pointing to `#` with the middle
mouse button opens a useless new tab, while buttons do nothing in this
case.

Now that we only have one "All" link on the page, we no longer need to
specify which "All" link we're clicking or which "All" link we are
checking, so we're simplifying the code doing so.
2024-06-06 16:18:33 +02:00
Javi Martín
fdf1fd5f5f Move links to check all/none on RTL languages
Since we don't usually style HTML classes starting with `js-`, we're
renaming it, so it's consistent with the `CheckAllNone` name used in the
`check_all_none.js` file.
2024-06-06 16:09:18 +02:00
Javi Martín
6ee5c0fcb8 Simplify expectations in "select all/none" tests 2024-06-06 16:09:18 +02:00
Javi Martín
f8f4054614 Make "select all/none" tests actually test something
Since we were on the "Pending review" filter, and there were no records
pending review, the code checking all checkboxes were checked/unchecked
didn't test anything because there were no checkboxes on the page.

So we're clicking on the "All" filter first.
2024-06-06 16:09:18 +02:00
Javi Martín
26a43ee0d2 Add a proper title to moderation index pages
Since this is already a component, we can use the `header` method
without much refactoring.
2024-06-06 16:09:18 +02:00
Javi Martín
75598972e3 Merge pull request #5570 from consuldemocracy/dependabot/bundler/rails-7.0.8.4
Bump rails from 7.0.8.1 to 7.0.8.4
2024-06-05 18:30:11 +02:00
dependabot[bot]
018b4aabbe Bump rails from 7.0.8.1 to 7.0.8.4
Bumps [rails](https://github.com/rails/rails) from 7.0.8.1 to 7.0.8.4.
- [Release notes](https://github.com/rails/rails/releases)
- [Commits](https://github.com/rails/rails/compare/v7.0.8.1...v7.0.8.4)

---
updated-dependencies:
- dependency-name: rails
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-05 15:44:31 +00:00
Javi Martín
1e2c78f3dc Merge pull request #5243 from consuldemocracy/tenant_locales
Allow different locales per tenant
2024-06-05 16:27:02 +02:00
Javi Martín
0c59c2dfb4 Extract model to handle locales settings
This way we can simplify the view, particularly the form. However, we're
still adding some complexity to the form so inputs are inside labels and
so the collection is easier to style with CSS.
2024-06-05 16:10:56 +02:00
Javi Martín
2596b4e78b Use multiple columns to display languages options
When the list of available languages becomes too large, having all of
them in one column makes it harder to select them.

What we're trying to do here is to have multiple columns, with each
column containing between 5 and 10 options, so they can all be easily
seen on the screen at the same time.

For that, there are mainly three options: a flex layout, a grid layout
or a multi-column layout.

Since languages are ordered (more or less) alphabetically, the natural
way to display them is showing the first few ones on the first column,
the following ones on the second column, and so on, as opposed to
displaying the first ones on the first row, the following ones on the
secord row, ... AFAIK this can't be accomplished using a flex layout.

I've tried to do so using a grid layout, and failed. The problem here is
that we don't know how many rows we're going to have.

So we're using a multi-column layout. I haven't found a way to guarantee
a minimum height for the content of each column, so in the end we're
using a hack with the `:has` pseudoclass. Note this pseudoclass is only
supported by about 92%-94% of the browsers (including the last few
versions of all major browsers); people using other browsers will still
see all the options on one column, just like people using small screens
do.
2024-06-05 16:10:56 +02:00
Javi Martín
78bbf430d5 Add a form to edit available locales
We're using different controls depending on the number of available
locales.

When there are only a few locales, the solution is obvious: radio
buttons to select the default language, and checkboxes to select the
available ones are simple and intuitive.

With many languages, showing two consecutive lists of 30 languages could
be confusing, though, particularly on small devices, where scrolling
through both lists could be hard.

So, in this case, we're rendering a <select> to choose the default
language. For selecting the available languages, however, we're sticking
to checkboxes because all the other existing options (like multiple
selects) are hard to use. We think it's OK because the form doesn't have
any additional fields, and there's only one big list of options to
scroll through.

While testing the application, we noticed that if we use the
`admin-fieldset-separator` styles when there's only one fieldset, it's
harder to notice that there's an additional field to select the default
language. So we're only using the `admin-fieldset-separator` styles when
all the fields are grouped in fieldsets.

Regarding the help text for the fieldset, if we leave the help text
outside the <legend> tag, people using screen readers won't hear about
this content. However, if we include it inside the <legend> tag, some
screen readers might read it every time they move to a different
checkbox (or radio button), which can be annoying. Since I don't think
these help messages are really essential, I'm leaving them out of the
<legend> tag. It's also easier to style them if they're outside the
<legend> tag.

Note we're using `display: table` for the labels, for the reasons
mentioned in commit 923c2a7ee.

Also note that, when there's only one available locale, this section is
useless. In this case, we aren't disabling it for now because there's a
chance people see it in the official Consul Democracy demo and then
wonder why it isn't available on their installation. We might disable it
in the future, though.
2024-06-05 16:10:56 +02:00
Javi Martín
999d5c2f67 Remove redundant "Manage" in admin menu entries
This is the admin section; it's obvious that every link in the menu will
take you to a page to manage something.

We're going to add a new item to either the "Settings" or the "Site
content" section, so it's a good time to improve what's already there.
2024-06-05 16:10:56 +02:00
Javi Martín
6de4737b70 Allow different default locales per tenant
Note that, for everything to work consistently, we need to make sure
that the default locale is one of the available locales.

Also note that we aren't overwriting the `#save ` method set by
globalize. I didn't feel too comfortable changing a monkey-patch which
ideally shouldn't be there in the first place, I haven't found a case
where `Globalize.locale` is `nil` (since it defaults to `I18n.locale`,
which should never be `nil`), so using `I18n.default_locale` probably
doesn't affect us.
2024-06-05 16:10:56 +02:00
Javi Martín
722e50a669 Simplify code to find a content block
We're only calling the `block_for` method from one place: the
`content_block` helper, and we're never passing the locale parameter to
that helper, which means we're always calling `block_for` using
`I18n.locale`.

So I'm not sure why we were doing the `locale ||=` assignment, since
`I18n.locale` doesn't return nil.

In any case, since this was added in commit c1de2dced, Ruby has added
support for arguments forwarding, so we can use it here to simplify the
code a little bit.
2024-06-05 16:10:56 +02:00
Javi Martín
647121d13e Allow different locales per tenant
Note that, currently, we take these settings from the database but we
don't provide a way to edit them through the admin interface, so the
locales must be manually introduced through a Rails console.

While we did consider using a comma-separated list, we're using spaces
in order to be consistent with the way we store the allowed content
types settings.

The `enabled_locales` nomenclature, which contrasts with
`available_locales`, is probably subconsciously based on similar
patterns like the one Nginx uses to enable sites.

Note that we aren't using `Setting.enabled_locales` in the globalize
initializer when setting the fallbacks. This means the following test
(which we could add to the shared globalizable examples) would fail:

```
it "Falls back to an enabled locale if the fallback is not enabled" do
  Setting["locales.default"] = "en"
  Setting["locales.enabled"] = "fr en"
  allow(I18n.fallbacks).to receive(:[]).and_return([:fr, :es])
  Globalize.set_fallbacks_to_all_available_locales

  I18n.with_locale(:fr) do
    expect(record.send(attribute)).to eq "In English"
  end
end
```

The reason is that the code making this test pass could be:

```
def Globalize.set_fallbacks_to_all_available_locales
  Globalize.fallbacks = I18n.available_locales.index_with do |locale|
    ((I18n.fallbacks[locale] & Setting.enabled_locales) + Setting.enabled_locales).uniq
  end
end
```

However, this would make it impossible to run `rake db:migrate` on new
applications because the initializer would try to load the `Setting`
model but the `settings` table wouldn't exist at that point.

Besides, this is a really rare case that IMHO we don't need to support.
For this scenario, an installation would have to enable a locale, create
records with contents in that locale, then disable that locale and have
that locale as a fallback for a language where content for that record
wasn't created. If that happened, it would be solved by creating content
for that record in every enabled language.
2024-06-05 16:10:56 +02:00
Javi Martín
790d515afc Remove unused code in globalizable concern
This code was added in commit 041abe904, but it was never used.
2024-06-05 16:10:56 +02:00
Javi Martín
c11780880c Move form builders to their own folder
We were defining one builder in the `app/lib/` folder and another one
inside a helper module.

So now we're grouping them together. This way we're following the "one
class per file" convention that we follow most of the time. And, by
extracting the `TranslatableFormBuilder` class to its own file, it'll be
easier to add tests for it.

Note that, for consistency, we're renaming the
`TranslationsFieldsBuilder` class so it ends in `FormBuilder`.
2024-06-05 16:10:56 +02:00
Javi Martín
26b48e527a Move information texts form partial to a component
This way it'll be easierto write tests for it when we change it.
2024-06-05 16:10:56 +02:00
Javi Martín
2a5edbb5dd Move content blocks forms partials to components
This way we can simplify the controller a little bit, and it'll be
easier to write tests for them when we change the code.
2024-06-05 16:10:56 +02:00
Javi Martín
1898bdec56 Remove redundant conditions in content blocks controller
In the case of the `edit` action, we're using
`load_and_authorize_resource`, which will always return a
`SiteCustomization::ContentBlock`. In the case of
`edit_heading_content_block`, we're using `Budget::ContentBlock.find`,
which always returns a `Budget::ContentBlock` (or raises an exception).

So, in both cases, the condition to assign `@selected_content_block` can
be removed.
2024-06-05 16:10:56 +02:00
Javi Martín
e7d2cfbf23 Add missing action to content blocks controller
The code works without this action because both the route and the view
are specified, and by default Rails renders the view when there's no
action defined.

However, the code is easier to understand if the action is present in
the controller, which is what we do most of the time.
2024-06-05 16:10:56 +02:00
Javi Martín
709f39c6ce Handle unavailable locales in subscriptions
There was an edge case where a user could configure a locale and then
the application would change the locales to that one would no longer be
available. In that case, we were getting a `I18n::InvalidLocale`
exception when accessing the subscriptions page.

So now, we're defaulting to `I18n.locale`. Note we're using
`I18n.locale`instead of `I18n.default_locale` because `set_user_locale`
is called inside the `switch_locale` block in `ApplicationController`,
which already sets `I18n.locale` based on `I18n.default_locale`.
2024-06-05 16:10:56 +02:00
Javi Martín
3e13f93ebd Add controller tests for switch_locale
This way it'll be easier to change it while checking we haven't broken
existing behavior.

While writing the tests, I noticed we were sometimes storing a symbol in
the session while sometimes we were storing a string. So we're adding a
`to_s` call so we always store a string in the session.
2024-06-05 16:10:56 +02:00
Javi Martín
a2177b4575 Refactor methods to get active locales count
The code is now a bit more readable.
2024-06-05 16:10:56 +02:00
Javi Martín
b188c5cae0 Simplify method to get existing locales
We can get the same results using `pluck`.
2024-06-05 16:10:56 +02:00