Commit Graph

927 Commits

Author SHA1 Message Date
Javi Martín
7f749bb9bb Add and apply Style/CollectionQuerying rubocop rule
This rule was added in rubocop 1.77. We were following it most of the
time. It makes the code more readable in my humble opinion.
2025-11-05 14:27:12 +01:00
Javi Martín
0ca94e5443 Add and apply Rails/FindByOrAssignmentMemoization rule
This rule was added in rubocop-rails 2.33.

At first, I wasn't very fond of this rule. It made the code less
readable even if it improved performace in some cases.

Then I realized that in the `Admin::MachineLearning::SettingComponent`
we were using `find_by` when we should be using `find_by!` instead, and
we detected that thanks to this rule.

So, only for that reason, I'm adding this rule, but I'm fine if we
remove it.
2025-11-05 11:51:23 +01:00
Javi Martín
048bdb2e9e Add and apply Rails/OrderArguments rubocop rule
This rule was introduced in rubocop-rails 2.33. We were following it
most of the time.
2025-11-05 11:51:23 +01:00
Javi Martín
251968ae72 Fix mark as featured button being rendered to everyone
We introduced this issue in commit f8faabf7d.

Since this component didn't have any tests (there are system tests for
it, though), we're also adding tests that check that only the right
buttons are rendered when accessing as administrator.
2025-10-31 16:01:33 +01:00
Sebastia
a73c1184fa Merge pull request #6061 from consuldemocracy/poll_text_answers
Add support for essay poll questions
2025-10-16 15:30:22 +02:00
taitus
b1cb6f8372 Exclude open-ended questions from managing physical votes
Also make the :yes_no factory trait create a votation_type_unique
by default, since yes/no questions should always be unique.
2025-10-16 14:31:16 +02:00
taitus
f3050a1aa5 Manage correctly results and stats for open-ended questions
Note that we are not including Poll::PartialResults for open-ended
questions resutls. The reason is that we do not contemplate the
possibility of there being open questions in booths. Manually
counting and introducing the votes in the system is not feasible.
2025-10-16 14:26:30 +02:00
taitus
2a2edd17d1 Move results specs to Polls::ResultsComponent
Running tests at the component level is faster than at the system level,
so we move tests from system/polls/results_spec.rb to the component.

Note that moving these tests removes vote_for_poll_via_web and the visit
to results_poll_path, but both are already covered in other tests. We
also take the opportunity to reuse the method in another test where
it makes sense.

Additionally, the spec title has been reverted from "Results for polls
with questions but without options" to "renders results for polls with
questions but without answers", as it was before commit 8997ed316c.
2025-10-16 11:09:36 +02:00
taitus
5a69ffc619 Reduce duplicated code and simplify code related with link_to_poll method 2025-10-16 11:09:36 +02:00
taitus
5944bb85c5 Use a loop instead of with_collection to render questions
This is what we usually do in components.
2025-10-16 11:09:36 +02:00
taitus
83b206f0b7 Enable voting for open-ended questions in public section 2025-10-16 11:09:36 +02:00
taitus
4e57e311dc Add support for open-ended questions in admin section
Introduce a new "open" votation type for poll questions in the admin
interface. This type allows open answers provided by the user.
2025-10-15 15:52:12 +02:00
taitus
eb10a3135b Refactor vote type descriptions to use data attributes
This makes it easier to extend support for new types (e.g., 'open')
without adding more conditional logic to the JavaScript.
2025-10-10 13:20:49 +02:00
Johann
e7f2210380 Add setting to require consent for notifications
Ensure GDPR compliance by default (Article 25 GDPR – privacy by design
and by default). Under GDPR, consent must be freely given, specific,
informed and unambiguous [1]. We were subscribing users without
explicity consent, which goes against the "No pre-ticked boxes"
principle.

For compatibility with existing installations, we're using a setting,
disabled by default. Once we release version 2.4.0 we will enable it by
default, which won't affect existing installations but only new ones.

[1] https://gdprinfo.eu/best-gdpr-newsletter-consent-examples-a-complete-guide-to-compliant-email-marketing
2025-10-09 10:53:00 +02:00
taitus
a29eeaf2e2 Add option_id to partial results and unique index
Similar to what we did in PR "Avoid duplicate records in poll answers" 5539,
specifically in commit 503369166, we want to stop relying on the plain text
"answer" and start using "option_id" to avoid issues with counts across
translations and to add consistency to the poll_partial_results table.

Note that we also moved the `possible_answers` method from Poll::Question to
Poll::Question::Option, since the list of valid answers really comes from the
options of a question and not from the question itself. Tests were updated
to validate answers against the translations of the assigned option.

