Compare commits

...

85 Commits

Author SHA1 Message Date
Rachel Arnould
7caaeffe80 Merge pull request #12206 from cyrillefr/Invoices-Several-tax-rates-are-showing-up-on-the-invoice-for-the-same-product
Fix incorrect results for multiple tax rates in report
2024-03-11 10:31:09 +01:00
cyrillefr
7d99197dde Requested changes: original fix moved up in code
- instead of selecting out unapplied tax rates in the total tax
    method, did it in the query_result instead. Reverted the
    total_excl_tax method to its initial state.
  - spec and logic of testing affected also.
2024-03-11 10:13:46 +01:00
cyrillefr
62739c0458 Requested changes in spec
- use of new service instead of manually advancing an order
2024-03-11 10:13:46 +01:00
cyrillefr
7fdf1a110d Fix incorrect results for multiple tax rates in report
- total_excl_tax would sum amounts and taxes without
    knowledge if taxes rates were really applied or not
  - spec shows use case described in issue 12066
2024-03-11 10:13:46 +01:00
filipefurtad0
07a43fecdf Update all locales with the latest Transifex translations 2024-03-08 11:48:31 +00:00
Maikel
b27e0b5339 Merge pull request #12228 from openfoodfoundation/dependabot/bundler/json-jwt-1.16.6
chore(deps): bump json-jwt from 1.16.5 to 1.16.6
2024-03-08 11:39:43 +11:00
Maikel
61f29a4ebf Merge pull request #12226 from openfoodfoundation/dependabot/bundler/rubocop-rspec-2.27.1
chore(deps-dev): bump rubocop-rspec from 2.27.0 to 2.27.1
2024-03-08 11:39:06 +11:00
Filipe
9abaf90907 Merge pull request #12233 from dacook/buu/unit-scale-basic-12005
[BUU] Unit Scale - basic implementation
2024-03-07 17:20:45 +00:00
Filipe
de9446f5f3 Merge pull request #12167 from mkllnk/haml-up
Update Haml syntax and gem to version 6
2024-03-07 15:36:29 +00:00
Rachel Arnould
cd9bef4f7b Merge pull request #12172 from abdellani/12067-fix-invoice-render-multiple-tax-rates
fix invoice render multiple tax rates
2024-03-07 10:53:52 +01:00
Maikel
b4385623b2 Merge pull request #12236 from openfoodfoundation/dependabot/bundler/i18n-1.14.3
chore(deps): bump i18n from 1.14.1 to 1.14.3
2024-03-07 14:45:45 +11:00
Maikel
a256d01440 Merge pull request #12224 from dacook/rubocop-negation-matcher
Add Rubocop negation matcher
2024-03-07 14:41:20 +11:00
Rachel Arnould
5f302f347a Merge pull request #12189 from abdellani/11829-remove-alternative-invoice-when-invoice-feature-is-enabled
hide alternative invoice checkbox if invoices feature is enabled
2024-03-06 11:25:38 +01:00
dependabot[bot]
c0db3eb6ff chore(deps): bump i18n from 1.14.1 to 1.14.3
Bumps [i18n](https://github.com/ruby-i18n/i18n) from 1.14.1 to 1.14.3.
- [Release notes](https://github.com/ruby-i18n/i18n/releases)
- [Changelog](https://github.com/ruby-i18n/i18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ruby-i18n/i18n/compare/v1.14.1...v1.14.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-06 09:35:21 +00:00
David Cook
29d3b34776 Increase dropdown height 2024-03-06 17:12:15 +11:00
David Cook
8612f7baab Only add extra padding on alignment edge
Saves a few precious pixels on the other edge.
2024-03-06 14:10:54 +11:00
David Cook
e770f10f2b Tomselect has minimum width 2024-03-06 14:10:54 +11:00
David Cook
cbcf388acc Ensure gap between fields wrapped over a line 2024-03-06 14:10:51 +11:00
David Cook
133c9c0609 Add descriptions for taxomony tree
Better late than never.
2024-03-06 13:41:22 +11:00
David Cook
864b95612a Show error message on variant_unit_name
Now passing options through to the error tag
2024-03-06 13:41:22 +11:00
David Cook
e8bd8389b5 Remove unused parameters
They're being silently discarded. I checked, and those classes weren't needed anyway. (theres' no conditions to even show an error in the second case, but nevermind..)
2024-03-06 13:41:22 +11:00
David Cook
38766f5256 Show variant_unit_name for 'items' 2024-03-06 13:41:22 +11:00
David Cook
e52b8daf50 Refactor: DRY 2024-03-06 13:41:22 +11:00
David Cook
b3cf977c96 Add unit name (items) field 2024-03-06 13:41:22 +11:00
David Cook
bfd6319cf2 Mark tom-select as changed
Thankfully I was able to use basic DOM features, so there's no coupling of the logic with tom-select.

It wasn't going to be simple to get tom-select to listen for the 'changed' class on the original select, so I found a simple solution with a CSS sibling selector instead.
2024-03-06 13:41:22 +11:00
David Cook
af748158aa Hide chevron until hover to allow a bit more space for text 2024-03-06 13:41:22 +11:00
David Cook
864b876a9a Add tom-select with naked style
The rem units are converted to em to make the padding relative to the chevron size. This means different font sizes will Just Work.
2024-03-06 13:41:22 +11:00
David Cook
822054b748 Use capybara helper to find field
This is more flexible and can find a field based on name, id or aria-label
2024-03-06 13:41:22 +11:00
David Cook
4b2406c9c2 Add unit scale dropdown 2024-03-06 13:41:17 +11:00
David Cook
8f0e9c9f5c Remove unnecessary selector
I can't see any reason that fieldsets, which are containers, should share styles with inputs. Maybe font styles, but everything looks fine still.
2024-03-06 13:01:44 +11:00
David Cook
958288b223 Move input styles to form stylesheet
A better way to arrange it, and as a bonus it makes the selectors simpler, yay!
2024-03-06 13:01:44 +11:00
David Cook
2ef9e34f28 Re-arrange imperial units
Who would have guessed it was this complicated.

Fingers crossed this doesn't break any other functionality...
2024-03-06 13:01:43 +11:00
David Cook
ea0067946d Generate variant unit options in Ruby
This re-implements Angular JS function VariantUnitManager.variantUnitOptions()

Well.. almost. See next commit.
2024-03-06 13:01:43 +11:00
David Cook
a1135f7db7 Move unit scale to separate column
This is because it's going to move from product to variant soon, as part of Product Refactor.
2024-03-06 13:01:43 +11:00
David Cook
8f31d8799f Adjust column widths
Table layout is tricky. I had originally hoped that the table would allow us to use min/max width. But that simply doesn't work with `table-layout: fixed`. So we need to set preconfigured widths.

Now I think that table layout doesn't bring any benefit, so I think we should consider switching to flexbox or grid. ButI'll wait until all elements are in place before trying anything new.
2024-03-06 13:01:43 +11:00
David Cook
3e0d54f5f8 Fix Layout/LineLength
Ha, `not_to have` is one character longer..
2024-03-06 09:20:22 +11:00
David Cook
ea0967e22e Safely autocorrect Capybara/NegationMatcher 2024-03-06 09:20:22 +11:00
David Cook
0a70d70118 Add rubocop Capybara/NegationMatcher
And remove other config which was actually disabled already.
2024-03-06 09:20:22 +11:00
Filipe
af9f07f496 Merge pull request #12194 from cyrillefr/Replace-dropdown_controller-with-generic-toggle-control_controller
Re-implement dropdown controller with html details element
2024-03-05 16:28:29 +00:00
Filipe
cd7a9c606e Merge pull request #12208 from abdellani/11673-add-a-coder-for-every-serialized-attribute
add for every serialized attribute a coder
2024-03-05 15:41:45 +00:00
dependabot[bot]
e95a58f735 chore(deps): bump json-jwt from 1.16.5 to 1.16.6
Bumps [json-jwt](https://github.com/nov/json-jwt) from 1.16.5 to 1.16.6.
- [Release notes](https://github.com/nov/json-jwt/releases)
- [Changelog](https://github.com/nov/json-jwt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nov/json-jwt/compare/v1.16.5...v1.16.6)

---
updated-dependencies:
- dependency-name: json-jwt
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 20:28:10 +00:00
dependabot[bot]
0f0ec729f1 chore(deps-dev): bump rubocop-rspec from 2.27.0 to 2.27.1
Bumps [rubocop-rspec](https://github.com/rubocop/rubocop-rspec) from 2.27.0 to 2.27.1.
- [Release notes](https://github.com/rubocop/rubocop-rspec/releases)
- [Changelog](https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rspec/compare/v2.27.0...v2.27.1)

---
updated-dependencies:
- dependency-name: rubocop-rspec
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 09:47:53 +00:00
Gaetan Craig-Riou
9ab775c774 Merge pull request #12221 from mkllnk/rspec-sql
Use new rspec-sql gem
2024-03-04 11:37:38 +11:00
David Cook
5440c0dc65 Merge pull request #12223 from openfoodfoundation/dependabot/bundler/rubocop-rspec-2.27.0
chore(deps-dev): bump rubocop-rspec from 2.26.1 to 2.27.0
2024-03-04 10:20:49 +11:00
David Cook
2fa681ae8a Merge pull request #12203 from feruzoripov/queries/naming
Standardize Naming Conventions for Query-Related Services in `app/queries`
2024-03-04 10:15:49 +11:00
Feruz Oripov
1f299c84bc Merge branch 'master' into queries/naming 2024-03-02 16:32:50 +05:00
Feruz Oripov
3bf76c81aa Update specs 2024-03-02 16:11:26 +05:00
dependabot[bot]
d761ddabb7 chore(deps-dev): bump rubocop-rspec from 2.26.1 to 2.27.0
Bumps [rubocop-rspec](https://github.com/rubocop/rubocop-rspec) from 2.26.1 to 2.27.0.
- [Release notes](https://github.com/rubocop/rubocop-rspec/releases)
- [Changelog](https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop-rspec/compare/v2.26.1...v2.27.0)

---
updated-dependencies:
- dependency-name: rubocop-rspec
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 09:35:47 +00:00
Maikel Linke
60b86e1d64 Replace custom query counter with new gem rspec-sql 2024-03-01 11:44:25 +11:00
Maikel Linke
58490c26c1 Add rspec-sql gem 2024-03-01 11:42:03 +11:00
Maikel
a692fc9d12 Merge pull request #12218 from openfoodfoundation/dependabot/bundler/jwt-2.8.1
chore(deps): bump jwt from 2.8.0 to 2.8.1
2024-03-01 08:25:29 +11:00
Maikel
3795880fcd Merge pull request #12216 from openfoodfoundation/dependabot/bundler/rack-2.2.8.1
chore(deps): bump rack from 2.2.8 to 2.2.8.1
2024-03-01 08:15:13 +11:00
Filipe
6cd79e66ad Merge pull request #12192 from openfoodfoundation/filipefurtad0_remove_zenhub_reference
Update README.md
2024-02-29 19:54:26 +00:00
dependabot[bot]
2fff568ef9 chore(deps): bump jwt from 2.8.0 to 2.8.1
Bumps [jwt](https://github.com/jwt/ruby-jwt) from 2.8.0 to 2.8.1.
- [Release notes](https://github.com/jwt/ruby-jwt/releases)
- [Changelog](https://github.com/jwt/ruby-jwt/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jwt/ruby-jwt/compare/v2.8.0...v2.8.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-29 09:57:42 +00:00
dependabot[bot]
bbc4603106 chore(deps): bump rack from 2.2.8 to 2.2.8.1
Bumps [rack](https://github.com/rack/rack) from 2.2.8 to 2.2.8.1.
- [Release notes](https://github.com/rack/rack/releases)
- [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rack/rack/compare/v2.2.8...v2.2.8.1)

---
updated-dependencies:
- dependency-name: rack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-29 01:38:02 +00:00
David Cook
5cfac3d2c7 Add comments 2024-02-29 10:10:57 +11:00
cyrillefr
f62b32a3b9 Requested changes after review
- modified css to increase clicking area
  - modified spec to more straightfoward and more user oriented link
2024-02-28 08:15:34 +01:00
Mohamed ABDELLANI
ca13b0154c add for every serialized attribute a coder 2024-02-27 18:59:50 +01:00
Feruz Oripov
c2d8bdd414 cops 2024-02-27 01:01:22 +05:00
Feruz Oripov
3cf75fce72 cops 2024-02-27 00:29:59 +05:00
Feruz Oripov
67cd6ea6ed cops 2024-02-26 23:44:58 +05:00
Feruz Oripov
ef17fd7d80 Cleanup 2024-02-26 23:41:48 +05:00
Feruz Oripov
ff6830f954 Update OutstandingBalanceQuery 2024-02-26 23:37:11 +05:00
Feruz Oripov
81f40a99d9 Update CustomersWithBalanceQuery 2024-02-26 23:25:33 +05:00
Feruz Oripov
d4f37a3daa Update CompleteVisibleOrdersQuery 2024-02-26 23:08:21 +05:00
Feruz Oripov
f8c0edd68b Update CompleteOrdersWithBalanceQuery 2024-02-26 23:05:25 +05:00
cyrillefr
b08623df23 Sytem specs + controller spec
- controller spec is lighter since it is based on an html element
2024-02-25 16:43:57 +01:00
cyrillefr
428b9b273c Replace old dropdown controller by new one
- menu items line are unchanged only beggining of file modified
2024-02-25 16:43:57 +01:00
cyrillefr
884d6f15ff Replace a divs controller by an html details one
- checked_controller close details element on checkboxes
  - dropdown_controller.js is to rebuild controller from many divs
    to be hidden and visible to an html detail elmnt one
  - details html element styling
2024-02-25 16:43:57 +01:00
Filipe
6e73558e66 Update README.md
Removes reference to Zenhub on the README.md from the main project repo.
2024-02-23 11:28:18 +00:00
Mohamed ABDELLANI
335c2475ab hide alternative invoice checkbox if invoices feature is enabled 2024-02-22 20:09:43 +01:00
Maikel Linke
ba51641271 Symbolise hash keys in HAML files
This was done by the haml-up script.
2024-02-22 15:01:14 +11:00
Maikel Linke
1ad58b214b Write symbols instead of hash rockets in HAML 2024-02-22 15:01:14 +11:00
Maikel Linke
e2ec3a642c Style flatten tree logic 2024-02-22 15:01:14 +11:00
Maikel Linke
66c6994d78 Fix typo in spec 2024-02-22 15:01:14 +11:00
Maikel Linke
2cf8a6dcb9 Skip haml-up spec with newer versions 2024-02-22 15:01:14 +11:00
Maikel Linke
7a767ab037 Make haml aware of custom boolean attributes 2024-02-22 15:01:13 +11:00
dependabot[bot]
cf7e0eb2cc Bump haml from 5.2.2 to 6.3.0
Bumps [haml](https://github.com/haml/haml) from 5.2.2 to 6.3.0.
- [Release notes](https://github.com/haml/haml/releases)
- [Changelog](https://github.com/haml/haml/blob/main/CHANGELOG.md)
- [Commits](https://github.com/haml/haml/compare/v5.2.2...v6.3.0)

---
updated-dependencies:
- dependency-name: haml
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-22 15:01:13 +11:00
Maikel Linke
c097f2b622 Upgrade HAML syntax with script 2024-02-22 15:01:13 +11:00
Maikel Linke
4516d90ede Add script to upgrade HAML syntax
[skip-ci]
2024-02-22 15:01:13 +11:00
Mohamed ABDELLANI
f4395a9d18 test display_line_item_tax_rate 2024-02-21 20:55:49 +01:00
Mohamed ABDELLANI
f44a4356c5 remove 0.0% if no tax rate applied to line items 2024-02-19 23:43:21 +01:00
Mohamed ABDELLANI
59a9034108 remove tax rates from line_items data presenter 2024-02-19 12:36:24 +01:00
Mohamed ABDELLANI
56fe7f5e21 fix tax rates listing in invoices 2024-02-19 12:32:11 +01:00
Mohamed ABDELLANI
91ecdb0eb9 remove tax_rates from line_items serializer 2024-02-19 11:35:09 +01:00
292 changed files with 2153 additions and 1678 deletions

View File

@@ -10,12 +10,12 @@ RSpec:
FactoryBot:
Enabled: false
# Enabled rules
Capybara/NegationMatcher:
Enabled: true
EnforcedStyle: not_to
RSpec/ExpectChange:
Enabled: true
EnforcedStyle: block
RSpec/MultipleExpectations:
Max: 5 # Default 1
RSpec/MultipleMemoizedHelpers:
Max: 10 # Default 5

View File

@@ -889,7 +889,6 @@ 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).

View File

@@ -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'

View File

@@ -175,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)
@@ -326,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)
@@ -359,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
@@ -380,7 +382,7 @@ GEM
rspec (>= 2.0, < 4.0)
jsonapi-serializer (2.2.0)
activesupport (>= 4.2)
jwt (2.8.0)
jwt (2.8.1)
base64
knapsack_pro (6.0.4)
rake
@@ -504,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)
@@ -626,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)
@@ -653,8 +658,8 @@ 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)
@@ -664,7 +669,7 @@ GEM
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rspec (2.26.1)
rubocop-rspec (2.27.1)
rubocop (~> 1.40)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
@@ -921,6 +926,7 @@ DEPENDENCIES
roo
rspec-rails (>= 3.5.2)
rspec-retry
rspec-sql
rswag
rswag-api
rswag-ui

View File

@@ -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

View File

@@ -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}" }

View File

@@ -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' }
&nbsp;&nbsp;&nbsp;
%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()" }
&times;

View File

@@ -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
= "&nbsp; #{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)" }

View File

@@ -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" }

View File

@@ -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')}

View File

@@ -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)

View File

@@ -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')

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"}

View File

@@ -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 }}" }

View File

@@ -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)' }

View File

@@ -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" }

View File

@@ -1,2 +1,2 @@
%td{ colspan: "{{columnCount}}", ng: { if: "template" } }
.panel{ ng: { include: "template" } }
%td{ colspan: "{{columnCount}}", "ng-if": "template" }
.panel{ "ng-include": "template" }

View File

@@ -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

View File

@@ -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

View File

@@ -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" }

View File

@@ -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 || "&nbsp;" }}
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage !== ''" }, style: 'color: #C85136' }
%h5#status-message{ style: 'color: #C85136', "ng-show": "StatusMessage.invalidMessage !== ''" }
{{ StatusMessage.invalidMessage || "&nbsp;" }}
.nine.columns.omega.text-right{ ng: { transclude: true } }
.nine.columns.omega.text-right{ "ng-transclude": true }

View File

@@ -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()' }

View File

@@ -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()" }
&#10006;

View File

@@ -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" }
&mdash;
{{ 'admin.has_one_rule' | t }}
%span.tag-with-rules{ ng: { if: "data.rules > 1" } }
%span.tag-with-rules{ "ng-if": "data.rules > 1" }
&mdash;
{{ 'admin.has_n_rules' | t:{ num: data.rules } }}
%span{ ng: { if: "!data.rules" } }
%span{ "ng-if": "!data.rules" }
{{$getDisplayText()}}

View File

@@ -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 %

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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" }

View File

@@ -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

View File

@@ -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"}

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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] },

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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) }

View File

@@ -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'

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -2,8 +2,7 @@
module Spree
class Preference < ApplicationRecord
serialize :value
serialize :value, coder: YAML
validates :key, presence: true
validates :value_type, presence: true

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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 &nbsp;
%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 &nbsp;
%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' }

View File

@@ -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"}

View File

@@ -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'

View File

@@ -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

View File

@@ -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) }}

