mirror of
https://github.com/strapi/strapi.git
synced 2025-12-12 23:44:08 +00:00
Merge branch 'features/media-lib' of github.com:strapi/strapi into features/media-lib-settings-view
This commit is contained in:
commit
efe0b1a424
57
.travis.yml
57
.travis.yml
@ -3,17 +3,13 @@ services:
|
||||
- mysql
|
||||
|
||||
addons:
|
||||
postgresql: '10'
|
||||
apt:
|
||||
packages:
|
||||
- postgresql-10
|
||||
- postgresql-client-10
|
||||
postgresql: '11.2'
|
||||
|
||||
env:
|
||||
global:
|
||||
- PGPORT=5433
|
||||
|
||||
sudo: required
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
|
||||
language: node_js
|
||||
|
||||
@ -33,14 +29,6 @@ e2e_tests: &e2e_tests
|
||||
- yarn run -s test:start-app & wait-on http://localhost:1337
|
||||
- yarn run -s test:e2e
|
||||
|
||||
install_mongo: &install_mongo
|
||||
before_install:
|
||||
- wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.6.tgz
|
||||
- tar -zxvf mongodb-linux-x86_64-3.6.6.tgz
|
||||
- mkdir -p ./data/db/27017
|
||||
- mkdir -p ./data/db/27000
|
||||
- ./mongodb-linux-x86_64-3.6.6/bin/mongod --fork --dbpath ./data/db/27017 --syslog --port 27017
|
||||
|
||||
before_script:
|
||||
- yarn build
|
||||
- yarn global add -g wait-on
|
||||
@ -50,11 +38,17 @@ jobs:
|
||||
include:
|
||||
- stage: test
|
||||
name: Snyk
|
||||
before_install:
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
script: yarn run -s test:snyk
|
||||
if: fork = false
|
||||
|
||||
- stage: test
|
||||
name: 'Lint / Unit Tests '
|
||||
before_install:
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
script:
|
||||
- yarn run -s lint
|
||||
- yarn run -s test:unit --coverage && codecov -C -F unit
|
||||
@ -63,8 +57,13 @@ jobs:
|
||||
- <<: *e2e_tests
|
||||
name: 'E2E Postgresql'
|
||||
before_install:
|
||||
- sudo cp /etc/postgresql/{9.6,10}/main/pg_hba.conf
|
||||
- sudo /etc/init.d/postgresql restart
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
- sudo apt-get update
|
||||
- sudo apt-get --yes remove postgresql-*
|
||||
- sudo apt-get install -y postgresql-11 postgresql-client-11
|
||||
- sudo cp /etc/postgresql/{9.6,11}/main/pg_hba.conf
|
||||
- sudo service postgresql restart 11
|
||||
- psql -c 'create database strapi_test;' -U postgres
|
||||
env:
|
||||
- DB_STRING='--dbclient=postgres --dbhost=localhost --dbport=5433 --dbname=strapi_test --dbusername=postgres --dbpassword='
|
||||
@ -72,6 +71,8 @@ jobs:
|
||||
- <<: *e2e_tests
|
||||
name: 'E2E Mysql'
|
||||
before_install:
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
- sudo cp $TRAVIS_BUILD_DIR/_travis/mysql.cnf /etc/mysql/conf.d/
|
||||
- sudo service mysql restart
|
||||
- mysql -e 'CREATE DATABASE strapi_test;'
|
||||
@ -80,21 +81,21 @@ jobs:
|
||||
|
||||
- <<: *e2e_tests
|
||||
name: 'E2E Sqlite'
|
||||
before_install:
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
env:
|
||||
- DB_STRING='--dbclient=sqlite --dbfile=./tmp/data.db'
|
||||
|
||||
- <<: *e2e_tests
|
||||
name: 'E2E MongoDB'
|
||||
<<: *install_mongo
|
||||
before_install:
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
- wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.6.6.tgz
|
||||
- tar -zxvf mongodb-linux-x86_64-3.6.6.tgz
|
||||
- mkdir -p ./data/db/27017
|
||||
- mkdir -p ./data/db/27000
|
||||
- ./mongodb-linux-x86_64-3.6.6/bin/mongod --fork --dbpath ./data/db/27017 --syslog --port 27017
|
||||
env:
|
||||
- DB_STRING='--dbclient=mongo --dbhost=localhost --dbport=27017 --dbname=strapi_test --dbusername= --dbpassword='
|
||||
# - name: 'Cypress tests'
|
||||
# <<: *install_mongo
|
||||
# install:
|
||||
# - yarn run -s bootstrap
|
||||
# - yarn global add -g wait-on
|
||||
# - cypress install
|
||||
# script:
|
||||
# - yarn run -s test:generate-app -- --dbclient=mongo --dbhost=localhost --dbport=27017 --dbname=strapi_test --dbusername= --dbpassword=
|
||||
# - yarn run -s test:start-app & wait-on http://localhost:1337
|
||||
# - node test/cypress.js
|
||||
|
||||
@ -9,7 +9,9 @@ const Wrapper = styled.div`
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - (${props => props.theme.main.sizes.leftMenu.height} + 10.2rem));
|
||||
height: calc(
|
||||
100vh - (${props => props.theme.main.sizes.leftMenu.height} + 10.2rem)
|
||||
);
|
||||
box-sizing: border-box;
|
||||
|
||||
.title {
|
||||
|
||||
@ -431,7 +431,6 @@ exports[`Admin | containers | EditView should match the snapshot 1`] = `
|
||||
font-size: 2.4rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1px;
|
||||
text-transform: capitalize;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
|
||||
@ -168,7 +168,6 @@ exports[`Admin | containers | ListView should match the snapshot 1`] = `
|
||||
font-size: 2.4rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1px;
|
||||
text-transform: capitalize;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
|
||||
@ -97,6 +97,14 @@
|
||||
"app.utils.placeholder.defaultMessage": " ",
|
||||
"components.AutoReloadBlocker.header": "مطلوب ميزة إعادة التحميل لهذه الإضافة.",
|
||||
"components.ErrorBoundary.title": "هناك خطأ ما...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "هو",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "يحتوي",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "يحتوي (حساس لحالة الأحرف)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "اكبر من",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "اكبر من او يساوي",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "اقل من",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "اقل من او يساوي",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "ليس",
|
||||
"components.Input.error.attribute.key.taken": "هذه القيمة موجودة مسبقًا",
|
||||
"components.Input.error.attribute.sameKeyAndName": "لا تتطابق",
|
||||
"components.Input.error.attribute.taken": "اسم الحقل هذا مستخدم مسبقًا",
|
||||
|
||||
@ -114,6 +114,16 @@
|
||||
"components.AutoReloadBlocker.description": "Spusťte Strapi jedním z následujících příkazů:",
|
||||
"components.AutoReloadBlocker.header": "Pro tento zásuvný modul musí být zapnuta funkce znovu načítání.",
|
||||
"components.ErrorBoundary.title": "Něco se pokazilo...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "je",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "obsahuje",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "obsahuje (citlivé na velká písmena)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "je větší než",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "je větší nebo rovno než",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "je menší než",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "je menší nebo rovno než",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "není",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "odpovídá jakékoliv hodnotě v poli hodnot",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "neodpovídá ani jedné hodnotě v poli hodnot",
|
||||
"components.Input.error.attribute.key.taken": "Tato hodnota již existuje",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Hodnoty nesmí být stejné",
|
||||
"components.Input.error.attribute.taken": "Název tohoto pole již existuje",
|
||||
|
||||
@ -111,6 +111,14 @@
|
||||
"components.AutoReloadBlocker.description": "Führen Sie Strapi mit einem der folgenden Befehle aus:",
|
||||
"components.AutoReloadBlocker.header": "Dieses Plugin benötigt das Neuladen-Feature.",
|
||||
"components.ErrorBoundary.title": "Etwas ist falsch gelaufen...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "ist",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "enthält",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "enthält (Groß-/Kleinschreibung beachten)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "ist größer als",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "ist größer oder gleich als",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "ist kleiner als",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "ist kleiner oder gleich als",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "ist nicht",
|
||||
"components.Input.error.attribute.key.taken": "Dieser Wert existiert bereits",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Darf nicht gleich sein",
|
||||
"components.Input.error.attribute.taken": "Dieser Feldname ist bereits vergeben",
|
||||
|
||||
@ -117,6 +117,16 @@
|
||||
"components.AutoReloadBlocker.description": "Run Strapi with one of the following commands:",
|
||||
"components.AutoReloadBlocker.header": "Reload feature is required for this plugin.",
|
||||
"components.ErrorBoundary.title": "Something went wrong...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "is",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contains",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contains (case sensitive)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "is greater than",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "is greater than or equal to",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "is lower than",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "is lower than or equal to",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "is not",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "matches any value in the array of values",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "doesn't match any value in the array of values",
|
||||
"components.Input.error.attribute.key.taken": "This value already exists",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Can't be equal",
|
||||
"components.Input.error.attribute.taken": "This field name already exists",
|
||||
|
||||
@ -110,6 +110,16 @@
|
||||
"components.AutoReloadBlocker.description": "Inicia Strapi con uno de los siguientes comandos:",
|
||||
"components.AutoReloadBlocker.header": "Es necesario recargar para este plugin.",
|
||||
"components.ErrorBoundary.title": "Algo salió mal...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "es",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contiene",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contiene (distinguiendo mayúsculas y minúsculas)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "es mayor que",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "es mayor o igual que",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "es menor que",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "es menor o igual que",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "no es",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "coincide con cualquier valor de la lista de registros",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "no coincide con ningún valor de la lista de registros",
|
||||
"components.Input.error.attribute.key.taken": "Este valor ya existe",
|
||||
"components.Input.error.attribute.sameKeyAndName": "No puede ser igual",
|
||||
"components.Input.error.attribute.taken": "Este nombre de campo ya existe",
|
||||
|
||||
@ -116,6 +116,14 @@
|
||||
"components.AutoReloadBlocker.description": "Démarrez Strapi avec l'une des commandes suivantes:",
|
||||
"components.AutoReloadBlocker.header": "L'autoReload doit être activé pour ce plugin.",
|
||||
"components.ErrorBoundary.title": "Une erreur est survenue...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "est",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contient",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contient (sensible à la casse)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "supérieur à",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "supérieur ou égal à",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "inférieur à",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "inférieur ou égal à",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "n'est pas",
|
||||
"components.Input.error.attribute.key.taken": "Cette valeur existe déjà",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Ne peuvent pas être égaux",
|
||||
"components.Input.error.attribute.taken": "Ce champ existe déjà",
|
||||
|
||||
@ -111,6 +111,14 @@
|
||||
"components.AutoReloadBlocker.description": "Avvia Strapi con uno dei seguenti comandi:",
|
||||
"components.AutoReloadBlocker.header": "Ricarica funzionalità è richiesto per questo plugin.",
|
||||
"components.ErrorBoundary.title": "Qualcosa è andato storto...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "si",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contiene",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contiene (maiuscole e minuscole)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "è maggiore di",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "è maggiore o uguale a",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "è inferiore",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "è inferiore o uguale a",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "non è",
|
||||
"components.Input.error.attribute.key.taken": "Valore già esistente",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Non può essere uguale",
|
||||
"components.Input.error.attribute.taken": "Nome campo già esistente",
|
||||
|
||||
@ -98,6 +98,14 @@
|
||||
"app.utils.SelectOption.defaultMessage": " ",
|
||||
"components.AutoReloadBlocker.header": "プラグインを有効化するにはリロードが必要です",
|
||||
"components.ErrorBoundary.title": "なにかが間違っています...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "は",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "含まれる",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "含まれる(大文字と小文字を区別)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "より大きい",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "より大きい、もしくは、等しい",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "より低い",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "より低い、もしくは、等しい",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "ではない",
|
||||
"components.Input.error.attribute.key.taken": "この値はすでに存在しています",
|
||||
"components.Input.error.attribute.sameKeyAndName": "等しくありません",
|
||||
"components.Input.error.attribute.taken": "このフィールド名はすでに存在します",
|
||||
|
||||
@ -111,6 +111,16 @@
|
||||
"components.AutoReloadBlocker.description": "다음 명령어 중 하나를 사용하여 Strapi를 실행합니다:",
|
||||
"components.AutoReloadBlocker.header": "이 플러그인은 리로드 기능이 필요합니다.",
|
||||
"components.ErrorBoundary.title": "에러가 발생했습니다.",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "같음",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "포함",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "포함(대소문자 구분)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "큼",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "크거나 같음",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "작음",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "작거나 같음",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "같지 않음",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "배열중에 일치하는 값이 있음",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "배열중에 일치하는 값이 없음",
|
||||
"components.Input.error.attribute.key.taken": "이미 사용중인 키입니다.",
|
||||
"components.Input.error.attribute.sameKeyAndName": "같은 값을 사용할 수 없습니다.",
|
||||
"components.Input.error.attribute.taken": "이미 사용중인 이름입니다.",
|
||||
@ -216,4 +226,4 @@
|
||||
"components.Input.error.password.noMatch": "패스워드가 일치하지 않습니다.",
|
||||
"form.button.done": "확인",
|
||||
"notification.form.error.fields": "잘못 입력된 필드가 존재합니다."
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,6 +98,14 @@
|
||||
"app.utils.placeholder.defaultMessage": " ",
|
||||
"components.AutoReloadBlocker.header": "De herlaad feature is nodig voor deze extensie",
|
||||
"components.ErrorBoundary.title": "Er is iets fout gegaan...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "is",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "bevat",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "bevat (hoofdletter gevoelig)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "is groter dan",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "is groter dan of gelijk aan",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "is lager dan",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "is lager dan of gelijk aan",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "is niet",
|
||||
"components.Input.error.attribute.key.taken": "Deze waarde bestaat al.",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Mag niet gelijk zijn.",
|
||||
"components.Input.error.attribute.taken": "Deze veld naam bestaat al",
|
||||
|
||||
@ -117,6 +117,16 @@
|
||||
"components.AutoReloadBlocker.description": "Uruchom Strapi z jedną z poniższych komend:",
|
||||
"components.AutoReloadBlocker.header": "Do tej wtyczki wymagana jest funkcja przeładowania.",
|
||||
"components.ErrorBoundary.title": "Coś poszło nie tak...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "jest identyczne z",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "zawiera",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "zawiera (rozróżnianie wielkości liter)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "jest większe od",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "jest większe od lub równe",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "dopasuj jakąkolwiek wartość z tablicy wartości",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "jest mniejsze od",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "jest mniejsze od lub równe",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "jest różne od",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "nie znaleziono pasującej wartości w tablicy wartości",
|
||||
"components.Input.error.attribute.key.taken": "Ta wartość już istnieje",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Nie mogą być takie same",
|
||||
"components.Input.error.attribute.taken": "Ta nazwa pola już istnieje",
|
||||
|
||||
@ -111,6 +111,14 @@
|
||||
"components.AutoReloadBlocker.description": "Execute o Strapi com um dos seguintes comandos:",
|
||||
"components.AutoReloadBlocker.header": "Auto recarregamento é necessário para esta extensão.",
|
||||
"components.ErrorBoundary.title": "Algo deu errado...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "é",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contém",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contém (case sensitive)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "é maior que",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "é maior que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "é menor que",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "é menor que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "não é",
|
||||
"components.Input.error.attribute.key.taken": "Este valor já existe",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Não pode ser igual",
|
||||
"components.Input.error.attribute.taken": "O nome deste campo já existe",
|
||||
|
||||
@ -97,6 +97,14 @@
|
||||
"app.utils.placeholder.defaultMessage": " ",
|
||||
"components.AutoReloadBlocker.header": "Recurso de recarga é necessário para esta extensão.",
|
||||
"components.ErrorBoundary.title": "Algo deu errado...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "é",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contém",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contém (case sensitive)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "é maior que",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "é maior que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "é menor que",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "é menor que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "não é",
|
||||
"components.Input.error.attribute.key.taken": "Este valor já existe",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Não pode ser igual",
|
||||
"components.Input.error.attribute.taken": "O nome deste campo já existe",
|
||||
|
||||
@ -115,6 +115,14 @@
|
||||
"components.AutoReloadBlocker.description": "Запустите Strapi с помощью одной из следующих команд:",
|
||||
"components.AutoReloadBlocker.header": "Функционал перезапуска необходим для этого плагина.",
|
||||
"components.ErrorBoundary.title": "Что-то пошло не так...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "равно",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "содержит",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "содержит (с учетом регистра)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "больше чем",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "больше или равно",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "меньше чем",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "меньше или равно",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "не равно",
|
||||
"components.Input.error.attribute.key.taken": "Это значение уже существует",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Не может быть одинаковым",
|
||||
"components.Input.error.attribute.taken": "Поле с таким названием уже существует",
|
||||
|
||||
@ -115,6 +115,16 @@
|
||||
"components.AutoReloadBlocker.description": "Spustite Strapi s jedným z nasledujúcich príkazov:",
|
||||
"components.AutoReloadBlocker.header": "Pre tento plugin je požadované opätovné načítanie stránky.",
|
||||
"components.ErrorBoundary.title": "Niečo sa pokazilo...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "je",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "obsahuje",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "obsahuje (záleží na veľkosti písmen)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "je väčšie ako",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "je väčšie ako alebo rovné",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "je menšie ako",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "je menšie ako alebo rovné",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "nie je",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "obsahuje hodnotu z poľa",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "neobsahuje žiadnu hodnotu z poľa",
|
||||
"components.Input.error.attribute.key.taken": "Táto hodnota už existuje",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Nemôže sa rovnať",
|
||||
"components.Input.error.attribute.taken": "Názov tohto políčka už existuje",
|
||||
|
||||
@ -27,14 +27,14 @@
|
||||
"app.components.DownloadInfo.text": "Det kan ta en minut. Tack för ditt tålamod.",
|
||||
"app.components.EmptyAttributes.title": "Det finns inga fält än ",
|
||||
"app.components.HomePage.button.blog": "SE MER PÅ BLOGGEN",
|
||||
"app.components.HomePage.button.quickStart": "Snabb introduktion",
|
||||
"app.components.HomePage.community": "Hitta gemenskapen på webben",
|
||||
"app.components.HomePage.community.content": "Diskutera med teammedlemmar, bidragsgivare och utvecklare på olika kanaler.",
|
||||
"app.components.HomePage.create": "Skapa din första innehållstyp",
|
||||
"app.components.HomePage.createBlock.content.first": "De",
|
||||
"app.components.HomePage.createBlock.content.second": "plugin hjälper dig att definiera datastrukturen för dina modeller. Om du är ny här rekommenderar vi dig starkt att följa vår",
|
||||
"app.components.HomePage.createBlock.content.tutorial": "snabbguide.",
|
||||
"app.components.HomePage.cta": "BEKRÄFTA",
|
||||
"app.components.HomePage.button.quickStart": "Snabb introduktion",
|
||||
"app.components.HomePage.community": "Hitta gemenskapen på webben",
|
||||
"app.components.HomePage.community.content": "Diskutera med teammedlemmar, bidragsgivare och utvecklare på olika kanaler.",
|
||||
"app.components.HomePage.create": "Skapa din första innehållstyp",
|
||||
"app.components.HomePage.createBlock.content.first": "De",
|
||||
"app.components.HomePage.createBlock.content.second": "plugin hjälper dig att definiera datastrukturen för dina modeller. Om du är ny här rekommenderar vi dig starkt att följa vår",
|
||||
"app.components.HomePage.createBlock.content.tutorial": "snabbguide.",
|
||||
"app.components.HomePage.cta": "BEKRÄFTA",
|
||||
"app.components.HomePage.newsLetter": "Prenumerera på nyhetsbrevet för att hålla dig uppdaterad om Strapi",
|
||||
"app.components.HomePage.support": "STÖD OSS",
|
||||
"app.components.HomePage.support.content": "Genom att köpa en T-shirt hjälper du oss att fortsätta vårt arbete med projektet för att ge dig bästa möjliga upplevelse! ",
|
||||
|
||||
@ -115,6 +115,14 @@
|
||||
"components.AutoReloadBlocker.description": "Strapi'yi aşağıdaki komutlardan biri ile çalıştırın:",
|
||||
"components.AutoReloadBlocker.header": "Bu eklenti için tekrar yükleme özelliği gerekiyor.",
|
||||
"components.ErrorBoundary.title": "Bir şeyler yanlış gitti...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "eşit",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "içermek",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "içermek (büyük-küçük harfe duyarlı)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "daha yüksek",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "daha yüksek ya da eşit",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "daha düşük",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "daha düşük ya da eşit",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "eşit değil",
|
||||
"components.Input.error.attribute.key.taken": "Bu değer zaten var.",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Eşit olamaz",
|
||||
"components.Input.error.attribute.taken": "Bu alan ismi zaten var.",
|
||||
|
||||
@ -111,6 +111,16 @@
|
||||
"components.AutoReloadBlocker.description": "Chạy Strapi với một trong các lệnh sau:",
|
||||
"components.AutoReloadBlocker.header": "Tính năng Tải lại bị bắt buộc cho plugin này.",
|
||||
"components.ErrorBoundary.title": "Điều gì đó không ổn...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "là",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "chứa",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "chứa (phân biệt chữ hoa thường)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "lớn hơn",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "lớn hơn hoặc bằng",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "nhỏ hơn",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "nhỏ hơn hoặc bằng",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "không bằng",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "khớp với bất cứ giá trị nào có trong mảng giá trị",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "không khớp với bất cứ giá trị nào có trong mảng giá trị",
|
||||
"components.Input.error.attribute.key.taken": "Giá trị này đã tồn tại",
|
||||
"components.Input.error.attribute.sameKeyAndName": "Không thể bằng nhau",
|
||||
"components.Input.error.attribute.taken": "Trường nhập liệu này đã tồn tại",
|
||||
|
||||
@ -108,7 +108,7 @@
|
||||
"app.components.listPlugins.title.plural": "{number} 个插件已安装",
|
||||
"app.components.listPlugins.title.singular": "{number} 个插件已安装",
|
||||
"app.components.listPluginsPage.deletePlugin.error": "卸载插件时出错",
|
||||
|
||||
|
||||
"app.links.configure-view": "配置视图",
|
||||
|
||||
"app.utils.SelectOption.defaultMessage": " ",
|
||||
@ -117,6 +117,16 @@
|
||||
"components.AutoReloadBlocker.description": "使用以下命令中的一个来运行 Strapi:",
|
||||
"components.AutoReloadBlocker.header": "这个插件需要重新加载特性。",
|
||||
"components.ErrorBoundary.title": "哪里出问题了…",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "等于",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "包含",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "包含(区分大小写)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "大于",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "大于等于",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "小于",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "小于等于",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "不等于",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "包含在指定数组中",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "不包含在指定数组中",
|
||||
"components.Input.error.attribute.key.taken": "此值已经存在",
|
||||
"components.Input.error.attribute.sameKeyAndName": "不能相等",
|
||||
"components.Input.error.attribute.taken": "此字段名称已经存在",
|
||||
|
||||
@ -97,6 +97,14 @@
|
||||
"app.utils.placeholder.defaultMessage": " ",
|
||||
"components.AutoReloadBlocker.header": "這個擴充功能需要自動重新整理功能才能載入",
|
||||
"components.ErrorBoundary.title": "有錯誤發生...",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "等於",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "包含",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "包含(區分大小寫)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "大於",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "大於等於",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "小於",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "小於等於",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "不等於",
|
||||
"components.Input.error.attribute.key.taken": "這個數值已經存在了",
|
||||
"components.Input.error.attribute.sameKeyAndName": "不能等於",
|
||||
"components.Input.error.attribute.taken": "這個欄位名稱已經存在了",
|
||||
|
||||
@ -22,11 +22,11 @@
|
||||
"@babel/preset-env": "^7.4.3",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/runtime": "^7.4.3",
|
||||
"@buffetjs/core": "3.0.0-next.1",
|
||||
"@buffetjs/custom": "3.0.0-next.1",
|
||||
"@buffetjs/hooks": "3.0.0-next.1",
|
||||
"@buffetjs/icons": "3.0.0-next.1",
|
||||
"@buffetjs/styles": "3.0.0-next.1",
|
||||
"@buffetjs/core": "3.0.0-next.3",
|
||||
"@buffetjs/custom": "3.0.0-next.3",
|
||||
"@buffetjs/hooks": "3.0.0-next.3",
|
||||
"@buffetjs/icons": "3.0.0-next.3",
|
||||
"@buffetjs/styles": "3.0.0-next.3",
|
||||
"@buffetjs/utils": "^2.0.0",
|
||||
"@fortawesome/fontawesome-free": "^5.11.2",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.25",
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const RemoveButton = styled.button`
|
||||
display: flex;
|
||||
justify-items: center;
|
||||
height: 13px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
margin-left: 10px;
|
||||
border-left: 2px solid rgba(0, 126, 255, 0.1);
|
||||
`;
|
||||
|
||||
export default RemoveButton;
|
||||
@ -0,0 +1,22 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
margin-bottom: 6px;
|
||||
margin-right: 10px;
|
||||
padding-left: 10px;
|
||||
background: rgba(0, 126, 255, 0.08);
|
||||
border: 1px solid rgba(0, 126, 255, 0.24);
|
||||
border-radius: 2px;
|
||||
line-height: 28px;
|
||||
color: #007eff;
|
||||
font-size: 13px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
> span:nth-child(2) {
|
||||
font-weight: 700;
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@ -0,0 +1,42 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { upperFirst } from 'lodash';
|
||||
|
||||
import Wrapper from './Wrapper';
|
||||
import RemoveButton from './RemoveButton';
|
||||
|
||||
import Close from '../../svgs/Close';
|
||||
|
||||
function Filter({ label, onClick }) {
|
||||
const { name, filter, value } = label;
|
||||
return (
|
||||
<Wrapper>
|
||||
<span>{upperFirst(name)} </span>
|
||||
<FormattedMessage
|
||||
id={`components.FilterOptions.FILTER_TYPES.${filter}`}
|
||||
/>
|
||||
<span> {value}</span>
|
||||
<RemoveButton type="button" onClick={onClick}>
|
||||
<Close width="11px" height="11px" fill="#007eff" />
|
||||
</RemoveButton>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
Filter.defaultProps = {
|
||||
children: null,
|
||||
onClick: () => {},
|
||||
};
|
||||
|
||||
Filter.propTypes = {
|
||||
children: PropTypes.node,
|
||||
label: PropTypes.shape({
|
||||
name: PropTypes.string,
|
||||
filter: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
}),
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default Filter;
|
||||
@ -15,6 +15,7 @@ export { default as ContainerFluid } from './components/ContainerFluid';
|
||||
export { default as EmptyAttributesBlock } from './components/EmptyAttributesBlock';
|
||||
export { default as ErrorBoundary } from './components/ErrorBoundary';
|
||||
export { default as ExtendComponent } from './components/ExtendComponent';
|
||||
export { default as FilterButton } from './components/FilterButton';
|
||||
export { default as GlobalPagination } from './components/GlobalPagination';
|
||||
export { default as HeaderNav } from './components/HeaderNav';
|
||||
export { default as HeaderModal } from './components/HeaderModal';
|
||||
@ -94,8 +95,10 @@ export { default as useQuery } from './hooks/useQuery';
|
||||
export { default as auth } from './utils/auth';
|
||||
export { default as cleanData } from './utils/cleanData';
|
||||
export { default as difference } from './utils/difference';
|
||||
export { default as dateFormats } from './utils/dateFormats';
|
||||
export { default as translatedErrors } from './utils/translatedErrors';
|
||||
export { darken } from './utils/colors';
|
||||
export { default as getFilterType } from './utils/getFilterType';
|
||||
export { default as getQueryParameters } from './utils/getQueryParameters';
|
||||
export { default as injectHooks } from './utils/injectHooks';
|
||||
export { default as validateInput } from './utils/inputsValidations';
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
const DATE_FORMATS = {
|
||||
const dateFormats = {
|
||||
date: 'dddd, MMMM Do YYYY',
|
||||
datetime: 'dddd, MMMM Do YYYY HH:mm',
|
||||
time: 'HH:mm A',
|
||||
timestamp: 'dddd, MMMM Do YYYY HH:mm',
|
||||
};
|
||||
|
||||
export default DATE_FORMATS;
|
||||
export default dateFormats;
|
||||
108
packages/strapi-helper-plugin/lib/src/utils/getFilterType.js
Normal file
108
packages/strapi-helper-plugin/lib/src/utils/getFilterType.js
Normal file
@ -0,0 +1,108 @@
|
||||
const getFilterType = type => {
|
||||
switch (type) {
|
||||
case 'string':
|
||||
case 'text':
|
||||
case 'password':
|
||||
case 'email':
|
||||
return [
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES.=',
|
||||
value: '=',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._ne',
|
||||
value: '_ne',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._lt',
|
||||
value: '_lt',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._lte',
|
||||
value: '_lte',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._gt',
|
||||
value: '_gt',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._gte',
|
||||
value: '_gte',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._contains',
|
||||
value: '_contains',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._containss',
|
||||
value: '_containss',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._in',
|
||||
value: '_in',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._nin',
|
||||
value: '_nin',
|
||||
},
|
||||
];
|
||||
case 'integer':
|
||||
case 'biginteger':
|
||||
case 'float':
|
||||
case 'decimal':
|
||||
case 'date':
|
||||
case 'datetime':
|
||||
case 'time':
|
||||
case 'timestamp':
|
||||
case 'timestampUpdate':
|
||||
return [
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES.=',
|
||||
value: '=',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._ne',
|
||||
value: '_ne',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._lt',
|
||||
value: '_lt',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._lte',
|
||||
value: '_lte',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._gt',
|
||||
value: '_gt',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._gte',
|
||||
value: '_gte',
|
||||
},
|
||||
// FIXME: commenting these filters as I am not sure if the UI
|
||||
// corresponds to the filter
|
||||
// {
|
||||
// id: 'components.FilterOptions.FILTER_TYPES._in',
|
||||
// value: '_in',
|
||||
// },
|
||||
// {
|
||||
// id: 'components.FilterOptions.FILTER_TYPES._nin',
|
||||
// value: '_nin',
|
||||
// },
|
||||
];
|
||||
default:
|
||||
return [
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES.=',
|
||||
value: '=',
|
||||
},
|
||||
{
|
||||
id: 'components.FilterOptions.FILTER_TYPES._ne',
|
||||
value: '_ne',
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export default getFilterType;
|
||||
@ -3,9 +3,12 @@ import { withRouter } from 'react-router';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, isEmpty, isNull, isObject, toLower, toString } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { IcoContainer, useGlobalContext } from 'strapi-helper-plugin';
|
||||
import {
|
||||
IcoContainer,
|
||||
useGlobalContext,
|
||||
dateFormats,
|
||||
} from 'strapi-helper-plugin';
|
||||
import useListView from '../../hooks/useListView';
|
||||
import DATE_FORMATS from '../../utils/DATE_FORMATS';
|
||||
import CustomInputCheckbox from '../CustomInputCheckbox';
|
||||
import MediaPreviewList from '../MediaPreviewList';
|
||||
import { ActionContainer, Truncate, Truncated } from './styledComponents';
|
||||
@ -42,7 +45,7 @@ const getDisplayedValue = (type, value, name) => {
|
||||
? JSON.stringify(value)
|
||||
: value;
|
||||
|
||||
return dateToUtcTime(date).format(DATE_FORMATS[type]);
|
||||
return dateToUtcTime(date).format(dateFormats[type]);
|
||||
}
|
||||
case 'password':
|
||||
return '••••••••';
|
||||
@ -63,7 +66,7 @@ const getDisplayedValue = (type, value, name) => {
|
||||
};
|
||||
const date = moment().set(timeObj);
|
||||
|
||||
return date.format(DATE_FORMATS.time);
|
||||
return date.format(dateFormats.time);
|
||||
}
|
||||
default:
|
||||
return '-';
|
||||
|
||||
@ -63,7 +63,7 @@ function TableHeader({ headers, isBulkable }) {
|
||||
{header.label}
|
||||
|
||||
{sortBy === header.name && (
|
||||
<Arrow className={`${sortOrder === 'ASC' && 'isAsc'}`} />
|
||||
<Arrow fill="#212529" isUp={sortOrder === 'ASC' && 'isAsc'} />
|
||||
)}
|
||||
</span>
|
||||
</th>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import { Carret } from '@buffetjs/icons';
|
||||
|
||||
const Table = styled.table`
|
||||
border-radius: 3px;
|
||||
@ -94,21 +95,14 @@ const TableRow = styled.tr`
|
||||
}
|
||||
`;
|
||||
|
||||
const Arrow = styled.div`
|
||||
&:after {
|
||||
content: '\f0d8';
|
||||
font-family: 'FontAwesome';
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: -12px;
|
||||
}
|
||||
&.isAsc {
|
||||
&:after {
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
}
|
||||
const Arrow = styled(props => <Carret {...props} />)`
|
||||
margin-left: 5px;
|
||||
${({ isUp }) =>
|
||||
isUp &&
|
||||
`
|
||||
transform: rotateZ(180deg);
|
||||
|
||||
`}
|
||||
`;
|
||||
|
||||
const Truncate = styled.div``;
|
||||
|
||||
@ -4,13 +4,12 @@ import PropTypes from 'prop-types';
|
||||
import { capitalize, get } from 'lodash';
|
||||
import { Collapse } from 'reactstrap';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { PluginHeader } from 'strapi-helper-plugin';
|
||||
import { PluginHeader, getFilterType } from 'strapi-helper-plugin';
|
||||
|
||||
import pluginId from '../../pluginId';
|
||||
import useListView from '../../hooks/useListView';
|
||||
import Container from '../Container';
|
||||
|
||||
import getFilterType from '../FilterPickerOption/utils';
|
||||
import FilterPickerOption from '../FilterPickerOption';
|
||||
import { Flex, Span, Wrapper } from './components';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import getFilterType from '../FilterPickerOption/utils';
|
||||
import { getFilterType } from 'strapi-helper-plugin';
|
||||
|
||||
function init(initialState, { name, type }) {
|
||||
// Create the first filter
|
||||
|
||||
@ -40,7 +40,7 @@ const getInputType = attrType => {
|
||||
|
||||
function Input({ type, ...rest }) {
|
||||
const Component = getInputType(type);
|
||||
let style = type !== 'time' ? { width: '210px', paddingTop: '4px' } : {};
|
||||
let style = type !== 'time' ? { width: '210px' } : {};
|
||||
|
||||
if (['integer', 'biginteger', 'float', 'decimal'].includes(type)) {
|
||||
style = { marginRight: '20px' };
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import React, { memo } from 'react';
|
||||
import { get, isEmpty } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import { CircleButton } from 'strapi-helper-plugin';
|
||||
import { CircleButton, getFilterType } from 'strapi-helper-plugin';
|
||||
import { Select } from '@buffetjs/core';
|
||||
|
||||
import { InputWrapper, Wrapper } from './components';
|
||||
import Input from './Input';
|
||||
import Option from './Option';
|
||||
import getFilters from './utils';
|
||||
|
||||
const styles = {
|
||||
select: {
|
||||
@ -20,11 +19,6 @@ const styles = {
|
||||
marginLeft: '10px',
|
||||
marginRight: '10px',
|
||||
},
|
||||
input: {
|
||||
width: '210px',
|
||||
marginRight: '10px',
|
||||
paddingTop: '4px',
|
||||
},
|
||||
};
|
||||
|
||||
function FilterPickerOption({
|
||||
@ -38,7 +32,7 @@ function FilterPickerOption({
|
||||
showAddButton,
|
||||
type,
|
||||
}) {
|
||||
const filtersOptions = getFilters(type);
|
||||
const filtersOptions = getFilterType(type);
|
||||
|
||||
return (
|
||||
<Wrapper borderLeft={!isEmpty(value)}>
|
||||
|
||||
@ -1,109 +0,0 @@
|
||||
const getFilters = type => {
|
||||
switch (type) {
|
||||
case 'string':
|
||||
case 'text':
|
||||
case 'password':
|
||||
case 'email':
|
||||
return [
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES.=',
|
||||
value: '=',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._ne',
|
||||
value: '_ne',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._lt',
|
||||
value: '_lt',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._lte',
|
||||
value: '_lte',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._gt',
|
||||
value: '_gt',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._gte',
|
||||
value: '_gte',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._contains',
|
||||
value: '_contains',
|
||||
},
|
||||
{
|
||||
id:
|
||||
'content-manager.components.FilterOptions.FILTER_TYPES._containss',
|
||||
value: '_containss',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._in',
|
||||
value: '_in',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._nin',
|
||||
value: '_nin',
|
||||
},
|
||||
];
|
||||
case 'integer':
|
||||
case 'biginteger':
|
||||
case 'float':
|
||||
case 'decimal':
|
||||
case 'date':
|
||||
case 'datetime':
|
||||
case 'time':
|
||||
case 'timestamp':
|
||||
case 'timestampUpdate':
|
||||
return [
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES.=',
|
||||
value: '=',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._ne',
|
||||
value: '_ne',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._lt',
|
||||
value: '_lt',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._lte',
|
||||
value: '_lte',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._gt',
|
||||
value: '_gt',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._gte',
|
||||
value: '_gte',
|
||||
},
|
||||
// FIXME: commenting these filters as I am not sure if the UI
|
||||
// corresponds to the filter
|
||||
// {
|
||||
// id: 'content-manager.components.FilterOptions.FILTER_TYPES._in',
|
||||
// value: '_in',
|
||||
// },
|
||||
// {
|
||||
// id: 'content-manager.components.FilterOptions.FILTER_TYPES._nin',
|
||||
// value: '_nin',
|
||||
// },
|
||||
];
|
||||
default:
|
||||
return [
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES.=',
|
||||
value: '=',
|
||||
},
|
||||
{
|
||||
id: 'content-manager.components.FilterOptions.FILTER_TYPES._ne',
|
||||
value: '_ne',
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export default getFilters;
|
||||
@ -1,12 +1,11 @@
|
||||
import React, { forwardRef } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Grab } from '@buffetjs/icons';
|
||||
import { Carret, Grab } from '@buffetjs/icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import pluginId from '../../pluginId';
|
||||
import PreviewCarret from '../PreviewCarret';
|
||||
import BannerWrapper from './BannerWrapper';
|
||||
import CarretTop from './CarretTop';
|
||||
|
||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||
|
||||
@ -45,7 +44,7 @@ const Banner = forwardRef(
|
||||
{isDragging && <PreviewCarret isComponent />}
|
||||
<>
|
||||
<span className="img-wrapper" style={{ display }}>
|
||||
<CarretTop isOpen={isOpen} hasErrors={hasErrors} />
|
||||
<Carret isOpen={isOpen} hasErrors={hasErrors} />
|
||||
</span>
|
||||
|
||||
<FormattedMessage
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { get, toString, upperFirst } from 'lodash';
|
||||
import { get, toString } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import pluginId from '../../pluginId';
|
||||
import DATE_FORMATS from '../../utils/DATE_FORMATS';
|
||||
import { FilterWrapper, Remove, Separator } from './components';
|
||||
import { dateFormats, FilterButton } from 'strapi-helper-plugin';
|
||||
|
||||
function Filter({
|
||||
changeParams,
|
||||
@ -27,9 +24,9 @@ function Filter({
|
||||
let format;
|
||||
|
||||
if (type === 'date' || type === 'timestamp') {
|
||||
format = DATE_FORMATS.date;
|
||||
format = dateFormats.date;
|
||||
} else {
|
||||
format = DATE_FORMATS.datetime;
|
||||
format = dateFormats.datetime;
|
||||
}
|
||||
|
||||
displayedValue = moment
|
||||
@ -38,25 +35,25 @@ function Filter({
|
||||
.format(format);
|
||||
}
|
||||
|
||||
return (
|
||||
<FilterWrapper>
|
||||
<span>{upperFirst(name)} </span>
|
||||
<FormattedMessage
|
||||
id={`${pluginId}.components.FilterOptions.FILTER_TYPES.${filter}`}
|
||||
/>
|
||||
<span> {displayedValue}</span>
|
||||
<Separator />
|
||||
<Remove
|
||||
onClick={() => {
|
||||
const updatedFilters = filters.slice().filter((_, i) => i !== index);
|
||||
const label = {
|
||||
name,
|
||||
filter,
|
||||
value: displayedValue,
|
||||
};
|
||||
|
||||
if (isFilterPickerOpen) {
|
||||
toggleFilterPickerState();
|
||||
}
|
||||
changeParams({ target: { name: 'filters', value: updatedFilters } });
|
||||
}}
|
||||
/>
|
||||
</FilterWrapper>
|
||||
return (
|
||||
<FilterButton
|
||||
onClick={() => {
|
||||
const updatedFilters = filters.slice().filter((_, i) => i !== index);
|
||||
|
||||
if (isFilterPickerOpen) {
|
||||
toggleFilterPickerState();
|
||||
}
|
||||
changeParams({ target: { name: 'filters', value: updatedFilters } });
|
||||
}}
|
||||
label={label}
|
||||
type={type}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.DraggableAttr.edit": "اضغط لتعديل",
|
||||
"components.EmptyAttributesBlock.button": "الذهاب الى صفحة الإعدادات",
|
||||
"components.EmptyAttributesBlock.description": "يمكنك تغيير إعداداتك",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "هو",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "يحتوي",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "يحتوي (حساس لحالة الأحرف)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "اكبر من",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "اكبر من او يساوي",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "اقل من",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "اقل من او يساوي",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "ليس",
|
||||
"components.FilterOptions.button.apply": "تطبيق",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "تطبيق",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "مسح الكل",
|
||||
|
||||
@ -14,16 +14,6 @@
|
||||
"components.EmptyAttributesBlock.button": "Přejít k nastavení",
|
||||
"components.EmptyAttributesBlock.description": "Můžete upravit svá nastavení",
|
||||
"components.FieldItem.linkToComponentLayout": "Nastavit rozložení komponentu",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "je",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "obsahuje",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "obsahuje (citlivé na velká písmena)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "je větší než",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "je větší nebo rovno než",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "je menší než",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "je menší nebo rovno než",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "není",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "odpovídá jakékoliv hodnotě v poli hodnot",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "neodpovídá ani jedné hodnotě v poli hodnot",
|
||||
"components.FilterOptions.button.apply": "Aplikovat",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Aplikovat",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Smazat vše",
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.DraggableAttr.edit": "Klicken zum Bearbeiten",
|
||||
"components.EmptyAttributesBlock.button": "Geh zu den Einstellungen",
|
||||
"components.EmptyAttributesBlock.description": "Du kannst deine Einstellungen ändern",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "ist",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "enthält",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "enthält (Groß-/Kleinschreibung beachten)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "ist größer als",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "ist größer oder gleich als",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "ist kleiner als",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "ist kleiner oder gleich als",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "ist nicht",
|
||||
"components.FilterOptions.button.apply": "Anwenden",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Anwenden",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Alle löschen",
|
||||
|
||||
@ -14,16 +14,6 @@
|
||||
"components.EmptyAttributesBlock.button": "Go to settings page",
|
||||
"components.EmptyAttributesBlock.description": "You can change your settings",
|
||||
"components.FieldItem.linkToComponentLayout": "Set the component's layout",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "is",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contains",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contains (case sensitive)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "is greater than",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "is greater than or equal to",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "is lower than",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "is lower than or equal to",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "is not",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "matches any value in the array of values",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "doesn't match any value in the array of values",
|
||||
"components.FilterOptions.button.apply": "Apply",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Apply",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Clear all",
|
||||
|
||||
@ -5,16 +5,6 @@
|
||||
"components.DraggableAttr.edit": "Click para editar",
|
||||
"components.EmptyAttributesBlock.button": "Ir a la página de configuraciones",
|
||||
"components.EmptyAttributesBlock.description": "Usted puede cambiar sus configuraciones",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "es",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contiene",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contiene (distinguiendo mayúsculas y minúsculas)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "es mayor que",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "es mayor o igual que",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "es menor que",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "es menor o igual que",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "no es",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "coincide con cualquier valor de la lista de registros",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "no coincide con ningún valor de la lista de registros",
|
||||
"components.FilterOptions.button.apply": "Aplicar",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Aplicar",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Limpiar todo",
|
||||
|
||||
@ -14,14 +14,6 @@
|
||||
"components.EmptyAttributesBlock.button": "Voir la page des configurations",
|
||||
"components.EmptyAttributesBlock.description": "Vous pouvez modifiez vos paramètres",
|
||||
"components.FieldItem.linkToComponentLayout": "Modifier le layout du composant",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "est",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contient",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contient (sensible à la casse)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "supérieur à",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "supérieur ou égal à",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "inférieur à",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "inférieur ou égal à",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "n'est pas",
|
||||
"components.FilterOptions.button.apply": "Appliquer",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Appliquer",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Tout supprimer",
|
||||
|
||||
@ -4,15 +4,7 @@
|
||||
"components.AddFilterCTA.hide": "Filtri",
|
||||
"components.DraggableAttr.edit": "Clicca per modificare",
|
||||
"components.EmptyAttributesBlock.button": "Vai alla pagina delle impostazioni",
|
||||
"components.EmptyAttributesBlock.description" : "Puoi cambiare le tue impostazioni",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "si",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contiene",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contiene (maiuscole e minuscole)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "è maggiore di",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "è maggiore o uguale a",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "è inferiore",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "è inferiore o uguale a",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "non è",
|
||||
"components.EmptyAttributesBlock.description": "Puoi cambiare le tue impostazioni",
|
||||
"components.FilterOptions.button.apply": "Applica",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Applica",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Cancella tutto",
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.DraggableAttr.edit": "クリックして編集",
|
||||
"components.EmptyAttributesBlock.button": "設定ページに移動",
|
||||
"components.EmptyAttributesBlock.description": "設定を変更することができます",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "は",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "含まれる",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "含まれる(大文字と小文字を区別)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "より大きい",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "より大きい、もしくは、等しい",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "より低い",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "より低い、もしくは、等しい",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "ではない",
|
||||
"components.FilterOptions.button.apply": "適用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "適用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "すべてクリア",
|
||||
|
||||
@ -10,16 +10,6 @@
|
||||
"components.EmptyAttributesBlock.button": "설정 페이지 이동",
|
||||
"components.EmptyAttributesBlock.description": "설정을 변경할 수 있습니다.",
|
||||
"components.FieldItem.linkToGroupLayout": "그룹 레이아웃 설정",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "같음",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "포함",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "포함(대소문자 구분)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "큼",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "크거나 같음",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "작음",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "작거나 같음",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "같지 않음",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "배열중에 일치하는 값이 있음",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "배열중에 일치하는 값이 없음",
|
||||
"components.FilterOptions.button.apply": "적용",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "적용",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "모두 재설정",
|
||||
@ -139,4 +129,4 @@
|
||||
"success.record.save": "저장",
|
||||
"notification.info.minimumFields": "표시될 필드가 최소 하나 이상 필요합니다.",
|
||||
"notification.upload.error": "파일 업로드 중에 에러가 발생했습니다."
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.DraggableAttr.edit": "Klik om aan te passen",
|
||||
"components.EmptyAttributesBlock.button": "Ga naar instellingen",
|
||||
"components.EmptyAttributesBlock.description": "U kunt uw instellingen aanpassen",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "is",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "bevat",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "bevat (hoofdletter gevoelig)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "is groter dan",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "is groter dan of gelijk aan",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "is lager dan",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "is lager dan of gelijk aan",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "is niet",
|
||||
"components.FilterOptions.button.apply": "Toepassen",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Toepassen",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Alles legen",
|
||||
|
||||
@ -11,16 +11,6 @@
|
||||
"components.EmptyAttributesBlock.button": "Przejdź do ustawień",
|
||||
"components.EmptyAttributesBlock.description": "Możesz zmienić ustawienia",
|
||||
"components.FieldItem.linkToComponentLayout": "Ustaw układ komponentu",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "jest identyczne z",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "zawiera",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "zawiera (rozróżnianie wielkości liter)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "jest większe od",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "jest większe od lub równe",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "dopasuj jakąkolwiek wartość z tablicy wartości",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "jest mniejsze od",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "jest mniejsze od lub równe",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "jest różne od",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "nie znaleziono pasującej wartości w tablicy wartości",
|
||||
"components.FilterOptions.button.apply": "Zastosuj",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Zastosuj",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Wyczyść",
|
||||
@ -74,7 +64,7 @@
|
||||
"containers.SettingPage.listSettings.title": "Lista (ustawienia)",
|
||||
"containers.SettingPage.editSettings.entry.title": "Tytuł wpisu",
|
||||
"containers.SettingPage.editSettings.entry.title.description": "Ustaw wyświetlane pole swojego wpisu",
|
||||
"containers.SettingsPage.Block.generalSettings.title": "Ogólne",
|
||||
"containers.SettingsPage.Block.generalSettings.title": "Ogólne",
|
||||
"containers.SettingPage.layout": "Układ",
|
||||
"containers.SettingPage.addField": "Dodaj nowy atrybut",
|
||||
"containers.SettingPage.editSettings.description": "Przeciągnij i upuś pola by zbudować układ",
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.DraggableAttr.edit": "Clique para editar",
|
||||
"components.EmptyAttributesBlock.button": "Ir para página de configurações",
|
||||
"components.EmptyAttributesBlock.description": "Você pode alterar suas configurações",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "é",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contém",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contém (case sensitive)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "é maior que",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "é maior que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "é menor que",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "é menor que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "não é",
|
||||
"components.FilterOptions.button.apply": "Aplicar",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Aplicar",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Limpar tudo",
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.EmptyAttributesBlock.button": "Ir para a página de configurações",
|
||||
"components.EmptyAttributesBlock.description": "Pode alterar as configurações",
|
||||
"components.FilterOptions.button.apply": "Aplicar",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "é",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "contém",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "contém (case sensitive)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "é maior que",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "é maior que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "é menor que",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "é menor que ou igual à",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "não é",
|
||||
"components.FiltersPickWrapper.hide": "Esconder",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Aplicar",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Limpar tudo",
|
||||
|
||||
@ -8,14 +8,6 @@
|
||||
"containers.Edit.addAnItem": "Добавить элемент",
|
||||
"containers.Edit.clickToJump": "Нажмите для перехода к записи",
|
||||
"containers.Edit.seeDetails": "Подробнее",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "равно",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "содержит",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "содержит (с учетом регистра)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "больше чем",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "больше или равно",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "меньше чем",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "меньше или равно",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "не равно",
|
||||
"components.FilterOptions.button.apply": "Применить",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Применить",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Очистить все",
|
||||
|
||||
@ -14,16 +14,6 @@
|
||||
"components.EmptyAttributesBlock.button": "Prejsť do nastavení",
|
||||
"components.EmptyAttributesBlock.description": "Môžte upravovať nastavenia",
|
||||
"components.FieldItem.linkToComponentLayout": "Nastaviť rozloženie komponenty",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "je",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "obsahuje",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "obsahuje (záleží na veľkosti písmen)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "je väčšie ako",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "je väčšie ako alebo rovné",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "je menšie ako",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "je menšie ako alebo rovné",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "nie je",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "obsahuje hodnotu z poľa",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "neobsahuje žiadnu hodnotu z poľa",
|
||||
"components.FilterOptions.button.apply": "Použiť",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Použiť",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Zmazať všetko",
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.DraggableAttr.edit": "Düzenlemek için tıklayın",
|
||||
"components.EmptyAttributesBlock.button": "Ayarlar sayfasına git",
|
||||
"components.EmptyAttributesBlock.description": "Ayarlarınızı değiştirebilirsiniz",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "eşit",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "içermek",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "içermek (büyük-küçük harfe duyarlı)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "daha yüksek",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "daha yüksek ya da eşit",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "daha düşük",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "daha düşük ya da eşit",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "eşit değil",
|
||||
"components.FilterOptions.button.apply": "Uygula",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Uygula",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Hepsini temizle",
|
||||
|
||||
@ -10,16 +10,6 @@
|
||||
"components.EmptyAttributesBlock.button": "Đến trang cài đặt",
|
||||
"components.EmptyAttributesBlock.description": "Bạn có thể thay đổi cài đặt của bạn",
|
||||
"components.FieldItem.linkToGroupLayout": "Cài đặt bố cục của nhóm",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "là",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "chứa",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "chứa (phân biệt chữ hoa thường)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "lớn hơn",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "lớn hơn hoặc bằng",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "nhỏ hơn",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "nhỏ hơn hoặc bằng",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "không bằng",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "khớp với bất cứ giá trị nào có trong mảng giá trị",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "không khớp với bất cứ giá trị nào có trong mảng giá trị",
|
||||
"components.FilterOptions.button.apply": "Áp dụng",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "Áp dụng",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "Xóa tất cả",
|
||||
|
||||
@ -14,16 +14,6 @@
|
||||
"components.EmptyAttributesBlock.button": "前往设置页面",
|
||||
"components.EmptyAttributesBlock.description": "您可以更改设置",
|
||||
"components.FieldItem.linkToComponentLayout": "设置组件的布局",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "等于",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "包含",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "包含(区分大小写)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "大于",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "大于等于",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "小于",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "小于等于",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "不等于",
|
||||
"components.FilterOptions.FILTER_TYPES._in": "包含在指定数组中",
|
||||
"components.FilterOptions.FILTER_TYPES._nin": "不包含在指定数组中",
|
||||
"components.FilterOptions.button.apply": "应用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "应用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "清除",
|
||||
|
||||
@ -5,14 +5,6 @@
|
||||
"components.DraggableAttr.edit": "點擊以編輯",
|
||||
"components.EmptyAttributesBlock.button": "前往設定頁面",
|
||||
"components.EmptyAttributesBlock.description": "您可以變更設定",
|
||||
"components.FilterOptions.FILTER_TYPES.=": "等於",
|
||||
"components.FilterOptions.FILTER_TYPES._contains": "包含",
|
||||
"components.FilterOptions.FILTER_TYPES._containss": "包含(區分大小寫)",
|
||||
"components.FilterOptions.FILTER_TYPES._gt": "大於",
|
||||
"components.FilterOptions.FILTER_TYPES._gte": "大於等於",
|
||||
"components.FilterOptions.FILTER_TYPES._lt": "小於",
|
||||
"components.FilterOptions.FILTER_TYPES._lte": "小於等於",
|
||||
"components.FilterOptions.FILTER_TYPES._ne": "不等於",
|
||||
"components.FilterOptions.button.apply": "套用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.apply": "套用",
|
||||
"components.FiltersPickWrapper.PluginHeader.actions.clearAll": "清除",
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.button`
|
||||
display: flex;
|
||||
height: 32px;
|
||||
margin-right: 10px;
|
||||
padding: 0 10px;
|
||||
text-align: center;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #E3E9F3;
|
||||
border-radius: 2px;
|
||||
line-height: 30px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
font-family: Lato;
|
||||
-webkit-font-smoothing-antialiased;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: #F7F8F8;
|
||||
}
|
||||
&:focus, &:active {
|
||||
outline:0;
|
||||
}
|
||||
> span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
> svg {
|
||||
margin: auto;
|
||||
> g {
|
||||
stroke: #282b2c;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@ -1,15 +0,0 @@
|
||||
import React from 'react';
|
||||
import { FilterIcon } from 'strapi-helper-plugin';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
const AddFilterCTA = () => {
|
||||
return (
|
||||
<Wrapper type="button">
|
||||
<FilterIcon />
|
||||
<FormattedMessage id="app.utils.filters" />
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddFilterCTA;
|
||||
@ -2,8 +2,11 @@ import styled from 'styled-components';
|
||||
|
||||
const ControlsWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 1px;
|
||||
> div {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import { themePropTypes } from 'strapi-helper-plugin';
|
||||
|
||||
import Text from '../Text';
|
||||
|
||||
const SortButton = styled(props => (
|
||||
const DropdownButton = styled(props => (
|
||||
<Text
|
||||
as="button"
|
||||
fontWeight="semiBold"
|
||||
@ -13,9 +13,10 @@ const SortButton = styled(props => (
|
||||
{...props}
|
||||
/>
|
||||
))`
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
padding: 0 10px;
|
||||
line-height: 30px;
|
||||
background-color: ${({ theme }) => theme.main.colors.white};
|
||||
border: 1px solid ${({ theme }) => theme.main.colors.darkGrey};
|
||||
border-radius: ${({ theme }) => theme.main.sizes.borderRadius};
|
||||
@ -24,26 +25,40 @@ const SortButton = styled(props => (
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
> svg + span,
|
||||
> span + svg {
|
||||
margin-left: 10px;
|
||||
}
|
||||
> svg g {
|
||||
stroke: ${({ theme }) => theme.main.colors.greyDark};
|
||||
}
|
||||
|
||||
${({ isActive, theme }) =>
|
||||
isActive
|
||||
? `
|
||||
background-color: ${theme.main.colors.lightBlue};
|
||||
border: 1px solid ${theme.main.colors.darkBlue};
|
||||
`
|
||||
background-color: ${theme.main.colors.lightBlue};
|
||||
border: 1px solid ${theme.main.colors.darkBlue};
|
||||
color: ${theme.main.colors.mediumBlue};
|
||||
> svg g {
|
||||
stroke: ${theme.main.colors.mediumBlue};
|
||||
}
|
||||
`
|
||||
: `
|
||||
&:hover {
|
||||
background-color: ${theme.main.colors.lightestGrey};
|
||||
}
|
||||
`}
|
||||
&:hover {
|
||||
background-color: ${theme.main.colors.lightestGrey};
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
SortButton.defaultProps = {
|
||||
DropdownButton.defaultProps = {
|
||||
isActive: false,
|
||||
type: 'button',
|
||||
};
|
||||
|
||||
SortButton.propTypes = {
|
||||
DropdownButton.propTypes = {
|
||||
isActive: PropTypes.bool,
|
||||
type: PropTypes.string,
|
||||
...themePropTypes,
|
||||
};
|
||||
|
||||
export default SortButton;
|
||||
export default DropdownButton;
|
||||
@ -0,0 +1,26 @@
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import { themePropTypes } from 'strapi-helper-plugin';
|
||||
|
||||
const DropdownSection = styled.div`
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 38px;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
background-color: ${({ theme }) => theme.main.colors.white};
|
||||
border: 1px solid ${({ theme }) => theme.main.colors.darkGrey};
|
||||
box-shadow: 0 2px 4px ${({ theme }) => theme.main.colors.greyAlpha};
|
||||
${({ isOpen }) => isOpen && 'display: block;'}
|
||||
`;
|
||||
|
||||
DropdownSection.defaultProps = {
|
||||
isOpen: false,
|
||||
};
|
||||
|
||||
DropdownSection.propTypes = {
|
||||
isOpen: PropTypes.bool,
|
||||
...themePropTypes,
|
||||
};
|
||||
|
||||
export default DropdownSection;
|
||||
@ -0,0 +1,37 @@
|
||||
/**
|
||||
*
|
||||
* InputWithAutoFocus that programatically manage the autofocus of another one
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { DateTime } from '@buffetjs/custom';
|
||||
import { InputText, Select } from '@buffetjs/core';
|
||||
|
||||
import SizeInput from '../SizeInput';
|
||||
|
||||
const getInputType = type => {
|
||||
switch (type) {
|
||||
case 'datetime':
|
||||
return DateTime;
|
||||
case 'size':
|
||||
return SizeInput;
|
||||
case 'enum':
|
||||
return Select;
|
||||
default:
|
||||
return InputText;
|
||||
}
|
||||
};
|
||||
|
||||
function Input({ type, ...rest }) {
|
||||
const Component = getInputType(type);
|
||||
|
||||
return <Component {...rest} autoComplete="off" />;
|
||||
}
|
||||
|
||||
Input.propTypes = {
|
||||
type: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Input;
|
||||
@ -0,0 +1,8 @@
|
||||
import styled from 'styled-components';
|
||||
import { Button } from '@buffetjs/core';
|
||||
|
||||
const InputWrapper = styled(Button)`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export default InputWrapper;
|
||||
@ -0,0 +1,7 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const InputWrapper = styled.div`
|
||||
margin-bottom: 11px;
|
||||
`;
|
||||
|
||||
export default InputWrapper;
|
||||
@ -0,0 +1,8 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
width: 260px;
|
||||
padding: 13px 15px;
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@ -0,0 +1,102 @@
|
||||
import React, { useReducer } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Select } from '@buffetjs/core';
|
||||
import { getFilterType } from 'strapi-helper-plugin';
|
||||
import getTrad from '../../utils/getTrad';
|
||||
|
||||
import reducer, { initialState } from './reducer';
|
||||
|
||||
import Wrapper from './Wrapper';
|
||||
import Button from './Button';
|
||||
import InputWrapper from './InputWrapper';
|
||||
|
||||
import Input from '../FilterInput';
|
||||
|
||||
const FiltersCard = ({ filters, onChange }) => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const name = state.get('name');
|
||||
const type = filters[name].type;
|
||||
|
||||
const defaultValue = filters[name].defaultValue;
|
||||
|
||||
const filtersOptions = getFilterType(type);
|
||||
|
||||
const handleChange = ({ target: { name, value } }) => {
|
||||
dispatch({
|
||||
type: 'ON_CHANGE',
|
||||
name,
|
||||
value,
|
||||
});
|
||||
};
|
||||
|
||||
const addFilter = () => {
|
||||
onChange({ target: { value: state.toJS() } });
|
||||
|
||||
dispatch({
|
||||
type: 'RESET_FORM',
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<InputWrapper>
|
||||
<Select
|
||||
onChange={e => {
|
||||
// Change the attribute
|
||||
handleChange(e);
|
||||
// Change other inputs so it reset values
|
||||
const {
|
||||
target: { value },
|
||||
} = e;
|
||||
handleChange({ target: { name: 'filter', value: '=' } });
|
||||
handleChange({
|
||||
target: { name: 'value', value: filters[value].defaultValue },
|
||||
});
|
||||
}}
|
||||
name="name"
|
||||
options={Object.keys(filters)}
|
||||
value={name}
|
||||
/>
|
||||
</InputWrapper>
|
||||
<InputWrapper>
|
||||
<Select
|
||||
onChange={handleChange}
|
||||
name="filter"
|
||||
options={filtersOptions.map(({ id, value }) => (
|
||||
<FormattedMessage id={id} key={id}>
|
||||
{msg => <option value={value}>{msg}</option>}
|
||||
</FormattedMessage>
|
||||
))}
|
||||
value={state.get('filter')}
|
||||
/>
|
||||
</InputWrapper>
|
||||
<InputWrapper>
|
||||
<Input
|
||||
type={type}
|
||||
onChange={handleChange}
|
||||
name="value"
|
||||
options={['image', 'video', 'files']}
|
||||
value={state.get('value') || defaultValue}
|
||||
/>
|
||||
</InputWrapper>
|
||||
<Button icon onClick={addFilter}>
|
||||
<FormattedMessage id={getTrad('filter.add')} />
|
||||
</Button>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
FiltersCard.defaultProps = {
|
||||
filters: {},
|
||||
onChange: () => {},
|
||||
};
|
||||
|
||||
FiltersCard.propTypes = {
|
||||
filters: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
export default FiltersCard;
|
||||
@ -0,0 +1,22 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import moment from 'moment';
|
||||
|
||||
const initialState = fromJS({
|
||||
name: 'created_at',
|
||||
filter: '=',
|
||||
value: moment(),
|
||||
});
|
||||
|
||||
function reducer(state, action) {
|
||||
switch (action.type) {
|
||||
case 'ON_CHANGE':
|
||||
return state.update(action.name, () => action.value);
|
||||
case 'RESET_FORM':
|
||||
return initialState;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default reducer;
|
||||
export { initialState };
|
||||
@ -0,0 +1,28 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const FiltersListItem = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 32px;
|
||||
margin-bottom: 4px;
|
||||
background: rgba(0, 126, 255, 0.08);
|
||||
border: 1px solid rgba(0, 126, 255, 0.24);
|
||||
border-radius: 2px;
|
||||
color: #007eff;
|
||||
font-size: 13px;
|
||||
span {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
line-height: 30px;
|
||||
}
|
||||
button {
|
||||
display: flex;
|
||||
justify-items: center;
|
||||
height: 13px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border-left: 2px solid rgba(0, 126, 255, 0.1);
|
||||
}
|
||||
`;
|
||||
|
||||
export default FiltersListItem;
|
||||
@ -0,0 +1,47 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
|
||||
import { dateFormats, FilterButton } from 'strapi-helper-plugin';
|
||||
|
||||
const FiltersList = ({ filters, onClick }) => {
|
||||
return filters.map((filter, index) => {
|
||||
const dateToUtcTime = date => moment.parseZone(date).utc();
|
||||
const { value } = filter;
|
||||
|
||||
let displayedValue = filter;
|
||||
|
||||
if (dateToUtcTime(value)._isUTC === true) {
|
||||
displayedValue = {
|
||||
...filter,
|
||||
value: dateToUtcTime(value).format(dateFormats.datetime),
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<FilterButton
|
||||
onClick={() => onClick(index)}
|
||||
key={JSON.stringify(filter)}
|
||||
label={displayedValue}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
FiltersList.defaultProps = {
|
||||
filters: [],
|
||||
onClick: () => {},
|
||||
};
|
||||
|
||||
FiltersList.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
filters: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
filter: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
export default FiltersList;
|
||||
@ -0,0 +1,7 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@ -0,0 +1,63 @@
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import moment from 'moment';
|
||||
import { isObject } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { FilterIcon } from 'strapi-helper-plugin';
|
||||
|
||||
import DropdownButton from '../DropdownButton';
|
||||
import DropdownSection from '../DropdownSection';
|
||||
|
||||
import Wrapper from './Wrapper';
|
||||
import FiltersCard from '../FiltersCard';
|
||||
|
||||
const FiltersPicker = ({ filters, onChange }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const handleChange = ({ target: { value } }) => {
|
||||
if (value.value) {
|
||||
let formattedValue = value;
|
||||
|
||||
if (value.value._isAMomentObject === true) {
|
||||
formattedValue.value = moment(
|
||||
value.value,
|
||||
'YYYY-MM-DD HH:mm:ss'
|
||||
).format();
|
||||
} else if (isObject(value)) {
|
||||
formattedValue.value = Object.values(value.value).join('');
|
||||
}
|
||||
|
||||
onChange({ target: { value: formattedValue } });
|
||||
}
|
||||
|
||||
hangleToggle();
|
||||
};
|
||||
|
||||
const hangleToggle = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<DropdownButton onClick={hangleToggle} isActive={isOpen}>
|
||||
<FilterIcon />
|
||||
<FormattedMessage id="app.utils.filters" />
|
||||
</DropdownButton>
|
||||
<DropdownSection isOpen={isOpen}>
|
||||
<FiltersCard onChange={handleChange} filters={filters} />
|
||||
</DropdownSection>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
FiltersPicker.defaultProps = {
|
||||
filters: {},
|
||||
onChange: () => {},
|
||||
};
|
||||
|
||||
FiltersPicker.propTypes = {
|
||||
filters: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
export default FiltersPicker;
|
||||
@ -2,7 +2,7 @@ import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: relative;
|
||||
margin-top: 25px;
|
||||
margin-top: 19px;
|
||||
padding: 0;
|
||||
|
||||
.btn-wrapper {
|
||||
|
||||
@ -3,7 +3,7 @@ import styled from 'styled-components';
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 32px;
|
||||
height: 30px;
|
||||
width: 35px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e3e9f3;
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
.col-6:last-of-type {
|
||||
padding-left: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@ -0,0 +1,79 @@
|
||||
/**
|
||||
*
|
||||
* SizeInput
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { InputNumber, Select } from '@buffetjs/core';
|
||||
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
function SizeInput({ onChange, value, ...rest }) {
|
||||
const options = ['KB', 'MB', 'GB'];
|
||||
const [size, setSize] = useState(0);
|
||||
const [format, setFormat] = useState('KB');
|
||||
|
||||
const handleChangeValue = ({ target: { value } }) => {
|
||||
setSize(value);
|
||||
|
||||
handleChange();
|
||||
};
|
||||
|
||||
const handleChangeFormat = ({ target: { value } }) => {
|
||||
setFormat(value);
|
||||
|
||||
handleChange();
|
||||
};
|
||||
|
||||
const handleChange = () => {
|
||||
onChange({
|
||||
target: {
|
||||
name: 'value',
|
||||
value: {
|
||||
size,
|
||||
format,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<div className="row">
|
||||
<div className="col-6">
|
||||
<InputNumber
|
||||
{...rest}
|
||||
name="size_value"
|
||||
onChange={handleChangeValue}
|
||||
value={value.size}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<Select
|
||||
name="format_value"
|
||||
onChange={handleChangeFormat}
|
||||
options={options}
|
||||
value={value.format}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
SizeInput.defaultProps = {
|
||||
onChange: () => {},
|
||||
value: {},
|
||||
};
|
||||
|
||||
SizeInput.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
value: PropTypes.shape({
|
||||
size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
format: PropTypes.string,
|
||||
}),
|
||||
};
|
||||
|
||||
export default SizeInput;
|
||||
@ -1,30 +1,18 @@
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import { themePropTypes } from 'strapi-helper-plugin';
|
||||
|
||||
const Wrapper = styled.ul`
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 38px;
|
||||
left: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
min-width: 230px;
|
||||
z-index: 1;
|
||||
list-style-type: none;
|
||||
font-size: ${({ theme }) => theme.main.fontSizes.md};
|
||||
background-color: ${({ theme }) => theme.main.colors.white};
|
||||
border: 1px solid ${({ theme }) => theme.main.colors.darkGrey};
|
||||
box-shadow: 0 2px 4px ${({ theme }) => theme.main.colors.greyAlpha};
|
||||
${({ isShown }) => isShown && 'display: block;'}
|
||||
`;
|
||||
|
||||
Wrapper.defaultProps = {
|
||||
isShown: false,
|
||||
};
|
||||
|
||||
Wrapper.propTypes = {
|
||||
isShown: PropTypes.bool,
|
||||
...themePropTypes,
|
||||
};
|
||||
|
||||
|
||||
@ -4,9 +4,9 @@ import PropTypes from 'prop-types';
|
||||
import Wrapper from './Wrapper';
|
||||
import SortListItem from '../SortListItem';
|
||||
|
||||
const SortList = ({ isShown, list, onClick, selectedItem }) => {
|
||||
const SortList = ({ list, onClick, selectedItem }) => {
|
||||
return (
|
||||
<Wrapper isShown={isShown}>
|
||||
<Wrapper>
|
||||
{Object.keys(list).map(item => {
|
||||
return (
|
||||
<SortListItem
|
||||
@ -24,14 +24,12 @@ const SortList = ({ isShown, list, onClick, selectedItem }) => {
|
||||
|
||||
SortList.defaultProps = {
|
||||
list: {},
|
||||
isShown: false,
|
||||
onClick: () => {},
|
||||
selectedItem: null,
|
||||
};
|
||||
|
||||
SortList.propTypes = {
|
||||
list: PropTypes.object,
|
||||
isShown: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
selectedItem: PropTypes.string,
|
||||
};
|
||||
|
||||
@ -2,11 +2,13 @@ import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Carret } from '@buffetjs/icons';
|
||||
import getTrad from '../../utils/getTrad';
|
||||
|
||||
import Wrapper from './Wrapper';
|
||||
import SortButton from './SortButton';
|
||||
import DropdownButton from '../DropdownButton';
|
||||
import DropdownSection from '../DropdownSection';
|
||||
import SortList from '../SortList';
|
||||
import Wrapper from './Wrapper';
|
||||
|
||||
const SortPicker = ({ onChange, value }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
@ -32,15 +34,18 @@ const SortPicker = ({ onChange, value }) => {
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<SortButton onClick={hangleToggle} isActive={isOpen}>
|
||||
<DropdownButton onClick={hangleToggle} isActive={isOpen}>
|
||||
<FormattedMessage id={getTrad('sort.label')} />
|
||||
</SortButton>
|
||||
<SortList
|
||||
isShown={isOpen}
|
||||
list={orders}
|
||||
selectedItem={value}
|
||||
onClick={handleChange}
|
||||
/>
|
||||
<Carret fill={isOpen ? '#007EFF' : '#292b2c'} />
|
||||
</DropdownButton>
|
||||
<DropdownSection isOpen={isOpen}>
|
||||
<SortList
|
||||
isShown={isOpen}
|
||||
list={orders}
|
||||
selectedItem={value}
|
||||
onClick={handleChange}
|
||||
/>
|
||||
</DropdownSection>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import React, { useReducer, useState, useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { includes } from 'lodash';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { Header } from '@buffetjs/custom';
|
||||
import {
|
||||
HeaderSearch,
|
||||
PageFooter,
|
||||
useGlobalContext,
|
||||
generateFiltersFromSearch,
|
||||
useQuery,
|
||||
generateSearchFromFilters,
|
||||
} from 'strapi-helper-plugin';
|
||||
@ -12,22 +15,30 @@ import Container from '../../components/Container';
|
||||
import ControlsWrapper from '../../components/ControlsWrapper';
|
||||
import SelectAll from '../../components/SelectAll';
|
||||
import SortPicker from '../../components/SortPicker';
|
||||
import FiltersPicker from '../../components/FiltersPicker';
|
||||
import FiltersList from '../../components/FiltersList';
|
||||
// import List from '../../components/List';
|
||||
import ListEmpty from '../../components/ListEmpty';
|
||||
import ModalStepper from '../ModalStepper';
|
||||
import getHeaderLabel from './utils/getHeaderLabel';
|
||||
import {
|
||||
filtersForm,
|
||||
generatePageFromStart,
|
||||
generateStartFromPage,
|
||||
getHeaderLabel,
|
||||
} from './utils';
|
||||
import init from './init';
|
||||
import reducer, { initialState } from './reducer';
|
||||
import AddFilterCTA from '../../components/AddFilterCTA';
|
||||
|
||||
const HomePage = () => {
|
||||
const { formatMessage } = useGlobalContext();
|
||||
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const { push } = useHistory();
|
||||
const { search } = useLocation();
|
||||
const query = useQuery();
|
||||
const { data, dataToDelete } = reducerState.toJS();
|
||||
const pluginName = formatMessage({ id: getTrad('plugin.name') });
|
||||
const paramsKeys = ['_limit', '_page', '_q', '_sort'];
|
||||
|
||||
useEffect(() => {
|
||||
// TODO - Retrieve data
|
||||
@ -40,7 +51,9 @@ const HomePage = () => {
|
||||
const getSearchParams = () => {
|
||||
const params = {};
|
||||
query.forEach((value, key) => {
|
||||
params[key] = value;
|
||||
if (includes(paramsKeys, key)) {
|
||||
params[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
return params;
|
||||
@ -53,6 +66,38 @@ const HomePage = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const handleChangeFilters = ({ target: { value } }) => {
|
||||
if (value) {
|
||||
// Add filter
|
||||
const updatedFilters = generateFiltersFromSearch(search);
|
||||
updatedFilters.push(value);
|
||||
|
||||
handleChangeParams({
|
||||
target: { name: 'filters', value: updatedFilters },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteFilter = index => {
|
||||
// Remove filter
|
||||
const updatedFilters = generateFiltersFromSearch(search);
|
||||
updatedFilters.splice(index, 1);
|
||||
|
||||
handleChangeParams({
|
||||
target: { name: 'filters', value: updatedFilters },
|
||||
});
|
||||
};
|
||||
|
||||
const handleChangeListParams = ({ target: { name, value } }) => {
|
||||
if (name.includes('_page')) {
|
||||
handleChangeParams({
|
||||
target: { name: '_start', value: generateStartFromPage(value, limit) },
|
||||
});
|
||||
} else {
|
||||
handleChangeParams({ target: { name: '_limit', value } });
|
||||
}
|
||||
};
|
||||
|
||||
const getQueryValue = key => {
|
||||
const queryParams = getSearchParams();
|
||||
|
||||
@ -104,6 +149,14 @@ const HomePage = () => {
|
||||
],
|
||||
};
|
||||
|
||||
const limit = parseInt(getQueryValue('_limit'), 10) || 10;
|
||||
const start = parseInt(getQueryValue('_start'), 10) || 0;
|
||||
|
||||
const params = {
|
||||
_limit: parseInt(getQueryValue('_limit'), 10) || 10,
|
||||
_page: generatePageFromStart(start, limit),
|
||||
};
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Header {...headerProps} />
|
||||
@ -122,10 +175,21 @@ const HomePage = () => {
|
||||
onChange={handleChangeParams}
|
||||
value={getQueryValue('_sort') || null}
|
||||
/>
|
||||
<AddFilterCTA />
|
||||
<FiltersPicker onChange={handleChangeFilters} filters={filtersForm} />
|
||||
<FiltersList
|
||||
filters={generateFiltersFromSearch(search)}
|
||||
onClick={handleDeleteFilter}
|
||||
/>
|
||||
</ControlsWrapper>
|
||||
<ListEmpty onClick={handleClickToggleModal} />
|
||||
{/* <List data={data} /> */}
|
||||
|
||||
<PageFooter
|
||||
count={50}
|
||||
context={{ emitEvent: () => {} }}
|
||||
onChangeParams={handleChangeListParams}
|
||||
params={params}
|
||||
/>
|
||||
<ModalStepper isOpen={isOpen} onToggle={handleClickToggleModal} />
|
||||
</Container>
|
||||
);
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import moment from 'moment';
|
||||
|
||||
const filtersForm = {
|
||||
created_at: {
|
||||
type: 'datetime',
|
||||
defaultValue: moment(),
|
||||
},
|
||||
updated_at: {
|
||||
type: 'datetime',
|
||||
defaultValue: moment(),
|
||||
},
|
||||
size: {
|
||||
type: 'size',
|
||||
defaultValue: {
|
||||
size: 0,
|
||||
format: 'KB',
|
||||
},
|
||||
},
|
||||
file_type: {
|
||||
type: 'enum',
|
||||
defaultValue: 'image',
|
||||
},
|
||||
};
|
||||
|
||||
export default filtersForm;
|
||||
@ -0,0 +1,5 @@
|
||||
const generatePageFromStart = (start, limit) => {
|
||||
return Math.floor(start / limit) + 1;
|
||||
};
|
||||
|
||||
export default generatePageFromStart;
|
||||
@ -0,0 +1,5 @@
|
||||
const generateStartFromPage = (page, limit) => {
|
||||
return page * limit - limit;
|
||||
};
|
||||
|
||||
export default generateStartFromPage;
|
||||
@ -0,0 +1,4 @@
|
||||
export { default as filtersForm } from './filtersForm';
|
||||
export { default as generateStartFromPage } from './generateStartFromPage';
|
||||
export { default as generatePageFromStart } from './generatePageFromStart';
|
||||
export { default as getHeaderLabel } from './getHeaderLabel';
|
||||
@ -0,0 +1,61 @@
|
||||
import generatePageFromStart from '../generatePageFromStart';
|
||||
|
||||
describe('MEDIA LIBRARY | containers | HomePage | utils', () => {
|
||||
describe('generatePageFromStart', () => {
|
||||
it('should return 1 if start is 0 and limit is 10', () => {
|
||||
const start = 0;
|
||||
const limit = 10;
|
||||
const expected = 1;
|
||||
|
||||
expect(generatePageFromStart(start, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return 2 if start is 10 and limit is 10', () => {
|
||||
const start = 10;
|
||||
const limit = 10;
|
||||
const expected = 2;
|
||||
|
||||
expect(generatePageFromStart(start, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return 3 if start is 20 and limit is 10', () => {
|
||||
const start = 20;
|
||||
const limit = 10;
|
||||
const expected = 3;
|
||||
|
||||
expect(generatePageFromStart(start, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return 1 if start is 10 and limit is 20', () => {
|
||||
const start = 10;
|
||||
const limit = 20;
|
||||
const expected = 1;
|
||||
|
||||
expect(generatePageFromStart(start, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return if start is 20 and limit is 20', () => {
|
||||
const start = 20;
|
||||
const limit = 20;
|
||||
const expected = 2;
|
||||
|
||||
expect(generatePageFromStart(start, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return if start is 50 and limit is 20', () => {
|
||||
const start = 50;
|
||||
const limit = 20;
|
||||
const expected = 3;
|
||||
|
||||
expect(generatePageFromStart(start, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return if start is 70 and limit is 20', () => {
|
||||
const start = 70;
|
||||
const limit = 20;
|
||||
const expected = 4;
|
||||
|
||||
expect(generatePageFromStart(start, limit)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,45 @@
|
||||
import generateStartFromPage from '../generateStartFromPage';
|
||||
|
||||
describe('MEDIA LIBRARY | containers | HomePage | utils', () => {
|
||||
describe('generateStartFromPage', () => {
|
||||
it('should return 0 if page is 1 and limit is 10', () => {
|
||||
const page = 1;
|
||||
const limit = 10;
|
||||
const expected = 0;
|
||||
|
||||
expect(generateStartFromPage(page, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return 10 if page is 2 and limit is 10', () => {
|
||||
const page = 2;
|
||||
const limit = 10;
|
||||
const expected = 10;
|
||||
|
||||
expect(generateStartFromPage(page, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return 20 if page is 3 and limit is 10', () => {
|
||||
const page = 3;
|
||||
const limit = 10;
|
||||
const expected = 20;
|
||||
|
||||
expect(generateStartFromPage(page, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return 20 if page is 2 and limit is 20', () => {
|
||||
const page = 2;
|
||||
const limit = 20;
|
||||
const expected = 20;
|
||||
|
||||
expect(generateStartFromPage(page, limit)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return 40 if page is 3 and limit is 20', () => {
|
||||
const page = 3;
|
||||
const limit = 20;
|
||||
const expected = 40;
|
||||
|
||||
expect(generateStartFromPage(page, limit)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -7,6 +7,7 @@
|
||||
"header.content.assets-empty": "No asset",
|
||||
"header.content.assets-multiple": "{number} assets",
|
||||
"header.content.assets-single": "1 asset",
|
||||
"filter.add": "Add filter",
|
||||
"input.label-bold": "Drag & drop",
|
||||
"input.label-normal": "to upload or",
|
||||
"input.button.label": "Browse files",
|
||||
|
||||
@ -11,13 +11,18 @@ const _ = require('lodash');
|
||||
|
||||
module.exports = async () => {
|
||||
// set plugin store
|
||||
const pluginStore = strapi.store({
|
||||
environment: strapi.config.environment,
|
||||
const configurator = strapi.store({
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
key: 'settings',
|
||||
});
|
||||
|
||||
strapi.plugins.upload.config.providers = [];
|
||||
Object.assign(strapi.plugins.upload.config, {
|
||||
enabled: true,
|
||||
provider: 'local',
|
||||
sizeLimit: 1000000,
|
||||
providers: [],
|
||||
});
|
||||
|
||||
const installedProviders = Object.keys(strapi.config.info.dependencies)
|
||||
.filter(d => d.includes('strapi-provider-upload-'))
|
||||
@ -28,19 +33,15 @@ module.exports = async () => {
|
||||
}
|
||||
|
||||
// if provider config does not exist set one by default
|
||||
const config = await pluginStore.get({ key: 'provider' });
|
||||
const config = await configurator.get();
|
||||
|
||||
if (!config) {
|
||||
const provider = _.find(strapi.plugins.upload.config.providers, {
|
||||
provider: 'local',
|
||||
await configurator.set({
|
||||
value: {
|
||||
sizeOptimization: true,
|
||||
responsiveDimensions: true,
|
||||
videoPreview: true,
|
||||
},
|
||||
});
|
||||
|
||||
const value = _.assign({}, provider, {
|
||||
enabled: true,
|
||||
// by default limit size to 1 GB
|
||||
sizeLimit: 1000000,
|
||||
});
|
||||
|
||||
await pluginStore.set({ key: 'provider', value });
|
||||
}
|
||||
};
|
||||
|
||||
@ -15,15 +15,7 @@
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/environments",
|
||||
"handler": "Upload.getEnvironments",
|
||||
"config": {
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/settings/:environment",
|
||||
"path": "/settings",
|
||||
"handler": "Upload.getSettings",
|
||||
"config": {
|
||||
"policies": []
|
||||
@ -31,7 +23,7 @@
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/settings/:environment",
|
||||
"path": "/settings",
|
||||
"handler": "Upload.updateSettings",
|
||||
"config": {
|
||||
"policies": []
|
||||
|
||||
@ -40,13 +40,7 @@ module.exports = {
|
||||
resolver: async (obj, { file: upload, ...fields }) => {
|
||||
const file = await formatFile(upload, fields);
|
||||
|
||||
const config = await strapi
|
||||
.store({
|
||||
environment: strapi.config.environment,
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
})
|
||||
.get({ key: 'provider' });
|
||||
const config = strapi.plugins.upload.config;
|
||||
|
||||
const uploadedFiles = await strapi.plugins.upload.services.upload.upload(
|
||||
[file],
|
||||
@ -66,13 +60,7 @@ module.exports = {
|
||||
uploads.map(upload => formatFile(upload, fields))
|
||||
);
|
||||
|
||||
const config = await strapi
|
||||
.store({
|
||||
environment: strapi.config.environment,
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
})
|
||||
.get({ key: 'provider' });
|
||||
const config = strapi.plugins.upload.config;
|
||||
|
||||
const uploadedFiles = await strapi.plugins.upload.services.upload.upload(
|
||||
files,
|
||||
|
||||
@ -3,17 +3,17 @@
|
||||
/**
|
||||
* Upload.js controller
|
||||
*
|
||||
* @description: A set of functions called "actions" of the `upload` plugin.
|
||||
*/
|
||||
|
||||
const _ = require('lodash');
|
||||
const validateSettings = require('./validation/settings');
|
||||
|
||||
module.exports = {
|
||||
async upload(ctx) {
|
||||
const uploadService = strapi.plugins.upload.services.upload;
|
||||
|
||||
// Retrieve provider configuration.
|
||||
const config = await uploadService.getConfig();
|
||||
const config = strapi.plugins.upload.config;
|
||||
|
||||
// Verify if the file upload is enable.
|
||||
if (config.enabled === false) {
|
||||
@ -98,48 +98,32 @@ module.exports = {
|
||||
ctx.send(uploadedFiles);
|
||||
},
|
||||
|
||||
async getEnvironments(ctx) {
|
||||
const environments = Object.keys(strapi.config.environments).map(
|
||||
environment => ({
|
||||
name: environment,
|
||||
active: strapi.config.environment === environment,
|
||||
})
|
||||
);
|
||||
|
||||
ctx.send({ environments });
|
||||
},
|
||||
|
||||
async getSettings(ctx) {
|
||||
const config = await strapi
|
||||
.store({
|
||||
environment: ctx.params.environment,
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
key: 'settings',
|
||||
})
|
||||
.get({ key: 'provider' });
|
||||
.get();
|
||||
|
||||
ctx.send({
|
||||
providers: strapi.plugins.upload.config.providers,
|
||||
config,
|
||||
data: config,
|
||||
});
|
||||
},
|
||||
|
||||
async updateSettings(ctx) {
|
||||
const {
|
||||
request: { body: newSettings },
|
||||
} = ctx;
|
||||
await strapi
|
||||
.store({
|
||||
environment: ctx.params.environment,
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
})
|
||||
.set({
|
||||
key: 'provider',
|
||||
value: { ...newSettings, sizeLimit: parseFloat(newSettings.sizeLimit) },
|
||||
});
|
||||
const configurator = strapi.store({
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
key: 'settings',
|
||||
});
|
||||
|
||||
ctx.send({ ok: true });
|
||||
const data = await validateSettings(ctx.request.body);
|
||||
|
||||
await configurator.set({ key: 'settings', value: data });
|
||||
|
||||
ctx.body = { data };
|
||||
},
|
||||
|
||||
async find(ctx) {
|
||||
@ -173,13 +157,7 @@ module.exports = {
|
||||
|
||||
async destroy(ctx) {
|
||||
const { id } = ctx.params;
|
||||
const config = await strapi
|
||||
.store({
|
||||
environment: strapi.config.environment,
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
})
|
||||
.get({ key: 'provider' });
|
||||
const config = strapi.plugins.upload.config;
|
||||
|
||||
const file = await strapi.plugins['upload'].services.upload.fetch({ id });
|
||||
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const { yup, formatYupErrors } = require('strapi-utils');
|
||||
|
||||
const settingsSchema = yup.object({
|
||||
sizeOptimization: yup.boolean().required(),
|
||||
responsiveDimensions: yup.boolean().required(),
|
||||
videoPreview: yup.boolean().required(),
|
||||
});
|
||||
|
||||
const validateSettings = data => {
|
||||
return settingsSchema
|
||||
.validate(data, {
|
||||
abortEarly: false,
|
||||
})
|
||||
.catch(error => {
|
||||
throw strapi.errors.badRequest('ValidationError', {
|
||||
errors: formatYupErrors(error),
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = validateSettings;
|
||||
@ -139,13 +139,7 @@ module.exports = {
|
||||
|
||||
async uploadToEntity(params, files, source) {
|
||||
// Retrieve provider settings from database.
|
||||
const config = await strapi
|
||||
.store({
|
||||
environment: strapi.config.environment,
|
||||
type: 'plugin',
|
||||
name: 'upload',
|
||||
})
|
||||
.get({ key: 'provider' });
|
||||
const config = strapi.plugins.upload.config;
|
||||
|
||||
const model = strapi.getModel(params.model, source);
|
||||
|
||||
|
||||
36
packages/strapi-plugin-upload/test/__tests__/bootstrap.test.js
vendored
Normal file
36
packages/strapi-plugin-upload/test/__tests__/bootstrap.test.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
const bootstrap = require('../../config/functions/bootstrap');
|
||||
|
||||
describe('Upload plugin bootstrap function', () => {
|
||||
test('Sets default config if id does not exist', async () => {
|
||||
const setStore = jest.fn(() => {});
|
||||
|
||||
global.strapi = {
|
||||
config: {
|
||||
info: {
|
||||
dependencies: {},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
upload: { config: {} },
|
||||
},
|
||||
store() {
|
||||
return {
|
||||
get() {
|
||||
return null;
|
||||
},
|
||||
set: setStore,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
await bootstrap();
|
||||
|
||||
expect(setStore).toHaveBeenCalledWith({
|
||||
value: {
|
||||
sizeOptimization: true,
|
||||
videoPreview: true,
|
||||
responsiveDimensions: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -8,85 +8,22 @@ const { createAuthRequest } = require('../../../test/helpers/request');
|
||||
|
||||
let rq;
|
||||
|
||||
const defaultProviderConfig = {
|
||||
provider: 'local',
|
||||
name: 'Local server',
|
||||
enabled: true,
|
||||
sizeLimit: 1000000,
|
||||
};
|
||||
|
||||
const resetProviderConfigToDefault = () => {
|
||||
return setConfigOptions(defaultProviderConfig);
|
||||
};
|
||||
|
||||
const setConfigOptions = assign => {
|
||||
return rq.put('/upload/settings/development', {
|
||||
body: {
|
||||
...defaultProviderConfig,
|
||||
...assign,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
describe('Upload plugin end to end tests', () => {
|
||||
beforeAll(async () => {
|
||||
const token = await registerAndLogin();
|
||||
rq = createAuthRequest(token);
|
||||
}, 60000);
|
||||
|
||||
afterEach(async () => {
|
||||
await resetProviderConfigToDefault();
|
||||
});
|
||||
|
||||
describe('GET /upload/environments => List available environments', () => {
|
||||
test('Returns the list of envrionments and which one is currently active', async () => {
|
||||
const res = await rq.get('/upload/environments');
|
||||
describe('GET /upload/settings => Get settings for an environment', () => {
|
||||
test('Returns the settings', async () => {
|
||||
const res = await rq.get('/upload/settings');
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.body).toEqual({
|
||||
environments: expect.arrayContaining([
|
||||
{
|
||||
name: 'development',
|
||||
active: true,
|
||||
},
|
||||
{
|
||||
name: 'staging',
|
||||
active: false,
|
||||
},
|
||||
{
|
||||
name: 'production',
|
||||
active: false,
|
||||
},
|
||||
]),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /upload/settings/:environment => Get settings for an environment', () => {
|
||||
test('Lists the available providers', async () => {
|
||||
const res = await rq.get('/upload/settings/development');
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.body).toMatchObject({
|
||||
providers: [
|
||||
{
|
||||
provider: 'local',
|
||||
name: 'Local server',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test('Return the default provider config', async () => {
|
||||
const res = await rq.get('/upload/settings/development');
|
||||
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.body).toMatchObject({
|
||||
config: {
|
||||
provider: 'local',
|
||||
name: 'Local server',
|
||||
enabled: true,
|
||||
sizeLimit: 1000000,
|
||||
data: {
|
||||
sizeOptimization: true,
|
||||
videoPreview: true,
|
||||
responsiveDimensions: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -94,24 +31,32 @@ describe('Upload plugin end to end tests', () => {
|
||||
|
||||
describe('PUT /upload/settings/:environment', () => {
|
||||
test('Updates an envrionment config correctly', async () => {
|
||||
const updateRes = await rq.put('/upload/settings/development', {
|
||||
const updateRes = await rq.put('/upload/settings', {
|
||||
body: {
|
||||
provider: 'test',
|
||||
enabled: false,
|
||||
sizeLimit: 1000,
|
||||
sizeOptimization: true,
|
||||
videoPreview: false,
|
||||
responsiveDimensions: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(updateRes.statusCode).toBe(200);
|
||||
expect(updateRes.body).toEqual({ ok: true });
|
||||
expect(updateRes.body).toEqual({
|
||||
data: {
|
||||
sizeOptimization: true,
|
||||
videoPreview: false,
|
||||
responsiveDimensions: true,
|
||||
},
|
||||
});
|
||||
|
||||
const getRes = await rq.get('/upload/settings/development');
|
||||
const getRes = await rq.get('/upload/settings');
|
||||
|
||||
expect(getRes.statusCode).toBe(200);
|
||||
expect(getRes.body.config).toEqual({
|
||||
provider: 'test',
|
||||
enabled: false,
|
||||
sizeLimit: 1000,
|
||||
expect(getRes.body).toEqual({
|
||||
data: {
|
||||
sizeOptimization: true,
|
||||
videoPreview: false,
|
||||
responsiveDimensions: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -142,21 +87,6 @@ describe('Upload plugin end to end tests', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('Rejects when provider is not enabled', async () => {
|
||||
await setConfigOptions({ enabled: false });
|
||||
|
||||
const res = await rq.post('/upload', {
|
||||
formData: {
|
||||
files: fs.createReadStream(__dirname + '/rec.jpg'),
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(400);
|
||||
expect(res.body).toMatchObject({
|
||||
message: [{ messages: [{ message: 'File upload is disabled' }] }],
|
||||
});
|
||||
});
|
||||
|
||||
test('Rejects when no files are provided', async () => {
|
||||
const res = await rq.post('/upload', {
|
||||
formData: {},
|
||||
@ -167,27 +97,6 @@ describe('Upload plugin end to end tests', () => {
|
||||
message: [{ messages: [{ message: 'Files are empty' }] }],
|
||||
});
|
||||
});
|
||||
|
||||
test('Rejects when any file if over the configured size limit', async () => {
|
||||
await setConfigOptions({
|
||||
sizeLimit: 0,
|
||||
});
|
||||
|
||||
const res = await rq.post('/upload', {
|
||||
formData: {
|
||||
files: fs.createReadStream(__dirname + '/rec.jpg'),
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.statusCode).toBe(400);
|
||||
expect(res.body).toMatchObject({
|
||||
message: [
|
||||
{
|
||||
messages: [{ message: 'rec.jpg file is bigger than limit size!' }],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /upload/files => Find files', () => {});
|
||||
|
||||
@ -471,7 +471,7 @@ class Strapi extends EventEmitter {
|
||||
this.log.warn('Make sure you call it?');
|
||||
}, timeoutMs);
|
||||
|
||||
async function execBootstrap(fn) {
|
||||
const execBootstrap = async fn => {
|
||||
if (!fn) return;
|
||||
|
||||
const timer = warnOnTimeout();
|
||||
@ -480,7 +480,7 @@ class Strapi extends EventEmitter {
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const pluginBoostraps = Object.keys(this.plugins).map(plugin => {
|
||||
return execBootstrap(
|
||||
|
||||
@ -51,7 +51,7 @@ const loadPlugins = async ({ installedPlugins }) => {
|
||||
|
||||
const files = await loadFiles(
|
||||
pluginPath,
|
||||
'{!(config|node_modules|test)//*.*(js|json),package.json}'
|
||||
'{!(config|node_modules|test)/*.*(js|json),package.json}'
|
||||
);
|
||||
|
||||
const conf = await loadConfig(pluginPath);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user