Additionally, we renamed lambda parameters in validations to improve clarity.
2025-09-26 15:05:34 +02:00
taitus
f2153f2b4d Extract officing results index to component 2025-09-26 09:59:10 +02:00
taitus
e3e475b4df Add votes_for(option) method and simplify results template
Move the summing logic from the template into the component. Introduce
a votes_for(option) method that looks up grouped partial results and
returns the total amount or 0.
2025-09-26 09:59:10 +02:00
taitus
7565fc5fc2 Remove redundant by_question grouping in Admin::Poll::Results::QuestionComponent
Stop grouping partial results by question_id inside the component.

Note that group_by on an empty collection already returns
an empty hash, so the previous "|| {}" is not needed.
2025-09-26 09:59:08 +02:00
taitus
7996933fc2 Extract by_answer variable to component method 2025-09-26 09:58:20 +02:00
taitus
7f376c3005 Extract admin poll results to component
Note that we have the same code in the officing section.
Then we can use the same component.

Note also that we are removing the parts of the system specs that are now
covered by the component itself, and taking the chance to unify tests.
In these removals and unifications we take into account that there are
other specs which already cover user interaction in this section.
2025-09-26 09:58:17 +02:00
Javi Martín
3cf6e9b1ca Merge pull request #6046 from Anamika1608/oidc_auth
Add support for OIDC authentication
2025-09-01 19:55:10 +02:00
Anamika Aggarwal
5e263baed2 Add OIDC section for sign in and sign up page
- name: :oidc → Identifier for this login provider in the app.
- scope: [:openid, :email, :profile] → Tells the provider we want the user’s ID (openid), their email, and basic profile info (name, picture, etc.).
- response_type: :code → Uses Authorization Code Flow, which is more secure because tokens are not exposed in the URL.
- issuer: Rails.application.secrets.oidc_issuer → The base URL of the OIDC provider (e.g., Auth0). Used to find its config.
- discovery: true → Automatically fetches the provider’s endpoints from its discovery document instead of manually setting them.
- client_auth_method: :basic → Sends client ID and secret using HTTP Basic Auth when exchanging the code for tokens.

Add system tests for OIDC Auth

Edit the oauth docs to support OIDC auth
2025-08-29 12:20:16 +02:00
taitus
3b08fa2e05 Use grid instead of Equalizer in dashboard polls 2025-08-27 17:40:45 +02:00
Javi Martín
de303aa1df Extract component to render dashboard polls
Just like we usually do when reorganizing code.
2025-08-27 17:40:45 +02:00
taitus
fc0d79b47b Move dashboard poll partial to component 2025-08-27 17:40:45 +02:00
taitus
1e06e676a4 Move dashboard system tests to resources component specs
We're making the `new_actions_since_last_login` parameter optional in
order to simplify the tests.
2025-08-27 17:40:45 +02:00
taitus
1dc4f1c534 Use grid instead of equalizer in dashboard resources
Move resource cards layout inside #available-resources-section and switch
from equalizer alignment to a responsive grid layout.

Note that using `grid-auto-rows: 1fr` requires us to change the CSS of
the card itself so the "see resource" link remains at the bottom of the
card.
2025-08-27 17:40:45 +02:00
taitus
1f97a996f8 Move resource partial to a component
We're renaming it to ActiveResource in order to better differentiate it
from the DefaultResource component.
2025-08-27 17:40:45 +02:00
taitus
9b0675aa06 Unify dashboard default resources partials to a component 2025-08-27 17:40:45 +02:00
taitus
048c8ce917 Move dashboard resources partial to a component
We're renaming the HTML class (and removing the id attribute, which was
only used in tests) in order to follow our naming conventions.
2025-08-27 17:40:45 +02:00
Javi Martín
4e129e7d9c Use grid instead of equalizer in recommendations
It's August 2025 and support for grid layout has been available in about
99% of the browsers for some time now. All major browsers added support
for grid layouts in 2017, which means our rule to support browsers that
are 7 years old allows us to start using `display: grid`.

Using a grid layout allows displaying a dynamic number of rows while
keepin all of them the same height, the same foundation's equalizer
does, by setting `grid-auto-rows: 1fr`.

