Compare commits

..

112 Commits

Author SHA1 Message Date
filipefurtad0
e190b87f12 Update all locales with the latest Transifex translations 2025-09-29 15:54:51 +01:00
Filipe
ff2e0f4d45 Merge pull request #13533 from chahmedejaz/task/13435-sort-products-by-on-hand-amount
Sort product list by 'on hand' amount
2025-09-29 15:07:00 +01:00
Gaetan Craig-Riou
9b0545c33f Merge pull request #13550 from openfoodfoundation/dependabot/bundler/rack-2.2.18
Bump rack from 2.2.14 to 2.2.18
2025-09-29 09:39:35 +10:00
dependabot[bot]
7631fd422e Bump rack from 2.2.14 to 2.2.18
Bumps [rack](https://github.com/rack/rack) from 2.2.14 to 2.2.18.
- [Release notes](https://github.com/rack/rack/releases)
- [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rack/rack/compare/v2.2.14...v2.2.18)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-25 17:32:06 +00:00
Gaetan Craig-Riou
693789d526 Merge pull request #13549 from openfoodfoundation/dependabot/npm_and_yarn/leaflet-geosearch-4.2.2
Bump leaflet-geosearch from 4.2.1 to 4.2.2
2025-09-24 09:49:41 +10:00
dependabot[bot]
d26b407801 Bump leaflet-geosearch from 4.2.1 to 4.2.2
Bumps [leaflet-geosearch](https://github.com/smeijer/leaflet-geosearch) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/smeijer/leaflet-geosearch/releases)
- [Commits](https://github.com/smeijer/leaflet-geosearch/compare/v4.2.1...v4.2.2)

---
updated-dependencies:
- dependency-name: leaflet-geosearch
  dependency-version: 4.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 09:12:58 +00:00
filipefurtad0
fe257162b7 Update all locales with the latest Transifex translations 2025-09-22 07:56:21 +01:00
Maikel
9e746d1b40 Merge pull request #13531 from rioug/better-stimulus-name-for-component
Load component stimulus controller with a shorter name
2025-09-17 17:10:37 +10:00
Filipe
273f78b214 Merge pull request #13530 from mkllnk/hub-address-feature
Remove retired hub_address feature
2025-09-16 17:23:42 +01:00
Filipe
bd1d9892a2 Merge pull request #13487 from rioug/security-241-fix-url-sanitization
Fix url sanitization for Stripe authorisation URL
2025-09-16 16:40:11 +01:00
David Cook
cb825df75b Merge pull request #13536 from openfoodfoundation/dependabot/npm_and_yarn/leaflet-geosearch-4.2.1
Bump leaflet-geosearch from 4.2.0 to 4.2.1
2025-09-16 15:32:29 +10:00
Filipe
bfcadfd7c0 Merge pull request #13404 from cyrillefr/UnsavedChangesMustAppearOnRemovingSingleTagFromOrderCycle
Fixes Save button does not enable when removing only tag in OC
2025-09-15 13:27:26 +01:00
dependabot[bot]
255b5f1cd5 Bump leaflet-geosearch from 4.2.0 to 4.2.1
Bumps [leaflet-geosearch](https://github.com/smeijer/leaflet-geosearch) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/smeijer/leaflet-geosearch/releases)
- [Commits](https://github.com/smeijer/leaflet-geosearch/compare/v4.2.0...v4.2.1)

---
updated-dependencies:
- dependency-name: leaflet-geosearch
  dependency-version: 4.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 09:27:26 +00:00
Ahmed Ejaz
dffcd446fd Simplify backorderable priority SQL query in product sorting concern 2025-09-15 12:03:04 +05:00
Ahmed Ejaz
1987f0b667 Remove redundant SQL string checks in product sorting specs for clarity 2025-09-15 11:57:33 +05:00
Ahmed Ejaz
0b5efae8c4 Refactor sorting expectations in product_sort_by_stocks_spec for clarity and accuracy 2025-09-15 11:56:07 +05:00
Gaetan Craig-Riou
36bb7cb317 Fix vertical ellipsis menu compoenent spec 2025-09-15 10:46:16 +10:00
Ahmed Ejaz
49dbe1d039 Refactor comments for clarity in product sorting concerns 2025-09-15 02:15:03 +05:00
Ahmed Ejaz
c326aa6b23 Add comprehensive specs for sorting functionality 2025-09-15 01:59:40 +05:00
Ahmed Ejaz
ec91d717c7 Fix default sorting for 'on_hand' column to 'name asc' in admin products table 2025-09-13 01:31:38 +05:00
Ahmed Ejaz
da843d1ba1 Add sorting by stock levels using ransacker and update locale for 'on_hand' header 2025-09-13 01:11:21 +05:00
filipefurtad0
2c4b3ab8fc Update all locales with the latest Transifex translations 2025-09-12 08:41:29 +01:00
Gaetan Craig-Riou
1c7fbd1d2d Rename vertical ellipsis menu component files
There is no need to have a different name scheme to shorten stimulus
controller name. It's now inline with the other components
2025-09-10 15:27:56 +10:00
Gaetan Craig-Riou
8042dac74f Fix stimulus controller name to use the shorter version 2025-09-10 15:10:10 +10:00
Gaetan Craig-Riou
ad1ce00223 Generate a better stimulus name for component controller
Using the helper `definitionsFromContext` generate quite long name for
stimulus controller in component, ie :
`tag-list-input-component--tag-list-input`.
This custom loader will generate much more readable name, ie L
`tag-list-input`. It's expecting the following pattern :
ofn_component/ofn_controller.js and will fall back to the default
of replacing "_" by "- and "/" by "--" for controller not matching
the pattern.
2025-09-10 15:03:31 +10:00
Maikel Linke
d916ed2c96 Remove retired hub_address feature 2025-09-10 09:59:47 +10:00
Filipe
da66a2947c Merge pull request #13502 from cillian/replace-darker-background-disable-dynamically-inline-alert-page-alert-directives
Replace darker-background, disable-dynamically, inline-alert and page-alert Angular directives
2025-09-08 16:28:51 +01:00
David Cook
646d3b8ed9 Merge pull request #13524 from mkllnk/cleanup
Code cleanup
2025-09-08 14:31:34 +10:00
Gaetan Craig-Riou
1f15f094ce Per review, check the URL is from a stripe subdomain 2025-09-08 11:00:11 +10:00
filipefurtad0
adddee2c3c Update all locales with the latest Transifex translations 2025-09-05 09:52:44 +01:00
Cillian O'Ruanaidh
74e7bd5172 Update spec/system/consumer/shopping/cart_spec.rb test to use new disabled selector 2025-09-05 09:38:20 +01:00
Cillian O'Ruanaidh
66859f44ca Include LinkHelper which includes new :link_to_or_disable method to fix spec/views/spree/orders/edit.html.haml_spec.rb test 2025-09-05 09:38:20 +01:00
Cillian O'Ruanaidh
6f7a547e15 Add a :link_to_or_disabled helper method 2025-09-05 09:38:20 +01:00
Cillian O'Ruanaidh
c057c72321 Replace ofn-page-alert angular directive 2025-09-05 09:38:20 +01:00
Cillian O'Ruanaidh
7a3b4d394b Replace inline-alert angular directive 2025-09-05 09:38:20 +01:00
Cillian O'Ruanaidh
32e3fc0175 Replace disable-dynamically angular directive 2025-09-05 09:38:20 +01:00
Cillian O'Ruanaidh
23c9410a25 Replace darker-background angular directive 2025-09-05 09:38:20 +01:00
Maikel
7e9c5ea58b Merge pull request #13523 from filipefurtad0/content_spec_html
Adds coverage to homepage alert HTML content
2025-09-05 14:35:07 +10:00
Maikel Linke
6c313a1b5a Remove duplicate include of TimeHelpers in specs 2025-09-05 14:30:46 +10:00
Maikel Linke
244a88a1cd Removed unused user from report classes
We needed them for a feature toggle that doesn't exist anymore.
2025-09-05 14:29:01 +10:00
filipefurtad0
589315780c Adds coverage to homepage alert HTML content 2025-09-04 19:07:29 +01:00
Gaetan Craig-Riou
2910082584 Merge pull request #13517 from openfoodfoundation/dependabot/npm_and_yarn/jasmine-core-5.10.0
Bump jasmine-core from 5.9.0 to 5.10.0
2025-09-03 16:54:57 +10:00
dependabot[bot]
70b5fda632 Bump jasmine-core from 5.9.0 to 5.10.0
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/main/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v5.9.0...v5.10.0)

---
updated-dependencies:
- dependency-name: jasmine-core
  dependency-version: 5.10.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 18:05:10 +00:00
Maikel Linke
9bf2dad343 Update all locales with the latest Transifex translations 2025-08-29 15:15:19 +10:00
David Cook
05b3417f77 Merge pull request #13512 from mkllnk/remove-timecop-usage
Remove remaining Timecop usage
2025-08-29 14:09:50 +10:00
Maikel Linke
403aa6ac6f Remove remaining Timecop usage 2025-08-29 11:16:20 +10:00
Filipe
fbad3ee9f4 Merge pull request #13484 from cesarlr/patch-1
Update Gemfile.lock
2025-08-28 19:38:59 +01:00
Filipe
ddb8b2d08f Merge pull request #13496 from dacook/fix-link
Fix link to enterprise payment methods tab
2025-08-28 19:17:37 +01:00
Filipe
42c9ee033a Merge pull request #13503 from AndreyUsyaev/usandy/fix-i18n-sells-options
Fix missed I18n translations for enterprises sells options
2025-08-28 18:50:07 +01:00
Maikel Linke
524634b4ea Bump wkhtmltopdf-binary from 0.12.6.9 to 0.12.6.10 to support Debian 13 2025-08-28 11:46:21 +01:00
César López Ramírez
0b97171bb0 Update Gemfile.lock
Upgrade wkhtmltopdf-binary to support Ubuntu 24.04
2025-08-28 11:46:21 +01:00
Filipe
b0c7e29b0d Merge pull request #13468 from mkllnk/rails-config-updates
Add Rails 7.0 and 7.1 framework defaults
2025-08-28 11:44:44 +01:00
Andrey Usyaev
3d7799df19 Fix code review remarks 2025-08-27 13:21:44 +03:00
Andrey Usyaev
5f02d88a86 Fix missed I18n translations for enterprises sells options 2025-08-27 13:21:44 +03:00
Maikel
bdae8e6478 Merge pull request #13475 from mkllnk/dfc-sib-tokens
Accept tokens from Startin'Blox OIDC server
2025-08-27 14:55:30 +10:00
Gaetan Craig-Riou
053ef05baf Merge pull request #13480 from mkllnk/time-travel
Replace Timecop with Rails' time helpers
2025-08-27 09:34:58 +10:00
Ahmed Ejaz
7fcb31d563 Update all locales with the latest Transifex translations 2025-08-25 11:49:44 +05:00
Gaetan Craig-Riou
31a7374808 Merge pull request #13444 from garethdavisrogers/fix-docker-dependency-and-db-dev-env
Added cmake dep to dockerfile and added script for db:schema:load tha…
2025-08-25 14:10:10 +10:00
Gareth
e5ce06ae39 Updated branch 2025-08-22 12:49:24 -04:00
Gareth Rogers
5f64204d51 Merge branch 'master' into fix-docker-dependency-and-db-dev-env 2025-08-22 08:31:27 -04:00
Maikel Linke
94b75540e4 Replace Timecop with Rails' time helpers
Rails 4.1 added time helpers but we never bothered using them. But now
I'm getting rid of the Timecop dependency and use standard helpers.

Beware though that the new helpers always freeze time. When you travel
to a certain date then the clock stops ticking while Timecop maintained
the passing of time.

The freezing of time could cause problems if you are trying to enforce a
timeout. But all current specs don't seem affected.

In most cases, the freezing will make it easier to avoid flaky specs.
2025-08-22 16:57:04 +10:00
Maikel Linke
6e489d7770 Enforce required DFC permissions 2025-08-22 16:46:59 +10:00
Maikel Linke
81b1169e77 Configure undercover to exclude files 2025-08-22 16:13:20 +10:00
Maikel
4b558b4820 Merge pull request #13501 from openfoodfoundation/dependabot/npm_and_yarn/sha.js-2.4.12
Bump sha.js from 2.4.11 to 2.4.12
2025-08-22 16:12:26 +10:00
Maikel
e224b8f63b Merge pull request #13500 from openfoodfoundation/dependabot/npm_and_yarn/cipher-base-1.0.6
Bump cipher-base from 1.0.4 to 1.0.6
2025-08-22 16:11:30 +10:00
Maikel
80bb0606b4 Merge pull request #13499 from openfoodfoundation/dependabot/npm_and_yarn/floating-ui/dom-1.7.4
Bump @floating-ui/dom from 1.7.3 to 1.7.4
2025-08-22 15:50:47 +10:00
dependabot[bot]
499fcc791e Bump sha.js from 2.4.11 to 2.4.12
Bumps [sha.js](https://github.com/crypto-browserify/sha.js) from 2.4.11 to 2.4.12.
- [Changelog](https://github.com/browserify/sha.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crypto-browserify/sha.js/compare/v2.4.11...v2.4.12)

---
updated-dependencies:
- dependency-name: sha.js
  dependency-version: 2.4.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-21 15:48:41 +00:00
dependabot[bot]
30dae3c3ea Bump cipher-base from 1.0.4 to 1.0.6
Bumps [cipher-base](https://github.com/crypto-browserify/cipher-base) from 1.0.4 to 1.0.6.
- [Changelog](https://github.com/browserify/cipher-base/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crypto-browserify/cipher-base/compare/v1.0.4...v1.0.6)

---
updated-dependencies:
- dependency-name: cipher-base
  dependency-version: 1.0.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-21 15:23:41 +00:00
dependabot[bot]
af247c32a3 Bump @floating-ui/dom from 1.7.3 to 1.7.4
Bumps [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) from 1.7.3 to 1.7.4.
- [Release notes](https://github.com/floating-ui/floating-ui/releases)
- [Changelog](https://github.com/floating-ui/floating-ui/blob/master/packages/dom/CHANGELOG.md)
- [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.7.4/packages/dom)

---
updated-dependencies:
- dependency-name: "@floating-ui/dom"
  dependency-version: 1.7.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-21 09:48:24 +00:00
Gareth
6f9dcf7e27 remove bundle check 2025-08-20 11:04:40 -04:00
Gareth
2d064bab64 Created a bundler service that runs once removing responsibilities from any other services. The bundler service always runs install which should still be pretty fast if nothing or only a few gems have changed. A healthcheck won't work unless bundler runs continuously which is impractical. Instead, a checksum is generated on bundle install and sentinels in the other services have a definite confirmation that bundle is complete. The nice thing about this approach is that web, webpack, and sidekiq (which share the same bundles dependencies) will not concurrently run bundle install solving dep install redundancies. 2025-08-20 10:13:20 -04:00
Gareth
b69eb9bdff Specified BUNDLE_PATH AND BUNDLE_APP_CONFIG in Dockerfile 2025-08-20 08:48:21 -04:00
David Cook
f79c1879bd Test that you can actually get to Stripe to connect your account
Well.. almost.
2025-08-20 13:06:59 +10:00
David Cook
646d538a3d Fix broken link
This link would go to the enterprise edit screen, but didn't successfully select the payment methods panel.

Ideally, the spec would try to follow the link and verify that you can see the Connect with Stripe button. But it opens the link in a new tab and I'm not sure how to test that.
2025-08-20 11:54:47 +10:00
Gareth
b95d798a27 Fixed webpack service so that web relies on its bundles. This has re-enabled JS 2025-08-18 12:24:27 -04:00
Gareth
e1e4aeac1f Added conditions to sidekiq too as it races db as well. Everything seems functional now 2025-08-18 11:52:52 -04:00
Gareth
c7ae47053e Added health check to avoid docker container racing 2025-08-18 11:38:57 -04:00
Gareth Rogers
5892ae1800 Merge branch 'master' into fix-docker-dependency-and-db-dev-env 2025-08-18 09:32:21 -04:00
Ahmed Ejaz
7aa9b164e6 Add scope for ordering products by stock levels and update admin table header for on_hand sorting 2025-08-17 07:16:46 +05:00
Gareth
74368f939b By creating the db in the container on composition, the first migration file rejects the schema of the empty database. All I had to do was remove db creation from docker so that db:prepare will default to creating open_food_network_dev from schema.rb rather than perceiving a mismatch from the precreated docker db 2025-08-15 14:23:13 -04:00
Gareth
cb02cd39fe Reverting unexpected change to schema.rb as requested 2025-08-15 12:27:10 -04:00
Gaetan Craig-Riou
118e18a78e Tighten url validation
Per recommendation from https://github.com/openfoodfoundation/openfoodnetwork/security/code-scanning/241
2025-08-13 22:27:42 +10:00
Gaetan Craig-Riou
cbced144d5 Clean up styling 2025-08-13 22:21:35 +10:00
Maikel Linke
1d2115766a Show product groups to platform user
I removed the caching of `managed_enterprises` in Permissions because
it's just a scope and calling it again is very cheap. And that makes the
method a lot easier to read now that we have a conditional here.

Accessing the managed enterprises via the user instead of a separate
scope on the Enterprise model also reduce the SQL queries. We may want
to use this method in more places. I prefer to keep the
admin-conditional in a permissions class instead of in the model.
2025-08-13 15:06:31 +10:00
Maikel Linke
6814ef43f4 Show addresses to platform users 2025-08-13 15:06:25 +10:00
Maikel Linke
c9e8294561 DRY with shared context 2025-08-13 15:02:09 +10:00
Maikel Linke
82d0e1bf68 Show enterprise to authorised platform user 2025-08-13 15:02:09 +10:00
Maikel Linke
b16e541a81 Show DFC catalog to authorised platform 2025-08-13 15:02:09 +10:00
Maikel Linke
c12d494de3 Demonstrate authentication as DFC client app 2025-08-13 15:02:09 +10:00
Maikel Linke
9be27842e1 Accepts tokens from Startin'Blox OIDC server
The API controllers don't know the new type of user yet and will raise
errors but we can work on that bit by bit.
2025-08-13 15:02:09 +10:00
Maikel Linke
2a7754edbf Add test for current token validation 2025-08-13 15:02:09 +10:00
Maikel Linke
cfeafbfc51 Update API docs with latest version 2025-08-13 15:02:08 +10:00
Maikel Linke
05b00f16ad Move config option to a better place 2025-08-12 20:24:16 +10:00
Maikel Linke
78fdaa68c8 Update config files with Rails 7.1 templates 2025-08-12 20:24:16 +10:00
Maikel Linke
e8813833fa Add Rails 7.1 framework defaults template 2025-08-12 15:43:45 +10:00
Maikel Linke
a5f44cb9b2 Update inflection config to Rails 7.0 template 2025-08-12 12:49:06 +10:00
Maikel Linke
97d21d8cbe Update parameter filtering to Rails 7.0 template 2025-08-12 12:45:48 +10:00
Maikel Linke
7afdd13b64 Update CSP config with Rails 7.0 template 2025-08-12 12:41:24 +10:00
Maikel Linke
54c446f0a3 Update asset config to Rails 7.0 templates 2025-08-12 12:30:30 +10:00
Maikel Linke
4454c90575 Update test config with Rails 7.0 template 2025-08-12 12:22:23 +10:00
Maikel Linke
dd3a61acdf Update production config with Rails 7.0 default 2025-08-12 12:10:22 +10:00
Maikel Linke
6d8ddd1eda Update development config with Rails 7.0 defaults 2025-08-12 12:10:19 +10:00
Maikel Linke
b8e8ab15d1 Update environment config with Rails 7.0 default 2025-08-12 11:06:33 +10:00
Maikel Linke
bf1d2f3620 Update boot config from Rails 7.0 template 2025-08-12 10:59:46 +10:00
Maikel Linke
43026ddc6a Update application config with Rails 7.0 defaults 2025-08-12 10:56:34 +10:00
Maikel Linke
18b83d2423 Add Rails 7.0 framework defaults templates 2025-08-12 10:42:37 +10:00
Gareth
3750898c44 Looks like db:prepare never fully ran and that's why it did not work. The issue seems to be using foreman with web, webpack, and sidekiq in the same script. Though not dependent on each other, the build order or port assignment was causing web to exit early upon build 2025-08-06 15:21:30 -04:00
Gareth
d34f8900d7 divided foreman queued services into 3 containers. Web was exiting seemingly at random and seems to be a conflict between web, web-pack, and sidekiq being run through foreman. The division into 3 dev containers has been very consistent in building the project correctly 2025-08-06 15:05:45 -04:00
Gareth
addf36a304 dummy commit for docker token check 2025-07-30 20:44:05 -04:00
Gareth
6a912b7d8c Added cmake dep to dockerfile and added script for db:schema:load that runs only if the schema is different than the latest migration 2025-07-30 20:12:53 -04:00
cyrillefr
8011449ce7 Adding a spec with one single tag
- need to add ids to ru the spec
2025-07-14 18:15:01 +02:00
cyrillefr
be0894653a Fixes Save button does not enable when removing only tag in OC 2025-06-30 12:41:41 +02:00
131 changed files with 1860 additions and 628 deletions

View File

@@ -2,10 +2,17 @@
# frozen_string_literal: true
SimpleCov.start 'rails' do
# The rails profile contains some filters already:
#
# - "/test/"
# - "/features/"
# - "/spec/"
# - "/autotest/"
# - /^\/config\//
# - /^\/db\//
add_filter '/bin/'
add_filter '/config/'
add_filter '/config/' # to include engine config
add_filter '/script'
add_filter '/db'
formatter SimpleCov::Formatter::SimpleFormatter
end

View File

@@ -1,4 +1,9 @@
#!/bin/env ruby
# frozen_string_literal: true
-c master
--compare master
# This shouldn't be needed in undercover > 0.7.4
#
# * https://github.com/grodowski/undercover/issues/233
--exclude-files "bin/*,db/*,config/*,spec/*,engines/*/config/*,engines/*/spec/*"

View File

@@ -2,7 +2,9 @@ FROM ruby:3.1.4-alpine3.19 AS base
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
TZ=Europe/London \
RAILS_ROOT=/usr/src/app
RAILS_ROOT=/usr/src/app \
BUNDLE_PATH=/bundles \
BUNDLE_APP_CONFIG=/bundles
RUN apk --no-cache upgrade && \
apk add --no-cache tzdata postgresql-client imagemagick imagemagick-jpeg && \
apk add --no-cache --virtual wkhtmltopdf
@@ -14,7 +16,7 @@ FROM base AS development-base
RUN apk add --no-cache --virtual .build-deps \
build-base postgresql-dev git nodejs yarn && \
apk add --no-cache --virtual .dev-utils \
bash curl less vim chromium-chromedriver zlib-dev openssl-dev \
bash curl less vim chromium-chromedriver zlib-dev openssl-dev cmake\
readline-dev yaml-dev sqlite-dev libxml2-dev libxslt-dev libffi-dev vips-dev && \
curl -o /usr/local/bin/wait-for-it https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \
chmod +x /usr/local/bin/wait-for-it

View File

@@ -25,7 +25,8 @@ RUN apt-get update && apt-get install -y \
libjemalloc-dev \
libssl-dev \
ca-certificates \
gnupg
gnupg \
cmake
# Setup ENV variables
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:/usr/local/src/nodenv/shims:/usr/local/src/nodenv/bin:$PATH

View File

@@ -167,7 +167,6 @@ group :test, :development do
gem 'rswag'
gem 'shoulda-matchers'
gem 'stimulus_reflex_testing', github: "podia/stimulus_reflex_testing", branch: :main
gem 'timecop'
end
group :test do

View File

@@ -575,7 +575,7 @@ GEM
railties (>= 4.2)
raabro (1.4.0)
racc (1.8.1)
rack (2.2.14)
rack (2.2.18)
rack-mini-profiler (2.3.4)
rack (>= 1.2.0)
rack-oauth2 (2.2.1)
@@ -842,7 +842,6 @@ GEM
thor (1.4.0)
thread-local (1.1.0)
tilt (2.3.0)
timecop (0.9.10)
timeout (0.4.3)
ttfunk (1.8.0)
bigdecimal (~> 3.1)
@@ -912,7 +911,7 @@ GEM
chronic (>= 0.6.3)
wicked_pdf (2.8.1)
activesupport
wkhtmltopdf-binary (0.12.6.7)
wkhtmltopdf-binary (0.12.6.10)
xml-simple (1.1.8)
xpath (3.2.0)
nokogiri (~> 1.8)
@@ -1049,7 +1048,6 @@ DEPENDENCIES
stimulus_reflex_testing!
stringex (~> 2.8.5)
stripe
timecop
turbo-rails
turbo_power
undercover

View File

@@ -15,4 +15,4 @@ angular.module("admin.paymentMethods").controller "StripeController", ($scope, $
permalink = shops.filter((shop) ->
shop.id == $scope.paymentMethod.preferred_enterprise_id
)[0].permalink
"/admin/enterprises/#{permalink}/edit#/payment_methods"
"/admin/enterprises/#{permalink}/edit#/payment_methods_panel"

View File

@@ -1,11 +0,0 @@
angular.module('Darkswarm').directive "darkerBackground", ->
restrict: "A"
link: (scope, elm, attr)->
toggleClass = (value) ->
elm.closest('.page-view').toggleClass("with-darker-background", value)
toggleClass(true)
# if an OrderCycle is selected, disable darker background
scope.$watch 'order_cycle.order_cycle_id', (newvalue, oldvalue) ->
toggleClass(false) if newvalue

View File

@@ -1,14 +0,0 @@
# Allows disabling of link buttons via disabled attribute.
# This is normally ignored, ie the link appears disabled but is still clickable.
angular.module('Darkswarm').directive "disableDynamically", ->
restrict: 'A'
link: (scope, element, attrs) ->
element.on 'click', (e) ->
if attrs.disabled
e.preventDefault()
return
scope.$on "$destroy", ->
element.off("click")

View File

@@ -1,7 +0,0 @@
angular.module('Darkswarm').directive "ofnInlineAlert", ->
restrict: 'A'
scope: true
link: (scope, elem, attrs) ->
scope.visible = true
scope.close = ->
scope.visible = false

View File

@@ -1,21 +0,0 @@
angular.module('Darkswarm').directive "ofnPageAlert", ($timeout) ->
restrict: 'A'
scope: true
link: (scope, elem, attrs) ->
moveSelectors = [".off-canvas-wrap .inner-wrap",
".off-canvas-wrap .inner-wrap .fixed",
".off-canvas-fixed .top-bar",
".off-canvas-fixed ofn-flash",
".off-canvas-fixed nav.tab-bar",
".off-canvas-fixed .page-alert"]
container_elems = $(moveSelectors.join(", "))
# Wait a moment after page load before showing the alert. Otherwise we often miss the
# start of the animation.
$timeout ->
container_elems.addClass("move-up")
, 1000
scope.close = ->
container_elems.removeClass("move-up")

View File

@@ -3,4 +3,4 @@
%span.text-normal
{{ 'admin.tags' | t }}
%br
%tags-with-translation.fullwidth{ object: 'object' }
%tags-with-translation.fullwidth{ object: 'object', form: 'order_cycle_form', id: 'tags_with_translation'}

View File

@@ -1,4 +1,5 @@
// This controller will be called "example-component--example", ie "component-subdirectory--js-file-name"
// This controller will be called "example", ie "js-file-name" minus the "_controller.js"
// see controller/index.js for more info
import { Controller } from "stimulus";
export default class extends Controller {}

View File

@@ -1,19 +1,19 @@
%div{ "data-controller": "tag-list-input-component--tag-list-input" }
%div{ "data-controller": "tag-list-input" }
.tags-input
.tags
- # We use display:none instead of hidden field, so changes to the value can be picked up by the bulkFormController
= f.text_field method.to_sym, value: tags.join(","), "data-tag-list-input-component--tag-list-input-target": "tagList", "style": "display: none"
%ul.tag-list{"data-tag-list-input-component--tag-list-input-target": "list"}
%template{"data-tag-list-input-component--tag-list-input-target": "template"}
= f.text_field method.to_sym, value: tags.join(","), "data-tag-list-input-target": "tagList", "style": "display: none"
%ul.tag-list{"data-tag-list-input-target": "list"}
%template{"data-tag-list-input-target": "template"}
%li.tag-item
.tag-template
%span
%a.remove-button{ "data-action": "click->tag-list-input-component--tag-list-input#removeTag" }
%a.remove-button{ "data-action": "click->tag-list-input#removeTag" }
×
- tags.each do |tag|
%li.tag-item
.tag-template
%span=tag
%a.remove-button{ "data-action": "click->tag-list-input-component--tag-list-input#removeTag" }
%a.remove-button{ "data-action": "click->tag-list-input#removeTag" }
×
= text_field_tag "variant_add_tag_#{f.object.id}".to_sym, nil, class: "input", placeholder: placeholder, "data-action": "keydown.enter->tag-list-input-component--tag-list-input#addTag keyup->tag-list-input-component--tag-list-input#filterInput", "data-tag-list-input-component--tag-list-input-target": "newTag", **aria_label_option
= text_field_tag "variant_add_tag_#{f.object.id}".to_sym, nil, class: "input", placeholder: placeholder, "data-action": "keydown.enter->tag-list-input#addTag keyup->tag-list-input#filterInput", "data-tag-list-input-target": "newTag", **aria_label_option

View File

@@ -1,6 +0,0 @@
# frozen_string_literal: true
module VerticalEllipsisMenu
class Component < ViewComponent::Base
end
end

View File

@@ -0,0 +1,4 @@
# frozen_string_literal: true
class VerticalEllipsisMenuComponent < ViewComponent::Base
end

View File

@@ -1,4 +1,4 @@
.vertical-ellipsis-menu{ "data-controller": "vertical-ellipsis-menu--component" }
%i.fa.fa-ellipsis-v{ "data-action": "click->vertical-ellipsis-menu--component#toggle" }
.vertical-ellipsis-menu-content{ "data-vertical-ellipsis-menu--component-target": "content" }
.vertical-ellipsis-menu{ "data-controller": "vertical-ellipsis-menu" }
%i.fa.fa-ellipsis-v{ "data-action": "click->vertical-ellipsis-menu#toggle" }
.vertical-ellipsis-menu-content{ "data-vertical-ellipsis-menu-target": "content" }
= content

View File

@@ -123,6 +123,13 @@ module Admin
@page = params[:page].presence || 1
@per_page = params[:per_page].presence || 15
@q = params.permit(q: {})[:q] || { s: 'name asc' }
# Transform on_hand sorting to include backorderable_priority (on-demand) for proper ordering
if @q[:s] == 'on_hand asc'
@q[:s] = ['backorderable_priority asc', @q[:s]]
elsif @q[:s] == 'on_hand desc'
@q[:s] = ['backorderable_priority desc', @q[:s]]
end
end
def producers
@@ -155,8 +162,27 @@ module Admin
product_query = OpenFoodNetwork::Permissions.new(spree_current_user)
.editable_products.merge(product_scope_with_includes).ransack(ransack_query).result
@pagy, @products = pagy(product_query.order(:name), limit: @per_page, page: @page,
size: [1, 2, 2, 1])
# Postgres requires ORDER BY expressions to appear in the SELECT list when using DISTINCT.
# When the current ransack sort uses the computed stock columns, include them in the select
# so the generated COUNT/DISTINCT query is valid.
sort_columns = Array(@q && @q[:s]).flatten
if sort_columns.any? { |s|
s.to_s.include?('on_hand') || s.to_s.include?('backorderable_priority')
}
product_query = product_query.select(
Arel.sql('spree_products.*'),
Spree::Product.backorderable_priority_sql,
Spree::Product.on_hand_sql
)
end
@pagy, @products = pagy(
product_query.order(:name),
limit: @per_page,
page: @page,
size: [1, 2, 2, 1]
)
end
def product_scope

View File

@@ -71,6 +71,11 @@ module Admin
"#{enterprise_attachment_removal_panel}_panel"
end
def enterprise_sells_options
scope = "admin.enterprises.admin_index.sells_options"
Enterprise::SELLS.map { |s| [I18n.t(s, scope:), s] }
end
private
def build_enterprise_side_menu_items(is_shop:, show_options: ) # rubocop:disable Metrics/MethodLength

View File

@@ -1,6 +1,29 @@
# frozen_string_literal: true
module LinkHelper
def link_to_or_disabled(name = nil, options = nil, html_options = nil, &block)
html_options, options, name = options, name, block if block_given?
html_options ||= {}
if !!html_options.delete(:disabled)
# https://www.scottohara.me/blog/2021/05/28/disabled-links.html
html_options.merge!(
'aria-disabled': true,
class: (html_options[:class].to_s.split + ["disabled"]).uniq.join(" "),
role: "link"
)
if block_given?
content_tag("a", name, **html_options, &block)
else
content_tag("a", name, **html_options)
end
elsif block_given?
link_to options, html_options, &block
else
link_to name, options, html_options
end
end
def link_to_service(baseurl, name, html_options = {}, &)
return if name.blank?

View File

@@ -62,6 +62,12 @@ module ShopHelper
true
end
def shop_tab_class(tab)
return unless (tab == "home" && show_home_tab?) || current_order(false)&.order_cycle.nil?
"with-darker-background"
end
private
def show_groups_tabs?

View File

@@ -9,6 +9,7 @@ class ApplicationRecord < ActiveRecord::Base
include ArelHelpers::JoinAssociation
self.abstract_class = true
self.include_root_in_json = true
def self.image_service
ENV["S3_BUCKET"].present? ? :amazon_public : :local

View File

@@ -0,0 +1,35 @@
# frozen_string_literal: true
module ProductSortByStocks
extend ActiveSupport::Concern
included do
@on_hand_sql = Arel.sql("(
SELECT COALESCE(SUM(si.count_on_hand), 0)
FROM spree_variants v
JOIN spree_stock_items si ON si.variant_id = v.id
WHERE v.product_id = spree_products.id
GROUP BY v.product_id
)")
@backorderable_priority_sql = Arel.sql("(
SELECT BOOL_OR(si.backorderable)
FROM spree_variants v
JOIN spree_stock_items si ON si.variant_id = v.id
WHERE v.product_id = spree_products.id
GROUP BY v.product_id
)")
class << self
attr_reader :on_hand_sql, :backorderable_priority_sql
end
ransacker :on_hand do
@on_hand_sql
end
ransacker :backorderable_priority do
@backorderable_priority_sql
end
end
end

View File

@@ -75,6 +75,7 @@ class Enterprise < ApplicationRecord
has_one :stripe_account, dependent: :destroy
has_many :vouchers, dependent: :restrict_with_exception
has_many :connected_apps, dependent: :destroy
has_many :dfc_permissions, dependent: :destroy
has_one :custom_tab, dependent: :destroy
delegate :latitude, :longitude, :city, :state_name, to: :address

View File

@@ -19,6 +19,7 @@ require 'open_food_network/property_merge'
module Spree
class Product < ApplicationRecord
include LogDestroyPerformer
include ProductSortByStocks
self.belongs_to_required_by_default = false
# These columns have been moved to variant. Currently this is only for documentation purposes,
@@ -30,7 +31,7 @@ module Spree
acts_as_paranoid
searchable_attributes :meta_keywords, :sku
searchable_attributes :meta_keywords, :sku, :on_hand, :backorderable_priority
searchable_associations :properties, :variants
searchable_scopes :active, :with_properties

View File

@@ -28,7 +28,7 @@
= enterprise_form.check_box :is_primary_producer
= t('.producer')
- if spree_current_user.admin?
%td= enterprise_form.select :sells, Enterprise::SELLS, {}, class: 'select2 fullwidth'
%td= enterprise_form.select :sells, enterprise_sells_options, {}, class: 'select2 fullwidth'
%td= enterprise_form.check_box :visible, {}, 'public', 'hidden'
- if spree_current_user.admin?
%td= enterprise_form.select :owner_id, enterprise.users.map{ |e| [ e.email, e.id ] }, {}, class: "select2 fullwidth"

View File

@@ -7,7 +7,7 @@
%td.receival-details
= text_field_tag 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', '', 'id' => 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', 'placeholder' => t('.receival_instructions_placeholder'), 'ng-model' => 'exchange.receival_instructions'
- if type == 'distributor'
%td.tags.panel-toggle.text-center{ name: "tags", "ng-if": 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' }
%td.tags.panel-toggle.text-center{ name: "tags", id: "tags", "ng-if": 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' }
{{ exchange.tags.length }}
%td.collection-details
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', '', 'ng-init' => 'setPickupTimeFieldDirty($index, exchange.pickup_time)', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', 'required' => 'required', 'placeholder' => t('.pickup_time_placeholder'), 'ng-model' => 'exchange.pickup_time', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator', 'maxlength' => 35
@@ -36,5 +36,5 @@
- if type == 'distributor'
%tr.panel-row{ object: "exchange",
panels: "{products: 'exchange_products_distributed', tags: 'exchange_tags'}",
locals: "$index,exchangeTotalVariants,order_cycle,exchange,enterprises,setExchangeVariants,incomingExchangeVariantsFor,variantSuppliedToOrderCycle,initializeExchangeProductsPanel,loadMoreExchangeProducts,loadAllExchangeProducts,productsLoading",
locals: "$index,exchangeTotalVariants,order_cycle,exchange,enterprises,setExchangeVariants,incomingExchangeVariantsFor,variantSuppliedToOrderCycle,initializeExchangeProductsPanel,loadMoreExchangeProducts,loadAllExchangeProducts,productsLoading,order_cycle_form",
colspan: 5 }

View File

@@ -24,7 +24,7 @@
%td.col-inherits_properties.align-left
.content= product.inherits_properties ? 'YES' : 'NO' #TODO: consider using https://github.com/RST-J/human_attribute_values, else use I18n.t (also below)
%td.align-right
= render(VerticalEllipsisMenu::Component.new) do
= render(VerticalEllipsisMenuComponent.new) do
= link_to t('admin.products_page.actions.edit'), edit_admin_product_path(product), 'data-turbo': false
= link_to t('admin.products_page.actions.clone'), admin_clone_product_path(product), 'data-turbo-method': :post
%a{ "data-controller": "modal-link", "data-action": "click->modal-link#setModalDataSetOnConfirm click->modal-link#open",

View File

@@ -59,7 +59,8 @@
%th.align-left.col-unit_scale.with-input= t('admin.products_page.columns.unit_scale')
%th.align-left.col-unit.with-input= t('admin.products_page.columns.unit')
%th.align-left.col-price.with-input= t('admin.products_page.columns.price')
%th.align-left.col-on_hand.with-input= t('admin.products_page.columns.on_hand')
= render partial: 'spree/admin/shared/stimulus_sortable_header',
locals: { column: :on_hand, sorted: params.dig(:q, :s), default: 'name asc' }
%th.align-left.col-producer= t('admin.products_page.columns.producer')
%th.align-left.col-category= t('admin.products_page.columns.category')
%th.align-left.col-tax_category= t('admin.products_page.columns.tax_category')

View File

@@ -84,7 +84,7 @@
%td.col-inherits_properties.align-left
-# empty
%td.align-right
= render(VerticalEllipsisMenu::Component.new) do
= render(VerticalEllipsisMenuComponent.new) do
- if variant.persisted?
= link_to t('admin.products_page.actions.edit'), edit_admin_product_variant_path(variant.product, variant)
- if variant.product.variants.size > 1

View File

@@ -11,7 +11,7 @@
= @order.shipping_method.name
%em.fees= payment_or_shipping_price(@order.shipping_method, @order)
.two-columns
= render "delivery_details" if @order.shipping_method.delivery? || feature?(:hub_address)
= render "delivery_details" if @order.shipping_method.delivery?
- if @order.shipping_method.description.present?
%div
.summary-subtitle

View File

@@ -13,10 +13,10 @@
%form{ name: 'about', novalidate: true, "ng-controller": "RegistrationFormCtrl", "ng-submit": "selectIfValid('images', about)" }
.row
.small-12.columns
.alert-box.info{ "ofn-inline-alert": true, "ng-show": "visible" }
.alert-box.info{ "data-controller": "toggle-control", "data-toggle-control-target": "content", style: "display: block;" }
%h6{ "ng-bind" => "'registration.steps.about.success' | t:{enterprise: enterprise.name}" }
%span= t(".registration_exit_message")
%a.close{ "ng-click": "close()" } &times;
%a.close{ "data-action": "toggle-control#toggleDisplay" } &times;
.small-12.large-8.columns
.row

View File

@@ -1,4 +1,4 @@
.text-center.page-alert.fixed{ "ofn-page-alert" => true }
.text-center.page-alert.fixed{ "data-controller" => "page-alert" }
.alert-box
= render 'shared/page_alert'
%a.close{ "ng-click": "close()" } &times;
%a.close{ "data-action" => "page-alert#close" } &times;

View File

@@ -1,7 +1,7 @@
.closed-shop-header
.row
.small-12.columns
.content{ "darker-background" => true }
.content
%h4
.warning-sign
.rectangle

View File

@@ -1,4 +1,4 @@
.content{ "darker-background" => true }
.content
.row.footer-pad
.small-12.columns{ "data-controller": "login-modal" }
%strong

View File

@@ -1,4 +1,4 @@
.content.footer-pad{ "darker-background" => true, "ng-show" => "order_cycle.order_cycle_id == null" }
.content.footer-pad{ "ng-show" => "order_cycle.order_cycle_id == null" }
.row
.small-12.columns
.select-oc-message

View File

@@ -10,8 +10,8 @@
.columns.large-4.show-for-large-up
= render partial: "shopping_shared/order_cycles"
- shop_tabs.each do |tab|
%div{id: "#{tab[:name]}_panel", "data-tabs-and-panels-target": "panel #{'default' if tab[:default]} #{'shop' if tab[:shop]}" }
.page-view
%div{id: "#{tab[:name]}_panel", "data-tabs-and-panels-target": "panel #{'default' if tab[:default]} #{'shop' if tab[:shop]}" }
.page-view{ class: shop_tab_class(tab[:name]) }
- if tab[:custom]
= render "shopping_shared/tabs/custom"
- else

View File

@@ -1,5 +1,3 @@
.row.links
%a.continue-shopping.button.secondary{href: current_shop_products_path, "ng-disabled" => "#{@insufficient_stock_lines.any?}", "disable-dynamically" => true}
= t :orders_edit_continue
%a#checkout-link.button.primary.right{href: main_app.checkout_path, "ng-disabled" => "#{@insufficient_stock_lines.any?}", "disable-dynamically" => true}
= t :orders_edit_checkout
= link_to_or_disabled t(:orders_edit_continue), current_shop_products_path, class: "continue-shopping button secondary", disabled: @insufficient_stock_lines.any?
= link_to_or_disabled t(:orders_edit_checkout), main_app.checkout_path, class: "button primary right", disabled: @insufficient_stock_lines.any?, id: "checkout-link"

View File

@@ -42,9 +42,9 @@
.row
.columns.large-12
- if order.changes_allowed?
.alert-box.order-summary{ "ofn-inline-alert" => true, "ng-show" => "visible" }
.alert-box.order-summary{ "data-controller": "toggle-control", "data-toggle-control-target": "content", style: "display: block;" }
= t(:orders_changeable_orders_alert_html, oc_close: l(order.order_cycle.orders_close_at, format: "%b %d, %Y %H:%M"))
%a.close{ "ng-click" => "close()" } &times;
%a.close{ "data-action": "toggle-control#toggleDisplay" } &times;
= form_for order, url: main_app.order_path(order), html: {id: 'update-order', name: 'update_order_form' } do |order_form|
- if order.changes_allowed?

View File

@@ -6,14 +6,37 @@ import StimulusReflex from "stimulus_reflex";
import consumer from "../channels/consumer";
import controller from "../controllers/application_controller";
import CableReady from "cable_ready";
import RailsNestedForm from '@stimulus-components/rails-nested-form/dist/stimulus-rails-nested-form.umd.js' // the default module entry point is broken
import RailsNestedForm from "@stimulus-components/rails-nested-form/dist/stimulus-rails-nested-form.umd.js"; // the default module entry point is broken
const application = Application.start();
const context = require.context("controllers", true, /_controller\.js$/);
const contextComponents = require.context("../../components", true, /_controller\.js$/);
application.load(definitionsFromContext(context));
application.load(definitionsFromContext(context).concat(definitionsFromContext(contextComponents)));
application.register('nested-form', RailsNestedForm);
// Load component controller, but generate a shorter controller name than "definitionsFromContext" would
// - for controller in a component subdirectory, get rid of the component folder and use
// the controller name, ie:
// ./tag_rule_group_form_component/tag_rule_group_form_controller.js -> tag-rule-group-form
// - for controller that don't match the pattern above, replace "_" by "-" and "/" by "--", ie:
// ./vertical_ellipsis_menu/component_controller.js -> vertical-ellipsis-menu--component
//
const contextComponents = require.context("../../components", true, /_controller\.js$/);
contextComponents.keys().forEach((path) => {
const module = contextComponents(path);
// Check whether a module has the default export defined
if (!module.default) return;
const identifier = path
.replace(/^\.\//, "")
.replace(/^\w+_component\//, "")
.replace(/_controller\.js$/, "")
.replace(/\//g, "--")
.replace(/_/g, "-");
application.register(identifier, module.default);
});
application.register("nested-form", RailsNestedForm);
application.consumer = consumer;
StimulusReflex.initialize(application, { controller, isolate: true });

View File

@@ -0,0 +1,34 @@
import { Controller } from "stimulus";
export default class extends Controller {
moveSelectors = [".off-canvas-wrap .inner-wrap",
".off-canvas-wrap .inner-wrap .fixed",
".off-canvas-fixed .top-bar",
".off-canvas-fixed ofn-flash",
".off-canvas-fixed nav.tab-bar",
".off-canvas-fixed .page-alert"];
connect() {
// Wait a moment after page load before showing the alert. Otherwise we often miss the
// start of the animation.
setTimeout(this.#show, 1000);
}
close() {
this.#moveElements().forEach((element) => {
element.classList.remove("move-up");
});
}
// private
#moveElements() {
return document.querySelectorAll(this.moveSelectors.join(","));
}
#show = () => {
this.#moveElements().forEach((element) => {
element.classList.add("move-up");
});
};
}

View File

@@ -127,7 +127,7 @@
@import "components/tom_select"; // admin_v3
@import "app/components/modal_component/modal_component";
@import "app/components/vertical_ellipsis_menu/component"; // admin_v3 and only V3
@import "app/components/vertical_ellipsis_menu_component/vertical_ellipsis_menu_component"; // admin_v3 and only V3
@import "app/components/tag_list_input_component/tag_list_input_component";
@import "app/webpacker/css/admin/trix.scss";

View File

@@ -182,6 +182,10 @@ a.button {
text-decoration: none;
}
a[aria-disabled] {
pointer-events: none;
}
.button.disruptive::before {
margin-right: 3px;

View File

@@ -1,5 +1,7 @@
.darkswarm {
products {
background-color: white;
product {
@import "shop_partials/shop-product-rows";
}

View File

@@ -5,20 +5,36 @@ services:
environment:
POSTGRES_PASSWORD: f00d
POSTGRES_USER: ofn
POSTGRES_DB: open_food_network_dev
ports:
- 5432:5432
volumes:
- 'postgres:/var/lib/postgresql/data'
healthcheck:
test: ["CMD-SHELL", "PGPASSWORD=$$POSTGRES_PASSWORD pg_isready -q -h 127.0.0.1 -p 5432 -U $$POSTGRES_USER || exit 1"]
interval: 5s
timeout: 10s
retries: 10
redis:
image: redis
bundler:
build: .
# Runs once: installs gems into /bundles, writes a checksum sentinel, then exits
command: >
sh -lc 'bundle install --jobs 4 --retry 3 --quiet;
sha256sum Gemfile.lock > /bundles/.Gemfile.lock.sha'
volumes:
- .:/usr/src/app
- gems:/bundles
restart: "no"
web:
tty: true
stdin_open: true
build: .
ports:
- 3000:3000
- 3035:3035
volumes:
- .:/usr/src/app
- gems:/bundles
@@ -26,20 +42,69 @@ services:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
depends_on:
- db
- redis
db:
condition: service_healthy
redis:
condition: service_started
webpack:
condition: service_started
environment:
DOCKER: true
DEV_CACHING: true
OFN_DB_HOST: db
OFN_REDIS_URL: redis://redis/
OFN_REDIS_JOBS_URL: redis://redis
OFN_REDIS_TEST_URL: redis://redis/3
WEBPACKER_DEV_SERVER_HOST: webpack
WEBPACKER_DEV_SERVER_PORT: 3035
WEBPACKER_DEV_SERVER_PUBLIC: localhost:3035
command: >
bash -c "rm -f tmp/pids/server.pid &&
(bundle check || bundle install) &&
bundle exec rake db:create &&
yarn install &&
bundle exec foreman start -f Procfile.docker"
sh -lc 'rm -f tmp/pids/server.pid;
until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done;
bundle exec rails db:prepare &&
yarn install &&
exec bundle exec rails s -b 0.0.0.0 -p 3000'
sidekiq:
build: .
command: >
sh -lc 'until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done;
exec bundle exec sidekiq'
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
volumes:
- .:/usr/src/app
- gems:/bundles
environment:
DOCKER: true
DEV_CACHING: true
OFN_DB_HOST: db
OFN_REDIS_URL: redis://redis/
OFN_REDIS_JOBS_URL: redis://redis
OFN_REDIS_TEST_URL: redis://redis/3
webpack:
build: .
command: >
sh -lc 'until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done;
exec ./bin/webpack-dev-server'
ports:
- "3035:3035"
volumes:
- .:/usr/src/app
- gems:/bundles
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:3035/webpack-dev-server >/dev/null || wget -qO- http://localhost:3035/sockjs-node/info >/dev/null"]
interval: 5s
timeout: 3s
retries: 30
environment:
WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
volumes:
gems:
postgres:

View File

@@ -1,24 +1,19 @@
require_relative 'boot'
require_relative "boot"
require "rails"
[
"active_record/railtie",
"active_storage/engine",
"action_controller/railtie",
"action_view/railtie",
"action_mailer/railtie",
"active_job/railtie",
"action_cable/engine",
# "action_mailbox/engine",
# "action_text/engine",
"rails/test_unit/railtie",
"sprockets/railtie" # Disable this after migrating to Webpacker
].each do |railtie|
begin
require railtie
rescue LoadError
end
end
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
# require "action_mailbox/engine"
# require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
require "rails/test_unit/railtie"
require "sprockets/railtie" # Disable this after migrating to Webpacker
require_relative "../lib/open_food_network/i18n_config"
require_relative '../lib/spree/core/environment'
@@ -26,15 +21,34 @@ require_relative '../lib/spree/core/mail_interceptor'
require_relative "../lib/i18n_digests"
require_relative "../lib/git_utils"
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups(:assets => %w(development test)))
module Openfoodnetwork
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.1
config.action_view.form_with_generates_remote_forms = false
config.active_record.cache_versioning = false
config.active_record.has_many_inversing = false
config.active_record.yaml_column_permitted_classes = [BigDecimal, Symbol, Time,
ActiveSupport::TimeWithZone,
ActiveSupport::TimeZone]
# Please, add to the `ignore` list any other `lib` subdirectories that do
# not contain `.rb` files, or that should not be reloaded or eager loaded.
# Common ones are `templates`, `generators`, or `middleware`, for example.
# config.autoload_lib(ignore: %w(assets tasks))
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
# in config/environments, which are processed later.
#
config.time_zone = ENV["TIMEZONE"]
# config.eager_load_paths << Rails.root.join("extras")
# Store a description of the current version
config.x.git_version = GitUtils::git_version
@@ -71,16 +85,6 @@ module Openfoodnetwork
end
end
# filter sensitive information during logging
initializer "spree.params.filter" do |app|
app.config.filter_parameters += [
:password,
:password_confirmation,
:number,
:verification_value
]
end
initializer "load_spree_calculators" do |app|
# Register Spree calculators
Rails.application.reloader.to_prepare do
@@ -161,10 +165,6 @@ module Openfoodnetwork
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
config.time_zone = ENV["TIMEZONE"]
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = OpenFoodNetwork::I18nConfig.default_locale
@@ -184,38 +184,14 @@ module Openfoodnetwork
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.2'
config.assets.initialize_on_precompile = true
# Unset X-Frame-Options header for embedded pages.
config.action_dispatch.default_headers.except! "X-Frame-Options"
# css and js files other than application.* are not precompiled by default
# Instead, they must be explicitly included below
# http://stackoverflow.com/questions/8012434/what-is-the-purpose-of-config-assets-precompile
config.assets.initialize_on_precompile = true
config.assets.precompile += ['admin/*.js', 'admin/**/*.js', 'admin_minimal.js']
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.
config.active_record.verbose_query_logs = ENV.fetch("VERBOSE_QUERY_LOGS", false)
# Apply framework defaults. New recommended defaults are successively added with each Rails version and
# include the defaults from previous versions. For more info see:
# https://guides.rubyonrails.org/configuring.html#results-of-config-load-defaults
config.load_defaults 6.1
config.action_view.form_with_generates_remote_forms = false
config.active_record.cache_versioning = false
config.active_record.has_many_inversing = false
config.active_record.yaml_column_permitted_classes = [BigDecimal, Symbol, Time,
ActiveSupport::TimeWithZone,
ActiveSupport::TimeZone]
config.active_support.escape_html_entities_in_json = true
config.active_job.queue_adapter = :sidekiq

View File

@@ -1,7 +1,4 @@
require 'rubygems'
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
require 'bootsnap/setup'
require "bundler/setup" # Set up gems listed in the Gemfile.
require "bootsnap/setup" # Speed up boot time by caching expensive operations.

View File

@@ -1,7 +1,5 @@
# Load the rails application
require_relative 'application'
# Load the Rails application.
require_relative "application"
# Initialize the rails application
Openfoodnetwork::Application.initialize!
ActiveRecord::Base.include_root_in_json = true
# Initialize the Rails application.
Rails.application.initialize!

View File

@@ -1,40 +1,87 @@
Openfoodnetwork::Application.configure do
config.action_controller.default_url_options = {host: "localhost", port: 3000}
# Settings specified here will take precedence over those in config/application.rb
#
require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# PROFILE switches several settings to a more "production-like" value
# for profiling and benchmarking the application locally. All changes you
# make to the app will require restart.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# In the development environment your application's code is reloaded any time
# it changes. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = !!ENV["PROFILE"]
config.action_controller.default_url_options = {host: "localhost", port: 3000}
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
# Enable server timing
config.server_timing = true
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
#
# To override this, set the appropriate locale in .env[.*] file.
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
config.log_level = ENV.fetch("DEV_LOG_LEVEL", :debug)
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join("tmp/caching-dev.txt").exist? || !ENV["PROFILE"] || !!ENV["DEV_CACHING"]
config.action_controller.perform_caching = true
config.action_controller.enable_fragment_cache_logging = true
# :file_store is used by default when no cache store is specifically configured.
if !!ENV["PROFILE"] || !!ENV["DEV_CACHING"]
config.cache_store = :redis_cache_store, {
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/1"),
expires_in: 90.minutes
}
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{2.days.to_i}"
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
config.eager_load = false
config.action_controller.default_url_options = {host: "localhost", port: 3000}
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = !!ENV["PROFILE"] || !!ENV["DEV_CACHING"]
# Store uploaded files on the local file system (see config/storage.yml for options).
# config.active_storage.service = :local
# Don't care if the mailer can't send
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.action_mailer.perform_caching = false
# Show emails using Letter Opener
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.default_url_options = { host: "localhost:3000" }
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Raise exceptions for disallowed deprecations.
config.active_support.disallowed_deprecation = :raise
# Tell Active Support which deprecation messages to disallow.
config.active_support.disallowed_deprecation_warnings = []
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true
# Highlight code that enqueued background job in logs.
config.active_job.verbose_enqueue_logs = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Do not compress assets
config.assets.compress = false
@@ -59,17 +106,17 @@ Openfoodnetwork::Application.configure do
# $ bundle exec rake assets:clean
config.assets.debug = !!ENV["DEBUG_ASSETS"]
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
#
# To override this, set the appropriate locale in .env[.*] file.
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
# Raises error for missing translations.
# config.i18n.raise_on_missing_translations = true
config.i18n.fallbacks = [:en]
# Show emails using Letter Opener
config.action_mailer.delivery_method = :letter_opener
config.action_mailer.default_url_options = { host: "localhost:3000" }
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
config.log_level = ENV.fetch("DEV_LOG_LEVEL", :debug)
# Uncomment if you wish to allow Action Cable access from any origin.
# config.action_cable.disable_request_forgery_protection = true
# Raise error when a before_action's only/except options reference missing actions
# config.action_controller.raise_on_missing_callback_actions = true
end

View File

@@ -1,69 +1,113 @@
Openfoodnetwork::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.enable_reloading = false
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Code is not reloaded between requests
config.cache_classes = true
# Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true
# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
config.public_file_server.enabled = false
# Compress CSS using a preprocessor.
# config.assets.css_compressor = :sass
# Do not fall back to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.asset_host = "http://assets.example.com"
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true
# Defaults to Rails.root.join("public/assets")
# config.assets.manifest = YOUR_PATH
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
# Specifies the header that your server uses for sending files
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
# Store uploaded files on the local file system (see config/storage.yml for options).
# We set it in application.rb.
# config.active_storage.service = :local
# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
# config.action_cable.url = "wss://example.com/cable"
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]
config.action_cable.url = "#{ENV['OFN_URL']}/cable"
config.action_cable.allowed_request_origins = [/http:\/\/#{ENV['OFN_URL']}\/*/, /https:\/\/#{ENV['OFN_URL']}\/*/]
# Assume all access to the app is happening through a SSL-terminating reverse proxy.
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
# config.assume_ssl = true
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true
# Use https in email links
config.action_mailer.default_url_options = { protocol: 'https' }
# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new(STDOUT)
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
# Set log level (default is :debug in Rails 4)
config.log_level = :info
# Configure logging:
config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" }
# Prepend all log lines with the following tags.
config.log_tags = [:request_id]
# Use a different cache store in production
# "info" includes generic and useful information about system operation, but avoids logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
# want to log everything, set the level to "debug".
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
config.cache_store = :redis_cache_store, {
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6380/0"),
reconnect_attempts: 1
}
config.action_cable.url = "#{ENV['OFN_URL']}/cable"
config.action_cable.allowed_request_origins = [/http:\/\/#{ENV['OFN_URL']}\/*/, /https:\/\/#{ENV['OFN_URL']}\/*/]
# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "openfoodnetwork_production"
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
config.action_mailer.perform_caching = false
# Disable delivery errors, bad email addresses will be ignored
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable threaded mode
# config.threadsafe!
# Use https in email links
config.action_mailer.default_url_options = { protocol: 'https' }
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = [:en]
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Enable DNS rebinding protection and other `Host` header attacks.
# config.hosts = [
# "example.com", # Allow requests from example.com
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
# ]
# Skip DNS rebinding protection for the default health check endpoint.
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
end

View File

@@ -1,17 +1,38 @@
Openfoodnetwork::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
require "active_support/core_ext/integer/time"
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# While tests run files are not watched, reloading is not necessary.
config.enable_reloading = false
# StimulusReflex requires caching to be enabled.
config.cache_classes = false
# Eager loading loads your entire application. When running a single test locally,
# this is usually not necessary, and can slow down your test suite. However, it's
# recommended that you enable it in continuous integration systems to ensure eager
# loading is working properly before deploying your code.
# config.eager_load = ENV["CI"].present?
config.eager_load = false
# Configure static asset server for tests with Cache-Control for performance
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{1.hour.to_i}"
}
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# config.cache_store = :null_store
# Separate cache stores when running in parallel
config.cache_store = :redis_cache_store, {
@@ -20,40 +41,31 @@ Openfoodnetwork::Application.configure do
reconnect_attempts: 1
}
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Render exception templates for rescuable exceptions and raise for other exceptions.
config.action_dispatch.show_exceptions = :rescuable
# Raise exceptions instead of rendering exception templates
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = false
# Store uploaded files on the local file system in a temporary directory.
# config.active_storage.service = :test
config.action_mailer.perform_caching = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Tests should fail when translations are missing.
config.i18n.raise_on_missing_translations = true
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
# Tests assume English text on the site.
config.i18n.default_locale = "en"
config.i18n.available_locales = ['en', 'es', 'pt']
config.i18n.fallbacks = [:en]
I18n.locale = config.i18n.locale = config.i18n.default_locale
# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
# Print deprecation notices to the stderr
# Print deprecation notices to the stderr.
# config.active_support.deprecation = :stderr
# Raise exceptions for disallowed deprecations.
config.active_support.disallowed_deprecation = :raise
# Tell Active Support which deprecation messages to disallow.
config.active_support.disallowed_deprecation_warnings = []
# Fail tests on deprecated code unless it's a known case to solve.
Rails.application.deprecators.behavior = ->(message, callstack, deprecator) do
allowed_warnings = [
@@ -82,5 +94,20 @@ Openfoodnetwork::Application.configure do
end
end
# Raises error for missing translations.
config.i18n.raise_on_missing_translations = true
# Tests assume English text on the site.
config.i18n.default_locale = "en"
config.i18n.available_locales = ['en', 'es', 'pt']
config.i18n.fallbacks = [:en]
I18n.locale = config.i18n.locale = config.i18n.default_locale
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
# Raise error when a before_action's only/except options reference missing actions
# config.action_controller.raise_on_missing_callback_actions = true
config.active_job.queue_adapter = :test
end

View File

@@ -1 +1,24 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = "1.2"
# Add additional assets to the asset load path.
Rails.application.config.assets.paths << Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
# css and js files other than application.* are not precompiled by default
# Instead, they must be explicitly included below
# http://stackoverflow.com/questions/8012434/what-is-the-purpose-of-config-assets-precompile
Rails.application.config.assets.precompile += [
'admin/*.js', 'admin/**/*.js', 'admin_minimal.js',
'web/all.js',
'darkswarm/all.js',
'shared/*',
'mail.scss',
'*.jpg', '*.jpeg', '*.png', '*.gif' '*.svg',
]

View File

@@ -1,8 +1,8 @@
# Be sure to restart your server when you modify this file.
# Define an application-wide content security policy
# For further information see the following documentation
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
# Define an application-wide content security policy.
# See the Securing Rails Applications Guide for more information:
# https://guides.rubyonrails.org/security.html#content-security-policy-header
Rails.application.config.content_security_policy do |policy|
policy.default_src :self, :https
@@ -23,15 +23,11 @@ Rails.application.config.content_security_policy do |policy|
# Specify URI for violation reports
# policy.report_uri "/csp-violation-report-endpoint"
# Generate session nonces for permitted importmap, inline scripts, and inline styles.
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
# config.content_security_policy_nonce_directives = %w(script-src style-src)
# Report violations without enforcing the policy.
# config.content_security_policy_report_only = true
end
# If you are using UJS then enable automatic nonce generation
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
# Set the nonce only to specific directives
# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
# Rails.application.config.content_security_policy_report_only = true

View File

@@ -1,4 +1,12 @@
# frozen_string_literal: true
# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password, :vine_api_key, :vine_secret]
# Be sure to restart your server when you modify this file.
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
# Use this to limit dissemination of sensitive information.
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
Rails.application.config.filter_parameters += [
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn,
:number, :verification_value,
:vine_api_key, :vine_secret,
]

View File

@@ -1,13 +1,20 @@
# Be sure to restart your server when you modify this file.
# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
# inflect.plural /^(ox)$/i, '\1en'
# inflect.singular /^(ox)en/i, '\1'
# inflect.irregular 'person', 'people'
# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.plural /^(ox)$/i, "\\1en"
# inflect.singular /^(ox)en/i, "\\1"
# inflect.irregular "person", "people"
# inflect.uncountable %w( fish sheep )
# end
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
# inflect.acronym "RESTful"
# end
Rails.autoloaders.each do |autoloader|
autoloader.inflector.inflect(
"stripe_sca" => "StripeSCA"

View File

@@ -0,0 +1,143 @@
# Be sure to restart your server when you modify this file.
#
# This file eases your Rails 7.0 framework defaults upgrade.
#
# Uncomment each configuration one by one to switch to the new default.
# Once your application is ready to run with all new defaults, you can remove
# this file and set the `config.load_defaults` to `7.0`.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
# `button_to` view helper will render `<button>` element, regardless of whether
# or not the content is passed as the first argument or as a block.
# Rails.application.config.action_view.button_to_generates_button_tag = true
# `stylesheet_link_tag` view helper will not render the media attribute by default.
# Rails.application.config.action_view.apply_stylesheet_media_default = false
# Change the digest class for the key generators to `OpenSSL::Digest::SHA256`.
# Changing this default means invalidate all encrypted messages generated by
# your application and, all the encrypted cookies. Only change this after you
# rotated all the messages using the key rotator.
#
# See upgrading guide for more information on how to build a rotator.
# https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
# Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
# Change the digest class for ActiveSupport::Digest.
# Changing this default means that for example Etags change and
# various cache keys leading to cache invalidation.
# Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
# Don't override ActiveSupport::TimeWithZone.name and use the default Ruby
# implementation.
# Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true
# Calls `Rails.application.executor.wrap` around test cases.
# This makes test cases behave closer to an actual request or job.
# Several features that are normally disabled in test, such as Active Record query cache
# and asynchronous queries will then be enabled.
# Rails.application.config.active_support.executor_around_test_case = true
# Set both the `:open_timeout` and `:read_timeout` values for `:smtp` delivery method.
# Rails.application.config.action_mailer.smtp_timeout = 5
# The ActiveStorage video previewer will now use scene change detection to generate
# better preview images (rather than the previous default of using the first frame
# of the video).
# Rails.application.config.active_storage.video_preview_arguments =
# "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2"
# Automatically infer `inverse_of` for associations with a scope.
# Rails.application.config.active_record.automatic_scope_inversing = true
# Raise when running tests if fixtures contained foreign key violations
# Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true
# Disable partial inserts.
# This default means that all columns will be referenced in INSERT queries
# regardless of whether they have a default or not.
# Rails.application.config.active_record.partial_inserts = false
# Protect from open redirect attacks in `redirect_back_or_to` and `redirect_to`.
# Rails.application.config.action_controller.raise_on_open_redirects = true
# Change the variant processor for Active Storage.
# Changing this default means updating all places in your code that
# generate variants to use image processing macros and ruby-vips
# operations. See the upgrading guide for detail on the changes required.
# The `:mini_magick` option is not deprecated; it's fine to keep using it.
# Rails.application.config.active_storage.variant_processor = :vips
# Enable parameter wrapping for JSON.
# Previously this was set in an initializer. It's fine to keep using that initializer if you've customized it.
# To disable parameter wrapping entirely, set this config to `false`.
# Rails.application.config.action_controller.wrap_parameters_by_default = true
# Specifies whether generated namespaced UUIDs follow the RFC 4122 standard for namespace IDs provided as a
# `String` to `Digest::UUID.uuid_v3` or `Digest::UUID.uuid_v5` method calls.
#
# See https://guides.rubyonrails.org/configuring.html#config-active-support-use-rfc4122-namespaced-uuids for
# more information.
# Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true
# Change the default headers to disable browsers' flawed legacy XSS protection.
# Rails.application.config.action_dispatch.default_headers = {
# "X-Frame-Options" => "SAMEORIGIN",
# "X-XSS-Protection" => "0",
# "X-Content-Type-Options" => "nosniff",
# "X-Download-Options" => "noopen",
# "X-Permitted-Cross-Domain-Policies" => "none",
# "Referrer-Policy" => "strict-origin-when-cross-origin"
# }
# ** Please read carefully, this must be configured in config/application.rb **
# Change the format of the cache entry.
# Changing this default means that all new cache entries added to the cache
# will have a different format that is not supported by Rails 6.1 applications.
# Only change this value after your application is fully deployed to Rails 7.0
# and you have no plans to rollback.
# When you're ready to change format, add this to `config/application.rb` (NOT this file):
# config.active_support.cache_format_version = 7.0
# Cookie serializer: 2 options
#
# If you're upgrading and haven't set `cookies_serializer` previously, your cookie serializer
# is `:marshal`. The default for new apps is `:json`.
#
# Rails.application.config.action_dispatch.cookies_serializer = :json
#
#
# To migrate an existing application to the `:json` serializer, use the `:hybrid` option.
#
# Rails transparently deserializes existing (Marshal-serialized) cookies on read and
# re-writes them in the JSON format.
#
# It is fine to use `:hybrid` long term; you should do that until you're confident *all* your cookies
# have been converted to JSON. To keep using `:hybrid` long term, move this config to its own
# initializer or to `config/application.rb`.
#
# Rails.application.config.action_dispatch.cookies_serializer = :hybrid
#
#
# If your cookies can't yet be serialized to JSON, keep using `:marshal` for backward-compatibility.
#
# If you have configured the serializer elsewhere, you can remove this section of the file.
#
# See https://guides.rubyonrails.org/action_controller_overview.html#cookies for more information.
# Change the return value of `ActionDispatch::Request#content_type` to the Content-Type header without modification.
# Rails.application.config.action_dispatch.return_only_request_media_type_on_content_type = false
# Active Storage `has_many_attached` relationships will default to replacing the current collection instead of appending to it.
# Thus, to support submitting an empty collection, the `file_field` helper will render an hidden field `include_hidden` by default when `multiple_file_field_include_hidden` is set to `true`.
# See https://guides.rubyonrails.org/configuring.html#config-active-storage-multiple-file-field-include-hidden for more information.
# Rails.application.config.active_storage.multiple_file_field_include_hidden = true
# ** Please read carefully, this must be configured in config/application.rb (NOT this file) **
# Disables the deprecated #to_s override in some Ruby core classes
# See https://guides.rubyonrails.org/configuring.html#config-active-support-disable-to-s-conversion for more information.
# config.active_support.disable_to_s_conversion = true

View File

@@ -0,0 +1,280 @@
# Be sure to restart your server when you modify this file.
#
# This file eases your Rails 7.1 framework defaults upgrade.
#
# Uncomment each configuration one by one to switch to the new default.
# Once your application is ready to run with all new defaults, you can remove
# this file and set the `config.load_defaults` to `7.1`.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
###
# No longer add autoloaded paths into `$LOAD_PATH`. This means that you won't be able
# to manually require files that are managed by the autoloader, which you shouldn't do anyway.
#
# This will reduce the size of the load path, making `require` faster if you don't use bootsnap, or reduce the size
# of the bootsnap cache if you use it.
#
# To set this configuration, add the following line to `config/application.rb` (NOT this file):
# config.add_autoload_paths_to_load_path = false
###
# Remove the default X-Download-Options headers since it is used only by Internet Explorer.
# If you need to support Internet Explorer, add back `"X-Download-Options" => "noopen"`.
#++
# Rails.application.config.action_dispatch.default_headers = {
# "X-Frame-Options" => "SAMEORIGIN",
# "X-XSS-Protection" => "0",
# "X-Content-Type-Options" => "nosniff",
# "X-Permitted-Cross-Domain-Policies" => "none",
# "Referrer-Policy" => "strict-origin-when-cross-origin"
# }
###
# Do not treat an `ActionController::Parameters` instance
# as equal to an equivalent `Hash` by default.
#++
# Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false
###
# Active Record Encryption now uses SHA-256 as its hash digest algorithm.
#
# There are 3 scenarios to consider.
#
# 1. If you have data encrypted with previous Rails versions, and you have
# +config.active_support.key_generator_hash_digest_class+ configured as SHA1 (the default
# before Rails 7.0), you need to configure SHA-1 for Active Record Encryption too:
#++
# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1
#
# 2. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA256 (the new default
# in 7.0), then you need to configure SHA-256 for Active Record Encryption:
#++
# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256
#
# 3. If you don't currently have data encrypted with Active Record encryption, you can disable this setting to
# configure the default behavior starting 7.1+:
#++
# Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = false
###
# No longer run after_commit callbacks on the first of multiple Active Record
# instances to save changes to the same database row within a transaction.
# Instead, run these callbacks on the instance most likely to have internal
# state which matches what was committed to the database, typically the last
# instance to save.
#++
# Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false
###
# Configures SQLite with a strict strings mode, which disables double-quoted string literals.
#
# SQLite has some quirks around double-quoted string literals.
# It first tries to consider double-quoted strings as identifier names, but if they don't exist
# it then considers them as string literals. Because of this, typos can silently go unnoticed.
# For example, it is possible to create an index for a non existing column.
# See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details.
#++
# Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true
###
# Disable deprecated singular associations names.
#++
# Rails.application.config.active_record.allow_deprecated_singular_associations_name = false
###
# Enable the Active Job `BigDecimal` argument serializer, which guarantees
# roundtripping. Without this serializer, some queue adapters may serialize
# `BigDecimal` arguments as simple (non-roundtrippable) strings.
#
# When deploying an application with multiple replicas, old (pre-Rails 7.1)
# replicas will not be able to deserialize `BigDecimal` arguments from this
# serializer. Therefore, this setting should only be enabled after all replicas
# have been successfully upgraded to Rails 7.1.
#++
# Rails.application.config.active_job.use_big_decimal_serializer = true
###
# Specify if an `ArgumentError` should be raised if `Rails.cache` `fetch` or
# `write` are given an invalid `expires_at` or `expires_in` time.
# Options are `true`, and `false`. If `false`, the exception will be reported
# as `handled` and logged instead.
#++
# Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true
###
# Specify whether Query Logs will format tags using the SQLCommenter format
# (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format.
# Options are `:legacy` and `:sqlcommenter`.
#++
# Rails.application.config.active_record.query_log_tags_format = :sqlcommenter
###
# Specify the default serializer used by `MessageEncryptor` and `MessageVerifier`
# instances.
#
# The legacy default is `:marshal`, which is a potential vector for
# deserialization attacks in cases where a message signing secret has been
# leaked.
#
# In Rails 7.1, the new default is `:json_allow_marshal` which serializes and
# deserializes with `ActiveSupport::JSON`, but can fall back to deserializing
# with `Marshal` so that legacy messages can still be read.
#
# In Rails 7.2, the default will become `:json` which serializes and
# deserializes with `ActiveSupport::JSON` only.
#
# Alternatively, you can choose `:message_pack` or `:message_pack_allow_marshal`,
# which serialize with `ActiveSupport::MessagePack`. `ActiveSupport::MessagePack`
# can roundtrip some Ruby types that are not supported by JSON, and may provide
# improved performance, but it requires the `msgpack` gem.
#
# For more information, see
# https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer
#
# If you are performing a rolling deploy of a Rails 7.1 upgrade, wherein servers
# that have not yet been upgraded must be able to read messages from upgraded
# servers, first deploy without changing the serializer, then set the serializer
# in a subsequent deploy.
#++
# Rails.application.config.active_support.message_serializer = :json_allow_marshal
###
# Enable a performance optimization that serializes message data and metadata
# together. This changes the message format, so messages serialized this way
# cannot be read by older versions of Rails. However, messages that use the old
# format can still be read, regardless of whether this optimization is enabled.
#
# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have
# not yet been upgraded must be able to read messages from upgraded servers,
# leave this optimization off on the first deploy, then enable it on a
# subsequent deploy.
#++
# Rails.application.config.active_support.use_message_serializer_for_metadata = true
###
# Set the maximum size for Rails log files.
#
# `config.load_defaults 7.1` does not set this value for environments other than
# development and test.
#++
# if Rails.env.local?
# Rails.application.config.log_file_size = 100 * 1024 * 1024
# end
###
# Enable raising on assignment to attr_readonly attributes. The previous
# behavior would allow assignment but silently not persist changes to the
# database.
#++
# Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true
###
# Enable validating only parent-related columns for presence when the parent is mandatory.
# The previous behavior was to validate the presence of the parent record, which performed an extra query
# to get the parent every time the child record was updated, even when parent has not changed.
#++
# Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false
###
# Enable precompilation of `config.filter_parameters`. Precompilation can
# improve filtering performance, depending on the quantity and types of filters.
#++
# Rails.application.config.precompile_filter_parameters = true
###
# Enable before_committed! callbacks on all enrolled records in a transaction.
# The previous behavior was to only run the callbacks on the first copy of a record
# if there were multiple copies of the same record enrolled in the transaction.
#++
# Rails.application.config.active_record.before_committed_on_all_records = true
###
# Disable automatic column serialization into YAML.
# To keep the historic behavior, you can set it to `YAML`, however it is
# recommended to explicitly define the serialization method for each column
# rather than to rely on a global default.
#++
# Rails.application.config.active_record.default_column_serializer = nil
###
# Enable a performance optimization that serializes Active Record models
# in a faster and more compact way.
#
# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have
# not yet been upgraded must be able to read caches from upgraded servers,
# leave this optimization off on the first deploy, then enable it on a
# subsequent deploy.
#++
# Rails.application.config.active_record.marshalling_format_version = 7.1
###
# Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model.
# This matches the behaviour of all other callbacks.
# In previous versions of Rails, they ran in the inverse order.
#++
# Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true
###
# Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`.
#++
# Rails.application.config.active_record.commit_transaction_on_non_local_return = true
###
# Controls when to generate a value for <tt>has_secure_token</tt> declarations.
#++
# Rails.application.config.active_record.generate_secure_token_on = :initialize
###
# ** Please read carefully, this must be configured in config/application.rb **
#
# Change the format of the cache entry.
#
# Changing this default means that all new cache entries added to the cache
# will have a different format that is not supported by Rails 7.0
# applications.
#
# Only change this value after your application is fully deployed to Rails 7.1
# and you have no plans to rollback.
# When you're ready to change format, add this to `config/application.rb` (NOT
# this file):
# config.active_support.cache_format_version = 7.1
###
# Configure Action View to use HTML5 standards-compliant sanitizers when they are supported on your
# platform.
#
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action View to use HTML5-compliant
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
#
# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor.
#++
# Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
###
# Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your
# platform.
#
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action Text to use HTML5-compliant
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
#
# In previous versions of Rails, Action Text always used `Rails::HTML4::Sanitizer` as its vendor.
#++
# Rails.application.config.action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
###
# Configure the log level used by the DebugExceptions middleware when logging
# uncaught exceptions during requests.
#++
# Rails.application.config.action_dispatch.debug_exception_log_level = :error
###
# Configure the test helpers in Action View, Action Dispatch, and rails-dom-testing to use HTML5
# parsers.
#
# Nokogiri::HTML5 isn't supported on JRuby, so JRuby applications must set this to :html4.
#
# In previous versions of Rails, these test helpers always used an HTML4 parser.
#++
# Rails.application.config.dom_testing_default_html_version = :html5

View File

@@ -0,0 +1,13 @@
# Be sure to restart your server when you modify this file.
# Define an application-wide HTTP permissions policy. For further
# information see: https://developers.google.com/web/updates/2018/06/feature-policy
# Rails.application.config.permissions_policy do |policy|
# policy.camera :none
# policy.gyroscope :none
# policy.microphone :none
# policy.usb :none
# policy.fullscreen :self
# policy.payment :self, "https://secure.example.com"
# end

View File

@@ -400,7 +400,7 @@ ca:
order_cycles: Cicles de comanda
bulk_order_management: Gestió de comandes en bloc
enterprises: Organitzacions
enterprise_groups: Grups
enterprise_groups: Xarxes
reports: Informes
listing_reports: Llistat d'informes
variant_overrides: Inventari
@@ -675,8 +675,13 @@ ca:
map: Mapa
dfc_product_imports:
index:
select_all: "Seleccionar/Desseleccionar Tot"
update: Actualitzar
new: Nou
selected:
zero: "Res seleccionat"
one: "1 seleccionat"
other: "%{count} seleccionat"
import: Importa
enterprise_fees:
index:
@@ -2280,12 +2285,12 @@ ca:
sell_motivation: "Mostra el teu bonic menjar."
sell_producers: "Productors"
sell_hubs: "Grups"
sell_groups: "Grups"
sell_groups: "Xarxes"
sell_producers_detail: "Configura un perfil per a la vostra empresa a Katuma en qüestió de minuts. En qualsevol moment pots convertir el teu perfil en una botiga en línia i vendre els teus productes directament a les consumidores."
sell_hubs_detail: "Configura un perfil per a la teva organització alimentària a Katuma. En qualsevol moment, pots modificar i convertir el teu perfil en una botiga de diverses productores."
sell_groups_detail: "Configura un directori personalitzat d'empreses (productores i altres empreses alimentàries) per a la teva regió o per a la teva xarxa, organització."
sell_user_guide: "Troba més informació a la nostra Guia d'usuari."
sell_listing_price: "El llistat al OFN és gratuït. Lobertura i lexecució duna botiga a OFN és gratuïta fins a 500 dòlars de vendes mensuals. Si veneu més, podeu escollir la vostra contribució comunitària entre l'1% i el 3% de les vendes. Per obtenir més informació sobre preus, consulteu la secció Plataforma de programari a través de lenllaç Sobre al menú superior."
sell_listing_price: "La inscripció a Katuma-OFN és gratuïta. Consulteu les tarifes d'ús de la plataforma a https://www.katuma.org/quotes. "
sell_embed: "També podem incrustar una botiga OFN al vostre web personalitzat o crear un lloc web personalitzat de la xarxa alimentària per a la teva regió."
sell_ask_services: "Pregunta'ns sobre els serveis d'OFN."
shops_title: Botigues
@@ -3750,7 +3755,7 @@ ca:
enterprises: "Organitzacions"
enterprise_relationships: "Permisos"
customers: "Consumidores"
groups: "Grups"
groups: "Xarxes"
overview: "Visió general"
product_import: "Importa"
enterprise_roles: "Rols"
@@ -4379,6 +4384,7 @@ ca:
search_input:
placeholder: Cerca
selector_with_filter:
selected_items: "%{count} seleccionat"
search_placeholder: Cerca
pagination:
next: Següent

View File

@@ -1446,6 +1446,8 @@ cy:
visible: Gweladwy?
owner: Perchennog
producer: Cynhyrchydd
sells_options:
none: dim
change_type_form:
producer_profile: Proffil Cynhyrchydd
connect_ofn: Cysylltu trwy'r Open Food Network

View File

@@ -1518,6 +1518,11 @@ en:
visible: Visible?
owner: Owner
producer: Producer
sells_options:
unspecified: unspecified
none: none
own: own
any: any
change_type_form:
producer_profile: Producer Profile
connect_ofn: Connect through OFN
@@ -4744,6 +4749,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
terms_of_service: "Terms of Service"
sortable_header:
name: "Name"
on_hand: "On Hand"
number: "Number"
completed_at: "Completed At"
state: "State"

View File

@@ -640,7 +640,7 @@ en_CA:
product: Product
quantity: Quantity
schedule: Schedule
shipping: Shipping
shipping: Shipping/Pickup
shipping_method: Shipping/Pick-up Method
shop: Shop
sku: SKU
@@ -1447,6 +1447,11 @@ en_CA:
visible: Visible?
owner: Owner
producer: Producer
sells_options:
unspecified: unspecified
none: none
own: own
any: any
change_type_form:
producer_profile: Producer Profile
connect_ofn: Connect through OFN
@@ -2357,7 +2362,7 @@ en_CA:
checkout_send: Place order now
checkout_your_order: Your order
checkout_cart_total: Cart total
checkout_shipping_price: Shipping
checkout_shipping_price: Shipping/Pickup
checkout_total_price: Total
checkout_back_to_cart: "Back to Cart"
cost_currency: "Cost Currency"
@@ -3618,7 +3623,7 @@ en_CA:
removed_terms_and_conditions_successfully: "Terms and Conditions file removed successfully"
insufficient_stock: "Insufficient stock available, only %{on_hand} remaining"
out_of_stock:
reduced_stock_available: Reduced stock available
reduced_stock_available: 'Reduced stock '
out_of_stock_text: >
While you've been shopping, the stock levels for one or more of the products
in your cart have reduced. Here's what's changed:
@@ -4259,7 +4264,7 @@ en_CA:
states:
authorized: "Authorized"
received: "Received"
canceled: "Canceled"
canceled: "Cancelled"
line_items:
index:
results_found: " %{number} Results found."
@@ -4636,7 +4641,7 @@ en_CA:
pending: pending
ready: ready
shipped: shipped
canceled: canceled
canceled: cancelled
payment_states:
balance_due: balance due
completed: completed

View File

@@ -1447,6 +1447,11 @@ en_FR:
visible: Visible?
owner: Owner
producer: Producer
sells_options:
unspecified: unspecified
none: none
own: own
any: any
change_type_form:
producer_profile: Producer Profile
connect_ofn: Connect through OFN

View File

@@ -1447,6 +1447,8 @@ en_GB:
visible: Visible?
owner: Owner
producer: Producer
sells_options:
none: none
change_type_form:
producer_profile: Producer Profile
connect_ofn: Connect through OFN
@@ -2622,7 +2624,7 @@ en_GB:
sell_ask_services: "Ask us about OFN services."
shops_title: Shops
shops_headline: Transform your shopping.
shops_text: Food grows in cycles, farmers harvest in cycles, and we order food in cycles. If you find an order cycle closed, check back soon.
shops_text: Food grows in cycles, farmers harvest in cycles, and we order food in cycles. If you find an order cycle closed, please check back soon.
shops_signup_title: Sign up as a hub
shops_signup_headline: Food hubs, unlimited.
shops_signup_motivation: Whatever your model, we support you. However you change, we're with you. We're non-profit, independent, and open-sourced. We're the software partners you've dreamed of.
@@ -2842,7 +2844,7 @@ en_GB:
enterprise_final_step: "Final step!"
enterprise_social_text: "How can people find %{enterprise} online?"
website: "Website"
website_placeholder: "eg. openfoodnetwork.org.au"
website_placeholder: "eg. openfoodnetwork.org.uk"
facebook: "Facebook"
facebook_placeholder: "eg. www.facebook.com/PageNameHere"
linkedin: "LinkedIn"

View File

@@ -38,11 +38,11 @@ es:
shipment_state: Provincia de envío
completed_at: Completado en
number: Número
state: Estado
state: Provincia
email: E-mail del consumidor
spree/payment:
amount: Cantidad
state: Estado
state: Provincia
source: Fuente
spree/product:
name: "nombre del producto"
@@ -1702,7 +1702,9 @@ es:
pack_by_customer: Pack por Consumidor
pack_by_supplier: Pack por proveedor
pack_by_product: Empaquetar por producto
pay_your_suppliers: Paga tus proveedoras
display:
report_is_big: "Este informe es grande y puede ralentizar su dispositivo."
display_anyway: "Mostrar de todos modos"
download:
button: "Descargar informe"
@@ -1944,7 +1946,7 @@ es:
label: País
shipping_info:
title: Información de envío
submit: Siguente - método de pago
submit: Siguiente - método de pago
cancel: Regresar a Editar cesta
step2:
payment_method:
@@ -2937,7 +2939,7 @@ es:
admin_share_city: "Ciudad"
admin_share_zipcode: "Código Postal"
admin_share_country: "País"
admin_share_state: "Estado"
admin_share_state: "Provincia"
hub_sidebar_hubs: "Hubs"
hub_sidebar_none_available: "Ninguno Disponible"
hub_sidebar_manage: "Gestionar"
@@ -3502,6 +3504,7 @@ es:
add_to_cart: "Añadir"
in_cart: "en el carrito"
quantity_in_cart: "%{quantity} en el carrito"
remaining_in_stock: "Solo queda %{quantity}"
bulk_buy_modal:
min_quantity: "Cantidad mínima"
max_quantity: "Cantidad máxima"
@@ -3951,7 +3954,7 @@ es:
states_required: "Estados requeridos"
editing_country: "Editar país"
back_to_countries_list: "Volver a la lista de países"
states: "Estados"
states: "Provincias"
abbreviation: "Abreviatura"
new_state: "Nuevo estado"
payment_methods: "Métodos de Pago"
@@ -4038,6 +4041,7 @@ es:
messages:
included_price_validation: "no se puede seleccionar a menos que haya establecido una zona fiscal predeterminada"
blank: "no puede estar vacío"
invalid_instagram_url: "Debe ser solo el nombre de usuario, por ejemplo, la_prof."
layouts:
admin:
login_nav:
@@ -4368,6 +4372,9 @@ es:
table:
select_and_search: "Seleccione filtros y haga clic en %{option} para acceder a sus datos."
hidden_customer_details_tip: "Si los nombres y/o los datos de contacto de las consumidoras están ocultos, puede solicitar a la distribuidora que actualice las preferencias de su tienda para permitir que sus proveedores vean los datos de las consumidoras en los informes."
products_and_inventory:
all_products:
message: "Ten en cuenta que los niveles de existencias indicados proceden únicamente de las listas de productos de los proveedores. Si utiliza Inventario para gestionar sus cantidades de existencias, estos valores se ignorarán en este informe."
users:
index:
listing_users: "Listado de Usuarias"

View File

@@ -1919,6 +1919,7 @@ eu:
invalid_email: "Sartu baliozko mezu elektroniko bat"
select_a_shipping_method: Hautatu bidalketa-metodoa
select_a_payment_method: Hautatu ordainketa-metodoa
add_voucher_error: Errore bat gertatu da bonoa gehitzean
shops:
hubs:
show_closed_shops: "Denda itxiak erakutsi"
@@ -2191,6 +2192,7 @@ eu:
order_not_paid: ORDAINDU GABE
order_total: Eskaera, guztira
order_payment: "Honekin ordainduz:"
no_payment_required: "Ez da ordainketarik behar"
order_billing_address: Kobratzeko helbidea
order_delivery_on: 'Entregatu hemen:'
order_delivery_address: Entregatzeko helbidea
@@ -2353,7 +2355,7 @@ eu:
products_updating_cart: "Zure saskia eguneratzen..."
products_cart_empty: "Gurditxo hutsa"
products_edit_cart: "Zure orgatxoa editatu"
products_from: Noiztik
products_from: 'nekazaria: '
products_change: "Ez dago aldaketarik gordetzeko."
products_update_error: "Akats hauengatik ezin izan da gorde:"
products_update_error_msg: "Ezin izan da gorde."
@@ -3174,6 +3176,7 @@ eu:
admin:
unit_price_tooltip: "Prezio unitarioak gardentasuna handitzen du, bezeroei produktuen eta bilgarriaren tamainen arteko prezioak erraz alderatzeko aukera ematen baitie. Kontuan izan erakusleihoan erakusten den azken prezio unitarioa diferentea izan daitekeela, zergak eta tarifak barne hartzen baititu. "
enterprise_limit_reached: "Konturako erakundeen muga estandarra lortu duzu. Idatzi %{contact_email} helbidera, handitu behar baduzu. "
deleting_item_will_cancel_order: "Eragiketa honek eskaera huts bat edo gehiago sortuko ditu, eta bertan behera utziko dira. Jarraitu nahi duzu?"
modals:
got_it: "Ulertzen dut"
confirm: "Baieztatu"
@@ -3413,6 +3416,7 @@ eu:
add_to_cart: "Gehitu"
in_cart: "orgatxoan"
quantity_in_cart: " %{quantity} orgatxoan"
remaining_in_stock: "%{quantity} bakarrik geratzen da"
bulk_buy_modal:
min_quantity: "Gutxieneko kopurua"
max_quantity: "Gehieneko kopurua"
@@ -3491,15 +3495,21 @@ eu:
trix:
bold: "Lodia"
code: "Kodea"
indent: "Maila handitu"
italic: "Italica"
link: "Esteka"
numbers: "Zenbakiak"
outdent: "Maila jaitsi"
redo: "Berregin"
strike: "Tatxatuta"
undo: "Desegin"
unlink: "Askatu"
url: "URL"
urlPlaceholder: "Mesedez, sartu URL bat txertatzeko"
inflections:
pot:
one: "lapiko"
other: "lapikoak"
producers:
signup:
start_free_profile: "Hasi doako profil batekin, eta zabaldu prest zaudenean!"
@@ -4100,6 +4110,7 @@ eu:
title: "Produktu berria"
new_product: "Produktu berria"
supplier: "Hornitzailea"
search_for_units: "Bilatu unitateak"
product_name: "produktuaren izena"
units: "Neurketa-unitatea"
value: "Balioa"
@@ -4216,6 +4227,9 @@ eu:
title: "Produktuaren kategoria berria"
edit:
title: "Produktuaren kategoria editatu"
destroy:
delete_taxon:
success: "Produktu-kategoria behar bezala ezabatu da"
form:
name: Izena
description: Deskribapena

View File

@@ -1445,6 +1445,8 @@ fi:
visible: Näkyvissä?
owner: Omistaja
producer: Tuottaja
sells_options:
none: ei yhtään
change_type_form:
producer_profile: Tuottajan profiili
connect_ofn: Yhdistä OFN:n kautta

View File

@@ -1449,6 +1449,8 @@ fr:
visible: Visible?
owner: Gestionnaire principal
producer: Producteur
sells_options:
none: aucun
change_type_form:
producer_profile: Profil simple
connect_ofn: Pour apparaître sur la carte et la liste des producteurs

View File

@@ -1451,6 +1451,11 @@ fr_CA:
visible: Visible?
owner: Gérant
producer: Producteur
sells_options:
unspecified: non spécifié
none: aucun
own: propre
any: Tous
change_type_form:
producer_profile: Profil producteur
connect_ofn: Gagnez en visibilité via OFN

View File

@@ -150,7 +150,7 @@ hu:
unauthorized:
message: "Nincs jogosultságod a művelet végrehajtására."
network_error:
message: "Hálózati hiba: Kérjük próbáld meg később."
message: "Hálózati hiba: Kérjük, próbáld meg később."
stripe:
error_code:
incorrect_number: "A kártyaszám hibás."
@@ -261,7 +261,7 @@ hu:
signed_up_but_unconfirmed: "Megerősítő linket tartalmazó üzenetet küldtünk az email címedre. Kérjük, nyisd meg a linket a fiók aktiválásához."
unknown_error: "Hiba történt a fiók létrehozásakor. Ellenőrizd email címed, és próbáld újra."
failure:
disabled: "A fiókot inaktiváltuk. Kérjük fordulj munkatársunkhoz, hogy feloldjuk."
disabled: "A fiókot inaktiváltuk. Kérjük, fordulj munkatársunkhoz, hogy feloldjuk."
invalid: |
Rossz email cím vagy jelszó.
Legutóbb is vendégként használtad a felületet? Talán létre kell hoznod egy fiókot vagy vissza kell állítanod a jelszavad:
@@ -403,7 +403,7 @@ hu:
explainer: Ezen rendelések fizetésének automatikus feldolgozása hiba miatt meghiúsult. A hiba feltüntetésre került, ahol lehetséges.
other:
title: Egyéb hiba (%{count} rendelés)
explainer: A megrendelések automatikus feldolgozása ismeretlen okból meghiúsult. Ennek nem szabadna előfordulnia, kérjük lépj kapcsolatba velünk, ha ezt látod.
explainer: A megrendelések automatikus feldolgozása ismeretlen okból meghiúsult. Ennek nem szabadna előfordulnia, kérjük, lépj kapcsolatba velünk, ha ezt látod.
home: "OFN"
title: "Open Food Network"
welcome_to: "Üdvözöl az"
@@ -687,7 +687,7 @@ hu:
settings: "Beállítások"
stripe_connect_enabled: Engedélyezi az átvételi pontok számára a fizetés elfogadását a Stripe Connect használatával?
no_api_key_msg: Ehhez a vállalkozáshoz nem tartozik Stripe-fiók.
configuration_explanation_html: A Stripe Connect integráció konfigurálására vonatkozó részletes utasításokért, kérjük <a href='https://github.com/openfoodfoundation/openfoodnetwork/wiki/Setting-up-Stripe-on-an-OFN-instance' target='_blank'>olvasd el ezt az útmutatót</a>.
configuration_explanation_html: A Stripe Connect integráció konfigurálására vonatkozó részletes utasításokért, kérjük, <a href='https://github.com/openfoodfoundation/openfoodnetwork/wiki/Setting-up-Stripe-on-an-OFN-instance' target='_blank'>olvasd el ezt az útmutatót</a>.
status: Státusz
ok: Rendben
instance_secret_key: Példány titkos kulcsa
@@ -695,7 +695,7 @@ hu:
account_id: Felhasználónév
business_name: Vállalkozás neve
charges_enabled: Díjak engedélyezve
charges_enabled_warning: "Figyelmeztetés: A terhelések nem engedélyezettek az Ön fiókban"
charges_enabled_warning: "Figyelmeztetés: a terhelések nem engedélyezettek a fiókodban"
auth_fail_error: A megadott API-kulcs érvénytelen
empty_api_key_error_html: Nincs megadva Stripe API kulcs. Az API-kulcs beállításához, kérjük, kövesd <a href="https://github.com/openfoodfoundation/openfoodnetwork/wiki/Setting-up-Stripe-on-an-OFN-instance" target="_blank">ezeket az utasításokat</a>
matomo_settings:
@@ -705,7 +705,7 @@ hu:
matomo_site_id: "Matomo webhelyazonosító"
matomo_tag_manager_url: "Matomo Címkekezelő URL-je"
info_html: "A Matomo egy webes és mobilelemző alkalmazás. A Matomo helyszíni üzemeltetését vagy felhőalapú szolgáltatást is használhatja. További információért lásd: <a href='http://matomo.org' target='_blank'>matomo.org</a>."
config_instructions_html: "Itt konfigurálhatja az OFN Matomo integrációt. Az alábbi Matomo URL-nek arra a Matomo-példányra kell mutatnia, ahová a felhasználó követési információkat küldi; ha üresen marad, a Matomo felhasználókövetés le lesz tiltva. A Webhelyazonosító mező nem kötelező, de hasznos, ha egynél több webhelyet követ nyomon egyetlen Matomo-példányon; a Matomo példánykonzolon található."
config_instructions_html: "Itt konfigurálhatod az OFN Matomo integrációt. Az alábbi Matomo URL-nek arra a Matomo-példányra kell mutatnia, ahová a felhasználó követési információkat küldi; ha üresen marad, a Matomo felhasználókövetés le lesz tiltva. A Webhelyazonosító mező nem kötelező, de hasznos, ha egynél több webhelyet követ nyomon egyetlen Matomo-példányon; a Matomo példánykonzolon található."
config_instructions_tag_manager_html: "A Matomo Címkekezelő URL-címének beállítása engedélyezi a Matomo Címkekezelőt. Ez az eszköz lehetővé teszi az elemzési események beállítását. A Matomo Címkekezelő URL-címe a Matomo Tag Manager Telepítési kód szakaszából lett kimásolva. Győződj meg róla, hogy a megfelelő tárolót és környezetet választotta, mivel ezek a beállítások megváltoztatják az URL-t."
connected_app_settings:
edit:
@@ -751,7 +751,7 @@ hu:
group_signup_page: Fogyasztói csoport regisztrációs oldal
main_links: Főmenü hivatkozások
footer_and_external_links: Lábléc és külső hivatkozások
your_content: Az Ön tartalma
your_content: A tartalmad
user_guide: Használati útmutató
map: Térkép
dfc_product_imports:
@@ -766,6 +766,8 @@ hu:
one: "1 kiválasztva"
other: "%{count}kiválasztva"
import: Importálás
import:
imported_products: "Importált termékek: %{count}"
enterprise_fees:
index:
title: "Vállalkozási díjak"
@@ -798,7 +800,7 @@ hu:
enterprise_role:
manages: kezeli
products:
unit_name_placeholder: 'például csokrok'
unit_name_placeholder: 'pl. csokrok'
index:
unit: Mértékegység
display_as: Megjelenítés mint
@@ -890,7 +892,7 @@ hu:
bulk_update:
success: Változtatások mentve
delete_product:
success: Sikeresen törölte a terméket
success: Sikeresen törölted a terméket
error: A terméket nem lehet törölni
delete_variant:
success: Sikeresen törölte a termék változatot
@@ -904,7 +906,7 @@ hu:
select_unit_scale: Válassz mértékegységet
add_a_tag: Adj hozzá egy címkét
clone:
success: Sikeresen klónozta a terméket
success: Sikeresen klónoztad a terméket
error: A terméket nem sikerült klónozni
product_import:
title: Termék importálás
@@ -923,7 +925,7 @@ hu:
values_must_be_same: azonos név alatt azonos terméknek kell szerepelnie
blank: nem lehet üres
products_no_permission: nincs engedélyed a vállalkozás termékeinek kezelésére
inventory_no_permission: nincs engedélye készlet létrehozására ehhez a termelőhöz
inventory_no_permission: nincs engedélye leltár létrehozására ehhez a termelőhöz
none_saved: egyetlen terméket sem mentett sikeresen
line_number: "%{number}. sor:"
encoding_error: "Kérjük, ellenőrizd a forrásfájl nyelvi beállítását, és győződj meg arról, hogy UTF-8 kódolással van mentve"
@@ -937,7 +939,7 @@ hu:
choose_import_type: Válaszd ki az importálás típusát
import_into: Importálás típusa
product_list: Terméklista
inventories: Készletek
inventories: Leltárak
import: Importálás
upload: Feltöltés
csv_templates: CSV-sablonok
@@ -956,14 +958,14 @@ hu:
import: Importálás
save: Mentés
results: Eredmények
save_imported: Mentse el az importált termékeket
save_imported: Importált termékek mentése
no_valid_entries: Nem található érvényes bejegyzés
none_to_save: Nincsenek menthető bejegyzések
some_invalid_entries: Az importált fájl érvénytelen bejegyzéseket tartalmaz
fix_before_import: Kérjük, javítsd ki ezeket a hibákat, és próbáld újra importálni a fájlt
save_valid?: Mented az érvényes bejegyzéseket, és elveted a többit?
no_errors: Nem észleltek hibát!
save_all_imported?: Mented az összes importált terméket?
no_errors: Nem észleltem hibát.
save_all_imported?: Mentsük a termékimport eredményeit?
options_and_defaults: Importálási lehetőségek és alapértelmezett beállítások
no_permission: nincs engedélye ennek a vállalkozásnak a kezelésére
not_found: vállalkozás nem található az adatbázisban
@@ -977,15 +979,15 @@ hu:
default_tax_cat: Adókategória beállítása
default_shipping_cat: Szállítási kategória beállítása
default_available_date: Állítsd be az elérhetőségi dátumot
validation_overview: Az importálás ellenőrzésének áttekintése
validation_overview: Importálás előtti ellenőrzés eredménye
entries_found: bejegyzés található az importált fájlban
entries_with_errors: Az elemek hibákat tartalmaznak, és nem importálhatók
products_to_create: termék jön létre
products_to_update: A termékek frissítésre kerülnek
inventory_to_create: A készletelemek létrehozásra kerülnek
inventory_to_update: A készletelemek frissülnek
products_to_update: termék fog frissülni
inventory_to_create: A leltár elemek létrehozásra kerülnek
inventory_to_update: A leltár elemek frissültek
products_to_reset: A meglévő termékek készlete nullára áll vissza
inventory_to_reset: A meglévő készletelemek készlete nullára áll vissza
inventory_to_reset: A meglévő leltárelemek készlete nullára áll vissza
line: Sor
item_line: Tételsor
import_review:
@@ -997,13 +999,13 @@ hu:
final_results: Az importálás eredménye
products_created: létrehozott termék
products_updated: Termékek frissítve
inventory_created: Készletelemek létrehozva
inventory_updated: A készletelemek frissítve
inventory_created: Leltárelemek létrehozva
inventory_updated: A leltárelemek frissítve
products_reset: termék készletét nullára állítottuk
inventory_reset: A készletelemek készletszintjét nullára állították vissza
inventory_reset: A leltárelemek készletszintjét nullára állítottuk vissza
all_saved: "Minden termék mentése sikeres."
some_saved: "elemek sikeresen mentve"
save_errors: Mentse el a hibákat
save_errors: Hibák mentése
import_again: Másik fájl feltöltése
view_products: Ugrás a Termékek oldalra
view_inventory: Ugrás a Leltár oldalra
@@ -1025,10 +1027,10 @@ hu:
tax_category: Adókategória
variant_overrides:
loading_flash:
loading_inventory: KÉSZLET BETÖLTÉSE
loading_inventory: LELTÁR BETÖLTÉSE
index:
title: Leltár
description: Ezen az oldalon kezelheted vállalkozásod készleteit. Az itt beállított termékadatok felülírják a „Termékek” oldalon megadottakat
description: Ezen az oldalon kezelheted vállalkozásod leltárait. Az itt beállított termékadatok felülírják a „Termékek” oldalon megadottakat
enable_reset?: Engedélyezi a készlet visszaállítását?
default_stock: "Alapértelmezett készlet"
inherit?: Örököl?
@@ -1037,21 +1039,21 @@ hu:
import_date: Importált
select_a_shop: Válassz Átvételi Pontot
review_now: Tekintsd át most
new_products_alert_message: '%{new_product_count} új termék áll rendelkezésre, amelyet hozzáadhatsz a készletedhez.'
new_products_alert_message: '%{new_product_count} új termék áll rendelkezésre, amelyet hozzáadhatsz a leltáradhoz.'
currently_empty: A leltár jelenleg üres
no_matching_products: Nem található megfelelő termék a leltárban
no_hidden_products: Egyetlen termék sincs elrejtve ebből a leltárból
no_matching_hidden_products: Egyetlen rejtett termék sem felel meg a keresési feltételeknek
no_new_products: Nincsenek új termékek, amelyeket hozzáadhatnának ehhez a készlethez
no_new_products: Nincsenek új termékek, amelyeket hozzáadhatnának ehhez a leltárhoz
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á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!
inventory_powertip: Ez a leltárké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 leltáradból, és nem lesz elérhető az oldalon. A "Hozzáadás" gombra kattintva hozzáadhatsz egy terméket a leltáradhoz.
new_powertip: Ezeket a termékeket hozzáadhatod a leltáradhoz. Kattints a 'Hozzáadás' gombra, ha hozzá szeretnél adni egy terméket a leltáradhoz, 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:
edit:
order_sure_want_to: Biztosan %{event} akarja ezt a megrendelést?
order_sure_want_to: Biztosan %{event} akarod ezt a megrendelést?
voucher_tax_included_in_price: "%{label}(a kupon tartalmazza az adót)"
tax_on_fees: "Díjak adója"
invoice_email_sent: 'Számla e-mail elküldve'
@@ -1121,9 +1123,9 @@ hu:
disabled: Tiltás
business_address:
company_legal_name: A cég hivatalos neve
company_placeholder: Példa Inc.
company_placeholder: Példa Kft.
address1: Hivatalos cím
address1_placeholder: János utca 11.
address1_placeholder: pl. János utca 11.
address2: Cím (folyt.)
legal_phone_number: Hivatalos telefonszám
phone_placeholder: "98 123 4565"
@@ -1137,12 +1139,12 @@ hu:
email_address_placeholder: pl. kapcsolat@frisszoldseg.hu
email_address_tip: "Ez az email cím megjelenik nyilvános profilodban"
phone: Telefon
phone_placeholder: például 98 7654 3210
phone_placeholder: pl. +36 20 654 3210
whatsapp_phone: WhatsApp telefonszám
whatsapp_phone_placeholder: pl. +36 28 1234567
whatsapp_phone_tip: "A telefonszám a nyilvános profilodban látszódni fog mint WhatsApp link."
website: Weboldal
website_placeholder: például www.truffles.com
website_placeholder: pl. www.truffles.com
enterprise_fees:
legend: "Vállalkozási díjak"
name: Név
@@ -1158,16 +1160,16 @@ hu:
logo: Logó
logo_size: "300 x 300 pixel"
inventory_settings:
legend: "Készletbeállítások"
legend: "Leltárbeállítások"
text1: Dönthetsz úgy, hogy a készletszinteket és az árakat a sajátodon keresztül kezeled
inventory: leltár
text2: >
Ha a leltár eszközt használod, kiválaszthatod, hogy a beszállítók által
hozzáadott termékeket hozzá kell-e adni a készletedhez. Ha nem használod
hozzáadott termékeket hozzá kell-e adni a leltáradhoz. Ha nem használod
a leltárt a termékek kezelésére, akkor válaszd az alábbi "ajánlott"
opciót:
preferred_product_selection_from_inventory_only_yes: Új termékek kerülhetnek az online kirakatomba (ajánlott)
preferred_product_selection_from_inventory_only_no: Az Új termékeket hozzá kell adnom a készletemhez, mielőtt az online kirakatomba kerülhetnének
preferred_product_selection_from_inventory_only_no: Az új termékeket hozzá kell adnom a leltáramhoz, mielőtt az online kirakatomba kerülhetnének
payment_methods:
legend: "Fizetési módok"
name: Név
@@ -1192,6 +1194,8 @@ hu:
sells: Értékesít
sells_tip: "Egyik sem - a vállalkozás nem értékesít közvetlenül<br />Saját - a vállalkozás saját termékeket ad el az ügyfeleknek.<br />Mindegyik - A vállalkozás saját vagy más vállalkozás termékeit is értékesítheti.<br />"
external_billing_id: Külső számlázási azonosító
external_billing_id_placeholder: pl. PKK-2025-123456
external_billing_id_tip: "Ezt az azonosítót használja a külső számlázási rendszer, hogy beazonosítsa a vállalkozást."
visible_in_search: Látható a keresésben?
visible_in_search_tip: "Az termelői és átvételi pont profilok lehetnek 1. nyilvánosak, amik megjelennek az OFN térképen és listákban, vagy 2. rejtve a térképen és listákban, de más átvételi pontok által elérhető módon, vagy 3. teljesen rejtve."
visible: Nyilvános
@@ -1272,8 +1276,8 @@ hu:
disabled: "Tiltva"
social:
legend: "Közösségi média"
twitter_placeholder: "például @the_prof"
instagram_placeholder: "például the_prof"
twitter_placeholder: "pl. @the_prof"
instagram_placeholder: "pl. the_prof"
facebook_placeholder: "pl. www.facebook.com/OldalNevedItt"
linkedin_placeholder: "pl. www.linkedin.com/in/TeNevedItt"
stripe_connect:
@@ -1366,7 +1370,7 @@ hu:
disable: "Lecsatlakozás"
need_to_be_manager: "Csak a megfelelő jogosultsággal rendelkező felhasználók csatlakoztathatnak alkalmazásokat."
vine_api_key: "VINE API kulcs"
connection_error: "API kapcsolódási hiba, kérjük próbáld újra"
connection_error: "API kapcsolódási hiba, kérjük, próbáld újra"
actions:
edit_profile: Beállítások
properties: Tulajdonságok
@@ -1383,6 +1387,10 @@ hu:
visible: Látható?
owner: Tulajdonos
producer: Termelő
sells_options:
none: n.a.
own: saját
any: bárkié
change_type_form:
producer_profile: Termelői Profil
connect_ofn: Csatlakozás OFN-en keresztül
@@ -1401,7 +1409,7 @@ hu:
hub_shop: Átvételi pont
hub_shop_text: 'Tedd elérhetővé más termelők termékeit is! '
hub_shop_description_text: Kezdeményezésed a helyi élelemrendszer kulcsa lehet. Összegyűjthetsz több termelőtől termékeket és Átvételi Pontként kínálhatod a fogyasztóknak. Lehetsz bevásárlóközösség, vásárlói csoport. Értékesítheted vegyesen saját és mások termékeit is.
choose_option: Kérjük, válasszon a fenti lehetőségek közül.
choose_option: Kérjük, válassz a fenti lehetőségek közül.
change_now: Változtass most
enterprise_user_index:
loading_enterprises: VÁLLALKOZÁSOK BETÖLTÉSE
@@ -1521,7 +1529,7 @@ hu:
automatic_notifications: Automatikus értesítések
automatic_notifications_tip: Automatikusan értesíti a termelőket rendeléseikről e-mailben, amikor a rendelés ciklus lezárul
title: További beállítások
choose_product_tip: bejövő és kimenő termékeket csak %{inventory} készletére korlátozhatja.
choose_product_tip: bejövő és kimenő termékeket csak %{inventory} leltárára korlátozhatja.
preferred_product_selection_from_coordinator_inventory_only_here: Csak a koordinátor leltár
preferred_product_selection_from_coordinator_inventory_only_all: Minden elérhető termék
save_reload: Oldal mentése és újratöltése
@@ -1574,7 +1582,7 @@ hu:
bulk_update:
no_data: Hm, valami elromlott. Nem található rendelési ciklus adat.
date_warning:
msg: Ez a rendelési ciklus %{n} nyitott előfizetéses megrendeléshez kapcsolódik. A dátum módosítása nem érinti a már leadott rendeléseket, de lehetőség szerint kerülni kell. Biztosan folytatja?
msg: Ez a rendelési ciklus %{n} nyitott előfizetéses megrendeléshez kapcsolódik. A dátum módosítása nem érinti a már leadott rendeléseket, de lehetőség szerint kerülni kell. Biztosan folytatod?
cancel: Mégsem
proceed: Folytassa
status:
@@ -1633,7 +1641,7 @@ hu:
payment_methods: "fizetési módok"
enterprise_fees: "Vállalkozási díjak"
enterprise_permissions: "Vállalkozási engedélyek"
inventory_settings: "Készletbeállítások"
inventory_settings: "Leltár beállítások"
tag_rules: "Címkeszabályok"
shop_preferences: "Átvételi ponti beállítások"
users: "Felhasználók"
@@ -1666,10 +1674,10 @@ hu:
supplier_totals: Rendelési ciklus Beszállítói végösszegek
percentage: "%{value} %"
supplier_totals_by_distributor: A ciklus Beszállítói végösszegei Elosztónként
totals_by_supplier: Megrendelési ciklus Elosztói végösszegi Beszállító szerint
totals_by_supplier: Megrendelési ciklus Elosztói összesítések Beszállító szerint
customer_totals: Rendelési ciklus Ügyfélösszegek
all_products: Minden termék
inventory: Készlet (kéznél)
inventory: Leltár (készleten)
lettuce_share: Részesedés
payment_methods: Fizetési módokról szóló jelentés
delivery: Kézbesítési jelentés
@@ -1712,7 +1720,7 @@ hu:
customers:
name: Ügyfelek
products_and_inventory:
name: Termékek és készlet
name: Termékek és leltár
users_and_enterprises:
name: Felhasználók és Vállalkozások
description: Vállalkozási tulajdonjog és státusz
@@ -1731,9 +1739,9 @@ hu:
enterprise_fees_with_tax_report_by_order: "Vállalkozási díjak adójelentései megrendelés alapján"
enterprise_fees_with_tax_report_by_producer: "Vállalkozási díjak Jelentés termelőnként"
errors:
no_report_type: "Adja meg a jelentés típusát"
no_report_type: "Add meg a jelentés típusát"
report_not_found: "A jelentés nem található"
missing_ransack_params: "Kérjük, adja meg a Ransack keresési paramétereit a kérelemben"
missing_ransack_params: "Kérjük, add meg a Ransack keresési paramétereit a kérelemben"
summary_row:
total: "ÖSSZESEN"
table:
@@ -1754,7 +1762,7 @@ hu:
generate_report: "Készíts jelentést"
on_screen: "A képernyőn"
spreadsheet: "Táblázat (Excel, OpenOffice...)"
display: Kijelző
display: Megjelenítés
summary_row: Összefoglaló sor
header_row: Fejléc sor
raw_data: Nyers adatok
@@ -1771,8 +1779,8 @@ hu:
link_your_account: "Először össze kell kapcsolnia fiókját a DFC (Les Communs Open ID Connect) által használt jogosultságszolgáltatóval."
link_account_button: "Kapcsold össze a Les Communs OIDC-fiókod"
note_expiry: |
A csatlakoztatott alkalmazások elérésére szolgáló tokenek lejártak. Kérjük, frissítse
a fiókkapcsolat, hogy minden integráció működjön.
A csatlakoztatott alkalmazások elérésére szolgáló tokenek lejártak. Kérjük, frissítsd
a fiókkapcsolatot, hogy minden integráció működjön.
refresh: "Jogosultság frissítése"
view_account: "Fiókod megtekintése, lásd:"
subscriptions:
@@ -1812,11 +1820,11 @@ hu:
details: 1. Alapvető részletek
address: 2. Cím
products: 3. Termékek hozzáadása
review: 4. Tekintse át és mentse el
review: 4. Áttekintés és mentés
subscription_line_items:
this_is_an_estimate: |
The displayed prices are only an estimate and calculated at the time the subscription is changed.: A megjelenített árak csak becslések, és az előfizetés megváltoztatásakor számíthatók ki.
If you change prices or fees, orders will be updated, but the subscription will still display the old values.: Ha módosítja az árakat vagy díjakat, a rendelések frissítésre kerülnek, de az előfizetés továbbra is a régi értékeket jeleníti meg.
A megjelenített árak csak becslések, és az előfizetés megváltoztatásakor számíthatók ki.
Ha módosítod az árakat vagy díjakat, a rendelések frissítésre kerülnek, de az előfizetés továbbra is a régi értékeket jeleníti meg.
not_in_open_and_upcoming_order_cycles_warning: "Ehhez a termékhez nincsenek nyitott vagy közelgő rendelési ciklusok."
autocomplete:
name_or_sku: "NÉV VAGY Cikkszám"
@@ -1843,7 +1851,7 @@ hu:
save: "MENTÉS"
saving: "MENTÉS"
saved: "MENTETT"
product_already_in_order: Ez a termék már felkerült a rendelésre. Kérjük, módosítsa közvetlenül a mennyiséget.
product_already_in_order: Ez a termék már szerepel a rendelésben. Kérjük, módosítsd ott a mennyiséget.
stock:
insufficient_stock: "Nem áll rendelkezésre elegendő készlet"
out_of_stock: "Nincs raktáron"
@@ -1857,12 +1865,12 @@ hu:
confirm_unpause_msg: "Ha az előfizetés ütemtervében van egy nyitott rendelési ciklus, akkor ennek az ügyfélnek a rendelése jön létre. Biztosan feloldja az előfizetés szüneteltetését?"
unpause_failure_msg: "Sajnáljuk, a szüneteltetés feloldása nem sikerült!"
confirm_cancel_open_orders_msg: "Az előfizetéshez tartozó néhány rendelés jelenleg nyitva van. A vásárlót már értesítették a rendelés feladásáról. Szeretné törölni vagy megtartani ezeket a rendelése(ke)t?"
resume_canceled_orders_msg: "Az előfizetéshez tartozó egyes rendelések már most újraindíthatók. A megrendelések legördülő menüből folytathatja őket."
resume_canceled_orders_msg: "Néhány ehhez az előfizetéshez tartozó rendelés már most újraindítható. Azokat a megrendelések legördülő menüből indíthatod újra."
yes_cancel_them: Törölje őket
no_keep_them: Tartsd meg
yes_i_am_sure: Igen, biztos vagyok benne
number: "Szám"
order_update_issues_msg: Egyes rendeléseket nem sikerült automatikusan frissíteni, ez valószínűleg azért van, mert manuálisan szerkesztették. Kérjük, tekintse át az alább felsorolt problémákat, és szükség esetén végezzen módosításokat az egyes rendeléseken.
order_update_issues_msg: Egyes rendeléseket nem sikerült automatikusan frissíteni, ez valószínűleg azért van, mert manuálisan szerkesztették. Kérjük, tekintsd át az alább felsorolt problémákat, és szükség esetén végezz módosításokat a rendeléseken.
no_results:
no_subscriptions: Még nincs előfizetés...
why_dont_you_add_one: Miért nem adsz hozzá egyet? :)
@@ -1899,7 +1907,7 @@ hu:
api:
unknown_error: "Valami elromlott. Csapatunk értesítést kapott."
invalid_api_key: "Érvénytelen API-kulcs (%{key}) van megadva."
unauthorized: "Ön nem jogosult ennek a műveletnek a végrehajtására."
unauthorized: "Nem vagyok jogosult ennek a műveletnek a végrehajtására."
unpermitted_parameters: "A kérésben nem megengedett paraméterek: %{params}"
missing_parameter: "Egy kötelező paraméter hiányzik vagy üres: %{param}"
invalid_resource: "Érvénytelen erőforrás. Javítsa ki a hibákat, és próbálja újra."
@@ -1917,7 +1925,7 @@ hu:
title: Érvénytelen lekérdezési paraméter
extra_fields: "Nem támogatott területek: %{fields}"
checkout:
failed: "A fizetés nem sikerült. Kérjük, jelezze felénk, hogy feldolgozhassuk megrendelését."
failed: "A fizetés nem sikerült. Kérjük, jelezd felénk, hogy feldolgozhassuk a megrendelésed."
payment_cancelled_due_to_stock: "Fizetés törölve: a fizetés készlethiba miatt nem fejezhető be."
order_not_loaded: "Nem található érvényes rendelés a fizetés feldolgozásához"
your_details_without_number: Az adataid
@@ -1971,9 +1979,9 @@ hu:
label: Év
stripe:
use_saved_card: Használd a mentett kártyát
use_new_card: Adja meg kártyaazonosítóit
save_card: Mentse el a kártyát későbbi használatra
create_new_card: vagy adja meg alább az új kártyaadatokat
use_new_card: Add meg kártyaazonosítóit
save_card: Kártya mentése későbbi használatra
create_new_card: vagy add meg alább az új kártyaadatokat
explaination: A következő lépésben megtekintheted és megerősítheted megrendelésedet, amely tartalmazza a várható költségeket. Amennyiben "Változó súlyú termék" jelölésű terméket rendeltél, a végösszeg a pontos súlyok függvényében változhat.
submit: Következő - Megrendelés összegzése
cancel: Vissza az adataidhoz
@@ -2013,10 +2021,10 @@ hu:
terms_not_accepted: 'Kérjük, fogadd el az Adatvédelmi Tájékoztatót és az Általános Szerződési Feltételeket '
required: A mező nem lehet üres
invalid_number: "Adj meg egy érvényes telefonszámot"
invalid_email: "Kérjük valós e-mail címet adj meg"
invalid_email: "Kérjük, valós e-mail címet adj meg"
select_a_shipping_method: Válassz áruátvételi módot!
select_a_payment_method: Válassz fizetési módot
no_shipping_methods_available: Átvételi és szállítási lehetőségek hiánya miatt a fizetés nem lehetséges. Kérjük, lépjen kapcsolatba az üzlet tulajdonosával.
no_shipping_methods_available: Átvételi és szállítási lehetőségek hiánya miatt a fizetés nem lehetséges. Kérjük, lépj kapcsolatba az üzlet tulajdonosával.
voucher_code_blank: Kérjük, valós kupon kódot adj meg
add_voucher_error: Hiba történt a kupon hozzáadása során
voucher_redeeming_error: Hiba történt a kupon beváltásakor
@@ -2144,19 +2152,19 @@ hu:
phone: Telefon
next: Következő
address: Cím
address_placeholder: például Saláta köz 15.
address_placeholder: pl. Saláta köz 15.
address2: Cím (folyt.)
city: Város
city_placeholder: például Kukutyin
city_placeholder: pl. Kukutyin
latitude: Szélességi kör
latitude_placeholder: például -37.4713077
latitude_placeholder: pl. -37.4713077
latitude_longitude_tip: A szélességi kör és a hosszúsági fok szükséges ahhoz, hogy a vállalkozásod megjelenjen a térképen.
longitude: Hosszúsági fok
longitude_placeholder: például 144.7851531
longitude_placeholder: pl. 144.7851531
use_geocoder: Próbálja automatikusan kiszámítani a szélességi kört és hosszúsági fokot a címből?
state: Megye
postcode: Irányítószám
postcode_placeholder: például 3070
postcode_placeholder: pl. 3070
suburb: Település
country: Ország
unauthorized: Jogosulatlan
@@ -2224,7 +2232,7 @@ hu:
cookie_domain: "Által meghatározott:"
cookie_session_desc: "Arra szolgál, hogy a webhely emlékezzen a felhasználókra az oldalváltások között, például emlékezzen a kosárban lévő tételekre."
cookie_consent_desc: "A sütik tárolására vonatkozó felhasználói hozzájárulás állapotának fenntartására szolgál"
cookie_remember_me_desc: "Akkor használatos, ha a felhasználóként arra kérted a webhelyet, hogy emlékezzen rád. Ez a süti 12 nap elteltével automatikusan törlődik. Ha felhasználóként szeretnéd törölni a sütit, csak ki kell jelentkezned. Ha nem szeretnéd, hogy a süti telepítve legyen a számítógépedre, ne jelöld be az „emlékezz rám” jelölőnégyzetet bejelentkezéskor."
cookie_remember_me_desc: "Akkor használjuk, ha a felhasználóként megkéred a weboldalt, hogy emlékezzen rád. Ez a süti 12 nap után automatikusan törlődik. Ha felhasználóként szeretnéd törölni a sütit, csak ki kell jelentkezned. Ha nem szeretnéd, hogy a süti települjön, ne jelöld be az „emlékezz rám” jelölőnégyzetet bejelentkezéskor."
cookie_openstreemap_desc: "Ezt a sütit barátságos, nyílt forráskódú térképszolgáltatónk (OpenStreetMap) használja annak biztosítására, hogy egy adott időszakon belül ne kapjon túl sok kérést, és megakadályozza a szolgáltatásaikkal való visszaélést."
cookie_stripe_desc: "A Stripe fizetési szolgáltató által a csalások felderítése céljából gyűjtött adatok https://stripe.com/cookies-policy/legal. Nem minden átvételi pont vagy termelő használja a Stripe-ot fizetési módszerként, de a csalás megelőzése érdekében jó gyakorlat, hogy minden oldalon alkalmazzuk. A Stripe valószínűleg képet alkot arról, hogy mely oldalaink lépnek általában kapcsolatba az API-jukkal, majd minden szokatlant megjelöl. A Stripe cookie beállításának tehát szélesebb funkciója van, mint egyszerűen a fizetési mód biztosítása a felhasználó számára. Eltávolítása befolyásolhatja magának a szolgáltatásnak a biztonságát. A Stripe-ról többet megtudhatsz, és elolvashatod adatvédelmi irányelveit a https://stripe.com/privacy oldalon."
statistics_cookies: "Statisztikai sütik"
@@ -2364,16 +2372,16 @@ hu:
email_so_placement_details_html: "A megrendelésed részletei <strong>%{distributor}</strong>:"
email_so_placement_changes: "Sajnos nem minden kért termék volt elérhető. Az általad kért eredeti mennyiségek alább áthúzva jelennek meg."
email_so_payment_success_intro_html: "A megrendelés automatikus fizetése megtörtént <strong>%{distributor}</strong> felé."
email_so_placement_explainer_html: "Ez a rendelés automatikusan létrejött az Ön számára."
email_so_placement_explainer_html: "Ez a rendelés automatikusan létrejött számodra."
email_so_edit_true_html: "Addig <a href='%{order_url}'>módosításokat hajthat végre</a>, amíg a rendelések le nem zárulnak a következő napon: %{orders_close_at}."
email_so_edit_false_html: "Bármikor <a href='%{order_url}'>megtekintheti a rendelés részleteit</a>."
email_so_edit_false_html: "Bármikor <a href='%{order_url}'>megtekintheted a rendelés részleteit</a>."
email_so_contact_distributor_html: "Ha bármilyen kérdésed van, itt érdeklődj: <strong>%{distributor}</strong>, %{email} ."
email_so_contact_distributor_to_change_order_html: "Ez a rendelés automatikusan létrejött számodra. Ha módosítási igényed van, %{orders_close_at} napon a rendelések lezárásáig jelezd itt: <strong>%{distributor}</strong>, %{email} ."
email_so_confirmation_intro_html: " <strong>%{distributor} </strong> megerősítette a rendelésedet."
email_so_confirmation_explainer_html: "Ezt a rendelést automatikusan feladtuk Önnek, és most már véglegesítettük."
email_so_confirmation_explainer_html: "Ezt a rendelést automatikusan feladtuk neked, és most már véglegesítettük."
email_so_confirmation_details_html: "Itt van minden, amit tudnod kell a <strong>%{distributor}</strong>-tól származó megrendeléseddel kapcsolatban:"
email_so_empty_intro_html: "Megpróbáltunk új rendelést leadni a <strong>%{distributor}</strong> szolgáltatónál, de volt néhány probléma..."
email_so_empty_explainer_html: "Sajnos az Ön által megrendelt termékek egyike sem volt elérhető, ezért rendelés nem történt. Az Ön által kért eredeti mennyiségek alább áthúzva jelennek meg."
email_so_empty_explainer_html: "Sajnos az általad megrendelt termékek egyike sem volt elérhető, ezért rendelés nem történt. Az általad kért eredeti mennyiségek alább áthúzva jelennek meg."
email_so_empty_details_html: "Itt vannak a(z) <strong>%{distributor}</strong> el nem adott rendelés részletei:"
email_so_failed_payment_intro_html: "Megpróbáltuk feldolgozni a befizetést, de volt néhány probléma..."
email_so_failed_payment_explainer_html: "A(z) <strong>%{distributor}</strong> előfizetésed kifizetése hitelkártyájával kapcsolatos probléma miatt meghiúsult. <strong>%{distributor}</strong> értesítést kapott erről a sikertelen fizetésről."
@@ -2395,7 +2403,7 @@ hu:
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ást."
set_a_password: "Ezután a rendszer kéri, hogy állíts be egy jelszót, mielőtt felügyeled a vállalkozást."
mistakenly_sent: "Nem tudod, miért kaptad ezt az e-mailt? További információért fordulj %{owner_email}-hoz."
producer_mail_greeting: "Kedves"
producer_mail_text_before: "Küldjük az alábbi rendelési ciklusra vonatkozó összesítést:"
@@ -2443,11 +2451,11 @@ hu:
hubs_distance: Legközelebb
hubs_distance_filter: "Mutass átvételi pontokat %{location} közelében"
shop_changeable_orders_alert_html:
one: 'Megrendelése a következővel: <a href=''%{path}'' target=''_blank''>%{shop} / %{order}</a> nyitva áll ellenőrzésre. A módosításokat a következő időpontig hajthatja végre: %{oc_close}.'
one: 'Megrendelésed a következővel: <a href=''%{path}'' target=''_blank''>%{shop} / %{order}</a> nyitva áll ellenőrzésre. A módosításokat a következő időpontig hajthatod végre: %{oc_close}.'
few: '<a href=''%{path}'' target=''_blank''>%{count} rendelése van a(z) %{shop}</a>-nál jelenleg ellenőrzésre nyitva. A módosításokat a következő időpontig végezhetsz: %{oc_close}.'
many: '<a href=''%{path}'' target=''_blank''>%{count} rendelése van a(z) %{shop}</a>-nál jelenleg ellenőrzésre nyitva. A módosításokat a következő időpontig végezhetsz: %{oc_close}.'
other: '<a href=''%{path}'' target=''_blank''>%{count} rendelése van a(z) %{shop}</a>-nál jelenleg ellenőrzésre nyitva. A módosításokat a következő időpontig végezhetsz: %{oc_close}.'
orders_changeable_orders_alert_html: 'Ezt a rendelést megerősítették, de módosíthatja a következőt: <strong>%{oc_close}</strong>.'
orders_changeable_orders_alert_html: 'Ez a rendelés meg lett erősítve, de módosíthatod a következő időpontig: <strong>%{oc_close}</strong>.'
products_clear: Mégsem
products_showing: "Megjelenítve:"
products_results_for: "eredmények"
@@ -2590,7 +2598,7 @@ hu:
orders_show_confirmed: "Megerősített"
orders_your_order_has_been_cancelled: "Megrendelését töröltük"
orders_could_not_cancel: "Sajnáljuk, a rendelést nem lehetett törölni"
orders_cannot_remove_the_final_item: "Az utolsó tétel nem távolítható el a rendelésből, kérjük, inkább törölje a rendelést."
orders_cannot_remove_the_final_item: "Az utolsó tétel nem távolítható el a rendelésből, helyette töröld a rendelést."
orders_bought_items_notice:
one: "Ehhez a rendelési ciklushoz egy további tétel már visszaigazolásra került"
few: "%{count} további tétel már megerősítve ehhez a rendelési ciklushoz"
@@ -2601,7 +2609,7 @@ hu:
orders_confirm_cancel: "Biztosan törlöd ezt a rendelést?"
order_processed_successfully: "Megrendelésed sikeresen feldolgoztuk"
thank_you_for_your_order: "Köszönjük a rendelésed!"
products_cart_distributor_choice: "Megrendelését az alábbi szervezet szolgáltatja:"
products_cart_distributor_choice: "Megrendelésed szolgáltatója:"
products_cart_distributor_change: "Ennek a rendelésnek a forgalmazója a következőre változik: %{name}, ha ezt a terméket a kosarába helyezi."
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."
@@ -2720,8 +2728,8 @@ hu:
phone_field: "Telefonszám"
whatsapp_phone_field: "WhatsApp telefonszám"
whatsapp_phone_tooltip: "Ez a szám a nyilvános profilodban látszódni fog, mint WhatsApp link."
phone_field_placeholder: "például +36 30 1234 567"
whatsapp_phone_field_placeholder: "például +36 20 123 5678"
phone_field_placeholder: "pl. +36 30 1234 567"
whatsapp_phone_field_placeholder: "pl. +36 20 123 5678"
type:
title: "Típus"
headline: "Utolsó lépés %{enterprise} profil létrehozásához!"
@@ -2744,9 +2752,9 @@ hu:
enterprise_long_desc_placeholder: "Itt a lehetőség, hogy elmeséld vállalkozásod történetét mitől vagy más és különleges? Javasoljuk, hogy a leírás ne haladja meg a 600 karaktert vagy 150 szót."
enterprise_long_desc_length: "%{num} karakter / legfeljebb 600 ajánlott"
enterprise_abn: "Cégjegyzékszám"
enterprise_abn_placeholder: "például 12345678-2-19"
enterprise_abn_placeholder: "pl. 12345678-2-19"
enterprise_acn: "Adószám"
enterprise_acn_placeholder: "például 01-09-562739"
enterprise_acn_placeholder: "pl. 01-09-562739"
enterprise_tax_required: "Ki kell választani."
images:
title: "Képek"
@@ -2776,15 +2784,15 @@ hu:
enterprise_final_step: "Utolsó lépés!"
enterprise_social_text: "Hogyan találhatják meg az emberek a %{enterprise}-t online?"
website: "Weboldal"
website_placeholder: "például openfoodnetwork.org.au"
website_placeholder: "pl. openfoodnetwork.org.au"
facebook: "Facebook"
facebook_placeholder: "például www.facebook.com/OldalNev"
facebook_placeholder: "pl. www.facebook.com/OldalNeve"
linkedin: "LinkedIn"
linkedin_placeholder: "például www.linkedin.com/neved"
linkedin_placeholder: "pl. www.linkedin.com/neved"
twitter: "Twitter"
twitter_placeholder: "például @twitter_handle"
twitter_placeholder: "pl. @twitter_handle"
instagram: "Instagram"
instagram_placeholder: "például @instagram_handle"
instagram_placeholder: "pl. @instagram_handle"
limit_reached:
headline: "Ó ne!"
message: "Elérted a korlátot!"
@@ -2854,16 +2862,16 @@ hu:
admin_enterprise_groups_data_powertip: "A csoportért felelős elsődleges felhasználó."
admin_enterprise_groups_data_powertip_logo: "Ez a csoport logója"
admin_enterprise_groups_data_powertip_promo_image: "Ez a kép a Csoport profil tetején jelenik meg"
admin_enterprise_groups_contact_phone_placeholder: "például 98 7654 3210"
admin_enterprise_groups_contact_address1_placeholder: "például Saláta köz 15."
admin_enterprise_groups_contact_phone_placeholder: "pl. +36 20 654 3210"
admin_enterprise_groups_contact_address1_placeholder: "pl. Saláta köz 15."
admin_enterprise_groups_contact_city: "Település"
admin_enterprise_groups_contact_city_placeholder: "például Kukutyin"
admin_enterprise_groups_contact_city_placeholder: "pl. Kukutyin"
admin_enterprise_groups_contact_zipcode: "Irányítószám"
admin_enterprise_groups_contact_zipcode_placeholder: "például 3070"
admin_enterprise_groups_contact_zipcode_placeholder: "pl. 3070"
admin_enterprise_groups_contact_state_id: "Megye"
admin_enterprise_groups_contact_country_id: "Ország"
admin_enterprise_groups_web_twitter: "például @the_prof"
admin_enterprise_groups_web_website_placeholder: "például www.truffles.com"
admin_enterprise_groups_web_twitter: "pl. @the_prof"
admin_enterprise_groups_web_website_placeholder: "pl. www.pecsikosar.hu"
admin_order_cycles: "Admin Rendelési Ciklusok"
open: "Nyit"
close: "Bezárás"
@@ -2883,13 +2891,13 @@ hu:
delivery_method: Áruátvételi Mód
fee_type: "Díjtípus"
tax_category: "Adókategória"
display: "Kijelző"
display: "Megjelenítés"
tags: "Címkék"
calculator: "Kiszámítási mód"
calculator_values: "Kiszámítás értékek"
calculator_settings_warning: "Ha módosítod a kiszámítás típusát, először mentened kell ahhoz, hogy szerkeszthesd a kiszámítás beállításait"
calculator_preferred_unit_error: "kg-nak vagy lb-nak kell lennie"
calculator_preferred_value_error: "Hibás bemenet. Kérjük, csak számokat használj. Például: 10, 5.5, -20"
calculator_preferred_value_error: "Hibás bemenet. Kérjük, csak számokat használj. Pl.: 10, 5.5, -20"
flat_percent_per_item: "Egységes százalék (tételenként)"
flat_rate_per_item: "Átalánydíj (tételenként)"
flat_rate_per_order: "Átalánydíj (rendelésenként)"
@@ -2918,8 +2926,8 @@ hu:
product: "Termék"
price: "Ár"
review: "Felülvizsgálat"
save_changes: "Változtatások Mentése"
order_saved: "Rendelés Mentve"
save_changes: "Változtatások mentése"
order_saved: "Rendelés mentve"
no_products: Nincsenek termékek
spree_admin_overview_enterprises_header: "Vállalkozásaim"
spree_admin_overview_enterprises_footer: "VÁLLALKOZÁSAIM KEZELÉSE"
@@ -2936,10 +2944,10 @@ hu:
unit_name: "Egység neve"
change_package: "Felhasználótípus módosítása"
spree_admin_single_enterprise_hint: "Tipp: Ha szeretnéd, hogy mások megtaláljanak, állítsd a profilod láthatóságát nyilvánosra alább: "
spree_admin_eg_pickup_from_school: "például \"Átvétel az általános iskolában\""
spree_admin_eg_collect_your_order: "például \"Kérjük, vedd át rendelésed a Képzelt utca 12-es címen\""
spree_admin_eg_pickup_from_school: "pl. \"Átvétel az általános iskolában\""
spree_admin_eg_collect_your_order: "pl. \"Kérjük, vedd át rendelésed a Képzelt utca 12-es címen\""
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_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álassz másikat."
spree_order_cycle_error: "Kérjük, válassz rendelési ciklust ehhez a rendeléshez."
spree_order_populator_availability_error: "Ez a termék nem elérhető a kiválasztott forgalmazótól vagy rendelési ciklusban."
spree_distributors_error: "Legalább egy Átvételi Pontot ki kell választani"
@@ -3221,7 +3229,7 @@ hu:
shipping_methods: "Áruátadási módok"
payment_methods: "Fizetési módok"
payment_method_fee: "Tranzakciós díj"
payment_processing_failed: "A fizetést nem sikerült feldolgozni, kérjük ellenőrizd a megadott adatokat"
payment_processing_failed: "A fizetést nem sikerült feldolgozni, kérjük, ellenőrizd a megadott adatokat"
payment_method_not_supported: "Ez a fizetési mód nem támogatott. Kérjük, válassz másikat."
payment_updated: "Fizetés frissítve"
cannot_perform_operation: "Nem sikerült frissíteni a fizetést"
@@ -3249,7 +3257,7 @@ hu:
product_import_inventory_disable: Importálás leltár termékek közé nem lehetséges
order_choosing_hub_notice: Átvételi pontod ki lett választva.
order_cycle_selecting_notice: Megrendelési ciklusod kiválasztásra került.
adjustments_tax_rate_error: "^Kérjük, ellenőrizze, hogy az adókulcs megfelelő-e ehhez a korrekcióhoz."
adjustments_tax_rate_error: "^Kérjük, ellenőrizd, hogy a módosításhoz tartozó adókulcs helyes-e."
active_distributors_not_ready_for_checkout_message_singular: >-
%{distributor_names} szerepel egy aktív rendelési ciklusban, de nincs érvényes
szállítási és fizetési mód beállítva hozzá. Amíg ezeket nem állítod be, a fogyasztók
@@ -3268,7 +3276,7 @@ hu:
order_cycles_bulk_update_notice: 'A rendelési ciklusok frissítve.'
order_cycles_no_permission_to_coordinate_error: "Egyik vállalkozásod sem rendelkezik engedéllyel egy rendelési ciklus koordinálására"
order_cycles_no_permission_to_create_error: "Nincs engedélye az adott vállalkozás által koordinált rendelési ciklus létrehozására"
order_cycle_closed: "A kiválasztott rendelési ciklus éppen most zárult le. Kérjük próbáld újra!"
order_cycle_closed: "A kiválasztott rendelési ciklus éppen most zárult le. Kérjük, próbáld újra!"
back_to_orders_list: "Vissza a rendelési listához"
no_orders_found: "Nem található rendelés"
order_information: "Rendelési információ"
@@ -3347,7 +3355,7 @@ hu:
message_1: "Minden vásárlónak egyszer el kell fogadnia ezeket a fizetéskor. Ha frissíted a fájlt, minden vásárlónak újra el kell fogadnia azokat a fizetéskor."
message_2: "Az előfizetéssel rendelkező vásárlóknak egyelőre e-mailben el kell küldened az Adatkezelési Tájékoztatót és az Általános Szerződési Feltételeket (vagy azok módosításait), mivel más értesítést nem kapnak a dokumentum frissítéséről."
business_address_info:
message: "A cég hivatalos neve, címe és telefonszáma olyan vállalkozásoknál használatos, amelyek nyilvános kereskedési adataiktól eltérő hivatalos adatokkal bejegyzett jogi személytől számláznak. Ezeket az adatokat CSAK számlákon használjuk fel. Ha ezek az adatok üresek, az Ön nyilvános neve, címe és telefonszáma kerül felhasználásra a számlákon."
message: "A cég hivatalos neve, címe és telefonszáma olyan vállalkozásoknál használatos, amelyek nyilvános kereskedési adataiktól eltérő hivatalos adatokkal bejegyzett jogi személytől számláznak. Ezeket az adatokat CSAK számlákon használjuk fel. Ha ezek az adatok üresek, az nyilvános neved, címed és telefonszámod kerül felhasználásra a számlákon."
panels:
save: MENTÉS
saved: MENTETT
@@ -3379,7 +3387,7 @@ hu:
csomagot a listából.: opciók a bal oldalon.
choose_package_text2: >
Kattints egy opcióra, hogy részletesebb információt kapj az egyes csomagokról,
és nyomja meg a piros MENTÉS gombot, ha végeztél!
és nyomd meg a piros MENTÉS gombot, ha végeztél!
profile_only: Csak profil
profile_only_cost: "KÖLTSÉG: MINDIG INGYENES"
profile_only_text1: >
@@ -3399,7 +3407,7 @@ hu:
producer_shop_text2: >
A Termelői Értékesítési Pont kizárólag a saját termékeid értékesítésére
szolgál. Ha nem csak a saját magad által termelt/előállított terméket
szeretnél értékesíteni, kérjük válaszd a „Termelői Átvételi Pont” lehetőséget.
szeretnél értékesíteni, kérjük, válaszd a „Termelői Átvételi Pont” lehetőséget.
producer_hub: Termelői Átvételi Pont
producer_hub_text1: >
Szervezeted a helyi élelmezési rendszer csomópontja. Más termelőktől
@@ -3450,7 +3458,7 @@ hu:
select_all_variants: "Válaszd ki az összes %{total_number_of_variants} változatot"
variants_loaded: "%{num_of_variants_loaded}/%{total_number_of_variants} változat betöltve"
loading_variants: "Változatok betöltése"
no_variants: "Nincs elérhető termékváltozat ehhez a termékhez (a készletbeállításokban rejtett státuszúak)."
no_variants: "Nincs elérhető termékváltozat ehhez a termékhez (a leltár beállításokban rejtett státuszúak)."
some_variants_hidden: "(Egyes termékváltozatok a leltárbeállítások miatt rejtve maradhatnak)"
tag_rules:
shipping_method_tagged_top: "Áruátadási módok felcímkézve"
@@ -3459,7 +3467,7 @@ hu:
payment_method_tagged_bottom: "vannak:"
order_cycle_tagged_top: "Rendelési ciklusok felcímkézve"
order_cycle_tagged_bottom: "vannak:"
inventory_tagged_top: "Készletváltozatok felcímkézve"
inventory_tagged_top: "Leltár változatok felcímkézve"
inventory_tagged_bottom: "vannak:"
new_tag_rule_dialog:
select_rule_type: "Válassz egy szabálytípust:"
@@ -3542,7 +3550,7 @@ hu:
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"
customer_placeholder: "ügyfél@example.org"
valid_email_error: "Kérjük valós e-mail címet adj meg"
valid_email_error: "Kérjük, valós e-mail címet adj meg"
subscriptions:
error_saving: "Hiba az előfizetés mentése közben"
new:
@@ -3579,7 +3587,7 @@ hu:
use_producer_settings: "Használd a termelői készletbeállításokat"
'yes': "Igen"
'no': "Nem"
inventory_products: "Készlettermékek"
inventory_products: "Leltár termékek"
hidden_products: "Rejtett Termékek"
new_products: "Új Termékek"
reset_stock_levels: Állítsd vissza a készletszinteket az alapértelmezett értékekre
@@ -3606,7 +3614,7 @@ hu:
add_to_order_cycle: "rendelési ciklushoz adás"
manage_products: "termékek kezelése"
edit_profile: "profil szerkesztése"
add_products_to_inventory: "termékek hozzáadása a készlethez"
add_products_to_inventory: "termékek hozzáadása a leltárhoz"
resources:
could_not_delete_customer: 'Nem sikerült törölni az ügyfelet'
product_import:
@@ -3870,7 +3878,7 @@ hu:
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"
name_or_sku: "Név vagy cikkszám (adja meg a termék nevének legalább első 4 karakterét)"
name_or_sku: "Név vagy cikkszám (gépelj be legalább 3 karaktert a termék nevéből)"
resend: "Újraküldés"
back_to_orders_list: "Vissza a rendelési listához"
back_to_payments_list: "Vissza a fizetési listához"
@@ -3940,9 +3948,9 @@ hu:
default_meta_keywords: "Alapértelmezett metakulcsszavak"
currency_decimal_mark: "Pénznem tizedesjegye"
currency_settings: "Pénznem beállításai"
currency_symbol_position: Tedd a "valuta szimbólumot az összeg elé vagy után?"
currency_symbol_position: Valuta szimbólum az összeg előtt vagy után legyen?
currency_thousands_separator: "Pénznem ezres elválasztó"
hide_cents: "Centek elrejtése"
hide_cents: "Fillérek elrejtése"
display_currency: "Megjelenítési pénznem"
choose_currency: "Válasszon pénznemet"
mail_method_settings: "Levelezési mód beállításai"
@@ -3998,7 +4006,7 @@ hu:
default: "alapértelmezett"
calculator: "Díjszámítási mód"
zone: "Zóna"
display: "Kijelző"
display: "Megjelenítés"
environment: "Környezet"
active: "Aktív"
nore: "Több"
@@ -4040,7 +4048,7 @@ hu:
successfully_created: '%{resource} sikeresen létrehozva!'
successfully_updated: '%{resource} sikeresen frissítve!'
payment_method: "Fizetési mód"
payment_processing_failed: "A fizetést nem sikerült feldolgozni, kérjük ellenőrizze a megadott adatokat"
payment_processing_failed: "A fizetést nem sikerült feldolgozni, kérjük, ellenőrizd a megadott adatokat"
not_available: "N/A"
sku: "SKU"
there_are_no_items_for_this_order: "Nincsenek tételek ehhez a rendeléshez."
@@ -4168,7 +4176,7 @@ hu:
add_product:
cannot_add_item_to_canceled_order: "A törölt rendeléshez nem lehet tételt hozzáadni"
cannot_add_item_to_shipped_order: "Lezárt rendeléshez nem adható hozzá további tétel"
include_out_of_stock_variants: "Tartalmazza azokat a változatokat, amelyeknél nincs raktárkészlet"
include_out_of_stock_variants: "Mutassa a készleten nem lévő termékeket is"
shipment:
mark_as_shipped_message_html: "Ezzel a megrendelést KISZÁLLÍTVA-ként jelölöd meg. Biztos, hogy folytatni szeretnéd?"
mark_as_shipped_label_message: "Szállítási/átvételi értesítő e-mail küldése az ügyfélnek."
@@ -4244,13 +4252,13 @@ hu:
products_tip: "A termékek, melyeket az Open Food hálózatán keresztül kínálsz"
active_products:
zero: "Nincsenek aktív termékeid."
one: "Egy aktív terméke van"
few: "%{count} aktív terméke van"
many: "%{count} aktív terméke van"
other: "%{count} aktív terméke van"
one: "Egy aktív terméked van"
few: "%{count} aktív terméked van"
many: "%{count} aktív terméked van"
other: "%{count} aktív terméked van"
order_cycles:
order_cycles: "Rendelési ciklusok"
order_cycles_tip: "A rendelési ciklusok határozzák meg, hogy a termékei mikor és hol állnak az ügyfelek rendelkezésére."
order_cycles_tip: "A rendelési ciklusok határozzák meg, hogy a termékeid mikor és hol állnak az ügyfelek rendelkezésére."
you_have_active:
zero: "Nincsenek aktív rendelési ciklusaid."
one: "Egy aktív rendelési ciklusod van."
@@ -4310,7 +4318,7 @@ hu:
back_to_payment_methods_list: "Vissza a fizetési módok listájához"
stripe_connect:
enterprise_select_placeholder: Választ...
loading_account_information_msg: Számlainformációk betöltése a csíkból, kérlek várj...
loading_account_information_msg: Számlainformációk betöltése a Stripe-ból, kérk várj...
stripe_disabled_msg: A Stripe fizetést a rendszergazda letiltotta.
request_failed_msg: Sajnálom. Hiba történt, amikor megpróbáltuk ellenőrizni a fiók adatait a Stripe segítségével...
account_missing_msg: Ehhez a vállalkozáshoz nem tartozik Stripe-fiók.
@@ -4368,7 +4376,7 @@ hu:
on_demand: "Igény szerint"
product_description: "Termékleírás"
image: "Kép"
unit_name_placeholder: 'például csokrok'
unit_name_placeholder: 'pl. csokrok'
index:
header:
title: Termékek tömeges szerkesztése
@@ -4447,8 +4455,8 @@ hu:
unit_price: "Egységár"
display_as: "Megjelenítés mint"
display_name: "Alternatív név"
display_as_placeholder: 'például 2 kg'
display_name_placeholder: 'például paradicsom'
display_as_placeholder: 'pl. 2 kg'
display_name_placeholder: 'pl. paradicsom'
unit_scale: "Mértékegység skála"
unit: Mértékegység
price: Ár
@@ -4504,13 +4512,13 @@ hu:
payment:
stripe:
choose_one: Válasszon
enter_new_card: Adja meg az új kártya adatait
enter_new_card: Add meg az új kártya adatait
used_saved_card: "Mentett kártya használata:"
or_enter_new_card: "Vagy adja meg az új kártya adatait:"
or_enter_new_card: "Vagy add meg az új kártya adatait:"
remember_this_card: Emlékszel erre a kártyára?
stripe_sca:
choose_one: Válassz egyet
enter_new_card: Adja meg az új kártya adatait
enter_new_card: Add meg az új kártya adatait
used_saved_card: "Mentett kártya használata:"
or_enter_new_card: "Vagy add meg az új kártya adatait:"
remember_this_card: Emlékezzen erre a kártyára?
@@ -4573,7 +4581,7 @@ hu:
invoice_attached_text: Mellékelten talál egy összesítőt a legutóbbi rendeléséről
user_mailer:
reset_password_instructions:
dear_customer: "Kedves Fogyasztó,"
dear_customer: "Kedves Megrendelő,"
request_sent_text: |
Jelszó visszaállítására irányuló kérés érkezett.
Ha nem te nyújtottad be ezt a kérést, egyszerűen hagyd figyelmen kívül ezt az e-mailt.
@@ -4587,7 +4595,7 @@ hu:
subject: "Kérjük, erősítsd meg Open Food fiókod"
payment_mailer:
authorize_payment:
subject: "Kérjük, engedélyezd fizetést %{distributor} részére az Open Food-on"
subject: "Kérjük, engedélyezd a fizetést %{distributor} részére az Open Food-on"
instructions: "%{amount} összegű befizetésed %{distributor} részére további hitelesítést igényel. Kérjük, keresd fel a következő URL-t a fizetés engedélyezéséhez:"
authorization_required:
subject: "A fizetéshez az ügyfél engedélye szükséges"
@@ -4598,10 +4606,10 @@ hu:
instructions: "Megrendelésed a(z) %{distributor}-tól elküldtük"
shipment_summary: "Szállítási összefoglaló"
subject: "Szállítási értesítés"
thanks: "Köszönjük üzletét."
thanks: "Köszönjük az üzletet."
track_information: "Követési információ: %{tracking}"
track_link: "! Követő link: %{url}"
picked_up_instructions: "Az Ön megrendelését %{distributor}termelőtől felvettük."
picked_up_instructions: "A megrendelésed %{distributor}termelőtől felvettük."
picked_up_subject: "Átvételi értesítés/megjegyzés"
test_mailer:
test_email:
@@ -4740,7 +4748,7 @@ hu:
distance_in_words:
about_x_hours:
one: kb 1 óra
other: kb %{count} óra
other: körülbelül %{count} óra
about_x_months:
one: kb 1 hónap
other: körülbelül %{count} hónap
@@ -4789,5 +4797,5 @@ hu:
tag_list_input:
default_placeholder: Adj hozzá egy címkét
invisible_captcha:
sentence_for_humans: "Kérjük hagyd üresen"
sentence_for_humans: "Kérjük, hagyd üresen"
timestamp_error_message: "Kérjük, próbáld meg 5 másodperc múlva."

View File

@@ -30,8 +30,7 @@ module DfcProvider
# - Spree::Shipment
# - Subscription
def authorized(address)
current_user.ship_address_id == address.id ||
current_user.bill_address_id == address.id ||
user_address(address) ||
[
customer_address(address),
public_enterprise_group_address(address),
@@ -40,6 +39,13 @@ module DfcProvider
].any?(&:exists?)
end
def user_address(address)
return false if current_user.is_a? ApiUser
current_user.ship_address_id == address.id ||
current_user.bill_address_id == address.id
end
def customer_address(address)
current_user.customers.where(bill_address: address).or(
current_user.customers.where(ship_address: address)

View File

@@ -3,12 +3,15 @@
# Controller used to provide the API products for the DFC application
module DfcProvider
class ApplicationController < ActionController::Base
class Unauthorized < StandardError; end
include ActiveStorage::SetCurrent
protect_from_forgery with: :null_session
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from CanCan::AccessDenied, with: :unauthorized
rescue_from Unauthorized, with: :unauthorized
before_action :check_authorization
@@ -16,6 +19,13 @@ module DfcProvider
private
def require_permission(scope)
return if current_user.is_a? Spree::User
return if current_user.permissions(scope).where(enterprise: current_enterprise).exists?
raise Unauthorized
end
def check_authorization
unauthorized if current_user.nil?
end

View File

@@ -7,6 +7,8 @@ module DfcProvider
before_action :check_enterprise
def index
require_permission "ReadProducts"
enterprises = current_user.enterprises.map do |enterprise|
EnterpriseBuilder.enterprise(enterprise)
end

View File

@@ -0,0 +1,36 @@
# frozen_string_literal: true
# Authorised user or client using the API
class ApiUser
CLIENT_MAP = {
"https://waterlooregionfood.ca/portal/profile" => "cqcm-dev",
}.freeze
def self.from_client_id(client_id)
id = CLIENT_MAP[client_id]
new(id) if id
end
attr_reader :id
def initialize(id)
@id = id
end
def admin?
false
end
def customers
Customer.none
end
def enterprises
Enterprise.where(dfc_permissions: permissions("ReadEnterprise"))
end
def permissions(scope)
DfcPermission.where(grantee: id, scope:)
end
end

View File

@@ -1,17 +1,29 @@
# frozen_string_literal: true
# Service used to authorize the user on DCF Provider API
# Authorize the user on the DFC API
#
# It controls an OICD Access token and an enterprise.
class AuthorizationControl
# Copied from: https://login.lescommuns.org/auth/realms/data-food-consortium/
LES_COMMUNES_PUBLIC_KEY = <<~KEY
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl68JGqAILFzoi/1+6siXXp2vylu+7mPjYKjKelTtHFYXWVkbmVptCsamHlY3jRhqSQYe6M1SKfw8D+uXrrWsWficYvpdlV44Vm7uETZOr1/XBOjpWOi1vLmBVtX6jFeqN1BxfE1PxLROAiGn+MeMg90AJKShD2c5RoNv26e20dgPhshRVFPUGru+0T1RoKyIa64z/qcTcTVD2V7KX+ANMweRODdoPAzQFGGjTnL1uUqIdUwSfHSpXYnKxXOsnPC3Mowkv8UIGWWDxS/yzhWc7sOk1NmC7pb+Cg7G8NKj+Pp9qQZnXF39Dg95ZsxJrl6fyPFvTo3zf9CPG/fUM1CkkwIDAQAB
-----END PUBLIC KEY-----
KEY
PUBLIC_KEYS = {
# Copied from: https://login.lescommuns.org/auth/realms/data-food-consortium/
"https://login.lescommuns.org/auth/realms/data-food-consortium" => <<~KEY,
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl68JGqAILFzoi/1+6siXXp2vylu+7mPjYKjKelTtHFYXWVkbmVptCsamHlY3jRhqSQYe6M1SKfw8D+uXrrWsWficYvpdlV44Vm7uETZOr1/XBOjpWOi1vLmBVtX6jFeqN1BxfE1PxLROAiGn+MeMg90AJKShD2c5RoNv26e20dgPhshRVFPUGru+0T1RoKyIa64z/qcTcTVD2V7KX+ANMweRODdoPAzQFGGjTnL1uUqIdUwSfHSpXYnKxXOsnPC3Mowkv8UIGWWDxS/yzhWc7sOk1NmC7pb+Cg7G8NKj+Pp9qQZnXF39Dg95ZsxJrl6fyPFvTo3zf9CPG/fUM1CkkwIDAQAB
-----END PUBLIC KEY-----
KEY
def self.public_key
OpenSSL::PKey::RSA.new(LES_COMMUNES_PUBLIC_KEY)
# Copied from: https://kc.cqcm.startinblox.com/realms/startinblox
"https://kc.cqcm.startinblox.com/realms/startinblox" => <<~KEY,
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqtvdb3BdHoLnNeMLaWd7nugPwdRAJJpdSySTtttEQY2/v1Q3byJ/kReSNGrUNkPVkOeDN3milgN5Apz+sNCwbtzOCulyFMmvuIOZFBqz5tcgwjZinSwpGBXpn6ehXyCET2LlcfLYAPA9axtaNg9wBLIHoxIPWpa2LcZstogyZY/yKUZXQTDqM5B5TyUkPN89xHFdq8SQuXPasbpYl7mGhZHkTDHiKZ9VK7K5tqsEZTD9dCuTGMKsthbOrlDnc9bAJ3PyKLRdib21Y1GGlTozo4Y/1q448E/DFp5rVC6jG6JFnsEnP0WVn+6qz7yxI7IfUU2YSAGgtGYaQkWtEfED0QIDAQAB
-----END PUBLIC KEY-----
KEY
}.freeze
def self.public_key(token)
unverified_payload = JWT.decode(token, nil, false, { algorithm: "RS256" }).first
key = PUBLIC_KEYS[unverified_payload["iss"]]
OpenSSL::PKey::RSA.new(key)
end
def initialize(request)
@@ -27,7 +39,11 @@ class AuthorizationControl
private
def oidc_user
find_ofn_user(decode_token) if access_token
return unless access_token
payload = decode_token
find_ofn_user(payload) || client_user(payload)
end
def ofn_api_user
@@ -41,7 +57,7 @@ class AuthorizationControl
def decode_token
JWT.decode(
access_token,
self.class.public_key,
self.class.public_key(access_token),
true, { algorithm: "RS256" }
).first
end
@@ -59,4 +75,8 @@ class AuthorizationControl
OidcAccount.find_by(uid: payload["email"])&.user
end
def client_user(payload)
ApiUser.from_client_id(payload["client_id"])
end
end

View File

@@ -3,6 +3,7 @@
require_relative "../swagger_helper"
RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
let(:Authorization) { nil }
let(:user) { create(:oidc_user, id: 12_345) }
let(:enterprise) {
create(
@@ -35,8 +36,15 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
get "List CatalogItems" do
produces "application/json"
security [oidc_token: []]
response "404", "not found" do
context "as platform user" do
include_context "authenticated as platform"
let(:enterprise_id) { 10_000 }
run_test!
end
context "without enterprises" do
let(:enterprise_id) { "default" }
@@ -53,6 +61,25 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
response "200", "success" do
before { product }
context "as platform user" do
include_context "authenticated as platform"
let(:enterprise_id) { 10_000 }
before {
DfcPermission.create!(
user:, enterprise_id:,
scope: "ReadEnterprise", grantee: "cqcm-dev",
)
DfcPermission.create!(
user:, enterprise_id:,
scope: "ReadProducts", grantee: "cqcm-dev",
)
}
run_test!
end
context "with default enterprise id" do
let(:enterprise_id) { "default" }
@@ -75,11 +102,31 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
end
response "401", "unauthorized" do
let(:enterprise_id) { "default" }
context "as platform user" do
include_context "authenticated as platform"
before { login_as nil }
let(:enterprise_id) { 10_000 }
run_test!
before {
product
DfcPermission.create!(
user:, enterprise_id:,
scope: "ReadEnterprise", grantee: "cqcm-dev",
)
# But no ReadProducts permission.
}
run_test!
end
context "without authorisation" do
let(:enterprise_id) { "default" }
before { login_as nil }
run_test!
end
end
end
end

View File

@@ -3,6 +3,7 @@
require_relative "../swagger_helper"
RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do
let(:Authorization) { nil }
let!(:user) { create(:oidc_user) }
let!(:enterprise) do
create(
@@ -51,6 +52,21 @@ RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do
produces "application/json"
response "200", "successful" do
context "as platform user" do
include_context "authenticated as platform"
let(:id) { 10_000 }
before {
DfcPermission.create!(
user:, enterprise_id: id,
scope: "ReadEnterprise", grantee: "cqcm-dev",
)
}
run_test!
end
context "without enterprise id" do
let(:id) { "default" }

View File

@@ -13,6 +13,7 @@ RSpec.describe "ProductGroups", swagger_doc: "dfc.yaml" do
variants: [variant]
)
}
let(:Authorization) { nil }
let(:variant) {
build(:base_variant, id: 10_001, unit_value: 1, primary_taxon: taxon, supplier: enterprise)
}
@@ -34,10 +35,28 @@ RSpec.describe "ProductGroups", swagger_doc: "dfc.yaml" do
get "Show ProductGroup" do
produces "application/json"
security [oidc_token: []]
response "200", "success" do
let(:id) { product.id }
context "as platform user" do
include_context "authenticated as platform"
before {
DfcPermission.create!(
user:, enterprise_id:,
scope: "ReadEnterprise", grantee: "cqcm-dev",
)
DfcPermission.create!(
user:, enterprise_id:,
scope: "ReadProducts", grantee: "cqcm-dev",
)
}
run_test!
end
run_test! do
expect(json_response["@id"]).to eq "http://test.host/api/dfc/product_groups/90000"

View File

@@ -11,11 +11,11 @@ RSpec.describe AffiliateSalesQuery do
let(:yesterday) { Time.zone.yesterday }
let(:tomorrow) { Time.zone.tomorrow }
around do |example|
before do
# Query dates are interpreted as UTC while the spec runs in
# Melbourne time. At noon in Melbourne, the date is the same.
# That simplifies the spec.
Timecop.travel(Time.zone.today.noon, &example)
travel_to(Time.zone.today.noon)
end
it "returns data" do

View File

@@ -0,0 +1,13 @@
# frozen_string_literal: true
require_relative "../spec_helper"
RSpec.describe ApiUser do
subject(:user) { described_class.new("cqcm-dev") }
describe "#customers" do
it "returns nothing" do
expect(user.customers).to be_empty
end
end
end

View File

@@ -8,6 +8,23 @@ RSpec.describe AuthorizationControl do
let(:user) { create(:oidc_user) }
describe "with OIDC token" do
it "accepts a token from Les Communs" do
user.oidc_account.update!(uid: "testdfc@protonmail.com")
lc_token = file_fixture("les_communs_access_token.jwt").read
travel_to(Date.parse("2025-06-13")) do
expect(auth(oidc_token: lc_token).user).to eq user
end
end
it "accepts a token from Startin'Blox" do
sib_token = file_fixture("startinblox_access_token.jwt").read
travel_to(Date.parse("2025-06-13")) do
expect(auth(oidc_token: sib_token).user.id).to eq "cqcm-dev"
end
end
it "finds the right user" do
create(:oidc_user) # another user
token = allow_token_for(email: user.email)

View File

@@ -0,0 +1,16 @@
# frozen_string_literal: true
# Authenticate via Authoriztion token
RSpec.shared_context "authenticated as platform" do
let(:Authorization) {
"Bearer #{file_fixture('startinblox_access_token.jwt').read}"
}
before do
# Once upon a time when the access token hadn't expired yet...
travel_to(Date.parse("2025-06-13"))
# Reset any login via session cookie.
login_as nil
end
end

View File

@@ -61,9 +61,6 @@ module OpenFoodNetwork
"inventory" => <<~DESC,
Enable the inventory.
DESC
"hub_address" => <<~DESC,
Show the hub's address as shipping address on pickup orders.
DESC
"cqcm-dev" => <<~DESC,
Show DFC Permissions interface to share data with CQCM dev platform.
DESC

View File

@@ -113,7 +113,9 @@ module OpenFoodNetwork
end
def managed_enterprises
@managed_enterprises ||= Enterprise.managed_by(@user)
return Enterprise.all if admin?
@user.enterprises
end
def coordinated_order_cycles

View File

@@ -4,9 +4,8 @@ module Reporting
class ReportHeadersBuilder
attr_reader :report
def initialize(report, current_user)
def initialize(report)
@report = report
@current_user = current_user
end
def table_headers

View File

@@ -7,9 +7,8 @@ module Reporting
attr_reader :report
def initialize(report, current_user)
def initialize(report)
@report = report
@current_user = current_user
end
# Compute the query result item into a result row

View File

@@ -4,9 +4,9 @@ module Reporting
class ReportRowsBuilder
attr_reader :report
def initialize(report, current_user)
def initialize(report)
@report = report
@builder = ReportRowBuilder.new(report, current_user)
@builder = ReportRowBuilder.new(report)
end
# Structured data by groups. This tree is used to render

View File

@@ -114,11 +114,11 @@ module Reporting
end
def rows_builder
@rows_builder ||= ReportRowsBuilder.new(self, @user)
@rows_builder ||= ReportRowsBuilder.new(self)
end
def headers_builder
@headers_builder ||= ReportHeadersBuilder.new(self, @user)
@headers_builder ||= ReportHeadersBuilder.new(self)
end
def ruler

View File

@@ -27,8 +27,9 @@ module Stripe
next_action_type = next_action["type"]
return unless %w(authorize_with_url redirect_to_url).include?(next_action_type)
url = next_action[next_action_type]["url"]
url if url.match(%r{https?://\S+}) && url.include?("stripe.com")
url = URI(next_action[next_action_type]["url"])
# Check the URL is from a stripe subdomain
url.to_s if url.is_a?(URI::HTTPS) && url.host.match?(/\.stripe.com\Z/)
end
# This field is used because the Spree code recognizes and stores it

View File

@@ -10,7 +10,7 @@
"pretty-quick": "pretty-quick"
},
"dependencies": {
"@floating-ui/dom": "^1.7.3",
"@floating-ui/dom": "^1.7.4",
"@hotwired/stimulus": "^3.2",
"@hotwired/turbo": "^8.0.13",
"@rails/webpacker": "5.4.4",
@@ -22,7 +22,7 @@
"jquery-ui": "1.14.1",
"js-big-decimal": "^2.2.0",
"leaflet": "1.9.4",
"leaflet-geosearch": "4.2.0",
"leaflet-geosearch": "4.2.2",
"leaflet-providers": "2.0.0",
"moment": "^2.30.1",
"mrujs": "^1.0.2",
@@ -37,7 +37,7 @@
"webpack": "~4"
},
"devDependencies": {
"jasmine-core": "~5.9.0",
"jasmine-core": "~5.10.0",
"jest": "^27.4.7",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",

View File

@@ -257,6 +257,7 @@ RSpec.configure do |config|
config.include OpenFoodNetwork::FiltersHelper
config.include OpenFoodNetwork::EnterpriseGroupsHelper
config.include OpenFoodNetwork::HtmlHelper
config.include ActiveSupport::Testing::TimeHelpers
config.include ActionView::Helpers::DateHelper
config.include OpenFoodNetwork::PerformanceHelper
config.include ActiveJob::TestHelper

View File

@@ -2,7 +2,7 @@
require "spec_helper"
RSpec.describe VerticalEllipsisMenu::Component, type: :component do
RSpec.describe VerticalEllipsisMenuComponent, type: :component do
it "displays the included links" do
content = "<a href>Edit</a>"
render_inline(described_class.new.with_content(content.html_safe))

View File

@@ -142,7 +142,7 @@ RSpec.describe Admin::OrderCyclesController do
select: {
enterprise_fees: 3,
enterprise_groups: 1,
enterprises: 22,
enterprises: 19,
exchanges: 7,
order_cycles: 6,
proxy_orders: 1,

View File

@@ -0,0 +1 @@
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJKVjg1bVRtUmh1MGtSeGNNb0FGUFl5azJMbS1WTExYV25HOG9HbUxNUkowIn0.eyJleHAiOjE3NDk3ODkyMzYsImlhdCI6MTc0OTc4NzQzNiwiYXV0aF90aW1lIjoxNzQ5Nzg3NDMzLCJqdGkiOiJmM2Q2ZGNmMi1lNGMwLTQyNzItODQzNC00NWFhZDczOTllYzUiLCJpc3MiOiJodHRwczovL2xvZ2luLmxlc2NvbW11bnMub3JnL2F1dGgvcmVhbG1zL2RhdGEtZm9vZC1jb25zb3J0aXVtIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjVmZjNhZjc4LTk0YTItNGI1Yi04ZGFkLWE3YzFkZWE4ODE2YSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImNvb3BjaXJjdWl0cyIsIm5vbmNlIjoiMTZkNmM3OGZkNTcwOWRkMjVkNzNkYzYwMmViNDBiZGYiLCJzZXNzaW9uX3N0YXRlIjoiYmE4Y2M0ZWYtMDJmMC00ZjVmLWFiMWEtMDUyNGRiNGViNzI5IiwiYWxsb3dlZC1vcmlnaW5zIjpbIiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJzaWQiOiJiYThjYzRlZi0wMmYwLTRmNWYtYWIxYS0wNTI0ZGI0ZWI3MjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJ0ZXN0IGRmYyIsInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RkZmNAcHJvdG9ubWFpbC5jb20iLCJsb2NhbGUiOiJlbiIsImdpdmVuX25hbWUiOiJ0ZXN0IiwiZmFtaWx5X25hbWUiOiJkZmMiLCJlbWFpbCI6InRlc3RkZmNAcHJvdG9ubWFpbC5jb20ifQ.NTuzVgy8es0GHKqGPmHgVaV8Kzz9uuFAiWgixLubfh8fl2OccFDxccNKyiTczj4wHD4jItdHPIxz-x9ZX2Ao7lwMFLno69KWjAK2eLpA8Fnu4stftlswfHqD0W-wzG0Cx24H6jXZbsM5tm1FYgQYwrlZ-uqwQOabN_cA_cTrwHmMTNVCjwCisScq7Np7r1me-4YEABmTGR362_eJVn2bRppG_7s12yjEAH_mcTyALXqlXNaF0XihDCxjmK8ybJiGy6_QwhEJci6EWqJ-w9H6ckheq94xTM5WpanQ4-ZHEm2TZlq2MOfMBVsknhwnGI0b-GbtSJrs7urWsopQyWSuhw

View File

@@ -0,0 +1 @@
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRRlJES1daQ2hzMllQYnRqYl9yQUtwQzNzMFo0T2FCMEtFQ056NnlxWHQ0In0.eyJleHAiOjE3NDk3ODk3MDcsImlhdCI6MTc0OTc4OTQwNywianRpIjoiOWE4ODU4NDAtODhjNy00OTliLWIyOGUtMmE5ZmViM2EyNmU0IiwiaXNzIjoiaHR0cHM6Ly9rYy5jcWNtLnN0YXJ0aW5ibG94LmNvbS9yZWFsbXMvc3RhcnRpbmJsb3giLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNWZlM2MyNmMtMjczNi00OGE0LWI2Y2YtYTllM2JjZmNkZjAwIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiaHR0cHM6Ly93YXRlcmxvb3JlZ2lvbmZvb2QuY2EvcG9ydGFsL3Byb2ZpbGUiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtc3RhcnRpbmJsb3giXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6IlJlYWRFbnRlcnByaXNlIFJlYWRQcm9kdWN0cyIsImNsaWVudEhvc3QiOiIxNzIuMTguMC4xIiwiY2xpZW50QWRkcmVzcyI6IjE3Mi4xOC4wLjEiLCJjbGllbnRfaWQiOiJodHRwczovL3dhdGVybG9vcmVnaW9uZm9vZC5jYS9wb3J0YWwvcHJvZmlsZSJ9.Ln7wY0_ptRAza7M8w3yXU02TvluH028uaoJ5VHiN9-PnakokzHve7SCuSd1hvVikYAivWFIBRP97vwfpb_DW-d9Afk_XcQqcA0L36ynUIZ69X5uQ2zakEW0kB6pwqd8AL8tlWVUg2PixBXJ6daJcgWNF7RlKXg6wgy4JYL_VxD3VJjST911-z4_TMuQ2OC-3SJNwNv3BspSmUXm7F6y8xGFN7wuCPjU90WIiZ_vxTbVdM0zNtBM0uMJFeFv2_ZzoJIIiNHYLWtD3LrKcXePLSejpo-DPVWR_lGdDdM7BmzOHPKZ9KMaV-oa3lYNYC5shhJOpoB3vHngtdYdv8jq7Cg

View File

@@ -50,4 +50,10 @@ RSpec.describe Admin::EnterprisesHelper do
expect(visible_items.pluck(:name)).to include "connected_apps"
end
end
describe '#enterprise_sells_options' do
it 'returns sells options with translations' do
expect(helper.enterprise_sells_options.map(&:first)).to eq %w[unspecified none own any]
end
end
end

View File

@@ -9,4 +9,25 @@ RSpec.describe LinkHelper do
expect(helper.ext_url("http://example.com/", "bla")).to eq("http://example.com/bla")
end
end
describe "link_to_or_disabled" do
it "behaves like the standard :link_to method e.g. it accepts the same arguments and accepts
blocks, etc." do
expect(helper.link_to_or_disabled("Go", "http://example.com/")).to eq(
"<a href=\"http://example.com/\">Go</a>"
)
expect(helper.link_to_or_disabled("Go", "http://example.com/", class: "button")).to eq(
"<a class=\"button\" href=\"http://example.com/\">Go</a>"
)
expect(helper.link_to_or_disabled("http://example.com/") { "Go" }).to eq(
"<a href=\"http://example.com/\">Go</a>"
)
end
it "accepts an additional boolean :disabled argument, which if true renders a disabled link" do
expect(helper.link_to_or_disabled("Go", "http://example.com/", disabled: true)).to eq(
"<a aria-disabled=\"true\" class=\"disabled\" role=\"link\">Go</a>"
)
end
end
end

View File

@@ -8,28 +8,28 @@ import tag_list_input_controller from "../../../app/components/tag_list_input_co
describe("TagListInputController", () => {
beforeAll(() => {
const application = Application.start();
application.register("tag-list-input-component--tag-list-input", tag_list_input_controller);
application.register("tag-list-input", tag_list_input_controller);
});
beforeEach(() => {
document.body.innerHTML = `
<div data-controller="tag-list-input-component--tag-list-input">
<div data-controller="tag-list-input">
<input
value="tag 1,tag 2,tag 3"
data-tag-list-input-component--tag-list-input-target="tagList"
data-tag-list-input-target="tagList"
type="hidden"
name="variant_tag_list" id="variant_tag_list"
>
<div class="tags-input">
<div class="tags">
<ul class="tag-list" data-tag-list-input-component--tag-list-input-target="list">
<template data-tag-list-input-component--tag-list-input-target="template">
<ul class="tag-list" data-tag-list-input-target="list">
<template data-tag-list-input-target="template">
<li class="tag-item">
<div class="tag-template">
<span></span>
<a
class="remove-button"
data-action="click->tag-list-input-component--tag-list-input#removeTag"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
@@ -39,7 +39,7 @@ describe("TagListInputController", () => {
<span>tag 1</span>
<a
class="remove-button"
data-action="click->tag-list-input-component--tag-list-input#removeTag"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
@@ -48,7 +48,7 @@ describe("TagListInputController", () => {
<span>tag 2</span>
<a
class="remove-button"
data-action="click->tag-list-input-component--tag-list-input#removeTag"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
@@ -57,7 +57,7 @@ describe("TagListInputController", () => {
<span>tag 3</span>
<a
class="remove-button"
data-action="click->tag-list-input-component--tag-list-input#removeTag"
data-action="click->tag-list-input#removeTag"
>✖</a>
</div>
</li>
@@ -67,7 +67,7 @@ describe("TagListInputController", () => {
name="variant_add_tag"
id="variant_add_tag"
placeholder="Add a tag"
data-action="keydown.enter->tag-list-input-component--tag-list-input#addTag keyup->tag-list-input-component--tag-list-input#filterInput" data-tag-list-input-component--tag-list-input-target="newTag"
data-action="keydown.enter->tag-list-input#addTag keyup->tag-list-input#filterInput" data-tag-list-input-target="newTag"
>
</div>
</div>

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