Commit Graph

17301 Commits

Author SHA1 Message Date
Javi Martín
16e48e7705 Add Indonesian SDG icons
Based on an EPS file downloaded from The Global Goals page [1].

We didn't have Indonesian SDG icons in any format.

[1] https://www.globalgoals.org/resources
2021-09-30 15:06:50 +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
78811f5f4d Load SDG icons in SVG when available
SVG files are smaller than PNG files, can be compressed, and are
scalable.

We're choosing to render SVG files as images instead of inline because
inline SVGs aren't cached nor compressed, and they might appear several
times on the same page, making the generated HTML much larger.

We could also load them with an SVG sprite, using `<use>`, which would
reduce the number of HTTP requests when several icons are present on the
page (like in the index of most sections). However, using SVG inside an
`<img>` tag is universally supported, while the `<use>` tag doesn't
work in Internet Explorer when using an external URI and support in
Opera Mini and UC Browser is unknown.
2021-09-30 15:06:50 +02:00
Javi Martín
5de90547a7 Rename folder method in SDG icon component
The method name was a bit confusing because it returned a locale.
2021-09-30 15:06:50 +02:00
Javi Martín
f5a5ac5f1f Merge pull request #4673 from consul/enable_sdg_by_default
Enable SDG content by default
2021-09-30 15:06:17 +02:00
Javi Martín
797f61c0ca Enable SDG content by default
We didn't enable it by default in commit 676adfcb3 so existing
installations didn't suddenly get a new section without expecting it.

But since the setting already exists for installations using version
CONSUL 1.3, now it will only be enabled for new installations.
2021-09-30 14:44:30 +02:00
Javi Martín
cd3a76b77d Merge pull request #4676 from consul/admin_menu_padding
Improve styles for long admin menu items
2021-09-30 14:44:10 +02:00
Javi Martín
d232e8cdf9 Reduce width of the admin menu on large screens
On very large screens, the admin menu had a lot of blank space for
languages where all sections had short names (like English). This was
inconvenient because the icon to open a submenu was far from its
associated menu item.

Using the `max-content` value for the `max-width` property, we reduce
the amount of blank space in these cases.
2021-09-30 13:35:13 +02:00
Javi Martín
e241bab130 Fix accordion icon overlap in admin menu
Since the icon was absolutely positioned, in some languages it
overlapped with the text.

Using a flex layout solves this issue. It also improves the appearance
of elements whose text spans over multiple lines; previously the second
line would go under their section icon.

We're also using the `$global-left` variable so the icon is properly
displayed in languages written from right to left. We could use the
`margin-inline-start` property instead, but it isn't universally
supported in every browser yet.

Since the layout is now incompatible with the old (and obsolete) way to
add icons to the menu (using classes which would use the
`[class^="icon-"]` selector), we're removing this code.
2021-09-30 13:35:10 +02:00
Javi Martín
d3a4a7bca3 Fix line-height in admin menu items
When items went over multiple lines, the distance between their lines
was the same as the distance between one element and another one. This
made it hard to differentiate how many elements there were.

Using a padding to separate the contents of one element and the contents
of the next one solves the issue.
2021-09-28 15:16:47 +02:00
dependabot[bot]
83b4be6052 Bump nokogiri from 1.12.3 to 1.12.5
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.12.3 to 1.12.5.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.12.3...v1.12.5)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-27 22:28:29 +02:00
Javi Martín
de9c63f2dc Merge pull request #4699 from consul/render_attachments
Remove unused attachments code
2021-09-24 17:48:09 +02:00
Javi Martín
c3b3bd4502 Test attachments from the user's point of view
These tests were checking the URLs of documents and images pointed to
the URL generated by the `attachment.url` method. In order to do so, we
were running database queries after starting the process running the
browser, which is sometimes causing database inconsistencies when
running the tests.

So I'm simply removing the URL check. The tests are slightly less useful
now, but it isn't like they were 100% right in the first place. After
all, if the `attachment.url` method wasn't working properly, the tests
were still passing.
2021-09-24 16:36:35 +02:00
Javi Martín
6f219beff0 Remove unused parameter in imageable tests method 2021-09-24 16:36:35 +02:00
Javi Martín
04585d289c Remove not-so-precise attachments test
We were testing the URL of the image changes to `missing.png`, but
actually that's confusing because the image record is now invalid and so
its changes can't be saved. That means that, when rendered in the
browser, the image won't render the `missing.png` image but will try to
render the destroyed one.