View File

@@ -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
&nbsp;
.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 &nbsp;
%hr

View File

@@ -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

View File

@@ -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" }}

View File

@@ -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')

View File

@@ -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'

View File

@@ -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()' }

View File

@@ -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|

View File

@@ -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 }

View File

@@ -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'

View File

@@ -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'

View File

@@ -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()'}

View File

@@ -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 &nbsp;
- else
.five.columns &nbsp;
.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()" }

View File

@@ -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

View File

@@ -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')

View File

@@ -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' }

View File

@@ -1,39 +1,39 @@
%tr{ class: "order-cycle-{{orderCycle.id}} {{orderCycle.status}}", ng: { repeat: 'orderCycle in orderCycles | schedule:scheduleFilter | involving:involvingFilter | filter:{name: query} track by orderCycle.id' } }
%td.name{ ng: { show: 'columns.name.visible' } }
%input{ id: 'oc{{::orderCycle.id}}_name', name: 'oc{{::orderCycle.id}}[name]', type: 'text', ng: { model: 'orderCycle.name', disabled: '!orderCycle.viewing_as_coordinator' } }
%td.schedules{ ng: { show: 'columns.schedules.visible' } }
%span{ ng: { repeat: 'schedule in orderCycle.schedules'} }
%tr{ class: "order-cycle-{{orderCycle.id}} {{orderCycle.status}}", "ng-repeat": 'orderCycle in orderCycles | schedule:scheduleFilter | involving:involvingFilter | filter:{name: query} track by orderCycle.id' }
%td.name{ "ng-show": 'columns.name.visible' }
%input{ id: 'oc{{::orderCycle.id}}_name', name: 'oc{{::orderCycle.id}}[name]', type: 'text', "ng-model": 'orderCycle.name', "ng-disabled": '!orderCycle.viewing_as_coordinator' }
%td.schedules{ "ng-show": 'columns.schedules.visible' }
%span{ "ng-repeat": 'schedule in orderCycle.schedules' }
%a{ 'schedule-dialog' => true, 'schedule-id' => '{{schedule.id}}' }
{{ schedule.name + ($last ? '' : ',') }}
%span{ ng: { show: 'orderCycle.schedules.length == 0'}} None
%td.orders_open_at{ ng: { show: 'columns.open.visible' } }
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at' }, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'change-warning' => 'orderCycle' }
%input{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at'}, disabled: true }
%td.orders_close_at{ ng: { show: 'columns.close.visible' } }
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at' }, data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, 'change-warning' => 'orderCycle' }
%input{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at'}, disabled: true }
%span{ "ng-show": 'orderCycle.schedules.length == 0' } None
%td.orders_open_at{ "ng-show": 'columns.open.visible' }
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, "change-warning": 'orderCycle', "ng-if": 'orderCycle.viewing_as_coordinator', "ng-model": 'orderCycle.orders_open_at' }
%input{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', disabled: true, "ng-if": '!orderCycle.viewing_as_coordinator', "ng-model": 'orderCycle.orders_open_at' }
%td.orders_close_at{ "ng-show": 'columns.close.visible' }
%input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', data: { controller: "flatpickr", "flatpickr-enable-time-value": true }, "change-warning": 'orderCycle', "ng-if": 'orderCycle.viewing_as_coordinator', "ng-model": 'orderCycle.orders_close_at' }
%input{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', disabled: true, "ng-if": '!orderCycle.viewing_as_coordinator', "ng-model": 'orderCycle.orders_close_at' }
- unless simple_index
%td.producers{ ng: { show: 'columns.producers.visible' } }
%span{'ofn-with-tip' => '{{ orderCycle.producerNames }}', ng: { show: 'orderCycle.producers.length > 3' } }
%td.producers{ "ng-show": 'columns.producers.visible' }
%span{ "ofn-with-tip": '{{ orderCycle.producerNames }}', "ng-show": 'orderCycle.producers.length > 3' }
{{ orderCycle.producers.length }}
= t('.suppliers')
%span{ ng: { hide: 'orderCycle.producers.length > 3', bind: 'orderCycle.producerNames' } }
%td.coordinator{ ng: { show: 'columns.coordinator.visible', bind: { html: 'orderCycle.coordinator.name'} } }
%td.shops{ ng: { show: 'columns.shops.visible' } }
%span{'ofn-with-tip' => '{{ orderCycle.shopNames }}', ng: { show: 'orderCycle.shops.length > 3' } }
%span{ "ng-hide": 'orderCycle.producers.length > 3', "ng-bind": 'orderCycle.producerNames' }
%td.coordinator{ "ng-show": 'columns.coordinator.visible', "ng-bind-html": 'orderCycle.coordinator.name' }
%td.shops{ "ng-show": 'columns.shops.visible' }
%span{ "ofn-with-tip": '{{ orderCycle.shopNames }}', "ng-show": 'orderCycle.shops.length > 3' }
{{ orderCycle.shops.length }}
= t('.distributors')
%span{ ng: { hide: 'orderCycle.shops.length > 3', bind: 'orderCycle.shopNames' } }
%span{ "ng-hide": 'orderCycle.shops.length > 3', "ng-bind": 'orderCycle.shopNames' }
%td.products{ ng: { show: 'columns.products.visible' } }
%td.products{ "ng-show": 'columns.products.visible' }
%span
{{orderCycle.variant_count}}
= t('.variants')
%td.actions
%a.edit-order-cycle.icon-edit.no-text{ ng: { href: '{{orderCycle.edit_path}}'}, 'ofn-with-tip' => t(:edit) }
%td.actions{ ng: { if: 'orderCycle.viewing_as_coordinator' } }
%a.clone-order-cycle.icon-copy.no-text{ ng: { href: '{{orderCycle.clone_path}}'}, 'ofn-with-tip' => t(:clone) }
%td.actions{ ng: { if: 'orderCycle.deletable && orderCycle.viewing_as_coordinator' }}
%a.delete-order-cycle.icon-trash.no-text{ ng: { href: '{{orderCycle.delete_path}}'}, data: { method: 'delete', confirm: t(:are_you_sure), "ujs-navigate": "false" }, 'ofn-with-tip' => t(:remove) }
%a.edit-order-cycle.icon-edit.no-text{ "ofn-with-tip": t(:edit), "ng-href": '{{orderCycle.edit_path}}' }
%td.actions{ "ng-if": 'orderCycle.viewing_as_coordinator' }
%a.clone-order-cycle.icon-copy.no-text{ "ofn-with-tip": t(:clone), "ng-href": '{{orderCycle.clone_path}}' }
%td.actions{ "ng-if": 'orderCycle.deletable && orderCycle.viewing_as_coordinator' }
%a.delete-order-cycle.icon-trash.no-text{ data: { method: 'delete', confirm: t(:are_you_sure), "ujs-navigate": "false" }, "ofn-with-tip": t(:remove), "ng-href": '{{orderCycle.delete_path}}' }

View File

@@ -1,4 +1,4 @@
.text-center.margin-bottom-50{ ng: { hide: "RequestMonitor.loading" } }
%input{ type: 'button', value: "#{t('admin.show_n_more', num: '30')} #{t(:days)}", ng: { click: 'showMore(30)' } }
.text-center.margin-bottom-50{ "ng-hide": "RequestMonitor.loading" }
%input{ type: 'button', value: "#{t('admin.show_n_more', num: '30')} #{t(:days)}", "ng-click": 'showMore(30)' }
%input{ type: 'button', value: "#{t('admin.show_n_more', num: '90')} #{t(:days)}", ng: { click: 'showMore(90)' } }
%input{ type: 'button', value: "#{t('admin.show_n_more', num: '90')} #{t(:days)}", "ng-click": 'showMore(90)' }

View File

@@ -15,9 +15,9 @@
= label_tag t('.products')
%table.exchanges
%tbody{ng: {repeat: "exchange in order_cycle.incoming_exchanges"}}
%tbody{ "ng-repeat": "exchange in order_cycle.incoming_exchanges" }
%tr.products
%td{ ng: { include: "'admin/panels/exchange_products_simple.html'" } }
%td{ "ng-include": "'admin/panels/exchange_products_simple.html'" }
%br
= label_tag t('.tags')

View File

@@ -19,13 +19,13 @@
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.orderCycles', 'ng-controller' => ng_controller, name: 'order_cycle_form'} do |f|
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
%input.red{ type: "button", value: t('.save'), ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input.red{ type: "button", value: t('.save'), "ng-click": "submit($event, null)", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
- if @order_cycle.simple?
%input.red{ type: "button", value: t('.save_and_back_to_list'), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input.red{ type: "button", value: t('.save_and_back_to_list'), "ng-click": "submit($event, '#{main_app.admin_order_cycles_path}')", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
- else
%input.red{ type: "button", value: t('.save_and_next'), ng: { click: "submit($event, '#{main_app.admin_order_cycle_incoming_path(@order_cycle)}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input{ type: "button", value: t('.next'), ng: { click: "cancel('#{main_app.admin_order_cycle_incoming_path(@order_cycle)}')", disabled: "order_cycle_form.$dirty" } }
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
%input.red{ type: "button", value: t('.save_and_next'), "ng-click": "submit($event, '#{main_app.admin_order_cycle_incoming_path(@order_cycle)}')", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
%input{ type: "button", value: t('.next'), "ng-click": "cancel('#{main_app.admin_order_cycle_incoming_path(@order_cycle)}')", "ng-disabled": "order_cycle_form.$dirty" }
%input{ type: "button", "ng-value": "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", "ng-click": "cancel('#{main_app.admin_order_cycles_path}')" }
- if @order_cycle.simple?
= render 'simple_form', f: f

View File

@@ -9,10 +9,10 @@
= render 'wizard_progress'
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
%input.red{ type: "button", value: t('.save'), ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input.red{ type: "button", value: t('.save_and_next'), ng: { click: "submit($event, '#{main_app.admin_order_cycle_outgoing_path(@order_cycle)}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input{ type: "button", value: t('.next'), ng: { click: "cancel('#{main_app.admin_order_cycle_outgoing_path(@order_cycle)}')", disabled: "order_cycle_form.$dirty" } }
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
%input.red{ type: "button", value: t('.save'), "ng-click": "submit($event, null)", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
%input.red{ type: "button", value: t('.save_and_next'), "ng-click": "submit($event, '#{main_app.admin_order_cycle_outgoing_path(@order_cycle)}')", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
%input{ type: "button", value: t('.next'), "ng-click": "cancel('#{main_app.admin_order_cycle_outgoing_path(@order_cycle)}')", "ng-disabled": "order_cycle_form.$dirty" }
%input{ type: "button", "ng-value": "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", "ng-click": "cancel('#{main_app.admin_order_cycles_path}')" }
%fieldset.no-border-bottom
%legend{ align: 'center'}= t('.incoming')

View File

@@ -14,19 +14,19 @@
= admin_inject_column_preferences module: 'admin.orderCycles'
%div{ ng: { controller: 'OrderCyclesCtrl' } }
%div{ "ng-controller": 'OrderCyclesCtrl' }
= render 'admin/order_cycles/filters'
%hr.divider
.row.controls{ ng: { show: "orderCycles.length > 0" } }
.row.controls{ "ng-show": "orderCycles.length > 0" }
.thirteen.columns.alpha &nbsp;
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
%form{ name: 'order_cycles_form' }
%save-bar{ dirty: "order_cycles_form.$dirty", persist: "false" }
%input.red{ type: "button", value: t(:save_changes), ng: { click: "saveAll()", disabled: "!order_cycles_form.$dirty" } }
%table.index#listing_order_cycles{ ng: { show: 'orderCycles.length > 0' } }
%input.red{ type: "button", value: t(:save_changes), "ng-click": "saveAll()", "ng-disabled": "!order_cycles_form.$dirty" }
%table.index#listing_order_cycles{ "ng-show": 'orderCycles.length > 0' }
= render 'admin/order_cycles/header' #, simple_index: simple_index
%tbody
= render 'admin/order_cycles/row' #, simple_index: simple_index

View File

@@ -9,8 +9,8 @@
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
- if @order_cycle.simple?
- custom_redirect_path = main_app.admin_order_cycles_path
%input.red{ type: "button", value: t('.create'), ng: { click: "submit($event, '#{custom_redirect_path}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
%input.red{ type: "button", value: t('.create'), "ng-click": "submit($event, '#{custom_redirect_path}')", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
%input{ type: "button", "ng-value": "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", "ng-click": "cancel('#{main_app.admin_order_cycles_path}')" }
- if @order_cycle.simple?
= render 'simple_form', f: f

View File

@@ -9,10 +9,10 @@
= render 'wizard_progress'
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
%input.red{ type: "button", value: t('.save'), ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input.red{ type: "button", value: t('.save_and_next'), ng: { click: "submit($event, '#{main_app.admin_order_cycle_checkout_options_path(@order_cycle)}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
%input{ type: "button", value: t('.next'), ng: { click: "cancel('#{main_app.admin_order_cycle_checkout_options_path(@order_cycle)}')", disabled: "order_cycle_form.$dirty" } }
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
%input.red{ type: "button", value: t('.save'), "ng-click": "submit($event, null)", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
%input.red{ type: "button", value: t('.save_and_next'), "ng-click": "submit($event, '#{main_app.admin_order_cycle_checkout_options_path(@order_cycle)}')", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
%input{ type: "button", value: t('.next'), "ng-click": "cancel('#{main_app.admin_order_cycle_checkout_options_path(@order_cycle)}')", "ng-disabled": "order_cycle_form.$dirty" }
%input{ type: "button", "ng-value": "order_cycle_form.$dirty ? '#{t('.cancel')}' : '#{t('.back_to_list')}'", "ng-click": "cancel('#{main_app.admin_order_cycles_path}')" }
%fieldset.no-border-bottom
%legend{ align: 'center'}= t('.outgoing')
@@ -27,7 +27,7 @@
%a{href: '#', 'ng-click' => "OrderCycle.toggleAllProducts('outgoing')"}
%span{'ng-show' => "OrderCycle.showProducts['outgoing']"}= t(:collapse_all)
%span{'ng-hide' => "OrderCycle.showProducts['outgoing']"}= t(:expand_all)
%th{ ng: { if: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } }
%th{ "ng-if": 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' }
= t('.tags')
%th= t('.delivery_details')
%th= t('.fees')

View File

@@ -5,10 +5,10 @@
%th #{t('admin.product_import.import.line')}
- @importer.table_headings.each do |heading|
%th= heading
%tr{ng: {repeat: "(line_number, entry) in (entries | entriesFilterValid:'#{entries}')"}}
%tr{ "ng-repeat": "(line_number, entry) in (entries | entriesFilterValid:'#{entries}')" }
%td
%i{ng: {class: "{'fa fa-warning error': (count(entry.errors) > 0), 'fa fa-check-circle success': (count(entry.errors) == 0)}"}}
%i{ "ng-class": "{'fa fa-warning error': (count(entry.errors) > 0), 'fa fa-check-circle success': (count(entry.errors) == 0)}" }
%td
{{line_number}}
%td{ng: {repeat: "(attribute, value) in entry.attributes", class: "{'invalid': attribute_invalid(attribute, line_number)}"}}
%td{ "ng-repeat": "(attribute, value) in entry.attributes", "ng-class": "{'invalid': attribute_invalid(attribute, line_number)}" }
{{value}}

View File

@@ -1,9 +1,9 @@
%div.import-errors{ng: {controller: 'ImportFeedbackCtrl', repeat: "(line_number, entry ) in (entries | entriesFilterValid:'invalid')"}}
%div.import-errors{ "ng-controller": 'ImportFeedbackCtrl', "ng-repeat": "(line_number, entry ) in (entries | entriesFilterValid:'invalid')" }
%p.line
%strong
#{t('admin.product_import.import.item_line')} {{line_number}}:
%span {{entry.attributes.name}}
%span{ng: {if: "entry.attributes.display_name"}}
%span{ "ng-if": "entry.attributes.display_name" }
( {{entry.attributes.display_name}} )
%p.error{ng: {repeat: "(attribute, error) in entry.errors", show: "ignore_fields.indexOf(attribute) < 0" }}
%p.error{ "ng-repeat": "(attribute, error) in entry.errors", "ng-show": "ignore_fields.indexOf(attribute) < 0" }
&nbsp;-&nbsp; {{error}}

View File

@@ -4,7 +4,7 @@
- @importer.enterprises_index.each do |name, attrs|
- if name and attrs[:id] and @importer.permission_by_id?(attrs[:id])
%div.panel-section.import-settings
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active}'}}
%div.panel-header{ "ng-click": 'togglePanel()', "ng-class": '{active: active}' }
%div.header-icon.success
%i.fa.fa-check-circle
%div.header-description

View File

@@ -1,7 +1,7 @@
%h5= t('admin.product_import.import.validation_overview')
%br
%div{ng: {controller: 'ImportFeedbackCtrl'}}
%div{ "ng-controller": 'ImportFeedbackCtrl' }
- if @importer.product_field_errors?
.alert-box.warning
@@ -9,10 +9,10 @@
%em= @non_updatable_fields.keys.join(', ') + "."
= t('.fields_ignored')
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl'}}
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count((entries | entriesFilterValid:"all"))}'}}
%div.panel-section{ "ng-controller": 'DropdownPanelsCtrl' }
%div.panel-header{ "ng-click": 'togglePanel()', "ng-class": '{active: active && count((entries | entriesFilterValid:"all"))}' }
%div.header-caret
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count((entries | entriesFilterValid:"all")) == 0'}}
%i{ "ng-class": "{'icon-chevron-down': active, 'icon-chevron-right': !active}", "ng-hide": 'count((entries | entriesFilterValid:"all")) == 0' }
%div.header-icon.success
%i.fa.fa-info-circle.info
%div.header-count
@@ -20,13 +20,13 @@
{{ count((entries | entriesFilterValid:"all")) }}
%div.header-description
= t('admin.product_import.import.entries_found')
%div.panel-content{ng: {hide: '!active || count((entries | entriesFilterValid:"all")) == 0'}}
%div.panel-content{ "ng-hide": '!active || count((entries | entriesFilterValid:"all")) == 0' }
= render 'entries_table', entries: 'all'
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', hide: 'count((entries | entriesFilterValid:"invalid")) == 0'}}
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count((entries | entriesFilterValid:"invalid"))}'}}
%div.panel-section{ "ng-controller": 'DropdownPanelsCtrl', "ng-hide": 'count((entries | entriesFilterValid:"invalid")) == 0' }
%div.panel-header{ "ng-click": 'togglePanel()', "ng-class": '{active: active && count((entries | entriesFilterValid:"invalid"))}' }
%div.header-caret
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count((entries | entriesFilterValid:"invalid")) == 0'}}
%i{ "ng-class": "{'icon-chevron-down': active, 'icon-chevron-right': !active}", "ng-hide": 'count((entries | entriesFilterValid:"invalid")) == 0' }
%div.header-icon.error
%i.fa.fa-warning
%div.header-count
@@ -34,15 +34,15 @@
{{ count((entries | entriesFilterValid:"invalid")) }}
%div.header-description
= t('admin.product_import.import.entries_with_errors')
%div.panel-content{ng: {hide: '!active || count((entries | entriesFilterValid:"invalid")) == 0'}}
%div.panel-content{ "ng-hide": '!active || count((entries | entriesFilterValid:"invalid")) == 0' }
= render 'errors_list'
%br
= render 'entries_table', entries: 'invalid'
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', hide: 'count((entries | entriesFilterValid:"create_product")) == 0'}}
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count((entries | entriesFilterValid:"create_product"))}'}}
%div.panel-section{ "ng-controller": 'DropdownPanelsCtrl', "ng-hide": 'count((entries | entriesFilterValid:"create_product")) == 0' }
%div.panel-header{ "ng-click": 'togglePanel()', "ng-class": '{active: active && count((entries | entriesFilterValid:"create_product"))}' }
%div.header-caret
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count((entries | entriesFilterValid:"create_product")) == 0'}}
%i{ "ng-class": "{'icon-chevron-down': active, 'icon-chevron-right': !active}", "ng-hide": 'count((entries | entriesFilterValid:"create_product")) == 0' }
%div.header-icon.success
%i.fa.fa-check-circle
%div.header-count
@@ -50,13 +50,13 @@
{{ count((entries | entriesFilterValid:"create_product")) }}
%div.header-description
= t('admin.product_import.import.products_to_create')
%div.panel-content{ng: {hide: '!active || count((entries | entriesFilterValid:"create_product")) == 0'}}
%div.panel-content{ "ng-hide": '!active || count((entries | entriesFilterValid:"create_product")) == 0' }
= render 'entries_table', entries: 'create_product'
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', hide: 'count((entries | entriesFilterValid:"update_product")) == 0'}}
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count((entries | entriesFilterValid:"update_product"))}'}}
%div.panel-section{ "ng-controller": 'DropdownPanelsCtrl', "ng-hide": 'count((entries | entriesFilterValid:"update_product")) == 0' }
%div.panel-header{ "ng-click": 'togglePanel()', "ng-class": '{active: active && count((entries | entriesFilterValid:"update_product"))}' }
%div.header-caret
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count((entries | entriesFilterValid:"update_product")) == 0'}}
%i{ "ng-class": "{'icon-chevron-down': active, 'icon-chevron-right': !active}", "ng-hide": 'count((entries | entriesFilterValid:"update_product")) == 0' }
%div.header-icon.success
%i.fa.fa-check-circle
%div.header-count
@@ -64,13 +64,13 @@
{{ count((entries | entriesFilterValid:"update_product")) }}
%div.header-description
= t('admin.product_import.import.products_to_update')
%div.panel-content{ng: {hide: '!active || count((entries | entriesFilterValid:"update_product")) == 0'}}
%div.panel-content{ "ng-hide": '!active || count((entries | entriesFilterValid:"update_product")) == 0' }
= render 'entries_table', entries: 'update_product'
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', hide: 'count((entries | entriesFilterValid:"create_inventory")) == 0'}}
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count((entries | entriesFilterValid:"create_inventory"))}'}}
%div.panel-section{ "ng-controller": 'DropdownPanelsCtrl', "ng-hide": 'count((entries | entriesFilterValid:"create_inventory")) == 0' }
%div.panel-header{ "ng-click": 'togglePanel()', "ng-class": '{active: active && count((entries | entriesFilterValid:"create_inventory"))}' }
%div.header-caret
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count((entries | entriesFilterValid:"create_inventory")) == 0'}}
%i{ "ng-class": "{'icon-chevron-down': active, 'icon-chevron-right': !active}", "ng-hide": 'count((entries | entriesFilterValid:"create_inventory")) == 0' }
%div.header-icon.success
%i.fa.fa-check-circle
%div.header-count
@@ -78,13 +78,13 @@
{{ count((entries | entriesFilterValid:"create_inventory")) }}
%div.header-description
= t('admin.product_import.import.inventory_to_create')
%div.panel-content{ng: {hide: '!active || count((entries | entriesFilterValid:"create_inventory")) == 0'}}
%div.panel-content{ "ng-hide": '!active || count((entries | entriesFilterValid:"create_inventory")) == 0' }
= render 'entries_table', entries: 'create_inventory'
%div.panel-section{ng: {controller: 'DropdownPanelsCtrl', hide: 'count((entries | entriesFilterValid:"update_inventory")) == 0'}}
%div.panel-header{ng: {click: 'togglePanel()', class: '{active: active && count((entries | entriesFilterValid:"update_inventory"))}'}}
%div.panel-section{ "ng-controller": 'DropdownPanelsCtrl', "ng-hide": 'count((entries | entriesFilterValid:"update_inventory")) == 0' }
%div.panel-header{ "ng-click": 'togglePanel()', "ng-class": '{active: active && count((entries | entriesFilterValid:"update_inventory"))}' }
%div.header-caret
%i{ng: {class: "{'icon-chevron-down': active, 'icon-chevron-right': !active}", hide: 'count((entries | entriesFilterValid:"update_inventory")) == 0'}}
%i{ "ng-class": "{'icon-chevron-down': active, 'icon-chevron-right': !active}", "ng-hide": 'count((entries | entriesFilterValid:"update_inventory")) == 0' }
%div.header-icon.success
%i.fa.fa-check-circle
%div.header-count
@@ -92,10 +92,10 @@
{{ count((entries | entriesFilterValid:"update_inventory")) }}
%div.header-description
= t('admin.product_import.import.inventory_to_update')
%div.panel-content{ng: {hide: '!active || count((entries | entriesFilterValid:"update_inventory")) == 0'}}
%div.panel-content{ "ng-hide": '!active || count((entries | entriesFilterValid:"update_inventory")) == 0' }
= render 'entries_table', entries: 'update_inventory'
%div.panel-section{ng: {controller: 'ImportOptionsFormCtrl', hide: 'resetTotal == 0'}}
%div.panel-section{ "ng-controller": 'ImportOptionsFormCtrl', "ng-hide": 'resetTotal == 0' }
%div.panel-header
%div.header-caret
%div.header-icon.info

View File

@@ -4,31 +4,31 @@
%div.post-save-results
%p{ng: {show: 'updates.products_created'}}
%i.fa{ng: {class: "{'fa-info-circle': updates.products_created == 0, 'fa-check-circle': updates.products_created > 0}"}}
%p{ "ng-show": 'updates.products_created' }
%i.fa{ "ng-class": "{'fa-info-circle': updates.products_created == 0, 'fa-check-circle': updates.products_created > 0}" }
%strong.created-count
{{ updates.products_created }}
= t('.products_created')
%p{ng: {show: 'updates.products_updated'}}
%i.fa{ng: {class: "{'fa-info-circle': updates.products_updated == 0, 'fa-check-circle': updates.products_updated > 0}"}}
%p{ "ng-show": 'updates.products_updated' }
%i.fa{ "ng-class": "{'fa-info-circle': updates.products_updated == 0, 'fa-check-circle': updates.products_updated > 0}" }
%strong.updated-count
{{ updates.products_updated }}
= t('.products_updated')
%p{ng: {show: 'updates.inventory_created'}}
%i.fa{ng: {class: "{'fa-info-circle': updates.inventory_created == 0, 'fa-check-circle': updates.inventory_created > 0}"}}
%p{ "ng-show": 'updates.inventory_created' }
%i.fa{ "ng-class": "{'fa-info-circle': updates.inventory_created == 0, 'fa-check-circle': updates.inventory_created > 0}" }
%strong.inv-created-count
{{ updates.inventory_created }}
= t('.inventory_created')
%p{ng: {show: 'updates.inventory_updated'}}
%i.fa{ng: {class: "{'fa-info-circle': updates.inventory_updated == 0, 'fa-check-circle': updates.inventory_updated > 0}"}}
%p{ "ng-show": 'updates.inventory_updated' }
%i.fa{ "ng-class": "{'fa-info-circle': updates.inventory_updated == 0, 'fa-check-circle': updates.inventory_updated > 0}" }
%strong.inv-updated-count
{{ updates.inventory_updated }}
= t('.inventory_updated')
%p{ng: {show: 'updates.products_reset'}}
%p{ "ng-show": 'updates.products_reset' }
%i.fa.fa-info-circle
%strong.reset-count
{{ updates.products_reset }}
@@ -39,24 +39,24 @@
%br
%p{ng: {show: 'update_errors.length == 0'}}
%p{ "ng-show": 'update_errors.length == 0' }
= t('.all_saved')
%div{ng: {show: 'update_errors.length > 0'}}
%div{ "ng-show": 'update_errors.length > 0' }
%p {{ updated_total }} #{t('.some_saved')}
%br
%h5= t('.save_errors')
%p.save-error{ng: {repeat: 'error in update_errors'}}
%p.save-error{ "ng-repeat": 'error in update_errors' }
&nbsp;-&nbsp; {{ error }}
%br
%div{ng: {show: 'updated_total > 0'}}
%a.button.view{href: main_app.admin_inventory_path, ng: {show: 'updates.inventory_created > 0 || updates.inventory_updated > 0'}}
%div{ "ng-show": 'updated_total > 0' }
%a.button.view{ href: main_app.admin_inventory_path, "ng-show": 'updates.inventory_created > 0 || updates.inventory_updated > 0' }
= t('.view_inventory')
%a.button.view{href: admin_products_path, ng: {show: 'updates.products_created > 0 || updates.products_updated > 0'}}
%a.button.view{ href: admin_products_path, "ng-show": 'updates.products_created > 0 || updates.products_updated > 0' }
= t('.view_products')
%a.button{href: main_app.admin_product_import_path}

View File

@@ -1,4 +1,4 @@
%div{ng: {app: 'admin.productImport', controller: 'ImportOptionsFormCtrl', init: "initForm()"}}
%div{ "ng-app": 'admin.productImport', "ng-controller": 'ImportOptionsFormCtrl', "ng-init": "initForm()" }
= form_tag main_app.admin_product_import_path, multipart: true, class: 'product-import' do

View File

@@ -4,7 +4,7 @@
= render partial: 'ams_data'
= render partial: 'spree/admin/shared/product_sub_menu'
.import-wrapper{ng: {app: 'admin.productImport', controller: 'ImportFormCtrl'}}
.import-wrapper{ "ng-app": 'admin.productImport', "ng-controller": 'ImportFormCtrl' }
- if @importer.item_count == 0
%h5
@@ -13,14 +13,14 @@
= t('.none_to_save')
%br
- else
.settings-section{ng: {show: 'step == "settings"'}}
.settings-section{ "ng-show": 'step == "settings"' }
= render 'import_options' if @importer.table_headings
%br
%a.button.proceed{href: '', ng: {click: 'confirmSettings()'}}
%a.button.proceed{ href: '', "ng-click": 'confirmSettings()' }
= t('.import')
%a.button{href: main_app.admin_product_import_path} #{t('admin.cancel')}
.progress-interface{ng: {show: 'step == "import"'}}
.progress-interface{ "ng-show": 'step == "import"' }
%span.filename
= @original_filename
%span.percentage
@@ -34,12 +34,12 @@
= render 'import_review' if @importer.table_headings
%div{ng: {controller: 'ImportFeedbackCtrl', show: 'count((entries | entriesFilterValid:"valid")) > 0'}}
%div{ng: {if: 'count((entries | entriesFilterValid:"invalid")) > 0'}}
%div{ "ng-controller": 'ImportFeedbackCtrl', "ng-show": 'count((entries | entriesFilterValid:"valid")) > 0' }
%div{ "ng-if": 'count((entries | entriesFilterValid:"invalid")) > 0' }
%br
%h5= t('admin.product_import.import.some_invalid_entries')
%p= t('admin.product_import.import.fix_before_import')
%div{ng: {show: 'count((entries | entriesFilterValid:"invalid")) == 0'}}
%div{ "ng-show": 'count((entries | entriesFilterValid:"invalid")) == 0' }
%br
%h5= t('.no_errors')
%p= t('.save_all_imported?')
@@ -47,22 +47,22 @@
= hidden_field_tag :filepath, @filepath
= hidden_field_tag "settings[import_into]", @import_into
%a.button.proceed{href: '', ng: {show: 'count((entries | entriesFilterValid:"invalid")) == 0', click: 'acceptResults()'}}
%a.button.proceed{ href: '', "ng-show": 'count((entries | entriesFilterValid:"invalid")) == 0', "ng-click": 'acceptResults()' }
= t('.save')
%a.button{href: main_app.admin_product_import_path}= t('admin.cancel')
%div{ng: {controller: 'ImportFeedbackCtrl', show: 'count((entries | entriesFilterValid:"valid")) == 0'}}
%div{ "ng-controller": 'ImportFeedbackCtrl', "ng-show": 'count((entries | entriesFilterValid:"valid")) == 0' }
%br
%a.button{href: main_app.admin_product_import_path}= t('admin.cancel')
.progress-interface{ng: {show: 'step == "save"'}}
.progress-interface{ "ng-show": 'step == "save"' }
%span.filename
#{t('.save_imported')} ({{ percentage.save }})
.progress-bar{}
%span.progress-track{ng: {style: "{'width': percentage.save }"}}
%span.progress-track{ "ng-style": "{'width': percentage.save }" }
%p.red
{{ exception }}
.save-results{ng: {show: 'step == "complete"'}}
.save-results{ "ng-show": 'step == "complete"' }
= render 'save_results'

View File

@@ -9,11 +9,18 @@
%td.field
= f.text_field :sku, 'aria-label': t('admin.products_page.columns.sku')
= error_message_on product, :sku
%td.multi-field{ 'data-controller': 'toggle-control', 'data-toggle-control-match-value': 'items' }
= f.select :variant_unit_with_scale,
options_for_select(WeightsAndMeasures.variant_unit_options, product.variant_unit_with_scale),
{},
class: "fullwidth no-input",
'aria-label': t('admin.products_page.columns.unit_scale'),
data: { "controller": "tom-select", "tom-select-options-value": '{ "plugins": [] }', action: "change->toggle-control#displayIfMatch"}
.field
= f.text_field :variant_unit_name, 'aria-label': t('items'), 'data-toggle-control-target': 'control', style: (product.variant_unit == "items" ? "" : "display: none")
= error_message_on product, :variant_unit_name, 'data-toggle-control-target': 'control'
%td.align-right
.content
= product.variant_unit.upcase_first
/ TODO: properly handle custom unit names
= WeightsAndMeasures::UNITS[product.variant_unit] && "(" + WeightsAndMeasures::UNITS[product.variant_unit][product.variant_unit_scale]["name"] + ")"
-# empty
%td.align-right
-# empty
%td.align-right

View File

@@ -6,20 +6,22 @@
} } do |form|
= render(partial: "admin/shared/flashes", locals: { flashes: }) if defined? flashes
%table.products
%col{ width:"4%" }
%col{ width:"15%" }
%col{ width:"5%", style: "max-width:5em" }
%col{ width:"8%" }
%col{ width:"5%", style: "max-width:5em"}
%col{ width:"8%", style: "max-width:5em"}
%col{ width:"10%" }= # producer
%col{ width:"10%" }
%col{ width:"5%" }
%col{ width:"5%", style: "max-width:5em" }
%col{ width:"5%", style: "max-width:5em" }
%colgroup
%col{ width:"56" }= # Img (size + padding)
%col= # (grow to fill) Name
%col{ width:"8%"}
%col{ width:"8%"}
%col{ width:"5%"}
%col{ width:"5%"}
%col{ width:"10%"}
%col{ width:"15%"}= # Producer
%col{ width:"8%"}
%col{ width:"8%"}
%col{ width:"8%"}
%col{ width:"8%"}= # Actions
%thead
%tr
%td.form-actions-wrapper{ colspan: 11 }
%td.form-actions-wrapper{ colspan: 12 }
.form-actions-wrapper2
%fieldset.form-actions{ class: ("hidden" unless defined?(error_counts)), 'data-bulk-form-target': "actions" }
.container
@@ -40,6 +42,7 @@
%th.align-left= # image
%th.align-left.with-input= t('admin.products_page.columns.name')
%th.align-left.with-input= t('admin.products_page.columns.sku')
%th.align-left.with-input= t('admin.products_page.columns.unit_scale')
%th.align-right= t('admin.products_page.columns.unit')
%th.align-left.with-input= t('admin.products_page.columns.price')
%th.align-left.with-input= t('admin.products_page.columns.on_hand')
@@ -50,7 +53,8 @@
%th.align-right= t('admin.products_page.columns.actions')
- products.each_with_index do |product, product_index|
= form.fields_for("products", product, index: product_index) do |product_form|
%tbody.relaxed{ data: { 'record-id': product_form.object.id, controller: "nested-form",
%tbody.relaxed.naked_inputs{ data: { 'record-id': product_form.object.id,
controller: "nested-form",
action: 'nested-form:add->bulk-form#registerElements' } }
%tr
= render partial: 'product_row', locals: { product:, f: product_form }
@@ -68,7 +72,7 @@
%tr{ 'data-nested-form-target': "target" }
%tr.condensed
%td
%td{ colspan: 10 }
%td{ colspan: 11 }
%button.secondary.condensed.naked.icon-plus{ 'data-action': "nested-form#add",
'aria-label': t('.new_variant') }
=t('.new_variant')

View File

@@ -7,6 +7,8 @@
%td.field
= f.text_field :sku, 'aria-label': t('admin.products_page.columns.sku')
= error_message_on variant, :sku
%td
-# empty
- if variant.persisted?
%td.align-right
.content= variant.unit_to_display

View File

@@ -2,6 +2,6 @@
%span{ :class => 'icon-eye-open' }= "&nbsp; #{t('admin.viewing', current_view_name: '{{ currentView().name }}')}".html_safe
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
%div.menu{ 'ng-show' => "expanded" }
%div.menu_item{ ng: { repeat: "(viewKey, view) in views" }, toggle: { view: true }, 'close-on-click' => true }
%div.menu_item{ "close-on-click": true, "ng-repeat": "(viewKey, view) in views", "toggle-view": true }
%span.check
%span.name {{ view.name }}

View File

@@ -4,48 +4,48 @@
%legend{ align: 'center'}= t(:bill_address)
.field
%label{ for: 'bill_address_firstname'}= t(:first_name)
%input.fullwidth#bill_address_firstname{ name: 'bill_address_firstname', type: 'text', required: true, ng: { model: "subscription.bill_address.firstname" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_firstname.$error.required' } }= t(:error_required)
.error{ ng: { repeat: "error in errors['bill_address.firstname']", show: 'subscription_address_form.bill_address_firstname.$pristine' } } {{ error }}
%input.fullwidth#bill_address_firstname{ name: 'bill_address_firstname', type: 'text', required: true, "ng-model": "subscription.bill_address.firstname" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_firstname.$error.required' }= t(:error_required)
.error{ "ng-repeat": "error in errors['bill_address.firstname']", "ng-show": 'subscription_address_form.bill_address_firstname.$pristine' } {{ error }}
.field
%label{ for: 'bill_address_lastname'}= t(:last_name)
%input.fullwidth#bill_address_lastname{ name: 'bill_address_lastname', type: 'text', required: true, ng: { model: "subscription.bill_address.lastname" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_lastname.$error.required' } }= t(:error_required)
.error{ ng: { repeat: "error in errors['bill_address.lastname']", show: 'subscription_address_form.bill_address_lastname.$pristine' } } {{ error }}
%input.fullwidth#bill_address_lastname{ name: 'bill_address_lastname', type: 'text', required: true, "ng-model": "subscription.bill_address.lastname" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_lastname.$error.required' }= t(:error_required)
.error{ "ng-repeat": "error in errors['bill_address.lastname']", "ng-show": 'subscription_address_form.bill_address_lastname.$pristine' } {{ error }}
.field
%label{ for: 'bill_address_address1'}= t(:address)
%input.fullwidth#bill_address_address1{ name: 'bill_address_address1', type: 'text', required: true, ng: { model: "subscription.bill_address.address1" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_address1.$error.required' } }= t(:error_required)
.error{ ng: { repeat: "error in errors['bill_address.address1']", show: 'subscription_address_form.bill_address_address1.$pristine' } } {{ error }}
%input.fullwidth#bill_address_address1{ name: 'bill_address_address1', type: 'text', required: true, "ng-model": "subscription.bill_address.address1" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_address1.$error.required' }= t(:error_required)
.error{ "ng-repeat": "error in errors['bill_address.address1']", "ng-show": 'subscription_address_form.bill_address_address1.$pristine' } {{ error }}
.field
%label{ for: 'bill_address_city'}= t(:suburb)
%input.fullwidth#bill_address_city{ name: 'bill_address_city', type: 'text', required: true, ng: { model: "subscription.bill_address.city" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_city.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.bill_address.city', show: 'subscription_address_form.bill_address_city.$pristine' } } {{ error }}
%input.fullwidth#bill_address_city{ name: 'bill_address_city', type: 'text', required: true, "ng-model": "subscription.bill_address.city" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_city.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.bill_address.city', "ng-show": 'subscription_address_form.bill_address_city.$pristine' } {{ error }}
.field
%label{ for: "bill_address_zipcode"}= t(:postcode)
%input.fullwidth#bill_address_zipcode{ name: 'bill_address_zipcode', type: 'text', required: true, ng: { model: "subscription.bill_address.zipcode" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_zipcode.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.bill_address.zipcode', show: 'subscription_address_form.bill_address_zipcode.$pristine' } } {{ error }}
%input.fullwidth#bill_address_zipcode{ name: 'bill_address_zipcode', type: 'text', required: true, "ng-model": "subscription.bill_address.zipcode" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_zipcode.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.bill_address.zipcode', "ng-show": 'subscription_address_form.bill_address_zipcode.$pristine' } {{ error }}
.field
%label{ for: "bill_address_phone"}= t(:phone)
%input.fullwidth#bill_address_phone{ name: 'bill_address_phone', type: 'text', required: true, ng: { model: "subscription.bill_address.phone" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_phone.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.bill_address.phone', show: 'subscription_address_form.bill_address_phone.$pristine' } } {{ error }}
%input.fullwidth#bill_address_phone{ name: 'bill_address_phone', type: 'text', required: true, "ng-model": "subscription.bill_address.phone" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_phone.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.bill_address.phone', "ng-show": 'subscription_address_form.bill_address_phone.$pristine' } {{ error }}
.field
%label{ for: "bill_address_country_id"}= t(:country)
%input.ofn-select2.fullwidth#bill_address_country_id{ name: 'bill_address_country_id', type: 'number', data: 'countries', required: true, placeholder: t('admin.choose'), ng: { model: 'subscription.bill_address.country_id' } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_country_id.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.bill_address.country', show: 'subscription_address_form.bill_address_country_id.$pristine' } } {{ error }}
%input.ofn-select2.fullwidth#bill_address_country_id{ name: 'bill_address_country_id', type: 'number', data: 'countries', required: true, placeholder: t('admin.choose'), "ng-model": 'subscription.bill_address.country_id' }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_country_id.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.bill_address.country', "ng-show": 'subscription_address_form.bill_address_country_id.$pristine' } {{ error }}
.field
%label{ for: "bill_address_state_id"}= t(:state)
%input.ofn-select2.fullwidth#bill_address_state_id{ name: 'bill_address_state_id', type: 'number', data: 'billStates', required: true, placeholder: t('admin.choose'), ng: { model: 'subscription.bill_address.state_id' } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.bill_address_state_id.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.bill_address.state', show: 'subscription_address_form.bill_address_state_id.$pristine' } } {{ error }}
%input.ofn-select2.fullwidth#bill_address_state_id{ name: 'bill_address_state_id', type: 'number', data: 'billStates', required: true, placeholder: t('admin.choose'), "ng-model": 'subscription.bill_address.state_id' }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.bill_address_state_id.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.bill_address.state', "ng-show": 'subscription_address_form.bill_address_state_id.$pristine' } {{ error }}
.two.columns
%a.button.red.fullwidth{ href: 'javascript:void(0)', ng: { click: 'shipAddressFromBilling()' } }
%a.button.red.fullwidth{ href: 'javascript:void(0)', "ng-click": 'shipAddressFromBilling()' }
= t('copy')
%i.icon-chevron-right
.seven.columns.omega
@@ -53,41 +53,41 @@
%legend{ align: 'center'}= t(:ship_address)
.field
%label{ for: 'ship_address_firstname'}= t(:first_name)
%input.fullwidth#ship_address_firstname{ name: 'ship_address_firstname', type: 'text', required: true, ng: { model: "subscription.ship_address.firstname" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_firstname.$error.required' } }= t(:error_required)
.error{ ng: { repeat: "error in errors['ship_address.firstname']", show: 'subscription_address_form.ship_address_firstname.$pristine' } } {{ error }}
%input.fullwidth#ship_address_firstname{ name: 'ship_address_firstname', type: 'text', required: true, "ng-model": "subscription.ship_address.firstname" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_firstname.$error.required' }= t(:error_required)
.error{ "ng-repeat": "error in errors['ship_address.firstname']", "ng-show": 'subscription_address_form.ship_address_firstname.$pristine' } {{ error }}
.field
%label{ for: 'ship_address_lastname'}= t(:last_name)
%input.fullwidth#ship_address_lastname{ name: 'ship_address_lastname', type: 'text', required: true, ng: { model: "subscription.ship_address.lastname" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_lastname.$error.required' } }= t(:error_required)
.error{ ng: { repeat: "error in errors['ship_address.lastname']", show: 'subscription_address_form.ship_address_lastname.$pristine' } } {{ error }}
%input.fullwidth#ship_address_lastname{ name: 'ship_address_lastname', type: 'text', required: true, "ng-model": "subscription.ship_address.lastname" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_lastname.$error.required' }= t(:error_required)
.error{ "ng-repeat": "error in errors['ship_address.lastname']", "ng-show": 'subscription_address_form.ship_address_lastname.$pristine' } {{ error }}
.field
%label{ for: 'ship_address_address1'}= t(:address)
%input.fullwidth#ship_address_address1{ name: 'ship_address_address1', type: 'text', required: true, ng: { model: "subscription.ship_address.address1" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_address1.$error.required' } }= t(:error_required)
.error{ ng: { repeat: "error in errors['ship_address.address1']", show: 'subscription_address_form.ship_address_address1.$pristine' } } {{ error }}
%input.fullwidth#ship_address_address1{ name: 'ship_address_address1', type: 'text', required: true, "ng-model": "subscription.ship_address.address1" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_address1.$error.required' }= t(:error_required)
.error{ "ng-repeat": "error in errors['ship_address.address1']", "ng-show": 'subscription_address_form.ship_address_address1.$pristine' } {{ error }}
.field
%label{ for: 'ship_address_city'}= t(:suburb)
%input.fullwidth#ship_address_city{ name: 'ship_address_city', type: 'text', required: true, ng: { model: "subscription.ship_address.city" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_city.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.ship_address.city', show: 'subscription_address_form.ship_address_city.$pristine' } } {{ error }}
%input.fullwidth#ship_address_city{ name: 'ship_address_city', type: 'text', required: true, "ng-model": "subscription.ship_address.city" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_city.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.ship_address.city', "ng-show": 'subscription_address_form.ship_address_city.$pristine' } {{ error }}
.field
%label{ for: "ship_address_zipcode"}= t(:postcode)
%input.fullwidth#ship_address_zipcode{ name: 'ship_address_zipcode', type: 'text', required: true, ng: { model: "subscription.ship_address.zipcode" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_zipcode.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.ship_address.zipcode', show: 'subscription_address_form.ship_address_zipcode.$pristine' } } {{ error }}
%input.fullwidth#ship_address_zipcode{ name: 'ship_address_zipcode', type: 'text', required: true, "ng-model": "subscription.ship_address.zipcode" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_zipcode.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.ship_address.zipcode', "ng-show": 'subscription_address_form.ship_address_zipcode.$pristine' } {{ error }}
.field
%label{ for: "ship_address_phone"}= t(:phone)
%input.fullwidth#ship_address_phone{ name: 'ship_address_phone', type: 'text', required: true, ng: { model: "subscription.ship_address.phone" } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_phone.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.ship_address.phone', show: 'subscription_address_form.ship_address_phone.$pristine' } } {{ error }}
%input.fullwidth#ship_address_phone{ name: 'ship_address_phone', type: 'text', required: true, "ng-model": "subscription.ship_address.phone" }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_phone.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.ship_address.phone', "ng-show": 'subscription_address_form.ship_address_phone.$pristine' } {{ error }}
.field
%label{ for: "ship_address_country_id"}= t(:country)
%input.ofn-select2.fullwidth#ship_address_country_id{ name: 'ship_address_country_id', type: 'number', data: 'countries', required: true, placeholder: t('admin.choose'), ng: { model: 'subscription.ship_address.country_id' } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_country_id.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.ship_address.country', show: 'subscription_address_form.ship_address_country_id.$pristine' } } {{ error }}
%input.ofn-select2.fullwidth#ship_address_country_id{ name: 'ship_address_country_id', type: 'number', data: 'countries', required: true, placeholder: t('admin.choose'), "ng-model": 'subscription.ship_address.country_id' }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_country_id.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.ship_address.country', "ng-show": 'subscription_address_form.ship_address_country_id.$pristine' } {{ error }}
.field
%label{ for: "ship_address_state_id"}= t(:state)
%input.ofn-select2.fullwidth#ship_address_state_id{ name: 'ship_address_state_id', type: 'number', data: 'shipStates', required: true, placeholder: t('admin.choose'), ng: { model: 'subscription.ship_address.state_id' } }
.error{ ng: { show: 'subscription_form.$submitted && subscription_address_form.ship_address_state_id.$error.required' } }= t(:error_required)
.error{ ng: { repeat: 'error in errors.ship_address.state', show: 'subscription_address_form.ship_address_state_id.$pristine' } } {{ error }}
%input.ofn-select2.fullwidth#ship_address_state_id{ name: 'ship_address_state_id', type: 'number', data: 'shipStates', required: true, placeholder: t('admin.choose'), "ng-model": 'subscription.ship_address.state_id' }
.error{ "ng-show": 'subscription_form.$submitted && subscription_address_form.ship_address_state_id.$error.required' }= t(:error_required)
.error{ "ng-repeat": 'error in errors.ship_address.state', "ng-show": 'subscription_address_form.ship_address_state_id.$pristine' } {{ error }}

View File

@@ -9,12 +9,12 @@
%td.vertical-align-top
.field
= label_tag :add_variant_id, t('.name_or_sku')
%input#add_variant_id.variant_autocomplete.fullwidth{ type: 'number', ng: { model: 'newItem.variant_id' } }
%input#add_variant_id.variant_autocomplete.fullwidth{ type: 'number', "ng-model": 'newItem.variant_id' }
%td.vertical-align-top
.field
= label_tag :add_quantity, t('.quantity')
%input#add_quantity.fullwidth{ type: 'number', min: 1, ng: { model: 'newItem.quantity' } }
%input#add_quantity.fullwidth{ type: 'number', min: 1, "ng-model": 'newItem.quantity' }
%td
.actions
%a.icon-plus.button.fullwidth{ href: 'javascript:void(0)', ng: { click: 'addSubscriptionLineItem()' } }
%a.icon-plus.button.fullwidth{ href: 'javascript:void(0)', "ng-click": 'addSubscriptionLineItem()' }
= t('.add')

View File

@@ -1,5 +1,5 @@
%hr.divider.sixteen.columns.alpha.omega{ ng: { show: 'shop_id && subscriptions.length > 0' } }
.controls.sixteen.columns.alpha.omega{ ng: { show: 'shop_id && subscriptions.length > 0' } }
%hr.divider.sixteen.columns.alpha.omega{ "ng-show": 'shop_id && subscriptions.length > 0' }
.controls.sixteen.columns.alpha.omega{ "ng-show": 'shop_id && subscriptions.length > 0' }
.twelve.columns.alpha
&nbsp;
.four.columns.omega

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