mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-04 02:31:33 +00:00
Compare commits
251 Commits
v4.4.30
...
7caaeffe80
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7caaeffe80 | ||
|
|
7d99197dde | ||
|
|
62739c0458 | ||
|
|
7fdf1a110d | ||
|
|
07a43fecdf | ||
|
|
b27e0b5339 | ||
|
|
61f29a4ebf | ||
|
|
9abaf90907 | ||
|
|
de9446f5f3 | ||
|
|
cd9bef4f7b | ||
|
|
b4385623b2 | ||
|
|
a256d01440 | ||
|
|
5f302f347a | ||
|
|
c0db3eb6ff | ||
|
|
29d3b34776 | ||
|
|
8612f7baab | ||
|
|
e770f10f2b | ||
|
|
cbcf388acc | ||
|
|
133c9c0609 | ||
|
|
864b95612a | ||
|
|
e8bd8389b5 | ||
|
|
38766f5256 | ||
|
|
e52b8daf50 | ||
|
|
b3cf977c96 | ||
|
|
bfd6319cf2 | ||
|
|
af748158aa | ||
|
|
864b876a9a | ||
|
|
822054b748 | ||
|
|
4b2406c9c2 | ||
|
|
8f0e9c9f5c | ||
|
|
958288b223 | ||
|
|
2ef9e34f28 | ||
|
|
ea0067946d | ||
|
|
a1135f7db7 | ||
|
|
8f31d8799f | ||
|
|
3e0d54f5f8 | ||
|
|
ea0967e22e | ||
|
|
0a70d70118 | ||
|
|
af9f07f496 | ||
|
|
cd7a9c606e | ||
|
|
e95a58f735 | ||
|
|
0f0ec729f1 | ||
|
|
9ab775c774 | ||
|
|
5440c0dc65 | ||
|
|
2fa681ae8a | ||
|
|
1f299c84bc | ||
|
|
3bf76c81aa | ||
|
|
d761ddabb7 | ||
|
|
60b86e1d64 | ||
|
|
58490c26c1 | ||
|
|
a692fc9d12 | ||
|
|
3795880fcd | ||
|
|
6cd79e66ad | ||
|
|
2fff568ef9 | ||
|
|
a9d586952d | ||
|
|
bbc4603106 | ||
|
|
5cfac3d2c7 | ||
|
|
8e29bc1a03 | ||
|
|
9ba43c64d7 | ||
|
|
ce2712f780 | ||
|
|
7652c72bd6 | ||
|
|
f62b32a3b9 | ||
|
|
f4e6095466 | ||
|
|
2d09c23456 | ||
|
|
6f2b29eeec | ||
|
|
8e56e076a3 | ||
|
|
48ba23af1c | ||
|
|
b5beeead74 | ||
|
|
e5cd8e5216 | ||
|
|
f634855826 | ||
|
|
8fb3f9a8b8 | ||
|
|
e0e89e6452 | ||
|
|
7f77de89fc | ||
|
|
7b5bc45d6c | ||
|
|
091023baf7 | ||
|
|
ca13b0154c | ||
|
|
29f9d1e374 | ||
|
|
0b93c1b92b | ||
|
|
cabf9a6502 | ||
|
|
6d6f79ffae | ||
|
|
a90d944404 | ||
|
|
d2af6279f4 | ||
|
|
a8a1f45f1a | ||
|
|
8e5adcd3a6 | ||
|
|
a786d08df4 | ||
|
|
e1a6cb1d28 | ||
|
|
cb1f877117 | ||
|
|
c2d8bdd414 | ||
|
|
3cf75fce72 | ||
|
|
67cd6ea6ed | ||
|
|
ef17fd7d80 | ||
|
|
ff6830f954 | ||
|
|
81f40a99d9 | ||
|
|
d4f37a3daa | ||
|
|
f8c0edd68b | ||
|
|
b3d9aafcde | ||
|
|
116c5d41d3 | ||
|
|
2c7d8745d9 | ||
|
|
6649039881 | ||
|
|
965d8d20a6 | ||
|
|
927acf01f6 | ||
|
|
e749c614a0 | ||
|
|
b08623df23 | ||
|
|
428b9b273c | ||
|
|
884d6f15ff | ||
|
|
6e73558e66 | ||
|
|
31d8f49c26 | ||
|
|
250f7be8a0 | ||
|
|
b758bf0735 | ||
|
|
2107aeded1 | ||
|
|
eaacaf42aa | ||
|
|
800bab5303 | ||
|
|
0091a60a6e | ||
|
|
715e8253ff | ||
|
|
6bb48f2c74 | ||
|
|
6a2d2c581b | ||
|
|
676f64cc4b | ||
|
|
55aa324028 | ||
|
|
68cc9ed2fe | ||
|
|
5a7258c58e | ||
|
|
335c2475ab | ||
|
|
277d185918 | ||
|
|
655fb77ce3 | ||
|
|
ba51641271 | ||
|
|
1ad58b214b | ||
|
|
e2ec3a642c | ||
|
|
66c6994d78 | ||
|
|
2cf8a6dcb9 | ||
|
|
7a767ab037 | ||
|
|
cf7e0eb2cc | ||
|
|
c097f2b622 | ||
|
|
4516d90ede | ||
|
|
d2b1511397 | ||
|
|
008e384f14 | ||
|
|
4d8bb25f86 | ||
|
|
0813f43b49 | ||
|
|
a9b72c8095 | ||
|
|
6d9c5a9c66 | ||
|
|
a89b22e397 | ||
|
|
4f3ae4f2a4 | ||
|
|
07a8617143 | ||
|
|
6c0d15b6f9 | ||
|
|
b4ee24368c | ||
|
|
4d680e5fd1 | ||
|
|
60dc710760 | ||
|
|
26f4ebc8f9 | ||
|
|
0be0e88646 | ||
|
|
cbb1e41bbc | ||
|
|
59c3bd02c7 | ||
|
|
f4395a9d18 | ||
|
|
89848efd23 | ||
|
|
f564d22941 | ||
|
|
4ac2830ce6 | ||
|
|
b91719d63c | ||
|
|
ccda70723d | ||
|
|
0ce75ec6e9 | ||
|
|
e423015f0a | ||
|
|
af085c223d | ||
|
|
87daf4eb79 | ||
|
|
741f5dfc83 | ||
|
|
f44a4356c5 | ||
|
|
2477a63f36 | ||
|
|
59a9034108 | ||
|
|
56fe7f5e21 | ||
|
|
7926ce0c79 | ||
|
|
91ecdb0eb9 | ||
|
|
f8908d0cf3 | ||
|
|
f961e2c38e | ||
|
|
cb83ad688e | ||
|
|
02019f7cae | ||
|
|
848767d50f | ||
|
|
89236f4c2f | ||
|
|
ef1d2fdb4d | ||
|
|
657f71c357 | ||
|
|
8832f2fef6 | ||
|
|
edc40c9ea9 | ||
|
|
0af9ccd17a | ||
|
|
549610bc35 | ||
|
|
214e8b85ea | ||
|
|
765ec81725 | ||
|
|
84f53abdfe | ||
|
|
8a0c32eec0 | ||
|
|
62fbaa8a6e | ||
|
|
fad37318b3 | ||
|
|
4bb1afcc8f | ||
|
|
7eccce138b | ||
|
|
17186a5974 | ||
|
|
39b83eae19 | ||
|
|
a3af15dbae | ||
|
|
49ebcc23b3 | ||
|
|
ba9f79c684 | ||
|
|
f0ecef193d | ||
|
|
08111f9a2c | ||
|
|
52dbe408dc | ||
|
|
fbbc47a8d8 | ||
|
|
c8af09e0a9 | ||
|
|
7164cbd0bd | ||
|
|
915a5ce66b | ||
|
|
5a0694acbb | ||
|
|
afef8b0a82 | ||
|
|
ae9229ec7a | ||
|
|
0c02b5d9bd | ||
|
|
b9eea88f5c | ||
|
|
c0e820e447 | ||
|
|
0662708247 | ||
|
|
3706b6d1da | ||
|
|
765ee0ed78 | ||
|
|
1df0eca4d1 | ||
|
|
6cca7a4a3a | ||
|
|
6e5154b922 | ||
|
|
977ea47487 | ||
|
|
5253aeab17 | ||
|
|
eff92b076f | ||
|
|
831d786d44 | ||
|
|
78bfd47ad3 | ||
|
|
c15bf61099 | ||
|
|
0e92bf33dc | ||
|
|
ec0e8b80eb | ||
|
|
3f98e2e559 | ||
|
|
d812815913 | ||
|
|
7e186091ff | ||
|
|
c65771eac6 | ||
|
|
50b325c944 | ||
|
|
024f324027 | ||
|
|
8751cc37f3 | ||
|
|
6e54b1e726 | ||
|
|
7cd7d2e8ea | ||
|
|
cffe573203 | ||
|
|
164bac63e0 | ||
|
|
0af3e8afcb | ||
|
|
a5bc1d5c48 | ||
|
|
17b13e75a8 | ||
|
|
6f4e071a28 | ||
|
|
1d9364ade6 | ||
|
|
28309c1910 | ||
|
|
930aac97eb | ||
|
|
e19d3d09dc | ||
|
|
5fd36e7eed | ||
|
|
c11d30eb13 | ||
|
|
7da516b637 | ||
|
|
e6fba74a87 | ||
|
|
5e4dd3864f | ||
|
|
98cfc68c3a | ||
|
|
d24348d0f2 | ||
|
|
f8cb98f43e | ||
|
|
75355b0359 | ||
|
|
b3692d7468 | ||
|
|
6189feadaa | ||
|
|
784f74f466 | ||
|
|
8c6d3a27ec | ||
|
|
da71f711c0 |
@@ -1,6 +1,8 @@
|
||||
# ENV vars for the test environment
|
||||
# Override locally with `.env.test.local`
|
||||
|
||||
OFN_REDIS_JOBS_URL="redis://localhost:6379/2"
|
||||
|
||||
SECRET_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
STRIPE_INSTANCE_SECRET_KEY="bogus_key"
|
||||
STRIPE_CUSTOMER="bogus_customer"
|
||||
|
||||
6
.github/ISSUE_TEMPLATE/release.md
vendored
6
.github/ISSUE_TEMPLATE/release.md
vendored
@@ -39,11 +39,11 @@ assignees: ''
|
||||
</details>
|
||||
- [ ] Notify [#instance-managers]:
|
||||
> @instance_managers The new release has been deployed.
|
||||
- [ ] Nudge next release manager
|
||||
- [ ] [Create issue] for next release and confirm with next release manager in [#core-devs].
|
||||
|
||||
The full process is described at https://github.com/openfoodfoundation/openfoodnetwork/wiki/Releasing.
|
||||
|
||||
[Ready To Go]: #zenhub
|
||||
[Ready To Go]: https://github.com/orgs/openfoodfoundation/projects/8?filterQuery=status%3A%22Ready+to+go+%F0%9F%9A%80%22
|
||||
[Transifex pull request]: https://github.com/openfoodfoundation/openfoodnetwork/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+head%3Atransifex
|
||||
[Draft new release]: https://github.com/openfoodfoundation/openfoodnetwork/releases/new?tag=v&title=v+Code+Name&body=Congrats%0A%0ADescription%0A%0A
|
||||
[releases]: https://github.com/openfoodfoundation/openfoodnetwork/releases
|
||||
@@ -51,3 +51,5 @@ The full process is described at https://github.com/openfoodfoundation/openfoodn
|
||||
[#testing]: https://openfoodnetwork.slack.com/app_redirect?channel=C02TZ6X00
|
||||
[Deploy to Staging]: https://github.com/openfoodfoundation/openfoodnetwork/actions/workflows/stage.yml
|
||||
[#global-community]: https://app.slack.com/client/T02G54U79/C59ADD8F2
|
||||
[Create issue]: https://github.com/openfoodfoundation/openfoodnetwork/issues/new?assignees=&labels=&projects=&template=release.md&title=Release
|
||||
[#core-devs]: https://openfoodnetwork.slack.com/archives/GK2T38QPJ
|
||||
|
||||
2
.github/workflows/linters.yml
vendored
2
.github/workflows/linters.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
uses: reviewdog/action-rubocop@v2
|
||||
with:
|
||||
rubocop_version: gemfile
|
||||
rubocop_extensions: rubocop-rails:gemfile
|
||||
rubocop_extensions: rubocop-rails:gemfile rubocop-rspec:gemfile
|
||||
reporter: github-pr-check
|
||||
level: error
|
||||
fail_on_error: true
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#
|
||||
# The configuration is split into three files. Look into those files for more details.
|
||||
#
|
||||
require: rubocop-rails
|
||||
require:
|
||||
- rubocop-rails
|
||||
- rubocop-rspec
|
||||
inherit_from:
|
||||
|
||||
# The automatically generated todo list to ignore all current violations.
|
||||
@@ -13,9 +15,10 @@ inherit_from:
|
||||
# The relaxed style rules as a common starting point which we can refine.
|
||||
- .rubocop_relaxed_styleguide.yml
|
||||
|
||||
# Our Open Food Network style guide. If you want to see all violations,
|
||||
# Our Open Food Network style guides. If you want to see all violations,
|
||||
# then use only that configuration:
|
||||
#
|
||||
# bundle exec rubocop -c .rubocop_styleguide.yml
|
||||
#
|
||||
- .rubocop_styleguide.yml
|
||||
- .rubocop_rspec_styleguide.yml
|
||||
|
||||
21
.rubocop_rspec_styleguide.yml
Normal file
21
.rubocop_rspec_styleguide.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
# OFN styleguide for rubocop-rspec
|
||||
# Because there are so many, we will disable by default, and enable rules as needed.
|
||||
|
||||
Capybara:
|
||||
Enabled: false
|
||||
|
||||
RSpec:
|
||||
Enabled: false
|
||||
|
||||
FactoryBot:
|
||||
Enabled: false
|
||||
|
||||
# Enabled rules
|
||||
|
||||
Capybara/NegationMatcher:
|
||||
Enabled: true
|
||||
EnforcedStyle: not_to
|
||||
|
||||
RSpec/ExpectChange:
|
||||
Enabled: true
|
||||
EnforcedStyle: block
|
||||
@@ -5,22 +5,55 @@ AllCops:
|
||||
NewCops: enable
|
||||
SuggestExtensions: false
|
||||
Exclude:
|
||||
- 'bin/**/*'
|
||||
- 'db/**/*'
|
||||
- 'config/**/*'
|
||||
- 'script/**/*'
|
||||
- 'vendor/**/*'
|
||||
- 'node_modules/**/*'
|
||||
- bin/**/*
|
||||
- db/**/*
|
||||
- config/**/*
|
||||
- script/**/*
|
||||
- vendor/**/*
|
||||
- node_modules/**/*
|
||||
# Excluding: inadequate Naming/FileName rule rejects GemFile name with camelcase
|
||||
- 'engines/web/Gemfile'
|
||||
- engines/web/Gemfile
|
||||
|
||||
## OFN SETTINGS
|
||||
#
|
||||
# Cop settings that have been agreed upon by the OFN community
|
||||
Bundler/DuplicatedGem:
|
||||
Enabled: false
|
||||
|
||||
Layout/LineLength:
|
||||
Enabled: true
|
||||
Max: 100
|
||||
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Enabled: true
|
||||
EnforcedStyle: indented
|
||||
|
||||
# Don't think this is a big issue, mostly picking up RPSEC scope definitions
|
||||
# with lamdas and RSpec '.to change{}' blocks
|
||||
Lint/AmbiguousBlockAssociation:
|
||||
Enabled: false
|
||||
|
||||
Lint/MissingSuper:
|
||||
Exclude:
|
||||
- app/components/**/*
|
||||
|
||||
Lint/RaiseException:
|
||||
Enabled: true
|
||||
|
||||
Lint/StructNewOverride:
|
||||
Enabled: true
|
||||
|
||||
# Heaps of offences (> 100) in specs, mostly in situations where two or more
|
||||
# instances of a model are required, but only one is referenced. Difficult to
|
||||
# fix without making the spec look messy or rewriting it.
|
||||
# Should definitely fix at some point.
|
||||
Lint/UselessAssignment:
|
||||
Exclude:
|
||||
- spec/**/*
|
||||
|
||||
Metrics:
|
||||
Enabled: true
|
||||
|
||||
Metrics/AbcSize:
|
||||
Max: 30 # default 17
|
||||
|
||||
Metrics/BlockLength:
|
||||
AllowedMethods: [
|
||||
"class_eval",
|
||||
@@ -46,13 +79,31 @@ Metrics/BlockLength:
|
||||
"xdescribe",
|
||||
]
|
||||
|
||||
Metrics/MethodLength:
|
||||
Enabled: true
|
||||
Max: 25 # default 10
|
||||
|
||||
Metrics/ParameterLists:
|
||||
CountKeywordArgs: false
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Enabled: true
|
||||
Max: 14 # default 8
|
||||
|
||||
Naming/PredicateName:
|
||||
Enabled: false
|
||||
|
||||
Naming/VariableNumber:
|
||||
AllowedIdentifiers:
|
||||
- street_address_1
|
||||
- street_address_2
|
||||
AllowedPatterns:
|
||||
- _v[\d]+
|
||||
|
||||
Rails/ApplicationRecord:
|
||||
Exclude:
|
||||
# Migrations should not contain application code:
|
||||
- "db/migrate/*.rb"
|
||||
- db/migrate/*.rb
|
||||
|
||||
# Allow many-to-many associations without explicit model.
|
||||
# - It avoids the additional code of a model class.
|
||||
@@ -61,23 +112,23 @@ Rails/ApplicationRecord:
|
||||
Rails/HasAndBelongsToMany:
|
||||
Enabled: false
|
||||
|
||||
Rails/SkipsModelValidations:
|
||||
AllowedMethods:
|
||||
- "touch"
|
||||
- "touch_all"
|
||||
- "update_all"
|
||||
- "update_attribute"
|
||||
- "update_column"
|
||||
- "update_columns"
|
||||
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- spec/**/*
|
||||
|
||||
Rails/SkipsModelValidations:
|
||||
AllowedMethods:
|
||||
- touch
|
||||
- touch_all
|
||||
- update_all
|
||||
- update_attribute
|
||||
- update_column
|
||||
- update_columns
|
||||
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
Style/StringLiterals:
|
||||
Style/FormatStringToken:
|
||||
Enabled: false
|
||||
|
||||
Style/HashSyntax:
|
||||
@@ -87,62 +138,5 @@ Style/HashSyntax:
|
||||
Style/Send:
|
||||
Enabled: true
|
||||
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Enabled: true
|
||||
EnforcedStyle: indented
|
||||
|
||||
Layout/LineLength:
|
||||
Enabled: true
|
||||
Max: 100
|
||||
|
||||
Lint/RaiseException:
|
||||
Enabled: true
|
||||
|
||||
Lint/StructNewOverride:
|
||||
Enabled: true
|
||||
|
||||
Naming/VariableNumber:
|
||||
AllowedIdentifiers:
|
||||
- street_address_1
|
||||
- street_address_2
|
||||
AllowedPatterns:
|
||||
- _v[\d]+
|
||||
|
||||
Bundler/DuplicatedGem:
|
||||
Enabled: false
|
||||
|
||||
## TEMPORARY/CONTESTED SETTINGS
|
||||
#
|
||||
# These are still to be decided upon, but recommended for inclusion by
|
||||
# oeoeaio after scrutinising offenses the codebase
|
||||
|
||||
# Don't think this is a big issue, mostly picking up RPSEC scope definitions
|
||||
# with lamdas and RSpec '.to change{}' blocks
|
||||
Lint/AmbiguousBlockAssociation:
|
||||
Enabled: false
|
||||
|
||||
# Heaps of offences (> 100) in specs, mostly in situations where two or more
|
||||
# instances of a model are required, but only one is referenced. Difficult to
|
||||
# fix without making the spec look messy or rewriting it.
|
||||
# Should definitely fix at some point.
|
||||
Lint/UselessAssignment:
|
||||
Exclude:
|
||||
- spec/**/*
|
||||
|
||||
Lint/MissingSuper:
|
||||
Exclude:
|
||||
- 'app/components/**/*'
|
||||
|
||||
Metrics/AbcSize:
|
||||
Max: 30 # default 17
|
||||
|
||||
Metrics/MethodLength:
|
||||
Enabled: true
|
||||
Max: 25 # default 10
|
||||
|
||||
Metrics/PerceivedComplexity:
|
||||
Enabled: true
|
||||
Max: 14 # default 8
|
||||
|
||||
Naming/PredicateName:
|
||||
Style/StringLiterals:
|
||||
Enabled: false
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400 --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.59.0.
|
||||
# using RuboCop version 1.60.2.
|
||||
# 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: 2
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
||||
# URISchemes: http, https
|
||||
Layout/LineLength:
|
||||
Exclude:
|
||||
- 'app/models/spree/payment.rb'
|
||||
- 'spec/system/admin/tag_rules_spec.rb'
|
||||
|
||||
# Offense count: 17
|
||||
# Offense count: 16
|
||||
# Configuration parameters: AllowedMethods.
|
||||
# AllowedMethods: enums
|
||||
Lint/ConstantDefinitionInBlock:
|
||||
Exclude:
|
||||
- 'lib/active_merchant/billing/gateways/stripe_payment_intents_decorator.rb'
|
||||
- 'lib/tasks/import_product_images.rake'
|
||||
- 'lib/tasks/users.rake'
|
||||
- 'spec/controllers/spree/admin/base_controller_spec.rb'
|
||||
@@ -153,8 +143,8 @@ Metrics/AbcSize:
|
||||
- 'lib/tasks/enterprises.rake'
|
||||
- 'spec/services/order_checkout_restart_spec.rb'
|
||||
|
||||
# Offense count: 44
|
||||
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
|
||||
# Offense count: 9
|
||||
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
||||
# AllowedMethods: refine
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
@@ -164,26 +154,6 @@ Metrics/BlockLength:
|
||||
- 'app/models/spree/shipment.rb'
|
||||
- 'lib/spree/core/controller_helpers/common.rb'
|
||||
- 'lib/tasks/data.rake'
|
||||
- 'spec/factories.rb'
|
||||
- 'spec/factories/address_factory.rb'
|
||||
- 'spec/factories/enterprise_factory.rb'
|
||||
- 'spec/factories/line_item_factory.rb'
|
||||
- 'spec/factories/order_cycle_factory.rb'
|
||||
- 'spec/factories/order_factory.rb'
|
||||
- 'spec/factories/product_factory.rb'
|
||||
- 'spec/factories/shipment_factory.rb'
|
||||
- 'spec/factories/shipping_method_factory.rb'
|
||||
- 'spec/factories/subscription_factory.rb'
|
||||
- 'spec/factories/user_factory.rb'
|
||||
- 'spec/factories/variant_factory.rb'
|
||||
- 'spec/requests/checkout/failed_checkout_spec.rb'
|
||||
- 'spec/requests/checkout/stripe_sca_spec.rb'
|
||||
- 'spec/support/cancan_helper.rb'
|
||||
- 'spec/support/matchers/select2_matchers.rb'
|
||||
- 'spec/support/matchers/table_matchers.rb'
|
||||
- 'spec/system/consumer/shopping/checkout_spec.rb'
|
||||
- 'spec/system/consumer/shopping/checkout_stripe_spec.rb'
|
||||
- 'spec/system/consumer/shopping/variant_overrides_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: CountBlocks, Max.
|
||||
@@ -445,7 +415,7 @@ Rails/HasManyOrHasOneDependent:
|
||||
- 'app/models/spree/tax_rate.rb'
|
||||
- 'app/models/spree/variant.rb'
|
||||
|
||||
# Offense count: 25
|
||||
# Offense count: 26
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/helpers/**/*.rb
|
||||
Rails/HelperInstanceVariable:
|
||||
@@ -612,12 +582,11 @@ Rails/ResponseParsedBody:
|
||||
- 'spec/controllers/spree/credit_cards_controller_spec.rb'
|
||||
- 'spec/controllers/user_registrations_controller_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Rails/RootPathnameMethods:
|
||||
Exclude:
|
||||
- 'spec/lib/reports/orders_and_fulfillment/order_cycle_customer_totals_report_spec.rb'
|
||||
- 'spec/models/terms_of_service_file_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
@@ -790,14 +759,6 @@ Style/ClassAndModuleChildren:
|
||||
- 'spec/controllers/spree/admin/base_controller_spec.rb'
|
||||
- 'spec/models/spree/payment_method_spec.rb'
|
||||
|
||||
# Offense count: 2
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
||||
# SupportedStyles: annotated, template, unannotated
|
||||
# AllowedMethods: redirect
|
||||
Style/FormatStringToken:
|
||||
EnforcedStyle: unannotated
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
@@ -928,7 +889,12 @@ Style/PreferredHashMethods:
|
||||
Style/RedundantArgument:
|
||||
Exclude:
|
||||
- 'engines/dfc_provider/app/services/authorization_control.rb'
|
||||
- 'spec/support/query_counter.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
Style/RedundantAssignment:
|
||||
Exclude:
|
||||
- 'spec/models/database_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
@@ -995,7 +961,7 @@ Style/SlicingWithRange:
|
||||
- 'engines/order_management/app/services/order_management/subscriptions/validator.rb'
|
||||
- 'lib/discourse/single_sign_on.rb'
|
||||
|
||||
# Offense count: 28
|
||||
# Offense count: 25
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: Mode.
|
||||
Style/StringConcatenation:
|
||||
@@ -1017,6 +983,5 @@ Style/StringConcatenation:
|
||||
- 'spec/models/spree/line_item_spec.rb'
|
||||
- 'spec/models/spree/product_spec.rb'
|
||||
- 'spec/services/embedded_page_service_spec.rb'
|
||||
- 'spec/support/api_helper.rb'
|
||||
- 'spec/support/features/datepicker_helper.rb'
|
||||
- 'spec/system/admin/products_spec.rb'
|
||||
|
||||
5
Gemfile
5
Gemfile
@@ -5,7 +5,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
||||
|
||||
ruby File.read('.ruby-version').chomp
|
||||
|
||||
gem 'dotenv-rails', require: 'dotenv/rails-now' # Load ENV vars before other gems
|
||||
gem 'dotenv', require: 'dotenv/load' # Load ENV vars before other gems
|
||||
|
||||
gem 'rails'
|
||||
|
||||
@@ -161,6 +161,7 @@ group :test, :development do
|
||||
gem 'letter_opener', '>= 1.4.1'
|
||||
gem 'rspec-rails', ">= 3.5.2"
|
||||
gem 'rspec-retry', require: false
|
||||
gem 'rspec-sql'
|
||||
gem 'rswag'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'stimulus_reflex_testing'
|
||||
@@ -186,8 +187,10 @@ group :development do
|
||||
gem 'rails-erd'
|
||||
gem 'rubocop'
|
||||
gem 'rubocop-rails'
|
||||
gem 'rubocop-rspec'
|
||||
gem 'spring'
|
||||
gem 'spring-commands-rspec'
|
||||
gem 'spring-commands-rubocop'
|
||||
gem 'web-console'
|
||||
|
||||
gem 'rack-mini-profiler', '< 3.0.0'
|
||||
|
||||
71
Gemfile.lock
71
Gemfile.lock
@@ -98,11 +98,12 @@ GEM
|
||||
activejob (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
globalid (>= 0.3.6)
|
||||
activemerchant (1.123.0)
|
||||
activemerchant (1.133.0)
|
||||
activesupport (>= 4.2)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
rexml (~> 3.2.5)
|
||||
activemodel (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
activerecord (7.0.8)
|
||||
@@ -174,7 +175,7 @@ GEM
|
||||
bcp47_spec (0.2.1)
|
||||
bcrypt (3.1.19)
|
||||
bigdecimal (3.0.2)
|
||||
bindata (2.4.15)
|
||||
bindata (2.5.0)
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.18.3)
|
||||
msgpack (~> 1.2)
|
||||
@@ -221,7 +222,7 @@ GEM
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.2.3)
|
||||
connection_pool (2.4.1)
|
||||
crack (0.4.6)
|
||||
crack (1.0.0)
|
||||
bigdecimal
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
@@ -258,10 +259,7 @@ GEM
|
||||
diff-lcs (1.5.0)
|
||||
digest (3.1.1)
|
||||
docile (1.4.0)
|
||||
dotenv (2.8.1)
|
||||
dotenv-rails (2.8.1)
|
||||
dotenv (= 2.8.1)
|
||||
railties (>= 3.2)
|
||||
dotenv (3.1.0)
|
||||
email_validator (2.2.4)
|
||||
activemodel
|
||||
erubi (1.12.0)
|
||||
@@ -286,7 +284,7 @@ GEM
|
||||
webrick (~> 1.7)
|
||||
websocket-driver (>= 0.6, < 0.8)
|
||||
ffaker (2.23.0)
|
||||
ffi (1.15.5)
|
||||
ffi (1.16.3)
|
||||
flipper (0.26.2)
|
||||
concurrent-ruby (< 2)
|
||||
flipper-active_record (0.26.2)
|
||||
@@ -328,16 +326,18 @@ GEM
|
||||
good_migrations (0.2.1)
|
||||
activerecord (>= 3.1)
|
||||
railties (>= 3.1)
|
||||
haml (5.2.2)
|
||||
temple (>= 0.8.0)
|
||||
haml (6.3.0)
|
||||
temple (>= 0.8.2)
|
||||
thor
|
||||
tilt
|
||||
hashdiff (1.1.0)
|
||||
hashery (2.1.2)
|
||||
hashie (5.0.0)
|
||||
highline (2.0.3)
|
||||
htmlentities (4.3.4)
|
||||
i18n (1.14.1)
|
||||
i18n (1.14.3)
|
||||
concurrent-ruby (~> 1.0)
|
||||
racc (~> 1.7)
|
||||
i18n-js (3.9.2)
|
||||
i18n (>= 0.6.6)
|
||||
image_processing (1.12.2)
|
||||
@@ -361,7 +361,7 @@ GEM
|
||||
railties (>= 3.2.16)
|
||||
json (2.7.1)
|
||||
json-canonicalization (1.0.0)
|
||||
json-jwt (1.16.5)
|
||||
json-jwt (1.16.6)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
base64
|
||||
@@ -382,16 +382,17 @@ GEM
|
||||
rspec (>= 2.0, < 4.0)
|
||||
jsonapi-serializer (2.2.0)
|
||||
activesupport (>= 4.2)
|
||||
jwt (2.7.1)
|
||||
jwt (2.8.1)
|
||||
base64
|
||||
knapsack_pro (6.0.4)
|
||||
rake
|
||||
language_server-protocol (3.17.0.3)
|
||||
launchy (2.5.0)
|
||||
addressable (~> 2.7)
|
||||
letter_opener (1.8.1)
|
||||
launchy (2.5.2)
|
||||
addressable (~> 2.8)
|
||||
letter_opener (1.9.0)
|
||||
launchy (>= 2.2, < 3)
|
||||
link_header (0.0.8)
|
||||
listen (3.8.0)
|
||||
listen (3.9.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.22.0)
|
||||
@@ -414,7 +415,7 @@ GEM
|
||||
mini_magick (4.11.0)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.5)
|
||||
minitest (5.22.1)
|
||||
minitest (5.22.2)
|
||||
monetize (1.13.0)
|
||||
money (~> 6.12)
|
||||
money (6.16.0)
|
||||
@@ -505,7 +506,7 @@ GEM
|
||||
railties (>= 4.2)
|
||||
raabro (1.4.0)
|
||||
racc (1.7.3)
|
||||
rack (2.2.8)
|
||||
rack (2.2.8.1)
|
||||
rack-mini-profiler (2.3.4)
|
||||
rack (>= 1.2.0)
|
||||
rack-oauth2 (2.2.1)
|
||||
@@ -582,7 +583,7 @@ GEM
|
||||
redcarpet (3.6.0)
|
||||
redis (5.1.0)
|
||||
redis-client (>= 0.17.0)
|
||||
redis-client (0.19.1)
|
||||
redis-client (0.20.0)
|
||||
connection_pool
|
||||
regexp_parser (2.9.0)
|
||||
reline (0.4.1)
|
||||
@@ -627,6 +628,9 @@ GEM
|
||||
rspec-support (~> 3.12)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-sql (0.0.1)
|
||||
activesupport
|
||||
rspec
|
||||
rspec-support (3.12.1)
|
||||
rswag (2.13.0)
|
||||
rswag-api (= 2.13.0)
|
||||
@@ -654,13 +658,21 @@ GEM
|
||||
rubocop-ast (>= 1.30.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.30.0)
|
||||
parser (>= 3.2.1.0)
|
||||
rubocop-ast (1.31.1)
|
||||
parser (>= 3.3.0.4)
|
||||
rubocop-capybara (2.20.0)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-factory_bot (2.25.1)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-rails (2.23.1)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
rubocop-ast (>= 1.30.0, < 2.0)
|
||||
rubocop-rspec (2.27.1)
|
||||
rubocop (~> 1.40)
|
||||
rubocop-capybara (~> 2.17)
|
||||
rubocop-factory_bot (~> 2.22)
|
||||
ruby-graphviz (1.2.5)
|
||||
rexml
|
||||
ruby-progressbar (1.13.0)
|
||||
@@ -684,7 +696,7 @@ GEM
|
||||
semantic_range (3.0.0)
|
||||
shoulda-matchers (6.1.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (7.2.1)
|
||||
sidekiq (7.2.2)
|
||||
concurrent-ruby (< 2)
|
||||
connection_pool (>= 2.3.0)
|
||||
rack (>= 2.2.4)
|
||||
@@ -705,6 +717,8 @@ GEM
|
||||
spring (4.1.3)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
spring-commands-rubocop (0.4.0)
|
||||
spring (>= 1.0)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
@@ -733,7 +747,7 @@ GEM
|
||||
stimulus_reflex (>= 3.3.0)
|
||||
stringex (2.8.6)
|
||||
stringio (3.1.0)
|
||||
stripe (10.8.0)
|
||||
stripe (10.10.0)
|
||||
swd (2.0.3)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
@@ -760,7 +774,7 @@ GEM
|
||||
validates_lengths_from_database (0.8.0)
|
||||
activerecord (>= 4)
|
||||
vcr (6.2.0)
|
||||
view_component (3.10.0)
|
||||
view_component (3.11.0)
|
||||
activesupport (>= 5.2.0, < 8.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
method_source (~> 1.0)
|
||||
@@ -781,7 +795,7 @@ GEM
|
||||
activesupport
|
||||
faraday (~> 2.0)
|
||||
faraday-follow_redirects
|
||||
webmock (3.20.0)
|
||||
webmock (3.23.0)
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
@@ -846,7 +860,7 @@ DEPENDENCIES
|
||||
devise-token_authenticatable
|
||||
dfc_provider!
|
||||
digest
|
||||
dotenv-rails
|
||||
dotenv
|
||||
factory_bot_rails (= 6.2.0)
|
||||
faraday
|
||||
ffaker
|
||||
@@ -912,11 +926,13 @@ DEPENDENCIES
|
||||
roo
|
||||
rspec-rails (>= 3.5.2)
|
||||
rspec-retry
|
||||
rspec-sql
|
||||
rswag
|
||||
rswag-api
|
||||
rswag-ui
|
||||
rubocop
|
||||
rubocop-rails
|
||||
rubocop-rspec
|
||||
sd_notify
|
||||
select2-rails!
|
||||
shoulda-matchers
|
||||
@@ -926,6 +942,7 @@ DEPENDENCIES
|
||||
spreadsheet_architect
|
||||
spring
|
||||
spring-commands-rspec
|
||||
spring-commands-rubocop
|
||||
state_machines-activerecord
|
||||
stimulus_reflex (= 3.5.0.rc3)
|
||||
stimulus_reflex_testing
|
||||
|
||||
@@ -32,7 +32,7 @@ We also have a [Super Admin Guide][super-admin-guide] to help with configuration
|
||||
|
||||
## Testing
|
||||
|
||||
If you'd like to help out with testing, please introduce yourself on the #testing channel on [Slack][slack-invite] and download the [ZenHub browser extension][zenhub] to view the development pipeline. Also, do have a look in our [Welcome New QAs board][welcome-qa] for some good first issues, both on manual and automated testing (RSpec/Capybara).
|
||||
If you'd like to help out with testing, please introduce yourself on the #testing channel on [Slack][slack-invite]. Also, do have a look in our [Welcome New QAs board][welcome-qa] for some good first issues, both on manual and automated testing (RSpec/Capybara).
|
||||
|
||||
We use [BrowserStack](https://www.browserstack.com/) as a manual testing tool. BrowserStack provides open source projects with unlimited and free of charge accounts. A big thanks to them!
|
||||
|
||||
@@ -53,4 +53,3 @@ Copyright (c) 2012 - 2024 Open Food Foundation, released under the AGPL licence.
|
||||
[super-admin-guide]: https://ofn-user-guide.gitbook.io/ofn-super-admin-guide
|
||||
[welcome-dev]: https://github.com/orgs/openfoodfoundation/projects/5
|
||||
[welcome-qa]: https://github.com/orgs/openfoodfoundation/projects/6
|
||||
[zenhub]: https://www.zenhub.com/extension
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
%li{ ng: { class: "{active: selector.active}" } }
|
||||
%a{ "tooltip" => "{{selector.object.value}}", "tooltip-placement" => "bottom",
|
||||
ng: { transclude: true, class: "{active: selector.active, 'has-tip': selector.object.value}" } }
|
||||
%li{ "ng-class": "{active: selector.active}" }
|
||||
%a{ tooltip: "{{selector.object.value}}", "tooltip-placement": "bottom", "ng-transclude": true, "ng-class": "{active: selector.active, 'has-tip': selector.object.value}" }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.sixteen.columns.alpha.omega.alert-row{ ng: { show: '!dismissed' } }
|
||||
.sixteen.columns.alpha.omega.alert-row{ "ng-show": '!dismissed' }
|
||||
.fifteen.columns.pad.alpha
|
||||
%span.message.text-big{ ng: { bind: 'message'} }
|
||||
%span.message.text-big{ "ng-bind": 'message' }
|
||||
|
||||
%input{ type: 'button', ng: { value: "buttonText", show: 'buttonText && buttonAction', click: "buttonAction()" } }
|
||||
%input{ type: 'button', "ng-value": "buttonText", "ng-show": 'buttonText && buttonAction', "ng-click": "buttonAction()" }
|
||||
.one.column.omega.pad.text-center
|
||||
%a.close{ href: "#", ng: { click: "dismiss()" } }
|
||||
%a.close{ href: "#", "ng-click": "dismiss()" }
|
||||
×
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
.ofn-drop-down.ofn-drop-down-v2.right#columns-dropdown{ ng: { controller: 'ColumnsDropdownCtrl' } }
|
||||
.ofn-drop-down.ofn-drop-down-v2.right#columns-dropdown{ "ng-controller": 'ColumnsDropdownCtrl' }
|
||||
.ofn-drop-down-label
|
||||
= " #{t('admin.columns')}".html_safe
|
||||
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
%div.menu{ 'ng-show' => "expanded" }
|
||||
.menu_items
|
||||
.menu_item{ ng: { repeat: "column in columns", click: "toggle(column);" } }
|
||||
%input.redesigned-input{ type: "checkbox", ng: { checked: "column.visible" } }
|
||||
.menu_item{ "ng-repeat": "column in columns", "ng-click": "toggle(column);" }
|
||||
%input.redesigned-input{ type: "checkbox", "ng-checked": "column.visible" }
|
||||
{{ column.name }}
|
||||
%hr
|
||||
%div.menu_item.text-center
|
||||
%input.fullwidth.orange{ type: "button", ng: { value: "saved() ? 'Saved': 'Saving'", show: "saved() || saving", disabled: "saved()" } }
|
||||
%input.fullwidth.red{ type: "button", :value => t('admin.column_save_as_default').html_safe, ng: { show: "!saved() && !saving", click: "saveColumnPreferences(action)"} }
|
||||
%input.fullwidth.orange{ type: "button", "ng-value": "saved() ? 'Saved': 'Saving'", "ng-show": "saved() || saving", "ng-disabled": "saved()" }
|
||||
%input.fullwidth.red{ type: "button", value: t('admin.column_save_as_default').html_safe, "ng-show": "!saved() && !saving", "ng-click": "saveColumnPreferences(action)" }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#confirm-dialog{ ng: { class: "dialog_class" } }
|
||||
#confirm-dialog{ "ng-class": "dialog_class" }
|
||||
.message.clearfix.margin-bottom-30
|
||||
.icon.text-center
|
||||
%i.icon-question-sign
|
||||
.text{ ng: { bind: "::message" } }
|
||||
.text{ "ng-bind": "::message" }
|
||||
.action-buttons.text-center
|
||||
%button.cancel{ ng: { click: "close()", bind: "::cancelText" } }
|
||||
%button.confirm.red{ ng: { click: "confirm()", bind: "::confirmText" } }
|
||||
%button.cancel{ "ng-click": "close()", "ng-bind": "::cancelText" }
|
||||
%button.confirm.red{ "ng-click": "confirm()", "ng-bind": "::confirmText" }
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#edit-address-dialog
|
||||
%h2 {{ addressType === 'bill_address' ? "#{t('admin.customers.index.edit_bill_address')}" : "#{t('admin.customers.index.edit_ship_address')}" }}
|
||||
%form{ name: 'edit_address_form', novalidate: true, ng: { submit: 'updateAddress()'}}
|
||||
%form{ name: 'edit_address_form', novalidate: true, "ng-submit": 'updateAddress()' }
|
||||
.row
|
||||
{{ 'admin.customers.index.required_fileds' | t }}
|
||||
(
|
||||
%span.required *
|
||||
)
|
||||
.error{ ng: { repeat: "error in errors", bind: "error" } }
|
||||
.error{ "ng-repeat": "error in errors", "ng-bind": "error" }
|
||||
|
||||
%table.no-borders
|
||||
%tr
|
||||
@@ -14,61 +14,55 @@
|
||||
{{ 'first_name' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'firstname', required: true, ng: { model: 'address.firstname'} }
|
||||
%input{ type: 'text', name: 'firstname', required: true, "ng-model": 'address.firstname' }
|
||||
%tr
|
||||
%td
|
||||
{{ 'last_name' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'lastname', required: true, ng: { model: 'address.lastname'} }
|
||||
%input{ type: 'text', name: 'lastname', required: true, "ng-model": 'address.lastname' }
|
||||
%tr
|
||||
%td
|
||||
{{ 'address' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'address1', required: true, ng: { model: 'address.address1'} }
|
||||
%input{ type: 'text', name: 'address1', required: true, "ng-model": 'address.address1' }
|
||||
%tr
|
||||
%td
|
||||
{{ 'address2' | t }}
|
||||
%td
|
||||
%input{ type: 'text', name: 'address2', ng: { model: 'address.address2'} }
|
||||
%input{ type: 'text', name: 'address2', "ng-model": 'address.address2' }
|
||||
%tr
|
||||
%td
|
||||
{{ 'city' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'city', required: true, ng: { model: 'address.city'} }
|
||||
%input{ type: 'text', name: 'city', required: true, "ng-model": 'address.city' }
|
||||
%tr
|
||||
%td
|
||||
{{ 'postcode' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'zipcode', required: true, ng: { model: 'address.zipcode'} }
|
||||
%input{ type: 'text', name: 'zipcode', required: true, "ng-model": 'address.zipcode' }
|
||||
%tr
|
||||
%td
|
||||
{{ 'country' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input.ofn-select2.fullwidth#country_id{ type: 'number',
|
||||
name: 'country_id', required: true,
|
||||
placeholder: "{{ 'admin.customers.index.select_country' | t }}",
|
||||
data: 'availableCountries', ng: { model: 'address.country_id' } }
|
||||
%input.ofn-select2.fullwidth#country_id{ type: 'number', name: 'country_id', required: true, placeholder: "{{ 'admin.customers.index.select_country' | t }}", data: 'availableCountries', "ng-model": 'address.country_id' }
|
||||
%tr
|
||||
%td
|
||||
{{ 'state' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input.ofn-select2.fullwidth#state_id{ type: 'number',
|
||||
name: 'state_id', required: true,
|
||||
placeholder: "{{ 'admin.customers.index.select_state' | t }}",
|
||||
data: 'states', ng: { model: 'address.state_id' } }
|
||||
%input.ofn-select2.fullwidth#state_id{ type: 'number', name: 'state_id', required: true, placeholder: "{{ 'admin.customers.index.select_state' | t }}", data: 'states', "ng-model": 'address.state_id' }
|
||||
|
||||
%tr
|
||||
%td
|
||||
{{ 'phone' | t }}
|
||||
%span.required *
|
||||
%td
|
||||
%input{ type: 'text', name: 'phone', required: true, ng: { model: 'address.phone'} }
|
||||
%input{ type: 'text', name: 'phone', required: true, "ng-model": 'address.phone' }
|
||||
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'submit', value: t('admin.customers.index.update_address')}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#info-dialog{ ng: { class: "dialog_class" } }
|
||||
#info-dialog{ "ng-class": "dialog_class" }
|
||||
.message.clearfix.margin-bottom-30
|
||||
.icon.text-center
|
||||
%i{ ng: { class: "icon_class" } }
|
||||
%i{ "ng-class": "icon_class" }
|
||||
.text
|
||||
{{ message }}
|
||||
.action-buttons.text-center
|
||||
%button{ ng: { click: "close()" } }
|
||||
%button{ "ng-click": "close()" }
|
||||
= t(:ok)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
%h4.modal-title
|
||||
= t('js.admin.orders.index.compiling_invoices')
|
||||
|
||||
%p.message{ ng: { show: 'message' } }
|
||||
%p.message{ "ng-show": 'message' }
|
||||
{{message}}
|
||||
%p.error{ ng: { show: 'error' } }
|
||||
%p.error{ "ng-show": 'error' }
|
||||
{{error}}
|
||||
|
||||
%img.spinner{ src: image_path("/spinning-circles.svg"), ng: { show: "loading" } }
|
||||
%p{ ng: { show: "loading" } }
|
||||
%img.spinner{ src: image_path("/spinning-circles.svg"), "ng-show": "loading" }
|
||||
%p{ "ng-show": "loading" }
|
||||
= t('js.admin.orders.index.please_wait')
|
||||
|
||||
%a.button{ target: '_blank', ng: { click: 'showBulkInvoice()', href: '/admin/orders/invoices/{{invoice_id}}', show: "!loading && !error" } }
|
||||
%a.button{ target: '_blank', "ng-click": 'showBulkInvoice()', "ng-href": '/admin/orders/invoices/{{invoice_id}}', "ng-show": "!loading && !error" }
|
||||
= t('js.admin.orders.index.view_file')
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
%a.close-reveal-modal{"ng-click" => "$close()"}
|
||||
%i.fa.fa-times-circle{'aria-hidden' => "true"}
|
||||
|
||||
%form#image_upload{ name: 'form', novalidate: true, enctype: 'multipart/form-data', multipart: true, ng: { controller: "ProductImageCtrl" } }
|
||||
%form#image_upload{ name: 'form', novalidate: true, enctype: 'multipart/form-data', multipart: true, "ng-controller": "ProductImageCtrl" }
|
||||
%div.image-preview
|
||||
%img.spinner{ src: image_path("/spinning-circles.svg"), ng: { hide: "!imageUploader.isUploading" }}
|
||||
%img.preview{ng: {src: "{{imagePreview}}", class: "{'faded': imageUploader.isUploading}"}}
|
||||
%img.spinner{ src: image_path("/spinning-circles.svg"), "ng-hide": "!imageUploader.isUploading" }
|
||||
%img.preview{ "ng-src": "{{imagePreview}}", "ng-class": "{'faded': imageUploader.isUploading}" }
|
||||
|
||||
%label{for: 'image-upload', class: 'button'} {{ 'admin.products.index.upload_an_image' | t }}
|
||||
%input#image-upload{hidden: true, type: 'file', 'nv-file-select' => true, uploader: "imageUploader"}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
{{ 'js.admin.customers.index.add_a_new_customer_for' | t:{ shop_name: CurrentShop.shop.name } }}
|
||||
|
||||
%form{ name: 'new_customer_form', novalidate: true, ng: { submit: "addCustomer()" }}
|
||||
%form{ name: 'new_customer_form', novalidate: true, "ng-submit": "addCustomer()" }
|
||||
|
||||
.text-center.margin-bottom-30
|
||||
%input.fullwidth{ type: 'email', name: 'email', required: true, placeholder: "{{ 'js.admin.customers.index.customer_placeholder' | t }}", ng: { model: "email" } }
|
||||
%div{ ng: { show: "submitted && new_customer_form.$pristine" } }
|
||||
.error{ ng: { show: "(new_customer_form.email.$error.email || new_customer_form.email.$error.required)" } }
|
||||
%input.fullwidth{ type: 'email', name: 'email', required: true, placeholder: "{{ 'js.admin.customers.index.customer_placeholder' | t }}", "ng-model": "email" }
|
||||
%div{ "ng-show": "submitted && new_customer_form.$pristine" }
|
||||
.error{ "ng-show": "(new_customer_form.email.$error.email || new_customer_form.email.$error.required)" }
|
||||
{{ 'js.admin.customers.index.valid_email_error' | t }}
|
||||
.error{ ng: { repeat: "error in errors", bind: "error" } }
|
||||
.error{ "ng-repeat": "error in errors", "ng-bind": "error" }
|
||||
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'submit', value: "{{ 'js.admin.customers.index.add_customer' | t }}" }
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
.text-center.margin-bottom-30
|
||||
-# %select.fullwidth{ 'select2-min-search' => 5, 'ng-model' => 'newRuleType', 'ng-options' => 'ruleType.id as ruleType.name for ruleType in availableRuleTypes' }
|
||||
%input.ofn-select2.fullwidth{ :id => 'rule_type_selector', ng: { model: "ruleType" }, data: "ruleTypes", 'min-search' => "5" }
|
||||
%input.ofn-select2.fullwidth{ id: 'rule_type_selector', data: "ruleTypes", "min-search": "5", "ng-model": "ruleType" }
|
||||
|
||||
.text-center
|
||||
%input.button.red.icon-plus{ type: 'button', value: "{{ 'js.admin.new_tag_rule_dialog.add_rule' | t }}", ng: { click: 'addRule(tagGroup, ruleType)' } }
|
||||
%input.button.red.icon-plus{ type: 'button', value: "{{ 'js.admin.new_tag_rule_dialog.add_rule' | t }}", "ng-click": 'addRule(tagGroup, ruleType)' }
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
%td#available-order-cycles
|
||||
{{ 'js.admin.order_cycles.schedules.available' | t }}
|
||||
.order-cycles
|
||||
.order-cycle{ ng: { repeat: 'orderCycle in orderCycles | available:selectedOrderCycles as availableOrderCycles', click: 'selections.available = orderCycle', dblclick: 'add(orderCycle)', class: '{selected: selections.available == orderCycle}' } }
|
||||
.order-cycle{ "ng-repeat": 'orderCycle in orderCycles | available:selectedOrderCycles as availableOrderCycles', "ng-click": 'selections.available = orderCycle', "ng-dblclick": 'add(orderCycle)', "ng-class": '{selected: selections.available == orderCycle}' }
|
||||
{{ orderCycle.name }}
|
||||
%td#add-remove-buttons
|
||||
%a.add.button{ href: 'javascript:void(0)', ng: { click: 'add()' } }
|
||||
%a.add.button{ href: 'javascript:void(0)', "ng-click": 'add()' }
|
||||
%i.icon-chevron-right
|
||||
%a.remove.button{ href: 'javascript:void(0)', ng: { click: 'remove()' } }
|
||||
%a.remove.button{ href: 'javascript:void(0)', "ng-click": 'remove()' }
|
||||
%i.icon-chevron-left
|
||||
%td#selected-order-cycles
|
||||
{{ 'js.admin.order_cycles.schedules.selected' | t }}
|
||||
.order-cycles
|
||||
.order-cycle{ ng: { repeat: 'orderCycle in selectedOrderCycles', click: 'selections.selected = orderCycle', dblclick: 'remove(orderCycle)', class: '{selected: selections.selected == orderCycle}' } }
|
||||
.order-cycle{ "ng-repeat": 'orderCycle in selectedOrderCycles', "ng-click": 'selections.selected = orderCycle', "ng-dblclick": 'remove(orderCycle)', "ng-class": '{selected: selections.selected == orderCycle}' }
|
||||
{{ orderCycle.name }}
|
||||
.error{ ng: { repeat: "error in errors", bind: "error" } }
|
||||
.error{ "ng-repeat": "error in errors", "ng-bind": "error" }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
%td{ colspan: "{{columnCount}}", ng: { if: "template" } }
|
||||
.panel{ ng: { include: "template" } }
|
||||
%td{ colspan: "{{columnCount}}", "ng-if": "template" }
|
||||
.panel{ "ng-include": "template" }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.row.enterprise_package_panel{ ng: { controller: 'indexPackagePanelCtrl' } }
|
||||
.row.enterprise_package_panel{ "ng-controller": 'indexPackagePanelCtrl' }
|
||||
.alpha.eight.columns
|
||||
%div{ ng: { if: "!enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%div{ "ng-if": "!enterprise.is_primary_producer", "ng-switch": "enterprise.sells" }
|
||||
.info{ "ng-switch-when": "none" }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.hub_profile' | t }}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.hub_profile_text2' | t }}
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
.info{ "ng-switch-when": "any" }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop' | t }}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop_text3' | t }}
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
.info{ "ng-switch-default": true }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package' | t }}
|
||||
%i.icon-arrow-right
|
||||
@@ -40,8 +40,8 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package_text2' | t }}
|
||||
|
||||
%div{ ng: { if: "enterprise.is_primary_producer", switch: "enterprise.sells" } }
|
||||
.info{ ng: { switch: { when: "none" } } }
|
||||
%div{ "ng-if": "enterprise.is_primary_producer", "ng-switch": "enterprise.sells" }
|
||||
.info{ "ng-switch-when": "none" }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only_text3' | t }}
|
||||
|
||||
.info{ ng: { switch: { when: "own" } } }
|
||||
.info{ "ng-switch-when": "own" }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_shop' | t }}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.producer_shop_text2' | t }}
|
||||
|
||||
.info{ ng: { switch: { when: "any" } } }
|
||||
.info{ "ng-switch-when": "any" }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub' | t }}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub_text3' | t }}
|
||||
|
||||
.info{ ng: { switch: { default: true } } }
|
||||
.info{ "ng-switch-default": true }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package' | t }}
|
||||
%i.icon-arrow-right
|
||||
@@ -93,9 +93,9 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.choose_package_text2' | t }}
|
||||
|
||||
.omega.eight.columns{ ng: { switch: "enterprise.is_primary_producer" } }
|
||||
%div{ ng: { switch: { when: "false" } } }
|
||||
%a.button.selector.hub-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
|
||||
.omega.eight.columns{ "ng-switch": "enterprise.is_primary_producer" }
|
||||
%div{ "ng-switch-when": "false" }
|
||||
%a.button.selector.hub-profile{ "ng-click": "enterprise.owned && (enterprise.sells='none')", "ng-class": "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" }
|
||||
.top
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
|
||||
@@ -103,15 +103,15 @@
|
||||
{{ 'js.admin.panels.enterprise_package.get_listing' | t }}
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_package.always_free' | t }}
|
||||
%a.button.selector.hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
|
||||
%a.button.selector.hub{ "ng-click": "enterprise.owned && (enterprise.sells='any')", "ng-class": "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" }
|
||||
.top
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.hub_shop' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.sell_produce_others' | t }}
|
||||
|
||||
%div{ ng: { switch: { when: "true" } } }
|
||||
%a.button.selector.producer-profile{ ng: { click: "enterprise.owned && (enterprise.sells='none')", class: "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" } }
|
||||
%div{ "ng-switch-when": "true" }
|
||||
%a.button.selector.producer-profile{ "ng-click": "enterprise.owned && (enterprise.sells='none')", "ng-class": "{selected: enterprise.sells=='none', disabled: !enterprise.owned}" }
|
||||
.top
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.profile_only' | t }}
|
||||
@@ -119,27 +119,27 @@
|
||||
{{ 'js.admin.panels.enterprise_package.get_listing' | t }}
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_package.always_free' | t }}
|
||||
%a.button.selector.producer-shop{ ng: { click: "enterprise.owned && (enterprise.sells='own')", class: "{selected: enterprise.sells=='own', disabled: !enterprise.owned}" } }
|
||||
%a.button.selector.producer-shop{ "ng-click": "enterprise.owned && (enterprise.sells='own')", "ng-class": "{selected: enterprise.sells=='own', disabled: !enterprise.owned}" }
|
||||
.top
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_shop' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.sell_own_produce' | t }}
|
||||
|
||||
%a.button.selector.producer-hub{ ng: { click: "enterprise.owned && (enterprise.sells='any')", class: "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" } }
|
||||
%a.button.selector.producer-hub{ "ng-click": "enterprise.owned && (enterprise.sells='any')", "ng-class": "{selected: enterprise.sells=='any', disabled: !enterprise.owned}" }
|
||||
.top
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_package.producer_hub' | t }}
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_package.sell_both' | t }}
|
||||
|
||||
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
|
||||
%span{ ng: {hide: "saved() || saving" } }
|
||||
%a.button.update.fullwidth{ "ng-show": "enterprise.owned", "ng-class": "{disabled: saved() && !saving, saving: saving}", "ng-click": "save()" }
|
||||
%span{ "ng-hide": "saved() || saving" }
|
||||
{{ 'js.admin.panels.save' | t }}
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
%span{ "ng-show": "saved() && !saving" }
|
||||
{{ 'js.admin.panels.saved' | t }}
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
%span{ "ng-show": "saving" }
|
||||
{{ 'js.admin.panels.saving' | t }}
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.row.enterprise_producer_panel{ ng: { controller: 'indexProducerPanelCtrl' } }
|
||||
.row.enterprise_producer_panel{ "ng-controller": 'indexProducerPanelCtrl' }
|
||||
.alpha.eight.columns
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==true" } }
|
||||
.info{ "ng-show": "enterprise.is_primary_producer==true" }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.producer' | t }}
|
||||
%p
|
||||
@@ -8,7 +8,7 @@
|
||||
%p
|
||||
{{ 'js.admin.panels.enterprise_producer.producer_text2' | t }}
|
||||
|
||||
.info{ ng: { show: "enterprise.is_primary_producer==false" } }
|
||||
.info{ "ng-show": "enterprise.is_primary_producer==false" }
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer' | t }}
|
||||
%p
|
||||
@@ -17,7 +17,7 @@
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer_text2' | t }}
|
||||
|
||||
.omega.eight.columns
|
||||
%a.button.selector.producer{ ng: { click: 'enterprise.owned && changeToProducer()', class: "{selected: enterprise.is_primary_producer==true, disabled: !enterprise.owned}" } }
|
||||
%a.button.selector.producer{ "ng-click": 'enterprise.owned && changeToProducer()', "ng-class": "{selected: enterprise.is_primary_producer==true, disabled: !enterprise.owned}" }
|
||||
.top
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.producer' | t }}
|
||||
@@ -26,7 +26,7 @@
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_producer.producer_example' | t }}
|
||||
|
||||
%a.button.selector.non-producer{ ng: { click: 'enterprise.owned && changeToNonProducer()', class: "{selected: enterprise.is_primary_producer==false, disabled: !enterprise.owned}" } }
|
||||
%a.button.selector.non-producer{ "ng-click": 'enterprise.owned && changeToNonProducer()', "ng-class": "{selected: enterprise.is_primary_producer==false, disabled: !enterprise.owned}" }
|
||||
.top
|
||||
%h3
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer' | t }}
|
||||
@@ -35,13 +35,13 @@
|
||||
.bottom
|
||||
{{ 'js.admin.panels.enterprise_producer.non_producer_example' | t }}
|
||||
|
||||
%a.button.update.fullwidth{ ng: { show: "enterprise.owned", class: "{disabled: saved() && !saving, saving: saving}", click: "save()" } }
|
||||
%span{ ng: {hide: "saved() || saving" } }
|
||||
%a.button.update.fullwidth{ "ng-show": "enterprise.owned", "ng-class": "{disabled: saved() && !saving, saving: saving}", "ng-click": "save()" }
|
||||
%span{ "ng-hide": "saved() || saving" }
|
||||
{{ 'js.admin.panels.save' | t }}
|
||||
%i.icon-save
|
||||
%span{ ng: {show: "saved() && !saving" } }
|
||||
%span{ "ng-show": "saved() && !saving" }
|
||||
{{ 'js.admin.panels.saved' | t }}
|
||||
%i.icon-ok-sign
|
||||
%span{ ng: {show: "saving" } }
|
||||
%span{ "ng-show": "saving" }
|
||||
{{ 'js.admin.panels.saving' | t }}
|
||||
%i.icon-refresh
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
.row.enterprise_status_panel{ ng: { controller: 'indexStatusPanelCtrl' } }
|
||||
.row.enterprise_status_panel{ "ng-controller": 'indexStatusPanelCtrl' }
|
||||
.alpha.omega.sixteen.columns
|
||||
%h4.status-ok.text-center{ ng: { show: "issues.length == 0 && warnings.length == 0" } }
|
||||
%h4.status-ok.text-center{ "ng-show": "issues.length == 0 && warnings.length == 0" }
|
||||
%i.icon-ok-sign
|
||||
{{ 'js.admin.panels.enterprise_status.status_title' | t:{ name: object.name } }}
|
||||
|
||||
%table{ ng: { show: "issues.length > 0 || warnings.length > 0" } }
|
||||
%table{ "ng-show": "issues.length > 0 || warnings.length > 0" }
|
||||
%thead
|
||||
%th.severity
|
||||
{{ 'js.admin.panels.enterprise_status.severity' | t }}
|
||||
@@ -12,17 +12,17 @@
|
||||
{{ 'js.admin.panels.enterprise_status.description' | t }}
|
||||
%th.resolve
|
||||
{{ 'js.admin.panels.enterprise_status.resolve' | t }}
|
||||
%tr{ ng: { repeat: "issue in issues"} }
|
||||
%tr{ "ng-repeat": "issue in issues" }
|
||||
%td.severity
|
||||
%i.icon-warning-sign.issue
|
||||
%td.description
|
||||
%span{ ng: { bind: "::issue.description" } }
|
||||
%span{ "ng-bind": "::issue.description" }
|
||||
%td.resolve
|
||||
%div{ ng: { bind: { html: "issue.link" } } }
|
||||
%tr{ ng: { repeat: "warning in warnings"} }
|
||||
%div{ "ng-bind-html": "issue.link" }
|
||||
%tr{ "ng-repeat": "warning in warnings" }
|
||||
%td.severity
|
||||
%i.icon-warning-sign.warning
|
||||
%td.description
|
||||
%span{ ng: { bind: "::warning.description" } }
|
||||
%span{ "ng-bind": "::warning.description" }
|
||||
%td.resolve
|
||||
%div{ ng: { bind: { html: "warning.link" } } }
|
||||
%div{ "ng-bind-html": "warning.link" }
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#save-bar.animate-show{ ng: { show: 'dirty || persist || StatusMessage.active()' } }
|
||||
#save-bar.animate-show{ "ng-show": 'dirty || persist || StatusMessage.active()' }
|
||||
.container
|
||||
.seven.columns.alpha
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage == ''", style: 'StatusMessage.statusMessage.style' } }
|
||||
%h5#status-message{ "ng-show": "StatusMessage.invalidMessage == ''", "ng-style": 'StatusMessage.statusMessage.style' }
|
||||
{{ StatusMessage.statusMessage.text || " " }}
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage !== ''" }, style: 'color: #C85136' }
|
||||
%h5#status-message{ style: 'color: #C85136', "ng-show": "StatusMessage.invalidMessage !== ''" }
|
||||
{{ StatusMessage.invalidMessage || " " }}
|
||||
.nine.columns.omega.text-right{ ng: { transclude: true } }
|
||||
.nine.columns.omega.text-right{ "ng-transclude": true }
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#schedule-dialog
|
||||
.text-normal.margin-bottom-30.text-center
|
||||
%span{ ng: { hide: 'schedule.id' } }
|
||||
%span{ "ng-hide": 'schedule.id' }
|
||||
{{ 'js.admin.order_cycles.schedules.adding_a_new_schedule' | t }}
|
||||
%span{ ng: { show: 'schedule.id' } }
|
||||
%span{ "ng-show": 'schedule.id' }
|
||||
{{ 'js.admin.order_cycles.schedules.updating_a_schedule' | t }}
|
||||
|
||||
%form{ name: 'schedule_form', novalidate: true, ng: { submit: "submit()" }}
|
||||
%form{ name: 'schedule_form', novalidate: true, "ng-submit": "submit()" }
|
||||
|
||||
.text-center.margin-bottom-20
|
||||
%input.fullwidth{ type: 'text', name: 'name', required: true, placeholder: "{{ 'js.admin.order_cycles.schedules.schedule_name_placeholder' | t }}", ng: { model: "schedule.name" } }
|
||||
%div{ ng: { show: "submitted && schedule_form.$pristine" } }
|
||||
.error{ ng: { show: "(schedule_form.name.$error.required)" } }
|
||||
%input.fullwidth{ type: 'text', name: 'name', required: true, placeholder: "{{ 'js.admin.order_cycles.schedules.schedule_name_placeholder' | t }}", "ng-model": "schedule.name" }
|
||||
%div{ "ng-show": "submitted && schedule_form.$pristine" }
|
||||
.error{ "ng-show": "(schedule_form.name.$error.required)" }
|
||||
{{ 'js.admin.order_cycles.schedules.name_required_error' | t }}
|
||||
|
||||
.order-cycles-selector.text-center.margin-bottom-30
|
||||
|
||||
.text-center
|
||||
|
||||
%input.button{ type: 'submit', value: "{{ 'js.admin.order_cycles.schedules.create_schedule' | t }}", ng: { hide: 'schedule.id' } }
|
||||
%input.button{ type: 'submit', value: "{{ 'js.admin.order_cycles.schedules.update_schedule' | t }}", ng: { show: 'schedule.id' } }
|
||||
%span{ ng: { show: 'schedule.id' } } or
|
||||
%input.button.red{ type: 'button', value: "{{ 'js.admin.order_cycles.schedules.delete_schedule' | t }}", ng: { show: 'schedule.id', click: 'delete()'} }
|
||||
%input.button{ type: 'button', value: "{{ 'actions.cancel' | t }}", ng: { click: 'close()' } }
|
||||
%input.button{ type: 'submit', value: "{{ 'js.admin.order_cycles.schedules.create_schedule' | t }}", "ng-hide": 'schedule.id' }
|
||||
%input.button{ type: 'submit', value: "{{ 'js.admin.order_cycles.schedules.update_schedule' | t }}", "ng-show": 'schedule.id' }
|
||||
%span{ "ng-show": 'schedule.id' } or
|
||||
%input.button.red{ type: 'button', value: "{{ 'js.admin.order_cycles.schedules.delete_schedule' | t }}", "ng-show": 'schedule.id', "ng-click": 'delete()' }
|
||||
%input.button{ type: 'button', value: "{{ 'actions.cancel' | t }}", "ng-click": 'close()' }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.tag-template
|
||||
%div
|
||||
%span.tag-with-rules{ ng: { if: "data.rules" }, "ofn-with-tip" => "{{ 'admin.tag_has_rules' | t:{num: data.rules} }}" }
|
||||
%span.tag-with-rules{ "ofn-with-tip": "{{ 'admin.tag_has_rules' | t:{num: data.rules} }}", "ng-if": "data.rules" }
|
||||
{{$getDisplayText()}}
|
||||
%span{ ng: { if: "!data.rules" } }
|
||||
%span{ "ng-if": "!data.rules" }
|
||||
{{$getDisplayText()}}
|
||||
%a.remove-button{ ng: {click: "$removeTag()"} }
|
||||
%a.remove-button{ "ng-click": "$removeTag()" }
|
||||
✖
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
.autocomplete-template
|
||||
%span.tag-with-rules{ ng: { if: "data.rules" } }
|
||||
%span.tag-with-rules{ "ng-if": "data.rules" }
|
||||
{{$getDisplayText()}}
|
||||
%span.tag-with-rules{ ng: { if: "data.rules == 1" } }
|
||||
%span.tag-with-rules{ "ng-if": "data.rules == 1" }
|
||||
—
|
||||
{{ 'admin.has_one_rule' | t }}
|
||||
%span.tag-with-rules{ ng: { if: "data.rules > 1" } }
|
||||
%span.tag-with-rules{ "ng-if": "data.rules > 1" }
|
||||
—
|
||||
{{ 'admin.has_n_rules' | t:{ num: data.rules } }}
|
||||
%span{ ng: { if: "!data.rules" } }
|
||||
%span{ "ng-if": "!data.rules" }
|
||||
{{$getDisplayText()}}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
%div
|
||||
%input{ type: "number",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_calculator_attributes_preferred_flat_percent",
|
||||
min: -100,
|
||||
max: 100,
|
||||
ng: { model: "rule.calculator.preferred_flat_percent" }, 'invert-number' => true }
|
||||
%input{ type: "number", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_calculator_attributes_preferred_flat_percent", min: -100, max: 100, "invert-number": true, "ng-model": "rule.calculator.preferred_flat_percent" }
|
||||
%span.text-normal %
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]",
|
||||
ng: { model: "rule.preferred_matched_order_cycles_visibility", if: "!rule.is_default" },
|
||||
data: 'visibilityOptions', "min-search" => 5 }
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_order_cycles_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_order_cycles_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_order_cycles_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
=t(:not_visible)
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]",
|
||||
ng: { model: "rule.preferred_matched_payment_methods_visibility", if: "!rule.is_default" },
|
||||
data: 'visibilityOptions', "min-search" => 5 }
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_payment_methods_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_payment_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_payment_methods_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
= t(:not_visible)
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]",
|
||||
ng: { model: "rule.preferred_matched_variants_visibility", if: "!rule.is_default" },
|
||||
data: 'visibilityOptions', "min-search" => 5 }
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_variants_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_variants_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_variants_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
= t(:not_visible)
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
%div
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]",
|
||||
ng: { model: "rule.preferred_matched_shipping_methods_visibility", if: "!rule.is_default" },
|
||||
data: 'visibilityOptions', "min-search" => 5 }
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]",
|
||||
ng: { value: "'hidden'", if: "rule.is_default" } }
|
||||
%span.text-normal{ ng: { if: "rule.is_default" } }
|
||||
%input.fullwidth.light.ofn-select2{ id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]", data: 'visibilityOptions', "min-search": 5, "ng-model": "rule.preferred_matched_shipping_methods_visibility", "ng-if": "!rule.is_default" }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_matched_shipping_methods_visibility", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_matched_shipping_methods_visibility]", "ng-value": "'hidden'", "ng-if": "rule.is_default" }
|
||||
%span.text-normal{ "ng-if": "rule.is_default" }
|
||||
= t(:not_visible)
|
||||
|
||||
|
||||
@@ -6,45 +6,27 @@
|
||||
%col.actions{ width: "10%" }
|
||||
%tr
|
||||
%td
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_id",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][id]",
|
||||
ng: { value: "rule.id" } }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_id", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][id]", "ng-value": "rule.id" }
|
||||
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_type",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][type]",
|
||||
ng: { value: "rule.type" } }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_type", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][type]", "ng-value": "rule.type" }
|
||||
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_priority",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][priority]",
|
||||
ng: { value: "tagGroup.startIndex + $index" } }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_priority", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][priority]", "ng-value": "tagGroup.startIndex + $index" }
|
||||
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_is_default",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][is_default]",
|
||||
ng: { value: "rule.is_default" } }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_is_default", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][is_default]", "ng-value": "rule.is_default" }
|
||||
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_customer_tags",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_customer_tags]",
|
||||
ng: { value: "rule.preferred_customer_tags" } }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_customer_tags", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_customer_tags]", "ng-value": "rule.preferred_customer_tags" }
|
||||
|
||||
%input{ type: "hidden",
|
||||
id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_{{opt[rule.type].taggable}}_tags",
|
||||
name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_{{opt[rule.type].taggable}}_tags]",
|
||||
ng: { value: "opt[rule.type].tagListFor(rule)" } }
|
||||
%input{ type: "hidden", id: "enterprise_tag_rules_attributes_{{tagGroup.startIndex + $index}}_preferred_{{opt[rule.type].taggable}}_tags", name: "enterprise[tag_rules_attributes][{{tagGroup.startIndex + $index}}][preferred_{{opt[rule.type].taggable}}_tags]", "ng-value": "opt[rule.type].tagListFor(rule)" }
|
||||
|
||||
%span.text-normal {{ opt[rule.type].textTop }}
|
||||
%td
|
||||
%tags-with-translation{ object: "rule", max: 1, "tags-attr" => "{{opt[rule.type].tagsAttr}}", "tag-list-attr" => "{{opt[rule.type].tagListAttr}}" }
|
||||
%td.actions{ rowspan: 2 }
|
||||
%a{ ng: { click: "deleteTagRule(tagGroup || defaultTagGroup, rule)" }, :class => "delete-tag-rule icon-trash no-text" }
|
||||
%a{ class: "delete-tag-rule icon-trash no-text", "ng-click": "deleteTagRule(tagGroup || defaultTagGroup, rule)" }
|
||||
%tr
|
||||
%td
|
||||
%span.text-normal {{ opt[rule.type].textBottom }}
|
||||
%td
|
||||
%div{ ng: { include: "opt[rule.type].inputTemplate"} }
|
||||
%div{ "ng-include": "opt[rule.type].inputTemplate" }
|
||||
|
||||
%hr
|
||||
|
||||
@@ -1,10 +1,2 @@
|
||||
%tags-input{ template: 'admin/tag.html',
|
||||
"placeholder" => t('admin.order_cycles.form.add_a_tag'),
|
||||
ng: { model: 'object[tagsAttr]', class: "{'limit-reached': limitReached}"},
|
||||
on: { tag: { added: 'tagAdded($tag)', removed:'tagRemoved()' } } }
|
||||
%auto-complete{ ng: { if: "findTags" }, source: "findTags({query: $query})",
|
||||
template: "admin/tag_autocomplete.html",
|
||||
"min-length" => "0",
|
||||
"load-on-focus" => "true",
|
||||
"load-on-empty" => "true",
|
||||
"max-results-to-show" => "32"}
|
||||
%tags-input{ template: 'admin/tag.html', placeholder: t('admin.order_cycles.form.add_a_tag'), "ng-model": 'object[tagsAttr]', "ng-class": "{'limit-reached': limitReached}", "on-tag-added": 'tagAdded($tag)', "on-tag-removed": 'tagRemoved()' }
|
||||
%auto-complete{ source: "findTags({query: $query})", template: "admin/tag_autocomplete.html", "min-length": "0", "load-on-focus": "true", "load-on-empty": "true", "max-results-to-show": "32", "ng-if": "findTags" }
|
||||
|
||||
@@ -22,24 +22,22 @@
|
||||
.variant-bulk-buy-quantity-label
|
||||
{{ "js.shopfront.bulk_buy_modal.min_quantity" | t }}
|
||||
%div
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(-1)", disabled: "!canAdd(-1)"}}>
|
||||
%button.bulk-buy-add.variant-quantity{ type: "button", "ng-click": "add(-1)", "ng-disabled": "!canAdd(-1)" }>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%input.bulk-buy.variant-quantity{type: "number", min: "0", max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.quantity", max: "Infinity"}}>
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "add(1)", disabled: "!canAdd(1)"}}
|
||||
%input.bulk-buy.variant-quantity{ type: "number", min: "0", max: "{{ available() }}", "ng-model": "variant.line_item.quantity", "ng-max": "Infinity" }>
|
||||
%button.bulk-buy-add.variant-quantity{ type: "button", "ng-click": "add(1)", "ng-disabled": "!canAdd(1)" }
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
+
|
||||
.columns.small-12.medium-6
|
||||
.variant-bulk-buy-quantity-label
|
||||
{{ "js.shopfront.bulk_buy_modal.max_quantity" | t }}
|
||||
%div
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(-1)", disabled: "!canAddMax(-1)"}}>
|
||||
%button.bulk-buy-add.variant-quantity{ type: "button", "ng-click": "addMax(-1)", "ng-disabled": "!canAddMax(-1)" }>
|
||||
-# U+FF0D Fullwidth Hyphen-Minus
|
||||
-
|
||||
%input.bulk-buy.variant-quantity{type: "number", min: "0", max: "{{ available() }}",
|
||||
ng: {model: "variant.line_item.max_quantity", max: "Infinity"}}>
|
||||
%button.bulk-buy-add.variant-quantity{type: "button", ng: {click: "addMax(1)", disabled: "!canAddMax(1)"}}
|
||||
%input.bulk-buy.variant-quantity{ type: "number", min: "0", max: "{{ available() }}", "ng-model": "variant.line_item.max_quantity", "ng-max": "Infinity" }>
|
||||
%button.bulk-buy-add.variant-quantity{ type: "button", "ng-click": "addMax(1)", "ng-disabled": "!canAddMax(1)" }
|
||||
-# U+FF0B Fullwidth Plus Sign
|
||||
+
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
%ul
|
||||
%active-selector{ ng: { repeat: "selector in allSelectors", show: "ifDefined(selector.fits, true)" } }
|
||||
%active-selector{ "ng-repeat": "selector in allSelectors", "ng-show": "ifDefined(selector.fits, true)" }
|
||||
%span{"ng-bind" => "::selector.object.name"}
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
.small-12.columns.text-center
|
||||
{{ helpText }}
|
||||
.row.text-center
|
||||
%button.primary.small{ ng: { click: '$close()' } }
|
||||
%button.primary.small{ "ng-click": '$close()' }
|
||||
= t(:ok)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.row.pad-top{ng: { if: 'enterprise.is_distributor' } }
|
||||
.row.pad-top{ "ng-if": 'enterprise.is_distributor' }
|
||||
.cta-container.small-12.columns
|
||||
.row
|
||||
.small-4.columns
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.joyride-tip-guide.price_breakdown{ng: {class: "{ in: tt_isOpen, fade: tt_animation }", show: "tt_isOpen"}}
|
||||
.joyride-tip-guide.price_breakdown{ "ng-class": "{ in: tt_isOpen, fade: tt_animation }", "ng-show": "tt_isOpen" }
|
||||
%span.joyride-nub.top
|
||||
.background{ng: {click: "tt_isOpen = false"}}
|
||||
.background{ "ng-click": "tt_isOpen = false" }
|
||||
.joyride-content-wrapper
|
||||
%h6 {{ "js.shopfront.price_breakdown" | t }}
|
||||
%ul
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.joyride-tip-guide.question-mark-tooltip{class: "{{ context }}", ng: {class: "{ in: tt_isOpen, fade: tt_animation }", show: "tt_isOpen"}}
|
||||
.background{ng: {click: "tt_isOpen = false"}}
|
||||
.joyride-tip-guide.question-mark-tooltip{ class: "{{ context }}", "ng-class": "{ in: tt_isOpen, fade: tt_animation }", "ng-show": "tt_isOpen" }
|
||||
.background{ "ng-click": "tt_isOpen = false" }
|
||||
.joyride-content-wrapper
|
||||
{{ key | t }}
|
||||
%span.joyride-nub.bottom
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
|
||||
&.justify-space-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
&.justify-end {
|
||||
justify-content: flex-end;
|
||||
input[type="button"] {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
input[type="button"] {
|
||||
margin: 5px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ModalComponent < ViewComponent::Base
|
||||
def initialize(id:, close_button: true, instant: false)
|
||||
def initialize(id:, close_button: true, instant: false, modal_class: :small)
|
||||
@id = id
|
||||
@close_button = close_button
|
||||
@instant = instant
|
||||
@modal_class = modal_class
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%div{ id: @id, "data-controller": "modal", "data-action": "keyup@document->modal#closeIfEscapeKey", "data-modal-instant-value": @instant }
|
||||
.reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#close" }
|
||||
.reveal-modal.fade.small.modal-component{ "data-modal-target": "modal" }
|
||||
.reveal-modal.fade.modal-component{ "data-modal-target": "modal", class: @modal_class }
|
||||
= content
|
||||
|
||||
- if close_button?
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
visibility: visible;
|
||||
position: fixed;
|
||||
top: 3em;
|
||||
min-height: auto; // reset from reveal-modal
|
||||
|
||||
&.in {
|
||||
padding: 1.2rem;
|
||||
}
|
||||
@@ -16,9 +18,39 @@
|
||||
p {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
img {
|
||||
// Ensure image fits in container
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* prevent arrow on selected admin menu item appearing above modal */
|
||||
body.modal-open #admin-menu li.selected a::after {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
text-align: center; // Ensure text inside fullwidth buttons are centred on small screens
|
||||
|
||||
&.justify-space-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
&.justify-end {
|
||||
justify-content: flex-end;
|
||||
input[type="button"] {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
input[type="button"] {
|
||||
margin: 5px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ module Admin
|
||||
|
||||
def collection
|
||||
if json_request? && params[:enterprise_id].present?
|
||||
CustomersWithBalance.new(customers).query.
|
||||
CustomersWithBalanceQuery.new(customers).call.
|
||||
includes(
|
||||
:enterprise,
|
||||
{ bill_address: [:state, :country] },
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
module Admin
|
||||
class OidcSettingsController < Spree::Admin::BaseController
|
||||
def index; end
|
||||
def index
|
||||
@account = spree_current_user.oidc_account
|
||||
end
|
||||
|
||||
def destroy
|
||||
spree_current_user.oidc_account&.destroy
|
||||
redirect_to admin_oidc_settings_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,6 +23,8 @@ module Api
|
||||
|
||||
OrderWorkflow.new(@order).advance_to_payment if @order.line_items.any?
|
||||
|
||||
@order.recreate_all_fees!
|
||||
|
||||
render json: @shipment, serializer: Api::ShipmentSerializer, status: :ok
|
||||
end
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ module Api
|
||||
|
||||
def customer
|
||||
@customer ||= if action_name == "show"
|
||||
CustomersWithBalance.new(Customer.where(id: params[:id])).query.first!
|
||||
CustomersWithBalanceQuery.new(Customer.where(id: params[:id])).call.first!
|
||||
else
|
||||
Customer.find(params[:id])
|
||||
end
|
||||
@@ -74,7 +74,7 @@ module Api
|
||||
customers = customers.where(enterprise_id: params[:enterprise_id]) if params[:enterprise_id]
|
||||
|
||||
if @extra_customer_fields.include?(:balance)
|
||||
customers = CustomersWithBalance.new(customers).query
|
||||
customers = CustomersWithBalanceQuery.new(customers).call
|
||||
end
|
||||
|
||||
customers.ransack(params[:q]).result.order(:id)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
def openid_connect
|
||||
spree_current_user.link_from_omniauth(request.env["omniauth.auth"])
|
||||
OidcAccount.link(spree_current_user, request.env["omniauth.auth"])
|
||||
|
||||
redirect_to admin_oidc_settings_path
|
||||
end
|
||||
|
||||
@@ -59,6 +59,8 @@ module Spree
|
||||
flash[:error] = t(:cannot_perform_operation)
|
||||
end
|
||||
rescue StandardError => e
|
||||
logger.error e.message
|
||||
Bugsnag.notify(e)
|
||||
flash[:error] = e.message
|
||||
ensure
|
||||
redirect_to request.referer
|
||||
|
||||
@@ -16,7 +16,7 @@ module Spree
|
||||
before_action :set_locale
|
||||
|
||||
def show
|
||||
@payments_requiring_action = PaymentsRequiringAction.new(spree_current_user).query
|
||||
@payments_requiring_action = PaymentsRequiringActionQuery.new(spree_current_user).call
|
||||
@orders = orders_collection.includes(:line_items)
|
||||
|
||||
customers = spree_current_user.customers
|
||||
@@ -79,7 +79,7 @@ module Spree
|
||||
private
|
||||
|
||||
def orders_collection
|
||||
CompleteOrdersWithBalance.new(@user).query
|
||||
CompleteOrdersWithBalanceQuery.new(@user).call
|
||||
end
|
||||
|
||||
def load_object
|
||||
|
||||
@@ -22,7 +22,7 @@ module ShopHelper
|
||||
{ name: 'home', title: t(:shopping_tabs_home), show: show_home_tab?,
|
||||
default: show_home_tab? },
|
||||
{ name: 'shop', title: t(:shopping_tabs_shop), show: !require_customer?,
|
||||
default: !show_home_tab? },
|
||||
default: !show_home_tab?, shop: true },
|
||||
{ name: 'about', title: t(:shopping_tabs_about), show: true },
|
||||
{ name: 'producers', title: t(:shopping_tabs_producers), show: true },
|
||||
{ name: 'contact', title: t(:shopping_tabs_contact), show: true },
|
||||
|
||||
@@ -12,7 +12,7 @@ module Spree
|
||||
id: "#{model}_#{method}_field")
|
||||
end
|
||||
|
||||
def error_message_on(object, method, _options = {})
|
||||
def error_message_on(object, method, options = {})
|
||||
object = convert_to_model(object)
|
||||
obj = object.respond_to?(:errors) ? object : instance_variable_get("@#{object}")
|
||||
|
||||
@@ -20,7 +20,7 @@ module Spree
|
||||
# rubocop:disable Rails/OutputSafety
|
||||
errors = obj.errors[method].map { |err| h(err) }.join('<br />').html_safe
|
||||
# rubocop:enable Rails/OutputSafety
|
||||
content_tag(:span, errors, class: 'formError')
|
||||
content_tag(:span, errors, class: 'formError', **options)
|
||||
else
|
||||
''
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ class Invoice < ApplicationRecord
|
||||
self.belongs_to_required_by_default = false
|
||||
|
||||
belongs_to :order, class_name: 'Spree::Order'
|
||||
serialize :data, Hash
|
||||
serialize :data, Hash, coder: YAML
|
||||
before_validation :serialize_order
|
||||
after_create :cancel_previous_invoices
|
||||
default_scope { order(created_at: :desc) }
|
||||
|
||||
@@ -91,6 +91,14 @@ class Invoice
|
||||
Spree::Money.new(shipment.amount + shipment.additional_tax_total, currency:)
|
||||
end
|
||||
|
||||
def display_line_item_tax_rate(item)
|
||||
all_tax_adjustments.select { |a|
|
||||
a.adjustable.type == 'Spree::LineItem' && a.adjustable.id == item.id
|
||||
}.map(&:originator).map { |tr|
|
||||
number_to_percentage(tr.amount * 100, precision: 1)
|
||||
}.join(", ")
|
||||
end
|
||||
|
||||
def display_shipment_tax_rates
|
||||
all_eligible_adjustments.select { |a|
|
||||
a.originator.type == 'Spree::TaxRate' && a.adjustable_type == 'Spree::Shipment'
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
class Invoice
|
||||
class DataPresenter
|
||||
class LineItem < Invoice::DataPresenter::Base
|
||||
attributes :added_tax, :currency, :included_tax, :price_with_adjustments, :quantity,
|
||||
attributes :id, :added_tax, :currency, :included_tax, :price_with_adjustments, :quantity,
|
||||
:variant_id, :unit_price_price_and_unit, :unit_presentation,
|
||||
:enterprise_fee_additional_tax, :enterprise_fee_included_tax
|
||||
attributes_with_presenter :variant
|
||||
array_attribute :tax_rates, class_name: 'TaxRate'
|
||||
invoice_generation_attributes :added_tax, :included_tax, :price_with_adjustments,
|
||||
:quantity, :variant_id
|
||||
|
||||
@@ -35,10 +34,6 @@ class Invoice
|
||||
fee_tax = enterprise_fee_included_tax || 0.0
|
||||
Spree::Money.new(price_with_adjustments - ((included_tax + fee_tax) / quantity), currency:)
|
||||
end
|
||||
|
||||
def display_line_item_tax_rates
|
||||
tax_rates.map { |tr| number_to_percentage(tr.amount * 100, precision: 1) }.join(", ")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
22
app/models/oidc_account.rb
Normal file
22
app/models/oidc_account.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OidcAccount < ApplicationRecord
|
||||
belongs_to :user, class_name: "Spree::User"
|
||||
|
||||
# When a user authenticates via token, the `uid` should be mapped to only one
|
||||
# OFN user and therefore it needs to be unique.
|
||||
validates :uid, presence: true, uniqueness: true
|
||||
|
||||
def self.link(user, auth)
|
||||
attributes = {
|
||||
user_id: user.id,
|
||||
provider: auth.provider,
|
||||
uid: auth.uid,
|
||||
token: auth.dig(:credentials, :token),
|
||||
refresh_token: auth.dig(:credentials, :refresh_token),
|
||||
}
|
||||
# This skips validations but we have database constraints in place.
|
||||
# We may replace this at some point.
|
||||
upsert_all([attributes], unique_by: [:user_id]) # rubocop:disable Rails/SkipsModelValidations
|
||||
end
|
||||
end
|
||||
@@ -4,5 +4,5 @@ class ReportRenderingOptions < ApplicationRecord
|
||||
self.belongs_to_required_by_default = false
|
||||
|
||||
belongs_to :user, class_name: "Spree::User"
|
||||
serialize :options, Hash
|
||||
serialize :options, Hash, coder: YAML
|
||||
end
|
||||
|
||||
@@ -177,7 +177,7 @@ module Spree
|
||||
|
||||
can [:admin, :create], :manager_invitation
|
||||
|
||||
can [:admin, :index], :oidc_setting
|
||||
can [:admin, :index, :destroy], :oidc_setting
|
||||
|
||||
can [:admin, :create], Voucher
|
||||
end
|
||||
|
||||
@@ -4,7 +4,6 @@ require 'stripe/profile_storer'
|
||||
require 'stripe/credit_card_cloner'
|
||||
require 'stripe/authorize_response_patcher'
|
||||
require 'stripe/payment_intent_validator'
|
||||
require 'active_merchant/billing/gateways/stripe_payment_intents_decorator'
|
||||
require 'active_merchant/billing/gateways/stripe'
|
||||
|
||||
module Spree
|
||||
@@ -44,7 +43,7 @@ module Spree
|
||||
StripeAccount.find_by(enterprise_id: preferred_enterprise_id)&.stripe_user_id
|
||||
end
|
||||
|
||||
# NOTE: the name of this method is determined by Spree::Payment::Processing
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def purchase(money, creditcard, gateway_options)
|
||||
begin
|
||||
payment_intent_id = fetch_payment_intent(creditcard, gateway_options)
|
||||
@@ -64,7 +63,7 @@ module Spree
|
||||
provider.capture(money, payment_intent_id, options)
|
||||
end
|
||||
|
||||
# NOTE: the name of this method is determined by Spree::Payment::Processing
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def charge_offline(money, creditcard, gateway_options)
|
||||
customer, payment_method =
|
||||
Stripe::CreditCardCloner.new(creditcard, stripe_account_id).find_or_clone
|
||||
@@ -75,7 +74,7 @@ module Spree
|
||||
failed_activemerchant_billing_response(e.message)
|
||||
end
|
||||
|
||||
# NOTE: the name of this method is determined by Spree::Payment::Processing
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def authorize(money, creditcard, gateway_options)
|
||||
authorize_response =
|
||||
provider.authorize(*options_for_authorize(money, creditcard, gateway_options))
|
||||
@@ -84,26 +83,27 @@ module Spree
|
||||
failed_activemerchant_billing_response(e.message)
|
||||
end
|
||||
|
||||
# NOTE: the name of this method is determined by Spree::Payment::Processing
|
||||
def void(response_code, _creditcard, gateway_options)
|
||||
payment_intent_id = response_code
|
||||
payment_intent_response = Stripe::PaymentIntent.retrieve(payment_intent_id,
|
||||
stripe_account: stripe_account_id)
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def void(payment_intent_id, _creditcard, gateway_options)
|
||||
payment_intent_response = Stripe::PaymentIntent.retrieve(
|
||||
payment_intent_id, stripe_account: stripe_account_id
|
||||
)
|
||||
gateway_options[:stripe_account] = stripe_account_id
|
||||
|
||||
# If a payment has been confirmed it can't be voided by Stripe, and must be refunded instead
|
||||
if voidable?(payment_intent_response)
|
||||
provider.void(response_code, gateway_options)
|
||||
provider.void(payment_intent_id, gateway_options)
|
||||
else
|
||||
provider.refund(refundable_amount(payment_intent_response), response_code,
|
||||
gateway_options)
|
||||
provider.refund(
|
||||
payment_intent_response.amount_received, payment_intent_id, gateway_options
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# NOTE: the name of this method is determined by Spree::Payment::Processing
|
||||
def credit(money, _creditcard, response_code, gateway_options)
|
||||
# NOTE: this method is required by Spree::Payment::Processing
|
||||
def credit(money, _creditcard, payment_intent_id, gateway_options)
|
||||
gateway_options[:stripe_account] = stripe_account_id
|
||||
provider.refund(money, response_code, gateway_options)
|
||||
provider.refund(money, payment_intent_id, gateway_options)
|
||||
end
|
||||
|
||||
def create_profile(payment)
|
||||
@@ -119,11 +119,6 @@ module Spree
|
||||
VOIDABLE_STATES.include? payment_intent_response.status
|
||||
end
|
||||
|
||||
def refundable_amount(payment_intent_response)
|
||||
payment_intent_response.amount_received -
|
||||
payment_intent_response.charges.data.map(&:amount_refunded).sum
|
||||
end
|
||||
|
||||
# In this gateway, what we call 'secret_key' is the 'login'
|
||||
def options
|
||||
options = super
|
||||
|
||||
@@ -193,6 +193,7 @@ module Spree
|
||||
adjustments.tax.additional.sum(:amount)
|
||||
end
|
||||
|
||||
# Some of the tax rates may not be applicable depending to the order's tax zone
|
||||
def tax_rates
|
||||
variant&.tax_category&.tax_rates || []
|
||||
end
|
||||
|
||||
@@ -21,7 +21,8 @@ module Spree
|
||||
belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
|
||||
|
||||
has_many :offsets, -> { where("source_type = 'Spree::Payment' AND amount < 0").completed },
|
||||
class_name: "Spree::Payment", foreign_key: :source_id, dependent: :restrict_with_exception
|
||||
class_name: "Spree::Payment", foreign_key: :source_id,
|
||||
dependent: :restrict_with_exception
|
||||
has_many :log_entries, as: :source, dependent: :destroy
|
||||
|
||||
has_one :adjustment, as: :adjustable, dependent: :destroy
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
module Spree
|
||||
class Preference < ApplicationRecord
|
||||
serialize :value
|
||||
|
||||
serialize :value, coder: YAML
|
||||
validates :key, presence: true
|
||||
validates :value_type, presence: true
|
||||
|
||||
|
||||
@@ -287,6 +287,22 @@ module Spree
|
||||
variants << variant
|
||||
end
|
||||
|
||||
# Format as per WeightsAndMeasures (todo: re-orgnaise maybe after product/variant refactor)
|
||||
def variant_unit_with_scale
|
||||
scale_clean = ActiveSupport::NumberHelper.number_to_rounded(variant_unit_scale,
|
||||
precision: nil,
|
||||
strip_insignificant_zeros: true)
|
||||
[variant_unit, scale_clean].compact_blank.join("_")
|
||||
end
|
||||
|
||||
def variant_unit_with_scale=(variant_unit_with_scale)
|
||||
values = variant_unit_with_scale.split("_")
|
||||
assign_attributes(
|
||||
variant_unit: values[0],
|
||||
variant_unit_scale: values[1] || nil
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_units
|
||||
|
||||
@@ -42,6 +42,7 @@ module Spree
|
||||
has_many :credit_cards, dependent: :destroy
|
||||
has_many :report_rendering_options, class_name: "::ReportRenderingOptions", dependent: :destroy
|
||||
has_many :webhook_endpoints, dependent: :destroy
|
||||
has_one :oidc_account, dependent: :destroy
|
||||
|
||||
accepts_nested_attributes_for :enterprise_roles, allow_destroy: true
|
||||
accepts_nested_attributes_for :webhook_endpoints
|
||||
@@ -51,11 +52,6 @@ module Spree
|
||||
|
||||
validates :email, 'valid_email_2/email': { mx: true }, if: :email_changed?
|
||||
validate :limit_owned_enterprises
|
||||
validates :uid, uniqueness: true, if: lambda { uid.present? }
|
||||
|
||||
# Same validation as in the openid_connect gem.
|
||||
# This validator is totally outdated but we indirectly depend on it.
|
||||
validates :uid, email: true, if: lambda { uid.present? }
|
||||
|
||||
class DestroyWithOrdersError < StandardError; end
|
||||
|
||||
@@ -63,10 +59,6 @@ module Spree
|
||||
User.admin.count > 0
|
||||
end
|
||||
|
||||
def link_from_omniauth(auth)
|
||||
update!(provider: auth.provider, uid: auth.uid)
|
||||
end
|
||||
|
||||
# Whether a user has a role or not.
|
||||
def has_spree_role?(role_in_question)
|
||||
spree_roles.where(name: role_in_question.to_s).any?
|
||||
|
||||
@@ -69,7 +69,7 @@ module Spree
|
||||
%w(weight volume).include?(variant.product&.variant_unit)
|
||||
}
|
||||
|
||||
validates :unit_value, numericality: { greater_than: 0 }
|
||||
validates :unit_value, numericality: { greater_than: 0 }, allow_blank: true
|
||||
validates :price, numericality: { greater_than_or_equal_to: 0 }
|
||||
|
||||
validates :unit_description, presence: true, if: ->(variant) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Fetches complete orders of the specified user including their balance as a computed column
|
||||
class CompleteOrdersWithBalance
|
||||
class CompleteOrdersWithBalanceQuery
|
||||
def initialize(user)
|
||||
@user = user
|
||||
end
|
||||
|
||||
def query
|
||||
OutstandingBalance.new(sorted_finalized_orders).query
|
||||
def call
|
||||
OutstandingBalanceQuery.new(sorted_finalized_orders).call
|
||||
end
|
||||
|
||||
private
|
||||
@@ -1,11 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CompleteVisibleOrders
|
||||
class CompleteVisibleOrdersQuery
|
||||
def initialize(order_permissions)
|
||||
@order_permissions = order_permissions
|
||||
end
|
||||
|
||||
def query
|
||||
def call
|
||||
order_permissions.visible_orders.complete
|
||||
end
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
# Adds an aggregated 'balance_value' to each customer based on their order history
|
||||
#
|
||||
class CustomersWithBalance
|
||||
class CustomersWithBalanceQuery
|
||||
def initialize(customers)
|
||||
@customers = customers
|
||||
end
|
||||
|
||||
def query
|
||||
def call
|
||||
@customers.
|
||||
joins(left_join_complete_orders).
|
||||
group("customers.id").
|
||||
@@ -20,7 +20,7 @@ class CustomersWithBalance
|
||||
# The resulting orders are in states that belong after the checkout. Only these can be considered
|
||||
# for a customer's balance.
|
||||
def left_join_complete_orders
|
||||
<<~SQL
|
||||
<<~SQL.squish
|
||||
LEFT JOIN spree_orders ON spree_orders.customer_id = customers.id
|
||||
AND #{finalized_states.to_sql}
|
||||
SQL
|
||||
@@ -32,6 +32,6 @@ class CustomersWithBalance
|
||||
end
|
||||
|
||||
def outstanding_balance_sum
|
||||
"SUM(#{OutstandingBalance.new.statement})::float"
|
||||
"SUM(#{OutstandingBalanceQuery.new.statement})::float"
|
||||
end
|
||||
end
|
||||
@@ -7,11 +7,11 @@
|
||||
# Alternatively, you can get the SQL by calling #statement, which is suitable for more complex
|
||||
# cases.
|
||||
#
|
||||
# See CompleteOrdersWithBalance or CustomersWithBalance as examples.
|
||||
# See CompleteOrdersWithBalanceQuery or CustomersWithBalanceQuery as examples.
|
||||
#
|
||||
# Note this query object and `app/models/concerns/balance.rb` should implement the same behavior
|
||||
# until we find a better way. If you change one, please, change the other too.
|
||||
class OutstandingBalance
|
||||
class OutstandingBalanceQuery
|
||||
# All the states of a finished order but that shouldn't count towards the balance (the customer
|
||||
# didn't get the order for whatever reason). Note it does not include complete
|
||||
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
|
||||
@@ -22,14 +22,14 @@ class OutstandingBalance
|
||||
@relation = relation
|
||||
end
|
||||
|
||||
def query
|
||||
def call
|
||||
relation.select("#{statement} AS balance_value")
|
||||
end
|
||||
|
||||
# Arel doesn't support CASE statements until v7.1.0 so we'll have to wait with SQL literals
|
||||
# a little longer. See https://github.com/rails/arel/pull/400 for details.
|
||||
def statement
|
||||
<<~SQL
|
||||
<<~SQL.squish
|
||||
CASE WHEN "spree_orders"."state" IN #{non_fulfilled_states_group.to_sql} THEN "spree_orders"."payment_total"
|
||||
WHEN "spree_orders"."state" IS NOT NULL THEN "spree_orders"."payment_total" - "spree_orders"."total"
|
||||
ELSE 0 END
|
||||
@@ -1,12 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class PaymentsRequiringAction
|
||||
class PaymentsRequiringActionQuery
|
||||
def initialize(user)
|
||||
@user = user
|
||||
end
|
||||
|
||||
def query
|
||||
Spree::Payment.joins(:order).where("spree_orders.user_id = ?", user.id).
|
||||
def call
|
||||
Spree::Payment.joins(:order).where(spree_orders: { user_id: user.id }).
|
||||
requires_authorization
|
||||
end
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
module Api
|
||||
module Admin
|
||||
# This serializer relies on `object` to respond to `#balance_value`. That's done in
|
||||
# `CustomersWithBalance` due to the fact that ActiveRecord maps the DB result set's columns to
|
||||
# instance methods. This way, the `balance_value` alias on that class ends up being
|
||||
# `CustomersWithBalanceQuery` due to the fact that ActiveRecord maps the DB result set's
|
||||
# columns to instance methods. This way, the `balance_value` alias on that class ends up being
|
||||
# `object.balance_value` here.
|
||||
class CustomerWithBalanceSerializer < CustomerSerializer
|
||||
attributes :balance, :balance_status
|
||||
|
||||
@@ -9,8 +9,8 @@ module Api
|
||||
|
||||
has_many :payments, serializer: Api::PaymentSerializer
|
||||
|
||||
# This method relies on `balance_value` as a computed DB column. See `CompleteOrdersWithBalance`
|
||||
# for reference.
|
||||
# This method relies on `balance_value` as a computed DB column.
|
||||
# See `CompleteOrdersWithBalanceQuery` for reference.
|
||||
def outstanding_balance
|
||||
-object.balance_value
|
||||
end
|
||||
|
||||
@@ -6,7 +6,6 @@ class Invoice
|
||||
:variant_id, :unit_price_price_and_unit, :unit_presentation,
|
||||
:enterprise_fee_additional_tax, :enterprise_fee_included_tax
|
||||
has_one :variant, serializer: Invoice::VariantSerializer
|
||||
has_many :tax_rates, serializer: Invoice::TaxRateSerializer
|
||||
|
||||
def enterprise_fee_additional_tax
|
||||
EnterpriseFeeAdjustments.new(object.enterprise_fee_adjustments).total_additional_tax
|
||||
|
||||
@@ -5,7 +5,8 @@ module PermittedAttributes
|
||||
def self.attributes
|
||||
[
|
||||
:id, :name, :description, :supplier_id, :price,
|
||||
:variant_unit, :variant_unit_scale, :unit_value, :unit_description, :variant_unit_name,
|
||||
:variant_unit, :variant_unit_scale, :variant_unit_with_scale, :unit_value,
|
||||
:unit_description, :variant_unit_name,
|
||||
:display_as, :sku, :group_buy, :group_buy_unit_size,
|
||||
:taxon_ids, :primary_taxon_id, :tax_category_id,
|
||||
:meta_keywords, :notes, :inherits_properties,
|
||||
|
||||
@@ -20,6 +20,44 @@ class WeightsAndMeasures
|
||||
scales[product_scale.to_f]['system']
|
||||
end
|
||||
|
||||
# @returns enumerable with label and value for select
|
||||
def self.variant_unit_options
|
||||
available_units_sorted.flat_map do |measurement, measurement_info|
|
||||
measurement_info.filter_map do |scale, unit_info|
|
||||
scale_clean =
|
||||
ActiveSupport::NumberHelper.number_to_rounded(scale, precision: nil,
|
||||
strip_insignificant_zeros: true)
|
||||
[
|
||||
"#{I18n.t(measurement)} (#{unit_info['name']})", # Label (eg "Weight (g)")
|
||||
"#{measurement}_#{scale_clean}", # Scale ID (eg "weight_1")
|
||||
]
|
||||
end
|
||||
end <<
|
||||
[
|
||||
I18n.t('items'),
|
||||
'items'
|
||||
]
|
||||
end
|
||||
|
||||
def self.available_units
|
||||
Spree::Config.available_units.split(",")
|
||||
end
|
||||
|
||||
def self.available_units_sorted
|
||||
self::UNITS.transform_values do |measurement_info|
|
||||
# Filter to only include available units
|
||||
measurement_info.filter do |_scale, unit_info|
|
||||
available_units.include?(unit_info['name'])
|
||||
end.
|
||||
# Remove duplicates by name
|
||||
uniq do |_scale, unit_info|
|
||||
unit_info['name']
|
||||
end.
|
||||
# Sort by unit number
|
||||
sort.to_h
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
UNITS = {
|
||||
@@ -29,10 +67,10 @@ class WeightsAndMeasures
|
||||
1000.0 => { 'name' => 'kg', 'system' => 'metric' },
|
||||
1_000_000.0 => { 'name' => 'T', 'system' => 'metric' },
|
||||
|
||||
28.349523125 => { 'name' => 'oz', 'system' => 'imperial' },
|
||||
28.35 => { 'name' => 'oz', 'system' => 'imperial' },
|
||||
453.59237 => { 'name' => 'lb', 'system' => 'imperial' },
|
||||
28.349523125 => { 'name' => 'oz', 'system' => 'imperial' },
|
||||
453.6 => { 'name' => 'lb', 'system' => 'imperial' },
|
||||
453.59237 => { 'name' => 'lb', 'system' => 'imperial' },
|
||||
},
|
||||
'volume' => {
|
||||
0.001 => { 'name' => 'mL', 'system' => 'metric' },
|
||||
@@ -49,7 +87,7 @@ class WeightsAndMeasures
|
||||
return @units[@variant.product.variant_unit] if ignore_available_units
|
||||
|
||||
@units[@variant.product.variant_unit]&.reject { |_scale, unit_info|
|
||||
available_units.exclude?(unit_info['name'])
|
||||
self.class.available_units.exclude?(unit_info['name'])
|
||||
}
|
||||
end
|
||||
|
||||
@@ -67,8 +105,4 @@ class WeightsAndMeasures
|
||||
|
||||
largest_unit
|
||||
end
|
||||
|
||||
def available_units
|
||||
Spree::Config.available_units.split(",")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,22 +14,22 @@
|
||||
= admin_inject_shops(@shops, module: 'admin.customers')
|
||||
= admin_inject_available_countries(module: 'admin.customers')
|
||||
|
||||
%div{ ng: { controller: 'customersCtrl' } }
|
||||
%div{ "ng-controller": 'customersCtrl' }
|
||||
.row.filters
|
||||
.sixteen.columns.alpha.omega
|
||||
.filter_select.five.columns.alpha
|
||||
%label{ :for => 'quick_search', ng: {class: '{disabled: !shop_id}'} }=t('admin.quick_search')
|
||||
%label{ for: 'quick_search', "ng-class": '{disabled: !shop_id}' }=t('admin.quick_search')
|
||||
%br
|
||||
%input.fullwidth{ :type => "text", :id => 'quick_search', ng: { model: 'quickSearch', disabled: '!shop_id' }, :placeholder => t('.search_by_email') }
|
||||
%input.fullwidth{ type: "text", id: 'quick_search', placeholder: t('.search_by_email'), "ng-model": 'quickSearch', "ng-disabled": '!shop_id' }
|
||||
.filter_select.four.columns
|
||||
%label{ :for => 'hub_id', ng: { bind: "shop_id ? '#{t('admin.shop')}' : '#{t('admin.variant_overrides.index.select_a_shop')}'" } }
|
||||
%label{ for: 'hub_id', "ng-bind": "shop_id ? '#{t('admin.shop')}' : '#{t('admin.variant_overrides.index.select_a_shop')}'" }
|
||||
%br
|
||||
%input.ofn-select2.fullwidth#shop_id{ 'ng-model' => 'shop_id', name: 'shop_id', data: 'shops', on: { selecting: 'confirmRefresh' } }
|
||||
%input.ofn-select2.fullwidth#shop_id{ "ng-model": 'shop_id', name: 'shop_id', data: 'shops', "on-selecting": 'confirmRefresh' }
|
||||
.seven.columns.omega
|
||||
|
||||
%hr.divider{ ng: { show: "!RequestMonitor.loading && filteredCustomers.length > 0" } }
|
||||
%hr.divider{ "ng-show": "!RequestMonitor.loading && filteredCustomers.length > 0" }
|
||||
|
||||
.row.controls{ ng: { show: "!RequestMonitor.loading && filteredCustomers.length > 0" } }
|
||||
.row.controls{ "ng-show": "!RequestMonitor.loading && filteredCustomers.length > 0" }
|
||||
.thirteen.columns.alpha
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
%h1
|
||||
= t :loading_customers
|
||||
|
||||
.row.margin-bottom-50{ ng: { show: "!RequestMonitor.loading" } }
|
||||
.row.margin-bottom-50{ "ng-show": "!RequestMonitor.loading" }
|
||||
%form{ name: "customers_form" }
|
||||
%h1#no_results{ 'ng-show' => '!RequestMonitor.loading && filteredCustomers.length == 0' }
|
||||
=t :no_customers_found
|
||||
|
||||
%save-bar{ dirty: "customers_form.$dirty", persist: "false" }
|
||||
%input.red{ type: "button", value: t(:save_changes), ng: { click: "submitAll(customers_form)" } }
|
||||
%input.red{ type: "button", value: t(:save_changes), "ng-click": "submitAll(customers_form)" }
|
||||
|
||||
%table.index#customers{ 'ng-show' => '!RequestMonitor.loading && filteredCustomers.length > 0' }
|
||||
%col.email{ width: "20%", 'ng-show' => 'columns.email.visible' }
|
||||
@@ -58,7 +58,7 @@
|
||||
%col.balance{ width: "10%", 'ng-show' => 'columns.balance.visible' }
|
||||
%col.actions{ width: "10%"}
|
||||
%thead
|
||||
%tr{ ng: { controller: "ColumnsCtrl" } }
|
||||
%tr{ "ng-controller": "ColumnsCtrl" }
|
||||
-# %th.bulk
|
||||
-# %input{ :type => "checkbox", :name => 'toggle_bulk', 'ng-click' => 'toggleAllCheckboxes()', 'ng-checked' => "allBoxesChecked()" }
|
||||
%th.email{ 'ng-show' => 'columns.email.visible' }
|
||||
@@ -81,12 +81,12 @@
|
||||
%span{ 'ng-bind' => '::customer.email' }
|
||||
%span.guest-label{ 'ng-show' => 'customer.user_id == null' }= t('.guest_label')
|
||||
%td.first_name{ 'ng-show' => 'columns.first_name.visible'}
|
||||
%input{ type: 'text', name: 'first_name', ng: { model: 'customer.first_name' }, 'obj-for-update' => 'customer', 'attr-for-update' => 'first_name'}
|
||||
%input{ type: 'text', name: 'first_name', "obj-for-update": 'customer', "attr-for-update": 'first_name', "ng-model": 'customer.first_name' }
|
||||
%td.last_name{ 'ng-show' => 'columns.last_name.visible'}
|
||||
%input{ type: 'text', name: 'last_name', ng: { model: 'customer.last_name' }, 'obj-for-update' => 'customer', 'attr-for-update' => 'last_name'}
|
||||
%input{ type: 'text', name: 'last_name', "obj-for-update": 'customer', "attr-for-update": 'last_name', "ng-model": 'customer.last_name' }
|
||||
%td.code{ 'ng-show' => 'columns.code.visible' }
|
||||
%input{ type: 'text', name: 'code', ng: {model: 'customer.code', change: 'checkForDuplicateCodes()'}, "obj-for-update" => "customer", "attr-for-update" => "code" }
|
||||
%i.icon-warning-sign{ ng: {if: 'duplicate'} }
|
||||
%input{ type: 'text', name: 'code', "obj-for-update": "customer", "attr-for-update": "code", "ng-model": 'customer.code', "ng-change": 'checkForDuplicateCodes()' }
|
||||
%i.icon-warning-sign{ "ng-if": 'duplicate' }
|
||||
= t('.duplicate_code')
|
||||
%td.tags{ 'ng-show' => 'columns.tags.visible' }
|
||||
.tag_watcher{ 'obj-for-update' => "customer", "attr-for-update" => "tag_list"}
|
||||
@@ -101,6 +101,6 @@
|
||||
%td.actions
|
||||
%a{ 'ng-click' => "deleteCustomer(customer)", :class => "delete-customer icon-trash no-text" }
|
||||
|
||||
%div.text-center{ ng: { show: "filteredCustomers.length > customerLimit" } }
|
||||
%input{ type: 'button', value: t(:show_more), ng: { click: 'customerLimit = customerLimit + 20' } }
|
||||
%input{ type: 'button', value: t(:show_all_with_more, num: '{{ filteredCustomers.length - customerLimit }}'), ng: { click: 'customerLimit = filteredCustomers.length' } }
|
||||
%div.text-center{ "ng-show": "filteredCustomers.length > customerLimit" }
|
||||
%input{ type: 'button', value: t(:show_more), "ng-click": 'customerLimit = customerLimit + 20' }
|
||||
%input{ type: 'button', value: t(:show_all_with_more, num: '{{ filteredCustomers.length - customerLimit }}'), "ng-click": 'customerLimit = filteredCustomers.length' }
|
||||
|
||||
@@ -29,20 +29,20 @@
|
||||
%th.actions
|
||||
%tbody
|
||||
= enterprise_fee_set_form.ng_fields_for :collection do |f|
|
||||
%tr{ ng: { repeat: 'enterprise_fee in enterprise_fees | filter:query' } }
|
||||
%tr{ "ng-repeat": 'enterprise_fee in enterprise_fees | filter:query' }
|
||||
%td
|
||||
= f.ng_hidden_field :id
|
||||
%ofn-select{ :id => angular_id(:enterprise_id), data: 'enterprises', ng: { model: 'enterprise_fee.enterprise_id' }, style: "width: 90%" }
|
||||
%input{ type: "hidden", name: angular_name(:enterprise_id), ng: { value: "enterprise_fee.enterprise_id" } }
|
||||
%ofn-select{ id: angular_id(:enterprise_id), data: 'enterprises', style: "width: 90%", "ng-model": 'enterprise_fee.enterprise_id' }
|
||||
%input{ type: "hidden", name: angular_name(:enterprise_id), "ng-value": "enterprise_fee.enterprise_id" }
|
||||
%td= f.ng_select :fee_type, enterprise_fee_type_options, 'enterprise_fee.fee_type'
|
||||
%td= f.ng_text_field :name, { placeholder: t('.name_placeholder') }
|
||||
%td
|
||||
%ofn-select{ :id => angular_id(:tax_category_id), data: 'tax_categories', include_blank: true, ng: { model: 'enterprise_fee.tax_category_id' } }
|
||||
%ofn-select{ id: angular_id(:tax_category_id), data: 'tax_categories', include_blank: true, "ng-model": 'enterprise_fee.tax_category_id' }
|
||||
%input{ type: "hidden", name: angular_name(:tax_category_id), 'watch-tax-category' => true }
|
||||
%input{ type: "hidden", name: angular_name(:inherits_tax_category), ng: { value: "enterprise_fee.inherits_tax_category" } }
|
||||
%input{ type: "hidden", name: angular_name(:inherits_tax_category), "ng-value": "enterprise_fee.inherits_tax_category" }
|
||||
%td
|
||||
%ofn-select.calculator_type{ :id => angular_id(:calculator_type), ng: { model: 'enterprise_fee.calculator_type' }, value_attr: 'name', text_attr: 'description', data: 'calculators', 'spree-ensure-calculator-preferences-match-type' => true }
|
||||
%input{ type: "hidden", name: angular_name(:calculator_type), ng: { value: "enterprise_fee.calculator_type" } }
|
||||
%ofn-select.calculator_type{ id: angular_id(:calculator_type), value_attr: 'name', text_attr: 'description', data: 'calculators', "spree-ensure-calculator-preferences-match-type": true, "ng-model": 'enterprise_fee.calculator_type' }
|
||||
%input{ type: "hidden", name: angular_name(:calculator_type), "ng-value": "enterprise_fee.calculator_type" }
|
||||
%td{'ng-bind-html-unsafe-compiled' => 'enterprise_fee.calculator_settings'}
|
||||
%td.actions{'spree-delete-resource' => "1"}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
= render 'spree/shared/error_messages', target: @enterprise
|
||||
|
||||
= form_for [main_app, :admin, @enterprise_group] do |f|
|
||||
.row{ ng: {app: 'admin.enterprise_groups', controller: 'enterpriseGroupCtrl'}, data: { controller: 'tabs-and-panels', "tabs-and-panels-class-name-value": "selected" } }
|
||||
.row{ data: { controller: 'tabs-and-panels', "tabs-and-panels-class-name-value": "selected" }, "ng-app": 'admin.enterprise_groups', "ng-controller": 'enterpriseGroupCtrl' }
|
||||
.sixteen.columns.alpha
|
||||
.four.columns.alpha
|
||||
= render 'admin/shared/side_menu'
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
%select.select2.fullwidth{id: "enterprise_relationship_child_id", "ng-model" => "child_id", "ng-options" => "e.id as e.name for e in Enterprises.all_enterprises"}
|
||||
%td
|
||||
%label
|
||||
%input{type: "checkbox", ng: {checked: "allPermissionsChecked()", click: "checkAllPermissions()"}}
|
||||
%input{ type: "checkbox", "ng-checked": "allPermissionsChecked()", "ng-click": "checkAllPermissions()" }
|
||||
= t 'admin_enterprise_relationships_everything'
|
||||
%div{"ng-repeat" => "permission in EnterpriseRelationships.all_permissions"}
|
||||
%label
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
%input.search{"ng-model" => "query", "placeholder" => t(:admin_enterprise_relationships_seach_placeholder)}
|
||||
|
||||
%label{ng: {repeat: "permission in EnterpriseRelationships.all_permissions"}}
|
||||
%input{type: "checkbox", ng: {click: "$parent.query = toggleKeyword($parent.query, permission)"}}
|
||||
%label{ "ng-repeat": "permission in EnterpriseRelationships.all_permissions" }
|
||||
%input{ type: "checkbox", "ng-click": "$parent.query = toggleKeyword($parent.query, permission)" }
|
||||
{{ EnterpriseRelationships.permission_presentation(permission) }}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
= form_for @enterprise, url: main_app.register_admin_enterprise_path(@enterprise),
|
||||
html: { name: "change_type", id: "change_type", novalidate: true, "ng-app" => "admin.enterprises", "ng-controller"=> 'changeTypeFormCtrl' } do |change_type_form|
|
||||
-# Have to use hidden:'true' on this input rather than type:'hidden' as the latter seems to break ngPattern and therefore validation
|
||||
%input{ hidden: "true", name: "sells", ng: { required: true, pattern: "/^(none|own|any)$/", model: 'sells', value: "sells"} }
|
||||
%input{ hidden: "true", name: "sells", "ng-required": true, "ng-pattern": "/^(none|own|any)$/", "ng-model": 'sells', "ng-value": "sells" }
|
||||
|
||||
.row
|
||||
.options.container
|
||||
- if @enterprise.is_primary_producer
|
||||
.basic_producer.option.six.columns.alpha
|
||||
%a.full-width.button.selector{ ng: { click: "sells='none'", class: "{selected: sells=='none'}" } }
|
||||
%a.full-width.button.selector{ "ng-click": "sells='none'", "ng-class": "{selected: sells=='none'}" }
|
||||
.top
|
||||
%h3= t('.producer_profile')
|
||||
%p= t('.connect_ofn')
|
||||
@@ -18,7 +18,7 @@
|
||||
= t('.producer_description_text')
|
||||
|
||||
.producer_shop.option.six.columns
|
||||
%a.full-width.button.selector{ ng: { click: "sells='own'", class: "{selected: sells=='own'}" } }
|
||||
%a.full-width.button.selector{ "ng-click": "sells='own'", "ng-class": "{selected: sells=='own'}" }
|
||||
.top
|
||||
%h3= t('.producer_shop')
|
||||
%p= t('.sell_your_produce')
|
||||
@@ -29,7 +29,7 @@
|
||||
= t('.producer_shop_description_text2')
|
||||
|
||||
.full_hub.option.six.columns.omega
|
||||
%a.full-width.button.selector{ ng: { click: "sells='any'", class: "{selected: sells=='any'}" } }
|
||||
%a.full-width.button.selector{ "ng-click": "sells='any'", "ng-class": "{selected: sells=='any'}" }
|
||||
.top
|
||||
%h3= t('.producer_hub')
|
||||
%p= t('.producer_hub_text')
|
||||
@@ -40,7 +40,7 @@
|
||||
.two.columns.alpha
|
||||
|
||||
.shop_profile.option.six.columns
|
||||
%a.full-width.button.selector{ ng: { click: "sells='none'", class: "{selected: sells=='none'}" } }
|
||||
%a.full-width.button.selector{ "ng-click": "sells='none'", "ng-class": "{selected: sells=='none'}" }
|
||||
.top
|
||||
%h3= t('.profile')
|
||||
%p= t('.get_listing')
|
||||
@@ -49,7 +49,7 @@
|
||||
= t('.profile_description_text')
|
||||
|
||||
.full_hub.option.six.columns
|
||||
%a.full-width.button.selector{ ng: { click: "sells='any'", class: "{selected: sells=='any'}" } }
|
||||
%a.full-width.button.selector{ "ng-click": "sells='any'", "ng-class": "{selected: sells=='any'}" }
|
||||
.top
|
||||
%h3= t('.hub_shop')
|
||||
%p= t('.hub_shop_text')
|
||||
@@ -60,11 +60,11 @@
|
||||
|
||||
.row
|
||||
.sixteen.columns.alpha
|
||||
%span.error{ ng: { show: "(change_type.sells.$error.required || change_type.sells.$error.pattern) && submitted" } }
|
||||
%span.error{ "ng-show": "(change_type.sells.$error.required || change_type.sells.$error.pattern) && submitted" }
|
||||
= t('.choose_option')
|
||||
- if @enterprise.sells == 'unspecified'
|
||||
%input.button.big{ type: 'submit', value: t(:select_continue), ng: { click: "submit(change_type)" } }
|
||||
%input.button.big{ type: 'submit', value: t(:select_continue), "ng-click": "submit(change_type)" }
|
||||
- else
|
||||
%input.button.big{ type: 'submit', value: t('.change_now'), ng: { click: "submit(change_type)" } }
|
||||
%input.button.big{ type: 'submit', value: t('.change_now'), "ng-click": "submit(change_type)" }
|
||||
%br
|
||||
%hr
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%div{ ng: { controller: 'enterprisesCtrl' } }
|
||||
%div{ "ng-controller": 'enterprisesCtrl' }
|
||||
.row{ 'ng-hide' => '!loaded' }
|
||||
.controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" }
|
||||
.four.columns.alpha
|
||||
@@ -15,32 +15,32 @@
|
||||
.row{ :class => "sixteen columns alpha", 'ng-show' => 'loaded && filteredEnterprises.length == 0'}
|
||||
%h1#no_results= t('.no_enterprises_found')
|
||||
|
||||
.row{ ng: { show: "loaded && filteredEnterprises.length > 0" } }
|
||||
.row{ "ng-show": "loaded && filteredEnterprises.length > 0" }
|
||||
%table.index#enterprises
|
||||
%col.name{ width: "28%", ng: { show: 'columns.name.visible' } }
|
||||
%col.producer{ width: "18%", ng: { show: 'columns.producer.visible' }}
|
||||
%col.package{ width: "18%", ng: { show: 'columns.package.visible' }}
|
||||
%col.status{ width: "18%", ng: { show: 'columns.status.visible' }}
|
||||
%col.manage{ width: "18%", ng: { show: 'columns.manage.visible' }}
|
||||
%col.name{ width: "28%", "ng-show": 'columns.name.visible' }
|
||||
%col.producer{ width: "18%", "ng-show": 'columns.producer.visible' }
|
||||
%col.package{ width: "18%", "ng-show": 'columns.package.visible' }
|
||||
%col.status{ width: "18%", "ng-show": 'columns.status.visible' }
|
||||
%col.manage{ width: "18%", "ng-show": 'columns.manage.visible' }
|
||||
%thead
|
||||
%tr{ ng: { controller: "ColumnsCtrl" } }
|
||||
%th.name{ ng: { show: 'columns.name.visible' } }=t('admin.name')
|
||||
%th.producer{ ng: { show: 'columns.producer.visible' } }=t('.producer?')
|
||||
%th.package{ ng: { show: 'columns.package.visible' } }=t('.package')
|
||||
%th.status{ ng: { show: 'columns.status.visible' } }=t('.status')
|
||||
%th.manage{ ng: { show: 'columns.manage.visible' } }=t('.manage')
|
||||
%tbody.panel-ctrl{ :id => "e_{{enterprise.id}}", object: "enterprise", ng: { repeat: "enterprise in filteredEnterprises = ( allEnterprises | filter:{ name: quickSearch } )" } }
|
||||
%tr.enterprise{ ng: { class: { even: "'even'", odd: "'odd'"} } }
|
||||
%td.name{ ng: { show: 'columns.name.visible' } }
|
||||
%span{ ng: { bind: "::enterprise.name" } }
|
||||
%td.producer.panel-toggle.text-center{ ng: { show: 'columns.producer.visible', class: "{error: enterprise.producerError}" }, name: "producer" }
|
||||
%h5{ ng: { bind: "enterprise.producer" } }
|
||||
%td.package.panel-toggle.text-center{ ng: { show: 'columns.package.visible', class: "{error: enterprise.packageError}" }, name: "package" }
|
||||
%h5{ ng: { bind: "enterprise.package" } }
|
||||
%td.status.panel-toggle.text-center{ ng: { show: 'columns.status.visible' }, name: "status" }
|
||||
%i.icon-status{ ng: { class: "enterprise.status" } }
|
||||
%td.manage{ ng: { show: 'columns.manage.visible' } }
|
||||
%a.button.fullwidth{ ng: { href: '{{::enterprise.edit_path}}' } }
|
||||
%tr{ "ng-controller": "ColumnsCtrl" }
|
||||
%th.name{ "ng-show": 'columns.name.visible' }=t('admin.name')
|
||||
%th.producer{ "ng-show": 'columns.producer.visible' }=t('.producer?')
|
||||
%th.package{ "ng-show": 'columns.package.visible' }=t('.package')
|
||||
%th.status{ "ng-show": 'columns.status.visible' }=t('.status')
|
||||
%th.manage{ "ng-show": 'columns.manage.visible' }=t('.manage')
|
||||
%tbody.panel-ctrl{ id: "e_{{enterprise.id}}", object: "enterprise", "ng-repeat": "enterprise in filteredEnterprises = ( allEnterprises | filter:{ name: quickSearch } )" }
|
||||
%tr.enterprise{ "ng-class-even": "'even'", "ng-class-odd": "'odd'" }
|
||||
%td.name{ "ng-show": 'columns.name.visible' }
|
||||
%span{ "ng-bind": "::enterprise.name" }
|
||||
%td.producer.panel-toggle.text-center{ name: "producer", "ng-show": 'columns.producer.visible', "ng-class": "{error: enterprise.producerError}" }
|
||||
%h5{ "ng-bind": "enterprise.producer" }
|
||||
%td.package.panel-toggle.text-center{ name: "package", "ng-show": 'columns.package.visible', "ng-class": "{error: enterprise.packageError}" }
|
||||
%h5{ "ng-bind": "enterprise.package" }
|
||||
%td.status.panel-toggle.text-center{ name: "status", "ng-show": 'columns.status.visible' }
|
||||
%i.icon-status{ "ng-class": "enterprise.status" }
|
||||
%td.manage{ "ng-show": 'columns.manage.visible' }
|
||||
%a.button.fullwidth{ "ng-href": '{{::enterprise.edit_path}}' }
|
||||
= t('.manage_link')
|
||||
%i.icon-arrow-right
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
"ng-cloak" => true } do |f|
|
||||
|
||||
%save-bar{ dirty: "enterprise_form.$dirty", persist: "true" }
|
||||
%input.red{ type: "button", value: t(:update), ng: { click: "submit()", disabled: "!enterprise_form.$dirty" } }
|
||||
%input{ type: "button", ng: { value: "enterprise_form.$dirty ? '#{t(:cancel)}' : '#{t(:close)}'", click: "cancel('#{main_app.admin_enterprises_path}')" } }
|
||||
%input.red{ type: "button", value: t(:update), "ng-click": "submit()", "ng-disabled": "!enterprise_form.$dirty" }
|
||||
%input{ type: "button", "ng-value": "enterprise_form.$dirty ? '#{t(:cancel)}' : '#{t(:close)}'", "ng-click": "cancel('#{main_app.admin_enterprises_path}')" }
|
||||
|
||||
.row{ data: {
|
||||
controller: "tabs-and-panels", "tabs-and-panels-class-name-value": "selected" }}
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
%br
|
||||
= t('.logo_size')
|
||||
.omega.eight.columns
|
||||
%img{ class: 'image-field-group__preview-image', ng: { src: '{{ Enterprise.logo.thumb }}', if: 'Enterprise.logo' } }
|
||||
%img{ class: 'image-field-group__preview-image', "ng-src": '{{ Enterprise.logo.thumb }}', "ng-if": 'Enterprise.logo' }
|
||||
%br
|
||||
= f.file_field :logo
|
||||
%a.button.red{ href: '', ng: {click: 'removeLogo()', if: 'Enterprise.logo'} }
|
||||
%a.button.red{ href: '', "ng-click": 'removeLogo()', "ng-if": 'Enterprise.logo' }
|
||||
= t('.remove_logo')
|
||||
|
||||
.row.page-admin-enterprises-form__promo-image-field-group.image-field-group
|
||||
@@ -21,7 +21,7 @@
|
||||
= t('.promo_image_note3')
|
||||
|
||||
.omega.eight.columns
|
||||
%img{ class: 'image-field-group__preview-image', ng: { src: '{{ Enterprise.promo_image.large }}', if: 'Enterprise.promo_image' } }
|
||||
%img{ class: 'image-field-group__preview-image', "ng-src": '{{ Enterprise.promo_image.large }}', "ng-if": 'Enterprise.promo_image' }
|
||||
= f.file_field :promo_image
|
||||
%a.button.red{ href: '', ng: {click: 'removePromoImage()', if: 'Enterprise.promo_image'} }
|
||||
%a.button.red{ href: '', "ng-click": 'removePromoImage()', "ng-if": 'Enterprise.promo_image' }
|
||||
= t('.remove_promo_image')
|
||||
|
||||
@@ -23,17 +23,13 @@
|
||||
= radio_button :enterprise, :preferred_shopfront_product_sorting_method, :by_category, { 'ng-model' => 'Enterprise.preferred_shopfront_product_sorting_method' }
|
||||
= label :enterprise, :preferred_shopfront_product_sorting_method_by_category, t('.shopfront_sort_by_category')
|
||||
.eight.columns.omega
|
||||
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6,
|
||||
'ofn-taxon-autocomplete' => '', 'multiple-selection' => 'true', placeholder: t('.shopfront_sort_by_category_placeholder'),
|
||||
ng: { model: 'Enterprise.preferred_shopfront_taxon_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_category'" }}
|
||||
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_taxon_order', name: 'enterprise[preferred_shopfront_taxon_order]', rows: 6, "ofn-taxon-autocomplete": '', "multiple-selection": 'true', placeholder: t('.shopfront_sort_by_category_placeholder'), "ng-model": 'Enterprise.preferred_shopfront_taxon_order', "ng-readonly": "Enterprise.preferred_shopfront_product_sorting_method != 'by_category'" }
|
||||
.row
|
||||
.three.columns.alpha
|
||||
= radio_button :enterprise, :preferred_shopfront_product_sorting_method, :by_producer, { 'ng-model' => 'Enterprise.preferred_shopfront_product_sorting_method' }
|
||||
= label :enterprise, :preferred_shopfront_product_sorting_method_by_producer, t('.shopfront_sort_by_producer')
|
||||
.eight.columns.omega
|
||||
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_producer_order', name: 'enterprise[preferred_shopfront_producer_order]', rows: 6,
|
||||
'ofn-producer-autocomplete' => '', 'multiple-selection' => 'true', placeholder: t('.shopfront_sort_by_producer_placeholder'),
|
||||
ng: { model: 'Enterprise.preferred_shopfront_producer_order', readonly: "Enterprise.preferred_shopfront_product_sorting_method != 'by_producer'" }}
|
||||
%textarea.fullwidth{ id: 'enterprise_preferred_shopfront_producer_order', name: 'enterprise[preferred_shopfront_producer_order]', rows: 6, "ofn-producer-autocomplete": '', "multiple-selection": 'true', placeholder: t('.shopfront_sort_by_producer_placeholder'), "ng-model": 'Enterprise.preferred_shopfront_producer_order', "ng-readonly": "Enterprise.preferred_shopfront_product_sorting_method != 'by_producer'" }
|
||||
|
||||
.row
|
||||
.three.columns.alpha
|
||||
@@ -56,7 +52,7 @@
|
||||
= f.radio_button :require_login, true, "ng-model" => "Enterprise.require_login", "ng-value" => "true"
|
||||
= f.label :require_login, t('.shopfront_requires_login_true'), value: :true
|
||||
|
||||
.row{ng: {if: "!Enterprise.require_login"}}
|
||||
.row{ "ng-if": "!Enterprise.require_login" }
|
||||
.three.columns.alpha
|
||||
%label= t '.allow_guest_orders'
|
||||
%div{'ofn-with-tip' => t('.allow_guest_orders_tip')}
|
||||
@@ -67,7 +63,7 @@
|
||||
.five.columns.omega
|
||||
= f.radio_button :allow_guest_orders, false, "ng-model" => "Enterprise.allow_guest_orders", "ng-value" => "false"
|
||||
= f.label :allow_guest_orders, t('.allow_guest_orders_false'), value: :false
|
||||
.row.warning{ng: {show: 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes'}}
|
||||
.row.warning{ "ng-show": 'Enterprise.allow_guest_orders && Enterprise.allow_order_changes' }
|
||||
.eight.columns.alpha.omega
|
||||
%i.icon-warning-sign
|
||||
= t '.recommend_require_login'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
.row{ ng: { controller: "TagRulesCtrl" } }
|
||||
.row{ "ng-controller": "TagRulesCtrl" }
|
||||
.eleven.columns.alpha.omega
|
||||
%ofn-sortable{ axis: "y", handle: ".header", items: '.customer_tag', position: "tagGroup.position", after: { sort: "updateRuleCounts()" } }
|
||||
.no_tags{ ng: { show: "tagGroups.length == 0" } }
|
||||
%ofn-sortable{ axis: "y", handle: ".header", items: '.customer_tag', position: "tagGroup.position", "after-sort": "updateRuleCounts()" }
|
||||
.no_tags{ "ng-show": "tagGroups.length == 0" }
|
||||
= t('.no_tags_yet')
|
||||
= render 'admin/enterprises/form/tag_rules/default_rules'
|
||||
-# = render 'customer_tags'
|
||||
.customer_tag{ id: "tg_{{tagGroup.position}}", ng: { repeat: "tagGroup in tagGroups" } }
|
||||
.customer_tag{ id: "tg_{{tagGroup.position}}", "ng-repeat": "tagGroup in tagGroups" }
|
||||
.header
|
||||
%table
|
||||
%colgroup
|
||||
@@ -16,12 +16,12 @@
|
||||
%h5
|
||||
= t('.for_customers_tagged')
|
||||
%td
|
||||
%tags-with-translation{ object: "tagGroup", max: 1, on: { tag: { added: "updateTagsRulesFor(tagGroup)", removed: "updateTagsRulesFor(tagGroup)" } } }
|
||||
%tags-with-translation{ object: "tagGroup", max: 1, "on-tag-added": "updateTagsRulesFor(tagGroup)", "on-tag-removed": "updateTagsRulesFor(tagGroup)" }
|
||||
|
||||
.no_rules{ ng: { show: "tagGroup.rules.length == 0" } }
|
||||
.no_rules{ "ng-show": "tagGroup.rules.length == 0" }
|
||||
= t('.no_rules_yet')
|
||||
.tag_rule{ ng: { repeat: "rule in tagGroup.rules" } }
|
||||
.tag_rule{ "ng-repeat": "rule in tagGroup.rules" }
|
||||
.add_rule.text-center
|
||||
%input.button.icon-plus{ type: 'button', value: t('.add_new_rule'), "add-new-rule-to" => "addNewRuleTo", "tag-group" => "tagGroup", "new-tag-rule-dialog" => true }
|
||||
.add_tag
|
||||
%input.button.red.icon-plus{ type: 'button', value: t('.add_new_tag'), ng: { click: 'addNewTag()' } }
|
||||
%input.button.red.icon-plus{ type: 'button', value: t('.add_new_tag'), "ng-click": 'addNewTag()' }
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
= render partial: 'admin/shared/whats_this_tooltip', locals: {tooltip_text: t('.contact_tip')}
|
||||
.eight.columns.omega
|
||||
- if full_permissions
|
||||
%select.select2.fullwidth{id: 'receives_notifications_dropdown', name: 'receives_notifications', ng: {model: 'receivesNotifications', init: "receivesNotifications = '#{@enterprise.contact.id}'"}}
|
||||
%option{ng: {repeat: 'user in Enterprise.users', selected: "user.id == #{@enterprise.contact.id}", hide: '!user.confirmed'}, value: '{{user.id}}'}
|
||||
%select.select2.fullwidth{ id: 'receives_notifications_dropdown', name: 'receives_notifications', "ng-model": 'receivesNotifications', "ng-init": "receivesNotifications = '#{@enterprise.contact.id}'" }
|
||||
%option{ value: '{{user.id}}', "ng-repeat": 'user in Enterprise.users', "ng-selected": "user.id == #{@enterprise.contact.id}", "ng-hide": '!user.confirmed' }
|
||||
{{user.email}}
|
||||
- else
|
||||
= @enterprise.contact.email
|
||||
@@ -41,16 +41,16 @@
|
||||
- # Ignore this input in the submit
|
||||
= hidden_field_tag :ignored, nil, class: "select2 fullwidth", 'user-select' => 'newManager', 'ng-model' => 'newManager'
|
||||
%td.actions
|
||||
%tr.animate-repeat{ id: "manager-{{manager.id}}", ng: { repeat: 'manager in Enterprise.users' }}
|
||||
%tr.animate-repeat{ id: "manager-{{manager.id}}", "ng-repeat": 'manager in Enterprise.users' }
|
||||
%td
|
||||
= hidden_field_tag "enterprise[user_ids][]", nil, multiple: true, 'ng-value' => 'manager.id'
|
||||
{{ manager.email }}
|
||||
%i.confirmation.confirmed.fa.fa-check-circle{ 'ofn-with-tip' => t('.email_confirmed'), ng: {show: 'manager.confirmed'} }
|
||||
%i.confirmation.unconfirmed.fa.fa-exclamation-triangle{ 'ofn-with-tip' => t('.email_not_confirmed'), ng: {show: '!manager.confirmed'} }
|
||||
%i.role.contact.fa.fa-envelope-o{ 'ofn-with-tip' => t('.contact'), ng: {show: 'manager.id == receivesNotifications'} }
|
||||
%i.role.owner.fa.fa-star{ 'ofn-with-tip' => t('.owner'), ng: {show: 'manager.id == Enterprise.owner.id'} }
|
||||
%i.confirmation.confirmed.fa.fa-check-circle{ "ofn-with-tip": t('.email_confirmed'), "ng-show": 'manager.confirmed' }
|
||||
%i.confirmation.unconfirmed.fa.fa-exclamation-triangle{ "ofn-with-tip": t('.email_not_confirmed'), "ng-show": '!manager.confirmed' }
|
||||
%i.role.contact.fa.fa-envelope-o{ "ofn-with-tip": t('.contact'), "ng-show": 'manager.id == receivesNotifications' }
|
||||
%i.role.owner.fa.fa-star{ "ofn-with-tip": t('.owner'), "ng-show": 'manager.id == Enterprise.owner.id' }
|
||||
%td.actions
|
||||
%a{ ng: {click: 'removeManager(manager)', class: "{disabled: manager.id == Enterprise.owner.id || manager.id == receivesNotifications}"}, :class => "icon-trash no-text" }
|
||||
%a{ class: "icon-trash no-text", "ng-click": 'removeManager(manager)', "ng-class": "{disabled: manager.id == Enterprise.owner.id || manager.id == receivesNotifications}" }
|
||||
|
||||
- else
|
||||
- @enterprise.users.each do |manager|
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
%h5
|
||||
= 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" }
|
||||
.no_rules{ ng: { show: "defaultTagGroup.rules.length == 0" } }
|
||||
.no_rules{ "ng-show": "defaultTagGroup.rules.length == 0" }
|
||||
= t('.no_rules_yet')
|
||||
.tag_rule{ ng: { repeat: "rule in defaultTagGroup.rules" } }
|
||||
.tag_rule{ "ng-repeat": "rule in defaultTagGroup.rules" }
|
||||
.add_rule.text-center
|
||||
%input.button.icon-plus{ type: 'button', value: t('.add_new_button'), "add-new-rule-to" => "addNewRuleTo", "tag-group" => "defaultTagGroup", "new-tag-rule-dialog" => true }
|
||||
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
|
||||
= form_for [main_app, :admin, @enterprise], html: { "nav-check" => '', "nav-callback" => '' } do |f|
|
||||
.row
|
||||
.twelve.columns.fullwidth_inputs{ ng: { controller: "NewEnterpriseController" } }
|
||||
.twelve.columns.fullwidth_inputs{ "ng-controller": "NewEnterpriseController" }
|
||||
= render 'new_form', f: f, scope: 'admin.enterprises.form'
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
= check_box_tag 'preferences[enable_invoices?]', '1', Spree::Config[:enable_invoices?]
|
||||
= label_tag nil, t('.enable_invoices?')
|
||||
|
||||
.field.align-center
|
||||
= hidden_field_tag 'preferences[invoice_style2?]', '0'
|
||||
= check_box_tag 'preferences[invoice_style2?]', '1', Spree::Config[:invoice_style2?]
|
||||
= label_tag nil, t('.invoice_style2?')
|
||||
- if ! OpenFoodNetwork::FeatureToggle.enabled?(:invoices, spree_current_user)
|
||||
.field.align-center
|
||||
= hidden_field_tag 'preferences[invoice_style2?]', '0'
|
||||
= check_box_tag 'preferences[invoice_style2?]', '1', Spree::Config[:invoice_style2?]
|
||||
= label_tag nil, t('.invoice_style2?')
|
||||
|
||||
.field.align-center
|
||||
= hidden_field_tag 'preferences[enterprise_number_required_on_invoices?]', '0'
|
||||
|
||||
@@ -7,14 +7,26 @@
|
||||
%h2= t(".connect")
|
||||
%br
|
||||
|
||||
- if spree_current_user.provider == 'openid_connect' && spree_current_user.uid.present?
|
||||
= t(".already_connected")
|
||||
= spree_current_user.uid
|
||||
- if @account
|
||||
= t(".connected", uid: @account.uid)
|
||||
%br
|
||||
%br
|
||||
|
||||
= t(".view_account")
|
||||
= link_to t(".les_communs_link"), "#{ Devise.omniauth_configs[:openid_connect].options[:issuer] }/account"
|
||||
%br
|
||||
%br
|
||||
= button_to t(".disconnect"), admin_oidc_setting_path(@account), method: :delete
|
||||
|
||||
- if @account.refresh_token.blank?
|
||||
%br
|
||||
%br
|
||||
%p= t(".note_expiry")
|
||||
%br
|
||||
%br
|
||||
= button_to t(".refresh"),
|
||||
Spree::Core::Engine.routes.url_helpers.spree_user_openid_connect_omniauth_authorize_path(auth_type: "login"),
|
||||
data: { method: :post, "ujs-navigate": "false" }
|
||||
|
||||
- else
|
||||
= t(".link_your_account")
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
.omega.eight.columns
|
||||
= f.check_box :automatic_notifications
|
||||
|
||||
.row{ "data-controller": "remote-toggle", "data-remote-toggle-selector-value": "#advanced_settings" }
|
||||
.row{ "data-controller": "toggle-control", "data-toggle-control-selector-value": "#advanced_settings" }
|
||||
.sixteen.columns.alpha.omega.text-center
|
||||
%input{ type: 'submit', value: t('.save_reload') }
|
||||
%a{ href: "#", "data-action": "click->remote-toggle#toggle" }= t(:close)
|
||||
%a{ href: "#", "data-action": "click->toggle-control#toggleAdvancedSettings" }= t(:close)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
%tr{ ng: { class: "'#{type} #{type}-{{ exchange.enterprise_id }}'" } }
|
||||
%tr{ "ng-class": "'#{type} #{type}-{{ exchange.enterprise_id }}'" }
|
||||
%td{:class => "#{type}_name"} {{ enterprises[exchange.enterprise_id].name }}
|
||||
%td.products.panel-toggle.text-center{ name: "products" }
|
||||
{{ exchangeSelectedVariants(exchange) }} / {{ exchangeTotalVariants(exchange) }}
|
||||
@@ -7,7 +7,7 @@
|
||||
%td.receival-details
|
||||
= text_field_tag 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', '', 'id' => 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', 'placeholder' => t('.receival_instructions_placeholder'), 'ng-model' => 'exchange.receival_instructions'
|
||||
- if type == 'distributor'
|
||||
%td.tags.panel-toggle.text-center{ name: "tags", ng: { if: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } }
|
||||
%td.tags.panel-toggle.text-center{ name: "tags", "ng-if": 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' }
|
||||
{{ exchange.tags.length }}
|
||||
%td.collection-details
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', '', 'ng-init' => 'setPickupTimeFieldDirty($index, exchange.pickup_time)', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', 'required' => 'required', 'placeholder' => t('.pickup_time_placeholder'), 'ng-model' => 'exchange.pickup_time', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator', 'maxlength' => 35
|
||||
@@ -16,7 +16,7 @@
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', 'placeholder' => t('.pickup_instructions_placeholder'), 'ng-model' => 'exchange.pickup_instructions', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator'
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('.pickup_instructions_tip')}
|
||||
%td.fees
|
||||
%ol{ ng: { show: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } }
|
||||
%ol{ "ng-show": 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' }
|
||||
%li{'ng-repeat' => 'enterprise_fee in exchange.enterprise_fees'}
|
||||
= select_tag 'order_cycle_{{ exchangeDirection(exchange) }}_exchange_{{ $parent.$index }}_enterprise_fees_{{ $index }}_enterprise_id', nil, {'id' => 'order_cycle_{{ exchangeDirection(exchange) }}_exchange_{{ $parent.$index }}_enterprise_fees_{{ $index }}_enterprise_id', 'ng-model' => 'enterprise_fee.enterprise_id', 'ng-options' => 'enterprise.id as enterprise.name for enterprise in enterprisesWithFees()'}
|
||||
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
.filter.four.columns.alpha
|
||||
%label{ :for => 'query' }=t('admin.quick_search')
|
||||
%br
|
||||
%input.fullwidth{ :type => "text", :id => 'query', ng: { model: 'query' }, placeholder: t(".search_by_order_cycle_name") }
|
||||
%input.fullwidth{ type: "text", id: 'query', placeholder: t(".search_by_order_cycle_name"), "ng-model": 'query' }
|
||||
.filter_select.four.columns
|
||||
%label{ :for => 'involving_filter' }=t('.involving')
|
||||
%br
|
||||
%input.ofn-select2.fullwidth{ id: 'involving_filter', type: 'number', blank: "{id: 0, name: '#{j t(".any_enterprise")}'}", data: 'enterprises', ng: { model: 'involvingFilter' } }
|
||||
%input.ofn-select2.fullwidth{ id: 'involving_filter', type: 'number', blank: "{id: 0, name: '#{j t(".any_enterprise")}'}", data: 'enterprises', "ng-model": 'involvingFilter' }
|
||||
- if subscriptions_enabled?
|
||||
.filter_select.four.columns
|
||||
%label{ :for => 'schedule_filter' }=t('admin.order_cycles.index.schedule')
|
||||
%br
|
||||
%input.ofn-select2.fullwidth{ id: 'schedule_filter', type: 'number', blank: "{id: 0, name: '#{j t(".any_schedule")}'}", data: 'schedules', ng: { model: 'scheduleFilter' } }
|
||||
%input.ofn-select2.fullwidth{ id: 'schedule_filter', type: 'number', blank: "{id: 0, name: '#{j t(".any_schedule")}'}", data: 'schedules', "ng-model": 'scheduleFilter' }
|
||||
.one.columns
|
||||
- else
|
||||
.five.columns
|
||||
.filter_clear.three.columns.omega
|
||||
%label{ :for => 'clear_all_filters' }
|
||||
%br
|
||||
%input.red.fullwidth{ :type => 'button', :id => 'clear_all_filters', :value => "#{t('admin.clear_all')}", ng: { click: "resetSelectFilters()" } }
|
||||
%input.red.fullwidth{ type: 'button', id: 'clear_all_filters', value: "#{t('admin.clear_all')}", "ng-click": "resetSelectFilters()" }
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
%colgroup
|
||||
%col{ ng: { show: 'columns.name.visible' } }
|
||||
%col{ ng: { show: 'columns.schedules.visible' } }
|
||||
%col{ ng: { show: 'columns.open.visible' }, style: 'width: 20%;' }
|
||||
%col{ ng: { show: 'columns.close.visible' }, style: 'width: 20%;' }
|
||||
%col{ "ng-show": 'columns.name.visible' }
|
||||
%col{ "ng-show": 'columns.schedules.visible' }
|
||||
%col{ style: 'width: 20%;', "ng-show": 'columns.open.visible' }
|
||||
%col{ style: 'width: 20%;', "ng-show": 'columns.close.visible' }
|
||||
- unless simple_index
|
||||
%col{ ng: { show: 'columns.producers.visible' } }
|
||||
%col{ ng: { show: 'columns.coordinator.visible' } }
|
||||
%col{ ng: { show: 'columns.shops.visible' } }
|
||||
%col{ ng: { show: 'columns.products.visible' } }
|
||||
%col{ "ng-show": 'columns.producers.visible' }
|
||||
%col{ "ng-show": 'columns.coordinator.visible' }
|
||||
%col{ "ng-show": 'columns.shops.visible' }
|
||||
%col{ "ng-show": 'columns.products.visible' }
|
||||
%col{ style: 'width: 5%;' }
|
||||
%col{ style: 'width: 5%;' }
|
||||
%col{ style: 'width: 5%;' }
|
||||
|
||||
%thead
|
||||
%tr
|
||||
%th{ ng: { show: 'columns.name.visible' } }
|
||||
%th{ "ng-show": 'columns.name.visible' }
|
||||
=t :name
|
||||
%th{ ng: { show: 'columns.schedules.visible' } }
|
||||
%th{ "ng-show": 'columns.schedules.visible' }
|
||||
=t('admin.order_cycles.index.schedules')
|
||||
%th{ ng: { show: 'columns.open.visible' } }
|
||||
%th{ "ng-show": 'columns.open.visible' }
|
||||
=t :open
|
||||
%th{ ng: { show: 'columns.close.visible' } }
|
||||
%th{ "ng-show": 'columns.close.visible' }
|
||||
=t :close
|
||||
- unless simple_index
|
||||
%th{ ng: { show: 'columns.producers.visible' } }
|
||||
%th{ "ng-show": 'columns.producers.visible' }
|
||||
=t :label_producers
|
||||
%th{ ng: { show: 'columns.coordinator.visible' } }
|
||||
%th{ "ng-show": 'columns.coordinator.visible' }
|
||||
=t :coordinator
|
||||
%th{ ng: { show: 'columns.shops.visible' } }
|
||||
%th{ "ng-show": 'columns.shops.visible' }
|
||||
=t :label_shops
|
||||
%th{ ng: { show: 'columns.products.visible' } }
|
||||
%th{ "ng-show": 'columns.products.visible' }
|
||||
=t :products
|
||||
%th.actions
|
||||
%th.actions
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%div.sixteen.columns.alpha.omega#loading{ ng: { cloak: true, if: 'RequestMonitor.loading' } }
|
||||
%div.sixteen.columns.alpha.omega#loading{ "ng-cloak": true, "ng-if": 'RequestMonitor.loading' }
|
||||
= render partial: "components/admin_spinner"
|
||||
%h1{ ng: { hide: 'orderCycles.length > 0' } }
|
||||
%h1{ "ng-hide": 'orderCycles.length > 0' }
|
||||
= t('.loading_order_cycles')
|
||||
%h1{ ng: { show: 'orderCycles.length > 0' } }
|
||||
%h1{ "ng-show": 'orderCycles.length > 0' }
|
||||
= t('.loading')
|
||||
|
||||
@@ -35,11 +35,6 @@
|
||||
= f.label :schedule_ids, t('admin.order_cycles.index.schedules')
|
||||
.six.columns
|
||||
- if viewing_as_coordinator_of?(@order_cycle)
|
||||
%input.fullwidth.ofn-select2#schedule_ids{ name: 'order_cycle[schedule_ids]',
|
||||
data: 'schedules',
|
||||
multiple: 'true',
|
||||
placeholder: t('admin.please_select'),
|
||||
filter: '{viewing_as_coordinator: true}',
|
||||
ng: { model: 'order_cycle.schedule_ids' } }
|
||||
%input.fullwidth.ofn-select2#schedule_ids{ name: 'order_cycle[schedule_ids]', data: 'schedules', multiple: 'true', placeholder: t('admin.please_select'), filter: '{viewing_as_coordinator: true}', "ng-model": 'order_cycle.schedule_ids' }
|
||||
- else
|
||||
%schedule-list{ 'order-cycle' => 'order_cycle' }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user