mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-04-06 07:29:16 +00:00
Merge branch 'master' into buu-dropdown-tweaks-11518
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
SECRET_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
STRIPE_SECRET_TEST_API_KEY="bogus_key"
|
||||
STRIPE_CUSTOMER="bogus_customer"
|
||||
STRIPE_ACCOUNT="bogus_account"
|
||||
STRIPE_CLIENT_ID="bogus_client_id"
|
||||
STRIPE_PUBLIC_TEST_API_KEY="bogus_stripe_publishable_key"
|
||||
|
||||
SITE_URL="test.host"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1400 --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.57.2.
|
||||
# using RuboCop version 1.59.0.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
@@ -116,13 +116,18 @@ Lint/RedundantSafeNavigation:
|
||||
Exclude:
|
||||
- 'app/models/spree/payment.rb'
|
||||
|
||||
# Offense count: 1
|
||||
Lint/SelfAssignment:
|
||||
Exclude:
|
||||
- 'app/models/spree/order/checkout.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Lint/UselessMethodDefinition:
|
||||
Exclude:
|
||||
- 'app/models/spree/gateway.rb'
|
||||
|
||||
# Offense count: 27
|
||||
# Offense count: 26
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
||||
Metrics/AbcSize:
|
||||
Exclude:
|
||||
@@ -520,21 +525,7 @@ Rails/NegateInclude:
|
||||
- 'lib/spree/localized_number.rb'
|
||||
- 'spec/support/matchers/table_matchers.rb'
|
||||
|
||||
# Offense count: 16
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'app/helpers/angular_form_helper.rb'
|
||||
- 'app/helpers/application_helper.rb'
|
||||
- 'app/helpers/reports_helper.rb'
|
||||
- 'app/helpers/spree/admin/base_helper.rb'
|
||||
- 'app/helpers/spree/admin/navigation_helper.rb'
|
||||
- 'app/helpers/spree/admin/orders_helper.rb'
|
||||
- 'app/helpers/spree/admin/zones_helper.rb'
|
||||
- 'lib/reporting/queries/query_builder.rb'
|
||||
- 'lib/reporting/queries/query_interface.rb'
|
||||
- 'lib/spree/money.rb'
|
||||
|
||||
# Offense count: 31
|
||||
# Offense count: 32
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Rails/Pluck:
|
||||
Exclude:
|
||||
@@ -553,6 +544,7 @@ Rails/Pluck:
|
||||
- 'spec/lib/reports/lettuce_share_report_spec.rb'
|
||||
- 'spec/lib/reports/users_and_enterprises_report_spec.rb'
|
||||
- 'spec/serializers/api/admin/for_order_cycle/supplied_product_serializer_spec.rb'
|
||||
- 'spec/support/api_helper.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
@@ -620,13 +612,12 @@ Rails/ResponseParsedBody:
|
||||
- 'spec/controllers/spree/credit_cards_controller_spec.rb'
|
||||
- 'spec/controllers/user_registrations_controller_spec.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Offense count: 2
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Rails/RootPathnameMethods:
|
||||
Exclude:
|
||||
- 'spec/lib/reports/orders_and_fulfillment/order_cycle_customer_totals_report_spec.rb'
|
||||
- 'spec/models/terms_of_service_file_spec.rb'
|
||||
- 'spec/system/admin/configuration/terms_of_service_files_spec.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
@@ -841,6 +832,22 @@ Style/HashConversion:
|
||||
- 'spec/controllers/admin/inventory_items_controller_spec.rb'
|
||||
- 'spec/controllers/admin/variant_overrides_controller_spec.rb'
|
||||
|
||||
# Offense count: 13
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: AllowedReceivers.
|
||||
# AllowedReceivers: Thread.current
|
||||
Style/HashEachMethods:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/enterprises_controller.rb'
|
||||
- 'app/controllers/spree/admin/shipping_methods_controller.rb'
|
||||
- 'app/forms/enterprise_fees_bulk_update.rb'
|
||||
- 'app/models/product_import/entry_processor.rb'
|
||||
- 'app/models/spree/preferences/configuration.rb'
|
||||
- 'app/services/sets/model_set.rb'
|
||||
- 'lib/reporting/reports/sales_tax/sales_tax_totals_by_producer.rb'
|
||||
- 'spec/models/product_importer_spec.rb'
|
||||
- 'spec/support/cancan_helper.rb'
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: MinBranchesCount.
|
||||
Style/HashLikeCase:
|
||||
|
||||
4
Gemfile
4
Gemfile
@@ -17,7 +17,7 @@ gem "image_processing"
|
||||
gem 'activemerchant', '>= 1.78.0'
|
||||
gem 'angular-rails-templates', '>= 0.3.0'
|
||||
gem 'awesome_nested_set'
|
||||
gem 'ransack', '~> 2.6.0'
|
||||
gem 'ransack', '~> 4.1.0'
|
||||
gem 'responders'
|
||||
gem 'rexml'
|
||||
gem 'webpacker', '~> 5'
|
||||
@@ -93,7 +93,7 @@ gem 'bootsnap', require: false
|
||||
gem 'geocoder'
|
||||
gem 'gmaps4rails'
|
||||
gem 'mimemagic', '> 0.3.5'
|
||||
gem 'paper_trail', '~> 12.1'
|
||||
gem 'paper_trail'
|
||||
gem 'rack-rewrite'
|
||||
gem 'rack-timeout'
|
||||
gem 'roadie-rails'
|
||||
|
||||
87
Gemfile.lock
87
Gemfile.lock
@@ -90,7 +90,7 @@ GEM
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
active_model_serializers (0.8.4)
|
||||
activemodel (>= 3.0)
|
||||
active_storage_validations (1.1.3)
|
||||
active_storage_validations (1.1.4)
|
||||
activejob (>= 5.2.0)
|
||||
activemodel (>= 5.2.0)
|
||||
activestorage (>= 5.2.0)
|
||||
@@ -155,22 +155,21 @@ GEM
|
||||
awesome_nested_set (3.6.0)
|
||||
activerecord (>= 4.0.0, < 7.2)
|
||||
aws-eventstream (1.3.0)
|
||||
aws-partitions (1.860.0)
|
||||
aws-sdk-core (3.189.0)
|
||||
aws-partitions (1.877.0)
|
||||
aws-sdk-core (3.190.1)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.8)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.74.0)
|
||||
aws-sdk-kms (1.75.0)
|
||||
aws-sdk-core (~> 3, >= 3.188.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.141.0)
|
||||
aws-sdk-s3 (1.142.0)
|
||||
aws-sdk-core (~> 3, >= 3.189.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.8)
|
||||
aws-sigv4 (1.8.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
base64 (0.2.0)
|
||||
bcp47_spec (0.2.1)
|
||||
bcrypt (3.1.19)
|
||||
bigdecimal (3.0.2)
|
||||
@@ -178,10 +177,10 @@ GEM
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.17.0)
|
||||
msgpack (~> 1.2)
|
||||
bugsnag (6.26.0)
|
||||
bugsnag (6.26.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.2.4)
|
||||
bullet (7.1.4)
|
||||
bullet (7.1.5)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
cable_ready (5.0.1)
|
||||
@@ -216,7 +215,7 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
combine_pdf (1.0.24)
|
||||
combine_pdf (1.0.26)
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.2.2)
|
||||
@@ -238,7 +237,7 @@ GEM
|
||||
datafoodconsortium-connector (1.0.0.pre.alpha.9)
|
||||
virtual_assembly-semantizer (~> 1.0, >= 1.0.5)
|
||||
date (3.3.3)
|
||||
debug (1.9.0)
|
||||
debug (1.9.1)
|
||||
irb (~> 1.10)
|
||||
reline (>= 0.3.8)
|
||||
debugger-linecache (1.2.0)
|
||||
@@ -271,13 +270,12 @@ GEM
|
||||
factory_bot_rails (6.2.0)
|
||||
factory_bot (~> 6.2.0)
|
||||
railties (>= 5.0.0)
|
||||
faraday (2.7.12)
|
||||
base64
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday (2.9.0)
|
||||
faraday-net_http (>= 2.0, < 3.2)
|
||||
faraday-follow_redirects (0.3.0)
|
||||
faraday (>= 1, < 3)
|
||||
faraday-net_http (3.0.2)
|
||||
faraday-net_http (3.1.0)
|
||||
net-http
|
||||
ferrum (0.14)
|
||||
addressable (~> 2.5)
|
||||
concurrent-ruby (~> 1.1)
|
||||
@@ -345,9 +343,9 @@ GEM
|
||||
ruby-vips (>= 2.0.17, < 3)
|
||||
immigrant (0.3.6)
|
||||
activerecord (>= 3.0)
|
||||
io-console (0.6.0)
|
||||
io-console (0.7.1)
|
||||
ipaddress (0.8.3)
|
||||
irb (1.10.1)
|
||||
irb (1.11.0)
|
||||
rdoc
|
||||
reline (>= 0.3.8)
|
||||
jmespath (1.6.2)
|
||||
@@ -380,7 +378,7 @@ GEM
|
||||
jsonapi-serializer (2.2.0)
|
||||
activesupport (>= 4.2)
|
||||
jwt (2.7.1)
|
||||
knapsack_pro (6.0.3)
|
||||
knapsack_pro (6.0.4)
|
||||
rake
|
||||
language_server-protocol (3.17.0.3)
|
||||
launchy (2.5.0)
|
||||
@@ -402,9 +400,9 @@ GEM
|
||||
marcel (1.0.2)
|
||||
matrix (0.4.2)
|
||||
method_source (1.0.0)
|
||||
mime-types (3.5.1)
|
||||
mime-types (3.5.2)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2023.0808)
|
||||
mime-types-data (3.2023.1205)
|
||||
mimemagic (0.4.3)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
@@ -419,6 +417,8 @@ GEM
|
||||
msgpack (1.7.2)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
net-http (0.4.1)
|
||||
uri
|
||||
net-imap (0.4.2)
|
||||
date
|
||||
net-protocol
|
||||
@@ -428,10 +428,9 @@ GEM
|
||||
timeout
|
||||
net-smtp (0.4.0)
|
||||
net-protocol
|
||||
newrelic_rpm (9.6.0)
|
||||
base64
|
||||
nio4r (2.5.9)
|
||||
nokogiri (1.15.5)
|
||||
newrelic_rpm (9.7.0)
|
||||
nio4r (2.7.0)
|
||||
nokogiri (1.16.0)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
oauth2 (1.4.11)
|
||||
@@ -464,10 +463,10 @@ GEM
|
||||
orm_adapter (0.5.0)
|
||||
pagy (5.10.1)
|
||||
activesupport
|
||||
paper_trail (12.3.0)
|
||||
activerecord (>= 5.2)
|
||||
request_store (~> 1.1)
|
||||
parallel (1.23.0)
|
||||
paper_trail (15.1.0)
|
||||
activerecord (>= 6.1)
|
||||
request_store (~> 1.4)
|
||||
parallel (1.24.0)
|
||||
paranoia (2.6.3)
|
||||
activerecord (>= 5.1, < 7.2)
|
||||
parser (3.2.2.4)
|
||||
@@ -478,7 +477,7 @@ GEM
|
||||
xml-simple
|
||||
paypal-sdk-merchant (1.117.2)
|
||||
paypal-sdk-core (~> 0.3.0)
|
||||
pdf-reader (2.11.0)
|
||||
pdf-reader (2.12.0)
|
||||
Ascii85 (~> 1.0)
|
||||
afm (~> 0.2.1)
|
||||
hashery (~> 2.0)
|
||||
@@ -489,10 +488,10 @@ GEM
|
||||
pry (0.13.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
psych (5.1.1.1)
|
||||
psych (5.1.2)
|
||||
stringio
|
||||
public_suffix (5.0.4)
|
||||
puma (6.4.0)
|
||||
puma (6.4.2)
|
||||
nio4r (~> 2.0)
|
||||
query_count (1.1.1)
|
||||
activerecord (>= 4.2)
|
||||
@@ -559,9 +558,9 @@ GEM
|
||||
zeitwerk (~> 2.5)
|
||||
rainbow (3.1.1)
|
||||
rake (13.1.0)
|
||||
ransack (2.6.0)
|
||||
activerecord (>= 6.0.4)
|
||||
activesupport (>= 6.0.4)
|
||||
ransack (4.1.1)
|
||||
activerecord (>= 6.1.5)
|
||||
activesupport (>= 6.1.5)
|
||||
i18n
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
@@ -569,13 +568,13 @@ GEM
|
||||
rdf (3.3.1)
|
||||
bcp47_spec (~> 0.2)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
rdoc (6.6.1)
|
||||
rdoc (6.6.2)
|
||||
psych (>= 4.0.0)
|
||||
redcarpet (3.6.0)
|
||||
redis (4.8.1)
|
||||
redis-client (0.18.0)
|
||||
connection_pool
|
||||
regexp_parser (2.8.2)
|
||||
regexp_parser (2.8.3)
|
||||
reline (0.4.1)
|
||||
io-console (~> 0.5)
|
||||
request_store (1.5.1)
|
||||
@@ -634,7 +633,7 @@ GEM
|
||||
rswag-ui (2.13.0)
|
||||
actionpack (>= 3.1, < 7.2)
|
||||
railties (>= 3.1, < 7.2)
|
||||
rubocop (1.58.0)
|
||||
rubocop (1.59.0)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
parallel (~> 1.10)
|
||||
@@ -647,7 +646,7 @@ GEM
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.30.0)
|
||||
parser (>= 3.2.1.0)
|
||||
rubocop-rails (2.22.2)
|
||||
rubocop-rails (2.23.1)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
@@ -658,7 +657,6 @@ GEM
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby-vips (2.1.4)
|
||||
ffi (~> 1.12)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
rufus-scheduler (3.8.2)
|
||||
fugit (~> 1.1, >= 1.1.6)
|
||||
@@ -674,7 +672,7 @@ GEM
|
||||
tilt (>= 1.1, < 3)
|
||||
sd_notify (0.1.1)
|
||||
semantic_range (3.0.0)
|
||||
shoulda-matchers (5.3.0)
|
||||
shoulda-matchers (6.0.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (7.2.0)
|
||||
concurrent-ruby (< 2)
|
||||
@@ -725,7 +723,7 @@ GEM
|
||||
stimulus_reflex (>= 3.3.0)
|
||||
stringex (2.8.6)
|
||||
stringio (3.1.0)
|
||||
stripe (10.2.0)
|
||||
stripe (10.3.0)
|
||||
swd (1.3.0)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
@@ -741,6 +739,7 @@ GEM
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (2.5.0)
|
||||
uniform_notifier (1.16.0)
|
||||
uri (0.13.0)
|
||||
valid_email2 (5.1.1)
|
||||
activemodel (>= 3.2)
|
||||
mail (~> 2.5)
|
||||
@@ -753,7 +752,7 @@ GEM
|
||||
validates_lengths_from_database (0.8.0)
|
||||
activerecord (>= 4)
|
||||
vcr (6.2.0)
|
||||
view_component (3.8.0)
|
||||
view_component (3.10.0)
|
||||
activesupport (>= 5.2.0, < 8.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
method_source (~> 1.0)
|
||||
@@ -878,7 +877,7 @@ DEPENDENCIES
|
||||
openid_connect (~> 1.3)
|
||||
order_management!
|
||||
pagy (~> 5.1)
|
||||
paper_trail (~> 12.1)
|
||||
paper_trail
|
||||
paranoia (~> 2.4)
|
||||
paypal-sdk-merchant (= 1.117.2)
|
||||
pdf-reader
|
||||
@@ -895,7 +894,7 @@ DEPENDENCIES
|
||||
rails-erd
|
||||
rails-i18n
|
||||
rails_safe_tasks (~> 1.0)
|
||||
ransack (~> 2.6.0)
|
||||
ransack (~> 4.1.0)
|
||||
redcarpet
|
||||
redis (>= 4.0)
|
||||
responders
|
||||
|
||||
@@ -44,7 +44,7 @@ We use [KnapsackPro](https://knapsackpro.com/) for optimal parallelisation of ou
|
||||
|
||||
## Licence
|
||||
|
||||
Copyright (c) 2012 - 2022 Open Food Foundation, released under the AGPL licence.
|
||||
Copyright (c) 2012 - 2024 Open Food Foundation, released under the AGPL licence.
|
||||
|
||||
[survey]: https://docs.google.com/a/eaterprises.com.au/forms/d/1zxR5vSiU9CigJ9cEaC8-eJLgYid8CR8er7PPH9Mc-30/edit#
|
||||
[slack-invite]: https://join.slack.com/t/openfoodnetwork/shared_invite/zt-9sjkjdlu-r02kUMP1zbrTgUhZhYPF~A
|
||||
|
||||
@@ -43,7 +43,8 @@ angular.module('admin.payments').factory 'Payment', (AdminStripeElements, curren
|
||||
submit: =>
|
||||
munged = @preprocess()
|
||||
PaymentResource.create({order_id: munged.order_id}, munged, (response, headers, status) ->
|
||||
document.body.innerHTML = Object.values(response).join('')
|
||||
rawHtml = Object.values(response).join('').replace('[object Object]true', '')
|
||||
document.body.innerHTML = rawHtml
|
||||
$window.history.pushState({}, '', "/admin/orders/" + munged.order_id + "/payments")
|
||||
, (response) ->
|
||||
StatusMessage.display 'error', t("spree.admin.payments.source_forms.stripe.error_saving_payment")
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
{{'hubs_delivery' | t}}
|
||||
.row
|
||||
.columns.small-12
|
||||
%a.cta-hub{"ng-href" => "{{::enterprise.path}}#/shop", "ng-attr-target" => "{{ embedded_layout ? '_blank' : undefined}}",
|
||||
%a.cta-hub{"ng-href" => "{{::enterprise.path}}#/shop_panel", "ng-attr-target" => "{{ embedded_layout ? '_blank' : undefined}}",
|
||||
"ng-class" => "{primary: enterprise.active, secondary: !enterprise.active}",
|
||||
"ng-click" => "$close()",
|
||||
"ofn-change-hub" => "enterprise"}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
.row
|
||||
.columns.small-12
|
||||
%a.cta-hub{"ng-repeat" => "hub in enterprise.hubs | filter:{id: '!'+enterprise.id} | orderBy:'-active'",
|
||||
"ng-href" => "{{::hub.path}}#/shop", "ofn-empties-cart" => "hub",
|
||||
"ng-href" => "{{::hub.path}}#/shop_panel", "ofn-empties-cart" => "hub",
|
||||
"ng-class" => "::{primary: hub.active, secondary: !hub.active}",
|
||||
"ng-click" => "$close()",
|
||||
"ofn-change-hub" => "hub"}
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ConfirmModalComponent < ModalComponent
|
||||
def initialize(id:, confirm_actions: nil, reflex: nil, controller: nil, message: nil,
|
||||
confirm_reflexes: nil)
|
||||
# @param actions_alignment_class [String] possible classes: 'justify-space-around', 'justify-end'
|
||||
def initialize(
|
||||
id:,
|
||||
reflex: nil,
|
||||
controller: nil,
|
||||
message: nil,
|
||||
confirm_actions: nil,
|
||||
confirm_reflexes: nil,
|
||||
confirm_button_class: :primary,
|
||||
confirm_button_text: I18n.t('js.admin.modals.confirm'),
|
||||
cancel_button_text: I18n.t('js.admin.modals.cancel'),
|
||||
actions_alignment_class: 'justify-space-around'
|
||||
)
|
||||
super(id:, close_button: true)
|
||||
@confirm_actions = confirm_actions
|
||||
@reflex = reflex
|
||||
@confirm_reflexes = confirm_reflexes
|
||||
@controller = controller
|
||||
@message = message
|
||||
@confirm_button_class = confirm_button_class
|
||||
@confirm_button_text = confirm_button_text
|
||||
@cancel_button_text = cancel_button_text
|
||||
@actions_alignment_class = actions_alignment_class
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
= render @message if @message
|
||||
|
||||
.modal-actions
|
||||
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: t('js.admin.modals.cancel'), "data-action": "click->modal#close" }
|
||||
%input{ class: "button icon-plus primary", type: 'button', value: t('js.admin.modals.confirm'), "data-action": @confirm_actions, "data-reflex": @confirm_reflexes }
|
||||
%div{ class: "modal-actions #{@actions_alignment_class}" }
|
||||
%input{ class: "button icon-plus #{close_button_class}", type: 'button', value: @cancel_button_text, "data-action": "click->modal#close" }
|
||||
%input{ id: 'modal-confirm-button', class: "button icon-plus #{@confirm_button_class}", type: 'button', value: @confirm_button_text, "data-action": @confirm_actions, "data-reflex": @confirm_reflexes }
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
&.justify-space-around {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
&.justify-end {
|
||||
justify-content: flex-end;
|
||||
input[type="button"] {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
input[type="button"] {
|
||||
margin: 5px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
visibility: visible;
|
||||
position: fixed;
|
||||
top: 3em;
|
||||
&.in {
|
||||
padding: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* prevent arrow on selected admin menu item appearing above modal */
|
||||
|
||||
@@ -38,7 +38,8 @@ module Admin
|
||||
@enterprise_fee_set = EnterpriseFeesBulkUpdate.new(params)
|
||||
|
||||
if @enterprise_fee_set.save
|
||||
redirect_to redirect_path, notice: I18n.t(:enterprise_fees_update_notice)
|
||||
flash[:success] = I18n.t(:enterprise_fees_update_notice)
|
||||
redirect_to redirect_path
|
||||
else
|
||||
redirect_to redirect_path,
|
||||
flash: { error: @enterprise_fee_set.errors.full_messages.to_sentence }
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
module Admin
|
||||
class EnterpriseRolesController < Admin::ResourceController
|
||||
def index
|
||||
@enterprise_roles = EnterpriseRole.by_user_email
|
||||
@users = Spree::User.order('spree_users.email')
|
||||
@my_enterprises = @all_enterprises = Enterprise.by_name
|
||||
@enterprise_roles, @users, @all_enterprises = Admin::EnterpriseRolesQuery.query
|
||||
@my_enterprises = @all_enterprises
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/permissions'
|
||||
require 'order_management/subscriptions/proxy_order_syncer'
|
||||
|
||||
module Admin
|
||||
class SchedulesController < Admin::ResourceController
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'api/admin/enterprise_serializer'
|
||||
|
||||
module Api
|
||||
module V0
|
||||
class EnterpriseAttachmentController < Api::V0::BaseController
|
||||
|
||||
@@ -9,6 +9,7 @@ module Spree
|
||||
helper 'admin/injection'
|
||||
helper 'admin/orders'
|
||||
helper 'admin/enterprises'
|
||||
helper 'admin/terms_of_service'
|
||||
helper 'enterprise_fees'
|
||||
helper 'angular_form'
|
||||
|
||||
|
||||
@@ -21,15 +21,28 @@ module Admin
|
||||
show_payment_methods = can?(:manage_payment_methods, enterprise) && is_shop
|
||||
show_enterprise_fees = can?(:manage_enterprise_fees,
|
||||
enterprise) && (is_shop || enterprise.is_primary_producer)
|
||||
show_connected_apps = feature?(:connected_apps, spree_current_user, enterprise)
|
||||
|
||||
build_enterprise_side_menu_items(is_shop, show_properties, show_shipping_methods,
|
||||
show_payment_methods, show_enterprise_fees)
|
||||
build_enterprise_side_menu_items(
|
||||
is_shop:,
|
||||
show_properties:,
|
||||
show_shipping_methods:,
|
||||
show_payment_methods:,
|
||||
show_enterprise_fees:,
|
||||
show_connected_apps:,
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_enterprise_side_menu_items(is_shop, show_properties, show_shipping_methods,
|
||||
show_payment_methods, show_enterprise_fees)
|
||||
def build_enterprise_side_menu_items(
|
||||
is_shop:,
|
||||
show_properties:,
|
||||
show_shipping_methods:,
|
||||
show_payment_methods:,
|
||||
show_enterprise_fees:,
|
||||
show_connected_apps:
|
||||
)
|
||||
[
|
||||
{ name: 'primary_details', icon_class: "icon-home", show: true, selected: 'selected' },
|
||||
{ name: 'address', icon_class: "icon-map-marker", show: true },
|
||||
@@ -50,6 +63,7 @@ module Admin
|
||||
{ name: 'shop_preferences', icon_class: "icon-shopping-cart", show: is_shop },
|
||||
{ name: 'users', icon_class: "icon-user", show: true },
|
||||
{ name: 'white_label', icon_class: "icon-leaf", show: true },
|
||||
{ name: 'connected_apps', icon_class: "icon-puzzle-piece", show: show_connected_apps },
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,13 +27,6 @@ module Admin
|
||||
Api::Admin::EnterpriseRelationshipSerializer
|
||||
end
|
||||
|
||||
def admin_inject_enterprise_roles(enterprise_roles)
|
||||
admin_inject_json_ams_array "ofn.admin",
|
||||
"enterpriseRoles",
|
||||
enterprise_roles,
|
||||
Api::Admin::EnterpriseRoleSerializer
|
||||
end
|
||||
|
||||
def admin_inject_payment_methods(payment_methods)
|
||||
admin_inject_json_ams_array "admin.paymentMethods",
|
||||
"paymentMethods",
|
||||
@@ -137,13 +130,6 @@ module Admin
|
||||
Api::Admin::TaxonSerializer
|
||||
end
|
||||
|
||||
def admin_inject_users(users)
|
||||
admin_inject_json_ams_array "ofn.admin",
|
||||
"users",
|
||||
users,
|
||||
Api::Admin::UserSerializer
|
||||
end
|
||||
|
||||
def admin_inject_variant_overrides(variant_overrides)
|
||||
admin_inject_json_ams_array "admin.variantOverrides",
|
||||
"variantOverrides",
|
||||
|
||||
25
app/helpers/admin/terms_of_service_helper.rb
Normal file
25
app/helpers/admin/terms_of_service_helper.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
module TermsOfServiceHelper
|
||||
def tos_need_accepting?
|
||||
return false unless spree_user_signed_in?
|
||||
|
||||
return false if Spree::Config.enterprises_require_tos == false
|
||||
|
||||
return false if TermsOfServiceFile.current.nil?
|
||||
|
||||
!accepted_tos?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def accepted_tos?
|
||||
file_uploaded_at = TermsOfServiceFile.updated_at
|
||||
|
||||
current_spree_user.terms_of_service_accepted_at.present? &&
|
||||
current_spree_user.terms_of_service_accepted_at > file_uploaded_at &&
|
||||
current_spree_user.terms_of_service_accepted_at < DateTime.now
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,7 +9,7 @@ module AngularFormHelper
|
||||
text, value = option_text_and_value(element).map(&:to_s)
|
||||
%(<option value="#{ERB::Util.html_escape(value)}"\
|
||||
#{html_attributes}>#{ERB::Util.html_escape(text)}</option>)
|
||||
end.join("\n").html_safe
|
||||
end.join("\n").html_safe # rubocop:disable Rails/OutputSafety
|
||||
end
|
||||
|
||||
def ng_options_from_collection_for_select(collection, value_method, text_method, angular_field)
|
||||
|
||||
@@ -10,7 +10,7 @@ module ApplicationHelper
|
||||
|
||||
return "" unless obj && obj.errors[method].present?
|
||||
|
||||
errors = obj.errors[method].map { |err| h(err) }.join('<br />').html_safe
|
||||
errors = obj.errors[method].map { |err| h(err) }.join('<br />').html_safe # rubocop:disable Rails/OutputSafety
|
||||
|
||||
if options[:standalone]
|
||||
content_tag(
|
||||
@@ -36,7 +36,7 @@ module ApplicationHelper
|
||||
hreflang: locale.to_s.gsub("_", "-").downcase,
|
||||
href: "#{request.protocol}#{request.host_with_port}/locales/#{locale}"
|
||||
)
|
||||
end.join("\n").html_safe
|
||||
end.join("\n").html_safe # rubocop:disable Rails/OutputSafety
|
||||
end
|
||||
|
||||
def ng_form_for(name, *args, &)
|
||||
|
||||
@@ -5,7 +5,9 @@ module ReportsHelper
|
||||
order_cycles.map do |oc|
|
||||
orders_open_at = oc.orders_open_at&.to_fs(:short) || 'NA'
|
||||
orders_close_at = oc.orders_close_at&.to_fs(:short) || 'NA'
|
||||
# rubocop:disable Rails/OutputSafety
|
||||
["#{oc.name} (#{orders_open_at} - #{orders_close_at})".html_safe, oc.id]
|
||||
# rubocop:enable Rails/OutputSafety
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -20,6 +20,6 @@ module SharedHelper
|
||||
end
|
||||
|
||||
def current_shop_products_path
|
||||
"#{main_app.enterprise_shop_path(current_distributor)}#/shop"
|
||||
"#{main_app.enterprise_shop_path(current_distributor)}#/shop_panel"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,7 +45,7 @@ module ShopHelper
|
||||
end
|
||||
|
||||
def shopfront_closed_message?(order_cycles)
|
||||
no_open_order_cycles?(order_cycles) && \
|
||||
no_open_order_cycles?(order_cycles) &&
|
||||
current_distributor.preferred_shopfront_closed_message.present?
|
||||
end
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@ module Spree
|
||||
obj = object.respond_to?(:errors) ? object : instance_variable_get("@#{object}")
|
||||
|
||||
if obj && obj.errors[method].present?
|
||||
# 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')
|
||||
else
|
||||
''
|
||||
@@ -110,12 +112,12 @@ module Spree
|
||||
|
||||
object.preferences.keys.map { |key|
|
||||
preference_label = form.label("preferred_#{key}",
|
||||
Spree.t(key.to_s.gsub("_from_list", "")) + ": ").html_safe
|
||||
Spree.t(key.to_s.gsub("_from_list", "")) + ": ")
|
||||
preference_field = preference_field_for(
|
||||
form,
|
||||
"preferred_#{key}",
|
||||
{ type: object.preference_type(key) }, object
|
||||
).html_safe
|
||||
)
|
||||
{ label: preference_label, field: preference_field }
|
||||
}
|
||||
end
|
||||
|
||||
@@ -98,7 +98,9 @@ module Spree
|
||||
options[:class] = (options[:class].to_s + " icon_link with-tip #{icon_name}").strip
|
||||
options[:class] += ' no-text' if options[:no_text]
|
||||
options[:title] = text if options[:no_text]
|
||||
# rubocop:disable Rails/OutputSafety
|
||||
text = options[:no_text] ? '' : raw("<span class='text'>#{text}</span>")
|
||||
# rubocop:enable Rails/OutputSafety
|
||||
options.delete(:no_text)
|
||||
link_to(text, url, options)
|
||||
end
|
||||
@@ -131,14 +133,14 @@ module Spree
|
||||
if html_options[:icon]
|
||||
html_options[:class] += " #{html_options[:icon]}"
|
||||
end
|
||||
link_to(text_for_button_link(text, html_options), url, html_options)
|
||||
link_to(text, url, html_options)
|
||||
end
|
||||
end
|
||||
|
||||
def text_for_button_link(text, _html_options)
|
||||
s = ''
|
||||
s << text
|
||||
raw(s)
|
||||
raw(s) # rubocop:disable Rails/OutputSafety
|
||||
end
|
||||
|
||||
def configurations_sidebar_menu_item(link_text, url, options = {})
|
||||
|
||||
@@ -7,7 +7,7 @@ module Spree
|
||||
links = []
|
||||
links << cancel_event_link if @order.can_cancel?
|
||||
links << resume_event_link if @order.can_resume?
|
||||
links.join(' ').html_safe
|
||||
links.join(' ').html_safe # rubocop:disable Rails/OutputSafety
|
||||
end
|
||||
|
||||
def line_item_shipment_price(line_item, quantity)
|
||||
|
||||
@@ -31,7 +31,7 @@ module Spree
|
||||
out = ''
|
||||
out << fields.hidden_field(:_destroy) unless fields.object.new_record?
|
||||
out << (link_to icon('icon-remove'), "#", class: 'remove')
|
||||
out.html_safe
|
||||
out.html_safe # rubocop:disable Rails/OutputSafety
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
28
app/jobs/connect_app_job.rb
Normal file
28
app/jobs/connect_app_job.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ConnectAppJob < ApplicationJob
|
||||
include CableReady::Broadcaster
|
||||
|
||||
def perform(app, token, channel: nil)
|
||||
url = "https://n8n.openfoodnetwork.org.uk/webhook/regen/connect-enterprise"
|
||||
event = "connect-app"
|
||||
enterprise = app.enterprise
|
||||
payload = {
|
||||
'@id': DfcBuilder.urls.enterprise_url(enterprise.id),
|
||||
access_token: token,
|
||||
}
|
||||
|
||||
response = WebhookDeliveryJob.perform_now(url, event, payload)
|
||||
app.update!(data: JSON.parse(response))
|
||||
|
||||
return unless channel
|
||||
|
||||
selector = "#edit_enterprise_#{enterprise.id} #connected-app-discover-regen"
|
||||
html = ApplicationController.render(
|
||||
partial: "admin/enterprises/form/connected_apps",
|
||||
locals: { enterprise: },
|
||||
)
|
||||
|
||||
cable_ready[channel].morph(selector:, html:).broadcast
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'order_management/subscriptions/summarizer'
|
||||
|
||||
# Confirms orders of unconfirmed proxy orders in recently closed Order Cycles
|
||||
class SubscriptionConfirmJob < ApplicationJob
|
||||
def perform
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'order_management/subscriptions/summarizer'
|
||||
|
||||
class SubscriptionPlacementJob < ApplicationJob
|
||||
def perform
|
||||
proxy_orders.each do |proxy_order|
|
||||
|
||||
@@ -46,5 +46,7 @@ class WebhookDeliveryJob < ApplicationJob
|
||||
# Raise a failed request error and let job runner handle retrying.
|
||||
# In theory, only 5xx errors should be retried, but who knows.
|
||||
raise FailedWebhookRequestError, response.status.to_s unless response.success?
|
||||
|
||||
response.body
|
||||
end
|
||||
end
|
||||
|
||||
11
app/models/connected_app.rb
Normal file
11
app/models/connected_app.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# An enterprise can be connected to other apps.
|
||||
#
|
||||
# Here we store keys and links to access the app.
|
||||
class ConnectedApp < ApplicationRecord
|
||||
belongs_to :enterprise
|
||||
|
||||
scope :connecting, -> { where(data: nil) }
|
||||
scope :ready, -> { where.not(data: nil) }
|
||||
end
|
||||
@@ -27,21 +27,24 @@ class ContentConfiguration < Spree::Preferences::Configuration
|
||||
default: I18n.t(:content_configuration_pricing_table)
|
||||
preference :producer_signup_case_studies_html, :text,
|
||||
default: I18n.t(:content_configuration_case_studies)
|
||||
preference :producer_signup_detail_html, :text, default: I18n.t(:content_configuration_detail)
|
||||
preference :producer_signup_detail_html, :text,
|
||||
default: I18n.t(:content_configuration_detail)
|
||||
|
||||
# Hubs sign-up page
|
||||
preference :hub_signup_pricing_table_html, :text,
|
||||
default: I18n.t(:content_configuration_pricing_table)
|
||||
preference :hub_signup_case_studies_html, :text,
|
||||
default: I18n.t(:content_configuration_case_studies)
|
||||
preference :hub_signup_detail_html, :text, default: I18n.t(:content_configuration_detail)
|
||||
preference :hub_signup_detail_html, :text,
|
||||
default: I18n.t(:content_configuration_detail)
|
||||
|
||||
# Groups sign-up page
|
||||
preference :group_signup_pricing_table_html, :text,
|
||||
default: I18n.t(:content_configuration_pricing_table)
|
||||
preference :group_signup_case_studies_html, :text,
|
||||
default: I18n.t(:content_configuration_case_studies)
|
||||
preference :group_signup_detail_html, :text, default: I18n.t(:content_configuration_detail)
|
||||
preference :group_signup_detail_html, :text,
|
||||
default: I18n.t(:content_configuration_detail)
|
||||
|
||||
# Main URLs
|
||||
preference :menu_1, :boolean, default: true
|
||||
|
||||
@@ -62,6 +62,7 @@ class Enterprise < ApplicationRecord
|
||||
has_many :tag_rules, dependent: :destroy
|
||||
has_one :stripe_account, dependent: :destroy
|
||||
has_many :vouchers
|
||||
has_many :connected_apps, dependent: :destroy
|
||||
has_one :custom_tab, dependent: :destroy
|
||||
|
||||
delegate :latitude, :longitude, :city, :state_name, to: :address
|
||||
|
||||
@@ -30,4 +30,8 @@ class Invoice < ApplicationRecord
|
||||
def display_number
|
||||
"#{order.distributor.id}-#{number}"
|
||||
end
|
||||
|
||||
def previous_invoice
|
||||
order.invoices.where("id < ?", id).first
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ class Invoice
|
||||
include ::ActionView::Helpers::NumberHelper
|
||||
attr_reader :invoice
|
||||
|
||||
delegate :display_number, :data, to: :invoice
|
||||
delegate :display_number, :data, :previous_invoice, to: :invoice
|
||||
delegate :date, to: :invoice, prefix: true
|
||||
|
||||
FINALIZED_NON_SUCCESSFUL_STATES = %w(canceled returned).freeze
|
||||
|
||||
@@ -5,6 +5,10 @@ class Invoice
|
||||
class ShippingMethod < Invoice::DataPresenter::Base
|
||||
attributes :id, :name, :require_ship_address
|
||||
invoice_generation_attributes :id
|
||||
|
||||
def category
|
||||
I18n.t "invoice_shipping_category_#{require_ship_address ? 'delivery' : 'pickup'}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/localized_number'
|
||||
require 'concerns/adjustment_scopes'
|
||||
|
||||
# Adjustments represent a change to the +item_total+ of an Order. Each adjustment
|
||||
# has an +amount+ that can be either positive or negative.
|
||||
|
||||
@@ -135,7 +135,7 @@ module Spree
|
||||
|
||||
# Enable cache
|
||||
preference :enable_products_cache?, :boolean,
|
||||
default: (Rails.env.production? || Rails.env.staging?)
|
||||
default: Rails.env.production? || Rails.env.staging?
|
||||
|
||||
# Available units
|
||||
preference :available_units, :string, default: "g,kg,T,mL,L,kL"
|
||||
|
||||
@@ -6,12 +6,6 @@ module Spree
|
||||
|
||||
validates :name, :iso_name, presence: true
|
||||
|
||||
def self.cached_find_by(attrs)
|
||||
Rails.cache.fetch("countries/#{attrs.hash}", expires_in: 1.hour) do
|
||||
find_by(attrs)
|
||||
end
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
name <=> other.name
|
||||
end
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'concerns/payment_method_distributors'
|
||||
|
||||
module Spree
|
||||
class Gateway < PaymentMethod
|
||||
acts_as_taggable
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
require 'variant_units/variant_and_line_item_naming'
|
||||
|
||||
module Spree
|
||||
class LineItem < ApplicationRecord
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spree/order/checkout'
|
||||
require 'open_food_network/enterprise_fee_calculator'
|
||||
require 'open_food_network/feature_toggle'
|
||||
require 'open_food_network/tag_rule_applicator'
|
||||
|
||||
module Spree
|
||||
class Order < ApplicationRecord
|
||||
include OrderShipment
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'concerns/payment_method_distributors'
|
||||
|
||||
module Spree
|
||||
class PaymentMethod < ApplicationRecord
|
||||
include CalculatedAdjustments
|
||||
|
||||
@@ -70,31 +70,31 @@ module Spree
|
||||
end
|
||||
|
||||
def preference_getter_method(name)
|
||||
"preferred_#{name}".to_sym
|
||||
:"preferred_#{name}"
|
||||
end
|
||||
|
||||
def preference_setter_method(name)
|
||||
"preferred_#{name}=".to_sym
|
||||
:"preferred_#{name}="
|
||||
end
|
||||
|
||||
def prefers_getter_method(name)
|
||||
"prefers_#{name}?".to_sym
|
||||
:"prefers_#{name}?"
|
||||
end
|
||||
|
||||
def prefers_setter_method(name)
|
||||
"prefers_#{name}=".to_sym
|
||||
:"prefers_#{name}="
|
||||
end
|
||||
|
||||
def preference_default_getter_method(name)
|
||||
"preferred_#{name}_default".to_sym
|
||||
:"preferred_#{name}_default"
|
||||
end
|
||||
|
||||
def preference_type_getter_method(name)
|
||||
"preferred_#{name}_type".to_sym
|
||||
:"preferred_#{name}_type"
|
||||
end
|
||||
|
||||
def preference_description_getter_method(name)
|
||||
"preferred_#{name}_description".to_sym
|
||||
:"preferred_#{name}_description"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/property_merge'
|
||||
require 'concerns/product_stock'
|
||||
|
||||
# PRODUCTS
|
||||
# Products represent an entity for sale in a store.
|
||||
@@ -189,7 +188,7 @@ module Spree
|
||||
.with_permission(:add_to_order_cycle)
|
||||
.where(enterprises: { is_primary_producer: true })
|
||||
.pluck(:parent_id)
|
||||
return where('spree_products.supplier_id IN (?)', [enterprise.id] | permitted_producer_ids)
|
||||
where('spree_products.supplier_id IN (?)', [enterprise.id] | permitted_producer_ids)
|
||||
}
|
||||
|
||||
scope :active, lambda { where("spree_products.deleted_at IS NULL") }
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/enterprise_fee_calculator'
|
||||
require 'variant_units/variant_and_line_item_naming'
|
||||
require 'concerns/variant_stock'
|
||||
require 'spree/localized_number'
|
||||
|
||||
module Spree
|
||||
|
||||
43
app/queries/admin/enterprise_roles_query.rb
Normal file
43
app/queries/admin/enterprise_roles_query.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class EnterpriseRolesQuery
|
||||
class << self
|
||||
def query
|
||||
enterprise_roles = query_enterprise_roles
|
||||
users = query_users
|
||||
enterprises = query_enterprises
|
||||
|
||||
[enterprise_roles, users, enterprises]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def query_enterprise_roles
|
||||
EnterpriseRole.joins(:user, :enterprise).order('spree_users.email ASC').
|
||||
pluck(:id, :user_id, :enterprise_id, 'spree_users.email', 'enterprises.name').
|
||||
map do |data|
|
||||
id, user_id, enterprise_id, user_email, enterprise_name = data
|
||||
|
||||
{ id:, user_id:, enterprise_id:, user_email:, enterprise_name: }
|
||||
end
|
||||
end
|
||||
|
||||
def query_users
|
||||
Spree::User.order(:email).pluck(:id, :email).map do |data|
|
||||
id, email = data
|
||||
|
||||
{ id:, email: }
|
||||
end
|
||||
end
|
||||
|
||||
def query_enterprises
|
||||
Enterprise.order(:name).pluck(:id, :name).map do |data|
|
||||
id, name = data
|
||||
|
||||
{ id:, name: }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
53
app/reflexes/admin/connected_app_reflex.rb
Normal file
53
app/reflexes/admin/connected_app_reflex.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class ConnectedAppReflex < ApplicationReflex
|
||||
def create
|
||||
authorize! :admin, enterprise
|
||||
|
||||
app = ConnectedApp.create!(enterprise_id: enterprise.id)
|
||||
|
||||
# Avoid race condition by sending before enqueuing job:
|
||||
broadcast_partial
|
||||
|
||||
ConnectAppJob.perform_later(
|
||||
app, current_user.spree_api_key,
|
||||
channel: SessionChannel.for_request(request),
|
||||
)
|
||||
morph :nothing
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize! :admin, enterprise
|
||||
|
||||
app = enterprise.connected_apps.first
|
||||
app.destroy
|
||||
|
||||
broadcast_partial
|
||||
|
||||
WebhookDeliveryJob.perform_later(
|
||||
app.data["destroy"],
|
||||
"disconnect-app",
|
||||
nil
|
||||
)
|
||||
morph :nothing
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def enterprise
|
||||
@enterprise ||= Enterprise.find(element.dataset.enterprise_id)
|
||||
end
|
||||
|
||||
def broadcast_partial
|
||||
selector = "#edit_enterprise_#{enterprise.id} #connected-app-discover-regen"
|
||||
html = ApplicationController.render(
|
||||
partial: "admin/enterprises/form/connected_apps",
|
||||
locals: { enterprise: },
|
||||
)
|
||||
|
||||
# Avoid race condition by sending before enqueuing job:
|
||||
cable_ready.morph(selector:, html:).broadcast
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,20 +6,20 @@ class ProductsReflex < ApplicationReflex
|
||||
before_reflex :init_filters_params, :init_pagination_params
|
||||
|
||||
def fetch
|
||||
fetch_and_render_products
|
||||
fetch_and_render_products_with_flash
|
||||
end
|
||||
|
||||
def change_per_page
|
||||
@per_page = element.value.to_i
|
||||
@page = 1
|
||||
|
||||
fetch_and_render_products
|
||||
fetch_and_render_products_with_flash
|
||||
end
|
||||
|
||||
def filter
|
||||
@page = 1
|
||||
|
||||
fetch_and_render_products
|
||||
fetch_and_render_products_with_flash
|
||||
end
|
||||
|
||||
def clear_search
|
||||
@@ -28,7 +28,7 @@ class ProductsReflex < ApplicationReflex
|
||||
@category_id = nil
|
||||
@page = 1
|
||||
|
||||
fetch_and_render_products
|
||||
fetch_and_render_products_with_flash
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
@@ -46,6 +46,34 @@ class ProductsReflex < ApplicationReflex
|
||||
render_products_form_with_flash
|
||||
end
|
||||
|
||||
def delete_product
|
||||
id = current_id_from_element(element)
|
||||
product = product_finder(id).find_product
|
||||
authorize! :delete, product
|
||||
|
||||
if product.destroy
|
||||
flash[:success] = I18n.t('admin.products_v3.delete_product.success')
|
||||
else
|
||||
flash[:error] = I18n.t('admin.products_v3.delete_product.error')
|
||||
end
|
||||
|
||||
fetch_and_render_products_with_flash
|
||||
end
|
||||
|
||||
def delete_variant
|
||||
id = current_id_from_element(element)
|
||||
variant = Spree::Variant.active.find(id)
|
||||
authorize! :delete, variant
|
||||
|
||||
if VariantDeleter.new.delete(variant)
|
||||
flash[:success] = I18n.t('admin.products_v3.delete_variant.success')
|
||||
else
|
||||
flash[:error] = I18n.t('admin.products_v3.delete_variant.error')
|
||||
end
|
||||
|
||||
fetch_and_render_products_with_flash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_filters_params
|
||||
@@ -63,7 +91,7 @@ class ProductsReflex < ApplicationReflex
|
||||
@per_page = element.dataset.perpage || params[:_per_page] || 15
|
||||
end
|
||||
|
||||
def fetch_and_render_products
|
||||
def fetch_and_render_products_with_flash
|
||||
fetch_products
|
||||
render_products
|
||||
end
|
||||
@@ -74,7 +102,8 @@ class ProductsReflex < ApplicationReflex
|
||||
html: render(partial: "admin/products_v3/content",
|
||||
locals: { products: @products, pagy: @pagy, search_term: @search_term,
|
||||
producer_options: producers, producer_id: @producer_id,
|
||||
category_options: categories, category_id: @category_id })
|
||||
category_options: categories, category_id: @category_id,
|
||||
flashes: flash })
|
||||
).broadcast
|
||||
|
||||
cable_ready.replace_state(
|
||||
@@ -195,4 +224,12 @@ class ProductsReflex < ApplicationReflex
|
||||
params.permit(products: ::PermittedAttributes::Product.attributes)
|
||||
.to_h.with_indifferent_access
|
||||
end
|
||||
|
||||
def product_finder(id)
|
||||
ProductScopeQuery.new(current_user, { id: })
|
||||
end
|
||||
|
||||
def current_id_from_element(element)
|
||||
element.dataset.current_id
|
||||
end
|
||||
end
|
||||
|
||||
9
app/reflexes/user_reflex.rb
Normal file
9
app/reflexes/user_reflex.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class UserReflex < ApplicationReflex
|
||||
def accept_terms_of_services
|
||||
current_user.update(terms_of_service_accepted_at: DateTime.now)
|
||||
|
||||
morph "#banner-container", ""
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,10 @@ class DefaultCountry
|
||||
end
|
||||
|
||||
def self.country
|
||||
Spree::Country.cached_find_by(iso: ENV.fetch("DEFAULT_COUNTRY_CODE",
|
||||
nil)) || Spree::Country.first
|
||||
# Changing ENV requires restarting the process.
|
||||
iso = ENV.fetch("DEFAULT_COUNTRY_CODE", nil)
|
||||
|
||||
# When ENV changes on restart, this cache will be reset as well.
|
||||
@country ||= Spree::Country.find_by(iso:) || Spree::Country.first
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/tag_rule_applicator'
|
||||
|
||||
class OrderAvailablePaymentMethods
|
||||
attr_reader :order, :customer
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/tag_rule_applicator'
|
||||
|
||||
class OrderAvailableShippingMethods
|
||||
attr_reader :order, :customer
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'order_management/subscriptions/proxy_order_syncer'
|
||||
|
||||
class OrderCycleClone
|
||||
def initialize(order_cycle)
|
||||
@original_order_cycle = order_cycle
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
require 'open_food_network/permissions'
|
||||
require 'open_food_network/order_cycle_form_applicator'
|
||||
require 'order_management/subscriptions/proxy_order_syncer'
|
||||
|
||||
class OrderCycleForm
|
||||
def initialize(order_cycle, order_cycle_params, user)
|
||||
|
||||
@@ -118,7 +118,7 @@ module Sets
|
||||
# Copy any variant errors to product
|
||||
variant&.errors&.each do |error|
|
||||
# The name is namespaced to avoid confusion with product attrs of same name.
|
||||
product.errors.add("variant_#{error.attribute}".to_sym, error.message)
|
||||
product.errors.add(:"variant_#{error.attribute}", error.message)
|
||||
end
|
||||
variant&.errors.blank?
|
||||
end
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'open_food_network/tag_rule_applicator'
|
||||
|
||||
# Lists available order cycles for a given customer in a given distributor
|
||||
module Shop
|
||||
class OrderCyclesList
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
# It contains all of our logic for creating and naming option values (which are associated
|
||||
# with both models) and methods for printing human readable "names" for instances of these models.
|
||||
|
||||
require 'variant_units/option_value_namer'
|
||||
|
||||
module VariantUnits
|
||||
module VariantAndLineItemNaming
|
||||
def options_text
|
||||
|
||||
8
app/views/admin/_terms_of_service_banner.html.haml
Normal file
8
app/views/admin/_terms_of_service_banner.html.haml
Normal file
@@ -0,0 +1,8 @@
|
||||
#banner-container
|
||||
.terms-of-service-banner.form-actions
|
||||
.column-left
|
||||
%p= t("admin.terms_of_service_have_been_updated_html", tos_link: link_to(t("admin.terms_of_service"), TermsOfServiceFile.current_url, target: "_blank"))
|
||||
.column-right
|
||||
%button{ data: { reflex: "click->user#accept_terms_of_services" } }
|
||||
= t("admin.accept_terms_of_service")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
= admin_inject_enterprise_roles(@enterprise_roles)
|
||||
= admin_inject_users(@users)
|
||||
= admin_inject_enterprises(@my_enterprises, @all_enterprises)
|
||||
|
||||
= admin_inject_json('ofn.admin', 'enterpriseRoles', @enterprise_roles)
|
||||
= admin_inject_json('ofn.admin', 'users', @users)
|
||||
= admin_inject_json('ofn.admin', 'my_enterprises', @my_enterprises) + admin_inject_json('ofn.admin', 'all_enterprises', @all_enterprises)
|
||||
|
||||
@@ -9,12 +9,6 @@
|
||||
%fieldset.alpha.no-border-bottom{ id: "#{item[:name]}_panel", data: { "tabs-and-panels-target": "panel" }}
|
||||
%legend= t(".#{ item[:name] }.legend")
|
||||
|
||||
- when 'vouchers'
|
||||
- if feature?(:vouchers, spree_current_user, @enterprise)
|
||||
%fieldset.alpha.no-border-bottom{ id: "#{item[:name]}_panel", data: { "tabs-and-panels-target": "panel" }}
|
||||
%legend= t(".#{ item[:form_name] || item[:name] }.legend")
|
||||
= render "admin/enterprises/form/#{ item[:form_name] || item[:name] }", f: f
|
||||
|
||||
- else
|
||||
%fieldset.alpha.no-border-bottom{ id: "#{item[:name]}_panel", data: { "tabs-and-panels-target": "panel" }}
|
||||
%legend= t(".#{ item[:form_name] || item[:name] }.legend")
|
||||
|
||||
31
app/views/admin/enterprises/form/_connected_apps.html.haml
Normal file
31
app/views/admin/enterprises/form/_connected_apps.html.haml
Normal file
@@ -0,0 +1,31 @@
|
||||
- enterprise ||= f.object
|
||||
#connected-app-discover-regen
|
||||
.connected-app__head
|
||||
%div
|
||||
%h3= t ".title"
|
||||
%p= t ".tagline"
|
||||
%div
|
||||
- if enterprise.connected_apps.empty?
|
||||
%button{ data: {reflex: "click->Admin::ConnectedApp#create", enterprise_id: enterprise.id} }
|
||||
= t ".enable"
|
||||
- elsif enterprise.connected_apps.connecting.present?
|
||||
%button{ disabled: true }
|
||||
%i.spinner.fa.fa-spin.fa-circle-o-notch
|
||||
|
||||
= t ".loading"
|
||||
- else
|
||||
%button{ data: {reflex: "click->Admin::ConnectedApp#destroy", enterprise_id: enterprise.id} }
|
||||
= t ".disable"
|
||||
|
||||
.connected-app__connection
|
||||
- if enterprise.connected_apps.ready.present?
|
||||
.connected-app__note
|
||||
- link = enterprise.connected_apps[0].data["link"]
|
||||
%p= t ".note"
|
||||
%div
|
||||
%a{ href: link, target: "_blank", class: "button secondary" }
|
||||
= t ".link_label"
|
||||
|
||||
%hr
|
||||
.connected-app__description
|
||||
= t ".description_html"
|
||||
@@ -2,7 +2,7 @@
|
||||
.alpha.three.columns
|
||||
= f.label :logo
|
||||
%br
|
||||
100 x 100 pixels
|
||||
= t('.logo_size')
|
||||
.omega.eight.columns
|
||||
%img{ class: 'image-field-group__preview-image', ng: { src: '{{ Enterprise.logo.thumb }}', if: 'Enterprise.logo' } }
|
||||
%br
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#products-content
|
||||
.container
|
||||
.sixteen.columns
|
||||
= render partial: 'admin/shared/flashes', locals: { flashes: } if defined? flashes
|
||||
= render partial: 'filters', locals: { search_term: search_term,
|
||||
producer_id: producer_id,
|
||||
producer_options: producer_options,
|
||||
|
||||
16
app/views/admin/products_v3/_delete_modal.html.haml
Normal file
16
app/views/admin/products_v3/_delete_modal.html.haml
Normal file
@@ -0,0 +1,16 @@
|
||||
-# object_type can be 'variant' or 'product'
|
||||
- base_translation_key = ".delete_#{object_type}_modal"
|
||||
- delete_modal = ConfirmModalComponent.new(id: "#{object_type}-delete-modal",
|
||||
confirm_button_text: t("#{base_translation_key}.confirmation_text"),
|
||||
cancel_button_text: t("#{base_translation_key}.cancellation_text"),
|
||||
confirm_button_class: :red,
|
||||
actions_alignment_class: 'justify-end',
|
||||
confirm_reflexes: "click->products#delete_#{object_type}",
|
||||
confirm_actions: "click->modal#close",
|
||||
)
|
||||
= render delete_modal do
|
||||
%h2.margin-bottom-20.black-text
|
||||
= t("#{base_translation_key}.heading")
|
||||
%p
|
||||
= t("#{base_translation_key}.prompt")
|
||||
.margin-bottom-50
|
||||
@@ -5,17 +5,6 @@
|
||||
'data-bulk-form-error-value': defined?(error_counts),
|
||||
} do |form|
|
||||
= render(partial: "admin/shared/flashes", locals: { flashes: }) if defined? flashes
|
||||
%fieldset.form-actions{ class: ("hidden" unless defined?(error_counts)), 'data-bulk-form-target': "actions" }
|
||||
.container
|
||||
.status.eleven.columns
|
||||
.modified_summary{ 'data-bulk-form-target': "changedSummary", 'data-translation-key': 'admin.products_v3.table.changed_summary'}
|
||||
- if defined?(error_counts)
|
||||
.error_summary
|
||||
-# X products were saved correctly, but Y products could not be saved correctly. Please review errors and try again
|
||||
= t('.error_summary.saved', count: error_counts[:saved]) + t('.error_summary.invalid', count: error_counts[:invalid])
|
||||
.form-buttons.five.columns
|
||||
= form.submit t('.reset'), type: :reset, class: "medium", 'data-reflex': 'click->products#fetch'
|
||||
= form.submit t('.save'), class: "medium"
|
||||
%table.products
|
||||
%col{ width:"15%" }
|
||||
%col{ width:"5%", style: "max-width:5em" }
|
||||
@@ -28,6 +17,20 @@
|
||||
%col{ width:"5%", style: "max-width:5em" }
|
||||
%col{ width:"5%", style: "max-width:5em" }
|
||||
%thead
|
||||
%tr
|
||||
%td.form-actions-wrapper{ colspan: 10 }
|
||||
.form-actions-wrapper2
|
||||
%fieldset.form-actions{ class: ("hidden" unless defined?(error_counts)), 'data-bulk-form-target': "actions" }
|
||||
.container
|
||||
.status
|
||||
.modified_summary{ 'data-bulk-form-target': "changedSummary", 'data-translation-key': 'admin.products_v3.table.changed_summary'}
|
||||
- if defined?(error_counts)
|
||||
.error_summary
|
||||
-# X products were saved correctly, but Y products could not be saved correctly. Please review errors and try again
|
||||
= t('.error_summary.saved', count: error_counts[:saved]) + t('.error_summary.invalid', count: error_counts[:invalid])
|
||||
.form-buttons
|
||||
= form.submit t('.reset'), type: :reset, class: "medium", 'data-reflex': 'click->products#fetch'
|
||||
= form.submit t('.save'), class: "medium"
|
||||
%tr
|
||||
%th.align-left.with-input= t('admin.products_page.columns.name')
|
||||
%th.align-right= t('admin.products_page.columns.sku')
|
||||
@@ -70,6 +73,10 @@
|
||||
= render(VerticalEllipsisMenu::Component.new) do
|
||||
= link_to t('admin.products_page.actions.edit'), edit_admin_product_path(product)
|
||||
= link_to t('admin.products_page.actions.clone'), clone_admin_product_path(product)
|
||||
%a{ "data-controller": "modal-link", "data-action": "click->modal-link#setModalDataSetOnConfirm click->modal-link#open",
|
||||
"data-modal-link-target-value": "product-delete-modal", "class": "delete",
|
||||
"data-modal-link-modal-dataset-value": {'data-current-id': product.id}.to_json }
|
||||
= t('admin.products_page.actions.delete')
|
||||
|
||||
- product.variants.each_with_index do |variant, variant_index|
|
||||
= form.fields_for("products][#{product_index}][variants_attributes][", variant, variant_index:) do |variant_form|
|
||||
@@ -108,3 +115,8 @@
|
||||
%td.align-right
|
||||
= render(VerticalEllipsisMenu::Component.new) do
|
||||
= link_to t('admin.products_page.actions.edit'), edit_admin_product_variant_path(product, variant)
|
||||
- if product.variants.size > 1
|
||||
%a{ "data-controller": "modal-link", "data-action": "click->modal-link#setModalDataSetOnConfirm click->modal-link#open",
|
||||
"data-modal-link-target-value": "variant-delete-modal", "class": "delete",
|
||||
"data-modal-link-modal-dataset-value": {'data-current-id': variant.id}.to_json }
|
||||
= t('admin.products_page.actions.delete')
|
||||
|
||||
@@ -17,3 +17,5 @@
|
||||
.spinner
|
||||
= t('.loading')
|
||||
#products-content
|
||||
- %w[product variant].each do |object_type|
|
||||
= render partial: 'delete_modal', locals: { object_type: }
|
||||
|
||||
@@ -28,4 +28,3 @@
|
||||
.alpha.two.columns= label_tag nil, t(:report_columns)
|
||||
.omega.fourteen.columns
|
||||
= render MultipleCheckedSelectComponent.new(name: "fields_to_show", options: @report.available_headers, selected: @rendering_options.options[:fields_to_show])
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
.side_menu#side_menu
|
||||
- if @enterprise
|
||||
- enterprise_side_menu_items(@enterprise).each do |item|
|
||||
- next if !item[:show] || (item[:name] == 'vouchers' && !feature?(:vouchers, spree_current_user, @enterprise))
|
||||
%a.menu_item{ href: item[:href] || "##{item[:name]}_panel", id: item[:name], data: { action: "tabs-and-panels#changeActivePanel tabs-and-panels#changeActiveTab", "tabs-and-panels-target": "tab" }, class: item[:selected] }
|
||||
- next if !item[:show]
|
||||
%a.menu_item{ href: item[:href] || "##{item[:name]}_panel", data: { action: "tabs-and-panels#activate", "tabs-and-panels-target": "tab", test: "link_for_#{item[:name]}" }, class: item[:selected] }
|
||||
%i{ class: item[:icon_class] }
|
||||
%span= t(".enterprise.#{item[:name] }")
|
||||
- else
|
||||
- enterprise_group_side_menu_items.each do |item|
|
||||
%a.menu_item{ href: "##{item[:name]}_panel", class: item[:selected], id: item[:name], data: { action: "tabs-and-panels#changeActivePanel tabs-and-panels#changeActiveTab", "tabs-and-panels-target": "tab" } }
|
||||
%a.menu_item{ href: "##{item[:name]}_panel", class: item[:selected], data: { action: "tabs-and-panels#activate", "tabs-and-panels-target": "tab", test: "link_for_#{item[:name]}" } }
|
||||
%i{ class: item[:icon_class] }
|
||||
%span= t(".enterprise_group.#{item[:name] }")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.medium-6#checkout-payment-methods
|
||||
- if feature?(:vouchers, spree_current_user, @order.distributor) && @order.distributor.vouchers.present?
|
||||
- if @order.distributor.vouchers.present?
|
||||
%div.checkout-substep
|
||||
= render partial: "checkout/voucher_section", locals: { order: @order, voucher_adjustment: @order.voucher_adjustments.first }
|
||||
|
||||
|
||||
@@ -37,20 +37,20 @@
|
||||
- @grouped_line_items.each_pair do |product_and_full_name, line_items|
|
||||
%tr
|
||||
%td
|
||||
#{line_items.first.variant.sku}
|
||||
= line_items.first.variant.sku
|
||||
- if @distributors_pickup_times.many?
|
||||
%td
|
||||
#{raw(line_items.first.product.supplier.name)}
|
||||
= line_items.first.product.supplier.name
|
||||
%td
|
||||
#{raw(product_and_full_name)}
|
||||
= product_and_full_name
|
||||
%td.text-right
|
||||
#{line_items.sum(&:quantity)}
|
||||
= line_items.sum(&:quantity)
|
||||
%td.text-right
|
||||
#{line_items.first.single_money}
|
||||
= line_items.first.single_money
|
||||
%td.text-right
|
||||
#{Spree::Money.new(line_items.sum(&:total), currency: line_items.first.currency) }
|
||||
= Spree::Money.new(line_items.sum(&:total), currency: line_items.first.currency)
|
||||
%td.tax.text-right
|
||||
#{Spree::Money.new(line_items.sum(&:included_tax), currency: line_items.first.currency) }
|
||||
= Spree::Money.new(line_items.sum(&:included_tax), currency: line_items.first.currency)
|
||||
%tr.total-row
|
||||
%td
|
||||
- if @distributors_pickup_times.many?
|
||||
@@ -59,9 +59,9 @@
|
||||
%td
|
||||
%td
|
||||
%td.text-right
|
||||
#{@total}
|
||||
= @total
|
||||
%td.text-right
|
||||
#{@tax_total}
|
||||
= @tax_total
|
||||
- if @customer_line_items
|
||||
%p
|
||||
= t :producer_mail_order_customer_text
|
||||
@@ -85,33 +85,34 @@
|
||||
- @customer_line_items.each do |line_item|
|
||||
%tr
|
||||
%td
|
||||
#{line_item[:sku]}
|
||||
= line_item[:sku]
|
||||
- if @distributors_pickup_times.many?
|
||||
%td
|
||||
#{raw(line_item[:supplier_name])}
|
||||
= line_item[:supplier_name]
|
||||
%td
|
||||
#{raw(line_item[:product_and_full_name])}
|
||||
= line_item[:product_and_full_name]
|
||||
%td.text-right
|
||||
#{line_item[:quantity]}
|
||||
= line_item[:quantity]
|
||||
%td
|
||||
#{raw(line_item[:first_name])}
|
||||
= line_item[:first_name]
|
||||
%td
|
||||
#{raw(line_item[:last_name])}
|
||||
= line_item[:last_name]
|
||||
%p
|
||||
= t :producer_mail_text_after
|
||||
%p
|
||||
#{t(:producer_mail_signoff)},
|
||||
= t(:producer_mail_signoff)
|
||||
,
|
||||
%em
|
||||
%p
|
||||
#{@coordinator.name}
|
||||
= @coordinator.name
|
||||
%p
|
||||
%br
|
||||
#{@coordinator.address.address1}
|
||||
= @coordinator.address.address1
|
||||
%br
|
||||
#{@coordinator.address.city}
|
||||
= @coordinator.address.city
|
||||
%br
|
||||
#{@coordinator.address.zipcode}
|
||||
= @coordinator.address.zipcode
|
||||
%p
|
||||
#{@coordinator.phone}
|
||||
= @coordinator.phone
|
||||
%p
|
||||
#{@coordinator.contact.email}
|
||||
= @coordinator.contact.email
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- if ContentConfig.home_page_alert_html.present?
|
||||
.alert-cta
|
||||
%h6= raw ContentConfig.home_page_alert_html
|
||||
%h6= sanitize(ContentConfig.home_page_alert_html, scrubber: TrixScrubber.new)
|
||||
|
||||
- else
|
||||
= render "shared/register_call"
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
%p
|
||||
= t('.require_login_link_html', login: ('<a data-action="click->login-modal#call">' + t('.login') + '</a>').html_safe)
|
||||
%p
|
||||
= t('.require_login_2_html', contact: link_to(t('.contact'), '#contact'), enterprise: current_distributor.name)
|
||||
= t('.require_login_2_html', contact: link_to(t('.contact'), '#contact_panel', data: { action: "tabs-and-panels#activate" }), enterprise: current_distributor.name)
|
||||
- else
|
||||
= t('.require_customer_html', contact: link_to(t('.contact'), '#contact'), enterprise: current_distributor.name)
|
||||
= t('.require_customer_html', contact: link_to(t('.contact'), '#contact_panel', data: { action: "tabs-and-panels#activate" }), enterprise: current_distributor.name)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
- if (@order&.distributor || current_distributor) == current_distributor
|
||||
|
||||
#shop-tabs{"data-controller": "tabs-and-panels shop-tabs", "data-tabs-and-panels-class-name-value": "selected"}
|
||||
#shop-tabs{"data-controller": "tabs-and-panels", "data-action": "orderCycleSelected@window->tabs-and-panels#activateDefaultPanel", "data-tabs-and-panels-class-name-value": "selected"}
|
||||
.tab-buttons
|
||||
.flex.row
|
||||
.columns.small-12.large-8
|
||||
- shop_tabs.each do |tab|
|
||||
.page
|
||||
%a{ id: tab[:name], href: "##{tab[:name]}_panel", data: { action: "tabs-and-panels#changeActivePanel tabs-and-panels#changeActiveTab", "tabs-and-panels-target": "tab" }, class: ("selected" if tab[:default]) }=tab[:title]
|
||||
%a{ href: "##{tab[:name]}_panel", data: { action: "tabs-and-panels#activate", "tabs-and-panels-target": "tab" }, class: ("selected" if tab[:default]) }=tab[:title]
|
||||
.columns.large-4.show-for-large-up
|
||||
= render partial: "shopping_shared/order_cycles"
|
||||
- shop_tabs.each do |tab|
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
- if show_generate_invoice_button?(@order)
|
||||
.alert-box.warning
|
||||
= t('.order_has_changed')
|
||||
|
||||
= render partial: 'spree/admin/shared/order_page_title'
|
||||
= render partial: 'spree/admin/shared/order_tabs', locals: { current: 'Invoices' }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%h5.inline-header
|
||||
= "#{raw(line_item.variant.product.name)}"
|
||||
= line_item.variant.product.name
|
||||
- unless line_item.variant.product.name.include? line_item.name_to_display
|
||||
%span= "- #{raw(line_item.name_to_display)}"
|
||||
%span= "- #{line_item.name_to_display}"
|
||||
- if line_item.unit_price_price_and_unit
|
||||
= raw("(#{line_item.unit_price_price_and_unit})")
|
||||
= raw("(#{line_item.unit_price_price_and_unit})")
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
= render 'spree/shared/line_item_name', line_item: item
|
||||
%br
|
||||
%small
|
||||
%em= raw(item.variant.product.supplier.name)
|
||||
%em= item.variant.product.supplier.name
|
||||
%td{:align => "right"}
|
||||
= item.quantity
|
||||
%td{:align => "right"}
|
||||
@@ -28,7 +28,7 @@
|
||||
- taxable = adjustment.adjustable_type == "Spree::Shipment" ? adjustment.adjustable : adjustment
|
||||
%tr
|
||||
%td
|
||||
%strong= "#{raw(adjustment.label)}"
|
||||
%strong= adjustment.label
|
||||
%td{:align => "right"}
|
||||
1
|
||||
%td{:align => "right"}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
= render 'spree/shared/line_item_name', line_item: item
|
||||
%br
|
||||
%small
|
||||
%em= raw(item.variant.product.supplier.name)
|
||||
%em= item.variant.product.supplier.name
|
||||
%td{:align => "right"}
|
||||
= item.quantity
|
||||
%td{:align => "right"}
|
||||
@@ -33,7 +33,7 @@
|
||||
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
|
||||
%tr
|
||||
%td
|
||||
%strong= "#{raw(adjustment.label)}"
|
||||
%strong= adjustment.label
|
||||
%td{:align => "right"}
|
||||
%td{:align => "right"}
|
||||
%td{:align => "right"}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
= render 'spree/admin/orders/_invoice/line_item_name', line_item: item
|
||||
%br
|
||||
%small
|
||||
%em= raw(item.variant.product.supplier.name)
|
||||
%em= item.variant.product.supplier.name
|
||||
%td{:align => "right"}
|
||||
= item.quantity
|
||||
%td{:align => "right"}
|
||||
@@ -37,8 +37,8 @@
|
||||
= item.display_amount_with_adjustments_and_with_taxes
|
||||
%tr
|
||||
%td
|
||||
%strong= "#{t(:shipping)} "
|
||||
= "( #{t(:invoice_shipping_type)} #{raw(@order.shipping_method.name)} )"
|
||||
%strong= "#{@order.shipping_method.category} "
|
||||
= "(#{@order.shipping_method.name})"
|
||||
%td{:align => "right"}
|
||||
%td{:align => "right"}
|
||||
%td{:align => "right"}
|
||||
@@ -51,7 +51,7 @@
|
||||
- @order.checkout_adjustments(exclude: [:line_item, :shipment]).reverse_each do |adjustment|
|
||||
%tr
|
||||
%td
|
||||
%strong= "#{raw(adjustment.label)}"
|
||||
%strong= adjustment.label
|
||||
%td{:align => "right"}
|
||||
%td{:align => "right"}
|
||||
%td{:align => "right"}
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
%br
|
||||
= "#{t :invoice_number}:"
|
||||
= @order.display_number
|
||||
- if @order.previous_invoice.present?
|
||||
= "#{t :invoice_cancel_and_replace_invoice} #{ @order.previous_invoice.display_number}"
|
||||
%br
|
||||
= t :invoice_issued_on
|
||||
= l @order.invoice_date
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
= render 'enterprises_header'
|
||||
|
||||
- if @enterprises.empty?
|
||||
%div.sixteen.columns.alpha.list-item.red
|
||||
%div.sixteen.columns.alpha.list-item.warning
|
||||
%span.text.fifteen.columns.alpha
|
||||
= t "spree_admin_enterprises_none_text"
|
||||
%span.one.columns.omega
|
||||
%span.icon-remove-sign
|
||||
%a.sixteen.columns.alpha.button.bottom.red{ href: "#{main_app.new_admin_enterprise_path}" }
|
||||
%a.sixteen.columns.alpha.button.bottom.warning{ href: "#{main_app.new_admin_enterprise_path}" }
|
||||
= t "spree_admin_enterprises_none_create_a_new_enterprise"
|
||||
%span.icon-arrow-right
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
%div.sixteen.columns.alpha.list
|
||||
= render partial: 'enterprise_row', collection: @enterprises, as: :enterprise
|
||||
|
||||
%a.sixteen.columns.alpha.button.bottom.blue{ href: "#{main_app.admin_enterprises_path}" }
|
||||
%a.sixteen.columns.alpha.button.bottom{ href: "#{main_app.admin_enterprises_path}" }
|
||||
= t "spree_admin_overview_enterprises_footer"
|
||||
%span.icon-arrow-right
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
%div.header.sixteen.columns.alpha{ :class => "#{@enterprises.count > 0 ? "" : "red"}"}
|
||||
%div.header.sixteen.columns.alpha{ :class => "#{@enterprises.count > 0 ? "" : "warning"}"}
|
||||
%h3.thirteen.columns.alpha
|
||||
= t "spree_admin_overview_enterprises_header"
|
||||
- if @enterprises.any?
|
||||
- if spree_current_user.can_own_more_enterprises?
|
||||
%a.three.columns.omega.icon-plus.button.blue.white-bottom{ href: "#{main_app.new_admin_enterprise_path}" }
|
||||
%a.three.columns.omega.icon-plus.button.white-bottom{ href: "#{main_app.new_admin_enterprise_path}" }
|
||||
= t "spree_admin_enterprises_create_new"
|
||||
- else
|
||||
%a{ "ofn-with-tip" => t('.ofn_with_tip') }
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
- color_class = @order_cycle_count > 0 ? "blue" : "orange"
|
||||
- icon_class = @order_cycle_count > 0 ? "icon-ok-sign" : "icon-warning-sign"
|
||||
- color_class = "warning" unless @order_cycle_count.positive?
|
||||
- icon_class = @order_cycle_count.positive? ? "icon-ok-sign" : "icon-warning-sign"
|
||||
%div.dashboard_item.seven.columns.omega#order_cycles
|
||||
%div.header.sixteen.columns.alpha{class: color_class}
|
||||
%h3.ten.columns.alpha
|
||||
= t ".order_cycles"
|
||||
- if @order_cycle_count > 0
|
||||
%a.six.columns.omega.icon-plus.button.blue{ href: main_app.new_admin_order_cycle_path }
|
||||
- if @order_cycle_count.positive?
|
||||
%a.six.columns.omega.icon-plus.button{ href: main_app.new_admin_order_cycle_path }
|
||||
= t "spree_admin_enterprises_create_new"
|
||||
- else
|
||||
%a{ "ofn-with-tip" => t(".order_cycles_tip") }
|
||||
@@ -13,9 +13,9 @@
|
||||
%div.sixteen.columns.alpha.list
|
||||
%div.sixteen.columns.alpha.list-item{class: color_class}
|
||||
%span.thirteen.columns.alpha
|
||||
= t('.you_have_active', count: @order_cycle_count)
|
||||
= t(".you_have_active", count: @order_cycle_count)
|
||||
%span.three.columns.omega
|
||||
%span{class: icon_class}
|
||||
%a.sixteen.columns.alpha.button.bottom{ href: main_app.admin_order_cycles_path, class: color_class }
|
||||
= t ".manage_order_cycles"
|
||||
%span.icon-arrow-right
|
||||
%a.sixteen.columns.alpha.button.bottom{ href: main_app.admin_order_cycles_path, class: color_class }
|
||||
= t ".manage_order_cycles"
|
||||
%span.icon-arrow-right
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
- color_class = "warning" unless @product_count.positive?
|
||||
- icon_class = @product_count.positive? ? "icon-ok-sign" : "icon-remove-sign"
|
||||
%div.dashboard_item.seven.columns.alpha#products
|
||||
%div.header.sixteen.columns.alpha{ :class => "#{@product_count > 0 ? "" : "red"}"}
|
||||
%div.header.sixteen.columns.alpha{class: color_class}
|
||||
%h3.ten.columns.alpha
|
||||
= t "products"
|
||||
- if @product_count > 0
|
||||
%a.six.columns.omega.icon-plus.button.blue{ href: "#{new_admin_product_path}" }
|
||||
- if @product_count.positive?
|
||||
%a.six.columns.omega.icon-plus.button{ href: new_admin_product_path }
|
||||
= t "spree_admin_enterprises_create_new"
|
||||
- else
|
||||
%a{ "ofn-with-tip" => t(".products_tip") }
|
||||
= t "admin.whats_this"
|
||||
%div.sixteen.columns.alpha.list
|
||||
- if @product_count > 0
|
||||
%div.sixteen.columns.alpha.list-item
|
||||
%span.thirteen.columns.alpha
|
||||
= t(".active_products", count: @product_count )
|
||||
%span.three.columns.omega
|
||||
%span.icon-ok-sign
|
||||
%a.sixteen.columns.alpha.button.bottom.blue{ href: "#{admin_products_path}" }
|
||||
= t "spree_admin_enterprises_producers_manage_products"
|
||||
%span.icon-arrow-right
|
||||
- else
|
||||
%div.sixteen.columns.alpha.list-item.red
|
||||
%span.thirteen.columns.alpha
|
||||
= t(".active_products", count: @product_count )
|
||||
%span.three.columns.omega
|
||||
%span.icon-remove-sign
|
||||
%a.sixteen.columns.alpha.button.bottom.red{ href: "#{new_admin_product_path}" }
|
||||
= t "spree_admin_enterprises_create_new_product"
|
||||
%span.icon-arrow-right
|
||||
%div.sixteen.columns.alpha.list-item{class: color_class}
|
||||
%span.thirteen.columns.alpha
|
||||
= t(".active_products", count: @product_count)
|
||||
%span.three.columns.omega
|
||||
%span{class: icon_class}
|
||||
- if @product_count.positive?
|
||||
%a.sixteen.columns.alpha.button.bottom{ href: admin_products_path, class: color_class }
|
||||
= t "spree_admin_enterprises_producers_manage_products"
|
||||
%span.icon-arrow-right
|
||||
- else
|
||||
%a.sixteen.columns.alpha.button.bottom{ href: new_admin_product_path, class: color_class }
|
||||
= t "spree_admin_enterprises_create_new_product"
|
||||
%span.icon-arrow-right
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
- content_for :page_title do
|
||||
= t('dashboard')
|
||||
|
||||
- content_for :page_actions do
|
||||
= render 'admin/shared/user_guide_link'
|
||||
|
||||
|
||||
%div{ 'ng-app' => 'ofn.admin' }
|
||||
%h1{ :style => 'margin-bottom: 30px' }
|
||||
= t 'dashboard'
|
||||
|
||||
- if @enterprises.empty?
|
||||
|
||||
= render partial: "enterprises"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- content_for :sub_menu do
|
||||
%ul#sub_nav.inline-menu
|
||||
= tab :products
|
||||
= tab :products, :products_v3
|
||||
= tab :properties
|
||||
= tab :variant_overrides, url: main_app.admin_inventory_path, match_path: '/inventory'
|
||||
= tab :import, url: main_app.admin_product_import_path, match_path: '/product_import'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
= tab :overview, label: 'dashboard', url: spree.admin_dashboard_path, icon: 'icon-dashboard'
|
||||
= tab :products, :properties, :inventory, :product_import, :images, :variants, :product_properties, :group_buy_options, :seo, url: admin_products_path, icon: 'icon-th-large'
|
||||
= tab :products, :properties, :inventory, :product_import, :images, :variants, :product_properties, :group_buy_options, :seo, :products_v3, :variant_overrides, url: admin_products_path, icon: 'icon-th-large'
|
||||
= tab :order_cycles, url: main_app.admin_order_cycles_path, icon: 'icon-refresh'
|
||||
= tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path, icon: 'icon-shopping-cart'
|
||||
= tab :reports, url: main_app.admin_reports_path, icon: 'icon-file'
|
||||
@@ -8,4 +8,4 @@
|
||||
= tab :customers, url: main_app.admin_customers_path
|
||||
= tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups'
|
||||
- if can? :admin, Spree::User
|
||||
= tab(:users, url: spree.admin_users_path, icon: 'icon-user')
|
||||
= tab(:users, :enterprise_roles, url: spree.admin_users_path, icon: 'icon-user')
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
%span= yield :sidebar_title
|
||||
= yield :sidebar
|
||||
|
||||
= render "admin/terms_of_service_banner" if tos_need_accepting?
|
||||
|
||||
%script
|
||||
= raw "Spree.api_key = \"#{spree_current_user.try(:spree_api_key).to_s}\";"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
= render 'spree/shared/line_item_name', line_item: item
|
||||
%br
|
||||
%small
|
||||
%em= raw(item.variant.product.supplier.name)
|
||||
%em= item.variant.product.supplier.name
|
||||
%td
|
||||
- if item.variant.sku.blank?
|
||||
\-
|
||||
@@ -43,7 +43,7 @@
|
||||
- checkout_adjustments_for(@order, exclude: [:line_item]).reverse_each do |adjustment|
|
||||
%tr
|
||||
%td{align: "right", colspan: "3"}
|
||||
= "#{raw(adjustment.label)}:"
|
||||
= "#{adjustment.label}:"
|
||||
%td{align: "right"}
|
||||
= adjustment.display_amount
|
||||
%tr
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
= t(:order_back_to_cart)
|
||||
- else
|
||||
.columns.small-12.medium-6
|
||||
= link_to "#{main_app.enterprise_shop_path(@order.distributor)}#/shop", class: "button expand" do
|
||||
= link_to "#{main_app.enterprise_shop_path(@order.distributor)}#/shop_panel", class: "button expand" do
|
||||
= t(:order_back_to_store)
|
||||
.columns.small-12.medium-6
|
||||
- if @order.distributor.website.present?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%h5.inline-header
|
||||
= "#{raw(line_item.product.name)}"
|
||||
= "#{line_item.product.name}"
|
||||
- unless line_item.product.name.include? line_item.name_to_display
|
||||
%span= "- #{raw(line_item.name_to_display)}"
|
||||
%span= "- #{line_item.name_to_display}"
|
||||
- if line_item.options_text
|
||||
= "(#{raw(line_item.options_text)})"
|
||||
= "(#{line_item.options_text})"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static values = { target: String };
|
||||
static values = { target: String, modalDataset: Object };
|
||||
|
||||
open() {
|
||||
let modal = document.getElementById(this.targetValue);
|
||||
@@ -12,6 +12,21 @@ export default class extends Controller {
|
||||
modalController.open();
|
||||
}
|
||||
|
||||
setModalDataSetOnConfirm(event) {
|
||||
try {
|
||||
const modalId = this.targetValue;
|
||||
const moodalConfirmButtonQuery = `#${modalId} #modal-confirm-button`;
|
||||
const confirmButton = document.querySelector(moodalConfirmButtonQuery);
|
||||
Object.keys(this.modalDatasetValue).forEach((datasetKey) => {
|
||||
confirmButton.setAttribute(datasetKey, this.modalDatasetValue[datasetKey]);
|
||||
});
|
||||
} catch (e) {
|
||||
// In case of any type of error in setting the dataset value, stop the further actions i.e. opening the modal
|
||||
event.stopImmediatePropagation();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
getIdentifier() {
|
||||
return "modal";
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import ApplicationController from "./application_controller";
|
||||
|
||||
export default class extends ApplicationController {
|
||||
static targets = ["loading"];
|
||||
static values = { currentId: Number };
|
||||
|
||||
connect() {
|
||||
super.connect();
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
window.addEventListener("orderCycleSelected", this.orderCycleSelected);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
window.removeEventListener("orderCycleSelected", this.orderCycleSelected);
|
||||
}
|
||||
|
||||
orderCycleSelected = (event) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("tabs-and-panels:click", {
|
||||
detail: {
|
||||
tab: "shop",
|
||||
panel: "shop_panel",
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -5,93 +5,46 @@ export default class extends Controller {
|
||||
static values = { className: String };
|
||||
|
||||
connect() {
|
||||
// hide all active panel
|
||||
this.panelTargets.forEach((panel) => {
|
||||
panel.style.display = "none";
|
||||
});
|
||||
|
||||
// only display the default panel
|
||||
this.defaultTarget.style.display = "block";
|
||||
|
||||
// Display panel specified in url anchor
|
||||
const anchors = window.location.toString().split("#");
|
||||
let anchor = anchors.length > 1 ? anchors.pop() : "";
|
||||
|
||||
if (anchor != "") {
|
||||
// Conveniently AngularJs rewrite "example.com#panel" to "example.com#/panel" :(
|
||||
// strip the starting / if any
|
||||
if (anchor[0] == "/") {
|
||||
anchor = anchor.slice(1);
|
||||
}
|
||||
// Add _panel to the anchor to match the panel id if needed
|
||||
if (!anchor.includes("_panel")) {
|
||||
anchor = `${anchor}_panel`;
|
||||
}
|
||||
this.updateActivePanel(anchor);
|
||||
|
||||
// tab
|
||||
const tab_id = anchor.split("_panel").shift();
|
||||
this.updateActiveTab(tab_id);
|
||||
}
|
||||
|
||||
window.addEventListener("tabs-and-panels:click", (event) => {
|
||||
this.simulateClick(event.detail.tab, event.detail.panel);
|
||||
});
|
||||
this._activateFromWindowLocationOrDefaultPanelTarget();
|
||||
|
||||
window.addEventListener("popstate", (event) => {
|
||||
const newPanelId = event.target.location.hash.replace("#/", "");
|
||||
const currentPanelId = this.currentActivePanel.id;
|
||||
|
||||
if (newPanelId !== currentPanelId) {
|
||||
const newTabId = newPanelId.split("_panel").shift();
|
||||
this.simulateClick(newTabId, newPanelId);
|
||||
}
|
||||
this._activateFromWindowLocationOrDefaultPanelTarget();
|
||||
});
|
||||
}
|
||||
|
||||
simulateClick(tab, panel) {
|
||||
this.updateActivePanel(panel);
|
||||
this.updateActiveTab(tab);
|
||||
}
|
||||
|
||||
changeActivePanel(event) {
|
||||
this.updateActivePanel(`${event.currentTarget.id}_panel`);
|
||||
}
|
||||
|
||||
updateActivePanel(panel_id) {
|
||||
const newActivePanel = this.panelTargets.find((panel) => panel.id == panel_id);
|
||||
|
||||
if (newActivePanel === undefined) {
|
||||
// No panel found
|
||||
return;
|
||||
_activateFromWindowLocationOrDefaultPanelTarget() {
|
||||
// Conveniently AngularJs rewrite "example.com#panel" to "example.com#/panel"
|
||||
const hashWithoutSlash = window.location.hash.replace("/", "");
|
||||
const tabWithSameHash = this.tabTargets.find((tab) => tab.hash == hashWithoutSlash);
|
||||
if (hashWithoutSlash != "" && tabWithSameHash) {
|
||||
this._activateByHash(tabWithSameHash.hash);
|
||||
} else {
|
||||
this._activateByHash(`#${this.defaultTarget.id}`);
|
||||
}
|
||||
|
||||
this.currentActivePanel.style.display = "none";
|
||||
newActivePanel.style.display = "block";
|
||||
}
|
||||
|
||||
changeActiveTab(event) {
|
||||
this.currentActiveTab.classList.remove(`${this.classNameValue}`);
|
||||
event.currentTarget.classList.add(`${this.classNameValue}`);
|
||||
activate(event) {
|
||||
this._activateByHash(event.currentTarget.hash);
|
||||
}
|
||||
|
||||
updateActiveTab(tab_id) {
|
||||
const newActiveTab = this.tabTargets.find((tab) => tab.id == tab_id);
|
||||
|
||||
if (newActiveTab === undefined) {
|
||||
// No tab found
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentActiveTab.classList.remove(`${this.classNameValue}`);
|
||||
newActiveTab.classList.add(`${this.classNameValue}`);
|
||||
activateDefaultPanel() {
|
||||
this._activateByHash(`#${this.defaultTarget.id}`);
|
||||
}
|
||||
|
||||
get currentActiveTab() {
|
||||
return this.tabTargets.find((tab) => tab.classList.contains("selected"));
|
||||
}
|
||||
|
||||
get currentActivePanel() {
|
||||
return this.panelTargets.find((panel) => panel.id == `${this.currentActiveTab.id}_panel`);
|
||||
_activateByHash(hash) {
|
||||
this.tabTargets.forEach((tab) => {
|
||||
if (tab.hash == hash) {
|
||||
tab.classList.add(this.classNameValue);
|
||||
} else {
|
||||
tab.classList.remove(this.classNameValue);
|
||||
}
|
||||
});
|
||||
this.panelTargets.forEach((panel) => {
|
||||
if (panel.id == hash.replace("#", "")) {
|
||||
panel.style.display = "block";
|
||||
} else {
|
||||
panel.style.display = "none";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
@import "alert";
|
||||
@import "animations";
|
||||
@import "change_type_form";
|
||||
@import "connected_apps";
|
||||
@import "customers";
|
||||
@import "dashboard_item";
|
||||
@import "dashboard-single-ent";
|
||||
@@ -111,6 +112,7 @@
|
||||
@import "side_menu";
|
||||
@import "tables";
|
||||
@import "tag_rules";
|
||||
@import "terms_of_service_banner";
|
||||
@import "terms_of_service_files";
|
||||
@import "validation";
|
||||
@import "variant_overrides";
|
||||
|
||||
41
app/webpacker/css/admin/connected_apps.scss
Normal file
41
app/webpacker/css/admin/connected_apps.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
#connected_apps_panel {
|
||||
max-width: 615px;
|
||||
}
|
||||
|
||||
.connected-app__head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1em;
|
||||
|
||||
h3 {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.connected-app__description {
|
||||
p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.connected-app__note {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
background-color: $color-14;
|
||||
border: none;
|
||||
border-left: $border-radius solid $color-3;
|
||||
border-radius: $border-radius;
|
||||
box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 2px 2px rgba(0, 0, 0, 0.07);
|
||||
margin: 2em 0;
|
||||
padding: 0.5em 1em;
|
||||
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
* {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
p {
|
||||
flex-shrink: 1;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user