If we want to render the `missing.png` image when the attachment has
been destroyed, we need to remove the attachment presence validation or
change the `url` method so it detects when an attachment is missing.
2021-09-24 16:36:35 +02:00
Javi Martín
bc18a6e10e Remove unused url method in poll question answers
This method would never work because it relies on the `image`
association, instead of the `images` association defined in the
`Galleryable` module.
2021-09-24 16:36:35 +02:00
Javi Martín
da055edb37 Simplify rendering proposal image in dashboard
So it's now similar to the way we render images in other places.
2021-09-24 16:36:35 +02:00
Javi Martín
6cf3c743cf Merge pull request #4598 from consul/active_storage_dual
Store files with both Paperclip and ActiveStorage
2021-09-24 16:31:56 +02:00
Javi Martín
be9c272ce4 Remove default Active Storage direct upload action
We're already using a custom controller to handle direct uploads.

Besides, as mentioned by one of Active Storage co-authors [1], the
Active Storage DirectUploadsController doesn't provide any
authentication or validation at all, meaning anyone could create blobs
in our database by posting to `/rails/active_storage/direct_uploads`.
The response there could be then used to upload any file (again, without
validation) to `/rails/active_storage/disk/`.

For now, we're monkey-patching the controllers in order to send
unauthorized responses, since we aren't using these routes. If we ever
enable direct uploads with Active Storage, we'll have to add some sort
of authentication.

Similar upload solutions like CKEditor don't have this issue since their
controllers inherit from `ApplicationController` (which includes
authorization rules), while Active Storage controllers inherit from
`ActionController::Base`.

[1] https://discuss.rubyonrails.org/t/activestorage-direct-uploads-safe-by-default-how-to-make-it-safe/74863/2
2021-09-24 13:39:15 +02:00
Javi Martín
259cd8e108 Add sample configurations for external storages
These configurations are based on the ones ActiveStorage generates
automatically for Rails 6 applications.
2021-09-24 13:39:15 +02:00
Senén Rodero Rodríguez
87e427f433 Allow remote storages in Active Storage migration
So forks that connected Paperclip with S3 buckets can migrate files too.
2021-09-24 13:39:15 +02:00
Senén Rodero Rodríguez
5a4921a1af Use URI.open to assign external cached attachments
We were having issues with cached attachments and external services.

A `Tempfile` is returned by `URI.open` when using S3, so we're dealing
with this case as well.
2021-09-24 13:39:15 +02:00
Javi Martín
b5026e12a7 Ignore missing records in Active Storage migration
There could be inconsistencies in the database and an attachment might
have a `record_id` pointing to a record which no longer exist. We were
getting an exception in this case.
2021-09-24 13:39:15 +02:00
Javi Martín
fd67477281 Don't migrate files already in Active Storage
This way we reduce the hypothetical problems we could find if executing
the task several times.
2021-09-24 13:39:15 +02:00
Javi Martín
7330bfb6ae Ignore deleted files in Active Storage migration
Files might be missing for whatever reason or records might not point to
any files; in these edge cases, we were getting an exception.
2021-09-24 13:39:15 +02:00
Javi Martín
038fb76896 Allow executing the migration task twice in tests
We were getting a duplicate prepared statement error when trying to
execute more than one test using this task. So we're checking whether
the prepared statement exists before defining it.
2021-09-24 13:39:15 +02:00
Javi Martín
9900a21fd5 Use the storage_ prefix for migrated attachments
Just like we add the `storage_` prefix for new records so we can use
both Active Storage and Paperclip at the same time.

