mirror of
https://github.com/strapi/strapi.git
synced 2025-09-16 20:10:05 +00:00
Merge branch 'master' into docs-client
This commit is contained in:
commit
d44b88a0d2
@ -132,6 +132,16 @@ Run the following statement in your database:
|
|||||||
:::
|
:::
|
||||||
::::
|
::::
|
||||||
|
|
||||||
|
## Date type changes
|
||||||
|
|
||||||
|
We introduced new types in the admin panel: `date`, `datetime` and `time`. Before all of those types where saved as `datetime`.
|
||||||
|
|
||||||
|
You will need to change the type of your fields from `date` to `datetime` if you don't want to migrate your data.
|
||||||
|
|
||||||
|
- To migrate yout old `date` to `datetime`, change the field type from `date` to `datetime`. NO data migration is required.
|
||||||
|
- To migrate your old `date` to new `date`, you will need to migrate yout data to be of the format: `YYYY-MM-DD`
|
||||||
|
- To migrate your old `date` to the new `time`, change the field type from `date` to `time`. You will also need to transform them to be of the format: `HH:mm:ss.SSS`
|
||||||
|
|
||||||
## Groups become Components
|
## Groups become Components
|
||||||
|
|
||||||
If you were using the groups feature you will need to apply some changes:
|
If you were using the groups feature you will need to apply some changes:
|
||||||
@ -370,10 +380,19 @@ _Repeat this query for every join table where you are using this component._
|
|||||||
|
|
||||||
```sql
|
```sql
|
||||||
UPDATE restaurant_components
|
UPDATE restaurant_components
|
||||||
SET component_type = 'groups_old_table_name'
|
SET component_type = 'components_new_table_name'
|
||||||
WHERE component_type = 'components_new_table_name';
|
WHERE component_type = 'groups_old_table_name';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**4. If you store files in groups, update the `related_type` values**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
UPDATE upload_file_morph
|
||||||
|
SET related_type = 'components_new_table_name'
|
||||||
|
WHERE related_type = 'groups_old_table_name';
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Mongo
|
#### Mongo
|
||||||
|
|
||||||
In `mongo` the relation between a content type and its components is held in an array of references. To know which component type it referes to, the array also contains a `kind` attribute containing the component Schema name.
|
In `mongo` the relation between a content type and its components is held in an array of references. To know which component type it referes to, the array also contains a `kind` attribute containing the component Schema name.
|
||||||
@ -450,6 +469,45 @@ We created new home pages when your go to your api url.
|
|||||||
You will need to copy `index.html` and `production.html` into your `public` folder.
|
You will need to copy `index.html` and `production.html` into your `public` folder.
|
||||||
You can find those two files [here](https://github.com/strapi/strapi/tree/master/packages/strapi-generate-new/lib/resources/files/public).
|
You can find those two files [here](https://github.com/strapi/strapi/tree/master/packages/strapi-generate-new/lib/resources/files/public).
|
||||||
|
|
||||||
|
## Updating `csp` options
|
||||||
|
|
||||||
|
The admin panel contains certain assets that use `data:img;base64` images. To allow rendering of those assets you can update the files `./config/environments/{env}/security.json` as follows:
|
||||||
|
|
||||||
|
**Before**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"csp": {
|
||||||
|
"enabled": true,
|
||||||
|
"policy": [
|
||||||
|
{
|
||||||
|
"img-src": "'self' http:"
|
||||||
|
},
|
||||||
|
"block-all-mixed-content"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
//....
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**After**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"csp": {
|
||||||
|
"enabled": true,
|
||||||
|
"policy": ["block-all-mixed-content"]
|
||||||
|
}
|
||||||
|
//....
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need more fine control you can also simply add the `data:` option to the `img-src` option.
|
||||||
|
|
||||||
## Rebuilding your administration panel
|
## Rebuilding your administration panel
|
||||||
|
|
||||||
Now delete the `.cache` and `build` folders. Then run `yarn develop`.
|
Now delete the `.cache` and `build` folders. Then run `yarn develop`.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
@ -43,11 +43,6 @@
|
|||||||
"full_name": {
|
"full_name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
|
||||||
"dz": {
|
|
||||||
"type": "dynamiczone",
|
|
||||||
"components": [],
|
|
||||||
"min": 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "getstarted",
|
"name": "getstarted",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "A Strapi application.",
|
"description": "A Strapi application.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"develop": "strapi develop",
|
"develop": "strapi develop",
|
||||||
@ -15,21 +15,21 @@
|
|||||||
"mysql": "^2.17.1",
|
"mysql": "^2.17.1",
|
||||||
"pg": "^7.10.0",
|
"pg": "^7.10.0",
|
||||||
"sqlite3": "^4.0.6",
|
"sqlite3": "^4.0.6",
|
||||||
"strapi": "3.0.0-beta.18.1",
|
"strapi": "3.0.0-beta.18.2",
|
||||||
"strapi-admin": "3.0.0-beta.18.1",
|
"strapi-admin": "3.0.0-beta.18.2",
|
||||||
"strapi-connector-bookshelf": "3.0.0-beta.18.1",
|
"strapi-connector-bookshelf": "3.0.0-beta.18.2",
|
||||||
"strapi-connector-mongoose": "3.0.0-beta.18.1",
|
"strapi-connector-mongoose": "3.0.0-beta.18.2",
|
||||||
"strapi-middleware-views": "3.0.0-beta.18.1",
|
"strapi-middleware-views": "3.0.0-beta.18.2",
|
||||||
"strapi-plugin-content-manager": "3.0.0-beta.18.1",
|
"strapi-plugin-content-manager": "3.0.0-beta.18.2",
|
||||||
"strapi-plugin-content-type-builder": "3.0.0-beta.18.1",
|
"strapi-plugin-content-type-builder": "3.0.0-beta.18.2",
|
||||||
"strapi-plugin-documentation": "3.0.0-beta.18.1",
|
"strapi-plugin-documentation": "3.0.0-beta.18.2",
|
||||||
"strapi-plugin-email": "3.0.0-beta.18.1",
|
"strapi-plugin-email": "3.0.0-beta.18.2",
|
||||||
"strapi-plugin-graphql": "3.0.0-beta.18.1",
|
"strapi-plugin-graphql": "3.0.0-beta.18.2",
|
||||||
"strapi-plugin-upload": "3.0.0-beta.18.1",
|
"strapi-plugin-upload": "3.0.0-beta.18.2",
|
||||||
"strapi-plugin-users-permissions": "3.0.0-beta.18.1",
|
"strapi-plugin-users-permissions": "3.0.0-beta.18.2",
|
||||||
"strapi-provider-email-mailgun": "3.0.0-beta.18.1",
|
"strapi-provider-email-mailgun": "3.0.0-beta.18.2",
|
||||||
"strapi-provider-upload-aws-s3": "3.0.0-beta.18.1",
|
"strapi-provider-upload-aws-s3": "3.0.0-beta.18.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"uuid": "getstarted"
|
"uuid": "getstarted"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*",
|
"packages/*",
|
||||||
"examples/*"
|
"examples/*"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "create-strapi-app",
|
"name": "create-strapi-app",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate a new Strapi application.",
|
"description": "Generate a new Strapi application.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
@ -21,7 +21,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "^2.20.0",
|
"commander": "^2.20.0",
|
||||||
"strapi-generate-new": "3.0.0-beta.18.1"
|
"strapi-generate-new": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"no tests yet\""
|
"test": "echo \"no tests yet\""
|
||||||
|
@ -26,9 +26,9 @@ const Logout = ({ history: { push } }) => {
|
|||||||
const id = get(auth.getUserInfo(), 'id');
|
const id = get(auth.getUserInfo(), 'id');
|
||||||
|
|
||||||
push({
|
push({
|
||||||
pathname: `/plugins/content-manager/administrator/${id}`,
|
pathname: `/plugins/content-manager/strapi::administrator/${id}`,
|
||||||
search:
|
search:
|
||||||
'?redirectUrl=/plugins/content-manager/administrator/?page=0&limit=0&sort=id&source=admin',
|
'?redirectUrl=/plugins/content-manager/strapi::administrator/?_page=0&_limit=0&_sort=id',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const handleGoToAdministrator = () => {
|
const handleGoToAdministrator = () => {
|
||||||
|
@ -48,7 +48,7 @@ function App(props) {
|
|||||||
|
|
||||||
if (uuid) {
|
if (uuid) {
|
||||||
try {
|
try {
|
||||||
await fetch('https://analytics.strapi.io/track', {
|
fetch('https://analytics.strapi.io/track', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
event: 'didInitializeAdministration',
|
event: 'didInitializeAdministration',
|
||||||
|
@ -130,6 +130,7 @@
|
|||||||
"components.Input.error.validation.required": "This value is required.",
|
"components.Input.error.validation.required": "This value is required.",
|
||||||
"components.Input.error.validation.unique": "This value is already used.",
|
"components.Input.error.validation.unique": "This value is already used.",
|
||||||
"components.InputSelect.option.placeholder": "Choose here",
|
"components.InputSelect.option.placeholder": "Choose here",
|
||||||
|
"component.Input.error.validation.integer": "The value must be an integer",
|
||||||
"components.ListRow.empty": "There is no data to be shown.",
|
"components.ListRow.empty": "There is no data to be shown.",
|
||||||
"components.OverlayBlocker.description": "You're using a feature that needs the server to restart. Please wait until the server is up.",
|
"components.OverlayBlocker.description": "You're using a feature that needs the server to restart. Please wait until the server is up.",
|
||||||
"components.OverlayBlocker.description.serverError": "The server should have restarted, please check your logs in the terminal.",
|
"components.OverlayBlocker.description.serverError": "The server should have restarted, please check your logs in the terminal.",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-admin",
|
"name": "strapi-admin",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Strapi Admin",
|
"description": "Strapi Admin",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -80,8 +80,8 @@
|
|||||||
"reselect": "^3.0.1",
|
"reselect": "^3.0.1",
|
||||||
"sanitize.css": "^4.1.0",
|
"sanitize.css": "^4.1.0",
|
||||||
"shelljs": "^0.7.8",
|
"shelljs": "^0.7.8",
|
||||||
"strapi-helper-plugin": "3.0.0-beta.18.1",
|
"strapi-helper-plugin": "3.0.0-beta.18.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1",
|
"strapi-utils": "3.0.0-beta.18.2",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^0.23.1",
|
||||||
"styled-components": "^4.2.0",
|
"styled-components": "^4.2.0",
|
||||||
"terser-webpack-plugin": "^1.2.3",
|
"terser-webpack-plugin": "^1.2.3",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-connector-bookshelf",
|
"name": "strapi-connector-bookshelf",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Bookshelf hook for the Strapi framework",
|
"description": "Bookshelf hook for the Strapi framework",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"pluralize": "^7.0.0",
|
"pluralize": "^7.0.0",
|
||||||
"rimraf": "^2.6.3",
|
"rimraf": "^2.6.3",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
@ -364,6 +364,14 @@ const createOnFetchPopulateFn = ({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (definition.modelType === 'component') {
|
||||||
|
definition.associations
|
||||||
|
.filter(ast => ast.autoPopulate !== false)
|
||||||
|
.forEach(ast => {
|
||||||
|
this.populate({ path: ast.alias });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
componentAttributes.forEach(key => {
|
componentAttributes.forEach(key => {
|
||||||
this.populate({ path: `${key}.ref` });
|
this.populate({ path: `${key}.ref` });
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-connector-mongoose",
|
"name": "strapi-connector-mongoose",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Mongoose hook for the Strapi framework",
|
"description": "Mongoose hook for the Strapi framework",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"mongoose-float": "^1.0.4",
|
"mongoose-float": "^1.0.4",
|
||||||
"mongoose-long": "^0.2.1",
|
"mongoose-long": "^0.2.1",
|
||||||
"pluralize": "^7.0.0",
|
"pluralize": "^7.0.0",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"email": "hi@strapi.io",
|
"email": "hi@strapi.io",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-database",
|
"name": "strapi-database",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Strapi's database layer",
|
"description": "Strapi's database layer",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate-api",
|
"name": "strapi-generate-api",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate an API for a Strapi application.",
|
"description": "Generate an API for a Strapi application.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate-controller",
|
"name": "strapi-generate-controller",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate a controller for a Strapi API.",
|
"description": "Generate a controller for a Strapi API.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate-model",
|
"name": "strapi-generate-model",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate a model for a Strapi API.",
|
"description": "Generate a model for a Strapi API.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate-new",
|
"name": "strapi-generate-new",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate a new Strapi application.",
|
"description": "Generate a new Strapi application.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate-plugin",
|
"name": "strapi-generate-plugin",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate an plugin for a Strapi application.",
|
"description": "Generate an plugin for a Strapi application.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate-policy",
|
"name": "strapi-generate-policy",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate a policy for a Strapi API.",
|
"description": "Generate a policy for a Strapi API.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate-service",
|
"name": "strapi-generate-service",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Generate a service for a Strapi API.",
|
"description": "Generate a service for a Strapi API.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-generate",
|
"name": "strapi-generate",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Master of ceremonies for the Strapi generators.",
|
"description": "Master of ceremonies for the Strapi generators.",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"fs-extra": "^8.0.1",
|
"fs-extra": "^8.0.1",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"reportback": "^2.0.2",
|
"reportback": "^2.0.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Strapi team",
|
"name": "Strapi team",
|
||||||
|
@ -8,6 +8,7 @@ const errorsTrads = {
|
|||||||
regex: 'components.Input.error.validation.regex',
|
regex: 'components.Input.error.validation.regex',
|
||||||
required: 'components.Input.error.validation.required',
|
required: 'components.Input.error.validation.required',
|
||||||
unique: 'components.Input.error.validation.unique',
|
unique: 'components.Input.error.validation.unique',
|
||||||
|
integer: 'component.Input.error.validation.integer',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default errorsTrads;
|
export default errorsTrads;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-helper-plugin",
|
"name": "strapi-helper-plugin",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Helper for Strapi plugins development",
|
"description": "Helper for Strapi plugins development",
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-hook-ejs",
|
"name": "strapi-hook-ejs",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "EJS hook for the Strapi framework",
|
"description": "EJS hook for the Strapi framework",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-hook-redis",
|
"name": "strapi-hook-redis",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Redis hook for the Strapi framework",
|
"description": "Redis hook for the Strapi framework",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -19,7 +19,7 @@
|
|||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"rimraf": "^2.6.3",
|
"rimraf": "^2.6.3",
|
||||||
"stack-trace": "0.0.10",
|
"stack-trace": "0.0.10",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"email": "hi@strapi.io",
|
"email": "hi@strapi.io",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-middleware-views",
|
"name": "strapi-middleware-views",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Views middleware to enable server-side rendering for the Strapi framework",
|
"description": "Views middleware to enable server-side rendering for the Strapi framework",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -8,6 +8,7 @@ import Tooltip from './Tooltip';
|
|||||||
const DynamicComponent = ({
|
const DynamicComponent = ({
|
||||||
componentUid,
|
componentUid,
|
||||||
friendlyName,
|
friendlyName,
|
||||||
|
icon,
|
||||||
setIsOverDynamicZone,
|
setIsOverDynamicZone,
|
||||||
}) => {
|
}) => {
|
||||||
const [state, setState] = useState(false);
|
const [state, setState] = useState(false);
|
||||||
@ -22,6 +23,7 @@ const DynamicComponent = ({
|
|||||||
<DynamicComponentCard
|
<DynamicComponentCard
|
||||||
componentUid={componentUid}
|
componentUid={componentUid}
|
||||||
friendlyName={friendlyName}
|
friendlyName={friendlyName}
|
||||||
|
icon={icon}
|
||||||
isOver={state}
|
isOver={state}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
push(
|
push(
|
||||||
@ -38,11 +40,13 @@ const DynamicComponent = ({
|
|||||||
|
|
||||||
DynamicComponent.defaultProps = {
|
DynamicComponent.defaultProps = {
|
||||||
friendlyName: '',
|
friendlyName: '',
|
||||||
|
icon: 'smile',
|
||||||
};
|
};
|
||||||
|
|
||||||
DynamicComponent.propTypes = {
|
DynamicComponent.propTypes = {
|
||||||
componentUid: PropTypes.string.isRequired,
|
componentUid: PropTypes.string.isRequired,
|
||||||
friendlyName: PropTypes.string,
|
friendlyName: PropTypes.string,
|
||||||
|
icon: PropTypes.string,
|
||||||
setIsOverDynamicZone: PropTypes.func.isRequired,
|
setIsOverDynamicZone: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,8 +46,8 @@ const DraggedFieldWithPreview = forwardRef(
|
|||||||
'dynamiczone',
|
'dynamiczone',
|
||||||
];
|
];
|
||||||
const withLongerHeight = higherFields.includes(type) && !dragStart;
|
const withLongerHeight = higherFields.includes(type) && !dragStart;
|
||||||
const getCompoFriendlyName = uid =>
|
const getCompoInfos = uid =>
|
||||||
get(componentLayouts, [uid, 'schema', 'info', 'name'], '');
|
get(componentLayouts, [uid, 'schema', 'info'], { name: '', icon: '' });
|
||||||
|
|
||||||
const componentData = get(componentLayouts, [componentUid], {});
|
const componentData = get(componentLayouts, [componentUid], {});
|
||||||
const componentLayout = get(componentData, ['layouts', 'edit'], []);
|
const componentLayout = get(componentData, ['layouts', 'edit'], []);
|
||||||
@ -146,11 +146,14 @@ const DraggedFieldWithPreview = forwardRef(
|
|||||||
{type === 'dynamiczone' && (
|
{type === 'dynamiczone' && (
|
||||||
<DynamicZoneWrapper>
|
<DynamicZoneWrapper>
|
||||||
{dynamicZoneComponents.map(compo => {
|
{dynamicZoneComponents.map(compo => {
|
||||||
|
const { name, icon } = getCompoInfos(compo);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DynamicComponent
|
<DynamicComponent
|
||||||
key={compo}
|
key={compo}
|
||||||
componentUid={compo}
|
componentUid={compo}
|
||||||
friendlyName={getCompoFriendlyName(compo)}
|
friendlyName={name}
|
||||||
|
icon={icon}
|
||||||
setIsOverDynamicZone={setIsOverDynamicZone}
|
setIsOverDynamicZone={setIsOverDynamicZone}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -14,7 +14,6 @@ const getInputType = (type = '') => {
|
|||||||
switch (toLower(type)) {
|
switch (toLower(type)) {
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
return 'bool';
|
return 'bool';
|
||||||
case 'biginteger':
|
|
||||||
case 'decimal':
|
case 'decimal':
|
||||||
case 'float':
|
case 'float':
|
||||||
case 'integer':
|
case 'integer':
|
||||||
@ -114,6 +113,14 @@ function Inputs({ autoFocus, keys, layout, name, onBlur }) {
|
|||||||
inputValue = [];
|
inputValue = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let step;
|
||||||
|
|
||||||
|
if (type === 'float' || type === 'decimal') {
|
||||||
|
step = 'any';
|
||||||
|
} else {
|
||||||
|
step = '1';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormattedMessage id={errorId}>
|
<FormattedMessage id={errorId}>
|
||||||
{error => {
|
{error => {
|
||||||
@ -141,6 +148,7 @@ function Inputs({ autoFocus, keys, layout, name, onBlur }) {
|
|||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
options={get(attribute, 'enum', [])}
|
options={get(attribute, 'enum', [])}
|
||||||
|
step={step}
|
||||||
type={getInputType(type)}
|
type={getInputType(type)}
|
||||||
validations={validations}
|
validations={validations}
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
|
@ -52,6 +52,7 @@ const RepeatableComponent = ({
|
|||||||
const errorsArray = componentErrorKeys.map(key =>
|
const errorsArray = componentErrorKeys.map(key =>
|
||||||
get(formErrors, [key, 'id'], '')
|
get(formErrors, [key, 'id'], '')
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasMinError =
|
const hasMinError =
|
||||||
get(errorsArray, [0], '').includes('min') &&
|
get(errorsArray, [0], '').includes('min') &&
|
||||||
!collapses.some(obj => obj.isOpen === true);
|
!collapses.some(obj => obj.isOpen === true);
|
||||||
|
@ -196,6 +196,10 @@ const EditViewDataManagerProvider = ({
|
|||||||
inputValue = null;
|
inputValue = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'biginteger' && value === '') {
|
||||||
|
inputValue = null;
|
||||||
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'ON_CHANGE',
|
type: 'ON_CHANGE',
|
||||||
keys: name.split('.'),
|
keys: name.split('.'),
|
||||||
@ -262,7 +266,7 @@ const EditViewDataManagerProvider = ({
|
|||||||
});
|
});
|
||||||
redirectToPreviousPage();
|
redirectToPreviousPage();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log({ err });
|
console.error({ err });
|
||||||
const error = get(
|
const error = get(
|
||||||
err,
|
err,
|
||||||
['response', 'payload', 'message', '0', 'messages', '0', 'id'],
|
['response', 'payload', 'message', '0', 'messages', '0', 'id'],
|
||||||
@ -277,6 +281,7 @@ const EditViewDataManagerProvider = ({
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const errors = getYupInnerErrors(err);
|
const errors = getYupInnerErrors(err);
|
||||||
|
console.error({ err, errors });
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'SUBMIT_ERRORS',
|
type: 'SUBMIT_ERRORS',
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
isArray,
|
isArray,
|
||||||
isEmpty,
|
isEmpty,
|
||||||
isNaN,
|
isNaN,
|
||||||
|
toNumber,
|
||||||
} from 'lodash';
|
} from 'lodash';
|
||||||
import * as yup from 'yup';
|
import * as yup from 'yup';
|
||||||
import { translatedErrors as errorsTrads } from 'strapi-helper-plugin';
|
import { translatedErrors as errorsTrads } from 'strapi-helper-plugin';
|
||||||
@ -28,6 +29,34 @@ yup.addMethod(yup.array, 'notEmptyMin', function(min) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
yup.addMethod(yup.string, 'isInferior', function(message, max) {
|
||||||
|
return this.test('isInferior', message, function(value) {
|
||||||
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isNaN(toNumber(value))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toNumber(max) >= toNumber(value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
yup.addMethod(yup.string, 'isSuperior', function(message, min) {
|
||||||
|
return this.test('isSuperior', message, function(value) {
|
||||||
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isNaN(toNumber(value))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toNumber(value) >= toNumber(min);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const getAttributes = data => get(data, ['schema', 'attributes'], {});
|
const getAttributes = data => get(data, ['schema', 'attributes'], {});
|
||||||
|
|
||||||
const createYupSchema = (model, { components }) => {
|
const createYupSchema = (model, { components }) => {
|
||||||
@ -80,7 +109,26 @@ const createYupSchema = (model, { components }) => {
|
|||||||
.nullable();
|
.nullable();
|
||||||
|
|
||||||
if (min) {
|
if (min) {
|
||||||
componentSchema = componentSchema.min(min, errorsTrads.min);
|
componentSchema = yup.lazy(array => {
|
||||||
|
if (attribute.required) {
|
||||||
|
return yup
|
||||||
|
.array()
|
||||||
|
.of(componentFieldSchema)
|
||||||
|
.defined()
|
||||||
|
.min(min, errorsTrads.min);
|
||||||
|
}
|
||||||
|
|
||||||
|
let schema = yup
|
||||||
|
.array()
|
||||||
|
.of(componentFieldSchema)
|
||||||
|
.nullable();
|
||||||
|
|
||||||
|
if (array && !isEmpty(array)) {
|
||||||
|
schema = schema.min(min, errorsTrads.min);
|
||||||
|
}
|
||||||
|
|
||||||
|
return schema;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max) {
|
if (max) {
|
||||||
@ -146,6 +194,7 @@ const createYupSchema = (model, { components }) => {
|
|||||||
|
|
||||||
const createYupSchemaAttribute = (type, validations) => {
|
const createYupSchemaAttribute = (type, validations) => {
|
||||||
let schema = yup.mixed();
|
let schema = yup.mixed();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
['string', 'text', 'richtext', 'email', 'password', 'enumeration'].includes(
|
['string', 'text', 'richtext', 'email', 'password', 'enumeration'].includes(
|
||||||
type
|
type
|
||||||
@ -153,6 +202,7 @@ const createYupSchemaAttribute = (type, validations) => {
|
|||||||
) {
|
) {
|
||||||
schema = yup.string();
|
schema = yup.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'json') {
|
if (type === 'json') {
|
||||||
schema = yup
|
schema = yup
|
||||||
.mixed(errorsTrads.json)
|
.mixed(errorsTrads.json)
|
||||||
@ -183,16 +233,22 @@ const createYupSchemaAttribute = (type, validations) => {
|
|||||||
if (type === 'email') {
|
if (type === 'email') {
|
||||||
schema = schema.email(errorsTrads.email);
|
schema = schema.email(errorsTrads.email);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['number', 'integer', 'biginteger', 'float', 'decimal'].includes(type)) {
|
if (['number', 'integer', 'biginteger', 'float', 'decimal'].includes(type)) {
|
||||||
schema = yup
|
schema = yup
|
||||||
.number()
|
.number()
|
||||||
.transform(cv => (isNaN(cv) ? undefined : cv))
|
.transform(cv => (isNaN(cv) ? undefined : cv))
|
||||||
.typeError();
|
.typeError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['date', 'datetime'].includes(type)) {
|
if (['date', 'datetime'].includes(type)) {
|
||||||
schema = yup.date();
|
schema = yup.date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === 'biginteger') {
|
||||||
|
schema = yup.string().matches(/^\d*$/);
|
||||||
|
}
|
||||||
|
|
||||||
Object.keys(validations).forEach(validation => {
|
Object.keys(validations).forEach(validation => {
|
||||||
const validationValue = validations[validation];
|
const validationValue = validations[validation];
|
||||||
if (
|
if (
|
||||||
@ -205,15 +261,25 @@ const createYupSchemaAttribute = (type, validations) => {
|
|||||||
case 'required':
|
case 'required':
|
||||||
schema = schema.required(errorsTrads.required);
|
schema = schema.required(errorsTrads.required);
|
||||||
break;
|
break;
|
||||||
case 'max':
|
case 'max': {
|
||||||
schema = schema.max(validationValue, errorsTrads.max);
|
if (type === 'biginteger') {
|
||||||
|
schema = schema.isInferior(errorsTrads.max, validationValue);
|
||||||
|
} else {
|
||||||
|
schema = schema.max(validationValue, errorsTrads.max);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'maxLength':
|
case 'maxLength':
|
||||||
schema = schema.max(validationValue, errorsTrads.maxLength);
|
schema = schema.max(validationValue, errorsTrads.maxLength);
|
||||||
break;
|
break;
|
||||||
case 'min':
|
case 'min': {
|
||||||
schema = schema.min(validationValue, errorsTrads.min);
|
if (type === 'biginteger') {
|
||||||
|
schema = schema.isSuperior(errorsTrads.min, validationValue);
|
||||||
|
} else {
|
||||||
|
schema = schema.min(validationValue, errorsTrads.min);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'minLength':
|
case 'minLength':
|
||||||
schema = schema.min(validationValue, errorsTrads.minLength);
|
schema = schema.min(validationValue, errorsTrads.minLength);
|
||||||
break;
|
break;
|
||||||
@ -249,6 +315,7 @@ const createYupSchemaAttribute = (type, validations) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-plugin-content-manager",
|
"name": "strapi-plugin-content-manager",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "A powerful UI to easily manage your data.",
|
"description": "A powerful UI to easily manage your data.",
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"name": "Content Manager",
|
"name": "Content Manager",
|
||||||
@ -32,8 +32,8 @@
|
|||||||
"redux-immutable": "^4.0.0",
|
"redux-immutable": "^4.0.0",
|
||||||
"reselect": "^3.0.1",
|
"reselect": "^3.0.1",
|
||||||
"showdown": "^1.9.0",
|
"showdown": "^1.9.0",
|
||||||
"strapi-helper-plugin": "3.0.0-beta.18.1",
|
"strapi-helper-plugin": "3.0.0-beta.18.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1",
|
"strapi-utils": "3.0.0-beta.18.2",
|
||||||
"styled-components": "^4.2.0",
|
"styled-components": "^4.2.0",
|
||||||
"yup": "^0.27.0"
|
"yup": "^0.27.0"
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg"><text transform="translate(-19 -4)" fill="#4B515A" fill-rule="evenodd" font-size="30" font-family="AppleColorEmoji, Apple Color Emoji"><tspan x="19" y="32">🏭</tspan></text></svg>
|
After Width: | Height: | Size: 244 B |
@ -1,29 +1,98 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { components } from 'react-select';
|
import { components } from 'react-select';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { Checkbox, CheckboxWrapper, Label } from '@buffetjs/styles';
|
import { Checkbox, CheckboxWrapper, Label } from '@buffetjs/styles';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import useDataManager from '../../hooks/useDataManager';
|
import useDataManager from '../../hooks/useDataManager';
|
||||||
|
import useQuery from '../../hooks/useQuery';
|
||||||
|
import getTrad from '../../utils/getTrad';
|
||||||
import UpperFirst from '../UpperFirst';
|
import UpperFirst from '../UpperFirst';
|
||||||
import SubUl from './SubUl';
|
import SubUl from './SubUl';
|
||||||
import Ul from './Ul';
|
import Ul from './Ul';
|
||||||
import hasSubArray from './utils/hasSubArray';
|
import hasSubArray from './utils/hasSubArray';
|
||||||
|
|
||||||
const MultipleMenuList = ({
|
const MultipleMenuList = ({
|
||||||
selectProps: { name, addComponentsToDynamicZone, /*refState, */ value },
|
selectProps: { name, addComponentsToDynamicZone, inputValue, value },
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
const { componentsGroupedByCategory } = useDataManager();
|
const { componentsGroupedByCategory, modifiedData } = useDataManager();
|
||||||
const collapsesObject = Object.keys(componentsGroupedByCategory).reduce(
|
const query = useQuery();
|
||||||
(acc, current) => {
|
const dzName = query.get('dynamicZoneTarget');
|
||||||
acc[current] = false;
|
const alreadyUsedComponents = get(
|
||||||
|
modifiedData,
|
||||||
|
['contentType', 'schema', 'attributes', dzName, 'components'],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const filteredComponentsGroupedByCategory = Object.keys(
|
||||||
|
componentsGroupedByCategory
|
||||||
|
).reduce((acc, current) => {
|
||||||
|
const filteredComponents = componentsGroupedByCategory[current].filter(
|
||||||
|
({ uid }) => {
|
||||||
|
return !alreadyUsedComponents.includes(uid);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (filteredComponents.length > 0) {
|
||||||
|
acc[current] = filteredComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const collapsesObject = Object.keys(
|
||||||
|
filteredComponentsGroupedByCategory
|
||||||
|
).reduce((acc, current) => {
|
||||||
|
acc[current] = false;
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
const [collapses, setCollapses] = useState(collapsesObject);
|
||||||
|
const [options, setOptions] = useState(filteredComponentsGroupedByCategory);
|
||||||
|
|
||||||
|
// Search for component
|
||||||
|
useEffect(() => {
|
||||||
|
const formattedOptions = Object.keys(
|
||||||
|
filteredComponentsGroupedByCategory
|
||||||
|
).reduce((acc, current) => {
|
||||||
|
const filteredComponents = filteredComponentsGroupedByCategory[
|
||||||
|
current
|
||||||
|
].filter(({ schema: { name } }) => {
|
||||||
|
return name.includes(inputValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (filteredComponents.length > 0) {
|
||||||
|
acc[current] = filteredComponents;
|
||||||
|
}
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
}, {});
|
||||||
{}
|
|
||||||
);
|
setOptions(formattedOptions);
|
||||||
const [collapses, setCollapses] = useState(collapsesObject);
|
|
||||||
|
const categoriesToOpen = Object.keys(formattedOptions);
|
||||||
|
|
||||||
|
if (inputValue !== '') {
|
||||||
|
// Close collapses
|
||||||
|
Object.keys(filteredComponentsGroupedByCategory)
|
||||||
|
.filter(cat => categoriesToOpen.indexOf(cat) === -1)
|
||||||
|
.forEach(catName => {
|
||||||
|
setCollapses(prevState => ({ ...prevState, [catName]: false }));
|
||||||
|
});
|
||||||
|
|
||||||
|
categoriesToOpen.forEach(catName => {
|
||||||
|
setCollapses(prevState => ({ ...prevState, [catName]: true }));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Close all collapses
|
||||||
|
categoriesToOpen.forEach(catName => {
|
||||||
|
setCollapses(prevState => ({ ...prevState, [catName]: false }));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [inputValue]);
|
||||||
|
|
||||||
const toggleCollapse = catName => {
|
const toggleCollapse = catName => {
|
||||||
setCollapses(prevState => ({
|
setCollapses(prevState => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
@ -33,18 +102,15 @@ const MultipleMenuList = ({
|
|||||||
|
|
||||||
const Component = components.MenuList;
|
const Component = components.MenuList;
|
||||||
|
|
||||||
const allComponentsCategory = Object.keys(componentsGroupedByCategory).reduce(
|
const allComponentsCategory = Object.keys(options).reduce((acc, current) => {
|
||||||
(acc, current) => {
|
const categoryCompos = options[current].map(compo => {
|
||||||
const categoryCompos = componentsGroupedByCategory[current].map(compo => {
|
return compo.uid;
|
||||||
return compo.uid;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
acc[current] = categoryCompos;
|
acc[current] = categoryCompos;
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
},
|
}, {});
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
const getCategoryValue = categoryName => {
|
const getCategoryValue = categoryName => {
|
||||||
const componentsCategory = allComponentsCategory[categoryName];
|
const componentsCategory = allComponentsCategory[categoryName];
|
||||||
@ -79,7 +145,18 @@ const MultipleMenuList = ({
|
|||||||
maxHeight: 150,
|
maxHeight: 150,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.keys(componentsGroupedByCategory).map(categoryName => {
|
{Object.keys(options).length === 0 && (
|
||||||
|
<FormattedMessage
|
||||||
|
id={getTrad(
|
||||||
|
`components.componentSelect.no-component-available${
|
||||||
|
inputValue === '' ? '' : '.with-search'
|
||||||
|
}`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{msg => <li style={{ paddingTop: 11 }}>{msg}</li>}
|
||||||
|
</FormattedMessage>
|
||||||
|
)}
|
||||||
|
{Object.keys(options).map(categoryName => {
|
||||||
const isChecked = getCategoryValue(categoryName);
|
const isChecked = getCategoryValue(categoryName);
|
||||||
const target = { name: categoryName, value: !isChecked };
|
const target = { name: categoryName, value: !isChecked };
|
||||||
|
|
||||||
@ -124,7 +201,7 @@ const MultipleMenuList = ({
|
|||||||
</CheckboxWrapper>
|
</CheckboxWrapper>
|
||||||
</div>
|
</div>
|
||||||
<SubUl tag="ul" isOpen={collapses[categoryName]}>
|
<SubUl tag="ul" isOpen={collapses[categoryName]}>
|
||||||
{componentsGroupedByCategory[categoryName].map(component => {
|
{options[categoryName].map(component => {
|
||||||
const isChecked = get(value, 'value', []).includes(
|
const isChecked = get(value, 'value', []).includes(
|
||||||
component.uid
|
component.uid
|
||||||
);
|
);
|
||||||
@ -165,6 +242,7 @@ const MultipleMenuList = ({
|
|||||||
|
|
||||||
MultipleMenuList.defaultProps = {
|
MultipleMenuList.defaultProps = {
|
||||||
selectProps: {
|
selectProps: {
|
||||||
|
inputValue: '',
|
||||||
refState: {
|
refState: {
|
||||||
current: {
|
current: {
|
||||||
select: {
|
select: {
|
||||||
@ -179,6 +257,7 @@ MultipleMenuList.defaultProps = {
|
|||||||
MultipleMenuList.propTypes = {
|
MultipleMenuList.propTypes = {
|
||||||
selectProps: PropTypes.shape({
|
selectProps: PropTypes.shape({
|
||||||
addComponentsToDynamicZone: PropTypes.func.isRequired,
|
addComponentsToDynamicZone: PropTypes.func.isRequired,
|
||||||
|
inputValue: PropTypes.string,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
refState: PropTypes.object,
|
refState: PropTypes.object,
|
||||||
value: PropTypes.object,
|
value: PropTypes.object,
|
||||||
|
@ -10,8 +10,18 @@ import { isEmpty, isNumber } from 'lodash';
|
|||||||
import { Inputs } from '@buffetjs/custom';
|
import { Inputs } from '@buffetjs/custom';
|
||||||
import StyledCustomCheckbox from './StyledCustomCheckbox';
|
import StyledCustomCheckbox from './StyledCustomCheckbox';
|
||||||
|
|
||||||
const CustomCheckbox = ({ label, name, onChange, value, ...rest }) => {
|
const CustomCheckbox = ({
|
||||||
|
label,
|
||||||
|
modifiedData,
|
||||||
|
name,
|
||||||
|
onChange,
|
||||||
|
value,
|
||||||
|
...rest
|
||||||
|
}) => {
|
||||||
const [checked, setChecked] = useState(isNumber(value) || !isEmpty(value));
|
const [checked, setChecked] = useState(isNumber(value) || !isEmpty(value));
|
||||||
|
const type = modifiedData.type === 'biginteger' ? 'text' : 'number';
|
||||||
|
const step = ['decimal', 'float'].includes(modifiedData.type) ? 'any' : '1';
|
||||||
|
const disabled = !modifiedData.type;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledCustomCheckbox>
|
<StyledCustomCheckbox>
|
||||||
@ -38,8 +48,10 @@ const CustomCheckbox = ({ label, name, onChange, value, ...rest }) => {
|
|||||||
{...rest}
|
{...rest}
|
||||||
name={name}
|
name={name}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
step={step}
|
||||||
|
disabled={disabled}
|
||||||
value={value}
|
value={value}
|
||||||
type="number"
|
type={type}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -49,12 +61,14 @@ const CustomCheckbox = ({ label, name, onChange, value, ...rest }) => {
|
|||||||
|
|
||||||
CustomCheckbox.defaultProps = {
|
CustomCheckbox.defaultProps = {
|
||||||
label: null,
|
label: null,
|
||||||
|
modifiedData: {},
|
||||||
name: '',
|
name: '',
|
||||||
value: null,
|
value: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
CustomCheckbox.propTypes = {
|
CustomCheckbox.propTypes = {
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
|
modifiedData: PropTypes.object,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||||
|
@ -132,7 +132,9 @@ const reducer = (state, action) => {
|
|||||||
dynamicZoneTarget,
|
dynamicZoneTarget,
|
||||||
'components',
|
'components',
|
||||||
],
|
],
|
||||||
() => fromJS(makeUnique(newComponents))
|
list => {
|
||||||
|
return fromJS(makeUnique([...list.toJS(), ...newComponents]));
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.updateIn(['modifiedData', 'components'], old => {
|
.updateIn(['modifiedData', 'components'], old => {
|
||||||
const componentsSchema = newComponents.reduce((acc, current) => {
|
const componentsSchema = newComponents.reduce((acc, current) => {
|
||||||
|
@ -213,8 +213,10 @@ const FormModal = () => {
|
|||||||
);
|
);
|
||||||
const attributeToEdit = {
|
const attributeToEdit = {
|
||||||
...attributeToEditNotFormatted,
|
...attributeToEditNotFormatted,
|
||||||
|
// We filter the available components
|
||||||
|
// Because this modal is only used for adding components
|
||||||
|
components: [],
|
||||||
name: dynamicZoneTarget,
|
name: dynamicZoneTarget,
|
||||||
// createComponent: true,
|
|
||||||
createComponent: false,
|
createComponent: false,
|
||||||
componentToCreate: { type: 'component' },
|
componentToCreate: { type: 'component' },
|
||||||
};
|
};
|
||||||
@ -1238,6 +1240,7 @@ const FormModal = () => {
|
|||||||
>
|
>
|
||||||
<Inputs
|
<Inputs
|
||||||
{...input}
|
{...input}
|
||||||
|
modifiedData={modifiedData}
|
||||||
addComponentsToDynamicZone={
|
addComponentsToDynamicZone={
|
||||||
handleClickAddComponentsToDynamicZone
|
handleClickAddComponentsToDynamicZone
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const NAME_REGEX = new RegExp('^[A-Za-z][_0-9A-Za-z]*$');
|
const CATEGORY_NAME_REGEX = new RegExp('^[A-Za-z][-_0-9A-Za-z]*$');
|
||||||
const ENUM_REGEX = new RegExp('^[_A-Za-z][_0-9A-Za-z]*$');
|
const ENUM_REGEX = new RegExp('^[_A-Za-z][_0-9A-Za-z]*$');
|
||||||
|
const NAME_REGEX = new RegExp('^[A-Za-z][_0-9A-Za-z]*$');
|
||||||
|
|
||||||
export { ENUM_REGEX, NAME_REGEX };
|
export { CATEGORY_NAME_REGEX, ENUM_REGEX, NAME_REGEX };
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import * as yup from 'yup';
|
import * as yup from 'yup';
|
||||||
import { get, isEmpty, toLower, trim } from 'lodash';
|
import { get, isEmpty, toLower, trim, toNumber } from 'lodash';
|
||||||
import { translatedErrors as errorsTrads } from 'strapi-helper-plugin';
|
import { translatedErrors as errorsTrads } from 'strapi-helper-plugin';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import pluginId from '../../../pluginId';
|
import pluginId from '../../../pluginId';
|
||||||
@ -8,7 +8,11 @@ import getTrad from '../../../utils/getTrad';
|
|||||||
import { createComponentUid, createUid, nameToSlug } from './createUid';
|
import { createComponentUid, createUid, nameToSlug } from './createUid';
|
||||||
import componentForm from './componentForm';
|
import componentForm from './componentForm';
|
||||||
import fields from './staticFields';
|
import fields from './staticFields';
|
||||||
import { NAME_REGEX, ENUM_REGEX } from './attributesRegexes';
|
import {
|
||||||
|
NAME_REGEX,
|
||||||
|
ENUM_REGEX,
|
||||||
|
CATEGORY_NAME_REGEX,
|
||||||
|
} from './attributesRegexes';
|
||||||
import RESERVED_NAMES from './reservedNames';
|
import RESERVED_NAMES from './reservedNames';
|
||||||
|
|
||||||
yup.addMethod(yup.mixed, 'defined', function() {
|
yup.addMethod(yup.mixed, 'defined', function() {
|
||||||
@ -52,6 +56,20 @@ yup.addMethod(yup.string, 'isAllowed', function(message) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
yup.addMethod(yup.string, 'isInferior', function(message, max) {
|
||||||
|
return this.test('isInferior', message, function(min) {
|
||||||
|
if (!min) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Number.isNaN(toNumber(min))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toNumber(max) >= toNumber(min);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const ATTRIBUTES_THAT_DONT_HAVE_MIN_MAX_SETTINGS = [
|
const ATTRIBUTES_THAT_DONT_HAVE_MIN_MAX_SETTINGS = [
|
||||||
'boolean',
|
'boolean',
|
||||||
'date',
|
'date',
|
||||||
@ -210,11 +228,50 @@ const forms = {
|
|||||||
case 'integer':
|
case 'integer':
|
||||||
case 'biginteger':
|
case 'biginteger':
|
||||||
case 'float':
|
case 'float':
|
||||||
case 'decimal':
|
case 'decimal': {
|
||||||
|
if (dataToValidate.type === 'biginteger') {
|
||||||
|
return yup.object().shape({
|
||||||
|
...commonShape,
|
||||||
|
default: yup
|
||||||
|
.string()
|
||||||
|
.nullable()
|
||||||
|
.matches(/^\d*$/),
|
||||||
|
min: yup
|
||||||
|
.string()
|
||||||
|
.nullable()
|
||||||
|
.matches(/^\d*$/)
|
||||||
|
.when('max', (max, schema) => {
|
||||||
|
if (max) {
|
||||||
|
return schema.isInferior(
|
||||||
|
getTrad('error.validation.minSupMax'),
|
||||||
|
max
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
max: yup
|
||||||
|
.string()
|
||||||
|
.nullable()
|
||||||
|
.matches(/^\d*$/),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let defaultType = yup.number();
|
||||||
|
|
||||||
|
if (dataToValidate.type === 'integer') {
|
||||||
|
defaultType = yup
|
||||||
|
.number()
|
||||||
|
.integer('component.Input.error.validation.integer');
|
||||||
|
}
|
||||||
|
|
||||||
return yup.object().shape({
|
return yup.object().shape({
|
||||||
...commonShape,
|
...commonShape,
|
||||||
|
default: defaultType.nullable(),
|
||||||
...numberTypeShape,
|
...numberTypeShape,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
case 'relation':
|
case 'relation':
|
||||||
return yup.object().shape({
|
return yup.object().shape({
|
||||||
name: yup
|
name: yup
|
||||||
@ -312,6 +369,24 @@ const forms = {
|
|||||||
|
|
||||||
const items = defaultItems.slice();
|
const items = defaultItems.slice();
|
||||||
|
|
||||||
|
if (type === 'number' && data.type !== 'biginteger') {
|
||||||
|
const step =
|
||||||
|
data.type === 'decimal' || data.type === 'float' ? 'any' : '1';
|
||||||
|
|
||||||
|
items.splice(0, 1, [
|
||||||
|
{
|
||||||
|
autoFocus: true,
|
||||||
|
name: 'default',
|
||||||
|
type: 'number',
|
||||||
|
step,
|
||||||
|
label: {
|
||||||
|
id: getTrad('form.attribute.settings.default'),
|
||||||
|
},
|
||||||
|
validations: {},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 'media') {
|
if (type === 'media') {
|
||||||
items.splice(0, 1);
|
items.splice(0, 1);
|
||||||
} else if (type === 'boolean') {
|
} else if (type === 'boolean') {
|
||||||
@ -758,7 +833,7 @@ const forms = {
|
|||||||
.required(errorsTrads.required),
|
.required(errorsTrads.required),
|
||||||
category: yup
|
category: yup
|
||||||
.string()
|
.string()
|
||||||
.matches(NAME_REGEX, errorsTrads.regex)
|
.matches(CATEGORY_NAME_REGEX, errorsTrads.regex)
|
||||||
.required(errorsTrads.required),
|
.required(errorsTrads.required),
|
||||||
icon: yup.string().required(errorsTrads.required),
|
icon: yup.string().required(errorsTrads.required),
|
||||||
collectionName: yup.string().nullable(),
|
collectionName: yup.string().nullable(),
|
||||||
@ -821,6 +896,7 @@ const forms = {
|
|||||||
return yup.object().shape({
|
return yup.object().shape({
|
||||||
name: yup
|
name: yup
|
||||||
.string()
|
.string()
|
||||||
|
.matches(CATEGORY_NAME_REGEX, errorsTrads.regex)
|
||||||
.unique(errorsTrads.unique, allowedCategories, toLower)
|
.unique(errorsTrads.unique, allowedCategories, toLower)
|
||||||
.required(errorsTrads.required),
|
.required(errorsTrads.required),
|
||||||
});
|
});
|
||||||
|
@ -34,7 +34,9 @@
|
|||||||
"button.component.add": "Add a component",
|
"button.component.add": "Add a component",
|
||||||
"button.component.create": "Create new component",
|
"button.component.create": "Create new component",
|
||||||
"button.model.create": "Create new content-type",
|
"button.model.create": "Create new content-type",
|
||||||
"components.componentSelect.value-component": "{number} component selected",
|
"components.componentSelect.no-component-available": "You have already added all your components",
|
||||||
|
"components.componentSelect.no-component-available.with-search": "There is no component matching your search",
|
||||||
|
"components.componentSelect.value-component": "{number} component selected (type to search for a component)",
|
||||||
"components.componentSelect.value-components": "{number} components selected",
|
"components.componentSelect.value-components": "{number} components selected",
|
||||||
"component.repeatable": "(repeatable)",
|
"component.repeatable": "(repeatable)",
|
||||||
"configurations": "configurations",
|
"configurations": "configurations",
|
||||||
|
@ -17,6 +17,7 @@ const validators = {
|
|||||||
|
|
||||||
const NAME_REGEX = new RegExp('^[A-Za-z][_0-9A-Za-z]*$');
|
const NAME_REGEX = new RegExp('^[A-Za-z][_0-9A-Za-z]*$');
|
||||||
const COLLECTION_NAME_REGEX = new RegExp('^[A-Za-z][-_0-9A-Za-z]*$');
|
const COLLECTION_NAME_REGEX = new RegExp('^[A-Za-z][-_0-9A-Za-z]*$');
|
||||||
|
const CATEGORY_NAME_REGEX = new RegExp('^[A-Za-z][-_0-9A-Za-z]*$');
|
||||||
const ENUM_REGEX = new RegExp('^[_A-Za-z][_0-9A-Za-z]*$');
|
const ENUM_REGEX = new RegExp('^[_A-Za-z][_0-9A-Za-z]*$');
|
||||||
const ICON_REGEX = new RegExp('^[A-Za-z0-9][-A-Za-z0-9]*$');
|
const ICON_REGEX = new RegExp('^[A-Za-z0-9][-A-Za-z0-9]*$');
|
||||||
|
|
||||||
@ -26,6 +27,12 @@ const isValidName = {
|
|||||||
test: val => val === '' || NAME_REGEX.test(val),
|
test: val => val === '' || NAME_REGEX.test(val),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isValidCategoryName = {
|
||||||
|
name: 'isValidCategoryName',
|
||||||
|
message: '${path} must match the following regex: /^[A-Za-z][_-0-9A-Za-z]*$/',
|
||||||
|
test: val => val === '' || CATEGORY_NAME_REGEX.test(val),
|
||||||
|
};
|
||||||
|
|
||||||
const isValidCollectionName = {
|
const isValidCollectionName = {
|
||||||
name: 'isValidCollectionName',
|
name: 'isValidCollectionName',
|
||||||
message: '${path} must match the following regex: /^[A-Za-z][-_0-9A-Za-z]*$/',
|
message: '${path} must match the following regex: /^[A-Za-z][-_0-9A-Za-z]*$/',
|
||||||
@ -55,6 +62,7 @@ module.exports = {
|
|||||||
validators,
|
validators,
|
||||||
|
|
||||||
isValidCollectionName,
|
isValidCollectionName,
|
||||||
|
isValidCategoryName,
|
||||||
isValidName,
|
isValidName,
|
||||||
isValidIcon,
|
isValidIcon,
|
||||||
isValidKey,
|
isValidKey,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
const yup = require('yup');
|
const yup = require('yup');
|
||||||
const formatYupErrors = require('./yup-formatter');
|
const formatYupErrors = require('./yup-formatter');
|
||||||
|
|
||||||
const { isValidName } = require('./common');
|
const { isValidCategoryName } = require('./common');
|
||||||
|
|
||||||
module.exports = data => {
|
module.exports = data => {
|
||||||
return componentCategorySchema
|
return componentCategorySchema
|
||||||
@ -19,7 +19,7 @@ const componentCategorySchema = yup
|
|||||||
name: yup
|
name: yup
|
||||||
.string()
|
.string()
|
||||||
.min(3)
|
.min(3)
|
||||||
.test(isValidName)
|
.test(isValidCategoryName)
|
||||||
.required('name.required'),
|
.required('name.required'),
|
||||||
})
|
})
|
||||||
.noUnknown();
|
.noUnknown();
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const yup = require('yup');
|
const yup = require('yup');
|
||||||
|
|
||||||
const { isValidName, isValidIcon } = require('./common');
|
const { isValidCategoryName, isValidIcon } = require('./common');
|
||||||
const formatYupErrors = require('./yup-formatter');
|
const formatYupErrors = require('./yup-formatter');
|
||||||
const createSchema = require('./model-schema');
|
const createSchema = require('./model-schema');
|
||||||
const { modelTypes, DEFAULT_TYPES } = require('./constants');
|
const { modelTypes, DEFAULT_TYPES } = require('./constants');
|
||||||
@ -23,7 +23,7 @@ const componentSchema = createSchema(VALID_TYPES, VALID_RELATIONS, {
|
|||||||
category: yup
|
category: yup
|
||||||
.string()
|
.string()
|
||||||
.nullable()
|
.nullable()
|
||||||
.test(isValidName)
|
.test(isValidCategoryName)
|
||||||
.required('category.required'),
|
.required('category.required'),
|
||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-plugin-content-type-builder",
|
"name": "strapi-plugin-content-type-builder",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Strapi plugin to create content type (API).",
|
"description": "Strapi plugin to create content type (API).",
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"name": "Content Type Builder",
|
"name": "Content Type Builder",
|
||||||
@ -29,9 +29,9 @@
|
|||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
"redux-immutable": "^4.0.0",
|
"redux-immutable": "^4.0.0",
|
||||||
"reselect": "^3.0.1",
|
"reselect": "^3.0.1",
|
||||||
"strapi-generate": "3.0.0-beta.18.1",
|
"strapi-generate": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-api": "3.0.0-beta.18.1",
|
"strapi-generate-api": "3.0.0-beta.18.2",
|
||||||
"strapi-helper-plugin": "3.0.0-beta.18.1",
|
"strapi-helper-plugin": "3.0.0-beta.18.2",
|
||||||
"yup": "^0.27.0"
|
"yup": "^0.27.0"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-plugin-documentation",
|
"name": "strapi-plugin-documentation",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "This is the description of the plugin.",
|
"description": "This is the description of the plugin.",
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"name": "Documentation",
|
"name": "Documentation",
|
||||||
@ -32,7 +32,7 @@
|
|||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
"redux-immutable": "^4.0.0",
|
"redux-immutable": "^4.0.0",
|
||||||
"reselect": "^4.0.0",
|
"reselect": "^4.0.0",
|
||||||
"strapi-helper-plugin": "3.0.0-beta.18.1",
|
"strapi-helper-plugin": "3.0.0-beta.18.2",
|
||||||
"swagger-ui-dist": "3.24.3"
|
"swagger-ui-dist": "3.24.3"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -115,7 +115,8 @@
|
|||||||
"required": false,
|
"required": false,
|
||||||
"description": "Get records that matches any value in the array of values",
|
"description": "Get records that matches any value in the array of values",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array"
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
},
|
},
|
||||||
"deprecated": false
|
"deprecated": false
|
||||||
},
|
},
|
||||||
@ -125,8 +126,9 @@
|
|||||||
"required": false,
|
"required": false,
|
||||||
"description": "Get records that doesn't match any value in the array of values",
|
"description": "Get records that doesn't match any value in the array of values",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "array"
|
"type": "array",
|
||||||
|
"items": { "type": "string" }
|
||||||
},
|
},
|
||||||
"deprecated": false
|
"deprecated": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-plugin-email",
|
"name": "strapi-plugin-email",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "This is the description of the plugin.",
|
"description": "This is the description of the plugin.",
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"name": "Email",
|
"name": "Email",
|
||||||
@ -12,13 +12,13 @@
|
|||||||
"test": "echo \"no tests yet\""
|
"test": "echo \"no tests yet\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"strapi-provider-email-sendmail": "3.0.0-beta.18.1",
|
"strapi-provider-email-sendmail": "3.0.0-beta.18.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"react-copy-to-clipboard": "5.0.1",
|
"react-copy-to-clipboard": "5.0.1",
|
||||||
"rimraf": "^2.6.3",
|
"rimraf": "^2.6.3",
|
||||||
"strapi-helper-plugin": "3.0.0-beta.18.1"
|
"strapi-helper-plugin": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Strapi team",
|
"name": "Strapi team",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-plugin-graphql",
|
"name": "strapi-plugin-graphql",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "This is the description of the plugin.",
|
"description": "This is the description of the plugin.",
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"name": "graphql",
|
"name": "graphql",
|
||||||
@ -23,7 +23,7 @@
|
|||||||
"graphql-type-long": "^0.1.1",
|
"graphql-type-long": "^0.1.1",
|
||||||
"koa-compose": "^4.1.0",
|
"koa-compose": "^4.1.0",
|
||||||
"pluralize": "^7.0.0",
|
"pluralize": "^7.0.0",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cross-env": "^5.2.0",
|
"cross-env": "^5.2.0",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-plugin-upload",
|
"name": "strapi-plugin-upload",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "This is the description of the plugin.",
|
"description": "This is the description of the plugin.",
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"name": "Files Upload",
|
"name": "Files Upload",
|
||||||
@ -23,9 +23,9 @@
|
|||||||
"react-router-dom": "^5.0.0",
|
"react-router-dom": "^5.0.0",
|
||||||
"react-transition-group": "^2.5.0",
|
"react-transition-group": "^2.5.0",
|
||||||
"reactstrap": "^5.0.0",
|
"reactstrap": "^5.0.0",
|
||||||
"strapi-helper-plugin": "3.0.0-beta.18.1",
|
"strapi-helper-plugin": "3.0.0-beta.18.2",
|
||||||
"strapi-provider-upload-local": "3.0.0-beta.18.1",
|
"strapi-provider-upload-local": "3.0.0-beta.18.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1",
|
"strapi-utils": "3.0.0-beta.18.2",
|
||||||
"stream-to-array": "^2.3.0",
|
"stream-to-array": "^2.3.0",
|
||||||
"uuid": "^3.2.1"
|
"uuid": "^3.2.1"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-plugin-users-permissions",
|
"name": "strapi-plugin-users-permissions",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Protect your API with a full-authentication process based on JWT",
|
"description": "Protect your API with a full-authentication process based on JWT",
|
||||||
"strapi": {
|
"strapi": {
|
||||||
"name": "Roles & Permissions",
|
"name": "Roles & Permissions",
|
||||||
@ -31,8 +31,8 @@
|
|||||||
"reactstrap": "^5.0.0",
|
"reactstrap": "^5.0.0",
|
||||||
"redux-saga": "^0.16.0",
|
"redux-saga": "^0.16.0",
|
||||||
"request": "^2.83.0",
|
"request": "^2.83.0",
|
||||||
"strapi-helper-plugin": "3.0.0-beta.18.1",
|
"strapi-helper-plugin": "3.0.0-beta.18.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1",
|
"strapi-utils": "3.0.0-beta.18.2",
|
||||||
"uuid": "^3.1.0"
|
"uuid": "^3.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-email-amazon-ses",
|
"name": "strapi-provider-email-amazon-ses",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Amazon SES provider for strapi email",
|
"description": "Amazon SES provider for strapi email",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-email-mailgun",
|
"name": "strapi-provider-email-mailgun",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Mailgun provider for strapi email plugin",
|
"description": "Mailgun provider for strapi email plugin",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-email-sendgrid",
|
"name": "strapi-provider-email-sendgrid",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Sendgrid provider for strapi email",
|
"description": "Sendgrid provider for strapi email",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-email-sendmail",
|
"name": "strapi-provider-email-sendmail",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Sendmail provider for strapi email",
|
"description": "Sendmail provider for strapi email",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-upload-aws-s3",
|
"name": "strapi-provider-upload-aws-s3",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "AWS S3 provider for strapi upload",
|
"description": "AWS S3 provider for strapi upload",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-upload-cloudinary",
|
"name": "strapi-provider-upload-cloudinary",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Cloudinary provider for strapi upload",
|
"description": "Cloudinary provider for strapi upload",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-upload-local",
|
"name": "strapi-provider-upload-local",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Local provider for strapi upload",
|
"description": "Local provider for strapi upload",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-provider-upload-rackspace",
|
"name": "strapi-provider-upload-rackspace",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Rackspace provider for strapi upload",
|
"description": "Rackspace provider for strapi upload",
|
||||||
"main": "./lib",
|
"main": "./lib",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi-utils",
|
"name": "strapi-utils",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "Shared utilities for the Strapi packages",
|
"description": "Shared utilities for the Strapi packages",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "strapi",
|
"name": "strapi",
|
||||||
"version": "3.0.0-beta.18.1",
|
"version": "3.0.0-beta.18.2",
|
||||||
"description": "An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MongoDB, MySQL, MariaDB, PostgreSQL, SQLite",
|
"description": "An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MongoDB, MySQL, MariaDB, PostgreSQL, SQLite",
|
||||||
"homepage": "http://strapi.io",
|
"homepage": "http://strapi.io",
|
||||||
"directories": {
|
"directories": {
|
||||||
@ -49,16 +49,16 @@
|
|||||||
"resolve-cwd": "^3.0.0",
|
"resolve-cwd": "^3.0.0",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
"shelljs": "^0.8.3",
|
"shelljs": "^0.8.3",
|
||||||
"strapi-database": "3.0.0-beta.18.1",
|
"strapi-database": "3.0.0-beta.18.2",
|
||||||
"strapi-generate": "3.0.0-beta.18.1",
|
"strapi-generate": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-api": "3.0.0-beta.18.1",
|
"strapi-generate-api": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-controller": "3.0.0-beta.18.1",
|
"strapi-generate-controller": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-model": "3.0.0-beta.18.1",
|
"strapi-generate-model": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-new": "3.0.0-beta.18.1",
|
"strapi-generate-new": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-plugin": "3.0.0-beta.18.1",
|
"strapi-generate-plugin": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-policy": "3.0.0-beta.18.1",
|
"strapi-generate-policy": "3.0.0-beta.18.2",
|
||||||
"strapi-generate-service": "3.0.0-beta.18.1",
|
"strapi-generate-service": "3.0.0-beta.18.2",
|
||||||
"strapi-utils": "3.0.0-beta.18.1"
|
"strapi-utils": "3.0.0-beta.18.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest --verbose",
|
"test": "jest --verbose",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user