We had inconsistent indentation in many places. Now we're fixing them
and adding a linter to our CI so we don't accidentally introduce
inconsistent indentations again.
As mentioned in commit 5311daadf, there are several reasons to use
buttons in these situations. And, as mentioned in the previous commits,
using buttons instead of links for actions requiring confirmation will
help us test for accessibility issues.
Having a class named `Poll::Question::Answer` and another class named
`Poll::Answer` was so confusing that no developer working on the project
has ever been capable of remembering which is which for more than a few
seconds.
Furthermore, we're planning to add open answers to polls, and we might
add a reference from the `poll_answers` table to the
`poll_question_answers` table to property differentiate between open
answers and closed answers. Having yet another thing named answer would
be more than what our brains can handle (we know it because we did this
once in a prototype).
So we're renaming `Poll::Question::Answer` to `Poll::Question::Option`.
Hopefully that'll make it easier to remember. The name is also (more or
less) consistent with the `Legislation::QuestionOption` class, which is
similar.
We aren't changing the table or columns names for now in order to avoid
possible issues when upgrading (old code running with the new database
tables/columns after running the migrations but before deployment has
finished, for instance). We might do it in the future.
I've tried not to change the internationalization keys either so
existing translations would still be valid. However, since we have to
change the keys in `activerecord.yml` so methods like
`human_attribute_name` keep working, I'm also changing them in places
where similar keys were used (like `poll_question_answer` or
`poll/question/answer`).
Note that it isn't clear whether we should use `option` or
`question_option` in some cases. In order to keep things simple, we're
using `option` where we were using `answer` and `question_option` where
we were using `question_answer`.
Also note we're adding tests for the admin menu component, since at
first I forgot to change the `answers` reference there and all tests
passed.
We were opening these links in a new tab/window because we assume they
were external links.
But, on the one hand, we don't even know whether these links are
external, since they could also point to URLs from our site. And, on the
other hand, opening external links in new windows results in usability
issues as well [1, 2].
On top of that, old browsers have security issues when opening links in
new tabs unless we add `rel="noopener"` [3], and we aren't doing so.
[1] https://www.nngroup.com/articles/new-browser-windows-and-tabs
[2] https://css-tricks.com/use-target_blank
[3] https://mathiasbynens.github.io/rel-noopener/
Out of the usability issues I've experienced when using Consul
Democracy, the biggest one has arguably been the fact that the link to
edit a proposal opens in a new tab. I guess the reasoning behind it is
that the page to edit a proposal is not part of the proposals dashboard,
but what the hell! Imagine if every link to edit something opened in a
new tab...
So we're reducing the impact of this nonsense by opening most dashboard
links in the same window; for now, we're still opening in a new window
links to download files and links that might point to external websites.
We'll address those ones in the future.
Quoting usability experts Jakob Nielsen and Anna Kaley [1]:
> [Opening PDF files in new tabs] is problematic, because it assumes
> users will always do the exact same things with certain file formats,
> which isn’t always the case.
There are many examples of this situation. For example, some people
(myself included) configure their browser so it downloads PDF files
instead of opening them in the browser. In this situation, a new tab is
opened, a blank page is displayed, the file is downloaded, and then
either the tab is closed or the blank page needs to be manually closed.
The end result is really annoying.
Other situations include people who use a mobile phone browser, where
navigating through tabs is generally much harder than doing so on a
desktop browser.
But IMHO the most important point is: every browser already provides a
way to open "regular" links in a new tab, so people can choose what to
do, but if we decide to open the link in a new tab, we take control away
from them, and people who'd like to open the link in the same tab might
feel frustrated.
In these cases, the links either say "download" or include the word
"PDF", so people know in advance that they're going to download/open a
PDF file, and so we're giving them information and, by removing the
`target` attribute, we're giving them control over their browser so they
can choose what's convenient for them.
[1] https://www.nngroup.com/articles/new-browser-windows-and-tabs
We were displaying documents in five places, and in five different ways.
Sometimes with the metadata in parenthesis after the title, sometimes
with the metadata below the title, sometimes without metadata, sometimes
with an icon in front of the document, and sometimes with a separate
link to download the file.
So we're now displaying the same thing everywhere. Not sure whether this
is the best solution, but at least it's consistent.
We aren't unifying the way we display a list of documents, though, since
different sections look pretty different and I'm not sure whether the
same style would look well everywhere.
Note that we're renaming the `document` HTML class in the documents
table to `document-row` so the styles for the `document` class don't
apply here.
This way it'll be easier to change them.
Note that there were two `.document-link` elements which aren't part of
a `.documents` element. We're renaming the HTML class of the link in
investments because it didn't contain links to download documents and
are slightly duplicating the CSS in the poll answer documents in order
to keep the `word-wrap` property.
For the HashAlignment rule, we're using the default `key` style (keys
are aligned and values aren't) instead of the `table` style (both keys
and values are aligned) because, even if we used both in the
application, we used the `key` style a lot more. Furthermore, the
`table` style looks strange in places where there are both very long and
very short keys and sometimes we weren't even consistent with the
`table` style, aligning some keys without aligning other keys.
Ideally we could align hashes to "either key or table", so developers
can decide whether keeping the symmetry of the code is worth it in a
case-per-case basis, but Rubocop doesn't allow this option.
Just like we did for budgets, we're doing the same thing in all the
places where we render background images attached by either regular
users or administrators.
This way we correctly render background images with characters like
brackets or quotes.
This task was "temporarily" removed in commit 7b6619528. Since that was
done three and a half years ago, right after the dashboard was
introduced, I think it's time to make this "temporary" measure a bit
more permanent ;).
This way we fix a bug we mentioned in commit 930bb753c which caused
links to documents to be broken when editing their title because the
title was used to generate the URL of the document.
Note we're still using Paperclip to render cached attachments because
this is the only case where we store files with just Paperclip and not
Active Storage.
With Active Storage, we render attachments just like any other resource,
using `polymorphic_path`. Paperclip included the `url` method in the
model; since the model doesn't have access to the request parameters
(like the host), this was inconvenient because it wasn't possible to
generate absolute URLs with Paperclip.
In order to simplify the code and make it similar to the way we used
Paperclip, we're adding a `variant` method accepting the name of a
variant and returning the variant.
In commit 905ac48bb we mentioned:
> Since we don't use `asset_path` to reference assets in the public
> folder, we can safely disable the `unknown_asset_fallback` option.
However, `asset_path` is used by the wicked_pdf gem when calling the
`wicked_pdf_stylesheet_link_tag` method. This method also checks the CSS
files, searching for `url()` calls and converting any relative URLs
referenced there to absolute URLs.
However, when compiling assets on production, our `application.css` file
contains the following line imported from Leaflet which says:
```
behavior: url(#default#VML);
```
When passing this URL to `asset_path` (which is something the wicked_pdf
gem does automatically), it doesn't find the URL, and so this call
crashes unless we enable then `unknown_asset_fallback` option.
Since the dashboard poster is a feature we might remove in the future,
we're avoiding changing a Rails global configuration just for this
feature. So, instead of enabling the `unknown_asset_fallback` option,
we're changing the `poster.pdf` view so it doesn't load all the CSS of
the application but only the CSS it needs.
Note we aren't adding a test case because this bug is only present on
production environments when assets have been precompiled.
Using `<a>` tags with no `href` means these elements cannot be activated
by keyboard users, so we're replacing them with buttons.
In the future we probably want to add more consistency so all toggle
buttons use the same code. We might also add styles depending on the
`aria-expanded` property.
We didn't upgrade Turbolinks when we upgraded to Rails 5 so we didn't
upgrade too many things at the same time, and postponed it... until now
:).
Note upgrading Turbolinks fixes an issue with foundation's sticky when
using the browser's back and forward buttons. We're adding tests for
these scenarios.
Co-authored-by: Senén Rodero Rodríguez <senenrodero@gmail.com>
We're going to change CKEditor to an inline editor, and the "ckeditor"
gem doesn't provide an option to do so.
Since using `cktext_area` would automatically generate a "classic"
iframe CKEditor, we need to use `text_area` and load the editor using
JavaScript. Personally I prefer this option anyway.
Note in the jQuery selector we need to use `textarea.html-area`; using
just `.html-area` would fail if there's an error message associated to
the textarea, since Rails will add the `.html-area` class to the error
message.
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.
Using the `_html` suffix in an i18n key is the same as using `html_safe`
on it, which means that translation could potentially be used for XSS
attacks.
Using `<%==` is the same as using `raw`. I'm not sure if we meant
`sanitize` in this case, or it's just a typo. I'm assuming the latter
since we don't use anything similar in any other places.
Sometimes we're interpolating a link inside a translation, and marking
the whole translations as HTML safe.
However, some translations added by admins to the database or through
crowdin are not entirely under our control.
Although AFAIK crowdin checks for potential cross-site scripting
attacks, it's a good practice to sanitize parts of a string potentially
out of our control before marking the string as HTML safe.
It's possible to create a newsletter or a proposed action with
<script> tags by filling in the body using a textarea instead of a
CKEditor. While we trust our administrators not to do so, it's better to
completely eliminate that possibility.
This way we can simplify the way we generate form fields. In some cases,
we also use the human attribute in table headers, which IMHO makes
sense.
I haven't moved all of them: for example, sometimes a label is
different depending on whether it's shown to administrators, valuators,
or users. And I haven't touched the ones related to devise, since I
wasn't sure about possible side effects.
Note I've also removed placeholders when they had the same text as their
labels, since they weren't helpful. On the contrary, the added redundant
text to the form, potentially distracting users.