mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-28 01:53:25 +00:00
Compare commits
178 Commits
v5.1.5
...
test/13521
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cab04553a | ||
|
|
1654bb2b0a | ||
|
|
9f396a40b7 | ||
|
|
4bf1b7ac08 | ||
|
|
2910082584 | ||
|
|
70b5fda632 | ||
|
|
9bf2dad343 | ||
|
|
05b3417f77 | ||
|
|
403aa6ac6f | ||
|
|
fbad3ee9f4 | ||
|
|
ddb8b2d08f | ||
|
|
42c9ee033a | ||
|
|
524634b4ea | ||
|
|
0b97171bb0 | ||
|
|
b0c7e29b0d | ||
|
|
3d7799df19 | ||
|
|
5f02d88a86 | ||
|
|
bdae8e6478 | ||
|
|
053ef05baf | ||
|
|
7fcb31d563 | ||
|
|
31a7374808 | ||
|
|
e5ce06ae39 | ||
|
|
5f64204d51 | ||
|
|
94b75540e4 | ||
|
|
6e489d7770 | ||
|
|
81b1169e77 | ||
|
|
4b558b4820 | ||
|
|
e224b8f63b | ||
|
|
80bb0606b4 | ||
|
|
499fcc791e | ||
|
|
30dae3c3ea | ||
|
|
af247c32a3 | ||
|
|
6f9dcf7e27 | ||
|
|
2d064bab64 | ||
|
|
b69eb9bdff | ||
|
|
f79c1879bd | ||
|
|
646d538a3d | ||
|
|
90288b8cbf | ||
|
|
c821b0a285 | ||
|
|
b95d798a27 | ||
|
|
e1e4aeac1f | ||
|
|
c7ae47053e | ||
|
|
5892ae1800 | ||
|
|
c37376d67e | ||
|
|
74368f939b | ||
|
|
cb02cd39fe | ||
|
|
49ec5b2089 | ||
|
|
92ef5fe3d5 | ||
|
|
ae477b7e52 | ||
|
|
0e191e5fca | ||
|
|
64f9ea6fc0 | ||
|
|
058c6749da | ||
|
|
2d15ec4458 | ||
|
|
56eaa8bb98 | ||
|
|
1e1f1e1e1b | ||
|
|
1d2115766a | ||
|
|
6814ef43f4 | ||
|
|
c9e8294561 | ||
|
|
82d0e1bf68 | ||
|
|
b16e541a81 | ||
|
|
c12d494de3 | ||
|
|
9be27842e1 | ||
|
|
2a7754edbf | ||
|
|
cfeafbfc51 | ||
|
|
1f8a9f9c76 | ||
|
|
b1893942ac | ||
|
|
ad59ed4d40 | ||
|
|
8491a167ed | ||
|
|
05b00f16ad | ||
|
|
78fdaa68c8 | ||
|
|
59277292fb | ||
|
|
e8813833fa | ||
|
|
354a7ab687 | ||
|
|
a5a1ee9bd9 | ||
|
|
ad3f78ef69 | ||
|
|
e02497b163 | ||
|
|
7d2d94398f | ||
|
|
0ecf004ff2 | ||
|
|
444f448207 | ||
|
|
d9381b23d7 | ||
|
|
6a9a2884d6 | ||
|
|
70edd4b898 | ||
|
|
b57a2befd9 | ||
|
|
fef9a78198 | ||
|
|
dd86736170 | ||
|
|
0d8c7ef118 | ||
|
|
20730b8768 | ||
|
|
ad7c69189b | ||
|
|
a5f44cb9b2 | ||
|
|
97d21d8cbe | ||
|
|
7afdd13b64 | ||
|
|
54c446f0a3 | ||
|
|
4454c90575 | ||
|
|
dd3a61acdf | ||
|
|
6d8ddd1eda | ||
|
|
b8e8ab15d1 | ||
|
|
bf1d2f3620 | ||
|
|
43026ddc6a | ||
|
|
18b83d2423 | ||
|
|
3a72aefc1c | ||
|
|
e855ea0dbd | ||
|
|
1eba950e19 | ||
|
|
9cd04c087e | ||
|
|
459d25e533 | ||
|
|
b06e562425 | ||
|
|
2936cfebca | ||
|
|
b8ad428b5d | ||
|
|
ca34d24847 | ||
|
|
6e581fce75 | ||
|
|
66041061fb | ||
|
|
e54c27c900 | ||
|
|
b3d3d6bf06 | ||
|
|
5876c52318 | ||
|
|
842f4ae40e | ||
|
|
342ef4e9eb | ||
|
|
210201514e | ||
|
|
2d3f18a71b | ||
|
|
9d284b7110 | ||
|
|
994f1ca6c6 | ||
|
|
f65e4797cf | ||
|
|
52aeec5ac4 | ||
|
|
7032b3f463 | ||
|
|
c26686b430 | ||
|
|
60c8f4ee20 | ||
|
|
25f396c126 | ||
|
|
0166abcd2a | ||
|
|
4cd0071dd4 | ||
|
|
32c96b72ad | ||
|
|
30701d61e2 | ||
|
|
45b712ddcd | ||
|
|
3153e99497 | ||
|
|
a2f263e081 | ||
|
|
3cb6a2617b | ||
|
|
420deca437 | ||
|
|
76aebf8a72 | ||
|
|
1ec570375f | ||
|
|
75c33b29d5 | ||
|
|
1bfff91c72 | ||
|
|
d469552afc | ||
|
|
3750898c44 | ||
|
|
d34f8900d7 | ||
|
|
e6cffde8fb | ||
|
|
910ded1a8c | ||
|
|
2555a9e710 | ||
|
|
f532c4712e | ||
|
|
3af28c4b5b | ||
|
|
63b864253d | ||
|
|
8efeec4301 | ||
|
|
bed33928e0 | ||
|
|
bb7a31b286 | ||
|
|
75b2fe1dd4 | ||
|
|
c0924fbe5e | ||
|
|
d72bc49409 | ||
|
|
06867ff7ea | ||
|
|
76a1fe7767 | ||
|
|
3363c523ea | ||
|
|
91628f8daa | ||
|
|
addf36a304 | ||
|
|
6a912b7d8c | ||
|
|
f3dfbab109 | ||
|
|
d01474ebcd | ||
|
|
a062a7b697 | ||
|
|
fe8b805e1f | ||
|
|
f3f43225cb | ||
|
|
65604f5b04 | ||
|
|
661bb29029 | ||
|
|
df4cf4b768 | ||
|
|
3f39d94bd3 | ||
|
|
acfe3f6589 | ||
|
|
1717c5376b | ||
|
|
1426b6eeb7 | ||
|
|
188b2eb754 | ||
|
|
6e055ddbdf | ||
|
|
025fc784a8 | ||
|
|
fefd0239e6 | ||
|
|
0fa67c69fd | ||
|
|
44cbe55c96 | ||
|
|
6da1200b64 |
13
.github/pull_request.json
vendored
Normal file
13
.github/pull_request.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"pull_request": {
|
||||
"number": 13490,
|
||||
"title": "Bump rails from 7.0.4 to 7.0.8",
|
||||
"id": 99999999,
|
||||
"user": { "login": "dependabot[bot]" }
|
||||
},
|
||||
"repository": {
|
||||
"owner": { "login": "openfoodnetwork" },
|
||||
"name": "openfoodnetwork"
|
||||
},
|
||||
"sender": { "login": "dependabot[bot]" }
|
||||
}
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -410,6 +410,6 @@ jobs:
|
||||
include-hidden-files: true
|
||||
- name: Compare SimpleCov results with Undercover
|
||||
run: |
|
||||
git fetch --no-tags origin master:master
|
||||
git fetch --no-tags origin ${{ github.event.pull_request.base.ref }}:master
|
||||
bundle exec undercover
|
||||
if: ${{ github.ref != 'refs/heads/master' }} # Does not run on master, as we can't fetch master in the master branch
|
||||
|
||||
139
.github/workflows/move-dependency-pr-to-code-review.yml
vendored
Normal file
139
.github/workflows/move-dependency-pr-to-code-review.yml
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
name: Auto-move Dependabot PRs to Code Review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
move-pr-to-code-review:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.user.login == 'dependabot[bot]' || startsWith(github.event.pull_request.title, 'Bump')
|
||||
steps:
|
||||
- name: Move PR to Code Review in Project v2
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const projectNumber = 8; // for "OFN Delivery board"
|
||||
const org = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
const prNumber = context.payload.pull_request.number;
|
||||
const statusFieldName = "Status";
|
||||
const statusValue = "Code review 🔎";
|
||||
|
||||
// ---- Helper: Get PR Node ID ----
|
||||
async function getPrNodeId(owner, repo, number) {
|
||||
const res = await github.graphql(`
|
||||
query($owner: String!, $repo: String!, $number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $number) {
|
||||
id
|
||||
number
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
`, { owner, repo, number });
|
||||
return res.repository.pullRequest.id;
|
||||
}
|
||||
|
||||
console.log("🚀 Starting ProjectV2 automation...");
|
||||
|
||||
// ---- Step 1: Get Project and Fields ----
|
||||
const projectRes = await github.graphql(`
|
||||
query($org: String!, $number: Int!) {
|
||||
organization(login: $org) {
|
||||
projectV2(number: $number) {
|
||||
id
|
||||
title
|
||||
fields(first: 50) {
|
||||
nodes {
|
||||
... on ProjectV2Field {
|
||||
id
|
||||
name
|
||||
}
|
||||
... on ProjectV2SingleSelectField {
|
||||
id
|
||||
name
|
||||
options {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`, { org, number: projectNumber });
|
||||
|
||||
const project = projectRes.organization.projectV2;
|
||||
if (!project) throw new Error(`❌ Project #${projectNumber} not found`);
|
||||
|
||||
console.log(`✅ Found project: ${project.title} (${project.id})`);
|
||||
|
||||
const statusField = project.fields.nodes.find(f => f.name === statusFieldName);
|
||||
if (!statusField) throw new Error(`❌ Field '${statusFieldName}' not found`);
|
||||
|
||||
const option = statusField.options.find(o => o.name === statusValue);
|
||||
if (!option) throw new Error(`❌ Option '${statusValue}' not found in '${statusFieldName}'`);
|
||||
|
||||
console.log(`✅ Found field '${statusFieldName}' and option '${statusValue}'`);
|
||||
|
||||
// ---- Step 2: Get PR Node ID ----
|
||||
const prNodeId = await getPrNodeId(org, repo, prNumber);
|
||||
console.log(`✅ PR #${prNumber} node ID: ${prNodeId}`);
|
||||
|
||||
// ---- Step 3: Check if PR is already in Project ----
|
||||
const itemRes = await github.graphql(`
|
||||
query($prId: ID!) {
|
||||
node(id: $prId) {
|
||||
... on PullRequest {
|
||||
projectItems(first: 50) {
|
||||
nodes {
|
||||
id
|
||||
project { id title }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`, { prId: prNodeId });
|
||||
|
||||
let projectItem = itemRes.node.projectItems.nodes.find(i => i.project.id === project.id);
|
||||
|
||||
if (!projectItem) {
|
||||
console.log("ℹ️ PR not yet in project, adding...");
|
||||
const addRes = await github.graphql(`
|
||||
mutation($projectId: ID!, $contentId: ID!) {
|
||||
addProjectV2ItemById(input: {projectId: $projectId, contentId: $contentId}) {
|
||||
item { id }
|
||||
}
|
||||
}
|
||||
`, { projectId: project.id, contentId: prNodeId });
|
||||
projectItem = addRes.addProjectV2ItemById.item;
|
||||
console.log(`✅ Added PR to project: ${projectItem.id}`);
|
||||
} else {
|
||||
console.log(`ℹ️ PR already in project: ${projectItem.id}`);
|
||||
}
|
||||
|
||||
// ---- Step 4: Update Status ----
|
||||
await github.graphql(`
|
||||
mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
|
||||
updateProjectV2ItemFieldValue(input: {
|
||||
projectId: $projectId,
|
||||
itemId: $itemId,
|
||||
fieldId: $fieldId,
|
||||
value: { singleSelectOptionId: $optionId }
|
||||
}) {
|
||||
projectV2Item { id }
|
||||
}
|
||||
}
|
||||
`, {
|
||||
projectId: project.id,
|
||||
itemId: projectItem.id,
|
||||
fieldId: statusField.id,
|
||||
optionId: option.id,
|
||||
});
|
||||
|
||||
console.log(`🎉 Moved PR #${prNumber} → '${statusValue}'`);
|
||||
@@ -16,6 +16,7 @@ AllCops:
|
||||
- node_modules/**/*
|
||||
# Excluding: inadequate Naming/FileName rule rejects GemFile name with camelcase
|
||||
- engines/web/Gemfile
|
||||
- .undercover
|
||||
|
||||
Bundler/DuplicatedGem:
|
||||
Enabled: false
|
||||
|
||||
20
.simplecov
20
.simplecov
@@ -2,19 +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 '/jobs/application_job.rb'
|
||||
add_filter '/schemas/'
|
||||
add_filter '/lib/generators'
|
||||
add_filter '/spec/'
|
||||
add_filter '/vendor/'
|
||||
add_filter '/public'
|
||||
add_filter '/swagger'
|
||||
add_filter '/config/' # to include engine config
|
||||
add_filter '/script'
|
||||
add_filter '/log'
|
||||
add_filter '/db'
|
||||
add_filter '/lib/tasks/sample_data/'
|
||||
|
||||
formatter SimpleCov::Formatter::SimpleFormatter
|
||||
end
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#!/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
-l coverage/lcov/openfoodnetwork.lcov
|
||||
-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/*"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
4
Gemfile
4
Gemfile
@@ -152,6 +152,7 @@ end
|
||||
group :test, :development do
|
||||
gem 'bullet'
|
||||
gem 'capybara'
|
||||
gem 'capybara-shadowdom'
|
||||
gem 'cuprite'
|
||||
gem 'database_cleaner', require: false
|
||||
gem 'debug', '>= 1.0.0'
|
||||
@@ -166,14 +167,13 @@ 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
|
||||
gem 'pdf-reader'
|
||||
gem 'puffing-billy'
|
||||
gem 'rails-controller-testing'
|
||||
gem 'simplecov', require: false
|
||||
gem 'simplecov-lcov', require: false
|
||||
gem 'undercover', require: false
|
||||
gem 'vcr', require: false
|
||||
gem 'webmock', require: false
|
||||
|
||||
235
Gemfile.lock
235
Gemfile.lock
@@ -48,54 +48,58 @@ PATH
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.1.0)
|
||||
actioncable (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
Ascii85 (2.0.1)
|
||||
actioncable (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activestorage (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
zeitwerk (~> 2.6)
|
||||
actionmailbox (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activestorage (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
actionview (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
actionmailer (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
actionview (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (7.0.8)
|
||||
actionview (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
rack (~> 2.0, >= 2.2.4)
|
||||
rails-dom-testing (~> 2.2)
|
||||
actionpack (7.1.5.2)
|
||||
actionview (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
nokogiri (>= 1.8.5)
|
||||
racc
|
||||
rack (>= 2.2.4)
|
||||
rack-session (>= 1.0.1)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
rails-dom-testing (~> 2.2)
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
actionpack-action_caching (1.2.2)
|
||||
actionpack (>= 4.0.0)
|
||||
actiontext (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activestorage (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
actiontext (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activestorage (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
actionview (7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
erubi (~> 1.11)
|
||||
rails-dom-testing (~> 2.2)
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
active_model_serializers (0.8.4)
|
||||
activemodel (>= 3.0)
|
||||
active_storage_validations (1.1.4)
|
||||
@@ -103,8 +107,8 @@ GEM
|
||||
activemodel (>= 5.2.0)
|
||||
activestorage (>= 5.2.0)
|
||||
activesupport (>= 5.2.0)
|
||||
activejob (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
activejob (7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
globalid (>= 0.3.6)
|
||||
activemerchant (1.133.0)
|
||||
activesupport (>= 4.2)
|
||||
@@ -112,11 +116,12 @@ GEM
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
rexml (~> 3.2.5)
|
||||
activemodel (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
activerecord (7.0.8)
|
||||
activemodel (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
activemodel (7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
activerecord (7.1.5.2)
|
||||
activemodel (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
timeout (>= 0.4.0)
|
||||
activerecord-import (1.6.0)
|
||||
activerecord (>= 4.2)
|
||||
activerecord-postgresql-adapter (0.0.1)
|
||||
@@ -128,17 +133,24 @@ GEM
|
||||
multi_json (~> 1.11, >= 1.11.2)
|
||||
rack (>= 2.0.8, < 4)
|
||||
railties (>= 6.1)
|
||||
activestorage (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
activestorage (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
marcel (~> 1.0)
|
||||
mini_mime (>= 1.1.0)
|
||||
activesupport (7.0.8)
|
||||
activesupport (7.1.5.2)
|
||||
base64
|
||||
benchmark (>= 0.3)
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
logger (>= 1.4.2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0)
|
||||
acts-as-taggable-on (10.0.0)
|
||||
activerecord (>= 6.1, < 7.2)
|
||||
@@ -177,9 +189,10 @@ GEM
|
||||
aws-sigv4 (~> 1.8)
|
||||
aws-sigv4 (1.8.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
base64 (0.2.0)
|
||||
base64 (0.3.0)
|
||||
bcp47_spec (0.2.1)
|
||||
bcrypt (3.1.20)
|
||||
benchmark (0.4.1)
|
||||
bigdecimal (3.2.2)
|
||||
bindata (2.5.0)
|
||||
bindex (0.8.1)
|
||||
@@ -188,7 +201,7 @@ GEM
|
||||
bugsnag (6.26.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.2.4)
|
||||
bullet (7.1.6)
|
||||
bullet (8.0.8)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
cable_ready (5.0.6)
|
||||
@@ -208,12 +221,14 @@ GEM
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
xpath (~> 3.2)
|
||||
capybara-shadowdom (0.3.0)
|
||||
capybara
|
||||
caxlsx (3.3.0)
|
||||
htmlentities (~> 4.3, >= 4.3.4)
|
||||
marcel (~> 1.0)
|
||||
nokogiri (~> 1.10, >= 1.10.4)
|
||||
rubyzip (>= 1.3.0, < 3)
|
||||
cgi (0.3.6)
|
||||
cgi (0.3.7)
|
||||
childprocess (5.0.0)
|
||||
choice (0.2.0)
|
||||
chronic (0.10.2)
|
||||
@@ -228,8 +243,9 @@ GEM
|
||||
combine_pdf (1.0.26)
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.3.1)
|
||||
connection_pool (2.4.1)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.3)
|
||||
cookiejar (0.3.4)
|
||||
crack (1.0.0)
|
||||
bigdecimal
|
||||
rexml
|
||||
@@ -248,7 +264,7 @@ GEM
|
||||
database_cleaner-core (2.0.1)
|
||||
datafoodconsortium-connector (1.1.0)
|
||||
virtual_assembly-semantizer (~> 1.0, >= 1.0.5)
|
||||
date (3.3.4)
|
||||
date (3.4.1)
|
||||
debug (1.9.2)
|
||||
irb (~> 1.10)
|
||||
reline (>= 0.3.8)
|
||||
@@ -269,11 +285,25 @@ GEM
|
||||
digest (3.1.1)
|
||||
docile (1.4.0)
|
||||
dotenv (3.1.2)
|
||||
drb (2.2.3)
|
||||
em-http-request (1.1.7)
|
||||
addressable (>= 2.3.4)
|
||||
cookiejar (!= 0.3.1)
|
||||
em-socksify (>= 0.3)
|
||||
eventmachine (>= 1.0.3)
|
||||
http_parser.rb (>= 0.6.0)
|
||||
em-socksify (0.3.3)
|
||||
base64
|
||||
eventmachine (>= 1.0.0.beta.4)
|
||||
em-synchrony (1.0.6)
|
||||
eventmachine (>= 1.0.0.beta.1)
|
||||
email_validator (2.2.4)
|
||||
activemodel
|
||||
erubi (1.12.0)
|
||||
et-orbi (1.2.7)
|
||||
et-orbi (1.3.0)
|
||||
tzinfo
|
||||
eventmachine (1.2.7)
|
||||
eventmachine_httpserver (0.2.1)
|
||||
excon (0.81.0)
|
||||
execjs (2.7.0)
|
||||
factory_bot (6.2.0)
|
||||
@@ -323,8 +353,8 @@ GEM
|
||||
nokogiri (>= 1.5.11, < 2.0.0)
|
||||
foreman (0.88.1)
|
||||
formatador (0.2.5)
|
||||
fugit (1.8.1)
|
||||
et-orbi (~> 1, >= 1.2.7)
|
||||
fugit (1.11.1)
|
||||
et-orbi (~> 1, >= 1.2.11)
|
||||
raabro (~> 1.4)
|
||||
fuubar (2.5.1)
|
||||
rspec-core (~> 3.0)
|
||||
@@ -347,6 +377,7 @@ GEM
|
||||
hashie (5.0.0)
|
||||
highline (2.0.3)
|
||||
htmlentities (4.3.4)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (1.14.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-js (3.9.2)
|
||||
@@ -420,7 +451,8 @@ GEM
|
||||
listen (3.9.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.22.0)
|
||||
logger (1.7.0)
|
||||
loofah (2.24.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.12.0)
|
||||
mail (2.8.1)
|
||||
@@ -440,7 +472,7 @@ GEM
|
||||
mini_magick (4.11.0)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.6)
|
||||
minitest (5.23.1)
|
||||
minitest (5.25.5)
|
||||
monetize (1.13.0)
|
||||
money (~> 6.12)
|
||||
money (6.16.0)
|
||||
@@ -448,9 +480,10 @@ GEM
|
||||
msgpack (1.7.2)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
mutex_m (0.3.0)
|
||||
net-http (0.4.1)
|
||||
uri
|
||||
net-imap (0.4.10)
|
||||
net-imap (0.4.20)
|
||||
date
|
||||
net-protocol
|
||||
net-pop (0.1.2)
|
||||
@@ -461,7 +494,7 @@ GEM
|
||||
net-protocol
|
||||
newrelic_rpm (9.9.0)
|
||||
nio4r (2.7.1)
|
||||
nokogiri (1.16.5)
|
||||
nokogiri (1.18.9)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
nokogiri-html5-inference (0.3.0)
|
||||
@@ -513,9 +546,9 @@ GEM
|
||||
xml-simple
|
||||
paypal-sdk-merchant (1.117.2)
|
||||
paypal-sdk-core (~> 0.3.0)
|
||||
pdf-reader (2.12.0)
|
||||
Ascii85 (~> 1.0)
|
||||
afm (~> 0.2.1)
|
||||
pdf-reader (2.15.0)
|
||||
Ascii85 (>= 1.0, < 3.0, != 2.0.0)
|
||||
afm (>= 0.2.1, < 2)
|
||||
hashery (~> 2.0)
|
||||
ruby-rc4
|
||||
ttfunk
|
||||
@@ -527,6 +560,14 @@ GEM
|
||||
psych (5.1.2)
|
||||
stringio
|
||||
public_suffix (5.0.5)
|
||||
puffing-billy (4.0.2)
|
||||
addressable (~> 2.5)
|
||||
em-http-request (~> 1.1, >= 1.1.0)
|
||||
em-synchrony
|
||||
eventmachine (~> 1.2)
|
||||
eventmachine_httpserver
|
||||
http_parser.rb (~> 0.8.0)
|
||||
multi_json
|
||||
puma (6.5.0)
|
||||
nio4r (~> 2.0)
|
||||
query_count (1.1.1)
|
||||
@@ -534,7 +575,7 @@ GEM
|
||||
railties (>= 4.2)
|
||||
raabro (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (2.2.11)
|
||||
rack (2.2.14)
|
||||
rack-mini-profiler (2.3.4)
|
||||
rack (>= 1.2.0)
|
||||
rack-oauth2 (2.2.1)
|
||||
@@ -555,20 +596,23 @@ GEM
|
||||
rack-test (2.1.0)
|
||||
rack (>= 1.3)
|
||||
rack-timeout (0.7.0)
|
||||
rails (7.0.8)
|
||||
actioncable (= 7.0.8)
|
||||
actionmailbox (= 7.0.8)
|
||||
actionmailer (= 7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
actiontext (= 7.0.8)
|
||||
actionview (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activemodel (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activestorage (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
rackup (1.0.1)
|
||||
rack (< 3)
|
||||
webrick
|
||||
rails (7.1.5.2)
|
||||
actioncable (= 7.1.5.2)
|
||||
actionmailbox (= 7.1.5.2)
|
||||
actionmailer (= 7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
actiontext (= 7.1.5.2)
|
||||
actionview (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activemodel (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activestorage (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.0.8)
|
||||
railties (= 7.1.5.2)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
actionview (>= 5.0.1.rc1)
|
||||
@@ -582,20 +626,21 @@ GEM
|
||||
activesupport (>= 4.2)
|
||||
choice (~> 0.2.0)
|
||||
ruby-graphviz (~> 1.2)
|
||||
rails-html-sanitizer (1.6.0)
|
||||
rails-html-sanitizer (1.6.1)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (~> 1.14)
|
||||
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||
rails-i18n (7.0.9)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 8)
|
||||
rails_safe_tasks (1.0.0)
|
||||
railties (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
method_source
|
||||
railties (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
irb
|
||||
rackup (>= 1.0.0)
|
||||
rake (>= 12.2)
|
||||
thor (~> 1.0)
|
||||
zeitwerk (~> 2.5)
|
||||
thor (~> 1.0, >= 1.2.2)
|
||||
zeitwerk (~> 2.6)
|
||||
rainbow (3.1.1)
|
||||
rake (13.2.1)
|
||||
ransack (4.1.1)
|
||||
@@ -729,6 +774,7 @@ GEM
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
sd_notify (0.1.1)
|
||||
securerandom (0.4.1)
|
||||
semantic_range (3.0.0)
|
||||
shoulda-matchers (6.2.0)
|
||||
activesupport (>= 5.2.0)
|
||||
@@ -746,7 +792,6 @@ GEM
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov_json_formatter (~> 0.1)
|
||||
simplecov-html (0.12.3)
|
||||
simplecov-lcov (0.8.0)
|
||||
simplecov_json_formatter (0.1.4)
|
||||
spreadsheet_architect (5.0.0)
|
||||
caxlsx (>= 3.3.0, < 4)
|
||||
@@ -794,12 +839,12 @@ GEM
|
||||
temple (0.8.2)
|
||||
terminal-table (4.0.0)
|
||||
unicode-display_width (>= 1.1.1, < 4)
|
||||
thor (1.3.1)
|
||||
thor (1.4.0)
|
||||
thread-local (1.1.0)
|
||||
tilt (2.3.0)
|
||||
timecop (0.9.8)
|
||||
timeout (0.4.1)
|
||||
ttfunk (1.7.0)
|
||||
timeout (0.4.3)
|
||||
ttfunk (1.8.0)
|
||||
bigdecimal (~> 3.1)
|
||||
turbo-rails (2.0.5)
|
||||
actionpack (>= 6.0.0)
|
||||
activejob (>= 6.0.0)
|
||||
@@ -817,8 +862,8 @@ GEM
|
||||
simplecov
|
||||
simplecov_json_formatter
|
||||
unicode-display_width (2.5.0)
|
||||
uniform_notifier (1.16.0)
|
||||
uri (0.13.0)
|
||||
uniform_notifier (1.17.0)
|
||||
uri (0.13.2)
|
||||
valid_email2 (5.2.3)
|
||||
activemodel (>= 3.2)
|
||||
mail (~> 2.5)
|
||||
@@ -858,7 +903,7 @@ GEM
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
webrick (1.8.1)
|
||||
webrick (1.8.2)
|
||||
websocket-driver (0.7.6)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
@@ -866,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)
|
||||
@@ -898,6 +943,7 @@ DEPENDENCIES
|
||||
cable_ready
|
||||
cancancan (~> 1.15.0)
|
||||
capybara
|
||||
capybara-shadowdom
|
||||
catalog!
|
||||
coffee-rails (~> 5.0.0)
|
||||
combine_pdf
|
||||
@@ -961,6 +1007,7 @@ DEPENDENCIES
|
||||
pg (~> 1.2.3)
|
||||
private_address_check
|
||||
pry (~> 0.13.0)
|
||||
puffing-billy
|
||||
puma
|
||||
query_count
|
||||
rack-mini-profiler (< 3.0.0)
|
||||
@@ -992,7 +1039,6 @@ DEPENDENCIES
|
||||
sidekiq
|
||||
sidekiq-scheduler
|
||||
simplecov
|
||||
simplecov-lcov
|
||||
spreadsheet_architect
|
||||
spring
|
||||
spring-commands-rspec
|
||||
@@ -1002,7 +1048,6 @@ DEPENDENCIES
|
||||
stimulus_reflex_testing!
|
||||
stringex (~> 2.8.5)
|
||||
stripe
|
||||
timecop
|
||||
turbo-rails
|
||||
turbo_power
|
||||
undercover
|
||||
|
||||
@@ -1,390 +0,0 @@
|
||||
angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout, $filter, $http, $window, $location, BulkProducts, DisplayProperties, DirtyProducts, VariantUnitManager, StatusMessage, producers, Taxons, Columns, tax_categories, RequestMonitor, SortOptions, ErrorsParser, ProductFiltersUrl) ->
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
|
||||
|
||||
$scope.RequestMonitor = RequestMonitor
|
||||
$scope.pagination = BulkProducts.pagination
|
||||
$scope.per_page_options = [
|
||||
{id: 15, name: t('js.admin.orders.index.per_page', results: 15)},
|
||||
{id: 50, name: t('js.admin.orders.index.per_page', results: 50)},
|
||||
{id: 100, name: t('js.admin.orders.index.per_page', results: 100)}
|
||||
]
|
||||
|
||||
$scope.q = {
|
||||
producerFilter: ""
|
||||
categoryFilter: ""
|
||||
importDateFilter: ""
|
||||
query: ""
|
||||
sorting: ""
|
||||
}
|
||||
|
||||
$scope.sorting = "name asc"
|
||||
$scope.producers = producers
|
||||
$scope.taxons = Taxons.all
|
||||
$scope.tax_categories = tax_categories
|
||||
$scope.page = 1
|
||||
$scope.per_page = 15
|
||||
$scope.products = BulkProducts.products
|
||||
$scope.DisplayProperties = DisplayProperties
|
||||
|
||||
$scope.sortOptions = SortOptions
|
||||
|
||||
$scope.initialise = ->
|
||||
$scope.q = ProductFiltersUrl.loadFromUrl($location.search())
|
||||
$scope.fetchProducts()
|
||||
|
||||
$scope.$watchCollection '[q.query, q.producerFilter, q.categoryFilter, q.importDateFilter, per_page]', ->
|
||||
$scope.page = 1 # Reset page when changing filters for new search
|
||||
|
||||
$scope.changePage = (newPage) ->
|
||||
$scope.page = newPage
|
||||
$scope.fetchProducts()
|
||||
|
||||
$scope.fetchProducts = ->
|
||||
removeClearedValues()
|
||||
params = {
|
||||
'q[name_cont]': $scope.q.query,
|
||||
'q[variants_supplier_id_eq]': $scope.q.producerFilter,
|
||||
'q[variants_primary_taxon_id_eq]': $scope.q.categoryFilter,
|
||||
'q[s]': $scope.sorting,
|
||||
import_date: $scope.q.importDateFilter,
|
||||
page: $scope.page,
|
||||
per_page: $scope.per_page
|
||||
}
|
||||
RequestMonitor.load(BulkProducts.fetch(params).$promise).then ->
|
||||
# update url with the filters used
|
||||
$location.search(ProductFiltersUrl.generate($scope.q))
|
||||
$scope.resetProducts()
|
||||
|
||||
removeClearedValues = ->
|
||||
delete $scope.q.producerFilter if $scope.q.producerFilter == "0"
|
||||
delete $scope.q.categoryFilter if $scope.q.categoryFilter == "0"
|
||||
delete $scope.q.importDateFilter if $scope.q.importDateFilter == "0"
|
||||
|
||||
$timeout ->
|
||||
if $scope.showLatestImport
|
||||
$scope.q.importDateFilter = $scope.importDates[1].id
|
||||
|
||||
$scope.resetProducts = ->
|
||||
DirtyProducts.clear()
|
||||
StatusMessage.clear()
|
||||
|
||||
$scope.updateOnHand = (product) ->
|
||||
on_demand_variants = []
|
||||
if product.variants
|
||||
on_demand_variants = (variant for id, variant of product.variants when variant.on_demand)
|
||||
|
||||
unless product.on_demand || on_demand_variants.length > 0
|
||||
product.on_hand = $scope.onHand(product)
|
||||
|
||||
|
||||
$scope.onHand = (product) ->
|
||||
onHand = 0
|
||||
if product.hasOwnProperty("variants") and product.variants instanceof Object
|
||||
for id, variant of product.variants
|
||||
onHand = onHand + parseInt(if variant.on_hand > 0 then variant.on_hand else 0)
|
||||
else
|
||||
onHand = "error"
|
||||
onHand
|
||||
|
||||
$scope.shiftTab = (tab) ->
|
||||
$scope.visibleTab.visible = false unless $scope.visibleTab == tab || $scope.visibleTab == undefined
|
||||
tab.visible = !tab.visible
|
||||
$scope.visibleTab = tab
|
||||
|
||||
$scope.resetSelectFilters = ->
|
||||
$scope.q.query = ""
|
||||
$scope.q.producerFilter = "0"
|
||||
$scope.q.categoryFilter = "0"
|
||||
$scope.q.importDateFilter = "0"
|
||||
$scope.fetchProducts()
|
||||
|
||||
$scope.$watch 'sortOptions', (sort) ->
|
||||
return unless sort && sort.predicate != ""
|
||||
|
||||
$scope.sorting = sort.getSortingExpr(defaultDirection: "asc")
|
||||
$scope.fetchProducts()
|
||||
, true
|
||||
|
||||
confirm_unsaved_changes = () ->
|
||||
(DirtyProducts.count() > 0 and confirm(t("unsaved_changes_confirmation"))) or (DirtyProducts.count() == 0)
|
||||
|
||||
editProductUrl = (product, variant) ->
|
||||
"/admin/products/" + product.id + ((if variant then "/variants/" + variant.id else "")) + "/edit"
|
||||
|
||||
$scope.editWarn = (product, variant) ->
|
||||
if confirm_unsaved_changes()
|
||||
$window.location.href = ProductFiltersUrl.buildUrl(editProductUrl(product, variant), $scope.q)
|
||||
|
||||
$scope.toggleShowAllVariants = ->
|
||||
showVariants = !DisplayProperties.showVariants 0
|
||||
$scope.products.forEach (product) ->
|
||||
DisplayProperties.setShowVariants product.id, showVariants
|
||||
DisplayProperties.setShowVariants 0, showVariants
|
||||
|
||||
$scope.addVariant = (product) ->
|
||||
# Set new variant category to same as last product variant category to keep compactibility with deleted variant callback to set new variant category
|
||||
newVariantId = $scope.nextVariantId();
|
||||
newVariantCategoryId = product.variants[product.variants.length - 1]?.category_id
|
||||
product.variants.push
|
||||
id: newVariantId
|
||||
unit_value: null
|
||||
unit_description: null
|
||||
on_demand: false
|
||||
display_as: null
|
||||
display_name: null
|
||||
on_hand: null
|
||||
price: null
|
||||
tax_category_id: null
|
||||
category_id: newVariantCategoryId
|
||||
DisplayProperties.setShowVariants product.id, true
|
||||
DirtyProducts.addVariantProperty(product.id, newVariantId, 'category_id', newVariantCategoryId)
|
||||
|
||||
|
||||
$scope.nextVariantId = ->
|
||||
$scope.variantIdCounter = 0 unless $scope.variantIdCounter?
|
||||
$scope.variantIdCounter -= 1
|
||||
$scope.variantIdCounter
|
||||
|
||||
$scope.deleteProduct = (product) ->
|
||||
if confirm(t('are_you_sure'))
|
||||
$http(
|
||||
method: "DELETE"
|
||||
url: "/api/v0/products/" + product.id
|
||||
).then (response) ->
|
||||
$scope.products.splice $scope.products.indexOf(product), 1
|
||||
DirtyProducts.deleteProduct product.id
|
||||
$scope.displayDirtyProducts()
|
||||
|
||||
|
||||
$scope.deleteVariant = (product, variant) ->
|
||||
if product.variants.length > 1
|
||||
if !$scope.variantSaved(variant)
|
||||
$scope.removeVariant(product, variant)
|
||||
else
|
||||
if confirm(t("are_you_sure"))
|
||||
$http(
|
||||
method: "DELETE"
|
||||
url: "/api/v0/products/" + product.id + "/variants/" + variant.id
|
||||
).then (response) ->
|
||||
$scope.removeVariant(product, variant)
|
||||
else
|
||||
alert(t("delete_product_variant"))
|
||||
|
||||
$scope.removeVariant = (product, variant) ->
|
||||
product.variants.splice product.variants.indexOf(variant), 1
|
||||
DirtyProducts.deleteVariant product.id, variant.id
|
||||
$scope.displayDirtyProducts()
|
||||
|
||||
|
||||
$scope.cloneProduct = (product) ->
|
||||
BulkProducts.cloneProduct product
|
||||
|
||||
$scope.hasVariants = (product) ->
|
||||
product.variants.length > 0
|
||||
|
||||
|
||||
$scope.hasUnit = (variant) ->
|
||||
variant.variant_unit_with_scale?
|
||||
|
||||
$scope.variantSaved = (variant) ->
|
||||
variant.hasOwnProperty('id') && variant.id > 0
|
||||
|
||||
|
||||
$scope.hasOnDemandVariants = (product) ->
|
||||
(variant for id, variant of product.variants when variant.on_demand).length > 0
|
||||
|
||||
|
||||
$scope.submitProducts = ->
|
||||
# Pack pack $scope.products, so they will match the list returned from the server,
|
||||
# then pack $scope.dirtyProducts, ensuring that the correct product info is sent to the server.
|
||||
$scope.packProduct product for id, product of $scope.products
|
||||
$scope.packProduct product for id, product of DirtyProducts.all()
|
||||
|
||||
productsToSubmit = filterSubmitProducts(DirtyProducts.all())
|
||||
if productsToSubmit.length > 0
|
||||
$scope.updateProducts productsToSubmit # Don't submit an empty list
|
||||
else
|
||||
StatusMessage.display 'alert', t("products_change")
|
||||
|
||||
|
||||
$scope.updateProducts = (productsToSubmit) ->
|
||||
$scope.displayUpdating()
|
||||
$http(
|
||||
method: "POST"
|
||||
url: "/admin/products/bulk_update"
|
||||
data:
|
||||
products: productsToSubmit
|
||||
filters:
|
||||
'q[name_cont]': $scope.q.query
|
||||
'q[variants_supplier_id_eq]': $scope.q.producerFilter
|
||||
'q[variants_primary_taxon_id_eq]': $scope.q.categoryFilter
|
||||
'q[s]': $scope.sorting
|
||||
import_date: $scope.q.importDateFilter
|
||||
page: $scope.page
|
||||
per_page: $scope.per_page
|
||||
).then((response) ->
|
||||
DirtyProducts.clear()
|
||||
BulkProducts.updateVariantLists(response.data.products || [])
|
||||
$timeout -> $scope.displaySuccess()
|
||||
).catch (response) ->
|
||||
if response.status == 400 && response.data.errors?
|
||||
errorsString = ErrorsParser.toString(response.data.errors, response.status)
|
||||
$scope.displayFailure t("products_update_error") + "\n" + errorsString
|
||||
else
|
||||
$scope.displayFailure t("products_update_error_data") + response.status
|
||||
|
||||
$scope.cancel = (destination) ->
|
||||
$window.location = destination
|
||||
|
||||
$scope.packProduct = (product) ->
|
||||
if product.variants
|
||||
for id, variant of product.variants
|
||||
$scope.packVariant variant
|
||||
|
||||
|
||||
$scope.packVariant = (variant) ->
|
||||
if variant.variant_unit_with_scale
|
||||
match = variant.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/)
|
||||
if match
|
||||
variant.variant_unit = match[1]
|
||||
variant.variant_unit_scale = parseFloat(match[2])
|
||||
else
|
||||
variant.variant_unit = variant.variant_unit_with_scale
|
||||
variant.variant_unit_scale = null
|
||||
|
||||
if variant.hasOwnProperty("unit_value_with_description")
|
||||
match = variant.unit_value_with_description.match(/^([\d\.\,]+(?= |$)|)( |)(.*)$/)
|
||||
if match
|
||||
variant.unit_value = parseFloat(match[1].replace(",", "."))
|
||||
variant.unit_value = null if isNaN(variant.unit_value)
|
||||
if variant.unit_value && variant.variant_unit_scale
|
||||
variant.unit_value = parseFloat(window.bigDecimal.multiply(variant.unit_value, variant.variant_unit_scale, 2))
|
||||
variant.unit_description = match[3]
|
||||
|
||||
$scope.incrementLimit = ->
|
||||
if $scope.limit < $scope.products.length
|
||||
$scope.limit = $scope.limit + 5
|
||||
|
||||
|
||||
$scope.displayUpdating = ->
|
||||
StatusMessage.display 'progress', t("saving")
|
||||
|
||||
|
||||
$scope.displaySuccess = ->
|
||||
StatusMessage.display 'success',t("products_changes_saved")
|
||||
$scope.bulk_product_form.$setPristine()
|
||||
|
||||
|
||||
$scope.displayFailure = (failMessage) ->
|
||||
StatusMessage.display 'failure', t("products_update_error_msg") + " #{failMessage}"
|
||||
|
||||
|
||||
$scope.displayDirtyProducts = ->
|
||||
count = DirtyProducts.count()
|
||||
switch count
|
||||
when 0 then StatusMessage.clear()
|
||||
when 1 then StatusMessage.display 'notice', t("one_product_unsaved")
|
||||
else StatusMessage.display 'notice', t("products_unsaved", n: count)
|
||||
|
||||
|
||||
filterSubmitProducts = (productsToFilter) ->
|
||||
filteredProducts = []
|
||||
if productsToFilter instanceof Object
|
||||
angular.forEach productsToFilter, (product) ->
|
||||
if product.hasOwnProperty("id")
|
||||
filteredProduct = {id: product.id}
|
||||
filteredVariants = []
|
||||
hasUpdatableProperty = false
|
||||
|
||||
if product.hasOwnProperty("variants")
|
||||
angular.forEach product.variants, (variant) ->
|
||||
result = filterSubmitVariant variant
|
||||
filteredVariant = result.filteredVariant
|
||||
variantHasUpdatableProperty = result.hasUpdatableProperty
|
||||
filteredVariants.push filteredVariant if variantHasUpdatableProperty
|
||||
|
||||
if product.hasOwnProperty("name")
|
||||
filteredProduct.name = product.name
|
||||
hasUpdatableProperty = true
|
||||
if product.hasOwnProperty("price")
|
||||
filteredProduct.price = product.price
|
||||
hasUpdatableProperty = true
|
||||
if product.hasOwnProperty("on_hand") and filteredVariants.length == 0 #only update if no variants present
|
||||
filteredProduct.on_hand = product.on_hand
|
||||
hasUpdatableProperty = true
|
||||
if product.hasOwnProperty("on_demand") and filteredVariants.length == 0 #only update if no variants present
|
||||
filteredProduct.on_demand = product.on_demand
|
||||
hasUpdatableProperty = true
|
||||
if product.hasOwnProperty("inherits_properties")
|
||||
filteredProduct.inherits_properties = product.inherits_properties
|
||||
hasUpdatableProperty = true
|
||||
if filteredVariants.length > 0 # Note that the name of the property changes to enable mass assignment of variants attributes with rails
|
||||
filteredProduct.variants_attributes = filteredVariants
|
||||
hasUpdatableProperty = true
|
||||
filteredProducts.push filteredProduct if hasUpdatableProperty
|
||||
|
||||
filteredProducts
|
||||
|
||||
|
||||
filterSubmitVariant = (variant) ->
|
||||
hasUpdatableProperty = false
|
||||
filteredVariant = {}
|
||||
if not variant.deleted_at? and variant.hasOwnProperty("id")
|
||||
filteredVariant.id = variant.id unless variant.id <= 0
|
||||
if variant.hasOwnProperty("sku")
|
||||
filteredVariant.sku = variant.sku
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("on_hand")
|
||||
filteredVariant.on_hand = variant.on_hand
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("on_demand")
|
||||
filteredVariant.on_demand = variant.on_demand
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("price")
|
||||
filteredVariant.price = variant.price
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("unit_value")
|
||||
filteredVariant.unit_value = variant.unit_value
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("unit_description")
|
||||
filteredVariant.unit_description = variant.unit_description
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("display_name")
|
||||
filteredVariant.display_name = variant.display_name
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("tax_category_id")
|
||||
filteredVariant.tax_category_id = variant.tax_category_id
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("category_id")
|
||||
filteredVariant.primary_taxon_id = variant.category_id
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("display_as")
|
||||
filteredVariant.display_as = variant.display_as
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("producer_id")
|
||||
filteredVariant.supplier_id = variant.producer_id
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("variant_unit_with_scale")
|
||||
filteredVariant.variant_unit = variant.variant_unit
|
||||
filteredVariant.variant_unit_scale = variant.variant_unit_scale
|
||||
hasUpdatableProperty = true
|
||||
if variant.hasOwnProperty("variant_unit_name")
|
||||
filteredVariant.variant_unit_name = variant.variant_unit_name
|
||||
hasUpdatableProperty = true
|
||||
|
||||
{filteredVariant: filteredVariant, hasUpdatableProperty: hasUpdatableProperty}
|
||||
|
||||
|
||||
toObjectWithIDKeys = (array) ->
|
||||
object = {}
|
||||
|
||||
for i of array
|
||||
if array[i] instanceof Object and array[i].hasOwnProperty("id")
|
||||
object[array[i].id] = angular.copy(array[i])
|
||||
object[array[i].id].variants = toObjectWithIDKeys(array[i].variants) if array[i].hasOwnProperty("variants") and array[i].variants instanceof Array
|
||||
|
||||
object
|
||||
@@ -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"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
angular.module("ofn.admin").controller "ProductImageCtrl", ($scope, ProductImageService) ->
|
||||
$scope.imageUploader = ProductImageService.imageUploader
|
||||
$scope.imagePreview = ProductImageService.imagePreview
|
||||
|
||||
$scope.$watch 'product.image_url', (newValue, oldValue) ->
|
||||
if newValue != oldValue
|
||||
$scope.imagePreview = newValue
|
||||
$scope.uploadModal.close()
|
||||
@@ -1,6 +0,0 @@
|
||||
angular.module("ofn.admin").directive "imageModal", ($modal, ProductImageService) ->
|
||||
restrict: 'C'
|
||||
link: (scope, elem, attrs, ctrl) ->
|
||||
elem.on "click", (ev) =>
|
||||
scope.uploadModal = $modal.open(templateUrl: 'admin/modals/image_upload.html', controller: ctrl, scope: scope, windowClass: 'simple-modal')
|
||||
ProductImageService.configure(scope.product)
|
||||
@@ -1,6 +0,0 @@
|
||||
angular.module("admin.resources").factory 'ProductResource', ($resource) ->
|
||||
$resource('/admin/product/:id/:action.json', {}, {
|
||||
'index':
|
||||
url: '/api/v0/products/bulk_products.json'
|
||||
method: 'GET'
|
||||
})
|
||||
@@ -1,76 +0,0 @@
|
||||
angular.module("ofn.admin").factory "BulkProducts", (ProductResource, dataFetcher, $http) ->
|
||||
new class BulkProducts
|
||||
products: []
|
||||
pagination: {}
|
||||
|
||||
fetch: (params) ->
|
||||
ProductResource.index params, (data) =>
|
||||
@products.length = 0
|
||||
@addProducts data.products
|
||||
angular.extend(@pagination, data.pagination)
|
||||
|
||||
cloneProduct: (product) ->
|
||||
$http.post("/api/v0/products/" + product.id + "/clone").then (response) =>
|
||||
dataFetcher("/api/v0/products/" + response.data.id + "?template=bulk_show").then (newProduct) =>
|
||||
@unpackProduct newProduct
|
||||
@insertProductAfter(product, newProduct)
|
||||
|
||||
updateVariantLists: (serverProducts) ->
|
||||
for server_product in serverProducts
|
||||
product = @findProductInList(server_product.id, @products)
|
||||
product.variants = server_product.variants
|
||||
@loadVariantUnitValues product.variants
|
||||
|
||||
find: (id) ->
|
||||
@findProductInList id, @products
|
||||
|
||||
findProductInList: (id, product_list) ->
|
||||
products = (product for product in product_list when product.id == id)
|
||||
if products.length == 0 then null else products[0]
|
||||
|
||||
addProducts: (products) ->
|
||||
for product in products
|
||||
@unpackProduct product
|
||||
@products.push product
|
||||
|
||||
insertProductAfter: (product, newProduct) ->
|
||||
index = @products.indexOf(product)
|
||||
@products.splice(index + 1, 0, newProduct)
|
||||
|
||||
unpackProduct: (product) ->
|
||||
@loadVariantUnit product
|
||||
|
||||
loadVariantUnit: (product) ->
|
||||
@loadVariantUnitValues product.variants if product.variants
|
||||
|
||||
loadVariantUnitValues: (variants) ->
|
||||
for variant in variants
|
||||
@loadVariantUnitValue variant
|
||||
|
||||
loadVariantUnitValue: (variant) ->
|
||||
variant.variant_unit_with_scale =
|
||||
if variant.variant_unit && variant.variant_unit_scale && variant.variant_unit != 'items'
|
||||
"#{variant.variant_unit}_#{variant.variant_unit_scale}"
|
||||
else if variant.variant_unit
|
||||
variant.variant_unit
|
||||
else
|
||||
null
|
||||
|
||||
unit_value = @variantUnitValue variant
|
||||
unit_value = if unit_value? then unit_value else ''
|
||||
variant.unit_value_with_description = "#{unit_value} #{variant.unit_description || ''}".trim()
|
||||
|
||||
variantUnitValue: (variant) ->
|
||||
if variant.unit_value?
|
||||
if variant.variant_unit_scale
|
||||
variant_unit_value = @divideAsInteger variant.unit_value, variant.variant_unit_scale
|
||||
parseFloat(window.bigDecimal.round(variant_unit_value, 2))
|
||||
else
|
||||
variant.unit_value
|
||||
else
|
||||
null
|
||||
|
||||
# forces integer division to avoid javascript floating point imprecision
|
||||
# using one billion as the multiplier so that it works for numbers with up to 9 decimal places
|
||||
divideAsInteger: (a, b) ->
|
||||
(a * 1000000000) / (b * 1000000000)
|
||||
@@ -54,7 +54,7 @@ module Api
|
||||
def error_during_processing(exception)
|
||||
Alert.raise(exception)
|
||||
|
||||
if Rails.env.development? || Rails.env.test?
|
||||
if Rails.env.local?
|
||||
render status: :unprocessable_entity,
|
||||
json: json_api_error(exception.message, meta: exception.backtrace)
|
||||
else
|
||||
|
||||
@@ -80,8 +80,6 @@ class CheckoutController < BaseController
|
||||
|
||||
@order.customer.touch :terms_and_conditions_accepted_at
|
||||
|
||||
return true if redirect_to_payment_gateway
|
||||
|
||||
# Redeem VINE voucher
|
||||
vine_voucher_redeemer = Vine::VoucherRedeemerService.new(order: @order)
|
||||
unless vine_voucher_redeemer.redeem
|
||||
@@ -94,6 +92,9 @@ class CheckoutController < BaseController
|
||||
return false
|
||||
# rubocop:enable Rails/DeprecatedActiveModelErrorsMethods
|
||||
end
|
||||
|
||||
return true if redirect_to_payment_gateway
|
||||
|
||||
@order.process_payments!
|
||||
@order.confirm!
|
||||
BackorderJob.check_stock(@order)
|
||||
|
||||
@@ -19,11 +19,6 @@ module Spree
|
||||
before_action :load_spree_api_key, only: [:index, :variant_overrides]
|
||||
before_action :strip_new_properties, only: [:create, :update]
|
||||
|
||||
def index
|
||||
@current_user = spree_current_user
|
||||
@show_latest_import = params[:latest_import] || false
|
||||
end
|
||||
|
||||
def show
|
||||
session[:return_to] ||= request.referer
|
||||
redirect_to( action: :edit )
|
||||
@@ -65,28 +60,6 @@ module Spree
|
||||
end
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
product_set = product_set_from_params
|
||||
|
||||
product_set.collection.each { |p| authorize! :update, p }
|
||||
|
||||
if product_set.save
|
||||
redirect_to main_app.bulk_products_api_v0_products_path(bulk_index_query)
|
||||
elsif product_set.errors.present?
|
||||
render json: { errors: product_set.errors }, status: :bad_request
|
||||
else
|
||||
render body: nil, status: :internal_server_error
|
||||
end
|
||||
end
|
||||
|
||||
def clone
|
||||
@new = @product.duplicate
|
||||
raise "Clone failed" unless @new.save
|
||||
|
||||
flash[:success] = t('.success')
|
||||
redirect_to spree.admin_products_url
|
||||
end
|
||||
|
||||
def group_buy_options
|
||||
@url_filters = ::ProductFilters.new.extract(request.query_parameters)
|
||||
end
|
||||
|
||||
@@ -26,8 +26,8 @@ module Admin
|
||||
show_enterprise_fees = can?(:manage_enterprise_fees,
|
||||
enterprise) && (is_shop || enterprise.is_primary_producer)
|
||||
show_connected_apps = can?(:manage_connected_apps, enterprise) &&
|
||||
feature?(:connected_apps, spree_current_user, enterprise) &&
|
||||
Spree::Config.connected_apps_enabled.present?
|
||||
(connected_apps_enabled(enterprise).present? ||
|
||||
dfc_platforms_available?)
|
||||
show_inventory_settings = feature?(:inventory, spree_current_user.enterprises) && is_shop
|
||||
|
||||
show_options = {
|
||||
@@ -42,11 +42,19 @@ module Admin
|
||||
build_enterprise_side_menu_items(is_shop:, show_options:)
|
||||
end
|
||||
|
||||
def connected_apps_enabled
|
||||
def connected_apps_enabled(enterprise)
|
||||
return [] unless feature?(:connected_apps, spree_current_user, enterprise)
|
||||
|
||||
connected_apps_enabled = Spree::Config.connected_apps_enabled&.split(',') || []
|
||||
ConnectedApp::TYPES & connected_apps_enabled
|
||||
end
|
||||
|
||||
def dfc_platforms_available?
|
||||
DfcProvider::PlatformsController::PLATFORM_IDS.keys.any? do |id|
|
||||
feature?(id, spree_current_user)
|
||||
end
|
||||
end
|
||||
|
||||
def enterprise_attachment_removal_modal_id
|
||||
attachment_removal_parameter # remove_logo|remove_promo_image|remove_white_label_logo
|
||||
end
|
||||
@@ -63,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
|
||||
|
||||
@@ -32,12 +32,8 @@ module Admin
|
||||
[precised_unit_value, variant.unit_description].compact_blank.join(" ")
|
||||
end
|
||||
|
||||
def products_return_to_url(url_filters)
|
||||
if feature?(:admin_style_v3, spree_current_user)
|
||||
return session[:products_return_to_url] || admin_products_url
|
||||
end
|
||||
|
||||
"#{admin_products_path}#{url_filters.empty? ? '' : "#?#{url_filters.to_query}"}"
|
||||
def products_return_to_url
|
||||
session[:products_return_to_url] || admin_products_url
|
||||
end
|
||||
|
||||
# if user hasn't saved any preferences on products page and there's only one producer;
|
||||
|
||||
@@ -5,10 +5,6 @@ module CheckoutHelper
|
||||
order.ship_address == order.bill_address
|
||||
end
|
||||
|
||||
def guest_checkout_allowed?
|
||||
current_order.distributor.allow_guest_orders?
|
||||
end
|
||||
|
||||
def checkout_adjustments_for(order, opts = {})
|
||||
exclude = opts[:exclude] || {}
|
||||
reject_zero_amount = opts.fetch(:reject_zero_amount, true)
|
||||
|
||||
@@ -29,13 +29,7 @@ module Spree
|
||||
scope: [:admin, :tab]).capitalize
|
||||
|
||||
css_classes = []
|
||||
|
||||
if options[:icon] && !feature?(:admin_style_v3, spree_current_user)
|
||||
link = link_to_with_icon(options[:icon], titleized_label, destination_url)
|
||||
css_classes << 'tab-with-icon'
|
||||
else
|
||||
link = link_to(titleized_label, destination_url)
|
||||
end
|
||||
link = link_to(titleized_label, destination_url)
|
||||
|
||||
selected = if options[:match_path]
|
||||
PathChecker
|
||||
|
||||
@@ -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
|
||||
|
||||
15
app/models/dfc_permission.rb
Normal file
15
app/models/dfc_permission.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Authorisations of a user allowing a platform to access to data.
|
||||
class DfcPermission < ApplicationRecord
|
||||
SCOPES = %w[
|
||||
ReadEnterprise ReadProducts ReadOrders
|
||||
WriteEnterprise WriteProducts WriteOrders
|
||||
].freeze
|
||||
|
||||
belongs_to :user, class_name: "Spree::User"
|
||||
belongs_to :enterprise
|
||||
|
||||
validates :grantee, presence: true
|
||||
validates :scope, presence: true, inclusion: { in: SCOPES }
|
||||
end
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
- connected_apps_enabled.each do |type|
|
||||
- connected_apps_enabled(enterprise).each do |type|
|
||||
= render partial: "/admin/enterprises/form/connected_apps/#{type}",
|
||||
locals: { enterprise:, connected_app: enterprise.connected_apps.public_send(type).first }
|
||||
|
||||
= render partial: "/admin/enterprises/form/dfc_permissions" if dfc_platforms_available?
|
||||
|
||||
30
app/views/admin/enterprises/form/_dfc_permissions.html.haml
Normal file
30
app/views/admin/enterprises/form/_dfc_permissions.html.haml
Normal file
@@ -0,0 +1,30 @@
|
||||
%script{type: "module", src: "https://cdn.jsdelivr.net/npm/@startinblox/core@latest/dist/index.js"}
|
||||
%script{type: "module"}
|
||||
:plain
|
||||
window.orbit = {
|
||||
client: {
|
||||
name: "Orbit",
|
||||
logo: "https://cdn.startinblox.com/logos/ACME.svg",
|
||||
},
|
||||
components: [],
|
||||
getRoute: (route) => route,
|
||||
getDefaultRoute: () => "",
|
||||
getComponent: () => undefined,
|
||||
getComponentFromRoute: () => undefined,
|
||||
Swal: () => {},
|
||||
defaultRoute: "",
|
||||
federations: {},
|
||||
componentSet: new Set(["routing", "menu", "menu-top", "autoLogin", "solid-permissioning"]),
|
||||
};
|
||||
|
||||
:plain
|
||||
<solid-permissioning
|
||||
data-src="#{DfcProvider::Engine.routes.url_helpers.enterprise_platforms_url(@enterprise.id)}"
|
||||
scopes-uri="https://cdn.startinblox.com/owl/dfc/taxonomies/scopes.jsonld"
|
||||
noRouter
|
||||
auto-lang
|
||||
lang="en"
|
||||
auth-token="#{form_authenticity_token}">
|
||||
</solid-permissioning>
|
||||
|
||||
%script{type: "module", src: "https://cdn.jsdelivr.net/npm/@startinblox/solid-data-permissioning@latest/dist/index.js"}
|
||||
@@ -1,4 +1,4 @@
|
||||
= form_with url: bulk_update_admin_products_path, method: :post, id: "products-form",
|
||||
= form_with url: admin_products_bulk_update_path, method: :post, id: "products-form",
|
||||
builder: BulkFormBuilder,
|
||||
html: { data: { 'turbo-frame': "_self",
|
||||
controller: "bulk-form",
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
.pagination{ "data-controller": "search" }
|
||||
- if pagy.prev
|
||||
%button.page.prev{ data: { action: 'click->search#changePage', page: pagy.prev } }
|
||||
- if feature?(:admin_style_v3, spree_current_user)
|
||||
%i.icon-chevron-left{ data: { action: 'click->search#changePage', page: pagy.prev } }
|
||||
- else
|
||||
!= pagy_t('pagy.prev')
|
||||
%i.icon-chevron-left{ data: { action: 'click->search#changePage', page: pagy.prev } }
|
||||
- else
|
||||
%button.page.disabled{disabled: "disabled"}!= pagy_t('pagy.prev')
|
||||
|
||||
@@ -22,9 +19,6 @@
|
||||
|
||||
- if pagy.next
|
||||
%button.page.next{ data: { action: 'click->search#changePage', page: pagy.next } }
|
||||
- if feature?(:admin_style_v3, spree_current_user)
|
||||
%i.icon-chevron-right{ data: { action: 'click->search#changePage', page: pagy.next } }
|
||||
- else
|
||||
!= pagy_t('pagy.next')
|
||||
%i.icon-chevron-right{ data: { action: 'click->search#changePage', page: pagy.next } }
|
||||
- else
|
||||
%button.page.disabled.pagination-next{disabled: "disabled"}!= pagy_t('pagy.next')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
= admin_inject_available_units
|
||||
|
||||
- content_for :page_actions do
|
||||
%li= button_link_to t('admin.products.back_to_products_list'), products_return_to_url(@url_filters), :icon => 'icon-arrow-left'
|
||||
%li= button_link_to t('admin.products.back_to_products_list'), products_return_to_url, :icon => 'icon-arrow-left'
|
||||
%li#new_product_link
|
||||
= button_link_to t(:new_product), new_object_url, { :icon => 'icon-plus', :id => 'admin_new_product' }
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
= button t(:update), 'icon-refresh'
|
||||
|
||||
= button_link_to t(:cancel), products_return_to_url(@url_filters), icon: 'icon-remove'
|
||||
= button_link_to t(:cancel), products_return_to_url, icon: 'icon-remove'
|
||||
|
||||
#product-preview-modal-container
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
= render 'spree/admin/products/index/header'
|
||||
= render 'spree/admin/products/index/data'
|
||||
= admin_inject_available_units
|
||||
|
||||
%div{ "ng-app": 'ofn.admin', "ng-controller": 'AdminProductEditCtrl', "ng-init": 'initialise()' }
|
||||
|
||||
= render 'spree/admin/products/index/filters'
|
||||
%div{ 'ng-cloak' => true }
|
||||
= render 'spree/admin/products/index/actions'
|
||||
= render 'spree/admin/products/index/indicators'
|
||||
= render 'spree/admin/products/index/products'
|
||||
|
||||
%div{'ng-show' => "!RequestMonitor.loading && products.length > 0" }
|
||||
= render partial: 'admin/shared/angular_pagination'
|
||||
@@ -1,11 +0,0 @@
|
||||
.controls.sixteen.columns.alpha{ 'ng-hide' => 'RequestMonitor.loading || products.length == 0' }
|
||||
.ten.columns.alpha.index-controls
|
||||
.per-page{'ng-show' => '!RequestMonitor.loading && products.length > 0'}
|
||||
%input.per-page-select.ofn-select2{type: 'number', data: 'per_page_options', 'min-search' => 999, 'ng-model' => 'per_page', 'ng-change' => 'fetchProducts()'}
|
||||
|
||||
%span.per-page-feedback
|
||||
{{ 'spree.admin.orders.index.results_found' | t:{number: pagination.results} }}
|
||||
{{ 'spree.admin.orders.index.viewing' | t:{start: ((pagination.page -1) * pagination.per_page) +1, end: ((pagination.page -1) * pagination.per_page) + products.length} }}
|
||||
|
||||
.six.columns.omega
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
@@ -1,5 +0,0 @@
|
||||
= admin_inject_producers(@producers)
|
||||
= admin_inject_taxons(@taxons)
|
||||
= admin_inject_tax_categories(@tax_categories)
|
||||
= admin_inject_spree_api_key(@spree_api_key)
|
||||
= admin_inject_column_preferences
|
||||
@@ -1,33 +0,0 @@
|
||||
%fieldset
|
||||
%legend{align: 'center'}= t(:search)
|
||||
|
||||
.filters.sixteen.columns.alpha.omega
|
||||
.quick_search.three.columns.alpha
|
||||
%label{ for: 'quick_filter' }
|
||||
%br
|
||||
%input.quick-search.fullwidth{ name: "quick_filter", type: 'text', placeholder: t('admin.quick_search'), "ng-keypress": "$event.keyCode === 13 && fetchProducts()", "ng-model": 'q.query' }
|
||||
.one.columns
|
||||
.filter_select.three.columns
|
||||
%label{ for: 'producer_filter' }= t 'producer'
|
||||
%br
|
||||
%select.fullwidth{ id: 'producer_filter', "ofn-select2-min-search": 5, "ng-model": 'q.producerFilter', "ng-options": 'producer.id as producer.name for producer in producers' }
|
||||
.filter_select.three.columns
|
||||
%label{ for: 'category_filter' }= t 'category'
|
||||
%br
|
||||
%select.fullwidth{ id: 'category_filter', "ofn-select2-min-search": 5, "ng-model": 'q.categoryFilter', "ng-options": 'taxon.id as taxon.name for taxon in taxons' }
|
||||
.filter_select.three.columns
|
||||
%label{ for: 'import_filter' }= t 'import_date'
|
||||
%br
|
||||
%select.fullwidth{ id: 'import_date_filter', "ofn-select2-min-search": 5, "ng-model": 'q.importDateFilter', "ng-init": "importDates = #{@import_dates}; showLatestImport = #{@show_latest_import}", "ng-options": 'date.id as date.name for date in importDates' }
|
||||
|
||||
.filter_clear.three.columns.omega
|
||||
%label{ for: 'clear_all_filters' }
|
||||
%br
|
||||
%input.fullwidth.red{ :type => 'button', :id => 'clear_all_filters', :value => t('admin.clear_filters'), 'ng-click' => "resetSelectFilters()" }
|
||||
|
||||
.clearfix
|
||||
|
||||
.actions.filter-actions
|
||||
%div
|
||||
%a.button.icon-search{'ng-click' => 'fetchProducts()'}
|
||||
= t(:filter_results)
|
||||
@@ -1,10 +0,0 @@
|
||||
- content_for :page_title do
|
||||
= t('.title')
|
||||
|
||||
- content_for :page_actions do
|
||||
%div{ :class => "toolbar" }
|
||||
%ul{ :class => "actions header-action-links inline-menu" }
|
||||
%li#new_product_link
|
||||
= button_link_to t(:new_product), new_object_url, { :icon => 'icon-plus', :id => 'admin_new_product' }
|
||||
|
||||
= render partial: 'spree/admin/shared/product_sub_menu'
|
||||
@@ -1,14 +0,0 @@
|
||||
.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
|
||||
= render partial: "components/admin_spinner"
|
||||
%h1
|
||||
= t('.title')
|
||||
|
||||
.sixteen.columns.alpha{ 'ng-show' => '!RequestMonitor.loading && products.length == 0 && q.query.length == 0' }
|
||||
%h1#no_results= t('.no_products')
|
||||
|
||||
.sixteen.columns.alpha{ 'ng-show' => '!RequestMonitor.loading && products.length == 0 && q.query.length != 0' }
|
||||
%h1#no_results
|
||||
= t('.no_results')
|
||||
'
|
||||
{{q.query}}
|
||||
'
|
||||
@@ -1,14 +0,0 @@
|
||||
.sixteen.columns.alpha{ 'ng-hide' => 'RequestMonitor.loading || products.length == 0' }
|
||||
%form{ name: 'bulk_product_form', autocomplete: "off" }
|
||||
%save-bar{ dirty: "bulk_product_form.$dirty", persist: "false" }
|
||||
%input.red{ type: "button", value: t(:save_changes), "ng-click": "submitProducts()", "ng-disabled": "!bulk_product_form.$dirty" }
|
||||
%input{ type: "button", value: t(:close), 'ng-click' => "cancel('#{admin_products_path}')" }
|
||||
|
||||
%table.index#listing_products.bulk
|
||||
|
||||
= render 'spree/admin/products/index/products_head'
|
||||
|
||||
%tbody{ 'ng-repeat' => 'product in products', 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'" }
|
||||
|
||||
= render 'spree/admin/products/index/products_product'
|
||||
= render 'spree/admin/products/index/products_variant'
|
||||
@@ -1,41 +0,0 @@
|
||||
%colgroup
|
||||
%col.actions
|
||||
%col.image{ "ng-show": 'columns.image.visible' }
|
||||
%col.producer{ "ng-show": 'columns.producer.visible' }
|
||||
%col.sku{ "ng-show": 'columns.sku.visible' }
|
||||
%col.name{ "ng-show": 'columns.name.visible' }
|
||||
%col.unit{ "ng-show": 'columns.unit.visible' }
|
||||
%col.display_as{ "ng-show": 'columns.unit.visible' }
|
||||
%col.price{ "ng-show": 'columns.price.visible' }
|
||||
%col.on_hand{ "ng-show": 'columns.on_hand.visible' }
|
||||
%col.on_demand{ "ng-show": 'columns.on_demand.visible' }
|
||||
%col.category{ "ng-show": 'columns.category.visible' }
|
||||
%col.tax_category{ "ng-show": 'columns.tax_category.visible' }
|
||||
%col.inherits_properties{ "ng-show": 'columns.inherits_properties.visible' }
|
||||
%col.import_date{ "ng-show": 'columns.import_date.visible' }
|
||||
%col.actions
|
||||
%col.actions
|
||||
%col.actions
|
||||
|
||||
%thead
|
||||
%tr{ "ng-controller": "ColumnsCtrl" }
|
||||
%th.left-actions
|
||||
%a{ 'ng-click' => 'toggleShowAllVariants()', :style => 'color: red; cursor: pointer' }
|
||||
= t(:expand_all)
|
||||
%th.image{ 'ng-show' => 'columns.image.visible' }
|
||||
%th.producer{ 'ng-show' => 'columns.producer.visible' }=t('admin.producer')
|
||||
%th.sku{ 'ng-show' => 'columns.sku.visible' }=t('admin.sku')
|
||||
%th.name{ 'ng-show' => 'columns.name.visible' }
|
||||
= render partial: 'spree/admin/shared/sortable_header', locals: {column_name: 'name'}
|
||||
%th.unit{ 'ng-show' => 'columns.unit.visible' }=t('.unit')
|
||||
%th.display_as{ 'ng-show' => 'columns.unit.visible' }=t('.display_as')
|
||||
%th.price{ 'ng-show' => 'columns.price.visible' }=t('admin.price')
|
||||
%th.on_hand{ 'ng-show' => 'columns.on_hand.visible' }=t('admin.on_hand')
|
||||
%th.on_demand{ 'ng-show' => 'columns.on_demand.visible' }=t('admin.on_demand?')
|
||||
%th.category{ 'ng-show' => 'columns.category.visible' }=t('.category')
|
||||
%th.tax_category{ 'ng-show' => 'columns.tax_category.visible' }=t('.tax_category')
|
||||
%th.inherits_properties{ 'ng-show' => 'columns.inherits_properties.visible' }=t('.inherits_properties?')
|
||||
%th.import_date{ 'ng-show' => 'columns.import_date.visible' }=t('.import_date')
|
||||
%th.actions
|
||||
%th.actions
|
||||
%th.actions
|
||||
@@ -1,33 +0,0 @@
|
||||
%tr.product{ :id => "p_{{product.id}}" }
|
||||
%td.left-actions
|
||||
%a{ 'ofn-toggle-variants' => 'true', :class => "view-variants", 'ng-show' => 'hasVariants(product)' }
|
||||
%a{ :class => "add-variant icon-plus-sign", 'ng-click' => "addVariant(product)", 'ng-show' => "!hasVariants(product) && hasUnit(product)" }
|
||||
%td.image{ 'ng-show' => 'columns.image.visible' }
|
||||
%a{class: 'image-modal'}
|
||||
%img{'ng-src' => '{{ product.thumb_url }}'}
|
||||
%td.producer{ 'ng-show' => 'columns.producer.visible' }
|
||||
%td.sku{ 'ng-show' => 'columns.sku.visible' }
|
||||
%input{ 'ng-model' => "product.sku", :name => 'product_sku', 'ofn-track-product' => 'sku', :type => 'text' }
|
||||
%td.name{ 'ng-show' => 'columns.name.visible' }
|
||||
%input{ 'ng-model' => "product.name", :name => 'product_name', 'ofn-track-product' => 'name', :type => 'text' }
|
||||
%td.unit{ 'ng-show' => 'columns.unit.visible' }
|
||||
%td.display_as{ 'ng-show' => 'columns.unit.visible' }
|
||||
%td.price{ 'ng-show' => 'columns.price.visible' }
|
||||
%input{ 'ng-model' => 'product.price', 'ofn-decimal' => :true, :name => 'price', 'ofn-track-product' => 'price', :type => 'text', 'ng-hide' => 'hasVariants(product)' }
|
||||
%td.on_hand{ 'ng-show' => 'columns.on_hand.visible' }
|
||||
%span{ 'ng-bind' => 'product.on_hand', :name => 'on_hand', 'ng-if' => '!hasOnDemandVariants(product) && (hasVariants(product) || product.on_demand)' }
|
||||
%input.field{ 'ng-model' => 'product.on_hand', :name => 'on_hand', 'ofn-track-product' => 'on_hand', 'ng-if' => '!(hasVariants(product) || product.on_demand)', :type => 'number' }
|
||||
%td.on_demand{ 'ng-show' => 'columns.on_demand.visible' }
|
||||
%input.field{ 'ng-model' => 'product.on_demand', :name => 'on_demand', 'ofn-track-product' => 'on_demand', :type => 'checkbox', 'ng-hide' => 'hasVariants(product)' }
|
||||
%td.category{ 'ng-if' => 'columns.category.visible' }
|
||||
%td.tax_category{ 'ng-if' => 'columns.tax_category.visible' }
|
||||
%td.inherits_properties{ 'ng-show' => 'columns.inherits_properties.visible' }
|
||||
%input{ 'ng-model' => 'product.inherits_properties', :name => 'inherits_properties', 'ofn-track-product' => 'inherits_properties', type: "checkbox" }
|
||||
%td.import_date{ 'ng-show' => 'columns.import_date.visible' }
|
||||
%span {{(product.import_date | date:"MMMM dd, yyyy HH:mm") || ""}}
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'editWarn(product)', :class => "edit-product icon-edit no-text", 'ofn-with-tip' => t(:edit) }
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'cloneProduct(product)', :class => "clone-product icon-copy no-text", 'ofn-with-tip' => t(:clone) }
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'deleteProduct(product)', :class => "delete-product icon-trash no-text", 'ofn-with-tip' => t(:remove) }
|
||||
@@ -1,39 +0,0 @@
|
||||
%tr.variant{ :id => "v_{{variant.id}}", 'ng-repeat' => 'variant in product.variants', 'ng-show' => 'DisplayProperties.showVariants(product.id)', 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'" }
|
||||
%td.left-actions
|
||||
%a{ :class => "variant-item icon-caret-right", 'ng-hide' => "$last" }
|
||||
%a{ :class => "add-variant icon-plus-sign", 'ng-click' => "addVariant(product)", 'ng-show' => "$last", 'ofn-with-tip' => t('.new_variant') }
|
||||
%td{ 'ng-show' => 'columns.image.visible' }
|
||||
%td{ 'ng-show' => 'columns.producer.visible' }
|
||||
%select.fullwidth{ "data-controller": "tom-select", 'ng-model' => 'variant.producer_id', :name => 'producer_id', 'ofn-track-variant' => 'producer_id', 'ng-options' => 'producer.id as producer.name for producer in producers' }
|
||||
%td{ 'ng-show' => 'columns.sku.visible' }
|
||||
%input{ 'ng-model' => "variant.sku", :name => 'variant_sku', 'ofn-track-variant' => 'sku', :type => 'text' }
|
||||
%td{ 'ng-show' => 'columns.name.visible' }
|
||||
%input{ 'ng-model' => 'variant.display_name', :name => 'variant_display_name', 'ofn-track-variant' => 'display_name', :type => 'text', placeholder: "{{ product.name }}" }
|
||||
%td.unit_value{ 'ng-show' => 'columns.unit.visible' }
|
||||
%select.no-search{ "data-controller": "tom-select", 'ng-model' => 'variant.variant_unit_with_scale', :name => 'variant_unit_with_scale', 'ofn-track-variant' => 'variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' }
|
||||
%input{ 'ng-model' => 'variant.unit_value_with_description', :name => 'variant_unit_value_with_description', 'ofn-track-variant' => 'unit_value_with_description', :type => 'text', :placeholder => 'value', 'ng-show' => "hasUnit(variant)" }
|
||||
%input{ 'ng-model' => 'variant.variant_unit_name', :name => 'variant_unit_name', 'ofn-track-variant' => 'variant_unit_name', :placeholder => 'unit', 'ng-show' => "variant.variant_unit_with_scale == 'items'", :type => 'text' }
|
||||
%td.display_as{ 'ng-show' => 'columns.unit.visible' }
|
||||
%input{ 'ofn-display-as' => 'variant', 'ng-model' => 'variant.display_as', name: 'variant_display_as', 'ofn-track-variant' => 'display_as', type: 'text', placeholder: '{{ placeholder_text }}' }
|
||||
%td{ 'ng-show' => 'columns.price.visible' }
|
||||
%input{ 'ng-model' => 'variant.price', 'ofn-decimal' => :true, :name => 'variant_price', 'ofn-track-variant' => 'price', :type => 'text' }
|
||||
%td{ 'ng-show' => 'columns.on_hand.visible' }
|
||||
%input.field{ 'ng-model' => 'variant.on_hand', 'ng-change' => 'updateOnHand(product)', :name => 'variant_on_hand', 'ng-if' => '!variant.on_demand', 'ofn-track-variant' => 'on_hand', :type => 'number' }
|
||||
%span{ :name => 'variant_on_hand', 'ng-if' => 'variant.on_demand' }
|
||||
= t(:on_demand)
|
||||
%td{ 'ng-show' => 'columns.on_demand.visible' }
|
||||
%input.field{ 'ng-model' => 'variant.on_demand', :name => 'variant_on_demand', 'ofn-track-variant' => 'on_demand', :type => 'checkbox' }
|
||||
%td{ 'ng-show' => 'columns.category.visible' }
|
||||
%input.fullwidth{ type: 'text', id: "p{{product.id}}_category_id", 'ng-model' => 'variant.category_id', 'ofn-taxon-autocomplete' => '', 'ofn-track-variant' => 'category_id', 'multiple-selection' => 'false', placeholder: 'Category' }
|
||||
%td{ 'ng-show' => 'columns.tax_category.visible' }
|
||||
%select.select2{ name: 'variant_tax_category_id', "ofn-track-variant": 'tax_category_id', "ng-model": 'variant.tax_category_id', "ng-options": 'tax_category.id as tax_category.name for tax_category in tax_categories' }
|
||||
%option{ value: '' }= t(:none)
|
||||
%td{ 'ng-show' => 'columns.inherits_properties.visible' }
|
||||
%td{ 'ng-show' => 'columns.import_date.visible' }
|
||||
%span {{variant.import_date | date:"MMMM dd, yyyy HH:mm"}}
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'editWarn(product,variant)', :class => "edit-variant icon-edit no-text", 'ng-show' => "variantSaved(variant)", 'ofn-with-tip' => t(:edit) }
|
||||
%td.actions
|
||||
%span.icon-warning-sign{ 'ng-if' => 'variant.variant_overrides_count > 0', 'ofn-with-tip' => "{{ 'spree.admin.products.index.products_variant.variant_has_n_overrides' | t:{n: variant.variant_overrides_count} }}" }
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'deleteVariant(product,variant)', "ng-class" => '{disabled: product.variants.length < 2}', :class => "delete-variant icon-trash no-text", 'ofn-with-tip' => t(:remove) }
|
||||
@@ -1,3 +0,0 @@
|
||||
.sixteen.columns.alpha{ 'ng-hide' => 'RequestMonitor.loading || products.length == 0', style: "margin-bottom: 10px" }
|
||||
.four.columns.alpha
|
||||
%input.four.columns.alpha{ :type => 'button', :value => t(:save_changes), 'ng-click' => 'submitProducts()'}
|
||||
@@ -14,12 +14,7 @@
|
||||
= " - OFN #{t(:administration)}"
|
||||
|
||||
%link{:href => "https://fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,400,600&subset=latin,cyrillic,greek,vietnamese", :rel => "stylesheet", :type => "text/css"}
|
||||
|
||||
- if feature?(:admin_style_v3, spree_current_user)
|
||||
= stylesheet_pack_tag 'admin-style-v3', media: "screen, print"
|
||||
- else
|
||||
= stylesheet_pack_tag 'admin-styles', media: "screen, print"
|
||||
|
||||
= stylesheet_pack_tag 'admin-style-v3', media: "screen, print"
|
||||
= render "layouts/bugsnag_js"
|
||||
|
||||
- if content_for? :minimal_js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- content_for :sub_menu do
|
||||
%ul#sub_nav.inline-menu
|
||||
= tab :products, :products_v3
|
||||
= tab :products, :products_v3, url: admin_products_path
|
||||
= tab :properties
|
||||
= tab :variant_overrides, url: main_app.admin_inventory_path, match_path: '/inventory' if feature?(:inventory, spree_current_user.enterprises)
|
||||
= tab :import, url: main_app.admin_product_import_path, match_path: '/product_import'
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
= tab :overview, label: 'dashboard', url: spree.admin_dashboard_path, icon: 'icon-dashboard'
|
||||
= tab :products, :properties, :inventory, :product_import, :images, :variants, :product_properties, :group_buy_options, :seo, :products_v3, :variant_overrides, url: admin_products_path, icon: 'icon-th-large'
|
||||
= tab :order_cycles, url: main_app.admin_order_cycles_path, icon: 'icon-refresh'
|
||||
= tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path, icon: 'icon-shopping-cart'
|
||||
= tab :reports, url: main_app.admin_reports_path, icon: 'icon-file'
|
||||
= tab :general_settings, :terms_of_service_files, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxons, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, :connected_app_settings, label: 'configuration', icon: 'icon-wrench', url: edit_admin_general_settings_path
|
||||
= tab :overview, label: 'dashboard', url: spree.admin_dashboard_path
|
||||
= tab :products, :properties, :inventory, :product_import, :images, :variants, :product_properties, :group_buy_options, :seo, :products_v3, :variant_overrides, url: admin_products_path
|
||||
= tab :order_cycles, url: main_app.admin_order_cycles_path
|
||||
= tab :orders, :subscriptions, :customer_details, :adjustments, :payments, :return_authorizations, url: admin_orders_path
|
||||
= tab :reports, url: main_app.admin_reports_path
|
||||
= tab :general_settings, :terms_of_service_files, :mail_methods, :tax_categories, :tax_rates, :tax_settings, :zones, :countries, :states, :payment_methods, :taxons, :shipping_methods, :shipping_categories, :enterprise_fees, :contents, :invoice_settings, :matomo_settings, :stripe_connect_settings, :connected_app_settings, label: 'configuration', url: edit_admin_general_settings_path
|
||||
= tab :enterprises, :enterprise_relationships, :vouchers, :oidc_settings, url: main_app.admin_enterprises_path
|
||||
= tab :customers, url: main_app.admin_customers_path
|
||||
= tab :enterprise_groups, url: main_app.admin_enterprise_groups_path, label: 'groups'
|
||||
- if can? :admin, Spree::User
|
||||
= tab(:users, :enterprise_roles, url: spree.admin_users_path, icon: 'icon-user')
|
||||
= tab(:users, :enterprise_roles, url: spree.admin_users_path)
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
// import Flatpickr
|
||||
import Flatpickr from "stimulus-flatpickr";
|
||||
import { ar } from "flatpickr/dist/l10n/ar";
|
||||
import { cat } from "flatpickr/dist/l10n/cat";
|
||||
import { cy } from "flatpickr/dist/l10n/cy";
|
||||
import { de } from "flatpickr/dist/l10n/de";
|
||||
import { fi } from "flatpickr/dist/l10n/fi";
|
||||
import { fr } from "flatpickr/dist/l10n/fr";
|
||||
import { it } from "flatpickr/dist/l10n/it";
|
||||
import { nl } from "flatpickr/dist/l10n/nl";
|
||||
import { pl } from "flatpickr/dist/l10n/pl";
|
||||
import { pt } from "flatpickr/dist/l10n/pt";
|
||||
import { ru } from "flatpickr/dist/l10n/ru";
|
||||
import { sv } from "flatpickr/dist/l10n/sv";
|
||||
import { tr } from "flatpickr/dist/l10n/tr";
|
||||
import { en } from "flatpickr/dist/l10n/default.js";
|
||||
import { hu } from "flatpickr/dist/l10n/hu";
|
||||
import ShortcutButtonsPlugin from "shortcut-buttons-flatpickr";
|
||||
import labelPlugin from "flatpickr/dist/plugins/labelPlugin/labelPlugin";
|
||||
|
||||
@@ -24,28 +9,11 @@ export default class extends Flatpickr {
|
||||
*/
|
||||
static values = { enableTime: Boolean, mode: String, defaultDate: String };
|
||||
static targets = ["start", "end"];
|
||||
locales = {
|
||||
ar: ar,
|
||||
cat: cat,
|
||||
cy: cy,
|
||||
de: de,
|
||||
fi: fi,
|
||||
fr: fr,
|
||||
it: it,
|
||||
nl: nl,
|
||||
pl: pl,
|
||||
pt: pt,
|
||||
ru: ru,
|
||||
sv: sv,
|
||||
tr: tr,
|
||||
en: en,
|
||||
hu: hu,
|
||||
};
|
||||
|
||||
initialize() {
|
||||
const datetimepicker = this.enableTimeValue === true;
|
||||
const mode = this.modeValue === "range" ? "range" : "single";
|
||||
// sets your language (you can also set some global setting for all time pickers)
|
||||
// configure flatpickr options (locale set dynamically in connect())
|
||||
this.config = {
|
||||
altInput: true,
|
||||
altFormat: datetimepicker
|
||||
@@ -54,13 +22,18 @@ export default class extends Flatpickr {
|
||||
dateFormat: datetimepicker ? "Y-m-d H:i" : "Y-m-d",
|
||||
enableTime: datetimepicker,
|
||||
time_24hr: datetimepicker,
|
||||
locale: I18n.base_locale,
|
||||
plugins: this.plugins(mode, datetimepicker),
|
||||
mode,
|
||||
};
|
||||
}
|
||||
|
||||
connect() {
|
||||
async connect() {
|
||||
const locale = await this.importFlatpickrLocale(I18n.base_locale);
|
||||
this.config = {
|
||||
...this.config,
|
||||
locale,
|
||||
};
|
||||
|
||||
super.connect();
|
||||
window.addEventListener("flatpickr:change", this.onChangeEvent);
|
||||
window.addEventListener("flatpickr:clear", this.clear);
|
||||
@@ -164,4 +137,16 @@ export default class extends Flatpickr {
|
||||
this.fp.setDate(moment().add(1, "days").startOf("day").format());
|
||||
}
|
||||
}
|
||||
|
||||
async importFlatpickrLocale(localeCode) {
|
||||
// null tells flatpickr to fall back to its built-in english locale
|
||||
if (!localeCode || localeCode === "en") return null;
|
||||
|
||||
try {
|
||||
const localeModule = await import(`flatpickr/dist/l10n/${localeCode}.js`);
|
||||
return localeModule.default?.[localeCode] ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
@import "vendor/assets/stylesheets/normalize";
|
||||
@import "vendor/assets/stylesheets/responsive-tables";
|
||||
@import "vendor/assets/stylesheets/jquery.powertip";
|
||||
@import "~jquery-ui/themes/base/core";
|
||||
@import "~jquery-ui/themes/base/button";
|
||||
@import "~jquery-ui/themes/base/resizable";
|
||||
@import "vendor/assets/stylesheets/jquery-ui-theme";
|
||||
@import "~jquery-ui/themes/base/dialog";
|
||||
@import "../shared/ng-tags-input.min";
|
||||
@import "vendor/assets/stylesheets/select2.css.scss";
|
||||
@import "~flatpickr/dist/flatpickr";
|
||||
@import "~flatpickr/dist/themes/material_blue";
|
||||
@import "~shortcut-buttons-flatpickr/dist/themes/light";
|
||||
|
||||
@import "globals/functions";
|
||||
@import "globals/palette";
|
||||
@import "globals/variables";
|
||||
@import "globals/mixins";
|
||||
|
||||
@import "plugins/font-awesome";
|
||||
|
||||
@import "../shared/variables/layout";
|
||||
@import "../shared/variables/variables";
|
||||
@import "../shared/utilities";
|
||||
@import "shared/typography";
|
||||
@import "shared/tables";
|
||||
@import "shared/icons";
|
||||
@import "shared/forms";
|
||||
@import "shared/layout";
|
||||
@import "shared/scroll_bar";
|
||||
|
||||
@import "../shared/trix";
|
||||
|
||||
@import "plugins/flatpickr-customization";
|
||||
@import "plugins/powertip";
|
||||
@import "plugins/select2";
|
||||
|
||||
@import "sections/orders";
|
||||
@import "sections/products";
|
||||
|
||||
@import "hacks/mozilla";
|
||||
@import "hacks/opera";
|
||||
@import "hacks/ie";
|
||||
|
||||
@import "components/actions";
|
||||
@import "components/alert-box";
|
||||
@import "components/alert_row";
|
||||
@import "components/buttons";
|
||||
@import "components/date-picker";
|
||||
@import "components/dialogs";
|
||||
@import "components/input";
|
||||
@import "components/jquery_dialog";
|
||||
@import "components/messages";
|
||||
@import "components/navigation";
|
||||
@import "components/ng-cloak";
|
||||
@import "components/page_actions";
|
||||
@import "components/pagination";
|
||||
@import "components/per_page_controls";
|
||||
@import "components/product_autocomplete";
|
||||
@import "components/progress";
|
||||
@import "components/save_bar";
|
||||
@import "components/sidebar";
|
||||
@import "components/simple_modal";
|
||||
@import "components/states";
|
||||
@import "components/stripe_connect_button";
|
||||
@import "components/subscriptions_states";
|
||||
@import "components/table-filter";
|
||||
@import "components/table_loading";
|
||||
@import "components/timepicker";
|
||||
@import "components/todo";
|
||||
@import "components/tooltip";
|
||||
@import "components/wizard_progress";
|
||||
|
||||
@import "pages/enterprise_form";
|
||||
@import "pages/subscription_form";
|
||||
@import "pages/subscription_line_items";
|
||||
@import "pages/subscription_review";
|
||||
|
||||
@import "advanced_settings";
|
||||
@import "alert";
|
||||
@import "animations";
|
||||
@import "change_type_form";
|
||||
@import "connected_apps";
|
||||
@import "customers";
|
||||
@import "dashboard_item";
|
||||
@import "dashboard-single-ent";
|
||||
@import "dialog";
|
||||
@import "disabled";
|
||||
@import "dropdown";
|
||||
@import "enterprise_index_panels";
|
||||
@import "enterprises";
|
||||
@import "filters_and_controls";
|
||||
@import "grid";
|
||||
@import "icons";
|
||||
@import "index_panel_buttons";
|
||||
@import "index_panels";
|
||||
@import "modals";
|
||||
@import "offsets";
|
||||
@import "openfoodnetwork";
|
||||
@import "order_cycles";
|
||||
@import "orders";
|
||||
@import "product_import";
|
||||
@import "products";
|
||||
@import "question-mark-tooltip";
|
||||
@import "relationships";
|
||||
@import "reports";
|
||||
@import "select2";
|
||||
@import "sidebar-item";
|
||||
@import "side_menu";
|
||||
@import "tables";
|
||||
@import "tag_rules";
|
||||
@import "terms_of_service_banner";
|
||||
@import "terms_of_service_files";
|
||||
@import "validation";
|
||||
@import "variant_overrides";
|
||||
@import "welcome";
|
||||
|
||||
@import "../shared/question-mark-icon";
|
||||
@import "question-mark-tooltip";
|
||||
|
||||
@import "~tom-select/src/scss/tom-select.default";
|
||||
@import "components/tom_select";
|
||||
|
||||
@import "app/components/modal_component/modal_component";
|
||||
@import "app/webpacker/css/admin/trix.scss";
|
||||
@@ -1,31 +0,0 @@
|
||||
table tbody tr {
|
||||
&.highlight {
|
||||
@each $action in $actions {
|
||||
&.action-#{$action} td {
|
||||
background-color: get-value($actions, $actions-bg-colors, $action);
|
||||
border-color: get-value($actions, $actions-brd-colors, $action);
|
||||
}
|
||||
}
|
||||
|
||||
&.action-remove td,
|
||||
&.action-void td {
|
||||
text-decoration: line-through;
|
||||
|
||||
&.actions {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.before-highlight {
|
||||
@each $action in $actions {
|
||||
&.action-#{$action} td {
|
||||
border-bottom-color: get-value($actions, $actions-brd-colors, $action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td.actions {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
input[type="submit"],
|
||||
input[type="button"]:not(.trix-button),
|
||||
button:not(.plain):not(.trix-button),
|
||||
.button {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
font-size: 85%;
|
||||
@include border-radius($border-radius);
|
||||
display: inline-block;
|
||||
padding: 8px 15px;
|
||||
border: none;
|
||||
background-color: $color-btn-bg;
|
||||
color: $color-btn-text;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600 !important;
|
||||
|
||||
&:before {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
&:visited,
|
||||
&:active,
|
||||
&:focus {
|
||||
color: $color-btn-text;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-btn-hover-bg;
|
||||
color: $color-btn-hover-text;
|
||||
}
|
||||
|
||||
&:active:focus {
|
||||
box-shadow: 0 0 8px 0 darken($color-btn-hover-bg, 5) inset;
|
||||
}
|
||||
|
||||
&.fullwidth {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background-color: transparent;
|
||||
border: 1px solid $color-btn-bg;
|
||||
color: $color-btn-bg;
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
background-color: #ebf3fb;
|
||||
}
|
||||
|
||||
&:active:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
transform: translateY(-50%);
|
||||
font-size: 10px;
|
||||
text-transform: capitalize;
|
||||
padding: 0px 5px;
|
||||
border-radius: 3px;
|
||||
|
||||
&:before {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background-color: $color-warning;
|
||||
}
|
||||
&.success {
|
||||
background-color: $spree-green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input.red,
|
||||
a.button.red,
|
||||
button.red {
|
||||
background-color: $color-warning;
|
||||
margin-right: 5px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
a.button.red {
|
||||
&:not(:hover) {
|
||||
color: #fff;
|
||||
background-color: $color-warning;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// scss-lint:disable QualifyingElement
|
||||
|
||||
input.datetimepicker {
|
||||
min-width: 12.9em;
|
||||
}
|
||||
|
||||
.container input[readonly].flatpickr-input,
|
||||
.container input[readonly].datepicker,
|
||||
.container input[readonly].datetimepicker {
|
||||
background-color: $white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img.ui-datepicker-trigger {
|
||||
margin-left: -1.75em;
|
||||
position: absolute;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
// scss-lint:enable QualifyingElement
|
||||
@@ -1,76 +0,0 @@
|
||||
.errorExplanation {
|
||||
padding: 10px;
|
||||
border: 1px solid very-light($color-error, 12);
|
||||
background-color: very-light($color-error, 6);
|
||||
border-radius: 3px;
|
||||
color: $color-error;
|
||||
margin-bottom: 15px;
|
||||
|
||||
h2 {
|
||||
font-size: 140%;
|
||||
color: $color-error;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-position: inside;
|
||||
|
||||
li {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flash-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
|
||||
.flash {
|
||||
padding: 18px;
|
||||
text-align: center;
|
||||
font-size: 120%;
|
||||
color: $color-1;
|
||||
font-weight: 600;
|
||||
margin-top: 0;
|
||||
|
||||
&.notice {
|
||||
background-color: rgba($color-notice, 0.8);
|
||||
}
|
||||
&.success {
|
||||
background-color: rgba($color-success, 0.8);
|
||||
}
|
||||
&.error {
|
||||
background-color: rgba($color-error, 0.8);
|
||||
}
|
||||
|
||||
// Adjust heights to fit main layout dimension (header, navbar...)
|
||||
&:nth-child(2) {
|
||||
padding: 24px;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: none; /* avoid adding new button on old design */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notice:not(.flash) {
|
||||
padding: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
background-color: $spree-light-blue;
|
||||
border-radius: $border-radius;
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
// Navigation
|
||||
//---------------------------------------------------
|
||||
.inline-menu {
|
||||
margin: 0;
|
||||
-webkit-margin-before: 0;
|
||||
-webkit-padding-start: 0;
|
||||
}
|
||||
|
||||
nav.menu {
|
||||
ul {
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
a {
|
||||
padding: 10px 0;
|
||||
display: block;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
border: 1px solid transparent;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
&.active a {
|
||||
color: $color-2;
|
||||
border-left-width: 0;
|
||||
border-bottom-color: $color-2;
|
||||
}
|
||||
|
||||
&:hover a {
|
||||
color: $color-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-login-navigation-bar {
|
||||
ul {
|
||||
text-align: right;
|
||||
|
||||
li {
|
||||
padding: 5px 0 5px 10px;
|
||||
text-align: right;
|
||||
font-size: 90%;
|
||||
color: $color-link;
|
||||
margin-top: 8px;
|
||||
|
||||
&.user-logged-in-as {
|
||||
width: 50%;
|
||||
color: $color-body-text;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
i {
|
||||
color: $color-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#admin-menu {
|
||||
background-color: $color-3;
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
li {
|
||||
min-width: 90px;
|
||||
flex-grow: 1;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 25px 5px;
|
||||
color: $color-1 !important;
|
||||
text-transform: uppercase;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
|
||||
i {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-2;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-top: 5px solid $color-2;
|
||||
bottom: 0px;
|
||||
margin-bottom: -5px;
|
||||
left: 50%;
|
||||
margin-left: -10px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
span.text {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
a::before {
|
||||
font-weight: normal;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
width: 300px;
|
||||
background-color: $color-3;
|
||||
width: 200px;
|
||||
z-index: 100000;
|
||||
|
||||
> li {
|
||||
width: 200px !important;
|
||||
|
||||
a:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.selected a {
|
||||
@extend a, :hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#sub-menu {
|
||||
background-color: $color-2;
|
||||
padding-bottom: 0;
|
||||
|
||||
li {
|
||||
a {
|
||||
display: block;
|
||||
padding: 12px 20px;
|
||||
color: $color-1;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
position: relative;
|
||||
font-size: 85%;
|
||||
}
|
||||
|
||||
&.selected a,
|
||||
a:hover {
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-top: 5px solid $color-2;
|
||||
bottom: 0px;
|
||||
margin-bottom: -5px;
|
||||
left: 50%;
|
||||
margin-left: -10px;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#header figure {
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
|
||||
#login-nav {
|
||||
line-height: 1.75em;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
.pagination {
|
||||
text-align: center;
|
||||
margin: 2em 0 1em;
|
||||
padding: 10px 0;
|
||||
|
||||
.page {
|
||||
padding: 5px 8px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
|
||||
&.current {
|
||||
background-color: $color-2;
|
||||
border-radius: 3px;
|
||||
color: $color-1;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0 0.35em;
|
||||
|
||||
&.active {
|
||||
background-color: darken($spree-blue, 15%);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background-color: $color-btn-disabled-bg;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Sidebar
|
||||
//---------------------------------------------------
|
||||
#sidebar {
|
||||
overflow: visible;
|
||||
border-top: 1px solid $color-border;
|
||||
margin-top: 17px;
|
||||
|
||||
.sidebar-title {
|
||||
color: $color-2;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
|
||||
> span {
|
||||
display: inline;
|
||||
background: #fff;
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
top: -14px;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
.ts-wrapper {
|
||||
min-height: initial;
|
||||
}
|
||||
|
||||
.ts-wrapper.multi {
|
||||
.ts-control {
|
||||
box-shadow: none;
|
||||
border-color: $pale-blue;
|
||||
|
||||
&:focus {
|
||||
border-color: $spree-green;
|
||||
}
|
||||
|
||||
[data-value] {
|
||||
text-shadow: none;
|
||||
background-image: none;
|
||||
background-repeat: initial;
|
||||
box-shadow: none;
|
||||
background-color: $spree-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.ts-control > div {
|
||||
border: none;
|
||||
background-color: $spree-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.ts-wrapper.plugin-remove_button .item .remove {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ts-dropdown {
|
||||
margin-top: 0;
|
||||
|
||||
.option {
|
||||
min-height: 2.25em;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.ts-wrapper.single .ts-control,
|
||||
.ts-dropdown.single {
|
||||
border-color: $color-tbl-border;
|
||||
}
|
||||
|
||||
.ts-control,
|
||||
.ts-wrapper.single.input-active .ts-control {
|
||||
cursor: pointer;
|
||||
padding: 6px 8px;
|
||||
outline: 0 !important;
|
||||
min-height: 2.5em;
|
||||
}
|
||||
|
||||
.ts-wrapper.single .ts-control {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.ts-wrapper.inline,
|
||||
.ts-wrapper.inline.input-active {
|
||||
width: fit-content;
|
||||
|
||||
.ts-control {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.ts-wrapper.single .ts-control {
|
||||
box-shadow: none;
|
||||
background-image: none;
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.ts-wrapper.primary.focus .ts-control,
|
||||
.ts-wrapper.primary .ts-control {
|
||||
background-color: $spree-blue;
|
||||
border-color: $spree-blue;
|
||||
color: $white;
|
||||
|
||||
&:after {
|
||||
border-color: $white transparent transparent transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.ts-wrapper .select-multiple {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ts-wrapper.dropdown-active.primary .ts-control {
|
||||
background-color: $spree-green;
|
||||
border-color: $spree-green;
|
||||
color: $white;
|
||||
|
||||
&:after {
|
||||
border-color: transparent transparent $white transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-input-wrap {
|
||||
padding: 0.2em;
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
@extend [class^="icon-"];
|
||||
@extend .icon-search;
|
||||
|
||||
position: absolute;
|
||||
opacity: 0.4;
|
||||
line-height: 2em;
|
||||
left: 0.75em;
|
||||
}
|
||||
|
||||
.dropdown-input {
|
||||
outline: 0;
|
||||
padding: 4px 6px;
|
||||
border: 1px solid $spree-green;
|
||||
border-radius: 0.3em;
|
||||
padding-left: 1.75em;
|
||||
}
|
||||
}
|
||||
|
||||
.ts-wrapper.no-search {
|
||||
.dropdown-input-wrap {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ts-dropdown .create:hover,
|
||||
.ts-dropdown #admin-menu li.selected a.create,
|
||||
#admin-menu li.selected .ts-dropdown a.create,
|
||||
.ts-dropdown .option:hover,
|
||||
.ts-dropdown #admin-menu li.selected a.option,
|
||||
#admin-menu li.selected .ts-dropdown a.option,
|
||||
.ts-dropdown .active {
|
||||
background-color: $spree-blue;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.ts-dropdown [data-selectable] .highlight {
|
||||
background: rgba(149, 180, 255, 0.26);
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
// -------------------------------------------------------------
|
||||
// Variables used in all other files
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// Fonts
|
||||
//--------------------------------------------------------------
|
||||
$base-font-family: "Open Sans", "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
|
||||
|
||||
// Colors
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// Body base colors
|
||||
$color-body-bg: $color-1 !default;
|
||||
$color-body-text: $color-4 !default;
|
||||
$color-headers: $color-4 !default;
|
||||
$color-link: $color-3 !default;
|
||||
$color-link-hover: $color-2 !default;
|
||||
$color-link-active: $color-2 !default;
|
||||
$color-link-focus: $color-2 !default;
|
||||
$color-link-visited: $color-3 !default;
|
||||
$color-border: very-light($color-3, 12) !default;
|
||||
|
||||
// Basic flash colors
|
||||
$color-success: $color-2 !default;
|
||||
$color-notice: $color-6 !default;
|
||||
$color-warning: $color-5 !default;
|
||||
$color-error: $color-5 !default;
|
||||
|
||||
// Table colors
|
||||
$color-tbl-odd: $color-1 !default;
|
||||
$color-tbl-even: very-light($color-3, 4) !default;
|
||||
$color-tbl-thead: very-light($color-3, 4) !default;
|
||||
$color-tbl-border: $pale-blue !default;
|
||||
|
||||
// Button colors
|
||||
$color-btn-bg: $color-3 !default;
|
||||
$color-btn-text: $color-1 !default;
|
||||
$color-btn-hover-bg: $color-2 !default;
|
||||
$color-btn-hover-text: $color-1 !default;
|
||||
$color-btn-disabled-bg: $light-grey !default;
|
||||
|
||||
// Actions colors
|
||||
$color-action-edit-bg: very-light($color-success, 5 ) !default;
|
||||
$color-action-edit-brd: very-light($color-success, 20 ) !default;
|
||||
$color-action-clone-bg: very-light($color-notice, 5 ) !default;
|
||||
$color-action-clone-brd: very-light($color-notice, 15 ) !default;
|
||||
$color-action-remove-bg: very-light($color-error, 5 ) !default;
|
||||
$color-action-remove-brd: very-light($color-error, 10 ) !default;
|
||||
$color-action-void-bg: very-light($color-error, 10 ) !default;
|
||||
$color-action-void-brd: very-light($color-error, 20 ) !default;
|
||||
$color-action-cancel-bg: very-light($color-notice, 10 ) !default;
|
||||
$color-action-cancel-brd: very-light($color-notice, 20 ) !default;
|
||||
$color-action-capture-bg: very-light($color-success, 5 ) !default;
|
||||
$color-action-capture-brd: very-light($color-success, 20 ) !default;
|
||||
$color-action-save-bg: very-light($color-success, 5 ) !default;
|
||||
$color-action-save-brd: very-light($color-success, 20 ) !default;
|
||||
$color-action-mail-bg: very-light($color-success, 5 ) !default;
|
||||
$color-action-mail-brd: very-light($color-success, 20 ) !default;
|
||||
|
||||
// Select2 select field colors
|
||||
$color-sel-bg: $color-3 !default;
|
||||
$color-sel-text: $color-1 !default;
|
||||
$color-sel-hover-bg: $color-2 !default;
|
||||
$color-sel-hover-text: $color-1 !default;
|
||||
|
||||
// Text inputs colors
|
||||
$color-txt-brd: $color-border !default;
|
||||
$color-txt-text: $color-3 !default;
|
||||
$color-txt-hover-brd: $color-2 !default;
|
||||
$vpadding-txt: 7px;
|
||||
$hpadding-txt: 10px;
|
||||
|
||||
// Modal colors
|
||||
$color-modal-close-btn: $color-5 !default;
|
||||
$color-modal-close-btn-hover: darken($color-5, 5%) !default;
|
||||
|
||||
// States label colors
|
||||
$color-ste-complete-bg: $color-success !default;
|
||||
$color-ste-complete-text: $color-1 !default;
|
||||
$color-ste-completed-bg: $color-success !default;
|
||||
$color-ste-completed-text: $color-1 !default;
|
||||
$color-ste-sold-bg: $color-success !default;
|
||||
$color-ste-sold-text: $color-1 !default;
|
||||
$color-ste-pending-bg: $color-notice !default;
|
||||
$color-ste-pending-text: $color-1 !default;
|
||||
$color-ste-requires_authorization-bg: $color-notice !default;
|
||||
$color-ste-requires_authorization-text: $color-1 !default;
|
||||
$color-ste-awaiting_return-bg: $color-notice !default;
|
||||
$color-ste-awaiting_return-text: $color-1 !default;
|
||||
$color-ste-returned-bg: $color-notice !default;
|
||||
$color-ste-returned-text: $color-1 !default;
|
||||
$color-ste-credit_owed-bg: $color-notice !default;
|
||||
$color-ste-credit_owed-text: $color-1 !default;
|
||||
$color-ste-paid-bg: $color-success !default;
|
||||
$color-ste-paid-text: $color-1 !default;
|
||||
$color-ste-shipped-bg: $color-success !default;
|
||||
$color-ste-shipped-text: $color-1 !default;
|
||||
$color-ste-balance_due-bg: $color-notice !default;
|
||||
$color-ste-balance_due-text: $color-1 !default;
|
||||
$color-ste-backorder-bg: $color-notice !default;
|
||||
$color-ste-backorder-text: $color-1 !default;
|
||||
$color-ste-none-bg: $color-error !default;
|
||||
$color-ste-none-text: $color-1 !default;
|
||||
$color-ste-ready-bg: $color-success !default;
|
||||
$color-ste-ready-text: $color-1 !default;
|
||||
$color-ste-void-bg: $color-error !default;
|
||||
$color-ste-void-text: $color-1 !default;
|
||||
$color-ste-canceled-bg: $color-error !default;
|
||||
$color-ste-canceled-text: $color-1 !default;
|
||||
$color-ste-address-bg: $color-error !default;
|
||||
$color-ste-address-text: $color-1 !default;
|
||||
$color-ste-checkout-bg: $color-notice !default;
|
||||
$color-ste-checkout-text: $color-1 !default;
|
||||
$color-ste-cart-bg: $color-notice !default;
|
||||
$color-ste-cart-text: $color-1 !default;
|
||||
$color-ste-payment-bg: $color-error !default;
|
||||
$color-ste-payment-text: $color-1 !default;
|
||||
$color-ste-delivery-bg: $color-success !default;
|
||||
$color-ste-delivery-text: $color-1 !default;
|
||||
$color-ste-confirmation-bg: $color-error !default;
|
||||
$color-ste-confirmation-text: $color-1 !default;
|
||||
$color-ste-active-bg: $color-success !default;
|
||||
$color-ste-active-text: $color-1 !default;
|
||||
$color-ste-inactive-bg: $color-notice !default;
|
||||
$color-ste-inactive-text: $color-1 !default;
|
||||
|
||||
// Available states
|
||||
$states: completed, complete, sold, pending, awaiting_return, returned, credit_owed, paid, shipped, balance_due, backorder, checkout, cart, address, delivery, payment, confirmation, canceled, ready, void, requires_authorization, active, inactive !default;
|
||||
$states-bg-colors: $color-ste-completed-bg, $color-ste-complete-bg, $color-ste-sold-bg, $color-ste-pending-bg, $color-ste-awaiting_return-bg, $color-ste-returned-bg, $color-ste-credit_owed-bg, $color-ste-paid-bg, $color-ste-shipped-bg, $color-ste-balance_due-bg, $color-ste-backorder-bg, $color-ste-checkout-bg, $color-ste-cart-bg, $color-ste-address-bg, $color-ste-delivery-bg, $color-ste-payment-bg, $color-ste-confirmation-bg, $color-ste-canceled-bg, $color-ste-ready-bg, $color-ste-void-bg, $color-ste-requires_authorization-bg, $color-ste-active-bg, $color-ste-inactive-bg !default;
|
||||
$states-text-colors: $color-ste-completed-text, $color-ste-complete-text, $color-ste-sold-text, $color-ste-pending-text, $color-ste-awaiting_return-text, $color-ste-returned-text, $color-ste-credit_owed-text, $color-ste-paid-text, $color-ste-shipped-text, $color-ste-balance_due-text, $color-ste-backorder-text, $color-ste-checkout-text, $color-ste-cart-text, $color-ste-address-text, $color-ste-delivery-text, $color-ste-payment-text, $color-ste-confirmation-text, $color-ste-canceled-text, $color-ste-ready-text, $color-ste-void-text, $color-ste-requires_authorization-text, $color-ste-active-text, $color-ste-inactive-text !default;
|
||||
|
||||
// Available actions
|
||||
$actions: edit, clone, remove, void, capture, save, cancel, mail !default;
|
||||
$actions-bg-colors: $color-action-edit-bg, $color-action-clone-bg, $color-action-remove-bg, $color-action-void-bg, $color-action-capture-bg, $color-action-save-bg, $color-action-cancel-bg, $color-action-mail-bg !default;
|
||||
$actions-brd-colors: $color-action-edit-brd, $color-action-clone-brd, $color-action-remove-brd, $color-action-void-brd, $color-action-capture-brd, $color-action-save-brd, $color-action-cancel-brd, $color-action-mail-brd !default;
|
||||
|
||||
// Sizes
|
||||
//--------------------------------------------------------------
|
||||
$body-font-size: 13px !default;
|
||||
|
||||
$h6-size: $body-font-size + 2 !default;
|
||||
$h5-size: $h6-size + 2 !default;
|
||||
$h4-size: $h5-size + 2 !default;
|
||||
$h3-size: $h4-size + 2 !default;
|
||||
$h2-size: $h3-size + 2 !default;
|
||||
$h1-size: $h2-size + 2 !default;
|
||||
|
||||
$border-radius: 3px !default;
|
||||
$border-input: 1px solid #2e3132; // Copied over from admin_v3 variables as a temporary solution
|
||||
|
||||
$font-weight-bold: 600 !default;
|
||||
$font-weight-normal: 400 !default;
|
||||
|
||||
// z-index
|
||||
//--------------------------------------------------------------
|
||||
$tos-banner-z-index: 102;
|
||||
@@ -1,68 +0,0 @@
|
||||
$background-grey: #eceef1;
|
||||
$background-blue: $color-3;
|
||||
|
||||
// scss-lint:disable SelectorFormat
|
||||
|
||||
.flatpickr-calendar {
|
||||
border-radius: 0;
|
||||
|
||||
// Disable animation
|
||||
&.animate.open {
|
||||
animation: none;
|
||||
}
|
||||
|
||||
&.arrowBottom::after {
|
||||
border-top-color: $background-grey;
|
||||
}
|
||||
|
||||
&.arrowTop::after {
|
||||
border-bottom-color: $background-blue;
|
||||
}
|
||||
|
||||
.flatpickr-months .flatpickr-month {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.flatpickr-months .flatpickr-month,
|
||||
.flatpickr-current-month .flatpickr-monthDropdown-months {
|
||||
background: $background-blue;
|
||||
}
|
||||
|
||||
.flatpickr-weekdays {
|
||||
background: $background-blue;
|
||||
|
||||
.flatpickr-weekday {
|
||||
background: $background-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.flatpickr-day.selected,
|
||||
.flatpickr-day.startRange,
|
||||
.flatpickr-day.endRange,
|
||||
.flatpickr-day.selected.inRange,
|
||||
.flatpickr-day.startRange.inRange,
|
||||
.flatpickr-day.endRange.inRange,
|
||||
.flatpickr-day.selected:focus,
|
||||
.flatpickr-day.startRange:focus,
|
||||
.flatpickr-day.endRange:focus,
|
||||
.flatpickr-day.selected:hover,
|
||||
.flatpickr-day.startRange:hover,
|
||||
.flatpickr-day.endRange:hover,
|
||||
.flatpickr-day.selected.prevMonthDay,
|
||||
.flatpickr-day.startRange.prevMonthDay,
|
||||
.flatpickr-day.endRange.prevMonthDay,
|
||||
.flatpickr-day.selected.nextMonthDay,
|
||||
.flatpickr-day.startRange.nextMonthDay,
|
||||
.flatpickr-day.endRange.nextMonthDay {
|
||||
background: $background-blue;
|
||||
border-color: $background-blue;
|
||||
}
|
||||
}
|
||||
|
||||
// scss-lint:enable SelectorFormat
|
||||
|
||||
// customization for shortcut-buttons
|
||||
.shortcut-buttons-flatpickr-wrapper > .shortcut-buttons-flatpickr-buttons {
|
||||
justify-content: space-between;
|
||||
flex-grow: 1;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
#powerTip {
|
||||
background-color: $color-3;
|
||||
padding: 5px 15px;
|
||||
@include border-radius($border-radius);
|
||||
|
||||
&.n:before,
|
||||
&.ne:before,
|
||||
&.nw:before {
|
||||
border-top-width: 5px;
|
||||
border-top-color: $color-3;
|
||||
bottom: -5px;
|
||||
}
|
||||
|
||||
&.e:before {
|
||||
border-right-width: 5px;
|
||||
border-right-color: $color-3;
|
||||
left: -5px;
|
||||
}
|
||||
&.s:before,
|
||||
&.se:before,
|
||||
&.sw:before {
|
||||
border-bottom-width: 5px;
|
||||
border-bottom-color: $color-3;
|
||||
top: -5px;
|
||||
}
|
||||
&.w:before {
|
||||
border-left-width: 5px;
|
||||
border-left-color: $color-3;
|
||||
right: -5px;
|
||||
}
|
||||
&.ne:before,
|
||||
&.se:before {
|
||||
border-right-width: 5px;
|
||||
border-right-color: $color-3;
|
||||
left: -5px;
|
||||
}
|
||||
&.nw:before,
|
||||
&.sw:before {
|
||||
border-left-width: 5px;
|
||||
border-right-color: $color-3;
|
||||
right: -5px;
|
||||
}
|
||||
|
||||
&.clone,
|
||||
&.yellow,
|
||||
&.cancel {
|
||||
background-color: $color-notice;
|
||||
|
||||
&.n:before,
|
||||
&.ne:before,
|
||||
&.nw:before {
|
||||
border-top-color: $color-notice;
|
||||
}
|
||||
&.e:before,
|
||||
&.nw:before,
|
||||
&.sw:before {
|
||||
border-right-color: $color-notice;
|
||||
}
|
||||
&.s:before,
|
||||
&.se:before,
|
||||
&.sw:before {
|
||||
border-bottom-color: $color-notice;
|
||||
}
|
||||
&.w:before {
|
||||
border-left-color: $color-notice;
|
||||
}
|
||||
}
|
||||
&.edit,
|
||||
&.green,
|
||||
&.capture,
|
||||
&.save,
|
||||
&.add {
|
||||
background-color: $color-success;
|
||||
|
||||
&.n:before,
|
||||
&.ne:before,
|
||||
&.nw:before {
|
||||
border-top-color: $color-success;
|
||||
}
|
||||
&.e:before,
|
||||
&.nw:before,
|
||||
&.sw:before {
|
||||
border-right-color: $color-success;
|
||||
}
|
||||
&.s:before,
|
||||
&.se:before,
|
||||
&.sw:before {
|
||||
border-bottom-color: $color-success;
|
||||
}
|
||||
&.w:before {
|
||||
border-left-color: $color-success;
|
||||
}
|
||||
}
|
||||
&.remove,
|
||||
&.red,
|
||||
&.void {
|
||||
background-color: $color-error;
|
||||
|
||||
&.n:before,
|
||||
&.ne:before,
|
||||
&.nw:before {
|
||||
border-top-color: $color-error;
|
||||
}
|
||||
&.e:before,
|
||||
&.nw:before,
|
||||
&.sw:before {
|
||||
border-right-color: $color-error;
|
||||
}
|
||||
&.s:before,
|
||||
&.se:before,
|
||||
&.sw:before {
|
||||
border-bottom-color: $color-error;
|
||||
}
|
||||
&.w:before {
|
||||
border-left-color: $color-error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
// Customize orders filter
|
||||
.admin-orders-index-search {
|
||||
select[data-placeholder="Status"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.select2-container {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Order-total
|
||||
.order-details-total {
|
||||
text-align: center;
|
||||
|
||||
.order-total {
|
||||
font-size: 35px;
|
||||
font-weight: 600;
|
||||
color: $color-success;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-order-form-fields {
|
||||
legend.stock-location {
|
||||
color: $color-body-text;
|
||||
|
||||
.shipment-number {
|
||||
color: $color-success;
|
||||
}
|
||||
.stock-location-name {
|
||||
color: $color-success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.insufficient-stock-items {
|
||||
legend {
|
||||
color: $color-error;
|
||||
}
|
||||
|
||||
table tr:last-child th {
|
||||
border-bottom: 1px solid $color-tbl-border;
|
||||
}
|
||||
}
|
||||
|
||||
// Customize orduct add fieldset
|
||||
#add-line-item {
|
||||
fieldset {
|
||||
padding: 10px 0;
|
||||
|
||||
.field {
|
||||
margin-bottom: 0;
|
||||
|
||||
input[type="text"],
|
||||
input[type="number"] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.actions {
|
||||
.button {
|
||||
margin-top: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
$text-inputs: "input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel]";
|
||||
|
||||
#{$text-inputs},
|
||||
input[type="date"],
|
||||
input[type="datetime"],
|
||||
input[type="time"],
|
||||
input[type="number"],
|
||||
textarea,
|
||||
fieldset {
|
||||
@include border-radius($border-radius);
|
||||
padding: $vpadding-txt $hpadding-txt;
|
||||
border: 1px solid $color-txt-brd;
|
||||
color: $color-txt-text;
|
||||
font-size: 90%;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: $color-txt-hover-brd;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
line-height: 19px;
|
||||
}
|
||||
|
||||
.fullwidth {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 85%;
|
||||
display: inline;
|
||||
margin-bottom: 5px;
|
||||
color: $color-4;
|
||||
|
||||
&.inline {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
&.block {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
.label-block label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
span.info {
|
||||
font-style: italic;
|
||||
font-size: 85%;
|
||||
color: lighten($color-body-text, 15);
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.field {
|
||||
padding: 10px 0;
|
||||
|
||||
&.checkbox {
|
||||
min-height: 70px;
|
||||
|
||||
input[type="checkbox"] {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
label {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
border-top: 1px solid $color-border;
|
||||
list-style: none;
|
||||
padding-top: 5px;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
padding-right: 10px;
|
||||
|
||||
label {
|
||||
font-weight: normal;
|
||||
text-transform: none;
|
||||
}
|
||||
&.white-space-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Errors described by default form builder
|
||||
.field_with_errors {
|
||||
label {
|
||||
color: $color-error;
|
||||
}
|
||||
|
||||
input {
|
||||
border-color: $color-error;
|
||||
}
|
||||
}
|
||||
// Errors described by Spree::Admin::BaseHelper
|
||||
.formError {
|
||||
color: $color-error;
|
||||
font-style: italic;
|
||||
font-size: 85%;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset {
|
||||
box-shadow: none;
|
||||
box-sizing: border-box;
|
||||
border-color: $color-border;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
position: relative;
|
||||
margin-bottom: 35px;
|
||||
padding: 10px 0 15px 0;
|
||||
background-color: transparent;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-radius: 0;
|
||||
|
||||
&.no-border-bottom {
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.no-border-top {
|
||||
border-top: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
background-color: $color-1;
|
||||
color: $color-2;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
padding: 8px 15px;
|
||||
margin: 0 auto;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
i {
|
||||
color: $color-link;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
color: lighten($color-body-text, 8);
|
||||
}
|
||||
|
||||
.filter-actions {
|
||||
margin-bottom: -32px;
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button,
|
||||
.button,
|
||||
input[type="submit"],
|
||||
input[type="button"],
|
||||
span.or {
|
||||
@include border-radius($border-radius);
|
||||
|
||||
-webkit-box-shadow: 0 0 0 15px $color-1;
|
||||
-moz-box-shadow: 0 0 0 15px $color-1;
|
||||
-ms-box-shadow: 0 0 0 15px $color-1;
|
||||
-o-box-shadow: 0 0 0 15px $color-1;
|
||||
box-shadow: 0 0 0 15px $color-1;
|
||||
|
||||
&:hover {
|
||||
border-color: $color-1;
|
||||
}
|
||||
|
||||
&:first-of-type {
|
||||
margin-right: 1.25em;
|
||||
}
|
||||
}
|
||||
|
||||
span.or {
|
||||
background-color: $color-1;
|
||||
border-width: 5px;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
position: relative;
|
||||
|
||||
-webkit-box-shadow: 0 0 0 5px $color-1;
|
||||
-moz-box-shadow: 0 0 0 5px $color-1;
|
||||
-ms-box-shadow: 0 0 0 5px $color-1;
|
||||
-o-box-shadow: 0 0 0 5px $color-1;
|
||||
box-shadow: 0 0 0 5px $color-1;
|
||||
}
|
||||
}
|
||||
|
||||
&.labels-inline {
|
||||
.field {
|
||||
margin-bottom: 0;
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
||||
label,
|
||||
input {
|
||||
display: table-cell !important;
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.checkbox {
|
||||
input {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.actions {
|
||||
padding: 0;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-buttons {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
select {
|
||||
@extend input, [type="text"];
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.inline-checkbox {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-top: 3px;
|
||||
|
||||
input,
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
label {
|
||||
margin: 0;
|
||||
padding-left: 0.4rem;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Some fixes for fontwesome stylesheets
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
&:before {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
&.button, &.icon_link {
|
||||
width: auto;
|
||||
|
||||
&:before {
|
||||
padding-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-email:before { @extend .icon-envelope, :before; }
|
||||
.icon-resend_authorization_email:before { @extend .icon-envelope, :before; }
|
||||
.icon-resume:before { @extend .icon-refresh, :before; }
|
||||
|
||||
.icon-cancel:before,
|
||||
.icon-void:before { @extend .icon-remove, :before; }
|
||||
|
||||
.icon-capture,
|
||||
.icon-capture_and_complete_order { @extend .icon-ok }
|
||||
.icon-credit:before { @extend .icon-ok, :before ; }
|
||||
@@ -1,134 +0,0 @@
|
||||
// Basics
|
||||
//---------------------------------------------------
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.admin {
|
||||
&__section-header {
|
||||
padding: 15px 0;
|
||||
background-color: very-light($color-3, 4);
|
||||
border-bottom: 1px solid $color-border;
|
||||
|
||||
.ofn-drop-down {
|
||||
border: 0;
|
||||
background-color: $spree-blue;
|
||||
color: $color-1;
|
||||
float: none;
|
||||
margin-left: 3px;
|
||||
&:hover,
|
||||
&.expanded {
|
||||
border: 0;
|
||||
color: $color-1;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
@media all and (min-width: $tablet_breakpoint) {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
@media all and (min-width: $tablet_breakpoint) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
@media all and (min-width: $tablet_breakpoint) {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
> li {
|
||||
display: flex;
|
||||
margin-right: 10px;
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.float-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.mr-0 {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.ml-0 {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.print-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Header
|
||||
//---------------------------------------------------
|
||||
#header {
|
||||
background-color: $color-1;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
#logo {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
i {
|
||||
color: $color-2;
|
||||
}
|
||||
}
|
||||
|
||||
// Content
|
||||
//---------------------------------------------------
|
||||
#content {
|
||||
background-color: $color-1;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
padding: 0;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
// Footer
|
||||
//---------------------------------------------------
|
||||
#footer {
|
||||
margin-top: 15px;
|
||||
border-top: 1px solid $color-border;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
@media print {
|
||||
header,
|
||||
nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
table {
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
border-collapse: separate;
|
||||
|
||||
th, td {
|
||||
padding: 7px 5px;
|
||||
border-right: 1px solid $color-border;
|
||||
border-bottom: 1px solid $color-border;
|
||||
vertical-align: middle;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
img {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-left: 1px solid $color-border;
|
||||
}
|
||||
|
||||
a {
|
||||
border-bottom: 1px dotted lighten($color-link, 10);
|
||||
|
||||
&:hover {
|
||||
border-color: lighten($color-link-hover, 10);
|
||||
}
|
||||
}
|
||||
|
||||
.handle {
|
||||
display: block !important;
|
||||
text-align: center;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
&.actions {
|
||||
background-color: transparent;
|
||||
border: none !important;
|
||||
text-align: center;
|
||||
|
||||
span.text {
|
||||
font-size: $body-font-size;
|
||||
}
|
||||
|
||||
[class*='icon-'].no-text {
|
||||
font-size: 120%;
|
||||
background-color: very-light($color-3);
|
||||
border: 1px solid $color-border;
|
||||
border-radius: 15px;
|
||||
width: 29px;
|
||||
height: 29px;
|
||||
display: inline-block;
|
||||
padding-top: 2px;
|
||||
|
||||
&:before {
|
||||
text-align: center !important;
|
||||
width: 27px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
button[class*='icon-'] {
|
||||
color: $color-link;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.icon-envelope-alt, .icon-eye-open {
|
||||
color: $color-link;
|
||||
padding-left: 0px;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-3;
|
||||
color: $color-1;
|
||||
}
|
||||
}
|
||||
.icon-trash:hover, .icon-void:hover {
|
||||
background-color: $color-error;
|
||||
color: $color-1;
|
||||
}
|
||||
.icon-cancel:hover {
|
||||
background-color: $color-notice;
|
||||
color: $color-1;
|
||||
}
|
||||
.icon-edit:hover, .icon-capture:hover, .icon-capture_and_complete_order:hover, .icon-ok:hover, .icon-plus:hover, .icon-road:hover {
|
||||
background-color: $color-success;
|
||||
color: $color-1;
|
||||
}
|
||||
.icon-copy:hover {
|
||||
background-color: $color-notice;
|
||||
color: $color-1;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="number"],
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.no-border {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.handle {
|
||||
@extend .icon-reorder;
|
||||
font-family: FontAwesome;
|
||||
text-decoration: inherit;
|
||||
display: inline-block;
|
||||
speak: none;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.no-borders {
|
||||
td, th {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
thead {
|
||||
th {
|
||||
padding: 10px;
|
||||
border-top: 1px solid $color-border;
|
||||
border-bottom: none;
|
||||
background-color: $color-tbl-thead;
|
||||
text-transform: uppercase;
|
||||
font-size: 85%;
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
tr {
|
||||
&:first-child th,
|
||||
&:first-child td {
|
||||
border-top: 1px solid $color-border;
|
||||
}
|
||||
&.even td {
|
||||
background-color: $color-tbl-even;
|
||||
|
||||
img {
|
||||
border: 1px solid very-light($color-3, 6);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover td {
|
||||
background-color: very-light($color-3, 5);
|
||||
|
||||
img {
|
||||
border: 1px solid $color-border;
|
||||
}
|
||||
}
|
||||
|
||||
&.deleted td {
|
||||
background-color: very-light($color-error, 6);
|
||||
border-color: very-light($color-error, 15);
|
||||
}
|
||||
|
||||
&.ui-sortable-placeholder td {
|
||||
border: 1px solid $color-2 !important;
|
||||
visibility: visible !important;
|
||||
|
||||
&.actions {
|
||||
background-color: transparent;
|
||||
border-right: none !important;
|
||||
border-top: none !important;
|
||||
border-bottom: none !important;
|
||||
border-left: 1px solid $color-2 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.ui-sortable-helper {
|
||||
width: 100%;
|
||||
|
||||
td {
|
||||
background-color: lighten($color-3, 33);
|
||||
border-bottom: 1px solid $color-border;
|
||||
|
||||
&.actions {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.no-border-top tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
&.grand-total {
|
||||
td {
|
||||
border-color: $color-2 !important;
|
||||
text-transform: uppercase;
|
||||
font-size: 110%;
|
||||
font-weight: 600;
|
||||
background-color: lighten($color-2, 50);
|
||||
}
|
||||
.total {
|
||||
background-color: $color-2;
|
||||
color: $color-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
// Base
|
||||
//--------------------------------------------------------------
|
||||
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; font-size: $body-font-size; }
|
||||
|
||||
body {
|
||||
font-family: $base-font-family;
|
||||
font-size: $body-font-size;
|
||||
font-weight: 400;
|
||||
color: $color-body-text;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top: 1px solid $color-border;
|
||||
border-bottom: 1px solid white;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
strong, b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// links
|
||||
//--------------------------------------------------------------
|
||||
a {
|
||||
color: $color-link;
|
||||
text-decoration: none;
|
||||
line-height: inherit;
|
||||
|
||||
&, &:hover, &:active, &:visited, &:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:visited {
|
||||
color: $color-link-visited;
|
||||
}
|
||||
&:focus {
|
||||
color: $color-link-focus;
|
||||
}
|
||||
&:active {
|
||||
color: $color-link-active;
|
||||
}
|
||||
&:hover {
|
||||
color: $color-link-hover;
|
||||
}
|
||||
}
|
||||
|
||||
// Headings
|
||||
//--------------------------------------------------------------
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
font-weight: 600;
|
||||
color: $color-headers;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
h1 { font-size: $h1-size; line-height: $h1-size + 6 }
|
||||
h2 { font-size: $h2-size; line-height: $h1-size + 4 }
|
||||
h3 { font-size: $h3-size; line-height: $h1-size + 2 }
|
||||
h4 { font-size: $h4-size; line-height: $h1-size }
|
||||
h5 { font-size: $h5-size; line-height: $h1-size }
|
||||
h6 { font-size: $h6-size; line-height: $h1-size }
|
||||
|
||||
|
||||
// Lists
|
||||
//--------------------------------------------------------------
|
||||
ul {
|
||||
&.inline-menu {
|
||||
li {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
&.fields {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
dl {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin: 5px 0;
|
||||
color: lighten($color-body-text, 15);
|
||||
|
||||
dt, dd {
|
||||
float: left;
|
||||
line-height: 16px;
|
||||
padding: 5px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
dt {
|
||||
width: 40%;
|
||||
font-weight: 600;
|
||||
padding-left: 0;
|
||||
text-transform: uppercase;
|
||||
font-size: 85%;
|
||||
}
|
||||
|
||||
dd {
|
||||
width: 60%;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
dd:after {
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Helpers
|
||||
.align-center { text-align: center }
|
||||
.align-right { text-align: right }
|
||||
.align-left { text-align: left }
|
||||
.align-justify { text-align: justify }
|
||||
|
||||
.uppercase { text-transform: uppercase }
|
||||
|
||||
.green { color: $color-2 }
|
||||
.blue { color: $color-3 }
|
||||
.red { color: $color-5 }
|
||||
.yellow { color: $color-6 }
|
||||
|
||||
.no-objects-found {
|
||||
text-align: center;
|
||||
font-size: 120%;
|
||||
text-transform: uppercase;
|
||||
padding: 40px 0px;
|
||||
color: lighten($color-body-text, 15);
|
||||
}
|
||||
|
||||
.text-normal {
|
||||
font-size: 1rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.text-big {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.text-red {
|
||||
color: $color-warning;
|
||||
}
|
||||
|
||||
input.text-big {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.pad-top {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
.white-space-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#banner-container {
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: $tos-banner-z-index;
|
||||
|
||||
.terms-of-service-banner {
|
||||
padding: 18px;
|
||||
text-align: center;
|
||||
font-size: 120%;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
margin-top: 0;
|
||||
background-color: rgba($color-notice, 0.8);
|
||||
display: flex;
|
||||
|
||||
.column-left {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.column-right {
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
@import "../css/admin/all.scss";
|
||||
@import "../../../node_modules/trix/dist/trix.css";
|
||||
83
compose.yaml
83
compose.yaml
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,25 +41,61 @@ 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
|
||||
# Print deprecation notices to the stderr.
|
||||
# config.active_support.deprecation = :stderr
|
||||
|
||||
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
|
||||
# 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 = [
|
||||
# List strings here to allow matching deprecations.
|
||||
#
|
||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
|
||||
"config.active_support.cache_format_version",
|
||||
|
||||
# `Rails.application.secrets` is deprecated in favor of `Rails.application.credentials` and will be removed in Rails 7.2
|
||||
"Rails.application.secrets",
|
||||
|
||||
"Passing the class as positional argument",
|
||||
|
||||
# Spree::Order model aliases `bill_address`, but `bill_address` is not an attribute. Starting in Rails 7.2, alias_attribute with non-attribute targets will raise. Use `alias_method :billing_address, :bill_address` or define the method manually. (called from initialize at app/models/spree/order.rb:188)
|
||||
"alias_attribute with non-attribute targets will raise",
|
||||
|
||||
# Spree::CreditCard model aliases `cc_type` and has a method called `cc_type=` defined. Starting in Rails 7.2 `brand=` will not be calling `cc_type=` anymore. You may want to additionally define `brand=` to preserve the current behavior.
|
||||
"model aliases",
|
||||
|
||||
# Setting action_dispatch.show_exceptions to true is deprecated. Set to :all instead.
|
||||
# spec/requests/errors_spec.rb
|
||||
"action_dispatch.show_exceptions",
|
||||
]
|
||||
unless allowed_warnings.any? { |pattern| message.match(pattern) }
|
||||
ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:raise].call(message, callstack, deprecator)
|
||||
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"
|
||||
@@ -46,23 +103,11 @@ Openfoodnetwork::Application.configure do
|
||||
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
|
||||
# Annotate rendered view with file names.
|
||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||
|
||||
# Print deprecation notices to the stderr
|
||||
# config.active_support.deprecation = :stderr
|
||||
|
||||
# Fail tests on deprecated code unless it's a known case to solve.
|
||||
ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) do
|
||||
allowed_warnings = [
|
||||
# List strings here to allow matching deprecations.
|
||||
]
|
||||
unless allowed_warnings.any? { |pattern| message.match(pattern) }
|
||||
ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:raise].call(message, callstack, deprecation_horizon, gem_name)
|
||||
end
|
||||
end
|
||||
# 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
|
||||
|
||||
@@ -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',
|
||||
]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
]
|
||||
|
||||
@@ -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"
|
||||
|
||||
143
config/initializers/new_framework_defaults_7_0.rb
Normal file
143
config/initializers/new_framework_defaults_7_0.rb
Normal 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
|
||||
280
config/initializers/new_framework_defaults_7_1.rb
Normal file
280
config/initializers/new_framework_defaults_7_1.rb
Normal 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
|
||||
13
config/initializers/permissions_policy.rb
Normal file
13
config/initializers/permissions_policy.rb
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1447,6 +1447,8 @@ en_CA:
|
||||
visible: Visible?
|
||||
owner: Owner
|
||||
producer: Producer
|
||||
sells_options:
|
||||
none: none
|
||||
change_type_form:
|
||||
producer_profile: Producer Profile
|
||||
connect_ofn: Connect through OFN
|
||||
@@ -3315,6 +3317,7 @@ en_CA:
|
||||
product_importer_products_save_error: did not save any products successfully
|
||||
product_import_file_not_found_notice: 'File not found or could not be opened'
|
||||
product_import_no_data_in_spreadsheet_notice: 'No data found in spreadsheet'
|
||||
product_import_inventory_disable: Importing into inventories is not available
|
||||
order_choosing_hub_notice: Your hub has been selected.
|
||||
order_cycle_selecting_notice: Your order cycle has been selected.
|
||||
adjustments_tax_rate_error: "^Please check that the tax rate for this adjustment is correct."
|
||||
@@ -3617,7 +3620,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:
|
||||
|
||||
@@ -1447,6 +1447,8 @@ en_FR:
|
||||
visible: Visible?
|
||||
owner: Owner
|
||||
producer: Producer
|
||||
sells_options:
|
||||
none: none
|
||||
change_type_form:
|
||||
producer_profile: Producer Profile
|
||||
connect_ofn: Connect through OFN
|
||||
@@ -3315,6 +3317,7 @@ en_FR:
|
||||
product_importer_products_save_error: did not save any products successfully
|
||||
product_import_file_not_found_notice: 'File not found or could not be opened'
|
||||
product_import_no_data_in_spreadsheet_notice: 'No data found in spreadsheet'
|
||||
product_import_inventory_disable: Importing into inventories is not available
|
||||
order_choosing_hub_notice: Your hub has been selected.
|
||||
order_cycle_selecting_notice: Your order cycle has been selected.
|
||||
adjustments_tax_rate_error: "^Please check that the tax rate for this adjustment is correct."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -3321,6 +3323,7 @@ fr:
|
||||
product_importer_products_save_error: n'a pu sauvegarder aucun produit :-(
|
||||
product_import_file_not_found_notice: 'Fichier non trouvé ou impossible à ouvrir'
|
||||
product_import_no_data_in_spreadsheet_notice: 'Aucune donnée trouvée dans le tableau'
|
||||
product_import_inventory_disable: L'importation vers les catalogues boutique n'est pas disponible
|
||||
order_choosing_hub_notice: Votre boutique a été sélectionnée.
|
||||
order_cycle_selecting_notice: Votre cycle de vente a été sélectionné.
|
||||
adjustments_tax_rate_error: "^Veuillez vérifier la TVA applicable pour cet ajustement."
|
||||
|
||||
@@ -1451,6 +1451,8 @@ fr_CA:
|
||||
visible: Visible?
|
||||
owner: Gérant
|
||||
producer: Producteur
|
||||
sells_options:
|
||||
none: aucun
|
||||
change_type_form:
|
||||
producer_profile: Profil producteur
|
||||
connect_ofn: Gagnez en visibilité via OFN
|
||||
@@ -3322,6 +3324,7 @@ fr_CA:
|
||||
product_importer_products_save_error: n'a pu sauvegarder aucun produit :-(
|
||||
product_import_file_not_found_notice: 'Fichier non trouvé ou impossible à ouvrir'
|
||||
product_import_no_data_in_spreadsheet_notice: 'Aucune donnée trouvée dans le tableau'
|
||||
product_import_inventory_disable: L'importation vers les catalogues boutique n'est pas disponible
|
||||
order_choosing_hub_notice: Votre hub a été sélectionné.
|
||||
order_cycle_selecting_notice: Votre cycle de vente a été sélectionné.
|
||||
adjustments_tax_rate_error: "^Veuillez vérifier le type de taxe applicable pour cet ajustement."
|
||||
|
||||
@@ -530,7 +530,7 @@ hu:
|
||||
save: "Mentés"
|
||||
edit: "Szerkesztés"
|
||||
update: "Frissítés"
|
||||
delete: "Töröl"
|
||||
delete: "Törlés"
|
||||
add: "Hozzáadás"
|
||||
cut: "Kivágás"
|
||||
paste: "Beillesztés"
|
||||
@@ -580,7 +580,7 @@ hu:
|
||||
actions:
|
||||
edit: Szerkesztés
|
||||
clone: Klón
|
||||
delete: Töröl
|
||||
delete: Törlés
|
||||
remove: Eltávolítás
|
||||
preview: Előnézet
|
||||
image:
|
||||
@@ -907,7 +907,7 @@ hu:
|
||||
success: Sikeresen klónozta a terméket
|
||||
error: A terméket nem sikerült klónozni
|
||||
product_import:
|
||||
title: Termék importálása
|
||||
title: Termék importálás
|
||||
file_not_found: A fájl nem található, vagy nem nyitható meg
|
||||
no_data: Nem található adat a táblázatban
|
||||
confirm_reset: "Ezzel nullára állítod a készletszintet a vállalkozás összes olyan termékénél, \namely nem szerepel a feltöltött fájlban"
|
||||
@@ -922,7 +922,7 @@ hu:
|
||||
not_updatable: nem frissíthető a meglévő termékeken termékimporttal
|
||||
values_must_be_same: azonos név alatt azonos terméknek kell szerepelnie
|
||||
blank: nem lehet üres
|
||||
products_no_permission: nincs engedélye a vállalkozás termékeinek kezelésére
|
||||
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
|
||||
none_saved: egyetlen terméket sem mentett sikeresen
|
||||
line_number: "%{number}. sor:"
|
||||
@@ -970,6 +970,7 @@ hu:
|
||||
no_name: Névtelen
|
||||
blank_enterprise: egyes termékekhez nincs definiálva a vállalkozás
|
||||
reset_absent?: Hiányzó termékek visszaállítása
|
||||
reset_absent_tip: Állítsa nullára a készletet az összes olyan terméknél, amely nem szerepel a fájlban
|
||||
overwrite_all: Az összes felülírása
|
||||
overwrite_empty: Ha üres, írja felül
|
||||
default_stock: Állítsd be a készletet
|
||||
@@ -977,15 +978,15 @@ hu:
|
||||
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
|
||||
entries_found: Bejegyzések találhatók az importált fájlban
|
||||
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ékek jönnek létre
|
||||
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_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
|
||||
line: Vonal
|
||||
line: Sor
|
||||
item_line: Tételsor
|
||||
import_review:
|
||||
not_updatable_tip: "A következő mezők nem frissíthetők tömeges importálással meglévő termékek esetén:"
|
||||
@@ -993,14 +994,14 @@ hu:
|
||||
entries_table:
|
||||
not_updatable: Ez a mező nem frissíthető tömeges importálással meglévő termékeken
|
||||
save_results:
|
||||
final_results: Végső eredmények importálása
|
||||
products_created: Létrehozott termékek
|
||||
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
|
||||
products_reset: A termékek készletszintjét nullára állítottuk vissza
|
||||
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
|
||||
all_saved: "Minden elem sikeresen mentve"
|
||||
all_saved: "Minden termék mentése sikeres."
|
||||
some_saved: "elemek sikeresen mentve"
|
||||
save_errors: Mentse el a hibákat
|
||||
import_again: Másik fájl feltöltése
|
||||
@@ -1011,7 +1012,7 @@ hu:
|
||||
producer: Termelő
|
||||
sku: SKU
|
||||
name: Név
|
||||
display_name: Megjelenítendő név
|
||||
display_name: Alternatív név
|
||||
category: Kategória
|
||||
description: Leírás
|
||||
units: Egységek
|
||||
@@ -1382,6 +1383,8 @@ hu:
|
||||
visible: Látható?
|
||||
owner: Tulajdonos
|
||||
producer: Termelő
|
||||
sells_options:
|
||||
none: n.a.
|
||||
change_type_form:
|
||||
producer_profile: Termelői Profil
|
||||
connect_ofn: Csatlakozás OFN-en keresztül
|
||||
@@ -1518,7 +1521,7 @@ hu:
|
||||
add_distributor: 'Elosztó hozzáadása'
|
||||
advanced_settings:
|
||||
automatic_notifications: Automatikus értesítések
|
||||
automatic_notifications_tip: Automatikusan értesíti a termelőket rendeléseikről e-mailben, amikor a rendelési ciklusok lezárulnak
|
||||
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.
|
||||
preferred_product_selection_from_coordinator_inventory_only_here: Csak a koordinátor leltár
|
||||
@@ -2397,11 +2400,11 @@ hu:
|
||||
set_a_password: "Ezután a rendszer kéri, hogy állítson be egy jelszót, mielőtt felügyelheti 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: "Alább megtalálja a rendelési ciklusra vonatkozó frissítést:"
|
||||
producer_mail_order_text: "Íme a termékei megrendelésének összefoglalása:"
|
||||
producer_mail_text_before: "Küldjük az alábbi rendelési ciklusra vonatkozó összesítést:"
|
||||
producer_mail_order_text: "Megrendelt termékek:"
|
||||
producer_mail_delivery_instructions: "Raktári átvételi/szállítási instrukciók:"
|
||||
producer_mail_signoff: "Köszönet és jókívánságok"
|
||||
producer_mail_order_customer_text: "Itt található a rendelések összegzése ügyfelek szerint csoportosítva"
|
||||
producer_mail_signoff: "Üdvözlettel,"
|
||||
producer_mail_order_customer_text: "A rendelések vásárlók szerint csoportosítva:"
|
||||
shopping_oc_closed: A rendelések lezárva
|
||||
shopping_oc_closed_description: "Kérjük, várd meg, amíg a következő ciklus megnyílik."
|
||||
shopping_oc_last_closed: "Az utolsó ciklus ennyi ideje zárult: %{distance_of_time}"
|
||||
@@ -2865,7 +2868,7 @@ hu:
|
||||
admin_enterprise_groups_web_website_placeholder: "például www.truffles.com"
|
||||
admin_order_cycles: "Admin Rendelési Ciklusok"
|
||||
open: "Nyit"
|
||||
close: "Zár"
|
||||
close: "Bezárás"
|
||||
create: "Létrehozás"
|
||||
search: "Keresés"
|
||||
supplier: "Beszállító"
|
||||
@@ -2902,7 +2905,7 @@ hu:
|
||||
edit_order_cycle: "Rendelési Ciklus Szerkesztése"
|
||||
roles: "Szerepek"
|
||||
update: "Frissítés"
|
||||
delete: Töröl
|
||||
delete: Törlés
|
||||
add_producer_property: "Termelői tulajdonság hozzáadása"
|
||||
in_progress: "Folyamatban"
|
||||
started_at: "Kezdődött:"
|
||||
@@ -3472,7 +3475,7 @@ hu:
|
||||
compiling_invoices: "Vevői lapok összeállítása"
|
||||
bulk_invoice_created: "Vevői lapok létrehozva"
|
||||
bulk_invoice_failed: "Nem sikerült létrehozni a tömeges számlát"
|
||||
please_wait: "A modul bezárása előtt várja meg, amíg a PDF elkészül."
|
||||
please_wait: "A modul bezárása előtt várd meg, amíg a PDF elkészül."
|
||||
order_state:
|
||||
address: "cím"
|
||||
adjustments: "kiigazításokat"
|
||||
@@ -3888,7 +3891,7 @@ hu:
|
||||
total: "Összesen"
|
||||
edit: "Szerkesztés"
|
||||
split: "Hasított"
|
||||
delete: "Töröl"
|
||||
delete: "Törlés"
|
||||
cannot_set_shipping_method_without_address: "A áruátvételi módot nem lehet beállítani, amíg meg nem adják az ügyfél adatait."
|
||||
no_tracking_present: "Nincsenek megadva nyomkövetési adatok."
|
||||
tracking: "Követés"
|
||||
@@ -4445,7 +4448,7 @@ hu:
|
||||
sku: "SKU"
|
||||
unit_price: "Egységár"
|
||||
display_as: "Megjelenítés mint"
|
||||
display_name: "Megjelenítendő név"
|
||||
display_name: "Alternatív név"
|
||||
display_as_placeholder: 'például 2 kg'
|
||||
display_name_placeholder: 'például paradicsom'
|
||||
unit_scale: "Mértékegység skála"
|
||||
|
||||
@@ -73,17 +73,13 @@ Openfoodnetwork::Application.routes.draw do
|
||||
post :import, on: :collection
|
||||
end
|
||||
|
||||
constraints FeatureToggleConstraint.new(:admin_style_v3) do
|
||||
# This might be easier to arrange once we rename the controller to plain old "products"
|
||||
post '/products/bulk_update', to: 'products_v3#bulk_update'
|
||||
get '/products', to: 'products_v3#index'
|
||||
# we already have DELETE admin/products/:id here
|
||||
delete 'products_v3/:id', to: 'products_v3#destroy', as: 'product_destroy'
|
||||
delete 'products_v3/destroy_variant/:id', to: 'products_v3#destroy_variant', as: 'destroy_variant'
|
||||
post 'clone/:id', to: 'products_v3#clone', as: 'clone_product'
|
||||
|
||||
resources :product_preview, only: [:show]
|
||||
end
|
||||
# This might be easier to arrange once we rename the controller to plain old "products"
|
||||
post '/products/bulk_update', to: 'products_v3#bulk_update', as: 'products_bulk_update'
|
||||
get '/products', to: 'products_v3#index', as: 'products'
|
||||
delete 'products_v3/:id', to: 'products_v3#destroy', as: 'product_destroy'
|
||||
delete 'products_v3/destroy_variant/:id', to: 'products_v3#destroy_variant', as: 'destroy_variant'
|
||||
post 'clone/:id', to: 'products_v3#clone', as: 'clone_product'
|
||||
resources :product_preview, only: [:show]
|
||||
|
||||
resources :variant_overrides do
|
||||
post :bulk_update, on: :collection
|
||||
|
||||
@@ -50,16 +50,8 @@ Spree::Core::Engine.routes.draw do
|
||||
|
||||
resources :users
|
||||
|
||||
constraints FeatureToggleConstraint.new(:admin_style_v3, negate: true) do
|
||||
# Show old bulk products screen
|
||||
resources :products, :index do
|
||||
post :bulk_update, :on => :collection, :as => :bulk_update
|
||||
end
|
||||
end
|
||||
|
||||
resources :products, except: :index do
|
||||
resources :products, except: [:index, :destroy] do
|
||||
member do
|
||||
get :clone
|
||||
get :group_buy_options
|
||||
get :seo
|
||||
end
|
||||
@@ -83,11 +75,6 @@ Spree::Core::Engine.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
if Rails.env.development?
|
||||
# duplicate old path for reference when admin_style_v3 enabled
|
||||
resources :products_old, to: 'products#index', only: :index
|
||||
end
|
||||
|
||||
get '/variants/search', :to => "variants#search", :as => :search_variants
|
||||
|
||||
resources :properties
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
class ActivateAdminStyleV3ForNewUsers < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
Flipper.enable_group(:admin_style_v3, :new_2024_07_03)
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
class EnableFeatureAdminStyleV3ForAdmins < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
Flipper.enable_group(:admin_style_v3, :admins)
|
||||
end
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
class EnableAdminStyleV3ByDefault < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
if Rails.env.development?
|
||||
Flipper.enable(:admin_style_v3)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
class ActivateAdminStyleV3For25PCentUsers < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
Flipper.enable_percentage_of_actors(:admin_style_v3, 25)
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
class ActivateAdminStyleV3For50PcUsers < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
Flipper.enable_percentage_of_actors(:admin_style_v3, 50)
|
||||
end
|
||||
end
|
||||
@@ -1,9 +0,0 @@
|
||||
class ActivateAdminStyleV3For75PcUsers < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
Flipper.enable_percentage_of_actors(:admin_style_v3, 75)
|
||||
end
|
||||
|
||||
def down
|
||||
Flipper.enable_percentage_of_actors(:admin_style_v3, 50)
|
||||
end
|
||||
end
|
||||
@@ -1,5 +0,0 @@
|
||||
class FullyEnableAdminStyleV3Flag < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
Flipper.enable(:admin_style_v3)
|
||||
end
|
||||
end
|
||||
16
db/migrate/20250515050349_create_dfc_permissions.rb
Normal file
16
db/migrate/20250515050349_create_dfc_permissions.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CreateDfcPermissions < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :dfc_permissions do |t|
|
||||
t.references :user, null: false, foreign_key: { to_table: :spree_users }
|
||||
t.references :enterprise, null: false, foreign_key: true
|
||||
t.string :grantee, null: false
|
||||
t.string :scope, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :dfc_permissions, :grantee
|
||||
add_index :dfc_permissions, :scope
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user