And the `grid-template-columns` property lets us use dynamic columns for
all screen sizes, always filling the available space. No need to use
breakpoints.
2025-08-27 17:38:37 +02:00
Javi Martín
34d87dff98 Use a list of links to display recommendations
We were using an <h3> tag with no content associated to it. This is like
having a chapter in a book with only the title.
2025-08-22 13:45:04 +02:00
Javi Martín
054fbf585e Simplify recommended index component parameters
We can get the path if we know the namespace, so we don't need to pass
both of them.
2025-08-22 13:42:41 +02:00
Javi Martín
3347e85017 Use a different parameter name in recommendex index
The problem with "recommended" is that it had identical singular and
plural, which means it wasn't clear whether we were using it to refer to
an item of a collection or to refer to the collection itself.
2025-08-22 13:40:45 +02:00
Javi Martín
34c8559065 Remove helper that returned a polymorphic path
This is similar to what we did in commits 1a902a967 and fa3781059.
2025-08-22 13:38:03 +02:00
Javi Martín
f5793013c9 Remove unused block parameter in recommended index 2025-08-22 13:37:52 +02:00
Javi Martín
a548c497fc Move recommended index partial to a component
Thanks to it, we can slightly simplify the debates view rendering it.
2025-08-22 13:32:04 +02:00
Javi Martín
d34c9905a4 Use flex instead of equalizer in following
We're also removing the padding in the (now called) followables element,
since it caused a gap on the right side of the border of the
`.menu.simple` element.
2025-08-22 13:31:55 +02:00
Javi Martín
909272d879 Move users following partial to a component 2025-08-22 13:25:50 +02:00
Javi Martín
c4d69416ca Use flex instead of equalizer in polls results
Note that the sidebar class isn't used since commit b91b766e9, so we're
removing it.
2025-08-22 13:25:30 +02:00
Javi Martín
22b0c04cf4 Use a component to render poll results
We're also renaming the `poll-results-stats` class to `poll-results`.
The former name was confusing because it had nothing to do with stats.
2025-08-22 13:19:04 +02:00
Javi Martín
8ca941ab02 Use flex in a poll in the polls index
Note we aren't using flex-with-gap because currently (until we decide to
use the `gap` property) this mixin sets a negative margin that would
move the border of this element to the left.
2025-08-22 13:12:10 +02:00
Javi Martín
b00ddfc931 Move helper method to the component 2025-08-22 13:12:10 +02:00
Javi Martín
1b9d321c4e Extract methods in poll status component
This way we remove duplication in the HTML.

We're also adding a test checking what happens when users can vote in
order to test the `render?` method we've added.
2025-08-22 13:09:49 +02:00
Javi Martín
b2a49cd291 Extract component to render the status of a poll
We're renaming the existing HTML class in order to be consistent with
the name of the component.
2025-08-22 12:13:41 +02:00
Javi Martín
4b7700b6f5 Add a border for each question in the poll form
This way polls look more similar to the way they did when the answers
were buttons instead of checkboxes or radio buttons.

Note the styling is tricky because we need to add a `float` property to
the legend so it's actually inside the fieldset. This forces us to add a
`::before` pseudo-element in order to add margin between the legend and
the first label. Another option would be:

```
legend {
  &:has(+ label) {
    margin-bottom: calc($line-height / 2);
  }

  + label {
    clear: $global-left;
  }
}
```

But the `:has` pseudo-class isn't universally supported yet, and we'd
still have to add `margin-top` to the first label when it comes after a
`.help-text` element.

Due to the presence of the border, we're increasing the margin between
elements a little bit.

Note that adding a pseudoelement to the label is a consequence of adding
the `float` property to the legend, so we're changing the order of the
code so the styles for `legend` appear before the styles in `label`.
2025-08-14 13:59:07 +02:00
Javi Martín
8deb1964bd Show errors when submitting too many answers
This could be the case when JavaScript is disabled.

Note that, in `Poll/WebVote` we're calling `given_answers` inside a
transaction. Putting this code before the transaction resulted in a test
failing sometimes, probably because of a bug that might be possible to
reproduce by doing simultaneous requests.
2025-08-14 13:06:43 +02:00
werdenktwas-gmbh
abf02808bf Disable other answers when reaching maximum votes
This is similar to the way we were disabling buttons in the old design.

Co-authored-by: Javi Martín <javim@elretirao.net>
2025-08-14 13:06:43 +02:00
Javi Martín
7ea4f63b07 Allow blank votes in polls via web
With the old interface, there wasn't a clear way to send a blank ballot.
But now that we've got a form, there's an easy way: clicking on "Vote"
while leaving the form blank.
2025-08-14 13:06:43 +02:00
Javi Martín
cd134ed44f Remove unused HTML class in polls callout
This class was added in commit 3d22c556e but was never used.
2025-08-14 13:06:43 +02:00