Merge branch 'master' of github.com:strapi/strapi

This commit is contained in:
Alexandre Bodin 2020-06-01 10:29:17 +02:00
commit ffecbd42d1
13 changed files with 90 additions and 50 deletions

View File

@ -10,6 +10,10 @@ Before you start, please make sure your issue is understandable and reproducible
To make your issue readable make sure you use valid Markdown syntax.
https://guides.github.com/features/mastering-markdown/
Please ensure you have also read and understand the contributing guide.
https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md#reporting-an-issue
-->
**Describe the bug**
@ -35,7 +39,7 @@ If applicable, add code samples to help explain your problem.
- Node.js version: <!-- Please ensure you are using the Node LTS version (v12) -->
- NPM version:
- Strapi version: <!-- Please make sure you are on the latest version -->
- Strapi version: <!-- Beta and Alpha versions are no longer supported -->
- Database:
- Operating system:

View File

@ -100,7 +100,7 @@ Options:
All these examples are equivalent.
::: warning
When configuring your application you often enter credentials for thrid party services (e.g authentication providers). Be aware that those credentials will also be dumped into the output of this command.
When configuring your application you often enter credentials for third party services (e.g authentication providers). Be aware that those credentials will also be dumped into the output of this command.
In case of doubt, you should avoid committing the dump file into a versioning system. Here are some methods you can explore:
- Copy the file directly to the environment you want and run the restore command there.
@ -137,7 +137,7 @@ All these examples are equivalent.
When running the restore command, you can choose from three different strategies:
- **replace**: Will create missing keys and replace existing ones.
- **merge**: Will create missing keys and merge existing keys whith there new value.
- **merge**: Will create missing keys and merge existing keys with their new value.
- **keep**: Will create missing keys and keep existing keys as is.
## strapi generate:api

View File

