diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0b97e00b61..eeda5718dd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,18 +2,26 @@ -My PR is a: +**My PR is a:** - [ ] 💥 Breaking change - [ ] 🐛 Bug fix #issueNumber - [ ] 💅 Enhancement - [ ] 🚀 New feature -Main update on the: +**Main update on the:** - [ ] Admin - [ ] Documentation - [ ] Framework - [ ] Plugin + +**Manual testing done on the follow databases:** +- [ ] Not applicable +- [ ] MongoDB +- [ ] MySQL +- [ ] Postgres + +**Description:** diff --git a/README.md b/README.md index ded3a2b0a9..dcabfe8d68 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Node: * NodeJS >= 10.x * NPM >= 6.x -**Please note that right now Node 11 is not Officially supported, and the current Node LTS (v10) should be used.** +**Please note that right now Node 11 is not supported, and the current Node LTS (v10) should be used.** Database: * MongoDB >= 3.x @@ -71,8 +71,8 @@ Database: npm install strapi@alpha -g ```` -**We recommend to use the latest version of Strapi to start your new project**. -Some breaking changes might happen, new releases are shipped every two weeks to fix/enhance the product. +**We recommend always using the latest version of Strapi to start your new project**. +As this project is currently in Alpha, some breaking changes may occur. New releases are shipped every two weeks to fix/enhance the project. #### 🏗 Create a new project @@ -80,7 +80,7 @@ Some breaking changes might happen, new releases are shipped every two weeks to strapi new my-project ``` -It will generate a brand new project with the default features (authentication, permissions, content management, content type builder & file upload). +This command will generate a brand new project with the default features (authentication, permissions, content management, content type builder & file upload). #### 🚀 Start your project @@ -109,8 +109,7 @@ Be aware that one of the content type builder won't work due to the writing file ## Features -- **Modern Admin Panel:** - Elegant, entirely customizable and fully extensible admin panel. +- **Modern Admin Panel:** Elegant, entirely customizable and fully extensible admin panel. - **Secure by default:** Reusable policies, CSRF, CORS, P3P, Xframe, XSS, and more. - **Plugins Oriented:** Install auth system, content management, custom plugins, and more, in seconds. - **Blazing Fast:** Built on top of Node.js, Strapi delivers amazing performances. @@ -133,7 +132,7 @@ For more information on the upcoming version, please take a look to our [ROADMAP For general help using Strapi, please refer to [the official Strapi documentation](https://strapi.io/documentation/). For additional help, you can use one of this channel to ask question: - [StackOverflow](http://stackoverflow.com/questions/tagged/strapi) -- [Slack](http://slack.strapi.io) (highly recommended for realtime support) +- [Slack](http://slack.strapi.io) (highly recommended for faster support) - [GitHub](https://github.com/strapi/strapi) - [Twitter](https://twitter.com/strapijs) - [Facebook](https://www.facebook.com/Strapi-616063331867161). diff --git a/docs/3.x.x/getting-started/installation.md b/docs/3.x.x/getting-started/installation.md index 821079ca66..683a1d7c0c 100644 --- a/docs/3.x.x/getting-started/installation.md +++ b/docs/3.x.x/getting-started/installation.md @@ -28,9 +28,9 @@ npm install strapi@alpha -g If you encounter npm permissions issues, [change the permissions to npm default directory](https://docs.npmjs.com/getting-started/fixing-npm-permissions#option-1-change-the-permission-to-npms-default-directory). ::: -It takes about 20 seconds with a good Internet connection. You can take a coffee ☕️ if you have a slow one. +It takes about 20 seconds with a good Internet connection. You can take a coffee ☕️ break if your internet is slow. -Having troubles during the installation? Check if someone already had the [same issue](https://github.com/strapi/strapi/issues). If not, please [post one](https://github.com/strapi/strapi/issues/new). +Having troubles during the installation? Check if someone already had the [same issue](https://github.com/strapi/strapi/issues). If not, please [submit an issue](https://github.com/strapi/strapi/issues/new). ## Check installation diff --git a/docs/3.x.x/guides/deployment.md b/docs/3.x.x/guides/deployment.md index 3c69f63588..eaf8a6da34 100644 --- a/docs/3.x.x/guides/deployment.md +++ b/docs/3.x.x/guides/deployment.md @@ -21,6 +21,22 @@ Update the `production` settings with the IP and domain name where the project w In case your database is not running on the same server, make sure that the environment of your production database (`./config/environments/production/database.json`) is set properly. +If you are passing a number of configuration item values via environment variables which is always encouraged for production environment to keep application stateless, checkout the section for [Dynamic Configuration](../configurations/configurations.md#dynamic-configurations). Here is a hint on how to do it for production, for the configuration mentioned above: + + **Path —** `./config/environments/production/server.json`. +```js +{ + "host": "${process.env.APP_HOST || '127.0.0.1'}" + "port": "${process.env.NODE_PORT || 1337}", + "autoReload": { + "enabled": false + }, + "admin": { + "path": "/dashboard" // We highly recommend to change the default `/admin` path for security reasons. + } +} +``` + **⚠️ If you changed the path to access to the administration, the step #2 is required.** #### #2 - Setup (optional) diff --git a/docs/3.x.x/guides/filters.md b/docs/3.x.x/guides/filters.md index 262bf885b9..315401fd59 100644 --- a/docs/3.x.x/guides/filters.md +++ b/docs/3.x.x/guides/filters.md @@ -82,7 +82,7 @@ Requests system can be implemented in custom code sections. ### Extracting requests filters -To extract the filters from an JavaScript object or a request, you need to call the [`strapi.utils.models.convertParams` helper](../api-reference/reference.md#strapiutils). +To extract the filters from a JavaScript object or a request, you need to call the [`strapi.utils.models.convertParams` helper](../api-reference/reference.md#strapiutils). ::: note The returned objects are formatted according to the ORM used by the model. diff --git a/docs/3.x.x/guides/graphql.md b/docs/3.x.x/guides/graphql.md index e2c120af41..48dfa1752f 100644 --- a/docs/3.x.x/guides/graphql.md +++ b/docs/3.x.x/guides/graphql.md @@ -194,7 +194,7 @@ You can also apply different parameters to the query to make more complex querie - `_lt`: Lower than. - `_lte`: Lower than or equal to. - `_gt`: Greater than. - - `_gte`: Lower than or equal to. + - `_gte`: Greater than or equal to. - `_contains`: Contains. - `_containss`: Contains sensitive. diff --git a/docs/3.x.x/guides/models.md b/docs/3.x.x/guides/models.md index fd9b43071e..df28f7ddec 100644 --- a/docs/3.x.x/guides/models.md +++ b/docs/3.x.x/guides/models.md @@ -27,6 +27,7 @@ The info key on the model-json states information about the model. This informat The options key on the model-json states. - `idAttribute`: This tells the model which attribute to expect as the unique identifier for each database row (typically an auto-incrementing primary key named 'id'). _Only valid for strapi-hook-bookshelf_ - `idAttributeType`: Data type of `idAttribute`, accepted list of value bellow. _Only valid for strapi-hook-bookshelf_ + - `timestamps`: This tells the model which attributes to use for timestamps. Accepts either `boolean` or `Array` of strings where frist element is create data and second elemtent is update date. Default value when set to `true` for Bookshelf is `["created_at", "updated_at"]` and for MongoDB is `["createdAt", "updatedAt"]`. ## Define the attributes @@ -56,6 +57,7 @@ If you're using SQL databases, you should use the native SQL constraints to appl - `required` (boolean) — if true adds a required validator for this property. - `unique` (boolean) — whether to define a unique index on this property. + - `index` (boolean) — adds an index on this property, this will create a [single field index](https://docs.mongodb.com/manual/indexes/#single-field) that will run in the background (*only supported by MongoDB*). - `max` (integer) — checks if the value is greater than or equal to the given minimum. - `min` (integer) — checks if the value is less than or equal to the given maximum. @@ -100,7 +102,8 @@ To improve the Developer eXperience when developing or using the administration "age": { "type": "integer", "min": 18, - "max": 99 + "max": 99, + "index": true }, "birthday": { "type": "date" diff --git a/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js b/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js index fda0e7abc4..ec6f44ca77 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js +++ b/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js @@ -8,6 +8,8 @@ import React from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import { PropTypes } from 'prop-types'; +import LeftMenuLink from 'components/LeftMenuLink'; + import styles from './styles.scss'; import messages from './messages.json'; defineMessages(messages); @@ -15,8 +17,22 @@ defineMessages(messages); function LeftMenuFooter({ version }) { // eslint-disable-line react/prefer-stateless-function return (
- - v{version} +
    + + +
