diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md
index 7ff900d243..acd5c4a60a 100644
--- a/.github/ISSUE_TEMPLATE/release.md
+++ b/.github/ISSUE_TEMPLATE/release.md
@@ -11,6 +11,7 @@ assignees: ''
- [ ] Merge pull requests in the [Ready To Go] column
- [ ] Include translations: `script/release/update_locales`
+ - You need the [Transifex Client] installed on your local dev environement to run the script.
- [ ] Increment version number: `git push upstream HEAD:refs/tags/vX.Y.Z`
- Major: if server changes are required (eg. provision with ofn-install)
- Minor: larger change that is irreversible (eg. migration deleting data)
@@ -53,3 +54,4 @@ The full process is described at https://github.com/openfoodfoundation/openfoodn
[#global-community]: https://app.slack.com/client/T02G54U79/C59ADD8F2
[Create issue]: https://github.com/openfoodfoundation/openfoodnetwork/issues/new?assignees=&labels=&projects=&template=release.md&title=Release
[#core-devs]: https://openfoodnetwork.slack.com/archives/GK2T38QPJ
+[Transifex Client]: https://developers.transifex.com/docs/cli
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 03d98ef5e8..70000b33ad 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -3,7 +3,7 @@ name: Build
on:
workflow_dispatch:
push:
- branches-ignore:
+ branches-ignore:
- 'dependabot/**'
pull_request:
@@ -47,7 +47,7 @@ jobs:
- name: Setup redis
uses: supercharge/redis-github-action@1.4.0
- with:
+ with:
redis-version: 6
- name: Set up Ruby
@@ -81,11 +81,20 @@ jobs:
# RSpec split test files by test examples feature - it's optional
# https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it
#KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES: true
- KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/controllers/**/*_spec.rb}"
+ KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/controllers/**/*_spec.rb}"
run: |
git show --no-patch # the commit being tested (which is often a merge due to actions/checkout@v3)
bin/rake knapsack_pro:rspec
+ - name: Save SimpleCov file
+ uses: actions/upload-artifact@v4
+ with:
+ name: simplecov-chunk-controllers-${{ matrix.ci_node_index }}
+ path: coverage/*.*
+ retention-days: 2 # doesn't need to be long, because it's the combined results that matter
+ if-no-files-found: ignore
+ include-hidden-files: true
+
models:
runs-on: ubuntu-22.04
services:
@@ -116,7 +125,7 @@ jobs:
- name: Setup redis
uses: supercharge/redis-github-action@1.4.0
- with:
+ with:
redis-version: 6
- name: Set up Ruby
@@ -141,10 +150,19 @@ jobs:
# RSpec split test files by test examples feature - it's optional
# https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it
#KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES: true
- KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/models/**/*_spec.rb}"
+ KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/models/**/*_spec.rb}"
run: |
bin/rake knapsack_pro:rspec
+ - name: Save SimpleCov file
+ uses: actions/upload-artifact@v4
+ with:
+ name: simplecov-chunk-models-${{ matrix.ci_node_index }}
+ path: coverage/*.*
+ retention-days: 2 # doesn't need to be long, because it's the combined results that matter
+ if-no-files-found: ignore
+ include-hidden-files: true
+
system_admin:
runs-on: ubuntu-22.04
services:
@@ -175,7 +193,7 @@ jobs:
- name: Setup redis
uses: supercharge/redis-github-action@1.4.0
- with:
+ with:
redis-version: 6
- name: Set up Ruby
@@ -209,16 +227,25 @@ jobs:
# RSpec split test files by test examples feature - it's optional
# https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it
#KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES: true
- KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/system/admin/**/*_spec.rb}"
+ KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/system/admin/**/*_spec.rb}"
run: |
bin/rake knapsack_pro:queue:rspec
+ - name: Save SimpleCov file
+ uses: actions/upload-artifact@v4
+ with:
+ name: simplecov-chunk-system-admin-${{ matrix.ci_node_index }}
+ path: coverage/*.*
+ retention-days: 2 # doesn't need to be long, because it's the combined results that matter
+ if-no-files-found: ignore
+ include-hidden-files: true
+
- name: Archive failed tests screenshots
if: failure()
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: failed-tests-screenshots
+ name: failed-admin_${{ matrix.ci_node_index }}-tests-screenshots
path: tmp/capybara/screenshots/*.png
retention-days: 7
if-no-files-found: ignore
@@ -247,13 +274,13 @@ jobs:
ci_node_total: [12]
# Indexes for parallel jobs (starting from zero).
# E.g. use [0, 1] for 2 parallel jobs, [0, 1, 2] for 3 parallel jobs, etc.
- ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
+ ci_node_index: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
steps:
- uses: actions/checkout@v3
- name: Setup redis
uses: supercharge/redis-github-action@1.4.0
- with:
+ with:
redis-version: 6
- name: Set up Ruby
@@ -287,16 +314,25 @@ jobs:
# RSpec split test files by test examples feature - it's optional
# https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it
#KNAPSACK_PRO_RSPEC_SPLIT_BY_TEST_EXAMPLES: true
- KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/system/consumer/**/*_spec.rb}"
+ KNAPSACK_PRO_TEST_FILE_PATTERN: "{spec/system/consumer/**/*_spec.rb}"
run: |
bin/rake knapsack_pro:queue:rspec
+ - name: Save SimpleCov file
+ uses: actions/upload-artifact@v4
+ with:
+ name: simplecov-chunk-system-consumer-${{ matrix.ci_node_index }}
+ path: coverage/*.*
+ retention-days: 2 # doesn't need to be long, because it's the combined results that matter
+ if-no-files-found: ignore
+ include-hidden-files: true
+
- name: Archive failed tests screenshots
if: failure()
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: failed-tests-screenshots
+ name: failed-consumer_${{ matrix.ci_node_index }}-tests-screenshots
path: tmp/capybara/screenshots/*.png
retention-days: 7
if-no-files-found: ignore
@@ -331,7 +367,7 @@ jobs:
- name: Setup redis
uses: supercharge/redis-github-action@1.4.0
- with:
+ with:
redis-version: 6
- name: Set up Ruby
@@ -371,14 +407,14 @@ jobs:
run: |
bin/rake knapsack_pro:rspec
- - name: Archive failed tests screenshots
- if: failure()
- uses: actions/upload-artifact@v3
+ - name: Save SimpleCov file
+ uses: actions/upload-artifact@v4
with:
- name: failed-tests-screenshots
- path: tmp/capybara/screenshots/*.png
- retention-days: 7
+ name: simplecov-chunk-engines-${{ matrix.ci_node_index }}
+ path: coverage/*.*
+ retention-days: 2 # doesn't need to be long, because it's the combined results that matter
if-no-files-found: ignore
+ include-hidden-files: true
test_the_rest:
runs-on: ubuntu-22.04
@@ -410,7 +446,7 @@ jobs:
- name: Setup redis
uses: supercharge/redis-github-action@1.4.0
- with:
+ with:
redis-version: 6
- name: Set up Ruby
@@ -448,6 +484,15 @@ jobs:
run: |
bin/rake knapsack_pro:rspec
+ - name: Save SimpleCov file
+ uses: actions/upload-artifact@v4
+ with:
+ name: simplecov-chunk-the-rest-${{ matrix.ci_node_index }}
+ path: coverage/*.*
+ retention-days: 2 # doesn't need to be long, because it's the combined results that matter
+ if-no-files-found: ignore
+ include-hidden-files: true
+
non_knapsack_jest_karma:
runs-on: ubuntu-22.04
services:
@@ -485,3 +530,39 @@ jobs:
- name: Run jest tests
run: yarn jest
+
+ collate_simplecov_results:
+ runs-on: ubuntu-22.04
+ needs:
+ - controllers
+ - models
+ - engines
+ - system_admin
+ - system_consumer
+ - test_the_rest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
+
+ - name: Download individual results from individual runners
+ uses: actions/download-artifact@v4
+ with:
+ pattern: simplecov-chunk-*
+ path: tmp/simplecov
+ merge-multiple: true
+
+ - name: collate results from each of the workers
+ run: bundle exec rake 'simplecov:collate_results[tmp/simplecov]'
+
+ - name: Upload collated results
+ uses: actions/upload-artifact@v4
+ with:
+ name: combined-simplecov-report
+ path: coverage/**/*.*
+ retention-days: 7
+ if-no-files-found: ignore
+ include-hidden-files: true
diff --git a/.simplecov b/.simplecov
index 0094b3ddcd..8cf02c6b54 100755
--- a/.simplecov
+++ b/.simplecov
@@ -14,4 +14,6 @@ SimpleCov.start 'rails' do
add_filter '/log'
add_filter '/db'
add_filter '/lib/tasks/sample_data/'
+
+ formatter SimpleCov::Formatter::SimpleFormatter
end
diff --git a/Gemfile b/Gemfile
index 94f0e62398..fb414a745a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -16,7 +16,6 @@ gem "image_processing"
gem 'activemerchant', '>= 1.78.0'
gem 'angular-rails-templates', '>= 0.3.0'
-gem 'awesome_nested_set'
gem 'ransack', '~> 4.1.0'
gem 'responders'
gem 'webpacker', '~> 5'
@@ -105,6 +104,7 @@ gem 'sidekiq-scheduler'
gem "cable_ready"
gem "stimulus_reflex"
+gem "turbo_power"
gem "turbo-rails"
gem 'combine_pdf'
diff --git a/Gemfile.lock b/Gemfile.lock
index ea6f3f1c07..f18294b3bb 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -161,8 +161,6 @@ GEM
activerecord (>= 3.1.0, < 8)
ast (2.4.2)
attr_required (1.0.2)
- awesome_nested_set (3.6.0)
- activerecord (>= 4.0.0, < 7.2)
aws-eventstream (1.3.0)
aws-partitions (1.929.0)
aws-sdk-core (3.196.1)
@@ -787,6 +785,8 @@ GEM
actionpack (>= 6.0.0)
activejob (>= 6.0.0)
railties (>= 6.0.0)
+ turbo_power (0.6.2)
+ turbo-rails (>= 1.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
@@ -837,7 +837,7 @@ GEM
websocket-extensions (0.1.5)
whenever (1.0.0)
chronic (>= 0.6.3)
- wicked_pdf (2.6.3)
+ wicked_pdf (2.8.1)
activesupport
wkhtmltopdf-binary (0.12.6.7)
xml-simple (1.1.8)
@@ -863,7 +863,6 @@ DEPENDENCIES
angularjs-file-upload-rails (~> 2.4.1)
angularjs-rails (= 1.8.0)
arel-helpers (~> 2.12)
- awesome_nested_set
aws-sdk-s3
bigdecimal (= 3.0.2)
bootsnap
@@ -976,6 +975,7 @@ DEPENDENCIES
stripe
timecop
turbo-rails
+ turbo_power
valid_email2
validates_lengths_from_database
vcr
diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js
index 6135d8cb5e..a35bf0f3cc 100644
--- a/app/assets/javascripts/admin/all.js
+++ b/app/assets/javascripts/admin/all.js
@@ -10,7 +10,6 @@
//= require jquery.ui.all
//= require jquery.powertip
//= require jquery.cookie
-//= require jquery.jstree/jquery.jstree
//= require jquery.vAlign
//= require angular
//= require angular-resource
diff --git a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee
index ab5cb51249..831be6d767 100644
--- a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee
+++ b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee
@@ -19,6 +19,8 @@ angular.module('admin.orderCycles')
$scope.submit = ($event, destination) ->
$event.preventDefault()
+ $scope.order_cycle?.trigger_action = $($event.target).data('trigger-action');
+ $scope.order_cycle?.confirm = $($event.target).data('confirm');
StatusMessage.display 'progress', t('js.saving')
OrderCycle.update(destination, $scope.order_cycle_form)
diff --git a/app/assets/javascripts/admin/order_cycles/controllers/order_cycles_controller.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/order_cycles_controller.js.coffee
index 490b0341e9..56d7636b7e 100644
--- a/app/assets/javascripts/admin/order_cycles/controllers/order_cycles_controller.js.coffee
+++ b/app/assets/javascripts/admin/order_cycles/controllers/order_cycles_controller.js.coffee
@@ -1,7 +1,11 @@
angular.module("admin.orderCycles").controller "OrderCyclesCtrl", ($scope, $q, Columns, StatusMessage, RequestMonitor, OrderCycles, Enterprises, Schedules, Dereferencer) ->
$scope.RequestMonitor = RequestMonitor
$scope.columns = Columns.columns
- $scope.saveAll = -> OrderCycles.saveChanges($scope.order_cycles_form)
+ $scope.saveAll = ($event) ->
+ trigger_action = $($event.target).data('trigger-action')
+ confirm = $($event.target).data('confirm')
+ OrderCycles.saveChanges($scope.order_cycles_form, { trigger_action, confirm })
+
$scope.ordersCloseAtLimit = -31 # days
$scope.resetSelectFilters = ->
diff --git a/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee
index fc043afaaa..625d6fb499 100644
--- a/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee
+++ b/app/assets/javascripts/admin/order_cycles/controllers/simple_edit.js.coffee
@@ -22,6 +22,8 @@ angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl",
$scope.submit = ($event, destination) ->
$event.preventDefault()
+ $scope.order_cycle?.trigger_action = $($event.target).data('trigger-action');
+ $scope.order_cycle?.confirm = $($event.target).data('confirm');
StatusMessage.display 'progress', t('js.saving')
OrderCycle.mirrorIncomingToOutgoingProducts()
OrderCycle.update(destination, $scope.order_cycle_form) if OrderCycle.confirmNoDistributors()
diff --git a/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee b/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee
index 88ad9da1b8..58dc0a8264 100644
--- a/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee
+++ b/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee
@@ -161,7 +161,11 @@ angular.module('admin.orderCycles').factory 'OrderCycle', ($resource, $window, $
StatusMessage.display('failure', t('js.order_cycles.create_failure'))
update: (destination, form) ->
- oc = new OrderCycleResource({order_cycle: this.dataForSubmit()})
+ oc = new OrderCycleResource({
+ order_cycle: this.dataForSubmit(),
+ confirm: this.order_cycle.confirm,
+ trigger_action: this.order_cycle.trigger_action
+ })
oc.$update {order_cycle_id: this.order_cycle.id, reloading: (if destination? then 1 else 0)}, (data) =>
form.$setPristine() if form
if destination?
@@ -171,6 +175,8 @@ angular.module('admin.orderCycles').factory 'OrderCycle', ($resource, $window, $
, (response) ->
if response.data.errors?
StatusMessage.display('failure', response.data.errors[0])
+ else if (response.data.trigger_action)
+ StatusMessage.display('notice', t('js.order_cycles.unsaved_changes'), response.data.trigger_action)
else
StatusMessage.display('failure', t('js.order_cycles.update_failure'))
diff --git a/app/assets/javascripts/admin/resources/services/order_cycles.js.coffee b/app/assets/javascripts/admin/resources/services/order_cycles.js.coffee
index 38c7c5e020..8eb53433f9 100644
--- a/app/assets/javascripts/admin/resources/services/order_cycles.js.coffee
+++ b/app/assets/javascripts/admin/resources/services/order_cycles.js.coffee
@@ -29,13 +29,13 @@ angular.module("admin.resources").factory 'OrderCycles', ($q, $injector, OrderCy
deferred.reject(response)
deferred.promise
- saveChanges: (form) ->
+ saveChanges: (form, params = {}) ->
changed = {}
for id, orderCycle of @byID when not @saved(orderCycle)
changed[Object.keys(changed).length] = @changesFor(orderCycle)
if Object.keys(changed).length > 0
StatusMessage.display('progress', "Saving...")
- OrderCycleResource.bulkUpdate { order_cycle_set: { collection_attributes: changed } }, (data) =>
+ OrderCycleResource.bulkUpdate { order_cycle_set: { collection_attributes: changed }, confirm: params['confirm'], trigger_action: params['trigger_action'] }, (data) =>
for orderCycle in data
delete orderCycle.coordinator
delete orderCycle.producers
@@ -47,8 +47,10 @@ angular.module("admin.resources").factory 'OrderCycles', ($q, $injector, OrderCy
, (response) =>
if response.data.errors?
StatusMessage.display('failure', response.data.errors[0])
+ else if (response.data.trigger_action)
+ StatusMessage.display('notice', t('js.order_cycles.unsaved_changes'), response.data.trigger_action)
else
- StatusMessage.display('failure', "Oh no! I was unable to save your changes.")
+ StatusMessage.display('failure', t('js.order_cycles.bulk_save_error'))
saved: (order_cycle) ->
@diff(order_cycle).length == 0
diff --git a/app/assets/javascripts/admin/spree/taxons/taxon_tree_menu.js.coffee b/app/assets/javascripts/admin/spree/taxons/taxon_tree_menu.js.coffee
deleted file mode 100644
index dca01a3aa3..0000000000
--- a/app/assets/javascripts/admin/spree/taxons/taxon_tree_menu.js.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-root = exports ? this
-
-root.taxon_tree_menu = (obj, context) ->
-
- base_url = Spree.url(Spree.routes.taxonomy_taxons)
- admin_base_url = Spree.url(Spree.routes.admin_taxonomy_taxons)
- edit_url = Spree.url(Spree.routes.admin_taxonomy_taxons + '/' + obj.attr("id") + "/edit");
-
- create:
- label: " " + Spree.translations.add,
- action: (obj) -> context.create(obj)
- rename:
- label: " " + Spree.translations.rename,
- action: (obj) -> context.rename(obj)
- remove:
- label: " " + Spree.translations.remove,
- action: (obj) -> context.remove(obj)
- edit:
- separator_before: true,
- label: " " + Spree.translations.edit,
- action: (obj) -> window.location = edit_url.toString()
diff --git a/app/assets/javascripts/admin/spree/taxons/taxonomy.js.coffee b/app/assets/javascripts/admin/spree/taxons/taxonomy.js.coffee
deleted file mode 100644
index a5b01868b1..0000000000
--- a/app/assets/javascripts/admin/spree/taxons/taxonomy.js.coffee
+++ /dev/null
@@ -1,139 +0,0 @@
-handle_ajax_error = (XMLHttpRequest, textStatus, errorThrown) ->
- $.jstree.rollback(last_rollback)
- $("#ajax_error").show().html("" + server_error + "
" + taxonomy_tree_error)
-
-handle_move = (e, data) ->
- last_rollback = data.rlbk
- position = data.rslt.cp
- node = data.rslt.o
- new_parent = data.rslt.np
-
- url = new URL(Spree.routes.admin_taxonomy_taxons)
- url.pathname = url.pathname + '/' + node.attr("id")
- data = {
- _method: "put",
- "taxon[position]": position,
- "taxon[parent_id]": if !isNaN(new_parent.attr("id")) then new_parent.attr("id") else undefined
- }
- $.ajax
- type: "POST",
- dataType: "json",
- url: url.toString(),
- data: data,
- error: handle_ajax_error
-
- true
-
-handle_create = (e, data) ->
- last_rollback = data.rlbk
- node = data.rslt.obj
- name = data.rslt.name
- position = data.rslt.position
- new_parent = data.rslt.parent
-
- data = {
- "taxon[name]": name,
- "taxon[position]": position
- "taxon[parent_id]": if !isNaN(new_parent.attr("id")) then new_parent.attr("id") else undefined
- }
- $.ajax
- type: "POST",
- dataType: "json",
- url: base_url.toString(),
- data: data,
- error: handle_ajax_error,
- success: (data,result) ->
- node.attr('id', data.id)
-
-handle_rename = (e, data) ->
- last_rollback = data.rlbk
- node = data.rslt.obj
- name = data.rslt.new_name
- # change the name inside the main input field as well if taxon is the root one
- document.getElementById("taxonomy_name").value = name if node.parents("[id]").attr("id") == "taxonomy_tree"
-
- url = new URL(base_url)
- url.pathname = url.pathname + '/' + node.attr("id")
-
- $.ajax
- type: "POST",
- dataType: "json",
- url: url.toString(),
- data: {_method: "put", "taxon[name]": name },
- error: handle_ajax_error
-
-handle_delete = (e, data) ->
- last_rollback = data.rlbk
- node = data.rslt.obj
- delete_url = new URL(base_url)
- delete_url.pathname = delete_url.pathname + '/' + node.attr("id")
- if confirm(Spree.translations.are_you_sure_delete)
- $.ajax
- type: "POST",
- dataType: "json",
- url: delete_url.toString(),
- data: {_method: "delete"},
- error: handle_ajax_error
- else
- $.jstree.rollback(last_rollback)
- last_rollback = null
-
-root = exports ? this
-root.setup_taxonomy_tree = (taxonomy_id) ->
- if taxonomy_id != undefined
- # this is defined within admin/taxonomies/edit
- root.base_url = Spree.url(Spree.routes.taxonomy_taxons)
-
- $.ajax
- url: base_url.pathname.replace("/taxons", "/jstree"),
- success: (taxonomy) ->
- last_rollback = null
-
- conf =
- json_data:
- data: taxonomy,
- ajax:
- url: (e) ->
- base_url.pathname + '/' + e.attr('id') + '/jstree'
- themes:
- theme: "apple",
- url: "/assets/jquery.jstree/themes/apple/style.css"
- strings:
- new_node: new_taxon,
- loading: Spree.translations.loading + "..."
- crrm:
- move:
- check_move: (m) ->
- position = m.cp
- node = m.o
- new_parent = m.np
-
- # no parent or cant drag and drop
- if !new_parent || node.attr("rel") == "root"
- return false
-
- # can't drop before root
- if new_parent.attr("id") == "taxonomy_tree" && position == 0
- return false
-
- true
- contextmenu:
- items: (obj) ->
- taxon_tree_menu(obj, this)
- plugins: ["themes", "json_data", "dnd", "crrm", "contextmenu"]
-
- $("#taxonomy_tree").jstree(conf)
- .bind("move_node.jstree", handle_move)
- .bind("remove.jstree", handle_delete)
- .bind("create.jstree", handle_create)
- .bind("rename.jstree", handle_rename)
- .bind "loaded.jstree", ->
- $(this).jstree("core").toggle_node($('.jstree-icon').first())
-
- $("#taxonomy_tree a").on "dblclick", (e) ->
- $("#taxonomy_tree").jstree("rename", this)
-
- # surpress form submit on enter/return
- $(document).keypress (e) ->
- if e.keyCode == 13
- e.preventDefault()
diff --git a/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee b/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee
index 89ebd5b90e..5d90b023dc 100644
--- a/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee
+++ b/app/assets/javascripts/admin/utils/services/navigation_check.js.coffee
@@ -9,6 +9,7 @@ angular.module("admin.utils")
$window.onbeforeunload = @onBeforeUnloadHandler
$rootScope.$on "$locationChangeStart", @locationChangeStartHandler
+ $window.onBeforeUnloadHandler = @onBeforeUnloadHandler
# Action for regular browser navigation.
onBeforeUnloadHandler: ($event) =>
diff --git a/app/assets/javascripts/admin/utils/services/status_message.js.coffee b/app/assets/javascripts/admin/utils/services/status_message.js.coffee
index 432c6ecf70..8355209fc1 100644
--- a/app/assets/javascripts/admin/utils/services/status_message.js.coffee
+++ b/app/assets/javascripts/admin/utils/services/status_message.js.coffee
@@ -10,7 +10,9 @@ angular.module("admin.utils").factory "StatusMessage", ->
statusMessage:
text: ""
- style: {}
+ style: {},
+ type: null,
+ actionName: null
invalidMessage: ""
@@ -23,11 +25,15 @@ angular.module("admin.utils").factory "StatusMessage", ->
active: ->
@statusMessage.text != ''
- display: (type, text) ->
+ display: (type, text, actionName = null) ->
@statusMessage.text = text
+ @statusMessage.type = type
+ @statusMessage.actionName = actionName
@statusMessage.style = @types[type].style
null
clear: ->
@statusMessage.text = ''
@statusMessage.style = {}
+ @statusMessage.type = null
+ @statusMessage.actionName = null
diff --git a/app/assets/javascripts/templates/active_selector.html.haml b/app/assets/javascripts/templates/active_selector.html.haml
index c7ddfc3577..3cfbe46f0f 100644
--- a/app/assets/javascripts/templates/active_selector.html.haml
+++ b/app/assets/javascripts/templates/active_selector.html.haml
@@ -1,2 +1,3 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
%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}" }
diff --git a/app/assets/javascripts/templates/admin/save_bar.html.haml b/app/assets/javascripts/templates/admin/save_bar.html.haml
index 2a33901459..e0ab0f437e 100644
--- a/app/assets/javascripts/templates/admin/save_bar.html.haml
+++ b/app/assets/javascripts/templates/admin/save_bar.html.haml
@@ -1,7 +1,7 @@
#save-bar.animate-show{ "ng-show": 'dirty || persist || StatusMessage.active()' }
.container
.seven.columns.alpha
- %h5#status-message{ "ng-show": "StatusMessage.invalidMessage == ''", "ng-style": 'StatusMessage.statusMessage.style' }
+ %h5#status-message{ "ng-show": "StatusMessage.invalidMessage == ''", "ng-style": 'StatusMessage.statusMessage.style', data: { 'order-cycle-form-target': 'statusMessage' }, "ng-attr-data-type": "{{StatusMessage.statusMessage.type}}", "ng-attr-data-action-name": "{{StatusMessage.statusMessage.actionName}}" }
{{ StatusMessage.statusMessage.text || " " }}
%h5#status-message{ style: 'color: #C85136', "ng-show": "StatusMessage.invalidMessage !== ''" }
{{ StatusMessage.invalidMessage || " " }}
diff --git a/app/assets/javascripts/templates/filter_selector.html.haml b/app/assets/javascripts/templates/filter_selector.html.haml
index 81559e4004..c2f110a1f7 100644
--- a/app/assets/javascripts/templates/filter_selector.html.haml
+++ b/app/assets/javascripts/templates/filter_selector.html.haml
@@ -1,3 +1,4 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
%ul
%active-selector{ "ng-repeat": "selector in allSelectors", "ng-show": "ifDefined(selector.fits, true)" }
%span{"ng-bind" => "::selector.object.name"}
diff --git a/app/assets/javascripts/templates/product_modal.html.haml b/app/assets/javascripts/templates/product_modal.html.haml
index 374f1bda4e..5a85554108 100644
--- a/app/assets/javascripts/templates/product_modal.html.haml
+++ b/app/assets/javascripts/templates/product_modal.html.haml
@@ -1,3 +1,4 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
.row
.columns.small-12.medium-6.large-6.product-header
%h3{"ng-bind" => "::product.name"}
diff --git a/app/assets/stylesheets/mail.scss b/app/assets/stylesheets/mail.scss
new file mode 100644
index 0000000000..e35654c0d2
--- /dev/null
+++ b/app/assets/stylesheets/mail.scss
@@ -0,0 +1 @@
+@import './mail/all.scss';
diff --git a/app/assets/stylesheets/mail/all.scss b/app/assets/stylesheets/mail/all.scss
new file mode 100644
index 0000000000..fa8445d726
--- /dev/null
+++ b/app/assets/stylesheets/mail/all.scss
@@ -0,0 +1,3 @@
+@import '../../../webpacker/css/admin/globals/palette.scss';
+@import 'email';
+@import 'payments_list';
diff --git a/app/webpacker/css/mail/email.scss b/app/assets/stylesheets/mail/email.scss
similarity index 100%
rename from app/webpacker/css/mail/email.scss
rename to app/assets/stylesheets/mail/email.scss
diff --git a/app/webpacker/css/mail/payments_list.scss b/app/assets/stylesheets/mail/payments_list.scss
similarity index 100%
rename from app/webpacker/css/mail/payments_list.scss
rename to app/assets/stylesheets/mail/payments_list.scss
diff --git a/app/components/admin_tooltip_component.rb b/app/components/admin_tooltip_component.rb
new file mode 100644
index 0000000000..f790fffd1d
--- /dev/null
+++ b/app/components/admin_tooltip_component.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AdminTooltipComponent < ViewComponent::Base
+ def initialize(text:, link_text:, placement: "top", link: "", link_class: "")
+ @text = text
+ @link_text = link_text
+ @placement = placement
+ @link = link
+ @link_class = link_class
+ end
+end
diff --git a/app/components/admin_tooltip_component/admin_tooltip_component.html.haml b/app/components/admin_tooltip_component/admin_tooltip_component.html.haml
new file mode 100644
index 0000000000..d4e7685940
--- /dev/null
+++ b/app/components/admin_tooltip_component/admin_tooltip_component.html.haml
@@ -0,0 +1,8 @@
+%div{"data-controller": "tooltip", "data-tooltip-placement-value": @placement }
+ %a{"data-tooltip-target": "element", href: @link, class: @link_class}
+ = @link_text
+ .tooltip-container
+ .tooltip{"data-tooltip-target": "tooltip"}
+ = sanitize @text
+ .arrow{"data-tooltip-target": "arrow"}
+
diff --git a/app/components/modal_component.rb b/app/components/modal_component.rb
index 1de8852a8c..f4b279278b 100644
--- a/app/components/modal_component.rb
+++ b/app/components/modal_component.rb
@@ -1,11 +1,15 @@
# frozen_string_literal: true
class ModalComponent < ViewComponent::Base
- def initialize(id:, close_button: true, instant: false, modal_class: :small)
+ def initialize(id:, close_button: true, instant: false, modal_class: :small, **options)
@id = id
@close_button = close_button
@instant = instant
@modal_class = modal_class
+ @options = options
+ @data_controller = "modal #{@options.delete(:'data-controller')}".squish
+ @data_action =
+ "keyup@document->modal#closeIfEscapeKey #{@options.delete(:'data-action')}".squish
end
private
diff --git a/app/components/modal_component/modal_component.html.haml b/app/components/modal_component/modal_component.html.haml
index 7be73deca4..76a484c528 100644
--- a/app/components/modal_component/modal_component.html.haml
+++ b/app/components/modal_component/modal_component.html.haml
@@ -1,4 +1,4 @@
-%div{ id: @id, "data-controller": "modal", "data-action": "keyup@document->modal#closeIfEscapeKey", "data-modal-instant-value": @instant }
+%div{ id: @id, "data-controller": @data_controller, "data-action": @data_action, "data-modal-instant-value": @instant, **@options }
.reveal-modal-bg.fade{ "data-modal-target": "background", "data-action": "click->modal#close" }
.reveal-modal.fade.modal-component{ "data-modal-target": "modal", class: @modal_class }
= content
diff --git a/app/components/modal_component/modal_component.scss b/app/components/modal_component/modal_component.scss
index 72c0e74088..58bd7e34b9 100644
--- a/app/components/modal_component/modal_component.scss
+++ b/app/components/modal_component/modal_component.scss
@@ -24,6 +24,19 @@
max-width: 100%;
height: auto;
}
+
+ .flex-column {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .gap-1 {
+ gap: 1rem;
+ }
+
+ .gap-2 {
+ gap: 2rem;
+ }
}
/* prevent arrow on selected admin menu item appearing above modal */
diff --git a/app/components/searchable_dropdown_component.rb b/app/components/searchable_dropdown_component.rb
index 9a53155085..c9d1549f72 100644
--- a/app/components/searchable_dropdown_component.rb
+++ b/app/components/searchable_dropdown_component.rb
@@ -11,7 +11,8 @@ class SearchableDropdownComponent < ViewComponent::Base
selected_option:,
placeholder_value:,
include_blank: false,
- aria_label: ''
+ aria_label: '',
+ other_attrs: {}
)
@f = form
@name = name
@@ -20,11 +21,13 @@ class SearchableDropdownComponent < ViewComponent::Base
@placeholder_value = placeholder_value
@include_blank = include_blank
@aria_label = aria_label
+ @other_attrs = other_attrs
end
private
- attr_reader :f, :name, :options, :selected_option, :placeholder_value, :include_blank, :aria_label
+ attr_reader :f, :name, :options, :selected_option, :placeholder_value, :include_blank,
+ :aria_label, :other_attrs
def classes
"fullwidth #{remove_search_plugin? ? 'no-input' : ''}"
diff --git a/app/components/searchable_dropdown_component/searchable_dropdown_component.html.haml b/app/components/searchable_dropdown_component/searchable_dropdown_component.html.haml
index 10043eaa29..14d8969348 100644
--- a/app/components/searchable_dropdown_component/searchable_dropdown_component.html.haml
+++ b/app/components/searchable_dropdown_component/searchable_dropdown_component.html.haml
@@ -1 +1 @@
-= f.select name, options_for_select(options, selected_option), { include_blank: }, class: classes, data:, 'aria-label': aria_label
+= f.select name, options_for_select(options, selected_option), { include_blank: }, class: classes, data:, 'aria-label': aria_label, **other_attrs
diff --git a/app/components/vertical_ellipsis_menu/component_controller.js b/app/components/vertical_ellipsis_menu/component_controller.js
index c783adf170..97b13592bd 100644
--- a/app/components/vertical_ellipsis_menu/component_controller.js
+++ b/app/components/vertical_ellipsis_menu/component_controller.js
@@ -8,6 +8,10 @@ export default class extends Controller {
window.addEventListener("click", this.#hideIfClickedOutside);
}
+ disconnect() {
+ window.removeEventListener("click", this.#hideIfClickedOutside);
+ }
+
toggle() {
this.contentTarget.classList.toggle("show");
}
diff --git a/app/controllers/admin/dfc_product_imports_controller.rb b/app/controllers/admin/dfc_product_imports_controller.rb
index c1076ea775..e85170db2f 100644
--- a/app/controllers/admin/dfc_product_imports_controller.rb
+++ b/app/controllers/admin/dfc_product_imports_controller.rb
@@ -35,13 +35,7 @@ module Admin
private
def fetch_catalog(url)
- if url =~ /food-data-collaboration/
- fdc_json = FdcRequest.new(spree_current_user).call(url)
- fdc_message = JSON.parse(fdc_json)
- fdc_message["products"]
- else
- DfcRequest.new(spree_current_user).call(url)
- end
+ DfcRequest.new(spree_current_user).call(url)
end
# Most of this code is the same as in the DfcProvider::SuppliedProductsController.
diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb
index 35333e7af7..12a3a9fe5c 100644
--- a/app/controllers/admin/order_cycles_controller.rb
+++ b/app/controllers/admin/order_cycles_controller.rb
@@ -2,6 +2,8 @@
module Admin
class OrderCyclesController < Admin::ResourceController
+ class DateTimeChangeError < StandardError; end
+
include ::OrderCyclesHelper
include PaperTrailLogging
@@ -62,9 +64,7 @@ module Admin
end
def update
- @order_cycle_form = OrderCycles::FormService.new(@order_cycle, order_cycle_params,
- spree_current_user)
-
+ @order_cycle_form = set_order_cycle_form
if @order_cycle_form.save
update_nil_subscription_line_items_price_estimate(@order_cycle)
respond_to do |format|
@@ -77,6 +77,9 @@ module Admin
elsif request.format.json?
render json: { errors: @order_cycle.errors.full_messages }, status: :unprocessable_entity
end
+ rescue DateTimeChangeError
+ render json: { trigger_action: params[:trigger_action] },
+ status: :unprocessable_entity
end
def bulk_update
@@ -90,6 +93,9 @@ module Admin
order_cycle = order_cycle_set.collection.find{ |oc| oc.errors.present? }
render json: { errors: order_cycle.errors.full_messages }, status: :unprocessable_entity
end
+ rescue DateTimeChangeError
+ render json: { trigger_action: params[:trigger_action] },
+ status: :unprocessable_entity
end
def bulk_update_nil_subscription_line_items_price_estimate
@@ -235,7 +241,7 @@ module Admin
else
begin
yield
- rescue ActiveRecord::InvalidForeignKey
+ rescue ActiveRecord::InvalidForeignKey, ActiveRecord::DeleteRestrictionError
redirect_to main_app.admin_order_cycles_url
flash[:error] = I18n.t('admin.order_cycles.destroy_errors.orders_present')
end
@@ -270,7 +276,10 @@ module Admin
end
def order_cycle_set
- @order_cycle_set ||= Sets::OrderCycleSet.new(@order_cycles, order_cycle_bulk_params)
+ @order_cycle_set ||= Sets::OrderCycleSet.new(
+ @order_cycles, { **order_cycle_bulk_params,
+ confirm_datetime_change: params[:confirm], error_class: DateTimeChangeError }
+ )
end
def require_order_cycle_set_params
@@ -294,5 +303,14 @@ module Admin
collection_attributes: [:id] + PermittedAttributes::OrderCycle.basic_attributes
).to_h.with_indifferent_access
end
+
+ def set_order_cycle_form
+ OrderCycles::FormService.new(
+ @order_cycle, order_cycle_params.merge(
+ { confirm_datetime_change: params[:order_cycle][:confirm],
+ error_class: DateTimeChangeError }
+ ), spree_current_user
+ )
+ end
end
end
diff --git a/app/controllers/admin/product_preview_controller.rb b/app/controllers/admin/product_preview_controller.rb
new file mode 100644
index 0000000000..8712d5497c
--- /dev/null
+++ b/app/controllers/admin/product_preview_controller.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Admin
+ class ProductPreviewController < Spree::Admin::BaseController
+ def show
+ @product = Spree::Product.find(params[:id])
+ authorize! :show, @product
+
+ respond_with do |format|
+ format.turbo_stream {
+ render "admin/products_v3/product_preview", status: :ok
+ }
+ end
+ end
+
+ private
+
+ def model_class
+ Spree::Product
+ end
+ end
+end
diff --git a/app/controllers/admin/products_v3_controller.rb b/app/controllers/admin/products_v3_controller.rb
index 327a4a4be9..1b15277373 100644
--- a/app/controllers/admin/products_v3_controller.rb
+++ b/app/controllers/admin/products_v3_controller.rb
@@ -11,6 +11,8 @@ module Admin
def index
fetch_products
render "index", locals: { producers:, categories:, tax_category_options:, flash: }
+
+ session[:products_return_to_url] = request.url
end
def bulk_update
@@ -38,6 +40,8 @@ module Admin
{ id: params[:id] }
).find_product
+ authorize! :delete, @record
+
@record.destroyed_by = spree_current_user
status = :ok
@@ -72,6 +76,8 @@ module Admin
def clone
@product = Spree::Product.find(params[:id])
+ authorize! :clone, @product
+
status = :ok
begin
diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb
index 699c326f3f..fe8a1874c1 100644
--- a/app/controllers/admin/reports_controller.rb
+++ b/app/controllers/admin/reports_controller.rb
@@ -6,7 +6,7 @@ module Admin
include ReportsActions
helper ReportsHelper
- before_action :authorize_report, only: [:show]
+ before_action :authorize_report, only: [:show, :create]
# Define model class for Can? permissions
def model_class
@@ -20,14 +20,17 @@ module Admin
end
def show
- @report = report_class.new(spree_current_user, params, render: render_data?)
- @rendering_options = rendering_options # also stores user preferences
+ @report = report_class.new(spree_current_user, params, render: false)
+ @rendering_options = rendering_options
- if render_data?
- render_in_background
- else
- show_report
- end
+ show_report
+ end
+
+ def create
+ @report = report_class.new(spree_current_user, params, render: true)
+ update_rendering_options
+
+ render_in_background
end
private
@@ -54,31 +57,15 @@ module Admin
@variant_serialized = Api::Admin::VariantSerializer.new(variant)
end
- def render_data?
- request.post?
- end
-
def render_in_background
- cable_ready[ScopedChannel.for_id(params[:uuid])]
- .inner_html(
- selector: "#report-go",
- html: helpers.button(t(:go), "report__submit-btn", "submit", disabled: true)
- ).inner_html(
- selector: "#report-table",
- html: render_to_string(partial: "admin/reports/loading")
- ).scroll_into_view(
- selector: "#report-table",
- block: "start"
- ).broadcast
+ @blob = ReportBlob.create_for_upload_later!(report_filename)
ReportJob.perform_later(
report_class:, user: spree_current_user, params:,
format: report_format,
- filename: report_filename,
+ blob: @blob,
channel: ScopedChannel.for_id(params[:uuid]),
)
-
- head :no_content
end
end
end
diff --git a/app/controllers/api/v0/taxonomies_controller.rb b/app/controllers/api/v0/taxonomies_controller.rb
deleted file mode 100644
index bf6077a9e1..0000000000
--- a/app/controllers/api/v0/taxonomies_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-module Api
- module V0
- class TaxonomiesController < Api::V0::BaseController
- respond_to :json
-
- skip_authorization_check only: :jstree
-
- def jstree
- @taxonomy = Spree::Taxonomy.find(params[:id])
- render json: @taxonomy.root, serializer: Api::TaxonJstreeSerializer
- end
- end
- end
-end
diff --git a/app/controllers/api/v0/taxons_controller.rb b/app/controllers/api/v0/taxons_controller.rb
index 75e85f5435..f5f8bf6275 100644
--- a/app/controllers/api/v0/taxons_controller.rb
+++ b/app/controllers/api/v0/taxons_controller.rb
@@ -5,12 +5,10 @@ module Api
class TaxonsController < Api::V0::BaseController
respond_to :json
- skip_authorization_check only: [:index, :show, :jstree]
+ skip_authorization_check only: [:index, :show]
def index
- @taxons = if taxonomy
- taxonomy.root.children
- elsif params[:ids]
+ @taxons = if params[:ids]
Spree::Taxon.where(id: raw_params[:ids].split(","))
else
Spree::Taxon.ransack(raw_params[:q]).result
@@ -18,23 +16,9 @@ module Api
render json: @taxons, each_serializer: Api::TaxonSerializer
end
- def jstree
- @taxon = taxon
- render json: @taxon.children, each_serializer: Api::TaxonJstreeSerializer
- end
-
def create
authorize! :create, Spree::Taxon
@taxon = Spree::Taxon.new(taxon_params)
- @taxon.taxonomy_id = params[:taxonomy_id]
- taxonomy = Spree::Taxonomy.find_by(id: params[:taxonomy_id])
-
- if taxonomy.nil?
- @taxon.errors.add(:taxonomy_id, I18n.t(:invalid_taxonomy_id, scope: 'spree.api'))
- invalid_resource!(@taxon) && return
- end
-
- @taxon.parent_id = taxonomy.root.id unless params.dig(:taxon, :parent_id)
if @taxon.save
render json: @taxon, serializer: Api::TaxonSerializer, status: :created
@@ -60,20 +44,14 @@ module Api
private
- def taxonomy
- return if params[:taxonomy_id].blank?
-
- @taxonomy ||= Spree::Taxonomy.find(params[:taxonomy_id])
- end
-
def taxon
- @taxon ||= taxonomy.taxons.find(params[:id])
+ @taxon = Spree::Taxon.find(params[:id])
end
def taxon_params
return if params[:taxon].blank?
- params.require(:taxon).permit([:name, :parent_id, :position])
+ params.require(:taxon).permit([:name, :position])
end
end
end
diff --git a/app/controllers/concerns/reports_actions.rb b/app/controllers/concerns/reports_actions.rb
index b19d6be9e9..9cf8095aa7 100644
--- a/app/controllers/concerns/reports_actions.rb
+++ b/app/controllers/concerns/reports_actions.rb
@@ -88,14 +88,10 @@ module ReportsActions
display_header_row: false
}
end
- update_rendering_options
- @rendering_options
end
def update_rendering_options
- return unless request.post?
-
- @rendering_options.update(
+ rendering_options.update(
options: {
fields_to_show: params[:fields_to_show],
display_summary_row: params[:display_summary_row].present?,
diff --git a/app/controllers/spree/admin/base_controller.rb b/app/controllers/spree/admin/base_controller.rb
index f926612ef0..0b549a437b 100644
--- a/app/controllers/spree/admin/base_controller.rb
+++ b/app/controllers/spree/admin/base_controller.rb
@@ -19,15 +19,18 @@ module Spree
before_action :authorize_admin
before_action :set_locale
- before_action :warn_invalid_order_cycles, if: :html_request?
+ before_action :warn_invalid_order_cycles, if: :page_load_request?
# Warn the user when they have an active order cycle with hubs that are not ready
# for checkout (ie. does not have valid shipping and payment methods).
def warn_invalid_order_cycles
- return if flash[:notice].present?
+ return if flash[:notice].present? || session[:displayed_order_cycle_warning]
warning = OrderCycles::WarningService.new(spree_current_user).call
- flash[:notice] = warning if warning.present?
+ return if warning.blank?
+
+ flash.now[:notice] = warning
+ session[:displayed_order_cycle_warning] = true
end
protected
@@ -81,6 +84,12 @@ module Spree
private
+ def page_load_request?
+ return false if request.format.include?('turbo')
+
+ html_request?
+ end
+
def html_request?
request.format.html?
end
diff --git a/app/controllers/spree/admin/products_controller.rb b/app/controllers/spree/admin/products_controller.rb
index 3ae92a38bd..4580a751f0 100644
--- a/app/controllers/spree/admin/products_controller.rb
+++ b/app/controllers/spree/admin/products_controller.rb
@@ -10,6 +10,7 @@ module Spree
include OpenFoodNetwork::SpreeApiKeyLoader
include OrderCyclesHelper
include EnterprisesHelper
+ helper ::Admin::ProductsHelper
before_action :load_data
before_action :load_producers, only: [:index, :new]
diff --git a/app/controllers/spree/admin/taxonomies_controller.rb b/app/controllers/spree/admin/taxonomies_controller.rb
deleted file mode 100644
index 68f65e000e..0000000000
--- a/app/controllers/spree/admin/taxonomies_controller.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Spree
- module Admin
- class TaxonomiesController < ::Admin::ResourceController
- respond_to :json, only: [:get_children]
-
- def get_children
- @taxons = Taxon.find(params[:parent_id]).children
- end
-
- private
-
- def location_after_save
- if @taxonomy.created_at == @taxonomy.updated_at
- spree.edit_admin_taxonomy_url(@taxonomy)
- else
- spree.admin_taxonomies_url
- end
- end
-
- def permitted_resource_params
- params.require(:taxonomy).permit(:name)
- end
- end
- end
-end
diff --git a/app/controllers/spree/admin/taxons_controller.rb b/app/controllers/spree/admin/taxons_controller.rb
index 9efc97ed79..e6020eb8b5 100644
--- a/app/controllers/spree/admin/taxons_controller.rb
+++ b/app/controllers/spree/admin/taxons_controller.rb
@@ -2,122 +2,70 @@
module Spree
module Admin
- class TaxonsController < Spree::Admin::BaseController
- respond_to :html, :json, :js
+ class TaxonsController < ::Admin::ResourceController
+ before_action :set_taxon, except: %i[create index new]
- def edit
- @taxonomy = Taxonomy.find(params[:taxonomy_id])
- @taxon = @taxonomy.taxons.find(params[:id])
- @permalink_part = @taxon.permalink.split("/").last
+ def index
+ @taxons = Taxon.order(:name)
end
+ def new
+ @taxon = Taxon.new
+ end
+
+ def edit; end
+
def create
- @taxonomy = Taxonomy.find(params[:taxonomy_id])
- @taxon = @taxonomy.taxons.build(params[:taxon])
+ @taxon = Spree::Taxon.new(taxon_params)
if @taxon.save
- respond_with(@taxon) do |format|
- format.json { render json: @taxon.to_json }
- end
+ flash[:success] = flash_message_for(@taxon, :successfully_created)
+ redirect_to edit_admin_taxon_path(@taxon.id)
else
- flash[:error] = Spree.t('errors.messages.could_not_create_taxon')
- respond_with(@taxon) do |format|
- format.html do
- if redirect_to @taxonomy
- spree.edit_admin_taxonomy_url(@taxonomy)
- else
- spree.admin_taxonomies_url
- end
- end
- end
+ render :new, status: :unprocessable_entity
end
end
def update
- @taxonomy = Taxonomy.find(params[:taxonomy_id])
- @taxon = @taxonomy.taxons.find(params[:id])
- parent_id = params[:taxon][:parent_id]
- new_position = params[:taxon][:position]
-
- if parent_id || new_position # taxon is being moved
- new_parent = parent_id.nil? ? @taxon.parent : Taxon.find(parent_id.to_i)
- new_position = new_position.nil? ? -1 : new_position.to_i
-
- # Bellow is a very complicated way of finding where in nested set we
- # should actually move the taxon to achieve sane results,
- # JS is giving us the desired position, which was awesome for previous setup,
- # but now it's quite complicated to find where we should put it as we have
- # to differenciate between moving to the same branch, up down and into
- # first position.
- new_siblings = new_parent.children
- if new_position <= 0 && new_siblings.empty?
- @taxon.move_to_child_of(new_parent)
- elsif new_parent.id != @taxon.parent_id
- if new_position.zero?
- @taxon.move_to_left_of(new_siblings.first)
- else
- @taxon.move_to_right_of(new_siblings[new_position - 1])
- end
- elsif new_position < new_siblings.index(@taxon)
- @taxon.move_to_left_of(new_siblings[new_position]) # we move up
- else
- @taxon.move_to_right_of(new_siblings[new_position - 1]) # we move down
- end
- # Reset legacy position, if any extensions still rely on it
- new_parent.children.reload.each do |t|
- t.update_columns(
- position: t.position,
- updated_at: Time.zone.now
- )
- end
-
- if parent_id
- @taxon.reload
- @taxon.set_permalink
- @taxon.save!
- @update_children = true
- end
- end
-
- if params.key? "permalink_part"
- parent_permalink = @taxon.permalink.split("/")[0...-1].join("/")
- parent_permalink += "/" if parent_permalink.present?
- params[:taxon][:permalink] = parent_permalink + params[:permalink_part]
- end
- # check if we need to rename child taxons if parent name or permalink changes
- if params[:taxon][:name] != @taxon.name || params[:taxon][:permalink] != @taxon.permalink
- @update_children = true
- end
-
if @taxon.update(taxon_params)
flash[:success] = flash_message_for(@taxon, :successfully_updated)
- end
-
- # rename child taxons
- if @update_children
- @taxon.descendants.each do |taxon|
- taxon.reload
- taxon.set_permalink
- taxon.save!
- end
- end
-
- respond_with(@taxon) do |format|
- format.html { redirect_to spree.edit_admin_taxonomy_url(@taxonomy) }
- format.json { render json: @taxon.to_json }
+ redirect_to edit_admin_taxon_path(@taxon.id)
+ else
+ render :edit, status: :unprocessable_entity
end
end
def destroy
- @taxon = Taxon.find(params[:id])
- @taxon.destroy
- respond_with(@taxon) { |format| format.json { render json: '' } }
+ status = if @taxon.destroy
+ flash_message = t('.delete_taxon.success')
+ status = :ok
+ else
+ flash_message = t('.delete_taxon.error')
+ status = :unprocessable_entity
+ end
+
+ respond_to do |format|
+ format.html {
+ flash[:success] = flash_message if status == :ok
+ flash[:error] = flash_message if status == :unprocessable_entity
+ redirect_to admin_taxons_path
+ }
+ format.turbo_stream {
+ flash[:success] = flash_message if status == :ok
+ flash[:error] = flash_message if status == :unprocessable_entity
+ render :destroy_taxon, status:
+ }
+ end
end
private
+ def set_taxon
+ @taxon = Taxon.find(params[:id])
+ end
+
def taxon_params
params.require(:taxon).permit(
- :name, :parent_id, :position, :icon, :description, :permalink, :taxonomy_id,
+ :name, :position, :icon, :description, :permalink,
:meta_description, :meta_keywords, :meta_title, :dfc_id
)
end
diff --git a/app/helpers/admin/products_helper.rb b/app/helpers/admin/products_helper.rb
index 1edd8d0a28..fe00c22002 100644
--- a/app/helpers/admin/products_helper.rb
+++ b/app/helpers/admin/products_helper.rb
@@ -10,8 +10,11 @@ module Admin
end
end
- def prepare_new_variant(product)
- product.variants.build
+ def prepare_new_variant(product, producer_options)
+ # e.g producer_options = [['producer name', id]]
+ product.variants.build do |new_variant|
+ new_variant.supplier_id = producer_options.first.second if producer_options.one?
+ end
end
def unit_value_with_description(variant)
@@ -29,5 +32,19 @@ module Admin
[precised_unit_value, variant.unit_description].compact_blank.join(" ")
end
+
+ def products_return_to_url(url_filters)
+ if feature?(:admin_style_v3, spree_current_user)
+ return session[:products_return_to_url] || admin_products_url
+ end
+
+ "#{admin_products_path}#{url_filters.empty? ? '' : "#?#{url_filters.to_query}"}"
+ end
+
+ # if user hasn't saved any preferences on products page and there's only one producer;
+ # we need to hide producer column
+ def hide_producer_column?(producer_options)
+ spree_current_user.column_preferences.bulk_edit_product.empty? && producer_options.one?
+ end
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 2f470529b2..f7787e35b9 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -61,15 +61,6 @@ module ApplicationHelper
classes << shopfront_layout
end
- def pdf_stylesheet_pack_tag(source)
- if running_in_development?
- options = { media: "all", host: "#{Webpacker.dev_server.host}:#{Webpacker.dev_server.port}" }
- stylesheet_pack_tag(source, **options)
- else
- wicked_pdf_stylesheet_pack_tag(source)
- end
- end
-
def cache_with_locale(key = nil, options = {}, &block)
cache(cache_key_with_locale(key, I18n.locale), options) do
yield(block)
diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb
index 63a0797992..0b21a7bb91 100644
--- a/app/helpers/injection_helper.rb
+++ b/app/helpers/injection_helper.rb
@@ -8,11 +8,13 @@ module InjectionHelper
include OrderCyclesHelper
def inject_enterprises(enterprises = nil)
+ enterprises ||= default_enterprise_query
+
inject_json_array(
"enterprises",
- enterprises || default_enterprise_query,
+ enterprises,
Api::EnterpriseSerializer,
- enterprise_injection_data,
+ enterprise_injection_data(enterprises.map(&:id)),
)
end
@@ -57,15 +59,16 @@ module InjectionHelper
inject_json_array "enterprises",
enterprises_and_relatives,
Api::EnterpriseSerializer,
- enterprise_injection_data
+ enterprise_injection_data(enterprises_and_relatives.map(&:id))
end
def inject_group_enterprises(group)
+ enterprises = group.enterprises.activated.visible.all
inject_json_array(
"enterprises",
- group.enterprises.activated.visible.all,
+ enterprises,
Api::EnterpriseSerializer,
- enterprise_injection_data,
+ enterprise_injection_data(enterprises.map(&:id)),
)
end
@@ -73,7 +76,7 @@ module InjectionHelper
inject_json "currentHub",
current_distributor,
Api::EnterpriseSerializer,
- enterprise_injection_data
+ enterprise_injection_data(current_distributor ? [current_distributor.id] : nil)
end
def inject_current_order
@@ -153,7 +156,9 @@ module InjectionHelper
Enterprise.activated.includes(address: [:state, :country]).all
end
- def enterprise_injection_data
- @enterprise_injection_data ||= { data: OpenFoodNetwork::EnterpriseInjectionData.new }
+ def enterprise_injection_data(enterprise_ids)
+ {
+ data: OpenFoodNetwork::EnterpriseInjectionData.new(enterprise_ids)
+ }
end
end
diff --git a/app/helpers/spree/admin/taxons_helper.rb b/app/helpers/spree/admin/taxons_helper.rb
deleted file mode 100644
index e8e4d8d918..0000000000
--- a/app/helpers/spree/admin/taxons_helper.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-module Spree
- module Admin
- module TaxonsHelper
- def taxon_path(taxon)
- taxon.ancestors.reverse.collect(&:name).join( " >> ")
- end
- end
- end
-end
diff --git a/app/jobs/report_job.rb b/app/jobs/report_job.rb
index 3c5aecab25..0367ddd259 100644
--- a/app/jobs/report_job.rb
+++ b/app/jobs/report_job.rb
@@ -9,12 +9,12 @@ class ReportJob < ApplicationJob
NOTIFICATION_TIME = 5.seconds
- def perform(report_class:, user:, params:, format:, filename:, channel: nil)
+ def perform(report_class:, user:, params:, format:, blob:, channel: nil)
start_time = Time.zone.now
report = report_class.new(user, params, render: true)
result = report.render_as(format)
- blob = ReportBlob.create!(filename, result)
+ blob.store(result)
execution_time = Time.zone.now - start_time
diff --git a/app/models/column_preference.rb b/app/models/column_preference.rb
index 3e86f36440..04a35ebbe8 100644
--- a/app/models/column_preference.rb
+++ b/app/models/column_preference.rb
@@ -15,10 +15,11 @@ class ColumnPreference < ApplicationRecord
validates :column_name, presence: true, inclusion: { in: proc { |p|
valid_columns_for(p.action_name)
} }
+ scope :bulk_edit_product, -> { where(action_name: 'products_v3_index') }
def self.for(user, action_name)
stored_preferences = where(user_id: user.id, action_name:)
- default_preferences = __send__("#{action_name}_columns")
+ default_preferences = get_default_preferences(action_name, user)
filter(default_preferences, user, action_name)
default_preferences.each_with_object([]) do |(column_name, default_attributes), preferences|
stored_preference = stored_preferences.find_by(column_name:)
@@ -36,7 +37,7 @@ class ColumnPreference < ApplicationRecord
end
def self.valid_columns_for(action_name)
- __send__("#{action_name}_columns").keys.map(&:to_s)
+ get_default_preferences(action_name, Spree::User.new).keys.map(&:to_s)
end
def self.known_actions
@@ -52,4 +53,13 @@ class ColumnPreference < ApplicationRecord
default_preferences.delete(:schedules)
end
+
+ def self.get_default_preferences(action_name, user)
+ case action_name
+ when 'products_v3_index'
+ products_v3_index_columns(user)
+ else
+ __send__("#{action_name}_columns")
+ end
+ end
end
diff --git a/app/models/concerns/stock_settings_override_validation.rb b/app/models/concerns/stock_settings_override_validation.rb
index 7040cb50e0..ecc3f2ec3b 100644
--- a/app/models/concerns/stock_settings_override_validation.rb
+++ b/app/models/concerns/stock_settings_override_validation.rb
@@ -6,14 +6,14 @@
# `count_on_hand` can either be: nil or a number
#
# This means that a variant override can be in six different stock states
-# but only three of them are valid.
+# but only four of them are valid.
#
# | on_demand | count_on_hand | stock_overridden? | use_producer_stock_settings? | valid? |
# |-----------|---------------|-------------------|------------------------------|--------|
-# | 1 | nil | false | false | true |
+# | 1 | nil | true | false | true |
# | 0 | x | true | false | true |
# | nil | nil | false | true | true |
-# | 1 | x | ? | ? | false |
+# | 1 | x | true | false | true |
# | 0 | nil | ? | ? | false |
# | nil | x | ? | ? | false |
#
@@ -27,7 +27,6 @@ module StockSettingsOverrideValidation
def require_compatible_on_demand_and_count_on_hand
disallow_count_on_hand_if_using_producer_stock_settings
- disallow_count_on_hand_if_on_demand
require_count_on_hand_if_limited_stock
end
@@ -39,14 +38,6 @@ module StockSettingsOverrideValidation
errors.add(:count_on_hand, error_message)
end
- def disallow_count_on_hand_if_on_demand
- return unless on_demand? && count_on_hand.present?
-
- error_message = I18n.t("count_on_hand.on_demand_but_count_on_hand_set",
- scope: i18n_scope_for_stock_settings_override_validation_error)
- errors.add(:count_on_hand, error_message)
- end
-
def require_count_on_hand_if_limited_stock
return unless on_demand == false && count_on_hand.blank?
diff --git a/app/models/concerns/variant_stock.rb b/app/models/concerns/variant_stock.rb
index f39ab38dc9..2e5023d46c 100644
--- a/app/models/concerns/variant_stock.rb
+++ b/app/models/concerns/variant_stock.rb
@@ -96,7 +96,7 @@ module VariantStock
# Here we depend only on variant.total_on_hand and variant.on_demand.
# This way, variant_overrides only need to override variant.total_on_hand and variant.on_demand.
def fill_status(quantity)
- on_hand = if total_on_hand >= quantity || on_demand
+ on_hand = if total_on_hand.to_i >= quantity || on_demand
quantity
else
[0, total_on_hand].max
@@ -112,8 +112,7 @@ module VariantStock
#
# This enables us to override this behaviour for variant overrides
def move(quantity, originator = nil)
- # Don't change variant stock if variant is on_demand or has been deleted
- return if on_demand || deleted_at
+ return if deleted_at
raise_error_if_no_stock_item_available
diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb
index 16ecf14af8..dfee85fef6 100644
--- a/app/models/enterprise.rb
+++ b/app/models/enterprise.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: false
-require "mini_magick"
-
class Enterprise < ApplicationRecord
SELLS = %w(unspecified none own any).freeze
ENTERPRISE_SEARCH_RADIUS = 100
@@ -249,12 +247,6 @@ class Enterprise < ApplicationRecord
count(distinct: true)
end
- # Remove any unsupported HTML.
- def long_description
- HtmlSanitizer.sanitize_and_enforce_link_target_blank(super)
- end
-
- # Remove any unsupported HTML.
def long_description=(html)
super(HtmlSanitizer.sanitize_and_enforce_link_target_blank(html))
end
@@ -488,7 +480,7 @@ class Enterprise < ApplicationRecord
return unless image.variable?
image_variant_url_for(image.variant(name))
- rescue ActiveStorage::Error, MiniMagick::Error, ActionView::Template::Error => e
+ rescue StandardError => e
Bugsnag.notify "Enterprise ##{id} #{image.try(:name)} error: #{e.message}"
Rails.logger.error(e.message)
diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb
index 060f75e4f0..f87e850fdd 100644
--- a/app/models/order_cycle.rb
+++ b/app/models/order_cycle.rb
@@ -24,6 +24,7 @@ class OrderCycle < ApplicationRecord
where incoming: false
}, class_name: "Exchange", dependent: :destroy
+ has_many :orders, class_name: 'Spree::Order', dependent: :restrict_with_exception
has_many :suppliers, -> { distinct }, source: :sender, through: :cached_incoming_exchanges
has_many :distributors, -> { distinct }, source: :receiver, through: :cached_outgoing_exchanges
has_many :order_cycle_schedules, dependent: :destroy
@@ -147,17 +148,20 @@ class OrderCycle < ApplicationRecord
# Find the earliest closing times for each distributor in an active order cycle, and return
# them in the format {distributor_id => closing_time, ...}
- def self.earliest_closing_times
- Hash[
- Exchange.
- outgoing.
- joins(:order_cycle).
- merge(OrderCycle.active).
- group('exchanges.receiver_id').
- select("exchanges.receiver_id AS receiver_id,
- MIN(order_cycles.orders_close_at) AS earliest_close_at").
- map { |ex| [ex.receiver_id, ex.earliest_close_at.to_time] }
- ]
+ #
+ # Optionally, specify some distributor_ids as a parameter to scope the results
+ def self.earliest_closing_times(distributor_ids = nil)
+ cycles = Exchange.
+ outgoing.
+ joins(:order_cycle).
+ merge(OrderCycle.active).
+ group('exchanges.receiver_id')
+
+ cycles = cycles.where(receiver_id: distributor_ids) if distributor_ids.present?
+
+ cycles.pluck("exchanges.receiver_id AS receiver_id",
+ "MIN(order_cycles.orders_close_at) AS earliest_close_at")
+ .to_h
end
def attachable_distributor_payment_methods
@@ -313,6 +317,13 @@ class OrderCycle < ApplicationRecord
coordinator.sells == 'own'
end
+ def same_datetime_value(attribute, string)
+ return true if self[attribute].blank? && string.blank?
+ return false if self[attribute].blank? || string.blank?
+
+ DateTime.parse(string).to_fs(:short) == self[attribute]&.to_fs(:short)
+ end
+
private
def opening?
diff --git a/app/models/report_blob.rb b/app/models/report_blob.rb
index b9d3927b68..17fda07005 100644
--- a/app/models/report_blob.rb
+++ b/app/models/report_blob.rb
@@ -5,7 +5,7 @@ class ReportBlob < ActiveStorage::Blob
# AWS S3 limits URL expiry to one week.
LIFETIME = 1.week
- def self.create!(filename, content)
+ def self.create_locally!(filename, content)
create_and_upload!(
io: StringIO.new(content),
filename:,
@@ -15,11 +15,34 @@ class ReportBlob < ActiveStorage::Blob
)
end
+ def self.create_for_upload_later!(filename)
+ # ActiveStorage discourages modifying a blob later but we need a blob
+ # before we know anything about the report file. It enables us to use the
+ # same blob in the controller to read the result.
+ create_before_direct_upload!(
+ filename:,
+ byte_size: 0,
+ checksum: "0",
+ content_type: content_type(filename),
+ service_name: :local,
+ ).tap do |blob|
+ ActiveStorage::PurgeJob.set(wait: LIFETIME).perform_later(blob)
+ end
+ end
+
def self.content_type(filename)
MIME::Types.of(filename).first&.to_s || "application/octet-stream"
end
+ def store(content)
+ io = StringIO.new(content)
+ upload(io, identify: false)
+ save!
+ end
+
def result
+ return if checksum == "0"
+
@result ||= download.force_encoding(Encoding::UTF_8)
end
diff --git a/app/models/spree/ability.rb b/app/models/spree/ability.rb
index 4e2a8601be..34328d5389 100644
--- a/app/models/spree/ability.rb
+++ b/app/models/spree/ability.rb
@@ -29,7 +29,6 @@ module Spree
can :update, Order do |order, token|
order.user == user || (order.token && token == order.token)
end
- can [:index, :read], Product
can [:index, :read], ProductProperty
can [:index, :read], Property
can :create, Spree::User
@@ -39,7 +38,6 @@ module Spree
can [:index, :read], StockLocation
can [:index, :read], StockMovement
can [:index, :read], Taxon
- can [:index, :read], Taxonomy
can [:index, :read], Variant
can [:index, :read], Zone
end
@@ -244,8 +242,8 @@ module Spree
can [:admin, :index], ::Admin::DfcProductImportsController
# Reports page
- can [:admin, :index, :show], ::Admin::ReportsController
- can [:admin, :show, :customers, :orders_and_distributors, :group_buys, :payments,
+ can [:admin, :index, :show, :create], ::Admin::ReportsController
+ can [:admin, :show, :create, :customers, :orders_and_distributors, :group_buys, :payments,
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management,
:packing, :enterprise_fee_summary, :bulk_coop], :report
end
@@ -325,7 +323,7 @@ module Spree
end
# Reports page
- can [:admin, :index, :show], ::Admin::ReportsController
+ can [:admin, :index, :show, :create], ::Admin::ReportsController
can [:admin, :customers, :group_buys, :sales_tax, :payments,
:orders_and_distributors, :orders_and_fulfillment, :products_and_inventory,
:order_cycle_management, :xero_invoices, :enterprise_fee_summary, :bulk_coop], :report
diff --git a/app/models/spree/image.rb b/app/models/spree/image.rb
index 77a463c301..45859a6b45 100644
--- a/app/models/spree/image.rb
+++ b/app/models/spree/image.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require "mini_magick"
-
module Spree
class Image < Asset
has_one_attached :attachment, service: image_service do |attachment|
@@ -35,7 +33,7 @@ module Spree
return self.class.default_image_url(size) unless attachment.attached?
image_variant_url_for(variant(size))
- rescue ActiveStorage::Error, MiniMagick::Error, ActionView::Template::Error => e
+ rescue StandardError => e
Bugsnag.notify "Product ##{viewable_id} Image ##{id} error: #{e.message}"
Rails.logger.error(e.message)
diff --git a/app/models/spree/product.rb b/app/models/spree/product.rb
index d484b6d123..d4872b3e84 100755
--- a/app/models/spree/product.rb
+++ b/app/models/spree/product.rb
@@ -263,10 +263,12 @@ module Spree
# Format as per WeightsAndMeasures (todo: re-orgnaise maybe after product/variant refactor)
def variant_unit_with_scale
+ # Our code is based upon English based number formatting with a period `.`
scale_clean = ActiveSupport::NumberHelper.number_to_rounded(variant_unit_scale,
precision: nil,
significant: false,
- strip_insignificant_zeros: true)
+ strip_insignificant_zeros: true,
+ locale: :en)
[variant_unit, scale_clean].compact_blank.join("_")
end
@@ -295,14 +297,8 @@ module Spree
# eg clone product. Will raise error if clonning a product with no variant
return if variants.first&.valid?
- unless Spree::Taxon.find_by(id: primary_taxon_id)
- errors.add(:primary_taxon_id,
- I18n.t('activerecord.errors.models.spree/product.must_exist'))
- end
- return if Enterprise.find_by(id: supplier_id)
-
- errors.add(:supplier_id,
- I18n.t('activerecord.errors.models.spree/product.must_exist'))
+ errors.add(:primary_taxon_id, :blank) unless Spree::Taxon.find_by(id: primary_taxon_id)
+ errors.add(:supplier_id, :blank) unless Enterprise.find_by(id: supplier_id)
end
def update_units
diff --git a/app/models/spree/shipping_method.rb b/app/models/spree/shipping_method.rb
index 68f2d19015..204dbc8b73 100644
--- a/app/models/spree/shipping_method.rb
+++ b/app/models/spree/shipping_method.rb
@@ -87,16 +87,20 @@ module Spree
# Return the services (pickup, delivery) that different distributors provide, in the format:
# {distributor_id => {pickup: true, delivery: false}, ...}
- def self.services
- Hash[
- Spree::ShippingMethod.
- joins(:distributor_shipping_methods).
- group('distributor_id').
- select("distributor_id").
- select("BOOL_OR(spree_shipping_methods.require_ship_address = 'f') AS pickup").
- select("BOOL_OR(spree_shipping_methods.require_ship_address = 't') AS delivery").
- map { |sm| [sm.distributor_id.to_i, { pickup: sm.pickup, delivery: sm.delivery }] }
- ]
+ #
+ # Optionally, specify some distributor_ids as a parameter to scope the results
+ def self.services(distributor_ids = nil)
+ methods = Spree::ShippingMethod.joins(:distributor_shipping_methods).group('distributor_id')
+
+ if distributor_ids.present?
+ methods = methods.where(distributor_shipping_methods: { distributor_id: distributor_ids })
+ end
+
+ methods.
+ pluck(Arel.sql("distributor_id"),
+ Arel.sql("BOOL_OR(spree_shipping_methods.require_ship_address = 'f') AS pickup"),
+ Arel.sql("BOOL_OR(spree_shipping_methods.require_ship_address = 't') AS delivery")).
+ to_h { |(distributor_id, pickup, delivery)| [distributor_id.to_i, { pickup:, delivery: }] }
end
def self.backend
diff --git a/app/models/spree/taxon.rb b/app/models/spree/taxon.rb
index bc0b85371a..09c772fdf0 100644
--- a/app/models/spree/taxon.rb
+++ b/app/models/spree/taxon.rb
@@ -2,19 +2,11 @@
module Spree
class Taxon < ApplicationRecord
- self.belongs_to_required_by_default = false
-
- acts_as_nested_set dependent: :destroy
-
- belongs_to :taxonomy, class_name: 'Spree::Taxonomy', touch: true
-
has_many :variants, class_name: "Spree::Variant", foreign_key: "primary_taxon_id",
inverse_of: :primary_taxon, dependent: :restrict_with_error
has_many :products, through: :variants, dependent: nil
- before_create :set_permalink
-
validates :name, presence: true
# Indicate which filters should be used for this taxon
@@ -31,40 +23,21 @@ module Spree
end
end
- def set_permalink
- if parent.present?
- self.permalink = [parent.permalink, permalink_end].join('/')
- elsif permalink.blank?
- self.permalink = UrlGenerator.to_url(name)
- end
- end
-
- # For #2759
- def to_param
- permalink
- end
-
- def pretty_name
- ancestor_chain = ancestors.inject("") do |name, ancestor|
- name + "#{ancestor.name} -> "
- end
- ancestor_chain + name.to_s
- end
-
# Find all the taxons of supplied products for each enterprise, indexed by enterprise.
# Format: {enterprise_id => [taxon_id, ...]}
- def self.supplied_taxons
- taxons = {}
+ #
+ # Optionally, specify some enterprise_ids to scope the results
+ def self.supplied_taxons(enterprise_ids = nil)
+ taxons = Spree::Taxon.joins(variants: :supplier)
- Spree::Taxon.
- joins(variants: :supplier).
- select('spree_taxons.*, enterprises.id AS enterprise_id').
- each do |t|
- taxons[t.enterprise_id.to_i] ||= Set.new
- taxons[t.enterprise_id.to_i] << t.id
- end
+ taxons = taxons.where(enterprises: { id: enterprise_ids }) if enterprise_ids.present?
taxons
+ .pluck('spree_taxons.id, enterprises.id AS enterprise_id')
+ .each_with_object({}) do |(taxon_id, enterprise_id), collection|
+ collection[enterprise_id.to_i] ||= Set.new
+ collection[enterprise_id.to_i] << taxon_id
+ end
end
# Find all the taxons of distributed products for each enterprise, indexed by enterprise.
@@ -72,7 +45,9 @@ module Spree
# or :current taxons (distributed in an open order cycle).
#
# Format: {enterprise_id => [taxon_id, ...]}
- def self.distributed_taxons(which_taxons = :all)
+ #
+ # Optionally, specify some enterprise_ids to scope the results
+ def self.distributed_taxons(which_taxons = :all, enterprise_ids = nil)
ents_and_vars = ExchangeVariant.joins(exchange: :order_cycle).merge(Exchange.outgoing)
.select("DISTINCT variant_id, receiver_id AS enterprise_id")
@@ -85,18 +60,14 @@ module Spree
INNER JOIN (#{ents_and_vars.to_sql}) AS ents_and_vars
ON spree_variants.id = ents_and_vars.variant_id")
+ if enterprise_ids.present?
+ taxons = taxons.where(ents_and_vars: { enterprise_id: enterprise_ids })
+ end
+
taxons.each_with_object({}) do |t, ts|
ts[t.enterprise_id.to_i] ||= Set.new
ts[t.enterprise_id.to_i] << t.id
end
end
-
- private
-
- def permalink_end
- return UrlGenerator.to_url(name) if permalink.blank?
-
- permalink.split('/').last
- end
end
end
diff --git a/app/models/spree/taxonomy.rb b/app/models/spree/taxonomy.rb
deleted file mode 100644
index a8600caa27..0000000000
--- a/app/models/spree/taxonomy.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-# frozen_string_literal: true
-
-module Spree
- class Taxonomy < ApplicationRecord
- validates :name, presence: true
-
- has_many :taxons, dependent: :nullify
- has_one :root, -> { where parent_id: nil }, class_name: "Spree::Taxon", dependent: :destroy
-
- after_save :set_name
-
- default_scope -> { order("#{table_name}.position") }
-
- private
-
- def set_name
- if root
- root.update_columns(
- name:,
- updated_at: Time.zone.now
- )
- else
- self.root = Taxon.create!(taxonomy_id: id, name:)
- end
- end
- end
-end
diff --git a/app/models/spree/user.rb b/app/models/spree/user.rb
index bef7609933..9eae2b5074 100644
--- a/app/models/spree/user.rb
+++ b/app/models/spree/user.rb
@@ -42,6 +42,7 @@ module Spree
has_many :credit_cards, dependent: :destroy
has_many :report_rendering_options, class_name: "::ReportRenderingOptions", dependent: :destroy
has_many :webhook_endpoints, dependent: :destroy
+ has_many :column_preferences, dependent: :destroy
has_one :oidc_account, dependent: :destroy
accepts_nested_attributes_for :enterprise_roles, allow_destroy: true
diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb
index cabc309a93..79a28508f2 100644
--- a/app/models/variant_override.rb
+++ b/app/models/variant_override.rb
@@ -15,7 +15,9 @@ class VariantOverride < ApplicationRecord
# Need to ensure this can be set by the user.
validates :default_stock, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
validates :price, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
- validates :count_on_hand, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true
+ validates :count_on_hand, numericality: {
+ greater_than_or_equal_to: 0, unless: :on_demand?
+ }, allow_nil: true
default_scope { where(permission_revoked_at: nil) }
@@ -36,9 +38,8 @@ class VariantOverride < ApplicationRecord
end
def stock_overridden?
- # If count_on_hand is present, it means on_demand is false
- # See StockSettingsOverrideValidation for details
- count_on_hand.present?
+ # Testing for not nil because for a boolean `false.present?` is false.
+ !on_demand.nil? || !count_on_hand.nil?
end
def use_producer_stock_settings?
diff --git a/app/serializers/api/admin/taxon_serializer.rb b/app/serializers/api/admin/taxon_serializer.rb
index cb18665f56..1a101d4cdc 100644
--- a/app/serializers/api/admin/taxon_serializer.rb
+++ b/app/serializers/api/admin/taxon_serializer.rb
@@ -3,7 +3,7 @@
module Api
module Admin
class TaxonSerializer < ActiveModel::Serializer
- attributes :id, :name, :pretty_name
+ attributes :id, :name
end
end
end
diff --git a/app/serializers/api/cached_enterprise_serializer.rb b/app/serializers/api/cached_enterprise_serializer.rb
index d9e08a0155..8210a85621 100644
--- a/app/serializers/api/cached_enterprise_serializer.rb
+++ b/app/serializers/api/cached_enterprise_serializer.rb
@@ -95,9 +95,7 @@ module Api
.merge(Exchange.to_enterprise(enterprise))
.select('DISTINCT spree_properties.*')
- return properties.merge(OrderCycle.active) if active
-
- properties
+ properties.merge(OrderCycle.active)
end
def distributed_producer_properties
@@ -106,16 +104,14 @@ module Api
properties = Spree::Property
.joins(
producer_properties: {
- producer: { supplied_products: { variants: { exchanges: :order_cycle } } }
+ producer: { supplied_variants: { exchanges: :order_cycle } }
}
)
.merge(Exchange.outgoing)
.merge(Exchange.to_enterprise(enterprise))
.select('DISTINCT spree_properties.*')
- return properties.merge(OrderCycle.active) if active
-
- properties
+ properties.merge(OrderCycle.active)
end
def active
diff --git a/app/serializers/api/taxon_serializer.rb b/app/serializers/api/taxon_serializer.rb
index 38eb2bf3dd..fc986a6708 100644
--- a/app/serializers/api/taxon_serializer.rb
+++ b/app/serializers/api/taxon_serializer.rb
@@ -4,5 +4,5 @@ class Api::TaxonSerializer < ActiveModel::Serializer
cached
delegate :cache_key, to: :object
- attributes :id, :name, :permalink, :pretty_name, :position, :parent_id, :taxonomy_id
+ attributes :id, :name, :permalink, :position
end
diff --git a/app/serializers/api/uncached_enterprise_serializer.rb b/app/serializers/api/uncached_enterprise_serializer.rb
index d92db46d28..c1d620facd 100644
--- a/app/serializers/api/uncached_enterprise_serializer.rb
+++ b/app/serializers/api/uncached_enterprise_serializer.rb
@@ -7,7 +7,7 @@ module Api
attributes :orders_close_at, :active
def orders_close_at
- options[:data].earliest_closing_times[object.id]
+ options[:data].earliest_closing_times[object.id]&.to_time
end
def active
diff --git a/app/services/order_cycles/form_service.rb b/app/services/order_cycles/form_service.rb
index 0b2f62d988..16f9f09755 100644
--- a/app/services/order_cycles/form_service.rb
+++ b/app/services/order_cycles/form_service.rb
@@ -7,6 +7,8 @@ module OrderCycles
class FormService
def initialize(order_cycle, order_cycle_params, user)
@order_cycle = order_cycle
+ @confirm_datetime_change = order_cycle_params.delete :confirm_datetime_change
+ @error_class = order_cycle_params.delete :error_class
@order_cycle_params = order_cycle_params
@specified_params = order_cycle_params.keys
@user = user
@@ -21,6 +23,9 @@ module OrderCycles
end
def save
+ # Check that order cycle datetime values changed if it has existing orders
+ verify_datetime_change!
+
schedule_ids = build_schedule_ids
order_cycle.assign_attributes(order_cycle_params)
return false unless order_cycle.valid?
@@ -229,5 +234,16 @@ module OrderCycles
DistributorShippingMethod.where(distributor_id: user_distributors_ids)
.pluck(:id)
end
+
+ def verify_datetime_change!
+ return unless @confirm_datetime_change
+ return unless @order_cycle.orders.exists?
+ return if @order_cycle.same_datetime_value(:orders_open_at,
+ @order_cycle_params[:orders_open_at]) &&
+ @order_cycle.same_datetime_value(:orders_close_at,
+ @order_cycle_params[:orders_close_at])
+
+ raise @error_class
+ end
end
end
diff --git a/app/services/permitted_attributes/product.rb b/app/services/permitted_attributes/product.rb
index f080f2b730..716549724d 100644
--- a/app/services/permitted_attributes/product.rb
+++ b/app/services/permitted_attributes/product.rb
@@ -9,7 +9,7 @@ module PermittedAttributes
:unit_description, :variant_unit_name,
:display_as, :sku, :group_buy, :group_buy_unit_size,
:taxon_ids, :primary_taxon_id, :tax_category_id, :supplier_id,
- :meta_keywords, :notes, :inherits_properties,
+ :meta_keywords, :notes, :inherits_properties, :shipping_category_id,
{ product_properties_attributes: [:id, :property_name, :value],
variants_attributes: [PermittedAttributes::Variant.attributes],
image_attributes: [:attachment] }
diff --git a/app/services/sets/order_cycle_set.rb b/app/services/sets/order_cycle_set.rb
index 663f684062..9d2e2dfee5 100644
--- a/app/services/sets/order_cycle_set.rb
+++ b/app/services/sets/order_cycle_set.rb
@@ -3,7 +3,31 @@
module Sets
class OrderCycleSet < ModelSet
def initialize(collection, attributes = {})
+ @confirm_datetime_change = attributes.delete :confirm_datetime_change
+ @error_class = attributes.delete :error_class
+
super(OrderCycle, collection, attributes)
end
+
+ def process(order_cycle, attributes)
+ if @confirm_datetime_change &&
+ order_cycle.orders.exists? &&
+ datetime_value_changed(order_cycle, attributes)
+ raise @error_class
+ end
+
+ super
+ end
+
+ private
+
+ def datetime_value_changed(order_cycle, attributes)
+ # return true if either key is present in params and change in values detected
+ return true if attributes.key?(:orders_open_at) &&
+ !order_cycle.same_datetime_value(:orders_open_at, attributes[:orders_open_at])
+
+ attributes.key?(:orders_close_at) &&
+ !order_cycle.same_datetime_value(:orders_close_at, attributes[:orders_close_at])
+ end
end
end
diff --git a/app/services/shops_list_service.rb b/app/services/shops_list_service.rb
index 0e4d42f99e..e145eedc93 100644
--- a/app/services/shops_list_service.rb
+++ b/app/services/shops_list_service.rb
@@ -1,12 +1,17 @@
# frozen_string_literal: true
class ShopsListService
+ # shops that are ready for checkout, and have an order cycle that is currently open
def open_shops
- shops_list.ready_for_checkout.all
+ shops_list.
+ ready_for_checkout.
+ distributors_with_active_order_cycles
end
+ # shops that are either not ready for checkout, or don't have an open order cycle; the inverse of
+ # #open_shops
def closed_shops
- shops_list.not_ready_for_checkout.all
+ shops_list.where.not(id: open_shops.reselect("enterprises.id"))
end
private
diff --git a/app/services/weights_and_measures.rb b/app/services/weights_and_measures.rb
index 170dacb208..e285a0baac 100644
--- a/app/services/weights_and_measures.rb
+++ b/app/services/weights_and_measures.rb
@@ -26,9 +26,15 @@ class WeightsAndMeasures
def self.variant_unit_options
available_units_sorted.flat_map do |measurement, measurement_info|
measurement_info.filter_map do |scale, unit_info|
+ # Our code is based upon English based number formatting
+ # Some language locales like +hu+ uses a comma(,) for decimal separator
+ # While in English, decimal separator is represented by a period.
+ # e.g. en: 0.001, hu: 0,001
+ # Hence the results become "weight_0,001" for hu while or code recognizes "weight_0.001"
scale_clean =
ActiveSupport::NumberHelper.number_to_rounded(scale, precision: nil, significant: false,
- strip_insignificant_zeros: true)
+ strip_insignificant_zeros: true,
+ locale: :en)
[
"#{I18n.t(measurement)} (#{unit_info['name']})", # Label (eg "Weight (g)")
"#{measurement}_#{scale_clean}", # Scale ID (eg "weight_1")
diff --git a/app/views/admin/order_cycles/_date_time_warning_modal_content.html.haml b/app/views/admin/order_cycles/_date_time_warning_modal_content.html.haml
new file mode 100644
index 0000000000..8742d80fad
--- /dev/null
+++ b/app/views/admin/order_cycles/_date_time_warning_modal_content.html.haml
@@ -0,0 +1,19 @@
+.flex-column-gap-1
+ %h6
+ = t('.title')
+ %div{ style: 'font-size: 1rem;' }
+ = t('.content')
+%p.modal-actions.justify-end.gap-1
+ - if action == 'simple_update'
+ %button.button.secondary{ "ng-click": "submit($event, null)", type: "button", style: "display: none;", data: { action: 'click->modal#close', 'trigger-action': 'save' } }
+ = t('.proceed')
+ %button.button.secondary{ "ng-click": "submit($event, '#{main_app.admin_order_cycle_incoming_path(@order_cycle)}')", type: "button", style: "display: none;", data: { action: 'click->modal#close', 'trigger-action': 'saveAndNext' } }
+ = t('.proceed')
+ %button.button.secondary{ "ng-click": "submit($event, '#{main_app.admin_order_cycles_path}')", type: "button", style: "display: none;", data: { action: 'click->modal#close', 'trigger-action': 'saveAndBack' } }
+ = t('.proceed')
+ = link_to t('.cancel'), admin_order_cycles_path, id: 'cancel', class: 'button primary', data: { 'order-cycle-form-target': 'cancel' }
+ - if action == 'bulk_update'
+ %button.button.secondary{ "ng-click": "saveAll($event)", type: "button", style: "display: none;", data: { action: 'click->modal#close', trigger_action: 'bulk_save' } }
+ = t('.proceed')
+ %button.button.primary{ type: "button", 'data-action': 'click->modal#close' }
+ = t('.cancel')
\ No newline at end of file
diff --git a/app/views/admin/order_cycles/edit.html.haml b/app/views/admin/order_cycles/edit.html.haml
index f6f3bc6f49..39e3305b18 100644
--- a/app/views/admin/order_cycles/edit.html.haml
+++ b/app/views/admin/order_cycles/edit.html.haml
@@ -16,18 +16,25 @@
- ng_controller = @order_cycle.simple? ? 'AdminSimpleEditOrderCycleCtrl' : 'AdminEditOrderCycleCtrl'
= admin_inject_order_cycle_instance(@order_cycle)
-= 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|
+%div{ data: { controller: 'order-cycle-form' } }
+ = 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)", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid", data: { confirm: "true", 'trigger-action': 'save' } }
+ - 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}')", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid", data: { confirm: "true", 'trigger-action': 'saveAndBack' } }
+ - else
+ %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", data: { confirm: "true", 'trigger-action': 'saveAndNext' } }
+ %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}')" }
- %save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
- %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}')", "ng-disabled": "!order_cycle_form.$dirty || order_cycle_form.$invalid" }
+ = render 'simple_form', f: f
- else
- %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}')" }
+ = render 'form', f: f
- - if @order_cycle.simple?
- = render 'simple_form', f: f
- - else
- = render 'form', f: f
+ %div.warning-modal{ data: { controller: 'modal modal-link', 'modal-link-target-value': "linked-order-warning-modal" } }
+ %button.modal-target-trigger{ type: 'button', data: { 'action': 'modal-link#open' }, style: 'display: none;' }
+ = render ModalComponent.new(id: "linked-order-warning-modal", close_button: false) do
+ .content.flex-column.gap-2
+ = render 'date_time_warning_modal_content', action: 'simple_update'
\ No newline at end of file
diff --git a/app/views/admin/order_cycles/index.html.haml b/app/views/admin/order_cycles/index.html.haml
index db6c544286..9e593e9245 100644
--- a/app/views/admin/order_cycles/index.html.haml
+++ b/app/views/admin/order_cycles/index.html.haml
@@ -23,12 +23,20 @@
.thirteen.columns.alpha
%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()", "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
- = render 'admin/order_cycles/loading_flash'
- = render 'admin/order_cycles/show_more'
+ %div{ data: { controller: 'order-cycle-form' } }
+ %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($event)", "ng-disabled": "!order_cycles_form.$dirty",
+ data: { confirm: "true", 'trigger-action': 'bulk_save' } }
+ %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
+ = render 'admin/order_cycles/loading_flash'
+ = render 'admin/order_cycles/show_more'
+
+ %div.warning-modal{ data: { controller: 'modal modal-link', 'modal-link-target-value': "linked-order-warning-modal" } }
+ %button.modal-target-trigger{ type: 'button', data: { 'action': 'modal-link#open' }, style: 'display: none;' }
+ = render ModalComponent.new(id: "linked-order-warning-modal", close_button: false) do
+ .content.flex-column.gap-2
+ = render 'date_time_warning_modal_content', action: 'bulk_update'
diff --git a/app/views/admin/products_v3/_product_row.html.haml b/app/views/admin/products_v3/_product_row.html.haml
index f5c4fd8b5d..edd9d406b6 100644
--- a/app/views/admin/products_v3/_product_row.html.haml
+++ b/app/views/admin/products_v3/_product_row.html.haml
@@ -25,7 +25,7 @@
-# empty
%td.col-on_hand.align-right
-# empty
-%td.col-on_hand.align-right
+%td.col-producer.align-right
-# empty
%td.col-category.align-left
-# empty
@@ -40,3 +40,4 @@
"data-modal-link-target-value": "product-delete-modal", "class": "delete",
"data-modal-link-modal-dataset-value": {'data-delete-path': admin_product_destroy_path(product)}.to_json }
= t('admin.products_page.actions.delete')
+ = link_to t('admin.products_page.actions.preview'), admin_product_preview_path(product), {"data-turbo-stream": "" }
diff --git a/app/views/admin/products_v3/_product_variant_row.html.haml b/app/views/admin/products_v3/_product_variant_row.html.haml
index b41e7c56b5..12b6702cba 100644
--- a/app/views/admin/products_v3/_product_variant_row.html.haml
+++ b/app/views/admin/products_v3/_product_variant_row.html.haml
@@ -11,7 +11,7 @@
%tr.condensed{ id: dom_id(variant), 'data-controller': "variant", 'class': "nested-form-wrapper", 'data-new-record': variant.new_record? ? "true" : false }
= render partial: 'variant_row', locals: { variant:, f: variant_form, category_options:, tax_category_options:, producer_options: }
- = form.fields_for("products][#{product_index}][variants_attributes][NEW_RECORD", prepare_new_variant(product)) do |new_variant_form|
+ = form.fields_for("products][#{product_index}][variants_attributes][NEW_RECORD", prepare_new_variant(product, producer_options)) do |new_variant_form|
%template{ 'data-nested-form-target': "template" }
%tr.condensed{ 'data-controller': "variant", 'class': "nested-form-wrapper", 'data-new-record': "true" }
= render partial: 'variant_row', locals: { variant: new_variant_form.object, f: new_variant_form, category_options:, tax_category_options:, producer_options: }
diff --git a/app/views/admin/products_v3/_sort.html.haml b/app/views/admin/products_v3/_sort.html.haml
index 4cb5f29ee9..2b25644639 100644
--- a/app/views/admin/products_v3/_sort.html.haml
+++ b/app/views/admin/products_v3/_sort.html.haml
@@ -1,7 +1,7 @@
#sort
%div.pagination-description
- if pagy.present?
- = t(".pagination.total_html", total: pagy.count, from: pagy.from, to: pagy.to)
+ = t(".pagination.products_total_html", count: pagy.count, from: pagy.from, to: pagy.to)
- if search_term.present? || producer_id.present? || category_id.present?
%a{ href: url_for(page: 1), class: "button disruptive", data: { 'turbo-frame': "_self", 'turbo-action': "advance" } }
diff --git a/app/views/admin/products_v3/_table.html.haml b/app/views/admin/products_v3/_table.html.haml
index e04f33b00a..71e777ba13 100644
--- a/app/views/admin/products_v3/_table.html.haml
+++ b/app/views/admin/products_v3/_table.html.haml
@@ -13,16 +13,16 @@
= hidden_field_tag :producer_id, @producer_id
= hidden_field_tag :category_id, @category_id
- %table.products{ 'data-column-preferences-target': "table" }
+ %table.products{ 'data-column-preferences-target': "table", class: (hide_producer_column?(producer_options) ? 'hide-producer' : '') }
%colgroup
-# The `min-width` property works in Chrome but not Firefox so is considered progressive enhancement.
- %col.col-image{ width:"56px" }= # (image size + padding)
+ %col.col-image{ width:"44px" }= # (image size + padding)
%col.col-name{ style:"min-width: 6em" }= # (grow to fill)
%col.col-sku{ width:"8%", style:"min-width: 6em" }
%col.col-unit_scale{ width:"8%" }
%col.col-unit{ width:"8%" }
- %col.col-price{ width:"5%", style:"min-width: 5em" }
- %col.col-on_hand{ width:"10%"}
+ %col.col-price{ width:"10%", style:"min-width: 5em" }
+ %col.col-on_hand{ width:"8%" }
%col.col-producer{ style:"min-width: 6em" }= # (grow to fill)
%col.col-category{ width:"8%" }
%col.col-tax_category{ width:"8%" }
diff --git a/app/views/admin/products_v3/index.html.haml b/app/views/admin/products_v3/index.html.haml
index 668a8527a4..fed068a609 100644
--- a/app/views/admin/products_v3/index.html.haml
+++ b/app/views/admin/products_v3/index.html.haml
@@ -20,3 +20,4 @@
= render partial: 'delete_modal', locals: { object_type: }
#modal-component
#edit_image_modal
+ #product-preview-modal-container
diff --git a/app/views/admin/products_v3/product_preview.turbo_stream.haml b/app/views/admin/products_v3/product_preview.turbo_stream.haml
new file mode 100644
index 0000000000..61935d012c
--- /dev/null
+++ b/app/views/admin/products_v3/product_preview.turbo_stream.haml
@@ -0,0 +1,119 @@
+= turbo_stream.update "product-preview-modal-container" do
+ = render ModalComponent.new(id: "product-preview-modal", instant: true, modal_class: "big") do
+ #product-preview{ "data-controller": "tabs" }
+ %h1
+ = t("admin.products_page.product_preview.product_preview")
+ %dl.admin-tabs
+ %dd
+ %a{ data: { "tabs-target": "tab", "action": "tabs#select" } }
+ = t("admin.products_page.product_preview.shop_tab")
+ %dd
+ %a{ data: { "tabs-target": "tab", "action": "tabs#select" } }
+ = t("admin.products_page.product_preview.product_details_tab")
+ .tabs-content
+ .content.active
+ %div{ data: { "tabs-target": "content" } }
+ .product-thumb
+ %a
+ - if @product.group_buy
+ %span.product-thumb__bulk-label
+ = t(".bulk")
+ = image_tag @product.image&.url(:small) || Spree::Image.default_image_url(:small)
+
+ .summary
+ .summary-header
+ %h3
+ %a
+ %span
+ = @product.name
+ - if @product.description
+ .product-description{ "data-controller": "add-blank-to-link" }
+ - # description is sanitized in Spree::Product#description method
+ = @product.description.html_safe
+
+ - if @product.variants.first.supplier.visible
+ %div
+ .product-producer
+ = t :products_from
+ %span
+ %a
+ = @product.variants.first.supplier.name
+ .product-properties.filter-shopfront.property-selectors
+ .filter-shopfront.property-selectors.inline-block
+ %ul
+ - @product.properties_including_inherited.each do |property|
+ %li
+ - if property[:value].present?
+ = render AdminTooltipComponent.new(text: property[:value], link_text: property[:name], placement: "bottom")
+ - else
+ %a
+ %span
+ = property[:name]
+ .shop-variants
+ - @product.variants.sort { |v1, v2| v1.name_to_display <=> v2.name_to_display }.sort { |v1, v2| v1.unit_value <=> v2.unit_value }.each do |variant|
+ .variants.row
+ .small-3.columns.variant-name
+ - if variant.display_name.present?
+ .inline
+ = variant.display_name
+ .variant-unit
+ = variant.unit_to_display
+ .small-4.medium-3.columns.variant-price
+ = number_to_currency(variant.price)
+ .unit-price.variant-unit-price
+ = render AdminTooltipComponent.new(text: t("js.shopfront.unit_price_tooltip"), link_text: "", placement: "top", link_class: "question-mark-icon")
+ - # TODO use an helper
+ - unit_price = UnitPrice.new(variant)
+ - price_per_unit = variant.price / (unit_price.denominator || 1)
+ = "#{number_to_currency(price_per_unit)} / #{unit_price.unit}".html_safe
+
+
+ .medium-3.columns.total-price
+ %span
+ = number_to_currency(0.00)
+ .small-5.medium-3.large-3.columns.variant-quantity-column.text-right
+ .variant-quantity-inputs
+ %button.add-variant
+ = t("js.shopfront.variant.add_to_cart")
+
+ - # TODO can't check the shop preferrence here, display by default ?
+ - if !variant.on_demand && variant.on_hand <= 3
+ .variant-remaining-stock
+ = t("js.shopfront.variant.remaining_in_stock", quantity: variant.on_hand)
+
+ %div{ data: { "tabs-target": "content" } }
+ .row
+ .columns.small-12.medium-6.large-6.product-header
+ %h3
+ = @product.name
+ %span
+ %em
+ = t("products_from")
+ %span
+ = @product.variants.first.supplier.name
+
+ %br
+
+ .filter-shopfront.property-selectors.inline-block
+ %ul
+ - @product.properties_including_inherited.each do |property|
+ %li
+ - if property[:value].present?
+ = render AdminTooltipComponent.new(text: property[:value], link_text: property[:name], placement: "bottom")
+ - else
+ %a
+ %span
+ = property[:name]
+
+
+ - if @product.description
+ .product-description{ 'data-controller': "add-blank-to-link" }
+ %p.text-small
+ - # description is sanitized in Spree::Product#description method
+ = @product.description.html_safe
+
+ .columns.small-12.medium-6.large-6.product-img
+ - if @product.image
+ %img{ src: @product.image.url(:large) }
+ -else
+ %img.placeholder{ src: Spree::Image.default_image_url(:large) }
diff --git a/app/views/admin/reports/_fallback_display.html.haml b/app/views/admin/reports/_fallback_display.html.haml
new file mode 100644
index 0000000000..cfac68c742
--- /dev/null
+++ b/app/views/admin/reports/_fallback_display.html.haml
@@ -0,0 +1,47 @@
+.download.hidden
+ = link_to t("admin.reports.download.button"), file_url, target: "_blank", class: "button icon icon-file"
+
+:javascript
+ (function () {
+ const tryDownload = function() {
+ const link = document.querySelector(".download a");
+
+ // If the report was already rendered via web sockets:
+ if (link == null) return;
+
+ fetch(link.href).then((response) => {
+ if (response.ok) {
+ response.blob().then((blob) => blob.text()).then((text) => {
+ const loading = document.querySelector(".loading");
+
+ if (loading == null) return;
+
+ loading.remove();
+ document.querySelector("#report-go button").disabled = false;
+
+ if (link.href.endsWith(".html")) {
+ // This replaces the hidden download button with the report:
+ link.parentElement.outerHTML = text;
+ } else {
+ // Or just show the download button when it's ready:
+ document.querySelector(".download").classList.remove("hidden")
+ }
+ });
+ } else {
+ setTimeout(tryDownload, 2000);
+ }
+ });
+ }
+
+ /*
+ A lot of reports are rendered within 250ms. Others take at least
+ 2.5 seconds. There's a big gap in between. Observed on:
+ https://openfoodnetwork.org.au/admin/sidekiq/metrics/ReportJob?period=8h
+ https://openfoodnetwork.org.uk/admin/sidekiq/metrics/ReportJob?period=8h
+ https://coopcircuits.fr/admin/sidekiq/metrics/ReportJob?period=8h
+
+ But let's leave the timed response to websockets for now and just poll
+ as a backup mechanism.
+ */
+ setTimeout(tryDownload, 3000);
+ })();
diff --git a/app/views/admin/reports/create.turbo_stream.haml b/app/views/admin/reports/create.turbo_stream.haml
new file mode 100644
index 0000000000..ecfa4f13a0
--- /dev/null
+++ b/app/views/admin/reports/create.turbo_stream.haml
@@ -0,0 +1,6 @@
+= turbo_stream.update "report-go" do
+ = button t(:go), "report__submit-btn", "submit", disabled: true
+= turbo_stream.update "report-table" do
+ = render "admin/reports/loading"
+ = render "admin/reports/fallback_display", file_url: @blob.expiring_service_url
+= turbo_stream.scroll_into_view("#report-table", behavior: "smooth")
diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml
index bc0b767f62..038eed9070 100644
--- a/app/views/admin/reports/show.html.haml
+++ b/app/views/admin/reports/show.html.haml
@@ -3,7 +3,7 @@
- content_for :minimal_js, true
-= form_for @report.search, { url: url_for, data: { remote: "true" } } do |f|
+= form_for @report.search, { url: url_for, data: { turbo: "true" } } do |f|
= hidden_field_tag "uuid", request.uuid
%fieldset.no-border-bottom.print-hidden
diff --git a/app/views/admin/shared/_tooltip.html.haml b/app/views/admin/shared/_tooltip.html.haml
deleted file mode 100644
index 6e28c08c43..0000000000
--- a/app/views/admin/shared/_tooltip.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-%div{"data-controller": "tooltip"}
- %a{"data-tooltip-target": "element", href: link, class: link_class}
- = link_text
- .tooltip-container
- .tooltip{"data-tooltip-target": "tooltip"}
- = sanitize tooltip_text
- .arrow{"data-tooltip-target": "arrow"}
diff --git a/app/views/admin/shared/_whats_this_tooltip.html.haml b/app/views/admin/shared/_whats_this_tooltip.html.haml
index d63fa41768..73d4a21d51 100644
--- a/app/views/admin/shared/_whats_this_tooltip.html.haml
+++ b/app/views/admin/shared/_whats_this_tooltip.html.haml
@@ -1 +1 @@
-= render partial: 'admin/shared/tooltip', locals: {link_class: "" ,link: nil, link_text: t('admin.whats_this'), tooltip_text: tooltip_text}
+= render AdminTooltipComponent.new(text: tooltip_text, link_text: t('admin.whats_this'), link: nil)
diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml
index 0a70687f14..12c654b3d1 100644
--- a/app/views/layouts/mailer.html.haml
+++ b/app/views/layouts/mailer.html.haml
@@ -5,7 +5,7 @@
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%title
= Spree::Config[:site_name]
- = stylesheet_pack_tag 'mail'
+ = stylesheet_link_tag 'mail'
%body{:bgcolor => "#FFFFFF" }
- unless @hide_ofn_navigation
%table.head-wrap{:bgcolor => "#f2f2f2"}
diff --git a/app/views/shop/products/_form.html.haml b/app/views/shop/products/_form.html.haml
index b40ea8255b..9d2679abc2 100644
--- a/app/views/shop/products/_form.html.haml
+++ b/app/views/shop/products/_form.html.haml
@@ -1,3 +1,4 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
= cache_with_locale do
%form{action: main_app.cart_path}
%products{"ng-init" => "refreshStaleData()", "ng-show" => "order_cycle.order_cycle_id != null", "ng-cloak" => true }
diff --git a/app/views/shop/products/_shop_variant.html.haml b/app/views/shop/products/_shop_variant.html.haml
index b6e91c8c2f..7aa1eb9354 100644
--- a/app/views/shop/products/_shop_variant.html.haml
+++ b/app/views/shop/products/_shop_variant.html.haml
@@ -1,8 +1,9 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
= cache_with_locale do
- .small-4.medium-4.large-5.columns.variant-name
+ .small-3.columns.variant-name
.inline{"ng-if" => "::variant.display_name"} {{ ::variant.display_name }}
.variant-unit {{ ::variant.unit_to_display }}
- .small-3.medium-3.large-2.columns.variant-price
+ .small-4.medium-3.columns.variant-price
%price-breakdown{"price-breakdown" => "_", variant: "variant",
"price-breakdown-append-to-body" => "true",
"price-breakdown-placement" => "bottom",
@@ -16,7 +17,7 @@
key: "'js.shopfront.unit_price_tooltip'"}
{{ variant.unit_price_price | localizeCurrency }} / {{ variant.unit_price_unit }}
- .medium-2.large-2.columns.total-price
+ .medium-3.columns.total-price
%span{"ng-class" => "{filled: variant.line_item.total_price}"}
{{ variant.line_item.total_price | localizeCurrency }}
= render partial: "shop/products/shop_variant_no_group_buy"
diff --git a/app/views/shop/products/_shop_variant_no_group_buy.html.haml b/app/views/shop/products/_shop_variant_no_group_buy.html.haml
index 20fbb09901..b9c7280d43 100644
--- a/app/views/shop/products/_shop_variant_no_group_buy.html.haml
+++ b/app/views/shop/products/_shop_variant_no_group_buy.html.haml
@@ -1,3 +1,4 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
= cache_with_locale do
.small-5.medium-3.large-3.columns.variant-quantity-column.text-right{"ng-if" => "::!variant.product.group_buy"}
diff --git a/app/views/shop/products/_shop_variant_with_group_buy.html.haml b/app/views/shop/products/_shop_variant_with_group_buy.html.haml
index 50b4812e5c..07e325a405 100644
--- a/app/views/shop/products/_shop_variant_with_group_buy.html.haml
+++ b/app/views/shop/products/_shop_variant_with_group_buy.html.haml
@@ -1,3 +1,4 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
= cache_with_locale do
.small-5.medium-3.large-3.columns.variant-quantity-column.text-right{"ng-if" => "::variant.product.group_buy"}
diff --git a/app/views/shop/products/_summary.html.haml b/app/views/shop/products/_summary.html.haml
index 8163d6e903..cd3d103a0c 100644
--- a/app/views/shop/products/_summary.html.haml
+++ b/app/views/shop/products/_summary.html.haml
@@ -1,3 +1,4 @@
+- # NOTE: make sure that any changes in this template are reflected in app/views/admin/products_v3/product_preview.turbo_stream.haml
= cache_with_locale do
.product-thumb
%a{"ng-click" => "triggerProductModal()"}
diff --git a/app/views/spree/admin/orders/_table_row.html.haml b/app/views/spree/admin/orders/_table_row.html.haml
index cb0b579391..7cc4aae10f 100644
--- a/app/views/spree/admin/orders/_table_row.html.haml
+++ b/app/views/spree/admin/orders/_table_row.html.haml
@@ -45,7 +45,7 @@
%div.row-loading-icons
- if local_assigns[:success]
%i.success.icon-ok-sign{"data-controller": "ephemeral"}
- = render partial: 'admin/shared/tooltip', locals: {link_class: "icon_link with-tip icon-edit no-text" ,link: edit_admin_order_path(order), link_text: "", tooltip_text: t('spree.admin.orders.index.edit')}
+ = render AdminTooltipComponent.new(text: t('spree.admin.orders.index.edit'), link_text: "", link: edit_admin_order_path(order), link_class: "icon_link with-tip icon-edit no-text")
- if order.ready_to_ship?
%form
= render ShipOrderComponent.new(order: order)
diff --git a/app/views/spree/admin/orders/invoice.html.haml b/app/views/spree/admin/orders/invoice.html.haml
index d1dbc32264..a72e7c1fff 100644
--- a/app/views/spree/admin/orders/invoice.html.haml
+++ b/app/views/spree/admin/orders/invoice.html.haml
@@ -1,4 +1,4 @@
-= pdf_stylesheet_pack_tag "mail"
+= wicked_pdf_stylesheet_link_tag "mail"
%table{:width => "100%"}
%tbody
diff --git a/app/views/spree/admin/orders/invoice2.html.haml b/app/views/spree/admin/orders/invoice2.html.haml
index c55a1f6637..935e370d7a 100644
--- a/app/views/spree/admin/orders/invoice2.html.haml
+++ b/app/views/spree/admin/orders/invoice2.html.haml
@@ -1,4 +1,4 @@
-= pdf_stylesheet_pack_tag "mail"
+= wicked_pdf_stylesheet_link_tag "mail"
%table{:width => "100%"}
%tbody
diff --git a/app/views/spree/admin/orders/invoice4.html.haml b/app/views/spree/admin/orders/invoice4.html.haml
index bf7eee3679..f05a463b88 100644
--- a/app/views/spree/admin/orders/invoice4.html.haml
+++ b/app/views/spree/admin/orders/invoice4.html.haml
@@ -1,4 +1,4 @@
-= pdf_stylesheet_pack_tag "mail"
+= wicked_pdf_stylesheet_link_tag "mail"
%table{:width => "100%"}
%tbody
diff --git a/app/views/spree/admin/products/_primary_taxon_form.html.haml b/app/views/spree/admin/products/_primary_taxon_form.html.haml
index fa4b0b1976..615d415bc1 100644
--- a/app/views/spree/admin/products/_primary_taxon_form.html.haml
+++ b/app/views/spree/admin/products/_primary_taxon_form.html.haml
@@ -1,6 +1,12 @@
-= f.field_container :primary_taxon do
+= f.field_container :primary_taxon_id do
= f.label :primary_taxon_id, t('.product_category')
%span.required *
%br
- = f.collection_select(:primary_taxon_id, Spree::Taxon.order(:name), :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"})
+ = render(SearchableDropdownComponent.new(form: f,
+ name: :primary_taxon_id,
+ aria_label: t('.product_category'),
+ options: Spree::Taxon.select(:name, :id).order(:name).pluck(:name, :id),
+ selected_option: @product.primary_taxon_id,
+ include_blank: true,
+ placeholder_value: t('.search_for_categories')))
= f.error_message_on :primary_taxon_id
diff --git a/app/views/spree/admin/products/_shipping_category_form.html.haml b/app/views/spree/admin/products/_shipping_category_form.html.haml
index 0f3635d698..d7157023ad 100644
--- a/app/views/spree/admin/products/_shipping_category_form.html.haml
+++ b/app/views/spree/admin/products/_shipping_category_form.html.haml
@@ -1,4 +1,4 @@
-= f.field_container :shipping_categories do
+= f.field_container :shipping_category_id do
= f.label :shipping_category_id, t(:shipping_category)
= f.collection_select(:shipping_category_id, Spree::ShippingCategory.all, :id, :name, {:include_blank => false}, {:class => 'select2 fullwidth'})
= f.error_message_on :shipping_category_id
diff --git a/app/views/spree/admin/products/edit.html.haml b/app/views/spree/admin/products/edit.html.haml
index 6a5ccb4c21..003a35eee6 100644
--- a/app/views/spree/admin/products/edit.html.haml
+++ b/app/views/spree/admin/products/edit.html.haml
@@ -1,7 +1,7 @@
= admin_inject_available_units
- content_for :page_actions do
- %li= button_link_to t('admin.products.back_to_products_list'), "#{admin_products_path}#{(@url_filters.empty? ? "" : "#?#{@url_filters.to_query}")}", :icon => 'icon-arrow-left'
+ %li= button_link_to t('admin.products.back_to_products_list'), products_return_to_url(@url_filters), :icon => 'icon-arrow-left'
%li#new_product_link
= button_link_to t(:new_product), new_object_url, { :icon => 'icon-plus', :id => 'admin_new_product' }
@@ -11,9 +11,13 @@
= render :partial => 'spree/shared/error_messages', :locals => { :target => @product }
= form_for [:admin, @product], :url => admin_product_path(@product, @url_filters), :method => :put, :html => { :multipart => true } do |f|
- %fieldset.no-border-top{'ng-app' => 'admin.products'}
+ %fieldset.no-border-top{'ng-app': 'admin.products', 'data-turbo': true, 'data-controller': "product-preview"}
= render :partial => 'form', :locals => { :f => f }
.form-buttons.filter-actions.actions
+ = link_to t("admin.products_page.actions.preview"), Rails.application.routes.url_helpers.admin_product_preview_path(@product), {"data-turbo-stream": "" , class: "button secondary"}
+
= button t(:update), 'icon-refresh'
- = button_link_to t(:cancel), "#{collection_url}#{(@url_filters.empty? ? "" : "#?#{@url_filters.to_query}")}", icon: 'icon-remove'
+ = button_link_to t(:cancel), products_return_to_url(@url_filters), icon: 'icon-remove'
+
+ #product-preview-modal-container
diff --git a/app/views/spree/admin/products/new.html.haml b/app/views/spree/admin/products/new.html.haml
index 70d620ef79..a716215738 100644
--- a/app/views/spree/admin/products/new.html.haml
+++ b/app/views/spree/admin/products/new.html.haml
@@ -8,10 +8,16 @@
%legend{align: "center"}= t(".new_product")
.sixteen.columns.alpha
.eight.columns.alpha
- = f.field_container :supplier do
- = f.label :supplier, t(".supplier")
+ = f.field_container :supplier_id do
+ = f.label :supplier_id, t(".supplier")
%span.required *
- = f.select :supplier_id, options_from_collection_for_select(@producers, :id, :name, @product.supplier_id), { include_blank: t("spree.admin.products.new.supplier_select_placeholder") }, { "data-controller": "tom-select", class: "primary" }
+ = render(SearchableDropdownComponent.new(form: f,
+ name: :supplier_id,
+ aria_label: t('.supplier'),
+ options: @producers.select(:name, :id).order(:name).pluck(:name, :id),
+ selected_option: @product.supplier_id,
+ include_blank: true,
+ placeholder_value: t('.search_for_suppliers')))
= f.error_message_on :supplier_id
.eight.columns.omega
= f.field_container :name do
@@ -25,8 +31,16 @@
= f.field_container :variant_unit do
= f.label :variant_unit, t(".units")
%span.required *
- %select{id: 'product_variant_unit_with_scale', 'ng-model' => 'product.variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options', "data-controller": "tom-select","data-tom-select-options-value": '{"allowEmptyOption":false}', class: "primary"}
- %option{'value' => '', 'ng-hide' => "hasUnit(product)"}
+ = f.select 'variant_unit', [],
+ { include_blank: true },
+ { id: 'product_variant_unit_with_scale',
+ name: 'product_variant_unit_with_scale',
+ 'ng-model' => 'product.variant_unit_with_scale',
+ 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options',
+ "data-controller": "tom-select",
+ "data-tom-select-options-value": '{"allowEmptyOption":false}',
+ class: "primary",
+ }
%input{ type: 'hidden', 'ng-value': 'product.variant_unit', "ng-init": "product.variant_unit='#{@product.variant_unit}'", name: 'product[variant_unit]' }
%input{ type: 'hidden', 'ng-value': 'product.variant_unit_scale', "ng-init": "product.variant_unit_scale='#{@product.variant_unit_scale}'", name: 'product[variant_unit_scale]' }
= f.error_message_on :variant_unit
@@ -34,16 +48,17 @@
= f.field_container :unit_value do
= f.label :unit_value, t(".value"), 'ng-disabled' => "!hasUnit(product)"
%span.required *
- %input.fullwidth{ id: 'product_unit_value', 'ng-model' => 'product.master.unit_value_with_description', :type => 'text', placeholder: "eg. 2", 'ng-disabled' => "!hasUnit(product)" }
+ = f.text_field :unit_value, placeholder: "eg. 2", 'ng-model' => 'product.master.unit_value_with_description', class: 'fullwidth', 'ng-disabled' => "!hasUnit(product)"
%input{ type: 'hidden', 'ng-value': 'product.master.unit_value', "ng-init": "product.master.unit_value='#{@product.unit_value}'", name: 'product[unit_value]' }
%input{ type: 'hidden', 'ng-value': 'product.master.unit_description', "ng-init": "product.master.unit_description='#{@product.unit_description}'", name: 'product[unit_description]' }
= f.error_message_on :unit_value
= render 'display_as', f: f
.six.columns.omega{ 'ng-show' => "product.variant_unit_with_scale == 'items'" }
- = f.field_container :unit_name do
- = f.label :product_variant_unit_name, t(".unit_name")
+ = f.field_container :variant_unit_name do
+ = f.label :variant_unit_name, t(".unit_name")
%span.required *
- %input.fullwidth{ id: 'product_variant_unit_name','ng-model' => 'product.variant_unit_name', :name => 'product[variant_unit_name]', :placeholder => t('admin.products.unit_name_placeholder'), :type => 'text' }
+ = f.text_field :variant_unit_name, :placeholder => t('admin.products.unit_name_placeholder'), 'ng-model' => 'product.variant_unit_name', class: 'fullwidth', 'ng-init': "product.variant_unit_name='#{@product.variant_unit_name}'"
+ = f.error_message_on :variant_unit_name
.sixteen.columns.alpha
.eight.columns.alpha
= render 'spree/admin/products/primary_taxon_form', f: f
diff --git a/app/views/spree/admin/shared/_configuration_menu.html.haml b/app/views/spree/admin/shared/_configuration_menu.html.haml
index 215011f6b6..0b0f2c2d80 100644
--- a/app/views/spree/admin/shared/_configuration_menu.html.haml
+++ b/app/views/spree/admin/shared/_configuration_menu.html.haml
@@ -15,7 +15,7 @@
- if DefaultCountry.id
= configurations_sidebar_menu_item Spree.t(:states), admin_country_states_path(DefaultCountry.id)
= configurations_sidebar_menu_item Spree.t(:payment_methods), admin_payment_methods_path
- = configurations_sidebar_menu_item Spree.t(:taxonomies), admin_taxonomies_path
+ = configurations_sidebar_menu_item Spree.t(:taxons), admin_taxons_path
= configurations_sidebar_menu_item Spree.t(:shipping_methods), admin_shipping_methods_path
= configurations_sidebar_menu_item Spree.t(:shipping_categories), admin_shipping_categories_path
= configurations_sidebar_menu_item t(:enterprise_fees), main_app.admin_enterprise_fees_path
diff --git a/app/views/spree/admin/shared/_tabs.html.haml b/app/views/spree/admin/shared/_tabs.html.haml
index f9a9c6613f..3ad1a1d53a 100644
--- a/app/views/spree/admin/shared/_tabs.html.haml
+++ b/app/views/spree/admin/shared/_tabs.html.haml
@@ -3,7 +3,7 @@
= 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'
-= tab :general_settings, :terms_of_service_files, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxonomies, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, :connected_app_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
+= tab :general_settings, :terms_of_service_files, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxons, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, :connected_app_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
= tab :enterprises, :enterprise_relationships, :vouchers, :oidc_settings, url: main_app.admin_enterprises_path
= tab :customers, url: main_app.admin_customers_path
= tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups'
diff --git a/app/views/spree/admin/taxonomies/_form.html.haml b/app/views/spree/admin/taxonomies/_form.html.haml
deleted file mode 100644
index ac60030374..0000000000
--- a/app/views/spree/admin/taxonomies/_form.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-.field.align-center
- = f.field_container :name do
- = f.label :name, t("spree.name")
- %span.required *
- %br/
- = error_message_on :taxonomy, :name
- = text_field :taxonomy, :name
diff --git a/app/views/spree/admin/taxonomies/_js_head.html.erb b/app/views/spree/admin/taxonomies/_js_head.html.erb
deleted file mode 100755
index e95f4bdeff..0000000000
--- a/app/views/spree/admin/taxonomies/_js_head.html.erb
+++ /dev/null
@@ -1,13 +0,0 @@
-<% content_for :head do %>
- <%= javascript_tag "var taxonomy_id = #{@taxonomy.id};
- var loading = '#{escape_javascript t("spree.loading")}';
- var new_taxon = '#{escape_javascript t("spree.new_taxon")}';
- var server_error = '#{escape_javascript t("spree.server_error")}';
- var taxonomy_tree_error = '#{escape_javascript t("spree.taxonomy_tree_error")}';
-
- $(document).ready(function(){
- setup_taxonomy_tree(taxonomy_id);
- });
- "
- %>
-<% end %>
diff --git a/app/views/spree/admin/taxonomies/_list.html.haml b/app/views/spree/admin/taxonomies/_list.html.haml
deleted file mode 100644
index 1574e8b718..0000000000
--- a/app/views/spree/admin/taxonomies/_list.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-%table#listing_taxonomies.index.sortable{"data-sortable-link" => update_positions_admin_taxonomies_url}
- %colgroup
- %col{style: "width: 85%"}/
- %col{style: "width: 15%"}/
- %thead
- %tr
- %th= t("spree.name")
- %th.actions
- %tbody
- - @taxonomies.each do |taxonomy|
- - tr_class = cycle('odd', 'even')
- - tr_id = spree_dom_id(taxonomy)
- %tr{class: tr_class, id: tr_id}
- %td
- %span.handle
- = taxonomy.name
- %td.actions
- = link_to_edit taxonomy.id, no_text: true
- = link_to_delete taxonomy, no_text: true
diff --git a/app/views/spree/admin/taxonomies/_taxon.html.haml b/app/views/spree/admin/taxonomies/_taxon.html.haml
deleted file mode 100644
index ce8fd21247..0000000000
--- a/app/views/spree/admin/taxonomies/_taxon.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- if taxon.children.length != 0
- %ul
- - taxon.children.each do |child|
- %li{id: "#{child.id}", rel: "taxon"}
- %a{href: "#"}= child.name
- - if child.children.length > 0
- = render partial: 'taxon', locals: { taxon: child }
diff --git a/app/views/spree/admin/taxonomies/edit.haml b/app/views/spree/admin/taxonomies/edit.haml
deleted file mode 100755
index 2b8065674e..0000000000
--- a/app/views/spree/admin/taxonomies/edit.haml
+++ /dev/null
@@ -1,27 +0,0 @@
-= render partial: 'spree/admin/shared/configuration_menu'
-
-= render partial: 'js_head'
-
-- content_for :page_title do
- = t("spree.taxonomy_edit")
-
-- content_for :page_actions do
- %li
- = button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
-
-#ajax_error.errorExplanation{style: "display:none;"}
-= form_for [:admin, @taxonomy] do |f|
- %fieldset.no-border-top
- = render partial: 'form', locals: { f: f }
- %div
- = label_tag nil, t("spree.tree")
- %br/
- :javascript
- Spree.routes.taxonomy_taxons = "#{main_app.api_v0_taxonomy_taxons_url(@taxonomy)}";
- Spree.routes.admin_taxonomy_taxons = "#{spree.admin_taxonomy_taxons_url(@taxonomy)}";
- #taxonomy_tree.tree
- .info= t("spree.taxonomy_tree_instruction")
- %br/
- .filter-actions.actions
- = button t('spree.actions.update'), 'icon-refresh'
- = button_link_to t('spree.actions.cancel'), admin_taxonomies_path, icon: 'icon-remove'
diff --git a/app/views/spree/admin/taxonomies/index.html.haml b/app/views/spree/admin/taxonomies/index.html.haml
deleted file mode 100644
index 63041138d1..0000000000
--- a/app/views/spree/admin/taxonomies/index.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-= render partial: 'spree/admin/shared/configuration_menu'
-
-- content_for :page_title do
- = t("spree.taxonomies")
-
-- content_for :page_actions do
- %li
- = button_link_to t("spree.new_taxonomy"), spree.new_admin_taxonomy_url, icon: 'icon-plus', id: 'admin_new_taxonomy_link'
-
-#list-taxonomies
- = render partial: 'list'
diff --git a/app/views/spree/admin/taxonomies/new.html.haml b/app/views/spree/admin/taxonomies/new.html.haml
deleted file mode 100644
index a84338ddf1..0000000000
--- a/app/views/spree/admin/taxonomies/new.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-= render partial: 'spree/admin/shared/configuration_menu'
-
-- content_for :page_title do
- = t("spree.new_taxonomy")
-
-- content_for :page_actions do
- %li
- = button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
-
-= form_for [:admin, @taxonomy] do |f|
- = render partial: 'form', locals: { f: f }
- %fieldset.no-border-top
- %br/
- .filter-actions.actions
- = button t("spree.create"), 'icon-ok'
diff --git a/app/views/spree/admin/taxons/_form.html.haml b/app/views/spree/admin/taxons/_form.html.haml
index 621b5eadf8..a14f351bae 100644
--- a/app/views/spree/admin/taxons/_form.html.haml
+++ b/app/views/spree/admin/taxons/_form.html.haml
@@ -6,12 +6,6 @@
%br/
= error_message_on :taxon, :name
= text_field :taxon, :name, class: 'fullwidth'
- = f.field_container :permalink_part do
- = f.label :permalink_part, t(".permalink")
- %span.required *
- %br/
- = @taxon.permalink.split("/")[0...-1].join("/") + "/"
- = text_field_tag :permalink_part, @permalink_part
= f.field_container :meta_title do
= f.label :meta_title, t(".meta_title")
%br/
diff --git a/app/views/spree/admin/taxons/destroy_taxon.turbo_stream.haml b/app/views/spree/admin/taxons/destroy_taxon.turbo_stream.haml
new file mode 100644
index 0000000000..6eb0c41014
--- /dev/null
+++ b/app/views/spree/admin/taxons/destroy_taxon.turbo_stream.haml
@@ -0,0 +1,4 @@
+- unless flash[:error]
+ = turbo_stream.remove(spree_dom_id(@taxon))
+= turbo_stream.append "flashes" do
+ = render(partial: 'admin/shared/flashes', locals: { flashes: flash })
\ No newline at end of file
diff --git a/app/views/spree/admin/taxons/edit.html.haml b/app/views/spree/admin/taxons/edit.html.haml
index 1df6e7288f..25c2815d07 100644
--- a/app/views/spree/admin/taxons/edit.html.haml
+++ b/app/views/spree/admin/taxons/edit.html.haml
@@ -1,16 +1,16 @@
= render partial: 'spree/admin/shared/configuration_menu'
- content_for :page_title do
- = t("spree.taxonomy_edit")
+ = t(".title")
- content_for :page_actions do
%li
- = button_link_to t("spree.back_to_taxonomies_list"), spree.admin_taxonomies_path, icon: 'icon-arrow-left'
+ = button_link_to t("spree.admin.taxons.back_to_list"), admin_taxons_path, icon: 'icon-arrow-left'
-- # Because otherwise the form would attempt to use to_param of @taxon
-- form_url = admin_taxonomy_taxon_path(@taxonomy.id, @taxon.id)
-= form_for [:admin, @taxonomy, @taxon], method: :put, url: form_url, html: { multipart: true } do |f|
+= form_with model: @taxon, url: admin_taxon_path(@taxon.id),
+ data: { turbo: true }, id: "edit-taxon-#{@taxon.id}",
+ method: :put, html: { multipart: true } do |f|
= render partial: 'form', locals: { f: f }
.form-buttons
= button t('spree.actions.update'), 'icon-refresh'
- = button_link_to t('spree.actions.cancel'), edit_admin_taxonomy_url(@taxonomy), icon: "icon-remove"
+ = button_link_to t('spree.actions.cancel'), admin_taxons_url, icon: "icon-remove"
diff --git a/app/views/spree/admin/taxons/index.html.haml b/app/views/spree/admin/taxons/index.html.haml
new file mode 100644
index 0000000000..c4f673421e
--- /dev/null
+++ b/app/views/spree/admin/taxons/index.html.haml
@@ -0,0 +1,27 @@
+= render partial: 'spree/admin/shared/configuration_menu'
+
+- content_for :page_title do
+ = t(".title")
+
+- content_for :page_actions do
+ %li
+ = button_link_to t(".new_taxon"), spree.new_admin_taxon_url, icon: 'icon-plus', id: 'admin_new_taxon_link'
+
+%table#listing_taxons.index
+ %colgroup
+ %col{style: "width: 85%"}/
+ %col{style: "width: 15%"}/
+ %thead
+ %tr
+ %th= t("spree.name")
+ %th.actions
+ %tbody
+ - @taxons.each do |taxon|
+ %tr{class: cycle('odd', 'even'), id: spree_dom_id(taxon)}
+ %td
+ = taxon.name
+ %td.actions
+ = link_to_edit taxon.id, no_text: true
+ = link_to '', admin_taxon_path(taxon.id), method: :delete,
+ class: "icon_link with-tip icon-trash no-text",
+ data: { turbo: true, turbo_method: :delete, turbo_confirm: t(:are_you_sure) }
diff --git a/app/views/spree/admin/taxons/new.html.haml b/app/views/spree/admin/taxons/new.html.haml
new file mode 100644
index 0000000000..38930fbcdf
--- /dev/null
+++ b/app/views/spree/admin/taxons/new.html.haml
@@ -0,0 +1,14 @@
+= render partial: 'spree/admin/shared/configuration_menu'
+
+- content_for :page_title do
+ = t(".title")
+
+- content_for :page_actions do
+ %li
+ = button_link_to t("spree.admin.taxons.back_to_list"), spree.admin_taxons_path, icon: 'icon-arrow-left'
+
+= form_with model: @taxon, url: admin_taxons_path, data: { turbo: true }, html: { multipart: true } do |f|
+ = render partial: 'form', locals: { f: f }
+ .form-buttons
+ = button t('actions.create'), 'icon-ok'
+ = button_link_to t('actions.cancel'), admin_taxons_url, icon: "icon-remove"
diff --git a/app/views/spree/shared/_line_item_name.html.haml b/app/views/spree/shared/_line_item_name.html.haml
index 8b1e75de55..4d732055d2 100644
--- a/app/views/spree/shared/_line_item_name.html.haml
+++ b/app/views/spree/shared/_line_item_name.html.haml
@@ -2,5 +2,5 @@
= "#{line_item.product.name}"
- unless line_item.product.name.include? line_item.name_to_display
%span= "- #{line_item.name_to_display}"
-- if line_item.options_text
- = "(#{line_item.options_text})"
+- if line_item.unit_to_display
+ = "(#{line_item.unit_to_display})"
diff --git a/app/views/subscription_mailer/_summary_detail.html.haml b/app/views/subscription_mailer/_summary_detail.html.haml
index a566b2396d..53706b2b5a 100644
--- a/app/views/subscription_mailer/_summary_detail.html.haml
+++ b/app/views/subscription_mailer/_summary_detail.html.haml
@@ -6,7 +6,7 @@
- separator = messages.values.any? ? ": " : ", "
- orders.each_with_index do |order, i|
- %a{ href: order_url(order) }>= order.number
+ %a{ href: spree.edit_admin_order_url(order) }>= order.number
= separator if messages.values.any? || i < orders.count - 1
- if messages.values.any?
= messages[order.id] || t(".no_message_provided")
diff --git a/app/webpacker/controllers/column_preferences_controller.js b/app/webpacker/controllers/column_preferences_controller.js
index 9b55a961dc..65202920f4 100644
--- a/app/webpacker/controllers/column_preferences_controller.js
+++ b/app/webpacker/controllers/column_preferences_controller.js
@@ -6,7 +6,7 @@ export default class ColumnPreferencesController extends Controller {
connect() {
this.table = document.querySelector('table[data-column-preferences-target="table"]');
this.cols = Array.from(this.table.querySelectorAll('col'));
- this.colSpanCells = this.table.querySelectorAll('th[colspan],td[colspan]');
+ this.colSpanCells = Array.from(this.table.querySelectorAll('th[colspan],td[colspan]'));
// Initialise data-default-col-span
this.colSpanCells.forEach((cell)=> {
cell.dataset.defaultColSpan ||= cell.colSpan;
@@ -19,6 +19,8 @@ export default class ColumnPreferencesController extends Controller {
// On checkbox changed
element.addEventListener("change", this.#showHideColumn.bind(this));
}
+
+ this.#observeProductsTableRows();
}
// private
@@ -30,14 +32,39 @@ export default class ColumnPreferencesController extends Controller {
this.table.classList.toggle(`hide-${name}`, !element.checked);
// Reset cell colspans
- const hiddenColCount = this.checkboxes.filter((checkbox)=> !checkbox.checked).length;
for(const cell of this.colSpanCells) {
- const span = parseInt(cell.dataset.defaultColSpan, 10) - hiddenColCount;
- cell.colSpan = span;
+ this.#updateColSpanCell(cell);
};
}
#showHideElement(element, show) {
element.style.display = show ? "" : "none";
}
+
+ #observeProductsTableRows(){
+ this.productsTableObserver = new MutationObserver((mutations, _observer) => {
+ const mutationRecord = mutations[0];
+
+ if(mutationRecord){
+ const productRowElement = mutationRecord.addedNodes[0];
+
+ if(productRowElement){
+ const newColSpanCell = productRowElement.querySelector('td[colspan]');
+ newColSpanCell.dataset.defaultColSpan ||= newColSpanCell.colSpan;
+ this.#updateColSpanCell(newColSpanCell);
+ this.colSpanCells.push(newColSpanCell);
+ }
+ }
+ });
+
+ this.productsTableObserver.observe(this.table, { childList: true });
+ }
+
+ #hiddenColCount(){
+ return this.checkboxes.filter((checkbox)=> !checkbox.checked).length;
+ }
+
+ #updateColSpanCell(cell){
+ cell.colSpan = parseInt(cell.dataset.defaultColSpan, 10) - this.#hiddenColCount();
+ }
}
diff --git a/app/webpacker/controllers/mixins/useOpenAndCloseAsAModal.js b/app/webpacker/controllers/mixins/useOpenAndCloseAsAModal.js
index 3c9e3d7b3d..7648563791 100644
--- a/app/webpacker/controllers/mixins/useOpenAndCloseAsAModal.js
+++ b/app/webpacker/controllers/mixins/useOpenAndCloseAsAModal.js
@@ -12,6 +12,9 @@ export const useOpenAndCloseAsAModal = (controller) => {
}.bind(controller),
close: function (_event, remove = false) {
+ // Only execute close if there is an open modal
+ if (!document.querySelector("body").classList.contains('modal-open')) return;
+
this.modalTarget.classList.remove("in");
this.backgroundTarget.classList.remove("in");
document.querySelector("body").classList.remove("modal-open");
diff --git a/app/webpacker/controllers/order_cycle_form_controller.js b/app/webpacker/controllers/order_cycle_form_controller.js
new file mode 100644
index 0000000000..a92d621dec
--- /dev/null
+++ b/app/webpacker/controllers/order_cycle_form_controller.js
@@ -0,0 +1,55 @@
+import { Controller } from "stimulus";
+
+export default class extends Controller {
+ static targets = ['statusMessage', 'cancel']
+ connect() {
+ this.observer = new MutationObserver(this.updateCallback);
+ this.observer.observe(
+ this.statusMessageTarget,
+ { attributes: true, attributeOldValue: true, attributeFilter: ['data-type'] }
+ );
+
+ if (this.hasCancelTarget) {
+ this.cancelTarget.addEventListener('click', this.removeUnloadEvent)
+ }
+ }
+
+ // Callback to trigger warning modal
+ updateCallback(mutationsList) {
+ const newDataType = document.getElementById('status-message').getAttribute('data-type');
+ const actionName = document.getElementById('status-message').getAttribute('data-action-name');
+ if(!actionName) return;
+
+ for(let mutation of mutationsList) {
+ if (mutation.type === 'attributes' && mutation.attributeName === 'data-type') {
+ // Only trigger warning modal when notice display (notice) is preceeded by progress display (progress)
+ if(mutation.oldValue === 'progress' && newDataType === 'notice') {
+ // Hide all confirmation buttons in warning modal
+ document.querySelectorAll(
+ '#linked-order-warning-modal .modal-actions button.secondary'
+ ).forEach((node) => {
+ node.style.display = 'none';
+ });
+ // Show the appropriate confirmation button, open warning modal, and return
+ document.querySelectorAll(
+ `#linked-order-warning-modal button[data-trigger-action=${actionName}]`
+ ).forEach((node) => {
+ node.style.display = 'block';
+ })
+ document.querySelector('.warning-modal button.modal-target-trigger').click();
+ }
+ }
+ }
+ }
+
+ removeUnloadEvent() {
+ window.removeEventListener('beforeunload', window.onBeforeUnloadHandler)
+ }
+
+ disconnect() {
+ this.observer.disconnect();
+ if (this.hasCancelTarget) {
+ this.cancelTarget.removeEventListener('click', this.removeUnloadEvent)
+ }
+ }
+}
diff --git a/app/webpacker/controllers/trixeditor_controller.js b/app/webpacker/controllers/trixeditor_controller.js
index 506086fb2b..e386352361 100644
--- a/app/webpacker/controllers/trixeditor_controller.js
+++ b/app/webpacker/controllers/trixeditor_controller.js
@@ -2,9 +2,14 @@ import { Controller } from "stimulus";
export default class extends Controller {
connect() {
- window.addEventListener("trix-change", this.#trixChange);
+ this.element.addEventListener("trix-change", this.#trixChange);
this.#trixInitialize();
- window.addEventListener("trix-initialize", this.#trixInitialize);
+ this.element.addEventListener("trix-initialize", this.#trixInitialize);
+ }
+
+ disconnect() {
+ this.element.removeEventListener("trix-change", this.#trixChange);
+ this.element.removeEventListener("trix-initialize", this.#trixInitialize);
}
#trixChange = (event) => {
diff --git a/app/webpacker/css/admin/all.scss b/app/webpacker/css/admin/all.scss
index 254b188a78..a63e543f90 100644
--- a/app/webpacker/css/admin/all.scss
+++ b/app/webpacker/css/admin/all.scss
@@ -33,7 +33,6 @@
@import "plugins/flatpickr-customization";
@import "plugins/powertip";
-@import "plugins/jstree";
@import "plugins/select2";
@import "sections/orders";
diff --git a/app/webpacker/css/admin/order_cycles.scss b/app/webpacker/css/admin/order_cycles.scss
index ea73266fb8..ace5c65498 100644
--- a/app/webpacker/css/admin/order_cycles.scss
+++ b/app/webpacker/css/admin/order_cycles.scss
@@ -62,3 +62,7 @@ form.order_cycle {
}
}
}
+
+#linked-order-warning-modal .reveal-modal{
+ width: 28rem;
+}
\ No newline at end of file
diff --git a/app/webpacker/css/admin/plugins/jstree.scss b/app/webpacker/css/admin/plugins/jstree.scss
deleted file mode 100644
index b16fd23a1a..0000000000
--- a/app/webpacker/css/admin/plugins/jstree.scss
+++ /dev/null
@@ -1,131 +0,0 @@
-#taxonomy_tree {
- > ul,
- .jstree-icon {
- background-image: none;
- }
-
- .jstree-icon {
- @extend [class^="icon-"], :before;
- }
-
- .jstree-open > .jstree-icon {
- @extend .icon-caret-down;
- }
- .jstree-closed > .jstree-icon {
- @extend .icon-caret-right;
- }
-
- li {
- background-image: none;
-
- a {
- background-color: very-light($color-3);
- border: 1px solid $color-border;
- color: $color-body-text;
- font-weight: $font-weight-bold;
- text-shadow: none;
- width: 90%;
- height: auto;
- line-height: inherit;
- padding: 5px 0 5px 10px;
- margin-bottom: 10px;
-
- .jstree-icon {
- padding-left: 0px;
- @extend .icon-move;
- }
- }
- }
-}
-
-#vakata-dragged.jstree-apple .jstree-invalid,
-#vakata-dragged.jstree-apple .jstree-ok,
-#jstree-marker {
- background-image: none !important;
- background-color: transparent !important;
- @extend [class^="icon-"], :before;
-}
-#vakata-dragged.jstree-apple .jstree-invalid {
- @extend .icon-remove;
- color: $color-5;
-}
-#vakata-dragged.jstree-apple .jstree-ok {
- @extend .icon-ok;
- color: $color-2;
-}
-
-#jstree-marker {
- @extend .icon-caret-right;
- color: $color-body-text !important;
- width: 4px !important;
-}
-
-#jstree-marker-line {
- @include border-radius($border-radius !important);
- height: 0px !important;
- margin-left: 5px !important;
- margin-top: -2px !important;
- border: none !important;
- border-bottom: 1px solid $color-body-text !important;
- background-color: very-light($color-3) !important;
-
- -webkit-box-shadow: none !important;
- -moz-box-shadow: none !important;
- box-shadow: none !important;
-}
-
-#vakata-contextmenu {
- background-color: $color-3 !important;
- -moz-box-shadow: none !important;
- -webkit-box-shadow: none !important;
- box-shadow: none !important;
- border: none !important;
- @include border-radius($border-radius !important);
-
- &:before {
- content: "";
- position: absolute;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-bottom: 10px solid $color-3;
- top: 0px;
- margin-top: -10px;
- left: 25px;
- z-index: 1;
- }
-
- a {
- color: $color-1 !important;
- line-height: inherit !important;
- padding: 5px 10px !important;
- margin: 0 !important;
- font-size: 90% !important;
-
- &:hover {
- @include border-radius($border-radius !important);
- background-color: $color-2 !important;
- border: none !important;
- -moz-box-shadow: none !important;
- -webkit-box-shadow: none !important;
- line-height: inherit !important;
- padding: 5px 10px !important;
- margin: 0 !important;
- }
- }
-
- li:first-child a:hover:before {
- content: "";
- position: absolute;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-bottom: 10px solid $color-2;
- top: 0px;
- margin-top: -10px;
- left: 25px;
- z-index: 1;
- }
-
- li.vakata-separator {
- display: none;
- }
-}
diff --git a/app/webpacker/css/admin/products_v3.scss b/app/webpacker/css/admin/products_v3.scss
index 32dc4c5cda..912e940608 100644
--- a/app/webpacker/css/admin/products_v3.scss
+++ b/app/webpacker/css/admin/products_v3.scss
@@ -148,7 +148,7 @@
border-bottom: 2px solid $color-tbl-bg;
&.with-image {
- padding: 8px;
+ padding: 4px 2px;
}
}
diff --git a/app/webpacker/css/admin_v3/all.scss b/app/webpacker/css/admin_v3/all.scss
index 843204ec1b..a5c673b909 100644
--- a/app/webpacker/css/admin_v3/all.scss
+++ b/app/webpacker/css/admin_v3/all.scss
@@ -38,7 +38,6 @@
@import "plugins/flatpickr-customization"; // admin_v3
@import "plugins/powertip"; // admin_v3
-@import "../admin/plugins/jstree";
@import "sections/orders"; // admin_v3
@import "../admin/sections/products";
@@ -131,3 +130,5 @@
@import "app/webpacker/css/admin/trix.scss";
@import "terms_of_service_banner"; // admin_v3
+
+@import "pages/product_preview"; // admin_v3
diff --git a/app/webpacker/css/admin_v3/components/navigation.scss b/app/webpacker/css/admin_v3/components/navigation.scss
index 4ef5d5a06c..70ea3cf8b9 100644
--- a/app/webpacker/css/admin_v3/components/navigation.scss
+++ b/app/webpacker/css/admin_v3/components/navigation.scss
@@ -1,11 +1,60 @@
// Navigation
//---------------------------------------------------
+
+@mixin menu-display {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+@mixin menu-link {
+ a {
+ display: inline-block;
+ padding: 16px 20px;
+ color: $color-9 !important;
+ text-align: center;
+ position: relative;
+ font-size: 14px;
+ font-weight: 600;
+
+ &:hover {
+ color: $red !important;
+
+ &:after {
+ content: "";
+ position: absolute;
+ bottom: 0;
+ left: 20px;
+ right: 20px;
+ height: 3px;
+ background: $red;
+ }
+ }
+
+ &.active {
+ @extend :hover;
+ }
+ }
+}
+
.inline-menu {
margin: 0;
-webkit-margin-before: 0;
-webkit-padding-start: 0;
}
+// tabs
+/// use the same styling as #admin-menu via menu-display and menu-link mixins
+dl.admin-tabs {
+ box-shadow: $box-shadow;
+ @include menu-display;
+
+ dd {
+ width: auto;
+ padding: 0;
+ @include menu-link;
+ }
+}
+
nav.menu {
ul {
list-style: none;
@@ -95,33 +144,10 @@ nav.menu {
}
ul {
- display: flex;
- flex-wrap: wrap;
+ @include menu-display;
li {
- a {
- display: inline-block;
- padding: 16px 20px;
- color: $color-9 !important;
- text-align: center;
- position: relative;
- font-size: 14px;
- font-weight: 600;
-
- &:hover {
- color: $red !important;
-
- &:after {
- content: "";
- position: absolute;
- bottom: 0;
- left: 20px;
- right: 20px;
- height: 3px;
- background: $red;
- }
- }
- }
+ @include menu-link;
&.selected a {
@extend a, :hover;
diff --git a/app/webpacker/css/admin_v3/globals/variables.scss b/app/webpacker/css/admin_v3/globals/variables.scss
index 41863422d4..6aa5247dd1 100644
--- a/app/webpacker/css/admin_v3/globals/variables.scss
+++ b/app/webpacker/css/admin_v3/globals/variables.scss
@@ -40,8 +40,8 @@ $color-tbl-thead-txt: $color-headers !default;
$color-tbl-thead-bg: $light-grey !default;
$color-tbl-border: $pale-blue !default;
$padding-tbl-cell: 12px;
-$padding-tbl-cell-condensed: 4px 12px;
-$padding-tbl-cell-relaxed: 12px 12px;
+$padding-tbl-cell-condensed: 4px 3px;
+$padding-tbl-cell-relaxed: 8px 3px;
// Button colors
$color-btn-bg: $teal !default;
diff --git a/app/webpacker/css/admin_v3/pages/product_preview.scss b/app/webpacker/css/admin_v3/pages/product_preview.scss
new file mode 100644
index 0000000000..4b7f7e3a6a
--- /dev/null
+++ b/app/webpacker/css/admin_v3/pages/product_preview.scss
@@ -0,0 +1,176 @@
+@import "../../darkswarm/branding";
+@import "../../darkswarm/mixins";
+
+#product-preview {
+ // The frontend css is base on foundation-sites https://github.com/foundation/foundation-sites
+ // Below we copied the sections that are relevant to the product preview modal
+
+ // from foundation-sites/scss/foundations/components/_types.scss
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ color: #222222;
+ font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
+ font-style: normal;
+ font-weight: normal;
+ line-height: 1.4;
+ margin-bottom: 0.5rem;
+ margin-top: 0.2rem;
+ text-rendering: optimizeLegibility;
+ }
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ line-height: 1.4;
+ }
+
+ h3 {
+ font-size: 1.6875rem;
+ }
+
+ em,
+ i {
+ font-style: italic;
+ line-height: inherit;
+ }
+
+ ul,
+ ol,
+ dl {
+ font-family: inherit;
+ font-size: 1rem;
+ line-height: 1.6;
+ list-style-position: outside;
+ margin-bottom: 1.25rem;
+ }
+
+ .text-right {
+ text-align: right !important;
+ }
+
+ // from foundation-sites/scss/foundations/components/_buttons.scss
+ button,
+ .button {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ border-radius: 0;
+ border-style: solid;
+ border-width: 0;
+ cursor: pointer;
+ font-family: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif;
+ font-weight: normal;
+ line-height: normal;
+ margin: 0 0 1.25rem;
+ position: relative;
+ text-align: center;
+ text-decoration: none;
+ display: inline-block;
+ padding: 1rem 2rem 1.0625rem 2rem;
+ font-size: 1rem;
+ background-color: #008cba;
+ border-color: #007095;
+ color: #ffffff;
+ transition: background-color 300ms ease-out;
+ }
+
+ // from foundation-sites/scss/foundations/components/_grid.scss
+ @media only screen and (min-width: 64.0625em) {
+ .column,
+ .columns {
+ position: relative;
+ padding-left: 0.9375rem;
+ padding-right: 0.9375rem;
+ float: left;
+ }
+ }
+
+ .column + .column:last-child,
+ .column + .columns:last-child,
+ .columns + .column:last-child,
+ .columns + .columns:last-child {
+ float: right;
+ }
+
+ .small-3 {
+ width: 25%;
+ }
+
+ @media only screen and (min-width: 40.0625em) {
+ .medium-3 {
+ width: 20%; // original value 25%
+ }
+ }
+
+ @media only screen and (min-width: 64.0625em) {
+ .large-3 {
+ width: 25%;
+ }
+ }
+
+ @media only screen and (min-width: 64.0625em) {
+ .large-6 {
+ width: 50%;
+ }
+ }
+
+ // from foundation-sites/scss/foundations/components/_global.scss
+ img {
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ // Import frontend partials
+
+ // Product details
+ @import "../../darkswarm/shop_partials/typography";
+ @import "../../darkswarm/overrides";
+
+ .row {
+ margin: 0 auto;
+ width: 100%;
+ }
+
+ @import "../../darkswarm/shop_partials/animations";
+ @import "../../darkswarm/shop_partials/shop-filters";
+ @import "../../darkswarm/shop-modals";
+ @import "../../darkswarm/shop_partials/images";
+
+ // Shop
+ @import "../../darkswarm/shop_partials/shop-product-thumb";
+ @import "../../darkswarm/shop_partials/shop-product-rows";
+ @import "../../darkswarm/shop_partials/shop-inputs";
+ @import "../../shared/question-mark-icon";
+
+ button.add-variant {
+ opacity: 0.5;
+ }
+
+ .variant-remaining-stock {
+ opacity: 0.5;
+ }
+
+ .question-mark-icon {
+ display: block;
+ }
+
+ .tooltip {
+ @include joyride-content;
+ width: $joyride-width;
+ text-transform: none;
+ }
+
+ .arrow {
+ background-color: $dynamic-blue;
+ }
+
+ .columns {
+ margin-left: 0;
+ }
+}
diff --git a/app/webpacker/css/darkswarm/_shop-filters.scss b/app/webpacker/css/darkswarm/_shop-filters.scss
index e4bceed102..f6de8c8536 100644
--- a/app/webpacker/css/darkswarm/_shop-filters.scss
+++ b/app/webpacker/css/darkswarm/_shop-filters.scss
@@ -1,102 +1,4 @@
-
-@mixin filter-selector($base-clr, $border-clr, $hover-clr) {
- &.inline-block, ul.inline-block {
- display: inline-block;
- }
-
- li {
- display: inline-block;
-
- @include border-radius(0);
-
- padding: 0;
- margin: 0 0.5rem 0.5rem 0;
-
- &:hover, &:focus {
- background: transparent;
- }
-
- &.active {
- box-shadow: none;
- }
-
- a, a.button {
- display: block;
-
- @include border-radius(0.5em);
-
- border: 1px solid $border-clr;
- padding: 0.5em 0.625em;
- color: $base-clr;
- font-size: 0.75em;
- background: white;
- margin: 0;
-
- i {
- padding-left: 0.25rem;
- }
-
- render-svg {
- &, & svg {
- width: 1rem;
- height: 1rem;
- float: left;
- padding-right: 0.25rem;
-
- path {
- @include csstrans;
-
- fill: $base-clr;
- }
- }
- }
-
- &:hover, &:focus {
- border-color: $hover-clr;
- color: $hover-clr;
-
- render-svg {
- svg {
- path {
- fill: $hover-clr;
- }
- }
- }
- }
-
- &.disabled {
- opacity: 0.6;
-
- &:hover, &:focus {
- border-color: $border-clr;
- color: $base-clr;
-
- render-svg {
- svg {
- path {
- fill: $base-clr;
- }
- }
- }
- }
- }
-
- &.active, &.active:hover, &.active:focus {
- border: 1px solid $base-clr;
- background: $base-clr;
- color: white;
-
- render-svg {
- svg {
- path {
- fill: white;
- }
- }
- }
- }
- }
- }
-}
+@import "shop_partials/shop-filters";
// Alert when search, taxon, filter is triggered
@@ -167,23 +69,3 @@
max-height: calc(100vh - #{$topbar-height});
overflow-y: auto;
}
-
-.filter-shopfront {
- &.taxon-selectors, &.property-selectors {
- background: transparent;
- }
-
- // Shopfront taxons
- &.taxon-selectors {
- @include filter-selector($clr-blue, $clr-blue-light, $clr-blue-bright);
- }
-
- // Shopfront properties
- &.property-selectors {
- @include filter-selector(#666, #ccc, #777);
- }
-
- ul {
- margin: 0;
- }
-}
diff --git a/app/webpacker/css/darkswarm/_shop-inputs.scss b/app/webpacker/css/darkswarm/_shop-inputs.scss
index 98f4f7fecf..26c28c2fa9 100644
--- a/app/webpacker/css/darkswarm/_shop-inputs.scss
+++ b/app/webpacker/css/darkswarm/_shop-inputs.scss
@@ -15,81 +15,7 @@
//
// They are not nested so that they can be used in modals.
-.variant-quantity-inputs {
- height: 2.5rem;
- white-space: nowrap;
-}
-
-button.add-variant, button.variant-quantity {
- height: 2.5rem;
- border-radius: 0;
- background-color: $orange-500;
- color: white;
- // Override foundation button styles:
- font-size: 1rem;
- margin: 0;
- padding: 0;
- transition: none;
-
- &:hover {
- background-color: $orange-600;
- }
-
- &[disabled] {
- background-color: $grey-400;
-
- &:hover, &:focus {
- background-color: $grey-400;
- }
- }
- &:nth-of-type(1) {
- border-bottom-left-radius: 0.25em;
- border-top-left-radius: 0.25em;
- }
- &:nth-last-of-type(1) {
- border-top-right-radius: 0.25em;
- border-bottom-right-radius: 0.25em;
- }
-}
-
-button.add-variant {
- min-width: 7rem;
- padding: 0 1em;
-
- &[disabled] {
- &:hover, &:focus {
- background-color: $orange-500;
- }
- }
-}
-
-button.variant-quantity {
- width: 2.25rem;
-
- &:nth-of-type(1):not(.bulk-buy):not(.bulk-buy-add) {
- border-right: .1em solid $orange-400;
- }
-}
-
-.variant-quantity-display, .variant-remaining-stock {
- font-size: 0.875em;
- margin-top: 0.25em;
- text-align: center;
- width: 7rem;
- display: inline-block;
-}
-
-.variant-quantity-display {
- visibility: hidden;
-
- &.visible {
- visibility: visible;
- }
-}
-
-.variant-remaining-stock {
- color: $red-500;
-}
+@import "shop_partials/shop-inputs";
button.bulk-buy.variant-quantity {
background-color: transparent;
diff --git a/app/webpacker/css/darkswarm/_shop-product-rows.scss b/app/webpacker/css/darkswarm/_shop-product-rows.scss
index 0ab0a8b1fd..ddf25d6d51 100644
--- a/app/webpacker/css/darkswarm/_shop-product-rows.scss
+++ b/app/webpacker/css/darkswarm/_shop-product-rows.scss
@@ -1,201 +1,7 @@
.darkswarm {
products {
product {
- // GENERAL LAYOUT
- .row {
- .columns {
- padding-top: 0em;
- padding-bottom: 0em;
- line-height: 1.1;
- }
- }
-
- .shop-variants {
- // product-thumb width + 1rem
- padding-left: calc(22.222% + 1rem);
-
- @include breakpoint(phablet) {
- padding-left: 0;
- clear: left;
- }
- }
-
- // ROW VARIANTS
- .row.variants {
- margin: 0 0 1em 0;
-
- &.out-of-stock {
- opacity: 0.2;
- }
-
- .variant-name,
- .total-price {
- padding-top: .74em;
- }
- .variant-price {
- padding-top: .65em;
- }
-
- // Variant name
- .variant-name {
- padding-left: 0;
- padding-right: 0;
-
- @include breakpoint(phablet) {
- padding-left: 0.5rem;
- }
-
- & > *:nth-child(n + 2) {
- color: $grey-550;
- font-size: 0.875rem;
- font-style: italic;
- line-height: normal;
- }
- }
-
- // Variant price
- .variant-price {
- white-space: nowrap;
- @include breakpoint(phablet) {
- padding-left: 1rem;
- }
- }
-
- .variant-unit-price {
- color: $grey-700;
- font-size: 0.85rem;
- margin-top: 15px;
- position: relative;
- left: -1px;
- }
-
- // Total price
- .total-price {
- padding-left: 0rem;
- color: $disabled-med;
-
- .filled {
- color: $med-drk-grey;
- }
-
- @include breakpoint(phablet) {
- display: none;
- }
- }
- }
-
- // ROW SUMMARY
- .summary {
- margin-left: 0;
- margin-right: 0;
- margin-bottom: 1.25em;
- background: #fff;
-
- .columns {
- padding-top: 1em;
- padding-bottom: 1em;
- line-height: 1;
-
- @include breakpoint(tablet) {
- padding-top: 0.65rem;
- padding-bottom: 0.65rem;
- }
- }
-
- .summary-header {
- // product-thumb width + 1rem
- padding-left: calc(22.222% + 1rem);
- padding-right: 1rem;
-
- @include breakpoint(phablet) {
- padding-left: calc(33.333% + 1rem);
- }
-
- .product-producer {
- color: $grey-550;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- font-style: italic;
-
- a {
- color: $teal-500;
-
- &:hover, &:focus, &:active {
- color: $teal-600;
- text-decoration: underline;
- }
- }
- }
-
- h3 {
- font-size: 1.3rem;
- margin-top: 0.75rem;
- margin-bottom: 0.6rem;
- }
-
- h3 a {
- color: $orange-500;
-
- &:hover, &:focus, &:active {
- color: $orange-600;
- text-decoration: underline;
- }
- }
-
- .product-description {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- margin-bottom: 0.75rem;
- cursor: pointer;
- // Force product description to be on one line
- // and truncate with ellipsis
- display: -webkit-box;
- -webkit-line-clamp: 1;
- -webkit-box-orient: vertical;
- overflow: hidden;
- // line-clamp is not supported in Safari
- // Trick to get overflow: hidden to work in old Safari
- line-height: 1rem;
- height: 1.75rem;
-
- > div {
- margin-bottom: 1.5rem; // Equivalent to p (trix doesn't use p as separator by default, so emulate div as p to be backward compatible)
- }
-
- @include trix-styles;
- }
-
- .product-properties {
- margin: .5em 0;
-
- li {
- margin: 0 0.25rem 0.25rem 0;
-
- a {
- padding: 0.1em 0.625em;
-
- cursor: auto;
-
- &.has-tip {
- cursor: pointer;
- font-weight: normal;
- }
- &:hover, &:focus {
- border-color: #ccc;
- }
- }
-
- // Foundation doesn't show the nub on mobile.
- // Repeating the style to show it here.
- .nub {
- border-color: transparent transparent #333333 transparent;
- }
- }
- }
- }
- }
+ @import "shop_partials/shop-product-rows";
}
}
}
diff --git a/app/webpacker/css/darkswarm/_shop-product-thumb.scss b/app/webpacker/css/darkswarm/_shop-product-thumb.scss
index 9b51d7f881..d218a9c1ad 100644
--- a/app/webpacker/css/darkswarm/_shop-product-thumb.scss
+++ b/app/webpacker/css/darkswarm/_shop-product-thumb.scss
@@ -1,34 +1,7 @@
.darkswarm {
products {
product {
- .product-thumb {
- // Desktop: the product summary is nine columns wide. Use two
- // for the image. 100% / 9 * 2 = 22.222% <= 192px
- width: calc(22.222%);
- float: left;
-
- // Mobile: the summary has full twelve columns and the image
- // should take four of them. 100% / 12 * 4 = 33.333% <= 227px
- @include breakpoint(phablet) {
- width: calc(33.333%);
- }
-
- // Make this an anchor for the bulk label.
- position: relative;
-
- .product-thumb__bulk-label {
- background-color: $grey-700;
- color: white;
- position: absolute;
- right: 0;
- top: .8em;
- padding: .25em .5em;
- }
-
- &:hover {
- filter: brightness(96%);
- }
- }
+ @import "shop_partials/shop-product-thumb";
}
}
}
diff --git a/app/webpacker/css/darkswarm/animations.scss b/app/webpacker/css/darkswarm/animations.scss
index 9fdb17eec7..bfe0b5b681 100644
--- a/app/webpacker/css/darkswarm/animations.scss
+++ b/app/webpacker/css/darkswarm/animations.scss
@@ -275,11 +275,4 @@ product.animate-repeat {
}
}
-@mixin csstrans {
- -webkit-transition: all 300ms ease;
- -moz-transition: all 300ms ease;
- -ms-transition: all 300ms ease;
- -o-transition: all 300ms ease;
- transition: all 300ms ease;
- -webkit-transform-style: preserve-3d;
-}
+@import "shop_partials/animations";
diff --git a/app/webpacker/css/darkswarm/images.scss b/app/webpacker/css/darkswarm/images.scss
index 9019971bfb..5ac895be9e 100644
--- a/app/webpacker/css/darkswarm/images.scss
+++ b/app/webpacker/css/darkswarm/images.scss
@@ -1,23 +1,4 @@
-.product-img {
- text-align: center;
-
- img {
- padding: 0.3rem;
-
- // placeholder for when no product images
- &.placeholder {
- opacity: 0.35;
-
- @include breakpoint(desktop) {
- display: none;
- }
- }
-
- @media only screen and (max-width: 1024px) {
- margin: 0 0 0.5rem;
- }
- }
-}
+@import "shop_partials/images";
.hero-img {
outline: 1px solid $disabled-bright;
diff --git a/app/webpacker/css/darkswarm/shop_partials/_animations.scss b/app/webpacker/css/darkswarm/shop_partials/_animations.scss
new file mode 100644
index 0000000000..ab06239fc8
--- /dev/null
+++ b/app/webpacker/css/darkswarm/shop_partials/_animations.scss
@@ -0,0 +1,8 @@
+@mixin csstrans {
+ -webkit-transition: all 300ms ease;
+ -moz-transition: all 300ms ease;
+ -ms-transition: all 300ms ease;
+ -o-transition: all 300ms ease;
+ transition: all 300ms ease;
+ -webkit-transform-style: preserve-3d;
+}
diff --git a/app/webpacker/css/darkswarm/shop_partials/_images.scss b/app/webpacker/css/darkswarm/shop_partials/_images.scss
new file mode 100644
index 0000000000..a08504547c
--- /dev/null
+++ b/app/webpacker/css/darkswarm/shop_partials/_images.scss
@@ -0,0 +1,21 @@
+.product-img {
+ text-align: center;
+
+ img {
+ padding: 0.3rem;
+
+ // placeholder for when no product images
+ &.placeholder {
+ opacity: 0.35;
+
+ @include breakpoint(desktop) {
+ display: none;
+ }
+ }
+
+ @media only screen and (max-width: 1024px) {
+ margin: 0 0 0.5rem;
+ }
+ }
+}
+
diff --git a/app/webpacker/css/darkswarm/shop_partials/_shop-filters.scss b/app/webpacker/css/darkswarm/shop_partials/_shop-filters.scss
new file mode 100644
index 0000000000..5a05979d7f
--- /dev/null
+++ b/app/webpacker/css/darkswarm/shop_partials/_shop-filters.scss
@@ -0,0 +1,119 @@
+@mixin filter-selector($base-clr, $border-clr, $hover-clr) {
+ &.inline-block, ul.inline-block {
+ display: inline-block;
+ }
+
+ li {
+ display: inline-block;
+
+ @include border-radius(0);
+
+ padding: 0;
+ margin: 0 0.5rem 0.5rem 0;
+
+ &:hover, &:focus {
+ background: transparent;
+ }
+
+ &.active {
+ box-shadow: none;
+ }
+
+ a, a.button {
+ display: block;
+
+ @include border-radius(0.5em);
+
+ border: 1px solid $border-clr;
+ padding: 0.5em 0.625em;
+ color: $base-clr;
+ font-size: 0.75em;
+ background: white;
+ margin: 0;
+
+ i {
+ padding-left: 0.25rem;
+ }
+
+ render-svg {
+ &, & svg {
+ width: 1rem;
+ height: 1rem;
+ float: left;
+ padding-right: 0.25rem;
+
+ path {
+ @include csstrans;
+
+ fill: $base-clr;
+ }
+ }
+ }
+
+ &:hover, &:focus {
+ border-color: $hover-clr;
+ color: $hover-clr;
+
+ render-svg {
+ svg {
+ path {
+ fill: $hover-clr;
+ }
+ }
+ }
+ }
+
+ &.disabled {
+ opacity: 0.6;
+
+ &:hover, &:focus {
+ border-color: $border-clr;
+ color: $base-clr;
+
+ render-svg {
+ svg {
+ path {
+ fill: $base-clr;
+ }
+ }
+ }
+ }
+ }
+
+ &.active, &.active:hover, &.active:focus {
+ border: 1px solid $base-clr;
+ background: $base-clr;
+ color: white;
+
+ render-svg {
+ svg {
+ path {
+ fill: white;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+.filter-shopfront {
+ &.taxon-selectors, &.property-selectors {
+ background: transparent;
+ }
+
+ // Shopfront taxons
+ &.taxon-selectors {
+ @include filter-selector($clr-blue, $clr-blue-light, $clr-blue-bright);
+ }
+
+ // Shopfront properties
+ &.property-selectors {
+ @include filter-selector(#666, #ccc, #777);
+ }
+
+ ul {
+ margin: 0;
+ }
+}
+
diff --git a/app/webpacker/css/darkswarm/shop_partials/_shop-inputs.scss b/app/webpacker/css/darkswarm/shop_partials/_shop-inputs.scss
new file mode 100644
index 0000000000..65dbfaca77
--- /dev/null
+++ b/app/webpacker/css/darkswarm/shop_partials/_shop-inputs.scss
@@ -0,0 +1,76 @@
+.variant-quantity-inputs {
+ height: 2.5rem;
+ white-space: nowrap;
+}
+
+button.add-variant, button.variant-quantity {
+ height: 2.5rem;
+ border-radius: 0;
+ background-color: $orange-500;
+ color: white;
+ // Override foundation button styles:
+ font-size: 1rem;
+ margin: 0;
+ padding: 0;
+ transition: none;
+
+ &:hover {
+ background-color: $orange-600;
+ }
+
+ &[disabled] {
+ background-color: $grey-400;
+
+ &:hover, &:focus {
+ background-color: $grey-400;
+ }
+ }
+ &:nth-of-type(1) {
+ border-bottom-left-radius: 0.25em;
+ border-top-left-radius: 0.25em;
+ }
+ &:nth-last-of-type(1) {
+ border-top-right-radius: 0.25em;
+ border-bottom-right-radius: 0.25em;
+ }
+}
+
+button.add-variant {
+ min-width: 7rem;
+ padding: 0 1em;
+
+ &[disabled] {
+ &:hover, &:focus {
+ background-color: $orange-500;
+ }
+ }
+}
+
+button.variant-quantity {
+ width: 2.25rem;
+
+ &:nth-of-type(1):not(.bulk-buy):not(.bulk-buy-add) {
+ border-right: .1em solid $orange-400;
+ }
+}
+
+.variant-quantity-display, .variant-remaining-stock {
+ font-size: 0.875em;
+ margin-top: 0.25em;
+ text-align: center;
+ width: 7rem;
+ display: inline-block;
+}
+
+.variant-quantity-display {
+ visibility: hidden;
+
+ &.visible {
+ visibility: visible;
+ }
+}
+
+.variant-remaining-stock {
+ color: $red-500;
+}
+
diff --git a/app/webpacker/css/darkswarm/shop_partials/_shop-product-rows.scss b/app/webpacker/css/darkswarm/shop_partials/_shop-product-rows.scss
new file mode 100644
index 0000000000..1cf62b4263
--- /dev/null
+++ b/app/webpacker/css/darkswarm/shop_partials/_shop-product-rows.scss
@@ -0,0 +1,195 @@
+// GENERAL LAYOUT
+.row {
+ .columns {
+ padding-top: 0em;
+ padding-bottom: 0em;
+ line-height: 1.1;
+ }
+}
+
+.shop-variants {
+ // product-thumb width + 1rem
+ padding-left: calc(22.222% + 1rem);
+
+ @include breakpoint(phablet) {
+ padding-left: 0;
+ clear: left;
+ }
+}
+
+// ROW VARIANTS
+.row.variants {
+ margin: 0 0 1em 0;
+
+ &.out-of-stock {
+ opacity: 0.2;
+ }
+
+ .variant-name,
+ .total-price {
+ padding-top: .74em;
+ }
+ .variant-price {
+ padding-top: .65em;
+ }
+
+ // Variant name
+ .variant-name {
+ padding-left: 0;
+ padding-right: 0;
+
+ @include breakpoint(phablet) {
+ padding-left: 0.5rem;
+ }
+
+ & > *:nth-child(n + 2) {
+ color: $grey-550;
+ font-size: 0.875rem;
+ font-style: italic;
+ line-height: normal;
+ }
+ }
+
+ // Variant price
+ .variant-price {
+ white-space: nowrap;
+ @include breakpoint(phablet) {
+ padding-left: 1rem;
+ }
+ }
+
+ .variant-unit-price {
+ color: $grey-700;
+ font-size: 0.85rem;
+ margin-top: 15px;
+ position: relative;
+ left: -1px;
+ }
+
+ // Total price
+ .total-price {
+ padding-left: 0rem;
+ color: $disabled-med;
+
+ .filled {
+ color: $med-drk-grey;
+ }
+
+ @include breakpoint(phablet) {
+ display: none;
+ }
+ }
+}
+
+// ROW SUMMARY
+.summary {
+ margin-left: 0;
+ margin-right: 0;
+ margin-bottom: 1.25em;
+ background: #fff;
+
+ .columns {
+ padding-top: 1em;
+ padding-bottom: 1em;
+ line-height: 1;
+
+ @include breakpoint(tablet) {
+ padding-top: 0.65rem;
+ padding-bottom: 0.65rem;
+ }
+ }
+
+ .summary-header {
+ // product-thumb width + 1rem
+ padding-left: calc(22.222% + 1rem);
+ padding-right: 1rem;
+
+ @include breakpoint(phablet) {
+ padding-left: calc(33.333% + 1rem);
+ }
+
+ .product-producer {
+ color: $grey-550;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-style: italic;
+
+ a {
+ color: $teal-500;
+
+ &:hover, &:focus, &:active {
+ color: $teal-600;
+ text-decoration: underline;
+ }
+ }
+ }
+
+ h3 {
+ font-size: 1.3rem;
+ margin-top: 0.75rem;
+ margin-bottom: 0.6rem;
+ }
+
+ h3 a {
+ color: $orange-500;
+
+ &:hover, &:focus, &:active {
+ color: $orange-600;
+ text-decoration: underline;
+ }
+ }
+
+ .product-description {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ margin-bottom: 0.75rem;
+ cursor: pointer;
+ // Force product description to be on one line
+ // and truncate with ellipsis
+ display: -webkit-box;
+ -webkit-line-clamp: 1;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ // line-clamp is not supported in Safari
+ // Trick to get overflow: hidden to work in old Safari
+ line-height: 1rem;
+ height: 1.75rem;
+
+ > div {
+ margin-bottom: 1.5rem; // Equivalent to p (trix doesn't use p as separator by default, so emulate div as p to be backward compatible)
+ }
+
+ @include trix-styles;
+ }
+
+ .product-properties {
+ margin: .5em 0;
+
+ li {
+ margin: 0 0.25rem 0.25rem 0;
+
+ a {
+ padding: 0.1em 0.625em;
+
+ cursor: auto;
+
+ &.has-tip {
+ cursor: pointer;
+ font-weight: normal;
+ }
+ &:hover, &:focus {
+ border-color: #ccc;
+ }
+ }
+
+ // Foundation doesn't show the nub on mobile.
+ // Repeating the style to show it here.
+ .nub {
+ border-color: transparent transparent #333333 transparent;
+ }
+ }
+ }
+ }
+}
diff --git a/app/webpacker/css/darkswarm/shop_partials/_shop-product-thumb.scss b/app/webpacker/css/darkswarm/shop_partials/_shop-product-thumb.scss
new file mode 100644
index 0000000000..eb88dd7405
--- /dev/null
+++ b/app/webpacker/css/darkswarm/shop_partials/_shop-product-thumb.scss
@@ -0,0 +1,28 @@
+.product-thumb {
+ // Desktop: the product summary is nine columns wide. Use two
+ // for the image. 100% / 9 * 2 = 22.222% <= 192px
+ width: calc(22.222%);
+ float: left;
+
+ // Mobile: the summary has full twelve columns and the image
+ // should take four of them. 100% / 12 * 4 = 33.333% <= 227px
+ @include breakpoint(phablet) {
+ width: calc(33.333%);
+ }
+
+ // Make this an anchor for the bulk label.
+ position: relative;
+
+ .product-thumb__bulk-label {
+ background-color: $grey-700;
+ color: white;
+ position: absolute;
+ right: 0;
+ top: .8em;
+ padding: .25em .5em;
+ }
+
+ &:hover {
+ filter: brightness(96%);
+ }
+}
diff --git a/app/webpacker/css/darkswarm/shop_partials/_typography.scss b/app/webpacker/css/darkswarm/shop_partials/_typography.scss
new file mode 100644
index 0000000000..5160a1c074
--- /dev/null
+++ b/app/webpacker/css/darkswarm/shop_partials/_typography.scss
@@ -0,0 +1,31 @@
+@mixin headingFont {
+ font-family: "Oswald", sans-serif;
+}
+
+// TODO should probably move that to a variables.scss
+$body-font: "Roboto", Arial, sans-serif;
+
+h1, h2, h3, h4, h5, h6 {
+ @include headingFont;
+
+ padding: 0px;
+}
+
+a {
+ color: $clr-brick;
+
+ &:hover, &:focus, &:active {
+ text-decoration: none;
+ color: $clr-brick-bright;
+ }
+}
+
+.text-small {
+ font-size: 0.875rem;
+ margin-bottom: 0.5rem;
+ font-family: $body-font;
+
+ &, & * {
+ font-size: 0.875rem;
+ }
+}
diff --git a/app/webpacker/css/darkswarm/split-checkout.scss b/app/webpacker/css/darkswarm/split-checkout.scss
index 1fc90b9815..2088f97286 100644
--- a/app/webpacker/css/darkswarm/split-checkout.scss
+++ b/app/webpacker/css/darkswarm/split-checkout.scss
@@ -347,7 +347,6 @@
margin-top: 40px;
.button.primary {
- background-color: $clr-turquoise;
&:hover {
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
}
diff --git a/app/webpacker/css/darkswarm/typography.scss b/app/webpacker/css/darkswarm/typography.scss
index 2261036d74..2740288f0c 100644
--- a/app/webpacker/css/darkswarm/typography.scss
+++ b/app/webpacker/css/darkswarm/typography.scss
@@ -1,14 +1,10 @@
-
-@mixin headingFont {
- font-family: "Oswald", sans-serif;
-}
+@import "shop_partials/typography";
@mixin bodyFont {
font-family: "Roboto", Arial, sans-serif;
}
$headingFont: "Oswald";
-$body-font: "Roboto", Arial, sans-serif;
body {
@include bodyFont;
@@ -16,15 +12,6 @@ body {
font-weight: 400;
}
-a {
- color: $clr-brick;
-
- &:hover, &:focus, &:active {
- text-decoration: none;
- color: $clr-brick-bright;
- }
-}
-
.text-vbig {
font-size: 2rem;
font-weight: 300;
@@ -39,16 +26,6 @@ small, .small {
font-size: 0.75rem;
}
-.text-small {
- font-size: 0.875rem;
- margin-bottom: 0.5rem;
- font-family: $body-font;
-
- &, & * {
- font-size: 0.875rem;
- }
-}
-
.text-normal {
font-weight: 400;
font-family: $body-font;
@@ -92,12 +69,6 @@ small, .small {
border-color: rgba(#ddd, 0.25);
}
-h1, h2, h3, h4, h5, h6 {
- @include headingFont;
-
- padding: 0px;
-}
-
.inline-header {
display: inline-block;
margin: 0px;
diff --git a/app/webpacker/css/mail/all.scss b/app/webpacker/css/mail/all.scss
deleted file mode 100644
index 087d2d1310..0000000000
--- a/app/webpacker/css/mail/all.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-@import '../admin/globals/palette.scss';
-@import 'email';
-@import 'payments_list';
diff --git a/app/webpacker/css/shared/question-mark-icon.scss b/app/webpacker/css/shared/question-mark-icon.scss
index e8720d207c..932c897844 100644
--- a/app/webpacker/css/shared/question-mark-icon.scss
+++ b/app/webpacker/css/shared/question-mark-icon.scss
@@ -50,8 +50,19 @@
margin-left: 2px;
}
+@mixin joyride-content {
+ background-color: $dynamic-blue;
+ padding: $padding-small;
+ border-radius: $radius-small;
+ color: $white;
+ width: 100%;
+ font-size: 0.8rem;
+}
+
+$joyride-width: 16rem;
+
.joyride-tip-guide.question-mark-tooltip {
- width: 16rem;
+ width: $joyride-width;
max-width: 65%;
// JS needs to be tweaked to adjust for left alignment - this is dynamic can't rewrite in CSS
margin-left: -7.4rem;
@@ -70,12 +81,7 @@
}
.joyride-content-wrapper {
- background-color: $dynamic-blue;
- padding: $padding-small;
- border-radius: $radius-small;
- color: $white;
- width: 100%;
- font-size: 0.8rem;
+ @include joyride-content;
}
.joyride-nub.bottom {
diff --git a/app/webpacker/js/turbo.js b/app/webpacker/js/turbo.js
index 4451810c93..d8816b4d2a 100644
--- a/app/webpacker/js/turbo.js
+++ b/app/webpacker/js/turbo.js
@@ -1,5 +1,8 @@
import "@hotwired/turbo";
+import TurboPower from "turbo_power";
+TurboPower.initialize(Turbo.StreamActions);
+
document.addEventListener("turbo:frame-missing", (event) => {
// don't replace frame contents
event.preventDefault();
diff --git a/app/webpacker/packs/admin.js b/app/webpacker/packs/admin.js
index 9ad33b1a1c..1625ce11bb 100644
--- a/app/webpacker/packs/admin.js
+++ b/app/webpacker/packs/admin.js
@@ -9,9 +9,6 @@ import "../js/moment";
import bigDecimal from "js-big-decimal";
window.bigDecimal = bigDecimal;
-import debounced from "debounced";
-debounced.initialize({ input: { wait: 300 } });
-
import Trix from "trix";
document.addEventListener("trix-before-initialize", (event) => {
diff --git a/app/webpacker/packs/mail.scss b/app/webpacker/packs/mail.scss
deleted file mode 100644
index d4f981e355..0000000000
--- a/app/webpacker/packs/mail.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "../css/mail/all.scss";
diff --git a/config/application.rb b/config/application.rb
index 09d8fb5abe..a1bda0a7d5 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -216,6 +216,7 @@ module Openfoodnetwork
config.assets.precompile += ['web/all.js']
config.assets.precompile += ['darkswarm/all.js']
config.assets.precompile += ['shared/*']
+ config.assets.precompile += ['mail.scss']
config.assets.precompile += ['*.jpg', '*.jpeg', '*.png', '*.gif' '*.svg']
# Highlight code that triggered database queries in logs.
diff --git a/config/initializers/wicked_pdf.rb b/config/initializers/wicked_pdf.rb
index d04e36dbf2..1ebccb6cc6 100644
--- a/config/initializers/wicked_pdf.rb
+++ b/config/initializers/wicked_pdf.rb
@@ -1,20 +1,13 @@
-if Rails.env.test?
- Rails.application.reloader.to_prepare do
- WickedPdf.config = {
- #:wkhtmltopdf => '/usr/local/bin/wkhtmltopdf',
- #:layout => "pdf.html",
- :page_size => 'A3',
- :exe_path => `bundle exec which wkhtmltopdf`.chomp
- }
- end
-else
- Rails.application.reloader.to_prepare do
- WickedPdf.config = {
- #:wkhtmltopdf => '/usr/local/bin/wkhtmltopdf',
- #:layout => "pdf.html",
- :page_size => 'A4', # default
- :exe_path => `bundle exec which wkhtmltopdf`.chomp
- }
+WickedPdf.configure do |c|
+ c.exe_path = `bundle exec which wkhtmltopdf`.chomp
+
+ if Rails.env.test?
+ # Conversion from PDF to text struggles with multi-line text.
+ # We avoid that by printing on bigger pages.
+ # https://github.com/openfoodfoundation/openfoodnetwork/pull/9674
+ c.page_size = "A3"
+ else
+ c.page_size = "A4"
end
end
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index c762b981bb..eabd7e2769 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -84,7 +84,6 @@ ar:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "يجب أن تكون فارغة بسبب استخدام إعدادات المخزون للمنتج"
- on_demand_but_count_on_hand_set: "يجب أن تكون فارغة إذا كانت عند الطلب"
limited_stock_but_no_count_on_hand: "يجب ان تكون تحديد بسبب فرض مدودية المخزون"
messages:
blank: "لا يمكن أن تكون فارغة"
@@ -483,6 +482,8 @@ ar:
remove: إزالة
image:
edit: تعديل
+ product_preview:
+ shop_tab: المتجر
adjustments:
skipped_changing_canceled_order: "لا يمكنك تغيير الطلب الذي تم إلغاؤه."
begins_at: يبدأ عند
@@ -686,7 +687,6 @@ ar:
variants:
infinity: "ما لا نهاية"
to_order_tip: "لا تحتوي المواد التي تريد طلبها على مستوى مخزون محدد ، مثل أرغفة الخبز المصنوعة طازجة حسب الطلب."
- back_to_products_list: "العودة إلى قائمة المنتجات"
editing_product: "تحرير المنتج"
tabs:
product_details: "تفاصيل المنتج"
@@ -1198,10 +1198,8 @@ ar:
contact_name: اسم جهة الاتصال
edit:
editing: 'الإعدادات:'
- back_link: العودة إلى قائمة المؤسسات
new:
title: شركة جديدة
- back_link: العودة إلى قائمة المؤسسات
welcome:
welcome_title: مرحبا بكم في شبكة الغذاء المفتوح الاردن - فلاحة جو !
welcome_text: لقد نجحت في إنشاء
@@ -1238,6 +1236,8 @@ ar:
choose_products_from: "اختر المنتجات من:"
re_notify_producers: إعادة إخطار المنتجين
notify_producers_tip: سيؤدي هذا إلى إرسال بريد إلكتروني إلى كل منتج مع قائمة طلباتهم.
+ date_time_warning_modal_content:
+ cancel: 'إلغاء'
incoming:
incoming: "الوارد"
supplier: "المورد"
@@ -2651,7 +2651,6 @@ ar:
spree_admin_single_enterprise_hint: "لمحة: للسماح للأشخاص بالعثور عليك ، قم بتشغيل الرؤية الخاصة بك أسفل"
spree_admin_eg_pickup_from_school: "على سبيل المثال. "البيك اب من المدرسة الابتدائية""
spree_admin_eg_collect_your_order: "على سبيل المثال. "يرجى جمع طلبك من 123 Imaginary St، Northcote ، 3070""
- spree_classification_primary_taxon_error: "Taxon %{taxon} هو التصنيف الأساسي %{product} ولا يمكن حذفه"
spree_order_availability_error: "لا يمكن لموزع أو دورة طلب توفير المنتجات في سلة التسوق"
spree_order_populator_error: "لا يمكن لهذا الموزع أو دورة الطلب توفير جميع المنتجات في سلة التسوق. الرجاء اختيار آخر."
spree_order_cycle_error: "الرجاء اختيار دورة الطلب لهذا الطلب."
@@ -2964,7 +2963,7 @@ ar:
order_cycles_no_permission_to_coordinate_error: "لا تملك أي من مؤسساتك إذنًا لتنسيق دورة الطلب"
order_cycles_no_permission_to_create_error: "ليس لديك إذن لإنشاء دورة طلب تنسقها تلك المؤسسة"
order_cycle_closed: "تم إغلاق دورة الطلب التي حددتها للتو. حاول مرة اخرى!"
- back_to_orders_list: "العودة إلى قائمة الطلب"
+ back_to_orders_list: "العودة إلى قائمة الطلبات"
no_orders_found: "لم يتم العثور على أية طلبات"
order_information: "معلومات الطلب"
new_payment: "دفعة جديد"
@@ -3300,6 +3299,8 @@ ar:
سيؤدي ذلك إلى ضبط مستوى المخزون لصفر على جميع المنتجات
المؤسسة غير موجودة في الملف الذي تم تحميله.
order_cycles:
+ unsaved_changes: "لم تحفظ التغييرات"
+ bulk_save_error: "عذرا لا! لم أستطع حفظ تغييراتك."
create_failure: "فشل في تكوين دورة الطلب"
update_success: 'تم تحديث دورة الطلب.'
update_failure: "فشل في تحديث دورة الطلب"
@@ -3617,7 +3618,6 @@ ar:
more: "أكثر"
new_adjustment: "تعديل جديد"
new_tax_category: "فئة ضريبية جديدة"
- new_taxon: "اصنوفة جديدة"
new_user: "مستخدم جديد"
no_pending_payments: "لا توجد دفعات معلقة"
remove: "إزالة"
@@ -3636,8 +3636,6 @@ ar:
delivery: "موقعة ومختومة وتم التسليم"
start_date: "تاريخ البدء"
successfully_removed: "تمت الإزالة بنجاح"
- taxonomy_edit: "التصنيف"
- tree: "شجرة"
updating: "تحديث"
your_order_is_empty_add_product: "طلبك فارغ ، يرجى البحث عن المنتج أعلاه وإضافته"
add_product: "أضف منتج"
@@ -3733,7 +3731,6 @@ ar:
tax_rate_amount_explanation: "معدلات الضرائب هي مبلغ عشري للمساعدة في العمليات الحسابية ، (أي إذا كان معدل الضريبة 5٪ ، فأدخل 0.05)"
included_in_price: "المدرجة في السعر"
show_rate_in_label: "عرض السعر في التسمية"
- back_to_tax_rates_list: "العودة إلى قائمة أسعار الضرائب"
tax_settings: "الإعدادات الضريبية"
zones: "مناطق"
new_zone: "منطقة جديدة"
@@ -3746,14 +3743,11 @@ ar:
iso_name: "اسم شهادة ISO"
states_required: "المنطقة مطلوبة"
editing_country: "تحرير الدولة"
- back_to_countries_list: "العودة إلى قائمة الدول"
states: "محافظات"
abbreviation: "الاختصار"
new_state: "محافظة جديدة"
payment_methods: "طرق الدفع"
- taxonomies: "التصنيفات"
- new_taxonomy: "تصنيف جديد"
- back_to_taxonomies_list: "العودة إلى قائمة التصنيفات"
+ taxons: "فئات المنتجات"
shipping_methods: "طرق الشحن"
shipping_method: "طريقة الشحن"
shipment: "الشحنة"
@@ -3910,7 +3904,6 @@ ar:
continue: "تابع"
new:
new_return_authorization: "عودة الترخيص جديد"
- back_to_return_authorizations_list: "العودة إلى قائمة عودة الترخيص"
continue: "تابع"
edit:
receive: "استلام"
@@ -4218,9 +4211,10 @@ ar:
total: "المجموع"
billing_address_name: "الاسم"
taxons:
+ index:
+ title: "فئات المنتجات"
form:
name: الاسم
- permalink: الرابط الثابت
description: وصف
general_settings:
edit:
@@ -4458,7 +4452,6 @@ ar:
key_cleared: "تم مسح المفتاح"
shipment:
cannot_ready: "لا يمكن تجهيز الشحنة"
- invalid_taxonomy_id: "معرف التصنيف غير صالح."
toggle_api_key_view: "إظهار عرض مفتاح API للمستخدم"
activerecord:
models:
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 6e1732d504..dd8bf38bce 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -86,7 +86,6 @@ ca:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "ha d'estar en blanc perquè s'utilitza la configuració d'estoc de la productora"
- on_demand_but_count_on_hand_set: "ha d'estar en blanc si és sota demanda"
limited_stock_but_no_count_on_hand: "cal especificar-se perquè força existències limitades"
messages:
blank: "no es pot deixar en blanc"
@@ -511,6 +510,8 @@ ca:
remove: Eliminar
image:
edit: Editar
+ product_preview:
+ shop_tab: Botiga
adjustments:
skipped_changing_canceled_order: "No podeu canviar una comanda cancel·lada."
begins_at: Comença a
@@ -717,7 +718,6 @@ ca:
variants:
infinity: "Infinit"
to_order_tip: "Els articles preparats per encàrrec no tenen un nivell fixat d'existències, com ara pa fet sota comanda."
- back_to_products_list: "Torna a la llista de productes"
editing_product: "Editant el producte"
tabs:
product_details: "Detalls del producte"
@@ -755,7 +755,6 @@ ca:
search: Cerca
sort:
pagination:
- total_html: "%{total} productes trobats pels vostres criteris de cerca. Mostrant de %{from} a %{to} ."
per_page:
show: Mostra
per_page: "%{num} per pàgina"
@@ -1253,10 +1252,8 @@ ca:
contact_name: Nom de contacte
edit:
editing: 'Configuració:'
- back_link: Tornar a la llista d'organitzacions
new:
title: Nova organització
- back_link: 'Tornar a la llista d''organitzacions '
welcome:
welcome_title: Benvingut a Katuma - Open Food Network!
welcome_text: Heu creat correctament un
@@ -1292,6 +1289,8 @@ ca:
save_and_back_to_list: "Desa i torna a la llista"
choose_products_from: "Trieu Productes des de:"
notify_producers_tip: Això enviarà un correu electrònic a cada productor amb la llista dels seus productes demanats a les comandes.
+ date_time_warning_modal_content:
+ cancel: 'Cancel·lar'
incoming:
incoming: "Entrant"
supplier: "Proveïdora"
@@ -2656,7 +2655,6 @@ ca:
spree_admin_single_enterprise_hint: "Suggeriment: per permetre que la gent us trobi, activeu la vostra visibilitat"
spree_admin_eg_pickup_from_school: "p. ex: 'Recollida al local del grup de consum'"
spree_admin_eg_collect_your_order: "p. ex: \"Recolliu la vostra comanda al c/Ample, n. 123'"
- spree_classification_primary_taxon_error: "El taxó %{taxon} és el principal taxó d'%{product} i no es pot eliminar"
spree_order_availability_error: "La distribuïdora o el cicle de comanda no pot subministrar els productes de la vostra cistella"
spree_order_populator_error: "Aquesta distribuïdora o cicle de comanda no pot subministrar tots els productes de la vostra cistella. Si us plau trieu-ne d'altres."
spree_order_cycle_error: "Seleccioneu un cicle per a aquesta comanda."
@@ -2947,7 +2945,7 @@ ca:
order_cycles_no_permission_to_coordinate_error: "Cap de les vostres organitzacions té permís per coordinar un cicle de comanda"
order_cycles_no_permission_to_create_error: "No teniu permís per crear un cicle de comandes coordinat per aquesta organització"
order_cycle_closed: "El cicle de comandes que has triat acaba de tancar. Sisplau prova en un altre moment."
- back_to_orders_list: "Torna a la llista de comandes"
+ back_to_orders_list: "Tornar a la llista de comandes"
no_orders_found: "No s'han trobat comandes"
order_information: "Informació de la comanda"
new_payment: "Nou pagament"
@@ -3281,6 +3279,8 @@ ca:
Això establirà el nivell d'estoc a zero en tots els productes per aquesta
organització que no estan presents al fitxer carregat.
order_cycles:
+ unsaved_changes: "Teniu canvis sense desar"
+ bulk_save_error: "Ah no! No he pogut desar els canvis."
create_failure: "No s'ha pogut crear el cicle de comanda"
update_success: 'S''ha actualitzat el cicle de comanda.'
update_failure: "No s'ha pogut actualitzar el cicle de comanda"
@@ -3494,7 +3494,6 @@ ca:
more: "Més"
new_adjustment: "Nou ajustament"
new_tax_category: "Nova categoria fiscal"
- new_taxon: "Nou tàxon"
new_user: "Nou usuari"
no_pending_payments: "No hi ha pagaments pendents"
remove: "Eliminar"
@@ -3513,8 +3512,6 @@ ca:
delivery: "Signat, segellat, lliurat"
start_date: "Data d'inici"
successfully_removed: "S'ha suprimit correctament"
- taxonomy_edit: "Edició de taxonomia"
- tree: "Arbre"
updating: "Actualitzant"
your_order_is_empty_add_product: "La comanda està buida, si us plau cerca i afegeix un producte a dalt"
add_product: "Afegeix un producte"
@@ -3611,7 +3608,6 @@ ca:
tax_rate_amount_explanation: "Les taxes impositives són un import decimal per ajudar en els càlculs (és a dir, si el tipus impositiu és del 5%, introduïu 0,05)"
included_in_price: "Inclòs al preu"
show_rate_in_label: "Mostra l'impost a l'etiqueta"
- back_to_tax_rates_list: "Tornar a la llista d'impostos"
tax_settings: "Configuració fiscal"
zones: "Zones"
new_zone: "Nova zona"
@@ -3624,14 +3620,11 @@ ca:
iso_name: "Nom ISO"
states_required: "Estats obligatoris"
editing_country: "Editar el país"
- back_to_countries_list: "Torna a la llista de països"
states: "Estats"
abbreviation: "Abreviatura"
new_state: "Nou estat"
payment_methods: "Mètodes de Pagament"
- taxonomies: "Taxonomies"
- new_taxonomy: "Nova taxonomia"
- back_to_taxonomies_list: "Torna a la llista de taxonomies"
+ taxons: "Tipus de productes"
shipping_methods: "Mètodes d'enviament"
shipping_method: "Mètode d'enviament"
shipment: "Enviament"
@@ -3785,7 +3778,6 @@ ca:
continue: "Continua"
new:
new_return_authorization: "Nova autorització de devolució"
- back_to_return_authorizations_list: "Tornar a la llista d'autorització"
continue: "Continua"
edit:
receive: "rebre"
@@ -4021,6 +4013,7 @@ ca:
product_name: Nom del producte
primary_taxon_form:
product_category: Categoria del producte
+ search_for_categories: "Cercar categories"
group_buy_form:
group_buy: "Compra en grup?"
bulk_unit_size: Mida de la unitat a granel
@@ -4096,9 +4089,10 @@ ca:
total: "Total"
billing_address_name: "Nom"
taxons:
+ index:
+ title: "Tipus de productes"
form:
name: Nom
- permalink: Enllaç permanent
description: Descripció
general_settings:
edit:
@@ -4326,7 +4320,6 @@ ca:
key_cleared: "La clau esborrada"
shipment:
cannot_ready: "No es pot fer l'enviament."
- invalid_taxonomy_id: "Identificador de taxonomia no vàlid."
activerecord:
models:
spree/payment:
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index 9b111b2005..24eea9cbe6 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -81,8 +81,6 @@ cy:
white_label_logo_link: "Defnyddiwyd dolen i’r logo yn ffrynt y siop"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Mae etifeddu’r categori treth yn golygu bod angen cyfrifiannell fesul eitem."
spree/user:
attributes:
email:
@@ -102,7 +100,6 @@ cy:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "rhaid bod yn wag oherwydd defnydd o osodiadau stoc cynhyrchwyr"
- on_demand_but_count_on_hand_set: "rhaid iddo fod yn wag os ar alw"
limited_stock_but_no_count_on_hand: "rhaid nodi hyn oherwydd gorfodi stoc gyfyngedig"
messages:
confirmation: "Nid yw’n cyfateb %{attribute}"
@@ -470,7 +467,7 @@ cy:
password_confirmation: Cadarnhau Cyfrinair
reset_password_token: Ailosod y cyfrinair
expired: wedi dod i ben, gofynnwch am un newydd
- back_to_payments_list: "Yn ôl i'r Rhestr Taliadau"
+ back_to_payments_list: "Yn ôl at y Rhestr Taliadau"
maestro_or_solo_cards: "Cardiau Maestro / Solo"
backordered: "Ol-archebwyd"
on_hand: "Ar gael"
@@ -541,6 +538,8 @@ cy:
remove: Dileu
image:
edit: Golygu
+ product_preview:
+ shop_tab: Siop
adjustments:
skipped_changing_canceled_order: "Nid yw'n bosib newid archeb a ganslwyd"
begins_at: Yn dechrau am
@@ -747,7 +746,6 @@ cy:
variants:
infinity: "Anfeidredd"
to_order_tip: "Nid oes gan eitemau a gynhyrchir ar gyfer archeb lefel stoc benodol, megis torthau o fara a gynhyrchir yn ffres ar gyfer archeb."
- back_to_products_list: "Yn ôl i'r rhestr cynnyrch"
editing_product: "Golygu cynnyrch"
tabs:
product_details: "Manylion Cynnyrch"
@@ -785,7 +783,6 @@ cy:
search: Chwilio
sort:
pagination:
- total_html: "%{total}Cafwyd hyd i cynnyrch ar gyfer eich meini prawf chwilio. Yn dangos %{from} i %{to}."
per_page:
show: Dangos
per_page: "%{num} fesul tudalen"
@@ -1315,10 +1312,8 @@ cy:
contact_name: Enw Cyswllt
edit:
editing: 'Gosodiadau:'
- back_link: Yn ôl i'r rhestr mentrau
new:
title: Menter Newydd
- back_link: Yn ôl i'r rhestr mentrau
welcome:
welcome_title: Croeso i'r Open Food Network!
welcome_text: 'Rydych chi wedi llwyddo i greu '
@@ -1355,6 +1350,8 @@ cy:
choose_products_from: "Dewis Cynnyrch gan:"
re_notify_producers: Ail-hysbysu cynhyrchwyr.
notify_producers_tip: Trwy hyn anfonir ebost at bob cynhyrchydd gyda rhestr o'r archebion.
+ date_time_warning_modal_content:
+ cancel: 'Canslo'
incoming:
incoming: "Yn dod i mewn"
supplier: "Cyflenwr"
@@ -2799,7 +2796,6 @@ cy:
spree_admin_single_enterprise_hint: "Awgrym: Er mwyn caniatáu i bobl ddod o hyd i chi, gofalwch fod pobl yn gallu eich gweld"
spree_admin_eg_pickup_from_school: "e.e. 'Casglu o'r Ysgol Gynradd'"
spree_admin_eg_collect_your_order: "e.e. 'Dylid casglu eich archeb o 123 Ffordd y Don, Pwllheli'"
- spree_classification_primary_taxon_error: "Tacson %{taxon} yw prif dacson %{product} ac ni ellir ei ddileu"
spree_order_availability_error: "Ni all dosbarthwr neu gylch archebu gyflenwi'r cynnyrch yn eich basged"
spree_order_populator_error: "Ni all y dosbarthwr neu'r cylch archebu dan sylw gyflenwi'r holl gynnyrch yn eich basged. Dewiswch un arall."
spree_order_cycle_error: "Dewiswch gylch archebu ar gyfer archeb hwn."
@@ -3119,7 +3115,7 @@ cy:
order_cycles_no_permission_to_coordinate_error: "Nid oes gan unrhyw un o'ch mentrau ganiatâd i gydlynu cylch archebu"
order_cycles_no_permission_to_create_error: "Nid oes gennych ganiatâd i greu cylch archebu a gydlynwyd gan y fenter honno"
order_cycle_closed: "Mae'r cylch archebu a ddewiswyd newydd gau. Rhowch gynnig arall!"
- back_to_orders_list: "Yn ôl i'r rhestr archebu"
+ back_to_orders_list: "Yn ôl i'r Rhestr Archebion"
no_orders_found: "Ni ddaethpwyd o hyd i archebion"
order_information: "Gwybodaeth Archebu"
new_payment: "Taliad Newydd"
@@ -3462,6 +3458,8 @@ cy:
This will set stock level to zero on all products for this
enterprise that are not present in the uploaded file.
order_cycles:
+ unsaved_changes: "Mae gennych chi newidiadau heb eu cadw"
+ bulk_save_error: "O na! Nid oeddyn bosib cadw eich newidiadau."
create_failure: "Wedi methu creu cylch archebu"
update_success: 'Diweddarwyd eich cylch archebu'
update_failure: "Wedi methu diweddaru'r cylch archebu"
@@ -3732,7 +3730,6 @@ cy:
more: "Mwy"
new_adjustment: "Addasiad newydd"
new_tax_category: "Categori treth newydd"
- new_taxon: "Tacson newydd"
new_user: "Defnyddiwr newydd"
no_pending_payments: "Dim taliadau yn yr arfaeth"
remove: "Dileu"
@@ -3751,8 +3748,6 @@ cy:
delivery: "Llofnodwyd, cadarnhawyd a chyflenwyd"
start_date: "Dyddiad cychwyn"
successfully_removed: "Llwyddwyd i ddileu"
- taxonomy_edit: "Golygu tacsonomi"
- tree: "Coeden"
updating: "Yn diweddaru"
your_order_is_empty_add_product: "Mae eich archeb yn wag, chwiliwch am ac ychwanegwch gynnyrch uchod"
add_product: "Ychwanegu Cynnyrch"
@@ -3849,7 +3844,6 @@ cy:
tax_rate_amount_explanation: "Mae cyfraddau treth yn swm degol i helpu gyda chyfrifiadau, (h.y. os yw'r gyfradd dreth yn 5% yna nodwch 0.05)"
included_in_price: "Wedi'i gynnwys yn y Pris"
show_rate_in_label: "Dangos cyfradd yn y label"
- back_to_tax_rates_list: "Yn ôl i'r Rhestr Cyfraddau Treth"
tax_settings: "Gosodiadau Treth"
zones: "Parthau"
new_zone: "Parth Newydd"
@@ -3862,14 +3856,11 @@ cy:
iso_name: "Enw ISO"
states_required: "Angen y Siroedd"
editing_country: "Yn golygu'r wlad "
- back_to_countries_list: "Yn ôl i'r Rhestr Gwledydd"
states: "Siroedd"
abbreviation: "Talfyriad"
new_state: "Sir Newydd"
payment_methods: "Dulliau Talu"
- taxonomies: "Tacsonomeg"
- new_taxonomy: "Tacsonomeg Newydd"
- back_to_taxonomies_list: "Yn ôl i'r Rhestr Tacsonomeg"
+ taxons: "Categorïau Cynnyrch"
shipping_methods: "Dulliau Anfon"
shipping_method: "Dull Anfon"
shipment: "Llwyth"
@@ -4029,7 +4020,6 @@ cy:
continue: "Parhau"
new:
new_return_authorization: "Awdurdodi Dychwelyd nwyddau newydd"
- back_to_return_authorizations_list: "Yn ôl i'r rhestr awdurdodi dychwelyd nwyddau"
continue: "Parhau"
edit:
receive: "derbyn"
@@ -4273,6 +4263,7 @@ cy:
product_name: Enw Cynnyrch
primary_taxon_form:
product_category: Categori Cynnyrch
+ search_for_categories: "Chwilio am gategorïau"
group_buy_form:
group_buy: "Prynu fel Grŵp?"
bulk_unit_size: Maint uned swmp
@@ -4350,13 +4341,15 @@ cy:
total: "Cyfanswm"
billing_address_name: "Enw"
taxons:
+ index:
+ title: "Categorïau Cynnyrch"
form:
name: Enw
- permalink: Permalink
meta_title: Meta Title
meta_description: Meta Description
meta_keywords: Meta Keywords
description: Disgrifiad
+ dfc_id: DFC URI
general_settings:
edit:
legal_settings: "Gosodiadau Cyfreithiol"
@@ -4593,7 +4586,6 @@ cy:
key_cleared: "Cliriwyd yr Allwedd"
shipment:
cannot_ready: "Methu â pharatoi'r llwyth."
- invalid_taxonomy_id: "Tacsonomeg id. annilys"
toggle_api_key_view: "Dangos gwedd yr allwedd API ar gyfer y defnyddiwr."
activerecord:
models:
diff --git a/config/locales/de_CH.yml b/config/locales/de_CH.yml
index 3606cc8eee..d99c0dd4fa 100644
--- a/config/locales/de_CH.yml
+++ b/config/locales/de_CH.yml
@@ -72,7 +72,6 @@ de_CH:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "muss leer sein, da die Einstellungen des Produzentenbestands verwendet werden"
- on_demand_but_count_on_hand_set: "muss leer sein, wenn unbegrenzt verfügbar oder die Produktion auf Bestellung erfolgt"
limited_stock_but_no_count_on_hand: "muss angegeben werden, da nur begrenzte Lagerbestände verfügbar sind"
messages:
blank: "darf nicht leer sein"
@@ -475,6 +474,8 @@ de_CH:
remove: Löschen
image:
edit: Bearbeiten
+ product_preview:
+ shop_tab: Laden
adjustments:
skipped_changing_canceled_order: "Eine stornierte Bestellung kann nicht geändert werden."
begins_at: Beginnt
@@ -673,7 +674,6 @@ de_CH:
variants:
infinity: "Unbegrenzt"
to_order_tip: "Artikel, die auf Anfrage hergestellt werden, haben keinen festgelegten Lagerbestand."
- back_to_products_list: "Zurück zur Produktliste"
editing_product: "Produkt bearbeiten"
tabs:
product_details: "Produktdetails"
@@ -1164,10 +1164,8 @@ de_CH:
contact_name: Kontaktname
edit:
editing: 'Einstellungen:'
- back_link: Zurück zur Unternehmensliste
new:
title: Neues Unternehmen
- back_link: Zurück zur Unternehmensliste
welcome:
welcome_title: Willkommen im Open Food Schweiz!
welcome_text: 'Erfolgreich erstellt:'
@@ -1204,6 +1202,8 @@ de_CH:
choose_products_from: "Wählen Sie Produkte von:"
re_notify_producers: Produzenten erneut benachrichtigen
notify_producers_tip: Benachrichtigen Sie die Produzenten per E-Mail über in diesem Bestellzyklus erhaltene Bestellungen.
+ date_time_warning_modal_content:
+ cancel: 'Stornieren'
incoming:
incoming: "Eingehend"
supplier: "Lieferant"
@@ -2574,7 +2574,6 @@ de_CH:
spree_admin_single_enterprise_hint: "Tipp: Damit andere Nutzer Sie finden können, aktivieren Sie Ihre Sichtbarkeit unter:"
spree_admin_eg_pickup_from_school: "z. B. \"Abholung von der Grundschule\""
spree_admin_eg_collect_your_order: "z. B. 'Bitte holen Sie Ihre Bestellung in der Gartenstrasse 123 in 30701 Nordwestheim ab.'"
- spree_classification_primary_taxon_error: "Kategorie %{taxon} ist die primäre Kategorie von %{product} und kann nicht gelöscht werden."
spree_order_availability_error: "Verteilstelle oder Bestellzyklus kann die Produkte in Ihrem Warenkorb nicht liefern"
spree_order_populator_error: "Diese Verteilstelle oder dieser Bestellzyklus kann nicht alle Produkte aus Ihrem Warenkorb liefern. Bitte ändern Sie Ihre Auswahl."
spree_order_cycle_error: "Bitte wählen Sie einen Bestellzyklus für diese Bestellung aus."
@@ -3210,6 +3209,8 @@ de_CH:
Dadurch wird der Lagerbestand für alle Produkte dieses Unternehmens,
die in der hochgeladenen Datei nicht vorhanden sind, auf Null gesetzt.
order_cycles:
+ unsaved_changes: "Sie haben nicht gespeicherte Änderungen."
+ bulk_save_error: "Ihre Änderungen konnten leider nicht gespeichert werden."
create_failure: "Fehler beim Erstellen des Bestellzyklus."
update_success: 'Ihr Bestellzyklus wurde aktualisiert.'
update_failure: "Fehler beim Aktualisieren des Bestellzyklus."
@@ -3423,7 +3424,6 @@ de_CH:
more: "Mehr"
new_adjustment: "Neue Anpassung"
new_tax_category: "Neue Steuerkategorie"
- new_taxon: "Neue Kategorie"
new_user: "Neuer Benutzer"
no_pending_payments: "Keine ausstehenden Zahlungen."
remove: "Löschen"
@@ -3440,8 +3440,6 @@ de_CH:
UPS Ground: "UPS Ground"
start_date: "Anfangsdatum"
successfully_removed: "Erfolgreich gelöscht"
- taxonomy_edit: "Kategorien bearbeiten"
- tree: "Struktur"
updating: "Aktualisierung"
your_order_is_empty_add_product: "Ihre Bestellung ist leer. Suchen Sie oben ein Produkt und fügen Sie es hinzu."
add_product: "Produkt hinzufügen"
@@ -3536,7 +3534,6 @@ de_CH:
tax_rate_amount_explanation: "Eingabe als Dezimalbetrag (d. h. bei Steuersatz 5 %, geben Sie 0.05 ein)."
included_in_price: "Im Preis enthalten"
show_rate_in_label: "Steuersatz im Namen anzeigen"
- back_to_tax_rates_list: "Zurück zur Liste der Steuersätze"
tax_settings: "Steuereinstellungen"
zones: "Zonen"
new_zone: "Neue Zone"
@@ -3549,14 +3546,11 @@ de_CH:
iso_name: "ISO-Name"
states_required: "Staaten/Bundesländer/Regionen erforderlich"
editing_country: "Land bearbeiten"
- back_to_countries_list: "Zurück zur Länderliste"
states: "Bundesländer"
abbreviation: "Abkürzung"
new_state: "Neuer Kanton"
payment_methods: "Zahlungsarten"
- taxonomies: "Kategorien"
- new_taxonomy: "Neue Kategorie"
- back_to_taxonomies_list: "Zurück zur Kategorieliste"
+ taxons: "Produktkategorien"
shipping_methods: "Lieferoptionen"
shipping_method: "Lieferoption"
shipment: "Lieferung"
@@ -3710,7 +3704,6 @@ de_CH:
continue: "Weiter"
new:
new_return_authorization: "Neue Retour"
- back_to_return_authorizations_list: "Zurück zur Retourenliste"
continue: "Weiter"
edit:
receive: "erhalten"
@@ -4002,9 +3995,10 @@ de_CH:
total: "Gesamt"
billing_address_name: "Name"
taxons:
+ index:
+ title: "Produktkategorien"
form:
name: Name
- permalink: Permalink
description: Beschreibung
general_settings:
edit:
@@ -4223,7 +4217,6 @@ de_CH:
key_cleared: "Schlüssel gelöscht"
shipment:
cannot_ready: "Versand nicht möglich."
- invalid_taxonomy_id: "Ungültige Kategorie-ID"
activerecord:
models:
spree/payment:
diff --git a/config/locales/de_DE.yml b/config/locales/de_DE.yml
index dee8187e4c..03b4024610 100644
--- a/config/locales/de_DE.yml
+++ b/config/locales/de_DE.yml
@@ -81,8 +81,6 @@ de_DE:
white_label_logo_link: "Verlinkungsziel des Logos im Online-Shop"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Um die Steuerkategorie des Produkts zu übernehmen, muss in der Spalte \"Berechnung\" eine Auswahl mit Zusatz \"pro Artikel\" verwendet werden."
spree/user:
attributes:
email:
@@ -102,7 +100,6 @@ de_DE:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "muss leer sein, da die Einstellungen des Produzentenbestands verwendet werden"
- on_demand_but_count_on_hand_set: "muss leer sein, wenn unbegrenzt verfügbar oder die Produktion auf Bestellung erfolgt"
limited_stock_but_no_count_on_hand: "muss angegeben werden, da nur begrenzte Lagerbestände verfügbar sind"
messages:
confirmation: "stimmt nicht mit %{attribute} überein"
@@ -541,6 +538,8 @@ de_DE:
remove: Löschen
image:
edit: Bearbeiten
+ product_preview:
+ shop_tab: Produkte
adjustments:
skipped_changing_canceled_order: "Eine stornierte Bestellung kann nicht geändert werden."
begins_at: Beginnt
@@ -747,7 +746,6 @@ de_DE:
variants:
infinity: "Unbegrenzt"
to_order_tip: "Artikel, die auf Anfrage hergestellt werden, haben keinen festgelegten Lagerbestand."
- back_to_products_list: "Zurück zur Produktliste"
editing_product: "Produkt bearbeiten"
tabs:
product_details: "Produktdetails"
@@ -772,7 +770,6 @@ de_DE:
search: Suche
sort:
pagination:
- total_html: "%{total} Produkte für Ihre Suchkriterien gefunden. Zeige %{from} bis %{to}."
per_page:
show: Zeige
per_page: "%{num} pro Seite"
@@ -1295,10 +1292,8 @@ de_DE:
contact_name: Kontaktname
edit:
editing: 'Einstellungen:'
- back_link: Zurück zur Unternehmensliste
new:
title: Neues Unternehmen
- back_link: Zurück zur Unternehmensliste
welcome:
welcome_title: Willkommen im Open Food Network!
welcome_text: 'Erfolgreich erstellt:'
@@ -1335,6 +1330,8 @@ de_DE:
choose_products_from: "Wählen Sie Produkte von:"
re_notify_producers: Produzenten erneut benachrichtigen
notify_producers_tip: Benachrichtigen Sie die Produzenten per E-Mail über in diesem Bestellzyklus erhaltene Bestellungen.
+ date_time_warning_modal_content:
+ cancel: 'Abbrechen'
incoming:
incoming: "Eingehend"
supplier: "Lieferant"
@@ -2779,7 +2776,6 @@ de_DE:
spree_admin_single_enterprise_hint: "Tipp: Damit andere Nutzer Sie finden können, aktivieren Sie Ihre Sichtbarkeit unter:"
spree_admin_eg_pickup_from_school: "z. B. \"Abholung von der Grundschule\""
spree_admin_eg_collect_your_order: "z. B. 'Bitte holen Sie Ihre Bestellung in der Gartenstraße 123 in 30701 Nordwestheim ab.'"
- spree_classification_primary_taxon_error: "Kategorie %{taxon} ist die primäre Kategorie von %{product} und kann nicht gelöscht werden."
spree_order_availability_error: "Verteilstelle oder Bestellzyklus kann die Produkte in Ihrem Warenkorb nicht liefern"
spree_order_populator_error: "Diese Verteilstelle oder dieser Bestellzyklus kann nicht alle Produkte aus Ihrem Warenkorb liefern. Bitte ändern Sie Ihre Auswahl."
spree_order_cycle_error: "Bitte wählen Sie einen Bestellzyklus für diese Bestellung aus."
@@ -3450,6 +3446,8 @@ de_DE:
Dadurch wird der Lagerbestand für alle Produkte dieses Unternehmens,
die in der hochgeladenen Datei nicht vorhanden sind, auf Null gesetzt.
order_cycles:
+ unsaved_changes: "Sie haben nicht gespeicherte Änderungen."
+ bulk_save_error: "Ihre Änderungen konnten leider nicht gespeichert werden."
create_failure: "Fehler beim Erstellen des Bestellzyklus."
update_success: 'Ihr Bestellzyklus wurde aktualisiert.'
update_failure: "Fehler beim Aktualisieren des Bestellzyklus."
@@ -3671,7 +3669,6 @@ de_DE:
more: "Mehr"
new_adjustment: "Neue Anpassung"
new_tax_category: "Neue Steuerkategorie"
- new_taxon: "Neue Kategorie"
new_user: "Neuer Benutzer"
no_pending_payments: "Keine ausstehenden Zahlungen."
remove: "Löschen"
@@ -3690,8 +3687,6 @@ de_DE:
delivery: "Lieferung"
start_date: "Anfangsdatum"
successfully_removed: "Erfolgreich gelöscht"
- taxonomy_edit: "Kategorien bearbeiten"
- tree: "Struktur"
updating: "Aktualisierung"
your_order_is_empty_add_product: "Ihre Bestellung ist leer. Suchen Sie oben ein Produkt und fügen Sie es hinzu."
add_product: "Produkt hinzufügen"
@@ -3788,7 +3783,6 @@ de_DE:
tax_rate_amount_explanation: "Eingabe als Dezimalbetrag (d. h. bei Steuersatz 5 %, geben Sie 0.05 ein)."
included_in_price: "Im Preis enthalten"
show_rate_in_label: "Steuersatz im Namen anzeigen"
- back_to_tax_rates_list: "Zurück zur Liste der Steuersätze"
tax_settings: "Steuereinstellungen"
zones: "Zonen"
new_zone: "Neue Zone"
@@ -3801,14 +3795,11 @@ de_DE:
iso_name: "ISO-Name"
states_required: "Staaten/Bundesländer/Regionen erforderlich"
editing_country: "Land bearbeiten"
- back_to_countries_list: "Zurück zur Länderliste"
states: "Bundesländer"
abbreviation: "Abkürzung"
new_state: "Neues Bundesland"
payment_methods: "Zahlungsarten"
- taxonomies: "Kategorien"
- new_taxonomy: "Neue Kategorie"
- back_to_taxonomies_list: "Zurück zur Kategorieliste"
+ taxons: "Produktkategorien"
shipping_methods: "Lieferoptionen"
shipping_method: "Lieferoption"
shipment: "Lieferung"
@@ -3966,7 +3957,6 @@ de_DE:
continue: "Weiter"
new:
new_return_authorization: "Neue Retour"
- back_to_return_authorizations_list: "Zurück zur Retourenliste"
continue: "Weiter"
edit:
receive: "erhalten"
@@ -4281,9 +4271,10 @@ de_DE:
total: "Gesamt"
billing_address_name: "Name"
taxons:
+ index:
+ title: "Produktkategorien"
form:
name: Name
- permalink: Permalink
description: Beschreibung
general_settings:
edit:
@@ -4520,7 +4511,6 @@ de_DE:
key_cleared: "Schlüssel gelöscht"
shipment:
cannot_ready: "Versand nicht möglich."
- invalid_taxonomy_id: "Ungültige Kategorie-ID"
toggle_api_key_view: "API-Schlüssel dem Benutzer anzeigen"
activerecord:
models:
diff --git a/config/locales/el.yml b/config/locales/el.yml
index e8a12eee70..e5b8efc881 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -78,8 +78,6 @@ el:
white_label_logo_link: "Σύνδεσμος για το λογότυπο που χρησιμοποιείται στο κατάστημα"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Η απόδοση της κατηγορίας φόρου απαιτεί έναν υπολογιστή ανά αντικείμενο."
spree/image:
attributes:
attachment:
@@ -103,7 +101,6 @@ el:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "πρέπει να είναι κενό επειδή χρησιμοποιούνται ρυθμίσεις αποθεμάτων παραγωγού"
- on_demand_but_count_on_hand_set: "πρέπει να παραμείνει κενό αν είναι κατόπιν ζήτησης"
limited_stock_but_no_count_on_hand: "πρέπει να καθοριστεί επειδή δημιουργεί περιορισμένο απόθεμα"
messages:
confirmation: "δεν ταιριάζει "
@@ -454,7 +451,7 @@ el:
admin_and_handling: Διαχείριση
profile: Προφίλ
supplier_only: Μόνο Προμηθευτής
- has_shopfront: Διαθέτει σελίδα καταστήματος
+ has_shopfront: Ενεργό κατάστημα
weight: Βάρος
volume: Όγκος
items: Αντικείμενα
@@ -486,7 +483,7 @@ el:
password_confirmation: Επιβεβαίωση κωδικού πρόσβασης
reset_password_token: Επαναφορά ένδειξης κωδικού
expired: έχει λήξει, παρακαλώ ζητήστε νέο
- back_to_payments_list: "Πίσω στην Λίστα Πληρωμών"
+ back_to_payments_list: "Επιστροφή στη λίστα πληρωμών"
maestro_or_solo_cards: "Κάρτα Maestro/Sola"
backordered: "Σε εκκρεμότητα"
on_hand: "Στο χέρι"
@@ -559,6 +556,8 @@ el:
remove: Αφαίρεση
image:
edit: Επεξεργασία
+ product_preview:
+ shop_tab: Κατάστημα
adjustments:
skipped_changing_canceled_order: "Δεν μπορείτε να κάνετε αλλαγή ακυρωμένης παραγγελίας."
begins_at: Ξεκινάει από
@@ -570,7 +569,7 @@ el:
email: Email
ends_at: Ολοκληρώνεται σε
ends_on: Ολοκληρώνεται στις
- name: Όνονα
+ name: Όνομα
first_name: Όνομα
last_name: Επίθετο
on_hand: Στο χέρι
@@ -725,7 +724,7 @@ el:
title: "Χρεώσεις επιχείρησης"
enterprise: "Επιχείρηση"
fee_type: "Κατηγορίες αμοιβών"
- name: "Όνονα"
+ name: "Όνομα"
tax_category: "Φορολογική Κατηγορία"
calculator: "Υπολογισμός"
calculator_values: "Υπολογισμός Αξίας"
@@ -773,7 +772,6 @@ el:
variants:
infinity: "Άπειρο"
to_order_tip: "Προιόντα κατά παραγγελία δεν έχουν καθορισμένο αριθμό σε απόθεμα,για παράδειγμα το ψωμί παραδίδεται κατά παραγγελία και φρέσκο."
- back_to_products_list: "Πίσω στην λίστα προϊόντων"
editing_product: "Επεξεργασία Προϊόντος"
tabs:
product_details: "Λεπτομέριες Προϊόντος"
@@ -811,7 +809,6 @@ el:
search: Αναζήτηση
sort:
pagination:
- total_html: "%{total}προϊόντα βρέθηκαν σύμφωνα με τα κριτήρια της αναζήτησής σας. Εμφανίζονται %{from} στα %{to}."
per_page:
show: Εμφάνιση
per_page: "%{num}ανα σελίδα"
@@ -875,7 +872,7 @@ el:
index:
notice: "Ειδοποίηση"
beta_notice: "Αυτή η λειτουργία είναι ακόμα σε δοκιμαστική έκδοση beta: ενδέχεται να αντιμετωπίσετε ορισμένα σφάλματα κατά τη χρήση της. Μη διστάσετε να επικοινωνήσετε με την υποστήριξη."
- select_file: Επιλέξτε φύλλο εργασίας προς ανέβασμα
+ select_file: Επιλέξτε αρχείο CSV
spreadsheet: Φύλλο Εργασίας
choose_import_type: Επιλογή τύπου εισαγωγής
import_into: Τύπος εισαγωγής
@@ -886,7 +883,7 @@ el:
csv_templates: Πρότυπο CSV
product_list_template: Λήψη προτύπου λίστας προϊόντων
inventory_template: Λήψη προτύπου κατάλογου προϊόντων
- category_values: Διαθέσιμες παραλλαγές Κατηγορίας
+ category_values: Διαθέσιμες κατηγορίες
product_categories: Κατηγορίες προϊόντος
tax_categories: Κατηγορίες Φορολόγησης
shipping_categories: Κατηγορίες Μεταφορικών
@@ -913,8 +910,8 @@ el:
not_found: δεν ήταν δυνατή η εύρεση της επιχείρησης στη βάση δεδομένων
no_name: Δεν υπάρχει όνομα
blank_enterprise: ορισμένα προϊόντα δεν έχουν συσχετιστεί με κάποια επιχείρηση
- reset_absent?: Επαναφέρετε τα προϊόντα που λείπουν
- reset_absent_tip: Ορίστε μηδενικό απόθεμα για όλα τα εξερχόμενα προϊόντα που δεν υπάρχουν στο αρχείο
+ reset_absent?: Σχετικά με τα υπόλοιπα προϊόντα
+ reset_absent_tip: Ορίστε μηδενικό απόθεμα για όλα τα προϊόντα που δεν υπάρχουν στο αρχείο
overwrite_all: Αντικατάσταση Όλων
overwrite_empty: Αντικατάσταση αν είναι κενό
default_stock: Ορισμός επιπέδου αποθέματος
@@ -1075,7 +1072,7 @@ el:
select_state: "Επέλεξε πόλη"
contact:
legend: "επικοινωνία"
- name: Όνονα
+ name: Όνομα
name_placeholder: π.χ Gustav Plum
email_address: Δημόσια Διεύθυνση Ηλεκτρονικού Ταχυδρομείου
email_address_placeholder: π.χ. inquiries@fresh-food.com
@@ -1089,9 +1086,9 @@ el:
website_placeholder: π.χ. www.truffles.com
enterprise_fees:
legend: "Χρεώσεις επιχείρησης"
- name: Όνονα
+ name: Όνομα
fee_type: Κατηγορίες αμοιβών
- manage_fees: Διαχείρηση Αμοιβών Επιχειρήσεων
+ manage_fees: Διαχείριση αμοιβών επιχειρήσεων
no_fees_yet: Δεν έχετε τέλη επιχείρησης ακόμα.
create_button: Δημιούργησε έναν τώρα
enterprise_permissions:
@@ -1121,7 +1118,7 @@ el:
preferred_product_selection_from_inventory_only_no: Νέα προϊόντα πρέπει να προστεθούν στο απόθεμά μου πριν μπορέσουν να τοποθετηθούν στη βιτρίνα μου
payment_methods:
legend: "Τρόποι πληρωμής"
- name: Όνονα
+ name: Όνομα
applies: Ισχύει?
manage: Διαχείριση Τρόπων Πληρωμής
no_method_yet: Δεν έχετε επιλέξει κανέναν τρόπο πληρωμής.
@@ -1129,7 +1126,7 @@ el:
create_one_button: Δημιούργησε έναν τώρα
primary_details:
legend: "Βασικές λεπτομέρειες"
- name: Όνονα
+ name: Όνομα
name_placeholder: π.χ. Βιοδυναμικές τρούφες του καθηγητή Plum
groups: Ομάδες
groups_tip: Επέλεξε κάποια ομάδα ή περιοχή. Αυτό θα βοηθήσει τους καταναλωτές να βρίσκουν την επιχείρησή σου.
@@ -1158,7 +1155,7 @@ el:
ofn_uid_tip: Το μοναδικό αναγνωριστικό που χρησιμοποιείται για την ταυτοποίηση της επιχείρησης στο Open Food Network.
shipping_methods:
legend: "Τρόποι αποστολής"
- name: "Όνονα"
+ name: "Όνομα"
applies: "Ενεργό;"
manage: "Διαχείριση Τρόπων Αποστολής"
create_button: "Δημιουργία Νέου Τρόπου Αποστολής"
@@ -1357,7 +1354,7 @@ el:
loading_enterprises: ΦΌΡΤΩΣΕ ΤΙΣ ΕΠΙΧΕΙΡΉΣΕΙΣ
no_enterprises_found: Δεν βρέθηκε επιχείρηση.
search_placeholder: Αναζήτηση Με Όνομα
- manage: Διαχείρηση
+ manage: Διαχείριση
manage_link: Ρυθμήσεις
producer?: "Παραγωγός?"
package: "Πακέτο"
@@ -1369,10 +1366,8 @@ el:
contact_name: Όνομα Επικοινωνίας
edit:
editing: 'Ρυθμίσεις:'
- back_link: Πίσω στην λίστα επιχειρήσεων
new:
title: Νέα Επιχείρηση
- back_link: Πίσω στην λίστα επιχειρήσεων
welcome:
welcome_title: Καλώς ήρθατε στο Open Food Network
welcome_text: επιτυχής δημιουργία
@@ -1409,6 +1404,8 @@ el:
choose_products_from: "Επιλογή προϊόντων Από:"
re_notify_producers: Επαναλάβετε την ειδοποίηση προς τους παραγωγούς
notify_producers_tip: Αυτό θα στείλει ένα email σε κάθε παραγωγό με τη λίστα των παραγγελιών τους.
+ date_time_warning_modal_content:
+ cancel: 'Ακύρωση'
incoming:
incoming: "Εισερχόμενο"
supplier: "Προμηθευτής"
@@ -1476,7 +1473,7 @@ el:
add: Προσθήκη κομίστρου συντονιστή
filters:
search_by_order_cycle_name: "Αναζήτηση με όνομα Κύκλου Παραγγελίας ..."
- involving: "Συμμετοχή"
+ involving: "Αφορά"
any_enterprise: "Οποιαδήποτε Επιχείρηση"
any_schedule: "Οποιοδήποτε Πρόγραμμα"
form:
@@ -1497,7 +1494,7 @@ el:
new_schedule: Νέο Πρόγραμμα
new_schedule_tooltip: Η συχνότητα με την οποία πραγματοποιείται μια συνδρομή
name_and_timing_form:
- name: Όνονα
+ name: Όνομα
orders_open: Οι παραγγελίες ανοιγούν στις
coordinator: Συντονιστής
orders_close: Οι παραγγελίες είναι κλείστες
@@ -1957,7 +1954,7 @@ el:
mobile_menu:
cart: "Καλάθι"
register_call:
- selling_on_ofn: "Ενδιαφέρεσαι να μπεις στο Open Food Network?"
+ selling_on_ofn: "Ενδιαφέρεσαι να πουλήσεις τα προϊόντα σου μέσω του Open Food Network;"
register: "Εγγραφή εδώ"
footer:
footer_secure: "Ασφαλές και Αξιόπιστο"
@@ -2024,7 +2021,7 @@ el:
menu_2_url: "/map"
menu_3_title: "Παραγωγοι"
menu_3_url: "/producers"
- menu_4_title: "Ομάδες"
+ menu_4_title: "Ομαδες"
menu_4_url: "/groups"
menu_5_title: "Σχετικα"
menu_5_url: "https://about.openfoodnetwork.org.au/"
@@ -2048,7 +2045,7 @@ el:
footer_links_md: "Σύνδεσμοι"
footer_about_url: "Σχετικά με τη διεύθυνση URL"
user_guide_link: "Σύνδεσμος οδηγού χρήστη"
- name: Όνονα
+ name: Όνομα
first_name: Όνομα
last_name: Επίθετο
email: Email
@@ -2333,7 +2330,7 @@ el:
enterprises_currently_open: "Οι παραγγελίες είναι προς το παρόν ανοιχτές"
enterprises_ready_for: "Έτοιμος για"
enterprises_choose: "Επιλέξτε πότε θέλετε την παραγγελία σας:"
- maps_open: "Ανοιξε"
+ maps_open: "Άνοιγμα"
maps_closed: "Κλειστό"
map_title: "Χάρτης"
hubs_buy: "Ψώνια για:"
@@ -2583,10 +2580,10 @@ el:
registration_checklist: "Τι χρειάζομαι?"
registration_time: "5-10 λεπτά"
registration_enterprise_address: "Διέυθυνση επιχείρησης"
- registration_contact_details: "Κύρια στοιχεία επικοινωνίας"
- registration_logo: "Η εικόνα του λογότυπου σας"
- registration_promo_image: "Εικόνα τοπίου για το προφίλ σας"
- registration_about_us: "Κείμενο "Σχετικά με εμάς""
+ registration_contact_details: "Τα στοιχεία επικοινωνίας σας"
+ registration_logo: "Το λογότυπο σας"
+ registration_promo_image: "Εικόνα για το προφίλ σας"
+ registration_about_us: "Ένα κέιμενο σχετικά με την επιχείρηση σας"
registration_outcome_headline: "Τι πέρνω?"
registration_outcome1_html: "Το προφίλ σου βοηθά τους ανθρώπους να σε βρουν και να επικοινωνήσουν μαζί σου στο Open Food Network."
registration_outcome2: "Χρησιμοποιήστε αυτόν τον χώρο για να πείτε την ιστορία της επιχείρησής σας, για να διευκολύνετε τις συνδέσεις με την κοινωνική και διαδικτυακή σας παρουσία."
@@ -2773,9 +2770,9 @@ el:
admin_enterprise_groups_contact_country_id: "Χώρα"
admin_enterprise_groups_web_twitter: "π.χ. @the_prof"
admin_enterprise_groups_web_website_placeholder: "π.χ. www.fresh-food-supplier.gr"
- admin_order_cycles: "Κύκλοι παραγγελίας διαχειριστή"
- open: "Ανοιξε"
- close: "Κλείσιμο"
+ admin_order_cycles: "Κύκλοι παραγγελιών διαχειριστή"
+ open: "Έναρξη"
+ close: "Λήξη"
create: "Δημιουργία"
search: "Αναζήτηση"
supplier: "Προμηθευτής"
@@ -2805,7 +2802,7 @@ el:
flexible_rate: "Ευέλικτο ποσοστό"
price_sack: "Price Sack"
new_order_cycles: "Κύκλοι νέας παραγγελίας"
- new_order_cycle: "Κύκλος νέας παραγγελίας"
+ new_order_cycle: "Νέος κύκλος παραγγελίας"
new_order_cycle_tooltip: "Ανοίξτε το κατάστημα για μια ορισμένη χρονική περίοδο"
select_a_coordinator_for_your_order_cycle: "Επιλέξτε έναν συντονιστή για τον κύκλο παραγγελιών σας"
notify_producers: 'Ειδοποιήστε τους παραγωγούς'
@@ -2832,7 +2829,7 @@ el:
no_products: Χωρίς Προϊόντα
spree_admin_overview_enterprises_header: "Οι Επιχειρήσεις μου"
spree_admin_overview_enterprises_footer: "ΔΙΑΧΕΙΡΙΣΤΕ ΤΙΣ ΕΠΙΧΕΙΡΗΣΕΙΣ ΜΟΥ"
- spree_admin_enterprises_hubs_name: "Όνονα"
+ spree_admin_enterprises_hubs_name: "Όνομα"
spree_admin_enterprises_create_new: "ΔΗΜΙΟΥΡΓΗΣΤΕ ΝΕΟ"
spree_admin_enterprises_shipping_methods: "Τρόποι αποστολής"
spree_admin_enterprises_fees: "Αμοιβή επιχείρησης"
@@ -2857,7 +2854,6 @@ el:
spree_admin_single_enterprise_hint: "Υπόδειξη: Για να επιτρέψεις στους άλλους να σε βρουν, ενεργοποίησε την ορατότητά σου κάτω"
spree_admin_eg_pickup_from_school: "π.χ. \"Παραλαβή από το Δημοτικό Σχολείο\""
spree_admin_eg_collect_your_order: "π.χ. "Παρακαλώ συλλέξτε την παραγγελία σας από 123 Imaginary St, Northcote, 3070""
- spree_classification_primary_taxon_error: "Το Taxon %{taxon} είναι το κύριο ταξινομικό του %{product} και δεν μπορεί να διαγραφεί"
spree_order_availability_error: "Ο κύκλος διανομής ή παραγγελίας δεν μπορεί να παρέχει τα προϊόντα στο καλάθι σας"
spree_order_populator_error: "Αυτός ο κύκλος διανομέων ή παραγγελιών δεν μπορεί να παρέχει όλα τα προϊόντα στο καλάθι σας. Επιλέξτε άλλο."
spree_order_cycle_error: "Επιλέξτε έναν κύκλο παραγγελιών για αυτήν την παραγγελία."
@@ -2865,17 +2861,17 @@ el:
spree_distributors_error: "Πρέπει να επιλεγεί τουλάχιστον ένας κόμβος"
spree_user_enterprise_limit_error: "^%{email} δεν επιτρέπεται να κατέχει άλλες επιχειρήσεις (το όριο είναι %{enterprise_limit})."
spree_variant_product_error: πρέπει να έχει τουλάχιστον μία παραλλαγή
- your_profil_live: "Το προφίλ σας ζωντανά"
+ your_profil_live: "Προφίλ καταστήματος"
see: "ΕΜΦΑΝΙΣΗ"
- live: "ζω"
- manage: "Διαχείρηση"
+ live: " "
+ manage: "Διαχείριση"
resend: "Ξαναστείλτε"
add_and_manage_products: "Προσθήκη και διαχείριση προϊόντων"
add_and_manage_order_cycles: "Προσθήκη & διαχείριση κύκλων παραγγελίας"
manage_order_cycles: "Διαχείριση κύκλων παραγγελίας"
- manage_products: "ΔΙΑΧΕΙΡΙΣΗ ΠΡΟΪΟΝΤΩΝ"
+ manage_products: "Διαχείριση προϊόντων"
edit_profile_details: "Επεξεργασία στοιχείων προφίλ"
- edit_profile_details_etc: "Αλλάξτε την περιγραφή του προφίλ σας, εικόνες κ.λπ."
+ edit_profile_details_etc: "Αλλάξτε την περιγραφή του καταστήματός σας, εικόνες κ.λ.π."
order_cycle: "Κύκλος Παραγγελειών"
enterprise_relationships: "Δικαιώματα επιχείρησης"
first_name_begins_with: "Το όνομα αρχίζει με"
@@ -2895,7 +2891,7 @@ el:
admin_share_state: "Πόλη"
hub_sidebar_hubs: "Σημείο Συλλογής "
hub_sidebar_none_available: "Κανένα διαθέσιμο"
- hub_sidebar_manage: "Διαχείρηση"
+ hub_sidebar_manage: "Διαχείριση"
hub_sidebar_at_least: "Πρέπει να επιλεγεί τουλάχιστον ένας κόμβος"
hub_sidebar_blue: "μπλε"
hub_sidebar_red: "το κόκκινο"
@@ -3512,6 +3508,8 @@ el:
Αυτό θα θέσει το επίπεδο αποθέματος σε μηδέν για όλα τα προϊόντα αυτής της
επιχείρησης που δεν υπάρχουν στο ανεβασμένο αρχείο.
order_cycles:
+ unsaved_changes: "Έχετε μη αποθηκευμένες αλλαγές"
+ bulk_save_error: "Ωχ όχι! Δεν μπόρεσα να αποθηκεύσω τις αλλαγές σας."
create_failure: "Η δημιουργία κύκλου παραγγελίας απέτυχε"
update_success: 'Ο κύκλος παραγγελιών σας ενημερώθηκε.'
update_failure: "Η ενημέρωση του κύκλου παραγγελίας απέτυχε"
@@ -3687,7 +3685,7 @@ el:
import_date: "Ημερομηνία εισαγωγής"
delivery: "Διανομή"
temperature_controlled: "Ελεγχόμενη θερμοκρασία"
- new_product: "Καινουργιο ΠΡΟΪΟΝ"
+ new_product: "Καινούργιο προϊόν"
administration: "Διαχείριση"
logged_in_as: "Συνδεδεμένος ως"
account: "Λογαριασμός"
@@ -3735,7 +3733,6 @@ el:
more: "Περισσότερα"
new_adjustment: "Νέα προσαρμογή"
new_tax_category: "Νέα Φορολογική Κατηγορία"
- new_taxon: "Νέο ταξί"
new_user: "Νέος χρήστης"
no_pending_payments: "Δεν υπάρχουν πληρωμές σε εκκρεμότητα"
remove: "Αφαίρεση"
@@ -3754,10 +3751,6 @@ el:
delivery: "Υπογράφηκε, σφραγίστηκε, παραδόθηκε"
start_date: "Ημερομηνία έναρξης"
successfully_removed: "Καταργήθηκε επιτυχώς"
- taxonomy_edit: "Επεξεργασία ταξινόμησης"
- taxonomy_tree_error: "Παρουσιάστηκε σφάλμα κατά την ενημέρωση του δέντρου ταξονομίας. "
- taxonomy_tree_instruction: "Κάντε δεξί κλικ σε ένα αντικείμενο για να προσθέσετε, μετονομάσετε, αφαιρέσετε ή επεξεργαστείτε."
- tree: "Δέντρο"
updating: "Ενημέρωση"
your_order_is_empty_add_product: "Η παραγγελία σας είναι κενή, αναζητήστε και προσθέστε ένα προϊόν παραπάνω"
add_product: "Προσθήκη Προϊόντος"
@@ -3855,7 +3848,6 @@ el:
tax_rate_amount_explanation: "Οι φορολογικοί συντελεστές είναι ένα δεκαδικό ποσό για βοήθεια στους υπολογισμούς, (δηλ. Εάν ο συντελεστής φόρου είναι 5%, τότε πληκτρολογήστε 0,05)"
included_in_price: "Περιλαμβάνεται στην Τιμή"
show_rate_in_label: "Εμφάνιση τιμής στην ετικέτα"
- back_to_tax_rates_list: "Επιστροφή στη λίστα φορολογικών συντελεστών"
tax_settings: "Ρυθμίσεις φόρου"
zones: "Ζώνες"
new_zone: "Νέα Ζώνη"
@@ -3868,14 +3860,11 @@ el:
iso_name: "Όνομα ISO"
states_required: "Απαιτούνται κράτη"
editing_country: "Χώρα επεξεργασίας"
- back_to_countries_list: "Επιστροφή στη λίστα χωρών"
states: "Κρατών"
abbreviation: "Συντομογραφία"
new_state: "Νέα Πολιτεία"
payment_methods: "τρόποι πληρωμής"
- taxonomies: "Ταξινομίες"
- new_taxonomy: "Νέα Ταξινομία"
- back_to_taxonomies_list: "Επιστροφή στη λίστα ταξινομιών"
+ taxons: "Κατηγορίες προϊόντος"
shipping_methods: "Τρόποι αποστολής"
shipping_method: "Τρόπος Αποστολής"
shipment: "Αποστολή"
@@ -4035,7 +4024,6 @@ el:
continue: "Συνέχεια"
new:
new_return_authorization: "Νέα εξουσιοδότηση επιστροφής"
- back_to_return_authorizations_list: "Πίσω στην επιστροφή λίστας εξουσιοδότησης"
continue: "Συνέχεια"
edit:
receive: "λαμβάνω"
@@ -4244,8 +4232,8 @@ el:
image_upload_error: "Παρακαλώ ανεβάστε την εικόνα σε τύπο αρχείου JPG, PNG, GIF, SVG ή WEBP."
image_not_processable: "Η συνημμένη εικόνα δεν υποστηρίζεται."
new:
- title: "Καινουργιο ΠΡΟΪΟΝ"
- new_product: "Καινουργιο ΠΡΟΪΟΝ"
+ title: "Καινούργιο προϊόν"
+ new_product: "Καινούργιο προϊόν"
supplier: "Προμηθευτής"
supplier_select_placeholder: "Διαλέξτε ένα προμηθευτή"
product_name: "Ονομασία προϊόντος"
@@ -4282,6 +4270,7 @@ el:
product_name: Ονομασία προϊόντος
primary_taxon_form:
product_category: Κατηγορία προϊόντων
+ search_for_categories: "Αναζήτηση κατηγοριών"
group_buy_form:
group_buy: "Ομαδική αγορά;"
bulk_unit_size: Μέγεθος μονάδας χύδην
@@ -4358,9 +4347,10 @@ el:
total: "Σύνολο"
billing_address_name: "Όνομα"
taxons:
+ index:
+ title: "Κατηγορίες προϊόντος"
form:
name: Όνομα
- permalink: Permalink
meta_title: Τίτλος Meta
meta_description: Περιγραφή Meta
meta_keywords: Λέξεις-κλειδιά Meta
@@ -4601,7 +4591,6 @@ el:
key_cleared: "Το κλειδί διαγράφηκε"
shipment:
cannot_ready: "Δεν είναι έτοιμη η αποστολή."
- invalid_taxonomy_id: "Μη έγκυρο αναγνωριστικό ταξινόμησης."
toggle_api_key_view: "Εμφάνιση προβολής κλειδιού API για τον χρήστη"
activerecord:
models:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 75abf73de9..22d339a1fd 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -103,7 +103,7 @@ en:
errors:
models:
enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Inheriting the tax categeory requires a per-item calculator."
+ inherit_tax_requires_per_item_calculator: "Inheriting the tax category requires a per-item calculator."
spree/image:
attributes:
attachment:
@@ -120,8 +120,6 @@ en:
attributes:
base:
card_expired: "has expired"
- spree/product:
- must_exist: 'must exist'
order_cycle:
attributes:
orders_close_at:
@@ -129,7 +127,6 @@ en:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings"
- on_demand_but_count_on_hand_set: "must be blank if on demand"
limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock"
messages:
confirmation: "doesn't match %{attribute}"
@@ -532,7 +529,7 @@ en:
password_confirmation: Password Confirmation
reset_password_token: Reset password token
expired: has expired, please request a new one
- back_to_payments_list: "Back to Payments List"
+ back_to_payments_list: "Back To Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
backordered: "Backordered"
on_hand: "On Hand"
@@ -607,8 +604,13 @@ en:
clone: Clone
delete: Delete
remove: Remove
+ preview: Preview
image:
edit: Edit
+ product_preview:
+ product_preview: Product preview
+ shop_tab: Shop
+ product_details_tab: Product details
adjustments:
skipped_changing_canceled_order: "You can't change a cancelled order."
# Common properties / models
@@ -855,7 +857,7 @@ en:
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
- back_to_products_list: "Back to products list"
+ back_to_products_list: "Back To Products List"
editing_product: "Editing Product"
tabs:
product_details: "Product Details"
@@ -895,7 +897,9 @@ en:
search: Search
sort:
pagination:
- total_html: "%{total} products found for your search criteria. Showing %{from} to %{to}."
+ products_total_html:
+ one: "%{count} product found for your search criteria. Showing %{from} to %{to}."
+ other: "%{count} products found for your search criteria. Showing %{from} to %{to}."
per_page:
show: Show
per_page: "%{num} per page"
@@ -1464,10 +1468,10 @@ en:
contact_name: Contact Name
edit:
editing: 'Settings:'
- back_link: Back to enterprises list
+ back_link: Back To Enterprises List
new:
title: New Enterprise
- back_link: Back to enterprises list
+ back_link: Back To Enterprises List
welcome:
welcome_title: Welcome to the Open Food Network!
welcome_text: You have successfully created a
@@ -1504,6 +1508,11 @@ en:
choose_products_from: "Choose Products From:"
re_notify_producers: Re notify producers
notify_producers_tip: This will send an email to each producer with the list of their orders.
+ date_time_warning_modal_content:
+ title: 'Orders are linked to this order cycle.'
+ content: 'If you wish to create a new order cycle, it is recommended to duplicate the order cycle first and then change the dates.'
+ proceed: 'Proceed anyway'
+ cancel: 'Cancel'
incoming:
incoming: "Incoming"
supplier: "Supplier"
@@ -3036,7 +3045,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under"
spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'"
spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Northcote, 3070'"
- spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted"
spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart"
spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another."
spree_order_cycle_error: "Please choose an order cycle for this order."
@@ -3358,7 +3366,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle"
order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise"
order_cycle_closed: "The order cycle you've selected has just closed. Please try again!"
- back_to_orders_list: "Back to order list"
+ back_to_orders_list: "Back To Orders List"
no_orders_found: "No Orders Found"
order_information: "Order Information"
new_payment: "New Payment"
@@ -3696,6 +3704,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
This will set stock level to zero on all products for this
enterprise that are not present in the uploaded file.
order_cycles:
+ unsaved_changes: "You have unsaved changes"
+ bulk_save_error: "Oh no! I was unable to save your changes."
create_failure: "Failed to create order cycle"
update_success: 'Your order cycle has been updated.'
update_failure: "Failed to update order cycle"
@@ -3956,7 +3966,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
more: "More"
new_adjustment: "New adjustment"
new_tax_category: "New Tax Category"
- new_taxon: "New taxon"
new_user: "New user"
no_pending_payments: "No pending payments"
remove: "Remove"
@@ -3975,10 +3984,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
delivery: "Signed, sealed, delivered"
start_date: "Start date"
successfully_removed: "Successfully Removed"
- taxonomy_edit: "Taxonomy edit"
- taxonomy_tree_error: "There was an error updating the taxonomy tree."
- taxonomy_tree_instruction: "Right-click on an item to add, rename, remove or edit."
- tree: "Tree"
updating: "Updating"
your_order_is_empty_add_product: "Your order is empty, please search for and add a product above"
add_product: "Add Product"
@@ -4080,7 +4085,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)"
included_in_price: "Included in Price"
show_rate_in_label: "Show rate in label"
- back_to_tax_rates_list: "Back to Tax Rates List"
+ back_to_tax_rates_list: "Back To Tax Rates List"
tax_settings: "Tax Settings"
zones: "Zones"
@@ -4095,17 +4100,14 @@ See the %{link} to find out more about %{sitename}'s features and to start using
iso_name: "ISO Name"
states_required: "States Required"
editing_country: "Editing Country"
- back_to_countries_list: "Back to Countries List"
+ back_to_countries_list: "Back To Countries List"
states: "States"
abbreviation: "Abbreviation"
new_state: "New State"
payment_methods: "Payment Methods"
-
- taxonomies: "Taxonomies"
- new_taxonomy: "New Taxonomy"
- back_to_taxonomies_list: "Back to Taxonomies List"
+ taxons: "Product Categories"
shipping_methods: "Shipping Methods"
shipping_method: "Shipping Method"
@@ -4274,7 +4276,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
continue: "Continue"
new:
new_return_authorization: "New Return Authorization"
- back_to_return_authorizations_list: "Back To Return Authorization List"
+ back_to_return_authorizations_list: "Back To Return Authorizations List"
continue: "Continue"
edit:
receive: "receive"
@@ -4487,6 +4489,8 @@ See the %{link} to find out more about %{sitename}'s features and to start using
new_product: "New Product"
supplier: "Supplier"
supplier_select_placeholder: "Select a supplier"
+ search_for_suppliers: "Search for suppliers"
+ search_for_units: "Search for units"
product_name: "Product Name"
units: "Unit Size"
value: "Value"
@@ -4521,6 +4525,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
product_name: Product Name
primary_taxon_form:
product_category: Product Category
+ search_for_categories: "Search for categories"
group_buy_form:
group_buy: "Group Buy?"
bulk_unit_size: Bulk unit size
@@ -4598,9 +4603,20 @@ See the %{link} to find out more about %{sitename}'s features and to start using
total: "Total"
billing_address_name: "Name"
taxons:
+ back_to_list: "Back To Product Categories List"
+ index:
+ title: "Product Categories"
+ new_taxon: 'New product category'
+ new:
+ title: "New Product Category"
+ edit:
+ title: "Edit Product Category"
+ destroy:
+ delete_taxon:
+ success: "Successfully deleted the product category"
+ error: "Unable to delete the product category due to assigned products."
form:
name: Name
- permalink: Permalink
meta_title: Meta Title
meta_description: Meta Description
meta_keywords: Meta Keywords
@@ -4842,7 +4858,6 @@ See the %{link} to find out more about %{sitename}'s features and to start using
key_cleared: "Key cleared"
shipment:
cannot_ready: "Cannot ready shipment."
- invalid_taxonomy_id: "Invalid taxonomy id."
toggle_api_key_view: "Show API key view for user"
activerecord:
models:
diff --git a/config/locales/en_AU.yml b/config/locales/en_AU.yml
index a8e1c84b4c..8495fd546c 100644
--- a/config/locales/en_AU.yml
+++ b/config/locales/en_AU.yml
@@ -65,7 +65,6 @@ en_AU:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings"
- on_demand_but_count_on_hand_set: "must be blank if on demand"
limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock"
messages:
blank: "can't be blank"
@@ -285,7 +284,6 @@ en_AU:
password_confirmation: Password Confirmation
reset_password_token: Reset password token
expired: has expired, please request a new one
- back_to_payments_list: "Back to Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
backordered: "Backordered"
on_hand: "On Hand"
@@ -350,6 +348,8 @@ en_AU:
remove: Remove
image:
edit: Edit
+ product_preview:
+ shop_tab: Shop
begins_at: Begins At
begins_on: Begins On
customer: Customer
@@ -534,7 +534,6 @@ en_AU:
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
- back_to_products_list: "Back to products list"
editing_product: "Editing Product"
tabs:
product_details: "Product Details"
@@ -1015,10 +1014,8 @@ en_AU:
contact_name: Contact Name
edit:
editing: 'Settings:'
- back_link: Back to enterprises list
new:
title: New Enterprise
- back_link: Back to enterprises list
welcome:
welcome_title: Welcome to the Open Food Network!
welcome_text: You have successfully created a
@@ -1053,6 +1050,8 @@ en_AU:
back_to_list: "Back To List"
save_and_back_to_list: "Save and Back to List"
choose_products_from: "Choose Products From:"
+ date_time_warning_modal_content:
+ cancel: 'Cancel'
incoming:
incoming: "Incoming"
supplier: "Supplier"
@@ -2333,7 +2332,6 @@ en_AU:
spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under"
spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'"
spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Northcote, 3070'"
- spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted"
spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart"
spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another."
spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle."
@@ -2614,7 +2612,7 @@ en_AU:
order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle"
order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise"
order_cycle_closed: "The order cycle you've selected has just closed. Please try again!"
- back_to_orders_list: "Back to order list"
+ back_to_orders_list: "Back To Orders List"
no_orders_found: "No Orders Found"
order_information: "Order Information"
new_payment: "New Payment"
@@ -2932,6 +2930,8 @@ en_AU:
This will set stock level to zero on all products for this
enterprise that are not present in the uploaded file.
order_cycles:
+ unsaved_changes: "You have unsaved changes"
+ bulk_save_error: "Oh no! I was unable to save your changes."
create_failure: "Failed to create order cycle"
update_success: 'Your order cycle has been updated.'
update_failure: "Failed to update order cycle"
@@ -3215,7 +3215,6 @@ en_AU:
tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)"
included_in_price: "Included in Price"
show_rate_in_label: "Show rate in label"
- back_to_tax_rates_list: "Back to Tax Rates List"
tax_settings: "Tax Settings"
zones: "Zones"
new_zone: "New Zone"
@@ -3228,14 +3227,11 @@ en_AU:
iso_name: "ISO Name"
states_required: "States Required"
editing_country: "Editing Country"
- back_to_countries_list: "Back to Countries List"
states: "States"
abbreviation: "Abbreviation"
new_state: "New State"
payment_methods: "Payment Methods"
- taxonomies: "Taxonomies"
- new_taxonomy: "New Taxonomy"
- back_to_taxonomies_list: "Back to Taxonomies List"
+ taxons: "Product Categories"
shipping_methods: "Shipping Methods"
shipping_method: "Shipping Method"
shipment: "Shipment"
@@ -3379,7 +3375,6 @@ en_AU:
continue: "Continue"
new:
new_return_authorization: "New Return Authorization"
- back_to_return_authorizations_list: "Back To Return Authorization List"
continue: "Continue"
edit:
receive: "receive"
@@ -3654,9 +3649,10 @@ en_AU:
total: "Total"
billing_address_name: "Name"
taxons:
+ index:
+ title: "Product Categories"
form:
name: Name
- permalink: Permalink
description: Description
general_settings:
edit:
@@ -3838,7 +3834,6 @@ en_AU:
key_cleared: "Key cleared"
shipment:
cannot_ready: "Cannot ready shipment."
- invalid_taxonomy_id: "Invalid taxonomy id."
activerecord:
models:
spree/payment:
diff --git a/config/locales/en_BE.yml b/config/locales/en_BE.yml
index f2ac862297..af01409c7f 100644
--- a/config/locales/en_BE.yml
+++ b/config/locales/en_BE.yml
@@ -57,7 +57,6 @@ en_BE:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings"
- on_demand_but_count_on_hand_set: "must be blank if on demand"
limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock"
messages:
blank: "can't be blank"
@@ -269,7 +268,6 @@ en_BE:
password_confirmation: Password Confirmation
reset_password_token: Reset password token
expired: has expired, please request a new one
- back_to_payments_list: "Back to Payments List"
on_hand: "On Hand"
on hand: "On Hand"
ship: "Ship"
@@ -324,6 +322,8 @@ en_BE:
remove: Remove
image:
edit: Edit
+ product_preview:
+ shop_tab: Shop
begins_at: Begins At
begins_on: Begins On
customer: Customer
@@ -502,7 +502,6 @@ en_BE:
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
- back_to_products_list: "Back to products list"
tabs:
group_buy_options: "Group Buy Options"
images: "Images"
@@ -938,10 +937,8 @@ en_BE:
contact_name: Contact Name
edit:
editing: 'Settings:'
- back_link: Back to enterprises list
new:
title: New Enterprise
- back_link: Back to enterprises list
welcome:
welcome_title: Welcome to the Open Food Network!
welcome_text: You have successfully created a
@@ -972,6 +969,8 @@ en_BE:
next: "Next"
cancel: "Cancel"
choose_products_from: "Choose Products From:"
+ date_time_warning_modal_content:
+ cancel: 'Cancel'
incoming:
incoming: "Incoming"
supplier: "Supplier"
@@ -2192,7 +2191,6 @@ en_BE:
spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under"
spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'"
spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Northcote, 3070'"
- spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted"
spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart"
spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another."
spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle."
@@ -2466,7 +2464,7 @@ en_BE:
order_cycles_bulk_update_notice: 'Order cycles have been updated.'
order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle"
order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise"
- back_to_orders_list: "Back to order list"
+ back_to_orders_list: "Back To Orders List"
no_orders_found: "No Orders Found"
order_information: "Order Information"
new_payment: "New Payment"
@@ -2759,6 +2757,8 @@ en_BE:
This will set stock level to zero on all products for this
enterprise that are not present in the uploaded file.
order_cycles:
+ unsaved_changes: "You have unsaved changes"
+ bulk_save_error: "Oh no! I was unable to save your changes."
create_failure: "Failed to create order cycle"
update_success: 'Your order cycle has been updated.'
update_failure: "Failed to update order cycle"
@@ -2948,7 +2948,6 @@ en_BE:
tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)"
included_in_price: "Included in Price"
show_rate_in_label: "Show rate in label"
- back_to_tax_rates_list: "Back to Tax Rates List"
tax_settings: "Tax Settings"
zones: "Zones"
new_zone: "New Zone"
@@ -2961,14 +2960,11 @@ en_BE:
iso_name: "ISO Name"
states_required: "States Required"
editing_country: "Editing Country"
- back_to_countries_list: "Back to Countries List"
states: "States"
abbreviation: "Abbreviation"
new_state: "New State"
payment_methods: "Payment Methods"
- taxonomies: "Taxonomies"
- new_taxonomy: "New Taxonomy"
- back_to_taxonomies_list: "Back to Taxonomies List"
+ taxons: "Product Categories"
shipping_methods: "Shipping Methods"
shipping_method: "Shipping Method"
shipment: "Shipment"
@@ -3308,6 +3304,8 @@ en_BE:
total: "Total"
billing_address_name: "Name"
taxons:
+ index:
+ title: "Product Categories"
form:
name: Name
description: Description
diff --git a/config/locales/en_CA.yml b/config/locales/en_CA.yml
index f97338b584..9093a04463 100644
--- a/config/locales/en_CA.yml
+++ b/config/locales/en_CA.yml
@@ -82,7 +82,7 @@ en_CA:
errors:
models:
enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Inheriting the tax category requires a per-item calculator"
+ inherit_tax_requires_per_item_calculator: "Inheriting the tax category requires a per-item calculator."
spree/image:
attributes:
attachment:
@@ -106,7 +106,6 @@ en_CA:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "must be blank because you are using producer stock settings"
- on_demand_but_count_on_hand_set: "must be blank if 'on demand' is used"
limited_stock_but_no_count_on_hand: "must be specified because you are forcing limited stock"
messages:
confirmation: "doesn't match %{attribute}"
@@ -484,7 +483,7 @@ en_CA:
password_confirmation: Password Confirmation
reset_password_token: Reset password token
expired: has expired, please request a new one
- back_to_payments_list: "Back to Payments List"
+ back_to_payments_list: "Back To Payments List"
maestro_or_solo_cards: "Maestro/Solo cards"
backordered: "Backordered"
on_hand: "On Hand"
@@ -557,6 +556,8 @@ en_CA:
remove: Remove
image:
edit: Edit
+ product_preview:
+ shop_tab: Shop
adjustments:
skipped_changing_canceled_order: "You can't change a cancelled order."
begins_at: Begins At
@@ -675,6 +676,16 @@ en_CA:
info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See 1matomo.org1 for more information."
config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console."
config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL."
+ connected_app_settings:
+ edit:
+ title: "Connected app settings"
+ info_html: "Enabled apps will appear under Enterprise Settings > Connected Apps."
+ enabled_legend: "Enabled connected apps"
+ connected_apps_enabled:
+ discover_regen: Discover Regenerative portal
+ affiliate_sales_data: DFC anonymised orders API for research purposes
+ update:
+ resource: Connected app settings
customers:
index:
new_customer: "New Customer"
@@ -772,7 +783,7 @@ en_CA:
variants:
infinity: "Infinity"
to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order."
- back_to_products_list: "Back to products list"
+ back_to_products_list: "Back To Products List"
editing_product: "Editing Product"
tabs:
product_details: "Product Details"
@@ -812,7 +823,6 @@ en_CA:
search: Search
sort:
pagination:
- total_html: "%{total} products found for your search criteria. Showing %{from} to %{to}."
per_page:
show: Show
per_page: "%{num} per page"
@@ -1299,6 +1309,15 @@ en_CA:
disable: "Stop sharing"
loading: "Loading"
need_to_be_manager: "Only managers can connect apps."
+ description_html: |
+
+ INRAE and UFC QUE CHOISIR are teaming up to study food prices in short food systems and compare them with prices in the supermarket, for a given set of products. The data that is used by INRAE is mixed with data coming from other short food chain platforms in France. No individual product prices will be publically disclosed through this project. +
++ Learn more about this research project + +
discover_regen: title: "Waterloo Food Directory" tagline: "Allow OFN Canada to publish your enterprise information." @@ -1308,8 +1327,8 @@ en_CA: need_to_be_manager: "Only managers can connect apps." note: | Your Open Food Network account is connected to the Waterloo Food Directory. - Changes made to your OFN profile will automatically update your Waterloo Food Directory listing. For any other changes please contact OFN Support. - link_label: "Manage listing" + Changes made to your OFN profile will update your Waterloo Food Directory listing when you click the 'Update listing' button. For any other changes please contact OFN Support at support@openfoodnetwork.ca. + link_label: "Update listing" description_html: |Eligible producers can showcase call to actions to Eat Local, Give Local, and/or Grow Local. @@ -1371,10 +1390,10 @@ en_CA: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list + back_link: Back To Enterprises List new: title: New Enterprise - back_link: Back to enterprises list + back_link: Back To Enterprises List welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1411,6 +1430,11 @@ en_CA: choose_products_from: "Choose Products From:" re_notify_producers: Re notify producers notify_producers_tip: This will send an email to each producer with the list of their orders. + date_time_warning_modal_content: + title: 'Orders are linked to this order cycle.' + content: 'If you wish to create a new order cycle, it is recommended to duplicate the order cycle first and then change the dates.' + proceed: 'Proceed anyway' + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -1931,7 +1955,7 @@ en_CA: all_terms_and_conditions: message_html: "I agree to the seller's %{terms_and_conditions_link} and the platform %{tos_link}" terms_and_conditions: "Terms and Conditions" - submit: Complete order + submit: Click to place order cancel: Back to Payment method errors: saving_failed: "Saving failed, please update the highlighted fields." @@ -2870,7 +2894,6 @@ en_CA: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Your City'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_cycle_error: "Please choose an order cycle for this order" @@ -3190,7 +3213,7 @@ en_CA: order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" order_cycle_closed: "The order cycle you've selected has just closed. Please try again!" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back to Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -3533,6 +3556,8 @@ en_CA: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3756,7 +3781,6 @@ en_CA: more: "More" new_adjustment: "New adjustment" new_tax_category: "New Tax Category" - new_taxon: "New taxon" new_user: "New user" no_pending_payments: "No pending payments" remove: "Remove" @@ -3775,10 +3799,6 @@ en_CA: delivery: "Signed, sealed, delivered" start_date: "Start date" successfully_removed: "Successfully Removed" - taxonomy_edit: "Taxonomy edit" - taxonomy_tree_error: "There was an error updating the taxonomy tree." - taxonomy_tree_instruction: "Right-click on an item to add, rename, remove or edit." - tree: "Tree" updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" @@ -3876,7 +3896,7 @@ en_CA: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calcuations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" + back_to_tax_rates_list: "Back To Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3889,14 +3909,12 @@ en_CA: iso_name: "ISO Name" states_required: "Provinces Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" + back_to_countries_list: "Back To Countries List" states: "Provinces" abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Delivery/Pick-up Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -4056,7 +4074,7 @@ en_CA: continue: "Continue" new: new_return_authorization: "New Return Authorization" - back_to_return_authorizations_list: "Back to Return Authorization List" + back_to_return_authorizations_list: "Back To Return Authorizations List" continue: "Continue" edit: receive: "receive" @@ -4121,7 +4139,7 @@ en_CA: email: "Customer E-Mail" invoice: issued_on: "Issued on" - tax_invoice: "Order Number" + tax_invoice: "INVOICE" code: "Code" from: "From" to: "Bill to" @@ -4269,6 +4287,8 @@ en_CA: new_product: "New Product" supplier: "Supplier" supplier_select_placeholder: "Select a supplier" + search_for_suppliers: "Search for suppliers" + search_for_units: "Search for units" product_name: "Product Name" units: "Unit Size" value: "Value" @@ -4303,6 +4323,7 @@ en_CA: product_name: Product Name primary_taxon_form: product_category: Product Category + search_for_categories: "Search for categories" group_buy_form: group_buy: "Group Buy?" bulk_unit_size: Bulk unit size @@ -4380,9 +4401,20 @@ en_CA: total: "Total" billing_address_name: "Name" taxons: + back_to_list: "Back To Product Categories List" + index: + title: "Product Categories" + new_taxon: 'New product category' + new: + title: "New Product Category" + edit: + title: "Edit Product Category" + destroy: + delete_taxon: + success: "Successfully deleted the product category" + error: "Unable to delete the product category due to assigned products." form: name: Name - permalink: Permalink meta_title: Meta Title meta_description: Meta Description meta_keywords: Meta Keywords @@ -4624,7 +4656,6 @@ en_CA: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid taxonomy id." toggle_api_key_view: "Show API key view for user" activerecord: models: diff --git a/config/locales/en_DE.yml b/config/locales/en_DE.yml index 643eb4af53..602c6b14f1 100644 --- a/config/locales/en_DE.yml +++ b/config/locales/en_DE.yml @@ -57,7 +57,6 @@ en_DE: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: blank: "can't be blank" @@ -272,7 +271,6 @@ en_DE: password_confirmation: Password Confirmation reset_password_token: Reset password token expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "On Hand" @@ -329,6 +327,8 @@ en_DE: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop begins_at: Begins At begins_on: Begins On customer: Customer @@ -507,7 +507,6 @@ en_DE: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" tabs: group_buy_options: "Group Buy Options" images: "Images" @@ -946,10 +945,8 @@ en_DE: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -980,6 +977,8 @@ en_DE: next: "Next" cancel: "Cancel" choose_products_from: "Choose Products From:" + date_time_warning_modal_content: + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2201,7 +2200,6 @@ en_DE: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Northcote, 3070'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle." @@ -2474,7 +2472,7 @@ en_DE: order_cycles_bulk_update_notice: 'Order cycles have been updated.' order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -2767,6 +2765,8 @@ en_DE: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -2959,7 +2959,6 @@ en_DE: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -2972,14 +2971,11 @@ en_DE: iso_name: "ISO Name" states_required: "States Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "States" abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -3323,6 +3319,8 @@ en_DE: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" form: name: Name description: Description diff --git a/config/locales/en_FR.yml b/config/locales/en_FR.yml index 07e8a98094..c1b1d344d3 100644 --- a/config/locales/en_FR.yml +++ b/config/locales/en_FR.yml @@ -82,7 +82,7 @@ en_FR: errors: models: enterprise_fee: - inherit_tax_requires_per_item_calculator: "Inheriting the tax categeory requires a per-item calculator." + inherit_tax_requires_per_item_calculator: "Inheriting the tax category requires a per-item calculator." spree/image: attributes: attachment: @@ -99,8 +99,6 @@ en_FR: attributes: base: card_expired: "has expired" - spree/product: - must_exist: 'must exist' order_cycle: attributes: orders_close_at: @@ -108,7 +106,6 @@ en_FR: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: confirmation: "doesn't match %{attribute}" @@ -486,7 +483,7 @@ en_FR: password_confirmation: Password Confirmation reset_password_token: Reset password token expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" + back_to_payments_list: "Back To Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "On Hand" @@ -559,6 +556,8 @@ en_FR: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop adjustments: skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At @@ -677,6 +676,16 @@ en_FR: info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.orgfor more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." + connected_app_settings: + edit: + title: "Connected app settings" + info_html: "Enabled apps will appear under Enterprise Settings > Connected Apps." + enabled_legend: "Enabled connected apps" + connected_apps_enabled: + discover_regen: Discover Regenerative portal + affiliate_sales_data: DFC anonymised orders API for research purposes + update: + resource: Connected app settings customers: index: new_customer: "New Customer" @@ -774,7 +783,7 @@ en_FR: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" + back_to_products_list: "Back To Products List" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -814,7 +823,9 @@ en_FR: search: Search sort: pagination: - total_html: "%{total} products found for your search criteria. Showing %{from} to %{to}." + products_total_html: + one: "%{count} product found for your search criteria. Showing %{from} to %{to}." + other: "%{count} products found for your search criteria. Showing %{from} to %{to}." per_page: show: Show per_page: "%{num} per page" @@ -1385,10 +1396,10 @@ en_FR: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list + back_link: Back To Enterprises List new: title: New Enterprise - back_link: Back to enterprises list + back_link: Back To Enterprises List welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1425,6 +1436,11 @@ en_FR: choose_products_from: "Choose Products From:" re_notify_producers: Re notify producers notify_producers_tip: This will send an email to each producer with the list of their orders. + date_time_warning_modal_content: + title: 'Orders are linked to this order cycle.' + content: 'If you wish to create a new order cycle, it is recommended to duplicate the order cycle first and then change the dates.' + proceed: 'Proceed anyway' + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2884,7 +2900,6 @@ en_FR: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Northcote, 3070'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_cycle_error: "Please choose an order cycle for this order." @@ -3204,7 +3219,7 @@ en_FR: order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" order_cycle_closed: "The order cycle you've selected has just closed. Please try again!" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -3548,6 +3563,8 @@ en_FR: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3771,7 +3788,6 @@ en_FR: more: "More" new_adjustment: "New adjustment" new_tax_category: "New Tax Category" - new_taxon: "New taxon" new_user: "New user" no_pending_payments: "No pending payments" remove: "Remove" @@ -3790,10 +3806,6 @@ en_FR: delivery: "Signed, sealed, delivered" start_date: "Start date" successfully_removed: "Successfully Removed" - taxonomy_edit: "Taxonomy edit" - taxonomy_tree_error: "There was an error updating the taxonomy tree." - taxonomy_tree_instruction: "Right-click on an item to add, rename, remove or edit." - tree: "Tree" updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" @@ -3891,7 +3903,7 @@ en_FR: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" + back_to_tax_rates_list: "Back To Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3904,14 +3916,12 @@ en_FR: iso_name: "ISO Name" states_required: "States Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" + back_to_countries_list: "Back To Countries List" states: "States" abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -4071,7 +4081,7 @@ en_FR: continue: "Continue" new: new_return_authorization: "New Return Authorization" - back_to_return_authorizations_list: "Back To Return Authorization List" + back_to_return_authorizations_list: "Back To Return Authorizations List" continue: "Continue" edit: receive: "receive" @@ -4284,6 +4294,8 @@ en_FR: new_product: "New Product" supplier: "Supplier" supplier_select_placeholder: "Select a supplier" + search_for_suppliers: "Search for suppliers" + search_for_units: "Search for units" product_name: "Product Name" units: "Unit Size" value: "Value" @@ -4318,6 +4330,7 @@ en_FR: product_name: Product Name primary_taxon_form: product_category: Product Category + search_for_categories: "Search for categories" group_buy_form: group_buy: "Group Buy?" bulk_unit_size: Bulk unit size @@ -4395,9 +4408,20 @@ en_FR: total: "Total" billing_address_name: "Name" taxons: + back_to_list: "Back To Product Categories List" + index: + title: "Product Categories" + new_taxon: 'New product category' + new: + title: "New Product Category" + edit: + title: "Edit Product Category" + destroy: + delete_taxon: + success: "Successfully deleted the product category" + error: "Unable to delete the product category due to assigned products." form: name: Name - permalink: Permalink meta_title: Meta Title meta_description: Meta Description meta_keywords: Meta Keywords @@ -4639,7 +4663,6 @@ en_FR: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid taxonomy id." toggle_api_key_view: "Show API key view for user" activerecord: models: diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index db025ca486..e0875b57bf 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -1,5 +1,8 @@ en_GB: language_name: "English" + time: + formats: + long: "%B %d, %Y %-l:%M %p" activerecord: models: spree/product: Product @@ -78,8 +81,6 @@ en_GB: white_label_logo_link: "Link for the logo used in shopfront" errors: models: - enterprise_fee: - inherit_tax_requires_per_item_calculator: "Inheriting the tax category requires a per-item calculator." spree/image: attributes: attachment: @@ -103,7 +104,6 @@ en_GB: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: confirmation: "doesn't match %{attribute}" @@ -194,6 +194,9 @@ en_GB: transaction_not_allowed: "The card has been declined for an unknown reason." try_again_later: "The card has been declined for an unknown reason." withdrawal_count_limit_exceeded: "The customer has exceeded the balance or credit limit available on their card." + disconnect_failure: "Failed to disconnect Stripe." + success_code: + disconnected: "Stripe account disconnected." activemodel: errors: messages: @@ -219,10 +222,16 @@ en_GB: not_available_to_shop: "is not available to %{shop}" card_details: "Card details" card_type: "Card type" + card_type_is: "Card type is" + unrecognized_card_type: "Unrecognised card type" + use_new_cc: "Use a new credit card" + what_is_this: "What is this?" cardholder_name: "Cardholder name" community_forum_url: "Community forum URL" customer_instructions: "Customer instructions" additional_information: "Additional Information" + connect_app: + url: "https://n8n.openfoodnetwork.org/webhook/regen/connect-enterprise" devise: passwords: spree_user: @@ -472,7 +481,7 @@ en_GB: password_confirmation: Password Confirmation reset_password_token: Reset password expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" + back_to_payments_list: "Back To Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "In Stock" @@ -545,6 +554,8 @@ en_GB: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop adjustments: skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At @@ -598,6 +609,7 @@ en_GB: show_n_more: Show %{num} more choose: "Choose..." please_select: Please select... + column_save_as_default: Save as default columns: Columns actions: Actions viewing: "Viewing: %{current_view_name}" @@ -646,6 +658,7 @@ en_GB: status: Status ok: Ok instance_secret_key: Instance Secret Key + instance_publishable_key: Instance Publishable Key account_id: Account ID business_name: Business Name charges_enabled: Charges Enabled @@ -661,6 +674,16 @@ en_GB: info_html: "Matomo is a Web and Mobile Analytics application. You can either host Matomo on-premises or use a cloud-hosted service. See matomo.org for more information." config_instructions_html: "Here you can configure the OFN Matomo integration. The Matomo URL below should point to the Matomo instance where the user tracking information will be sent to; if it is left empty, Matomo user tracking will be disabled. The Site ID field is not mandatory but useful if you are tracking more than one website on a single Matomo instance; it can be found on the Matomo instance console." config_instructions_tag_manager_html: "Setting the Matomo Tag Manager URL enables Matomo Tag Manager. This tool allows you to set up analytics events. The Matomo Tag Manager URL is copied from the Install Code section of Matomo Tag Manager. Ensure you select the right container and environment as these options change the URL." + connected_app_settings: + edit: + title: "Connected app settings" + info_html: "Enabled apps will appear under Enterprise Settings > Connected Apps." + enabled_legend: "Enabled connected apps" + connected_apps_enabled: + discover_regen: Discover Regenerative portal + affiliate_sales_data: DFC anonymised orders API for research purposes + update: + resource: Connected app settings customers: index: new_customer: "New Customer" @@ -685,6 +708,9 @@ en_GB: balance_due: "Balance Due" destroy: has_associated_subscriptions: "Delete failed: This customer has active subscriptions. Cancel them first." + column_preferences: + bulk_update: + success: "Column preferences saved" contents: edit: title: Content @@ -700,6 +726,7 @@ en_GB: map: Map dfc_product_imports: index: + title: "Importing a DFC product catalogue" imported_products: "Imported products:" enterprise_fees: index: @@ -754,7 +781,6 @@ en_GB: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -794,7 +820,9 @@ en_GB: search: Search sort: pagination: - total_html: "%{total} products found for your search criteria. Showing %{from} to %{to}." + products_total_html: + one: "%{count} product found for your search criteria. Showing %{from} to %{to}." + other: "%{count} products found for your search criteria. Showing %{from} to %{to}." per_page: show: Show per_page: "%{num} per page" @@ -828,9 +856,13 @@ en_GB: error: Unable to delete the variant variant_row: none_tax_category: None + search_for_tax_categories: "Search for tax categories" category_field_name: "Category" tax_category_field_name: "Tax Category" producer_field_name: "Producer" + clone: + success: Successfully cloned the product + error: Unable to clone the product product_import: title: Product Import file_not_found: File not found or could not be opened @@ -873,7 +905,9 @@ en_GB: tax_categories: Tax Categories shipping_categories: Shipping Categories dfc_import_form: + title: "Import from DFC catalogue" enterprise: "Enterprise" + catalog_url: "DFC catalogue URL" import: "Import" import: review: Review @@ -977,6 +1011,7 @@ en_GB: edit: order_sure_want_to: Are you sure you want to %{event} this order? voucher_tax_included_in_price: "%{label}(tax included in voucher)" + tax_on_fees: "Tax on fees" invoice_email_sent: 'Invoice email has been sent' order_email_resent: 'Order email has been resent' bulk_management: @@ -1183,6 +1218,7 @@ en_GB: open_date: "Open Date" close_date: "Close Date" display_ordering_in_shopfront: "Display ordering in shopfront:" + shopfront_sort_by_product: "By product" shopfront_sort_by_category: "By category" shopfront_sort_by_producer: "By producer" shopfront_sort_by_category_placeholder: "Category" @@ -1267,15 +1303,18 @@ en_GB: connected_apps: legend: "Connected apps" affiliate_sales_data: + tagline: "Allow this research project to access your orders data anonymously" enable: "Allow data sharing" disable: "Stop sharing" loading: "Loading" + need_to_be_manager: "Only managers can connect apps." discover_regen: title: "Discover Regenerative" tagline: "Allow Discover Regenerative to publish your enterprise information." enable: "Allow data sharing" disable: "Stop sharing" loading: "Loading" + need_to_be_manager: "Only managers can connect apps." note: | Your Open Food Network account is connected to Discover Regenerative. Add or update information on your Discover Regenerative listing here. @@ -1344,10 +1383,8 @@ en_GB: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1384,6 +1421,11 @@ en_GB: choose_products_from: "Choose Products From:" re_notify_producers: Re notify producers notify_producers_tip: This will send an email to each producer with the list of their orders. + date_time_warning_modal_content: + title: 'Orders are linked to this order cycle.' + content: 'If you wish to create a new order cycle, it is recommended to duplicate the order cycle first and then change the dates.' + proceed: 'Proceed anyway' + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -1583,6 +1625,9 @@ en_GB: pack_by_customer: Pack By Customer pack_by_supplier: Pack By Supplier pack_by_product: Pack By Product + display: + report_is_big: "This report is big and may slow down your device." + display_anyway: "Display anyway" download: button: "Download Report" show: @@ -2160,7 +2205,7 @@ en_GB: system_step3_text: "Set up payment methods and add your collection and delivery options." cta_headline: "The sustainable food network of our future." cta_label: "Start shopping" - stats_headline: "Join over 15k shoppers and producers in creating a new food system" + stats_headline: "Join over 18k shoppers and producers in creating a new food system" stats_producers: "food producers" stats_shops: "food shops" stats_shoppers: "food shoppers" @@ -2493,6 +2538,7 @@ en_GB: orders_bought_already_confirmed: "* already confirmed" orders_confirm_cancel: "Are you sure you want to cancel this order?" order_processed_successfully: "Your order has been processed successfully" + thank_you_for_your_order: "Thank you for your order" products_cart_distributor_choice: "Distributor for your order:" products_cart_distributor_change: "Your distributor for this order will be changed to %{name} if you add this product to your cart." products_cart_distributor_is: "Your distributor for this order is %{name}." @@ -2839,7 +2885,6 @@ en_GB: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Newcastle, NE1 1AA'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_cycle_error: "Please choose an order cycle for this order." @@ -3159,7 +3204,7 @@ en_GB: order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" order_cycle_closed: "The order cycle you've selected has just closed." - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -3509,6 +3554,8 @@ en_GB: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3723,6 +3770,7 @@ en_GB: editing_tax_category: "Editing tax category" editing_tax_rate: "Editing tax rate" editing_zone: "Editing zone" + editing_state: "Editing County" expiration: "Expiration" invalid_payment_provider: "Invalid payment provider" items_cannot_be_shipped: "Items cannot be shipped" @@ -3731,7 +3779,6 @@ en_GB: more: "More" new_adjustment: "New adjustment" new_tax_category: "New Tax Category" - new_taxon: "New taxon" new_user: "New user" no_pending_payments: "No pending payments" remove: "Remove" @@ -3750,10 +3797,6 @@ en_GB: delivery: "Signed, sealed, delivered" start_date: "Start date" successfully_removed: "Successfully Removed" - taxonomy_edit: "Taxonomy edit" - taxonomy_tree_error: "There was an error updating the taxonomy tree." - taxonomy_tree_instruction: "Right-click on an item to add, rename, remove or edit." - tree: "Tree" updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" @@ -3761,6 +3804,7 @@ en_GB: resend: "Resend" back_to_orders_list: "Back To Orders List" back_to_payments_list: "Back To Payments List" + back_to_states_list: "Back To Counties List" return_authorizations: "Return Authorisations" cannot_create_returns: "Cannot create returns as this order has no shipped units." select_stock: "Select stock" @@ -3850,7 +3894,6 @@ en_GB: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3863,14 +3906,11 @@ en_GB: iso_name: "ISO Name" states_required: "Counties Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "Counties" abbreviation: "Abbreviation" new_state: "New County" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -4030,7 +4070,6 @@ en_GB: continue: "Continue" new: new_return_authorization: "New Return Authorisation" - back_to_return_authorizations_list: "Back To Return Authorisation List" continue: "Continue" edit: receive: "receive" @@ -4277,6 +4316,7 @@ en_GB: product_name: Product Name primary_taxon_form: product_category: Product Category + search_for_categories: "Search for categories" group_buy_form: group_buy: "Group Buy?" bulk_unit_size: Bulk unit size @@ -4354,9 +4394,18 @@ en_GB: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" + new_taxon: 'New product category' + new: + title: "New Product Category" + edit: + title: "Edit Product Category" + destroy: + delete_taxon: + success: "Successfully deleted the product category" form: name: Name - permalink: Permalink meta_title: Meta Title meta_description: Meta Description meta_keywords: Meta Keywords @@ -4598,7 +4647,6 @@ en_GB: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid taxonomy id." toggle_api_key_view: "Show API key view for user" activerecord: models: diff --git a/config/locales/en_IE.yml b/config/locales/en_IE.yml index 8c8b70123b..b983f32980 100644 --- a/config/locales/en_IE.yml +++ b/config/locales/en_IE.yml @@ -81,8 +81,6 @@ en_IE: white_label_logo_link: "Link for the logo used in shopfront" errors: models: - enterprise_fee: - inherit_tax_requires_per_item_calculator: "Inheriting the tax categeory requires a per-item calculator." spree/image: attributes: attachment: @@ -106,7 +104,6 @@ en_IE: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: confirmation: "doesn't match %{attribute}" @@ -475,7 +472,7 @@ en_IE: password_confirmation: Password Confirmation reset_password_token: Reset password expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" + back_to_payments_list: "Back To Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "In Stock" @@ -547,6 +544,8 @@ en_IE: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop adjustments: skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At @@ -753,7 +752,6 @@ en_IE: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -791,7 +789,6 @@ en_IE: search: Search sort: pagination: - total_html: "%{total} products found for your search criteria. Showing %{from} to %{to}." per_page: show: Show per_page: "%{num} per page" @@ -1341,10 +1338,8 @@ en_IE: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1381,6 +1376,8 @@ en_IE: choose_products_from: "Choose Products From:" re_notify_producers: Re notify producers notify_producers_tip: This will send an email to each producer with the list of their orders. + date_time_warning_modal_content: + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2836,7 +2833,6 @@ en_IE: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Dublin, D01 XXXX'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_cycle_error: "Please choose an order cycle for this order." @@ -3156,7 +3152,7 @@ en_IE: order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" order_cycle_closed: "The order cycle you've selected has just closed. Please try again!" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -3506,6 +3502,8 @@ en_IE: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3728,7 +3726,6 @@ en_IE: more: "More" new_adjustment: "New adjustment" new_tax_category: "New Tax Category" - new_taxon: "New taxon" new_user: "New user" no_pending_payments: "No pending payments" remove: "Remove" @@ -3747,10 +3744,6 @@ en_IE: delivery: "Signed, sealed, delivered" start_date: "Start date" successfully_removed: "Successfully Removed" - taxonomy_edit: "Taxonomy edit" - taxonomy_tree_error: "There was an error updating the taxonomy tree." - taxonomy_tree_instruction: "Right-click on an item to add, rename, remove or edit." - tree: "Tree" updating: "Updating" your_order_is_empty_add_product: "Your order is empty, please search for and add a product above" add_product: "Add Product" @@ -3847,7 +3840,6 @@ en_IE: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3860,14 +3852,11 @@ en_IE: iso_name: "ISO Name" states_required: "Counties Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "Counties" abbreviation: "Abbreviation" new_state: "New County" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -4027,7 +4016,6 @@ en_IE: continue: "Continue" new: new_return_authorization: "New Return Authorisation" - back_to_return_authorizations_list: "Back To Return Authorisation List" continue: "Continue" edit: receive: "receive" @@ -4274,6 +4262,7 @@ en_IE: product_name: Product Name primary_taxon_form: product_category: Product Category + search_for_categories: "Search for categories" group_buy_form: group_buy: "Group Buy?" bulk_unit_size: Bulk unit size @@ -4351,9 +4340,10 @@ en_IE: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" form: name: Name - permalink: Permalink meta_title: Meta Title meta_description: Meta Description meta_keywords: Meta Keywords @@ -4595,7 +4585,6 @@ en_IE: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid taxonomy id." toggle_api_key_view: "Show API key view for user" activerecord: models: diff --git a/config/locales/en_IN.yml b/config/locales/en_IN.yml index f6f4f26cf3..832a159876 100644 --- a/config/locales/en_IN.yml +++ b/config/locales/en_IN.yml @@ -61,7 +61,6 @@ en_IN: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: blank: "can't be blank" @@ -280,7 +279,6 @@ en_IN: password_confirmation: Password Confirmation reset_password_token: Reset password expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "In Stock" @@ -337,6 +335,8 @@ en_IN: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop begins_at: Begins At begins_on: Begins On customer: Customer @@ -518,7 +518,6 @@ en_IN: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -971,10 +970,8 @@ en_IN: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1009,6 +1006,8 @@ en_IN: back_to_list: "Back To List" save_and_back_to_list: "Save and Back to List" choose_products_from: "Choose Products From:" + date_time_warning_modal_content: + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2271,7 +2270,6 @@ en_IN: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Newcastle, NE1 1AA'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle." @@ -2547,7 +2545,7 @@ en_IN: order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" order_cycle_closed: "The order cycle you've selected has just closed." - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -2857,6 +2855,8 @@ en_IN: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3129,7 +3129,6 @@ en_IN: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3142,14 +3141,11 @@ en_IN: iso_name: "ISO Name" states_required: "Counties Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "Counties" abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -3286,7 +3282,6 @@ en_IN: continue: "Continue" new: new_return_authorization: "New Return Authorisation" - back_to_return_authorizations_list: "Back To Return Authorisation List" continue: "Continue" edit: receive: "receive" @@ -3556,6 +3551,8 @@ en_IN: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" form: name: Name description: Description @@ -3732,7 +3729,6 @@ en_IN: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid taxonomy id." unit: unit components: search_input: diff --git a/config/locales/en_NZ.yml b/config/locales/en_NZ.yml index a1add26c14..acc97f78cc 100644 --- a/config/locales/en_NZ.yml +++ b/config/locales/en_NZ.yml @@ -70,7 +70,6 @@ en_NZ: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: blank: "can't be blank" @@ -407,7 +406,7 @@ en_NZ: password_confirmation: Password Confirmation reset_password_token: Reset password token expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" + back_to_payments_list: "Back To Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "On Hand" @@ -474,6 +473,8 @@ en_NZ: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop adjustments: skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At @@ -673,7 +674,6 @@ en_NZ: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -1164,10 +1164,8 @@ en_NZ: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1204,6 +1202,8 @@ en_NZ: choose_products_from: "Choose Products From:" re_notify_producers: Re notify producers notify_producers_tip: This will send an email to each producer with the list of their orders. + date_time_warning_modal_content: + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2564,7 +2564,6 @@ en_NZ: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Imaginary St, Northcote, 3070'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_cycle_error: "Please choose an order cycle for this order." @@ -2848,7 +2847,7 @@ en_NZ: order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" order_cycle_closed: "The order cycle you've selected has just closed. Please try again!" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -3169,6 +3168,8 @@ en_NZ: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3455,7 +3456,6 @@ en_NZ: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3468,14 +3468,11 @@ en_NZ: iso_name: "ISO Name" states_required: "States Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "States" abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -3620,7 +3617,6 @@ en_NZ: continue: "Continue" new: new_return_authorization: "New Return Authorization" - back_to_return_authorizations_list: "Back To Return Authorization List" continue: "Continue" edit: receive: "receive" @@ -3906,9 +3902,10 @@ en_NZ: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" form: name: Name - permalink: Permalink description: Description general_settings: edit: @@ -4125,7 +4122,6 @@ en_NZ: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid taxonomy id." activerecord: models: spree/payment: diff --git a/config/locales/en_PH.yml b/config/locales/en_PH.yml index f6dc004c68..e7fd58bcd3 100644 --- a/config/locales/en_PH.yml +++ b/config/locales/en_PH.yml @@ -61,7 +61,6 @@ en_PH: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: blank: "can't be blank" @@ -279,7 +278,6 @@ en_PH: password_confirmation: Password Confirmation reset_password_token: Reset password token expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "On Hand" @@ -336,6 +334,8 @@ en_PH: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop begins_at: Begins At begins_on: Begins On customer: Customer @@ -514,7 +514,6 @@ en_PH: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -961,10 +960,8 @@ en_PH: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -999,6 +996,8 @@ en_PH: back_to_list: "Back To List" save_and_back_to_list: "Save and Back to List" choose_products_from: "Choose Products From:" + date_time_warning_modal_content: + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2242,7 +2241,6 @@ en_PH: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Kapayapaan St., Tobias Fornier, Antique 5716'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle." @@ -2516,7 +2514,7 @@ en_PH: order_cycles_bulk_update_notice: 'Order cycles have been updated.' order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -2816,6 +2814,8 @@ en_PH: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3082,7 +3082,6 @@ en_PH: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3095,14 +3094,11 @@ en_PH: iso_name: "ISO Name" states_required: "Provinces Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "Provinces" abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Category" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -3233,7 +3229,6 @@ en_PH: continue: "Continue" new: new_return_authorization: "New Return Authorization" - back_to_return_authorizations_list: "Back To Return Authorization List" continue: "Continue" edit: receive: "receive" @@ -3491,6 +3486,8 @@ en_PH: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" form: name: Name description: Description @@ -3657,7 +3654,6 @@ en_PH: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid category ID." unit: unit components: search_input: diff --git a/config/locales/en_US.yml b/config/locales/en_US.yml index 183564ef11..0b6cf12bd8 100644 --- a/config/locales/en_US.yml +++ b/config/locales/en_US.yml @@ -68,7 +68,6 @@ en_US: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: blank: "can't be blank" @@ -383,7 +382,7 @@ en_US: password_confirmation: Password Confirmation reset_password_token: Reset password token expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" + back_to_payments_list: "Back To Payments List" maestro_or_solo_cards: "Debit cards" backordered: "Backordered" on_hand: "On Hand" @@ -450,6 +449,8 @@ en_US: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop adjustments: skipped_changing_canceled_order: "You can't change a cancelled order." begins_at: Begins At @@ -649,7 +650,6 @@ en_US: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -1125,10 +1125,8 @@ en_US: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1165,6 +1163,8 @@ en_US: choose_products_from: "Choose Products From:" re_notify_producers: Re notify producers notify_producers_tip: This will send an email to each producer with the list of their orders. + date_time_warning_modal_content: + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2516,7 +2516,6 @@ en_US: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick up at Community Center'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 High Street, Asheville, NC 22806'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_cycle_error: "Please choose an order cycle for this order." @@ -2802,7 +2801,7 @@ en_US: order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" order_cycle_closed: "The order cycle you've selected has just closed. Please try again with a different order cycle!" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -3132,6 +3131,8 @@ en_US: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3346,7 +3347,6 @@ en_US: more: "More" new_adjustment: "New adjustment" new_tax_category: "New Tax Category" - new_taxon: "New taxon" new_user: "New user" no_pending_payments: "No pending payments" remove: "Remove" @@ -3363,8 +3363,6 @@ en_US: UPS Ground: "UPS Ground" start_date: "Start date" successfully_removed: "Successfully Removed" - taxonomy_edit: "Taxonomy edit" - tree: "Tree" updating: "Updating" your_order_is_empty_add_product: "Your cart is empty, please search for and add a product above" add_product: "Add Product" @@ -3459,7 +3457,6 @@ en_US: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3472,14 +3469,11 @@ en_US: iso_name: "ISO Name" states_required: "States Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "States" abbreviation: "Abbreviation" new_state: "New State" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -3633,7 +3627,6 @@ en_US: continue: "Continue" new: new_return_authorization: "New Return Authorization" - back_to_return_authorizations_list: "Back To Return Authorization List" continue: "Continue" edit: receive: "receive" @@ -3924,9 +3917,10 @@ en_US: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" form: name: Name - permalink: Permalink description: Description general_settings: edit: @@ -4147,7 +4141,6 @@ en_US: key_cleared: "Key cleared" shipment: cannot_ready: "Cannot ready shipment." - invalid_taxonomy_id: "Invalid taxonomy id." activerecord: models: spree/payment: diff --git a/config/locales/en_ZA.yml b/config/locales/en_ZA.yml index 0bdc4080a1..b4bd46097c 100644 --- a/config/locales/en_ZA.yml +++ b/config/locales/en_ZA.yml @@ -61,7 +61,6 @@ en_ZA: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "must be blank because using producer stock settings" - on_demand_but_count_on_hand_set: "must be blank if on demand" limited_stock_but_no_count_on_hand: "must be specified because forcing limited stock" messages: blank: "can't be blank" @@ -279,7 +278,6 @@ en_ZA: password_confirmation: Password Confirmation reset_password_token: Reset password expired: has expired, please request a new one - back_to_payments_list: "Back to Payments List" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "Backordered" on_hand: "In Stock" @@ -336,6 +334,8 @@ en_ZA: remove: Remove image: edit: Edit + product_preview: + shop_tab: Shop begins_at: Begins At begins_on: Begins On customer: Customer @@ -514,7 +514,6 @@ en_ZA: variants: infinity: "Infinity" to_order_tip: "Items made to order do not have a set stock level, such as loaves of bread made fresh to order." - back_to_products_list: "Back to products list" editing_product: "Editing Product" tabs: product_details: "Product Details" @@ -962,10 +961,8 @@ en_ZA: contact_name: Contact Name edit: editing: 'Settings:' - back_link: Back to enterprises list new: title: New Enterprise - back_link: Back to enterprises list welcome: welcome_title: Welcome to the Open Food Network! welcome_text: You have successfully created a @@ -1000,6 +997,8 @@ en_ZA: back_to_list: "Back To List" save_and_back_to_list: "Save and Back to List" choose_products_from: "Choose Products From:" + date_time_warning_modal_content: + cancel: 'Cancel' incoming: incoming: "Incoming" supplier: "Supplier" @@ -2251,7 +2250,6 @@ en_ZA: spree_admin_single_enterprise_hint: "Hint: To allow people to find you, turn on your visibility under" spree_admin_eg_pickup_from_school: "eg. 'Pick-up from Primary School'" spree_admin_eg_collect_your_order: "eg. 'Please collect your order from 123 Church Street, Newcastle, 2094'" - spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted" spree_order_availability_error: "Distributor or order cycle cannot supply the products in your cart" spree_order_populator_error: "That distributor or order cycle can't supply all the products in your cart. Please choose another." spree_order_populator_availability_error: "That product is not available from the chosen distributor or order cycle." @@ -2525,7 +2523,7 @@ en_ZA: order_cycles_bulk_update_notice: 'Order cycles have been updated.' order_cycles_no_permission_to_coordinate_error: "None of your enterprises have permission to coordinate an order cycle" order_cycles_no_permission_to_create_error: "You don't have permission to create an order cycle coordinated by that enterprise" - back_to_orders_list: "Back to order list" + back_to_orders_list: "Back To Orders List" no_orders_found: "No Orders Found" order_information: "Order Information" new_payment: "New Payment" @@ -2831,6 +2829,8 @@ en_ZA: This will set stock level to zero on all products for this enterprise that are not present in the uploaded file. order_cycles: + unsaved_changes: "You have unsaved changes" + bulk_save_error: "Oh no! I was unable to save your changes." create_failure: "Failed to create order cycle" update_success: 'Your order cycle has been updated.' update_failure: "Failed to update order cycle" @@ -3021,7 +3021,6 @@ en_ZA: tax_rate_amount_explanation: "Tax rates are a decimal amount to aid in calculations, (i.e. if the tax rate is 5% then enter 0.05)" included_in_price: "Included in Price" show_rate_in_label: "Show rate in label" - back_to_tax_rates_list: "Back to Tax Rates List" tax_settings: "Tax Settings" zones: "Zones" new_zone: "New Zone" @@ -3034,14 +3033,11 @@ en_ZA: iso_name: "ISO Name" states_required: "Provinces Required" editing_country: "Editing Country" - back_to_countries_list: "Back to Countries List" states: "Provinces" abbreviation: "Abbreviation" new_state: "New Province" payment_methods: "Payment Methods" - taxonomies: "Taxonomies" - new_taxonomy: "New Taxonomy" - back_to_taxonomies_list: "Back to Taxonomies List" + taxons: "Product Categories" shipping_methods: "Shipping Methods" shipping_method: "Shipping Method" shipment: "Shipment" @@ -3383,6 +3379,8 @@ en_ZA: total: "Total" billing_address_name: "Name" taxons: + index: + title: "Product Categories" form: name: Name description: Description diff --git a/config/locales/es.yml b/config/locales/es.yml index 908ef3ad36..73d23bc2c3 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -84,7 +84,6 @@ es: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque estás usando la configuración de estoc de la productora" - on_demand_but_count_on_hand_set: "debe estar en blanco si está bajo demanda" limited_stock_but_no_count_on_hand: "se debe especificar porque se ha definido estoc limitado" messages: blank: "no puede estar vacío" @@ -484,6 +483,8 @@ es: remove: Eliminar image: edit: Editar + product_preview: + shop_tab: Tienda adjustments: skipped_changing_canceled_order: "No puede cambiar un pedido cancelado." begins_at: Empieza en @@ -685,7 +686,6 @@ es: variants: infinity: "infinito" to_order_tip: "Los artículos hechos según demanda no tienen un nivel de stock, como por ejemplo panes hechos según demanda." - back_to_products_list: "Volver a la lista de productos" editing_product: "Editando producto" tabs: product_details: "Detalles del Producto" @@ -1195,10 +1195,8 @@ es: contact_name: Nombre de Contacto edit: editing: 'Configuración:' - back_link: Volver a la lista de organizaciones new: title: Nueva Organización - back_link: Volver a la lista de organizaciones welcome: welcome_title: Bienvenida a Open Food Network! welcome_text: Has creado correctamente un @@ -1235,6 +1233,8 @@ es: choose_products_from: "Escoger Productos desde:" re_notify_producers: Re notificar a los productores notify_producers_tip: Esto le enviará un correo a cada productor con su lista de pedidos. + date_time_warning_modal_content: + cancel: 'Cancelar' incoming: incoming: "Entrante" supplier: "Proveedora" @@ -2621,7 +2621,6 @@ es: spree_admin_single_enterprise_hint: "Sugerencia: Para permitir que la gente te encuentre, activa tu visibilidad" spree_admin_eg_pickup_from_school: "p.ej. 'Recogida en la Cooperativa'" spree_admin_eg_collect_your_order: "p.ej. 'Por favor recoge tu pedido en la Calle del Hormiguero nº3'" - spree_classification_primary_taxon_error: "La clasificación %{taxon} es la clasificación primaria de %{product} y no puede ser eliminada" spree_order_availability_error: "El Distribuidor o el Ciclo de Pedido no pueden suministrar los productos en su carrito" spree_order_populator_error: "Este Distribuidor o Ciclo de Pedido no puede suministrar todos los productos en tu carrito. Por favor, elige otro." spree_order_cycle_error: "Elija un ciclo de pedido para este pedido." @@ -3254,6 +3253,8 @@ es: Esto establecerá el nivel de stock a cero en todos los productos para este organización no está presente en el archivo subido. order_cycles: + unsaved_changes: "Tienes cambios sin guardar" + bulk_save_error: "¡Vaya! No se ha podido guardar los cambios." create_failure: "Error al crear el ciclo de pedido" update_success: 'Se ha actualizado su ciclo de pedido.' update_failure: "Error al actualizar el ciclo de pedido" @@ -3491,7 +3492,6 @@ es: more: "Más" new_adjustment: "Nuevo ajuste" new_tax_category: "Nueva categoría de impuestos" - new_taxon: "Nuevo taxón" new_user: "Nuevo usuario" no_pending_payments: "No tiene pagos pendientes" remove: "Eliminar" @@ -3509,8 +3509,6 @@ es: pick_up: "Recoger en la granja" start_date: "Fecha de inicio" successfully_removed: "Eliminado con éxito" - taxonomy_edit: "editar taxonomía" - tree: "Árbol" updating: "Actualizando" your_order_is_empty_add_product: "Su pedido está vacío, busque y añada un producto arriba" add_product: "Añadir Producto" @@ -3605,7 +3603,6 @@ es: tax_rate_amount_explanation: "Las tasas de impuestos son una cantidad decimal para ayudar en los cálculos (es decir, si la tasa de impuestos es del 5%, introduzca 0.05)" included_in_price: "Incluido en el precio" show_rate_in_label: "Mostrar impuesto en la etiqueta" - back_to_tax_rates_list: "Volver a la lista de impuestos" tax_settings: "Configuración de Impuestos" zones: "Zonas" new_zone: "Nueva zona" @@ -3618,14 +3615,11 @@ es: iso_name: "Nombre ISO" states_required: "Estados requeridos" editing_country: "Editar país" - back_to_countries_list: "Volver a la lista de países" states: "Estados" abbreviation: "Abreviatura" new_state: "Nuevo estado" payment_methods: "Métodos de Pago" - taxonomies: "Taxonomias" - new_taxonomy: "Nueva taxonomía" - back_to_taxonomies_list: "Volver a la Lista de Taxonomías" + taxons: "Categorías de Producto" shipping_methods: "Métodos de envío" shipping_method: "Método de envío" shipment: "Envío" @@ -3779,7 +3773,6 @@ es: continue: "Continuar" new: new_return_authorization: "Nueva autorización de devolución" - back_to_return_authorizations_list: "Back To Return Authorization List" continue: "Continuar" edit: receive: "recibir" @@ -4080,9 +4073,10 @@ es: total: "Total" billing_address_name: "Nombre" taxons: + index: + title: "Categorías de Producto" form: name: Nombre - permalink: Enlace permanente description: Descripción general_settings: edit: @@ -4309,7 +4303,6 @@ es: key_cleared: "valor borrado" shipment: cannot_ready: "No se puede completar envío" - invalid_taxonomy_id: "El identificador de taxonomía es inválido." activerecord: models: spree/payment: diff --git a/config/locales/es_CO.yml b/config/locales/es_CO.yml index c6e9fb8c23..f12ff74d77 100644 --- a/config/locales/es_CO.yml +++ b/config/locales/es_CO.yml @@ -68,7 +68,6 @@ es_CO: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque está usando la configuración de inventario del productor" - on_demand_but_count_on_hand_set: "debe estar en blanco si es bajo demanda" limited_stock_but_no_count_on_hand: "debe estar especificado porque se ha definido un inventario limitado" messages: blank: "no puede estar vacío" @@ -300,7 +299,6 @@ es_CO: password_confirmation: Confirmación de contraseña reset_password_token: Token de restablecimiento de contraseña expired: ha expirado, por favor solicite una nueva - back_to_payments_list: "Volver a la lista de pagos" maestro_or_solo_cards: "Solo tarjetas MasterCard" backordered: "Pedido pendiente" on_hand: "Disponibles" @@ -360,6 +358,8 @@ es_CO: remove: Eliminar image: edit: Editar + product_preview: + shop_tab: Tienda begins_at: Empieza en begins_on: Comienza en customer: Cliente @@ -541,7 +541,6 @@ es_CO: variants: infinity: "infinito" to_order_tip: "Los artículos hechos según el pedido no tienen un nivel fijado de inventario, como por ejemplo panes hechos según demanda." - back_to_products_list: "Volver a la lista de productos" editing_product: "Editando producto" tabs: product_details: "Detalles del producto" @@ -994,10 +993,8 @@ es_CO: contact_name: Nombre de contacto edit: editing: 'Configuración:' - back_link: Volver a la lista de organizaciones new: title: Nueva Organización - back_link: Volver a la lista de organizaciones welcome: welcome_title: ¡Bienvenido a Open Food Network! welcome_text: Ha creado correctamente un @@ -1032,6 +1029,8 @@ es_CO: back_to_list: "Regresar a la lista" save_and_back_to_list: "Guardar y volver a lista" choose_products_from: "Escoger productos desde:" + date_time_warning_modal_content: + cancel: 'Cancelar' incoming: incoming: "Entrante" supplier: "Proveedor" @@ -2300,7 +2299,6 @@ es_CO: spree_admin_single_enterprise_hint: "Sugerencia: Para permitir que la gente te encuentre, activa tu visibilidad" spree_admin_eg_pickup_from_school: "p.ej. 'Recogida en la Cooperativa'" spree_admin_eg_collect_your_order: "p.ej. 'Por favor recoge tu pedido en la Calle del Hormiguero nº3'" - spree_classification_primary_taxon_error: "La clasificación %{taxon} es la clasificación primaria de %{product} y no puede ser eliminada" spree_order_availability_error: "El Distribuidor o el Ciclo de Pedido no pueden suministrar los productos en su carrito" spree_order_populator_error: "Este Distribuidor o Ciclo de Pedido no puede suministrar todos los productos en tu carrito. Por favor, elige otro." spree_order_populator_availability_error: "Este producto no está disponible por el distribuidor o Ciclo de Pedido elegido." @@ -2886,6 +2884,8 @@ es_CO: Esto establecerá el nivel de stock a cero en todos los productos para esta organización que no están presentes en el archivo subido. order_cycles: + unsaved_changes: "Tiene cambios sin guardar" + bulk_save_error: "¡Vaya! No se ha podido guardar los cambios." create_failure: "Error al crear el ciclo de pedido" update_success: 'Se ha actualizado su ciclo de pedido.' update_failure: "Error al actualizar el ciclo de pedido" @@ -3188,7 +3188,6 @@ es_CO: tax_rate_amount_explanation: "Las tarifas de impuestos son una cantidad decimal para ayudar en los cálculos (es decir, si la tasa de impuestos es del 5%, introduzca 0.05)" included_in_price: "Incluido en el precio" show_rate_in_label: "Mostrar tarifa en la etiqueta" - back_to_tax_rates_list: "Volver a la lista de tarifas de impuestos" tax_settings: "Configuración de Impuestos" zones: "Zonas" new_zone: "Nueva zona" @@ -3201,14 +3200,11 @@ es_CO: iso_name: "Nombre de ISO" states_required: "Provincias requeridas" editing_country: "Editar país" - back_to_countries_list: "Volver a la lista de países" states: "Provincias" abbreviation: "Abreviatura" new_state: "Nueva provincia" payment_methods: "Métodos de pago" - taxonomies: "Taxonomías" - new_taxonomy: "Nueva taxonomía" - back_to_taxonomies_list: "Volver a la lista de taxonomías" + taxons: "Categorías de producto" shipping_methods: "Métodos de envío" shipping_method: "Método de envío" shipment: "Envío" @@ -3342,7 +3338,6 @@ es_CO: continue: "Continuar" new: new_return_authorization: "Nueva autorización de devolución" - back_to_return_authorizations_list: "Volver a lista de autorización de devolución" continue: "Continuar" edit: receive: "recibir" @@ -3616,6 +3611,8 @@ es_CO: total: "Total" billing_address_name: "Nombre" taxons: + index: + title: "Categorías de producto" form: name: Nombre description: Descripción @@ -3796,7 +3793,6 @@ es_CO: key_cleared: "Llave borrada" shipment: cannot_ready: "No se puede completar envío" - invalid_taxonomy_id: "El identificador de taxonomía es inválido." activerecord: models: spree/payment: diff --git a/config/locales/es_CR.yml b/config/locales/es_CR.yml index c281024b48..85a63c3e73 100644 --- a/config/locales/es_CR.yml +++ b/config/locales/es_CR.yml @@ -70,7 +70,6 @@ es_CR: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque está usando la configuración de inventario del productor" - on_demand_but_count_on_hand_set: "debe estar en blanco si es bajo demanda" limited_stock_but_no_count_on_hand: "debe estar especificado porque se ha definido un inventario limitado" messages: blank: "no puede estar en blanco" @@ -407,7 +406,6 @@ es_CR: password_confirmation: Confirmación de contraseña reset_password_token: Token de restablecimiento de contraseña expired: ha expirado, por favor solicite una nueva - back_to_payments_list: "Volver a la lista de pagos" maestro_or_solo_cards: "Solo tarjetas MasterCard" backordered: "Pedido pendiente" on_hand: "Disponibles" @@ -474,6 +472,8 @@ es_CR: remove: Eliminar image: edit: Editar + product_preview: + shop_tab: Tienda adjustments: skipped_changing_canceled_order: "No se puede cambiar una orden cancelada" begins_at: Empieza en @@ -677,7 +677,6 @@ es_CR: variants: infinity: "infinito" to_order_tip: "Los artículos hechos según el pedido no tienen un nivel fijado de inventario, como por ejemplo panes hechos según demanda." - back_to_products_list: "Volver a la lista de productos" editing_product: "Editando producto" tabs: product_details: "Detalles del producto" @@ -1171,10 +1170,8 @@ es_CR: contact_name: Nombre de contacto edit: editing: 'Configuración:' - back_link: Volver a la lista de organizaciones new: title: Nueva Organización - back_link: Volver a la lista de organizaciones welcome: welcome_title: ¡Bienvenido a Open Food Network (LaFeriaCR)! welcome_text: Ha creado correctamente un @@ -1211,6 +1208,8 @@ es_CR: choose_products_from: "Escoger productos desde:" re_notify_producers: Re notificar a los productores notify_producers_tip: Esto enviará un correo electrónico a cada productor con la lista de sus pedidos. + date_time_warning_modal_content: + cancel: 'Cancelar' incoming: incoming: "Entrante" supplier: "Proveedor" @@ -2579,7 +2578,6 @@ es_CR: spree_admin_single_enterprise_hint: "Sugerencia: Para permitir que la gente te encuentre, activa tu visibilidad" spree_admin_eg_pickup_from_school: "p.ej. 'Recogida en la Cooperativa'" spree_admin_eg_collect_your_order: "p.ej. 'Por favor recoge tu pedido en la Calle del Hormiguero nº3'" - spree_classification_primary_taxon_error: "La clasificación %{taxon} es la clasificación primaria de %{product} y no puede ser eliminada" spree_order_availability_error: "El Distribuidor o el Ciclo de Pedido no pueden suministrar los productos en su carrito" spree_order_populator_error: "Este Distribuidor o Ciclo de Pedido no puede suministrar todos los productos en tu carrito. Por favor, elige otro." spree_order_cycle_error: "Elija un ciclo de pedido para este pedido." @@ -3209,6 +3207,8 @@ es_CR: Esto establecerá el nivel de stock a cero en todos los productos para esta organización que no están presentes en el archivo subido. order_cycles: + unsaved_changes: "Tiene cambios sin guardar" + bulk_save_error: "¡Vaya! No se ha podido guardar los cambios." create_failure: "Error al crear el ciclo de pedido" update_success: 'Se ha actualizado su ciclo de pedido.' update_failure: "Error al actualizar el ciclo de pedido" @@ -3447,7 +3447,6 @@ es_CR: more: "Más" new_adjustment: "Nuevo ajuste" new_tax_category: "Nueva categoría de impuestos" - new_taxon: "Nuevo taxon" new_user: "Nuevo usuari" no_pending_payments: "No tiene pagos pendientes" remove: "Eliminar" @@ -3539,7 +3538,6 @@ es_CR: tax_rate_amount_explanation: "Las tarifas de impuestos son una cantidad decimal para ayudar en los cálculos (es decir, si la tasa de impuestos es del 5%, introduzca 0.05)" included_in_price: "Incluido en el precio" show_rate_in_label: "Mostrar tarifa en la etiqueta" - back_to_tax_rates_list: "Volver a la lista de tarifas de impuestos" tax_settings: "Configuración de Impuestos" zones: "Zonas" new_zone: "Nueva zona" @@ -3552,14 +3550,11 @@ es_CR: iso_name: "Nombre de ISO" states_required: "Provincias requeridas" editing_country: "Editar país" - back_to_countries_list: "Volver a la lista de países" states: "Provincias" abbreviation: "Abreviatura" new_state: "Nueva provincia" payment_methods: "Métodos de pago" - taxonomies: "Taxonomías" - new_taxonomy: "Nueva taxonomía" - back_to_taxonomies_list: "Volver a la lista de taxonomías" + taxons: "Categorías de producto" shipping_methods: "Métodos de envío" shipping_method: "Método de envío" shipment: "Envío" @@ -3691,7 +3686,6 @@ es_CR: continue: "Continuar" new: new_return_authorization: "Nueva autorización de devolución" - back_to_return_authorizations_list: "Volver a lista de autorización de devolución" continue: "Continuar" edit: receive: "recibir" @@ -3955,9 +3949,10 @@ es_CR: total: "Total" billing_address_name: "Nombre" taxons: + index: + title: "Categorías de producto" form: name: Nombre - permalink: Enlace permanente description: Descripción general_settings: edit: @@ -4123,7 +4118,6 @@ es_CR: key_cleared: "Llave borrada" shipment: cannot_ready: "No se puede completar envío" - invalid_taxonomy_id: "El identificador de taxonomía es inválido." unit: unidad components: search_input: diff --git a/config/locales/es_US.yml b/config/locales/es_US.yml index 21f59cf2fc..62d008adeb 100644 --- a/config/locales/es_US.yml +++ b/config/locales/es_US.yml @@ -68,7 +68,6 @@ es_US: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "debe estar en blanco porque estás usando la configuración de estoc de la productora" - on_demand_but_count_on_hand_set: "debe estar en blanco si está bajo demanda" limited_stock_but_no_count_on_hand: "se debe especificar porque se ha definido estoc limitado" messages: blank: "no puede estar vacío" @@ -382,7 +381,7 @@ es_US: password_confirmation: Confirmación de contraseña reset_password_token: token de restablecimiento de contraseña expired: ha expirado, por favor solicite una nueva - back_to_payments_list: "Volver a la lista de pagos" + back_to_payments_list: "Regresar a la lista de pagos" maestro_or_solo_cards: "Tarjetas Maestro/Solo" backordered: "Reabastecido" on_hand: "Disponibles" @@ -449,6 +448,8 @@ es_US: remove: Eliminar image: edit: Editar + product_preview: + shop_tab: Tienda adjustments: skipped_changing_canceled_order: "No puede modificar un pedido cancelado." begins_at: Empieza en @@ -647,7 +648,6 @@ es_US: variants: infinity: "infinito" to_order_tip: "Los artículos hechos según demanda no tienen un nivel de stock, como por ejemplo panes hechos según demanda." - back_to_products_list: "Volver a la lista de productos" editing_product: "Editando producto" tabs: product_details: "Detalles del Producto" @@ -1124,10 +1124,8 @@ es_US: contact_name: Nombre de Contacto edit: editing: 'Configuración:' - back_link: Volver a la lista de organizaciones new: title: Nueva Organización - back_link: Volver a la lista de organizaciones welcome: welcome_title: Bienvenida a Open Food Network! welcome_text: Has creado correctamente un @@ -1164,6 +1162,8 @@ es_US: choose_products_from: "Escoger Productos desde:" re_notify_producers: Re notificar a productores notify_producers_tip: Esto enviará un correo electrónico a cada productor con la lista de sus pedidos. + date_time_warning_modal_content: + cancel: 'Cancelar' incoming: incoming: "Entrante" supplier: "Proveedora" @@ -2466,7 +2466,6 @@ es_US: spree_admin_single_enterprise_hint: "Sugerencia: Para permitir que la gente te encuentre, activa tu visibilidad" spree_admin_eg_pickup_from_school: "p.ej. 'Recogida en la Cooperativa'" spree_admin_eg_collect_your_order: "p.ej. 'Por favor recoge tu pedido en la Calle del Hormiguero nº3'" - spree_classification_primary_taxon_error: "La clasificación %{taxon} es la clasificación primaria de %{product} y no puede ser eliminada" spree_order_availability_error: "El Distribuidor o el Ciclo de Pedido no pueden suministrar los productos en su carrito" spree_order_populator_error: "Este Distribuidor o Ciclo de Pedido no puede suministrar todos los productos en tu carrito. Por favor, elige otro." spree_order_cycle_error: "Elija un ciclo de pedido para este pedido." @@ -3076,6 +3075,8 @@ es_US: Esto establecerá el nivel de stock a cero en todos los productos para este organización no está presente en el archivo subido. order_cycles: + unsaved_changes: "Tienes cambios sin guardar" + bulk_save_error: "¡Vaya! No se ha podido guardar los cambios." create_failure: "Error al crear el ciclo de pedido" update_success: 'Se ha actualizado su ciclo de pedido.' update_failure: "Error al actualizar el ciclo de pedido" @@ -3315,7 +3316,6 @@ es_US: resend_authorization_email: "Reenviar email de autorización" refund: "Reembolso" server_error: "Error del Servidor" - tree: "Árbol" updating: "Actualizando" your_order_is_empty_add_product: "Su pedido está vacío, busque y añada un producto arriba" add_product: "Añadir Producto" @@ -3410,7 +3410,6 @@ es_US: tax_rate_amount_explanation: "Las tasas de impuestos son una cantidad decimal para ayudar en los cálculos (es decir, si la tasa de impuestos es del 5%, introduzca 0.05)" included_in_price: "Incluido en el precio" show_rate_in_label: "Mostrar impuesto en la etiqueta" - back_to_tax_rates_list: "Volver a la lista de impuestos" tax_settings: "Configuración de Impuestos" zones: "Zonas" new_zone: "Nueva zona" @@ -3423,14 +3422,11 @@ es_US: iso_name: "Nombre ISO" states_required: "Estados requeridos" editing_country: "Editar país" - back_to_countries_list: "Volver a la lista de países" states: "Estados" abbreviation: "Abreviatura" new_state: "Nuevo estado" payment_methods: "Métodos de Pago" - taxonomies: "Taxonomias" - new_taxonomy: "Nueva taxonomía" - back_to_taxonomies_list: "Volver a la Lista de Taxonomías" + taxons: "Categorías de Producto" shipping_methods: "Métodos de envío" shipping_method: "Método de envío" shipment: "Envío" @@ -3584,7 +3580,6 @@ es_US: continue: "Continuar" new: new_return_authorization: "Nueva autorización de devolución" - back_to_return_authorizations_list: "Back To Return Authorization List" continue: "Continuar" edit: receive: "recibir" @@ -3872,9 +3867,10 @@ es_US: total: "Total" billing_address_name: "Nombre" taxons: + index: + title: "Categorías de Producto" form: name: Nombre - permalink: Enlace permanente description: Descripción general_settings: edit: @@ -4091,7 +4087,6 @@ es_US: key_cleared: "valor borrado" shipment: cannot_ready: "No se puede completar envío" - invalid_taxonomy_id: "El identificador de taxonomía es inválido." activerecord: models: spree/payment: diff --git a/config/locales/fil_PH.yml b/config/locales/fil_PH.yml index f9a4b73116..e69a44085e 100644 --- a/config/locales/fil_PH.yml +++ b/config/locales/fil_PH.yml @@ -61,7 +61,6 @@ fil_PH: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "ay dapat blanko sapagkat ginagamit ang stock settings ng producer" - on_demand_but_count_on_hand_set: "ay dapat blanko kung on demand" limited_stock_but_no_count_on_hand: "ay dapat matukoy sapagkat ipipilit ang limitadong stock" messages: blank: "hindi maaaring iwanang blanko" @@ -279,7 +278,6 @@ fil_PH: password_confirmation: Kumpirmasyon ng password reset_password_token: i-reset ang password token expired: ay expired na, magrequest ng bago - back_to_payments_list: "bumalik sa listahan ng mga bayad" maestro_or_solo_cards: "Maestro/Solo cards" backordered: "na-backorder" on_hand: "on hand" @@ -336,6 +334,8 @@ fil_PH: remove: Tanggalin image: edit: i-edit + product_preview: + shop_tab: Shop begins_at: nagsimula sa begins_on: nagsisimula sa customer: Customer @@ -514,7 +514,6 @@ fil_PH: variants: infinity: "walang katapusan" to_order_tip: "ang mga item na made to order ay hindi maaaring i-set ng lebel ng stock, tulad ng mga tinapay na ginagawa lamang kapag may order." - back_to_products_list: "bumalik sa listahan ng mga produkto" editing_product: "ine-edit ang mga produkto" tabs: product_details: "mga detalye ng produkto" @@ -962,10 +961,8 @@ fil_PH: contact_name: Contact name edit: editing: 'Settings:' - back_link: bumalik sa listahan ng mga enterprise new: title: bagong enterprise - back_link: bumalik sa listahan ng mga enterprise welcome: welcome_title: Welcome sa Open Food Network! welcome_text: matagumpay mong nagawa ang @@ -1000,6 +997,8 @@ fil_PH: back_to_list: "bumalik sa listahan" save_and_back_to_list: "i-save at bumalik sa listahan" choose_products_from: "pumili ng mga produkto mula sa:" + date_time_warning_modal_content: + cancel: 'kanselahin' incoming: incoming: "paparating" supplier: "Supplier" @@ -2244,7 +2243,6 @@ fil_PH: spree_admin_single_enterprise_hint: "payo: para mahanap ka ng ibang tao, i-turn on ang visibility sa ilalim ng" spree_admin_eg_pickup_from_school: "hal. 'Pick-up mula sa Primary School'" spree_admin_eg_collect_your_order: "hal. 'Kolektahin ang inyong order sa 123 Kapayapaan St., Tobias Fornier, Antique 5716'" - spree_classification_primary_taxon_error: "ang Tax sa%{taxon}ay ang pangunahing tax ng %{product}at hindi maaaring tanggalin" spree_order_availability_error: "ang distributor o order cycle ay hindi kayang ibigay ang mga produkto sa inyong cart" spree_order_populator_error: "ang distributor o order cycle na ito ay hindi kayang ibigay lahat ng mga produkto sa inyong cart. pumili ng iba." spree_order_populator_availability_error: "ang produktong ito ay hindi ngayon available mula sa napiling distributor o order cycle." @@ -2520,7 +2518,7 @@ fil_PH: order_cycles_bulk_update_notice: 'ang mga order cycle ay na-update na' order_cycles_no_permission_to_coordinate_error: "wala sa inyong mga enterprise ay may pahintulot na magsa-ayos ng order cycle" order_cycles_no_permission_to_create_error: "wala kang pahintulot na gumawa ng order cycle na isinaayos ng enterprise na iyon." - back_to_orders_list: "bumalik sa listahan ng order" + back_to_orders_list: "bumalik sa listahan ng mga order" no_orders_found: "walang mahanap na mga order" order_information: "impormasyon tungkol sa order" new_payment: "Bagong Pagbabayad" @@ -2827,6 +2825,8 @@ fil_PH: ise-set nito ang lebel ng stock sa zero para sa lahat ng mga produkto para dito enterprise na hindi makikita sa inupload na file. order_cycles: + unsaved_changes: "May mga pagbabago na hindi na-save" + bulk_save_error: "paumanhin! hindi ko na-save ang mga pagbabagong ginawa mo." create_failure: "hindi nagtagumpay sa paggawa ng order cycle" update_success: 'ang iyong order cycle ay na-update na' update_failure: "hindi nagtagumpay sa pag-update ng order cycle" @@ -3093,7 +3093,6 @@ fil_PH: tax_rate_amount_explanation: "ang mga rate ng tax ay mga halagang may decimal na makakatulong sa pagkukuwenta, (hal. kung ang rate ng tax ay 5% ang ilalagay ay 0.05)" included_in_price: "nakasama sa presyo" show_rate_in_label: "ipakita ang rate sa tatak" - back_to_tax_rates_list: "bumalik sa listahan ng rate ng tax" tax_settings: "Settings ng tax" zones: "mga sona" new_zone: "bagong sona" @@ -3106,14 +3105,11 @@ fil_PH: iso_name: "pangalan ng ISO" states_required: "Kailangang nakasaad ang mga Lalawigan" editing_country: "pag-edit ng bansa" - back_to_countries_list: "bumalik sa listahan ng mga bansa" states: "Mga Lalawigan" abbreviation: "Pinaikli" new_state: "Bagong Status" payment_methods: "Mga Paraan ng Pagbabayad" - taxonomies: "taxonomies" - new_taxonomy: "bagong taxonomy" - back_to_taxonomies_list: "bumalik sa listahan ng mga taxonomy" + taxons: "kategorya ng produkto" shipping_methods: "mga paraan ng pagpapadala" shipping_method: "paraan ng pagpapadala" shipment: "kargamento" @@ -3244,7 +3240,6 @@ fil_PH: continue: "Magpatuloy" new: new_return_authorization: "bagong awtorisasyon sa pagbabalik" - back_to_return_authorizations_list: "bumalik sa listahan ng awtorisasyon sa pagbabalik" continue: "Magpatuloy" edit: receive: "tumanggap" @@ -3502,6 +3497,8 @@ fil_PH: total: "kabuuan" billing_address_name: "Pangalan" taxons: + index: + title: "kategorya ng produkto" form: name: Pangalan description: paglalarawan @@ -3668,7 +3665,6 @@ fil_PH: key_cleared: "binura ang key" shipment: cannot_ready: "hindi maihanda ang kargamento" - invalid_taxonomy_id: "hindi valid na taxonomy id." unit: yunit components: search_input: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index ca96bfcd67..7ce1745a4e 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -82,7 +82,7 @@ fr: errors: models: enterprise_fee: - inherit_tax_requires_per_item_calculator: "Déterminer la catégorie de taxe requiert l'utilisation du calculateur par article. " + inherit_tax_requires_per_item_calculator: "Déterminer la catégorie de taxe requiert l'utilisation du calculateur par article" spree/image: attributes: attachment: @@ -99,8 +99,6 @@ fr: attributes: base: card_expired: "a expiré" - spree/product: - must_exist: 'doit exister' order_cycle: attributes: orders_close_at: @@ -108,7 +106,6 @@ fr: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "doit être vide car utilise les informations de stock du producteur" - on_demand_but_count_on_hand_set: "doit être vide si \"à volonté\"" limited_stock_but_no_count_on_hand: "doit être spécifié car pas \"à volonté\"" messages: confirmation: "ne correspond pas %{attribute}" @@ -676,6 +673,16 @@ fr: info_html: "Matomo est un outil de suivi de traffic et de comportement des utilisateurs. Matomo est open source et validée par la CNIL française car non intrusif dans les données personnelles des utilisateurs. Pour plus d'infos : matomo.org." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec CoopCircuits. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." config_instructions_tag_manager_html: "Ajouter l'URL du Tag Manager rend actif Matomo Tag Manager. Cet outil vous permet de suivre des évènements en particulier. Pour trouver l'URL rendez-vous sur l' \"Install Code section\" du Tag Manager. Attention à bien copier le bon contener et le bon environnement, car ils font varier l'URL." + connected_app_settings: + edit: + title: "Paramètres de l'application connectée" + info_html: "Les applications autorisées apparaitront dans Entreprises > Configuration > Applications connectées" + enabled_legend: "Applications connectées autorisées" + connected_apps_enabled: + discover_regen: Portail Discover Regenerative + affiliate_sales_data: API de commandes anonymisées DFC à fins de recherche + update: + resource: Paramètres de l'application connectée customers: index: new_customer: "Nouvel acheteur" @@ -773,7 +780,7 @@ fr: variants: infinity: "Infini" to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main." - back_to_products_list: "Retour à la liste produits" + back_to_products_list: "Revenir à la liste des produits" editing_product: "Modifier le produit" tabs: product_details: "Détails" @@ -813,7 +820,10 @@ fr: search: Rechercher sort: pagination: - total_html: "%{total} produits trouvés selon vos critères de recherche. Résultats %{from} à %{to}." + products_total_html: + one: "%{count} produit trouvé pour vos critères de recherche. Affichage %{from} à %{to} ." + many: "%{count} produits trouvés pour vos critères de recherche. Affichage %{from} à %{to} ." + other: "%{count} produits trouvés pour vos critères de recherche. Affichage %{from} à %{to} ." per_page: show: Montrer per_page: "%{num} par page" @@ -1386,7 +1396,7 @@ fr: contact_name: Nom du contact principal edit: editing: 'Configuration:' - back_link: Revenir à la liste des entreprises + back_link: Retour à la liste des entreprises new: title: Nouvelle entreprise back_link: Revenir à la liste des entreprises @@ -1426,6 +1436,11 @@ fr: choose_products_from: "Choisir produits depuis :" re_notify_producers: Notifier les producteurs notify_producers_tip: Cette action va envoyer un mail à tous les producteurs avec le contenu du cycle de vente. + date_time_warning_modal_content: + title: 'Les commandes sont liées à ce cycle de vente.' + content: 'Si vous souhaitez créer un nouveau cycle de vente, il est recommandé de dupliquer un cycle de vente existant puis de changer les dates.' + proceed: 'Procéder quand même' + cancel: 'Annuler' incoming: incoming: "Produits entrants (pouvant être mis en vente par les boutiques du cycle de vente)" supplier: "Fournisseur" @@ -2889,7 +2904,6 @@ fr: spree_admin_single_enterprise_hint: "Astuce: Pour permettre aux gens de vous trouver, activez votre visibilité " spree_admin_eg_pickup_from_school: "ex : \"Retrait des produits à l'Ecole Marimati / Au Café du coin / chez Babette / ...\"" spree_admin_eg_collect_your_order: "ex : \"Veuillez récupérer votre commande au 34 rue Victor Hugo, 75018 Paris\"" - spree_classification_primary_taxon_error: "La catégorie %{taxon} est utilisée par %{product} et ne peut être supprimée" spree_order_availability_error: "Le distributeur ne peut fournir les produits de votre panier pour ce cycle de vente." spree_order_populator_error: "Le distributeur ne peut fournir tous les produits de votre panier pour ce cycle de vente. Merci de choisir un autre distributeur ou un autre cycle de vente." spree_order_cycle_error: "Veuillez sélectionner une option pour cette commande." @@ -3581,6 +3595,8 @@ fr: Cette action remettra tous les niveaux de stock à zero pour cette entreprise pour les produits non présents dans ce fichier. order_cycles: + unsaved_changes: "Des modifications n'ont pas été sauvegardées" + bulk_save_error: "Oups ! Nous n'avons pas réussi à sauvegarder vos modification :-(" create_failure: "La création du cycle de vente a échoué" update_success: 'Votre cycle de vente a été mis à jour.' update_failure: "La mise à jour du cycle de vente à échoué" @@ -3828,7 +3844,6 @@ fr: more: "Plus" new_adjustment: "Nouvel ajustement" new_tax_category: "Nouvelle catégorie de taxe" - new_taxon: "Nouvelle taxonomie" new_user: "Nouvel utilisateur" no_pending_payments: "Aucun paiement en attente." remove: "Supprimer" @@ -3847,10 +3862,6 @@ fr: delivery: "Signé, scellé, livré" start_date: "Date de début" successfully_removed: "Supprimé avec succès" - taxonomy_edit: "Modifier la taxonomie" - taxonomy_tree_error: "Erreur lors de la mise à jour de l'arbre de taxonomie." - taxonomy_tree_instruction: "Faites un clic droit sur un article pour ajouter, renommer, supprimer ou modifier." - tree: "Arbre" updating: "Mettre à jour" your_order_is_empty_add_product: "Votre commande est vide, veuillez ajouter des produits" add_product: "Ajouter un produit" @@ -3948,7 +3959,7 @@ fr: tax_rate_amount_explanation: "Les taux de taxe sont présentés en nombres décimaux pour faciliter les calculs (ex : si le taux est 5,5% saisissez 0.055)" included_in_price: "Inclus dans le prix" show_rate_in_label: "Montrer le taux dans le nom" - back_to_tax_rates_list: "Retour à la liste des taux de taxe" + back_to_tax_rates_list: "Revenir à la liste des taux de taxe" tax_settings: "Paramètres TVA" zones: "Zones" new_zone: "Nouvelle zone" @@ -3961,14 +3972,12 @@ fr: iso_name: "Noms ISO" states_required: "États/Départements requis" editing_country: "Pays en cours de mise à jour" - back_to_countries_list: "Retour à la liste des pays" + back_to_countries_list: "Revenir à la liste des pays" states: "Départements" abbreviation: "Code" new_state: "Nouveau département" payment_methods: "Méthodes de paiement" - taxonomies: "Taxonomies" - new_taxonomy: "Nouvelle taxonomie" - back_to_taxonomies_list: "Retour à la liste des taxonomies" + taxons: "Catégorie Produit" shipping_methods: "Méthodes de livraison" shipping_method: "Option d'expédition" shipment: "Livraison" @@ -4341,6 +4350,8 @@ fr: new_product: "Nouveau Produit" supplier: "Fournisseur" supplier_select_placeholder: "Sélectionner un producteur" + search_for_suppliers: "Chercher des fournisseurs" + search_for_units: "Chercher des unités" product_name: "Nom du Produit" units: "Unité de mesure" value: "Quantité" @@ -4375,6 +4386,7 @@ fr: product_name: Nom du Produit primary_taxon_form: product_category: Catégorie Produit + search_for_categories: "Rechercher" group_buy_form: group_buy: "Achat groupé de lots fixes ?" bulk_unit_size: Quantité totale du lot @@ -4452,9 +4464,20 @@ fr: total: "Total" billing_address_name: "Nom" taxons: + back_to_list: "Revenir à la liste des catégories de produits" + index: + title: "Catégorie Produit" + new_taxon: 'Nouvelle catégorie de produit' + new: + title: "Nouvelle catégorie de produit" + edit: + title: "Editer la catégorie de produit" + destroy: + delete_taxon: + success: "Catégorie de produit supprimée" + error: "Impossible de supprimer la catégorie de produit car des produits sont liés à cette catégorie." form: name: Nom - permalink: Permalien meta_title: Méta titre meta_description: Méta description meta_keywords: Méta mots clés @@ -4697,7 +4720,6 @@ fr: key_cleared: "Clé supprimée" shipment: cannot_ready: "La livraison ne peut pas être préparée." - invalid_taxonomy_id: "L'identifiant de la catégorie n'est pas valide." toggle_api_key_view: "Montrer la clé API pour cet utilisateur" activerecord: models: diff --git a/config/locales/fr_BE.yml b/config/locales/fr_BE.yml index a05d383b5b..af40396788 100644 --- a/config/locales/fr_BE.yml +++ b/config/locales/fr_BE.yml @@ -73,8 +73,6 @@ fr_BE: white_label_logo_link: "Lien pour le logo utilisé en vitrine" errors: models: - enterprise_fee: - inherit_tax_requires_per_item_calculator: "L'héritage de la catégorie de taxe nécessite un calculateur par article." spree/user: attributes: email: @@ -94,7 +92,6 @@ fr_BE: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "doit être vide car les paramètres de stock du producteur sont utilisés" - on_demand_but_count_on_hand_set: "doit être vide si à la demande" limited_stock_but_no_count_on_hand: "doit être spécifié car le stock limité est forcé" messages: confirmation: "ne correspond pas à %{attribute}" @@ -488,6 +485,8 @@ fr_BE: remove: Supprimer image: edit: Modifier + product_preview: + shop_tab: Comptoir adjustments: skipped_changing_canceled_order: "Vous ne pouvez pas modifier une commande annulée." begins_at: Commence @@ -693,7 +692,7 @@ fr_BE: variants: infinity: "Infinité" to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main." - back_to_products_list: "Retour à la liste produits" + back_to_products_list: "Retour à la liste des produits" editing_product: "Éditer le produit" tabs: product_details: "Détails du produit" @@ -720,7 +719,10 @@ fr_BE: search: Rechercher sort: pagination: - total_html: "%{total} produits trouvés pour vos critères de recherche. Affichage %{from} à %{to} ." + products_total_html: + one: "%{count} produit trouvé pour vos critères de recherche. Affichage %{from} à %{to} ." + many: "%{count} produits trouvés pour vos critères de recherche. Affichage %{from} à %{to} ." + other: "%{count} produits trouvés pour vos critères de recherche. Affichage %{from} à %{to} ." per_page: show: Montrer per_page: "%{num} par page" @@ -1232,10 +1234,8 @@ fr_BE: contact_name: Nom du contact principal edit: editing: 'Configuration:' - back_link: Revenir à la liste des entreprises new: title: Nouvelle entreprise - back_link: Revenir à la liste des entreprises welcome: welcome_title: Bienvenue sur Open Food Network ! welcome_text: 'Vous avez créé avec succès ' @@ -1272,6 +1272,11 @@ fr_BE: choose_products_from: "Choisir produits depuis :" re_notify_producers: Notifier les producteurs notify_producers_tip: Cette action va envoyer un mail à tous les producteurs avec leur contenu du cycle de vente. + date_time_warning_modal_content: + title: 'Des commandes sont liées à ce cycle de commande.' + content: 'Si vous souhaitez créer un nouveau cycle de commande, il est recommandé de dupliquer d''abord le cycle de commande, puis de modifier les dates.' + proceed: 'Continuer quand même' + cancel: 'Annuler' incoming: incoming: "Produits entrants (pouvant être mis en vente par les comptoirs)" supplier: "Disitributeur·trice" @@ -1469,6 +1474,9 @@ fr_BE: Désolé, ce rapport a pris trop de temps à traiter. Il peut contenir beaucoup de données ou nous sommes occupés par d'autres rapports. Vous pouvez réessayer plus tard. + report_taking_longer_html: > + Le traitement de ce rapport prend plus de temps. Il peut contenir beaucoup + de données ou nous sommes occupés avec d'autres rapports. report_link_label: Télécharger le rapport (si disponible) revenues_by_hub: name: CA par comptoir @@ -2658,7 +2666,6 @@ fr_BE: spree_admin_single_enterprise_hint: "Astuce: Pour permettre aux gens de vous trouver, activez votre visibilité " spree_admin_eg_pickup_from_school: "ex : \"Retrait des produits à l'Ecole Marimati / Au Café du coin / chez Babette / ...\"" spree_admin_eg_collect_your_order: "ex : \"Veuillez récupérer votre commande au 131 Rue Provinciale, 1300 Wavre\"" - spree_classification_primary_taxon_error: "La catégorie %{taxon}est utilisée par %{product} et ne peut être supprimée" spree_order_availability_error: "Le distributeur ne peut fournir les produits de votre panier pour ce cycle de vente." spree_order_populator_error: "Le distributeur ne peut fournir tous les produits de votre panier pour ce cycle de vente. Merci de choisir un autre distributeur ou un autre cycle de vente." spree_order_cycle_error: "Veuillez choisir un cycle de commande pour cette commande." @@ -2971,7 +2978,7 @@ fr_BE: order_cycles_no_permission_to_coordinate_error: "Aucune de vos entreprises n'a les droits requis pour coordonner un cycle de vente" order_cycles_no_permission_to_create_error: "Vous n'avez pas les droits requis pour créer un cycle de vente coordonné par cette entreprise" order_cycle_closed: "Le cycle de commande que vous avez sélectionner vient de fermer. Essayer plus tard." - back_to_orders_list: "Retour à la liste des commandes" + back_to_orders_list: "Retour vers la liste des commandes " no_orders_found: "Aucune commande trouvée pour ces critères" order_information: "Info commande" new_payment: "Nouveau paiement" @@ -3316,6 +3323,8 @@ fr_BE: Cette action remettra tous les niveaux de stock à zero pour cette entreprise pour les produits non présents dans ce fichier. order_cycles: + unsaved_changes: "Des modifications n'ont pas été sauvegardées" + bulk_save_error: "Oups ! Nous n'avons pas réussi à sauvegarder vos modification :-(" create_failure: "La création du cycle de vente a échoué" update_success: 'Votre cycle de vente a été mis à jour.' update_failure: "La mise à jour du cycle de vente a échoué" @@ -3462,13 +3471,13 @@ fr_BE: notice_messages: variant_deleted: "Variante supprimée" start_date: "Date de début" - taxonomy_tree_instruction: "Faites un clic droit sur un élément pour ajouter, renommer, supprimer ou modifier." updating: "Mettre à jour" your_order_is_empty_add_product: "Votre commande est vide, merci de chercher et d'ajouter un des produits ci-dessus" add_product: "Ajoutez un produit" name_or_sku: "Nom ou N° d'article (entrer au moins 4 lettres du nom du produit) " resend: "Renvoyer" back_to_orders_list: "Retour vers la liste des commandes " + back_to_payments_list: "Retour à la liste des paiements" back_to_states_list: "Retour à la liste des provinces" return_authorizations: "Autorisations de retour" cannot_create_returns: "Impossible de créer des retours car cette commande n'a pas d'unités expédiées." @@ -3553,7 +3562,6 @@ fr_BE: tax_rate_amount_explanation: "Les taux sont décimaux pour faciliter les calculs (par ex. un taux de 5% sera entré en tant que 0.05) " included_in_price: "Inclus dans le prix " show_rate_in_label: "Montrer le taux sur l'étiquette " - back_to_tax_rates_list: "Retour à la liste des taux de TVA" tax_settings: "Paramètres TVA" zones: "Zones" new_zone: "Nouvelle zone " @@ -3566,14 +3574,11 @@ fr_BE: iso_name: "Nom ISO" states_required: "Provinces requises" editing_country: "Éditer le pays" - back_to_countries_list: "Retouner vers la liste des pays" states: "Provinces" abbreviation: "Abréviation" new_state: "Nouvelle Province" payment_methods: "Méthodes de paiement" - taxonomies: "Taxonomies " - new_taxonomy: "Nouvelle taxonomie" - back_to_taxonomies_list: "Retour à la liste des taxonomies" + taxons: "Catégorie Produit" shipping_methods: "Méthodes de livraison" shipping_method: "Méthode de Livraison" shipment: "Envoi" @@ -3724,7 +3729,6 @@ fr_BE: continue: "Suivant" new: new_return_authorization: "Nouvelle autorisation de retour" - back_to_return_authorizations_list: "Retour vers la liste d'autorisation de retour" continue: "Suivant" edit: receive: "recevoir" @@ -3952,6 +3956,7 @@ fr_BE: product_name: Nom du Produit primary_taxon_form: product_category: Catégorie Produit + search_for_categories: "Rechercher des catégories" group_buy_form: group_buy: "Achat groupé de lots fixes ?" bulk_unit_size: Quantité totale du lot @@ -4026,9 +4031,10 @@ fr_BE: total: "Total" billing_address_name: "Nom" taxons: + index: + title: "Catégorie Produit" form: name: Nom - permalink: 'Permalien : Nom pour URL (sans espace)' description: Description general_settings: edit: @@ -4220,7 +4226,6 @@ fr_BE: key_cleared: "clé effacée" shipment: cannot_ready: "Impossible de préparer l'expédition." - invalid_taxonomy_id: "Id taxonomique invalide." unit: unité per_unit: Montant par unité datetime: diff --git a/config/locales/fr_CA.yml b/config/locales/fr_CA.yml index cdae1f1664..a9d6950651 100644 --- a/config/locales/fr_CA.yml +++ b/config/locales/fr_CA.yml @@ -106,7 +106,6 @@ fr_CA: variant_override: count_on_hand: using_producer_stock_settings_but_count_on_hand_set: "doit être vide car utilise les informations de stock du producteur" - on_demand_but_count_on_hand_set: "doit être vide si \"à volonté\"" limited_stock_but_no_count_on_hand: "doit être spécifié car pas \"à volonté\"" messages: confirmation: "ne correspond pas %{attribute}" @@ -557,6 +556,8 @@ fr_CA: remove: Supprimer image: edit: Modifier + product_preview: + shop_tab: Boutique adjustments: skipped_changing_canceled_order: "Vous ne pouvez pas modifier une commande annulée." begins_at: Commence à @@ -675,6 +676,16 @@ fr_CA: info_html: "Matomo est un outil de suivi de traffic et de comportement des utilisateurs. Matomo est open source et validée par la CNIL française car non intrusif dans les données personnelles des utilisateurs. Pour plus d'infos : 1matomo.org1." config_instructions_html: "Pour utiliser Matomo, vous devez configurer l'intégration avec Open Food France. L'URL de l'instance sur Matomo correspond à l'url du site internet visé par le suivi de la navigation utilisateur. Si le champ est vide, Matomo n'effectuera aucune analyse sur ce site. L'ID de l'instance sur Matomo n'est pas obligatoire, mais nécessaire si vous souhaitez analyser plusieurs sites web sur une seule instance Matomo. Cet ID peut être trouvé sur l'espace administrateur Matomo." config_instructions_tag_manager_html: "Ajouter l'URL du Tag Manager rend actif Matomo Tag Manager. Cet outil vous permet de suivre des évènements en particulier. Pour trouver l'URL rendez-vous sur l' \"Install Code section\" du Tag Manager. Attention à bien copier le bon contener et le bon environnement, car ils font varier l'URL." + connected_app_settings: + edit: + title: "Paramètres de l'application connectée" + info_html: "Les applications autorisées apparaitront dans Entreprises > Configuration > Applications connectées" + enabled_legend: "Applications connectées autorisées" + connected_apps_enabled: + discover_regen: Portail Discover Regenerative + affiliate_sales_data: API de commandes anonymisées DFC à fins de recherche + update: + resource: Paramètres de l'application connectée customers: index: new_customer: "Nouveau client" @@ -772,7 +783,7 @@ fr_CA: variants: infinity: "Infini" to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main." - back_to_products_list: "Retour à la liste produits" + back_to_products_list: "Revenir à la liste des produits" editing_product: "Modifier le produit" tabs: product_details: " Détails" @@ -800,8 +811,10 @@ fr_CA: filters: search_products: Chercher des produits search_for_producers: Rechercher des producteurs + select_producer: Sélectionner producteur all_producers: Tous les producteurs search_for_categories: Rechercher des catégories + select_category: Sélectionner catégorie all_categories: Toutes les catégories producers: label: Producteurs @@ -810,7 +823,6 @@ fr_CA: search: Chercher sort: pagination: - total_html: "%{total} produits trouvés selon vos critères de recherche. Montrer %{from} à %{to}." per_page: show: Montrer per_page: "%{num} par page" @@ -1294,10 +1306,21 @@ fr_CA: connected_apps: legend: "Applications connectées" affiliate_sales_data: + title: "Programme de recherche INRAE / UFC QUE CHOISIR" + tagline: "Autoriser ce programme de recherche à accéder à vos données de commandes anonymisées" enable: "Autoriser le partage de données" disable: "Arrêter le partage" loading: "Chargement en cours" need_to_be_manager: "Seuls les gestionnaires peuvent connecter des applications." + description_html: | +
+ L'INRAE et UFC QUE CHOISIR travaillent conjointement sur les prix des produits distribués en circuit court, comparés aux prix des mêmes produits vendus en supermarché, pour un échantillon de produits. Les données utilisées dans le cadre de ce programme de recherche sont une agrégation des données fournies par plusieurs plateformes de vente en circuit court en France. Aucun prix de produit d'une boutique en particulier ne sera transmis publiquement à travers ce programme. +
++ En savoir plus à propos de ce programme de recherche + +
discover_regen: title: "Annuaire alimentaire de Waterloo" tagline: "Permettre à l'OFN Canada de publier les informations relatives à votre entreprise." @@ -1307,8 +1330,8 @@ fr_CA: need_to_be_manager: "Seuls les gestionnaires peuvent connecter des applications." note: | Votre compte Open Food Network est connecté à Annuaire alimentaire de Waterloo. - Les modifications apportées à votre profil OFN mettront automatiquement à jour votre liste Annuaire alimentaire de Waterloo. Pour toute autre modification, veuillez contacter le service d'assistance de l'OFN. - link_label: "Gérer la liste" + Les modifications apportées à votre profil OFN mettront à jour votre liste Waterloo Food Directory lorsque vous cliquerez sur le bouton 'Mise à jour de la liste'. Pour toute autre modification, veuillez contacter le service d'assistance de l'OFN et support@openfoodnetwork.ca. + link_label: "Mise à jour de la liste" description_html: |Les producteurs éligibles peuvent présenter des appels à l'action en faveur du manger local, donner local, et/ou cultiver local..
Cela simplifie la façon dont les producteurs peuvent se connecter dans la région de Waterloo autour de la justice et de la souveraineté alimentaires.
@@ -1370,10 +1393,10 @@ fr_CA:
contact_name: Nom du contact principal
edit:
editing: 'Configuration:'
- back_link: Revenir à la liste des entreprises
+ back_link: Retour à la liste des entreprises
new:
title: Nouvelle entreprise
- back_link: Revenir à la liste des entreprises
+ back_link: Retour à la liste des entreprises
welcome:
welcome_title: Bienvenue sur Open Food Network !
welcome_text: 'Vous avez créé avec succès '
@@ -1410,6 +1433,11 @@ fr_CA:
choose_products_from: "Choisir produits depuis :"
re_notify_producers: Notifier les producteurs
notify_producers_tip: Cette action va envoyer un mail à tous les producteurs avec le contenu du cycle de vente.
+ date_time_warning_modal_content:
+ title: 'Les commandes sont liées à ce cycle de vente.'
+ content: 'Si vous souhaitez créer un nouveau cycle de vente, il est recommandé de dupliquer un cycle de vente existant puis de changer les dates.'
+ proceed: 'Procéder quand même'
+ cancel: 'Annuler'
incoming:
incoming: "Produits entrants (pouvant être mis en vente par les hubs)"
supplier: "Fournisseur"
@@ -2872,7 +2900,6 @@ fr_CA:
spree_admin_single_enterprise_hint: "Astuce: Pour permettre aux gens de vous trouver, activez votre visibilité "
spree_admin_eg_pickup_from_school: "ex : \"Retrait des produits à l'Ecole Marimati / Au Café du coin / chez Babette / ...\""
spree_admin_eg_collect_your_order: "ex : \"Veuillez récupérer votre commande au 123 Parliament Street, Toronto, Ontario 3070 \""
- spree_classification_primary_taxon_error: "L'intitulé %{taxon} est l'intitulé de base pour %{product} et ne peut être supprimé"
spree_order_availability_error: "Le distributeur ne peut fournir les produits de votre panier pour ce cycle de vente."
spree_order_populator_error: "Le distributeur ne peut fournir tous les produits de votre panier pour ce cycle de vente. Merci de choisir un autre distributeur ou un autre cycle de vente."
spree_order_cycle_error: "Veuillez sélectionner une option pour cette commande."
@@ -3548,6 +3575,8 @@ fr_CA:
Cette action remettra tous les niveaux de stock à zero pour cette
entreprises pour les produits non présents dans ce fichier.
order_cycles:
+ unsaved_changes: "Des modifications n'ont pas été sauvegardées"
+ bulk_save_error: "Oups ! Nous n'avons pas réussi à sauvegarder vos modification :-("
create_failure: "La création du cycle de vente a échoué"
update_success: 'Votre cycle de vente a été mis à jour.'
update_failure: "La mise à jour du cycle de vente à échoué"
@@ -3795,7 +3824,6 @@ fr_CA:
more: "Plus"
new_adjustment: "Nouvel ajustement"
new_tax_category: "Nouvelle catégorie de taxe"
- new_taxon: "Nouvelle taxonomie"
new_user: "Nouvel utilisateur"
no_pending_payments: "Aucun paiement en attente."
remove: "Supprimer"
@@ -3814,10 +3842,6 @@ fr_CA:
delivery: "Signé, scellé, livré"
start_date: "Date de début"
successfully_removed: "Supprimé avec succès"
- taxonomy_edit: "Modifier la taxonomie"
- taxonomy_tree_error: "Erreur lors de la mise à jour de l'arbre de taxonomie."
- taxonomy_tree_instruction: "Faites un clic droit sur un article pour ajouter, renommer, supprimer ou modifier."
- tree: "Arbre"
updating: "Mettre à jour"
your_order_is_empty_add_product: "Votre commande est vide, veuillez ajouter des produits"
add_product: "Ajouter un produit"
@@ -3915,7 +3939,7 @@ fr_CA:
tax_rate_amount_explanation: "Les taux de taxe sont présentés en nombres décimaux pour faciliter les calculs (ex : si le taux est 5% saisissez 0.05)"
included_in_price: "Inclus dans le prix"
show_rate_in_label: "Montrer le taux dans le nom"
- back_to_tax_rates_list: "Retour à la liste des taux de taxe"
+ back_to_tax_rates_list: "Revenir à la liste des taux de taxe"
tax_settings: "Paramètres taxe"
zones: "Zones"
new_zone: "Nouvelle zone"
@@ -3928,14 +3952,12 @@ fr_CA:
iso_name: "Noms ISO"
states_required: "États/Départements requis"
editing_country: "Pays en cours de mise à jour"
- back_to_countries_list: "Retour à la liste des pays"
+ back_to_countries_list: "Revenir à la liste des pays"
states: "États/Départements requis"
abbreviation: "Code"
new_state: "Nouveau Région:"
payment_methods: "Méthodes de paiement"
- taxonomies: "Taxonomies"
- new_taxonomy: "Nouvelle taxonomie"
- back_to_taxonomies_list: "Retour à la liste des taxonomies"
+ taxons: "Catégorie Produit"
shipping_methods: "Méthodes de livraison"
shipping_method: "Option d'expédition"
shipment: "Livraison"
@@ -4308,6 +4330,8 @@ fr_CA:
new_product: "Nouveau Produit"
supplier: "Fournisseur"
supplier_select_placeholder: "Sélectionner un producteur"
+ search_for_suppliers: "Chercher des fournisseurs"
+ search_for_units: "Chercher des unités"
product_name: "Nom du Produit"
units: "Unité de mesure"
value: "Nb unités"
@@ -4342,6 +4366,7 @@ fr_CA:
product_name: Nom du Produit
primary_taxon_form:
product_category: Catégorie Produit
+ search_for_categories: "Rechercher des catégories"
group_buy_form:
group_buy: "Achat groupé ?"
bulk_unit_size: Quantité totale du lot
@@ -4419,9 +4444,20 @@ fr_CA:
total: "Total"
billing_address_name: "Nom"
taxons:
+ back_to_list: "Revenir à la liste des catégories de produits"
+ index:
+ title: "Catégorie Produit"
+ new_taxon: 'Nouvelle catégorie de produit'
+ new:
+ title: "Nouvelle catégorie de produit"
+ edit:
+ title: "Editer la catégorie de produit"
+ destroy:
+ delete_taxon:
+ success: "Catégorie de produit supprimée"
+ error: "Impossible de supprimer la catégorie de produit car des produits sont liés à cette catégorie."
form:
name: Nom
- permalink: Nom pour URL (sans espace)
meta_title: Méta titre
meta_description: Méta description
meta_keywords: Méta mots clés
@@ -4664,7 +4700,6 @@ fr_CA:
key_cleared: "Clé supprimée"
shipment:
cannot_ready: "La livraison ne peut pas être préparée."
- invalid_taxonomy_id: "L'identifiant de la catégorie n'est pas valide."
toggle_api_key_view: "Montrer la clé API pour cet utilisateur"
activerecord:
models:
diff --git a/config/locales/fr_CH.yml b/config/locales/fr_CH.yml
index 3526797864..99498246ab 100644
--- a/config/locales/fr_CH.yml
+++ b/config/locales/fr_CH.yml
@@ -68,7 +68,6 @@ fr_CH:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "doit être vide car utilise les informations de stock du producteur"
- on_demand_but_count_on_hand_set: "doit être vide si \"à volonté\""
limited_stock_but_no_count_on_hand: "doit être spécifié car pas \"à volonté\""
messages:
blank: "Champ obligatoire"
@@ -471,6 +470,8 @@ fr_CH:
remove: Supprimer
image:
edit: Modifier
+ product_preview:
+ shop_tab: Faire mes courses
adjustments:
skipped_changing_canceled_order: "Vous ne pouvez pas modifier une commande annulée."
begins_at: Commence
@@ -669,7 +670,6 @@ fr_CH:
variants:
infinity: "Infini"
to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main."
- back_to_products_list: "Retour à la liste produits"
editing_product: "Modifier le produit"
tabs:
product_details: "Détails"
@@ -1157,10 +1157,8 @@ fr_CH:
contact_name: Nom du contact principal
edit:
editing: 'Configuration:'
- back_link: Revenir à la liste des entreprises
new:
title: Nouvelle entreprise
- back_link: Revenir à la liste des entreprises
welcome:
welcome_title: Bienvenue sur Open Food Suisse !
welcome_text: 'Vous avez créé avec succès '
@@ -1197,6 +1195,8 @@ fr_CH:
choose_products_from: "Choisir produits depuis :"
re_notify_producers: Notifier les producteurs
notify_producers_tip: Cette action va envoyer un mail à tous les producteurs avec le contenu du cycle de vente.
+ date_time_warning_modal_content:
+ cancel: 'Annuler'
incoming:
incoming: "Produits entrants (pouvant être mis en vente par les boutiques du cycle de vente)"
supplier: "Fournisseur"
@@ -2560,7 +2560,6 @@ fr_CH:
spree_admin_single_enterprise_hint: "Astuce: Pour permettre aux gens de vous trouver, activez votre visibilité "
spree_admin_eg_pickup_from_school: "ex : \"Retrait des produits à l'Ecole Marimati / Au Café du coin / chez Babette / ...\""
spree_admin_eg_collect_your_order: "ex : \"Veuillez récupérer votre commande au 34 rue Victor Hugo, 75018 Paris\""
- spree_classification_primary_taxon_error: "La catégorie %{taxon} est utilisée par %{product} et ne peut être supprimée"
spree_order_availability_error: "Le distributeur ne peut fournir les produits de votre panier pour ce cycle de vente."
spree_order_populator_error: "Le distributeur ne peut fournir tous les produits de votre panier pour ce cycle de vente. Merci de choisir un autre distributeur ou un autre cycle de vente."
spree_order_cycle_error: "Veuillez sélectionner une option pour cette commande."
@@ -3214,6 +3213,8 @@ fr_CH:
Cette action remettra tous les niveaux de stock à zero pour cette
entreprise pour les produits non présents dans ce fichier.
order_cycles:
+ unsaved_changes: "Des modifications n'ont pas été sauvegardées"
+ bulk_save_error: "Oups ! Nous n'avons pas réussi à sauvegarder vos modification :-("
create_failure: "La création du cycle de vente a échoué"
update_success: 'Votre cycle de vente a été mis à jour.'
update_failure: "La mise à jour du cycle de vente à échoué"
@@ -3452,7 +3453,6 @@ fr_CH:
more: "Plus"
new_adjustment: "Nouvel ajustement"
new_tax_category: "Nouvelle catégorie de taxe"
- new_taxon: "Nouvelle taxonomie"
new_user: "Nouvel utilisateur"
no_pending_payments: "Aucun paiement en attente."
remove: "Supprimer"
@@ -3469,8 +3469,6 @@ fr_CH:
UPS Ground: "UPS Ground"
start_date: "Date de début"
successfully_removed: "Supprimé avec succès"
- taxonomy_edit: "Modifier la taxonomie"
- tree: "Arbre"
updating: "Mettre à jour"
your_order_is_empty_add_product: "Votre commande est vide, veuillez ajouter des produits"
add_product: "Ajouter un produit"
@@ -3565,7 +3563,6 @@ fr_CH:
tax_rate_amount_explanation: "Les taux de taxe sont présentés en nombres décimaux pour faciliter les calculs (ex : si le taux est 5,5% saisissez 0.055)"
included_in_price: "Inclus dans le prix"
show_rate_in_label: "Montrer le taux dans le nom"
- back_to_tax_rates_list: "Retour à la liste des taux de taxe"
tax_settings: "Paramètres TVA"
zones: "Zones"
new_zone: "Nouvelle zone"
@@ -3578,14 +3575,11 @@ fr_CH:
iso_name: "Noms ISO"
states_required: "États/Départements requis"
editing_country: "Pays en cours de mise à jour"
- back_to_countries_list: "Retour à la liste des pays"
states: "Départements"
abbreviation: "Code"
new_state: "Nouveau département"
payment_methods: "Méthodes de paiement"
- taxonomies: "Taxonomies"
- new_taxonomy: "Nouvelle taxonomie"
- back_to_taxonomies_list: "Retour à la liste des taxonomies"
+ taxons: "Catégorie Produit"
shipping_methods: "Méthodes de livraison"
shipping_method: "Option d'expédition"
shipment: "Livraison"
@@ -3739,7 +3733,6 @@ fr_CH:
continue: "Suivant"
new:
new_return_authorization: "Nouvelle autorisation de retour"
- back_to_return_authorizations_list: "Revenir à la liste des autorisations"
continue: "Suivant"
edit:
receive: "reçoit"
@@ -4030,9 +4023,10 @@ fr_CH:
total: "Total"
billing_address_name: "Produit/Variante"
taxons:
+ index:
+ title: "Catégorie Produit"
form:
name: Produit/Variante
- permalink: Permalien
description: Description
general_settings:
edit:
@@ -4253,7 +4247,6 @@ fr_CH:
key_cleared: "Clé supprimée"
shipment:
cannot_ready: "La livraison ne peut pas être préparée."
- invalid_taxonomy_id: "L'identifiant de la catégorie n'est pas valide."
activerecord:
models:
spree/payment:
diff --git a/config/locales/fr_CM.yml b/config/locales/fr_CM.yml
index 0a0ff82302..471eae5da6 100644
--- a/config/locales/fr_CM.yml
+++ b/config/locales/fr_CM.yml
@@ -68,7 +68,6 @@ fr_CM:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "doit être vide car utilise les informations de stock du producteur"
- on_demand_but_count_on_hand_set: "doit être vide si \"à volonté\""
limited_stock_but_no_count_on_hand: "doit être spécifié car pas \"à volonté\""
messages:
blank: "Champ obligatoire"
@@ -408,6 +407,8 @@ fr_CM:
remove: Supprimer
image:
edit: Modifier
+ product_preview:
+ shop_tab: Faire mes courses
adjustments:
skipped_changing_canceled_order: "Vous ne pouvez pas modifier une commande annulée."
begins_at: Commence
@@ -606,7 +607,6 @@ fr_CM:
variants:
infinity: "Infini"
to_order_tip: "Les articles fabriqués sur commande n'ont pas un niveau de stock défini, comme des pains faits à la main."
- back_to_products_list: "Retour à la liste produits"
editing_product: "Modifier le produit"
tabs:
product_details: "Détails"
@@ -1081,10 +1081,8 @@ fr_CM:
contact_name: Nom du contact principal
edit:
editing: 'Configuration:'
- back_link: Revenir à la liste des entreprises
new:
title: Nouvelle entreprise
- back_link: Revenir à la liste des entreprises
welcome:
welcome_title: Bienvenue sur CoopCircuits !
welcome_text: 'Vous avez créé avec succès '
@@ -1121,6 +1119,8 @@ fr_CM:
choose_products_from: "Choisir produits depuis :"
re_notify_producers: Notifier les producteurs
notify_producers_tip: Cette action va envoyer un mail à tous les producteurs avec le contenu du cycle de vente.
+ date_time_warning_modal_content:
+ cancel: 'Annuler'
incoming:
incoming: "Produits entrants (pouvant être mis en vente par les boutiques du cycle de vente)"
supplier: "Fournisseur"
@@ -2469,7 +2469,6 @@ fr_CM:
spree_admin_single_enterprise_hint: "Astuce: Pour permettre aux gens de vous trouver, activez votre visibilité "
spree_admin_eg_pickup_from_school: "ex : \"Retrait des produits à l'Ecole Marimati / Au Café du coin / chez Babette / ...\""
spree_admin_eg_collect_your_order: "ex : \"Veuillez récupérer votre commande au 34 rue Victor Hugo, 75018 Paris\""
- spree_classification_primary_taxon_error: "La catégorie %{taxon}est utilisée par %{product} et ne peut être supprimée"
spree_order_availability_error: "Le distributeur ne peut fournir les produits de votre panier pour ce cycle de vente."
spree_order_populator_error: "Le distributeur ne peut fournir tous les produits de votre panier pour ce cycle de vente. Merci de choisir un autre distributeur ou un autre cycle de vente."
spree_order_cycle_error: "Veuillez sélectionner une option pour cette commande."
@@ -3108,6 +3107,8 @@ fr_CM:
Cette action remettra tous les niveaux de stock à zero pour cette
entreprise pour les produits non présents dans ce fichier.
order_cycles:
+ unsaved_changes: "Des modifications n'ont pas été sauvegardées"
+ bulk_save_error: "Oups ! Nous n'avons pas réussi à sauvegarder vos modification :-("
create_failure: "La création du cycle de vente a échoué"
update_success: 'Votre cycle de vente a été mis à jour.'
update_failure: "La mise à jour du cycle de vente à échoué"
@@ -3346,7 +3347,6 @@ fr_CM:
more: "Plus"
new_adjustment: "Nouvel ajustement"
new_tax_category: "Nouvelle catégorie de taxe"
- new_taxon: "Nouvelle taxonomie"
new_user: "Nouvel utilisateur"
no_pending_payments: "Aucun paiement en attente."
remove: "Supprimer"
@@ -3363,8 +3363,6 @@ fr_CM:
UPS Ground: "UPS Ground"
start_date: "Date de début"
successfully_removed: "Supprimé avec succès"
- taxonomy_edit: "Modifier la taxonomie"
- tree: "Arbre"
updating: "Mettre à jour"
your_order_is_empty_add_product: "Votre commande est vide, veuillez ajouter des produits"
add_product: "Ajouter un produit"
@@ -3459,7 +3457,6 @@ fr_CM:
tax_rate_amount_explanation: "Les taux de taxe sont présentés en nombres décimaux pour faciliter les calculs (ex : si le taux est 5,5% saisissez 0.055)"
included_in_price: "Inclus dans le prix"
show_rate_in_label: "Montrer le taux dans le nom"
- back_to_tax_rates_list: "Retour à la liste des taux de taxe"
tax_settings: "Paramètres TVA"
zones: "Zones"
new_zone: "Nouvelle zone"
@@ -3472,14 +3469,11 @@ fr_CM:
iso_name: "Noms ISO"
states_required: "États/Départements requis"
editing_country: "Pays en cours de mise à jour"
- back_to_countries_list: "Retour à la liste des pays"
states: "Départements"
abbreviation: "Code"
new_state: "Nouveau département"
payment_methods: "Méthodes de paiement"
- taxonomies: "Taxonomies"
- new_taxonomy: "Nouvelle taxonomie"
- back_to_taxonomies_list: "Retour à la liste des taxonomies"
+ taxons: "Catégorie Produit"
shipping_methods: "Méthodes de livraison"
shipping_method: "Option d'expédition"
shipment: "Livraison"
@@ -3633,7 +3627,6 @@ fr_CM:
continue: "Suivant"
new:
new_return_authorization: "Nouvelle autorisation de retour"
- back_to_return_authorizations_list: "Revenir à la liste des autorisations"
continue: "Suivant"
edit:
receive: "reçoit"
@@ -3924,9 +3917,10 @@ fr_CM:
total: "Total"
billing_address_name: "Produit/Variante"
taxons:
+ index:
+ title: "Catégorie Produit"
form:
name: Produit/Variante
- permalink: Permalien
description: Description
general_settings:
edit:
@@ -4147,7 +4141,6 @@ fr_CM:
key_cleared: "Clé supprimée"
shipment:
cannot_ready: "La livraison ne peut pas être préparée."
- invalid_taxonomy_id: "L'identifiant de la catégorie n'est pas valide."
activerecord:
models:
spree/payment:
diff --git a/config/locales/hi.yml b/config/locales/hi.yml
index cf469138a5..788d44d392 100644
--- a/config/locales/hi.yml
+++ b/config/locales/hi.yml
@@ -81,8 +81,6 @@ hi:
white_label_logo_link: "शॉपफ्रन्ट में इस्तेमाल किए गए लोगो के लिए लिंक"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "टैक्स की श्रेणी को इन्हेरिट करने के लिए प्रति-आइटम कॅल्क्युलेटर की आवश्यकता है।"
spree/user:
attributes:
email:
@@ -102,7 +100,6 @@ hi:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "उत्पादक स्टॉक सेटिंग्स का उपयोग करने के कारण खाली होना ही चाहिए"
- on_demand_but_count_on_hand_set: "यदि मांग हो तो खाली होना ही चाहिए"
limited_stock_but_no_count_on_hand: "सीमित स्टॉक को मजबूर करने के कारण निर्दिष्ट किया जाना ही चाहिए"
messages:
confirmation: "%{attribute} से मेल नहीं खाता"
@@ -541,6 +538,8 @@ hi:
remove: मिटाएँ
image:
edit: एडिट करें
+ product_preview:
+ shop_tab: शॉप
adjustments:
skipped_changing_canceled_order: "आप रद्द किए गए ऑर्डर को बदल नहीं सकते।"
begins_at: को शुरू होता है
@@ -744,7 +743,6 @@ hi:
variants:
infinity: "इन्फिनिटी"
to_order_tip: "ऑर्डर करने के लिए बनाई गई वस्तुओं का एक निर्धारित स्टॉक स्तर नहीं होता है, जैसे कि ऑर्डर करने के लिए ताजा बनाई गई ब्रेड की रोटियां।"
- back_to_products_list: "उत्पादों की सूची पर वापस जाएं"
editing_product: "उत्पाद की एडिटिंग हो रही है"
tabs:
product_details: "उत्पाद का विवरण"
@@ -769,7 +767,6 @@ hi:
search: सर्च
sort:
pagination:
- total_html: "%{total} उत्पाद आपके सर्च क्राइटेरिया के लिए मिले। %{from} से %{to} दिखा रहा है।"
per_page:
show: दिखाएं
per_page: "%{num} प्रति पेज"
@@ -1288,10 +1285,8 @@ hi:
contact_name: संपर्क का नाम
edit:
editing: 'सेटिंग्स:'
- back_link: एंटरप्राइज़ सूची पर वापस जाएं
new:
title: न्यू एंटरप्राइज़
- back_link: एंटरप्राइज़ सूची पर वापस जाएं
welcome:
welcome_title: Open Food Network में आपका स्वागत है!
welcome_text: आपने सफलतापूर्वक एक बनाया है
@@ -1328,6 +1323,8 @@ hi:
choose_products_from: "इनमें से उत्पाद चुनें:"
re_notify_producers: उत्पादकों को फिर से नोटिफाई करें
notify_producers_tip: यह प्रत्येक उत्पादक को उनके ऑर्डर्स की सूची के साथ एक ईमेल भेजेगा।
+ date_time_warning_modal_content:
+ cancel: 'रद्द करें'
incoming:
incoming: "इनकमिंग"
supplier: "आपूर्तिकर्ता"
@@ -2771,7 +2768,6 @@ hi:
spree_admin_single_enterprise_hint: "संकेत: लोगों को आपको ढूंढने की अनुमति देने के लिए, नीचे से अपनी दृश्यता चालू करें"
spree_admin_eg_pickup_from_school: "उदाहरण 'प्राइमरी स्कूल से पिक-अप'"
spree_admin_eg_collect_your_order: "उदाहरण 'कृपया 123 इमेजिनरी सेंट, नॉर्थकोट, 3070 से अपना ऑर्डर एकत्र करें'"
- spree_classification_primary_taxon_error: "टैक्सोन %{taxon} %{product} का प्राथमिक टैक्सोन है और इसे हटाया नहीं जा सकता"
spree_order_availability_error: "आपके कार्ट में वितरक या ऑर्डर साइकिल उत्पादों की आपूर्ति नहीं कर सकता है"
spree_order_populator_error: "वह वितरक या ऑर्डर साइकिल आपके कार्ट में सभी उत्पादों की आपूर्ति नहीं कर सकता है। कृपया कोई दूसरा चुनें।"
spree_order_cycle_error: "कृपया इस ऑर्डर के लिए ऑर्डर साइकल चुनें।"
@@ -3434,6 +3430,8 @@ hi:
यह इस एंटरप्राइज़ के लिए उन सभी उत्पादों पर स्टॉक स्तर शून्य पर सेट कर देगा
जो अपलोड की गई फ़ाइल में मौजूद नहीं हैं।
order_cycles:
+ unsaved_changes: "आपके पास बिना सेव किए गए परिवर्तन हैं"
+ bulk_save_error: "अरे नहीं! मैं आपके परिवर्तनों को सेव करने में असमर्थ था।"
create_failure: "ऑर्डर साइकल बनाने में विफल हुआ"
update_success: 'आपका ऑर्डर साइकल अपडेट कर दिया गया है।'
update_failure: "ऑर्डर साइकल अपडेट करने में विफल हुआ"
@@ -3656,7 +3654,6 @@ hi:
more: "और ज्यादा"
new_adjustment: "नया एडजस्टमेंट"
new_tax_category: "नई टैक्स श्रेणी"
- new_taxon: "नया टैक्सोन"
new_user: "नया यूज़र"
no_pending_payments: "कोई पेंडिंग भुगतान नहीं"
remove: "मिटाएँ"
@@ -3675,8 +3672,6 @@ hi:
delivery: "हस्ताक्षरित, सीलबंद, डिलीवर किया गया"
start_date: "शुरू होने की तिथि"
successfully_removed: "सफलतापूर्वक हटाया गया"
- taxonomy_edit: "टैक्सोनॉमी एडिट करें"
- tree: "ट्री"
updating: "अपडेट किया जा रहा है"
your_order_is_empty_add_product: "आपका ऑर्डर खाली है, कृपया ऊपर दिए गए उत्पाद को सर्च करें और जोड़ें"
add_product: "उत्पाद जोड़ें"
@@ -3773,7 +3768,6 @@ hi:
tax_rate_amount_explanation: "कैलकुलेशन में सहायता के लिए टैक्स दरें एक दशमलव राशि हैं, (यानी यदि टैक्स की दर 5% है तो 0.05 एंटर करें)"
included_in_price: "कीमत में शामिल"
show_rate_in_label: "लेबल में रेट दिखाएं"
- back_to_tax_rates_list: "टैक्स दरों की सूची पर वापस जाएं"
tax_settings: "टैक्स सेटिंग्स"
zones: "ज़ोन"
new_zone: "न्यू ज़ोन"
@@ -3786,14 +3780,11 @@ hi:
iso_name: "ISO का नाम"
states_required: "आवश्यक राज्य"
editing_country: "एडिटिंग देश"
- back_to_countries_list: "देशों की सूची पर वापस जाएं"
states: "राज्य"
abbreviation: "संक्षेपण"
new_state: "नया राज्य"
payment_methods: "भुगतान की विधियाँ"
- taxonomies: "टैक्सोनॉमीज़"
- new_taxonomy: "न्यू टैक्सोनॉमी"
- back_to_taxonomies_list: "टैक्सोनॉमीज़ सूची पर वापस जाएं"
+ taxons: "उत्पाद श्रेणियां"
shipping_methods: "शिपिंग की विधियाँ"
shipping_method: "शिपिंग की विधि"
shipment: "शिपमेंट"
@@ -3951,7 +3942,6 @@ hi:
continue: "जारी रखें"
new:
new_return_authorization: "नया रिटर्न प्राधिकरण"
- back_to_return_authorizations_list: "रिटर्न प्राधिकरण सूची पर वापस जाएं"
continue: "जारी रखें"
edit:
receive: "प्राप्त करें"
@@ -4266,9 +4256,10 @@ hi:
total: "कुल"
billing_address_name: "नाम"
taxons:
+ index:
+ title: "उत्पाद श्रेणियां"
form:
name: नाम
- permalink: पर्मलिंक
description: विवरण
general_settings:
edit:
@@ -4506,7 +4497,6 @@ hi:
key_cleared: "कुंजी साफ़ हो गई"
shipment:
cannot_ready: "शिपमेंट तैयार नहीं कर सकते।"
- invalid_taxonomy_id: "अमान्य टैक्सोनॉमी id।"
toggle_api_key_view: "यूज़र्स के लिए API कुंजी दृश्य दिखाएं"
activerecord:
models:
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index eb9338a8be..48a5e7dba9 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -81,8 +81,6 @@ hu:
white_label_logo_link: "A főoldalon használt logo linkje"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Az adókategória örökléséhez tételenkénti kalkulátor szükséges."
spree/image:
attributes:
attachment:
@@ -99,8 +97,6 @@ hu:
attributes:
base:
card_expired: "lejárt"
- spree/product:
- must_exist: 'léteznie kell'
order_cycle:
attributes:
orders_close_at:
@@ -108,7 +104,6 @@ hu:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "üresnek kell lennie, mert a termelői készlet beállításait használja"
- on_demand_but_count_on_hand_set: "igény esetén üresnek kell lennie"
limited_stock_but_no_count_on_hand: "meg kell adni, mert korlátozott a készlet"
messages:
confirmation: "nem egyezik %{attribute}"
@@ -347,7 +342,7 @@ hu:
link_label: "%{name}"
shipment_mailer:
shipped_email:
- dear_customer: "Kedves Ügyfelünk,"
+ dear_customer: "Kedves Felhasználónk,"
instructions: "Megrendelésed kiszállították"
shipment_summary: "Szállítási összefoglaló"
subject: "Szállítási értesítés"
@@ -559,6 +554,8 @@ hu:
remove: Eltávolítás
image:
edit: Szerkesztés
+ product_preview:
+ shop_tab: Átvételi pont
adjustments:
skipped_changing_canceled_order: "A törölt rendelést nem módosíthatod."
begins_at: 'Kezdete:'
@@ -588,7 +585,7 @@ hu:
schedule: Menetrend
shipping: Szállítás
shipping_method: Szállítási Mód
- shop: Átadási pont
+ shop: Átvételi pont
sku: SKU
status_state: Ország
tags: Címkék
@@ -774,7 +771,6 @@ hu:
variants:
infinity: "Végtelen"
to_order_tip: "A megrendelésre készült termékeknek nincs meghatározott készletszintjük, például a rendelésre frissen készült kenyérnek."
- back_to_products_list: "Vissza a termékek listájához"
editing_product: "Termék szerkesztése"
tabs:
product_details: "Termék leírás"
@@ -814,7 +810,6 @@ hu:
search: Keresés
sort:
pagination:
- total_html: "%{total} terméket találtunk a keresési feltételek alapján. %{from}-től %{to}-ig mutat."
per_page:
show: Mutasd
per_page: "%{num}per oldal"
@@ -885,7 +880,7 @@ hu:
spreadsheet: Táblázat
choose_import_type: Válaszd ki az importálás típusát
import_into: Importálás típusa
- product_list: Termék
+ product_list: Terméklista
inventories: Készletek
import: Importálás
upload: Feltöltés
@@ -996,7 +991,7 @@ hu:
no_matching_new_products: Egyetlen új termék sem felel meg a keresési feltételeknek
inventory_powertip: Ez a termékkészleted. Termékek hozzáadásához a válaszd az "Új Termék" lehetőséget a legördülő menüből..
hidden_powertip: Ezeket a termékeket elrejtetted a készletedből, és nem lesz elérhető az oldalon. A "Hozzáadás" gombra kattintva hozzáadhatsz egy terméket a készletedhez.
- new_powertip: Ezeket a termékeket hozzáadhatja a készletéhez. Kattintson a 'Hozzáadás' gombra, ha hozzá szeretne adni egy terméket a készletéhez, vagy a 'Elrejtés' gombra, ha el szeretné rejteni a terméket. Később bármikor meggondolhatja magát!
+ new_powertip: Ezeket a termékeket hozzáadhatod a készletedhez. Kattints a 'Hozzáadás' gombra, ha hozzá szeretnél adni egy terméket a készletéhez, vagy a 'Elrejtés' gombra, ha el szeretnéd rejteni a terméket. Később bármikor meggondolhatod magad!
controls:
back_to_my_inventory: Vissza a leltárhoz
orders:
@@ -1380,10 +1375,8 @@ hu:
contact_name: Kapcsolattartó neve
edit:
editing: 'Beállítások:'
- back_link: Vissza a vállalkozások listájához
new:
title: Új Vállalkozás
- back_link: Vissza a vállalkozások listájához
welcome:
welcome_title: Üdvözölünk az Open Food Network-ben!
welcome_text: Sikeresen létrehoztad a
@@ -1420,6 +1413,10 @@ hu:
choose_products_from: "Válasszon termékeket a következők közül:"
re_notify_producers: Értesítse újra a termelőket
notify_producers_tip: Ez minden termelőnak e-mailt küld a rendeléseik listájával.
+ date_time_warning_modal_content:
+ title: 'Ebben a rendelési ciklusban már vannak rendelések.'
+ content: 'Ha új rendelési ciklust szeretnél létrehozni, ajánlott először megduplázni a rendelési ciklust, majd módosítani a dátumokat.'
+ cancel: 'Törlés'
incoming:
incoming: "Beérkező"
supplier: "Beszállító"
@@ -1547,7 +1544,7 @@ hu:
resume:
could_not_resume_the_order: Nem sikerült folytatni a rendelést
select2:
- minimal_search_length: Kérlek írj be 1%{count} vagy több karaktert
+ minimal_search_length: Kérlek írj be %{count} vagy több karaktert
searching: Keresés...
no_matches: Nincs találat
shared:
@@ -1664,7 +1661,7 @@ hu:
enterprise_fee_summary:
name: "Vállalkozási díjak összefoglalója"
description: "Összefoglaló a beszedett vállalkozási díjakról"
- enterprise_fees_with_tax_report_by_order: "Vállalkozási díjak adójelentéssel megrendelés alapján"
+ enterprise_fees_with_tax_report_by_order: "Vállalkozási díjak adójelentéssei megrendelés alapján"
enterprise_fees_with_tax_report_by_producer: "Vállalkozási díjak termelői adóbevallással"
errors:
no_report_type: "Adja meg a jelentés típusát"
@@ -2002,9 +1999,9 @@ hu:
customer_required:
login: "Belépés"
contact: "kapcsolatba lépni"
- require_customer_login: "Csak jóváhagyott vásárlók férhetnek hozzá ehhez az üzlethez."
- require_login_link_html: "Ha már jóváhagyott ügyfél, %{login} a folytatáshoz."
- require_login_2_html: "Itt szeretne vásárolni? Kérjük, %{contact} %{enterprise} és érdeklődjön a csatlakozásról."
+ require_customer_login: "Csak regisztrált és jóváhagyott vásárlók férhetnek hozzá az átadópont kínálatához."
+ require_login_link_html: "Ha már regisztrált felhasználó vagy, a folytatáshoz be kell lépned: %{login}"
+ require_login_2_html: "Ezen az átadóponton szeretnél vásárolni? %{enterprise}-el itt tudsz %{contact}, és érdeklődni a csatlakozásról."
require_customer_html: "Ha itt szeretne vásárolni, kérjük, %{contact} %{enterprise} érdeklődjön a csatlakozásról."
select_oc:
select_oc_html: "Kérjük, válaszd ki, hogy mikorra szeretnéd megrendelni, hogy megtudd, milyen termékek állnak rendelkezésre."
@@ -2028,7 +2025,7 @@ hu:
invoice_column_tax_rate: "Adókulcs"
invoice_tax_total: "ÁFA összesen:"
invoice_cancel_and_replace_invoice: "érvényteleníti és cseréli a számlát"
- tax_invoice: "Rendelés sorszáma"
+ tax_invoice: "VEVŐI LAP"
tax_total: "Teljes adó (%{rate}):"
invoice_shipping_category_delivery: "Szállítás"
invoice_shipping_category_pickup: "Átvétel"
@@ -2037,7 +2034,7 @@ hu:
total_all_tax: "Összes adó:"
abn: "Adószám:"
acn: "Közösségi Adószám (EU):"
- invoice_issued_on: "Kiállított számla:"
+ invoice_issued_on: "Kiállítás dátuma:"
order_number: "Rendelés sorszáma:"
date_of_transaction: "A tranzakció dátuma:"
menu_1_title: "Átvételi pontok"
@@ -2261,11 +2258,11 @@ hu:
products_at: "itt: %{distributor}"
products_elsewhere: "Máshol talált termékek"
email_confirmed: "Köszönjük, hogy megerősítette e-mail címét."
- email_confirmation_activate_account: "Mielőtt aktiválhatnánk új fiókját, meg kell erősíteni az e-mail címét."
+ email_confirmation_activate_account: "Mielőtt aktiválhatnánk az új fiókodat, meg kell erősíteni az e-mail címed."
email_confirmation_greeting: "Kedves %{contact}!"
email_confirmation_profile_created: "A %{name} profilod sikeresen létrejött! Profilod aktiválásához meg kell erősíteni ezt az e-mail címet."
- email_confirmation_click_link: "Kérjük, kattintson az alábbi linkre az e-mail-cím megerősítéséhez és a profil beállításának folytatásához."
- email_confirmation_link_label: "Erősítse meg ezt az e-mail címet »"
+ email_confirmation_click_link: "Kérjük, kattints az alábbi linkre az e-mail-cím megerősítéséhez és a profil beállításának folytatásához."
+ email_confirmation_link_label: "E-mail cím megerősítése »"
email_confirmation_help_html: "Az e-mail-cím megerősítése után hozzáférhetsz a vállalkozás adminisztrációs fiókjához. Tekintsd meg a %{link} webhelyet, hogy többet megtudj %{sitename} szolgáltatásairól, és elkezdhesd használni profilod vagy online áruházad."
email_confirmation_notice_unexpected: "Azért kaptad ezt az üzenetet, mert regisztráltál a(z) %{sitename} webhelyen, vagy egy olyan személy, akit valószínűleg ismersz, meghívott. Ha nem érted, miért kaptad ezt az e-mailt, kérjük, írj a %{contact} címre."
email_social: "Lépj kapcsolatba velünk:"
@@ -2317,14 +2314,14 @@ hu:
email_shipping_collection_time: "Átvétel időpontja:"
email_shipping_collection_instructions: "Átvételi információk:"
email_special_instructions: "Megjegyzés:"
- email_signup_greeting: Helló!
- email_signup_welcome: "Üdvözlünk a %{sitename} oldalon!"
- email_signup_confirmed_email: "Köszönjük, hogy megerősítette e-mailjét."
- email_signup_shop_html: "Most már bejelentkezhet a %{link} címen."
+ email_signup_greeting: Üdv!
+ email_signup_welcome: "Köszöntünk az %{sitename} oldalon!"
+ email_signup_confirmed_email: "Köszönjük, hogy megerősítetted az e-mail címed."
+ email_signup_shop_html: "Most már bejelentkezhetsz a %{link} címen."
email_signup_text: "Köszönjük, hogy csatlakoztál a hálózathoz! "
email_signup_help_html: "Szívesen fogadunk minden kérdést és visszajelzést; ehhez bátran használd a Visszajelzés küldése gombot a weboldalon, vagy írhatsz nekünk egy e-mailt a következő címre: %{email}"
invite_email:
- greeting: "Helló!"
+ greeting: "Üdv!"
invited_to_manage: "Meghívást kaptál, hogy kezeld a(z) %{enterprise} %{instance} szolgáltatást."
confirm_your_email: "Egy megerősítő linket tartalmazó e-mailt kellett volna kapnia, vagy hamarosan kapni fog. Addig nem férhetsz hozzá %{enterprise} profiljához, amíg meg nem erősíted az e-mail címedet."
set_a_password: "Ezután a rendszer kéri, hogy állítson be egy jelszót, mielőtt felügyelheti a vállalkozásot."
@@ -2397,7 +2394,7 @@ hu:
products_updating_cart: "Kosár frissítése..."
products_cart_empty: "Kosár üres"
products_edit_cart: "Kosár szerkesztése"
- products_from: Elosztó
+ products_from: elosztó
products_change: "Nincs mentendő módosítás."
products_update_error: "A mentés a következő hibá(k) miatt nem sikerült:"
products_update_error_msg: "A mentés nem sikerült."
@@ -2477,7 +2474,7 @@ hu:
sell_headline: "Legyél Te is a hálózat tagja!"
sell_motivation: "Mutasd be termékeidet, tedd elérhetővé a fogyasztók számára."
sell_producers: "Termelők"
- sell_hubs: "Átvételi Pont"
+ sell_hubs: "Átvételi Pontok"
sell_groups: "Csoportok"
sell_producers_detail: "Őstermelő, kistermelő, családi gazdálkodó, vagy épp kisválllalkozás vagy? Hozz létre termelői profilt az OFN-en percek alatt. Bármikor frissítheted profilod egy online áruházra, és közvetlenül ajánlhatod termékeidet a fogyasztóknak."
sell_hubs_detail: "Bevásárlóközösséget indítanál? Vagy csak összefognál a termelőtársakkal és közösen szólítanátok meg a fogyasztókat? Hozz létre új profilt, vagy bármikor frissítheted a profilodat egy többtermelős átvételi pontra."
@@ -2538,7 +2535,7 @@ hu:
products_cart_distributor_is: "Megrendelésed szolgáltatója: %{name}."
products_distributor_error: "Kérjük, fejezd be a rendelésed a %{link} címen, mielőtt másik szolgáltatónál vásárolnál."
products_oc: "Rendelési ciklus a megrendeléshez:"
- products_oc_change: "Ha ezt a terméket a kosárba helyezi, a rendelési ciklusa a következőre módosul: %{name}."
+ products_oc_change: "Ha ezt a terméket a kosárba helyezed, a rendelési ciklus a következőre módosul: %{name}."
products_oc_is: "Rendelési ciklusod ehhez a rendeléshez: %{name}."
products_oc_error: "Kérjük, fejezd be rendelésed a %{link} webhelyről, mielőtt másik rendelési ciklusban vásárolnál."
products_oc_current: "aktuális rendelési ciklusod"
@@ -2592,7 +2589,7 @@ hu:
signup_email: "Email címed"
choose_password: "Adj meg egy jelszót"
confirm_password: "Jelszó megerősítése"
- action_signup: "Regisztrálj most"
+ action_signup: "Regisztrálok"
forgot_password: "Elfelejtett jelszó"
password_reset_sent: "Elküldtük a jelszó visszaállítására vonatkozó utasításokat tartalmazó e-mailt!"
reset_password: "Jelszó visszaállítása"
@@ -2607,7 +2604,7 @@ hu:
registration_enterprise_address: "Vállalkozási cím"
registration_contact_details: "Elsődleges elérhetőségek"
registration_logo: "A logó képe"
- registration_promo_image: "Fejléc a profilodhoz"
+ registration_promo_image: "Fejléckép a profilodhoz"
registration_about_us: "Bemutatkozó szöveg"
registration_outcome_headline: "Mit kapsz?"
registration_outcome1_html: "Profilod segít az embereknek megtalálni és kapcsolatba lépni Veled az Open Food Network hálózaton."
@@ -2879,7 +2876,6 @@ hu:
spree_admin_single_enterprise_hint: "Tipp: Ha szeretnéd, hogy mások megtaláljanak, kapcsold be a nyilvános beállítást:"
spree_admin_eg_pickup_from_school: "például. \"Átvétel az Általános iskolából\""
spree_admin_eg_collect_your_order: "például. \"Kérjük, vegye át rendelését a 123 Imaginary St, Northcote, 3070 címről\""
- spree_classification_primary_taxon_error: "A %{taxon} taxon a %{product} elsődleges taxonja, és nem törölhető"
spree_order_availability_error: "A forgalmazó vagy a rendelési ciklus nem tudja szállítani a kosárban lévő termékeket"
spree_order_populator_error: "Ez a forgalmazó vagy a rendelési ciklus nem tudja a kosárban lévő összes terméket szállítani. Kérjük, válasszon másikat."
spree_order_cycle_error: "Kérjük, válassz rendelési ciklust ehhez a rendeléshez."
@@ -3118,7 +3114,7 @@ hu:
report_header_total_taxable_admin: Összes adóköteles rendszergazdai korrekció (adóval együtt)
report_header_voucher_label: Kupon címke
report_header_voucher_amount: "Kuponösszeg (%{currency_symbol})"
- report_line_cost_of_produce: Termékek költsége, termelési költségek?
+ report_line_cost_of_produce: Termékek költsége, termelési költségek
report_line_line_items: tételsor
report_header_last_completed_order_date: Utolsó teljesített rendelés dátuma
report_xero_configuration: Xero konfiguráció
@@ -3269,7 +3265,7 @@ hu:
elrejtése) a megadott címkével rendelkező ügyfelek számára.
terms_and_conditions_info:
title: "Általános Szerződési Feltételek feltöltése"
- message_1: "Az Általános Szerződési Feltételek az Ön, az eladó és a vásárló közötti szerződés. Ha feltölt egy fájlt ide, a vásárlóknak el kell fogadniuk az Általános Szerződési Feltételeket a fizetés befejezéséhez. A vásárló számára ez egy jelölőnégyzetként jelenik meg a pénztárnál, amelyet be kell jelölnie a fizetés folytatásához. Javasoljuk, hogy a nemzeti jogszabályokkal összhangban töltse fel az Általános Szerződési Feltételeket."
+ message_1: "Az Általános Szerződési Feltételek az Ön, az eladó és a vásárló közötti szerződés. Ha feltöltesz egy fájlt ide, a vásárlóknak el kell fogadniuk az Általános Szerződési Feltételeket a fizetés befejezéséhez. A vásárló számára ez egy jelölőnégyzetként jelenik meg a pénztárnál, amelyet be kell jelölnie a fizetés folytatásához. Javasoljuk, hogy a nemzeti jogszabályokkal összhangban tölts fel Általános Szerződési Feltételeket."
message_2: "A vásárlóknak csak egyszer kell elfogadniuk az Általános Szerződési Feltételeket. Ha azonban megváltoztatja az Általános Szerződési Feltételeket, a vásárlóknak ismét el kell fogadniuk azokat, mielőtt fizetésre kerülne a rendelésük."
terms_and_conditions_warning:
title: "Általános Szerződési Feltételek feltöltése"
@@ -3399,7 +3395,7 @@ hu:
index:
per_page: "%{results} találat oldalanként"
view_file: "Fájl megtekintése"
- compiling_invoices: "Számlák összeállítása"
+ compiling_invoices: "Vevői lapok összeállítása"
bulk_invoice_created: "Tömeges számla létrehozva"
bulk_invoice_failed: "Nem sikerült létrehozni a tömeges számlát"
please_wait: "A modul bezárása előtt várja meg, amíg a PDF elkészül."
@@ -3469,7 +3465,7 @@ hu:
customers:
index:
add_customer: "Ügyfél hozzáadása"
- add_a_new_customer_for: "Új vásárló hozzáadása a %{shop_name}számára"
+ add_a_new_customer_for: "Új vásárló hozzáadása a %{shop_name}számára"
customer_placeholder: "ügyfél@example.org"
valid_email_error: "Kérjük valós e-mail címet adj meg"
subscriptions:
@@ -3547,6 +3543,8 @@ hu:
Ez nullára állítja a készletszintet a vállalkozás összes olyan termékénél,
amely nem szerepel a feltöltött fájlban.
order_cycles:
+ unsaved_changes: "Nem mentett módosításaid vannak"
+ bulk_save_error: "Hopsz! Nem tudtuk menteni a módosításokat."
create_failure: "Nem sikerült létrehozni a rendelési ciklust"
update_success: 'Megrendelési ciklusod frissült.'
update_failure: "Nem sikerült frissíteni a rendelési ciklust"
@@ -3565,7 +3563,7 @@ hu:
users:
order: "Rendelés"
registration:
- welcome_to_ofn: "Üdvözlünk az Open Food Hálózatában!"
+ welcome_to_ofn: "Köszöntünk az Open Food Hálózatában!"
signup_or_login: "Kezd a regisztrációval (vagy bejelentkezéssel)"
have_an_account: "Már van fiókod?"
action_login: "Jelentkezz be most."
@@ -3768,9 +3766,8 @@ hu:
gateway_config_unavailable: "Az átjáró konfigurációja nem érhető el"
gateway_error: "Fizetés meghiúsult"
more: "Több"
- new_adjustment: "Új beállítás"
+ new_adjustment: "Új kiigazítás"
new_tax_category: "Új adókategória"
- new_taxon: "Új taxon"
new_user: "Új felhasználó"
no_pending_payments: "Nincsenek függőben lévő kifizetések"
remove: "Eltávolítás"
@@ -3789,10 +3786,6 @@ hu:
delivery: "Aláírva, lepecsételve, kézbesítve"
start_date: "Kezdő dátum"
successfully_removed: "Sikeresen eltávolítva"
- taxonomy_edit: "Termékkategória szerkesztése"
- taxonomy_tree_error: "Hiba lépett fel a Kategória-fa frissítésében."
- taxonomy_tree_instruction: "Kattints a jobb gombbal egy elemre a hozzáadáshoz, átnevezéshez, eltávolításhoz vagy szerkesztéshez."
- tree: "Fa"
updating: "Frissítés"
your_order_is_empty_add_product: "Rendelésed üres, kérünk adj hozzá legalább egy terméket"
add_product: "Termék hozzáadása"
@@ -3890,7 +3883,6 @@ hu:
tax_rate_amount_explanation: "Az adókulcsok tizedesjegyek, amelyek segítik a számításokat (azaz ha az adókulcs 5%, akkor írj be 0,05-öt)"
included_in_price: "Az ár tartalmazza"
show_rate_in_label: "Mutassa az arányát a címkén"
- back_to_tax_rates_list: "Vissza az adókulcs-listához"
tax_settings: "Adóbeállítások"
zones: "Zónák"
new_zone: "Új zóna"
@@ -3903,14 +3895,11 @@ hu:
iso_name: "ISO név"
states_required: "Állam kötelező"
editing_country: "Ország szerkesztése"
- back_to_countries_list: "Vissza az országok listájához"
states: "Államok"
abbreviation: "Rövidítés"
new_state: "Új állam"
payment_methods: "Fizetési módok"
- taxonomies: "Taxonómiák"
- new_taxonomy: "Új termék kategória"
- back_to_taxonomies_list: "Vissza a taxonómiák listájához"
+ taxons: "Termékkategóriák"
shipping_methods: "Szállítási módok"
shipping_method: "Szállítási Mód"
shipment: "Szállítás"
@@ -4070,7 +4059,6 @@ hu:
continue: "Tovább"
new:
new_return_authorization: "Új visszaküldési engedély"
- back_to_return_authorizations_list: "Vissza a visszaküldési engedélyek listájához"
continue: "Tovább"
edit:
receive: "kap"
@@ -4135,7 +4123,7 @@ hu:
email: "Ügyfél e-mail"
invoice:
issued_on: "Kiadott"
- tax_invoice: "Rendelés sorszáma"
+ tax_invoice: "VEVŐI LAP"
code: "Kód"
from: "Küldő"
to: "Vevő"
@@ -4317,6 +4305,7 @@ hu:
product_name: Termék név
primary_taxon_form:
product_category: Termékkategória
+ search_for_categories: "Keresés termékkategóriára"
group_buy_form:
group_buy: "Csoportos vásárlás?"
bulk_unit_size: Tömeges mértékegység
@@ -4394,9 +4383,10 @@ hu:
total: "Összesen"
billing_address_name: "Név"
taxons:
+ index:
+ title: "Termékkategóriák"
form:
name: Név
- permalink: Permalink
meta_title: Meta Cím (SEO cím)
meta_description: Meta Leírás
meta_keywords: Meta Kulcsszavak
@@ -4470,7 +4460,7 @@ hu:
details: "Itt vannak a megrendelt termékek részletei:"
unpaid_order: "Megrendelésed nem lett kifizetve, így visszatérítés nem történt"
paid_order: "Megrendelésed fizetésre került, így %{distributor} visszatérítette a teljes összeget"
- credit_order: "Megrendelésed kifizették, számládon jóváhagyták."
+ credit_order: "Megrendelésed kifizetésre került, számládon jóváhagyták a tranzakciót."
subject: "Megrendelés törlése"
cancel_email_for_shop:
greeting: "Kedves %{name}!"
@@ -4570,7 +4560,7 @@ hu:
header: Esemény típusa
url:
header: Végpont URL
- create_placeholder: Adja meg a távoli webhook végpont URL-címét
+ create_placeholder: Add meg a távoli webhook végpont URL-címét
developer_settings:
title: Fejlesztői beállítások
form:
@@ -4582,14 +4572,14 @@ hu:
cards: Bankkártyák
transactions: Tranzakciók
settings: Fiók beállítások
- unconfirmed_email: "E-mail megerősítésre vár: %{unconfirmed_email}. Az Ön e-mail címe frissítésre kerül, amint az új e-mailt megerősítjük."
+ unconfirmed_email: "E-mail megerősítésre vár: %{unconfirmed_email}. E-mail címed frissítésre kerül, amint az új e-mailt megerősítjük."
orders:
open_orders: Rendelések megnyitása
past_orders: Korábbi megrendelések
transactions:
transaction_history: Tranzakciós előzmények
authorisation_required: Engedély szükséges
- authorise: Engedélyezze
+ authorise: Engedélyezd
open_orders:
order: Rendelés
shop: Átvételi Pont
@@ -4615,7 +4605,7 @@ hu:
delete?: Töröl?
cards:
authorised_shops: Engedélyezett átvételi pontok
- authorised_shops_agreement: Ez azon átvételi pontok listája, amelyek megterhelhetik alapértelmezett hitelkártyáját az esetleges előfizetéseiért (azaz ismétlődő rendeléseiért). Kártyája adatait biztonságban tartjuk, és nem osztjuk meg az üzlet tulajdonosaival. Mindig értesítést kap, amikor felszámítják. Ha bejelöli az üzlet jelölőnégyzetét, beleegyezel abba, hogy felhatalmazod az üzletet, hogy utasításokat küldjön a kártyáját kibocsátó pénzintézetnek a fizetések fogadására az adott üzlettel létrehozott előfizetés feltételei szerint.
+ authorised_shops_agreement: Ez azon átvételi pontok listája, amelyek megterhelhetik alapértelmezett hitelkártyád az esetleges előfizetési díjakkal (azaz ismétlődő rendeléseid összegével). Kártyád adatait biztonságban tartjuk, és nem osztjuk meg az adott termelő vagy átvételi pont kezelőivel. Mindig értesítést kapsz, amikor díj felszámítás történik. Ha bejelölöd az átvételi pont jelölőnégyzetét, beleegyezel abba, hogy felhatalmazod az átvételi pontot, hogy utasításokat küldjön a kártyád kibocsátó pénzintézetének a fizetések fogadására az adott átvételi ponttal létrehozott előfizetés feltételei szerint.
saved_cards_popover: Ez azon kártyák listája, amelyeket későbbi használatra ment el. A rendszer automatikusan kiválasztja az „alapértelmezett” kártyát a rendelés leadásakor, és ezt minden olyan üzlet megterhelheti, ahol ezt engedélyezted (lásd jobbra).
authorised_shops:
shop_name: "Átvételi pont neve"
@@ -4638,7 +4628,6 @@ hu:
key_cleared: "Kulcs törölve"
shipment:
cannot_ready: "Nem áll készen a szállításra."
- invalid_taxonomy_id: "Érvénytelen termékkategória azonosító."
toggle_api_key_view: "API-kulcs nézet megjelenítése a felhasználó számára"
activerecord:
models:
@@ -4698,5 +4687,5 @@ hu:
next: Következő
previous: Előző
invisible_captcha:
- sentence_for_humans: "Kérjük hagyja üresen"
+ sentence_for_humans: "Kérjük hagyd üresen"
timestamp_error_message: "Kérjük, próbáld meg 5 másodperc múlva."
diff --git a/config/locales/it.yml b/config/locales/it.yml
index 33c73cdd42..c06344ed23 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -84,7 +84,6 @@ it:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "deve restare vuoto perché si stanno utilizzando le impostazioni di magazzino del produttore"
- on_demand_but_count_on_hand_set: "deve restare vuoto se su richiesta"
limited_stock_but_no_count_on_hand: "deve essere specificato a causa di una disponibilità limitata"
messages:
blank: "non può essere lasciato vuoto"
@@ -433,7 +432,7 @@ it:
password_confirmation: 'Conferma Password '
reset_password_token: Token per il reset della password
expired: è scaduto, si prega di richiederne uno nuovo
- back_to_payments_list: "Torna alla Lista dei Pagamenti"
+ back_to_payments_list: "Torna Alla Lista Pagamenti"
maestro_or_solo_cards: "Carte Maestro/Solo"
backordered: "Ordini arretrati"
on_hand: "Disponibile"
@@ -504,6 +503,8 @@ it:
remove: Rimuovi
image:
edit: Modifica
+ product_preview:
+ shop_tab: Negozio
adjustments:
skipped_changing_canceled_order: "Non puoi modificare una richiesta annullata"
begins_at: Inizia a
@@ -707,7 +708,6 @@ it:
variants:
infinity: "Infinito"
to_order_tip: "Gli articoli messi in ordine non hanno un livello di stock impostato, come ad esempio il Pane fresco su ordinazione."
- back_to_products_list: "Indietro alla lista dei prodotti"
editing_product: "Modifica prodotto"
tabs:
product_details: "Dettagli Prodotto"
@@ -1202,10 +1202,8 @@ it:
contact_name: Nome contatto
edit:
editing: 'Impostazioni:'
- back_link: Indietro alla lista delle aziende
new:
title: Nuova Azienda
- back_link: Indietro alla lista delle aziende
welcome:
welcome_title: Benvenuto su Open Food Network!
welcome_text: Hai creato con successo una
@@ -1242,6 +1240,8 @@ it:
choose_products_from: "Scegli i prodotti da:"
re_notify_producers: Ri-notifica i produttori
notify_producers_tip: Sarà inviata una mail a ciascun produttore con la lista dei suoi ordini.
+ date_time_warning_modal_content:
+ cancel: 'Annulla'
incoming:
incoming: "In arrivo"
supplier: "Fornitore"
@@ -2631,7 +2631,6 @@ it:
spree_admin_single_enterprise_hint: "Suggerimento: Per permettere alle persone di trovarti, abilita la tua visibilità sotto"
spree_admin_eg_pickup_from_school: "es. \"Ritiro presso la Cooperativa\""
spree_admin_eg_collect_your_order: "es. \"Prego ritira il tuo ordine in via Roma 45\""
- spree_classification_primary_taxon_error: "La classificazione %{taxon} è la classificazione primaria di %{product} e non può essere cancellata"
spree_order_availability_error: "Il distributore o il ciclo di richiesta non possono rifornire i prodotti nel tuo carrello"
spree_order_populator_error: "Il distributore o il ciclo di richieste non hanno disponibilità di alcuni prodotti nel tuo carrello. Per favore scegline un altro."
spree_order_cycle_error: "Per favore seleziona un ciclo di richieste per questa gentile richiesta."
@@ -2946,7 +2945,7 @@ it:
order_cycles_no_permission_to_coordinate_error: "Nessuna delle tue aziende ha il permesso di coordinare un ciclo di richieste"
order_cycles_no_permission_to_create_error: "Non hai il permesso di creare un ciclo di richieste coordinato da questa azienda"
order_cycle_closed: "Il ciclo di richieste che hai selezionato è appena chiuso. Riprova per favore!"
- back_to_orders_list: "Indietro alla lista delle gentili richieste"
+ back_to_orders_list: "Torna alla lista delle richieste"
no_orders_found: "Nessuna gentile richiesta trovata"
order_information: "Informazioni Gentile Richiesta"
new_payment: "Nuovo pagamento"
@@ -3283,6 +3282,8 @@ it:
Questo imposterà il livello delle scorte a zero su tutti i prodotti per questa
impresa che non sono presenti nel file caricato.
order_cycles:
+ unsaved_changes: "Hai modifiche non salvate"
+ bulk_save_error: "Oh no! non siamo riusciti a salvare le tue modifiche"
create_failure: "Impossibile creare il ciclo dell'ordine"
update_success: 'Il tuo ciclo di richieste è stato aggiornato'
update_failure: "Impossibile aggiornare il ciclo dell'ordine"
@@ -3521,7 +3522,6 @@ it:
more: "Di più"
new_adjustment: "Nuovo aggiustamento"
new_tax_category: "Nuova Categoria imposta"
- new_taxon: "Nuova tassonomia"
new_user: "Nuovo utente"
no_pending_payments: "Nessun pagamento in sospeso"
remove: "Rimuovi"
@@ -3540,8 +3540,6 @@ it:
delivery: "Firmato, sigillato, consegnato"
start_date: "Data inizio"
successfully_removed: "Rimosso con successo"
- taxonomy_edit: "Modifica tassonomia"
- tree: "Schema"
updating: "In aggiornamento"
your_order_is_empty_add_product: "Il tuo ordine è vuoto, cerca e aggiungi un prodotto qui sopra"
add_product: "Aggiungi prodotto"
@@ -3637,7 +3635,6 @@ it:
tax_rate_amount_explanation: "Le tariffe sono un importo decimale da utilizzare nei calcoli (ad esempio, se l'aliquota fiscale è del 5%, inserire 0,05)"
included_in_price: "Incluso nel prezzo"
show_rate_in_label: "Mostra tariffa in etichetta"
- back_to_tax_rates_list: "Torna all'elenco delle tariffe"
tax_settings: "Impostazione contributi"
zones: "Zone"
new_zone: "Nuova zona"
@@ -3650,14 +3647,11 @@ it:
iso_name: "Nome ISO"
states_required: "Provincia richiesta"
editing_country: "Modifica Paese"
- back_to_countries_list: "Torna all'elenco dei Paesi"
states: "Stati"
abbreviation: "Abbreviazione"
new_state: "Nuovo Stato"
payment_methods: "Metodi di pagamento"
- taxonomies: "Tassonomie"
- new_taxonomy: "Nuova tassonomia"
- back_to_taxonomies_list: "Torna all'elenco delle tassonomie"
+ taxons: "Categorie Prodotti"
shipping_methods: "Metodi di spedizione"
shipping_method: "Metodo di spedizione"
shipment: "Spedizione"
@@ -3814,7 +3808,6 @@ it:
continue: "Continua"
new:
new_return_authorization: "Nuova autorizzazione resi"
- back_to_return_authorizations_list: "Torna alla lista di autorizzazioni resi"
continue: "Continua"
edit:
receive: "ricevi"
@@ -4119,9 +4112,10 @@ it:
total: "Totale"
billing_address_name: "Nome"
taxons:
+ index:
+ title: "Categorie Prodotti"
form:
name: Nome
- permalink: Permalink
description: Descrizione
general_settings:
edit:
@@ -4349,7 +4343,6 @@ it:
key_cleared: "Chiave cancellata"
shipment:
cannot_ready: "Impossibile spedizione immediata."
- invalid_taxonomy_id: "ID tassonomia non valido."
toggle_api_key_view: "Mostra la chiave API per l'utente"
activerecord:
models:
diff --git a/config/locales/it_CH.yml b/config/locales/it_CH.yml
index b3fb3fac14..d5a376509f 100644
--- a/config/locales/it_CH.yml
+++ b/config/locales/it_CH.yml
@@ -68,7 +68,6 @@ it_CH:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "deve restare vuoto perché si stanno utilizzando le impostazioni di magazzino del produttore"
- on_demand_but_count_on_hand_set: "deve restare vuoto se su richiesta"
limited_stock_but_no_count_on_hand: "deve essere specificato a causa di una disponibilità limitata"
messages:
blank: "non può essere lasciato vuoto"
@@ -382,7 +381,7 @@ it_CH:
password_confirmation: 'Conferma Password '
reset_password_token: Token per il reset della password
expired: è scaduto, si prega di richiederne uno nuovo
- back_to_payments_list: "Torna alla Lista dei Pagamenti"
+ back_to_payments_list: "Torna Alla Lista Pagamenti"
maestro_or_solo_cards: "Carte Maestro/Solo"
backordered: "Ordini arretrati"
on_hand: "Disponibile"
@@ -449,6 +448,8 @@ it_CH:
remove: Rimuovi
image:
edit: Modifica
+ product_preview:
+ shop_tab: Negozio
adjustments:
skipped_changing_canceled_order: "Non puoi modificare una richiesta annullata"
begins_at: Inizia a
@@ -647,7 +648,6 @@ it_CH:
variants:
infinity: "Infinito"
to_order_tip: "Gli articoli messi in ordine non hanno un livello di stock impostato, come ad esempio il Pane fresco su ordinazione."
- back_to_products_list: "Indietro alla lista dei prodotti"
editing_product: "Modifica prodotto"
tabs:
product_details: "Dettagli Prodotto"
@@ -1131,10 +1131,8 @@ it_CH:
contact_name: Nome contatto
edit:
editing: 'Impostazioni:'
- back_link: Indietro alla lista delle aziende
new:
title: Nuova Azienda
- back_link: Indietro alla lista delle aziende
welcome:
welcome_title: Benvenuto su Open Food Svizzera!
welcome_text: Hai creato con successo una
@@ -1171,6 +1169,8 @@ it_CH:
choose_products_from: "Scegli i prodotti da:"
re_notify_producers: Ri-notifica i produttori
notify_producers_tip: Sarà inviata una mail a ciascun produttore con la lista dei suoi ordini.
+ date_time_warning_modal_content:
+ cancel: 'Annulla'
incoming:
incoming: "In arrivo"
supplier: "Fornitore"
@@ -2524,7 +2524,6 @@ it_CH:
spree_admin_single_enterprise_hint: "Suggerimento: Per permettere alle persone di trovarti, abilita la tua visibilità sotto"
spree_admin_eg_pickup_from_school: "es. \"Ritiro presso la Cooperativa\""
spree_admin_eg_collect_your_order: "es. \"Prego ritira il tuo ordine in via Roma 45\""
- spree_classification_primary_taxon_error: "La classificazione %{taxon} è la classificazione primaria di %{product} e non può essere cancellata"
spree_order_availability_error: "Il distributore o il ciclo di richiesta non possono rifornire i prodotti nel tuo carrello"
spree_order_populator_error: "Il distributore o il ciclo di richieste non hanno disponibilità di alcuni prodotti nel tuo carrello. Per favore scegline un altro."
spree_order_cycle_error: "Per favore seleziona un ciclo di richieste per questa gentile richiesta."
@@ -2809,7 +2808,7 @@ it_CH:
order_cycles_no_permission_to_coordinate_error: "Nessuna delle tue aziende ha il permesso di coordinare un ciclo di richieste"
order_cycles_no_permission_to_create_error: "Non hai il permesso di creare un ciclo di richieste coordinato da questa azienda"
order_cycle_closed: "Il ciclo di richieste che hai selezionato è appena chiuso. Riprova per favore!"
- back_to_orders_list: "Indietro alla lista delle gentili richieste"
+ back_to_orders_list: "Torna alla lista delle richieste"
no_orders_found: "Nessuna gentile richiesta trovata"
order_information: "Informazioni Gentile Richiesta"
new_payment: "Nuovo pagamento"
@@ -3143,6 +3142,8 @@ it_CH:
Questo imposterà il livello delle scorte a zero su tutti i prodotti per questa
impresa che non sono presenti nel file caricato.
order_cycles:
+ unsaved_changes: "Hai modifiche non salvate"
+ bulk_save_error: "Oh no! non siamo riusciti a salvare le tue modifiche"
create_failure: "Impossibile creare il ciclo dell'ordine"
update_success: 'Il tuo ciclo di richieste è stato aggiornato'
update_failure: "Impossibile aggiornare il ciclo dell'ordine"
@@ -3381,7 +3382,6 @@ it_CH:
more: "Di più"
new_adjustment: "Nuovo aggiustamento"
new_tax_category: "Nuova Categoria imposta"
- new_taxon: "Nuova tassonomia"
new_user: "Nuovo utente"
no_pending_payments: "Nessun pagamento in sospeso"
remove: "Rimuovi"
@@ -3398,8 +3398,6 @@ it_CH:
UPS Ground: "UPS Ground"
start_date: "Data inizio"
successfully_removed: "Rimosso con successo"
- taxonomy_edit: "Modifica tassonomia"
- tree: "Schema"
updating: "In aggiornamento"
your_order_is_empty_add_product: "Il tuo ordine è vuoto, cerca e aggiungi un prodotto qui sopra"
add_product: "Aggiungi prodotto"
@@ -3494,7 +3492,6 @@ it_CH:
tax_rate_amount_explanation: "Le tariffe sono un importo decimale da utilizzare nei calcoli (ad esempio, se l'aliquota fiscale è del 5%, inserire 0,05)"
included_in_price: "Incluso nel prezzo"
show_rate_in_label: "Mostra tariffa in etichetta"
- back_to_tax_rates_list: "Torna all'elenco delle tariffe"
tax_settings: "Impostazione contributi"
zones: "Zone"
new_zone: "Nuova zona"
@@ -3507,14 +3504,11 @@ it_CH:
iso_name: "Nome ISO"
states_required: "Provincia richiesta"
editing_country: "Modifica Paese"
- back_to_countries_list: "Torna all'elenco dei Paesi"
states: "Stati"
abbreviation: "Abbreviazione"
new_state: "Nuovo Stato"
payment_methods: "Metodi di pagamento"
- taxonomies: "Tassonomie"
- new_taxonomy: "Nuova tassonomia"
- back_to_taxonomies_list: "Torna all'elenco delle tassonomie"
+ taxons: "Categorie Prodotti"
shipping_methods: "Metodi di spedizione"
shipping_method: "Metodo di spedizione"
shipment: "Spedizione"
@@ -3668,7 +3662,6 @@ it_CH:
continue: "Continua"
new:
new_return_authorization: "Nuova autorizzazione resi"
- back_to_return_authorizations_list: "Torna alla lista di autorizzazioni resi"
continue: "Continua"
edit:
receive: "ricevi"
@@ -3959,9 +3952,10 @@ it_CH:
total: "Totale"
billing_address_name: "Nome"
taxons:
+ index:
+ title: "Categorie Prodotti"
form:
name: Nome
- permalink: Permalink
description: Descrizione
general_settings:
edit:
@@ -4181,7 +4175,6 @@ it_CH:
key_cleared: "Chiave cancellata"
shipment:
cannot_ready: "Impossibile spedizione immediata."
- invalid_taxonomy_id: "ID tassonomia non valido."
activerecord:
models:
spree/payment:
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index d0078b9015..a0f33b802e 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -68,7 +68,6 @@ ko:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "생산자 제고 관리를 위해 빈 칸으로 남겨야 합니다."
- on_demand_but_count_on_hand_set: "요구 사항이 있을 경우 빈 칸으로 남겨야 합니다."
limited_stock_but_no_count_on_hand: "한정된 재고 사항에 따라 명시되어야 합니다."
messages:
blank: "빈칸이 될 수 없습니다."
@@ -405,7 +404,7 @@ ko:
password_confirmation: 비밀번호 확인
reset_password_token: 비밀번호 초기화
expired: 만료되었습니다. 새로 요청하세요.
- back_to_payments_list: "결제 리스트로 돌아가기"
+ back_to_payments_list: "결제 목록으로 돌아가기"
maestro_or_solo_cards: "마스터/전용 카드"
backordered: "일시 품절됨"
on_hand: "대기 중"
@@ -472,6 +471,8 @@ ko:
remove: 제거
image:
edit: 편집
+ product_preview:
+ shop_tab: 쇼핑
adjustments:
skipped_changing_canceled_order: "취소된 명령을 바꿀 수 없습니다."
begins_at: 시작 시간
@@ -670,7 +671,6 @@ ko:
variants:
infinity: "무한성"
to_order_tip: "주문 제작 품목은 갓 주문한 빵 덩어리와 같이 정해진 재고 수준이 없습니다."
- back_to_products_list: "제품 목록으로 돌아가기"
editing_product: "제품 편집"
tabs:
product_details: "상품 세부사항"
@@ -1151,10 +1151,8 @@ ko:
contact_name: 연락처 이름
edit:
editing: '설정 :'
- back_link: 회사 목록으로 돌아가기
new:
title: 새로운 회사
- back_link: 회사 목록으로 돌아가기
welcome:
welcome_title: Open Food Network에 오신 것을 환영합니다!
welcome_text: 성공적으로 생성되었습니다.
@@ -1191,6 +1189,8 @@ ko:
choose_products_from: "제품 위치 선택:"
re_notify_producers: 생산자에게 재통보
notify_producers_tip: 이렇게 하면 각 생산자에게 주문 목록과 함께 이메일이 전송됩니다.
+ date_time_warning_modal_content:
+ cancel: '취소'
incoming:
incoming: "새로 들어옴"
supplier: "공급업체"
@@ -2554,7 +2554,6 @@ ko:
spree_admin_single_enterprise_hint: "힌트 : 다른 사용자가 사용자를 찾을 수 있도록 하려면 다음에서 사용자 가시성을 켜십시오."
spree_admin_eg_pickup_from_school: "예. '초등학교에서 픽업'"
spree_admin_eg_collect_your_order: "예. '123 Imaginary St, Northcote, 3070번지에서 주문을 받으십시오.'"
- spree_classification_primary_taxon_error: "분류군%{taxon}은 %{product}의 기본 분류군이며 삭제할 수 없습니다."
spree_order_availability_error: "대리점 또는 주문 주기가 카트의 제품을 제공할 수 없습니다."
spree_order_populator_error: "해당 유통업체나 주문 주기가 카트에 있는 모든 제품을 공급할 수는 없습니다. 다른 항목을 선택하십시오."
spree_order_cycle_error: "이 주문에 대한 주문 주기를 선택하십시오."
@@ -3157,6 +3156,8 @@ ko:
confirmation: |
업로드된 파일에 없는 이 기업의 모든 제품에 대한 재고 수준이 0으로 설정됩니다.
order_cycles:
+ unsaved_changes: "저장되지 않은 변경이 있습니다."
+ bulk_save_error: "이런! 변경 내용을 저장할 수 없습니다."
create_failure: "주문 주기를 생성하지 못했습니다."
update_success: '주문 주기가 업데이트 되었습니다.'
update_failure: "주문 주기를 업데이트하지 못했습니다."
@@ -3347,7 +3348,6 @@ ko:
more: "추가 정보"
new_adjustment: "새 조정"
new_tax_category: "신규 세금 카테고리"
- new_taxon: "새 분류군"
new_user: "신규 사용자"
no_pending_payments: "미지금급"
remove: "제거"
@@ -3364,8 +3364,6 @@ ko:
UPS Ground: "UPS 배경"
start_date: "시작 날짜"
successfully_removed: "성공적으로 제거됨"
- taxonomy_edit: "분류법 편집"
- tree: "트리"
updating: "업데이트 중"
your_order_is_empty_add_product: "주문이 비어 있습니다. 위의 제품을 검색하여 추가하십시오."
add_product: "상품 추가"
@@ -3460,7 +3458,6 @@ ko:
tax_rate_amount_explanation: "세율은 소수로 계산하면 도움이 됩니다. (예: 세율이 5%인 경우라면 0.05를 입력하세요.)"
included_in_price: "가격에 포함되어있음"
show_rate_in_label: "레이블에 비율 표시"
- back_to_tax_rates_list: "세율 리스트로 돌아가기"
tax_settings: "세금 설정"
zones: "구역"
new_zone: "신규 구역"
@@ -3473,14 +3470,11 @@ ko:
iso_name: "ISO 이름"
states_required: "주를 작성하셔야 합니다."
editing_country: "국가 편집"
- back_to_countries_list: "국가 리스트로 돌아가기"
states: "주"
abbreviation: "축약"
new_state: "신규 주"
payment_methods: "결제 방법"
- taxonomies: "분류법"
- new_taxonomy: "신규 분류법"
- back_to_taxonomies_list: "분류법 리스트로 돌아가기"
+ taxons: "제품 카테고리"
shipping_methods: "전송 방법"
shipping_method: "배송 방법"
shipment: "수송"
@@ -3634,7 +3628,6 @@ ko:
continue: "계속하기"
new:
new_return_authorization: "신규 반품 승인"
- back_to_return_authorizations_list: "반품 승인 리스트로 돌아가기"
continue: "계속하기"
edit:
receive: "수신"
@@ -3926,9 +3919,10 @@ ko:
total: "총합"
billing_address_name: "이름"
taxons:
+ index:
+ title: "제품 카테고리"
form:
name: 이름
- permalink: 하이퍼링크
description: 설명
general_settings:
edit:
@@ -4148,7 +4142,6 @@ ko:
key_cleared: "키 지워짐"
shipment:
cannot_ready: "발송을 준비할 수 없습니다."
- invalid_taxonomy_id: "분류법 ID가 잘못되었습니다."
activerecord:
models:
spree/payment:
diff --git a/config/locales/ml.yml b/config/locales/ml.yml
index 2ab418835a..a8849d8778 100644
--- a/config/locales/ml.yml
+++ b/config/locales/ml.yml
@@ -81,8 +81,6 @@ ml:
white_label_logo_link: "കടയുടെ മുൻവശത്ത് ഉപയോഗിക്കുന്ന ലോഗോയ്ക്കുള്ള ലിങ്ക്"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "നികുതി വിഭാഗം അവകാശമായി ലഭിക്കുന്നതിന് ഓരോ ഇനത്തിനും കാൽക്കുലേറ്റർ ആവശ്യമാണ്."
spree/user:
attributes:
email:
@@ -102,7 +100,6 @@ ml:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "പ്രൊഡ്യൂസർ സ്റ്റോക്ക് ക്രമീകരണങ്ങൾ ഉപയോഗിക്കുന്നതിനാൽ ശൂന്യമായിരിക്കണം"
- on_demand_but_count_on_hand_set: "ആവശ്യകത കൂടിയിരുന്നാൽ ശൂന്യമായിരിക്കണം"
limited_stock_but_no_count_on_hand: "സ്റ്റോക്ക് പരിമിതമായതിനാൽ വ്യക്തമാക്കണം"
messages:
confirmation: "%{attribute} എന്നതുമായി പൊരുത്തപ്പെടുന്നില്ല"
@@ -541,6 +538,8 @@ ml:
remove: നീക്കം ചെയ്യുക
image:
edit: എഡിറ്റ് ചെയ്യുക
+ product_preview:
+ shop_tab: ഷോപ്പ്
adjustments:
skipped_changing_canceled_order: "നിങ്ങൾക്ക് റദ്ദാക്കിയ ഓർഡർ മാറ്റാൻ കഴിയില്ല."
begins_at: ആരംഭിക്കുന്നത്
@@ -747,7 +746,6 @@ ml:
variants:
infinity: "അനന്തത"
to_order_tip: "ഓർഡർ ചെയ്യാൻ തയ്യാറാക്കിയ ഇനങ്ങൾക്ക് സെറ്റ് സ്റ്റോക്ക് ലെവൽ ഇല്ല, ഉദാഹരണത്തിന്, ഓർഡർ അനുസരിച്ച് തയ്യാറാക്കുന്ന ബ്രഡ് പാക്കറ്റുകൾ."
- back_to_products_list: "ഉൽപ്പന്നങ്ങളുടെ പട്ടികയിലേക്ക് മടങ്ങുക"
editing_product: "ഉൽപ്പന്നം തിരുത്തുന്നു"
tabs:
product_details: "ഉൽപ്പന്നത്തിന്റെ വിവരം"
@@ -772,7 +770,6 @@ ml:
search: തിരയുക
sort:
pagination:
- total_html: "നിങ്ങളുടെ തിരയൽ മാനദണ്ഡങ്ങൾക്കനുസരിച്ച് %{total} ഉൽപ്പന്നങ്ങൾ കണ്ടെത്തി. %{from} മുതൽ %{to} വരെ കാണിക്കുന്നു."
per_page:
show: കാണിക്കുക
per_page: "ഓരോ പേജിലും %{num}"
@@ -1297,10 +1294,8 @@ ml:
contact_name: ബന്ധപ്പെടാനുള്ള പേര്
edit:
editing: 'ക്രമീകരണങ്ങൾ:'
- back_link: എന്റർപ്രൈസസ് ലിസ്റ്റിലേക്ക് മടങ്ങുക
new:
title: പുതിയ എന്റർപ്രൈസ്
- back_link: എന്റർപ്രൈസസ് ലിസ്റ്റിലേക്ക് മടങ്ങുക
welcome:
welcome_title: ഓപ്പൺ ഫുഡ് നെറ്റ്വർക്കിലേക്ക് സ്വാഗതം!
welcome_text: നിങ്ങൾ വിജയകരമായി സൃഷ്ടിച്ചു
@@ -1337,6 +1332,8 @@ ml:
choose_products_from: "ഇതിൽ നിന്ന് ഉൽപ്പന്നങ്ങൾ തിരഞ്ഞെടുക്കുക:"
re_notify_producers: പ്രൊഡ്യൂസേഴ്സിനെ വീണ്ടും അറിയിക്കുക
notify_producers_tip: ഇത് ഓരോ പ്രൊഡ്യൂസേഴ്സിനും അവരുടെ ഓർഡറുകളുടെ ലിസ്റ്റുമായി ഒരു ഇമെയിൽ അയയ്ക്കും.
+ date_time_warning_modal_content:
+ cancel: 'റദ്ദാക്കുക'
incoming:
incoming: "ഇൻകമിംഗ്"
supplier: "വിതരണക്കാരൻ"
@@ -2787,7 +2784,6 @@ ml:
spree_admin_single_enterprise_hint: "സൂചന: നിങ്ങളെ കണ്ടെത്താൻ ആളുകളെ അനുവദിക്കുന്നതിന്, ചുവടെ നിങ്ങളുടെ ദൃശ്യപരത ഓണാക്കുക"
spree_admin_eg_pickup_from_school: "ഉദാ. 'പ്രൈമറി സ്കൂളിൽ നിന്ന് പിക്കപ്പ് ചെയ്യുക'"
spree_admin_eg_collect_your_order: "ഉദാ. 'ദയവായി 123 ഇമാജിനറി സ്ട്രീറ്റ്, നോർത്ത്കോട്ട്, 3070-ൽ നിന്ന് നിങ്ങളുടെ ഓർഡർ ശേഖരിക്കുക'"
- spree_classification_primary_taxon_error: "ടാക്സോൺ %{taxon} എന്നത് %{product} -ന്റെ പ്രാഥമിക ടാക്സോണാണ്, അത് ഇല്ലാതാക്കാൻ കഴിയില്ല"
spree_order_availability_error: "ഡിസ്ട്രിബ്യൂട്ടർക്കോ അല്ലെങ്കിൽ ഓർഡർ സൈക്കിളിനോ നിങ്ങളുടെ കാർട്ടിലെ ഉൽപ്പന്നങ്ങൾ വിതരണം ചെയ്യാൻ കഴിയില്ല"
spree_order_populator_error: "നിങ്ങളുടെ കാർട്ടിലെ എല്ലാ ഉൽപ്പന്നങ്ങളും വിതരണം ചെയ്യാൻ ആ വിതരണക്കാരനോ ഓർഡർ സൈക്കിളിനോ കഴിയില്ല. ദയവായി മറ്റൊന്ന് തിരഞ്ഞെടുക്കുക."
spree_order_cycle_error: "ഈ ഓർഡറിനായി ഒരു ഓർഡർ സൈക്കിൾ തിരഞ്ഞെടുക്കുക."
@@ -3458,6 +3454,8 @@ ml:
ഇതിനായുള്ള എല്ലാ ഉൽപ്പന്നങ്ങളുടെയും സ്റ്റോക്ക് ലെവൽ പൂജ്യമായി സജ്ജമാക്കും
അപ്ലോഡ് ചെയ്ത ഫയലിൽ ഇല്ലാത്ത എന്റർപ്രൈസ്.
order_cycles:
+ unsaved_changes: "നിങ്ങൾക്ക് സേവ് ചെയ്യാത്ത മാറ്റങ്ങളുണ്ട്"
+ bulk_save_error: "അയ്യോ! നിങ്ങളുടെ മാറ്റങ്ങൾ സേവ് ചെയ്യാൻ എനിക്ക് കഴിഞ്ഞില്ല."
create_failure: "ഓർഡർ സൈക്കിൾ സൃഷ്ടിക്കുന്നതിൽ പരാജയപ്പെട്ടു"
update_success: 'നിങ്ങളുടെ ഓർഡർ സൈക്കിൾ അപ്ഡേറ്റ് ചെയ്തു.'
update_failure: "ഓർഡർ സൈക്കിൾ അപ്ഡേറ്റ് ചെയ്യുന്നതിൽ പരാജയപ്പെട്ടു"
@@ -3680,7 +3678,6 @@ ml:
more: "കൂടുതൽ"
new_adjustment: "പുതിയ മാറ്റംവരുത്തൽ"
new_tax_category: "പുതിയ നികുതി വിഭാഗം"
- new_taxon: "പുതിയ ടാക്സൺ"
new_user: "പുതിയ ഉപയോക്താവ്"
no_pending_payments: "തീർപ്പാക്കാത്ത പേയ്മെന്റുകളൊന്നുമില്ല"
remove: "നീക്കം ചെയ്യുക"
@@ -3699,8 +3696,6 @@ ml:
delivery: "ഒപ്പിട്ടു, സീൽ ചെയ്തു, എത്തിച്ചു"
start_date: "ആരംഭിക്കുന്ന തീയതി"
successfully_removed: "വിജയകരമായി നീക്കം ചെയ്തു"
- taxonomy_edit: "ടാക്സോണമി എഡിറ്റ്"
- tree: "ട്രീ"
updating: "അപ്ഡേറ്റ് ചെയ്യുന്നു"
your_order_is_empty_add_product: "നിങ്ങളുടെ ഓർഡർ ശൂന്യമാണ്, മുകളിൽ ഒരു ഉൽപ്പന്നം തിരയുകയും ചേർക്കുകയും ചെയ്യുക"
add_product: "ഉൽപ്പന്നം ചേർക്കുക"
@@ -3797,7 +3792,6 @@ ml:
tax_rate_amount_explanation: "കണക്കുകൂട്ടലുകളെ സഹായിക്കുന്നതിനുള്ള ഒരു ദശാംശ തുകയാണ് നികുതി നിരക്കുകൾ, (അതായത് നികുതി നിരക്ക് 5% ആണെങ്കിൽ 0.05 നൽകുക)"
included_in_price: "വിലയിൽ ഉൾപ്പെടുത്തിയിട്ടുണ്ട്"
show_rate_in_label: "ലേബലിൽ നിരക്ക് കാണിക്കുക"
- back_to_tax_rates_list: "നികുതി നിരക്കുകളുടെ പട്ടികയിലേക്ക് മടങ്ങുക"
tax_settings: "നികുതി ക്രമീകരണങ്ങൾ"
zones: "സോണുകൾ"
new_zone: "പുതിയ സോൺ"
@@ -3810,14 +3804,11 @@ ml:
iso_name: "ഐഎസ്ഓ നാമം"
states_required: "ആവശ്യമുള്ള സംസ്ഥാനങ്ങൾ"
editing_country: "രാജ്യം എഡിറ്റ് ചെയ്യുന്നു"
- back_to_countries_list: "രാജ്യങ്ങളുടെ പട്ടികയിലേക്ക് മടങ്ങുക"
states: "സംസ്ഥാനങ്ങൾ"
abbreviation: "ചുരുക്കെഴുത്ത്"
new_state: "പുതിയ സംസ്ഥാനം"
payment_methods: "പേയ്മെന്റ് രീതികൾ"
- taxonomies: "ടാക്സോണമികൾ"
- new_taxonomy: "പുതിയ ടാക്സോണമി"
- back_to_taxonomies_list: "ടാക്സോണമി ലിസ്റ്റിലേക്ക് മടങ്ങുക"
+ taxons: "ഉൽപ്പന്ന വിഭാഗങ്ങൾ"
shipping_methods: "ഷിപ്പിംഗ് രീതികൾ"
shipping_method: "ഷിപ്പിംഗ് രീതി"
shipment: "കയറ്റുമതി"
@@ -3975,7 +3966,6 @@ ml:
continue: "തുടരുക"
new:
new_return_authorization: "പുതിയ റിട്ടേൺ അനുമതി"
- back_to_return_authorizations_list: "റിട്ടേൺ അനുമതി ലിസ്റ്റിലേക്ക് മടങ്ങുക"
continue: "തുടരുക"
edit:
receive: "സ്വീകരിക്കുക"
@@ -4293,9 +4283,10 @@ ml:
total: "ആകെ"
billing_address_name: "പേര്"
taxons:
+ index:
+ title: "ഉൽപ്പന്ന വിഭാഗങ്ങൾ"
form:
name: പേര്
- permalink: പെർമലിങ്ക്
description: വിവരണം
general_settings:
edit:
@@ -4533,7 +4524,6 @@ ml:
key_cleared: "കീ മായ്ച്ചു"
shipment:
cannot_ready: "കയറ്റുമതി തയ്യാറാക്കാൻ കഴിയില്ല."
- invalid_taxonomy_id: "ടാക്സോണമി ഐഡി അസാധുവാണ്."
toggle_api_key_view: "ഉപയോക്താവിനായി എപിഐ കീ കാണിക്കുക"
activerecord:
models:
diff --git a/config/locales/mr.yml b/config/locales/mr.yml
index fa0807fbf8..b6dbd18185 100644
--- a/config/locales/mr.yml
+++ b/config/locales/mr.yml
@@ -81,8 +81,6 @@ mr:
white_label_logo_link: "शॉपफ्रंटमध्ये वापरलेल्या लोगोची लिंक"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "कर श्रेणीचा वारसा मिळवण्यासाठी प्रति-आयटम कॅल्क्युलेटर आवश्यक आहे."
spree/user:
attributes:
email:
@@ -102,7 +100,6 @@ mr:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "उत्पादक स्टॉक सेटिंग्ज वापरल्याने रिक्त असणे आवश्यक आहे"
- on_demand_but_count_on_hand_set: "मागणी केली असल्यास रिक्त असणे आवश्यक आहे"
limited_stock_but_no_count_on_hand: "मर्यादित स्टॉकची सक्ती केल्यामुळे निर्दिष्ट करणे आवश्यक आहे"
messages:
confirmation: "%{attribute} जुळत नाही"
@@ -470,7 +467,6 @@ mr:
password_confirmation: पासवर्ड पुष्टीकरण
reset_password_token: पासवर्ड टोकन रीसेट करा
expired: कालबाह्य झाले आहे, कृपया नवीन विनंती करा
- back_to_payments_list: "पेमेंट्स लिस्टकडे परत"
maestro_or_solo_cards: "मेस्ट्रो/सोलो कार्ड"
backordered: "बॅकऑर्डर केलेले"
on_hand: "आता उपलब्ध"
@@ -538,6 +534,8 @@ mr:
clone: क्लोन
image:
edit: सुधारित करा
+ product_preview:
+ shop_tab: शॉप
adjustments:
skipped_changing_canceled_order: "तुम्ही रद्द केलेली ऑर्डर बदलू शकत नाही."
begins_at: वाजता सुरू होते
@@ -741,7 +739,6 @@ mr:
variants:
infinity: "अनंत"
to_order_tip: "ऑर्डरप्रमाणे बनवलेल्या वस्तूंची स्टॉक लेव्हल नसते, जसे की ऑर्डरप्रमाणे बनवलेले ताजे ब्रेडस्. "
- back_to_products_list: "उत्पादनांच्या सूचीकडे परत"
editing_product: "उत्पादन संपादित करत आहे"
tabs:
product_details: "उत्पादन तपशील"
@@ -764,7 +761,6 @@ mr:
search: शोधा
sort:
pagination:
- total_html: "तुमच्या शोध निकषांसाठी %{total} उत्पादने आढळली. %{from} ते %{to} दाखवत आहे."
per_page:
show: दाखवा
per_page: "%{num} प्रति पृष्ठ"
@@ -1277,10 +1273,8 @@ mr:
contact_name: संपर्क नाव
edit:
editing: 'सेटिंग्ज:'
- back_link: उपक्रमांच्या सूचीकडे परत
new:
title: नवे एंटरप्राइज
- back_link: एंटरप्राइझ लिस्टकडे परता
welcome:
welcome_title: ओपन फूड नेटवर्कमध्ये आपले स्वागत आहे!
welcome_text: आपण यशस्वीरित्या तयार केले आहे
@@ -1311,6 +1305,8 @@ mr:
choose_products_from: "यामधून उत्पादने निवडा:"
re_notify_producers: उत्पादकांना पुन्हा सूचित करा
notify_producers_tip: हे प्रत्येक उत्पादकाला त्यांच्या ऑर्डरच्या सूचीचे ईमेल पाठवेल.
+ date_time_warning_modal_content:
+ cancel: 'रद्द करा'
incoming:
incoming: "येणारे"
supplier: "पुरवठादार"
@@ -2695,7 +2691,6 @@ mr:
spree_admin_single_enterprise_hint: "सूचना: लोकांना तुम्हाला शोधण्याची अनुमती देण्यासाठी, या अंतर्गत तुमची दृश्यमानता चालू करा"
spree_admin_eg_pickup_from_school: "उदा. 'प्राथमिक शाळेतून पिक-अप'"
spree_admin_eg_collect_your_order: "उदा. 'कृपया 123 सरदार वल्लभभाई पटेल रोड, सुरत, 301070 वरून तुमची ऑर्डर प्राप्त करा'"
- spree_classification_primary_taxon_error: "टॅक्सन %{taxon} हा %{product} चा प्राथमिक टॅक्सन आहे आणि तो हटवला जाऊ शकत नाही"
spree_order_availability_error: "वितरक किंवा ऑर्डर सायकल तुमच्या कार्ट मधील उत्पादने पुरवू शकत नाही"
spree_order_populator_error: "तो वितरक किंवा ऑर्डर सायकल तुमच्या कार्टमधील सर्व उत्पादने पुरवू शकत नाही. कृपया दुसरा वितरक किंवा दुसरी ऑर्डर सायकल निवडा."
spree_order_cycle_error: "कृपया या ऑर्डरसाठी ऑर्डर सायकल निवडा."
@@ -3013,7 +3008,6 @@ mr:
order_cycles_no_permission_to_coordinate_error: "तुमच्या कोणत्याही एंटरप्राइझला ऑर्डर सायकल को-ऑर्डिनेट करण्याची परवानगी नाही"
order_cycles_no_permission_to_create_error: "तुम्हाला त्या एंटरप्राइझद्वारे को-ऑर्डिनेट केलेल्या ऑर्डर सायकल तयार करण्याची परवानगी नाही"
order_cycle_closed: "तुम्ही निवडलेले ऑर्डर सायकल नुकतेच बंद झाले आहे. कृपया पुन्हा प्रयत्न करा!"
- back_to_orders_list: "ऑर्डर सूचीकडे परत"
no_orders_found: "कोणत्याही ऑर्डर आढळल्या नाहीत"
order_information: "ऑर्डर माहिती"
new_payment: "नवीन पेमेंट"
@@ -3358,6 +3352,8 @@ mr:
हे अपलोड केलेल्या फाइलमध्ये उपस्थित नसलेल्या एंटरप्राइझसाठी
सर्व उत्पादनांचा साठा शून्यावर सेट करेल.
order_cycles:
+ unsaved_changes: "तुमच्याकडे सेव्ह न केलेले बदल आहेत"
+ bulk_save_error: "क्षमस्व ! तुमचे बदल मी सेव्ह करू शकलो नाही."
create_failure: "ऑर्डर सायकल तयार करण्यात अयशस्वी"
update_success: 'तुमची ऑर्डर सायकल अपडेट केली गेली आहे.'
update_failure: "ऑर्डर सायकल अपडेट करण्यात अयशस्वी"
@@ -3580,7 +3576,6 @@ mr:
more: "अधिक"
new_adjustment: "नवीन समायोजन"
new_tax_category: "नवीन कर श्रेणी"
- new_taxon: "नवीन टॅक्सन"
new_user: "नवीन वापरकर्ता"
no_pending_payments: "कोणतीही प्रलंबित देयके नाहीत"
none: "कोणतेही नाही"
@@ -3598,8 +3593,6 @@ mr:
delivery: "स्वाक्षरी, सीलबंद, वितरित"
start_date: "प्रारंभ तारीख"
successfully_removed: "यशस्वीरित्या काढले"
- taxonomy_edit: "वर्गीकरण संपादन"
- tree: "वृक्ष"
updating: "अपडेट करत आहे"
your_order_is_empty_add_product: "तुमची ऑर्डर रिकामी आहे, कृपया उत्पादन शोधा आणि वर समाविष्ट करा"
add_product: "उत्पादन जोडा"
@@ -3696,7 +3689,6 @@ mr:
tax_rate_amount_explanation: "कर दर ही गणना करण्यात मदत करण्यासाठीची दशांश रक्कम आहे, (म्हणजे कर दर 5% असल्यास 0.05 प्रविष्ट करा)"
included_in_price: "किंमतीमध्ये समाविष्ट आहे"
show_rate_in_label: "लेबलमध्ये दर दर्शवा"
- back_to_tax_rates_list: "कर दर सूचीकडे परत"
tax_settings: "कर सेटिंग्ज"
zones: "क्षेत्रे"
new_zone: "नवीन क्षेत्र"
@@ -3709,14 +3701,10 @@ mr:
iso_name: "आयएसओ नाव"
states_required: "राज्ये आवश्यक"
editing_country: "संपादन देश"
- back_to_countries_list: "देशांच्या यादीकडे परत"
states: "राज्ये"
abbreviation: "संक्षेप"
new_state: "नवीन राज्य"
payment_methods: "पेमेंट पद्धती"
- taxonomies: "वर्गीकरण"
- new_taxonomy: "नवीन वर्गीकरण"
- back_to_taxonomies_list: "वर्गीकरण सूचीकडे परत जा"
shipping_methods: "शिपिंग पद्धती"
shipping_method: "शिपिंग पद्धत "
shipment: "शिपमेंट"
@@ -3868,7 +3856,6 @@ mr:
continue: "सुरू ठेवा "
new:
new_return_authorization: "रिटर्न अधिकृतता"
- back_to_return_authorizations_list: "रिटर्न अधिकृतता सूचीकडे परता"
continue: "सुरू ठेवा "
edit:
receive: "प्राप्त"
@@ -4421,7 +4408,6 @@ mr:
key_cleared: "Key क्लिअर केली"
shipment:
cannot_ready: "शिपमेंट तयार करू शकत नाही."
- invalid_taxonomy_id: "अवैध वर्गीकरण आयडी."
toggle_api_key_view: "वापरकर्त्यासाठी API key दृश्य दर्शवा"
activerecord:
models:
diff --git a/config/locales/nb.yml b/config/locales/nb.yml
index 79d6eea4fd..7272f9597a 100644
--- a/config/locales/nb.yml
+++ b/config/locales/nb.yml
@@ -81,8 +81,6 @@ nb:
white_label_logo_link: "Link til logoen som brukes i butikk"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Å arve skattekategorien krever en varekalkulator."
spree/image:
attributes:
attachment:
@@ -99,8 +97,6 @@ nb:
attributes:
base:
card_expired: "har utgått"
- spree/product:
- must_exist: 'må eksistere'
order_cycle:
attributes:
orders_close_at:
@@ -108,7 +104,6 @@ nb:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "må være tomt fordi du bruker produsentens lagerinnstillinger"
- on_demand_but_count_on_hand_set: "må være tom hvis på forespørsel"
limited_stock_but_no_count_on_hand: "må spesifiseres fordi det tvinger begrenset lager"
messages:
confirmation: "samsvarer ikke med %{attribute}"
@@ -559,6 +554,8 @@ nb:
remove: Fjern
image:
edit: Rediger
+ product_preview:
+ shop_tab: Butikk
adjustments:
skipped_changing_canceled_order: "Du kan ikke endre en avbrutt bestilling."
begins_at: Begynner på
@@ -774,7 +771,6 @@ nb:
variants:
infinity: "Uendelig"
to_order_tip: "Varer laget for bestilling har ikke et lagernivå, slik som ferske skiver brød laget for bestilling."
- back_to_products_list: "Tilbake til produktlisten"
editing_product: "Redigerer produkt"
tabs:
product_details: "Produktdetaljer"
@@ -814,7 +810,6 @@ nb:
search: Søk
sort:
pagination:
- total_html: "%{total} produkter funnet for søkekriteriene dine. Viser %{from} til %{to} ."
per_page:
show: Vis
per_page: "%{num} per side"
@@ -1385,10 +1380,8 @@ nb:
contact_name: Kontaktnavn
edit:
editing: 'innstillinger:'
- back_link: Tilbake til bedriftsliste
new:
title: Ny Bedrift
- back_link: Tilbake til bedriftsliste
welcome:
welcome_title: Velkommen til Open Food Network!
welcome_text: Du har opprettet en
@@ -1425,6 +1418,8 @@ nb:
choose_products_from: "Velg Produkter Fra:"
re_notify_producers: Varsle produsentene på nytt
notify_producers_tip: Dette vil sende en epost til hver produsent med listen over deres bestillinger.
+ date_time_warning_modal_content:
+ cancel: 'Avbryt'
incoming:
incoming: "Innkommende"
supplier: "Leverandør"
@@ -2884,7 +2879,6 @@ nb:
spree_admin_single_enterprise_hint: "Hint: For å hjelpe folk til å finne deg, skru på din synlighet under"
spree_admin_eg_pickup_from_school: "f.eks. 'Henting ved Sammfunnshuset'"
spree_admin_eg_collect_your_order: "f.eks. 'Vennligst hente din bestilling fra 123 Matveien, Nesodden, 3070'"
- spree_classification_primary_taxon_error: "Gruppe %{taxon} er hovedgruppe til %{product} og kan ikke slettes"
spree_order_availability_error: "Distributør eller bestillingsrunde kan ikke levere produktene i handlekurven din"
spree_order_populator_error: "Den distributøren eller bestillingsrunden kan ikke levere alle produktene i handlekurven din. Vennligst velg en annen."
spree_order_cycle_error: "Vennligst velg en bestillingsrunde for denne bestillingen."
@@ -3204,7 +3198,7 @@ nb:
order_cycles_no_permission_to_coordinate_error: "Ingen av bedriftene dine har tillatelse til å koordinere en bestillingsrunde"
order_cycles_no_permission_to_create_error: "Du har ikke rettigheter til å opprette en bestillingsrunde som er koordinert av den bedriften"
order_cycle_closed: "Bestillingsrunden du har valgt har akkurat stengt. Vennligst prøv igjen!"
- back_to_orders_list: "Tilbake til bestillingslisten"
+ back_to_orders_list: "Tilbake til Bestillingsliste"
no_orders_found: "Ingen bestillinger funnet"
order_information: "Bestillingsinformasjon"
new_payment: "Ny betaling"
@@ -3547,6 +3541,8 @@ nb:
confirmation: |
Dette vil sette varebeholdning til null på alle produkter for denne virksomheten som ikke er til stede i den nedlastede filen.
order_cycles:
+ unsaved_changes: "Du har ulagrede endringer"
+ bulk_save_error: "Å nei! Jeg kunne ikke lagre endringene dine."
create_failure: "Kunne ikke opprette bestillingsrunde"
update_success: 'Din bestillingsrunde har blitt oppdatert.'
update_failure: "Kunne ikke oppdatere bestillingsrunde"
@@ -3768,7 +3764,6 @@ nb:
more: "Mer"
new_adjustment: "Ny justering"
new_tax_category: "Ny avgiftskategori"
- new_taxon: "Ny kategori"
new_user: "Ny bruker"
no_pending_payments: "Ingen ventende betalinger"
remove: "Fjern"
@@ -3787,10 +3782,6 @@ nb:
delivery: "Signert, forseglet, levert"
start_date: "Startdato"
successfully_removed: "Fjernet OK"
- taxonomy_edit: "Rediger kategori"
- taxonomy_tree_error: "Det oppsto en feil under oppdatering av kategoritreet."
- taxonomy_tree_instruction: "Høyreklikk på et element for å legge til, gi nytt navn, fjerne eller redigere."
- tree: "Tre"
updating: "Oppdaterer"
your_order_is_empty_add_product: "Bestillingen din er tom, vennligst søk etter og legg til et produkt over"
add_product: "Legg til produkt"
@@ -3888,7 +3879,6 @@ nb:
tax_rate_amount_explanation: "Avgiftssatser er et desimalbeløp til hjelp i beregninger, (dvs. dersom avgiftssatsen er 5%, angi 0,05)"
included_in_price: "Inkludert i Pris"
show_rate_in_label: "Vis sats på merkelapp"
- back_to_tax_rates_list: "Tilbake til siden for Avgiftssats"
tax_settings: "Avgiftsinnstillinger"
zones: "Soner"
new_zone: "Ny Sone"
@@ -3901,14 +3891,11 @@ nb:
iso_name: "ISO-navn"
states_required: "Regioner Påkrevd"
editing_country: "Redigerer Land"
- back_to_countries_list: "Tilbake til Landlisten"
states: "Regioner"
abbreviation: "Forkortelse"
new_state: "Ny Region"
payment_methods: "Betalingsmetoder"
- taxonomies: "Taksonomier"
- new_taxonomy: "Ny Taksonomi"
- back_to_taxonomies_list: "Tilbake til Taksonomiliste"
+ taxons: "Produktkategorier"
shipping_methods: "Leveringsmetoder"
shipping_method: "Leveringsmetode"
shipment: "Leveranse"
@@ -4068,7 +4055,6 @@ nb:
continue: "Fortsett"
new:
new_return_authorization: "Ny Returautorisasjon"
- back_to_return_authorizations_list: "Tilbake til liste over Returautorisasjoner"
continue: "Fortsett"
edit:
receive: "motta"
@@ -4315,6 +4301,7 @@ nb:
product_name: Produktnavn
primary_taxon_form:
product_category: Produktkategori
+ search_for_categories: "Søk etter kategorier"
group_buy_form:
group_buy: "Gruppekjøp?"
bulk_unit_size: Bulk enhetsstørrelse
@@ -4392,9 +4379,10 @@ nb:
total: "Total"
billing_address_name: "Navn"
taxons:
+ index:
+ title: "Produktkategorier"
form:
name: Navn
- permalink: Permalink
meta_title: Metatittel
meta_description: Metabeskrivelse
meta_keywords: Meta nøkkelord
@@ -4636,7 +4624,6 @@ nb:
key_cleared: "Nøkkelen ble fjernet"
shipment:
cannot_ready: "Kan ikke gjøre klar forsendelse."
- invalid_taxonomy_id: "Ugyldig kategori-id."
toggle_api_key_view: "Vis API-nøkkelvisning for bruker"
activerecord:
models:
diff --git a/config/locales/nl_BE.yml b/config/locales/nl_BE.yml
index 02bce0f0f6..a62582ba15 100644
--- a/config/locales/nl_BE.yml
+++ b/config/locales/nl_BE.yml
@@ -65,7 +65,6 @@ nl_BE:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "moet leeg zijn omdat u de instellingen voor de voorraad van de producent gebruikt"
- on_demand_but_count_on_hand_set: "moet leeg zijn op aanvraag"
limited_stock_but_no_count_on_hand: "moet worden opgegeven omdat een beperkte voorraad wordt geforceerd"
messages:
blank: "kan niet leeg zijn"
@@ -285,7 +284,6 @@ nl_BE:
password_confirmation: Wachtwoord Bevestiging
reset_password_token: Reset wachtwoord token
expired: is verlopen, gelieve een nieuwe aan te vragen
- back_to_payments_list: "Terug naar Betalingslijst"
maestro_or_solo_cards: "Maestro/Solo kaart"
backordered: "Niet in stock"
on_hand: "Bij de Hand"
@@ -345,6 +343,8 @@ nl_BE:
remove: Verwijderen
image:
edit: bewerking
+ product_preview:
+ shop_tab: winkel
begins_at: Begint Bij
begins_on: Begint Op
customer: Klant
@@ -527,7 +527,6 @@ nl_BE:
variants:
infinity: "Oneindigheid"
to_order_tip: "Op bestelling gemaakte artikelen hebben geen vast voorraadniveau, zoals broden die vers op bestelling worden gemaakt."
- back_to_products_list: "Terug naar productenlijst"
editing_product: "Product bijwerken"
tabs:
product_details: "Product details"
@@ -985,10 +984,8 @@ nl_BE:
contact_name: Naam contactpersoon
edit:
editing: 'Instellingen:'
- back_link: Terug naar bedrijvenlijst
new:
title: Nieuwe onderneming
- back_link: Terug naar bedrijvenlijst
welcome:
welcome_title: Welkom bij het Open Food Network!
welcome_text: U heeft met succes een
@@ -1023,6 +1020,8 @@ nl_BE:
back_to_list: "Terug naar lijst"
save_and_back_to_list: "Opslaan en terug naar lijst"
choose_products_from: "Kies Producten Uit:"
+ date_time_warning_modal_content:
+ cancel: 'Annuleren'
incoming:
incoming: "Binnenkomend"
supplier: "Leverancier"
@@ -2294,7 +2293,6 @@ nl_BE:
spree_admin_single_enterprise_hint: "Hint: Om het voor mensen mogelijk te maken je te vinden, zet je zichtbaarheid aan"
spree_admin_eg_pickup_from_school: "bv. 'Ophaling op een basisschool'"
spree_admin_eg_collect_your_order: "bv. 'Verzamel alsjeblieft je bestelling op de stationsstraat 123, 9000 Gent'"
- spree_classification_primary_taxon_error: "Taxon %{taxon} is de eerste taxon van %{product} en kan niet verwijderd worden."
spree_order_availability_error: "De verdeler of de bestelcyclus kan de producten in je winkelwagentje niet toevoegen"
spree_order_populator_error: "De verdeler of de bestelcyclus kan al de producten in je winkelwagentje niet toevoegen. Gelieve een andere te kiezen."
spree_order_populator_availability_error: "Dit produkt is niet toegelaten op de gekozen verdeler of bestelcyclus."
@@ -2575,7 +2573,7 @@ nl_BE:
order_cycles_no_permission_to_coordinate_error: "Geen van uw bedrijven heeft de vereiste rechten om een verkoopcyclus te coördineren"
order_cycles_no_permission_to_create_error: "U bezit de vereiste rechten niet om een bestelcyclus te maken die gecoördineerd wordt door dat bedrijf"
order_cycle_closed: "De hub die u hebt geselecteerd is tijdelijk gesloten. Probeer gerust later terug."
- back_to_orders_list: "Terug naar de bestellijst"
+ back_to_orders_list: "Terug naar de bestellingslijst"
no_orders_found: "Geen bestelling gevonden"
order_information: "Info bestelling"
new_payment: "Nieuwe betaling"
@@ -2885,6 +2883,8 @@ nl_BE:
Deze handeling zet het stockpeil op nul
bedrijf voor de produkten niet aanwezig in deze file
order_cycles:
+ unsaved_changes: "U heeft niet opgeslagen wijzigingen"
+ bulk_save_error: "Ah nee! Ik kon onmogelijk uw wijzigingen opslaan."
create_failure: "Het maken van de bestelcyclus is mislukt"
update_success: 'Uw bestelcyclus is bijgewerkt'
update_failure: "De bijwerking van de bestelcyclus is mislukt"
@@ -3086,7 +3086,6 @@ nl_BE:
tax_rate_amount_explanation: "BTW percentages zijn decimaal om de berekening gemakkelijker te maken, (bv. als de percentage 5% is dan 0.05 invoeren)"
included_in_price: "In de prijs inbegrepen "
show_rate_in_label: "Toon de percentahe op de label "
- back_to_tax_rates_list: "Terug naar de lijst BTW percentages"
tax_settings: "Belastings Instellingen"
zones: "Zones "
new_zone: "Nieuwe zone"
@@ -3099,14 +3098,11 @@ nl_BE:
iso_name: "ISO Naam"
states_required: "Staten Vereist"
editing_country: "Editing Land"
- back_to_countries_list: "Terug naar landenlijst"
states: "Provincies"
abbreviation: "Afkortingen "
new_state: "Nieuw Provincie"
payment_methods: "Betalingsmethode"
- taxonomies: "Taxonomies "
- new_taxonomy: "Nieuwe taxonomie "
- back_to_taxonomies_list: "Terug naar de lijst Taxonomies"
+ taxons: "Productcategorieën"
shipping_methods: "Methode Verzending"
shipping_method: "Het verschepen Methode"
shipment: "Verzending"
@@ -3240,7 +3236,6 @@ nl_BE:
continue: "Ga verder"
new:
new_return_authorization: "Nieuwe terugkeer goedkeuring"
- back_to_return_authorizations_list: "Terug naar goedkeuringslijst"
continue: "Ga verder"
edit:
receive: "Ontvangst"
@@ -3515,9 +3510,10 @@ nl_BE:
total: "Totaal"
billing_address_name: "Naam"
taxons:
+ index:
+ title: "Productcategorieën"
form:
name: Naam
- permalink: Permalink
description: Beschrijving
general_settings:
edit:
@@ -3698,7 +3694,6 @@ nl_BE:
key_cleared: "Sleutel gewist"
shipment:
cannot_ready: "Kan levering niet klaarmaken"
- invalid_taxonomy_id: "Onjuiste taxonomie id."
components:
search_input:
placeholder: Zoeken
diff --git a/config/locales/pa.yml b/config/locales/pa.yml
index a0da7d78e1..97cf9822b0 100644
--- a/config/locales/pa.yml
+++ b/config/locales/pa.yml
@@ -78,8 +78,6 @@ pa:
white_label_logo_link: "ਸ਼ੌਪਫਰੰਟ ਵਿੱਚ ਵਰਤੇ ਗਏ ਲੋਗੋ ਦਾ ਲਿੰਕ"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "ਟੈਕਸ ਸ਼੍ਰੇਣੀ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਪ੍ਰਤੀ-ਆਈਟਮ ਕੈਲਕੁਲੇਟਰ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।"
spree/user:
attributes:
email:
@@ -99,7 +97,6 @@ pa:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "ਖਾਲੀ ਹੋਣੀ ਚਾਹੀਦੀ ਹੈ ਕਿਉਂਕਿ ਉਤਪਾਦਕ ਸਟਾਕ ਸੈਟਿੰਗਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਹੈ"
- on_demand_but_count_on_hand_set: "ਜੇ ਡਿਮਾਂਡ ਤੇ ਹੋਵੇ ਤਾਂ ਖਾਲੀ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ"
limited_stock_but_no_count_on_hand: "ਸੀਮਤ ਸਟਾਕ ਨੂੰ ਮਜਬੂਰ ਕਰਨ ਕਰਕੇ ਨਿਰਧਾਰਤ ਕੀਤਾ ਜਾਣਾ ਚਾਹੀਦਾ ਹੈ"
messages:
confirmation: "%{attribute} ਨਾਲ ਮੇਲ ਨਹੀਂ ਖਾਂਦਾ"
@@ -463,7 +460,7 @@ pa:
password_confirmation: ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ
reset_password_token: ਪਾਸਵਰਡ ਟੋਕਨ ਨੂੰ ਰੀਸੈਟ ਕਰੋ
expired: ਮਿਆਦ ਪੁੱਗ ਗਈ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਨਵੇਂ ਲਈ ਬੇਨਤੀ ਕਰੋ
- back_to_payments_list: "ਭੁਗਤਾਨ ਸੂਚੀ ਤੇ ਵਾਪਸ"
+ back_to_payments_list: "ਭੁਗਤਾਨ ਸੂਚੀ ਤੇ ਵਾਪਸ ਜਾਓ"
maestro_or_solo_cards: "ਮਾਏਸਟ੍ਰੋ/ਸੋਲੋ ਕਾਰਡ"
backordered: "ਬੈਕਆਰਡਰ ਕੀਤਾ ਗਿਆ"
on_hand: "ਹੱਥ ਵਿਚ"
@@ -534,6 +531,8 @@ pa:
remove: Remove
image:
edit: ਸੰਪਾਦਿਤ ਕਰੋ
+ product_preview:
+ shop_tab: ਸ਼ਾਪ
adjustments:
skipped_changing_canceled_order: "ਤੁਸੀਂ ਰੱਦ ਕੀਤੇ ਆਰਡਰ ਨੂੰ ਬਦਲ ਨਹੀਂ ਸਕਦੇ ਹੋ।"
begins_at: ਇਸਤੇ ਸ਼ੁਰੂ ਹੋਵੇਗਾ
@@ -736,7 +735,6 @@ pa:
variants:
infinity: "ਇਨਫਿਨਿਟੀ"
to_order_tip: "ਆਰਡਰ ਉਤੇ ਬਣੀਆਂ ਆਈਟਮਾਂ ਵਿੱਚ ਸਟਾਕ ਦੇ ਪੱਧਰ ਨਿਰਧਾਰਤ ਨਹੀਂ ਹੁੰਦੇ, ਜਿਵੇਂ ਕਿ ਆਰਡਰ ਤੇ ਬਣਾਈ ਗਈ ਤਾਜ਼ਾ ਬ੍ਰੈਡ।"
- back_to_products_list: "ਉਤਪਾਦਾਂ ਦੀ ਸੂਚੀ ਤੇ ਵਾਪਿਸ"
editing_product: "ਉਤਪਾਦ ਦਾ ਸੰਪਾਦਨ"
tabs:
product_details: "ਉਤਪਾਦ ਵੇਰਵੇ"
@@ -761,7 +759,6 @@ pa:
search: ਖੋਜੋ
sort:
pagination:
- total_html: "ਤੁਹਾਡੇ ਖੋਜ ਮਾਪਦੰਡ ਲਈ %{total} ਉਤਪਾਦ ਮਿਲੇ ਹਨ। %{from} ਤੋਂ %{to} ਦਿਖਾ ਰਹੇ ਹਨ।"
per_page:
show: ਵਿਖਾਓ
per_page: "%{num} ਪ੍ਰਤੀ ਪੇਜ"
@@ -1272,10 +1269,8 @@ pa:
contact_name: ਸੰਪਰਕ ਨਾਮ
edit:
editing: 'ਸੈਟਿੰਗਾਂ:'''
- back_link: ਐਂਟਰਪ੍ਰਾਈਜ਼ ਸੂਚੀ ਤੇ ਵਾਪਸ ਜਾਓ
new:
title: ਐਂਟਰਪ੍ਰਾਈਜ਼ਜ਼
- back_link: ਐਂਟਰਪ੍ਰਾਈਜ਼ ਸੂਚੀ ਤੇ ਵਾਪਸ ਜਾਓ
welcome:
welcome_title: ਓਪਨ ਫੂਡ ਨੈਟਵਰਕ ਵਿੱਚ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ!
welcome_text: ਤੁਸੀਂ ਸਫਲਤਾਪੂਰਵਕ ਇਹ ਬਣਾ ਲਿਆ ਹੈ
@@ -1312,6 +1307,8 @@ pa:
choose_products_from: "ਇਥੋਂ ਉਤਪਾਦ ਚੁਣੋ:"
re_notify_producers: ਉਤਪਾਦਕਾਂ ਨੂੰ ਦੁਬਾਰਾ ਸੂਚਿਤ ਕਰੋ
notify_producers_tip: ਇਹ ਹਰੇਕ ਉਤਪਾਦਕ ਨੂੰ ਉਹਨਾਂ ਦੇ ਆਰਡਰ ਦੀ ਸੂਚੀ ਦੇ ਨਾਲ ਇੱਕ ਈਮੇਲ ਭੇਜੇਗਾ।
+ date_time_warning_modal_content:
+ cancel: 'ਰੱਦ ਕਰੋ'
incoming:
incoming: "ਅੰਦਰ ਆਉਣ ਵਾਲੇ"
supplier: "ਸਪਲਾਇਰ"
@@ -2741,7 +2738,6 @@ pa:
spree_admin_single_enterprise_hint: "ਸੰਕੇਤ: ਲੋਕਾਂ ਨੂੰ ਤੁਹਾਨੂੰ ਲੱਭਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣ ਲਈ, ਇਸ ਦੇ ਹੇਠਾਂ ਆਪਣੀ ਦਿੱਖ ਨੂੰ ਚਾਲੂ ਕਰੋ"
spree_admin_eg_pickup_from_school: "ਜਿਵੇਂ ਕਿ 'ਪ੍ਰਾਇਮਰੀ ਸਕੂਲ ਤੋਂ ਪਿਕ-ਅੱਪ'"
spree_admin_eg_collect_your_order: "ਜਿਵੇਂ ਕਿ 'ਕਿਰਪਾ ਕਰਕੇ 123 ਇਮੇਜਿਨਰੀ ਸੇਂਟ, ਨੌਰਥਕੋਟ, 3070' ਤੋਂ ਆਪਣਾ ਆਰਡਰ ਲਵੋ"
- spree_classification_primary_taxon_error: "ਟੈਕਸਨ %{taxon}, %{product} ਦਾ ਪ੍ਰਾਇਮਰੀ ਟੈਕਸਨ ਹੈ ਅਤੇ ਇਸ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"
spree_order_availability_error: "ਵਿਤਰਕ ਜਾਂ ਆਰਡਰ ਸਾਈਕਲ ਤੁਹਾਡੇ ਕਾਰਟ ਵਿੱਚ ਉਤਪਾਦਾਂ ਦੀ ਸਪਲਾਈ ਨਹੀਂ ਕਰ ਸਕਦਾ"
spree_order_populator_error: "ਉਹ ਵਿਤਰਕ ਜਾਂ ਆਰਡਰ ਸਾਈਕਲ ਤੁਹਾਡੇ ਕਾਰਟ ਵਿੱਚ ਦਿੱਤੇ ਸਾਰੇ ਉਤਪਾਦਾਂ ਦੀ ਸਪਲਾਈ ਨਹੀਂ ਕਰ ਸਕਦਾ। ਕਿਰਪਾ ਕਰਕੇ ਕੋਈ ਹੋਰ ਚੁਣੋ।"
spree_order_cycle_error: "ਕਿਰਪਾ ਕਰਕੇ ਇਸ ਆਰਡਰ ਲਈ ਇੱਕ ਆਰਡਰ ਸਾਈਕਲ ਚੁਣੋ।"
@@ -3403,6 +3399,8 @@ pa:
confirmation: |
ਇਹ ਇਸ ਐਂਟਰਪ੍ਰਾਈਜ਼ ਲਈ ਉਹਨਾਂ ਸਾਰੇ ਉਤਪਾਦਾਂ ਦੇ ਸਟਾਕ ਪੱਧਰ ਨੂੰ ਜ਼ੀਰੋ ਤੇ ਸੇਟ ਕਰ ਦੇਵੇਗਾ ਜੋ ਅੱਪਲੋਡ ਕੀਤੀ ਫਾਈਲ ਵਿੱਚ ਮੌਜੂਦ ਨਹੀਂ ਹਨ।
order_cycles:
+ unsaved_changes: "ਤੁਹਾਡੇ ਕੋਲ ਸੇਵ ਨਾ ਕੀਤੀਆਂ ਤਬਦੀਲੀਆਂ ਹਨ"
+ bulk_save_error: "ਓ ਨਹੀਂ! ਮੈਂ ਤੁਹਾਡੇ ਬਦਲਾਵਾਂ ਨੂੰ ਸੇਵ ਕਰਨ ਵਿੱਚ ਅਸਮਰੱਥ ਰਿਹਾ।"
create_failure: "ਆਰਡਰ ਸਾਈਕਲ ਬਣਾਉਣ ਵਿੱਚ ਅਸਫਲ"
update_success: 'ਤੁਹਾਡਾ ਆਰਡਰ ਸਾਈਕਲ ਅੱਪਡੇਟ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ।'''
update_failure: "ਆਰਡਰ ਸਾਈਕਲ ਅੱਪਡੇਟ ਕਰਨ ਵਿੱਚ ਅਸਫਲ"
@@ -3550,7 +3548,6 @@ pa:
more: "ਹੋਰ"
new_adjustment: "ਨਵਾਂ ਸਮਾਯੋਜਨ"
new_tax_category: "ਨਵੀਂ ਟੈਕਸ ਸ਼੍ਰੇਣੀ"
- new_taxon: "ਨਵਾਂ ਟੈਕਸੋਨ"
new_user: "ਨਵਾਂ ਉਪਭੋਗਤਾ"
no_pending_payments: "ਕੋਈ ਬਕਾਇਆ ਭੁਗਤਾਨ ਨਹੀਂ ਹੈ"
remove: "Remove"
@@ -3569,8 +3566,6 @@ pa:
delivery: "ਦਸਤਖਤ ਕੀਤੇ, ਸੀਲ ਕੀਤੇ, ਡਿਲੀਵਰ ਕੀਤੇ ਗਏ"
start_date: "ਸ਼ੁਰੂ ਕਰਨ ਦੀ ਮਿਤੀ"
successfully_removed: "ਸਫਲਤਾਪੂਰਵਕ ਹਟਾਇਆ ਗਿਆ"
- taxonomy_edit: "ਟੈਕਸੋਨੌਮੀ ਸੰਪਾਦਨ"
- tree: "ਟ੍ਰੀ"
updating: "ਅੱਪਡੇਟ ਹੋ ਰਿਹਾ ਹੈ"
your_order_is_empty_add_product: "ਤੁਹਾਡਾ ਆਰਡਰ ਖਾਲੀ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਉਪਰ ਇੱਕ ਉਤਪਾਦ ਦੀ ਖੋਜ ਕਰੋ ਅਤੇ ਜੋੜੋ"
add_product: "ਉਤਪਾਦ ਜੋੜੋ"
@@ -3667,7 +3662,6 @@ pa:
tax_rate_amount_explanation: "ਟੈਕਸ ਦੀਆਂ ਦਰਾਂ ਗਣਨਾ ਵਿੱਚ ਸਹਾਇਤਾ ਲਈ ਇੱਕ ਦਸ਼ਮਲਵ ਰਕਮ ਹਨ, (ਜਿਵੇਂ ਕਿ ਜੇਕਰ ਟੈਕਸ ਦਰ 5% ਹੈ ਤਾਂ 0.05 ਦਰਜ ਕਰੋ)"
included_in_price: "ਕੀਮਤ ਵਿੱਚ ਸ਼ਾਮਲ"
show_rate_in_label: "ਲੇਬਲ ਵਿੱਚ ਦਰ ਦਿਖਾਓ"
- back_to_tax_rates_list: "ਟੈਕਸ ਦਰਾਂ ਦੀ ਸੂਚੀ ਤੇ ਵਾਪਸ"
tax_settings: "ਟੈਕਸ ਸੈਟਿੰਗਾਂ"
zones: "ਜ਼ੋਨਾਂ"
new_zone: "ਨਵਾਂ ਜ਼ੋਨ"
@@ -3680,14 +3674,11 @@ pa:
iso_name: "ISO ਨਾਂ"
states_required: "ਰਾਜਾਂ ਦੀ ਲੋੜ ਹੈ"
editing_country: "ਦੇਸ਼ ਦਾ ਸੰਪਾਦਨ"
- back_to_countries_list: "ਦੇਸ਼ਾਂ ਦੀ ਸੂਚੀ ਤੇ ਵਾਪਸ"
states: "ਰਾਜ"
abbreviation: "ਸੰਖਿਪਤ ਰੂਪ"
new_state: "ਨਵਾਂ ਰਾਜ"
payment_methods: "ਭੁਗਤਾਨ ਦੇ ਢੰਗ"
- taxonomies: "ਟੈਕਸੋਨੌਮੀਜ਼"
- new_taxonomy: "ਨਵਾਂ ਟੈਕਸੋਨੌਮੀ"
- back_to_taxonomies_list: "\"ਟੈਕਸਨੋਮੀਜ਼ ਸੂਚੀ ਤੇ ਵਾਪਸ"
+ taxons: "ਉਤਪਾਦ ਸ਼੍ਰੇਣੀਆਂ"
shipping_methods: "ਸ਼ਿਪਿੰਗ ਦੇ ਢੰਗ"
shipping_method: "ਸ਼ਿਪਿੰਗ ਦਾ ਤਰੀਕਾ"
shipment: "ਸ਼ਿਪਮੈਂਟ"
@@ -3845,7 +3836,6 @@ pa:
continue: "ਜਾਰੀ ਰੱਖੋ"
new:
new_return_authorization: "ਨਵਾਂ ਵਾਪਸੀ ਅਧਿਕਾਰ"
- back_to_return_authorizations_list: "ਵਾਪਸੀ ਅਧਿਕਾਰ ਸੂਚੀ ਤੇ ਵਾਪਸ"
continue: "ਜਾਰੀ ਰੱਖੋ"
edit:
receive: "ਪ੍ਰਾਪਤ ਕਰੋ"
@@ -4160,9 +4150,10 @@ pa:
total: "ਕੁੱਲ"
billing_address_name: "ਨਾਮ"
taxons:
+ index:
+ title: "ਉਤਪਾਦ ਸ਼੍ਰੇਣੀਆਂ"
form:
name: ਨਾਂ
- permalink: ਪਰਮਾਲਿੰਕ
description: ਵਰਣਨ
general_settings:
edit:
@@ -4400,7 +4391,6 @@ pa:
key_cleared: "ਕੁੰਜੀ ਹਟਾਈ ਗਈ"
shipment:
cannot_ready: "ਸ਼ਿਪਮੈਂਟ ਤਿਆਰ ਨਹੀਂ ਹੋ ਸਕਦੀ।"
- invalid_taxonomy_id: "ਅਵੈਧ ਟੈਕਸੋਨੌਮੀ ਆਈਡੀ।"
toggle_api_key_view: "ਉਪਭੋਗਤਾ ਲਈ API ਕੁੰਜੀ ਦ੍ਰਿਸ਼ ਵਿਖਾਓ"
unit: ਯੂਨਿਟ
per_unit: ਪ੍ਰਤੀ ਯੂਨਿਟ
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index c88ef74532..40ce862678 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -63,7 +63,6 @@ pl:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "musi być puste, ponieważ używane są ustawienia zapasów producenta"
- on_demand_but_count_on_hand_set: "musi być puste, jeśli na żądanie"
limited_stock_but_no_count_on_hand: "należy określić, z powodu ograniczonych zapasów"
messages:
blank: "nie może być puste"
@@ -286,7 +285,6 @@ pl:
password_confirmation: Potwierdzenie hasła
reset_password_token: Token resetowania hasła
expired: wygasł, poproś o nowy
- back_to_payments_list: "Powrót do listy płatności"
maestro_or_solo_cards: "Karty Maestro / Solo"
backordered: "Zamówienie zaległe"
on_hand: "Dostępne"
@@ -341,6 +339,8 @@ pl:
remove: Usuń
image:
edit: Edytuj
+ product_preview:
+ shop_tab: Sklep
begins_at: Początek o
begins_on: Początek się w dniu
customer: Klient
@@ -511,7 +511,6 @@ pl:
variants:
infinity: "Nieskończoność"
to_order_tip: "Przedmioty wykonane na zamówienie nie mają ustalonego poziomu zapasów, np. Świeże bochenki chleba na zamówienie."
- back_to_products_list: "Powrót do listy produktów"
editing_product: "Edycja produktu"
tabs:
product_details: "Szczegóły produktu"
@@ -933,10 +932,8 @@ pl:
contact_name: Nazwa Kontaktu
edit:
editing: 'Ustawienia:'
- back_link: Powrót do listy podmiotów
new:
title: Nowy podmiot
- back_link: Powrót do listy podmiotów
welcome:
welcome_title: Witamy w Open Food Network!
welcome_text: Pomyślnie utworzyłeś
@@ -967,6 +964,8 @@ pl:
back_to_list: "Powrót do listy"
save_and_back_to_list: "Zapisz i wróć do listy"
choose_products_from: "Wybierz produkty z:"
+ date_time_warning_modal_content:
+ cancel: 'Anuluj'
incoming:
incoming: "Przychodzący"
supplier: "Dostawca"
@@ -2173,7 +2172,6 @@ pl:
spree_admin_single_enterprise_hint: "Wskazówka: aby inni mogli Cię znaleźć, włącz widoczność poniżej"
spree_admin_eg_pickup_from_school: "np: 'Odbiór w Domu Kultury Krąg'"
spree_admin_eg_collect_your_order: "np. „Proszę odebrać zamówienie pod adresem Słowackiego 19, Poznań”"
- spree_classification_primary_taxon_error: "Takson %{taxon} jest głównym taksonem %{product} i nie można go usunąć"
spree_order_availability_error: "Dystrybutor lub cykl zamówień nie mogą dostarczyć produktów w Twoim koszyku"
spree_order_populator_error: "Ten dystrybutor lub cykl zamówień nie może dostarczyć wszystkich produktów w Twoim koszyku. Proszę wybierz inny."
spree_order_populator_availability_error: "Ten produkt nie jest dostępny u wybranego dystrybutora lub cyklu zamówień."
@@ -2444,7 +2442,6 @@ pl:
order_cycles_no_permission_to_coordinate_error: "Żaden z Twoich podmiotów nie ma uprawnień do koordynowania cyklu zamówień"
order_cycles_no_permission_to_create_error: "Nie masz uprawnień do tworzenia cyklu zamówień koordynowanego przez ten podmiot"
order_cycle_closed: "Wybrany cykl zamówień właśnie się zakończył. Proszę spróbuj ponownie!"
- back_to_orders_list: "Powrót do listy zamówień"
no_orders_found: "Nie znaleziono zamówień"
order_information: "Szczegóły zamówienia"
date_completed: "Data zakończenia"
@@ -2748,6 +2745,7 @@ pl:
confirmation: |
Spowoduje to ustawienie poziomu zapasów na zero dla wszystkich produktów tego podmiotu, których nie ma w przesłanym pliku.
order_cycles:
+ unsaved_changes: "Masz niezapisane zmiany"
create_failure: "Nie udało się utworzyć cyklu zamówień"
update_success: 'Twój cykl zamówień został zaktualizowany.'
update_failure: "Nie udało się zaktualizować cyklu zamówień"
@@ -3070,7 +3068,6 @@ pl:
tax_rate_amount_explanation: "Stawki podatku są kwotami dziesiętnymi, aby ułatwić obliczenia (tj. Jeśli stawka podatku wynosi 5%, wprowadź 0,05)"
included_in_price: "Wliczony w cenę"
show_rate_in_label: "Pokaż kurs na etykiecie"
- back_to_tax_rates_list: "Powrót do listy stawek podatkowych"
tax_settings: "Ustawienia podatkowe"
zones: "Strefy"
new_zone: "Nowa strefa"
@@ -3083,14 +3080,11 @@ pl:
iso_name: "Nazwa ISO"
states_required: "Województwo wymagane"
editing_country: "Edycja kraju"
- back_to_countries_list: "Powrót do listy krajów"
states: "Województwa"
abbreviation: "Skrót"
new_state: "Nowe województwo"
payment_methods: "Metody płatności"
- taxonomies: "Taksonomie"
- new_taxonomy: "Nowa taksonomia"
- back_to_taxonomies_list: "Powrót do listy taksonomii"
+ taxons: "Kategorie produktów"
shipping_methods: "Metody dostaw"
shipping_method: "Metoda dostawy"
payment: "Płatność"
@@ -3217,7 +3211,6 @@ pl:
continue: "Kontyntynuj"
new:
new_return_authorization: "Nowa autoryzacja zwrotu"
- back_to_return_authorizations_list: "Powrót do listy autoryzacji zwrotu"
continue: "Kontyntynuj"
edit:
receive: "otrzymać"
@@ -3481,6 +3474,8 @@ pl:
total: "Razem"
billing_address_name: "Nazwa"
taxons:
+ index:
+ title: "Kategorie produktów"
form:
name: Nazwa
description: Opis
@@ -3656,7 +3651,6 @@ pl:
key_cleared: "Klucz wyczyszczony"
shipment:
cannot_ready: "Nie można przygotować wysyłki."
- invalid_taxonomy_id: "Nieprawidłowy identyfikator taksonomii."
activerecord:
models:
spree/payment:
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index bc8ab99d9d..746d9b6cf0 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -68,7 +68,6 @@ pt:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "deve ser vazio dado estar a usar as configurações do produtor"
- on_demand_but_count_on_hand_set: "deve ser vazio dado estar sob encomenda"
limited_stock_but_no_count_on_hand: "deve ser definido dado não estar sob encomenda"
messages:
blank: "não pode ser vazio"
@@ -317,7 +316,6 @@ pt:
password_confirmation: Confirmação de Palavra-passe
reset_password_token: Redefinir palavra-passe
expired: expirou, por favor peça uma nova
- back_to_payments_list: "Voltar à lista de pagamentos"
maestro_or_solo_cards: "Cartões Maestro/Solo"
backordered: "Encomendado"
on_hand: "Disponível"
@@ -382,6 +380,8 @@ pt:
remove: Remover
image:
edit: Editar
+ product_preview:
+ shop_tab: Loja
begins_at: Começa às
begins_on: Começa em
customer: Consumidor/a
@@ -566,7 +566,6 @@ pt:
variants:
infinity: "Infinito"
to_order_tip: "Os itens feitos por encomenda não têm um nível de stock definido, como pão fresco, por exemplo."
- back_to_products_list: "Voltar à lista de produtos"
editing_product: "Editando um Produto"
tabs:
product_details: "Detalhes do Produto"
@@ -1025,10 +1024,8 @@ pt:
contact_name: Nome do contacto
edit:
editing: 'Configurações'
- back_link: Voltar à lista de organizações
new:
title: Nova Organização
- back_link: Voltar à lista de organizações
welcome:
welcome_title: Bem-vindo à Open Food Network!
welcome_text: Você criou com sucesso uma
@@ -1063,6 +1060,8 @@ pt:
back_to_list: "Voltar à Lista"
save_and_back_to_list: "Guardar e Voltar à Lista"
choose_products_from: "Escolha produtos de:"
+ date_time_warning_modal_content:
+ cancel: 'Cancelar'
incoming:
incoming: "Entrada"
supplier: "Fornecedor"
@@ -2299,7 +2298,6 @@ pt:
spree_admin_single_enterprise_hint: "Dica: Para permitir que as pessoas te encontrem, ative sua visibilidade em"
spree_admin_eg_pickup_from_school: "ex: \"Levantar na Escola Primária\""
spree_admin_eg_collect_your_order: "ex: \"Por favor levante a sua encomenda na Rua Imaginária, nº 123, 3070\""
- spree_classification_primary_taxon_error: "A Taxon %{taxon}é a taxon primária de %{product} e não pode ser apagada."
spree_order_availability_error: "O distribuidor ou ciclo de encomendas não pode fornecer os produtos do seu carrinho"
spree_order_populator_error: "Esse distribuidor ou ciclo de encomendas não pode fornecer todos os produtos do seu carrinho. Por favor escolha outro."
spree_order_populator_availability_error: "Esse produto não está disponível no distribuidor ou ciclo de encomendas selecionado."
@@ -2575,7 +2573,7 @@ pt:
order_cycles_bulk_update_notice: 'Os ciclos de encomendas foram actualizados.'
order_cycles_no_permission_to_coordinate_error: "Nenhuma das suas organizações tem permissão para coordenar um ciclo de encomendas."
order_cycles_no_permission_to_create_error: "Não tem permissão para criar um ciclo de encomendas coordenado por essa organização."
- back_to_orders_list: "Voltar à lista de encomendas"
+ back_to_orders_list: "Voltar à Lista de Encomendas"
no_orders_found: "Nenhuma encomenda encontrada"
order_information: "Informação da Encomenda"
new_payment: "Novo Pagamento"
@@ -2861,6 +2859,8 @@ pt:
confirmation: |
Isto colocará a zero o stock de todos os produtos desta organização que não estejam presentes no ficheiro carregado.
order_cycles:
+ unsaved_changes: "Tem alterações por guardar"
+ bulk_save_error: "Oh não! Não conseguimos guardar as suas alterações."
create_failure: "Falhou a criação do ciclo de encomendas"
update_success: 'O seu ciclo de encomendas foi actualizado.'
update_failure: "Falhou a atualização do ciclo de encomendas"
@@ -3100,7 +3100,6 @@ pt:
tax_rate_amount_explanation: "Taxas de Imposto são uma quantidade decimal que suportam o cálculo (por exemplo, se a taxa de imposto for 5%, insira 0.05)"
included_in_price: "Incluído no Preço"
show_rate_in_label: "Mostrar taxa na etiqueta"
- back_to_tax_rates_list: "Voltar à lista de Taxas de Imposto"
tax_settings: "Configurações de Impostos"
zones: "Zonas"
new_zone: "Nova Zona"
@@ -3113,14 +3112,11 @@ pt:
iso_name: "Nome ISO"
states_required: "Regiões obrigatórias"
editing_country: "Editar País"
- back_to_countries_list: "Voltar à Lista de Países"
states: "Regiões"
abbreviation: "Abreviatura"
new_state: "Nova Região"
payment_methods: "Métodos de pagamento"
- taxonomies: "Taxonomias"
- new_taxonomy: "Nova Taxonomia"
- back_to_taxonomies_list: "Voltar à Lista de Taxonomias"
+ taxons: "Categorias de Produtos"
shipping_methods: "Métodos de Envio"
shipping_method: "Método de Envio"
shipment: "Envio"
@@ -3480,6 +3476,8 @@ pt:
total: "Total"
billing_address_name: "Nome"
taxons:
+ index:
+ title: "Categorias de Produtos"
form:
name: Nome
description: Descrição
diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml
index 26b7bbfa2d..2c47f965b5 100644
--- a/config/locales/pt_BR.yml
+++ b/config/locales/pt_BR.yml
@@ -66,7 +66,6 @@ pt_BR:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "deve estar em branco porque está usando configurações de estoque do produtor"
- on_demand_but_count_on_hand_set: "deve ficar em branco se sob demanda"
limited_stock_but_no_count_on_hand: "deve ser especificado porque está forçando o estoque limitado"
messages:
blank: "Não pode ser vazio"
@@ -345,7 +344,7 @@ pt_BR:
password_confirmation: Confirmação de senha
reset_password_token: Redefinir chave de senha
expired: expirou, por favor solicite um novo
- back_to_payments_list: "voltar para lista de pagamento"
+ back_to_payments_list: "Voltar pra Lista de Pagamentos"
maestro_or_solo_cards: "Cartões Maestro / Solo"
backordered: "Pedidos em atraso"
on_hand: "Disponível"
@@ -410,6 +409,8 @@ pt_BR:
remove: Remover
image:
edit: Editar
+ product_preview:
+ shop_tab: Comprar
adjustments:
skipped_changing_canceled_order: "Não é possível modificar um pedido cancelado"
begins_at: Começa em
@@ -608,7 +609,6 @@ pt_BR:
variants:
infinity: "Infinidade"
to_order_tip: "Os itens feitos por encomenda não têm um nível de estoque definido, como pão fresco, por exemplo."
- back_to_products_list: "Voltar à lista de produtos"
editing_product: "Editando Produto"
tabs:
product_details: "Detalhes do Produto"
@@ -1064,10 +1064,8 @@ pt_BR:
contact_name: Nome para contato
edit:
editing: 'Configurações:'
- back_link: Voltar à lista de iniciativas
new:
title: Nova iniciativa
- back_link: Voltar à lista de iniciativas
welcome:
welcome_title: Bem-vindo à Ajunta!
welcome_text: Você criou com sucesso uma
@@ -1102,6 +1100,8 @@ pt_BR:
back_to_list: "Voltar Para a Lista"
save_and_back_to_list: "Salvar e Voltar para a Lista"
choose_products_from: "Escolha produtos de:"
+ date_time_warning_modal_content:
+ cancel: 'Cancelar'
incoming:
incoming: "Entrada"
supplier: "Fornecedor"
@@ -2403,7 +2403,6 @@ pt_BR:
spree_admin_single_enterprise_hint: "Dica: Para permitir que as pessoas te encontrem, ative sua visibilidade em"
spree_admin_eg_pickup_from_school: "ex: 'Buscar na Escola'"
spree_admin_eg_collect_your_order: "ex: 'Por favor, colete seu pedido na Rua dos Sonhos, 123, casa 5, Bairro Liberdade"
- spree_classification_primary_taxon_error: "O táxon %{taxon} é o táxon principal de %{product} e não pode ser excluído"
spree_order_availability_error: "O distribuidor ou o ciclo de pedidos não pode fornecer os produtos no seu carrinho"
spree_order_populator_error: "Distribuidor ou ciclo de pedidos não pode fornecer os produtos no seu carrinho. Por favor, escolha outro."
spree_order_cycle_error: "Favor escolher um ciclo de pedidos para este pedido"
@@ -2685,7 +2684,7 @@ pt_BR:
order_cycles_no_permission_to_coordinate_error: "Nenhuma das suas iniciativas tem permissão para coordenar um ciclo de pedidos"
order_cycles_no_permission_to_create_error: "Você não tem permissão para criar um ciclo de pedidos coordenado por esta iniciativa"
order_cycle_closed: "O ciclo de pedidos selecionado acabou de fechar, por favor tente novamente depois!"
- back_to_orders_list: "Voltar à lista de pedidos"
+ back_to_orders_list: "Voltar Para Lista de Pedidos"
no_orders_found: "Nenhum pedido encontrado"
order_information: "Informações sobre pedidos"
new_payment: "Novo Pagamento"
@@ -3009,6 +3008,8 @@ pt_BR:
Isso ajustará o nível de estoque para zero em todos os produtos para esta
iniciativa que não está presente no arquivo carregado.
order_cycles:
+ unsaved_changes: "Você possui alterações não salvas"
+ bulk_save_error: "Ah não! Não consegui salvar suas alterações."
create_failure: "Falha ao criar o ciclo do pedidos"
update_success: 'O seu ciclo de pedidos foi atualizado.'
update_failure: "Falha ao atualizar o ciclo do pedidos"
@@ -3241,7 +3242,6 @@ pt_BR:
more: "Mais"
new_adjustment: "Novo ajuste"
new_tax_category: "Nova Categoria de Taxa"
- new_taxon: "Nova taxonomia"
new_user: "Novo usuário"
no_pending_payments: "Nenhum pagamento pendente"
remove: "Remover"
@@ -3255,8 +3255,6 @@ pt_BR:
server_error: "Erro de servidor"
start_date: "Data de início"
successfully_removed: "Removido com Sucesso"
- taxonomy_edit: "Editar Taxonomia"
- tree: "Árvore"
updating: "Atualizando"
your_order_is_empty_add_product: "Seu pedido está vazio, pesquise e adicione um produto acima"
add_product: "Adicionar produto"
@@ -3351,7 +3349,6 @@ pt_BR:
tax_rate_amount_explanation: "As alíquotas são um valor decimal para ajudar nos cálculos (por exemplo, se a alíquota for de 5%, digite 0,05)"
included_in_price: "Incluído no preço"
show_rate_in_label: "Mostrar taxa no rótulo"
- back_to_tax_rates_list: "Voltar à lista de alíquotas."
tax_settings: "Configurações de Taxas"
zones: "Zonas"
new_zone: "Nova Zona"
@@ -3364,14 +3361,10 @@ pt_BR:
iso_name: "Nome ISO"
states_required: "Estados Necessários"
editing_country: "Editando País"
- back_to_countries_list: "Voltar à lista de países"
states: "Estados"
abbreviation: "Abreviação"
new_state: "Estado novo"
payment_methods: "Métodos de pagamento"
- taxonomies: "Taxonomias"
- new_taxonomy: "Nova taxonomia"
- back_to_taxonomies_list: "Voltar à lista de taxonomias"
shipping_methods: "Métodos de envio"
shipping_method: "Método de envio"
shipment: "Envio"
@@ -3525,7 +3518,6 @@ pt_BR:
continue: "Continuar"
new:
new_return_authorization: "Nova Autorização de Retorno"
- back_to_return_authorizations_list: "Voltar Para Lista de Autorização de Retorno"
continue: "Continuar"
edit:
receive: "receber"
@@ -3812,7 +3804,6 @@ pt_BR:
taxons:
form:
name: Nome
- permalink: Permalink
description: Descrição
general_settings:
edit:
@@ -4029,7 +4020,6 @@ pt_BR:
key_cleared: "Chave apagada"
shipment:
cannot_ready: "Não é possível completar a entrega."
- invalid_taxonomy_id: "Id invalido de taxonomia"
activerecord:
models:
spree/payment:
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index a442599358..4d9dc86bbf 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -81,8 +81,6 @@ ru:
white_label_logo_link: "Ссылка на логотип, используемый на витрине магазина"
errors:
models:
- enterprise_fee:
- inherit_tax_requires_per_item_calculator: "Для наследования налоговой категории требуется поэлементный калькулятор."
spree/image:
attributes:
attachment:
@@ -106,7 +104,6 @@ ru:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "должно быть пустым, потому что используются настройки склада производителя"
- on_demand_but_count_on_hand_set: "должен быть пустым, если по требованию'"
limited_stock_but_no_count_on_hand: "необходимо указать, поскольку принудительный ограниченный запас"
messages:
confirmation: "не соответствует %{attribute}"
@@ -476,7 +473,7 @@ ru:
password_confirmation: Подтверждение Пароля
reset_password_token: Сброс пароля токена
expired: истёк, пожалуйста запросите новый
- back_to_payments_list: "Назад к Списку Платежей"
+ back_to_payments_list: "Вернуться К Списку Платежей"
maestro_or_solo_cards: "Дебитовые карты"
backordered: "Предзаказано"
on_hand: "В наличии"
@@ -549,6 +546,8 @@ ru:
remove: Удалить
image:
edit: Изменить
+ product_preview:
+ shop_tab: Магазин
adjustments:
skipped_changing_canceled_order: "Вы не можете изменить отмененный заказ."
begins_at: Начинается С
@@ -759,7 +758,6 @@ ru:
variants:
infinity: "Безграничный"
to_order_tip: "Товары, изготовленные на заказ, не имеют определенного уровня запасов, например, буханки хлеба, приготовленные на заказ."
- back_to_products_list: "Назад к списку товаров"
editing_product: "Изменение Товара"
tabs:
product_details: "Информация о Товаре"
@@ -797,7 +795,6 @@ ru:
search: Поиск
sort:
pagination:
- total_html: "%{total} товаров найдено по вашим критериям поиска. Показаны %{from} до %{to} ."
per_page:
show: Показывать
per_page: "%{num} на странице"
@@ -1341,10 +1338,8 @@ ru:
contact_name: Имя Контакта
edit:
editing: 'Настройки:'
- back_link: Назад к списку Предприятий
new:
title: Новое Предприятие
- back_link: Назад к списку Предприятий
welcome:
welcome_title: Добро пожаловать в Открытую Сеть Продуктов!
welcome_text: Вы успешно создали
@@ -1381,6 +1376,8 @@ ru:
choose_products_from: "Выбрать Товары Из:"
re_notify_producers: Повторно уведомить производителей
notify_producers_tip: Каждому производителю будет отправлено электронное письмо со списком их заказов.
+ date_time_warning_modal_content:
+ cancel: 'Выход'
incoming:
incoming: "Входящие"
supplier: "Поставщик"
@@ -2842,7 +2839,6 @@ ru:
spree_admin_single_enterprise_hint: "Подсказка: чтобы люди могли вас найти, включите видимость в"
spree_admin_eg_pickup_from_school: "напр. 'Самовывоз у школы'"
spree_admin_eg_collect_your_order: "напр. 'Пожалуйста, заберите свой заказ по адресу: ул. Школьная д.1, Воронеж'"
- spree_classification_primary_taxon_error: "Taxon %{taxon} is the primary taxon of %{product} and cannot be deleted"
spree_order_availability_error: "Дистрибьютор или цикл заказа не могут поставить продукты в Вашей корзине"
spree_order_populator_error: "Этот дистрибьютор или цикл заказа не может поставить все продукты в Вашей корзине. Пожалуйста, выберите другой."
spree_order_cycle_error: "Выберите цикл для этого заказа."
@@ -3162,7 +3158,7 @@ ru:
order_cycles_no_permission_to_coordinate_error: "Ни одно из ваших Предприятий не имеет разрешения координировать цикл заказа"
order_cycles_no_permission_to_create_error: "У вас нет разрешения на создание цикла заказов, координируемого этим Предприятием"
order_cycle_closed: "Выбранный вами цикл заказов закрылся. Пожалуйста, попробуйте еще раз!"
- back_to_orders_list: "Назад к списку заказов"
+ back_to_orders_list: "Назад К Списку Заказов"
no_orders_found: "Заказов Не Найдено"
order_information: "Информация по Заказу"
new_payment: "Новый Платёж"
@@ -3513,6 +3509,8 @@ ru:
Это установит нулевой уровень запасов для всех продуктов этого
предприятия, которых нет в загруженном файле.
order_cycles:
+ unsaved_changes: "Есть не сохраненные изменения"
+ bulk_save_error: "Ой! Не удалось сохранить Ваши изменения"
create_failure: "Не удалось создать цикл заказа"
update_success: 'Ваш цикл заказа был обновлен.'
update_failure: "Не удалось обновить цикл заказа"
@@ -3783,7 +3781,6 @@ ru:
more: "Ещё"
new_adjustment: "Новая корректировка"
new_tax_category: "Новая Налоговая Категория"
- new_taxon: "Новая таксономия"
new_user: "Новый пользователь"
no_pending_payments: "Нет ожидающих платежей"
remove: "Удалить"
@@ -3802,10 +3799,6 @@ ru:
delivery: "Подписано, запечатано, доставлено"
start_date: "Дата начала"
successfully_removed: "Успешно удалено"
- taxonomy_edit: "Изменить таксономию"
- taxonomy_tree_error: "Произошла ошибка при обновлении дерева таксономии."
- taxonomy_tree_instruction: "Щелкните правой кнопкой мыши элемент, чтобы добавить, переименовать, удалить или отредактировать."
- tree: "Дерево"
updating: "Обновление"
your_order_is_empty_add_product: "Ваша корзина пуста, пожалуйста, найдите и добавьте товар выше"
add_product: "Добавить Товар"
@@ -3902,7 +3895,6 @@ ru:
tax_rate_amount_explanation: "Налоговые ставки представляют собой десятичную сумму для помощи в расчетах (т.е. если налоговая ставка составляет 5%, введите 0,05)"
included_in_price: "Включено в Стоимость"
show_rate_in_label: "Показывать ставку в метке"
- back_to_tax_rates_list: "Назад к Списку Налоговых Ставок"
tax_settings: "Настройки Налогов"
zones: "Торговая зона"
new_zone: "Новая Торговая зона"
@@ -3915,14 +3907,11 @@ ru:
iso_name: "ISO Имя"
states_required: "Области Обязательны"
editing_country: "Редактирование Страны"
- back_to_countries_list: "Назад к Списку Стран"
states: "Регионы"
abbreviation: "Сокращение"
new_state: "Новый Регион"
payment_methods: "Способы Оплаты"
- taxonomies: "Таксономии"
- new_taxonomy: "Новая Таксономия"
- back_to_taxonomies_list: "Назад к Списку Таксономий"
+ taxons: "Категории Товаров"
shipping_methods: "Способы Доставки"
shipping_method: "Способ Доставки"
shipment: "Доставка"
@@ -4082,7 +4071,6 @@ ru:
continue: "Продолжить"
new:
new_return_authorization: "Новое разрешение на возврат"
- back_to_return_authorizations_list: "Назад К Списку Разрешений На Возврат"
continue: "Продолжить"
edit:
receive: "получить"
@@ -4329,6 +4317,7 @@ ru:
product_name: Имя Товара
primary_taxon_form:
product_category: Категория Товара
+ search_for_categories: "Поиск категорий"
group_buy_form:
group_buy: "Групповая покупка?"
bulk_unit_size: Размер оптовой еденицы
@@ -4406,9 +4395,10 @@ ru:
total: "Всего"
billing_address_name: "Название"
taxons:
+ index:
+ title: "Категории Товаров"
form:
name: Название
- permalink: Постоянная ссылка
description: Описание
general_settings:
edit:
@@ -4647,7 +4637,6 @@ ru:
key_cleared: "Ключ очищен"
shipment:
cannot_ready: "Не может готовая отгрузка."
- invalid_taxonomy_id: "Неверный ID таксономии."
toggle_api_key_view: "Показать ключ API для пользователя"
activerecord:
models:
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index bd04ceb7bd..ddac7dc728 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -180,6 +180,8 @@ sv:
remove: Ta bort
image:
edit: Redigera
+ product_preview:
+ shop_tab: 'Butik '
customer: Kund
date: Datum
email: epost
@@ -613,11 +615,8 @@ sv:
owner_tip: Den primära användaren är ansvarig för detta företag.
i_am_producer: Jag är en Tillverkare
contact_name: Kontaktperson
- edit:
- back_link: Åter till företagslistan
new:
title: Nya företag
- back_link: Åter till företagslistan
welcome:
welcome_title: Välkommen till OFN!
welcome_text: Du har korrekt slutfört en
@@ -638,6 +637,8 @@ sv:
next: "Näst"
cancel: "Avbryt"
choose_products_from: "Välj produkter från:"
+ date_time_warning_modal_content:
+ cancel: 'Avbryt'
incoming:
incoming: "Inkommande"
supplier: "Leverantör"
@@ -1595,7 +1596,6 @@ sv:
spree_admin_single_enterprise_hint: "Tips: För att folk skall hitta dig lättare, slå på din reklam under"
spree_admin_eg_pickup_from_school: "t.ex. \"Upphämtning från grundskolan\""
spree_admin_eg_collect_your_order: "t.ex. \"Var snäll och samla din beställning från Exempelgatan, 100 00 Stad '"
- spree_classification_primary_taxon_error: "Gruppen %{taxon} är den primära gruppen för %{product} och kan inte raderas"
spree_order_availability_error: "Distributören eller beställningsomgången kan inte leverera produkterna i din kundvagn"
spree_order_populator_error: "Denna distributör eller beställningsomgång kan inte leverera alla produkter i din kundvagn. Vänligen välj en annan."
spree_order_populator_availability_error: "Den produkten är inte tillgänglig från den valda distributören eller denna beställningsomgång."
@@ -2085,6 +2085,8 @@ sv:
confirmation: |
Detta kommer att ställa lagersaldot till noll på alla produkter för detta företag, som inte är närvarande i den uppladdade filen.
order_cycles:
+ unsaved_changes: "Du har osparade ändringar"
+ bulk_save_error: "Å nej! Jag kunde inte spara dina ändringar."
update_success: 'Din beställningsomgång har uppdaterats.'
no_distributors: Det finns inga distributörer i denna beställningsomgång. Den kommer inte att vara synlig för kunderna tills du lägger till en distributör. Vill du fortsätta och spara denna beställningsomgång? '
enterprises:
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index e9525c3929..1c7d15f1cc 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -68,7 +68,6 @@ tr:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "Boş bırakılmalı çünkü üretici stok ayarları kullanılıyor"
- on_demand_but_count_on_hand_set: "talep üzerine is boş bırakılmalıdır"
limited_stock_but_no_count_on_hand: "Sınırlı stok durumundan dolayı belirtilmeli"
messages:
blank: "boş olamaz"
@@ -390,6 +389,8 @@ tr:
remove: Kaldır
image:
edit: Düzenle
+ product_preview:
+ shop_tab: DÜKKAN
adjustments:
skipped_changing_canceled_order: "İptal edilmiş bir siparişi değiştiremezsiniz."
begins_at: Başlangıç
@@ -588,7 +589,6 @@ tr:
variants:
infinity: "Sonsuz"
to_order_tip: "Sipariş üzerine yapılan ürünlerin, belirlenmiş stok seviyeleri yoktur."
- back_to_products_list: "Ürün listesine geri dön"
editing_product: "Ürün Düzenleme"
tabs:
product_details: "Ürün Detayları"
@@ -1053,10 +1053,8 @@ tr:
contact_name: İLETİŞİM Kurulacak KİŞİ
edit:
editing: 'Ayarlar:'
- back_link: İşletmeler LİSTESİNE gerİ dön
new:
title: Yeni İşletme
- back_link: İşletmeler LİSTESİNE gerİ dön
welcome:
welcome_title: Açık Gıda Ağı'na Hoşgeldiniz!
welcome_text: 'BAŞARILI ŞEKİLDE OLUŞTURULDU:'
@@ -1091,6 +1089,8 @@ tr:
back_to_list: "Listeye geri dön"
save_and_back_to_list: "KAYDET VE LİSTEYE DÖN"
choose_products_from: "Ürünlerİ Buradan SeÇ:"
+ date_time_warning_modal_content:
+ cancel: 'İptal et'
incoming:
incoming: "Gelen"
supplier: "TEDARİKÇİ"
@@ -2415,7 +2415,6 @@ tr:
spree_admin_single_enterprise_hint: "İpucu: İnsanların sizi bulmasına izin vermek için 'Görünür' olmayı ayarlamayı unutmayın:"
spree_admin_eg_pickup_from_school: "Örn. 'Teslimat noktası: Moda İlkokulu Bahçesi'"
spree_admin_eg_collect_your_order: "Örn. Lütfen siparişinizi Moda Cad. No:17 Temiz Dükkan'dan teslim alınız."
- spree_classification_primary_taxon_error: "%{taxon} cinsi, %{product}ürününün birincil cinsidir ve silinemez"
spree_order_availability_error: "Dağıtımcı veya sipariş dönemi sepetinizdeki ürünleri tedarik edemiyor"
spree_order_populator_error: "Bu dağıtımcı veya sipariş dönemi, sepetinizdeki tüm ürünleri tedarik edemiyor. Lütfen başka birini seçin."
spree_order_cycle_error: "Bu sipariş için bir sipariş dönemi seçin."
@@ -2699,7 +2698,7 @@ tr:
order_cycles_no_permission_to_coordinate_error: "Hiçbir işletmenizin sipariş dönemini koordine etme izni yok"
order_cycles_no_permission_to_create_error: "Bu işletme tarafından koordine edilen bir sipariş dönemi oluşturma izniniz yok"
order_cycle_closed: "Seçmiş olduğunuz sipariş dönemi az önce kapandı. Lütfen daha sonra tekrar deneyin :("
- back_to_orders_list: "Sipariş listesine geri dön"
+ back_to_orders_list: "SİPARİŞLER LİSTESİNE GERİ DÖN"
no_orders_found: "SİPARİŞ BULUNAMADI"
order_information: "Sipariş Bilgisi"
new_payment: "Yeni Ödeme"
@@ -3025,6 +3024,8 @@ tr:
Yüklenen dosyada bulunmayan tüm işletmeler için
tüm ürünlerin stok seviyelerini sıfır olarak ayar.
order_cycles:
+ unsaved_changes: "kaydedilmemiş değişiklikleriniz var"
+ bulk_save_error: "Pardon! Yaptığınız değişiklikleri kaydedemedim."
create_failure: "Sipariş dönemi oluşturulamadı"
update_success: 'Sipariş döneminiz güncellendi.'
update_failure: "Sipariş dönemi güncellenemedi"
@@ -3238,7 +3239,6 @@ tr:
more: "Daha Fazla"
new_adjustment: "Yeni düzenleme"
new_tax_category: "Yeni Vergi Kategorisi"
- new_taxon: "Yeni kategori"
new_user: "Yeni kullanıcı"
no_pending_payments: "Bekleyen ödeme yok"
remove: "Kaldır"
@@ -3253,8 +3253,6 @@ tr:
server_error: "Server hatası"
start_date: "Başlangıç tarihi"
successfully_removed: "Başarıyla Kaldırıldı"
- taxonomy_edit: "Kategori düzenleme"
- tree: "Ağaç"
updating: "Güncelleniyor"
your_order_is_empty_add_product: "Sepetiniz boş, lütfen bir ürün arayın ve ekleyin"
add_product: "ürün ekle"
@@ -3349,7 +3347,6 @@ tr:
tax_rate_amount_explanation: "Vergi oranları ondalık bir tutar olmalı (yani vergi oranı % 5 ise 0.05 girin)"
included_in_price: "Fiyata Dahil"
show_rate_in_label: "Oranı etikette göster"
- back_to_tax_rates_list: "Vergi Oranları Listesine Geri Dön"
tax_settings: "Vergi Ayarları"
zones: "bölgeler"
new_zone: "Yeni Bölge"
@@ -3362,14 +3359,11 @@ tr:
iso_name: "ISO Adı"
states_required: "Şehİr Gerekli"
editing_country: "Ülkeyi Düzenle"
- back_to_countries_list: "Ülke Listesine Geri Dön"
states: "Şehİrler"
abbreviation: "Kısaltma"
new_state: "Yeni Şehir"
payment_methods: "ÖDEME YÖNTEMLERİ"
- taxonomies: "KATEGORİ"
- new_taxonomy: "YENİ KATEGORİ"
- back_to_taxonomies_list: "Kategori Listesine Geri Dön"
+ taxons: "Ürün Kategorileri"
shipping_methods: "TESLİMAT YÖNTEMLERİ"
shipping_method: "TESLİMAT YÖNTEMİ"
shipment: "Teslimat"
@@ -3523,7 +3517,6 @@ tr:
continue: "Devam et"
new:
new_return_authorization: "Yeni İade Yetkisi"
- back_to_return_authorizations_list: "İade Yetkisi Listesine Geri Dön"
continue: "Devam et"
edit:
receive: "Al"
@@ -3813,9 +3806,10 @@ tr:
total: "Toplam"
billing_address_name: "Ad"
taxons:
+ index:
+ title: "Ürün Kategorileri"
form:
name: Ad
- permalink: Permalink
description: Açıklama
general_settings:
edit:
@@ -4035,7 +4029,6 @@ tr:
key_cleared: "Anahtar temizlendi"
shipment:
cannot_ready: "Gönderim hazırlanamıyor."
- invalid_taxonomy_id: "Geçersiz kategori kimliği."
activerecord:
models:
spree/payment:
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index a60b0cef26..58c2732fa7 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -70,7 +70,6 @@ uk:
variant_override:
count_on_hand:
using_producer_stock_settings_but_count_on_hand_set: "має бути порожнім, оскільки використовуються налаштування запасів виробника"
- on_demand_but_count_on_hand_set: "має бути порожнім, якщо на вимогу"
limited_stock_but_no_count_on_hand: "необхідно вказати, оскільки запаси обмежені"
messages:
blank: "не може бути порожнім"
@@ -474,6 +473,8 @@ uk:
remove: Видалити
image:
edit: Редагувати
+ product_preview:
+ shop_tab: Магазин
adjustments:
skipped_changing_canceled_order: "Ви не можете змінити скасоване замовлення."
begins_at: Починається о
@@ -675,7 +676,6 @@ uk:
variants:
infinity: "Нескінченність"
to_order_tip: "Товари, виготовлені на замовлення, не мають встановленого рівня запасів, наприклад, хліб, свіжий на замовлення."
- back_to_products_list: "Повернутися до списку продуктів"
editing_product: "Редагування продукту"
tabs:
product_details: "Деталі продукту"
@@ -1168,10 +1168,8 @@ uk:
contact_name: Контактна Особа
edit:
editing: 'Налаштування:'
- back_link: Повернутися до списку підприємств
new:
title: Нове підприємство
- back_link: Повернутися до списку підприємств
welcome:
welcome_title: Ласкаво просимо до Open Food Network!
welcome_text: 'Ви успішно створили '
@@ -1208,6 +1206,8 @@ uk:
choose_products_from: "Виберіть продукти з:"
re_notify_producers: Повторно повідомте виробників
notify_producers_tip: Це надішле електронний лист кожному виробнику зі списком їхніх замовлень.
+ date_time_warning_modal_content:
+ cancel: 'Скасувати'
incoming:
incoming: "Вхідні"
supplier: "Постачальник"
@@ -2577,7 +2577,6 @@ uk:
spree_admin_single_enterprise_hint: "Підказка: щоб люди могли вас знайти, увімкніть свою видимість під"
spree_admin_eg_pickup_from_school: "напр. «Забір із першої школи»"
spree_admin_eg_collect_your_order: "напр. \"Будь ласка, заберіть своє замовлення за адресою: 123 Imaginary St, Northcote \";"
- spree_classification_primary_taxon_error: "Таксон %{taxon} є основним таксоном %{product} і не може бути видалений"
spree_order_availability_error: "Дистриб’ютор або цикл замовлення не можуть надати продукти у вашому кошику"
spree_order_populator_error: "Цей дистриб’ютор або цикл замовлення не може забезпечити всі продукти у вашому кошику. Виберіть інший."
spree_order_cycle_error: "Будь ласка, виберіть цикл замовлення для цього замовлення."
@@ -2871,7 +2870,7 @@ uk:
order_cycles_no_permission_to_coordinate_error: "Жодне з ваших підприємств не має дозволу на координацію циклу замовлення"
order_cycles_no_permission_to_create_error: "У вас немає дозволу на створення циклу замовлення, який координує це підприємство"
order_cycle_closed: "Вибраний вами цикл замовлення щойно закрито. Будь ласка спробуйте ще раз!"
- back_to_orders_list: "Повернутися до списку замовлень"
+ back_to_orders_list: "Назад до списку замовлень"
no_orders_found: "Замовлень не знайдено"
order_information: "Інформація про замовлення"
new_payment: "Нова оплата"
@@ -3204,6 +3203,8 @@ uk:
confirmation: |
Це призведе до нульового рівня запасів для всіх продуктів для цього підприємства, яких немає в завантаженому файлі.
order_cycles:
+ unsaved_changes: "У вас є незбережені зміни"
+ bulk_save_error: "О ні! Мені не вдалося зберегти ваші зміни."
create_failure: "Не вдалося створити цикл замовлення"
update_success: 'Ваш цикл замовлення оновлено.'
update_failure: "Не вдалося оновити цикл замовлення"
@@ -3464,7 +3465,6 @@ uk:
more: "Більше"
new_adjustment: "Нове коригування"
new_tax_category: "Нова податкова категорія"
- new_taxon: "Новий таксон"
new_user: "Новий користувач"
no_pending_payments: "Немає незавершених платежів"
remove: "Видалити"
@@ -3481,8 +3481,6 @@ uk:
UPS Ground: "UPS наземна"
start_date: "Дата початку"
successfully_removed: "Успішно видалено"
- taxonomy_edit: "Редагування таксономії"
- tree: "Дерево"
updating: "Оновлення"
your_order_is_empty_add_product: "Ваше замовлення порожнє, знайдіть і додайте продукт вище"
add_product: "Додати продукт"
@@ -3577,7 +3575,6 @@ uk:
tax_rate_amount_explanation: "Ставки податку – це десяткова сума, яка допомагає під час розрахунків (тобто, якщо ставка податку становить 5%, введіть 0,05)"
included_in_price: "Входить у вартість"
show_rate_in_label: "Показати ставку в етикетці"
- back_to_tax_rates_list: "Повернутися до списку податкових ставок"
tax_settings: "Налаштування податку"
zones: "Зони"
new_zone: "Нова зона"
@@ -3590,14 +3587,11 @@ uk:
iso_name: "Назва ISO"
states_required: "Регіони обовязкові"
editing_country: "Країна редагування"
- back_to_countries_list: "Назад до списку країн"
states: "Області"
abbreviation: "Абревіатура"
new_state: "Новий регіон"
payment_methods: "методи оплати"
- taxonomies: "Таксономії"
- new_taxonomy: "Нова таксономія"
- back_to_taxonomies_list: "Назад до списку таксономій"
+ taxons: "Категорії продуктів"
shipping_methods: "Способи доставки"
shipping_method: "Спосіб доставки"
shipment: "Відвантаження"
@@ -3751,7 +3745,6 @@ uk:
continue: "Продовжити"
new:
new_return_authorization: "Авторизація на нове повернення"
- back_to_return_authorizations_list: "Назад до списку Авторизації повернень"
continue: "Продовжити"
edit:
receive: "отримати"
@@ -4051,9 +4044,10 @@ uk:
total: "Всього"
billing_address_name: "Ім'я"
taxons:
+ index:
+ title: "Категорії продуктів"
form:
name: Ім'я
- permalink: Постійне посилання
description: Опис
general_settings:
edit:
@@ -4273,7 +4267,6 @@ uk:
key_cleared: "Ключ видалено"
shipment:
cannot_ready: "Неможливо підготувати відправлення."
- invalid_taxonomy_id: "Недійсний ID таксономії."
activerecord:
models:
spree/payment:
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index fe91db5633..8036788d46 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -79,6 +79,8 @@ Openfoodnetwork::Application.routes.draw do
delete 'products_v3/:id', to: 'products_v3#destroy', as: 'product_destroy'
delete 'products_v3/destroy_variant/:id', to: 'products_v3#destroy_variant', as: 'destroy_variant'
post 'clone/:id', to: 'products_v3#clone', as: 'clone_product'
+
+ resources :product_preview, only: [:show]
end
resources :variant_overrides do
@@ -135,6 +137,7 @@ Openfoodnetwork::Application.routes.draw do
end
get '/reports', to: 'reports#index', as: :reports
- match '/reports/:report_type(/:report_subtype)', to: 'reports#show', via: [:get, :post], as: :report
+ match '/reports/:report_type(/:report_subtype)', to: 'reports#show', via: :get, as: :report
+ match '/reports/:report_type(/:report_subtype)', to: 'reports#create', via: :post
end
end
diff --git a/config/routes/api.rb b/config/routes/api.rb
index 74f2ad3652..30bd7cd1b1 100644
--- a/config/routes/api.rb
+++ b/config/routes/api.rb
@@ -79,18 +79,7 @@ Openfoodnetwork::Application.routes.draw do
resources :states, :only => [:index, :show]
- resources :taxons, :only => [:index]
-
- resources :taxonomies do
- member do
- get :jstree
- end
- resources :taxons do
- member do
- get :jstree
- end
- end
- end
+ resources :taxons, except: %i[show edit]
get '/reports/:report_type(/:report_subtype)', to: 'reports#show',
constraints: lambda { |_| OpenFoodNetwork::FeatureToggle.enabled?(:api_reports) }
diff --git a/config/routes/spree.rb b/config/routes/spree.rb
index f59e4e7dca..e9d21a66cb 100644
--- a/config/routes/spree.rb
+++ b/config/routes/spree.rb
@@ -142,15 +142,7 @@ Spree::Core::Engine.routes.draw do
end
resources :states
- resources :taxonomies do
- collection do
- post :update_positions
- end
- member do
- get :get_children
- end
- resources :taxons
- end
+ resources :taxons, except: :show
resources :tax_rates
resource :tax_settings
diff --git a/db/migrate/20240510033206_sanitize_enterprise_long_description.rb b/db/migrate/20240510033206_sanitize_enterprise_long_description.rb
new file mode 100644
index 0000000000..5f69464ed3
--- /dev/null
+++ b/db/migrate/20240510033206_sanitize_enterprise_long_description.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+class SanitizeEnterpriseLongDescription < ActiveRecord::Migration[7.0]
+ class Enterprise < ApplicationRecord
+ end
+
+ # This is a copy from our application code at the time of writing.
+ # We prefer to keep migrations isolated and not affected by changing
+ # application code in the future.
+ # If we need to change the sanitizer in the future we may need a new
+ # migration (not change the old one) to sanitise the data properly.
+ class HtmlSanitizer
+ ALLOWED_TAGS = %w[h1 h2 h3 h4 div p br b i u a strong em del pre blockquote ul ol li hr
+ figure].freeze
+ ALLOWED_ATTRIBUTES = %w[href target].freeze
+ ALLOWED_TRIX_DATA_ATTRIBUTES = %w[data-trix-attachment].freeze
+
+ def self.sanitize(html)
+ @sanitizer ||= Rails::HTML5::SafeListSanitizer.new
+ @sanitizer.sanitize(
+ html, tags: ALLOWED_TAGS, attributes: (ALLOWED_ATTRIBUTES + ALLOWED_TRIX_DATA_ATTRIBUTES)
+ )
+ end
+ end
+
+ def up
+ Enterprise.where.not(long_description: [nil, ""]).find_each do |enterprise|
+ long_description = HtmlSanitizer.sanitize(enterprise.long_description)
+ enterprise.update!(long_description:)
+ end
+ end
+
+ private
+
+ def sanitize(html)
+ HtmlSanitizer.sanitize(html)
+ end
+end
diff --git a/db/migrate/20240806135838_drop_spree_taxonomies_table.rb b/db/migrate/20240806135838_drop_spree_taxonomies_table.rb
new file mode 100644
index 0000000000..99a24f1ad8
--- /dev/null
+++ b/db/migrate/20240806135838_drop_spree_taxonomies_table.rb
@@ -0,0 +1,19 @@
+class DropSpreeTaxonomiesTable < ActiveRecord::Migration[7.0]
+ def change
+ # Remove columns
+ remove_column :spree_taxons, :lft, :integer
+ remove_column :spree_taxons, :rgt, :integer
+
+ # Remove references
+ remove_reference :spree_taxons, :parent, index: true, foreign_key: { to_table: :spree_taxons }
+ remove_reference :spree_taxons, :taxonomy, index: true, foreign_key: { to_table: :spree_taxonomies }
+
+ # Drop table
+ drop_table :spree_taxonomies, id: :serial, force: :cascade do |t|
+ t.string "name", limit: 255, null: false
+ t.datetime "created_at", precision: nil, null: false
+ t.datetime "updated_at", precision: nil, null: false
+ t.integer "position", default: 0
+ end
+ end
+end
diff --git a/db/migrate/20240810150912_activate_admin_style_v3_for75_pc_users.rb b/db/migrate/20240810150912_activate_admin_style_v3_for75_pc_users.rb
new file mode 100644
index 0000000000..cc412c0b58
--- /dev/null
+++ b/db/migrate/20240810150912_activate_admin_style_v3_for75_pc_users.rb
@@ -0,0 +1,9 @@
+class ActivateAdminStyleV3For75PcUsers < ActiveRecord::Migration[7.0]
+ def up
+ Flipper.enable_percentage_of_actors(:admin_style_v3, 75)
+ end
+
+ def down
+ Flipper.enable_percentage_of_actors(:admin_style_v3, 50)
+ end
+end
diff --git a/db/migrate/20240828203544_fully_enable_admin_style_v3_flag.rb b/db/migrate/20240828203544_fully_enable_admin_style_v3_flag.rb
new file mode 100644
index 0000000000..db2fd6007f
--- /dev/null
+++ b/db/migrate/20240828203544_fully_enable_admin_style_v3_flag.rb
@@ -0,0 +1,5 @@
+class FullyEnableAdminStyleV3Flag < ActiveRecord::Migration[7.0]
+ def up
+ Flipper.enable(:admin_style_v3)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 04013a7caf..c398b00eb3 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2024_08_01_034710) do
+ActiveRecord::Schema[7.0].define(version: 2024_08_28_203544) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "plpgsql"
@@ -878,31 +878,18 @@ ActiveRecord::Schema[7.0].define(version: 2024_08_01_034710) do
t.datetime "deleted_at", precision: nil
end
- create_table "spree_taxonomies", id: :serial, force: :cascade do |t|
- t.string "name", limit: 255, null: false
- t.datetime "created_at", precision: nil, null: false
- t.datetime "updated_at", precision: nil, null: false
- t.integer "position", default: 0
- end
-
create_table "spree_taxons", id: :serial, force: :cascade do |t|
- t.integer "parent_id"
t.integer "position", default: 0
t.string "name", limit: 255, null: false
t.string "permalink", limit: 255
- t.integer "taxonomy_id"
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
- t.integer "lft"
- t.integer "rgt"
t.text "description"
t.string "meta_title", limit: 255
t.string "meta_description", limit: 255
t.string "meta_keywords", limit: 255
t.string "dfc_id"
- t.index ["parent_id"], name: "index_taxons_on_parent_id"
t.index ["permalink"], name: "index_taxons_on_permalink"
- t.index ["taxonomy_id"], name: "index_taxons_on_taxonomy_id"
end
create_table "spree_tokenized_permissions", id: :serial, force: :cascade do |t|
@@ -1220,8 +1207,6 @@ ActiveRecord::Schema[7.0].define(version: 2024_08_01_034710) do
add_foreign_key "spree_stock_movements", "spree_stock_items", column: "stock_item_id"
add_foreign_key "spree_tax_rates", "spree_tax_categories", column: "tax_category_id", name: "spree_tax_rates_tax_category_id_fk"
add_foreign_key "spree_tax_rates", "spree_zones", column: "zone_id", name: "spree_tax_rates_zone_id_fk"
- add_foreign_key "spree_taxons", "spree_taxonomies", column: "taxonomy_id", name: "spree_taxons_taxonomy_id_fk"
- add_foreign_key "spree_taxons", "spree_taxons", column: "parent_id", name: "spree_taxons_parent_id_fk"
add_foreign_key "spree_users", "spree_addresses", column: "bill_address_id", name: "spree_users_bill_address_id_fk"
add_foreign_key "spree_users", "spree_addresses", column: "ship_address_id", name: "spree_users_ship_address_id_fk"
add_foreign_key "spree_variants", "enterprises", column: "supplier_id"
diff --git a/engines/dfc_provider/app/controllers/dfc_provider/affiliate_sales_data_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/affiliate_sales_data_controller.rb
new file mode 100644
index 0000000000..bff7447301
--- /dev/null
+++ b/engines/dfc_provider/app/controllers/dfc_provider/affiliate_sales_data_controller.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module DfcProvider
+ # Aggregates anonymised sales data for a research project.
+ class AffiliateSalesDataController < DfcProvider::ApplicationController
+ rescue_from Date::Error, with: -> { head :bad_request }
+
+ def show
+ person = AffiliateSalesDataBuilder.person(current_user, filter_params)
+
+ render json: DfcIo.export(person)
+ end
+
+ private
+
+ def filter_params
+ {
+ start_date: parse_date(params[:startDate]),
+ end_date: parse_date(params[:endDate]),
+ }
+ end
+
+ def parse_date(string)
+ return if string.blank?
+
+ Date.parse(string)
+ end
+ end
+end
diff --git a/engines/dfc_provider/app/services/affiliate_sales_data_builder.rb b/engines/dfc_provider/app/services/affiliate_sales_data_builder.rb
new file mode 100644
index 0000000000..26d11b3a98
--- /dev/null
+++ b/engines/dfc_provider/app/services/affiliate_sales_data_builder.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AffiliateSalesDataBuilder < DfcBuilder
+ class << self
+ def person(user, filters = {})
+ data = AffiliateSalesQuery.data(user.affiliate_enterprises, **filters)
+ suppliers = data.map do |row|
+ AffiliateSalesDataRowBuilder.new(row).build_supplier
+ end
+
+ DataFoodConsortium::Connector::Person.new(
+ urls.affiliate_sales_data_url,
+ affiliatedOrganizations: suppliers,
+ )
+ end
+ end
+end
diff --git a/engines/dfc_provider/app/services/affiliate_sales_data_row_builder.rb b/engines/dfc_provider/app/services/affiliate_sales_data_row_builder.rb
new file mode 100644
index 0000000000..073097a04f
--- /dev/null
+++ b/engines/dfc_provider/app/services/affiliate_sales_data_row_builder.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+# Represents a single row of the aggregated sales data.
+class AffiliateSalesDataRowBuilder < DfcBuilder
+ attr_reader :item
+
+ def initialize(row)
+ super()
+ @item = AffiliateSalesQuery.label_row(row)
+ end
+
+ def build_supplier
+ DataFoodConsortium::Connector::Enterprise.new(
+ nil,
+ localizations: [build_address(item[:supplier_postcode])],
+ suppliedProducts: [build_product],
+ )
+ end
+
+ def build_distributor
+ DataFoodConsortium::Connector::Enterprise.new(
+ nil,
+ localizations: [build_address(item[:distributor_postcode])],
+ )
+ end
+
+ def build_product
+ DataFoodConsortium::Connector::SuppliedProduct.new(
+ nil,
+ name: item[:product_name],
+ quantity: build_product_quantity,
+ ).tap do |product|
+ product.registerSemanticProperty("dfc-b:concernedBy") {
+ build_order_line
+ }
+ end
+ end
+
+ def build_order_line
+ DataFoodConsortium::Connector::OrderLine.new(
+ nil,
+ quantity: build_line_quantity,
+ price: build_price,
+ order: build_order,
+ )
+ end
+
+ def build_order
+ DataFoodConsortium::Connector::Order.new(
+ nil,
+ saleSession: build_sale_session,
+ )
+ end
+
+ def build_sale_session
+ DataFoodConsortium::Connector::SaleSession.new(
+ nil,
+ ).tap do |session|
+ session.registerSemanticProperty("dfc-b:objectOf") {
+ build_coordination
+ }
+ end
+ end
+
+ def build_coordination
+ DfcProvider::Coordination.new(
+ nil,
+ coordinator: build_distributor,
+ )
+ end
+
+ def build_product_quantity
+ DataFoodConsortium::Connector::QuantitativeValue.new(
+ unit: QuantitativeValueBuilder.unit(item[:unit_type]),
+ value: item[:units]&.to_f,
+ )
+ end
+
+ def build_line_quantity
+ DataFoodConsortium::Connector::QuantitativeValue.new(
+ unit: DfcLoader.connector.MEASURES.PIECE,
+ value: item[:quantity_sold]&.to_f,
+ )
+ end
+
+ def build_price
+ DataFoodConsortium::Connector::QuantitativeValue.new(
+ value: item[:price]&.to_f,
+ )
+ end
+
+ def build_address(postcode)
+ DataFoodConsortium::Connector::Address.new(
+ nil,
+ postalCode: postcode,
+ )
+ end
+end
diff --git a/engines/dfc_provider/app/services/affiliate_sales_query.rb b/engines/dfc_provider/app/services/affiliate_sales_query.rb
new file mode 100644
index 0000000000..3193ed5623
--- /dev/null
+++ b/engines/dfc_provider/app/services/affiliate_sales_query.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+class AffiliateSalesQuery
+ class << self
+ def data(enterprises, start_date: nil, end_date: nil)
+ end_date = end_date&.end_of_day # Include the whole end date.
+
+ Spree::LineItem
+ .joins(tables)
+ .where(
+ spree_orders: {
+ state: "complete", distributor_id: enterprises,
+ completed_at: [start_date..end_date],
+ },
+ )
+ .group(key_fields)
+ .pluck(fields)
+ end
+
+ # Create a hash with labels for an array of data points:
+ #
+ # { product_name: "Apple", ... }
+ def label_row(row)
+ labels.zip(row).to_h
+ end
+
+ private
+
+ # We want to collect a lot of data from only a few columns.
+ # It's more efficient with `pluck`. But therefore we need well named
+ # tables and columns, especially because we are going to join some tables
+ # twice for different columns. For example the distributer postcode and
+ # the supplier postcode. That's why we need SQL here instead of nice Rails
+ # associations.
+ def tables
+ <<~SQL.squish
+ JOIN spree_variants ON spree_variants.id = spree_line_items.variant_id
+ JOIN spree_products ON spree_products.id = spree_variants.product_id
+ JOIN enterprises AS suppliers ON suppliers.id = spree_variants.supplier_id
+ JOIN spree_addresses AS supplier_addresses ON supplier_addresses.id = suppliers.address_id
+ JOIN spree_orders ON spree_orders.id = spree_line_items.order_id
+ JOIN enterprises AS distributors ON distributors.id = spree_orders.distributor_id
+ JOIN spree_addresses AS distributor_addresses ON distributor_addresses.id = distributors.address_id
+ SQL
+ end
+
+ def fields
+ <<~SQL.squish
+ spree_products.name AS product_name,
+ spree_variants.display_name AS unit_name,
+ spree_products.variant_unit AS unit_type,
+ spree_variants.unit_value AS units,
+ spree_variants.unit_presentation,
+ spree_line_items.price,
+ distributor_addresses.zipcode AS distributor_postcode,
+ supplier_addresses.zipcode AS supplier_postcode,
+
+ SUM(spree_line_items.quantity) AS quantity_sold
+ SQL
+ end
+
+ def key_fields
+ <<~SQL.squish
+ product_name,
+ unit_name,
+ unit_type,
+ units,
+ spree_variants.unit_presentation,
+ spree_line_items.price,
+ distributor_postcode,
+ supplier_postcode
+ SQL
+ end
+
+ # A list of column names as symbols to be used as hash keys.
+ def labels
+ %i[
+ product_name
+ unit_name
+ unit_type
+ units
+ unit_presentation
+ price
+ distributor_postcode
+ supplier_postcode
+ quantity_sold
+ ]
+ end
+ end
+end
diff --git a/engines/dfc_provider/app/services/fdc_request.rb b/engines/dfc_provider/app/services/fdc_request.rb
deleted file mode 100644
index 5252cff85a..0000000000
--- a/engines/dfc_provider/app/services/fdc_request.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-require "private_address_check"
-require "private_address_check/tcpsocket_ext"
-
-# Request a JSON document from the FDC API with authentication.
-#
-# Currently, the API doesn't quite comply with the DFC standard and we need
-# to authenticate a little bit differently.
-#
-# And then we get slightly different data as well.
-class FdcRequest < DfcRequest
- # Override main method to POST authorization data.
- def call(url, data = {})
- response = request(url, auth_data.merge(data).to_json)
-
- if response.status >= 400 && token_stale?
- refresh_access_token!
- response = request(url, auth_data.merge(data).to_json)
- end
-
- response.body
- end
-
- private
-
- def auth_data
- {
- userId: @user.oidc_account.uid,
- accessToken: @user.oidc_account.token,
- }
- end
-end
diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb
index 6baac1eecf..ecbc0f4c59 100644
--- a/engines/dfc_provider/app/services/quantitative_value_builder.rb
+++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb
@@ -11,13 +11,13 @@
class QuantitativeValueBuilder < DfcBuilder
def self.quantity(variant)
DataFoodConsortium::Connector::QuantitativeValue.new(
- unit: unit(variant),
+ unit: unit(variant.product.variant_unit),
value: variant.unit_value,
)
end
- def self.unit(variant)
- case variant.product.variant_unit
+ def self.unit(unit_name)
+ case unit_name
when "volume"
DfcLoader.connector.MEASURES.LITRE
when "weight"
diff --git a/engines/dfc_provider/config/routes.rb b/engines/dfc_provider/config/routes.rb
index 5bde8f23ba..8fc0850729 100644
--- a/engines/dfc_provider/config/routes.rb
+++ b/engines/dfc_provider/config/routes.rb
@@ -12,4 +12,6 @@ DfcProvider::Engine.routes.draw do
resources :affiliated_by, only: [:create, :destroy], module: 'enterprise_groups'
end
resources :persons, only: [:show]
+
+ resource :affiliate_sales_data, only: [:show]
end
diff --git a/engines/dfc_provider/lib/dfc_provider.rb b/engines/dfc_provider/lib/dfc_provider.rb
index 526cceb9c3..51f3ec2ef4 100644
--- a/engines/dfc_provider/lib/dfc_provider.rb
+++ b/engines/dfc_provider/lib/dfc_provider.rb
@@ -9,6 +9,7 @@ require "dfc_provider/engine"
# Custom data types
require "dfc_provider/supplied_product"
require "dfc_provider/address"
+require "dfc_provider/coordination"
module DfcProvider
DataFoodConsortium::Connector::Importer.register_type(SuppliedProduct)
diff --git a/engines/dfc_provider/lib/dfc_provider/coordination.rb b/engines/dfc_provider/lib/dfc_provider/coordination.rb
new file mode 100644
index 0000000000..49b16aa97a
--- /dev/null
+++ b/engines/dfc_provider/lib/dfc_provider/coordination.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+if defined? DataFoodConsortium::Connector::Coordination
+ ActiveSupport::Deprecation.warn <<~TEXT
+ DataFoodConsortium::Connector::Coordination is now available.
+ Please replace your own implementation with the official class.
+ TEXT
+end
+
+module DfcProvider
+ class Coordination
+ include VirtualAssembly::Semantizer::SemanticObject
+
+ SEMANTIC_TYPE = "dfc-b:Coordination"
+
+ attr_accessor :coordinator
+
+ def initialize(semantic_id, coordinator: nil)
+ super(semantic_id)
+
+ self.semanticType = SEMANTIC_TYPE
+
+ @coordinator = coordinator
+ registerSemanticProperty("dfc-b:coordinatedBy", &method("coordinator"))
+ .valueSetter = method("coordinator=")
+ end
+ end
+end
diff --git a/engines/dfc_provider/spec/requests/affiliate_sales_data_spec.rb b/engines/dfc_provider/spec/requests/affiliate_sales_data_spec.rb
new file mode 100644
index 0000000000..3199fc4a22
--- /dev/null
+++ b/engines/dfc_provider/spec/requests/affiliate_sales_data_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require_relative "../swagger_helper"
+
+RSpec.describe "AffiliateSalesData", swagger_doc: "dfc.yaml", rswag_autodoc: true do
+ let(:user) { create(:oidc_user) }
+
+ before { login_as user }
+
+ path "/api/dfc/affiliate_sales_data" do
+ parameter name: :startDate, in: :query, type: :string
+ parameter name: :endDate, in: :query, type: :string
+
+ get "Show sales data of person's affiliate enterprises" do
+ produces "application/json"
+
+ response "200", "successful", feature: :affiliate_sales_data do
+ let(:startDate) { Date.yesterday }
+ let(:endDate) { Time.zone.today }
+
+ before do
+ order = create(:order_with_totals_and_distribution, :completed)
+ ConnectedApps::AffiliateSalesData.new(
+ enterprise: order.distributor
+ ).connect({})
+ end
+
+ context "with date filters" do
+ let(:startDate) { Date.tomorrow }
+ let(:endDate) { Date.tomorrow }
+
+ run_test! do
+ expect(json_response).to include(
+ "@id" => "http://test.host/api/dfc/affiliate_sales_data",
+ "@type" => "dfc-b:Person",
+ )
+
+ expect(json_response["dfc-b:affiliates"]).to eq nil
+ end
+ end
+
+ context "not filtered" do
+ run_test! do
+ expect(json_response).to include(
+ "@id" => "http://test.host/api/dfc/affiliate_sales_data",
+ "@type" => "dfc-b:Person",
+ )
+ expect(json_response["dfc-b:affiliates"]).to be_present
+ end
+ end
+ end
+
+ response "400", "bad request" do
+ let(:startDate) { "yesterday" }
+ let(:endDate) { "tomorrow" }
+
+ run_test!
+ end
+ end
+ end
+end
diff --git a/engines/dfc_provider/spec/services/affiliate_sales_data_builder_spec.rb b/engines/dfc_provider/spec/services/affiliate_sales_data_builder_spec.rb
new file mode 100644
index 0000000000..9673b70045
--- /dev/null
+++ b/engines/dfc_provider/spec/services/affiliate_sales_data_builder_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require_relative "../spec_helper"
+
+RSpec.describe AffiliateSalesDataBuilder do
+ let(:user) { build(:user) }
+
+ describe ".person" do
+ let(:person) { described_class.person(user) }
+
+ it "returns data as Person" do
+ expect(person).to be_a DataFoodConsortium::Connector::Person
+ expect(person.semanticId).to eq "http://test.host/api/dfc/affiliate_sales_data"
+ end
+
+ describe "with sales data" do
+ before do
+ supplier = create(
+ :supplier_enterprise,
+ owner: user,
+ users: [user],
+ address: create(:address, zipcode: "5555"),
+ )
+ product = create(
+ :product,
+ name: "Pomme",
+ supplier_id: supplier.id,
+ variant_unit: "item",
+ )
+ variant = product.variants.first
+ distributor = create(
+ :distributor_enterprise,
+ owner: user,
+ address: create(:address, zipcode: "6666"),
+ )
+ ConnectedApps::AffiliateSalesData.new(enterprise: distributor).connect({})
+ line_item = build(
+ :line_item,
+ variant:,
+ quantity: 2,
+ price: 3,
+ )
+ order_cycle = create(
+ :order_cycle,
+ suppliers: [supplier],
+ distributors: [distributor],
+ )
+ order_cycle.exchanges.incoming.first.variants << variant
+ order_cycle.exchanges.outgoing.first.variants << variant
+ create(
+ :order,
+ state: "complete",
+ order_cycle:,
+ distributor:,
+ line_items: [line_item],
+ )
+ end
+
+ it "returns required sales data", feature: :affiliate_sales_data do
+ supplier = person.affiliatedOrganizations[0]
+ product = supplier.suppliedProducts[0]
+ line = product.semanticPropertyValue("dfc-b:concernedBy")
+ session = line.order.saleSession
+ coordination = session.semanticPropertyValue("dfc-b:objectOf")
+ distributor = coordination.coordinator
+
+ expect(supplier.localizations[0].postalCode).to eq "5555"
+ expect(distributor.localizations[0].postalCode).to eq "6666"
+
+ expect(product.name).to eq "Pomme"
+ expect(product.quantity.unit).to eq DfcLoader.connector.MEASURES.PIECE
+ expect(product.quantity.value).to eq 1
+
+ expect(line.quantity.unit).to eq DfcLoader.connector.MEASURES.PIECE
+ expect(line.quantity.value).to eq 2
+ expect(line.price.value).to eq 3
+ end
+ end
+ end
+end
diff --git a/engines/dfc_provider/spec/services/affiliate_sales_query_spec.rb b/engines/dfc_provider/spec/services/affiliate_sales_query_spec.rb
new file mode 100644
index 0000000000..f1ab830977
--- /dev/null
+++ b/engines/dfc_provider/spec/services/affiliate_sales_query_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require_relative "../spec_helper"
+
+RSpec.describe AffiliateSalesQuery do
+ subject(:query) { described_class }
+
+ describe ".data" do
+ let(:order) { create(:order_with_totals_and_distribution, :completed) }
+ let(:today) { Time.zone.today }
+ let(:yesterday) { Time.zone.yesterday }
+ let(:tomorrow) { Time.zone.tomorrow }
+
+ it "returns data" do
+ # Test data creation takes time.
+ # So I'm executing more tests in one `it` block here.
+ # And make it simpler to call the subject many times:
+ count_rows = lambda do |**args|
+ query.data(order.distributor, **args).count
+ end
+
+ # Without any filters:
+ expect(count_rows.call).to eq 1
+
+ # From today:
+ expect(count_rows.call(start_date: today)).to eq 1
+
+ # Until today:
+ expect(count_rows.call(end_date: today)).to eq 1
+
+ # Just today:
+ expect(count_rows.call(start_date: today, end_date: today)).to eq 1
+
+ # Yesterday:
+ expect(count_rows.call(start_date: yesterday, end_date: yesterday)).to eq 0
+
+ # Until yesterday:
+ expect(count_rows.call(end_date: yesterday)).to eq 0
+
+ # From tomorrow:
+ expect(count_rows.call(start_date: tomorrow)).to eq 0
+ end
+ end
+
+ describe ".label_row" do
+ it "converts an array to a hash" do
+ row = [
+ "Apples",
+ "item", "item", nil, nil,
+ 15.50,
+ "3210", "3211",
+ 3,
+ ]
+ expect(query.label_row(row)).to eq(
+ {
+ product_name: "Apples",
+ unit_name: "item",
+ unit_type: "item",
+ units: nil,
+ unit_presentation: nil,
+ price: 15.50,
+ distributor_postcode: "3210",
+ supplier_postcode: "3211",
+ quantity_sold: 3,
+ }
+ )
+ end
+ end
+end
diff --git a/engines/dfc_provider/spec/services/dfc_request_spec.rb b/engines/dfc_provider/spec/services/dfc_request_spec.rb
index ea17ae02af..0de024b670 100644
--- a/engines/dfc_provider/spec/services/dfc_request_spec.rb
+++ b/engines/dfc_provider/spec/services/dfc_request_spec.rb
@@ -59,4 +59,28 @@ RSpec.describe DfcRequest do
# would raise errors because we didn't setup Webmock or VCR.
# The absence of errors makes this test pass.
end
+
+ it "refreshes the access token and retrieves the FDC catalog", vcr: true do
+ # A refresh is only attempted if the token is stale.
+ account.uid = "testdfc@protonmail.com"
+ account.refresh_token = ENV.fetch("OPENID_REFRESH_TOKEN")
+ account.updated_at = 1.day.ago
+
+ response = nil
+ expect {
+ response = api.call(
+ "https://env-0105831.jcloud-ver-jpe.ik-server.com/api/dfc/Enterprises/test-hodmedod/SuppliedProducts"
+ )
+ }.to change {
+ account.token
+ }.and change {
+ account.refresh_token
+ }
+
+ json = JSON.parse(response)
+
+ graph = DfcIo.import(json)
+ products = graph.select { |s| s.semanticType == "dfc-b:SuppliedProduct" }
+ expect(products).to be_present
+ end
end
diff --git a/engines/dfc_provider/spec/services/fdc_request_spec.rb b/engines/dfc_provider/spec/services/fdc_request_spec.rb
deleted file mode 100644
index c1f59d40f8..0000000000
--- a/engines/dfc_provider/spec/services/fdc_request_spec.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "../spec_helper"
-
-RSpec.describe FdcRequest do
- subject(:api) { FdcRequest.new(user) }
-
- let(:user) { build(:oidc_user) }
- let(:account) { user.oidc_account }
- let(:url) {
- "https://food-data-collaboration-produc-fe870152f634.herokuapp.com/fdc/products?shop=test-hodmedod.myshopify.com"
- }
-
- it "refreshes the access token and retrieves a catalog", vcr: true do
- # A refresh is only attempted if the token is stale.
- account.uid = "testdfc@protonmail.com"
- account.refresh_token = ENV.fetch("OPENID_REFRESH_TOKEN")
- account.updated_at = 1.day.ago
-
- response = nil
- expect {
- response = api.call(url)
- }.to change {
- account.token
- }.and change {
- account.refresh_token
- }
-
- json = JSON.parse(response)
- expect(json["message"]).to eq "Products retrieved successfully"
-
- graph = DfcIo.import(json["products"])
- products = graph.select { |s| s.semanticType == "dfc-b:SuppliedProduct" }
- expect(products).to be_present
- end
-end
diff --git a/engines/order_management/app/services/order_management/subscriptions/variants_list.rb b/engines/order_management/app/services/order_management/subscriptions/variants_list.rb
index fb06ed8829..f3a817219a 100644
--- a/engines/order_management/app/services/order_management/subscriptions/variants_list.rb
+++ b/engines/order_management/app/services/order_management/subscriptions/variants_list.rb
@@ -32,7 +32,9 @@ module OrderManagement
.merge(Enterprise.is_primary_producer)
.pluck(:parent_id)
- other_permitted_producer_ids | [distributor.id]
+ # Append to the potentially gigantic array instead of using union, which creates a new array
+ # The db IN statement won't care if there's a duplicate.
+ other_permitted_producer_ids << distributor.id
end
def self.outgoing_exchange_variant_ids(distributor)
diff --git a/lib/open_food_network/column_preference_defaults.rb b/lib/open_food_network/column_preference_defaults.rb
index f851efc794..9da9ef36e9 100644
--- a/lib/open_food_network/column_preference_defaults.rb
+++ b/lib/open_food_network/column_preference_defaults.rb
@@ -77,7 +77,9 @@ module OpenFoodNetwork
}
end
- def products_v3_index_columns
+ def products_v3_index_columns(user)
+ producer_visibility = display_producer_column?(user)
+
I18n.with_options scope: 'admin.products_page.columns' do
{
image: { name: t(:image), visible: true },
@@ -87,7 +89,7 @@ module OpenFoodNetwork
unit_scale: { name: t(:unit_scale), visible: true },
price: { name: t(:price), visible: true },
on_hand: { name: t(:on_hand), visible: true },
- producer: { name: t(:producer), visible: true },
+ producer: { name: t(:producer), visible: producer_visibility },
category: { name: t(:category), visible: true },
tax_category: { name: t(:tax_category), visible: true },
inherits_properties: { name: t(:inherits_properties), visible: true },
@@ -134,5 +136,12 @@ module OpenFoodNetwork
shipping_method: { name: I18n.t("admin.shipping_method"), visible: false }
}
end
+
+ def display_producer_column?(user)
+ producers = OpenFoodNetwork::Permissions.new(user)
+ .managed_product_enterprises.is_primary_producer
+
+ producers.many?
+ end
end
end
diff --git a/lib/open_food_network/enterprise_injection_data.rb b/lib/open_food_network/enterprise_injection_data.rb
index 31801c63f9..046d2f4941 100644
--- a/lib/open_food_network/enterprise_injection_data.rb
+++ b/lib/open_food_network/enterprise_injection_data.rb
@@ -2,40 +2,55 @@
module OpenFoodNetwork
class EnterpriseInjectionData
+ # By default, data is fetched for *every* enterprise in the DB, but we specify some ids of
+ # enterprises that we are interested in, there is a lot less data to fetch
+ def initialize(enterprise_ids = nil)
+ @enterprise_ids = enterprise_ids
+ end
+
def active_distributor_ids
@active_distributor_ids ||=
- Enterprise.distributors_with_active_order_cycles.ready_for_checkout.pluck(:id)
+ begin
+ enterprises = Enterprise.distributors_with_active_order_cycles.ready_for_checkout
+ enterprises = enterprises.where(id: @enterprise_ids) if @enterprise_ids.present?
+ enterprises.pluck(:id)
+ end
end
def earliest_closing_times
- @earliest_closing_times ||= OrderCycle.earliest_closing_times
+ @earliest_closing_times ||= OrderCycle.earliest_closing_times(@enterprise_ids)
end
def shipping_method_services
- @shipping_method_services ||= CacheService.cached_data_by_class("shipping_method_services",
- Spree::ShippingMethod) do
+ @shipping_method_services ||= CacheService.cached_data_by_class(
+ "shipping_method_services_#{@enterprise_ids.hash}",
+ Spree::ShippingMethod
+ ) do
# This result relies on a simple join with DistributorShippingMethod.
# Updated DistributorShippingMethod records touch their associated Spree::ShippingMethod.
- Spree::ShippingMethod.services
+ Spree::ShippingMethod.services(@enterprise_ids)
end
end
def supplied_taxons
- @supplied_taxons ||= CacheService.cached_data_by_class("supplied_taxons", Spree::Taxon) do
+ @supplied_taxons ||= CacheService.cached_data_by_class(
+ "supplied_taxons_#{@enterprise_ids.hash}",
+ Spree::Taxon
+ ) do
# This result relies on a join with associated supplied products, through the
# class Classification which maps the relationship. Classification records touch
# their associated Spree::Taxon when updated. A Spree::Product's primary_taxon
# is also touched when changed.
- Spree::Taxon.supplied_taxons
+ Spree::Taxon.supplied_taxons(@enterprise_ids)
end
end
def all_distributed_taxons
- @all_distributed_taxons ||= Spree::Taxon.distributed_taxons(:all)
+ @all_distributed_taxons ||= Spree::Taxon.distributed_taxons(:all, @enterprise_ids)
end
def current_distributed_taxons
- @current_distributed_taxons ||= Spree::Taxon.distributed_taxons(:current)
+ @current_distributed_taxons ||= Spree::Taxon.distributed_taxons(:current, @enterprise_ids)
end
end
end
diff --git a/lib/open_food_network/feature_toggle.rb b/lib/open_food_network/feature_toggle.rb
index aedef176fb..a3b1d8b253 100644
--- a/lib/open_food_network/feature_toggle.rb
+++ b/lib/open_food_network/feature_toggle.rb
@@ -44,6 +44,10 @@ module OpenFoodNetwork
Enterprise data can be shared with another app.
The first example is the Australian Discover Regenerative Portal.
DESC
+ "affiliate_sales_data" => <<~DESC,
+ Activated for a user.
+ The user (INRAE researcher) has access to anonymised sales.
+ DESC
}.freeze
# Features you would like to be enabled to start with.
diff --git a/lib/open_food_network/scope_variant_to_hub.rb b/lib/open_food_network/scope_variant_to_hub.rb
index d7a29cbb9c..90bfef39d4 100644
--- a/lib/open_food_network/scope_variant_to_hub.rb
+++ b/lib/open_food_network/scope_variant_to_hub.rb
@@ -43,11 +43,7 @@ module OpenFoodNetwork
# - updates variant_override.count_on_hand
# - does not create stock_movement
# - does not update stock_item.count_on_hand
- # If it is a variant override with on_demand:
- # - don't change stock or call super (super would change the variant's stock)
def move(quantity, originator = nil)
- return if @variant_override&.on_demand
-
if @variant_override&.stock_overridden?
@variant_override.move_stock! quantity
else
diff --git a/lib/open_food_network/scope_variants_for_search.rb b/lib/open_food_network/scope_variants_for_search.rb
index 14a1bc25df..e154096524 100644
--- a/lib/open_food_network/scope_variants_for_search.rb
+++ b/lib/open_food_network/scope_variants_for_search.rb
@@ -42,7 +42,7 @@ module OpenFoodNetwork
end
def distributor
- Enterprise.find params[:distributor_id]
+ @distributor ||= Enterprise.find params[:distributor_id]
end
def scope_to_schedule
diff --git a/lib/reporting/reports/bulk_coop/supplier_report.rb b/lib/reporting/reports/bulk_coop/supplier_report.rb
index 6e797cd389..33f87263c6 100644
--- a/lib/reporting/reports/bulk_coop/supplier_report.rb
+++ b/lib/reporting/reports/bulk_coop/supplier_report.rb
@@ -10,7 +10,7 @@ module Reporting
def columns
{
- supplier: :variant_product_supplier_name,
+ supplier: :variant_supplier_name,
product: :variant_product_name,
bulk_unit_size: :variant_product_group_buy_unit_size_f,
variant: :full_name,
@@ -44,8 +44,8 @@ module Reporting
private
- def variant_product_supplier_name(line_items)
- line_items.first.variant.product.supplier.name
+ def variant_supplier_name(line_items)
+ line_items.first.variant.supplier.name
end
end
end
diff --git a/lib/reporting/reports/orders_and_distributors/base.rb b/lib/reporting/reports/orders_and_distributors/base.rb
index 4b695d33d1..47a389de41 100644
--- a/lib/reporting/reports/orders_and_distributors/base.rb
+++ b/lib/reporting/reports/orders_and_distributors/base.rb
@@ -15,7 +15,7 @@ module Reporting
customer_city: proc { |line_item| line_item.order.bill_address.city },
sku: proc { |line_item| line_item.product.sku },
item_name: proc { |line_item| line_item.product.name },
- variant: proc { |line_item| line_item.options_text },
+ variant: proc { |line_item| line_item.unit_to_display },
quantity: proc { |line_item| line_item.quantity },
max_quantity: proc { |line_item| line_item.max_quantity },
cost: proc { |line_item| line_item.price * line_item.quantity },
diff --git a/lib/spree/core.rb b/lib/spree/core.rb
index 4c39461913..e50c687f2f 100644
--- a/lib/spree/core.rb
+++ b/lib/spree/core.rb
@@ -2,7 +2,6 @@
require 'active_merchant'
require 'acts_as_list'
-require 'awesome_nested_set'
require 'cancan'
require 'pagy'
require 'mail'
@@ -35,7 +34,3 @@ require 'spree/core/permalinks'
require 'spree/core/token_resource'
require 'spree/core/product_duplicator'
require 'spree/core/gateway_error'
-
-ActiveRecord::Base.class_eval do
- include CollectiveIdea::Acts::NestedSet
-end
diff --git a/lib/tasks/sample_data/taxon_factory.rb b/lib/tasks/sample_data/taxon_factory.rb
index d9545c24d1..46e26c396e 100644
--- a/lib/tasks/sample_data/taxon_factory.rb
+++ b/lib/tasks/sample_data/taxon_factory.rb
@@ -8,23 +8,20 @@ module SampleData
def create_samples
log "Creating taxonomies:"
- taxonomy = Spree::Taxonomy.find_or_create_by!(name: 'Products')
taxons = ['Vegetables', 'Fruit', 'Oils', 'Preserves and Sauces', 'Dairy', 'Fungi']
taxons.each do |taxon_name|
- create_taxon(taxonomy, taxon_name)
+ create_taxon(taxon_name)
end
end
private
- def create_taxon(taxonomy, taxon_name)
+ def create_taxon(taxon_name)
return if Spree::Taxon.where(name: taxon_name).exists?
log "- #{taxon_name}"
Spree::Taxon.create!(
- name: taxon_name,
- parent_id: taxonomy.root.id,
- taxonomy_id: taxonomy.id
+ name: taxon_name
)
end
end
diff --git a/lib/tasks/simplecov.rake b/lib/tasks/simplecov.rake
new file mode 100644
index 0000000000..b0c896ecb7
--- /dev/null
+++ b/lib/tasks/simplecov.rake
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+namespace :simplecov do
+ desc "Collates all result sets produced during parallel test runs"
+ task :collate_results, # rubocop:disable Rails/RakeEnvironment doesn't need the full env
+ [:path_to_results, :coverage_dir] do |_t, args|
+ require "simplecov"
+
+ path_to_results = args[:path_to_results].presence || "tmp/simplecov"
+ output_path = args[:coverage_dir].presence || "coverage"
+
+ SimpleCov.collate Dir[File.join(path_to_results, "**", ".resultset.json")], "rails" do
+ formatter(SimpleCov::Formatter::HTMLFormatter)
+ coverage_dir(output_path)
+ end
+ end
+end
diff --git a/package.json b/package.json
index 1c20cce038..6673c18670 100644
--- a/package.json
+++ b/package.json
@@ -10,23 +10,22 @@
"pretty-quick": "pretty-quick"
},
"dependencies": {
- "@floating-ui/dom": "^1.6.10",
+ "@floating-ui/dom": "^1.6.11",
"@hotwired/stimulus": "^3.2",
- "@hotwired/turbo": "^8.0.5",
+ "@hotwired/turbo": "^8.0.10",
"@rails/webpacker": "5.4.4",
"@stimulus-components/rails-nested-form": "^5.0.0",
"cable_ready": "5.0.5",
- "debounced": "^0.0.5",
"flatpickr": "^4.6.9",
"foundation-sites": "^5.5.3",
"hotkeys-js": "^3.13.7",
"jquery-ui": "1.14.0",
- "js-big-decimal": "^2.0.7",
+ "js-big-decimal": "^2.1.0",
"leaflet": "1.9.4",
"leaflet-geosearch": "4.0.0",
"leaflet-providers": "2.0.0",
"moment": "^2.30.1",
- "mrujs": "^1.0.0",
+ "mrujs": "^1.0.2",
"select2": "^4.0.13",
"shortcut-buttons-flatpickr": "^0.4.0",
"stimulus": "^3.2.2",
@@ -34,10 +33,11 @@
"stimulus_reflex": "3.5.1",
"tom-select": "^2.3.1",
"trix": "^2.1.5",
+ "turbo_power": "^0.7.0",
"webpack": "~4"
},
"devDependencies": {
- "jasmine-core": "~5.2.0",
+ "jasmine-core": "~5.3.0",
"jest": "^27.4.7",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
diff --git a/spec/base_spec_helper.rb b/spec/base_spec_helper.rb
index b56cb83492..5579890b64 100644
--- a/spec/base_spec_helper.rb
+++ b/spec/base_spec_helper.rb
@@ -4,8 +4,9 @@
ENV["RAILS_ENV"] ||= 'test'
+# for full configuration, see .simplecov
require 'simplecov' if ENV["COVERAGE"]
-require 'rubygems'
+
require 'pry' unless ENV['CI']
require 'view_component/test_helpers'
@@ -27,6 +28,12 @@ end
require 'knapsack_pro'
KnapsackPro::Adapters::RSpecAdapter.bind
+if ENV["COVERAGE"] && defined?(SimpleCov)
+ KnapsackPro::Hooks::Queue.before_queue do
+ SimpleCov.command_name("rspec_ci_node_#{KnapsackPro::Config::Env.ci_node_index}")
+ end
+end
+
# Allow connections to selenium whilst raising errors when connecting to external sites
require 'webmock/rspec'
WebMock.enable!
diff --git a/spec/components/admin_tooltip_component_spec.rb b/spec/components/admin_tooltip_component_spec.rb
new file mode 100644
index 0000000000..4e0039dcea
--- /dev/null
+++ b/spec/components/admin_tooltip_component_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe AdminTooltipComponent, type: :component do
+ it "displays the tooltip link" do
+ render_inline(described_class.new(text: "Tooltip description", link_text: "Hover here"))
+
+ expect(page).to have_selector "a", text: "Hover here"
+ end
+
+ describe "text" do
+ it "displays the tooltip text" do
+ render_inline(described_class.new(text: "Tooltip description", link_text: "Hover here"))
+
+ expect(page).to have_selector ".tooltip", text: "Tooltip description"
+ end
+
+ it "sanitizes the tooltip text" do
+ render_inline(described_class.new( text: "Tooltip description",
+ link_text: "Hover here"))
+
+ expect(page).to have_selector ".tooltip", text: "Tooltip description"
+ end
+ end
+
+ describe "placement" do
+ it "uses top as default" do
+ render_inline(described_class.new(text: "Tooltip description",
+ link_text: "Hover here"))
+
+ expect(page).to have_selector '[data-tooltip-placement-value="top"]'
+ end
+
+ it "uses the given placement" do
+ render_inline(described_class.new(text: "Tooltip description",
+ link_text: "Hover here", placement: "left"))
+ expect(page).to have_selector '[data-tooltip-placement-value="left"]'
+ end
+ end
+
+ it "adds the correct link" do
+ render_inline(described_class.new(text: "Tooltip description", link_text: "Hover here",
+ link: "www.ofn.com"))
+
+ expect(page).to have_selector '[href="www.ofn.com"]'
+ end
+
+ it "adds the correct link_class" do
+ render_inline(described_class.new(text: "Tooltip description", link_text: "Hover here",
+ link_class: "pretty"))
+ expect(page).to have_selector 'a[class="pretty"]'
+ end
+end
diff --git a/spec/components/modal_component_spec.rb b/spec/components/modal_component_spec.rb
new file mode 100644
index 0000000000..e50dbd3d1f
--- /dev/null
+++ b/spec/components/modal_component_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe ModalComponent, type: :component do
+ it "renders default 'data-action' and 'data-controller'" do
+ render_inline(described_class.new(id: "test-id"))
+
+ expect(page).to have_selector "#test-id"
+ expect(page).to have_selector '[data-controller="modal"]'
+ expect(page).to have_selector '[data-action="keyup@document->modal#closeIfEscapeKey"]'
+ end
+
+ it "accepts html attributes options" do
+ render_inline(described_class.new(id: "test-id", 'data-test': "some data"))
+
+ expect(page).to have_selector "#test-id"
+ expect(page).to have_selector '[data-test="some data"]'
+ end
+
+ it "merges 'data-controller' attribute when present in options" do
+ render_inline(described_class.new(id: "test-id", 'data-controller': "other-controller"))
+
+ expect(page).to have_selector "#test-id"
+ expect(page).to have_selector '[data-controller="modal other-controller"]'
+ end
+
+ it "merges 'data-action' attribute when present in options" do
+ render_inline(described_class.new(id: "test-id", 'data-action': "click->other-controller#test"))
+
+ expect(page).to have_selector "#test-id"
+ expect(page).to have_selector(
+ '[data-action="keyup@document->modal#closeIfEscapeKey click->other-controller#test"]'
+ )
+ end
+end
diff --git a/spec/controllers/admin/order_cycles_controller_spec.rb b/spec/controllers/admin/order_cycles_controller_spec.rb
index 2a859e7210..6f02b81802 100644
--- a/spec/controllers/admin/order_cycles_controller_spec.rb
+++ b/spec/controllers/admin/order_cycles_controller_spec.rb
@@ -5,6 +5,10 @@ require 'spec_helper'
module Admin
RSpec.describe OrderCyclesController, type: :controller do
let!(:distributor_owner) { create(:user) }
+ let(:datetime_confirmation_attrs) {
+ { confirm_datetime_change: nil,
+ error_class: Admin::OrderCyclesController::DateTimeChangeError }
+ }
before do
allow(controller).to receive_messages spree_current_user: distributor_owner
@@ -276,7 +280,8 @@ module Admin
it "can update preference product_selection_from_coordinator_inventory_only" do
expect(OrderCycles::FormService).to receive(:new).
with(order_cycle,
- { "preferred_product_selection_from_coordinator_inventory_only" => true },
+ { "preferred_product_selection_from_coordinator_inventory_only" => true,
+ **datetime_confirmation_attrs },
anything) { form_mock }
allow(form_mock).to receive(:save) { true }
@@ -289,7 +294,7 @@ module Admin
it "can update preference automatic_notifications" do
expect(OrderCycles::FormService).to receive(:new).
with(order_cycle,
- { "automatic_notifications" => true },
+ { "automatic_notifications" => true, **datetime_confirmation_attrs },
anything) { form_mock }
allow(form_mock).to receive(:save) { true }
@@ -323,13 +328,17 @@ module Admin
format: :json, id: order_cycle.id, order_cycle: allowed.merge(restricted)
}
}
- let(:form_mock) { instance_double(OrderCycles::FormService, save: true) }
+ let(:form_mock) {
+ instance_double(OrderCycles::FormService, save: true)
+ }
before { allow(controller).to receive(:spree_current_user) { user } }
context "as a manager of the coordinator" do
let(:user) { coordinator.owner }
- let(:expected) { [order_cycle, allowed.merge(restricted), user] }
+ let(:expected) {
+ [order_cycle, allowed.merge(restricted).merge(datetime_confirmation_attrs), user]
+ }
it "allows me to update exchange information for exchanges, name and dates" do
expect(OrderCycles::FormService).to receive(:new).with(*expected) { form_mock }
@@ -339,7 +348,7 @@ module Admin
context "as a producer supplying to an order cycle" do
let(:user) { producer.owner }
- let(:expected) { [order_cycle, allowed, user] }
+ let(:expected) { [order_cycle, allowed.merge(datetime_confirmation_attrs), user] }
it "allows me to update exchange information for exchanges, but not name or dates" do
expect(OrderCycles::FormService).to receive(:new).with(*expected) { form_mock }
diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb
index 4501adf433..81eeccbf77 100644
--- a/spec/controllers/admin/reports_controller_spec.rb
+++ b/spec/controllers/admin/reports_controller_spec.rb
@@ -310,14 +310,15 @@ RSpec.describe Admin::ReportsController, type: :controller do
end
it "triggers the delivery report" do
- spree_post :show, {
+ spree_post :create, {
+ format: :turbo,
q: { completed_at_lt: 1.day.ago },
shipping_method_in: ["123"], # We just need to search for shipping methods
report_type: :order_cycle_management,
report_subtype: "delivery",
}
- expect(response).to have_http_status(:no_content)
+ expect(response).to have_http_status(:ok)
end
end
diff --git a/spec/controllers/api/v0/shops_controller_spec.rb b/spec/controllers/api/v0/shops_controller_spec.rb
index c00be92165..b3acf2d710 100644
--- a/spec/controllers/api/v0/shops_controller_spec.rb
+++ b/spec/controllers/api/v0/shops_controller_spec.rb
@@ -32,10 +32,19 @@ RSpec.describe Api::V0::ShopsController, type: :controller do
end
describe "#closed_shops" do
+ let!(:hub_open_order_cycle) {
+ create(:simple_order_cycle, orders_open_at: 10.days.ago,
+ orders_close_at: 17.days.from_now,
+ suppliers: [create(:supplier_enterprise)],
+ distributors: [hub], variants: [product.variants.first])
+ }
+
it "returns data for all closed shops" do
get :closed_shops, params: {}
- expect(json_response).not_to match hub.name
+ # `hub` has an open order cycle (hub_open_order_cycle), so it should be excluded from
+ # results
+ expect(json_response.inspect).not_to match hub.name
response_ids = json_response.pluck(:id)
expect(response_ids).to contain_exactly(closed_hub1.id, closed_hub2.id)
diff --git a/spec/controllers/api/v0/taxonomies_controller_spec.rb b/spec/controllers/api/v0/taxonomies_controller_spec.rb
deleted file mode 100644
index 3426342ed5..0000000000
--- a/spec/controllers/api/v0/taxonomies_controller_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-module Api
- RSpec.describe V0::TaxonomiesController do
- render_views
-
- let(:taxonomy) { create(:taxonomy) }
- let(:taxon) { create(:taxon, name: "Ruby", taxonomy:) }
- let(:taxon2) { create(:taxon, name: "Rails", taxonomy:) }
- let(:attributes) { [:id, :name] }
-
- before do
- allow(controller).to receive(:spree_current_user) { current_api_user }
-
- taxon2.children << create(:taxon, name: "3.2.2", taxonomy:)
- taxon.children << taxon2
- taxonomy.root.children << taxon
- end
-
- context "as a normal user" do
- let(:current_api_user) { build(:user) }
-
- it "gets the jstree-friendly version of a taxonomy" do
- api_get :jstree, id: taxonomy.id
-
- expect(json_response["data"]).to eq(taxonomy.root.name)
- expect(json_response["attr"]).to eq("id" => taxonomy.root.id, "name" => taxonomy.root.name)
- expect(json_response["state"]).to eq("closed")
- end
- end
- end
-end
diff --git a/spec/controllers/api/v0/taxons_controller_spec.rb b/spec/controllers/api/v0/taxons_controller_spec.rb
index 2c333027e9..a41f7c7d75 100644
--- a/spec/controllers/api/v0/taxons_controller_spec.rb
+++ b/spec/controllers/api/v0/taxons_controller_spec.rb
@@ -5,30 +5,19 @@ require 'spec_helper'
RSpec.describe Api::V0::TaxonsController do
render_views
- let(:taxonomy) { create(:taxonomy) }
- let(:taxon) { create(:taxon, name: "Ruby", taxonomy:) }
- let(:taxon2) { create(:taxon, name: "Rails", taxonomy:) }
- let(:attributes) {
- ["id", "name", "pretty_name", "permalink", "position", "parent_id", "taxonomy_id"]
+ let!(:taxon) { create(:taxon, name: "Ruby") }
+ let!(:taxon2) { create(:taxon, name: "Rails") }
+ let!(:attributes) {
+ ["id", "name", "permalink", "position"]
}
before do
allow(controller).to receive(:spree_current_user) { current_api_user }
-
- taxon2.children << create(:taxon, name: "3.2.2", taxonomy:)
- taxon.children << taxon2
- taxonomy.root.children << taxon
end
context "as a normal user" do
let(:current_api_user) { build(:user) }
- it "gets all taxons for a taxonomy" do
- api_get :index, taxonomy_id: taxonomy.id
-
- expect(json_response.first['name']).to eq taxon.name
- end
-
it "gets all taxons" do
api_get :index
@@ -43,31 +32,21 @@ RSpec.describe Api::V0::TaxonsController do
expect(json_response.first['name']).to eq "Ruby"
end
- it "gets all taxons in JSTree form" do
- api_get :jstree, taxonomy_id: taxonomy.id, id: taxon.id
-
- response = json_response.first
- expect(response["data"]).to eq(taxon2.name)
- expect(response["attr"]).to eq("name" => taxon2.name, "id" => taxon2.id)
- expect(response["state"]).to eq("closed")
- end
-
it "cannot create a new taxon if not an admin" do
- api_post :create, taxonomy_id: taxonomy.id, taxon: { name: "Location" }
+ api_post :create, taxon: { name: "Location" }
assert_unauthorized!
end
it "cannot update a taxon" do
- api_put :update, taxonomy_id: taxonomy.id,
- id: taxon.id,
+ api_put :update, id: taxon.id,
taxon: { name: "I hacked your store!" }
assert_unauthorized!
end
it "cannot delete a taxon" do
- api_delete :destroy, taxonomy_id: taxonomy.id, id: taxon.id
+ api_delete :destroy, id: taxon.id
assert_unauthorized!
end
@@ -77,42 +56,25 @@ RSpec.describe Api::V0::TaxonsController do
let(:current_api_user) { build(:admin_user) }
it "can create" do
- api_post :create, taxonomy_id: taxonomy.id, taxon: { name: "Colors" }
+ api_post :create, taxon: { name: "Colors" }
expect(attributes.all? { |a| json_response.include? a }).to be true
expect(response.status).to eq(201)
-
- expect(taxonomy.reload.root.children.count).to eq 2
-
- expect(Spree::Taxon.last.parent_id).to eq taxonomy.root.id
- expect(Spree::Taxon.last.taxonomy_id).to eq taxonomy.id
end
it "cannot create a new taxon with invalid attributes" do
- api_post :create, taxonomy_id: taxonomy.id, taxon: {}
+ api_post :create, taxon: {}
expect(response.status).to eq(422)
expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
errors = json_response["errors"]
- expect(taxonomy.reload.root.children.count).to eq 1
- end
-
- it "cannot create a new taxon with invalid taxonomy_id" do
- api_post :create, taxonomy_id: 1000, taxon: { name: "Colors" }
-
- expect(response.status).to eq(422)
- expect(json_response["error"]).to eq("Invalid resource. Please fix errors and try again.")
-
- errors = json_response["errors"]
- expect(errors["taxonomy_id"]).not_to be_nil
- expect(errors["taxonomy_id"].first).to eq "Invalid taxonomy id."
-
- expect(taxonomy.reload.root.children.count).to eq 1
+ expect(Spree::Taxon.last).to eq taxon2
+ expect(errors['name']).to eq ["can't be blank"]
end
it "can destroy" do
- api_delete :destroy, taxonomy_id: taxonomy.id, id: taxon2.id
+ api_delete :destroy, id: taxon2.id
expect(response.status).to eq(204)
end
diff --git a/spec/controllers/spree/admin/taxons_controller_spec.rb b/spec/controllers/spree/admin/taxons_controller_spec.rb
index 3abc6669aa..4afa43166b 100644
--- a/spec/controllers/spree/admin/taxons_controller_spec.rb
+++ b/spec/controllers/spree/admin/taxons_controller_spec.rb
@@ -5,28 +5,68 @@ require 'spec_helper'
RSpec.describe Spree::Admin::TaxonsController do
render_views
- let(:taxonomy) { create(:taxonomy) }
- let(:taxon) { create(:taxon, name: "Ruby", taxonomy:) }
- let(:taxon2) { create(:taxon, name: "Rails", taxonomy:) }
+ let!(:taxon) { create(:taxon, name: "Ruby") }
+ let!(:taxon2) { create(:taxon, name: "Rails") }
+ let(:valid_attributes) { attributes_for(:taxon) }
before do
allow(controller).to receive(:spree_current_user) { current_api_user }
-
- taxonomy.root.children << taxon
- taxonomy.root.children << taxon2
end
- context "as an admin" do
+ describe 'admin user' do
let(:current_api_user) { build(:admin_user) }
- it "can reorder taxons" do
- spree_post :update,
- taxonomy_id: taxonomy.id,
- id: taxon2.id,
- taxon: { parent_id: taxonomy.root.id, position: 0 }
+ it "can view all taxons" do
+ spree_get :index
- expect(taxon2.reload.lft).to eq 2
- expect(Spree::Taxonomy.find(taxonomy.id).root.children.first).to eq(taxon2)
+ expect(response).to have_http_status :ok
+ end
+
+ it "open taxon edit form" do
+ spree_get :edit, { id: taxon.id }
+
+ expect(response).to have_http_status :ok
+ end
+
+ it "open taxon edit form" do
+ spree_get :new
+
+ expect(response).to have_http_status :ok
+ end
+
+ context "create" do
+ it "persist data with valid attributes" do
+ spree_post :create, valid_attributes
+
+ expect(Spree::Taxon.last.name).to eq valid_attributes[:name]
+ expect(response).to have_http_status :found
+ end
+
+ it "returns error with invalid attributes" do
+ spree_post :create, { name: '' }
+
+ expect(Spree::Taxon.count).to eq 2
+ expect(response).to have_http_status :unprocessable_entity
+ end
+ end
+
+ context "update" do
+ let!(:new_taxon) { create(:taxon, valid_attributes) }
+ it "persist data with valid attributes" do
+ spree_post :update, id: new_taxon.id,
+ taxon: valid_attributes.merge({ name: 'Taxon name updated' })
+
+ expect(new_taxon.reload.name).to eq 'Taxon name updated'
+ expect(response).to have_http_status :found
+ end
+
+ it "returns error with invalid attributes" do
+ spree_post :update, id: new_taxon.id,
+ taxon: { **valid_attributes, name: '' }
+
+ expect(new_taxon.reload.name).to eq valid_attributes[:name]
+ expect(response).to have_http_status :unprocessable_entity
+ end
end
end
end
diff --git a/spec/factories/taxon_factory.rb b/spec/factories/taxon_factory.rb
index fa8bae12d3..2344e35fe5 100644
--- a/spec/factories/taxon_factory.rb
+++ b/spec/factories/taxon_factory.rb
@@ -3,7 +3,5 @@
FactoryBot.define do
factory :taxon, class: Spree::Taxon do
name { 'Ruby on Rails' }
- taxonomy
- parent_id { nil }
end
end
diff --git a/spec/factories/taxonomy_factory.rb b/spec/factories/taxonomy_factory.rb
deleted file mode 100644
index eafe9f8a61..0000000000
--- a/spec/factories/taxonomy_factory.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :taxonomy, class: Spree::Taxonomy do
- name { 'Brand' }
- end
-end
diff --git a/spec/fixtures/simplecov/customer/.resultset.json b/spec/fixtures/simplecov/customer/.resultset.json
new file mode 100644
index 0000000000..130cfe0072
--- /dev/null
+++ b/spec/fixtures/simplecov/customer/.resultset.json
@@ -0,0 +1,85 @@
+{
+ "RSpec": {
+ "coverage": {
+ "/Users/josephjohansen/code/open_food_foundation/openfoodnetwork/app/models/customer.rb": {
+ "lines": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ 1,
+ null,
+ 1,
+ null,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ null,
+ 1,
+ 1,
+ 1,
+ null,
+ 1,
+ 1,
+ 1,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 8,
+ 1,
+ 6,
+ null,
+ 2,
+ 2,
+ null,
+ 1,
+ null,
+ 1,
+ 0,
+ null,
+ null,
+ 1,
+ null,
+ 1,
+ 31,
+ null,
+ null,
+ 1,
+ 31,
+ null,
+ null,
+ 1,
+ 24,
+ null,
+ null,
+ 1,
+ 0,
+ 0,
+ 0,
+ null,
+ 0,
+ null,
+ null
+ ]
+ }
+ },
+ "timestamp": 1724235565
+ }
+}
diff --git a/spec/fixtures/simplecov/voucher/.resultset.json b/spec/fixtures/simplecov/voucher/.resultset.json
new file mode 100644
index 0000000000..db9d793e0e
--- /dev/null
+++ b/spec/fixtures/simplecov/voucher/.resultset.json
@@ -0,0 +1,68 @@
+{
+ "RSpec": {
+ "coverage": {
+ "/Users/josephjohansen/code/open_food_foundation/openfoodnetwork/app/models/voucher.rb": {
+ "lines": [
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ 1,
+ null,
+ 1,
+ null,
+ null,
+ null,
+ 1,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ null,
+ 1,
+ null,
+ 1,
+ 15,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 1,
+ null,
+ 3,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 3,
+ null,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null,
+ 1,
+ 1,
+ null,
+ null
+ ]
+ }
+ },
+ "timestamp": 1724239602
+ }
+}
diff --git a/spec/fixtures/vcr_cassettes/DFC_Product_Import/imports_from_a_FDC_catalog.yml b/spec/fixtures/vcr_cassettes/DFC_Product_Import/imports_from_a_FDC_catalog.yml
index ad4af0b09b..3b476e79da 100644
--- a/spec/fixtures/vcr_cassettes/DFC_Product_Import/imports_from_a_FDC_catalog.yml
+++ b/spec/fixtures/vcr_cassettes/DFC_Product_Import/imports_from_a_FDC_catalog.yml
@@ -1,11 +1,11 @@
---
http_interactions:
- request:
- method: post
- uri: https://food-data-collaboration-produc-fe870152f634.herokuapp.com/fdc/products?shop=test-hodmedod.myshopify.com
+ method: get
+ uri: https://env-0105831.jcloud-ver-jpe.ik-server.com/api/dfc/Enterprises/test-hodmedod/SuppliedProducts
body:
- encoding: UTF-8
- string: '{"userId":"testdfc@protonmail.com","accessToken":" 𝐂𝐎̛𝐌 𝐓𝐀̂́𝐌 𝐂𝐇𝐔́ 𝐁𝐄́ is now available in Melbourne, everyone. 😂 𝐂𝐎̛𝐌 𝐓𝐀̂́𝐌 𝐂𝐇𝐔́ 𝐁𝐄́ is now available in Melbourne, everyone. 😂 Fred Farmer is a certified organic
+ ... Fred Farmer is a certified organic alert(\"Gotcha!\")...
+ <>>> The story is this is a person who loves to eat...
+ <>>> The story is this is a person who loves to eat..."); }
- obj.children("ul").prepend(d);
- tmp = obj;
- break;
- case "last":
- if(!obj.children("ul").length) { obj.append("
"); }
- obj.children("ul").append(d);
- tmp = obj;
- break;
- default:
- if(!obj.children("ul").length) { obj.append("
"); }
- if(!position) { position = 0; }
- tmp = obj.children("ul").children("li").eq(position);
- if(tmp.length) { tmp.before(d); }
- else { obj.children("ul").append(d); }
- tmp = obj;
- break;
- }
- if(tmp === -1 || tmp.get(0) === this.get_container().get(0)) { tmp = -1; }
- this.clean_node(tmp);
- this.__callback({ "obj" : d, "parent" : tmp });
- if(callback) { callback.call(this, d); }
- return d;
- },
- // Basic operations: rename (deal with text)
- get_text : function (obj) {
- obj = this._get_node(obj);
- if(!obj.length) { return false; }
- var s = this._get_settings().core.html_titles;
- obj = obj.children("a:eq(0)");
- if(s) {
- obj = obj.clone();
- obj.children("INS").remove();
- return obj.html();
- }
- else {
- obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
- return obj.nodeValue;
- }
- },
- set_text : function (obj, val) {
- obj = this._get_node(obj);
- if(!obj.length) { return false; }
- obj = obj.children("a:eq(0)");
- if(this._get_settings().core.html_titles) {
- var tmp = obj.children("INS").clone();
- obj.html(val).prepend(tmp);
- this.__callback({ "obj" : obj, "name" : val });
- return true;
- }
- else {
- obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
- this.__callback({ "obj" : obj, "name" : val });
- return (obj.nodeValue = val);
- }
- },
- rename_node : function (obj, val) {
- obj = this._get_node(obj);
- this.__rollback();
- if(obj && obj.length && this.set_text.apply(this, Array.prototype.slice.call(arguments))) { this.__callback({ "obj" : obj, "name" : val }); }
- },
- // Basic operations: deleting nodes
- delete_node : function (obj) {
- obj = this._get_node(obj);
- if(!obj.length) { return false; }
- this.__rollback();
- var p = this._get_parent(obj), prev = $([]), t = this;
- obj.each(function () {
- prev = prev.add(t._get_prev(this));
- });
- obj = obj.detach();
- if(p !== -1 && p.find("> ul > li").length === 0) {
- p.removeClass("jstree-open jstree-closed").addClass("jstree-leaf");
- }
- this.clean_node(p);
- this.__callback({ "obj" : obj, "prev" : prev, "parent" : p });
- return obj;
- },
- prepare_move : function (o, r, pos, cb, is_cb) {
- var p = {};
-
- p.ot = $.jstree._reference(o) || this;
- p.o = p.ot._get_node(o);
- p.r = r === - 1 ? -1 : this._get_node(r);
- p.p = (typeof pos === "undefined" || pos === false) ? "last" : pos; // TODO: move to a setting
- if(!is_cb && prepared_move.o && prepared_move.o[0] === p.o[0] && prepared_move.r[0] === p.r[0] && prepared_move.p === p.p) {
- this.__callback(prepared_move);
- if(cb) { cb.call(this, prepared_move); }
- return;
- }
- p.ot = $.jstree._reference(p.o) || this;
- p.rt = $.jstree._reference(p.r) || this; // r === -1 ? p.ot : $.jstree._reference(p.r) || this
- if(p.r === -1 || !p.r) {
- p.cr = -1;
- switch(p.p) {
- case "first":
- case "before":
- case "inside":
- p.cp = 0;
- break;
- case "after":
- case "last":
- p.cp = p.rt.get_container().find(" > ul > li").length;
- break;
- default:
- p.cp = p.p;
- break;
- }
- }
- else {
- if(!/^(before|after)$/.test(p.p) && !this._is_loaded(p.r)) {
- return this.load_node(p.r, function () { this.prepare_move(o, r, pos, cb, true); });
- }
- switch(p.p) {
- case "before":
- p.cp = p.r.index();
- p.cr = p.rt._get_parent(p.r);
- break;
- case "after":
- p.cp = p.r.index() + 1;
- p.cr = p.rt._get_parent(p.r);
- break;
- case "inside":
- case "first":
- p.cp = 0;
- p.cr = p.r;
- break;
- case "last":
- p.cp = p.r.find(" > ul > li").length;
- p.cr = p.r;
- break;
- default:
- p.cp = p.p;
- p.cr = p.r;
- break;
- }
- }
- p.np = p.cr == -1 ? p.rt.get_container() : p.cr;
- p.op = p.ot._get_parent(p.o);
- p.cop = p.o.index();
- if(p.op === -1) { p.op = p.ot ? p.ot.get_container() : this.get_container(); }
- if(!/^(before|after)$/.test(p.p) && p.op && p.np && p.op[0] === p.np[0] && p.o.index() < p.cp) { p.cp++; }
- //if(p.p === "before" && p.op && p.np && p.op[0] === p.np[0] && p.o.index() < p.cp) { p.cp--; }
- p.or = p.np.find(" > ul > li:nth-child(" + (p.cp + 1) + ")");
- prepared_move = p;
- this.__callback(prepared_move);
- if(cb) { cb.call(this, prepared_move); }
- },
- check_move : function () {
- var obj = prepared_move, ret = true, r = obj.r === -1 ? this.get_container() : obj.r;
- if(!obj || !obj.o || obj.or[0] === obj.o[0]) { return false; }
- if(obj.op && obj.np && obj.op[0] === obj.np[0] && obj.cp - 1 === obj.o.index()) { return false; }
- obj.o.each(function () {
- if(r.parentsUntil(".jstree", "li").andSelf().index(this) !== -1) { ret = false; return false; }
- });
- return ret;
- },
- move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) {
- if(!is_prepared) {
- return this.prepare_move(obj, ref, position, function (p) {
- this.move_node(p, false, false, is_copy, true, skip_check);
- });
- }
- if(is_copy) {
- prepared_move.cy = true;
- }
- if(!skip_check && !this.check_move()) { return false; }
-
- this.__rollback();
- var o = false;
- if(is_copy) {
- o = obj.o.clone(true);
- o.find("*[id]").andSelf().each(function () {
- if(this.id) { this.id = "copy_" + this.id; }
- });
- }
- else { o = obj.o; }
-
- if(obj.or.length) { obj.or.before(o); }
- else {
- if(!obj.np.children("ul").length) { $("
").appendTo(obj.np); }
- obj.np.children("ul:eq(0)").append(o);
- }
-
- try {
- obj.ot.clean_node(obj.op);
- obj.rt.clean_node(obj.np);
- if(!obj.op.find("> ul > li").length) {
- obj.op.removeClass("jstree-open jstree-closed").addClass("jstree-leaf").children("ul").remove();
- }
- } catch (e) { }
-
- if(is_copy) {
- prepared_move.cy = true;
- prepared_move.oc = o;
- }
- this.__callback(prepared_move);
- return prepared_move;
- },
- _get_move : function () { return prepared_move; }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree ui plugin
- * This plugins handles selecting/deselecting/hovering/dehovering nodes
- */
-(function ($) {
- var scrollbar_width, e1, e2;
- $(function() {
- if (/msie/.test(navigator.userAgent.toLowerCase())) {
- e1 = $('').css({ position: 'absolute', top: -1000, left: 0 }).appendTo('body');
- e2 = $('').css({ position: 'absolute', top: -1000, left: 0 }).appendTo('body');
- scrollbar_width = e1.width() - e2.width();
- e1.add(e2).remove();
- }
- else {
- e1 = $('').css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: 0 })
- .prependTo('body').append('').find('div').css({ width: '100%', height: 200 });
- scrollbar_width = 100 - e1.width();
- e1.parent().remove();
- }
- });
- $.jstree.plugin("ui", {
- __init : function () {
- this.data.ui.selected = $();
- this.data.ui.last_selected = false;
- this.data.ui.hovered = null;
- this.data.ui.to_select = this.get_settings().ui.initially_select;
-
- this.get_container()
- .delegate("a", "click.jstree", $.proxy(function (event) {
- event.preventDefault();
- event.currentTarget.blur();
- if(!$(event.currentTarget).hasClass("jstree-loading")) {
- this.select_node(event.currentTarget, true, event);
- }
- }, this))
- .delegate("a", "mouseenter.jstree", $.proxy(function (event) {
- if(!$(event.currentTarget).hasClass("jstree-loading")) {
- this.hover_node(event.target);
- }
- }, this))
- .delegate("a", "mouseleave.jstree", $.proxy(function (event) {
- if(!$(event.currentTarget).hasClass("jstree-loading")) {
- this.dehover_node(event.target);
- }
- }, this))
- .bind("reopen.jstree", $.proxy(function () {
- this.reselect();
- }, this))
- .bind("get_rollback.jstree", $.proxy(function () {
- this.dehover_node();
- this.save_selected();
- }, this))
- .bind("set_rollback.jstree", $.proxy(function () {
- this.reselect();
- }, this))
- .bind("close_node.jstree", $.proxy(function (event, data) {
- var s = this._get_settings().ui,
- obj = this._get_node(data.rslt.obj),
- clk = (obj && obj.length) ? obj.children("ul").find("a.jstree-clicked") : $(),
- _this = this;
- if(s.selected_parent_close === false || !clk.length) { return; }
- clk.each(function () {
- _this.deselect_node(this);
- if(s.selected_parent_close === "select_parent") { _this.select_node(obj); }
- });
- }, this))
- .bind("delete_node.jstree", $.proxy(function (event, data) {
- var s = this._get_settings().ui.select_prev_on_delete,
- obj = this._get_node(data.rslt.obj),
- clk = (obj && obj.length) ? obj.find("a.jstree-clicked") : [],
- _this = this;
- clk.each(function () { _this.deselect_node(this); });
- if(s && clk.length) {
- data.rslt.prev.each(function () {
- if(this.parentNode) { _this.select_node(this); return false; /* if return false is removed all prev nodes will be selected */}
- });
- }
- }, this))
- .bind("move_node.jstree", $.proxy(function (event, data) {
- if(data.rslt.cy) {
- data.rslt.oc.find("a.jstree-clicked").removeClass("jstree-clicked");
- }
- }, this));
- },
- defaults : {
- select_limit : -1, // 0, 1, 2 ... or -1 for unlimited
- select_multiple_modifier : "ctrl", // on, or ctrl, shift, alt
- select_range_modifier : "shift",
- selected_parent_close : "select_parent", // false, "deselect", "select_parent"
- selected_parent_open : true,
- select_prev_on_delete : true,
- disable_selecting_children : false,
- initially_select : []
- },
- _fn : {
- _get_node : function (obj, allow_multiple) {
- if(typeof obj === "undefined" || obj === null) { return allow_multiple ? this.data.ui.selected : this.data.ui.last_selected; }
- var $obj = $(obj, this.get_container());
- if($obj.is(".jstree") || obj == -1) { return -1; }
- $obj = $obj.closest("li", this.get_container());
- return $obj.length ? $obj : false;
- },
- _ui_notify : function (n, data) {
- if(data.selected) {
- this.select_node(n, false);
- }
- },
- save_selected : function () {
- var _this = this;
- this.data.ui.to_select = [];
- this.data.ui.selected.each(function () { if(this.id) { _this.data.ui.to_select.push("#" + this.id.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:")); } });
- this.__callback(this.data.ui.to_select);
- },
- reselect : function () {
- var _this = this,
- s = this.data.ui.to_select;
- s = $.map($.makeArray(s), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
- // this.deselect_all(); WHY deselect, breaks plugin state notifier?
- $.each(s, function (i, val) { if(val && val !== "#") { _this.select_node(val); } });
- this.data.ui.selected = this.data.ui.selected.filter(function () { return this.parentNode; });
- this.__callback();
- },
- refresh : function (obj) {
- this.save_selected();
- return this.__call_old();
- },
- hover_node : function (obj) {
- obj = this._get_node(obj);
- if(!obj.length) { return false; }
- //if(this.data.ui.hovered && obj.get(0) === this.data.ui.hovered.get(0)) { return; }
- if(!obj.hasClass("jstree-hovered")) { this.dehover_node(); }
- this.data.ui.hovered = obj.children("a").addClass("jstree-hovered").parent();
- this._fix_scroll(obj);
- this.__callback({ "obj" : obj });
- },
- dehover_node : function () {
- var obj = this.data.ui.hovered, p;
- if(!obj || !obj.length) { return false; }
- p = obj.children("a").removeClass("jstree-hovered").parent();
- if(this.data.ui.hovered[0] === p[0]) { this.data.ui.hovered = null; }
- this.__callback({ "obj" : obj });
- },
- select_node : function (obj, check, e) {
- obj = this._get_node(obj);
- if(obj == -1 || !obj || !obj.length) { return false; }
- var s = this._get_settings().ui,
- is_multiple = (s.select_multiple_modifier == "on" || (s.select_multiple_modifier !== false && e && e[s.select_multiple_modifier + "Key"])),
- is_range = (s.select_range_modifier !== false && e && e[s.select_range_modifier + "Key"] && this.data.ui.last_selected && this.data.ui.last_selected[0] !== obj[0] && this.data.ui.last_selected.parent()[0] === obj.parent()[0]),
- is_selected = this.is_selected(obj),
- proceed = true,
- t = this;
- if(check) {
- if(s.disable_selecting_children && is_multiple &&
- (
- (obj.parentsUntil(".jstree","li").children("a.jstree-clicked").length) ||
- (obj.children("ul").find("a.jstree-clicked:eq(0)").length)
- )
- ) {
- return false;
- }
- proceed = false;
- switch(!0) {
- case (is_range):
- this.data.ui.last_selected.addClass("jstree-last-selected");
- obj = obj[ obj.index() < this.data.ui.last_selected.index() ? "nextUntil" : "prevUntil" ](".jstree-last-selected").andSelf();
- if(s.select_limit == -1 || obj.length < s.select_limit) {
- this.data.ui.last_selected.removeClass("jstree-last-selected");
- this.data.ui.selected.each(function () {
- if(this !== t.data.ui.last_selected[0]) { t.deselect_node(this); }
- });
- is_selected = false;
- proceed = true;
- }
- else {
- proceed = false;
- }
- break;
- case (is_selected && !is_multiple):
- this.deselect_all();
- is_selected = false;
- proceed = true;
- break;
- case (!is_selected && !is_multiple):
- if(s.select_limit == -1 || s.select_limit > 0) {
- this.deselect_all();
- proceed = true;
- }
- break;
- case (is_selected && is_multiple):
- this.deselect_node(obj);
- break;
- case (!is_selected && is_multiple):
- if(s.select_limit == -1 || this.data.ui.selected.length + 1 <= s.select_limit) {
- proceed = true;
- }
- break;
- }
- }
- if(proceed && !is_selected) {
- if(!is_range) { this.data.ui.last_selected = obj; }
- obj.children("a").addClass("jstree-clicked");
- if(s.selected_parent_open) {
- obj.parents(".jstree-closed").each(function () { t.open_node(this, false, true); });
- }
- this.data.ui.selected = this.data.ui.selected.add(obj);
- this._fix_scroll(obj.eq(0));
- this.__callback({ "obj" : obj, "e" : e });
- }
- },
- _fix_scroll : function (obj) {
- var c = this.get_container()[0], t;
- if(c.scrollHeight > c.offsetHeight) {
- obj = this._get_node(obj);
- if(!obj || obj === -1 || !obj.length || !obj.is(":visible")) { return; }
- t = obj.offset().top - this.get_container().offset().top;
- if(t < 0) {
- c.scrollTop = c.scrollTop + t - 1;
- }
- if(t + this.data.core.li_height + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0) > c.offsetHeight) {
- c.scrollTop = c.scrollTop + (t - c.offsetHeight + this.data.core.li_height + 1 + (c.scrollWidth > c.offsetWidth ? scrollbar_width : 0));
- }
- }
- },
- deselect_node : function (obj) {
- obj = this._get_node(obj);
- if(!obj.length) { return false; }
- if(this.is_selected(obj)) {
- obj.children("a").removeClass("jstree-clicked");
- this.data.ui.selected = this.data.ui.selected.not(obj);
- if(this.data.ui.last_selected.get(0) === obj.get(0)) { this.data.ui.last_selected = this.data.ui.selected.eq(0); }
- this.__callback({ "obj" : obj });
- }
- },
- toggle_select : function (obj) {
- obj = this._get_node(obj);
- if(!obj.length) { return false; }
- if(this.is_selected(obj)) { this.deselect_node(obj); }
- else { this.select_node(obj); }
- },
- is_selected : function (obj) { return this.data.ui.selected.index(this._get_node(obj)) >= 0; },
- get_selected : function (context) {
- return context ? $(context).find("a.jstree-clicked").parent() : this.data.ui.selected;
- },
- deselect_all : function (context) {
- var ret = context ? $(context).find("a.jstree-clicked").parent() : this.get_container().find("a.jstree-clicked").parent();
- ret.children("a.jstree-clicked").removeClass("jstree-clicked");
- this.data.ui.selected = $([]);
- this.data.ui.last_selected = false;
- this.__callback({ "obj" : ret });
- }
- }
- });
- // include the selection plugin by default
- $.jstree.defaults.plugins.push("ui");
-})(jQuery);
-//*/
-
-/*
- * jsTree CRRM plugin
- * Handles creating/renaming/removing/moving nodes by user interaction.
- */
-(function ($) {
- $.jstree.plugin("crrm", {
- __init : function () {
- this.get_container()
- .bind("move_node.jstree", $.proxy(function (e, data) {
- if(this._get_settings().crrm.move.open_onmove) {
- var t = this;
- data.rslt.np.parentsUntil(".jstree").andSelf().filter(".jstree-closed").each(function () {
- t.open_node(this, false, true);
- });
- }
- }, this));
- },
- defaults : {
- input_width_limit : 200,
- move : {
- always_copy : false, // false, true or "multitree"
- open_onmove : true,
- default_position : "last",
- check_move : function (m) { return true; }
- }
- },
- _fn : {
- _show_input : function (obj, callback) {
- obj = this._get_node(obj);
- var rtl = this._get_settings().core.rtl,
- w = this._get_settings().crrm.input_width_limit,
- w1 = obj.children("ins").width(),
- w2 = obj.find("> a:visible > ins").width() * obj.find("> a:visible > ins").length,
- t = this.get_text(obj),
- h1 = $("", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"),
- h2 = obj.css("position","relative").append(
- $("", {
- "value" : t,
- "class" : "jstree-rename-input",
- // "size" : t.length,
- "css" : {
- "padding" : "0",
- "border" : "1px solid silver",
- "position" : "absolute",
- "left" : (rtl ? "auto" : (w1 + w2 + 4) + "px"),
- "right" : (rtl ? (w1 + w2 + 4) + "px" : "auto"),
- "top" : "0px",
- "height" : (this.data.core.li_height - 2) + "px",
- "lineHeight" : (this.data.core.li_height - 2) + "px",
- "width" : "150px" // will be set a bit further down
- },
- "blur" : $.proxy(function () {
- var i = obj.children(".jstree-rename-input"),
- v = i.val();
- if(v === "") { v = t; }
- h1.remove();
- i.remove(); // rollback purposes
- this.set_text(obj,t); // rollback purposes
- this.rename_node(obj, v);
- callback.call(this, obj, v, t);
- obj.css("position","");
- }, this),
- "keyup" : function (event) {
- var key = event.keyCode || event.which;
- if(key == 27) { this.value = t; this.blur(); return; }
- else if(key == 13) { this.blur(); return; }
- else {
- h2.width(Math.min(h1.text("pW" + this.value).width(),w));
- }
- },
- "keypress" : function(event) {
- var key = event.keyCode || event.which;
- if(key == 13) { return false; }
- }
- })
- ).children(".jstree-rename-input");
- this.set_text(obj, "");
- h1.css({
- fontFamily : h2.css('fontFamily') || '',
- fontSize : h2.css('fontSize') || '',
- fontWeight : h2.css('fontWeight') || '',
- fontStyle : h2.css('fontStyle') || '',
- fontStretch : h2.css('fontStretch') || '',
- fontVariant : h2.css('fontVariant') || '',
- letterSpacing : h2.css('letterSpacing') || '',
- wordSpacing : h2.css('wordSpacing') || ''
- });
- h2.width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select();
- },
- rename : function (obj) {
- obj = this._get_node(obj);
- this.__rollback();
- var f = this.__callback;
- this._show_input(obj, function (obj, new_name, old_name) {
- f.call(this, { "obj" : obj, "new_name" : new_name, "old_name" : old_name });
- });
- },
- create : function (obj, position, js, callback, skip_rename) {
- var t, _this = this;
- obj = this._get_node(obj);
- if(!obj) { obj = -1; }
- this.__rollback();
- t = this.create_node(obj, position, js, function (t) {
- var p = this._get_parent(t),
- pos = $(t).index();
- if(callback) { callback.call(this, t); }
- if(p.length && p.hasClass("jstree-closed")) { this.open_node(p, false, true); }
- if(!skip_rename) {
- this._show_input(t, function (obj, new_name, old_name) {
- _this.__callback({ "obj" : obj, "name" : new_name, "parent" : p, "position" : pos });
- });
- }
- else { _this.__callback({ "obj" : t, "name" : this.get_text(t), "parent" : p, "position" : pos }); }
- });
- return t;
- },
- remove : function (obj) {
- obj = this._get_node(obj, true);
- var p = this._get_parent(obj), prev = this._get_prev(obj);
- this.__rollback();
- obj = this.delete_node(obj);
- if(obj !== false) { this.__callback({ "obj" : obj, "prev" : prev, "parent" : p }); }
- },
- check_move : function () {
- if(!this.__call_old()) { return false; }
- var s = this._get_settings().crrm.move;
- if(!s.check_move.call(this, this._get_move())) { return false; }
- return true;
- },
- move_node : function (obj, ref, position, is_copy, is_prepared, skip_check) {
- var s = this._get_settings().crrm.move;
- if(!is_prepared) {
- if(typeof position === "undefined") { position = s.default_position; }
- if(position === "inside" && !s.default_position.match(/^(before|after)$/)) { position = s.default_position; }
- return this.__call_old(true, obj, ref, position, is_copy, false, skip_check);
- }
- // if the move is already prepared
- if(s.always_copy === true || (s.always_copy === "multitree" && obj.rt.get_index() !== obj.ot.get_index() )) {
- is_copy = true;
- }
- this.__call_old(true, obj, ref, position, is_copy, true, skip_check);
- },
-
- cut : function (obj) {
- obj = this._get_node(obj, true);
- if(!obj || !obj.length) { return false; }
- this.data.crrm.cp_nodes = false;
- this.data.crrm.ct_nodes = obj;
- this.__callback({ "obj" : obj });
- },
- copy : function (obj) {
- obj = this._get_node(obj, true);
- if(!obj || !obj.length) { return false; }
- this.data.crrm.ct_nodes = false;
- this.data.crrm.cp_nodes = obj;
- this.__callback({ "obj" : obj });
- },
- paste : function (obj) {
- obj = this._get_node(obj);
- if(!obj || !obj.length) { return false; }
- var nodes = this.data.crrm.ct_nodes ? this.data.crrm.ct_nodes : this.data.crrm.cp_nodes;
- if(!this.data.crrm.ct_nodes && !this.data.crrm.cp_nodes) { return false; }
- if(this.data.crrm.ct_nodes) { this.move_node(this.data.crrm.ct_nodes, obj); this.data.crrm.ct_nodes = false; }
- if(this.data.crrm.cp_nodes) { this.move_node(this.data.crrm.cp_nodes, obj, false, true); }
- this.__callback({ "obj" : obj, "nodes" : nodes });
- }
- }
- });
- // include the crr plugin by default
- // $.jstree.defaults.plugins.push("crrm");
-})(jQuery);
-//*/
-
-/*
- * jsTree themes plugin
- * Handles loading and setting themes, as well as detecting path to themes, etc.
- */
-(function ($) {
- var themes_loaded = [];
- // this variable stores the path to the themes folder - if left as false - it will be autodetected
- $.jstree._themes = false;
- $.jstree.plugin("themes", {
- __init : function () {
- this.get_container()
- .bind("init.jstree", $.proxy(function () {
- var s = this._get_settings().themes;
- this.data.themes.dots = s.dots;
- this.data.themes.icons = s.icons;
- this.set_theme(s.theme, s.url);
- }, this))
- .bind("loaded.jstree", $.proxy(function () {
- // bound here too, as simple HTML tree's won't honor dots & icons otherwise
- if(!this.data.themes.dots) { this.hide_dots(); }
- else { this.show_dots(); }
- if(!this.data.themes.icons) { this.hide_icons(); }
- else { this.show_icons(); }
- }, this));
- },
- defaults : {
- theme : "default",
- url : false,
- dots : true,
- icons : true
- },
- _fn : {
- set_theme : function (theme_name, theme_url) {
- if(!theme_name) { return false; }
- if(!theme_url) { theme_url = $.jstree._themes + theme_name + '/style.css'; }
- if($.inArray(theme_url, themes_loaded) == -1) {
- $.vakata.css.add_sheet({ "url" : theme_url });
- themes_loaded.push(theme_url);
- }
- if(this.data.themes.theme != theme_name) {
- this.get_container().removeClass('jstree-' + this.data.themes.theme);
- this.data.themes.theme = theme_name;
- }
- this.get_container().addClass('jstree-' + theme_name);
- if(!this.data.themes.dots) { this.hide_dots(); }
- else { this.show_dots(); }
- if(!this.data.themes.icons) { this.hide_icons(); }
- else { this.show_icons(); }
- this.__callback();
- },
- get_theme : function () { return this.data.themes.theme; },
-
- show_dots : function () { this.data.themes.dots = true; this.get_container().children("ul").removeClass("jstree-no-dots"); },
- hide_dots : function () { this.data.themes.dots = false; this.get_container().children("ul").addClass("jstree-no-dots"); },
- toggle_dots : function () { if(this.data.themes.dots) { this.hide_dots(); } else { this.show_dots(); } },
-
- show_icons : function () { this.data.themes.icons = true; this.get_container().children("ul").removeClass("jstree-no-icons"); },
- hide_icons : function () { this.data.themes.icons = false; this.get_container().children("ul").addClass("jstree-no-icons"); },
- toggle_icons: function () { if(this.data.themes.icons) { this.hide_icons(); } else { this.show_icons(); } }
- }
- });
- // autodetect themes path
- $(function () {
- if($.jstree._themes === false) {
- $("script").each(function () {
- if(this.src.toString().match(/jquery\.jstree[^\/]*?\.js(\?.*)?$/)) {
- $.jstree._themes = this.src.toString().replace(/jquery\.jstree[^\/]*?\.js(\?.*)?$/, "") + 'themes/';
- return false;
- }
- });
- }
- if($.jstree._themes === false) { $.jstree._themes = "themes/"; }
- });
- // include the themes plugin by default
- $.jstree.defaults.plugins.push("themes");
-})(jQuery);
-//*/
-
-/*
- * jsTree hotkeys plugin
- * Enables keyboard navigation for all tree instances
- * Depends on the jstree ui & jquery hotkeys plugins
- */
-(function ($) {
- var bound = [];
- function exec(i, event) {
- var f = $.jstree._focused(), tmp;
- if(f && f.data && f.data.hotkeys && f.data.hotkeys.enabled) {
- tmp = f._get_settings().hotkeys[i];
- if(tmp) { return tmp.call(f, event); }
- }
- }
- $.jstree.plugin("hotkeys", {
- __init : function () {
- if(typeof $.hotkeys === "undefined") { throw "jsTree hotkeys: jQuery hotkeys plugin not included."; }
- if(!this.data.ui) { throw "jsTree hotkeys: jsTree UI plugin not included."; }
- $.each(this._get_settings().hotkeys, function (i, v) {
- if(v !== false && $.inArray(i, bound) == -1) {
- $(document).bind("keydown", i, function (event) { return exec(i, event); });
- bound.push(i);
- }
- });
- this.get_container()
- .bind("lock.jstree", $.proxy(function () {
- if(this.data.hotkeys.enabled) { this.data.hotkeys.enabled = false; this.data.hotkeys.revert = true; }
- }, this))
- .bind("unlock.jstree", $.proxy(function () {
- if(this.data.hotkeys.revert) { this.data.hotkeys.enabled = true; }
- }, this));
- this.enable_hotkeys();
- },
- defaults : {
- "up" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
- this.hover_node(this._get_prev(o));
- return false;
- },
- "ctrl+up" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
- this.hover_node(this._get_prev(o));
- return false;
- },
- "shift+up" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
- this.hover_node(this._get_prev(o));
- return false;
- },
- "down" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
- this.hover_node(this._get_next(o));
- return false;
- },
- "ctrl+down" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
- this.hover_node(this._get_next(o));
- return false;
- },
- "shift+down" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
- this.hover_node(this._get_next(o));
- return false;
- },
- "left" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected;
- if(o) {
- if(o.hasClass("jstree-open")) { this.close_node(o); }
- else { this.hover_node(this._get_prev(o)); }
- }
- return false;
- },
- "ctrl+left" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected;
- if(o) {
- if(o.hasClass("jstree-open")) { this.close_node(o); }
- else { this.hover_node(this._get_prev(o)); }
- }
- return false;
- },
- "shift+left" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected;
- if(o) {
- if(o.hasClass("jstree-open")) { this.close_node(o); }
- else { this.hover_node(this._get_prev(o)); }
- }
- return false;
- },
- "right" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected;
- if(o && o.length) {
- if(o.hasClass("jstree-closed")) { this.open_node(o); }
- else { this.hover_node(this._get_next(o)); }
- }
- return false;
- },
- "ctrl+right" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected;
- if(o && o.length) {
- if(o.hasClass("jstree-closed")) { this.open_node(o); }
- else { this.hover_node(this._get_next(o)); }
- }
- return false;
- },
- "shift+right" : function () {
- var o = this.data.ui.hovered || this.data.ui.last_selected;
- if(o && o.length) {
- if(o.hasClass("jstree-closed")) { this.open_node(o); }
- else { this.hover_node(this._get_next(o)); }
- }
- return false;
- },
- "space" : function () {
- if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").click(); }
- return false;
- },
- "ctrl+space" : function (event) {
- event.type = "click";
- if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); }
- return false;
- },
- "shift+space" : function (event) {
- event.type = "click";
- if(this.data.ui.hovered) { this.data.ui.hovered.children("a:eq(0)").trigger(event); }
- return false;
- },
- "f2" : function () { this.rename(this.data.ui.hovered || this.data.ui.last_selected); },
- "del" : function () { this.remove(this.data.ui.hovered || this._get_node(null)); }
- },
- _fn : {
- enable_hotkeys : function () {
- this.data.hotkeys.enabled = true;
- },
- disable_hotkeys : function () {
- this.data.hotkeys.enabled = false;
- }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree JSON plugin
- * The JSON data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions.
- */
-(function ($) {
- $.jstree.plugin("json_data", {
- __init : function() {
- var s = this._get_settings().json_data;
- if(s.progressive_unload) {
- this.get_container().bind("after_close.jstree", function (e, data) {
- data.rslt.obj.children("ul").remove();
- });
- }
- },
- defaults : {
- // `data` can be a function:
- // * accepts two arguments - node being loaded and a callback to pass the result to
- // * will be executed in the current tree's scope & ajax won't be supported
- data : false,
- ajax : false,
- correct_state : true,
- progressive_render : false,
- progressive_unload : false
- },
- _fn : {
- load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_json(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
- _is_loaded : function (obj) {
- var s = this._get_settings().json_data;
- obj = this._get_node(obj);
- return obj == -1 || !obj || (!s.ajax && !s.progressive_render && !$.isFunction(s.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").length > 0;
- },
- refresh : function (obj) {
- obj = this._get_node(obj);
- var s = this._get_settings().json_data;
- if(obj && obj !== -1 && s.progressive_unload && ($.isFunction(s.data) || !!s.ajax)) {
- obj.removeData("jstree-children");
- }
- return this.__call_old();
- },
- load_node_json : function (obj, s_call, e_call) {
- var s = this.get_settings().json_data, d,
- error_func = function () {},
- success_func = function () {};
- obj = this._get_node(obj);
-
- if(obj && obj !== -1 && (s.progressive_render || s.progressive_unload) && !obj.is(".jstree-open, .jstree-leaf") && obj.children("ul").children("li").length === 0 && obj.data("jstree-children")) {
- d = this._parse_json(obj.data("jstree-children"), obj);
- if(d) {
- obj.append(d);
- if(!s.progressive_unload) { obj.removeData("jstree-children"); }
- }
- this.clean_node(obj);
- if(s_call) { s_call.call(this); }
- return;
- }
-
- if(obj && obj !== -1) {
- if(obj.data("jstree-is-loading")) { return; }
- else { obj.data("jstree-is-loading",true); }
- }
- switch(!0) {
- case (!s.data && !s.ajax): throw "Neither data nor ajax settings supplied.";
- // function option added here for easier model integration (also supporting async - see callback)
- case ($.isFunction(s.data)):
- s.data.call(this, obj, $.proxy(function (d) {
- d = this._parse_json(d, obj);
- if(!d) {
- if(obj === -1 || !obj) {
- if(s.correct_state) { this.get_container().children("ul").empty(); }
- }
- else {
- obj.children("a.jstree-loading").removeClass("jstree-loading");
- obj.removeData("jstree-is-loading");
- if(s.correct_state) { this.correct_state(obj); }
- }
- if(e_call) { e_call.call(this); }
- }
- else {
- if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); }
- else { obj.append(d).children("a.jstree-loading").removeClass("jstree-loading"); obj.removeData("jstree-is-loading"); }
- this.clean_node(obj);
- if(s_call) { s_call.call(this); }
- }
- }, this));
- break;
- case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)):
- if(!obj || obj == -1) {
- d = this._parse_json(s.data, obj);
- if(d) {
- this.get_container().children("ul").empty().append(d.children());
- this.clean_node();
- }
- else {
- if(s.correct_state) { this.get_container().children("ul").empty(); }
- }
- }
- if(s_call) { s_call.call(this); }
- break;
- case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
- error_func = function (x, t, e) {
- var ef = this.get_settings().json_data.ajax.error;
- if(ef) { ef.call(this, x, t, e); }
- if(obj != -1 && obj.length) {
- obj.children("a.jstree-loading").removeClass("jstree-loading");
- obj.removeData("jstree-is-loading");
- if(t === "success" && s.correct_state) { this.correct_state(obj); }
- }
- else {
- if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); }
- }
- if(e_call) { e_call.call(this); }
- };
- success_func = function (d, t, x) {
- var sf = this.get_settings().json_data.ajax.success;
- if(sf) { d = sf.call(this,d,t,x) || d; }
- if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "") || (!$.isArray(d) && !$.isPlainObject(d))) {
- return error_func.call(this, x, t, "");
- }
- d = this._parse_json(d, obj);
- if(d) {
- if(obj === -1 || !obj) { this.get_container().children("ul").empty().append(d.children()); }
- else { obj.append(d).children("a.jstree-loading").removeClass("jstree-loading"); obj.removeData("jstree-is-loading"); }
- this.clean_node(obj);
- if(s_call) { s_call.call(this); }
- }
- else {
- if(obj === -1 || !obj) {
- if(s.correct_state) {
- this.get_container().children("ul").empty();
- if(s_call) { s_call.call(this); }
- }
- }
- else {
- obj.children("a.jstree-loading").removeClass("jstree-loading");
- obj.removeData("jstree-is-loading");
- if(s.correct_state) {
- this.correct_state(obj);
- if(s_call) { s_call.call(this); }
- }
- }
- }
- };
- s.ajax.context = this;
- s.ajax.error = error_func;
- s.ajax.success = success_func;
- if(!s.ajax.dataType) { s.ajax.dataType = "json"; }
- if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); }
- if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); }
- $.ajax(s.ajax);
- break;
- }
- },
- _parse_json : function (js, obj, is_callback) {
- var d = false,
- p = this._get_settings(),
- s = p.json_data,
- t = p.core.html_titles,
- tmp, i, j, ul1, ul2;
-
- if(!js) { return d; }
- if(s.progressive_unload && obj && obj !== -1) {
- obj.data("jstree-children", d);
- }
- if($.isArray(js)) {
- d = $('
');
- if(!js.length) { return false; }
- for(i = 0, j = js.length; i < j; i++) {
- tmp = this._parse_json(js[i], obj, true);
- if(tmp.length) { d = d.append(tmp); }
- }
- d = d.children();
- }
- else {
- if(typeof js == "string") { js = { data : js }; }
- if(!js.data && js.data !== "") { return d; }
- d = $("");
- if(js.attr) { d.attr(js.attr); }
- if(js.metadata) { d.data(js.metadata); }
- if(js.state) { d.addClass("jstree-" + js.state); }
- if(!$.isArray(js.data)) { tmp = js.data; js.data = []; js.data.push(tmp); }
- $.each(js.data, function (i, m) {
- tmp = $("");
- if($.isFunction(m)) { m = m.call(this, js); }
- if(typeof m == "string") { tmp.attr('href','#')[ t ? "html" : "text" ](m); }
- else {
- if(!m.attr) { m.attr = {}; }
- if(!m.attr.href) { m.attr.href = '#'; }
- tmp.attr(m.attr)[ t ? "html" : "text" ](m.title);
- if(m.language) { tmp.addClass(m.language); }
- }
- tmp.prepend(" ");
- if(!m.icon && js.icon) { m.icon = js.icon; }
- if(m.icon) {
- if(m.icon.indexOf("/") === -1) { tmp.children("ins").addClass(m.icon); }
- else { tmp.children("ins").css("background","url('" + m.icon + "') center center no-repeat"); }
- }
- d.append(tmp);
- });
- d.prepend(" ");
- if(js.children) {
- if(s.progressive_render && js.state !== "open") {
- d.addClass("jstree-closed").data("jstree-children", js.children);
- }
- else {
- if(s.progressive_unload) { d.data("jstree-children", js.children); }
- if($.isArray(js.children) && js.children.length) {
- tmp = this._parse_json(js.children, obj, true);
- if(tmp.length) {
- ul2 = $("
");
- ul2.append(tmp);
- d.append(ul2);
- }
- }
- }
- }
- }
- if(!is_callback) {
- ul1 = $("
");
- ul1.append(d);
- d = ul1;
- }
- return d;
- },
- get_json : function (obj, li_attr, a_attr, is_callback) {
- var result = [],
- s = this._get_settings(),
- _this = this,
- tmp1, tmp2, li, a, t, lang;
- obj = this._get_node(obj);
- if(!obj || obj === -1) { obj = this.get_container().find("> ul > li"); }
- li_attr = $.isArray(li_attr) ? li_attr : [ "id", "class" ];
- if(!is_callback && this.data.types) { li_attr.push(s.types.type_attr); }
- a_attr = $.isArray(a_attr) ? a_attr : [ ];
-
- obj.each(function () {
- li = $(this);
- tmp1 = { data : [] };
- if(li_attr.length) { tmp1.attr = { }; }
- $.each(li_attr, function (i, v) {
- tmp2 = li.attr(v);
- if(tmp2 && tmp2.length && tmp2.replace(/jstree[^ ]*/ig,'').length) {
- tmp1.attr[v] = (" " + tmp2).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
- }
- });
- if(li.hasClass("jstree-open")) { tmp1.state = "open"; }
- if(li.hasClass("jstree-closed")) { tmp1.state = "closed"; }
- if(li.data()) { tmp1.metadata = li.data(); }
- a = li.children("a");
- a.each(function () {
- t = $(this);
- if(
- a_attr.length ||
- $.inArray("languages", s.plugins) !== -1 ||
- t.children("ins").get(0).style.backgroundImage.length ||
- (t.children("ins").get(0).className && t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').length)
- ) {
- lang = false;
- if($.inArray("languages", s.plugins) !== -1 && $.isArray(s.languages) && s.languages.length) {
- $.each(s.languages, function (l, lv) {
- if(t.hasClass(lv)) {
- lang = lv;
- return false;
- }
- });
- }
- tmp2 = { attr : { }, title : _this.get_text(t, lang) };
- $.each(a_attr, function (k, z) {
- tmp2.attr[z] = (" " + (t.attr(z) || "")).replace(/ jstree[^ ]*/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
- });
- if($.inArray("languages", s.plugins) !== -1 && $.isArray(s.languages) && s.languages.length) {
- $.each(s.languages, function (k, z) {
- if(t.hasClass(z)) { tmp2.language = z; return true; }
- });
- }
- if(t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/^\s+$/ig,"").length) {
- tmp2.icon = t.children("ins").get(0).className.replace(/jstree[^ ]*|$/ig,'').replace(/\s+$/ig," ").replace(/^ /,"").replace(/ $/,"");
- }
- if(t.children("ins").get(0).style.backgroundImage.length) {
- tmp2.icon = t.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")","");
- }
- }
- else {
- tmp2 = _this.get_text(t);
- }
- if(a.length > 1) { tmp1.data.push(tmp2); }
- else { tmp1.data = tmp2; }
- });
- li = li.find("> ul > li");
- if(li.length) { tmp1.children = _this.get_json(li, li_attr, a_attr, true); }
- result.push(tmp1);
- });
- return result;
- }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree languages plugin
- * Adds support for multiple language versions in one tree
- * This basically allows for many titles coexisting in one node, but only one of them being visible at any given time
- * This is useful for maintaining the same structure in many languages (hence the name of the plugin)
- */
-(function ($) {
- $.jstree.plugin("languages", {
- __init : function () { this._load_css(); },
- defaults : [],
- _fn : {
- set_lang : function (i) {
- var langs = this._get_settings().languages,
- st = false,
- selector = ".jstree-" + this.get_index() + ' a';
- if(!$.isArray(langs) || langs.length === 0) { return false; }
- if($.inArray(i,langs) == -1) {
- if(!!langs[i]) { i = langs[i]; }
- else { return false; }
- }
- if(i == this.data.languages.current_language) { return true; }
- st = $.vakata.css.get_css(selector + "." + this.data.languages.current_language, false, this.data.languages.language_css);
- if(st !== false) { st.style.display = "none"; }
- st = $.vakata.css.get_css(selector + "." + i, false, this.data.languages.language_css);
- if(st !== false) { st.style.display = ""; }
- this.data.languages.current_language = i;
- this.__callback(i);
- return true;
- },
- get_lang : function () {
- return this.data.languages.current_language;
- },
- _get_string : function (key, lang) {
- var langs = this._get_settings().languages,
- s = this._get_settings().core.strings;
- if($.isArray(langs) && langs.length) {
- lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language;
- }
- if(s[lang] && s[lang][key]) { return s[lang][key]; }
- if(s[key]) { return s[key]; }
- return key;
- },
- get_text : function (obj, lang) {
- obj = this._get_node(obj) || this.data.ui.last_selected;
- if(!obj.size()) { return false; }
- var langs = this._get_settings().languages,
- s = this._get_settings().core.html_titles;
- if($.isArray(langs) && langs.length) {
- lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language;
- obj = obj.children("a." + lang);
- }
- else { obj = obj.children("a:eq(0)"); }
- if(s) {
- obj = obj.clone();
- obj.children("INS").remove();
- return obj.html();
- }
- else {
- obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
- return obj.nodeValue;
- }
- },
- set_text : function (obj, val, lang) {
- obj = this._get_node(obj) || this.data.ui.last_selected;
- if(!obj.size()) { return false; }
- var langs = this._get_settings().languages,
- s = this._get_settings().core.html_titles,
- tmp;
- if($.isArray(langs) && langs.length) {
- lang = (lang && $.inArray(lang,langs) != -1) ? lang : this.data.languages.current_language;
- obj = obj.children("a." + lang);
- }
- else { obj = obj.children("a:eq(0)"); }
- if(s) {
- tmp = obj.children("INS").clone();
- obj.html(val).prepend(tmp);
- this.__callback({ "obj" : obj, "name" : val, "lang" : lang });
- return true;
- }
- else {
- obj = obj.contents().filter(function() { return this.nodeType == 3; })[0];
- this.__callback({ "obj" : obj, "name" : val, "lang" : lang });
- return (obj.nodeValue = val);
- }
- },
- _load_css : function () {
- var langs = this._get_settings().languages,
- str = "/* languages css */",
- selector = ".jstree-" + this.get_index() + ' a',
- ln;
- if($.isArray(langs) && langs.length) {
- this.data.languages.current_language = langs[0];
- for(ln = 0; ln < langs.length; ln++) {
- str += selector + "." + langs[ln] + " {";
- if(langs[ln] != this.data.languages.current_language) { str += " display:none; "; }
- str += " } ";
- }
- this.data.languages.language_css = $.vakata.css.add_sheet({ 'str' : str, 'title' : "jstree-languages" });
- }
- },
- create_node : function (obj, position, js, callback) {
- var t = this.__call_old(true, obj, position, js, function (t) {
- var langs = this._get_settings().languages,
- a = t.children("a"),
- ln;
- if($.isArray(langs) && langs.length) {
- for(ln = 0; ln < langs.length; ln++) {
- if(!a.is("." + langs[ln])) {
- t.append(a.eq(0).clone().removeClass(langs.join(" ")).addClass(langs[ln]));
- }
- }
- a.not("." + langs.join(", .")).remove();
- }
- if(callback) { callback.call(this, t); }
- });
- return t;
- }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree cookies plugin
- * Stores the currently opened/selected nodes in a cookie and then restores them
- * Depends on the jquery.cookie plugin
- */
-(function ($) {
- $.jstree.plugin("cookies", {
- __init : function () {
- if(typeof $.cookie === "undefined") { throw "jsTree cookie: jQuery cookie plugin not included."; }
-
- var s = this._get_settings().cookies,
- tmp;
- if(!!s.save_loaded) {
- tmp = $.cookie(s.save_loaded);
- if(tmp && tmp.length) { this.data.core.to_load = tmp.split(","); }
- }
- if(!!s.save_opened) {
- tmp = $.cookie(s.save_opened);
- if(tmp && tmp.length) { this.data.core.to_open = tmp.split(","); }
- }
- if(!!s.save_selected) {
- tmp = $.cookie(s.save_selected);
- if(tmp && tmp.length && this.data.ui) { this.data.ui.to_select = tmp.split(","); }
- }
- this.get_container()
- .one( ( this.data.ui ? "reselect" : "reopen" ) + ".jstree", $.proxy(function () {
- this.get_container()
- .bind("open_node.jstree close_node.jstree select_node.jstree deselect_node.jstree", $.proxy(function (e) {
- if(this._get_settings().cookies.auto_save) { this.save_cookie((e.handleObj.namespace + e.handleObj.type).replace("jstree","")); }
- }, this));
- }, this));
- },
- defaults : {
- save_loaded : "jstree_load",
- save_opened : "jstree_open",
- save_selected : "jstree_select",
- auto_save : true,
- cookie_options : {}
- },
- _fn : {
- save_cookie : function (c) {
- if(this.data.core.refreshing) { return; }
- var s = this._get_settings().cookies;
- if(!c) { // if called manually and not by event
- if(s.save_loaded) {
- this.save_loaded();
- $.cookie(s.save_loaded, this.data.core.to_load.join(","), s.cookie_options);
- }
- if(s.save_opened) {
- this.save_opened();
- $.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options);
- }
- if(s.save_selected && this.data.ui) {
- this.save_selected();
- $.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options);
- }
- return;
- }
- switch(c) {
- case "open_node":
- case "close_node":
- if(!!s.save_opened) {
- this.save_opened();
- $.cookie(s.save_opened, this.data.core.to_open.join(","), s.cookie_options);
- }
- if(!!s.save_loaded) {
- this.save_loaded();
- $.cookie(s.save_loaded, this.data.core.to_load.join(","), s.cookie_options);
- }
- break;
- case "select_node":
- case "deselect_node":
- if(!!s.save_selected && this.data.ui) {
- this.save_selected();
- $.cookie(s.save_selected, this.data.ui.to_select.join(","), s.cookie_options);
- }
- break;
- }
- }
- }
- });
- // include cookies by default
- // $.jstree.defaults.plugins.push("cookies");
-})(jQuery);
-//*/
-
-/*
- * jsTree sort plugin
- * Sorts items alphabetically (or using any other function)
- */
-(function ($) {
- $.jstree.plugin("sort", {
- __init : function () {
- this.get_container()
- .bind("load_node.jstree", $.proxy(function (e, data) {
- var obj = this._get_node(data.rslt.obj);
- obj = obj === -1 ? this.get_container().children("ul") : obj.children("ul");
- this.sort(obj);
- }, this))
- .bind("rename_node.jstree create_node.jstree create.jstree", $.proxy(function (e, data) {
- this.sort(data.rslt.obj.parent());
- }, this))
- .bind("move_node.jstree", $.proxy(function (e, data) {
- var m = data.rslt.np == -1 ? this.get_container() : data.rslt.np;
- this.sort(m.children("ul"));
- }, this));
- },
- defaults : function (a, b) { return this.get_text(a) > this.get_text(b) ? 1 : -1; },
- _fn : {
- sort : function (obj) {
- var s = this._get_settings().sort,
- t = this;
- obj.append($.makeArray(obj.children("li")).sort($.proxy(s, t)));
- obj.find("> li > ul").each(function() { t.sort($(this)); });
- this.clean_node(obj);
- }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree DND plugin
- * Drag and drop plugin for moving/copying nodes
- */
-(function ($) {
- var o = false,
- r = false,
- m = false,
- ml = false,
- sli = false,
- sti = false,
- dir1 = false,
- dir2 = false,
- last_pos = false;
- $.vakata.dnd = {
- is_down : false,
- is_drag : false,
- helper : false,
- scroll_spd : 10,
- init_x : 0,
- init_y : 0,
- threshold : 5,
- helper_left : 5,
- helper_top : 10,
- user_data : {},
-
- drag_start : function (e, data, html) {
- if($.vakata.dnd.is_drag) { $.vakata.drag_stop({}); }
- try {
- e.currentTarget.unselectable = "on";
- e.currentTarget.onselectstart = function() { return false; };
- if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; }
- } catch(err) { }
- $.vakata.dnd.init_x = e.pageX;
- $.vakata.dnd.init_y = e.pageY;
- $.vakata.dnd.user_data = data;
- $.vakata.dnd.is_down = true;
- $.vakata.dnd.helper = $("").html(html); //.fadeTo(10,0.25);
- $(document).bind("mousemove", $.vakata.dnd.drag);
- $(document).bind("mouseup", $.vakata.dnd.drag_stop);
- return false;
- },
- drag : function (e) {
- if(!$.vakata.dnd.is_down) { return; }
- if(!$.vakata.dnd.is_drag) {
- if(Math.abs(e.pageX - $.vakata.dnd.init_x) > 5 || Math.abs(e.pageY - $.vakata.dnd.init_y) > 5) {
- $.vakata.dnd.helper.appendTo("body");
- $.vakata.dnd.is_drag = true;
- $(document).triggerHandler("drag_start.vakata", { "event" : e, "data" : $.vakata.dnd.user_data });
- }
- else { return; }
- }
-
- // maybe use a scrolling parent element instead of document?
- if(e.type === "mousemove") { // thought of adding scroll in order to move the helper, but mouse poisition is n/a
- var d = $(document), t = d.scrollTop(), l = d.scrollLeft();
- if(e.pageY - t < 20) {
- if(sti && dir1 === "down") { clearInterval(sti); sti = false; }
- if(!sti) { dir1 = "up"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() - $.vakata.dnd.scroll_spd); }, 150); }
- }
- else {
- if(sti && dir1 === "up") { clearInterval(sti); sti = false; }
- }
- if($(window).height() - (e.pageY - t) < 20) {
- if(sti && dir1 === "up") { clearInterval(sti); sti = false; }
- if(!sti) { dir1 = "down"; sti = setInterval(function () { $(document).scrollTop($(document).scrollTop() + $.vakata.dnd.scroll_spd); }, 150); }
- }
- else {
- if(sti && dir1 === "down") { clearInterval(sti); sti = false; }
- }
-
- if(e.pageX - l < 20) {
- if(sli && dir2 === "right") { clearInterval(sli); sli = false; }
- if(!sli) { dir2 = "left"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() - $.vakata.dnd.scroll_spd); }, 150); }
- }
- else {
- if(sli && dir2 === "left") { clearInterval(sli); sli = false; }
- }
- if($(window).width() - (e.pageX - l) < 20) {
- if(sli && dir2 === "left") { clearInterval(sli); sli = false; }
- if(!sli) { dir2 = "right"; sli = setInterval(function () { $(document).scrollLeft($(document).scrollLeft() + $.vakata.dnd.scroll_spd); }, 150); }
- }
- else {
- if(sli && dir2 === "right") { clearInterval(sli); sli = false; }
- }
- }
-
- $.vakata.dnd.helper.css({ left : (e.pageX + $.vakata.dnd.helper_left) + "px", top : (e.pageY + $.vakata.dnd.helper_top) + "px" });
- $(document).triggerHandler("drag.vakata", { "event" : e, "data" : $.vakata.dnd.user_data });
- },
- drag_stop : function (e) {
- if(sli) { clearInterval(sli); }
- if(sti) { clearInterval(sti); }
- $(document).unbind("mousemove", $.vakata.dnd.drag);
- $(document).unbind("mouseup", $.vakata.dnd.drag_stop);
- $(document).triggerHandler("drag_stop.vakata", { "event" : e, "data" : $.vakata.dnd.user_data });
- $.vakata.dnd.helper.remove();
- $.vakata.dnd.init_x = 0;
- $.vakata.dnd.init_y = 0;
- $.vakata.dnd.user_data = {};
- $.vakata.dnd.is_down = false;
- $.vakata.dnd.is_drag = false;
- }
- };
- $(function() {
- var css_string = '#vakata-dragged { display:block; margin:0 0 0 0; padding:4px 4px 4px 24px; position:absolute; top:-2000px; line-height:16px; z-index:10000; } ';
- $.vakata.css.add_sheet({ str : css_string, title : "vakata" });
- });
-
- $.jstree.plugin("dnd", {
- __init : function () {
- this.data.dnd = {
- active : false,
- after : false,
- inside : false,
- before : false,
- off : false,
- prepared : false,
- w : 0,
- to1 : false,
- to2 : false,
- cof : false,
- cw : false,
- ch : false,
- i1 : false,
- i2 : false,
- mto : false
- };
- this.get_container()
- .bind("mouseenter.jstree", $.proxy(function (e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
- if(this.data.themes) {
- m.attr("class", "jstree-" + this.data.themes.theme);
- if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
- $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
- }
- //if($(e.currentTarget).find("> ul > li").length === 0) {
- if(e.currentTarget === e.target && $.vakata.dnd.user_data.obj && $($.vakata.dnd.user_data.obj).length && $($.vakata.dnd.user_data.obj).parents(".jstree:eq(0)")[0] !== e.target) { // node should not be from the same tree
- var tr = $.jstree._reference(e.target), dc;
- if(tr.data.dnd.foreign) {
- dc = tr._get_settings().dnd.drag_check.call(this, { "o" : o, "r" : tr.get_container(), is_root : true });
- if(dc === true || dc.inside === true || dc.before === true || dc.after === true) {
- $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
- }
- }
- else {
- tr.prepare_move(o, tr.get_container(), "last");
- if(tr.check_move()) {
- $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
- }
- }
- }
- }
- }, this))
- .bind("mouseup.jstree", $.proxy(function (e) {
- //if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && $(e.currentTarget).find("> ul > li").length === 0) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && e.currentTarget === e.target && $.vakata.dnd.user_data.obj && $($.vakata.dnd.user_data.obj).length && $($.vakata.dnd.user_data.obj).parents(".jstree:eq(0)")[0] !== e.target) { // node should not be from the same tree
- var tr = $.jstree._reference(e.currentTarget), dc;
- if(tr.data.dnd.foreign) {
- dc = tr._get_settings().dnd.drag_check.call(this, { "o" : o, "r" : tr.get_container(), is_root : true });
- if(dc === true || dc.inside === true || dc.before === true || dc.after === true) {
- tr._get_settings().dnd.drag_finish.call(this, { "o" : o, "r" : tr.get_container(), is_root : true });
- }
- }
- else {
- tr.move_node(o, tr.get_container(), "last", e[tr._get_settings().dnd.copy_modifier + "Key"]);
- }
- }
- }, this))
- .bind("mouseleave.jstree", $.proxy(function (e) {
- if(e.relatedTarget && e.relatedTarget.id && e.relatedTarget.id === "jstree-marker-line") {
- return false;
- }
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
- if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
- if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
- if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); }
- if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); }
- if($.vakata.dnd.helper.children("ins").hasClass("jstree-ok")) {
- $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
- }
- }
- }, this))
- .bind("mousemove.jstree", $.proxy(function (e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
- var cnt = this.get_container()[0];
-
- // Horizontal scroll
- if(e.pageX + 24 > this.data.dnd.cof.left + this.data.dnd.cw) {
- if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
- this.data.dnd.i1 = setInterval($.proxy(function () { this.scrollLeft += $.vakata.dnd.scroll_spd; }, cnt), 100);
- }
- else if(e.pageX - 24 < this.data.dnd.cof.left) {
- if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
- this.data.dnd.i1 = setInterval($.proxy(function () { this.scrollLeft -= $.vakata.dnd.scroll_spd; }, cnt), 100);
- }
- else {
- if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
- }
-
- // Vertical scroll
- if(e.pageY + 24 > this.data.dnd.cof.top + this.data.dnd.ch) {
- if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
- this.data.dnd.i2 = setInterval($.proxy(function () { this.scrollTop += $.vakata.dnd.scroll_spd; }, cnt), 100);
- }
- else if(e.pageY - 24 < this.data.dnd.cof.top) {
- if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
- this.data.dnd.i2 = setInterval($.proxy(function () { this.scrollTop -= $.vakata.dnd.scroll_spd; }, cnt), 100);
- }
- else {
- if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
- }
-
- }
- }, this))
- .bind("scroll.jstree", $.proxy(function (e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && m && ml) {
- m.hide();
- ml.hide();
- }
- }, this))
- .delegate("a", "mousedown.jstree", $.proxy(function (e) {
- if(e.which === 1) {
- this.start_drag(e.currentTarget, e);
- return false;
- }
- }, this))
- .delegate("a", "mouseenter.jstree", $.proxy(function (e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
- this.dnd_enter(e.currentTarget);
- }
- }, this))
- .delegate("a", "mousemove.jstree", $.proxy(function (e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
- if(!r || !r.length || r.children("a")[0] !== e.currentTarget) {
- this.dnd_enter(e.currentTarget);
- }
- if(typeof this.data.dnd.off.top === "undefined") { this.data.dnd.off = $(e.target).offset(); }
- this.data.dnd.w = (e.pageY - (this.data.dnd.off.top || 0)) % this.data.core.li_height;
- if(this.data.dnd.w < 0) { this.data.dnd.w += this.data.core.li_height; }
- this.dnd_show();
- }
- }, this))
- .delegate("a", "mouseleave.jstree", $.proxy(function (e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
- if(e.relatedTarget && e.relatedTarget.id && e.relatedTarget.id === "jstree-marker-line") {
- return false;
- }
- if(m) { m.hide(); }
- if(ml) { ml.hide(); }
- /*
- var ec = $(e.currentTarget).closest("li"),
- er = $(e.relatedTarget).closest("li");
- if(er[0] !== ec.prev()[0] && er[0] !== ec.next()[0]) {
- if(m) { m.hide(); }
- if(ml) { ml.hide(); }
- }
- */
- this.data.dnd.mto = setTimeout(
- (function (t) { return function () { t.dnd_leave(e); }; })(this),
- 0);
- }
- }, this))
- .delegate("a", "mouseup.jstree", $.proxy(function (e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree) {
- this.dnd_finish(e);
- }
- }, this));
-
- $(document)
- .bind("drag_stop.vakata", $.proxy(function () {
- if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); }
- if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); }
- if(this.data.dnd.i1) { clearInterval(this.data.dnd.i1); }
- if(this.data.dnd.i2) { clearInterval(this.data.dnd.i2); }
- this.data.dnd.after = false;
- this.data.dnd.before = false;
- this.data.dnd.inside = false;
- this.data.dnd.off = false;
- this.data.dnd.prepared = false;
- this.data.dnd.w = false;
- this.data.dnd.to1 = false;
- this.data.dnd.to2 = false;
- this.data.dnd.i1 = false;
- this.data.dnd.i2 = false;
- this.data.dnd.active = false;
- this.data.dnd.foreign = false;
- if(m) { m.css({ "top" : "-2000px" }); }
- if(ml) { ml.css({ "top" : "-2000px" }); }
- }, this))
- .bind("drag_start.vakata", $.proxy(function (e, data) {
- if(data.data.jstree) {
- var et = $(data.event.target);
- if(et.closest(".jstree").hasClass("jstree-" + this.get_index())) {
- this.dnd_enter(et);
- }
- }
- }, this));
- /*
- .bind("keydown.jstree-" + this.get_index() + " keyup.jstree-" + this.get_index(), $.proxy(function(e) {
- if($.vakata.dnd.is_drag && $.vakata.dnd.user_data.jstree && !this.data.dnd.foreign) {
- var h = $.vakata.dnd.helper.children("ins");
- if(e[this._get_settings().dnd.copy_modifier + "Key"] && h.hasClass("jstree-ok")) {
- h.parent().html(h.parent().html().replace(/ \(Copy\)$/, "") + " (Copy)");
- }
- else {
- h.parent().html(h.parent().html().replace(/ \(Copy\)$/, ""));
- }
- }
- }, this)); */
-
-
-
- var s = this._get_settings().dnd;
- if(s.drag_target) {
- $(document)
- .delegate(s.drag_target, "mousedown.jstree-" + this.get_index(), $.proxy(function (e) {
- o = e.target;
- $.vakata.dnd.drag_start(e, { jstree : true, obj : e.target }, "" + $(e.target).text() );
- if(this.data.themes) {
- if(m) { m.attr("class", "jstree-" + this.data.themes.theme); }
- if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
- $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
- }
- $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
- var cnt = this.get_container();
- this.data.dnd.cof = cnt.offset();
- this.data.dnd.cw = parseInt(cnt.width(),10);
- this.data.dnd.ch = parseInt(cnt.height(),10);
- this.data.dnd.foreign = true;
- e.preventDefault();
- }, this));
- }
- if(s.drop_target) {
- $(document)
- .delegate(s.drop_target, "mouseenter.jstree-" + this.get_index(), $.proxy(function (e) {
- if(this.data.dnd.active && this._get_settings().dnd.drop_check.call(this, { "o" : o, "r" : $(e.target), "e" : e })) {
- $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
- }
- }, this))
- .delegate(s.drop_target, "mouseleave.jstree-" + this.get_index(), $.proxy(function (e) {
- if(this.data.dnd.active) {
- $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
- }
- }, this))
- .delegate(s.drop_target, "mouseup.jstree-" + this.get_index(), $.proxy(function (e) {
- if(this.data.dnd.active && $.vakata.dnd.helper.children("ins").hasClass("jstree-ok")) {
- this._get_settings().dnd.drop_finish.call(this, { "o" : o, "r" : $(e.target), "e" : e });
- }
- }, this));
- }
- },
- defaults : {
- copy_modifier : "ctrl",
- check_timeout : 100,
- open_timeout : 500,
- drop_target : ".jstree-drop",
- drop_check : function (data) { return true; },
- drop_finish : $.noop,
- drag_target : ".jstree-draggable",
- drag_finish : $.noop,
- drag_check : function (data) { return { after : false, before : false, inside : true }; }
- },
- _fn : {
- dnd_prepare : function () {
- if(!r || !r.length) { return; }
- this.data.dnd.off = r.offset();
- if(this._get_settings().core.rtl) {
- this.data.dnd.off.right = this.data.dnd.off.left + r.width();
- }
- if(this.data.dnd.foreign) {
- var a = this._get_settings().dnd.drag_check.call(this, { "o" : o, "r" : r });
- this.data.dnd.after = a.after;
- this.data.dnd.before = a.before;
- this.data.dnd.inside = a.inside;
- this.data.dnd.prepared = true;
- return this.dnd_show();
- }
- this.prepare_move(o, r, "before");
- this.data.dnd.before = this.check_move();
- this.prepare_move(o, r, "after");
- this.data.dnd.after = this.check_move();
- if(this._is_loaded(r)) {
- this.prepare_move(o, r, "inside");
- this.data.dnd.inside = this.check_move();
- }
- else {
- this.data.dnd.inside = false;
- }
- this.data.dnd.prepared = true;
- return this.dnd_show();
- },
- dnd_show : function () {
- if(!this.data.dnd.prepared) { return; }
- var o = ["before","inside","after"],
- r = false,
- rtl = this._get_settings().core.rtl,
- pos;
- if(this.data.dnd.w < this.data.core.li_height/3) { o = ["before","inside","after"]; }
- else if(this.data.dnd.w <= this.data.core.li_height*2/3) {
- o = this.data.dnd.w < this.data.core.li_height/2 ? ["inside","before","after"] : ["inside","after","before"];
- }
- else { o = ["after","inside","before"]; }
- $.each(o, $.proxy(function (i, val) {
- if(this.data.dnd[val]) {
- $.vakata.dnd.helper.children("ins").attr("class","jstree-ok");
- r = val;
- return false;
- }
- }, this));
- if(r === false) { $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid"); }
-
- pos = rtl ? (this.data.dnd.off.right - 18) : (this.data.dnd.off.left + 10);
- switch(r) {
- case "before":
- m.css({ "left" : pos + "px", "top" : (this.data.dnd.off.top - 6) + "px" }).show();
- if(ml) { ml.css({ "left" : (pos + 8) + "px", "top" : (this.data.dnd.off.top - 1) + "px" }).show(); }
- break;
- case "after":
- m.css({ "left" : pos + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height - 6) + "px" }).show();
- if(ml) { ml.css({ "left" : (pos + 8) + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height - 1) + "px" }).show(); }
- break;
- case "inside":
- m.css({ "left" : pos + ( rtl ? -4 : 4) + "px", "top" : (this.data.dnd.off.top + this.data.core.li_height/2 - 5) + "px" }).show();
- if(ml) { ml.hide(); }
- break;
- default:
- m.hide();
- if(ml) { ml.hide(); }
- break;
- }
- last_pos = r;
- return r;
- },
- dnd_open : function () {
- this.data.dnd.to2 = false;
- this.open_node(r, $.proxy(this.dnd_prepare,this), true);
- },
- dnd_finish : function (e) {
- if(this.data.dnd.foreign) {
- if(this.data.dnd.after || this.data.dnd.before || this.data.dnd.inside) {
- this._get_settings().dnd.drag_finish.call(this, { "o" : o, "r" : r, "p" : last_pos });
- }
- }
- else {
- this.dnd_prepare();
- this.move_node(o, r, last_pos, e[this._get_settings().dnd.copy_modifier + "Key"]);
- }
- o = false;
- r = false;
- m.hide();
- if(ml) { ml.hide(); }
- },
- dnd_enter : function (obj) {
- if(this.data.dnd.mto) {
- clearTimeout(this.data.dnd.mto);
- this.data.dnd.mto = false;
- }
- var s = this._get_settings().dnd;
- this.data.dnd.prepared = false;
- r = this._get_node(obj);
- if(s.check_timeout) {
- // do the calculations after a minimal timeout (users tend to drag quickly to the desired location)
- if(this.data.dnd.to1) { clearTimeout(this.data.dnd.to1); }
- this.data.dnd.to1 = setTimeout($.proxy(this.dnd_prepare, this), s.check_timeout);
- }
- else {
- this.dnd_prepare();
- }
- if(s.open_timeout) {
- if(this.data.dnd.to2) { clearTimeout(this.data.dnd.to2); }
- if(r && r.length && r.hasClass("jstree-closed")) {
- // if the node is closed - open it, then recalculate
- this.data.dnd.to2 = setTimeout($.proxy(this.dnd_open, this), s.open_timeout);
- }
- }
- else {
- if(r && r.length && r.hasClass("jstree-closed")) {
- this.dnd_open();
- }
- }
- },
- dnd_leave : function (e) {
- this.data.dnd.after = false;
- this.data.dnd.before = false;
- this.data.dnd.inside = false;
- $.vakata.dnd.helper.children("ins").attr("class","jstree-invalid");
- m.hide();
- if(ml) { ml.hide(); }
- if(r && r[0] === e.target.parentNode) {
- if(this.data.dnd.to1) {
- clearTimeout(this.data.dnd.to1);
- this.data.dnd.to1 = false;
- }
- if(this.data.dnd.to2) {
- clearTimeout(this.data.dnd.to2);
- this.data.dnd.to2 = false;
- }
- }
- },
- start_drag : function (obj, e) {
- o = this._get_node(obj);
- if(this.data.ui && this.is_selected(o)) { o = this._get_node(null, true); }
- var dt = o.length > 1 ? this._get_string("multiple_selection") : this.get_text(o),
- cnt = this.get_container();
- if(!this._get_settings().core.html_titles) { dt = dt.replace(//ig,">"); }
- $.vakata.dnd.drag_start(e, { jstree : true, obj : o }, "" + dt );
- if(this.data.themes) {
- if(m) { m.attr("class", "jstree-" + this.data.themes.theme); }
- if(ml) { ml.attr("class", "jstree-" + this.data.themes.theme); }
- $.vakata.dnd.helper.attr("class", "jstree-dnd-helper jstree-" + this.data.themes.theme);
- }
- this.data.dnd.cof = cnt.offset();
- this.data.dnd.cw = parseInt(cnt.width(),10);
- this.data.dnd.ch = parseInt(cnt.height(),10);
- this.data.dnd.active = true;
- }
- }
- });
- $(function() {
- var css_string = '' +
- '#vakata-dragged ins { display:block; text-decoration:none; width:16px; height:16px; margin:0 0 0 0; padding:0; position:absolute; top:4px; left:4px; ' +
- ' border-radius:4px; -webkit-border-radius:4px; ' +
- '} ' +
- '#vakata-dragged .jstree-ok { background:green; } ' +
- '#vakata-dragged .jstree-invalid { background:red; } ' +
- '#jstree-marker { padding:0; margin:0; font-size:12px; overflow:hidden; height:12px; width:8px; position:absolute; top:-30px; z-index:10001; background-repeat:no-repeat; display:none; background-color:transparent; text-shadow:1px 1px 1px white; color:black; line-height:10px; } ' +
- '#jstree-marker-line { padding:0; margin:0; line-height:0%; font-size:1px; overflow:hidden; height:1px; width:100px; position:absolute; top:-30px; z-index:10000; background-repeat:no-repeat; display:none; background-color:#456c43; ' +
- ' cursor:pointer; border:1px solid #eeeeee; border-left:0; -moz-box-shadow: 0px 0px 2px #666; -webkit-box-shadow: 0px 0px 2px #666; box-shadow: 0px 0px 2px #666; ' +
- ' border-radius:1px; -webkit-border-radius:1px; ' +
- '}' +
- '';
- $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
- m = $("").attr({ id : "jstree-marker" }).hide().html("»")
- .bind("mouseleave mouseenter", function (e) {
- m.hide();
- ml.hide();
- e.preventDefault();
- e.stopImmediatePropagation();
- return false;
- })
- .appendTo("body");
- ml = $("").attr({ id : "jstree-marker-line" }).hide()
- .bind("mouseup", function (e) {
- if(r && r.length) {
- r.children("a").trigger(e);
- e.preventDefault();
- e.stopImmediatePropagation();
- return false;
- }
- })
- .bind("mouseleave", function (e) {
- var rt = $(e.relatedTarget);
- if(rt.is(".jstree") || rt.closest(".jstree").length === 0) {
- if(r && r.length) {
- r.children("a").trigger(e);
- m.hide();
- ml.hide();
- e.preventDefault();
- e.stopImmediatePropagation();
- return false;
- }
- }
- })
- .appendTo("body");
- $(document).bind("drag_start.vakata", function (e, data) {
- if(data.data.jstree) { m.show(); if(ml) { ml.show(); } }
- });
- $(document).bind("drag_stop.vakata", function (e, data) {
- if(data.data.jstree) { m.hide(); if(ml) { ml.hide(); } }
- });
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree checkbox plugin
- * Inserts checkboxes in front of every node
- * Depends on the ui plugin
- * DOES NOT WORK NICELY WITH MULTITREE DRAG'N'DROP
- */
-(function ($) {
- $.jstree.plugin("checkbox", {
- __init : function () {
- this.data.checkbox.noui = this._get_settings().checkbox.override_ui;
- if(this.data.ui && this.data.checkbox.noui) {
- this.select_node = this.deselect_node = this.deselect_all = $.noop;
- this.get_selected = this.get_checked;
- }
-
- this.get_container()
- .bind("open_node.jstree create_node.jstree clean_node.jstree refresh.jstree", $.proxy(function (e, data) {
- this._prepare_checkboxes(data.rslt.obj);
- }, this))
- .bind("loaded.jstree", $.proxy(function (e) {
- this._prepare_checkboxes();
- }, this))
- .delegate( (this.data.ui && this.data.checkbox.noui ? "a" : "ins.jstree-checkbox") , "click.jstree", $.proxy(function (e) {
- e.preventDefault();
- if(this._get_node(e.target).hasClass("jstree-checked")) { this.uncheck_node(e.target); }
- else { this.check_node(e.target); }
- if(this.data.ui && this.data.checkbox.noui) {
- this.save_selected();
- if(this.data.cookies) { this.save_cookie("select_node"); }
- }
- else {
- e.stopImmediatePropagation();
- return false;
- }
- }, this));
- },
- defaults : {
- override_ui : false,
- two_state : false,
- real_checkboxes : false,
- checked_parent_open : true,
- real_checkboxes_names : function (n) { return [ ("check_" + (n[0].id || Math.ceil(Math.random() * 10000))) , 1]; }
- },
- __destroy : function () {
- this.get_container()
- .find("input.jstree-real-checkbox").removeClass("jstree-real-checkbox").end()
- .find("ins.jstree-checkbox").remove();
- },
- _fn : {
- _checkbox_notify : function (n, data) {
- if(data.checked) {
- this.check_node(n, false);
- }
- },
- _prepare_checkboxes : function (obj) {
- obj = !obj || obj == -1 ? this.get_container().find("> ul > li") : this._get_node(obj);
- if(obj === false) { return; } // added for removing root nodes
- var c, _this = this, t, ts = this._get_settings().checkbox.two_state, rc = this._get_settings().checkbox.real_checkboxes, rcn = this._get_settings().checkbox.real_checkboxes_names;
- obj.each(function () {
- t = $(this);
- c = t.is("li") && (t.hasClass("jstree-checked") || (rc && t.children(":checked").length)) ? "jstree-checked" : "jstree-unchecked";
- t.find("li").andSelf().each(function () {
- var $t = $(this), nm;
- $t.children("a" + (_this.data.languages ? "" : ":eq(0)") ).not(":has(.jstree-checkbox)").prepend(" ").parent().not(".jstree-checked, .jstree-unchecked").addClass( ts ? "jstree-unchecked" : c );
- if(rc) {
- if(!$t.children(":checkbox").length) {
- nm = rcn.call(_this, $t);
- $t.prepend("");
- }
- else {
- $t.children(":checkbox").addClass("jstree-real-checkbox");
- }
- if(c === "jstree-checked") {
- $t.children(":checkbox").attr("checked","checked");
- }
- }
- if(c === "jstree-checked" && !ts) {
- $t.find("li").addClass("jstree-checked");
- }
- });
- });
- if(!ts) {
- if(obj.length === 1 && obj.is("li")) { this._repair_state(obj); }
- if(obj.is("li")) { obj.each(function () { _this._repair_state(this); }); }
- else { obj.find("> ul > li").each(function () { _this._repair_state(this); }); }
- obj.find(".jstree-checked").parent().parent().each(function () { _this._repair_state(this); });
- }
- },
- change_state : function (obj, state) {
- obj = this._get_node(obj);
- var coll = false, rc = this._get_settings().checkbox.real_checkboxes;
- if(!obj || obj === -1) { return false; }
- state = (state === false || state === true) ? state : obj.hasClass("jstree-checked");
- if(this._get_settings().checkbox.two_state) {
- if(state) {
- obj.removeClass("jstree-checked").addClass("jstree-unchecked");
- if(rc) { obj.children(":checkbox").removeAttr("checked"); }
- }
- else {
- obj.removeClass("jstree-unchecked").addClass("jstree-checked");
- if(rc) { obj.children(":checkbox").attr("checked","checked"); }
- }
- }
- else {
- if(state) {
- coll = obj.find("li").andSelf();
- if(!coll.filter(".jstree-checked, .jstree-undetermined").length) { return false; }
- coll.removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked");
- if(rc) { coll.children(":checkbox").removeAttr("checked"); }
- }
- else {
- coll = obj.find("li").andSelf();
- if(!coll.filter(".jstree-unchecked, .jstree-undetermined").length) { return false; }
- coll.removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked");
- if(rc) { coll.children(":checkbox").attr("checked","checked"); }
- if(this.data.ui) { this.data.ui.last_selected = obj; }
- this.data.checkbox.last_selected = obj;
- }
- obj.parentsUntil(".jstree", "li").each(function () {
- var $this = $(this);
- if(state) {
- if($this.children("ul").children("li.jstree-checked, li.jstree-undetermined").length) {
- $this.parentsUntil(".jstree", "li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined");
- if(rc) { $this.parentsUntil(".jstree", "li").andSelf().children(":checkbox").removeAttr("checked"); }
- return false;
- }
- else {
- $this.removeClass("jstree-checked jstree-undetermined").addClass("jstree-unchecked");
- if(rc) { $this.children(":checkbox").removeAttr("checked"); }
- }
- }
- else {
- if($this.children("ul").children("li.jstree-unchecked, li.jstree-undetermined").length) {
- $this.parentsUntil(".jstree", "li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined");
- if(rc) { $this.parentsUntil(".jstree", "li").andSelf().children(":checkbox").removeAttr("checked"); }
- return false;
- }
- else {
- $this.removeClass("jstree-unchecked jstree-undetermined").addClass("jstree-checked");
- if(rc) { $this.children(":checkbox").attr("checked","checked"); }
- }
- }
- });
- }
- if(this.data.ui && this.data.checkbox.noui) { this.data.ui.selected = this.get_checked(); }
- this.__callback(obj);
- return true;
- },
- check_node : function (obj) {
- if(this.change_state(obj, false)) {
- obj = this._get_node(obj);
- if(this._get_settings().checkbox.checked_parent_open) {
- var t = this;
- obj.parents(".jstree-closed").each(function () { t.open_node(this, false, true); });
- }
- this.__callback({ "obj" : obj });
- }
- },
- uncheck_node : function (obj) {
- if(this.change_state(obj, true)) { this.__callback({ "obj" : this._get_node(obj) }); }
- },
- check_all : function () {
- var _this = this,
- coll = this._get_settings().checkbox.two_state ? this.get_container_ul().find("li") : this.get_container_ul().children("li");
- coll.each(function () {
- _this.change_state(this, false);
- });
- this.__callback();
- },
- uncheck_all : function () {
- var _this = this,
- coll = this._get_settings().checkbox.two_state ? this.get_container_ul().find("li") : this.get_container_ul().children("li");
- coll.each(function () {
- _this.change_state(this, true);
- });
- this.__callback();
- },
-
- is_checked : function(obj) {
- obj = this._get_node(obj);
- return obj.length ? obj.is(".jstree-checked") : false;
- },
- get_checked : function (obj, get_all) {
- obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj);
- return get_all || this._get_settings().checkbox.two_state ? obj.find(".jstree-checked") : obj.find("> ul > .jstree-checked, .jstree-undetermined > ul > .jstree-checked");
- },
- get_unchecked : function (obj, get_all) {
- obj = !obj || obj === -1 ? this.get_container() : this._get_node(obj);
- return get_all || this._get_settings().checkbox.two_state ? obj.find(".jstree-unchecked") : obj.find("> ul > .jstree-unchecked, .jstree-undetermined > ul > .jstree-unchecked");
- },
-
- show_checkboxes : function () { this.get_container().children("ul").removeClass("jstree-no-checkboxes"); },
- hide_checkboxes : function () { this.get_container().children("ul").addClass("jstree-no-checkboxes"); },
-
- _repair_state : function (obj) {
- obj = this._get_node(obj);
- if(!obj.length) { return; }
- var rc = this._get_settings().checkbox.real_checkboxes,
- a = obj.find("> ul > .jstree-checked").length,
- b = obj.find("> ul > .jstree-undetermined").length,
- c = obj.find("> ul > li").length;
- if(c === 0) { if(obj.hasClass("jstree-undetermined")) { this.change_state(obj, false); } }
- else if(a === 0 && b === 0) { this.change_state(obj, true); }
- else if(a === c) { this.change_state(obj, false); }
- else {
- obj.parentsUntil(".jstree","li").andSelf().removeClass("jstree-checked jstree-unchecked").addClass("jstree-undetermined");
- if(rc) { obj.parentsUntil(".jstree", "li").andSelf().children(":checkbox").removeAttr("checked"); }
- }
- },
- reselect : function () {
- if(this.data.ui && this.data.checkbox.noui) {
- var _this = this,
- s = this.data.ui.to_select;
- s = $.map($.makeArray(s), function (n) { return "#" + n.toString().replace(/^#/,"").replace(/\\\//g,"/").replace(/\//g,"\\\/").replace(/\\\./g,".").replace(/\./g,"\\.").replace(/\:/g,"\\:"); });
- this.deselect_all();
- $.each(s, function (i, val) { _this.check_node(val); });
- this.__callback();
- }
- else {
- this.__call_old();
- }
- },
- save_loaded : function () {
- var _this = this;
- this.data.core.to_load = [];
- this.get_container_ul().find("li.jstree-closed.jstree-undetermined").each(function () {
- if(this.id) { _this.data.core.to_load.push("#" + this.id); }
- });
- }
- }
- });
- $(function() {
- var css_string = '.jstree .jstree-real-checkbox { display:none; } ';
- $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree XML plugin
- * The XML data store. Datastores are build by overriding the `load_node` and `_is_loaded` functions.
- */
-(function ($) {
- $.vakata.xslt = function (xml, xsl, callback) {
- var rs = "", xm, xs, processor, support;
- // TODO: IE9 no XSLTProcessor, no document.recalc
- if(document.recalc) {
- xm = document.createElement('xml');
- xs = document.createElement('xml');
- xm.innerHTML = xml;
- xs.innerHTML = xsl;
- $("body").append(xm).append(xs);
- setTimeout( (function (xm, xs, callback) {
- return function () {
- callback.call(null, xm.transformNode(xs.XMLDocument));
- setTimeout( (function (xm, xs) { return function () { $(xm).remove(); $(xs).remove(); }; })(xm, xs), 200);
- };
- })(xm, xs, callback), 100);
- return true;
- }
- if(typeof window.DOMParser !== "undefined" && typeof window.XMLHttpRequest !== "undefined" && typeof window.XSLTProcessor === "undefined") {
- xml = new DOMParser().parseFromString(xml, "text/xml");
- xsl = new DOMParser().parseFromString(xsl, "text/xml");
- // alert(xml.transformNode());
- // callback.call(null, new XMLSerializer().serializeToString(rs));
-
- }
- if(typeof window.DOMParser !== "undefined" && typeof window.XMLHttpRequest !== "undefined" && typeof window.XSLTProcessor !== "undefined") {
- processor = new XSLTProcessor();
- support = $.isFunction(processor.transformDocument) ? (typeof window.XMLSerializer !== "undefined") : true;
- if(!support) { return false; }
- xml = new DOMParser().parseFromString(xml, "text/xml");
- xsl = new DOMParser().parseFromString(xsl, "text/xml");
- if($.isFunction(processor.transformDocument)) {
- rs = document.implementation.createDocument("", "", null);
- processor.transformDocument(xml, xsl, rs, null);
- callback.call(null, new XMLSerializer().serializeToString(rs));
- return true;
- }
- else {
- processor.importStylesheet(xsl);
- rs = processor.transformToFragment(xml, document);
- callback.call(null, $("").append(rs).html());
- return true;
- }
- }
- return false;
- };
- var xsl = {
- 'nest' : '<' + '?xml version="1.0" encoding="utf-8" ?>' +
- '
' +
- '
' +
- '' +
- '
' +
- '' +
- '
' +
- ' ";
- $.each(s, function (i, val) {
- if(!val) { return true; }
- $.vakata.context.func[i] = val.action;
- if(!was_sep && val.separator_before) {
- str += "";
- }
- was_sep = false;
- str += "";
- if(val.separator_after) {
- str += "";
- was_sep = true;
- }
- });
- str = str.replace(/
";
- $(document).triggerHandler("context_parse.vakata");
- return str.length > 10 ? str : false;
- },
- exec : function (i) {
- if($.isFunction($.vakata.context.func[i])) {
- // if is string - eval and call it!
- $.vakata.context.func[i].call($.vakata.context.data, $.vakata.context.par);
- return true;
- }
- else { return false; }
- }
- };
- $(function () {
- var css_string = '' +
- '#vakata-contextmenu { display:block; visibility:hidden; left:0; top:-200px; position:absolute; margin:0; padding:0; min-width:180px; background:#ebebeb; border:1px solid silver; z-index:10000; *width:180px; } ' +
- '#vakata-contextmenu ul { min-width:180px; *width:180px; } ' +
- '#vakata-contextmenu ul, #vakata-contextmenu li { margin:0; padding:0; list-style-type:none; display:block; } ' +
- '#vakata-contextmenu li { line-height:20px; min-height:20px; position:relative; padding:0px; } ' +
- '#vakata-contextmenu li a { padding:1px 6px; line-height:17px; display:block; text-decoration:none; margin:1px 1px 0 1px; } ' +
- '#vakata-contextmenu li ins { float:left; width:16px; height:16px; text-decoration:none; margin-right:2px; } ' +
- '#vakata-contextmenu li a:hover, #vakata-contextmenu li.vakata-hover > a { background:gray; color:white; } ' +
- '#vakata-contextmenu li ul { display:none; position:absolute; top:-2px; left:100%; background:#ebebeb; border:1px solid gray; } ' +
- '#vakata-contextmenu .right { right:100%; left:auto; } ' +
- '#vakata-contextmenu .bottom { bottom:-1px; top:auto; } ' +
- '#vakata-contextmenu li.vakata-separator { min-height:0; height:1px; line-height:1px; font-size:1px; overflow:hidden; margin:0 2px; background:silver; /* border-top:1px solid #fefefe; */ padding:0; } ';
- $.vakata.css.add_sheet({ str : css_string, title : "vakata" });
- $.vakata.context.cnt
- .delegate("a","click", function (e) { e.preventDefault(); })
- .delegate("a","mouseup", function (e) {
- if(!$(this).parent().hasClass("jstree-contextmenu-disabled") && $.vakata.context.exec($(this).attr("rel"))) {
- $.vakata.context.hide();
- }
- else { $(this).blur(); }
- })
- .delegate("a","mouseover", function () {
- $.vakata.context.cnt.find(".vakata-hover").removeClass("vakata-hover");
- })
- .appendTo("body");
- $(document).bind("mousedown", function (e) { if($.vakata.context.vis && !$.contains($.vakata.context.cnt[0], e.target)) { $.vakata.context.hide(); } });
- if(typeof $.hotkeys !== "undefined") {
- $(document)
- .bind("keydown", "up", function (e) {
- if($.vakata.context.vis) {
- var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").prevAll("li:not(.vakata-separator)").first();
- if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").last(); }
- o.addClass("vakata-hover");
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- })
- .bind("keydown", "down", function (e) {
- if($.vakata.context.vis) {
- var o = $.vakata.context.cnt.find("ul:visible").last().children(".vakata-hover").removeClass("vakata-hover").nextAll("li:not(.vakata-separator)").first();
- if(!o.length) { o = $.vakata.context.cnt.find("ul:visible").last().children("li:not(.vakata-separator)").first(); }
- o.addClass("vakata-hover");
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- })
- .bind("keydown", "right", function (e) {
- if($.vakata.context.vis) {
- $.vakata.context.cnt.find(".vakata-hover").children("ul").show().children("li:not(.vakata-separator)").removeClass("vakata-hover").first().addClass("vakata-hover");
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- })
- .bind("keydown", "left", function (e) {
- if($.vakata.context.vis) {
- $.vakata.context.cnt.find(".vakata-hover").children("ul").hide().children(".vakata-separator").removeClass("vakata-hover");
- e.stopImmediatePropagation();
- e.preventDefault();
- }
- })
- .bind("keydown", "esc", function (e) {
- $.vakata.context.hide();
- e.preventDefault();
- })
- .bind("keydown", "space", function (e) {
- $.vakata.context.cnt.find(".vakata-hover").last().children("a").click();
- e.preventDefault();
- });
- }
- });
-
- $.jstree.plugin("contextmenu", {
- __init : function () {
- this.get_container()
- .delegate("a", "contextmenu.jstree", $.proxy(function (e) {
- e.preventDefault();
- if(!$(e.currentTarget).hasClass("jstree-loading")) {
- this.show_contextmenu(e.currentTarget, e.pageX, e.pageY);
- }
- }, this))
- .bind("destroy.jstree", $.proxy(function () {
- // TODO: move this to descruct method
- if(this.data.contextmenu) {
- $.vakata.context.hide();
- }
- }, this));
- $(document).bind("context_hide.vakata", $.proxy(function () { this.data.contextmenu = false; }, this));
- },
- defaults : {
- select_node : false, // requires UI plugin
- show_at_node : true,
- items : { // Could be a function that should return an object like this one
- "create" : {
- "separator_before" : false,
- "separator_after" : true,
- "label" : "Create",
- "action" : function (obj) { this.create(obj); }
- },
- "rename" : {
- "separator_before" : false,
- "separator_after" : false,
- "label" : "Rename",
- "action" : function (obj) { this.rename(obj); }
- },
- "remove" : {
- "separator_before" : false,
- "icon" : false,
- "separator_after" : false,
- "label" : "Delete",
- "action" : function (obj) { if(this.is_selected(obj)) { this.remove(); } else { this.remove(obj); } }
- },
- "ccp" : {
- "separator_before" : true,
- "icon" : false,
- "separator_after" : false,
- "label" : "Edit",
- "action" : false,
- "submenu" : {
- "cut" : {
- "separator_before" : false,
- "separator_after" : false,
- "label" : "Cut",
- "action" : function (obj) { this.cut(obj); }
- },
- "copy" : {
- "separator_before" : false,
- "icon" : false,
- "separator_after" : false,
- "label" : "Copy",
- "action" : function (obj) { this.copy(obj); }
- },
- "paste" : {
- "separator_before" : false,
- "icon" : false,
- "separator_after" : false,
- "label" : "Paste",
- "action" : function (obj) { this.paste(obj); }
- }
- }
- }
- }
- },
- _fn : {
- show_contextmenu : function (obj, x, y) {
- obj = this._get_node(obj);
- var s = this.get_settings().contextmenu,
- a = obj.children("a:visible:eq(0)"),
- o = false,
- i = false;
- if(s.select_node && this.data.ui && !this.is_selected(obj)) {
- this.deselect_all();
- this.select_node(obj, true);
- }
- if(s.show_at_node || typeof x === "undefined" || typeof y === "undefined") {
- o = a.offset();
- x = o.left;
- y = o.top + this.data.core.li_height;
- }
- i = obj.data("jstree") && obj.data("jstree").contextmenu ? obj.data("jstree").contextmenu : s.items;
- if($.isFunction(i)) { i = i.call(this, obj); }
- this.data.contextmenu = true;
- $.vakata.context.show(i, a, x, y, this, obj, this._get_settings().core.rtl);
- if(this.data.themes) { $.vakata.context.cnt.attr("class", "jstree-" + this.data.themes.theme + "-context"); }
- }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree types plugin
- * Adds support types of nodes
- * You can set an attribute on each li node, that represents its type.
- * According to the type setting the node may get custom icon/validation rules
- */
-(function ($) {
- $.jstree.plugin("types", {
- __init : function () {
- var s = this._get_settings().types;
- this.data.types.attach_to = [];
- this.get_container()
- .bind("init.jstree", $.proxy(function () {
- var types = s.types,
- attr = s.type_attr,
- icons_css = "",
- _this = this;
-
- $.each(types, function (i, tp) {
- $.each(tp, function (k, v) {
- if(!/^(max_depth|max_children|icon|valid_children)$/.test(k)) { _this.data.types.attach_to.push(k); }
- });
- if(!tp.icon) { return true; }
- if( tp.icon.image || tp.icon.position) {
- if(i == "default") { icons_css += '.jstree-' + _this.get_index() + ' a > .jstree-icon { '; }
- else { icons_css += '.jstree-' + _this.get_index() + ' li[' + attr + '="' + i + '"] > a > .jstree-icon { '; }
- if(tp.icon.image) { icons_css += ' background-image:url(' + tp.icon.image + '); '; }
- if(tp.icon.position){ icons_css += ' background-position:' + tp.icon.position + '; '; }
- else { icons_css += ' background-position:0 0; '; }
- icons_css += '} ';
- }
- });
- if(icons_css !== "") { $.vakata.css.add_sheet({ 'str' : icons_css, title : "jstree-types" }); }
- }, this))
- .bind("before.jstree", $.proxy(function (e, data) {
- var s, t,
- o = this._get_settings().types.use_data ? this._get_node(data.args[0]) : false,
- d = o && o !== -1 && o.length ? o.data("jstree") : false;
- if(d && d.types && d.types[data.func] === false) { e.stopImmediatePropagation(); return false; }
- if($.inArray(data.func, this.data.types.attach_to) !== -1) {
- if(!data.args[0] || (!data.args[0].tagName && !data.args[0].jquery)) { return; }
- s = this._get_settings().types.types;
- t = this._get_type(data.args[0]);
- if(
- (
- (s[t] && typeof s[t][data.func] !== "undefined") ||
- (s["default"] && typeof s["default"][data.func] !== "undefined")
- ) && this._check(data.func, data.args[0]) === false
- ) {
- e.stopImmediatePropagation();
- return false;
- }
- }
- }, this));
- if(is_ie6) {
- this.get_container()
- .bind("load_node.jstree set_type.jstree", $.proxy(function (e, data) {
- var r = data && data.rslt && data.rslt.obj && data.rslt.obj !== -1 ? this._get_node(data.rslt.obj).parent() : this.get_container_ul(),
- c = false,
- s = this._get_settings().types;
- $.each(s.types, function (i, tp) {
- if(tp.icon && (tp.icon.image || tp.icon.position)) {
- c = i === "default" ? r.find("li > a > .jstree-icon") : r.find("li[" + s.type_attr + "='" + i + "'] > a > .jstree-icon");
- if(tp.icon.image) { c.css("backgroundImage","url(" + tp.icon.image + ")"); }
- c.css("backgroundPosition", tp.icon.position || "0 0");
- }
- });
- }, this));
- }
- },
- defaults : {
- // defines maximum number of root nodes (-1 means unlimited, -2 means disable max_children checking)
- max_children : -1,
- // defines the maximum depth of the tree (-1 means unlimited, -2 means disable max_depth checking)
- max_depth : -1,
- // defines valid node types for the root nodes
- valid_children : "all",
-
- // whether to use $.data
- use_data : false,
- // where is the type stores (the rel attribute of the LI element)
- type_attr : "rel",
- // a list of types
- types : {
- // the default type
- "default" : {
- "max_children" : -1,
- "max_depth" : -1,
- "valid_children": "all"
-
- // Bound functions - you can bind any other function here (using boolean or function)
- //"select_node" : true
- }
- }
- },
- _fn : {
- _types_notify : function (n, data) {
- if(data.type && this._get_settings().types.use_data) {
- this.set_type(data.type, n);
- }
- },
- _get_type : function (obj) {
- obj = this._get_node(obj);
- return (!obj || !obj.length) ? false : obj.attr(this._get_settings().types.type_attr) || "default";
- },
- set_type : function (str, obj) {
- obj = this._get_node(obj);
- var ret = (!obj.length || !str) ? false : obj.attr(this._get_settings().types.type_attr, str);
- if(ret) { this.__callback({ obj : obj, type : str}); }
- return ret;
- },
- _check : function (rule, obj, opts) {
- obj = this._get_node(obj);
- var v = false, t = this._get_type(obj), d = 0, _this = this, s = this._get_settings().types, data = false;
- if(obj === -1) {
- if(!!s[rule]) { v = s[rule]; }
- else { return; }
- }
- else {
- if(t === false) { return; }
- data = s.use_data ? obj.data("jstree") : false;
- if(data && data.types && typeof data.types[rule] !== "undefined") { v = data.types[rule]; }
- else if(!!s.types[t] && typeof s.types[t][rule] !== "undefined") { v = s.types[t][rule]; }
- else if(!!s.types["default"] && typeof s.types["default"][rule] !== "undefined") { v = s.types["default"][rule]; }
- }
- if($.isFunction(v)) { v = v.call(this, obj); }
- if(rule === "max_depth" && obj !== -1 && opts !== false && s.max_depth !== -2 && v !== 0) {
- // also include the node itself - otherwise if root node it is not checked
- obj.children("a:eq(0)").parentsUntil(".jstree","li").each(function (i) {
- // check if current depth already exceeds global tree depth
- if(s.max_depth !== -1 && s.max_depth - (i + 1) <= 0) { v = 0; return false; }
- d = (i === 0) ? v : _this._check(rule, this, false);
- // check if current node max depth is already matched or exceeded
- if(d !== -1 && d - (i + 1) <= 0) { v = 0; return false; }
- // otherwise - set the max depth to the current value minus current depth
- if(d >= 0 && (d - (i + 1) < v || v < 0) ) { v = d - (i + 1); }
- // if the global tree depth exists and it minus the nodes calculated so far is less than `v` or `v` is unlimited
- if(s.max_depth >= 0 && (s.max_depth - (i + 1) < v || v < 0) ) { v = s.max_depth - (i + 1); }
- });
- }
- return v;
- },
- check_move : function () {
- if(!this.__call_old()) { return false; }
- var m = this._get_move(),
- s = m.rt._get_settings().types,
- mc = m.rt._check("max_children", m.cr),
- md = m.rt._check("max_depth", m.cr),
- vc = m.rt._check("valid_children", m.cr),
- ch = 0, d = 1, t;
-
- if(vc === "none") { return false; }
- if($.isArray(vc) && m.ot && m.ot._get_type) {
- m.o.each(function () {
- if($.inArray(m.ot._get_type(this), vc) === -1) { d = false; return false; }
- });
- if(d === false) { return false; }
- }
- if(s.max_children !== -2 && mc !== -1) {
- ch = m.cr === -1 ? this.get_container().find("> ul > li").not(m.o).length : m.cr.find("> ul > li").not(m.o).length;
- if(ch + m.o.length > mc) { return false; }
- }
- if(s.max_depth !== -2 && md !== -1) {
- d = 0;
- if(md === 0) { return false; }
- if(typeof m.o.d === "undefined") {
- // TODO: deal with progressive rendering and async when checking max_depth (how to know the depth of the moved node)
- t = m.o;
- while(t.length > 0) {
- t = t.find("> ul > li");
- d ++;
- }
- m.o.d = d;
- }
- if(md - m.o.d < 0) { return false; }
- }
- return true;
- },
- create_node : function (obj, position, js, callback, is_loaded, skip_check) {
- if(!skip_check && (is_loaded || this._is_loaded(obj))) {
- var p = (typeof position == "string" && position.match(/^before|after$/i) && obj !== -1) ? this._get_parent(obj) : this._get_node(obj),
- s = this._get_settings().types,
- mc = this._check("max_children", p),
- md = this._check("max_depth", p),
- vc = this._check("valid_children", p),
- ch;
- if(typeof js === "string") { js = { data : js }; }
- if(!js) { js = {}; }
- if(vc === "none") { return false; }
- if($.isArray(vc)) {
- if(!js.attr || !js.attr[s.type_attr]) {
- if(!js.attr) { js.attr = {}; }
- js.attr[s.type_attr] = vc[0];
- }
- else {
- if($.inArray(js.attr[s.type_attr], vc) === -1) { return false; }
- }
- }
- if(s.max_children !== -2 && mc !== -1) {
- ch = p === -1 ? this.get_container().find("> ul > li").length : p.find("> ul > li").length;
- if(ch + 1 > mc) { return false; }
- }
- if(s.max_depth !== -2 && md !== -1 && (md - 1) < 0) { return false; }
- }
- return this.__call_old(true, obj, position, js, callback, is_loaded, skip_check);
- }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree HTML plugin
- * The HTML data store. Datastores are build by replacing the `load_node` and `_is_loaded` functions.
- */
-(function ($) {
- $.jstree.plugin("html_data", {
- __init : function () {
- // this used to use html() and clean the whitespace, but this way any attached data was lost
- this.data.html_data.original_container_html = this.get_container().find(" > ul > li").clone(true);
- // remove white space from LI node - otherwise nodes appear a bit to the right
- this.data.html_data.original_container_html.find("li").andSelf().contents().filter(function() { return this.nodeType == 3; }).remove();
- },
- defaults : {
- data : false,
- ajax : false,
- correct_state : true
- },
- _fn : {
- load_node : function (obj, s_call, e_call) { var _this = this; this.load_node_html(obj, function () { _this.__callback({ "obj" : _this._get_node(obj) }); s_call.call(this); }, e_call); },
- _is_loaded : function (obj) {
- obj = this._get_node(obj);
- return obj == -1 || !obj || (!this._get_settings().html_data.ajax && !$.isFunction(this._get_settings().html_data.data)) || obj.is(".jstree-open, .jstree-leaf") || obj.children("ul").children("li").size() > 0;
- },
- load_node_html : function (obj, s_call, e_call) {
- var d,
- s = this.get_settings().html_data,
- error_func = function () {},
- success_func = function () {};
- obj = this._get_node(obj);
- if(obj && obj !== -1) {
- if(obj.data("jstree-is-loading")) { return; }
- else { obj.data("jstree-is-loading",true); }
- }
- switch(!0) {
- case ($.isFunction(s.data)):
- s.data.call(this, obj, $.proxy(function (d) {
- if(d && d !== "" && d.toString && d.toString().replace(/^[\s\n]+$/,"") !== "") {
- d = $(d);
- if(!d.is("ul")) { d = $("").append(d); }
- if(obj == -1 || !obj) { this.get_container().children("ul").empty().append(d.children()).find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend(" ").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); }
- else { obj.children("a.jstree-loading").removeClass("jstree-loading"); obj.append(d).children("ul").find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend(" ").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); obj.removeData("jstree-is-loading"); }
- this.clean_node(obj);
- if(s_call) { s_call.call(this); }
- }
- else {
- if(obj && obj !== -1) {
- obj.children("a.jstree-loading").removeClass("jstree-loading");
- obj.removeData("jstree-is-loading");
- if(s.correct_state) {
- this.correct_state(obj);
- if(s_call) { s_call.call(this); }
- }
- }
- else {
- if(s.correct_state) {
- this.get_container().children("ul").empty();
- if(s_call) { s_call.call(this); }
- }
- }
- }
- }, this));
- break;
- case (!s.data && !s.ajax):
- if(!obj || obj == -1) {
- this.get_container()
- .children("ul").empty()
- .append(this.data.html_data.original_container_html)
- .find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend(" ").end()
- .filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon");
- this.clean_node();
- }
- if(s_call) { s_call.call(this); }
- break;
- case (!!s.data && !s.ajax) || (!!s.data && !!s.ajax && (!obj || obj === -1)):
- if(!obj || obj == -1) {
- d = $(s.data);
- if(!d.is("ul")) { d = $("
").append(d); }
- this.get_container()
- .children("ul").empty().append(d.children())
- .find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend(" ").end()
- .filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon");
- this.clean_node();
- }
- if(s_call) { s_call.call(this); }
- break;
- case (!s.data && !!s.ajax) || (!!s.data && !!s.ajax && obj && obj !== -1):
- obj = this._get_node(obj);
- error_func = function (x, t, e) {
- var ef = this.get_settings().html_data.ajax.error;
- if(ef) { ef.call(this, x, t, e); }
- if(obj != -1 && obj.length) {
- obj.children("a.jstree-loading").removeClass("jstree-loading");
- obj.removeData("jstree-is-loading");
- if(t === "success" && s.correct_state) { this.correct_state(obj); }
- }
- else {
- if(t === "success" && s.correct_state) { this.get_container().children("ul").empty(); }
- }
- if(e_call) { e_call.call(this); }
- };
- success_func = function (d, t, x) {
- var sf = this.get_settings().html_data.ajax.success;
- if(sf) { d = sf.call(this,d,t,x) || d; }
- if(d === "" || (d && d.toString && d.toString().replace(/^[\s\n]+$/,"") === "")) {
- return error_func.call(this, x, t, "");
- }
- if(d) {
- d = $(d);
- if(!d.is("ul")) { d = $("
").append(d); }
- if(obj == -1 || !obj) { this.get_container().children("ul").empty().append(d.children()).find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend(" ").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); }
- else { obj.children("a.jstree-loading").removeClass("jstree-loading"); obj.append(d).children("ul").find("li, a").filter(function () { return !this.firstChild || !this.firstChild.tagName || this.firstChild.tagName !== "INS"; }).prepend(" ").end().filter("a").children("ins:first-child").not(".jstree-icon").addClass("jstree-icon"); obj.removeData("jstree-is-loading"); }
- this.clean_node(obj);
- if(s_call) { s_call.call(this); }
- }
- else {
- if(obj && obj !== -1) {
- obj.children("a.jstree-loading").removeClass("jstree-loading");
- obj.removeData("jstree-is-loading");
- if(s.correct_state) {
- this.correct_state(obj);
- if(s_call) { s_call.call(this); }
- }
- }
- else {
- if(s.correct_state) {
- this.get_container().children("ul").empty();
- if(s_call) { s_call.call(this); }
- }
- }
- }
- };
- s.ajax.context = this;
- s.ajax.error = error_func;
- s.ajax.success = success_func;
- if(!s.ajax.dataType) { s.ajax.dataType = "html"; }
- if($.isFunction(s.ajax.url)) { s.ajax.url = s.ajax.url.call(this, obj); }
- if($.isFunction(s.ajax.data)) { s.ajax.data = s.ajax.data.call(this, obj); }
- $.ajax(s.ajax);
- break;
- }
- }
- }
- });
- // include the HTML data plugin by default
- $.jstree.defaults.plugins.push("html_data");
-})(jQuery);
-//*/
-
-/*
- * jsTree themeroller plugin
- * Adds support for jQuery UI themes. Include this at the end of your plugins list, also make sure "themes" is not included.
- */
-(function ($) {
- $.jstree.plugin("themeroller", {
- __init : function () {
- var s = this._get_settings().themeroller;
- this.get_container()
- .addClass("ui-widget-content")
- .addClass("jstree-themeroller")
- .delegate("a","mouseenter.jstree", function (e) {
- if(!$(e.currentTarget).hasClass("jstree-loading")) {
- $(this).addClass(s.item_h);
- }
- })
- .delegate("a","mouseleave.jstree", function () {
- $(this).removeClass(s.item_h);
- })
- .bind("init.jstree", $.proxy(function (e, data) {
- data.inst.get_container().find("> ul > li > .jstree-loading > ins").addClass("ui-icon-refresh");
- this._themeroller(data.inst.get_container().find("> ul > li"));
- }, this))
- .bind("open_node.jstree create_node.jstree", $.proxy(function (e, data) {
- this._themeroller(data.rslt.obj);
- }, this))
- .bind("loaded.jstree refresh.jstree", $.proxy(function (e) {
- this._themeroller();
- }, this))
- .bind("close_node.jstree", $.proxy(function (e, data) {
- this._themeroller(data.rslt.obj);
- }, this))
- .bind("delete_node.jstree", $.proxy(function (e, data) {
- this._themeroller(data.rslt.parent);
- }, this))
- .bind("correct_state.jstree", $.proxy(function (e, data) {
- data.rslt.obj
- .children("ins.jstree-icon").removeClass(s.opened + " " + s.closed + " ui-icon").end()
- .find("> a > ins.ui-icon")
- .filter(function() {
- return this.className.toString()
- .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
- .indexOf("ui-icon-") === -1;
- }).removeClass(s.item_open + " " + s.item_clsd).addClass(s.item_leaf || "jstree-no-icon");
- }, this))
- .bind("select_node.jstree", $.proxy(function (e, data) {
- data.rslt.obj.children("a").addClass(s.item_a);
- }, this))
- .bind("deselect_node.jstree deselect_all.jstree", $.proxy(function (e, data) {
- this.get_container()
- .find("a." + s.item_a).removeClass(s.item_a).end()
- .find("a.jstree-clicked").addClass(s.item_a);
- }, this))
- .bind("dehover_node.jstree", $.proxy(function (e, data) {
- data.rslt.obj.children("a").removeClass(s.item_h);
- }, this))
- .bind("hover_node.jstree", $.proxy(function (e, data) {
- this.get_container()
- .find("a." + s.item_h).not(data.rslt.obj).removeClass(s.item_h);
- data.rslt.obj.children("a").addClass(s.item_h);
- }, this))
- .bind("move_node.jstree", $.proxy(function (e, data) {
- this._themeroller(data.rslt.o);
- this._themeroller(data.rslt.op);
- }, this));
- },
- __destroy : function () {
- var s = this._get_settings().themeroller,
- c = [ "ui-icon" ];
- $.each(s, function (i, v) {
- v = v.split(" ");
- if(v.length) { c = c.concat(v); }
- });
- this.get_container()
- .removeClass("ui-widget-content")
- .find("." + c.join(", .")).removeClass(c.join(" "));
- },
- _fn : {
- _themeroller : function (obj) {
- var s = this._get_settings().themeroller;
- obj = !obj || obj == -1 ? this.get_container_ul() : this._get_node(obj).parent();
- obj
- .find("li.jstree-closed")
- .children("ins.jstree-icon").removeClass(s.opened).addClass("ui-icon " + s.closed).end()
- .children("a").addClass(s.item)
- .children("ins.jstree-icon").addClass("ui-icon")
- .filter(function() {
- return this.className.toString()
- .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
- .indexOf("ui-icon-") === -1;
- }).removeClass(s.item_leaf + " " + s.item_open).addClass(s.item_clsd || "jstree-no-icon")
- .end()
- .end()
- .end()
- .end()
- .find("li.jstree-open")
- .children("ins.jstree-icon").removeClass(s.closed).addClass("ui-icon " + s.opened).end()
- .children("a").addClass(s.item)
- .children("ins.jstree-icon").addClass("ui-icon")
- .filter(function() {
- return this.className.toString()
- .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
- .indexOf("ui-icon-") === -1;
- }).removeClass(s.item_leaf + " " + s.item_clsd).addClass(s.item_open || "jstree-no-icon")
- .end()
- .end()
- .end()
- .end()
- .find("li.jstree-leaf")
- .children("ins.jstree-icon").removeClass(s.closed + " ui-icon " + s.opened).end()
- .children("a").addClass(s.item)
- .children("ins.jstree-icon").addClass("ui-icon")
- .filter(function() {
- return this.className.toString()
- .replace(s.item_clsd,"").replace(s.item_open,"").replace(s.item_leaf,"")
- .indexOf("ui-icon-") === -1;
- }).removeClass(s.item_clsd + " " + s.item_open).addClass(s.item_leaf || "jstree-no-icon");
- }
- },
- defaults : {
- "opened" : "ui-icon-triangle-1-se",
- "closed" : "ui-icon-triangle-1-e",
- "item" : "ui-state-default",
- "item_h" : "ui-state-hover",
- "item_a" : "ui-state-active",
- "item_open" : "ui-icon-folder-open",
- "item_clsd" : "ui-icon-folder-collapsed",
- "item_leaf" : "ui-icon-document"
- }
- });
- $(function() {
- var css_string = '' +
- '.jstree-themeroller .ui-icon { overflow:visible; } ' +
- '.jstree-themeroller a { padding:0 2px; } ' +
- '.jstree-themeroller .jstree-no-icon { display:none; }';
- $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree unique plugin
- * Forces different names amongst siblings (still a bit experimental)
- * NOTE: does not check language versions (it will not be possible to have nodes with the same title, even in different languages)
- */
-(function ($) {
- $.jstree.plugin("unique", {
- __init : function () {
- this.get_container()
- .bind("before.jstree", $.proxy(function (e, data) {
- var nms = [], res = true, p, t;
- if(data.func == "move_node") {
- // obj, ref, position, is_copy, is_prepared, skip_check
- if(data.args[4] === true) {
- if(data.args[0].o && data.args[0].o.length) {
- data.args[0].o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); });
- res = this._check_unique(nms, data.args[0].np.find("> ul > li").not(data.args[0].o), "move_node");
- }
- }
- }
- if(data.func == "create_node") {
- // obj, position, js, callback, is_loaded
- if(data.args[4] || this._is_loaded(data.args[0])) {
- p = this._get_node(data.args[0]);
- if(data.args[1] && (data.args[1] === "before" || data.args[1] === "after")) {
- p = this._get_parent(data.args[0]);
- if(!p || p === -1) { p = this.get_container(); }
- }
- if(typeof data.args[2] === "string") { nms.push(data.args[2]); }
- else if(!data.args[2] || !data.args[2].data) { nms.push(this._get_string("new_node")); }
- else { nms.push(data.args[2].data); }
- res = this._check_unique(nms, p.find("> ul > li"), "create_node");
- }
- }
- if(data.func == "rename_node") {
- // obj, val
- nms.push(data.args[1]);
- t = this._get_node(data.args[0]);
- p = this._get_parent(t);
- if(!p || p === -1) { p = this.get_container(); }
- res = this._check_unique(nms, p.find("> ul > li").not(t), "rename_node");
- }
- if(!res) {
- e.stopPropagation();
- return false;
- }
- }, this));
- },
- defaults : {
- error_callback : $.noop
- },
- _fn : {
- _check_unique : function (nms, p, func) {
- var cnms = [];
- p.children("a").each(function () { cnms.push($(this).text().replace(/^\s+/g,"")); });
- if(!cnms.length || !nms.length) { return true; }
- cnms = cnms.sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",");
- if((cnms.length + nms.length) != cnms.concat(nms).sort().join(",,").replace(/(,|^)([^,]+)(,,\2)+(,|$)/g,"$1$2$4").replace(/,,+/g,",").replace(/,$/,"").split(",").length) {
- this._get_settings().unique.error_callback.call(null, nms, p, func);
- return false;
- }
- return true;
- },
- check_move : function () {
- if(!this.__call_old()) { return false; }
- var p = this._get_move(), nms = [];
- if(p.o && p.o.length) {
- p.o.children("a").each(function () { nms.push($(this).text().replace(/^\s+/g,"")); });
- return this._check_unique(nms, p.np.find("> ul > li").not(p.o), "check_move");
- }
- return true;
- }
- }
- });
-})(jQuery);
-//*/
-
-/*
- * jsTree wholerow plugin
- * Makes select and hover work on the entire width of the node
- * MAY BE HEAVY IN LARGE DOM
- */
-(function ($) {
- $.jstree.plugin("wholerow", {
- __init : function () {
- if(!this.data.ui) { throw "jsTree wholerow: jsTree UI plugin not included."; }
- this.data.wholerow.html = false;
- this.data.wholerow.to = false;
- this.get_container()
- .bind("init.jstree", $.proxy(function (e, data) {
- this._get_settings().core.animation = 0;
- }, this))
- .bind("open_node.jstree create_node.jstree clean_node.jstree loaded.jstree", $.proxy(function (e, data) {
- this._prepare_wholerow_span( data && data.rslt && data.rslt.obj ? data.rslt.obj : -1 );
- }, this))
- .bind("search.jstree clear_search.jstree reopen.jstree after_open.jstree after_close.jstree create_node.jstree delete_node.jstree clean_node.jstree", $.proxy(function (e, data) {
- if(this.data.to) { clearTimeout(this.data.to); }
- this.data.to = setTimeout( (function (t, o) { return function() { t._prepare_wholerow_ul(o); }; })(this, data && data.rslt && data.rslt.obj ? data.rslt.obj : -1), 0);
- }, this))
- .bind("deselect_all.jstree", $.proxy(function (e, data) {
- this.get_container().find(" > .jstree-wholerow .jstree-clicked").removeClass("jstree-clicked " + (this.data.themeroller ? this._get_settings().themeroller.item_a : "" ));
- }, this))
- .bind("select_node.jstree deselect_node.jstree ", $.proxy(function (e, data) {
- data.rslt.obj.each(function () {
- var ref = data.inst.get_container().find(" > .jstree-wholerow li:visible:eq(" + ( parseInt((($(this).offset().top - data.inst.get_container().offset().top + data.inst.get_container()[0].scrollTop) / data.inst.data.core.li_height),10)) + ")");
- // ref.children("a")[e.type === "select_node" ? "addClass" : "removeClass"]("jstree-clicked");
- ref.children("a").attr("class",data.rslt.obj.children("a").attr("class"));
- });
- }, this))
- .bind("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) {
- this.get_container().find(" > .jstree-wholerow .jstree-hovered").removeClass("jstree-hovered " + (this.data.themeroller ? this._get_settings().themeroller.item_h : "" ));
- if(e.type === "hover_node") {
- var ref = this.get_container().find(" > .jstree-wholerow li:visible:eq(" + ( parseInt(((data.rslt.obj.offset().top - this.get_container().offset().top + this.get_container()[0].scrollTop) / this.data.core.li_height),10)) + ")");
- // ref.children("a").addClass("jstree-hovered");
- ref.children("a").attr("class",data.rslt.obj.children(".jstree-hovered").attr("class"));
- }
- }, this))
- .delegate(".jstree-wholerow-span, ins.jstree-icon, li", "click.jstree", function (e) {
- var n = $(e.currentTarget);
- if(e.target.tagName === "A" || (e.target.tagName === "INS" && n.closest("li").is(".jstree-open, .jstree-closed"))) { return; }
- n.closest("li").children("a:visible:eq(0)").click();
- e.stopImmediatePropagation();
- })
- .delegate("li", "mouseover.jstree", $.proxy(function (e) {
- e.stopImmediatePropagation();
- if($(e.currentTarget).children(".jstree-hovered, .jstree-clicked").length) { return false; }
- this.hover_node(e.currentTarget);
- return false;
- }, this))
- .delegate("li", "mouseleave.jstree", $.proxy(function (e) {
- if($(e.currentTarget).children("a").hasClass("jstree-hovered").length) { return; }
- this.dehover_node(e.currentTarget);
- }, this));
- if(is_ie7 || is_ie6) {
- $.vakata.css.add_sheet({ str : ".jstree-" + this.get_index() + " { position:relative; } ", title : "jstree" });
- }
- },
- defaults : {
- },
- __destroy : function () {
- this.get_container().children(".jstree-wholerow").remove();
- this.get_container().find(".jstree-wholerow-span").remove();
- },
- _fn : {
- _prepare_wholerow_span : function (obj) {
- obj = !obj || obj == -1 ? this.get_container().find("> ul > li") : this._get_node(obj);
- if(obj === false) { return; } // added for removing root nodes
- obj.each(function () {
- $(this).find("li").andSelf().each(function () {
- var $t = $(this);
- if($t.children(".jstree-wholerow-span").length) { return true; }
- $t.prepend(" ");
- });
- });
- },
- _prepare_wholerow_ul : function () {
- var o = this.get_container().children("ul").eq(0), h = o.html();
- o.addClass("jstree-wholerow-real");
- if(this.data.wholerow.last_html !== h) {
- this.data.wholerow.last_html = h;
- this.get_container().children(".jstree-wholerow").remove();
- this.get_container().append(
- o.clone().removeClass("jstree-wholerow-real")
- .wrapAll("").parent()
- .width(o.parent()[0].scrollWidth)
- .css("top", (o.height() + ( is_ie7 ? 5 : 0)) * -1 )
- .find("li[id]").each(function () { this.removeAttribute("id"); }).end()
- );
- }
- }
- }
- });
- $(function() {
- var css_string = '' +
- '.jstree .jstree-wholerow-real { position:relative; z-index:1; } ' +
- '.jstree .jstree-wholerow-real li { cursor:pointer; } ' +
- '.jstree .jstree-wholerow-real a { border-left-color:transparent !important; border-right-color:transparent !important; } ' +
- '.jstree .jstree-wholerow { position:relative; z-index:0; height:0; } ' +
- '.jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { width:100%; } ' +
- '.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li, .jstree .jstree-wholerow a { margin:0 !important; padding:0 !important; } ' +
- '.jstree .jstree-wholerow, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow li { background:transparent !important; }' +
- '.jstree .jstree-wholerow ins, .jstree .jstree-wholerow span, .jstree .jstree-wholerow input { display:none !important; }' +
- '.jstree .jstree-wholerow a, .jstree .jstree-wholerow a:hover { text-indent:-9999px; !important; width:100%; padding:0 !important; border-right-width:0px !important; border-left-width:0px !important; } ' +
- '.jstree .jstree-wholerow-span { position:absolute; left:0; margin:0px; padding:0; height:18px; border-width:0; padding:0; z-index:0; }';
- if(is_ff2) {
- css_string += '' +
- '.jstree .jstree-wholerow a { display:block; height:18px; margin:0; padding:0; border:0; } ' +
- '.jstree .jstree-wholerow-real a { border-color:transparent !important; } ';
- }
- if(is_ie7 || is_ie6) {
- css_string += '' +
- '.jstree .jstree-wholerow, .jstree .jstree-wholerow li, .jstree .jstree-wholerow ul, .jstree .jstree-wholerow a { margin:0; padding:0; line-height:18px; } ' +
- '.jstree .jstree-wholerow a { display:block; height:18px; line-height:18px; overflow:hidden; } ';
- }
- $.vakata.css.add_sheet({ str : css_string, title : "jstree" });
- });
-})(jQuery);
-//*/
-
-/*
-* jsTree model plugin
-* This plugin gets jstree to use a class model to retrieve data, creating great dynamism
-*/
-(function ($) {
- var nodeInterface = ["getChildren","getChildrenCount","getAttr","getName","getProps"],
- validateInterface = function(obj, inter) {
- var valid = true;
- obj = obj || {};
- inter = [].concat(inter);
- $.each(inter, function (i, v) {
- if(!$.isFunction(obj[v])) { valid = false; return false; }
- });
- return valid;
- };
- $.jstree.plugin("model", {
- __init : function () {
- if(!this.data.json_data) { throw "jsTree model: jsTree json_data plugin not included."; }
- this._get_settings().json_data.data = function (n, b) {
- var obj = (n == -1) ? this._get_settings().model.object : n.data("jstree_model");
- if(!validateInterface(obj, nodeInterface)) { return b.call(null, false); }
- if(this._get_settings().model.async) {
- obj.getChildren($.proxy(function (data) {
- this.model_done(data, b);
- }, this));
- }
- else {
- this.model_done(obj.getChildren(), b);
- }
- };
- },
- defaults : {
- object : false,
- id_prefix : false,
- async : false
- },
- _fn : {
- model_done : function (data, callback) {
- var ret = [],
- s = this._get_settings(),
- _this = this;
-
- if(!$.isArray(data)) { data = [data]; }
- $.each(data, function (i, nd) {
- var r = nd.getProps() || {};
- r.attr = nd.getAttr() || {};
- if(nd.getChildrenCount()) { r.state = "closed"; }
- r.data = nd.getName();
- if(!$.isArray(r.data)) { r.data = [r.data]; }
- if(_this.data.types && $.isFunction(nd.getType)) {
- r.attr[s.types.type_attr] = nd.getType();
- }
- if(r.attr.id && s.model.id_prefix) { r.attr.id = s.model.id_prefix + r.attr.id; }
- if(!r.metadata) { r.metadata = { }; }
- r.metadata.jstree_model = nd;
- ret.push(r);
- });
- callback.call(null, ret);
- }
- }
- });
-})(jQuery);
-//*/
-
-})();
\ No newline at end of file
diff --git a/vendor/assets/javascripts/jquery.jstree/themes/apple/bg.jpg b/vendor/assets/javascripts/jquery.jstree/themes/apple/bg.jpg
deleted file mode 100755
index ac38d8c27f..0000000000
Binary files a/vendor/assets/javascripts/jquery.jstree/themes/apple/bg.jpg and /dev/null differ
diff --git a/vendor/assets/javascripts/jquery.jstree/themes/apple/d.png b/vendor/assets/javascripts/jquery.jstree/themes/apple/d.png
deleted file mode 100755
index 050becf0cd..0000000000
Binary files a/vendor/assets/javascripts/jquery.jstree/themes/apple/d.png and /dev/null differ
diff --git a/vendor/assets/javascripts/jquery.jstree/themes/apple/dot_for_ie.gif b/vendor/assets/javascripts/jquery.jstree/themes/apple/dot_for_ie.gif
deleted file mode 100755
index c0cc5fda7c..0000000000
Binary files a/vendor/assets/javascripts/jquery.jstree/themes/apple/dot_for_ie.gif and /dev/null differ
diff --git a/vendor/assets/javascripts/jquery.jstree/themes/apple/style.css b/vendor/assets/javascripts/jquery.jstree/themes/apple/style.css
deleted file mode 100644
index a4a69a38af..0000000000
--- a/vendor/assets/javascripts/jquery.jstree/themes/apple/style.css
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * jsTree apple theme 1.0
- * Supported features: dots/no-dots, icons/no-icons, focused, loading
- * Supported plugins: ui (hovered, clicked), checkbox, contextmenu, search
- */
-
-.jstree-apple > ul { background:url("bg.jpg") left top repeat; }
-.jstree-apple li,
-.jstree-apple ins { background-image:url("d.png"); background-repeat:no-repeat; background-color:transparent; }
-.jstree-apple li { background-position:-90px 0; background-repeat:repeat-y; }
-.jstree-apple li.jstree-last { background:transparent; }
-.jstree-apple .jstree-open > ins { background-position:-72px 0; }
-.jstree-apple .jstree-closed > ins { background-position:-54px 0; }
-.jstree-apple .jstree-leaf > ins { background-position:-36px 0; }
-
-.jstree-apple a { border-radius:4px; -webkit-border-radius:4px; text-shadow:1px 1px 1px white; }
-.jstree-apple .jstree-hovered { background:#e7f4f9; border:1px solid #d8f0fa; padding:0 3px 0 1px; text-shadow:1px 1px 1px silver; }
-.jstree-apple .jstree-clicked { background:#beebff; border:1px solid #99defd; padding:0 3px 0 1px; }
-.jstree-apple a .jstree-icon { background-position:-56px -20px; }
-
-.jstree-apple.jstree-focused { background:white; }
-
-.jstree-apple .jstree-no-dots li,
-.jstree-apple .jstree-no-dots .jstree-leaf > ins { background:transparent; }
-.jstree-apple .jstree-no-dots .jstree-open > ins { background-position:-18px 0; }
-.jstree-apple .jstree-no-dots .jstree-closed > ins { background-position:0 0; }
-
-.jstree-apple .jstree-no-icons a .jstree-icon { display:none; }
-
-.jstree-apple .jstree-search { font-style:italic; }
-
-.jstree-apple .jstree-no-icons .jstree-checkbox { display:inline-block; }
-.jstree-apple .jstree-no-checkboxes .jstree-checkbox { display:none !important; }
-.jstree-apple .jstree-checked > a > .jstree-checkbox { background-position:-38px -19px; }
-.jstree-apple .jstree-unchecked > a > .jstree-checkbox { background-position:-2px -19px; }
-.jstree-apple .jstree-undetermined > a > .jstree-checkbox { background-position:-20px -19px; }
-.jstree-apple .jstree-checked > a > .checkbox:hover { background-position:-38px -37px; }
-.jstree-apple .jstree-unchecked > a > .jstree-checkbox:hover { background-position:-2px -37px; }
-.jstree-apple .jstree-undetermined > a > .jstree-checkbox:hover { background-position:-20px -37px; }
-
-#vakata-dragged.jstree-apple ins { background:transparent !important; }
-/*#vakata-dragged.jstree-apple .jstree-ok { background:url("d.png") -2px -53px no-repeat !important; }*/
-/*#vakata-dragged.jstree-apple .jstree-invalid { background:url("d.png") -18px -53px no-repeat !important; }*/
-/*#jstree-marker.jstree-apple { background:url("d.png") -41px -57px no-repeat !important; text-indent:-100px; }*/
-
-.jstree-apple a.jstree-search { color:aqua; }
-.jstree-apple .jstree-locked a { color:silver; cursor:default; }
-
-#vakata-contextmenu.jstree-apple-context,
-#vakata-contextmenu.jstree-apple-context li ul { background:#f0f0f0; border:1px solid #979797; -moz-box-shadow: 1px 1px 2px #999; -webkit-box-shadow: 1px 1px 2px #999; box-shadow: 1px 1px 2px #999; }
-#vakata-contextmenu.jstree-apple-context li { }
-#vakata-contextmenu.jstree-apple-context a { color:black; }
-#vakata-contextmenu.jstree-apple-context a:hover,
-#vakata-contextmenu.jstree-apple-context .vakata-hover > a { padding:0 5px; background:#e8eff7; border:1px solid #aecff7; color:black; -webkit-border-radius:2px; border-radius:2px; }
-#vakata-contextmenu.jstree-apple-context li.jstree-contextmenu-disabled a,
-#vakata-contextmenu.jstree-apple-context li.jstree-contextmenu-disabled a:hover { color:silver; background:transparent; border:0; padding:1px 4px; }
-#vakata-contextmenu.jstree-apple-context li.vakata-separator { background:white; border-top:1px solid #e0e0e0; margin:0; }
-#vakata-contextmenu.jstree-apple-context li ul { margin-left:-4px; }
-
-/* TODO: IE6 support - the `>` selectors */
\ No newline at end of file
diff --git a/vendor/assets/javascripts/jquery.jstree/themes/apple/throbber.gif b/vendor/assets/javascripts/jquery.jstree/themes/apple/throbber.gif
deleted file mode 100755
index 08eb9a0bab..0000000000
Binary files a/vendor/assets/javascripts/jquery.jstree/themes/apple/throbber.gif and /dev/null differ
diff --git a/yarn.lock b/yarn.lock
index 1b81a7e1ff..157fcd8c2c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1099,18 +1099,18 @@
dependencies:
"@floating-ui/utils" "^0.2.4"
-"@floating-ui/dom@^1.6.10":
- version "1.6.10"
- resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.10.tgz#b74c32f34a50336c86dcf1f1c845cf3a39e26d6f"
- integrity sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==
+"@floating-ui/dom@^1.6.11":
+ version "1.6.11"
+ resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.11.tgz#8631857838d34ee5712339eb7cbdfb8ad34da723"
+ integrity sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==
dependencies:
"@floating-ui/core" "^1.6.0"
- "@floating-ui/utils" "^0.2.7"
+ "@floating-ui/utils" "^0.2.8"
-"@floating-ui/utils@^0.2.4", "@floating-ui/utils@^0.2.7":
- version "0.2.7"
- resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.7.tgz#d0ece53ce99ab5a8e37ebdfe5e32452a2bfc073e"
- integrity sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==
+"@floating-ui/utils@^0.2.4", "@floating-ui/utils@^0.2.8":
+ version "0.2.8"
+ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62"
+ integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==
"@googlemaps/js-api-loader@^1.16.6":
version "1.16.6"
@@ -1129,10 +1129,10 @@
resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.2.tgz#071aab59c600fed95b97939e605ff261a4251608"
integrity sha512-eGeIqNOQpXoPAIP7tC1+1Yc1yl1xnwYqg+3mzqxyrbE5pg5YFBZcA6YoTiByJB6DKAEsiWtl6tjTJS4IYtbB7A==
-"@hotwired/turbo@^8.0.5":
- version "8.0.5"
- resolved "https://registry.yarnpkg.com/@hotwired/turbo/-/turbo-8.0.5.tgz#abae6dad018a891e4286e87fa0959217e3866d5a"
- integrity sha512-TdZDA7fxVQ2ZycygvpnzjGPmFq4sO/E2QVg+2em/sJ3YTSsIWVEis8HmWlumz+c9DjWcUkcCuB+muF08TInpAQ==
+"@hotwired/turbo@^8.0.10":
+ version "8.0.10"
+ resolved "https://registry.yarnpkg.com/@hotwired/turbo/-/turbo-8.0.10.tgz#d95569d259f0daad6e824ee1ada877ff94beb72b"
+ integrity sha512-xen1YhNQirAHlA8vr/444XsTNITC1Il2l/Vx4w8hAWPpI5nQO78mVHNsmFuayETodzPwh25ob2TgfCEV/Loiog==
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
@@ -2229,10 +2229,10 @@ bn.js@^5.2.1:
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
-body-parser@1.20.2, body-parser@^1.19.0:
- version "1.20.2"
- resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
- integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
+body-parser@1.20.3, body-parser@^1.19.0:
+ version "1.20.3"
+ resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6"
+ integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==
dependencies:
bytes "3.1.2"
content-type "~1.0.5"
@@ -2242,7 +2242,7 @@ body-parser@1.20.2, body-parser@^1.19.0:
http-errors "2.0.0"
iconv-lite "0.4.24"
on-finished "2.4.1"
- qs "6.11.0"
+ qs "6.13.0"
raw-body "2.5.2"
type-is "~1.6.18"
unpipe "1.0.0"
@@ -2507,6 +2507,17 @@ call-bind@^1.0.0, call-bind@^1.0.2:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
+call-bind@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
+ integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.4"
+ set-function-length "^1.2.1"
+
caller-callsite@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
@@ -3253,11 +3264,6 @@ date-format@^4.0.3:
resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.3.tgz#f63de5dc08dc02efd8ef32bf2a6918e486f35873"
integrity sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==
-debounced@^0.0.5:
- version "0.0.5"
- resolved "https://registry.yarnpkg.com/debounced/-/debounced-0.0.5.tgz#e540b6eebfe703d93462711b4f3562ffd101b87f"
- integrity sha512-8Bgheu1YxQB7ocqYmK2enbLGVoo4nCtu/V6UD/SMDOeV3g2LocG2CrA5oxudlyl79Ja07UiqGdp9pWZoJn52EQ==
-
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -3329,6 +3335,15 @@ default-gateway@^4.2.0:
execa "^1.0.0"
ip-regex "^2.1.0"
+define-data-property@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
+ integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ gopd "^1.0.1"
+
define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -3542,9 +3557,9 @@ electron-to-chromium@^1.4.284:
integrity sha512-XKGdI4pWM78eLH2cbXJHiBnWUwFSzZM7XujsB6stDiGu9AeSqziedP6amNLpJzE3i0rLTcfAwdCTs5ecP5yeSg==
elliptic@^6.5.3, elliptic@^6.5.4:
- version "6.5.4"
- resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
- integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
+ version "6.5.7"
+ resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b"
+ integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==
dependencies:
bn.js "^4.11.9"
brorand "^1.1.0"
@@ -3579,6 +3594,11 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
+encodeurl@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58"
+ integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==
+
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
@@ -3662,6 +3682,18 @@ es-abstract@^1.17.2, es-abstract@^1.18.0-next.2:
string.prototype.trimstart "^1.0.4"
unbox-primitive "^1.0.0"
+es-define-property@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
+ integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
+ dependencies:
+ get-intrinsic "^1.2.4"
+
+es-errors@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
+ integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
+
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
@@ -3830,36 +3862,36 @@ expect@^27.5.1:
jest-message-util "^27.5.1"
express@^4.17.1:
- version "4.19.2"
- resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
- integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
+ version "4.21.0"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915"
+ integrity sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
- body-parser "1.20.2"
+ body-parser "1.20.3"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.6.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "2.0.0"
- encodeurl "~1.0.2"
+ encodeurl "~2.0.0"
escape-html "~1.0.3"
etag "~1.8.1"
- finalhandler "1.2.0"
+ finalhandler "1.3.1"
fresh "0.5.2"
http-errors "2.0.0"
- merge-descriptors "1.0.1"
+ merge-descriptors "1.0.3"
methods "~1.1.2"
on-finished "2.4.1"
parseurl "~1.3.3"
- path-to-regexp "0.1.7"
+ path-to-regexp "0.1.10"
proxy-addr "~2.0.7"
- qs "6.11.0"
+ qs "6.13.0"
range-parser "~1.2.1"
safe-buffer "5.2.1"
- send "0.18.0"
- serve-static "1.15.0"
+ send "0.19.0"
+ serve-static "1.16.2"
setprototypeof "1.2.0"
statuses "2.0.1"
type-is "~1.6.18"
@@ -3977,13 +4009,13 @@ finalhandler@1.1.2:
statuses "~1.5.0"
unpipe "~1.0.0"
-finalhandler@1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
- integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
+finalhandler@1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019"
+ integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==
dependencies:
debug "2.6.9"
- encodeurl "~1.0.2"
+ encodeurl "~2.0.0"
escape-html "~1.0.3"
on-finished "2.4.1"
parseurl "~1.3.3"
@@ -4162,6 +4194,11 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+function-bind@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+
functions-have-names@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
@@ -4195,6 +4232,17 @@ get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"
+get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
+ integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
+ dependencies:
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ has-proto "^1.0.1"
+ has-symbols "^1.0.3"
+ hasown "^2.0.0"
+
get-package-type@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
@@ -4296,6 +4344,13 @@ globby@^6.1.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
+gopd@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
+ integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+ dependencies:
+ get-intrinsic "^1.1.3"
+
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.9"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
@@ -4328,6 +4383,18 @@ has-property-descriptors@^1.0.0:
dependencies:
get-intrinsic "^1.1.1"
+has-property-descriptors@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
+ integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
+ dependencies:
+ es-define-property "^1.0.0"
+
+has-proto@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
+ integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
+
has-symbols@^1.0.1, has-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
@@ -4400,6 +4467,13 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"
+hasown@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
+ integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
+ dependencies:
+ function-bind "^1.1.2"
+
hex-color-regex@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
@@ -5071,10 +5145,10 @@ istanbul-reports@^3.1.3:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
-jasmine-core@~5.2.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-5.2.0.tgz#7d0aa4c26cb3dbaed201d0505489baf1e48faeca"
- integrity sha512-tSAtdrvWybZkQmmaIoDgnvHG8ORUNw5kEVlO5CvrXj02Jjr9TZrmjFq7FUiOUzJiOP2wLGYT6PgrQgQF4R1xiw==
+jasmine-core@~5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-5.3.0.tgz#ed784e5a10af43988d8408bad80b9f08e240a3f8"
+ integrity sha512-zsOmeBKESky4toybvWEikRiZ0jHoBEu79wNArLfMdSnlLMZx3Xcp6CSm2sUcYyoJC+Uyj8LBJap/MUbVSfJ27g==
jest-changed-files@^27.5.1:
version "27.5.1"
@@ -5502,10 +5576,10 @@ jquery-ui@1.14.0:
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de"
integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==
-js-big-decimal@^2.0.7:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/js-big-decimal/-/js-big-decimal-2.0.7.tgz#fb9b44b4c1eae08903cb191c0cf37b82f3a8d7c4"
- integrity sha512-XGc79t2Iv3b7LFlYaTT8WoQBuWL4K81aST+dq2YGHV6giedbnoG0s33ju24Uw/BGqLYfPPgn4HGRrPS2mfKk3Q==
+js-big-decimal@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/js-big-decimal/-/js-big-decimal-2.1.0.tgz#9e06c10590969aa1ffb8570af25072391b6973bb"
+ integrity sha512-6BOJi5gJ/u5KIOiRjwDnYee64wDw48/mzObV10L5ZYZ/u3ujpzJrO1JyIdIYbfxJPhIT7+oKn7d/1Fw1kOsh2w==
js-tokens@^4.0.0:
version "4.0.0"
@@ -5911,10 +5985,10 @@ memory-fs@^0.5.0:
errno "^0.1.3"
readable-stream "^2.0.1"
-merge-descriptors@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
- integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
+merge-descriptors@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5"
+ integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==
merge-stream@^2.0.0:
version "2.0.0"
@@ -6141,10 +6215,10 @@ mri@^1.2.0:
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
-mrujs@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/mrujs/-/mrujs-1.0.0.tgz#b1d5bf86dd17612c2758388005919fb44a9878f6"
- integrity sha512-uQv7o4fyrO+qDKJhBh7B9ox3tA1gVrdksSueZPEkyQ++re70G6D27HJpzKm6JlsnRE98Q5F4BdtJFYUv1j2OnQ==
+mrujs@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/mrujs/-/mrujs-1.0.2.tgz#f19818735d8f5865dab75254f4cfc38d33804f2e"
+ integrity sha512-dGTUHLH+COsGOn78R7lUFUK/eDLaY8W14N25EymB6lXknENeyoVL31Hsxfb2hEsMb2yjBx0cB//ibO/NTECIzQ==
dependencies:
morphdom ">=2.6.0 <3.0.0"
@@ -6344,6 +6418,11 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
+object-inspect@^1.13.1:
+ version "1.13.2"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff"
+ integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==
+
object-inspect@^1.9.0:
version "1.12.2"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
@@ -6659,10 +6738,10 @@ path-parse@^1.0.6, path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
-path-to-regexp@0.1.7:
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
- integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
+path-to-regexp@0.1.10:
+ version "0.1.10"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b"
+ integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==
path-type@^4.0.0:
version "4.0.0"
@@ -7544,12 +7623,12 @@ qjobs@^1.2.0:
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==
-qs@6.11.0:
- version "6.11.0"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
- integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
+qs@6.13.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906"
+ integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==
dependencies:
- side-channel "^1.0.4"
+ side-channel "^1.0.6"
query-string@^4.1.0:
version "4.3.4"
@@ -7989,10 +8068,10 @@ semver@^7.3.2:
dependencies:
lru-cache "^6.0.0"
-send@0.18.0:
- version "0.18.0"
- resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
- integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
+send@0.19.0:
+ version "0.19.0"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8"
+ integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==
dependencies:
debug "2.6.9"
depd "2.0.0"
@@ -8035,21 +8114,33 @@ serve-index@^1.9.1:
mime-types "~2.1.17"
parseurl "~1.3.2"
-serve-static@1.15.0:
- version "1.15.0"
- resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
- integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
+serve-static@1.16.2:
+ version "1.16.2"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296"
+ integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==
dependencies:
- encodeurl "~1.0.2"
+ encodeurl "~2.0.0"
escape-html "~1.0.3"
parseurl "~1.3.3"
- send "0.18.0"
+ send "0.19.0"
set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
+set-function-length@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
+ integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
+ dependencies:
+ define-data-property "^1.1.4"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.4"
+ gopd "^1.0.1"
+ has-property-descriptors "^1.0.2"
+
set-value@^2.0.0, set-value@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
@@ -8112,14 +8203,15 @@ shortcut-buttons-flatpickr@^0.4.0:
resolved "https://registry.yarnpkg.com/shortcut-buttons-flatpickr/-/shortcut-buttons-flatpickr-0.4.0.tgz#a36e0a88a670ed2637b7b1adb5bee0914c29a7e7"
integrity sha512-JKmT4my3Hm1e18OvG4Q6RcFhN4WRqqpTMkHrvZ7fup/dp6aTIWGVCHdRYtASkp/FCzDlJh6iCLQ/VcwwNpAMoQ==
-side-channel@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
- integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
+side-channel@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
+ integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
dependencies:
- call-bind "^1.0.0"
- get-intrinsic "^1.0.2"
- object-inspect "^1.9.0"
+ call-bind "^1.0.7"
+ es-errors "^1.3.0"
+ get-intrinsic "^1.2.4"
+ object-inspect "^1.13.1"
signal-exit@^3.0.0:
version "3.0.7"
@@ -8825,6 +8917,11 @@ tty-browserify@0.0.0:
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
+turbo_power@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/turbo_power/-/turbo_power-0.7.0.tgz#537cc82f3617feb1c70b94ee6c8b7d42cdce81db"
+ integrity sha512-KU5YbHnyYXluETUKmq02tH4/Vy/yJ4my1Nn7USRPWyEFV6LiXICPlhr2ETJ90pf11khs7WMNKEEqNTcGLngs6w==
+
type-check@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"