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.
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.
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.
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.
As mentioned in commits 5311daadf and bb958daf0, using links combined
with JavaScript to generate POST (or, in this case, DELETE) requests to
the server has a few issues.
Note that the AJAX response stopped working after replacing the link
with a button. Not sure about the reason, but, since this is one of the
very few places where we use AJAX calls to delete content, the easiest
solution is to stop using AJAX and be consistent with what we do in the
rest of the admin section.
In the admin section, when clicking on a link that leads to a page in
the public area, sometimes the page was opened in the same window and
sometimes it would open in a new window, with no clear criteria
regarding when either scenario would take place.
This was really confusing, so now we're more consistent and open
(almost) every link in the same window. The main reason behind it is
simple: if we add `target: _blank`, people who want to open those links
in the same window can no longer do so, so we're taking control away
from them. However, if we don't add this attribute, people can choose
whether to open the link on the same tab or to open it on a new one,
since all browsers implement a method to do so.
More reasons behind this decision can be found in "Opening Links in New
Browser Windows and Tabs" [1].
We're keeping some exceptions, though:
* Opening the link to edit an investment on the same tab would result in
losing all the investment filters already applied when searching for
investments, so until we implement a way to keep these filters, we're
also opening the link to edit an investment in a new tab
* For now, we're also opening links to download files in a new window;
we'll deal with this case in the future
[1] https://www.nngroup.com/articles/new-browser-windows-and-tabs/
We were adding <div> tags with the `images` or `documents` HTML class
prettly much every time we rendered a NestedComponent. We're now
including the HTML class inside the component, as we usually do.
We're also rendering the nested components directly, since it's been a
while since the partials were changed to simply render the components.
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.
Note that the `create` action doesn't create an image but updates an
answer instead. We're removing the references to `:create` in the
abilities since it isn't used.
In the future we might change the form to add an image to an answer
because it's been broken for ages since it shows all the attached
images.
Adding, modifiying, and/or deleting questions for an already started
poll is far away from being democratic and can lead to unwanted side
effects like missing votes in the results or stats.
So, from now on, only modifiying questions will be possible only if
the poll has not started yet.
In this form, the only case where `poll` might be present without
`question.poll` being present to is going to be the `new` action. We can
assign the poll in the `new` action and get rid of the `poll` variable
in the form.
We were already saving it as a time, but we didn't offer an interface to
select the time due to lack of decent browser support for this field
back when this feature was added.
However, nowadays all major browsers support this field type and, at the
time of writing, at least 86.5% of the browsers support it [1]. This
percentage could be much higher, since support in 11.25% of the browsers
is unknown.
Note we still need to support the case where this field isn't supported,
and so we offer a fallback and on the server side we don't assume we're
always getting a time. We're doing a strange hack so we set the field
type to text before changing its value; otherwise old Firefox browsers
crashed.
Also note that, until now, we were storing end dates in the database as
a date with 00:00 as its time, but we were considering the poll to be
open until 23:59 that day. So, in order to keep backwards compatibility,
we're adding a task to update the dates of existing polls so we get the
same behavior we had until now.
This also means budget polls are now created so they end at the
beginning of the day when the balloting phase ends. This is consistent
with the dates we display in the budget phases table.
Finally, there's one test where we're using `beginning_of_minute` when
creating a poll. That's because Chrome provides an interface to enter a
time in a `%H:%M` format when the "seconds" value of the provided time
is zero. However, when the "seconds" value isn't zero, Chrome provides
an interface to enter a time in a `%H:%M:%S` format. Since Capybara
doesn't enter the seconds when using `fill_in` with a time, the test
failed when Capybara tried to enter a time in the `%H:%M` format when
Chrome expected a time in the `%H:%M:%S` format.
To solve this last point, an alternative would be to manually provide
the format when using `fill_in` so it includes the seconds.
[1] https://caniuse.com/mdn-html_elements_input_type_datetime-local
This is consistent with the way we show the duration of a budget and its
phases. Since budgets are the section with the most recent changes in
the admin area, we're using it as a reference.
Note that, unlike budgets (which are shown to finish at the beginning of
their ending day), a poll has always been considered to finish at the
end of their ending day, so we're showing it this way.
We're also solving a minor usability issue. While it's pretty intuitive
that a poll starting on a certain date will start at the beginning of
the day, a poll ending on a certain date isn't clear about when it
finishes exactly: is it at the beginning of the day, or at the end of
the day?
So now we're making this point clear.
In some cases (e.g. after editing or creating a resource
with errors) the default back_link did not redirect to the
expected page.
Now we force the back_links to the index pages, so we
always get the desired redirect.
Until now, in order to edit an answer, we had to click on its title on
the table and then on the "Edit answer" link.
That was tedious and different from what we usually do in the admin
section. Furthermore, the code for the answers table was written twice
and when we modified it we forgot to update the one in the `show`
action, meaning the table here provided less information than the
information present in the answers tables.
Co-Authored-By: Javi Martín <javim@elretirao.net>
We might change the style of this caption or remove it completely in the
future. In the meantime, we use the right HTML tag for the task to give
information regarding what the table is about, and that tag is
`<caption>`.
Since we were creating a new answer in the form, we weren't getting the
errors associated to the answer the administrator was trying to create,
and so we were skipping the test.
Using the answer which contains the information about validation errors
fixes the issue and so we don't have to skip the tests.
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.
This way it will be easier to change the behavior of all table actions,
like adding ARIA attributes. In the past, when we changed the behavior
of the `link_to` method, we had to change all table action classes.
The imageable/documentable object is always the object the form builder
is based on; since we're already passing the form builder, we don't have
to pass the object as well.
The only exception are the poll answers. In this case, we're passing a
new answer as the object. That's OK; the same hack that we're using to
send the data to the answer URL without displaying existing attachments
causes the form to keep working the same way.
Now the padding is only applied in two places (administration forms) so
we can apply it just there instead of applying it everywhere and then
removing it in most places. We're using the `column` class here because
it's what's used in the rest of the fields of these forms and because we
haven't defined (yet) general margin/padding rules for the
administration views.
As mentioned in commit 5214d89c8, using a `<select>` tag which
automatically submits a form on change has a few accessibility issues,
particularly for keyboard users who might accidentally submit the form
while browsing the options.
So we're adding a submit button and removing the "submit on change"
behavior.
Note that, while `<select>` tags have their own usability issues,
alternatives in this case are not obvious because the number of existing
polls could be very low (zero, for instance) or very high (dozens, if
the application has been used for years).
I thought of using a `<datalist>` tag with a regular text input. The
problem here is we don't want to send the name of the poll to the server
(as we would with a `<datalist>` tag); we want to send the ID of the
poll.
Maybe we could add an automplete field instead, providing a similar
funcionality. However, for now we're keeping it simple. This poll
questions page isn't even accessible through the admin menu since commit
83e8d603, so right now anything we change here will be pretty much
useless.
The `include_all` parameter was always used, and the option was
redundant because we already had a prompt offering the same
functionality.
I guess one possible reason was users would want to filter by all polls,
and having to click on "select a poll" to do so wasn't that intuitive.
So we're using "All" as the prompt instead.
When we see a list of, let's say, banners, and each one has a link to
edit them, the word "banner" in the text "edit banner" is redundant and
adds noise; even for users with cognitive disabilities, it's obvious
that the "edit" link refers to the banner.