Compare commits

...

170 Commits

Author SHA1 Message Date
filipefurtad0
f18487ea68 Update all locales with the latest Transifex translations 2025-11-10 11:22:54 +00:00
Maikel
7c4714288d Merge pull request #13675 from deivid-rodriguez/unify-linters
Unify linters and linter related tools
2025-11-10 16:24:36 +11:00
Maikel
b6e393eabb Merge pull request #13662 from filipefurtad0/spec_deprecation_nil_in_sum
Catches exceptions on final_weight_volume inputs
2025-11-10 15:25:49 +11:00
Gaetan Craig-Riou
d18aeb9918 Merge pull request #13687 from openfoodfoundation/dependabot/bundler/openid_connect-2.3.1
Bump openid_connect from 2.3.0 to 2.3.1
2025-11-10 15:15:32 +11:00
Maikel
587f76415b Merge pull request #13656 from pacodelaluna/replace-alias-attribute-with-alias-method
Replace alias_attribute with alias_method
2025-11-10 11:50:33 +11:00
dependabot[bot]
665aee6eb0 Bump openid_connect from 2.3.0 to 2.3.1
Bumps [openid_connect](https://github.com/nov/openid_connect) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/nov/openid_connect/releases)
- [Changelog](https://github.com/nov/openid_connect/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nov/openid_connect/compare/v2.3.0...v2.3.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 00:48:19 +00:00
Gaetan Craig-Riou
5e505c1240 Merge pull request #13683 from openfoodfoundation/dependabot/bundler/omniauth_openid_connect-0.8.0
Bump omniauth_openid_connect from 0.7.1 to 0.8.0
2025-11-10 11:46:51 +11:00
Gaetan Craig-Riou
e948f89625 Merge pull request #13682 from openfoodfoundation/dependabot/bundler/activerecord-session_store-2.2.0
Bump activerecord-session_store from 2.1.0 to 2.2.0
2025-11-10 11:31:56 +11:00
Gaetan Craig-Riou
f42b91f414 Merge pull request #13681 from openfoodfoundation/dependabot/bundler/spring-4.4.0
Bump spring from 4.2.1 to 4.4.0
2025-11-10 11:25:57 +11:00
Rachel Arnould
94bda6d0f8 Merge pull request #13592 from rioug/13266-tag-variant-tag-rule
[Variant tags] Add tag rules for variant
2025-11-07 14:14:50 +01:00
Filipe
1422b440e4 Merge pull request #13493 from dacook/bump-stripe-v13
Bump stripe to v13
2025-11-06 13:48:52 +00:00
Filipe
95ad87d840 Merge pull request #13666 from chahmedejaz/bugfix/13519-order-disappear-from-orders-page
Order lines are deleted when one tries to capture a payment after order cycle is closed
2025-11-06 13:07:36 +00:00
Konrad
7357419f6f Merge pull request #13652 from navaneethkp36/13651-fix-button-size-order-confirmation
Make the width of "Back to Store" and "Back to Website" buttons consistent with other buttons in order confirmation page
2025-11-05 19:29:42 +01:00
filipefurtad0
8e5404a268 Replaces negative assertion with a positive assertion
Adds test case on white spece

Refactors to have tests as shared_examples
2025-11-05 11:12:55 +00:00
filipefurtad0
04fc729a5a Changes tests not to trigger error
after https://github.com/openfoodfoundation/openfoodnetwork/pull/13571 was merged
2025-11-05 10:34:52 +00:00
filipefurtad0
8818a98230 Catches exceptions on final_weight_volume inputs 2025-11-05 10:34:52 +00:00
David Rodríguez
d3efa3afa6 Remove pretty-quick
Because:

* We already have reviewdog running prettier in CI.
* We already removed the associated commit hooks.
* Running plain prettier is already very fast in our case.
2025-11-05 10:08:04 +01:00
David Rodríguez
4414879b3f Completely remove codeclimate as well
Most of it is already disabled, and the stuff that's not actually
disabled don't seem worth enough for me to keep it.
2025-11-05 10:08:04 +01:00
David Rodríguez
3c7aac59e9 Remove ancient rubocop plugin from codeclimate config
We already get RuboCop offense information through reviewdog.
2025-11-05 10:08:04 +01:00
David Rodríguez
41cd40a55b Completely get rid of hound
We already get RuboCop offense information through reviewdog.
2025-11-05 10:08:04 +01:00
David Rodríguez
a0e8111b3a Remove spurious scss-lint configuration
It was broken due to several reasons:

* Bad globs from not catching up after file renames.
* Bad rule indentation.

Also, the scss-lint project itself recommends using other tools, because
it relies on the ruby SASS implementation while upstream has moved to a
dart-based implementation.

Even when you fix the config and try to run the tool, you feel the pain
of this deviation:

```
$ scss-lint
(...)

app/webpacker/css/admin/grid.scss:10:1 [E] Syntax: Syntax Error: Invalid CSS after "$col-width: math": expected selector or at-rule, was ".div($total-col..."

(...)
```

The grid.scss file use using `math.div` feature, which is only supported
by the `sass` version based on dart. `scss-lint` will never be able to
parse this file at all.

Also, we're already handling scss rule formatting through prettier.

Because of all these reasons, it's best to forget about scss-lint.
2025-11-05 10:08:03 +01:00
David Rodríguez
8f07ee5bf7 Move haml-lint from hound to reviewdog
We can somewhat easily get it passing and integrate nice with reviewdog
by adding a TODO file for the rules that we had enabled, so that we
don't need to correct anything now, but we still get alerted for new
offenses. So I say let's keep it and enforce it from now on.
2025-11-05 10:08:03 +01:00
David Rodríguez
43da235d15 Make sure all linters run even if some of them fails 2025-11-05 10:08:03 +01:00
dependabot[bot]
3252de19a3 Bump omniauth_openid_connect from 0.7.1 to 0.8.0
Bumps [omniauth_openid_connect](https://github.com/omniauth/omniauth_openid_connect) from 0.7.1 to 0.8.0.
- [Changelog](https://github.com/omniauth/omniauth_openid_connect/blob/master/CHANGELOG.md)
- [Commits](https://github.com/omniauth/omniauth_openid_connect/compare/v0.7.1...v0.8.0)

---
updated-dependencies:
- dependency-name: omniauth_openid_connect
  dependency-version: 0.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-05 09:04:05 +00:00
dependabot[bot]
fd3bd062fe Bump activerecord-session_store from 2.1.0 to 2.2.0
Bumps [activerecord-session_store](https://github.com/rails/activerecord-session_store) from 2.1.0 to 2.2.0.
- [Release notes](https://github.com/rails/activerecord-session_store/releases)
- [Changelog](https://github.com/rails/activerecord-session_store/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/activerecord-session_store/compare/v2.1.0...v2.2.0)

---
updated-dependencies:
- dependency-name: activerecord-session_store
  dependency-version: 2.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-05 09:02:12 +00:00
dependabot[bot]
029d447d98 Bump spring from 4.2.1 to 4.4.0
Bumps [spring](https://github.com/rails/spring) from 4.2.1 to 4.4.0.
- [Release notes](https://github.com/rails/spring/releases)
- [Changelog](https://github.com/rails/spring/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rails/spring/compare/v4.2.1...v4.4.0)

---
updated-dependencies:
- dependency-name: spring
  dependency-version: 4.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-05 09:01:40 +00:00
David Cook
8e5fac9fb3 Merge pull request #13632 from rioug/security-247-code-injection
[security] Fix potential code injection
2025-11-05 16:34:37 +11:00
Gaetan Craig-Riou
30c0bcc910 Merge pull request #13678 from deivid-rodriguez/remove-debugger-linecache
Remove debugger-linecache
2025-11-05 11:14:11 +11:00
Gaetan Craig-Riou
1a4ba9b689 Merge pull request #13672 from openfoodfoundation/dependabot/bundler/i18n-tasks-1.0.15
Bump i18n-tasks from 1.0.14 to 1.0.15
2025-11-05 10:21:46 +11:00
Gaetan Craig-Riou
4de8191e27 Merge pull request #13579 from openfoodfoundation/dependabot/bundler/flipper-ui-1.3.6
Bump flipper-ui from 1.3.0 to 1.3.6
2025-11-05 10:06:43 +11:00
Gaetan Craig-Riou
472ca5a16b Merge pull request #13490 from openfoodfoundation/dependabot/bundler/turbo_power-0.7.0
Bump turbo_power from 0.6.2 to 0.7.0
2025-11-05 10:00:07 +11:00
Gaetan Craig-Riou
dab626031b Merge pull request #13041 from openfoodfoundation/dependabot/npm_and_yarn/turbo_power-0.7.1
Bump turbo_power from 0.7.0 to 0.7.1
2025-11-05 09:57:40 +11:00
Ahmed Ejaz
913dded766 Refactor order cycle handling to simplify closed cycle checks and improve redirection messaging 2025-11-05 02:50:01 +05:00
filipefurtad0
a36b7ce01a deletes all old VCR cassettes 2025-11-04 15:40:45 +00:00
David Cook
e4be336630 Bump Stripe to v13 2025-11-04 15:36:53 +00:00
David Cook
cae13df2c7 Bump Stripe to v12
re-recording cassettes with script/test-stripe-live
2025-11-04 15:32:05 +00:00
David Cook
81796db6e5 Fix date-dependent spec 2025-11-04 15:17:45 +00:00
David Cook
ba3553854e Allow script to continue if you've already deleted the old files 2025-11-04 15:17:45 +00:00
David Rodríguez
c386d1af01 Remove debugger-linecache
This gem has not been updated since 2013 and serves no purpose these
days.
2025-11-04 10:22:37 +01:00
dependabot[bot]
9916b361e4 Bump turbo_power from 0.6.2 to 0.7.0
Bumps [turbo_power](https://github.com/marcoroth/turbo_power-rails) from 0.6.2 to 0.7.0.
- [Release notes](https://github.com/marcoroth/turbo_power-rails/releases)
- [Commits](https://github.com/marcoroth/turbo_power-rails/compare/v0.6.2...v0.7.0)

---
updated-dependencies:
- dependency-name: turbo_power
  dependency-version: 0.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 11:05:43 +00:00
François Turbelin
b2d7d797d9 Use wrap_parameters to handle address params on Customer v1 API 2025-11-03 11:35:39 +01:00
François Turbelin
e385b9f708 Revert "Use customer-nested params for Customer v1 API writing operations"
This reverts commit cf4cd311b3.
2025-11-03 10:32:26 +01:00
dependabot[bot]
2b9b02aeea Bump i18n-tasks from 1.0.14 to 1.0.15
Bumps [i18n-tasks](https://github.com/glebm/i18n-tasks) from 1.0.14 to 1.0.15.
- [Release notes](https://github.com/glebm/i18n-tasks/releases)
- [Changelog](https://github.com/glebm/i18n-tasks/blob/main/CHANGES.md)
- [Commits](https://github.com/glebm/i18n-tasks/compare/v1.0.14...v1.0.15)

---
updated-dependencies:
- dependency-name: i18n-tasks
  dependency-version: 1.0.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 09:06:01 +00:00
dependabot[bot]
009b5e5ff1 Bump flipper-ui from 1.3.0 to 1.3.6
Bumps [flipper-ui](https://github.com/flippercloud/flipper) from 1.3.0 to 1.3.6.
- [Release notes](https://github.com/flippercloud/flipper/releases)
- [Changelog](https://github.com/flippercloud/flipper/blob/main/Changelog.md)
- [Commits](https://github.com/flippercloud/flipper/compare/v1.3.0...v1.3.6)

---
updated-dependencies:
- dependency-name: flipper-ui
  dependency-version: 1.3.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 17:31:57 +11:00
dependabot[bot]
7c310e7e46 Bump turbo_power from 0.7.0 to 0.7.1
Bumps [turbo_power](https://github.com/marcoroth/turbo_power) from 0.7.0 to 0.7.1.
- [Release notes](https://github.com/marcoroth/turbo_power/releases)
- [Commits](https://github.com/marcoroth/turbo_power/compare/v0.7.0...v0.7.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 05:17:35 +00:00
Gaetan Craig-Riou
bd0db57768 Per review, more concise code 2025-11-03 15:58:27 +11:00
Gaetan Craig-Riou
bb8ecccc31 Fix variant tag rules endpoint
It now returns tag rules filtered on the preferred variant tags and not
the prefered customer tags
2025-11-03 15:50:12 +11:00
Gaetan Craig-Riou
ffd5817749 Add spec for variant_tag_rules 2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
1a68236c3c Add variant_tag_rule ability
It's needed to allow enterprise user to get a tag autocomplete. Classic
mistake of not testing with a non superadmin user.
2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
c057bab493 Use route helpers for autocomplete url
Co-authored-by: Maikel <maikel@email.org.au>
2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
59340c7cff Per review, remove unnecessary new translation 2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
aebb18da99 Per review, improve specs 2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
ce60335a60 Per review, fix leftover comment 2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
307acdd9d1 Per review, fixing specs descriptions 2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
d51e257904 Fix order cycle tag rule specs
It works better when you actually save the changes to the tag_list...
2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
07a3e83dc6 Fix enterprise specs
Plus small refactor
2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
38f58b168a Fix tag rules spec
Make sure the autocomplete dropdown list is hidden by default
2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
34abca5ff1 Add missing js unit test got TagListInput component 2025-11-03 14:25:48 +11:00
Gaetan Craig-Riou
145764a921 Add testing library
See :https://testing-library.com/docs/
It allows us to query DOM node in way that's similar to how a user would
interect with element on the page. It's particularly usefull for
elements that trigger AJAX request.
2025-11-03 14:25:40 +11:00
Gaetan Craig-Riou
9bbe573335 Fix test to match the improved controller 2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
c5d5694f24 Tweaked jest configuration
- include app/components in the directories to search for modules, ie we
  can require view component js controller like this :
  `import tag_list_input_controller from "tag_list_input_component/tag_list_input_controller";`
- fixed the regexp to skip transformation so it skips any modules
  starting by "stimulus"
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
ab194a0e80 Add styling for the dropdown
It's mostly the same styling as the AngularJs version but with updated
colors
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
749944fc25 Rework TagListInputComponent to integrate autocomplete
The component now will try to load a list of existing tag if you give an
`autocomplete_url`. I tried to keep the tag input and the autocomplete
functionality decoupled but is wasn't really possible. Instead I opted
to sub class the Autocomplete stimulus controller, but it only gets
initialised if we pass an `autocomplete_url`.
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
3cffc5538a Add tag filtering for tag autocomplete 2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
6d7908e1f8 Style formatting 2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
965b34318f Add new component to provide tag autocomplete for variant tag
It uses composition and inject the TagListInputComponent as a depency,
which should be more flexible that creating a sub class. This new
component could potentially be made more generic if needed
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
3bb9eb9765 Add endpoint to provide autocomplete tag for variant
It return a list of available tags and number of related rules, based on
the given enterprise and a partial match on the given tag
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
bd39595917 Add ability to pass option to the tag input field
And also render any content given to the component via block
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
81e16a9cdf Add stimulus-autocomplete package
https://github.com/afcapel/stimulus-autocomplete/tree/main
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
c38c8bcff2 Pass the variant_tag_enbabled options to relevant services
Plus add integration testing for variant tag rule filtering.
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
7633af8ff2 Call VariantTagRulesFilterer when variant_tag feature is enabled
We only support either inventory or variant_tag feature, with the later
taking precedence if both are turned on.
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
94c0ebd897 Fix error in the muliple tag rules spec 2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
7b3db4bae4 Add VariantTagRuleFilterer to filter variants by tag rule 2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
b1d95cac7f Display filter by variant tag rule
We only support one of filter by inventory variants or filter by variants
at any given time, based on enabled feature. If both features inventory
and variant tag are enabled, variant tag takes precedence.
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
3f297a8afa Add tag rule to filter by variant 2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
af111a9625 Clean up tag rules specs
Remove unnecessary use mocking and use of `__send__`
2025-11-03 14:25:05 +11:00
Gaetan Craig-Riou
96f715b62b Merge pull request #13661 from deivid-rodriguez/ruby-3.2
Bump Ruby from 3.1.7 to 3.2.9
2025-11-03 13:29:40 +11:00
Maikel
33b4e38fc5 Merge pull request #13664 from openfoodfoundation/dependabot/npm_and_yarn/jasmine-core-5.12.1
Bump jasmine-core from 5.12.0 to 5.12.1
2025-11-03 13:11:49 +11:00
Maikel
27e4ae9892 Merge pull request #13639 from deivid-rodriguez/verify-latest-reviewdog
Upgrade to latest reviewdog
2025-11-03 12:28:01 +11:00
Gaetan Craig-Riou
f434d8b066 Merge pull request #13658 from openfoodfoundation/dependabot/bundler/paranoia-2.6.4
Bump paranoia from 2.6.3 to 2.6.4
2025-11-03 12:05:44 +11:00
Gaetan Craig-Riou
43d471f93d Merge pull request #13657 from openfoodfoundation/dependabot/npm_and_yarn/hotwired/turbo-8.0.20
Bump @hotwired/turbo from 8.0.13 to 8.0.20
2025-11-03 12:03:58 +11:00
Ahmed Ejaz
3794f69cad Add shared examples to handle closed order cycle in checkout process 2025-11-02 01:48:10 +05:00
François Turbelin
cf4cd311b3 Use customer-nested params for Customer v1 API writing operations 2025-10-31 14:39:55 +01:00
François Turbelin
275326eaa6 Replace alias_attribute with alias_method 2025-10-31 14:26:33 +01:00
David Rodríguez
0c392d5302 Drop version constraints for pg and pry entirely, so their versions can be fully managed by Dependabot
Co-authored-by: Maikel <maikel@email.org.au>
2025-10-31 09:18:12 +01:00
David Rodríguez
e71a2603bd Bump pry to a version that plays nice with Ruby 3.2
Otherwise you get the following error when starting RSpec:

```
(...)
An error occurred while loading base_spec_helper.
Failure/Error: require 'pry' unless ENV['CI']

NameError:
  undefined method `=~' for class `Pry::Code'
# ./spec/base_spec_helper.rb:10:in `<top (required)>'
No examples found.
(...)
```
2025-10-31 09:18:11 +01:00
David Rodríguez
5aea527962 Use Bundler version that comes with Ruby 3.2.9 by default 2025-10-31 09:18:11 +01:00
David Rodríguez
05b3e97a0e Bump Ruby from 3.1.7 to 3.2.9
Release announcements:

* https://www.ruby-lang.org/en/news/2025/07/24/ruby-3-2-9-released/
* https://www.ruby-lang.org/en/news/2025/03/26/ruby-3-2-8-released/
* https://www.ruby-lang.org/en/news/2025/02/04/ruby-3-2-7-released/
* https://www.ruby-lang.org/en/news/2024/10/30/ruby-3-2-6-released/
* https://www.ruby-lang.org/en/news/2024/07/26/ruby-3-2-5-released/
* https://www.ruby-lang.org/en/news/2024/04/23/ruby-3-2-4-released/
* https://www.ruby-lang.org/en/news/2024/01/18/ruby-3-2-3-released/
* https://www.ruby-lang.org/en/news/2023/03/30/ruby-3-2-2-released/
* https://www.ruby-lang.org/en/news/2023/02/08/ruby-3-2-1-released/
* https://www.ruby-lang.org/en/news/2022/12/25/ruby-3-2-0-released/

Also autocorrect new offenses.
2025-10-31 09:18:11 +01:00
Maikel Linke
f9b76fadbd Update all locales with the latest Transifex translations 2025-10-31 16:05:11 +11:00
Maikel
64f44b8a9b Merge pull request #13571 from pacodelaluna/update_sum_calcultation
Update sum calculation in order_cycle_customer_totals spec
2025-10-31 16:03:11 +11:00
Maikel Linke
5dfb7645cb Avoid enabling rubocop rule listed in todo file 2025-10-31 15:39:58 +11:00
Maikel Linke
74927dd03d Regenerate Rubocop todo file 2025-10-31 15:30:17 +11:00
François Turbelin
71dd398131 Apply cosmetics and fix specs 2025-10-31 15:20:44 +11:00
François Turbelin
245f0caedb Adjust sum for remaining reports 2025-10-31 15:20:44 +11:00
François Turbelin
18bc95c6a3 Update sum calculation in order_cycle_customer_totals spec 2025-10-31 15:20:44 +11:00
Ahmed Ejaz
243190491b Fix specs 2025-10-31 04:40:44 +05:00
dependabot[bot]
7213dcf124 Bump jasmine-core from 5.12.0 to 5.12.1
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 5.12.0 to 5.12.1.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/main/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v5.12.0...v5.12.1)

---
updated-dependencies:
- dependency-name: jasmine-core
  dependency-version: 5.12.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-30 09:02:08 +00:00
David Rodríguez
e90569bdcc Adjust error format to latest prettier output
To avoid generating an unnecessary annotation.
2025-10-29 11:55:11 +01:00
David Rodríguez
404e27ab71 Run reviewdog directly
So that we can control the version we run without depending on external
actions, and so that we use a consistent version for all linters.

At the same time, unify to running the latest version of reviewdog,
0.21.0, which also involves changing the deprecated `fail_on_error` flag
previously used by prettier action to `fail_level`.
2025-10-29 11:55:10 +01:00
David Rodríguez
5af6d534df Use "nofilter" for prettier
Now that we fixed all prettier issues.
2025-10-29 11:55:03 +01:00
David Rodríguez
65410aabad Speed up rubocop reviewdog by skipping install
Since we already run `bundle install` at the beginning of the job.
2025-10-29 11:55:03 +01:00
David Rodríguez
2e78ea62b6 Change linters workflow label to reviewdog 2025-10-29 11:55:03 +01:00
David Rodríguez
201461918d Fix prettier offense
I accidentally introduced this, not sure how, when correcting all
prettier issues.
2025-10-29 11:55:03 +01:00
dependabot[bot]
3efe0c7835 Bump paranoia from 2.6.3 to 2.6.4
Bumps [paranoia](https://github.com/rubysherpas/paranoia) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/rubysherpas/paranoia/releases)
- [Changelog](https://github.com/rubysherpas/paranoia/blob/core/CHANGELOG.md)
- [Commits](https://github.com/rubysherpas/paranoia/compare/v2.6.3...v2.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 09:02:20 +00:00
dependabot[bot]
e3d453e397 Bump @hotwired/turbo from 8.0.13 to 8.0.20
Bumps [@hotwired/turbo](https://github.com/hotwired/turbo) from 8.0.13 to 8.0.20.
- [Release notes](https://github.com/hotwired/turbo/releases)
- [Commits](https://github.com/hotwired/turbo/compare/8.0.13...v8.0.20)

---
updated-dependencies:
- dependency-name: "@hotwired/turbo"
  dependency-version: 8.0.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 09:01:59 +00:00
Maikel
0ecfc23c67 Merge pull request #13644 from deivid-rodriguez/more-rspec-fixes
Fix Rspec warnings and the broken Stripe intent API specs that fixing them revealed
2025-10-29 15:04:22 +11:00
Maikel
ff16b575c4 Merge pull request #13653 from deivid-rodriguez/bump-rubocop
Bump rubocop to 1.86.6
2025-10-29 12:00:31 +11:00
Maikel
faa826a76e Merge pull request #13647 from deivid-rodriguez/remove-obsoleted-gem
Remove obsolete gem
2025-10-29 11:44:59 +11:00
Maikel
1e02084f95 Merge pull request #13646 from deivid-rodriguez/bump-ruby
Bump Ruby from 3.1.4 to 3.1.7
2025-10-29 11:43:04 +11:00
Maikel
44cca40db6 Merge pull request #13643 from deivid-rodriguez/fix-prettier-issues
Fix all existing prettier issues
2025-10-29 11:36:54 +11:00
David Cook
52174b1e06 Merge pull request #13645 from deivid-rodriguez/review-dog-write-checks
Fix reviewdog workflow failing to create checks
2025-10-29 09:17:26 +11:00
Filipe
cdf0777d8e Merge pull request #13641 from openfoodfoundation/dependabot/bundler/knapsack_pro-8.4.0
Bump knapsack_pro from 8.1.2 to 8.4.0
2025-10-28 12:31:44 +00:00
David Cook
9cb7c46b44 Merge pull request #13631 from rioug/13117-upgrade-node
Upgrade to node version 24
2025-10-28 10:52:34 +11:00
David Rodríguez
4c6d894bc0 Bump RuboCop to 1.86.6
There were a few changes needed:

* Plugins are now specified through `plugin:` config keyword.
* All plugin gems need to be specified explicitly in Gemfile since they
  are no longer dependencies of plugins already specified explicitly.
* All plugin gems need to be updated in other to use the new APIs.
* One cop was renamed.
* New offenses safe to correct were corrected directly with `bundle exec
  rubocop -a`.
* New offenses unsafe to correct were added to the TODO configuration
  with `bundle exec rubocop --auto-gen-config --auto-gen-only-exclude
  --exclude-limit 1400 --no-auto-gen-timestamp`.
2025-10-27 11:30:33 +01:00
David Rodríguez
27975252f5 Rename pm_card to payment_method_id
And also remove a couple of now unused `let`'s that were already using
this terminology.

Co-authored-by: David Cook <david@openfoodnetwork.org.au>
2025-10-27 10:52:36 +01:00
David Rodríguez
9fc82776ec Move Stripe test payment method handling to a single place
And comment a bit on them.

Co-authored-by: David Cook <david@openfoodnetwork.org.au>
2025-10-27 10:45:45 +01:00
David Rodríguez
2c8bf82426 Migrate some spec to not send raw card numbers to Stripe API
If I regenerate the VCR cassetes for
spec/lib/stripe/payment_intent_validator_spec.rb, I get a lot of errors
like this:

```
Stripe::CardError:

Sending credit card numbers directly to the Stripe API is generally
unsafe. We suggest you use test tokens that map to the test card you are
using, see https://stripe.com/docs/testing. To enable testing raw card
data APIs, see
https://support.stripe.com/questions/enabling-access-to-raw-card-data-apis.
```

It seems the sandbox environment associated to my developer API keys is
not allowed to send raw credit card data.

Instead of requesting Stripe support to enable that, or regenerate
cassettes with the API keys in Bitwarden, I figured we could migrate the
tests to not use raw credit card data.
2025-10-27 09:08:30 +01:00
David Rodríguez
121019411c Fix spec instantiating payment method with wrong source
Previous error is fixed, which allows the spec to proceed further, and
reveals that the current cassettes are missing some requests:

```
  1) Stripe::PaymentIntentValidator#call as a guest when payment intent is valid valid non-3D credit cards are correctly handled behaves like payments intents from Visa returns payment intent id and does not raise
     Failure/Error:
       payment_intent_response = Stripe::PaymentIntent.retrieve(
         payment_intent_id,
         stripe_account: stripe_account_id
       )

     VCR::Errors::UnhandledHTTPRequestError:

       ================================================================================
       An HTTP request has been made that VCR does not know how to handle:
         GET https://api.stripe.com/v1/payment_intents/pi_3P8hNGKuuB1fWySn0dvhu9lG

       VCR is currently using the following cassette:

       (...)
```
2025-10-27 09:08:29 +01:00
David Rodríguez
1a5eb5b39a Remove raise_error negative block to fix RSpec warnings
Currently RSpec warns these specs like this:

```
WARNING: Using `expect { }.not_to raise_error(SpecificErrorClass)` risks false positives, since literally any other error would cause the
expectation to pass, including those raised by Ruby (e.g. `NoMethodError`, `NameError` and `ArgumentError`), meaning the code you are intending
to test may not even get reached. Instead consider using `expect { }.not_to raise_error` or `expect { }.to raise_error(DifferentSpecificErrorClass)`.
This message can be suppressed by setting: `RSpec::Expectations.configuration.on_potential_false_positives = :nothing`.
Called from /path/to/spec/lib/stripe/payment_intent_validator_spec.rb:53:in `block (7 levels) in <main>'.
```

The warnings are super accurate in this particular case: the inner
assertion is not actually getting reached due to a previous unrelated
error.

Since there's an inner assertion already, I think it's best to
completely remove to `raise_error` negative block, since it just hides
errors and buys us nothing.

By removing it, the underlying error surfaces:

```
  1) Stripe::PaymentIntentValidator#call as a guest when payment intent is valid valid non-3D credit cards are correctly handled behaves like payments intents from Visa returns payment intent id and does not raise
     Failure/Error:
       create(:payment, amount: payment_intent.amount, payment_method:,
                        response_code: payment_intent.id, source: pm_card)

     NoMethodError:
       undefined method `has_query_constraints?' for Stripe::PaymentMethod:Class

               elsif (klass || self.klass).has_query_constraints? || options[:query_constraints]
                                          ^^^^^^^^^^^^^^^^^^^^^^^
     Shared Example Group: "payments intents" called from ./spec/lib/stripe/payment_intent_validator_spec.rb:75
     # ./spec/lib/stripe/payment_intent_validator_spec.rb:16:in `block (3 levels) in <main>'
     # ./spec/lib/stripe/payment_intent_validator_spec.rb:19:in `block (3 levels) in <main>'
     # ./spec/lib/stripe/payment_intent_validator_spec.rb:53:in `block (7 levels) in <main>'
     # ./spec/base_spec_helper.rb:208:in `block (2 levels) in <main>'
     # ./spec/base_spec_helper.rb:155:in `block (3 levels) in <main>'
     # ./spec/base_spec_helper.rb:155:in `block (2 levels) in <main>'
     # -e:1:in `<main>'
```
2025-10-27 09:08:29 +01:00
David Rodríguez
2bd536298b Showcase the problem with some specs
They're always passing because an error (different from `StripeError`),
is actually making them pass.
2025-10-27 09:08:29 +01:00
Ahmed Ejaz
7415503b63 Update all locales with the latest Transifex translations 2025-10-27 05:55:44 +05:00
Ahmed Ejaz
895e142e2c Enhance order cycle closure handling with improved messaging and redirection logic 2025-10-26 02:08:53 +05:00
Navaneeth
f1ffadd39c Make the width of "Back to Store" and "Back to Website" buttons consistent with other buttons in order confirmation page 2025-10-25 22:15:14 +05:30
Filipe
cc35d118eb Merge pull request #13627 from guidoDutra/10261/bad-table-format-in-edit-order-page
fix table format in edit order page
2025-10-24 13:16:49 +01:00
David Rodríguez
e09d78dfb2 Remove obsolete gem
Even without it, Rails seems to do this by default:

```console
$ RAILS_ENV=production SITE_URL=foo.bar SECRET_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx bin/rails db:drop
I, [2025-10-23T12:38:12.383244 #32647]  INFO -- : [dotenv] Loaded .env
I, [2025-10-23T12:38:12.383292 #32647]  INFO -- : [dotenv] Loaded .env
W, [2025-10-23T12:38:12.411675 #32647]  WARN -- [Bugsnag]: No valid API key has been set, notifications will not be sent
bin/rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1

Tasks: TOP => db:drop => db:check_protected_environments
(See full trace by running task with --trace)
```

And the gem hasn't been updated in 10 years, so probably best to get rid
of it.
2025-10-23 12:41:37 +02:00
David Rodríguez
dad7cfc180 Bump Ruby from 3.1.4 to 3.1.7
Release announcmenets:

* https://www.ruby-lang.org/en/news/2024/04/23/ruby-3-1-5-released/
* https://www.ruby-lang.org/en/news/2024/05/29/ruby-3-1-6-released/
* https://www.ruby-lang.org/en/news/2025/03/26/ruby-3-1-7-released/
2025-10-23 10:34:21 +02:00
David Rodríguez
678497914f Fix reviewdog workflow failing to create checks 2025-10-22 19:59:10 +02:00
David Rodríguez
852e7fa81e Fix all existing prettier issues 2025-10-22 15:30:36 +02:00
dependabot[bot]
fb437fb34d Bump knapsack_pro from 8.1.2 to 8.4.0
Bumps [knapsack_pro](https://github.com/KnapsackPro/knapsack_pro-ruby) from 8.1.2 to 8.4.0.
- [Changelog](https://github.com/KnapsackPro/knapsack_pro-ruby/blob/main/CHANGELOG.md)
- [Commits](https://github.com/KnapsackPro/knapsack_pro-ruby/compare/v8.1.2...v8.4.0)

---
updated-dependencies:
- dependency-name: knapsack_pro
  dependency-version: 8.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-22 09:02:10 +00:00
Maikel
025f8b25b1 Merge pull request #13637 from deivid-rodriguez/fix-missing-stripe-js-error-in-edge-case
Fix JS error when Stripe connect is disabled but Stripe API keys are setup
2025-10-22 13:09:58 +11:00
Maikel
3017f61047 Merge pull request #13638 from deivid-rodriguez/refactor-specs
Remove only usage of `STRIPE_PUBLIC_TEST_API_KEY` env and refactor specs that were using it
2025-10-22 13:08:31 +11:00
Maikel
8cb3d06f7c Merge pull request #13635 from deivid-rodriguez/testing-stripe-wiki
Link to Stripe testing wiki page from the cassette regeneration script
2025-10-22 13:02:21 +11:00
Maikel
8f442e82ed Merge pull request #13634 from openfoodfoundation/dependabot/bundler/activerecord-import-2.2.0
Bump activerecord-import from 1.6.0 to 2.2.0
2025-10-22 13:00:43 +11:00
David Rodríguez
b28886dd38 Normalize casing 2025-10-21 17:34:40 +02:00
David Rodríguez
bd4f115185 Create account directly with the proper stripe_user_id 2025-10-21 17:34:40 +02:00
David Rodríguez
c43650034f Remove unnecessary test specific environment variable 2025-10-21 17:34:40 +02:00
David Rodríguez
94bc787283 Remove unused let 2025-10-21 17:34:40 +02:00
David Rodríguez
58851a8e67 Move client_id let to the only spec using it 2025-10-21 17:34:39 +02:00
David Rodríguez
c3e2382600 Move let! to the only spec using it 2025-10-21 17:34:39 +02:00
David Rodríguez
802878b4eb Fix JS error when Stripe connect is disabled but Stripe API keys are setup 2025-10-21 17:24:34 +02:00
Filipe
69d8fc3cad Merge pull request #13624 from chahmedejaz/bugfix/13556-fix-500-error-on-stripe-checkout
Error 500 checking out with Stripe, after navigating back to the Summary page
2025-10-21 14:34:53 +01:00
David Rodríguez
6a226e476d Link to Stripe testing wiki page from the cassette regeneration script
I think this is the more relevant wiki page for someone looking into
regenerating cassettes.

Also, no need to mention bitwarden explicitly, the wiki page already
explains everything.
2025-10-21 14:38:10 +02:00
dependabot[bot]
479d52a2bb Bump activerecord-import from 1.6.0 to 2.2.0
Bumps [activerecord-import](https://github.com/zdennis/activerecord-import) from 1.6.0 to 2.2.0.
- [Changelog](https://github.com/zdennis/activerecord-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zdennis/activerecord-import/compare/v1.6.0...v2.2.0)

---
updated-dependencies:
- dependency-name: activerecord-import
  dependency-version: 2.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 09:02:00 +00:00
Gaetan Craig-Riou
8afd6eb0ab Upgrade node to 24.10.0
This is the latest node 24 version which set to be the next lts.
2025-10-21 15:56:50 +11:00
Gaetan Craig-Riou
8d4a1ff320 Update spec to cover new code path 2025-10-21 15:48:27 +11:00
Gaetan Craig-Riou
1f0e541743 Update spec description wording 2025-10-21 15:48:27 +11:00
Gaetan Craig-Riou
adb7563ccb Fix possible code injection
It will fix this security issue :
https://github.com/openfoodfoundation/openfoodnetwork/security/code-scanning/247
2025-10-21 15:48:27 +11:00
Gaetan Craig-Riou
73688b9544 Merge pull request #13630 from openfoodfoundation/dependabot/bundler/webmock-3.25.1
Bump webmock from 3.23.1 to 3.25.1
2025-10-21 10:02:14 +11:00
dependabot[bot]
02ea3cb61c Bump webmock from 3.23.1 to 3.25.1
Bumps [webmock](https://github.com/bblimke/webmock) from 3.23.1 to 3.25.1.
- [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bblimke/webmock/compare/v3.23.1...v3.25.1)

---
updated-dependencies:
- dependency-name: webmock
  dependency-version: 3.25.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 09:26:20 +00:00
Maikel
c7d0594257 Merge pull request #13622 from deivid-rodriguez/no-reviewdog-master
Don't run reviewdog on pushes
2025-10-20 16:34:06 +11:00
Maikel
4eee7ad603 Merge pull request #13604 from deivid-rodriguez/silent-puma
Silence capybara starting puma during system specs
2025-10-20 16:26:18 +11:00
David Cook
23f7f2974a Merge pull request #13618 from deivid-rodriguez/remove-unnecessary-sleeps
Remove unnecessary explicit sleeps
2025-10-20 16:06:44 +11:00
Maikel
8105b919e0 Merge pull request #13600 from deivid-rodriguez/profile-enables-dev-caching
The PROFILE env variable should actually enable, not disable, caching
2025-10-20 16:03:20 +11:00
David Cook
53ef5148e9 Merge pull request #13617 from deivid-rodriguez/upgrade-cache-format-version
Upgrade cache format version
2025-10-20 15:41:52 +11:00
David Cook
93e6f9034c Merge pull request #13602 from deivid-rodriguez/bump-mini_magick
Update mini_magick to a version that plays nice with imagemagick v7
2025-10-20 15:26:20 +11:00
David Cook
125a92346c Merge pull request #13599 from deivid-rodriguez/fix-duplicate-key-warning
Fix duplicate keys warnings in some views
2025-10-20 15:21:40 +11:00
Gaetan Craig-Riou
31b8fe16cb Merge pull request #13623 from deivid-rodriguez/follow-up-to-old-rename
Follow up to old ofnEmptiesCart to ofnChangeHub rename
2025-10-20 10:53:47 +11:00
Gaetan Craig-Riou
cbffea8d30 Merge pull request #13616 from openfoodfoundation/dependabot/bundler/state_machines-activerecord-0.31.0
Bump state_machines-activerecord from 0.9.0 to 0.31.0
2025-10-20 09:50:30 +11:00
Ahmed Ejaz
10917161b0 Refactor order cycle expiry handling to allow skipping order emptying during checkout 2025-10-20 01:42:20 +05:00
Guido Oliveira
be9da62d98 fix table format in edit order page 2025-10-19 07:58:40 -03:00
Ahmed Ejaz
9f6c149735 Add check for payment authorization state in StripeScaPaymentAuthorize and corresponding spec 2025-10-17 05:25:45 +05:00
David Rodríguez
50578647ee Follow up to old ofnEmptiesCart to ofnChangeHub rename
This happened back in 2015 through
9c9051498b, but two places were missed.

One was a code comment so did not affect anything (other than confused
code readers I guess?). The other one did create a regression but was
later fixed by 18d966f0de in 2021.
2025-10-16 12:56:17 +02:00
David Rodríguez
a28f05fddc Don't run reviewdog on pushes
As configured, it's meant to annotate PRs with linter errors (so you
don't have to skim through logs). So it does not make sense for pushes.

In fact, on pushes rubocop action is doing nothing, and prettier action
is failing with:

> reviewdog: this is not PullRequest build.
> sed: couldn't write 80 items to stdout: Broken pipe
2025-10-16 12:34:37 +02:00
David Rodríguez
d6c044fd5b Remove unnecessary explicit sleeps
Capybara helpers already wait for the content to show up (and we already
have a default of 10 seconds configured), so I don't think waiting more is
actually the problem in these specs.

But if we wanted to wait more, I think it's better to pass the `:wait`
option to capybara matchers, because that's a "maximum waiting value"
but we'll still proceed earlier if the content shows up.

Using the same idea, I changed the positive assertions to happen first,
because negative assertions do spend "max wait time" waiting, while
positive assertions only wait until the content shows up.
2025-10-15 13:09:52 +02:00
David Rodríguez
a75ea5b506 Upgrade cache format version
It's supposed to be faster and more compact, and the previous format
will become unsupported in Rails 7.2 as per Rails boot warnings:

> DEPRECATION WARNING: Support for `config.active_support.cache_format_version = 6.1` has been deprecated and will be removed in Rails 7.2.
>
> Check the Rails upgrade guide at https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
> for more information on how to upgrade.
>    (called from <main> at /path/to/config/environment.rb:5)
2025-10-15 12:17:03 +02:00
dependabot[bot]
7f937fd4b1 Bump state_machines-activerecord from 0.9.0 to 0.31.0
Bumps [state_machines-activerecord](https://github.com/state-machines/state_machines-activerecord) from 0.9.0 to 0.31.0.
- [Release notes](https://github.com/state-machines/state_machines-activerecord/releases)
- [Changelog](https://github.com/state-machines/state_machines-activerecord/blob/master/CHANGELOG.md)
- [Commits](https://github.com/state-machines/state_machines-activerecord/compare/v0.9.0...state_machines-activerecord/v0.31.0)

---
updated-dependencies:
- dependency-name: state_machines-activerecord
  dependency-version: 0.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-15 09:02:41 +00:00
David Rodríguez
667ce5eda2 Silence capybara starting puma during system specs
##### Before

```
$ bin/rspec spec/system/admin/order_cycles/simple_spec.rb:460
Running via Spring preloader in process 79308
Run options: include {:locations=>{"./spec/system/admin/order_cycles/simple_spec.rb"=>[460]}}

As an administrator
    I want to manage simple order cycles
  as an enterprise user
    that is a manager of the coordinator
      when variants are hidden via inventory settings
Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:51103
        shows a warning when going to 'outgoing products' tab

Finished in 3.95 seconds (files took 0.45949 seconds to load)
1 example, 0 failures
```

##### After

```
$ bin/rspec spec/system/admin/order_cycles/simple_spec.rb:460
Running via Spring preloader in process 79234
Run options: include {:locations=>{"./spec/system/admin/order_cycles/simple_spec.rb"=>[460]}}

As an administrator
    I want to manage simple order cycles
  as an enterprise user
    that is a manager of the coordinator
      when variants are hidden via inventory settings
        shows a warning when going to 'outgoing products' tab

Finished in 4.03 seconds (files took 0.49981 seconds to load)
1 example, 0 failures
```
2025-10-14 20:34:05 +02:00
David Rodríguez
c72f9477cd bundle update mini_magick
This is mainly to shush a lot of warnings when running the test suite,
like the following:

```
WARNING: The convert command is deprecated in IMv7, use "magick" instead of "convert" or "magick convert"
```
2025-10-14 08:17:12 +02:00
David Rodríguez
8787eed863 The PROFILE env variable should actually enable, not disable, caching
I think this may be a typo from 6d8ddd1edac17a431222c86482bceb83e8a7d32f?
2025-10-14 08:03:15 +02:00
David Rodríguez
e2b6199f26 Fix duplicate keys warnings in some views
We're passing the `id` key twice, and with different value, resulting in
warnings like:

> /path/to/app/views/producers/index.html.haml:27: warning: key :id is duplicated and overwritten on line 31

Use only the latest value passed to remove the warning.

##### Before

```
$ bundle exec rspec -e "displays in an iframe" -e "logging in with a redirect set"

(...)

Run options: include {:full_description=>/(?-mix:displays\ in\ an\ iframe)|(?-mix:logging\ in\ with\ a\ redirect\ set)/}
Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:50292
/path/to/app/views/producers/index.html.haml:27: warning: key :id is duplicated and overwritten on line 31
./path/to/app/views/groups/show.html.haml:68: warning: key :id is duplicated and overwritten on line 72
Modal window with text `Unable to load map. Please check your browser settings and allow 3rd party cookies for this website.` has been opened, but you didn't wrap your code into (`accept_prompt` | `dismiss_prompt` | `accept_confirm` | `dismiss_confirm` | `accept_alert`), accepting by default
.

Finished in 4.54 seconds (files took 4.04 seconds to load)
2 examples, 0 failures
```

##### After

```
$ bundle exec rspec -e "displays in an iframe" -e "logging in with a redirect set"

(...)

Run options: include {:full_description=>/(?-mix:displays\ in\ an\ iframe)|(?-mix:logging\ in\ with\ a\ redirect\ set)/}
Capybara starting Puma...
* Version 6.5.0, codename: Sky's Version
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:50256
.Modal window with text `Unable to load map. Please check your browser settings and allow 3rd party cookies for this website.` has been opened, but you didn't wrap your code into (`accept_prompt` | `dismiss_prompt` | `accept_confirm` | `dismiss_confirm` | `accept_alert`), accepting by default
.

Finished in 4.17 seconds (files took 4.1 seconds to load)
2 examples, 0 failures
```
2025-10-14 07:58:32 +02:00
408 changed files with 27146 additions and 42813 deletions

View File

@@ -1,56 +0,0 @@
version: "2"
plugins:
rubocop:
enabled: true
channel: "rubocop-1-12"
config:
file: ".rubocop.yml"
scss-lint:
enabled: true
checks:
ImportantRule:
enabled: false
VendorPrefix:
enabled: false
LeadingZero:
enabled: false
PropertySortOrder:
enabled: false
StringQuotes:
enabled: false
DeclarationOrder:
enabled: false
NestingDepth:
enabled: false
duplication:
enabled: true
exclude_patterns:
- "db/**"
- "config/initializers/active_record_postgresql_referential_integrity_patch.rb"
checks:
argument-count:
enabled: false
complex-logic:
enabled: false
file-lines:
enabled: false
method-complexity:
enabled: false
method-count:
enabled: false
method-lines:
enabled: false
nested-control-flow:
enabled: false
return-statements:
enabled: false
similar-code:
enabled: false
identical-code:
enabled: false
exclude_patterns:
- "spec/**/*"
- "vendor/**/*"
- "app/assets/javascripts/shared/*"
- "app/assets/javascripts/jquery-migrate-1.0.0.js"

View File

@@ -20,7 +20,6 @@ STRIPE_INSTANCE_SECRET_KEY="bogus_key"
STRIPE_CUSTOMER="bogus_customer"
STRIPE_ACCOUNT="bogus_account"
STRIPE_CLIENT_ID="bogus_client_id"
STRIPE_PUBLIC_TEST_API_KEY="bogus_stripe_publishable_key"
SITE_URL="test.host"

View File

@@ -1,10 +1,11 @@
name: Linters
on: [push, pull_request]
on: [pull_request]
permissions:
contents: read # to fetch code (actions/checkout)
checks: write # to post check annotations
jobs:
lint:
name: prettier and rubocop
name: reviewdog
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -21,21 +22,10 @@ jobs:
- run: git show --no-patch # the commit being tested (which is often a merge due to actions/checkout@v3)
- name: prettier
uses: EPMatt/reviewdog-action-prettier@v1
- uses: reviewdog/action-setup@v1
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-check
level: error
fail_on_error: true
reviewdog_version: v0.21.0
- name: rubocop
uses: reviewdog/action-rubocop@v2
with:
rubocop_version: gemfile
rubocop_extensions: rubocop-rails:gemfile rubocop-rspec:gemfile
reporter: github-pr-check
level: error
filter_mode: nofilter
use_bundler: true
fail_level: any
- run: ./script/reviewdog.sh
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}

View File

@@ -2,19 +2,12 @@
# frameworks such as Jekyll/Middleman
skip_frontmatter: false
inherits_from: .haml-lint_todo.yml
linters:
AltText:
enabled: false
ClassAttributeWithStaticValue:
enabled: true
ClassesBeforeIds:
enabled: true
ConsecutiveComments:
enabled: true
ConsecutiveSilentScripts:
enabled: true
max_consecutive: 2
@@ -32,7 +25,6 @@ linters:
enabled: true
LineLength:
enabled: true
max: 80
MultilinePipe:
@@ -47,24 +39,11 @@ linters:
RuboCop:
enabled: false
RubyComments:
enabled: true
SpaceBeforeScript:
enabled: true
SpaceInsideHashAttributes:
enabled: true
style: no_space
TagName:
enabled: true
TrailingWhitespace:
enabled: true
UnnecessaryInterpolation:
enabled: true
UnnecessaryStringOutput:
enabled: true

153
.haml-lint_todo.yml Normal file
View File

@@ -0,0 +1,153 @@
# This configuration was generated by
# `haml-lint --auto-gen-config`
# on 2025-10-30 09:19:50 +0100 using Haml-Lint version 0.66.0.
# The point is for the user to remove these configuration records
# one by one as the lints are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of Haml-Lint, may require this file to be generated again.
linters:
# Offense count: 35
ClassAttributeWithStaticValue:
enabled: false
# Offense count: 77
ClassesBeforeIds:
enabled: false
# Offense count: 18
ConsecutiveComments:
enabled: false
# Offense count: 22
ConsecutiveSilentScripts:
exclude:
- "app/views/admin/contents/_fieldset.html.haml"
- "app/views/admin/enterprises/form/_tag_rules.html.haml"
- "app/views/admin/order_cycles/edit.html.haml"
- "app/views/admin/products_v3/product_preview.turbo_stream.haml"
- "app/views/admin/reports/_date_range_form.html.haml"
- "app/views/checkout/_details.html.haml"
- "app/views/checkout/_payment.html.haml"
- "app/views/spree/admin/adjustments/_adjustments_table.html.haml"
- "app/views/spree/admin/orders/customer_details/_address_form.html.haml"
- "app/views/spree/admin/tax_categories/index.html.haml"
- "app/views/spree/admin/users/index.html.haml"
# Offense count: 14
FinalNewline:
exclude:
- "app/assets/javascripts/templates/shared/question_mark_with_tooltip.html.haml"
- "app/views/admin/enterprises/form/_social.html.haml"
- "app/views/admin/json/_injection_ams.html.haml"
- "app/views/admin/order_cycles/_date_time_warning_modal_content.html.haml"
- "app/views/admin/order_cycles/edit.html.haml"
- "app/views/admin/product_import/_ams_data.html.haml"
- "app/views/admin/reports/_row_group.haml"
- "app/views/admin/reports/filters/_enterprise_fee_summary.html.haml"
- "app/views/admin/reports/filters/_users_and_enterprises.html.haml"
- "app/views/shop/_blocked_cookies.html.haml"
- "app/views/spree/admin/orders/_invoice/_order_note.html.haml"
- "app/views/spree/admin/orders/invoice4.html.haml"
- "app/views/spree/admin/taxons/destroy_taxon.turbo_stream.haml"
- "app/views/spree/admin/users/_email_confirmation.html.haml"
# Offense count: 130
IdNames:
enabled: false
# Offense count: 5
Indentation:
exclude:
- "app/views/admin/products_v3/clone.turbo_stream.haml"
- "app/views/admin/products_v3/destroy_product_variant.turbo_stream.haml"
- "app/views/spree/admin/taxons/destroy_taxon.turbo_stream.haml"
# Offense count: 191
InlineStyles:
enabled: false
# Offense count: 589
InstanceVariables:
enabled: false
# Offense count: 2
LeadingCommentSpace:
exclude:
- "app/views/admin/reports/_row_group.haml"
# Offense count: 2331
LineLength:
enabled: false
# Offense count: 1
MultilinePipe:
exclude:
- "app/views/admin/reports/_rendering_options.html.haml"
# Offense count: 2
MultilineScript:
exclude:
- "app/views/admin/products_v3/product_preview.turbo_stream.haml"
- "app/views/checkout/_voucher_section.html.haml"
# Offense count: 2
RepeatedId:
exclude:
- "app/assets/javascripts/templates/admin/save_bar.html.haml"
# Offense count: 24
RubyComments:
enabled: false
# Offense count: 104
SpaceBeforeScript:
enabled: false
# Offense count: 3345
SpaceInsideHashAttributes:
enabled: false
# Offense count: 22
TrailingEmptyLines:
enabled: false
# Offense count: 73
TrailingWhitespace:
enabled: false
# Offense count: 13
UnnecessaryInterpolation:
exclude:
- "app/components/example_component/example_component.html.haml"
- "app/views/admin/product_import/_entries_table.html.haml"
- "app/views/admin/product_import/import.html.haml"
- "app/views/admin/variant_overrides/_filters.html.haml"
- "app/views/registration/steps/_introduction.html.haml"
- "app/views/spree/order_mailer/_shipping.html.haml"
- "app/views/spree/order_mailer/invoice_email.html.haml"
- "app/views/spree/shared/_shipment_delivery_details.html.haml"
- "app/views/spree/shared/_shipment_pickup_details.html.haml"
# Offense count: 68
UnnecessaryStringOutput:
enabled: false
# Offense count: 14
ViewLength:
exclude:
- "app/assets/javascripts/templates/admin/panels/enterprise_package.html.haml"
- "app/views/admin/customers/index.html.haml"
- "app/views/admin/enterprises/_new_form.html.haml"
- "app/views/admin/enterprises/form/_shop_preferences.html.haml"
- "app/views/admin/product_import/_import_review.html.haml"
- "app/views/admin/products_v3/product_preview.turbo_stream.haml"
- "app/views/checkout/_details.html.haml"
- "app/views/groups/show.html.haml"
- "app/views/producer_mailer/order_cycle_report.html.haml"
- "app/views/shared/_footer.html.haml"
- "app/views/spree/admin/orders/bulk_management.html.haml"
- "app/views/spree/admin/orders/invoice4.html.haml"
- "app/views/spree/admin/products/new.html.haml"
- "app/views/spree/admin/variants/_form.html.haml"

View File

@@ -1,6 +0,0 @@
rubocop:
config_file: .rubocop_styleguide.yml
scss:
config_file: .scss-lint.yml
haml:
config_file: .haml-lint.yml

View File

@@ -1 +1 @@
17.9.1
24.10.0

View File

@@ -4,7 +4,7 @@
#
# The configuration is split into three files. Look into those files for more details.
#
require:
plugins:
- rubocop-capybara
- rubocop-factory_bot
- rubocop-rails

View File

@@ -94,7 +94,7 @@ Metrics/PerceivedComplexity:
Enabled: true
Max: 14 # default 8
Naming/PredicateName:
Naming/PredicatePrefix:
Enabled: false
Naming/VariableNumber:

View File

@@ -1,11 +1,44 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400 --no-auto-gen-timestamp`
# using RuboCop version 1.64.1.
# using RuboCop version 1.81.6.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: RequireParenthesesForMethodChains.
Lint/AmbiguousRange:
Exclude:
- 'app/models/concerns/permalink_generator.rb'
# Offense count: 6
Lint/CopDirectiveSyntax:
Exclude:
- 'app/services/orders/bulk_cancel_service.rb'
- 'lib/tasks/simplecov.rake'
- 'spec/models/database_spec.rb'
- 'spec/system/admin/bulk_order_management_spec.rb'
- 'spec/system/admin/enterprise_relationships_spec.rb'
# Offense count: 2
Lint/DuplicateMethods:
Exclude:
- 'app/models/spree/order.rb'
- 'engines/order_management/app/services/order_management/subscriptions/form.rb'
# Offense count: 3
Lint/UselessConstantScoping:
Exclude:
- 'app/services/weights_and_measures.rb'
- 'lib/reporting/report_metadata_builder.rb'
# Offense count: 1
Lint/UselessOr:
Exclude:
- 'app/models/product_import/entry_validator.rb'
# Offense count: 24
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
Metrics/AbcSize:
@@ -42,7 +75,7 @@ Metrics/BlockLength:
- 'lib/tasks/data.rake'
# Offense count: 1
# Configuration parameters: CountBlocks, Max.
# Configuration parameters: CountBlocks, CountModifierForms, Max.
Metrics/BlockNesting:
Exclude:
- 'app/models/spree/payment/processing.rb'
@@ -100,7 +133,7 @@ Metrics/ClassLength:
- 'lib/reporting/reports/enterprise_fee_summary/scope.rb'
- 'lib/reporting/reports/xero_invoices/base.rb'
# Offense count: 30
# Offense count: 35
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
Metrics/CyclomaticComplexity:
Exclude:
@@ -123,6 +156,11 @@ Metrics/CyclomaticComplexity:
- 'app/models/spree/tax_rate.rb'
- 'app/models/spree/zone.rb'
- 'lib/open_food_network/enterprise_issue_validator.rb'
- 'lib/reporting/reports/orders_and_fulfillment/order_cycle_customer_totals.rb'
- 'lib/reporting/reports/orders_and_fulfillment/order_cycle_supplier_totals.rb'
- 'lib/reporting/reports/payments/itemised_payment_totals.rb'
- 'lib/reporting/reports/payments/payment_totals.rb'
- 'lib/reporting/reports/sales_tax/sales_tax_totals_by_producer.rb'
- 'lib/reporting/reports/xero_invoices/base.rb'
- 'lib/spree/core/controller_helpers/order.rb'
- 'lib/spree/core/controller_helpers/respond_with.rb'
@@ -182,8 +220,9 @@ Metrics/PerceivedComplexity:
- 'app/models/spree/order/checkout.rb'
# Offense count: 1
# Configuration parameters: EnforcedStyle, AllowedPatterns.
# Configuration parameters: EnforcedStyle, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns.
# SupportedStyles: snake_case, camelCase
# ForbiddenIdentifiers: __id__, __send__
Naming/MethodName:
Exclude:
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
@@ -195,23 +234,132 @@ Naming/MethodParameterName:
Exclude:
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
# Offense count: 59
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
# AllowedMethods: call
# WaywardPredicates: nonzero?
Naming/PredicateMethod:
Exclude:
- 'app/controllers/admin/product_import_controller.rb'
- 'app/controllers/api/v0/order_cycles_controller.rb'
- 'app/controllers/spree/admin/overview_controller.rb'
- 'app/controllers/spree/admin/payments_controller.rb'
- 'app/controllers/voucher_adjustments_controller.rb'
- 'app/forms/enterprise_fees_bulk_update.rb'
- 'app/forms/schedule_form.rb'
- 'app/helpers/spree/orders_helper.rb'
- 'app/models/concerns/variant_stock.rb'
- 'app/models/enterprise.rb'
- 'app/models/enterprise_fee.rb'
- 'app/models/invoice/data_presenter.rb'
- 'app/models/order_cycle.rb'
- 'app/models/product_import/entry_processor.rb'
- 'app/models/product_import/entry_validator.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/order_contents.rb'
- 'app/models/spree/payment.rb'
- 'app/models/spree/payment/processing.rb'
- 'app/models/spree/state_change.rb'
- 'app/models/spree/user.rb'
- 'app/reflexes/admin/orders_reflex.rb'
- 'app/serializers/api/admin/for_order_cycle/enterprise_serializer.rb'
- 'app/serializers/api/admin/index_enterprise_serializer.rb'
- 'app/serializers/api/admin/index_order_cycle_serializer.rb'
- 'app/serializers/api/admin/order_cycle_serializer.rb'
- 'app/serializers/api/admin/order_serializer.rb'
- 'app/serializers/api/admin/schedule_serializer.rb'
- 'app/serializers/api/admin/subscription_line_item_serializer.rb'
- 'app/serializers/api/admin/user_serializer.rb'
- 'app/serializers/api/admin/variant_serializer.rb'
- 'app/serializers/api/enterprise_shopfront_serializer.rb'
- 'app/serializers/api/enterprise_thin_serializer.rb'
- 'app/serializers/api/order_serializer.rb'
- 'app/serializers/api/uncached_enterprise_serializer.rb'
- 'app/services/cart_service.rb'
- 'app/services/orders/fetch_adjustments_service.rb'
- 'app/services/orders/workflow_service.rb'
- 'app/services/sets/model_set.rb'
- 'app/services/sets/order_cycle_set.rb'
- 'app/services/sets/product_set.rb'
- 'engines/dfc_provider/app/controllers/dfc_provider/addresses_controller.rb'
- 'lib/open_food_network/order_cycle_form_applicator.rb'
- 'lib/open_food_network/order_cycle_permissions.rb'
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_order.rb'
- 'lib/reporting/reports/enterprise_fee_summary/enterprise_fees_with_tax_report_by_producer.rb'
- 'lib/tasks/data/check_invalid_address_used.rake'
# Offense count: 3
# Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns.
# Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns.
# SupportedStyles: snake_case, camelCase
Naming/VariableName:
Exclude:
- 'engines/dfc_provider/lib/dfc_provider/catalog_item.rb'
# Offense count: 6
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/FindByOrAssignmentMemoization:
Exclude:
- 'app/controllers/admin/customers_controller.rb'
- 'app/controllers/admin/resource_controller.rb'
- 'app/controllers/api/v0/enterprise_fees_controller.rb'
- 'app/controllers/api/v0/order_cycles_controller.rb'
- 'lib/stripe/account_connector.rb'
# Offense count: 32
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/OrderArguments:
Exclude:
- 'app/controllers/admin/enterprise_fees_controller.rb'
- 'app/controllers/admin/enterprises_controller.rb'
- 'app/controllers/admin/order_cycles_controller.rb'
- 'app/controllers/admin/product_import_controller.rb'
- 'app/controllers/api/v0/states_controller.rb'
- 'app/controllers/spree/admin/overview_controller.rb'
- 'app/controllers/spree/admin/products_controller.rb'
- 'app/helpers/enterprises_helper.rb'
- 'app/models/enterprise.rb'
- 'app/models/enterprise_group.rb'
- 'app/models/enterprise_relationship_permission.rb'
- 'app/models/order_cycle.rb'
- 'app/models/product_import/product_importer.rb'
- 'app/models/schedule.rb'
- 'app/models/spree/country.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/shipping_rate.rb'
- 'app/models/spree/user.rb'
- 'app/models/spree/zone.rb'
- 'app/models/subscription_line_item.rb'
- 'app/models/tag_rule.rb'
- 'app/models/variant_override.rb'
- 'lib/open_food_network/address_finder.rb'
- 'spec/services/orders/generate_invoice_service_spec.rb'
- 'spec/system/admin/order_cycles/simple_spec.rb'
# Offense count: 1
# Configuration parameters: TransactionMethods.
Rails/TransactionExitStatement:
Exclude:
- 'app/services/place_proxy_order.rb'
# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/ArrayIntersect:
Exclude:
- 'app/models/spree/ability.rb'
- 'app/models/spree/variant.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/BitwisePredicate:
Exclude:
- 'app/helpers/admin/enterprises_helper.rb'
# Offense count: 23
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# Configuration parameters: EnforcedStyle, EnforcedStyleForClasses, EnforcedStyleForModules.
# SupportedStyles: nested, compact
# SupportedStylesForClasses: ~, nested, compact
# SupportedStylesForModules: ~, nested, compact
Style/ClassAndModuleChildren:
Exclude:
- 'app/models/calculator/flat_percent_per_item.rb'
@@ -237,13 +385,33 @@ Style/ClassAndModuleChildren:
- 'lib/open_food_network/locking.rb'
- 'spec/models/spree/payment_method_spec.rb'
# Offense count: 4
# Offense count: 14
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/CollectionQuerying:
Exclude:
- 'app/controllers/spree/credit_cards_controller.rb'
- 'app/models/product_import/product_importer.rb'
- 'app/models/product_import/spreadsheet_entry.rb'
- 'app/models/spree/order.rb'
- 'app/models/spree/order_inventory.rb'
- 'app/models/spree/payment_method.rb'
- 'app/models/spree/user.rb'
- 'app/models/stripe_account.rb'
- 'app/services/order_cycles/warning_service.rb'
- 'lib/reporting/report_renderer.rb'
- 'lib/tasks/sample_data.rake'
# Offense count: 2
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/HashSlice:
Exclude:
- 'app/services/product_filters.rb'
- 'lib/reporting/report_row_builder.rb'
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/MapToHash:
Exclude:
- 'lib/reporting/report_query_template.rb'
- 'lib/reporting/report_row_builder.rb'
- 'lib/reporting/reports/enterprise_fee_summary/fee_summary.rb'
- 'lib/tasks/sample_data/user_factory.rb'
# Offense count: 38
@@ -274,3 +442,22 @@ Style/OptionalBooleanParameter:
- 'engines/order_management/app/services/order_management/stock/estimator.rb'
- 'lib/spree/core/controller_helpers/order.rb'
- 'spec/support/request/web_helper.rb'
# Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all).
Style/RedundantFormat:
Exclude:
- 'spec/models/product_importer_spec.rb'
- 'spec/requests/checkout/stripe_sca_spec.rb'
- 'spec/system/consumer/account/cards_spec.rb'
# Offense count: 8
# Configuration parameters: Max.
Style/SafeNavigationChainLength:
Exclude:
- 'app/controllers/concerns/extra_fields.rb'
- 'app/services/customer_syncer.rb'
- 'app/services/fdc_offer_broker.rb'
- 'engines/dfc_provider/app/services/dfc_catalog.rb'
- 'engines/dfc_provider/app/services/image_builder.rb'
- 'engines/dfc_provider/app/services/quantitative_value_builder.rb'

View File

@@ -1 +1 @@
3.1.4
3.2.9

View File

@@ -1,19 +0,0 @@
scss_files: 'app/assets/stylesheets/**/*.css.scss'
exclude: 'app/assets/stylesheets/shared/**'
linters:
ImportantRule:
enabled: false
VendorPrefix:
enabled: false
LeadingZero:
enabled: false
PropertySortOrder:
enabled: false
StringQuotes:
enabled: false
DeclarationOrder:
enabled: false
NestingDepth:
enabled: false

View File

@@ -1,4 +1,4 @@
FROM ruby:3.1.4-alpine3.19 AS base
FROM ruby:3.2.9-alpine3.19 AS base
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
TZ=Europe/London \

12
Gemfile
View File

@@ -27,7 +27,6 @@ gem 'sprockets', '~> 3.7'
gem 'i18n'
gem 'i18n-js', '~> 3.9.0'
gem 'rails-i18n'
gem 'rails_safe_tasks', '~> 1.0'
gem "activerecord-import"
gem "db2fog", github: "openfoodfoundation/db2fog", branch: "rails-7"
@@ -44,7 +43,7 @@ gem 'web', path: './engines/web'
gem "activerecord-postgresql-adapter"
gem "arel-helpers", "~> 2.12"
gem "pg", "~> 1.2.3"
gem "pg"
gem 'acts_as_list', '1.0.4'
gem 'cancancan', '~> 1.15.0'
@@ -58,7 +57,7 @@ gem 'state_machines-activerecord'
gem 'stringex', '~> 2.8.5', require: false
gem 'paypal-sdk-merchant', '1.117.2'
gem 'stripe'
gem 'stripe', '~> 13'
gem 'devise'
gem 'devise-encryptable'
@@ -186,16 +185,19 @@ group :test do
end
group :development do
gem 'debugger-linecache'
gem 'foreman'
gem 'haml_lint', require: false
gem 'i18n-tasks'
gem 'listen'
gem 'pry', '~> 0.13.0'
gem 'pry'
gem 'query_count'
gem 'rails-erd'
gem 'rubocop'
gem 'rubocop-capybara'
gem 'rubocop-factory_bot'
gem 'rubocop-rails'
gem 'rubocop-rspec'
gem 'rubocop-rspec_rails'
gem 'spring'
gem 'spring-commands-rspec'
gem 'spring-commands-rubocop'

View File

@@ -122,17 +122,16 @@ GEM
activemodel (= 7.1.5.2)
activesupport (= 7.1.5.2)
timeout (>= 0.4.0)
activerecord-import (1.6.0)
activerecord-import (2.2.0)
activerecord (>= 4.2)
activerecord-postgresql-adapter (0.0.1)
pg
activerecord-session_store (2.1.0)
actionpack (>= 6.1)
activerecord (>= 6.1)
activerecord-session_store (2.2.0)
actionpack (>= 7.0)
activerecord (>= 7.0)
cgi (>= 0.3.6)
multi_json (~> 1.11, >= 1.11.2)
rack (>= 2.0.8, < 4)
railties (>= 6.1)
railties (>= 7.0)
activestorage (7.1.5.2)
actionpack (= 7.1.5.2)
activejob (= 7.1.5.2)
@@ -156,8 +155,8 @@ GEM
activerecord (>= 6.1, < 7.2)
acts_as_list (1.0.4)
activerecord (>= 4.2)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
aes_key_wrap (1.1.0)
afm (0.2.2)
angular-rails-templates (1.2.1)
@@ -192,9 +191,9 @@ GEM
base64 (0.3.0)
bcp47_spec (0.2.1)
bcrypt (3.1.20)
benchmark (0.4.1)
bigdecimal (3.2.2)
bindata (2.5.0)
benchmark (0.5.0)
bigdecimal (3.3.1)
bindata (2.5.1)
bindex (0.8.1)
bootsnap (1.18.3)
msgpack (~> 1.2)
@@ -264,11 +263,10 @@ GEM
database_cleaner-core (2.0.1)
datafoodconsortium-connector (1.1.0)
virtual_assembly-semantizer (~> 1.0, >= 1.0.5)
date (3.4.1)
date (3.5.0)
debug (1.9.2)
irb (~> 1.10)
reline (>= 0.3.8)
debugger-linecache (1.2.0)
devise (4.9.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -299,8 +297,7 @@ GEM
eventmachine (>= 1.0.0.beta.1)
email_validator (2.2.4)
activemodel
erb (4.0.4)
cgi (>= 0.3.3)
erb (5.1.3)
erubi (1.13.1)
et-orbi (1.3.0)
tzinfo
@@ -315,9 +312,9 @@ GEM
railties (>= 5.0.0)
faraday (2.9.0)
faraday-net_http (>= 2.0, < 3.2)
faraday-follow_redirects (0.3.0)
faraday-follow_redirects (0.4.0)
faraday (>= 1, < 3)
faraday-net_http (3.1.0)
faraday-net_http (3.1.1)
net-http
ferrum (0.14)
addressable (~> 2.5)
@@ -331,13 +328,13 @@ GEM
flipper-active_record (1.3.0)
activerecord (>= 4.2, < 8)
flipper (~> 1.3.0)
flipper-ui (1.3.0)
flipper-ui (1.3.6)
erubi (>= 1.0.0, < 2.0.0)
flipper (~> 1.3.0)
flipper (~> 1.3.6)
rack (>= 1.4, < 4)
rack-protection (>= 1.5.3, < 5.0.0)
rack-session (>= 1.0.2, < 3.0.0)
sanitize (< 7)
sanitize (< 8)
fog-aws (2.0.1)
fog-core (~> 1.38)
fog-json (~> 1.0)
@@ -364,7 +361,7 @@ GEM
geocoder (1.8.3)
base64 (>= 0.1.0)
csv (>= 3.0.0)
globalid (1.2.1)
globalid (1.3.0)
activesupport (>= 6.1)
gmaps4rails (2.1.2)
good_migrations (0.2.1)
@@ -374,17 +371,23 @@ GEM
temple (>= 0.8.2)
thor
tilt
hashdiff (1.1.0)
haml_lint (0.67.0)
haml (>= 5.0)
parallel (~> 1.10)
rainbow
rubocop (>= 1.0)
sysexits (~> 1.1)
hashdiff (1.2.1)
hashery (2.1.2)
hashie (5.0.0)
highline (2.0.3)
htmlentities (4.3.4)
http_parser.rb (0.8.0)
i18n (1.14.5)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
i18n-js (3.9.2)
i18n (>= 0.6.6)
i18n-tasks (1.0.14)
i18n-tasks (1.0.15)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
erubi
@@ -393,6 +396,7 @@ GEM
parser (>= 3.2.2.1)
rails-i18n
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.8, >= 1.8.1)
terminal-table (>= 1.5.1)
image_processing (1.12.2)
mini_magick (>= 4.9.5, < 5)
@@ -405,7 +409,7 @@ GEM
rails (>= 5.2)
io-console (0.8.1)
ipaddress (0.8.3)
irb (1.15.2)
irb (1.15.3)
pp (>= 0.6.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
@@ -416,9 +420,9 @@ GEM
thor (>= 0.14, < 2.0)
jquery-ui-rails (4.2.1)
railties (>= 3.2.16)
json (2.7.2)
json (2.15.2)
json-canonicalization (1.0.0)
json-jwt (1.16.6)
json-jwt (1.17.0)
activesupport (>= 4.2)
aes_key_wrap
base64
@@ -442,15 +446,16 @@ GEM
activesupport (>= 4.2)
jwt (2.8.1)
base64
knapsack_pro (8.1.2)
knapsack_pro (8.4.0)
rake
language_server-protocol (3.17.0.3)
language_server-protocol (3.17.0.5)
launchy (3.0.0)
addressable (~> 2.8)
childprocess (~> 5.0)
letter_opener (1.10.0)
launchy (>= 2.2, < 4)
link_header (0.0.8)
lint_roller (1.1.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
@@ -458,7 +463,8 @@ GEM
loofah (2.24.1)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.8.1)
mail (2.9.0)
logger
mini_mime (>= 0.1.1)
net-imap
net-pop
@@ -473,28 +479,28 @@ GEM
mimemagic (0.4.3)
nokogiri (~> 1)
rake
mini_magick (4.11.0)
mini_magick (4.13.2)
mini_mime (1.1.5)
mini_portile2 (2.8.6)
minitest (5.25.5)
minitest (5.26.1)
monetize (1.13.0)
money (~> 6.12)
money (6.16.0)
i18n (>= 0.6.4, <= 2)
msgpack (1.7.2)
multi_json (1.15.0)
multi_json (1.17.0)
multi_xml (0.6.0)
mutex_m (0.3.0)
net-http (0.4.1)
net-http (0.7.0)
uri
net-imap (0.4.20)
net-imap (0.5.12)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.2)
timeout
net-smtp (0.5.0)
net-smtp (0.5.1)
net-protocol
newrelic_rpm (9.22.0)
nio4r (2.7.1)
@@ -510,17 +516,18 @@ GEM
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
observer (0.1.2)
omniauth (2.1.2)
omniauth (2.1.4)
hashie (>= 3.4.6)
logger
rack (>= 2.2.3)
rack-protection
omniauth-rails_csrf_protection (1.0.2)
actionpack (>= 4.2)
omniauth (~> 2.0)
omniauth_openid_connect (0.7.1)
omniauth_openid_connect (0.8.0)
omniauth (>= 1.9, < 3)
openid_connect (~> 2.2)
openid_connect (2.3.0)
openid_connect (2.3.1)
activemodel
attr_required (>= 1.0.0)
email_validator
@@ -539,10 +546,10 @@ GEM
paper_trail (15.1.0)
activerecord (>= 6.1)
request_store (~> 1.4)
parallel (1.24.0)
paranoia (2.6.3)
parallel (1.27.0)
paranoia (2.6.4)
activerecord (>= 5.1, < 7.2)
parser (3.3.9.0)
parser (3.3.10.0)
ast (~> 2.4.1)
racc
paypal-sdk-core (0.3.4)
@@ -556,18 +563,19 @@ GEM
hashery (~> 2.0)
ruby-rc4
ttfunk
pg (1.2.3)
pp (0.6.2)
pg (1.6.2)
pp (0.6.3)
prettyprint
prettyprint (0.2.0)
prism (1.6.0)
private_address_check (0.5.0)
pry (0.13.1)
pry (0.15.2)
coderay (~> 1.1)
method_source (~> 1.0)
psych (5.2.6)
date
stringio
public_suffix (5.0.5)
public_suffix (6.0.2)
puffing-billy (4.0.2)
addressable (~> 2.5)
em-http-request (~> 1.1, >= 1.1.0)
@@ -583,10 +591,10 @@ GEM
railties (>= 4.2)
raabro (1.4.0)
racc (1.8.1)
rack (2.2.20)
rack (2.2.21)
rack-mini-profiler (2.3.4)
rack (>= 1.2.0)
rack-oauth2 (2.2.1)
rack-oauth2 (2.3.0)
activesupport
attr_required
faraday (~> 2.0)
@@ -640,7 +648,6 @@ GEM
rails-i18n (7.0.10)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails_safe_tasks (1.0.0)
railties (7.1.5.2)
actionpack (= 7.1.5.2)
activesupport (= 7.1.5.2)
@@ -650,7 +657,7 @@ GEM
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.3.0)
rake (13.3.1)
ransack (4.1.1)
activerecord (>= 6.1.5)
activesupport (>= 6.1.5)
@@ -662,7 +669,7 @@ GEM
bcp47_spec (~> 0.2)
bigdecimal (~> 3.1, >= 3.1.5)
link_header (~> 0.0, >= 0.0.8)
rdoc (6.15.0)
rdoc (6.15.1)
erb
psych (>= 4.0.0)
tsort
@@ -671,7 +678,7 @@ GEM
redis-client (>= 0.22.0)
redis-client (0.26.1)
connection_pool
regexp_parser (2.9.2)
regexp_parser (2.11.3)
reline (0.6.2)
io-console (~> 0.5)
request_store (1.5.1)
@@ -734,35 +741,39 @@ GEM
rswag-ui (2.16.0)
actionpack (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rubocop (1.64.1)
rubocop (1.81.6)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.47.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.3)
parser (>= 3.3.1.0)
rubocop-capybara (2.20.0)
rubocop (~> 1.41)
rubocop-factory_bot (2.25.1)
rubocop (~> 1.41)
rubocop-rails (2.28.0)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.47.1)
parser (>= 3.3.7.2)
prism (~> 1.4)
rubocop-capybara (2.22.1)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-factory_bot (2.27.1)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rails (2.33.4)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
rubocop (>= 1.52.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (2.29.2)
rubocop (~> 1.40)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
rubocop-rspec_rails (~> 2.28)
rubocop-rspec_rails (2.28.3)
rubocop (~> 1.40)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.44.0, < 2.0)
rubocop-rspec (3.7.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec_rails (2.31.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-rspec (~> 3.5)
ruby-graphviz (1.2.5)
rexml
ruby-progressbar (1.13.0)
@@ -773,9 +784,9 @@ GEM
rufus-scheduler (3.8.2)
fugit (~> 1.1, >= 1.1.6)
rugged (1.9.0)
sanitize (6.1.0)
sanitize (7.0.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
nokogiri (>= 1.16.8)
sass (3.4.25)
sass-rails (5.0.8)
railties (>= 5.2.0)
@@ -806,7 +817,7 @@ GEM
spreadsheet_architect (5.0.0)
caxlsx (>= 3.3.0, < 4)
rodf (>= 1.0.0, < 2)
spring (4.2.1)
spring (4.4.0)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
spring-commands-rubocop (0.4.0)
@@ -819,13 +830,13 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
state_machines (0.6.0)
state_machines-activemodel (0.9.0)
activemodel (>= 6.0)
state_machines (>= 0.6.0)
state_machines-activerecord (0.9.0)
activerecord (>= 6.0)
state_machines-activemodel (>= 0.9.0)
state_machines (0.20.0)
state_machines-activemodel (0.10.0)
activemodel (>= 7.1)
state_machines (>= 0.10.0)
state_machines-activerecord (0.31.0)
activerecord (>= 7.1)
state_machines-activemodel (>= 0.10.0)
stimulus_reflex (3.5.5)
actioncable (>= 5.2)
actionpack (>= 5.2)
@@ -840,20 +851,21 @@ GEM
redis (>= 4.0, < 6.0)
stringex (2.8.6)
stringio (3.1.7)
stripe (11.1.0)
strscan (3.1.2)
stripe (13.5.1)
strscan (3.1.5)
swd (2.0.3)
activesupport (>= 3)
attr_required (>= 0.0.5)
faraday (~> 2.0)
faraday-follow_redirects
sysexits (1.2.0)
temple (0.8.2)
terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4)
thor (1.4.0)
thread-local (1.1.0)
tilt (2.3.0)
timeout (0.4.3)
timeout (0.4.4)
tsort (0.2.0)
ttfunk (1.8.0)
bigdecimal (~> 3.1)
@@ -861,7 +873,7 @@ GEM
actionpack (>= 6.0.0)
activejob (>= 6.0.0)
railties (>= 6.0.0)
turbo_power (0.6.2)
turbo_power (0.7.0)
turbo-rails (>= 1.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
@@ -873,9 +885,11 @@ GEM
rugged (>= 0.27, < 1.10)
simplecov
simplecov_json_formatter
unicode-display_width (2.5.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.1.0)
uniform_notifier (1.17.0)
uri (0.13.2)
uri (1.1.1)
valid_email2 (5.2.3)
activemodel (>= 3.2)
mail (~> 2.5)
@@ -906,7 +920,7 @@ GEM
activesupport
faraday (~> 2.0)
faraday-follow_redirects
webmock (3.23.1)
webmock (3.25.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -927,7 +941,7 @@ GEM
xml-simple (1.1.8)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.18)
zeitwerk (2.7.3)
PLATFORMS
ruby
@@ -964,7 +978,6 @@ DEPENDENCIES
datafoodconsortium-connector
db2fog!
debug (>= 1.0.0)
debugger-linecache
devise
devise-encryptable
devise-i18n
@@ -985,6 +998,7 @@ DEPENDENCIES
gmaps4rails
good_migrations
haml
haml_lint
highline (= 2.0.3)
i18n
i18n-js (~> 3.9.0)
@@ -1016,9 +1030,9 @@ DEPENDENCIES
paranoia (~> 2.4)
paypal-sdk-merchant (= 1.117.2)
pdf-reader
pg (~> 1.2.3)
pg
private_address_check
pry (~> 0.13.0)
pry
puffing-billy
puma
query_count
@@ -1029,7 +1043,6 @@ DEPENDENCIES
rails-controller-testing
rails-erd
rails-i18n
rails_safe_tasks (~> 1.0)
ransack (~> 4.1.0)
redcarpet
redis
@@ -1043,8 +1056,11 @@ DEPENDENCIES
rswag-api
rswag-ui
rubocop
rubocop-capybara
rubocop-factory_bot
rubocop-rails
rubocop-rspec
rubocop-rspec_rails
sd_notify
select2-rails!
shoulda-matchers
@@ -1060,7 +1076,7 @@ DEPENDENCIES
stimulus_reflex
stimulus_reflex_testing!
stringex (~> 2.8.5)
stripe
stripe (~> 13)
turbo-rails
turbo_power
undercover
@@ -1078,7 +1094,7 @@ DEPENDENCIES
wkhtmltopdf-binary
RUBY VERSION
ruby 3.1.4p223
ruby 3.2.9p265
BUNDLED WITH
2.4.3
2.4.19

View File

@@ -1,6 +1,6 @@
angular.module('Darkswarm').directive "activeTableHubLink", (CurrentHub, CurrentOrder) ->
# Change the text of the hub link based on CurrentHub
# To be used with ofnEmptiesCart
# To be used with ofnChangeHub
# Takes "change" and "shop" as text string attributes
restrict: "A"
scope:

View File

@@ -12,7 +12,7 @@
.row
.columns.small-12
%a.cta-hub{"ng-repeat" => "hub in enterprise.hubs | filter:{id: '!'+enterprise.id} | orderBy:'-active'",
"ng-href" => "{{::hub.path}}#/shop_panel", "ofn-empties-cart" => "hub",
"ng-href" => "{{::hub.path}}#/shop_panel",
"ng-class" => "::{primary: hub.active, secondary: !hub.active}",
"ng-click" => "$close()",
"ofn-change-hub" => "hub"}

View File

@@ -30,7 +30,7 @@ class SearchableDropdownComponent < ViewComponent::Base
:aria_label, :other_attrs
def classes
"fullwidth #{remove_search_plugin? ? 'no-input' : ''}"
"fullwidth #{'no-input' if remove_search_plugin?}"
end
def data

View File

@@ -5,16 +5,19 @@ class TagListInputComponent < ViewComponent::Base
placeholder: I18n.t("components.tag_list_input.default_placeholder"),
only_one: false,
aria_label: nil,
hidden_field_data_options: {})
hidden_field_data_options: {},
autocomplete_url: "")
@name = name
@tags = tags
@placeholder = placeholder
@only_one = only_one
@aria_label_option = aria_label ? { 'aria-label': aria_label } : {}
@hidden_field_data_options = hidden_field_data_options
@autocomplete_url = autocomplete_url
end
attr_reader :name, :tags, :placeholder, :only_one, :aria_label_option, :hidden_field_data_options
attr_reader :name, :tags, :placeholder, :only_one, :aria_label_option,
:hidden_field_data_options, :autocomplete_url
private

View File

@@ -1,4 +1,4 @@
%div{ "data-controller": "tag-list-input", "data-tag-list-input-only-one-value": "#{only_one}" }
%div{ "data-controller": "tag-list-input", "data-tag-list-input-only-one-value": "#{only_one}", "data-tag-list-input-url-value": autocomplete_url, "data-action": "autocomplete.change->tag-list-input#addTag" }
.tags-input
.tags
- # We use display:none instead of hidden field, so changes to the value can be picked up by the bulkFormController
@@ -16,4 +16,12 @@
%span=tag
%a.remove-button{ "data-action": "click->tag-list-input#removeTag" }
×
= text_field_tag "variant_add_tag", nil, class: "input", placeholder: placeholder, "data-action": "keydown.enter->tag-list-input#addTag keyup->tag-list-input#filterInput blur->tag-list-input#addTag", "data-tag-list-input-target": "newTag", **aria_label_option, style: "display: #{display};"
= text_field_tag("variant_add_tag",
nil,
{ class: "input",
placeholder: placeholder,
"data-action": "keydown.enter->tag-list-input#keyboardAddTag keyup->tag-list-input#filterInput blur->tag-list-input#onBlur focus->tag-list-input#onInputChange",
"data-tag-list-input-target": "input",
**aria_label_option,
style: "display: #{display};"})
%ul.suggestion-list{ "data-tag-list-input-target": "results" , hidden: true }

View File

@@ -67,4 +67,35 @@
font-size: 14px;
}
}
ul.suggestion-list {
margin-top: 5px;
padding: 5px 0;
z-index: $tag-drop-down-z-index;
width: fit-content;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: $shadow-dropdown;
list-style-type: none;
max-height: 280px;
overflow-y: auto;
position: relative;
li.suggestion-item {
padding: 5px 10px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #000;
background-color: #fff;
width: stretch;
&.active,
&:hover {
color: #fff;
background-color: $color-link-visited;
}
}
}
}

View File

@@ -1,14 +1,23 @@
import { Controller } from "stimulus";
import { Autocomplete } from "stimulus-autocomplete";
export default class extends Controller {
static targets = ["tagList", "newTag", "template", "list"];
// Extend the stimulus-autocomplete controller, so we can load tag with existing rules
// The autocomplete functionality is only loaded if the url value is set
// For more informatioon on "stimulus-autocomplete", see:
// https://github.com/afcapel/stimulus-autocomplete/tree/main
//
export default class extends Autocomplete {
static targets = ["tagList", "input", "template", "list"];
static values = { onlyOne: Boolean };
addTag(event) {
// prevent hotkey form submitting the form (default action for "enter" key)
event.preventDefault();
connect() {
// Don't start autocomplete controller if we don't have an url
if (this.urlValue.length == 0) return;
const newTagName = this.newTagTarget.value.trim().replaceAll(" ", "-");
super.connect();
}
addTag(event) {
const newTagName = this.inputTarget.value.trim().replaceAll(" ", "-");
if (newTagName.length == 0) {
return;
}
@@ -18,7 +27,7 @@ export default class extends Controller {
const index = tags.indexOf(newTagName);
if (index != -1) {
// highlight the value in red
this.newTagTarget.classList.add("tag-error");
this.inputTarget.classList.add("tag-error");
return;
}
@@ -38,14 +47,23 @@ export default class extends Controller {
this.listTarget.appendChild(newTagElement);
// Clear new tag value
this.newTagTarget.value = "";
this.inputTarget.value = "";
// hide tag input if limited to one tag
if (this.tagListTarget.value.split(",").length == 1 && this.onlyOneValue == true) {
this.newTagTarget.style.display = "none";
this.inputTarget.style.display = "none";
}
}
keyboardAddTag(event) {
// prevent hotkey form submitting the form (default action for "enter" key)
if (event) {
event.preventDefault();
}
this.addTag();
}
removeTag(event) {
// Text to remove
const tagName = event.srcElement.previousElementSibling.textContent;
@@ -62,14 +80,14 @@ export default class extends Controller {
// Make sure the tag input is displayed
if (this.tagListTarget.value.length == 0) {
this.newTagTarget.style.display = "block";
this.inputTarget.style.display = "block";
}
}
filterInput(event) {
// clear error class if key is not enter
if (event.key !== "Enter") {
this.newTagTarget.classList.remove("tag-error");
this.inputTarget.classList.remove("tag-error");
}
// Strip comma from tag name
@@ -77,4 +95,53 @@ export default class extends Controller {
event.srcElement.value = event.srcElement.value.replace(",", "");
}
}
// Add tag if we don't have an autocomplete list open
onBlur() {
// check if we have any autocomplete results
if (this.resultsTarget.childElementCount == 0) this.addTag();
}
// Override original to add tag filtering
replaceResults(html) {
const filteredHtml = this.#filterResults(html);
// Don't show result if we don't have anything to show
if (filteredHtml.length == 0) return;
super.replaceResults(filteredHtml);
}
// Override original to all empty query, which will return all existing tags
onInputChange = () => {
if (this.urlValue.length == 0) return;
if (this.hasHiddenTarget) this.hiddenTarget.value = "";
const query = this.inputTarget.value.trim();
if (query.length >= this.minLengthValue) {
this.fetchResults(query);
} else {
this.hideAndRemoveOptions();
}
};
//private
#filterResults(html) {
const existingTags = this.tagListTarget.value.split(",");
// Parse the HTML
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const lis = doc.getElementsByTagName("li");
// Filter
let filteredHtml = "";
for (let li of lis) {
if (!existingTags.includes(li.dataset.autocompleteValue)) {
filteredHtml += li.outerHTML;
}
}
return filteredHtml;
}
}

View File

@@ -47,6 +47,13 @@ class TagRuleFormComponent < ViewComponent::Base
taggable: "variant",
visibility_field: "preferred_matched_variants_visibility",
}
when "TagRule::FilterVariants"
{
text_top: t('components.tag_rule_form.tag_rules.variant_tagged_top'),
text_bottom: t('components.tag_rule_form.tag_rules.variant_tagged_bottom'),
taggable: "variant",
visibility_field: "preferred_matched_variants_visibility",
}
end
end

View File

@@ -3,6 +3,7 @@
module Admin
class BulkLineItemsController < Spree::Admin::BaseController
include PaginationData
# GET /admin/bulk_line_items.json
#
def index

View File

@@ -51,6 +51,7 @@ module Admin
load_tag_rule_types
load_tag_rules
return unless params[:stimulus]
@enterprise.is_primary_producer = params[:is_primary_producer]
@@ -84,6 +85,7 @@ module Admin
end
else
load_tag_rule_types
load_tag_rules
respond_with(@object) do |format|
format.json {
render json: { errors: @object.errors.messages }, status: :unprocessable_entity
@@ -398,9 +400,26 @@ module Admin
[t(".form.tag_rules.show_hide_order_cycles"), "FilterOrderCycles"]
]
return unless helpers.feature?(:inventory, @object)
if helpers.feature?(:variant_tag, @object)
@tag_rule_types.prepend([t(".form.tag_rules.show_hide_variants"), "FilterVariants"])
elsif helpers.feature?(:inventory, @object)
@tag_rule_types.prepend([t(".form.tag_rules.show_hide_variants"), "FilterProducts"])
end
end
@tag_rule_types.prepend([t(".form.tag_rules.show_hide_variants"), "FilterProducts"])
def load_tag_rules
if helpers.feature?(:variant_tag, @object)
@default_rules = @enterprise.tag_rules.exclude_inventory.select(&:is_default)
@rules = @enterprise.tag_rules.exclude_inventory.prioritised.reject(&:is_default)
elsif helpers.feature?(:inventory, @object)
@default_rules = @enterprise.tag_rules.exclude_variant.select(&:is_default)
@rules = @enterprise.tag_rules.exclude_variant.prioritised.reject(&:is_default)
else
@default_rules =
@enterprise.tag_rules.exclude_inventory.exclude_variant.select(&:is_default)
@rules =
@enterprise.tag_rules.exclude_inventory.exclude_variant.prioritised.reject(&:is_default)
end
end
def setup_property

View File

@@ -4,6 +4,7 @@ module Admin
class ReportsController < Spree::Admin::BaseController
include ActiveStorage::SetCurrent
include ReportsActions
helper ReportsHelper
before_action :authorize_report, only: [:show, :create]

View File

@@ -41,6 +41,7 @@ module Admin
end
end
# Used by the tag input autocomplete
def map_by_tag
respond_to do |format|
format.json do
@@ -50,6 +51,26 @@ module Admin
end
end
# Use to populate autocomplete with available rule for the given tag/enterprise
def variant_tag_rules
tag_rules =
TagRule.matching_variant_tag_rules_by_enterprises(params[:enterprise_id], params[:q])
@formatted_tag_rules = tag_rules.each_with_object({}) do |rule, mapping|
rule.preferred_variant_tags.split(",").each do |tag|
if mapping[tag]
mapping[tag][:rules] += 1
else
mapping[tag] = { tag:, rules: 1 }
end
end
end.values
respond_with do |format|
format.html { render :variant_tag_rules, layout: false }
end
end
private
def collection_actions
@@ -78,7 +99,7 @@ module Admin
end
def permitted_tag_rule_type
%w{FilterOrderCycles FilterPaymentMethods FilterProducts FilterShippingMethods}
%w{FilterOrderCycles FilterPaymentMethods FilterProducts FilterShippingMethods FilterVariants}
end
end
end

View File

@@ -7,6 +7,7 @@ module Api
module V0
class ExchangeProductsController < Api::V0::BaseController
include PaginationData
DEFAULT_PER_PAGE = 100
skip_authorization_check only: [:index]

View File

@@ -23,7 +23,8 @@ module Api
order_cycle,
customer,
search_params,
inventory_enabled:
inventory_enabled:,
variant_tag_enabled:
).products_json
render plain: products
@@ -96,13 +97,17 @@ module Api
def distributed_products
OrderCycles::DistributedProductsService.new(
distributor, order_cycle, customer, inventory_enabled:
distributor, order_cycle, customer, inventory_enabled:, variant_tag_enabled:,
).products_relation.pluck(:id)
end
def inventory_enabled
OpenFoodNetwork::FeatureToggle.enabled?(:inventory, distributor)
end
def variant_tag_enabled
OpenFoodNetwork::FeatureToggle.enabled?(:variant_tag, distributor)
end
end
end
end

View File

@@ -7,6 +7,7 @@ module Api
module V0
class ProductsController < Api::V0::BaseController
include PaginationData
respond_to :json
DEFAULT_PER_PAGE = 15

View File

@@ -8,6 +8,10 @@ module Api
include AddressTransformation
include ExtraFields
wrap_parameters :customer, include:
Customer.attribute_names +
[:billing_address, :shipping_address]
skip_authorization_check only: :index
before_action :authorize_action, only: [:show, :update, :destroy]
@@ -88,7 +92,8 @@ module Api
attributes = params.require(:customer).permit(
:email, :enterprise_id,
:code, :first_name, :last_name,
:billing_address, shipping_address: [
:billing_address,
shipping_address: [
:phone, :latitude, :longitude,
:first_name, :last_name,
:street_address_1, :street_address_2,

View File

@@ -20,25 +20,43 @@ module OrderStockCheck
@updated_variants = check_stock_service.update_line_items
end
def check_order_cycle_expiry
def check_order_cycle_expiry(should_empty_order: true)
return unless current_order_cycle&.closed?
Alert.raise_with_record("Notice: order cycle closed during checkout completion", current_order)
current_order.empty!
current_order.assign_order_cycle! nil
flash[:info] = I18n.t('order_cycle_closed')
respond_to do |format|
format.cable_ready {
render status: :see_other, cable_ready: cable_car.redirect_to(url: main_app.shop_path)
}
format.json { render json: { path: main_app.shop_path }, status: :see_other }
format.html { redirect_to main_app.shop_path, status: :see_other }
end
handle_closed_order_cycle if should_empty_order
flash[:info] = build_order_cycle_message(should_empty_order)
redirect_to_shop_page(should_empty_order)
end
private
def handle_closed_order_cycle
current_order.empty!
current_order.assign_order_cycle!(nil)
end
def build_order_cycle_message(should_empty_order)
# If order is not emptied, we assume user will contact support for next steps
key = should_empty_order ? 'order_cycle_closed' : 'order_cycle_closed_next_steps'
I18n.t(key, order_number: current_order.number)
end
def redirect_to_shop_page(should_empty_order)
# If order is not emptied, redirect to shops page because shop page empties the order by default
redirect_url = should_empty_order ? main_app.shop_path : main_app.shops_path
respond_to do |format|
format.cable_ready {
render status: :see_other, cable_ready: cable_car.redirect_to(url: redirect_url)
}
format.json { render json: { path: redirect_url }, status: :see_other }
format.html { redirect_to redirect_url, status: :see_other }
end
end
def check_stock_service
@check_stock_service ||= Orders::CheckStockService.new(order: @order)
end

View File

@@ -8,7 +8,9 @@ module PaymentGateways
before_action :destroy_orphaned_paypal_payments, only: :confirm
before_action :load_checkout_order, only: [:express, :confirm]
before_action :handle_insufficient_stock, only: [:express, :confirm]
before_action :check_order_cycle_expiry, only: [:express, :confirm]
before_action -> { check_order_cycle_expiry(should_empty_order: false) }, only: [
:express, :confirm
]
before_action :permit_parameters!
after_action :reset_order_when_complete, only: :confirm

View File

@@ -7,7 +7,7 @@ module PaymentGateways
before_action :load_checkout_order, only: :confirm
before_action :validate_payment_intent, only: :confirm
before_action :check_order_cycle_expiry, only: :confirm
before_action -> { check_order_cycle_expiry(should_empty_order: false) }, only: :confirm
def confirm
validate_stock

View File

@@ -6,6 +6,7 @@ module Spree
module Admin
class OrdersController < Spree::Admin::BaseController
include OpenFoodNetwork::SpreeApiKeyLoader
helper CheckoutHelper
before_action :load_order, only: [:edit, :update, :fire, :resend, :invoice, :print]

View File

@@ -10,6 +10,12 @@ module Spree
respond_to :html
PAYMENT_METHODS = %w{
Spree::PaymentMethod::Check
Spree::Gateway::PayPalExpress
Spree::Gateway::StripeSCA
}.index_with(&:constantize).freeze
def create
force_environment
@@ -89,8 +95,9 @@ module Spree
@payment_method = PaymentMethod.find(params[:pm_id])
end
else
@payment_method = params[:provider_type].constantize.new
@payment_method = PAYMENT_METHODS.fetch(params[:provider_type], PaymentMethod).new
end
render partial: 'provider_settings'
end

View File

@@ -10,6 +10,7 @@ module Spree
include OpenFoodNetwork::SpreeApiKeyLoader
include OrderCyclesHelper
include EnterprisesHelper
helper ::Admin::ProductsHelper
helper Spree::Admin::TaxCategoriesHelper

View File

@@ -14,6 +14,7 @@ module Spree
include Spree::Core::ControllerHelpers::Order
include I18nHelper
before_action :set_locale
# Devise::PasswordsController allows for blank passwords.

View File

@@ -36,9 +36,7 @@ class ScheduleForm
false unless @schedule.update(permitted_resource_params)
end
def order_cycle_ids
@schedule.order_cycle_ids
end
delegate :order_cycle_ids, to: :@schedule
private

View File

@@ -52,9 +52,9 @@ module ApplicationHelper
# Pass URL helper calls on to spree where applicable so that we don't need to use
# spree.foo_path in any view rendered from non-spree-namespaced controllers.
def method_missing(method, *args, &)
def method_missing(method, *, &)
if method.to_s.end_with?('_path', '_url') && spree.respond_to?(method)
spree.public_send(method, *args)
spree.public_send(method, *)
else
super
end

View File

@@ -120,7 +120,7 @@ module InjectionHelper
def inject_enterprise_attributes(enterprise_attributes)
render partial: "json/injection_ams",
locals: { name: 'enterpriseAttributes', json: enterprise_attributes.to_json.to_s }
locals: { name: 'enterpriseAttributes', json: enterprise_attributes.to_json }
end
def inject_saved_credit_cards

View File

@@ -44,9 +44,7 @@ module ReportsHelper
.pluck(:name, :id)
end
def currency_symbol
Spree::Money.currency_symbol
end
delegate :currency_symbol, to: :'Spree::Money'
def enterprise_fee_owner_ids(orders)
EnterpriseFee.where(id: enterprise_fee_ids(orders))

View File

@@ -10,9 +10,7 @@ module TermsAndConditionsHelper
TermsOfService.required?(distributor)
end
def platform_terms_required?
TermsOfService.platform_terms_required?
end
delegate :platform_terms_required?, to: :TermsOfService
def distributor_terms_required?
TermsOfService.distributor_terms_required?(current_order.distributor)

View File

@@ -2,6 +2,7 @@
class BulkInvoiceJob < ApplicationJob
include CableReady::Broadcaster
delegate :render, to: ActionController::Base
attr_reader :options

View File

@@ -3,6 +3,7 @@
# Renders a report and stores it in a given blob.
class ReportJob < ApplicationJob
include CableReady::Broadcaster
delegate :render, to: ActionController::Base
before_perform :enable_active_storage_urls

View File

@@ -29,7 +29,7 @@ class ApplicationRecord < ActiveRecord::Base
end
end
def url_for(*args)
Rails.application.routes.url_helpers.url_for(*args)
def url_for(*)
Rails.application.routes.url_helpers.url_for(*)
end
end

View File

@@ -4,6 +4,7 @@ require 'active_support/concern'
module LogDestroyPerformer
extend ActiveSupport::Concern
included do
attr_accessor :destroyed_by

View File

@@ -25,11 +25,13 @@ class Customer < ApplicationRecord
before_destroy :update_orders_and_delete_canceled_subscriptions
belongs_to :bill_address, class_name: "Spree::Address", optional: true
alias_attribute :billing_address, :bill_address
alias_method :billing_address, :bill_address
alias_method :billing_address=, :bill_address=
accepts_nested_attributes_for :bill_address
belongs_to :ship_address, class_name: "Spree::Address", optional: true
alias_attribute :shipping_address, :ship_address
alias_method :shipping_address, :ship_address
alias_method :shipping_address=, :ship_address=
accepts_nested_attributes_for :ship_address
validates :code, uniqueness: { scope: :enterprise_id, allow_nil: true }

View File

@@ -408,7 +408,7 @@ class Enterprise < ApplicationRecord
def category
# Make this crazy logic human readable so we can argue about it sanely.
cat = is_primary_producer ? "producer_" : "non_producer_"
cat << ("sells_#{sells}")
cat << "sells_#{sells}"
# Map backend cases to front end cases.
case cat

View File

@@ -3,6 +3,7 @@
class Invoice
class DataPresenter
include ::ActionView::Helpers::NumberHelper
attr_reader :invoice
delegate :display_number, :data, :previous_invoice, to: :invoice
@@ -142,7 +143,7 @@ class Invoice
end
def paid?
data[:payment_state] == 'paid' || data[:payment_state] == 'credit_owed'
['paid', 'credit_owed'].include?(data[:payment_state])
end
def outstanding_balance?

View File

@@ -4,6 +4,7 @@ class Invoice
class DataPresenter
class Base
include ::ActionView::Helpers::NumberHelper
attr_reader :data
def initialize(data)

View File

@@ -81,17 +81,13 @@ module ProductImport
@reset_counts
end
def enterprises_index
@spreadsheet_data.enterprises_index
end
delegate :enterprises_index, to: :@spreadsheet_data
def enterprise_products
@processor&.enterprise_products
end
def total_enterprise_products
@processor.total_enterprise_products
end
delegate :total_enterprise_products, to: :@processor
def entries_json
entries = {}
@@ -130,13 +126,9 @@ module ProductImport
@processor.inventory_updated
end
def products_reset_count
@processor.products_reset_count
end
delegate :products_reset_count, to: :@processor
def total_saved_count
@processor.total_saved_count
end
delegate :total_saved_count, to: :@processor
def import_results
{ entries: entries_json, reset_counts: }
@@ -183,7 +175,7 @@ module ProductImport
end
def staged_import?
@import_settings&.key?(:start) && @import_settings&.key?(:end)
@import_settings&.key?(:start) && @import_settings.key?(:end)
end
def init_permissions

View File

@@ -143,7 +143,7 @@ module Spree
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty
can :new, TagRule
can [:admin, :map_by_tag, :destroy], TagRule do |tag_rule|
can [:admin, :map_by_tag, :destroy, :variant_tag_rules], TagRule do |tag_rule|
user.enterprises.include? tag_rule.enterprise
end

View File

@@ -31,9 +31,7 @@ module Spree
self.class.name.titleize.gsub("Calculator/", "")
end
def description
self.class.description
end
delegate :description, to: :class
def available?(_object)
true

View File

@@ -34,11 +34,11 @@ module Spree
@provider.respond_to?(method_name, include_private) || super
end
def method_missing(method, *args)
def method_missing(method, *)
if @provider.nil? || !@provider.respond_to?(method)
super
else
provider.__send__(method, *args)
provider.__send__(method, *)
end
end

View File

@@ -35,10 +35,12 @@ module Spree
belongs_to :created_by, class_name: "Spree::User", optional: true
belongs_to :bill_address, class_name: 'Spree::Address', optional: true
alias_attribute :billing_address, :bill_address
alias_method :billing_address, :bill_address
alias_method :billing_address=, :bill_address=
belongs_to :ship_address, class_name: 'Spree::Address', optional: true
alias_attribute :shipping_address, :ship_address
alias_method :shipping_address, :ship_address
alias_method :shipping_address=, :ship_address=
has_many :state_changes, as: :stateful, dependent: :destroy
has_many :line_items, -> {
@@ -97,7 +99,7 @@ module Spree
}
validate :disallow_guest_order
validates :email, presence: true,
format: /\A([\w.%+\-']+)@([\w\-]+\.)+(\w{2,})\z/i,
format: /\A([\w.%+\-']+)@([\w-]+\.)+(\w{2,})\z/i,
if: :require_email
validates :order_cycle, presence: true, on: :require_distribution
@@ -417,7 +419,7 @@ module Spree
# Helper methods for checkout steps
def paid?
payment_state == 'paid' || payment_state == 'credit_owed'
['paid', 'credit_owed'].include?(payment_state)
end
# "Checkout" is the initial state and, for card payments, "pending" is the state after auth

View File

@@ -3,6 +3,7 @@
module Spree
class ShippingMethod < ApplicationRecord
include CalculatedAdjustments
DISPLAY_ON_OPTIONS = {
both: "",
back_end: "back_end"

View File

@@ -56,8 +56,8 @@ module Spree
# Send devise-based user emails asyncronously via ActiveJob
# See: https://github.com/heartcombo/devise/tree/v3.5.10#activejob-integration
def send_devise_notification(notification, *args)
devise_mailer.public_send(notification, self, *args).deliver_later
def send_devise_notification(notification, *)
devise_mailer.public_send(notification, self, *).deliver_later
end
def regenerate_reset_password_token

View File

@@ -24,8 +24,10 @@ class Subscription < ApplicationRecord
has_many :proxy_orders, dependent: :destroy
has_many :orders, through: :proxy_orders
alias_attribute :billing_address, :bill_address
alias_attribute :shipping_address, :ship_address
alias_method :billing_address, :bill_address
alias_method :billing_address=, :bill_address=
alias_method :shipping_address, :ship_address
alias_method :shipping_address=, :ship_address=
accepts_nested_attributes_for :subscription_line_items, allow_destroy: true
accepts_nested_attributes_for :bill_address, :ship_address

View File

@@ -7,6 +7,8 @@ class TagRule < ApplicationRecord
scope :for, ->(enterprise) { where(enterprise_id: enterprise) }
scope :prioritised, -> { order('priority ASC') }
scope :exclude_inventory, -> { where.not(type: "TagRule::FilterProducts") }
scope :exclude_variant, -> { where.not(type: "TagRule::FilterVariants") }
def self.mapping_for(enterprises)
self.for(enterprises).each_with_object({}) do |rule, mapping|
@@ -20,6 +22,14 @@ class TagRule < ApplicationRecord
end
end
def self.matching_variant_tag_rules_by_enterprises(enterprise_id, tag)
rules = where(type: "TagRule::FilterVariants").for(enterprise_id)
return [] if rules.empty?
rules.select { |r| r.preferred_variant_tags =~ /#{tag}/ }
end
# The following method must be overriden in a concrete tagRule
def tags
raise NotImplementedError, 'please use concrete TagRule'

View File

@@ -0,0 +1,22 @@
# frozen_string_literal: true
class TagRule
class FilterVariants < TagRule
preference :matched_variants_visibility, :string, default: "visible"
preference :variant_tags, :string, default: ""
def tags_match?(variant)
variant_tags = variant&.[]("tag_list") || []
preferred_tags = preferred_variant_tags.split(",")
variant_tags.intersect?(preferred_tags)
end
def reject_matched?
preferred_matched_variants_visibility != "visible"
end
def tags
preferred_variant_tags
end
end
end

View File

@@ -8,24 +8,14 @@ module Api
:open_street_map_default_latitude,
:open_street_map_default_longitude
def open_street_map_enabled
ContentConfig.open_street_map_enabled
end
delegate :open_street_map_enabled, to: :ContentConfig
def open_street_map_provider_name
ContentConfig.open_street_map_provider_name
end
delegate :open_street_map_provider_name, to: :ContentConfig
def open_street_map_provider_options
ContentConfig.open_street_map_provider_options
end
delegate :open_street_map_provider_options, to: :ContentConfig
def open_street_map_default_latitude
ContentConfig.open_street_map_default_latitude
end
delegate :open_street_map_default_latitude, to: :ContentConfig
def open_street_map_default_longitude
ContentConfig.open_street_map_default_longitude
end
delegate :open_street_map_default_longitude, to: :ContentConfig
end
end

View File

@@ -36,7 +36,7 @@ class EmbeddedPageService
def embedding_without_https?
@request.referer && URI(@request.referer).scheme != 'https' &&
!Rails.env.test? && !Rails.env.development?
!Rails.env.local?
end
def process_embedded_request

View File

@@ -118,13 +118,22 @@ module OrderCycles
end
def variants
options[:inventory_enabled] ? stocked_variants_and_overrides : stocked_variants
return tag_rule_filtered_variants if options[:variant_tag_enabled]
return stocked_variants_and_overrides if options[:inventory_enabled]
stocked_variants
end
def stocked_variants
Spree::Variant.joins(:stock_items).where(query_stock)
end
def tag_rule_filtered_variants
VariantTagRulesFilterer.new(distributor:, customer:,
variants_relation: stocked_variants).call
end
def stocked_variants_and_overrides
stocked_variants = Spree::Variant.
joins("LEFT OUTER JOIN variant_overrides ON variant_overrides.variant_id = spree_variants.id

View File

@@ -9,7 +9,7 @@
# ( despite the use of `TagRule::FilterProducts.prioritised` ). It will apply the "show rule"
# if any
# * When there is no default rule, the order of customer related rules doesn't matter, it will
# apply the "hide rule" if any
# apply the "show rule" over any hide rule
#
class ProductTagRulesFilterer
def initialize(distributor, customer, variants_relation)

View File

@@ -0,0 +1,109 @@
# frozen_string_literal: true
# Takes a Spree::Variant AR object and filters results based on applicable tag rules.
# Tag rules exists in the context of enterprise, customer, and variants.
# Returns a Spree::Variant AR object.
# The filtering is somewhat not intuitive when they are conflicting rules in play:
# * When a variant is hidden by a default rule, It will apply the "show rule" if any
# * When there is no default rule, it will apply the "show rule" over any "hide rule"
#
class VariantTagRulesFilterer
def initialize(distributor:, customer:, variants_relation: )
@distributor = distributor
@customer = customer
@variants_relation = variants_relation
end
def call
return variants_relation unless distributor_rules.any?
filter(variants_relation)
end
private
attr_accessor :distributor, :customer, :variants_relation
def distributor_rules
@distributor_rules ||= TagRule::FilterVariants.for(distributor).all
end
def filter(variants_relation)
return variants_relation unless variants_to_hide.any?
variants_relation.where(query_with_tag_rules)
end
def query_with_tag_rules
"#{variant_not_hidden_by_rule} OR #{variant_shown_by_rule}"
end
def variant_not_hidden_by_rule
return "FALSE" unless variants_to_hide.any?
"spree_variants.id NOT IN (#{variants_to_hide.join(',')})"
end
def variant_shown_by_rule
return "FALSE" unless variants_to_show.any?
"spree_variants.id IN (#{variants_to_show.join(',')})"
end
def variants_to_hide
@variants_to_hide ||= Spree::Variant.where(supplier: distributor)
.tagged_with(default_rule_tags + hide_rule_tags, any: true)
.pluck(:id)
end
def variants_to_show
@variants_to_show ||= Spree::Variant.where(supplier: distributor)
.tagged_with(show_rule_tags, any: true)
.pluck(:id)
end
def default_rule_tags
default_rules.map(&:preferred_variant_tags)
end
def hide_rule_tags
hide_rules.map(&:preferred_variant_tags)
end
def show_rule_tags
show_rules.map(&:preferred_variant_tags)
end
def default_rules
# These rules hide a variant with tag X and apply to all customers
distributor_rules.select(&:is_default?)
end
def non_default_rules
# These rules show or hide a variant with tag X for customer with tag Y
distributor_rules.reject(&:is_default?)
end
def customer_applicable_rules
# Rules which apply specifically to the current customer
@customer_applicable_rules ||= non_default_rules.select{ |rule| customer_tagged?(rule) }
end
def hide_rules
@hide_rules ||= customer_applicable_rules
.select{ |rule| rule.preferred_matched_variants_visibility == 'hidden' }
end
def show_rules
customer_applicable_rules - hide_rules
end
def customer_tagged?(rule)
customer_tag_list.include? rule.preferred_customer_tags
end
def customer_tag_list
customer&.tag_list || []
end
end

View File

@@ -5,15 +5,14 @@
- # We use a high enough index increment so that the default tag rule should not overlap with the tag rules
- # Rails will deal with non continous numbered tag_rules_attributes just fine, it saves us from having to manage the index state in javascript
- current_rule_index = 1000
- rules = @enterprise.tag_rules.prioritised.reject(&:is_default)
- if rules.empty?
- if @rules.empty?
.no_tags
= t('.no_tags_yet')
= render 'admin/enterprises/form/tag_rules/default_rules', f:, current_rule_index:
#customer-tag-rule
- tag_groups(rules).each_with_index do |group, group_index|
- tag_groups(@rules).each_with_index do |group, group_index|
- current_group_index = group_index + 1
= render TagRuleGroupFormComponent.new(group:, index: group_index, customer_rule_index: current_rule_index, tag_rule_types: @tag_rule_types)
- # Same as above, We use a high enough increcment so that the previous tag rule group does not overlap with the next tag rule group

View File

@@ -9,13 +9,12 @@
= t('.by_default')
%i.text-big.icon-question-sign{ "data-controller": "help-modal-link", "data-action": "click->help-modal-link#open", "data-help-modal-link-target-value": "tag_rule_help_modal" }
#default-tag-rule
- default_rules = @enterprise.tag_rules.select(&:is_default)
- current_rule_index = 0
- if default_rules.empty?
- if @default_rules.empty?
.no_rules
= t('.no_rules_yet')
- else
- default_rules.each_with_index do |default_rule, index|
- @default_rules.each_with_index do |default_rule, index|
- current_rule_index = index + 1
= render TagRuleFormComponent.new(rule: default_rule, index: index)
%hr

View File

@@ -80,7 +80,7 @@
= error_message_on variant, :tax_category
- if feature?(:variant_tag, spree_current_user)
%td.col-tags.field.naked_inputs
= render TagListInputComponent.new(name: f.field_name(:tag_list), tags: variant.tag_list, placeholder: t('.add_a_tag'), aria_label: t('admin.products_page.columns.tags'))
= render TagListInputComponent.new(name: f.field_name(:tag_list), tags: variant.tag_list, autocomplete_url: variant_tag_rules_admin_tag_rules_path(enterprise_id: variant.supplier_id), placeholder: t('.add_a_tag'), aria_label: t('admin.products_page.columns.tags'))
%td.col-inherits_properties.align-left
-# empty
%td.align-right

View File

@@ -0,0 +1,3 @@
- @formatted_tag_rules.each do |tag_rule|
%li.suggestion-item{ role: "option", "data-autocomplete-value": tag_rule[:tag], "data-autocomplete-label": tag_rule[:tag] }
= t("admin.products_v3.tag_rules.rules_per_tag", tag: tag_rule[:tag], count: tag_rule[:rules])

View File

@@ -65,7 +65,7 @@
.row
.small-12.columns
.active_table
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
%producer.active_table_node.row.animate-repeat{
"ng-repeat" => "producer in filteredEnterprises = (Enterprises.producers | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties:'supplied_properties')",
"ng-controller" => "ProducerNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",

View File

@@ -24,7 +24,7 @@
.row
.small-12.columns
.active_table
%producer.active_table_node.row.animate-repeat{id: "{{producer.path}}",
%producer.active_table_node.row.animate-repeat{
"ng-repeat" => "producer in filteredEnterprises = (Enterprises.producers | searchEnterprises:query | taxons:activeTaxons | properties:activeProperties:'supplied_properties')",
"ng-controller" => "ProducerNodeCtrl",
"ng-class" => "{'closed' : !open(), 'open' : open(), 'inactive' : !producer.active}",

View File

@@ -1,21 +1,19 @@
.row
.columns.small-12.medium-5
- if current_order.nil? || current_order.distributor.nil? || current_order.distributor == @order.distributor
- if current_order&.line_items.present?
= link_to main_app.cart_path, :class => "button expand" do
= t(:order_back_to_cart)
- else
.columns.small-12.medium-6
= link_to "#{main_app.enterprise_shop_path(@order.distributor)}#/shop_panel", class: "button expand" do
= t(:order_back_to_store)
.columns.small-12.medium-6
- if @order.distributor.website.present?
= link_to_service "https://", @order.distributor.website, class: "button expand" do
= t(:order_back_to_website)
- if current_order.nil? || current_order.distributor.nil? || current_order.distributor == @order.distributor
- if current_order&.line_items.present?
= link_to main_app.cart_path, :class => "button expand" do
= t(:order_back_to_cart)
- else
&nbsp;
.columns.small-12.medium-3
= link_to "#{main_app.enterprise_shop_path(@order.distributor)}#/shop_panel", class: "button expand" do
= t(:order_back_to_store)
.columns.small-12.medium-3
- if @order.distributor.website.present?
= link_to_service "https://", @order.distributor.website, class: "button expand" do
= t(:order_back_to_website)
- else
&nbsp;
- if order.changes_allowed?
.columns.show-for-medium-up.medium-1 &nbsp;
.columns.small-12.medium-3
= link_to main_app.cancel_order_path(@order), method: :put, class: "button secondary expand", "data-confirm": t('orders_confirm_cancel') do
%i.ofn-i_009-close

View File

@@ -3,7 +3,7 @@
= inject_json_array("shops", @shops.all, Api::ShopForOrdersSerializer)
= inject_saved_credit_cards
- if Stripe.publishable_key
- if Spree::Config.stripe_connect_enabled && Stripe.publishable_key
:javascript
angular.module('Darkswarm').value("stripeObject", Stripe("#{Stripe.publishable_key}"))
angular.module('Darkswarm').value("stripePublishableKey", "#{Stripe.publishable_key}")

View File

@@ -1,8 +1,8 @@
import consumer from './consumer'
import CableReady from 'cable_ready'
import consumer from "./consumer";
import CableReady from "cable_ready";
consumer.subscriptions.create("SessionChannel", {
received(data) {
if (data.cableReady) CableReady.perform(data.operations)
}
if (data.cableReady) CableReady.perform(data.operations);
},
});

View File

@@ -1,8 +1,8 @@
import ApplicationController from "./application_controller";
export default class extends ApplicationController {
static targets = ["extraParams"]
static values = { reflex: String }
static targets = ["extraParams"];
static values = { reflex: String };
connect() {
super.connect();
@@ -12,7 +12,7 @@ export default class extends ApplicationController {
let params = { bulk_ids: this.getSelectedIds() };
if (this.hasExtraParamsTarget) {
Object.assign(params, this.extraFormData())
Object.assign(params, this.extraFormData());
}
this.stimulate(this.reflexValue, params);
@@ -21,15 +21,15 @@ export default class extends ApplicationController {
// private
getSelectedIds() {
const checkboxes = document.querySelectorAll(
"table input[name='bulk_ids[]']:checked"
);
const checkboxes = document.querySelectorAll("table input[name='bulk_ids[]']:checked");
return Array.from(checkboxes).map((checkbox) => checkbox.value);
}
extraFormData() {
if (this.extraParamsTarget.constructor.name !== "HTMLFormElement") { return {} }
if (this.extraParamsTarget.constructor.name !== "HTMLFormElement") {
return {};
}
return Object.fromEntries(new FormData(this.extraParamsTarget).entries())
return Object.fromEntries(new FormData(this.extraParamsTarget).entries());
}
}

View File

@@ -35,7 +35,7 @@ export default class extends Controller {
countValueChanged() {
window.dispatchEvent(
new CustomEvent("checked:updated", { detail: { count: this.countValue } })
new CustomEvent("checked:updated", { detail: { count: this.countValue } }),
);
}
@@ -50,11 +50,10 @@ export default class extends Controller {
}
#closeDetails(elmnt) {
if (elmnt.getElementsByTagName('details').length == 0)
return;
if (elmnt.getElementsByTagName("details").length == 0) return;
Array.from(elmnt.getElementsByTagName('details')).forEach((element) => element.open = false);
}
Array.from(elmnt.getElementsByTagName("details")).forEach((element) => (element.open = false));
}
#toggleDisabled() {
if (!this.hasDisableTarget) {

View File

@@ -5,10 +5,10 @@ import { Controller } from "stimulus";
export default class ColumnPreferencesController extends Controller {
connect() {
this.table = document.querySelector('table[data-column-preferences-target="table"]');
this.cols = Array.from(this.table.querySelectorAll('col'));
this.colSpanCells = Array.from(this.table.querySelectorAll('th[colspan],td[colspan]'));
this.cols = Array.from(this.table.querySelectorAll("col"));
this.colSpanCells = Array.from(this.table.querySelectorAll("th[colspan],td[colspan]"));
// Initialise data-default-col-span
this.colSpanCells.forEach((cell)=> {
this.colSpanCells.forEach((cell) => {
cell.dataset.defaultColSpan ||= cell.colSpan;
});
@@ -33,24 +33,24 @@ export default class ColumnPreferencesController extends Controller {
this.table.classList.toggle(`hide-${name}`, !element.checked);
// Reset cell colspans
for(const cell of this.colSpanCells) {
for (const cell of this.colSpanCells) {
this.#updateColSpanCell(cell);
};
}
}
#showHideElement(element, show) {
element.style.display = show ? "" : "none";
}
#observeProductsTableRows(){
#observeProductsTableRows() {
this.productsTableObserver = new MutationObserver((mutations, _observer) => {
const mutationRecord = mutations[0];
if(mutationRecord){
if (mutationRecord) {
const productRowElement = mutationRecord.addedNodes[0];
if(productRowElement){
const newColSpanCell = productRowElement.querySelector('td[colspan]');
if (productRowElement) {
const newColSpanCell = productRowElement.querySelector("td[colspan]");
newColSpanCell.dataset.defaultColSpan ||= newColSpanCell.colSpan;
this.#updateColSpanCell(newColSpanCell);
this.colSpanCells.push(newColSpanCell);
@@ -61,11 +61,11 @@ export default class ColumnPreferencesController extends Controller {
this.productsTableObserver.observe(this.table, { childList: true });
}
#hiddenColCount(){
return this.checkboxes.filter((checkbox)=> !checkbox.checked).length;
#hiddenColCount() {
return this.checkboxes.filter((checkbox) => !checkbox.checked).length;
}
#updateColSpanCell(cell){
#updateColSpanCell(cell) {
cell.colSpan = parseInt(cell.dataset.defaultColSpan, 10) - this.#hiddenColCount();
}
}

View File

@@ -4,9 +4,7 @@ export default class extends Controller {
static targets = ["reportType", "checkbox", "label"];
handleSelectChange() {
this.reportTypeTarget.value == "csv" ?
this.disableField():
this.enableField();
this.reportTypeTarget.value == "csv" ? this.disableField() : this.enableField();
}
disableField() {

View File

@@ -2,7 +2,6 @@ import { Controller } from "stimulus";
// Close a <details> element when click outside
export default class extends Controller {
connect() {
document.body.addEventListener("click", this.#close.bind(this));
this.element.addEventListener("click", this.#stopPropagation.bind(this));

View File

@@ -1,7 +1,7 @@
import { Controller } from "stimulus";
document.addEventListener("turbolinks:before-cache", () =>
document.getElementById("flash").remove()
document.getElementById("flash").remove(),
);
export default class extends Controller {

View File

@@ -9,7 +9,7 @@ export default class extends Controller {
connect() {
if (this.hasSummaryTarget) {
window.addEventListener('beforeunload', this.handlePageUnload);
window.addEventListener("beforeunload", this.handlePageUnload);
}
if (!this.hasGuestTarget) {
@@ -50,7 +50,7 @@ export default class extends Controller {
removeUnloadEvent() {
if (this.hasSummaryTarget) {
window.removeEventListener('beforeunload', this.handlePageUnload);
window.removeEventListener("beforeunload", this.handlePageUnload);
}
}
}

View File

@@ -7,6 +7,7 @@ import consumer from "../channels/consumer";
import controller from "../controllers/application_controller";
import CableReady from "cable_ready";
import RailsNestedForm from "@stimulus-components/rails-nested-form/dist/stimulus-rails-nested-form.umd.js"; // the default module entry point is broken
import { Autocomplete } from "stimulus-autocomplete";
const application = Application.start();
const context = require.context("controllers", true, /_controller\.js$/);
@@ -37,6 +38,7 @@ contextComponents.keys().forEach((path) => {
});
application.register("nested-form", RailsNestedForm);
application.register("autocomplete", Autocomplete);
application.consumer = consumer;
StimulusReflex.initialize(application, { controller, isolate: true });

View File

@@ -9,10 +9,7 @@ export default class extends Controller {
}
countCharacters() {
this.displayCount(
this.inputTarget.value.length,
this.inputTarget.maxLength
);
this.displayCount(this.inputTarget.value.length, this.inputTarget.maxLength);
}
displayCount(count, max) {

View File

@@ -40,20 +40,11 @@ export default class extends Controller {
document.querySelector("body").classList.add("modal-open");
});
window._paq?.push([
"trackEvent",
"Signin/Signup",
"Login Modal View",
window.location.href,
]);
window._paq?.push(["trackEvent", "Signin/Signup", "Login Modal View", window.location.href]);
};
close() {
history.pushState(
{},
"",
window.location.pathname + window.location.search
);
history.pushState({}, "", window.location.pathname + window.location.search);
this.modalTarget.classList.remove("in");
this.backgroundTarget.classList.remove("in");

View File

@@ -4,9 +4,7 @@ export default class extends Controller {
static targets = ["reportType", "checkbox", "label"];
handleSelectChange() {
this.reportTypeTarget.value == "csv" ?
this.enableField():
this.disableField();
this.reportTypeTarget.value == "csv" ? this.enableField() : this.disableField();
}
disableField() {
@@ -27,4 +25,4 @@ export default class extends Controller {
this.labelTarget.classList.remove("disabled");
}
}
}
}

View File

@@ -10,12 +10,8 @@ export const useRenderCustomer = (controller) => {
${
item.bill_address.firstname
? `<strong>${I18n.t("bill_address")}</strong>
${item.bill_address.firstname} ${
item.bill_address.lastname
}<br>
${item.bill_address.address1}, ${
item.bill_address.address2
}<br>
${item.bill_address.firstname} ${item.bill_address.lastname}<br>
${item.bill_address.address1}, ${item.bill_address.address2}<br>
${item.bill_address.city}
<br>
${
@@ -27,8 +23,7 @@ export const useRenderCustomer = (controller) => {
}
${
item.bill_address.country &&
item.bill_address.country.name
item.bill_address.country && item.bill_address.country.name
? item.bill_address.country.name
: item.bill_address.country_name
}
@@ -41,9 +36,7 @@ export const useRenderCustomer = (controller) => {
renderWithNoBillAddress(item, escape) {
return `<div class='customer-autocomplete-item'>
<div class='customer-details'><h5>${escape(
item.email
)}</h5></div>
<div class='customer-details'><h5>${escape(item.email)}</h5></div>
</div>`;
},
});

View File

@@ -3,13 +3,15 @@ import { useOpenAndCloseAsAModal } from "./mixins/useOpenAndCloseAsAModal";
export default class extends Controller {
static targets = ["background", "modal"];
static values = { instant: { type: Boolean, default: false } }
static values = { instant: { type: Boolean, default: false } };
connect() {
useOpenAndCloseAsAModal(this);
window.addEventListener("modal:close", this.close.bind(this));
if (this.instantValue) { this.open() }
if (this.instantValue) {
this.open();
}
}
disconnect() {
@@ -17,6 +19,6 @@ export default class extends Controller {
}
remove(event) {
this.close(event, true)
this.close(event, true);
}
}

View File

@@ -7,7 +7,7 @@ export default class extends Controller {
let modal = document.getElementById(this.targetValue);
let modalController = this.application.getControllerForElementAndIdentifier(
modal,
this.getIdentifier()
this.getIdentifier(),
);
modalController.open();
}

View File

@@ -1,7 +1,7 @@
import { Controller } from "stimulus";
import L from "leaflet";
import LeafetProviders from "leaflet-providers";
import { OpenStreetMapProvider } from 'leaflet-geosearch';
import { OpenStreetMapProvider } from "leaflet-geosearch";
export default class extends Controller {
static targets = ["confirmAddressField", "dragPinNote"];
@@ -9,7 +9,7 @@ export default class extends Controller {
defaultLatitude: Number,
defaultLongitude: Number,
providerName: String,
providerOptions: Object
providerOptions: Object,
};
connect() {
@@ -23,7 +23,7 @@ export default class extends Controller {
async locateAddress() {
const results = await this.provider.search({ query: this.#addressQuery() });
if(results.length > 0) {
if (results.length > 0) {
const result = results[0];
this.#setLatitudeLongitude(result.y, result.x);
this.#addMarker(result.y, result.x);
@@ -46,13 +46,15 @@ export default class extends Controller {
// If someone clicks the locate address on map button without filling in their address the
// geocoded address will not be very accurate so don't zoom in too close so it's easier for
// people to see where the marker is.
if(!addressLine1 && !city && !zipcode) {
if (!addressLine1 && !city && !zipcode) {
this.zoomLevel = 6;
} else {
this.zoomLevel = 14;
}
return [addressLine1, addressLine2, city, state, zipcode, country].filter((value) => !!value).join(", ")
return [addressLine1, addressLine2, city, state, zipcode, country]
.filter((value) => !!value)
.join(", ");
}
#addMarker(latitude, longitude) {
@@ -72,13 +74,13 @@ export default class extends Controller {
#displayMap() {
// Don't initialise map in test environment because that could possibly abuse OSM tile servers
if(process.env.RAILS_ENV == "test") {
if (process.env.RAILS_ENV == "test") {
return false;
}
this.map = L.map('open-street-map')
L.tileLayer.provider(this.providerNameValue, this.providerOptionsValue).addTo(this.map)
this.map.setView([this.defaultLatitudeValue, this.defaultLongitudeValue], this.zoomLevel)
this.map = L.map("open-street-map");
L.tileLayer.provider(this.providerNameValue, this.providerOptionsValue).addTo(this.map);
this.map.setView([this.defaultLatitudeValue, this.defaultLongitudeValue], this.zoomLevel);
this.provider = new OpenStreetMapProvider();
}
@@ -88,12 +90,12 @@ export default class extends Controller {
#displayMapWhenAtRegistrationDetailsStep() {
const observer = new IntersectionObserver(
([intersectionObserverEntry]) => {
if(intersectionObserverEntry.target.offsetParent !== null) {
if (intersectionObserverEntry.target.offsetParent !== null) {
this.#displayMap();
observer.disconnect()
observer.disconnect();
}
},
{ threshold: [0] }
{ threshold: [0] },
);
observer.observe(document.getElementById("registration-details"));
}

View File

@@ -1,55 +1,58 @@
import { Controller } from "stimulus";
export default class extends Controller {
static targets = ['statusMessage', 'cancel']
static targets = ["statusMessage", "cancel"];
connect() {
this.observer = new MutationObserver(this.updateCallback);
this.observer.observe(
this.statusMessageTarget,
{ attributes: true, attributeOldValue: true, attributeFilter: ['data-type'] }
);
this.observer.observe(this.statusMessageTarget, {
attributes: true,
attributeOldValue: true,
attributeFilter: ["data-type"],
});
if (this.hasCancelTarget) {
this.cancelTarget.addEventListener('click', this.removeUnloadEvent)
this.cancelTarget.addEventListener("click", this.removeUnloadEvent);
}
}
// Callback to trigger warning modal
updateCallback(mutationsList) {
const newDataType = document.getElementById('status-message').getAttribute('data-type');
const actionName = document.getElementById('status-message').getAttribute('data-action-name');
if(!actionName) return;
const newDataType = document.getElementById("status-message").getAttribute("data-type");
const actionName = document.getElementById("status-message").getAttribute("data-action-name");
if (!actionName) return;
for(let mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-type') {
for (let mutation of mutationsList) {
if (mutation.type === "attributes" && mutation.attributeName === "data-type") {
// Only trigger warning modal when notice display (notice) is preceeded by progress display (progress)
if(mutation.oldValue === 'progress' && newDataType === 'notice') {
if (mutation.oldValue === "progress" && newDataType === "notice") {
// Hide all confirmation buttons in warning modal
document.querySelectorAll(
'#linked-order-warning-modal .modal-actions button.secondary'
).forEach((node) => {
node.style.display = 'none';
});
document
.querySelectorAll("#linked-order-warning-modal .modal-actions button.secondary")
.forEach((node) => {
node.style.display = "none";
});
// Show the appropriate confirmation button, open warning modal, and return
document.querySelectorAll(
`#linked-order-warning-modal button[data-trigger-action=${actionName}]`
).forEach((node) => {
node.style.display = 'block';
})
document.querySelector('.warning-modal button.modal-target-trigger').click();
document
.querySelectorAll(
`#linked-order-warning-modal button[data-trigger-action=${actionName}]`,
)
.forEach((node) => {
node.style.display = "block";
});
document.querySelector(".warning-modal button.modal-target-trigger").click();
}
}
}
}
removeUnloadEvent() {
window.removeEventListener('beforeunload', window.onBeforeUnloadHandler)
window.removeEventListener("beforeunload", window.onBeforeUnloadHandler);
}
disconnect() {
this.observer.disconnect();
if (this.hasCancelTarget) {
this.cancelTarget.removeEventListener('click', this.removeUnloadEvent)
this.cancelTarget.removeEventListener("click", this.removeUnloadEvent);
}
}
}

View File

@@ -1,12 +1,14 @@
import { Controller } from "stimulus";
export default class extends Controller {
moveSelectors = [".off-canvas-wrap .inner-wrap",
".off-canvas-wrap .inner-wrap .fixed",
".off-canvas-fixed .top-bar",
".off-canvas-fixed ofn-flash",
".off-canvas-fixed nav.tab-bar",
".off-canvas-fixed .page-alert"];
moveSelectors = [
".off-canvas-wrap .inner-wrap",
".off-canvas-wrap .inner-wrap .fixed",
".off-canvas-fixed .top-bar",
".off-canvas-fixed ofn-flash",
".off-canvas-fixed nav.tab-bar",
".off-canvas-fixed .page-alert",
];
connect() {
// Wait a moment after page load before showing the alert. Otherwise we often miss the

View File

@@ -21,11 +21,8 @@ export default class extends Controller {
}
setPaymentMethod(paymentMethodContainerId) {
Array.from(
document.getElementsByClassName("paymentmethod-container")
).forEach((container) => {
const enabled =
container.dataset.paymentmethodId === paymentMethodContainerId;
Array.from(document.getElementsByClassName("paymentmethod-container")).forEach((container) => {
const enabled = container.dataset.paymentmethodId === paymentMethodContainerId;
if (enabled) {
container.style.display = "block";

View File

@@ -12,9 +12,7 @@ export default class extends Controller {
this.hideAvailability();
this.showSpinner();
const response = await fetch(
this.urlValue + `?permalink="${this.permalinkFieldTarget.value}"`
);
const response = await fetch(this.urlValue + `?permalink="${this.permalinkFieldTarget.value}"`);
const result = await response.text();
if (this.initialPermalinkValue == result) {

View File

@@ -4,8 +4,8 @@ import { Controller } from "stimulus";
export default class PopoutController extends Controller {
static targets = ["button", "dialog"];
static values = {
updateDisplay: { Boolean, default: true }
}
updateDisplay: { Boolean, default: true },
};
connect() {
this.displayElements = Array.from(this.element.querySelectorAll('input:not([type="hidden"]'));

View File

@@ -23,7 +23,7 @@ export default class extends Controller {
{
method: "GET",
headers: { "Content-type": "application/json; charset=UTF-8" },
}
},
)
.then((data) => data.json())
.then((operation) => {

View File

@@ -18,11 +18,11 @@ export default class extends ApplicationController {
}
delete_product() {
this.#deleteByRecordType('product');
this.#deleteByRecordType("product");
}
delete_variant() {
this.#deleteByRecordType('variant');
this.#deleteByRecordType("variant");
}
showLoading = () => {
@@ -44,51 +44,52 @@ export default class extends ApplicationController {
getLoadingController = () => {
return (this.loadingController ||= this.application.getControllerForElementAndIdentifier(
this.loadingTarget,
"loading"
"loading",
));
};
// +recordType+ can either be 'product' or 'variant'
#deleteByRecordType(recordType) {
const deletePath = document.querySelector(`#${recordType}-delete-modal #modal-confirm-button`).getAttribute('data-delete-path');
const deletePath = document
.querySelector(`#${recordType}-delete-modal #modal-confirm-button`)
.getAttribute("data-delete-path");
const elementToBeRemoved = this.#getElementToBeRemoved(deletePath, recordType);
const handleSlideOutAnimationEnd = async () => {
// in case of test env, we won't be having csrf token
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");
try {
const response = await fetch(deletePath, {
method: 'DELETE',
method: "DELETE",
headers: {
Accept: 'text/vnd.turbo-stream.html',
'X-CSRF-Token': csrfToken,
}
Accept: "text/vnd.turbo-stream.html",
"X-CSRF-Token": csrfToken,
},
});
// need to render the turboStream message, that's why not throwing error here
if(response.status === 500) elementToBeRemoved.classList.remove('slide-out');
// need to render the turboStream message, that's why not throwing error here
if (response.status === 500) elementToBeRemoved.classList.remove("slide-out");
const responseTurboStream = await response.text();
Turbo.renderStreamMessage(responseTurboStream);
} catch(error) {
} catch (error) {
console.error(error.message);
elementToBeRemoved.classList.remove('slide-out');
}
finally {
elementToBeRemoved.removeEventListener('animationend', handleSlideOutAnimationEnd);
elementToBeRemoved.classList.remove("slide-out");
} finally {
elementToBeRemoved.removeEventListener("animationend", handleSlideOutAnimationEnd);
}
};
// remove the clone animation before deleting
elementToBeRemoved.classList.remove('slide-in');
elementToBeRemoved.classList.add('slide-out');
elementToBeRemoved.addEventListener('animationend', handleSlideOutAnimationEnd);
};
elementToBeRemoved.classList.remove("slide-in");
elementToBeRemoved.classList.add("slide-out");
elementToBeRemoved.addEventListener("animationend", handleSlideOutAnimationEnd);
}
#getElementToBeRemoved(path, recordType) {
const recordId = path.substring(path.lastIndexOf('/') + 1);
const recordId = path.substring(path.lastIndexOf("/") + 1);
const elementDomId = `${recordType}_${recordId}`;
return document.getElementById(elementDomId);
};
}
}

View File

@@ -12,7 +12,7 @@ export default class extends Controller {
received(data) {
if (data.cableReady) CableReady.perform(data.operations);
},
}
},
);
}

View File

@@ -3,16 +3,12 @@ import ApplicationController from "./application_controller";
export default class extends ApplicationController {
connect() {
super.connect();
this.element
.querySelector("input")
.addEventListener("keydown", this.searchOnEnter);
this.element.querySelector("input").addEventListener("keydown", this.searchOnEnter);
}
disconnect() {
super.disconnect();
this.element
.querySelector("input")
.removeEventListener("keydown", this.searchOnEnter);
this.element.querySelector("input").removeEventListener("keydown", this.searchOnEnter);
}
searchOnEnter = (e) => {
@@ -22,7 +18,6 @@ export default class extends ApplicationController {
};
search(e) {
this.element.querySelector(".search-button").dataset["value"] =
e.target.value;
this.element.querySelector(".search-button").dataset["value"] = e.target.value;
}
}

View File

@@ -42,11 +42,11 @@ export default class extends TomSelectController {
});
this.setValueOnTomSelectController(
document.querySelector(attribute_wrapper + "state_id"),
data ? data.state_id : ""
data ? data.state_id : "",
);
this.setValueOnTomSelectController(
document.querySelector(attribute_wrapper + "country_id"),
data ? data.country_id : ""
data ? data.country_id : "",
);
});
document.querySelector("#order_email").value = customer.email;

Some files were not shown because too many files have changed in this diff Show More