@ -23,7 +23,7 @@ strapi.config.get('server.host', 'defaultValueIfUndefined');
Nested keys are accessible with `dot-notation`.
:::tip NOTE
You can notice the filename is used as prefix to access the configurations.
Notice that the filename is used as a prefix to access the configurations.
:::
## Formats
@ -50,7 +50,7 @@ module.exports = ({ env }) => {
## Environment variables
In most usecases you will have different configurations between your environments. For example: your database credentials.
In most use cases you will have different configurations between your environments. For example: your database credentials.
Instead of writting those credentials into your configuration files, you can define those variables in a `.env` file at the root of your application.
@ -111,9 +111,9 @@ env.date('VAR', new Date());
## Environments
What if you need to specific static configurations for specific environments and using environement variables becomes tedious ?
What if you need to specific static configurations for specific environments and using environment variables becomes tedious?
Strapi configurations can also be created per environment in `./config/env/{env}/{filename}`. These configurations will be merged into the base ones defined in the `./config` folder.
Strapi configurations can also be created per environment in `./config/env/{env}/{filename}`. These configurations will be merged into the base configurations defined in the `./config` folder.
The environment is based on the `NODE_ENV` environment variable (defaults to `development`).
When starting strapi with `NODE_ENV=production` it will load the configuration from `./config/*` and `./config/env/production/*`. Everything defined in the production config will override the default config.
@ -179,7 +179,7 @@ module.exports = ({ env }) => ({
| `admin` | Admin panel configuration | Object | |
| `admin.url` | Url of your admin panel. Default value: `/admin`. Note: If the url is relative, it will be concatenated with `url`. | string | `/admin` |
| `admin.autoOpen` | Enable or disabled administration opening on start. | boolean | `true` |
| `admin.watchIgnoreFiles` | Add custom files that should not be watched during development. See more [here](https://github.com/paulmillr/chokidar#path-filtering) (property `ignored`). | Array(string) | `[]`. |
| `admin.watchIgnoreFiles` | Add custom files that should not be watched during development. See more [here](https://github.com/paulmillr/chokidar#path-filtering) (property `ignored`). | Array(string) | `[]` |
## Functions

View File

@ -65,14 +65,15 @@ It's important to call `throw(error);` to avoid stopping the middleware stack. I
## Configure the middleware
Make sure your middleware is added at the end of the middleware stack.
Make sure your middleware is added at the beginning of the middleware stack.
**Path —** `./config/middleware.js`
```js
module.exports = {
load: {
after: ['parser', 'router', 'sentry'],
before: ['sentry', 'responseTime', 'logger', ...],
...
},
};
```

View File

@ -1,12 +1,12 @@
# Create is owner policy
This guide will explain how to restrict content edition to content authors only.
This guide will explain how to restrict content editing to content authors only.
## Introduction
It is often required that the author of an entry is the only user allowed to edit or delete the entry.
This is a feature that is requested a lot and in this guide we will see how to implement it.
This is a feature that is requested a lot and in this guide we will show how to implement it.
## Example

View File

@ -127,14 +127,14 @@ Please note that by default the `strapi` user **cannot run sudo commands** this
Once you are in the Strapi service account you can now use [PM2](https://pm2.keymetrics.io/docs/usage/quick-start/#managing-processes) to manage the Strapi process and view the logs.
The default service is called `strapi-develop` and should be running with an ID of `0`. Below are some example commands for PM2:
The default service is called `strapi-development` and should be running with an ID of `0`. Below are some example commands for PM2:
```bash
pm2 list # Will show you a list of all running processes
pm2 restart strapi-develop # Restart the Strapi process manually
pm2 stop strapi-develop # Stop the Strapi process
pm2 start strapi-develop # Start the Strapi process
pm2 logs strapi-develop # Show the logs in real time (to exit use ctrl +c)
pm2 restart strapi-development # Restart the Strapi process manually
pm2 stop strapi-development # Stop the Strapi process
pm2 start strapi-development # Start the Strapi process
pm2 logs strapi-development # Show the logs in real time (to exit use ctrl +c)
```
Strapi will automatically start if the virtual machine is rebooted, you can also manually view the log files under `/srv/strapi/.pm2/logs` if you encounter any errors during the bootup.
@ -147,7 +147,7 @@ Use the following steps to change the PostgreSQL password and update Strapi's co
- Stop the current strapi process and change the password for the `strapi` database user
```bash
pm2 stop strapi-develop
pm2 stop strapi-development
psql -c "ALTER USER strapi with password 'your-new-password';"
```
@ -160,6 +160,6 @@ DATABASE_PASSWORD=your-new-password
- Restart Strapi and confirm the password change was successful
```bash
pm2 start strapi-develop
pm2 logs strapi-develop
pm2 start strapi-development
pm2 logs strapi-development
```

View File

@ -1,6 +1,6 @@
# Migration guide from 3.0.0-beta.20 to 3.0.0
Upgrading your strapi application to `3.0.0`.
Upgrading your Strapi application to `3.0.0`.
**Make sure your server is not running until the end of the migration**
@ -32,7 +32,7 @@ Then run either `yarn install` or `npm install`.
## New configuration loader
We have reworked the way a strapi project is configured to make it simpler yet more powerfull.
We have reworked the way a strapi project is configured to make it simpler yet more powerful.
Some of the improvements are:
@ -44,19 +44,19 @@ Before migrating, you should first read the new [configuration documentation](..
### Migrating
**Server**
#### Server
Your server configuration can move from `./config/environments/{env}/server.json` to `./config/server.js` like shown [here](../concepts/configurations.md#server).
**Database configuration**
#### Database configuration
Your database configuration can move from `./config/environments/{env}/database.json` to `./config/database.js` like shown [here](../concepts/configurations.md#database).
**Middlewares**
#### Middlewares
We have moved all the middleware related configurations into one place: `./config/middleware.js`.
The middlewares were configured in mutliple files:
The middlewares were configured in multiple files:
- `./config/middleware.json`
- `./config/application.json`
@ -94,7 +94,7 @@ You can review all possible options the [middleware documentation](../concepts/m
If you never configured any middlewares you can delete the file all together. You can also only set the configurations you want to customize and leave the others out.
:::
**Hook**
#### Hook
We applied the same logic from the `middleware` configuration to the `hook` configuration.
@ -104,19 +104,19 @@ First you can create a file `./config/hook.js`, and you can move the content of
If you never configured any hook you can delete the file all together. You can also only set the configurations you want to customize and leave the others out.
:::
**Functions**
#### Functions
You can leave your functions as is, we didn't change how they work.
**Policies**
#### Policies
You can leave your policies as is, we didn't change how they work.
**Custom**
#### Custom
Any custom configuration you have can still be used. You can read the [configuration documentation](../concepts/configurations.md) to know more.
**Plugin**
#### Plugin
From now on, you can set your plugin configurations in `./config/plugins.js` or `./config/env/{env}/plugin.js`.
@ -130,9 +130,9 @@ module.exports = {
};
```
### Final strucutre
### Final structure
Here is an example of the strucuture you could have after migrating:
Here is an example of the structure you could have after migrating:
**Before**
@ -217,9 +217,9 @@ Once you have setup your configuration, you can cleanup your database by deletin
If you are using the graphql `register` mutation, the input and response types have changed. You can check the code [here](https://github.com/strapi/strapi/pull/6047).
The `changePassword` mutation got renamed to `resetPassword` to reflect what it does. You can check the code [here](https://github.com/strapi/strapi/pull/5655.
The `changePassword` mutation got renamed to `resetPassword` to reflect what it does. You can check the code [here](https://github.com/strapi/strapi/pull/5655).
## Remove `idAttribute` and `idAttributeType` options.
## Remove `idAttribute` and `idAttributeType` options
Currently using the idAttribute and idAttributeType options can break strapi in many ways. Fixing this is going to require a lot of work on the database and content management layer.
@ -235,7 +235,7 @@ We replaced the `proxy` option found in `./config/server.json` by the `url` opti
This option also makes the `admin.build.backend` option obsolete.
This option tells strapi where it is hosted and is usefull for generating links or telling the admin panel where the API is available.
This option tells strapi where it is hosted and is useful for generating links or telling the admin panel where the API is available.
**Before**

View File

@ -1,6 +1,7 @@
{
"Analytics": "Аналитика",
"Content Manager": "Редактор контента",
"Content Type Builder": "Типы контента",
"Documentation": "Документация",
"Email": "E-mail",
"Files Upload": "Загрузка файлов",
@ -31,6 +32,7 @@
"app.components.HomePage.button.quickStart": "ОЗНАКОМИТЬСЯ С РУКОВОДСТВОМ ПО БЫСТРОМУ СТАРТУ",
"app.components.HomePage.community": "Найдите сообщество в интернете",
"app.components.HomePage.community.content": "Обсуждайте с членами команды и разработчиками в разных каналах.",
"app.components.HomePage.create": "Создайте свой первый тип контента",
"app.components.HomePage.createBlock.content.first": " ",
"app.components.HomePage.createBlock.content.second": " — плагин, который поможет вам определить структуру ваших моделей данных. Если вы новичок, мы настоятельно рекомендуем вам изучить наше ",
"app.components.HomePage.createBlock.content.tutorial": " руководство.",
@ -74,7 +76,8 @@
"app.components.LeftMenuLinkContainer.general": "Общие",
"app.components.LeftMenuLinkContainer.installNewPlugin": "Магазин",
"app.components.LeftMenuLinkContainer.listPlugins": "Плагины",
"app.components.LeftMenuLinkContainer.contentTypes": "Типы контента",
"app.components.LeftMenuLinkContainer.collectionTypes": "Коллекции",
"app.components.LeftMenuLinkContainer.singleTypes": "Страницы",
"app.components.LeftMenuLinkContainer.noPluginsInstalled": "Нет установленных плагинов",
"app.components.LeftMenuLinkContainer.plugins": "Плагины",
"app.components.LeftMenuLinkContainer.settings": "Настройки",
@ -121,6 +124,9 @@
"components.FilterOptions.FILTER_TYPES._lt": "меньше чем",
"components.FilterOptions.FILTER_TYPES._lte": "меньше или равно",
"components.FilterOptions.FILTER_TYPES._ne": "не равно",
"components.FilterOptions.FILTER_TYPES._ncontains": "не содержит",
"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": "Поле с таким названием уже существует",
@ -146,6 +152,7 @@
"components.PageFooter.select": "записей на странице",
"components.ProductionBlocker.description": "В целях безопасности мы должны отключить этот плагин в других средах.",
"components.ProductionBlocker.header": "Этот плагин доступен только на стадии разработки.",
"components.Search.placeholder": "Поиск...",
"components.Wysiwyg.ToggleMode.markdown": "Переключиться в режим markdown",
"components.Wysiwyg.ToggleMode.preview": "Переключиться в режим предпросмотра",
"components.Wysiwyg.collapse": "Свернуть",
@ -168,12 +175,14 @@
"notification.error.layout": "Не удалось получить макет",
"request.error.model.unknown": "Модель данных не существует",
"app.utils.delete": "Удалить",
"app.utils.filters": "Фильтры",
"HomePage.helmet.title": "Домашняя страница",
"HomePage.welcome.congrats": "Поздравляем!",
"HomePage.welcome.congrats.content": "Вы вошли как первый администратор. Чтобы открыть для себя мощные функции, предоставляемые Strapi,",
"HomePage.welcome.congrats.content.bold": "мы рекомендуем вам создать свою первую коллекцию.",
"HomePage.community": "Присоединяйтесь к сообществу",
"HomePage.roadmap": "Смотрите нашу дорожную карту",
"HomePage.greetings": "Привет {name}!",
"HomePage.greetings": "Привет, {name}!",
"Auth.advanced.allow_register": "",
"Auth.privacy-policy-agreement.terms": "условия",
"Auth.privacy-policy-agreement.policy": "политика конфиденциальности",
@ -209,16 +218,16 @@
"Auth.form.login.password.label": "Пароль",
"Auth.form.login.rememberMe.label": "Запомнить меня",
"Auth.form.login.username.label": "Имя пользователя",
"Auth.form.login.username.placeholder": "John Doe",
"Auth.form.login.username.placeholder": "Иван Иванов",
"Auth.form.register-success.email.label": "Письмо успешно отправлено e-mail",
"Auth.form.register-success.email.placeholder": "mysuperemail@gmail.com",
"Auth.form.register.confirmPassword.label": "Подтверждение пароля",
"Auth.form.register.email.label": "E-mail",
"Auth.form.register.email.placeholder": "johndoe@gmail.com",
"Auth.form.register.email.placeholder": "ivanivanov@gmail.com",
"Auth.form.register.news.label": "Держите меня в курсе о новых функциях и предстоящих улучшениях (делая это, вы принимаете {terms} и {policy}).",
"Auth.form.register.password.label": "Пароль",
"Auth.form.register.username.label": "Имя пользователя",
"Auth.form.register.username.placeholder": "John Doe",
"Auth.form.register.username.placeholder": "Иван Иванов",
"Auth.header.register.description": "Для завершения установки и обеспечения безопасности приложения, создайте вашего первого пользователя (root admin), заполнив форму ниже.",
"Auth.link.forgot-password": "Забыли пароль?",
"Auth.link.ready": "Готовы войти?",
@ -258,7 +267,9 @@
"components.Input.error.password.noMatch": "Пароль не совпадает",
"form.button.done": "Выполнено",
"form.button.finish": "Финиш",
"notification.contentType.relations.conflict": "Некоторые элементы ссылаются на данный тип контента",
"notification.form.error.fields": "Форма содержит некоторые ошибки",
"notification.form.success.fields": "Изменения сохранены",
"notification.success.delete": "Элемент удален",
"global.prompt.unsaved": "Вы действительно хотите покинуть эту страницу? Все Ваши изменения будут потеряны"
}

View File

@ -1,7 +1,7 @@
'use strict';
/**
* Read the documentation (https://strapi.io/documentation/v3.x/concepts/models.html#life-cycle-callbacks)
* Read the documentation (https://strapi.io/documentation/v3.x/concepts/models.html#lifecycle-hooks)
* to customize this model
*/

View File

@ -160,11 +160,11 @@
"popUpWarning.bodyMessage.contentType.delete": "Weet je zeker dat je dit collectie type wilt verwijderen?",
"prompt.unsaved": "Weet je zeker dat je wilt stoppen? Al uw wijzigingen gaan verloren.",
"relation.attributeName.placeholder": "Bijv.: auteur, categorie, tag",
"relation.manyToMany": "heeft en behoord tot veel",
"relation.manyToOne": "heeft veel en behoord tot één",
"relation.manyToMany": "heeft en behoort tot veel",
"relation.manyToOne": "heeft veel en behoort tot één",
"relation.manyWay": "heeft veel",
"relation.oneToMany": "behoord tot vele",
"relation.oneToOne": "heeft en behoord tot één",
"relation.oneToMany": "behoort tot vele",
"relation.oneToOne": "heeft en behoort tot één",
"relation.oneWay": "heeft één",
"table.attributes.title.plural": "{number} velden",
"table.attributes.title.singular": "{number} veld"

View File

@ -0,0 +1,12 @@
import styled from 'styled-components';
import { colors } from '@buffetjs/styles';
const ErrorMessage = styled.p`
font-size: 1.3rem !important;
padding-top: 5px;
margin: 0;
color: ${colors.darkOrange};
`;
export default ErrorMessage;

View File

@ -1,7 +1,11 @@
import styled from 'styled-components';
const Wrapper = styled.div`
margin-bottom: 2.3rem;
margin-bottom: ${({ hasError }) => (hasError ? '1.7rem' : '2.3rem')};
`;
Wrapper.defaultProps = {
hasError: false,
};
export default Wrapper;

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { get } from 'lodash';
import { get, isEmpty } from 'lodash';
import { prefixFileUrlWithBackendUrl } from 'strapi-helper-plugin';
import { getTrad, formatFileForEditing } from '../../utils';
@ -16,8 +16,9 @@ import InputModalStepper from '../../containers/InputModalStepper';
import Name from './Name';
import Wrapper from './Wrapper';
import Input from '../Input';
import ErrorMessage from './ErrorMessage';
const InputMedia = ({ label, onChange, name, attribute, value, type }) => {
const InputMedia = ({ label, onChange, name, attribute, value, type, id, error }) => {
const [modal, setModal] = useState({
isOpen: false,
step: 'list',
@ -31,6 +32,8 @@ const InputMedia = ({ label, onChange, name, attribute, value, type }) => {
const prefixedFileURL = fileURL ? prefixFileUrlWithBackendUrl(fileURL) : null;
const displaySlidePagination =
attribute.multiple && value.length > 1 ? ` (${fileToDisplay + 1}/${value.length})` : '';
const inputId = id || name;
const errorId = `error-${inputId}`;
useEffect(() => {
setFileToDisplay(0);
@ -104,7 +107,7 @@ const InputMedia = ({ label, onChange, name, attribute, value, type }) => {
};
return (
<Wrapper>
<Wrapper hasError={!isEmpty(error)}>
<Name htmlFor={name}>{`${label}${displaySlidePagination}`}</Name>
<CardPreviewWrapper onDragOver={handleAllowDrop} onDrop={handleDrop}>
@ -166,6 +169,7 @@ const InputMedia = ({ label, onChange, name, attribute, value, type }) => {
allowedTypes={attribute.allowedTypes}
/>
)}
{error && <ErrorMessage id={errorId}>{error}</ErrorMessage>}
</Wrapper>
);
};
@ -177,6 +181,8 @@ InputMedia.propTypes = {
required: PropTypes.bool,
type: PropTypes.string,
}).isRequired,
error: PropTypes.string,
id: PropTypes.string,
label: PropTypes.string,
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
@ -184,6 +190,8 @@ InputMedia.propTypes = {
value: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
};
InputMedia.defaultProps = {
id: null,
error: null,
label: '',
value: null,
};