Now the migration actually works, at least for basic cases.
2021-09-24 13:39:15 +02:00
Javi Martín
b4b42c7cc9 Fix duplicate entries in Active Storage migation
Using `LASTVAL()` wasn't working 100% of the time for some reason after
inserting and deleting some rows. So we're using `RETURNING` instead.
2021-09-24 13:39:15 +02:00
Javi Martín
a92e82326b Ignore OldPassword in Active Storage migration
This model is added by the devise-security gem, but we don't use it. We
were getting an error while migrating:

ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "old_passwords" does not exist
LINE 8:                WHERE a.attrelid = '"old_passwords"'::regclas...
                                          ^
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
     pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
     c.collname, col_description(a.attrelid, a.attnum) AS comment
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
WHERE a.attrelid = '"old_passwords"'::regclass
  AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
lib/tasks/active_storage.rake:27:in `block (4 levels) in <top (required)>'
lib/tasks/active_storage.rake:26:in `each'
lib/tasks/active_storage.rake:26:in `block (3 levels) in <top (required)>'
lib/tasks/active_storage.rake:25:in `block (2 levels) in <top (required)>'

Caused by:
PG::UndefinedTable: ERROR: relation "old_passwords" does not exist
2021-09-24 13:39:15 +02:00
Javi Martín
a6025d3a12 Simplify copying files in Active Storage migration
We can use the `ActiveStorage::Blob` class to find where the file is
supposed to be stored instead of manually setting the path. This is also
more robust because it works with Active Storage configurations which
don't store files in the default folder.
2021-09-24 13:39:15 +02:00
Javi Martín
619d402f92 Add task to migrate files to Active Storage
This task was copied from Thoughtbot's migration guide [1]. They use a
migration file, but we usually use rake tasks to migrate data.

[1] https://github.com/thoughtbot/paperclip/blob/master/MIGRATING.md
2021-09-24 13:39:15 +02:00
Javi Martín
1290e2ecd3 Store files with both Paperclip and ActiveStorage
In order to migrate existing files from Paperclip to ActiveStorage, we
need Paperclip to find out the files associated to existing database
records. So we can't simply replace Paperclip with ActiveStorage.

That's why it's usually recommended [1] to first run the migration and
then replace Paperclip with ActiveStorage using two consecutive
deployments.

However, in our case we can't rely on two consecutive deployments
because we have to make an easy process so existing CONSUL installations
don't run into any issues. We can't just release version 1.4.0 and 1.5.0
and day and ask everyone to upgrade twice on the same day.

Instead, we're following a different plan:

* We're going to provide a Rake task (which will require Paperclip) to
  migrate existing files
* We still use Paperclip to generate link and image tags
* New files are handled using both Paperclip and ActiveStorage; that
  way, when we make the switch, we won't have to migrate them, and in
  the meantime they'll be accessible thanks to Paperclip
* After we make the switch, we'll update the `name` column in the active
  storage attachments tables in order to remove the `storage_` prefix

Regarding our handling of new files, the exception are cached
attachments. Since those attachments are temporary files used while
submitting a form and we have to delete them afterwards, we're only
handling them with Paperclip. We'll handle these ones in version 1.5.0.

Note the task creating the dev seeds was failing after these changes
with an `ActiveStorage::IntegrityError` exception because we were
opening some files without closing them. If the same file was attached
twice, it failed the second time.

We're solving it by closing the files with `File.open` and a block. Even
though we didn't get any errors, we're doing the same thing in the
`Attachable` concern because it's a good practice to close files after
we're done with them.

Also note we have to change the CKEditor Active Storage code so it's
compatible with Paperclip. In this case, I haven't been able to write a
test to confirm the attachment exists; I was getting the same
`ActiveStorage::IntegrityError` mentioned above.

Finally, we're updating the site customization image controller to use
`update` so the image and the attachment are updated within the same
transaction. This is also what we do in most controllers.

[1] https://www.youtube.com/watch?v=tZ_WNUytO9o
2021-09-24 13:39:15 +02:00
Javi Martín
f412ab2c9a Add CKEditor support for ActiveStorage
ActiveStorage support was added to CKEditor in version 5.1.0. However,
we can't upgrade to version 5.0.0 or later because it only supports
loading CKEditor via CDN.