+
); } diff --git a/packages/strapi-admin/admin/src/components/LeftMenuFooter/messages.json b/packages/strapi-admin/admin/src/components/LeftMenuFooter/messages.json index 1259c5c559..6db35356c0 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuFooter/messages.json +++ b/packages/strapi-admin/admin/src/components/LeftMenuFooter/messages.json @@ -1,4 +1,12 @@ { + "documentation": { + "id": "app.components.LeftMenuFooter.documentation", + "defaultMessage": "Documentation" + }, + "help": { + "id": "app.components.LeftMenuFooter.help", + "defaultMessage": "Help" + }, "poweredBy": { "id": "app.components.LeftMenuFooter.poweredBy", "defaultMessage": "Proudly powered by " diff --git a/packages/strapi-admin/admin/src/components/LeftMenuFooter/styles.scss b/packages/strapi-admin/admin/src/components/LeftMenuFooter/styles.scss index ad1f464c5d..e4d6360667 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuFooter/styles.scss +++ b/packages/strapi-admin/admin/src/components/LeftMenuFooter/styles.scss @@ -4,26 +4,27 @@ .leftMenuFooter { /* stylelint-disable */ position: absolute; width: 100%; - display: flex; - justify-content: space-between; + background: $left-menu-bg; + bottom: 0; +} + +.list { + list-style: none; + padding: 0; + margin-bottom: 0; +} + +.poweredBy { + width: 100%; bottom: 0; height: 3rem; padding-left: 15px; padding-right: 15px; line-height: 3rem; - font-family: 'Lato'; background-color: rgba(255, 255, 255, .02); font-size: 1rem; font-weight: 400; letter-spacing: 0.05rem; vertical-align: middle; color: $strapi-gray-light; - - a { - color: #0097f7; - } - - select{ - outline: none; - } } diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js index d37f84e0bc..3ee932c32c 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js +++ b/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js @@ -47,8 +47,22 @@ class LeftMenuLink extends React.Component { {this.props.label} ); - return ( -
  • + // Icon. + const icon = ; + + // Create external or internal link. + const link = this.props.destination.includes('http') + ? ( + + {icon} + {content} + + ) + : ( - + {icon} {content} + ); + + return ( +
  • + {link} {plugin}
  • ); diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/styles.scss b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/styles.scss index bdf52d6f93..ac571ffbea 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/styles.scss +++ b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/styles.scss @@ -3,6 +3,7 @@ .leftMenuLinkContainer { /* stylelint-ignore */ padding-top: .6rem; + padding-bottom: 10.2rem; // LeftMenuFooter height position: absolute; top: 60px; right: 0; diff --git a/packages/strapi-admin/admin/src/components/Logout/index.js b/packages/strapi-admin/admin/src/components/Logout/index.js index c97d9a9c35..2f94aabc0a 100644 --- a/packages/strapi-admin/admin/src/components/Logout/index.js +++ b/packages/strapi-admin/admin/src/components/Logout/index.js @@ -5,6 +5,7 @@ */ import React from 'react'; +import { FormattedMessage } from 'react-intl'; import { get } from 'lodash'; import PropTypes from 'prop-types'; import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap'; @@ -40,10 +41,10 @@ class Logout extends React.Component { // eslint-disable-line react/prefer-state - Profile + - Logout + diff --git a/packages/strapi-admin/admin/src/containers/AdminPage/index.js b/packages/strapi-admin/admin/src/containers/AdminPage/index.js index 72c6a31ce9..0580bb6dea 100644 --- a/packages/strapi-admin/admin/src/containers/AdminPage/index.js +++ b/packages/strapi-admin/admin/src/containers/AdminPage/index.js @@ -256,6 +256,7 @@ AdminPage.propTypes = { blockApp: PropTypes.bool.isRequired, disableGlobalOverlayBlocker: PropTypes.func.isRequired, enableGlobalOverlayBlocker: PropTypes.func.isRequired, + getAdminData: PropTypes.func.isRequired, hasUserPlugin: PropTypes.bool, history: PropTypes.object.isRequired, isAppLoading: PropTypes.bool, diff --git a/packages/strapi-admin/admin/src/translations/ar.json b/packages/strapi-admin/admin/src/translations/ar.json index 6202ac2ee8..434cc5bb7c 100644 --- a/packages/strapi-admin/admin/src/translations/ar.json +++ b/packages/strapi-admin/admin/src/translations/ar.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "قائمة الإضافيات المثبتة في المشروع.", "app.components.ListPluginsPage.helmet.title": "قائمة الإضافات", "app.components.ListPluginsPage.title": "الإضافات", + "app.components.Logout.profile": "الملف الشخصي", + "app.components.Logout.logout": "الخروج", "app.components.NotFoundPage.back": "العودة للرئيسية", "app.components.NotFoundPage.description": "لا يوجد", "app.components.Official": "الرسمية", @@ -138,4 +140,4 @@ "notification.error.layout": "تعذّر استرداد التنسيق", "request.error.model.unknow": "هذا النموذج غير موجود", "request.error.model.unknown": "هذا النموذج غير موجود" -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/de.json b/packages/strapi-admin/admin/src/translations/de.json index 05ecb5c30d..70cc7a304a 100644 --- a/packages/strapi-admin/admin/src/translations/de.json +++ b/packages/strapi-admin/admin/src/translations/de.json @@ -75,6 +75,8 @@ "app.components.LeftMenuLinkContainer.plugins": "Plugins", "app.components.ListPluginsPage.description": "Liste aller im Projekt installierten Plugins.", "app.components.ListPluginsPage.helmet.title": "Plugins anzeigen", + "app.components.Logout.profile": "Profil", + "app.components.Logout.logout": "Ausloggen", "app.components.ListPluginsPage.title": "Plugins", "app.components.NotFoundPage.back": "Zurück zur Homepage", "app.components.NotFoundPage.description": "Nicht gefunden", diff --git a/packages/strapi-admin/admin/src/translations/en.json b/packages/strapi-admin/admin/src/translations/en.json index ed3f265cfe..c2f67b952b 100644 --- a/packages/strapi-admin/admin/src/translations/en.json +++ b/packages/strapi-admin/admin/src/translations/en.json @@ -65,6 +65,8 @@ "app.components.InstallPluginPopup.navLink.faq": "faq", "app.components.InstallPluginPopup.navLink.screenshots": "Screenshots", "app.components.InstallPluginPopup.noDescription": "No description available", + "app.components.LeftMenuFooter.documentation": "Documentation", + "app.components.LeftMenuFooter.help": "Help", "app.components.LeftMenuFooter.poweredBy": "Powered by ", "app.components.LeftMenuLinkContainer.configuration": "Configurations", "app.components.LeftMenuLinkContainer.general": "General", @@ -75,6 +77,8 @@ "app.components.ListPluginsPage.description": "List of the installed plugins in the project.", "app.components.ListPluginsPage.helmet.title": "List plugins", "app.components.ListPluginsPage.title": "Plugins", + "app.components.Logout.profile": "Profile", + "app.components.Logout.logout": "Logout", "app.components.NotFoundPage.back": "Back to homepage", "app.components.NotFoundPage.description": "Not Found", "app.components.Official": "Official", @@ -138,4 +142,4 @@ "notification.error.layout": "Couldn't retrieve the layout", "request.error.model.unknown": "This model doesn't exist", "app.utils.delete": "Delete" -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/es.json b/packages/strapi-admin/admin/src/translations/es.json index d12f1837f6..fb109317e3 100644 --- a/packages/strapi-admin/admin/src/translations/es.json +++ b/packages/strapi-admin/admin/src/translations/es.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Lista de los plugins instalados en el proyecto.", "app.components.ListPluginsPage.helmet.title": "Lista de plugins", "app.components.ListPluginsPage.title": "Plugins", + "app.components.Logout.profile": "Perfil", + "app.components.Logout.logout": "Cerrar sesión", "app.components.NotFoundPage.back": "Volver a la página de inicio", "app.components.NotFoundPage.description": "No encontrado", "app.components.Official": "Oficial", @@ -138,4 +140,4 @@ "notification.error.layout": "No se pudo recuperar el esquema", "request.error.model.unknown": "Este modelo no existe", "app.utils.delete": "Eliminar" -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/fr.json b/packages/strapi-admin/admin/src/translations/fr.json index 7f002a80e8..a3e01582a2 100644 --- a/packages/strapi-admin/admin/src/translations/fr.json +++ b/packages/strapi-admin/admin/src/translations/fr.json @@ -66,6 +66,8 @@ "app.components.InstallPluginPopup.navLink.faq": "FAQ", "app.components.InstallPluginPopup.navLink.screenshots": "Captures d'écran", "app.components.InstallPluginPopup.noDescription": "Aucune description disponible", + "app.components.LeftMenuFooter.documentation": "Documentation", + "app.components.LeftMenuFooter.help": "Aide", "app.components.LeftMenuFooter.poweredBy": "Propulsé par ", "app.components.LeftMenuLinkContainer.configuration": "Configurations", "app.components.LeftMenuLinkContainer.general": "Général", @@ -75,6 +77,8 @@ "app.components.LeftMenuLinkContainer.plugins": "Plugins", "app.components.ListPluginsPage.description": "Liste des plugins installés dans le projet.", "app.components.ListPluginsPage.helmet.title": "List plugins", + "app.components.Logout.profile": "Profil", + "app.components.Logout.logout": "Connectez - Out", "app.components.ListPluginsPage.title": "Plugins", "app.components.NotFoundPage.back": "Retourner à la page d'accueil", "app.components.NotFoundPage.description": "Page introuvable", diff --git a/packages/strapi-admin/admin/src/translations/it.json b/packages/strapi-admin/admin/src/translations/it.json index 6e97e59eca..872f38ee0e 100644 --- a/packages/strapi-admin/admin/src/translations/it.json +++ b/packages/strapi-admin/admin/src/translations/it.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Lista dei plugin installati nel progetto.", "app.components.ListPluginsPage.helmet.title": "Lista plugin", "app.components.ListPluginsPage.title": "Plugins", + "app.components.Logout.profile": "Profilo", + "app.components.Logout.logout": "Disconnettersi", "app.components.NotFoundPage.back": "Torna alla home", "app.components.NotFoundPage.description": "Non trovato", "app.components.Official": "Ufficiale", diff --git a/packages/strapi-admin/admin/src/translations/ja.json b/packages/strapi-admin/admin/src/translations/ja.json index dc940acb2f..4207c7f8b3 100644 --- a/packages/strapi-admin/admin/src/translations/ja.json +++ b/packages/strapi-admin/admin/src/translations/ja.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "このプロジェクトでインストールされたプラグイン一覧", "app.components.ListPluginsPage.helmet.title": "プラグイン一覧", "app.components.ListPluginsPage.title": "プラグイン", + "app.components.Logout.profile": "プロフィール", + "app.components.Logout.logout": "ログアウト", "app.components.NotFoundPage.back": "ホームページに戻る", "app.components.NotFoundPage.description": "見つかりません", "app.components.Official": "オフィシャル", diff --git a/packages/strapi-admin/admin/src/translations/ko.json b/packages/strapi-admin/admin/src/translations/ko.json index 50f7c3321b..8fd25623f2 100644 --- a/packages/strapi-admin/admin/src/translations/ko.json +++ b/packages/strapi-admin/admin/src/translations/ko.json @@ -74,6 +74,8 @@ "app.components.ListPluginsPage.description": "이 프로젝트에 설치된 플러그인 목록입니다.", "app.components.ListPluginsPage.helmet.title": "플러그인 목록", "app.components.ListPluginsPage.title": "플러그인", + "app.components.Logout.profile": "옆모습", + "app.components.Logout.logout": "로그 아웃", "app.components.NotFoundPage.back": "홈으로 돌아가기", "app.components.NotFoundPage.description": "찾을 수 없는 페이지입니다.", "app.components.Official": "공식", @@ -136,4 +138,4 @@ "notification.error": "에러가 발생했습니다.", "notification.error.layout": "레이아웃을 가져올 수 없습니다.", "request.error.model.unknown": "모델이 없습니다." -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/nl.json b/packages/strapi-admin/admin/src/translations/nl.json index aba6364ec7..cc573ccf02 100644 --- a/packages/strapi-admin/admin/src/translations/nl.json +++ b/packages/strapi-admin/admin/src/translations/nl.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Lijst van alle plugins voor dit project", "app.components.ListPluginsPage.helmet.title": "Alle extensies", "app.components.ListPluginsPage.title": "Extensies", + "app.components.Logout.profile": "Profil", + "app.components.Logout.logout": "Log ud", "app.components.NotFoundPage.back": "Terug naar home pagina", "app.components.NotFoundPage.description": "Niets gevonden", "app.components.Official": "Officieel", @@ -137,4 +139,4 @@ "notification.error": "Er is een fout opgetreden", "notification.error.layout": "Kon de opzet niet laden", "request.error.model.unknown": "Dit model bestaat niet" -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/pl.json b/packages/strapi-admin/admin/src/translations/pl.json index a0f72f429e..521e345e75 100644 --- a/packages/strapi-admin/admin/src/translations/pl.json +++ b/packages/strapi-admin/admin/src/translations/pl.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Lista zainstalowanych wtyczek w projekcie.", "app.components.ListPluginsPage.helmet.title": "Lista wtyczek", "app.components.ListPluginsPage.title": "Wtyczki", + "app.components.Logout.profile": "Profil", + "app.components.Logout.logout": "Wyloguj", "app.components.NotFoundPage.back": "Powrót do strony głównej", "app.components.NotFoundPage.description": "Nie znaleziono", "app.components.Official": "Oficjalna", diff --git a/packages/strapi-admin/admin/src/translations/pt-BR.json b/packages/strapi-admin/admin/src/translations/pt-BR.json index 0c1282247e..f47a81e4d5 100644 --- a/packages/strapi-admin/admin/src/translations/pt-BR.json +++ b/packages/strapi-admin/admin/src/translations/pt-BR.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Lista de extensões instaladas no projeto.", "app.components.ListPluginsPage.helmet.title": "Lista de extensões", "app.components.ListPluginsPage.title": "Extensões", + "app.components.Logout.profile": "Perfil", + "app.components.Logout.logout": "Sair", "app.components.NotFoundPage.back": "Voltar à página inicial", "app.components.NotFoundPage.description": "Não encontrado", "app.components.Official": "Oficial", diff --git a/packages/strapi-admin/admin/src/translations/pt.json b/packages/strapi-admin/admin/src/translations/pt.json index 7e2be79f02..9cbe9da034 100644 --- a/packages/strapi-admin/admin/src/translations/pt.json +++ b/packages/strapi-admin/admin/src/translations/pt.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Lista de extensões instaladas no projecto.", "app.components.ListPluginsPage.helmet.title": "Lista de extensões", "app.components.ListPluginsPage.title": "Extensões", + "app.components.Logout.profile": "Perfil", + "app.components.Logout.logout": "Sair", "app.components.NotFoundPage.back": "Voltar à página inicial", "app.components.NotFoundPage.description": "Não encontrado", "app.components.Official": "Oficial", @@ -137,4 +139,4 @@ "notification.error": "Ocorreu um erro", "notification.error.layout": "Não foi possível recuperar o layout", "request.error.model.unknown": "Este modelo não existe" -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/ru.json b/packages/strapi-admin/admin/src/translations/ru.json index 777f92ea62..c4a2f26fa0 100644 --- a/packages/strapi-admin/admin/src/translations/ru.json +++ b/packages/strapi-admin/admin/src/translations/ru.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Список установленных плагинов.", "app.components.ListPluginsPage.helmet.title": "Список плагинов", "app.components.ListPluginsPage.title": "Плагины", + "app.components.Logout.profile": "Профиль", + "app.components.Logout.logout": "Выйти", "app.components.NotFoundPage.back": "Вернуться на главную", "app.components.NotFoundPage.description": "Не найдено", "app.components.Official": "Официальный", diff --git a/packages/strapi-admin/admin/src/translations/tr.json b/packages/strapi-admin/admin/src/translations/tr.json index a617294458..e381ea668a 100644 --- a/packages/strapi-admin/admin/src/translations/tr.json +++ b/packages/strapi-admin/admin/src/translations/tr.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "Projedeki yüklenen eklentiler.", "app.components.ListPluginsPage.helmet.title": "Eklenti Listesi", "app.components.ListPluginsPage.title": "Etklentiler", + "app.components.Logout.profile": "Profil", + "app.components.Logout.logout": "Çıkış Yap", "app.components.NotFoundPage.back": "Anasayfaya geri dön", "app.components.NotFoundPage.description": "Bulunamadı", "app.components.Official": "Resmi", @@ -138,4 +140,4 @@ "notification.error.layout": "Düzen alınamadı", "request.error.model.unknown": "Bu model bulunmamaktadır.", "app.utils.delete": "Sil" -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/zh-Hans.json b/packages/strapi-admin/admin/src/translations/zh-Hans.json index 666d0f9b29..196a24fa43 100644 --- a/packages/strapi-admin/admin/src/translations/zh-Hans.json +++ b/packages/strapi-admin/admin/src/translations/zh-Hans.json @@ -72,6 +72,8 @@ "app.components.ListPluginsPage.description": "项目中已安装的插件列表", "app.components.ListPluginsPage.helmet.title": "插件列表", "app.components.ListPluginsPage.title": "插件", + "app.components.Logout.profile": "轮廓", + "app.components.Logout.logout": "登出", "app.components.NotFoundPage.back": "返回主页", "app.components.NotFoundPage.description": "没有找到", "app.components.Official": "官方", @@ -133,4 +135,4 @@ "notification.error": "发生了一个错误", "notification.error.layout": "无法获取布局", "request.error.model.unknown": "这个模型已不存在" -} \ No newline at end of file +} diff --git a/packages/strapi-admin/admin/src/translations/zh.json b/packages/strapi-admin/admin/src/translations/zh.json index d00b103c4f..8a343ea8e3 100644 --- a/packages/strapi-admin/admin/src/translations/zh.json +++ b/packages/strapi-admin/admin/src/translations/zh.json @@ -75,6 +75,8 @@ "app.components.ListPluginsPage.description": "這個專案安裝的擴充功能列表", "app.components.ListPluginsPage.helmet.title": "擴充功能列表", "app.components.ListPluginsPage.title": "擴充功能", + "app.components.Logout.profile": "輪廓", + "app.components.Logout.logout": "登出", "app.components.NotFoundPage.back": "回到主頁", "app.components.NotFoundPage.description": "找不到此頁面", "app.components.Official": "官方", @@ -138,4 +140,4 @@ "notification.error.layout": "無法取得佈局", "request.error.model.unknown": "不存在的資料", "app.utils.delete": "刪除" -} \ No newline at end of file +} diff --git a/packages/strapi-generate-new/files/config/environments/production/server.json b/packages/strapi-generate-new/files/config/environments/production/server.json index 4e5d9d1b5e..a72d469d48 100644 --- a/packages/strapi-generate-new/files/config/environments/production/server.json +++ b/packages/strapi-generate-new/files/config/environments/production/server.json @@ -1,6 +1,7 @@ { "host": "localhost", "port": "${process.env.PORT || 1337}", + "production": true, "proxy": { "enabled": false }, diff --git a/packages/strapi-generate-new/files/config/environments/staging/server.json b/packages/strapi-generate-new/files/config/environments/staging/server.json index 4e5d9d1b5e..a72d469d48 100644 --- a/packages/strapi-generate-new/files/config/environments/staging/server.json +++ b/packages/strapi-generate-new/files/config/environments/staging/server.json @@ -1,6 +1,7 @@ { "host": "localhost", "port": "${process.env.PORT || 1337}", + "production": true, "proxy": { "enabled": false }, diff --git a/packages/strapi-generate-new/lib/before.js b/packages/strapi-generate-new/lib/before.js index 3bdce44d98..f8cc961ac8 100644 --- a/packages/strapi-generate-new/lib/before.js +++ b/packages/strapi-generate-new/lib/before.js @@ -190,7 +190,7 @@ module.exports = (scope, cb) => { default: _.get(scope.database, 'authenticationDatabase', undefined) }, { - when: !hasDatabaseConfig && scope.client.database === 'mongo', + when: !hasDatabaseConfig, type: 'boolean', name: 'ssl', message: 'Enable SSL connection:', @@ -209,7 +209,11 @@ module.exports = (scope, cb) => { scope.database.settings.username = answers.username; scope.database.settings.password = answers.password; scope.database.options.authenticationDatabase = answers.authenticationDatabase; - scope.database.options.ssl = _.toString(answers.ssl) === 'true'; + if (scope.client.database === 'mongo') { + scope.database.options.ssl = _.toString(answers.ssl) === 'true'; + } else { + scope.database.settings.ssl = _.toString(answers.ssl) === 'true'; + } console.log(); console.log('⏳ Testing database connection...'); diff --git a/packages/strapi-generate-new/package.json b/packages/strapi-generate-new/package.json index daa5f2aa0e..079ddd6638 100644 --- a/packages/strapi-generate-new/package.json +++ b/packages/strapi-generate-new/package.json @@ -15,7 +15,7 @@ "dependencies": { "enpeem": "^2.2.0", "fs-extra": "^4.0.0", - "inquirer": "^4.0.2", + "inquirer": "^6.2.1", "listr": "^0.14.1", "lodash": "^4.17.5", "ora": "^2.1.0", @@ -49,4 +49,4 @@ "npm": ">= 6.0.0" }, "license": "MIT" -} \ No newline at end of file +} diff --git a/packages/strapi-hook-bookshelf/lib/index.js b/packages/strapi-hook-bookshelf/lib/index.js index c4e6b7a533..abfaa347bb 100644 --- a/packages/strapi-hook-bookshelf/lib/index.js +++ b/packages/strapi-hook-bookshelf/lib/index.js @@ -89,7 +89,7 @@ module.exports = function(strapi) { // Register the final model for Bookshelf. const loadedModel = _.assign({ tableName: definition.collectionName, - hasTimestamps: _.get(definition, 'options.timestamps') === true, + hasTimestamps: _.get(definition, 'options.timestamps', false), idAttribute: _.get(definition, 'options.idAttribute', 'id'), associations: [], defaults: Object.keys(definition.attributes).reduce((acc, current) => { @@ -100,7 +100,14 @@ module.exports = function(strapi) { return acc; }, {}) }, definition.options); - + // Use default timestamp column names if value is `true` + if (_.get(loadedModel, 'hasTimestamps') === true) { + _.set(loadedModel, 'hasTimestamps', ['created_at', 'updated_at']); + } + // Use false for values other than `Boolean` or `Array` + if (!_.isArray(_.get(loadedModel, 'hasTimestamps')) && !_.isBoolean(_.get(loadedModel, 'hasTimestamps'))) { + _.set(loadedModel, 'hasTimestamps', false); + } if (_.isString(_.get(connection, 'options.pivot_prefix'))) { loadedModel.toJSON = function(options = {}) { const { shallow = false, omitPivot = false } = options; @@ -619,10 +626,10 @@ module.exports = function(strapi) { // Add created_at and updated_at field if timestamp option is true if (loadedModel.hasTimestamps) { - definition.attributes['created_at'] = { + definition.attributes[_.isString(loadedModel.hasTimestamps[0]) ? loadedModel.hasTimestamps[0] : 'created_at'] = { type: 'timestamp' }; - definition.attributes['updated_at'] = { + definition.attributes[_.isString(loadedModel.hasTimestamps[1]) ? loadedModel.hasTimestamps[1] : 'updated_at'] = { type: 'timestampUpdate' }; } @@ -701,8 +708,8 @@ module.exports = function(strapi) { // Remove from attributes (auto handled by bookshlef and not displayed on ctb) if (loadedModel.hasTimestamps) { - delete definition.attributes['created_at']; - delete definition.attributes['updated_at']; + delete definition.attributes[_.isString(loadedModel.hasTimestamps[0]) ? loadedModel.hasTimestamps[0] : 'created_at']; + delete definition.attributes[_.isString(loadedModel.hasTimestamps[1]) ? loadedModel.hasTimestamps[1] : 'updated_at']; } resolve(); diff --git a/packages/strapi-hook-bookshelf/package.json b/packages/strapi-hook-bookshelf/package.json index f0104486bc..44997432eb 100644 --- a/packages/strapi-hook-bookshelf/package.json +++ b/packages/strapi-hook-bookshelf/package.json @@ -17,7 +17,7 @@ "main": "./lib", "dependencies": { "bookshelf": "^0.12.1", - "inquirer": "^5.2.0", + "inquirer": "^6.2.1", "lodash": "^4.17.5", "pluralize": "^6.0.0", "rimraf": "^2.6.2", @@ -56,4 +56,4 @@ "npm": ">= 6.0.0" }, "license": "MIT" -} \ No newline at end of file +} diff --git a/packages/strapi-hook-mongoose/lib/index.js b/packages/strapi-hook-mongoose/lib/index.js index 025ea36247..80ab48fcaf 100644 --- a/packages/strapi-hook-mongoose/lib/index.js +++ b/packages/strapi-hook-mongoose/lib/index.js @@ -207,7 +207,16 @@ module.exports = function (strapi) { }); }); - collection.schema.set('timestamps', _.get(definition, 'options.timestamps') === true); + // Use provided timestamps if the elemnets in the array are string else use default. + if (_.isArray(_.get(definition, 'options.timestamps'))) { + const timestamps = { + createdAt: _.isString(_.get(definition, 'options.timestamps[0]')) ? _.get(definition, 'options.timestamps[0]') : 'createdAt', + updatedAt: _.isString(_.get(definition, 'options.timestamps[1]')) ? _.get(definition, 'options.timestamps[1]') : 'updatedAt' + }; + collection.schema.set('timestamps', timestamps); + } else { + collection.schema.set('timestamps', _.get(definition, 'options.timestamps') === true); + } collection.schema.set('minimize', _.get(definition, 'options.minimize', false) === true); collection.schema.options.toObject = collection.schema.options.toJSON = { diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js index 1c906ba375..cd94930713 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/saga.js @@ -77,15 +77,10 @@ export function* submit() { let shouldAddTranslationSuffix = false; // Remove the updated_at & created_at fields so it is updated correctly when using Postgres or MySQL db - if (record.updated_at) { - delete record.created_at; - delete record.updated_at; - } - - // Remove the updatedAt & createdAt fields so it is updated correctly when using MongoDB - if (record.updatedAt) { - delete record.createdAt; - delete record.updatedAt; + const timestamps = get(schema, ['models', currentModelName, 'options', 'timestamps'], null); + if (timestamps) { + delete record[timestamps[0]]; + delete record[timestamps[1]]; } try { diff --git a/packages/strapi-plugin-content-manager/config/functions/bootstrap.js b/packages/strapi-plugin-content-manager/config/functions/bootstrap.js index 19f95e9c33..3886c5b8cc 100644 --- a/packages/strapi-plugin-content-manager/config/functions/bootstrap.js +++ b/packages/strapi-plugin-content-manager/config/functions/bootstrap.js @@ -17,6 +17,7 @@ const pickData = (model) => _.pick(model, [ 'globalId', 'globalName', 'orm', + 'options.timestamps', 'loadedModel', 'primaryKey', 'associations' @@ -84,6 +85,7 @@ module.exports = async cb => { pageEntries: 10, defaultSort: model.primaryKey, sort: 'ASC', + options: model.options, editDisplay: { availableFields: {}, fields: [], @@ -330,8 +332,9 @@ module.exports = async cb => { // Here we just need to add the data from the current schema Object apisToAdd.map(apiPath => { const api = _.get(schema.models, apiPath); - const { search, filters, bulkActions, pageEntries } = _.get(prevSchema, 'generalSettings'); + const { search, filters, bulkActions, pageEntries, options } = _.get(prevSchema, 'generalSettings'); + _.set(api, 'options', options); _.set(api, 'filters', filters); _.set(api, 'search', search); _.set(api, 'bulkActions', bulkActions); diff --git a/packages/strapi-plugin-graphql/services/Schema.js b/packages/strapi-plugin-graphql/services/Schema.js index d13249e3ed..dc5d28261b 100644 --- a/packages/strapi-plugin-graphql/services/Schema.js +++ b/packages/strapi-plugin-graphql/services/Schema.js @@ -266,8 +266,10 @@ module.exports = { resolvers, }); - // Write schema. - this.writeGenerateSchema(graphql.printSchema(schema)); + if (!strapi.config.currentEnvironment.server.production) { + // Write schema. + this.writeGenerateSchema(graphql.printSchema(schema)); + } // Remove custom scaler (like Upload); typeDefs = Types.removeCustomScalar(typeDefs, resolvers); diff --git a/packages/strapi-plugin-users-permissions/config/routes.json b/packages/strapi-plugin-users-permissions/config/routes.json index 848bfbb616..5598810339 100644 --- a/packages/strapi-plugin-users-permissions/config/routes.json +++ b/packages/strapi-plugin-users-permissions/config/routes.json @@ -111,6 +111,14 @@ "policies": [] } }, + { + "method": "GET", + "path": "/permissions", + "handler": "UsersPermissions.getPermissions", + "config": { + "policies": [] + } + }, { "method": "GET", "path": "/providers", diff --git a/packages/strapi-plugin-users-permissions/services/Providers.js b/packages/strapi-plugin-users-permissions/services/Providers.js index 158674e7b9..4c2f28533e 100644 --- a/packages/strapi-plugin-users-permissions/services/Providers.js +++ b/packages/strapi-plugin-users-permissions/services/Providers.js @@ -45,11 +45,9 @@ exports.connect = (provider, query) => { } try { - const users = await strapi.query('user', 'users-permissions').find({ - where: { - email: profile.email - } - }); + const users = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { + email: profile.email + })); const advanced = await strapi.store({ environment: '', diff --git a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js index 397fb1221a..6df284bd8e 100644 --- a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js +++ b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js @@ -438,8 +438,10 @@ module.exports = { try { // Disable auto-reload. strapi.reload.isWatching = false; - // Rewrite actions.json file. - fs.writeFileSync(actionsPath, JSON.stringify({ actions: data }), 'utf8'); + if (!strapi.config.currentEnvironment.server.production) { + // Rewrite actions.json file. + fs.writeFileSync(actionsPath, JSON.stringify({ actions: data }), 'utf8'); + } // Set value to AST to avoid restart. _.set(strapi.plugins['users-permissions'], 'config.actions', data); // Disable auto-reload. diff --git a/packages/strapi/lib/core/plugins.js b/packages/strapi/lib/core/plugins.js index 51893e0f8b..a22cf4dfec 100644 --- a/packages/strapi/lib/core/plugins.js +++ b/packages/strapi/lib/core/plugins.js @@ -88,12 +88,18 @@ module.exports = async function() { return; } + const existBuildPath = await fs.pathExists(buildPath); + if (strapi.config.currentEnvironment.server.production && existBuildPath) { + return; + } else if (strapi.config.currentEnvironment.server.production && !existBuildPath) { + console.log('The plugins.json file is missing and the front-end cannot work without it. Please, create it first at development environment.'); + } + // arrange system directories await Promise.all([ fs.remove(sourcePath), (async () => { - const existBuildPath = await fs.pathExists(buildPath); if (existBuildPath) { await fs.remove(buildPath); } else { diff --git a/packages/strapi/lib/middlewares/boom/index.js b/packages/strapi/lib/middlewares/boom/index.js index c73b8d57ea..1b7dc2a98a 100644 --- a/packages/strapi/lib/middlewares/boom/index.js +++ b/packages/strapi/lib/middlewares/boom/index.js @@ -37,7 +37,7 @@ module.exports = strapi => { ctx.status = error.status || 500; ctx.body = _.get(ctx.body, 'isBoom') ? ctx.body || error && error.message - : Boom.wrap(error, ctx.status, ctx.body || error.message); + : Boom.wrap(error, ctx.status); } if (ctx.response.headers.location) {