So we're copying the code related to ActiveStorage instead. I tried to
move it to the `vendor/` folder, but couldn't find a way to load it from
there and if I found one I wouldn't be sure it'd work on production
environments.
2021-09-24 13:39:15 +02:00
Javi Martín
73a0a21001 Configure Active Storage 2021-09-24 13:39:15 +02:00
Javi Martín
66ef345a2d Create ActiveStorage tables
This migration was generated using the `active_storage:install` task.
2021-09-24 13:39:15 +02:00
Javi Martín
886006d497 Enable ActiveStorage
This reverts commit 7496c1bcb9.
2021-09-24 13:39:15 +02:00
Javi Martín
02825f0a23 Merge pull request #4704 from consul/hanging_tests
Add missing expectations in investments test
2021-09-24 13:38:37 +02:00
Javi Martín
4f314bf6ff Add missing expectations in investments test
We ended the test with two requests and no expectations. Debugging shows
sometimes the test was hanging forever [1], probably due to simultaenous
requests.

So now we're adding expectations after each request.

[1] https://github.com/consul/consul/runs/3687898744
2021-09-24 13:21:18 +02:00
Sebastia
a83ccdd1f9 Merge pull request #4702 from consul/improve-moderator-activity
Add sanitize to description on moderator activity
2021-09-23 16:46:46 +02:00
Javi Martín
9e85d29ee2 Merge pull request #4681 from consul/setting_switch
Use a switch control to enable/disable features
2021-09-23 13:48:57 +02:00
Javi Martín
2ca5f5c815 Add ARIA label and description to settings fields
These fields have no label associated to them. While it's more or less
obvious for sighted users that these fields are associated with the
table cell next to them, visually impaired users might not get that
association when using the screen reader in forms mode.

Note we're using `aria-label` instead of `aria-labelledby`. IMHO in this
case `aria-labelledby` is the superior method because it guarantees the
text is present for both sighted and visually impaired users. However,
testing for fields with no label other than the one provided by
`aria-labelledby` is hard since Capybara has no support for this
attribute.

So we're using `aria-label` and testing the presence of the text on the
page (with the `within "tr", text:` statements) as well as the ARIA
label (with the `fill_in` statements).
2021-09-23 13:25:22 +02:00
Javi Martín
ead5eac67f Update settings using an AJAX requests
Having to wait for a whole page refresh after updating each setting was
painful when modifying several settings.

Even though the navigation is updated immediately to reflect which
sections have been enabled/disabled, there's one gotcha. Changing the
"SDG" setting will not update the user menu (which contains a link to
SDG content) nor the "SDG Configuration" tab; refreshing the page will
be necessary to check these changes. The same happens with the map and
remote census tabs. So in these cases we're making an exception and
sending the form. We might find a better solution in the future.

For this reason, we aren't using the `switch` ARIA role. Some users
might not expect a switch control to refresh the page, just like they
usually don't expect checkboxes to refresh the page. Furthermore, screen
reader support for the `switch` role seems to be inconsistent. For
instance, NVDA with Chrome announces the control as a checkbox instead
of a switch.

Note AJAX is only used for feature settings. Other settings are still
updated with regular HTTP requests.

Since we're now using AJAX requests, we have to make sure to add an
expectation in the homepage tests in order to make sure the request has
finished before starting a new one.
2021-09-23 13:25:22 +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
71aa651f6f Fix invalid HTML in admin settings page
There were duplicate IDs and the `lines` attribute doesn't do anything
for textareas (I guess it was accidentally used instead of the `rows`
attribute; I'm just removing it so the page looks the same way it did
until now).

Even though the `value` field didn't generate duplicate IDs, we're also
changing it because we usually set an element with the `dom_id` of a
record when it contains the whole information about a record, and not
just one piece of it. For instance, in some places we assign this ID to
the table row related to the record.
2021-09-23 13:24:17 +02:00
Javi Martín
d9076b9d02 Simplify attributes in settings forms
Rails automatically assigns that id and that URL to forms for existing
records.
2021-09-23 13:24:17 +02:00
Javi Martín
e6127decac Move featured settings form partial to a component 2021-09-23 13:24:17 +02:00
taitus
8e8c009d2c Add sanitize to description on moderator activity
Currently html tags were being displayed in the description.
We used the sanitize method to not display them.
2021-09-23 11:09:10 +02:00
Javi Martín
34fcfa706f Merge pull request #4703 from consul/suggestion_specs
Wait for suggestions to finish loading in tests
2021-09-22 19:16:00 +02:00