diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1f7ab54906..214ad5ec1d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,27 +1,29 @@ + + +#### Description: + + + -**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 following databases:** +#### Manual testing done on the following databases: - [ ] Not applicable - [ ] MongoDB - [ ] MySQL - [ ] Postgres - - -**Description:** - - +- [ ] SQLite diff --git a/docs/3.x.x/getting-started/installation.md b/docs/3.x.x/getting-started/installation.md index 683a1d7c0c..ad100896ed 100644 --- a/docs/3.x.x/getting-started/installation.md +++ b/docs/3.x.x/getting-started/installation.md @@ -42,7 +42,7 @@ strapi -v That should print `3.0.0-alpha.x`. -Strapi is installed globally on your computer. Type `strapi` in your terminal you will have access to every available command lines. +Strapi is installed globally on your computer. Type `strapi` in your terminal you will have access to every available command line command. *** diff --git a/docs/3.x.x/guides/authentication.md b/docs/3.x.x/guides/authentication.md index cc956add90..e7c90e4906 100644 --- a/docs/3.x.x/guides/authentication.md +++ b/docs/3.x.x/guides/authentication.md @@ -1,19 +1,48 @@ # Authentication -::: warning -This feature requires the Users & Permissions plugin (installed by default). -::: +This Authentication API requires the Users & Permissions plugin which comes with Strapi, installed by default. + +## Token usage + +A jwt token may be used for making permission-restricted API requests. To make an API request as a user, place the jwt token into an `Authorization` header of the GET request. A request without a token, will assume the `public` role permissions by default. Modify the permissions of each user's role in admin dashboard. Authentication failures return a 401 (unauthorized) error. + +#### Usage + +- The `token` variable is the `data.jwt` received when login in or registering. + +```js +import axios from 'axios'; + +const token = 'YOUR_TOKEN_HERE'; + +// Request API. +axios + .get('http://localhost:1337/posts', { + headers: { + Authorization: `Bearer ${token}` + } + }) + .then(response => { + // Handle success. + console.log('Data: ', response.data); + }) + .catch(error => { + // Handle error. + console.log('An error occurred:', error); + }); +``` ## Registration -This route lets you create new users. +Creates a new user in the database with a default role as 'registered'. #### Usage ```js import axios from 'axios'; -// Request API. +// Request API. +// Add your own code here to customize or restrict how the public can register new users. axios .post('http://localhost:1337/auth/local/register', { username: 'Strapi user', @@ -34,7 +63,7 @@ axios ## Login -This route lets you login your users by getting an authentication token. +Submit the user's identifier and password credentials for authentication. When the authentication is successful, the response data returned will have the users information along with a jwt authentication token. #### Local @@ -76,12 +105,12 @@ Strapi comes with the following providers: --- -To use the providers authentication, set your credentials in the admin interface (Plugin Users & Permissions > Providers). +Set your providers credentials in the admin interface (Plugin Users & Permissions > Providers). Then update and enable the provider you want use. -Redirect your user to: `GET /connect/:provider`. eg: `GET /connect/facebook` +To authenticate the user, use the GET method to request the url, `/connect/:provider`. eg: `GET /connect/facebook` -After his approval, he will be redirected to `/auth/:provider/callback`. The `jwt` and `user` data will be available in the body response. +After authentication, create and customize your own redirect callback at `/auth/:provider/callback`. The `jwt` and `user` data will be available in a .json response. Response payload: @@ -92,36 +121,6 @@ Response payload: } ``` -## Token usage - -By default, each API request is identified as `guest` role (see permissions of `guest`'s role in your admin dashboard). To make a request as a user, you have to set the `Authorization` token in your request headers. You receive a 401 error if you are not authorized to make this request or if your authorization header is not correct. - -#### Usage - -- The `token` variable is the `data.jwt` received when login in or registering. - -```js -import axios from 'axios'; - -const token = 'YOUR_TOKEN_HERE'; - -// Request API. -axios - .get('http://localhost:1337/posts', { - headers: { - Authorization: `Bearer ${token}` - } - }) - .then(response => { - // Handle success. - console.log('Data: ', response.data); - }) - .catch(error => { - // Handle error. - console.log('An error occurred:', error); - }); -``` - ## Forgotten password This action sends an email to a user with the link of you reset password page. This link contains an URL param `code` which is required to reset user password. @@ -220,18 +219,15 @@ packages/strapi-plugin-users-permissions/admin/src/translations/en.json We will go step by step. ### Configure your Provider Request -First, we need to configure our new provider onto `Provider.js` file. +Configure the new provider in the `Provider.js` file at the `getProfile` function. -Jump onto the `getProfile` function, you will see the list of currently available providers in the form of a `switch...case`. - -As you can see, `getProfile` take three params: +The `getProfile` takes three params: 1. provider :: The name of the used provider as a string. 2. query :: The query is the result of the provider callback. 3. callback :: The callback function who will continue the internal Strapi login logic. -Let's take the `discord` one as an example since it's not the easier, it should cover most of the case you -may encounter trying to implement your own provider. +Here is an example that uses the `discord` provider. #### Configure your oauth generic information @@ -259,14 +255,16 @@ may encounter trying to implement your own provider. } ``` -So here, you can see that we use a module called `Purest`. This module gives us with a generic way to interact -with the REST API. +This code creates a `Purest` object that gives us a generic way to interact with the provider's REST API. -To understand each value usage, and the templating syntax, I invite you to read the [Official Purest Documentation](https://github.com/simov/purest/tree/2.x) +For more specs on using the `Purest` module, please refer to the [Official Purest Documentation](https://github.com/simov/purest/tree/2.x) You may also want to take a look onto the numerous already made configurations [here](https://github.com/simov/purest-providers/blob/master/config/providers.json). -#### Retrieve your user informations: +#### Retrieve your user's information: + +For our discord provider it will look like: + ```js discord.query().get('users/@me').auth(access_token).request((err, res, body) => { if (err) { @@ -300,9 +298,9 @@ to retrieve your user from the database and log you in. Now, we need to configure our 'model' for our new provider. That way, our settings can be stored in the database, and managed from the admin panel. -Into: `packages/strapi-plugin-users-permissions/config/functions/bootstrap.js` +Open the file `packages/strapi-plugin-users-permissions/config/functions/bootstrap.js` -Simply add the fields your provider need into the `grantConfig` object. +Add the fields your provider needs into the `grantConfig` object. For our discord provider it will look like: ```js @@ -319,31 +317,29 @@ For our discord provider it will look like: }, ``` -You have already done the hard part, now, we simply need to make our new provider available from the front -side of our application. So let's do it! - ### Configure frontend for your new provider -First, let's edit: `packages/strapi-plugin-users-permissions/admin/src/components/PopUpForm/index.js` -As for backend, we have a `switch...case` where we need to put our new provider info. +To make the new provider available on the front end of the application, +edit `packages/strapi-plugin-users-permissions/admin/src/components/PopUpForm/index.js` +Add the new provider info. For our discord provider it will look like: ```js case 'discord': return `${strapi.backendURL}/connect/discord/callback`; ``` -Add the corresponding translation into: `packages/strapi-plugin-users-permissions/admin/src/translations/en.json` +### Add language translation + +Add the language translation in `packages/strapi-plugin-users-permissions/admin/src/translations/en.json` ```js 'PopUpForm.Providers.discord.providerConfig.redirectURL': 'The redirect URL to add in your Discord application configurations', ```` -These two change will set up the popup message who appear on the UI when we will configure our new provider. - -That's it, now you should be able to use your new provider. +These two change will set up the popup message that appears in the UI. That's it, now you should be able to use your new provider. ## Email templates diff --git a/docs/3.x.x/migration-guide/README.md b/docs/3.x.x/migration-guide/README.md index 4a286a2bc9..17c113910b 100644 --- a/docs/3.x.x/migration-guide/README.md +++ b/docs/3.x.x/migration-guide/README.md @@ -29,3 +29,4 @@ - [Migration guide from alpha.20 to alpha.21](migration-guide-alpha.20-to-alpha.21.md) - [Migration guide from alpha.21 to alpha.22](migration-guide-alpha.21-to-alpha.22.md) - [Migration guide from alpha.22 to alpha.23](migration-guide-alpha.22-to-alpha.23.md) +- [Migration guide from alpha.23 to alpha.24](migration-guide-alpha.23-to-alpha.24.md) diff --git a/docs/3.x.x/migration-guide/migration-guide-alpha.23-to-alpha.24.md b/docs/3.x.x/migration-guide/migration-guide-alpha.23-to-alpha.24.md new file mode 100644 index 0000000000..36f026ff7c --- /dev/null +++ b/docs/3.x.x/migration-guide/migration-guide-alpha.23-to-alpha.24.md @@ -0,0 +1,62 @@ +# Migration guide from alpha.23 to alpha.24 + +**Here are the major changes:** + +- Fix send email user register +- Documentation + +**Useful links:** +- Changelog: [https://github.com/strapi/strapi/releases/tag/v3.0.0-alpha.24](https://github.com/strapi/strapi/releases/tag/v3.0.0-alpha.24.1) +- GitHub diff: [https://github.com/strapi/strapi/compare/v3.0.0-alpha.23...v3.0.0-alpha.24](https://github.com/strapi/strapi/compare/v3.0.0-alpha.23...v3.0.0-alpha.24) + +
+ +::: note +Feel free to [join us on Slack](http://slack.strapi.io) and ask questions about the migration process. +::: + +
+ +## Getting started + +Install Strapi `alpha.24.1` globally on your computer. To do so run `npm install strapi@3.0.0-alpha.24.1 -g`. + +When it's done, generate a new empty project `strapi new myNewProject` (don't pay attention to the database configuration). + +
+ +## Update node modules + +Update the Strapi's dependencies version (move Strapi's dependencies to `3.0.0-alpha.24.1` version) of your project. + +Run `npm install strapi@3.0.0-alpha.24.1 --save` to update your strapi version. + +
+ +## Update the Admin + +::: note +If you performed updates in the Admin, you will have to manually migrate your changes. +::: + +Delete your old admin folder and replace it with the new one. + +
+ +## Update the Plugins + +::: note +If you did a custom update on one of the plugins, you will have to manually migrate your update. +::: + +Copy the fields and relations you had in your `/plugins/users-permissions/models/User.settings.json` and `/plugins/users-permissions/config/jwt.json` file in the new one. + +Then, delete your old `plugins` folder and replace it with the new one. + +## Update custom plugin store + +If you write your own plugins please follow these instructions https://github.com/strapi/strapi/pull/2808 + +
+ +That's all, you have now upgraded to Strapi `alpha.24.1`. diff --git a/package.json b/package.json index 896dfefe57..e96b34f013 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "private": true, - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "dependencies": {}, "devDependencies": { "assert": "~1.3.0", "axios": "^0.18.0", "babel-eslint": "^6.1.2", "chalk": "^2.4.1", + "cross-env": "^5.2.0", "cypress": "3.1.2", "eslint": "^4.19.1", "eslint-plugin-babel": "^4.0.0", diff --git a/packages/strapi-admin/admin/src/app.js b/packages/strapi-admin/admin/src/app.js index 5dacde44bf..754c27534b 100644 --- a/packages/strapi-admin/admin/src/app.js +++ b/packages/strapi-admin/admin/src/app.js @@ -13,7 +13,7 @@ import 'whatwg-fetch'; import { getAppPluginsSucceeded, unsetHasUserPlugin, -} from 'containers/App/actions'; +} from './containers/App/actions'; import { basename, store } from './createStore'; import './intlPolyfill'; import './public-path'; diff --git a/packages/strapi-admin/admin/src/appDev.js b/packages/strapi-admin/admin/src/appDev.js index 14dff854a3..3710ccc341 100644 --- a/packages/strapi-admin/admin/src/appDev.js +++ b/packages/strapi-admin/admin/src/appDev.js @@ -6,12 +6,12 @@ */ import { findIndex } from 'lodash'; +import 'babel-polyfill'; +import 'sanitize.css/sanitize.css'; import { getAppPluginsSucceeded, unsetHasUserPlugin, -} from 'containers/App/actions'; -import 'babel-polyfill'; -import 'sanitize.css/sanitize.css'; +} from './containers/App/actions'; import { store } from './createStore'; import render from './renderApp'; import './intlPolyfill'; diff --git a/packages/strapi-admin/admin/src/components/InstallPluginPopup/index.js b/packages/strapi-admin/admin/src/components/InstallPluginPopup/index.js index 95de1be494..7da80071dc 100644 --- a/packages/strapi-admin/admin/src/components/InstallPluginPopup/index.js +++ b/packages/strapi-admin/admin/src/components/InstallPluginPopup/index.js @@ -11,7 +11,7 @@ import { Modal, ModalHeader, ModalBody } from 'reactstrap'; import { map } from 'lodash'; import cn from 'classnames'; -import Official from 'components/Official'; +import Official from '../Official'; // import StarsContainer from 'components/StarsContainer'; import styles from './styles.scss'; diff --git a/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js b/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js index ec6f44ca77..1a10007fd8 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js +++ b/packages/strapi-admin/admin/src/components/LeftMenuFooter/index.js @@ -8,7 +8,7 @@ import React from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import { PropTypes } from 'prop-types'; -import LeftMenuLink from 'components/LeftMenuLink'; +import LeftMenuLink from '../LeftMenuLink'; import styles from './styles.scss'; import messages from './messages.json'; diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js b/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js index 3ee932c32c..51a577fdf0 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js +++ b/packages/strapi-admin/admin/src/components/LeftMenuLink/index.js @@ -10,7 +10,7 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; -import en from 'translations/en.json'; +import en from '../../translations/en.json'; import styles from './styles.scss'; diff --git a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js index 8334a3b250..673e4b1940 100644 --- a/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js +++ b/packages/strapi-admin/admin/src/components/LeftMenuLinkContainer/index.js @@ -9,7 +9,7 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { findIndex, get, snakeCase, isEmpty, map, sortBy } from 'lodash'; -import LeftMenuLink from 'components/LeftMenuLink'; +import LeftMenuLink from '../LeftMenuLink'; import styles from './styles.scss'; import messages from './messages.json'; diff --git a/packages/strapi-admin/admin/src/components/ListPlugins/index.js b/packages/strapi-admin/admin/src/components/ListPlugins/index.js index 64a6ead46d..f7d8e6e5d3 100644 --- a/packages/strapi-admin/admin/src/components/ListPlugins/index.js +++ b/packages/strapi-admin/admin/src/components/ListPlugins/index.js @@ -12,7 +12,7 @@ import { map, size } from 'lodash'; // Design import Button from 'components/Button'; -import Row from 'components/Row'; +import Row from '../Row'; import styles from './styles.scss'; diff --git a/packages/strapi-admin/admin/src/components/NotificationsContainer/index.js b/packages/strapi-admin/admin/src/components/NotificationsContainer/index.js index a34208afe6..14302bf858 100644 --- a/packages/strapi-admin/admin/src/components/NotificationsContainer/index.js +++ b/packages/strapi-admin/admin/src/components/NotificationsContainer/index.js @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { CSSTransition, TransitionGroup } from 'react-transition-group'; -import Notification from 'components/Notification'; +import Notification from '../Notification'; import styles from './styles.scss'; diff --git a/packages/strapi-admin/admin/src/components/NotificationsContainer/styles.scss b/packages/strapi-admin/admin/src/components/NotificationsContainer/styles.scss index 3f1e7b5041..5234d3d63d 100644 --- a/packages/strapi-admin/admin/src/components/NotificationsContainer/styles.scss +++ b/packages/strapi-admin/admin/src/components/NotificationsContainer/styles.scss @@ -2,7 +2,7 @@ @import '../../styles/variables/variables'; .notificationsContainer { /* stylelint-disable */ - position: absolute; + position: fixed; top: 72px; left: 240px; right: 0; diff --git a/packages/strapi-admin/admin/src/components/Official/index.js b/packages/strapi-admin/admin/src/components/Official/index.js index 22aa25d2fd..2c20399baa 100644 --- a/packages/strapi-admin/admin/src/components/Official/index.js +++ b/packages/strapi-admin/admin/src/components/Official/index.js @@ -10,7 +10,6 @@ import PropTypes from 'prop-types'; import styles from './styles.scss'; function Official(props) { - return ( + + + ); + } +} +Onboarding.contextTypes = { + emitEvent: PropTypes.func, +}; + +Onboarding.defaultProps = { + onClick: () => {}, + removeVideos: () => {}, + setVideoDuration: () => {}, + setVideoEnd: () => {}, + shouldOpenModal: false, + videos: [], + updateVideoStartTime: () => {}, +}; + +Onboarding.propTypes = { + getVideos: PropTypes.func.isRequired, + onClick: PropTypes.func, + removeVideos: PropTypes.func, + setVideoDuration: PropTypes.func, + setVideoEnd: PropTypes.func, + shouldOpenModal: PropTypes.bool, + updateVideoStartTime: PropTypes.func, + videos: PropTypes.array, +}; + +const mapStateToProps = makeSelectOnboarding(); + +function mapDispatchToProps(dispatch) { + return bindActionCreators({ getVideos, onClick, setVideoDuration, updateVideoStartTime, setVideoEnd, removeVideos }, dispatch); +} + +const withConnect = connect( + mapStateToProps, + mapDispatchToProps, +); + +/* Remove this line if the container doesn't have a route and + * check the documentation to see how to create the container's store + */ +const withReducer = injectReducer({ key: 'onboarding', reducer }); + +/* Remove the line below the container doesn't have a route and + * check the documentation to see how to create the container's store + */ +const withSaga = injectSaga({ key: 'onboarding', saga }); + +export default compose( + withReducer, + withSaga, + withConnect, +)(Onboarding); diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/reducer.js b/packages/strapi-admin/admin/src/containers/Onboarding/reducer.js new file mode 100644 index 0000000000..06e15ff8ec --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/reducer.js @@ -0,0 +1,69 @@ +/* + * + * Onboarding reducer + * + */ + +import { fromJS } from 'immutable'; +import { GET_VIDEOS_SUCCEEDED, SHOULD_OPEN_MODAL, ON_CLICK, SET_VIDEOS_DURATION, UPDATE_VIDEO_START_TIME, SET_VIDEO_END, REMOVE_VIDEOS } from './constants'; + +const initialState = fromJS({ + videos: fromJS([]), +}); + +function onboardingReducer(state = initialState, action) { + switch (action.type) { + case GET_VIDEOS_SUCCEEDED: + return state.update('videos', () => fromJS(action.videos)); + case SHOULD_OPEN_MODAL: + return state.update('shouldOpenModal', () => action.opened); + case ON_CLICK: + return state.updateIn(['videos'], list => { + return list.reduce((acc, current, index) => { + + if (index === action.index) { + return acc.updateIn([index, 'isOpen'], v => !v); + } + + return acc.updateIn([index, 'isOpen'], () => false); + }, list); + }); + case SET_VIDEOS_DURATION: + return state.updateIn(['videos', action.index, 'duration'], () => action.duration); + case UPDATE_VIDEO_START_TIME: { + + const storedVideos = JSON.parse(localStorage.getItem('videos')); + const videos = state.updateIn(['videos'], list => { + return list.reduce((acc, current, index) => { + + if (index === action.index) { + storedVideos[index].startTime = action.startTime; + return acc.updateIn([index, 'startTime'], () => action.startTime); + } + + storedVideos[index].startTime = 0; + + return acc.updateIn([index, 'startTime'], () => 0); + }, list); + }); + + localStorage.setItem('videos', JSON.stringify(storedVideos)); + + return videos; + } + case SET_VIDEO_END: { + + const storedVideos = JSON.parse(localStorage.getItem('videos')); + storedVideos[action.index].end = action.end; + localStorage.setItem('videos', JSON.stringify(storedVideos)); + + return state.updateIn(['videos', action.index, 'end'], () => action.end); + } + case REMOVE_VIDEOS: + return initialState; + default: + return state; + } +} + +export default onboardingReducer; diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/saga.js b/packages/strapi-admin/admin/src/containers/Onboarding/saga.js new file mode 100644 index 0000000000..541a9aed58 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/saga.js @@ -0,0 +1,66 @@ +import request from 'utils/request'; +import { all, call, fork, takeLatest, put } from 'redux-saga/effects'; + +import { GET_VIDEOS } from './constants'; +import { getVideosSucceeded, shouldOpenModal } from './actions'; + +function* getVideos() { + try { + const data = yield call(request, 'https://strapi.io/videos', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }, + false, + true, + { noAuth: true }, + ); + + const storedVideo = JSON.parse(localStorage.getItem('videos')) || null; + + const videos = data.map(video => { + const { end, startTime } = storedVideo ? storedVideo.find(v => v.order === video.order) : { end: false, startTime: 0}; + + return { + ...video, + duration: null, + end, + isOpen: false, + key: video.order, + startTime, + }; + }).sort((a,b) => (a.order - b.order)); + + localStorage.setItem('videos', JSON.stringify(videos)); + + yield put( + getVideosSucceeded(videos), + ); + + const isFirstTime = JSON.parse(localStorage.getItem('onboarding')) || null; + + if (isFirstTime === null) { + yield new Promise(resolve => { + setTimeout(() => { + resolve(); + }, 500); + }); + + yield put( + shouldOpenModal(true), + ); + localStorage.setItem('onboarding', true); + } + + } catch (err) { + console.log(err); // eslint-disable-line no-console + } +} + + +function* defaultSaga() { + yield all([fork(takeLatest, GET_VIDEOS, getVideos)]); +} + +export default defaultSaga; diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/selectors.js b/packages/strapi-admin/admin/src/containers/Onboarding/selectors.js new file mode 100644 index 0000000000..2f5dd23c08 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/selectors.js @@ -0,0 +1,25 @@ +import { createSelector } from 'reselect'; + +/** + * Direct selector to the onboarding state domain + */ +const selectOnboardingDomain = () => (state) => state.get('onboarding'); + +/** + * Other specific selectors + */ + + +/** + * Default selector used by Onboarding + */ + +const makeSelectOnboarding = () => createSelector( + selectOnboardingDomain(), + (substate) => substate.toJS() +); + +export default makeSelectOnboarding; +export { + selectOnboardingDomain, +}; diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/styles.scss b/packages/strapi-admin/admin/src/containers/Onboarding/styles.scss new file mode 100644 index 0000000000..1d0af4dcd4 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/styles.scss @@ -0,0 +1,116 @@ +.videosWrapper { + position: fixed; + right: 15px; + bottom: 15px; + button, + button:focus, + a { + cursor: pointer; + outline: 0; + } + p { + margin-bottom: 0; + } + .videosHeader { + padding: 25px 15px 0 15px; + p { + display: inline-block; + vertical-align: top; + width: 50%; + font-family: Lato; + font-weight: bold; + font-size: 11px; + color: #5c5f66; + letter-spacing: 0.5px; + text-transform: uppercase; + &:last-of-type { + color: #5a9e06; + text-align: right; + } + } + } + &.visible { + opacity: 1; + } + &.hidden { + opacity: 0; + } + .videosContent { + min-width: 320px; + margin-bottom: 10px; + margin-right: 15px; + background-color: white; + box-shadow: 0 2px 4px 0 #e3e9f3; + border-radius: 3px; + overflow: hidden; + &.shown { + animation: fadeIn 0.5s forwards; + } + &.hide { + animation: fadeOut 0.5s forwards; + } + + ul { + padding: 10px 0; + margin-bottom: 0; + list-style: none; + } + } + .openBtn { + float: right; + width: 38px; + height: 38px; + button { + width: 100%; + height: 100%; + border-radius: 50%; + color: white; + background: #0e7de7; + box-shadow: 0px 2px 4px 0px rgba(227, 233, 243, 1); + i:last-of-type { + display: none; + } + &.active { + i:first-of-type { + display: none; + } + i:last-of-type { + display: block; + } + } + } + } +} + + +@keyframes fadeIn { + 0% { + width: auto; + height: auto; + opacity: 0; + } + + 5% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fadeOut { + 0% { + opacity: 1; + } + + 60% { + opacity: 0; + } + + 100% { + opacity: 0; + width: 0; + height: 0; + } +} \ No newline at end of file diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/tests/actions.test.js b/packages/strapi-admin/admin/src/containers/Onboarding/tests/actions.test.js new file mode 100644 index 0000000000..336c014b91 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/tests/actions.test.js @@ -0,0 +1,18 @@ + +import { + defaultAction, +} from '../actions'; +import { + DEFAULT_ACTION, +} from '../constants'; + +describe('Onboarding actions', () => { + describe('Default Action', () => { + it('has a type of DEFAULT_ACTION', () => { + const expected = { + type: DEFAULT_ACTION, + }; + expect(defaultAction()).toEqual(expected); + }); + }); +}); diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/tests/index.test.js b/packages/strapi-admin/admin/src/containers/Onboarding/tests/index.test.js new file mode 100644 index 0000000000..dec83b8b24 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/tests/index.test.js @@ -0,0 +1,10 @@ +// import React from 'react'; +// import { shallow } from 'enzyme'; + +// import { Onboarding } from '../index'; + +describe('', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(true); + }); +}); diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/tests/reducer.test.js b/packages/strapi-admin/admin/src/containers/Onboarding/tests/reducer.test.js new file mode 100644 index 0000000000..dfe1223f3f --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/tests/reducer.test.js @@ -0,0 +1,9 @@ + +import { fromJS } from 'immutable'; +import onboardingReducer from '../reducer'; + +describe('onboardingReducer', () => { + it('returns the initial state', () => { + expect(onboardingReducer(undefined, [])).toEqual(fromJS([])); + }); +}); diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/tests/saga.test.js b/packages/strapi-admin/admin/src/containers/Onboarding/tests/saga.test.js new file mode 100644 index 0000000000..a5d8823023 --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/tests/saga.test.js @@ -0,0 +1,15 @@ +/** + * Test sagas + */ + +/* eslint-disable redux-saga/yield-effects */ +// import { take, call, put, select } from 'redux-saga/effects'; +// import { defaultSaga } from '../saga'; + +// const generator = defaultSaga(); + +describe('defaultSaga Saga', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(true); + }); +}); diff --git a/packages/strapi-admin/admin/src/containers/Onboarding/tests/selectors.test.js b/packages/strapi-admin/admin/src/containers/Onboarding/tests/selectors.test.js new file mode 100644 index 0000000000..2c24a379eb --- /dev/null +++ b/packages/strapi-admin/admin/src/containers/Onboarding/tests/selectors.test.js @@ -0,0 +1,10 @@ +// import { fromJS } from 'immutable'; +// import { makeSelectOnboardingDomain } from '../selectors'; + +// const selector = makeSelectOnboardingDomain(); + +describe('makeSelectOnboardingDomain', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(true); + }); +}); diff --git a/packages/strapi-admin/admin/src/containers/PluginPage/index.js b/packages/strapi-admin/admin/src/containers/PluginPage/index.js index 8ef6a1d2a2..04bad48ef1 100644 --- a/packages/strapi-admin/admin/src/containers/PluginPage/index.js +++ b/packages/strapi-admin/admin/src/containers/PluginPage/index.js @@ -13,7 +13,7 @@ import { createSelector } from 'reselect'; import BlockerComponent from 'components/BlockerComponent'; import ErrorBoundary from 'components/ErrorBoundary'; -import { selectPlugins } from 'containers/App/selectors'; +import { selectPlugins } from '../App/selectors'; export class PluginPage extends React.Component { // eslint-disable-line react/prefer-stateless-function render() { diff --git a/packages/strapi-admin/admin/src/createStore.js b/packages/strapi-admin/admin/src/createStore.js index ffcb08401b..72e083c283 100644 --- a/packages/strapi-admin/admin/src/createStore.js +++ b/packages/strapi-admin/admin/src/createStore.js @@ -13,7 +13,7 @@ const history = createHistory({ const store = configureStore({}, history); if (window.Cypress) { - window.__store__ = Object.assign(window.__store__ || {}, { strapiAdmin: store }); + window.__store__ = Object.assign(window.__store__ || {}, { store }); } -export { basename, history, store }; \ No newline at end of file +export { basename, history, store }; diff --git a/packages/strapi-admin/admin/src/reducers.js b/packages/strapi-admin/admin/src/reducers.js index af77133771..29af47f30c 100644 --- a/packages/strapi-admin/admin/src/reducers.js +++ b/packages/strapi-admin/admin/src/reducers.js @@ -6,9 +6,9 @@ import { fromJS } from 'immutable'; import { combineReducers } from 'redux-immutable'; import { LOCATION_CHANGE } from 'react-router-redux'; -import globalReducer from 'containers/App/reducer'; -import languageProviderReducer from 'containers/LanguageProvider/reducer'; -import notificationProviderReducer from 'containers/NotificationProvider/reducer'; +import globalReducer from './containers/App/reducer'; +import languageProviderReducer from './containers/LanguageProvider/reducer'; +import notificationProviderReducer from './containers/NotificationProvider/reducer'; /* * routeReducer diff --git a/packages/strapi-admin/admin/src/renderApp.js b/packages/strapi-admin/admin/src/renderApp.js index da4ad9eb68..09733ab1cc 100644 --- a/packages/strapi-admin/admin/src/renderApp.js +++ b/packages/strapi-admin/admin/src/renderApp.js @@ -6,8 +6,8 @@ import { Provider } from 'react-redux'; import React from 'react'; import ReactDOM from 'react-dom'; import { ConnectedRouter } from 'react-router-redux'; -import LanguageProvider from 'containers/LanguageProvider'; -import App from 'containers/App'; +import LanguageProvider from './containers/LanguageProvider'; +import App from './containers/App'; import { history, store } from './createStore'; const render = (translatedMessages) => { @@ -23,4 +23,4 @@ const render = (translatedMessages) => { ); }; -export default render; \ No newline at end of file +export default render; diff --git a/packages/strapi-admin/admin/src/strapi.js b/packages/strapi-admin/admin/src/strapi.js index 107b073647..f81a894735 100644 --- a/packages/strapi-admin/admin/src/strapi.js +++ b/packages/strapi-admin/admin/src/strapi.js @@ -8,8 +8,10 @@ import { pluginLoaded, unfreezeApp, updatePlugin, -} from 'containers/App/actions'; -import { showNotification } from 'containers/NotificationProvider/actions'; +} from './containers/App/actions'; +import { showNotification } from './containers/NotificationProvider/actions'; +import injectReducer from './utils/injectReducer'; +import injectSaga from './utils/injectSaga'; import { history, store } from './createStore'; import { translationMessages, languages } from './i18n'; import './public-path'; @@ -94,4 +96,7 @@ window.strapi = Object.assign(window.strapi || {}, { currentLanguage: window.localStorage.getItem('strapi-admin-language') || window.navigator.language || window.navigator.userLanguage || 'en', lockApp, unlockApp, -}); \ No newline at end of file + injectReducer, + injectSaga, + store, +}); diff --git a/packages/strapi-admin/admin/src/translations/en.json b/packages/strapi-admin/admin/src/translations/en.json index 67dacc1e6c..d797736785 100644 --- a/packages/strapi-admin/admin/src/translations/en.json +++ b/packages/strapi-admin/admin/src/translations/en.json @@ -84,6 +84,8 @@ "app.components.NotFoundPage.back": "Back to homepage", "app.components.NotFoundPage.description": "Not Found", "app.components.Official": "Official", + "app.components.Onboarding.label.completed": "% completed", + "app.components.Onboarding.title": "Get Started Videos", "app.components.PluginCard.Button.label.download": "Download", "app.components.PluginCard.Button.label.install": "Already installed", "app.components.PluginCard.Button.label.support": "Support us", @@ -119,7 +121,9 @@ "components.Input.error.validation.required": "This value is required.", "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.serverError": "The server should have restarted, please check your logs in the terminal.", "components.OverlayBlocker.title": "Waiting for restart...", + "components.OverlayBlocker.title.serverError": "The restart takes longer than expected", "components.PageFooter.select": "entries per page", "components.ProductionBlocker.description": "For safety purposes we have to disable this plugin in other environments.", "components.ProductionBlocker.header": "This plugin is only available in development.", @@ -145,4 +149,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/fr.json b/packages/strapi-admin/admin/src/translations/fr.json index ca05153c06..da9a869f29 100644 --- a/packages/strapi-admin/admin/src/translations/fr.json +++ b/packages/strapi-admin/admin/src/translations/fr.json @@ -85,6 +85,8 @@ "app.components.NotFoundPage.back": "Retourner à la page d'accueil", "app.components.NotFoundPage.description": "Page introuvable", "app.components.Official": "Officiel", + "app.components.Onboarding.label.completed": "% complétées", + "app.components.Onboarding.title": "Démarrons ensemble", "app.components.PluginCard.Button.label.download": "Télécharger", "app.components.PluginCard.Button.label.install": "Déjà installé", "app.components.PluginCard.Button.label.support": "Nous soutenir", @@ -120,7 +122,9 @@ "components.Input.error.validation.required": "Ce champ est obligatoire.", "components.ListRow.empty": "Il n'y a pas de données à afficher.", "components.OverlayBlocker.description": "Vous utilisez une fonctionnalité qui nécessite le redémarrage du server. Merci d'attendre que celui-ci ait redémarré.", + "components.OverlayBlocker.description.serverError": "Le serveur aurait déjà du redémarrer, vous devriez regarder les messages dans le terminal.", "components.OverlayBlocker.title": "Le serveur est en train de redémarrer", + "components.OverlayBlocker.title.serverError": "Le serveur aurait déjà du redémarrer", "components.PageFooter.select": "entrées par page", "components.ProductionBlocker.description": "Pour des raisons de sécurité il est désactivé dans les autres environnements.", "components.ProductionBlocker.header": "Ce plugin est disponible uniquement en développement.", @@ -146,4 +150,4 @@ "notification.error.layout": "Impossible de récupérer le layout de l'admin", "request.error.model.unknown": "Le model n'existe pas", "app.utils.delete": "Supprimer" -} +} \ No newline at end of file diff --git a/packages/strapi-admin/admin/src/utils/injectReducer.js b/packages/strapi-admin/admin/src/utils/injectReducer.js index 4af84187f3..c9d2dcecb4 100644 --- a/packages/strapi-admin/admin/src/utils/injectReducer.js +++ b/packages/strapi-admin/admin/src/utils/injectReducer.js @@ -11,7 +11,7 @@ import getInjectors from './reducerInjectors'; * @param {function} reducer A reducer that will be injected * */ -export default ({ key, reducer }) => (WrappedComponent) => { +export default ({ key, reducer, pluginId }) => (WrappedComponent) => { class ReducerInjector extends React.Component { static WrappedComponent = WrappedComponent; static displayName = `withReducer(${(WrappedComponent.displayName || WrappedComponent.name || 'Component')})`; @@ -21,8 +21,9 @@ export default ({ key, reducer }) => (WrappedComponent) => { componentWillMount() { const { injectReducer } = this.injectors; + const reducerName = pluginId ? `${pluginId}_${key}` : key; - injectReducer(key, reducer); + injectReducer(reducerName, reducer); } injectors = getInjectors(this.context.store); diff --git a/packages/strapi-admin/admin/src/utils/injectSaga.js b/packages/strapi-admin/admin/src/utils/injectSaga.js index 158b0e1732..a42c0367ff 100644 --- a/packages/strapi-admin/admin/src/utils/injectSaga.js +++ b/packages/strapi-admin/admin/src/utils/injectSaga.js @@ -15,7 +15,7 @@ import getInjectors from './sagaInjectors'; * - constants.ONCE_TILL_UNMOUNT—behaves like 'RESTART_ON_REMOUNT' but never runs it again. * */ -export default ({ key, saga, mode }) => (WrappedComponent) => { +export default ({ key, saga, mode, pluginId }) => (WrappedComponent) => { class InjectSaga extends React.Component { static WrappedComponent = WrappedComponent; static displayName = `withSaga(${(WrappedComponent.displayName || WrappedComponent.name || 'Component')})`; @@ -25,14 +25,16 @@ export default ({ key, saga, mode }) => (WrappedComponent) => { componentWillMount() { const { injectSaga } = this.injectors; + const sagaName = pluginId ? `${pluginId}_${key}` : key; - injectSaga(key, { saga, mode }, this.props); + injectSaga(sagaName, { saga, mode }, this.props); } componentWillUnmount() { const { ejectSaga } = this.injectors; + const sagaName = pluginId ? `${pluginId}_${key}` : key; - ejectSaga(key); + ejectSaga(sagaName); } injectors = getInjectors(this.context.store); diff --git a/packages/strapi-admin/controllers/Admin.js b/packages/strapi-admin/controllers/Admin.js index 3b4ff00f41..77001166e3 100644 --- a/packages/strapi-admin/controllers/Admin.js +++ b/packages/strapi-admin/controllers/Admin.js @@ -1,7 +1,7 @@ 'use strict'; const path = require('path'); -const exec = require('child_process').spawnSync; +const shell = require('shelljs'); const _ = require('lodash'); /** @@ -52,7 +52,7 @@ module.exports = { strapi.reload.isWatching = false; strapi.log.info(`Installing ${plugin}...`); - exec('node', [strapiBin, 'install', plugin, (port === '4000') ? '--dev' : '']); + shell.exec(`node ${strapiBin} install ${plugin} ${(port === '4000') ? '--dev' : ''}`, {silent: true}); ctx.send({ ok: true }); @@ -85,7 +85,7 @@ module.exports = { strapi.reload.isWatching = false; strapi.log.info(`Uninstalling ${plugin}...`); - exec('node', [strapiBin, 'uninstall', plugin]); + shell.exec(`node ${strapiBin} uninstall ${plugin}`, {silent: true}); ctx.send({ ok: true }); diff --git a/packages/strapi-admin/package.json b/packages/strapi-admin/package.json index b26f087a28..ff118fbbb2 100644 --- a/packages/strapi-admin/package.json +++ b/packages/strapi-admin/package.json @@ -1,6 +1,6 @@ { "name": "strapi-admin", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Strapi Admin", "repository": { "type": "git", @@ -10,13 +10,13 @@ "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", - "prebuild": "APP_PATH=$APP_PATH node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production IS_ADMIN=true node ./node_modules/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js", - "build:dev": "npm run build:dll && node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development IS_ADMIN=true node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config ./node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "APP_PATH=$APP_PATH npm run build:dll && node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production IS_ADMIN=true node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config ./node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:dll": "APP_PATH=$APP_PATH node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production IS_ADMIN=true node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config ./node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.dll.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "prestart": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development PORT=4000 IS_ADMIN=true node ./node_modules/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development PORT=4000 IS_ADMIN=true node ./node_modules/strapi-helper-plugin/lib/server", + "prebuild": "cross-env NODE_ENV=production IS_ADMIN=true node ./node_modules/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js", + "build:dev": "cross-env npm run build:dll && NODE_ENV=development IS_ADMIN=true node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config ./node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env APP_PATH=$APP_PATH npm run build:dll && cross-env NODE_ENV=production IS_ADMIN=true ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config ./node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:dll": "cross-env APP_PATH=$APP_PATH NODE_ENV=production IS_ADMIN=true ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config ./node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.dll.babel.js --color -p --progress", + "build:clean": "cross-env node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", + "prestart": "cross-env NODE_ENV=development PORT=4000 IS_ADMIN=true node ./node_modules/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js", + "start": "cross-env NODE_ENV=development PORT=4000 IS_ADMIN=true node ./node_modules/strapi-helper-plugin/lib/server", "generate": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "echo \"Error: no test specified\"", @@ -25,14 +25,18 @@ "presetup": "node ./scripts/preSetup.js" }, "dependencies": { + "intl": "^1.2.5", "react-ga": "^2.4.1", + "redux": "^4.0.1", "remove-markdown": "^0.2.2", - "shelljs": "^0.7.8" + "shelljs": "^0.7.8", + "video-react": "^0.13.2" }, "devDependencies": { + "cross-env": "^5.0.5", "sanitize.css": "^4.1.0", - "strapi-helper-plugin": "3.0.0-alpha.23.1", - "strapi-utils": "3.0.0-alpha.23.1" + "strapi-helper-plugin": "3.0.0-alpha.24.1", + "strapi-utils": "3.0.0-alpha.24.1" }, "author": { "name": "Strapi", diff --git a/packages/strapi-admin/scripts/preSetup.js b/packages/strapi-admin/scripts/preSetup.js index 40999fbf94..2d71979bea 100644 --- a/packages/strapi-admin/scripts/preSetup.js +++ b/packages/strapi-admin/scripts/preSetup.js @@ -21,23 +21,19 @@ shell.rm('-rf', path.resolve(appPath, 'package-lock.json')); shell.rm('-rf', path.resolve(appPath, 'admin', 'package-lock.json')); // Install the project dependencies. -shell.exec(`cd "${appPath}" && npm install --ignore-scripts`, { - silent -}); +shell.cd(appPath); +shell.exec('npm install --ignore-scripts', {silent}); // Install the administration dependencies. -shell.exec(`cd "${path.resolve(appPath, 'admin')}" && npm install`, { - silent -}); +shell.cd(path.resolve(appPath, 'admin')); +shell.exec('npm install', {silent}); if (isDevelopmentMode) { - shell.exec(`cd "${path.resolve(appPath, 'admin')}" && npm link strapi-helper-plugin && npm link strapi-utils`, { - silent - }); + shell.cd(path.resolve(appPath, 'admin')); + shell.exec('npm link strapi-helper-plugin && npm link strapi-utils', {silent}); } else { - shell.exec(`cd "${path.resolve(appPath, 'admin', 'node_modules', 'strapi-helper-plugin')}" && npm install`, { - silent - }); + shell.cd(path.resolve(appPath, 'admin', 'node_modules', 'strapi-helper-plugin')); + shell.exec('npm install', {silent}); } -shell.echo('Packaged installed successfully'); +shell.echo('Packages installed successfully'); diff --git a/packages/strapi-admin/scripts/setup.js b/packages/strapi-admin/scripts/setup.js index 37120f8eb9..7e209642a3 100644 --- a/packages/strapi-admin/scripts/setup.js +++ b/packages/strapi-admin/scripts/setup.js @@ -11,9 +11,8 @@ const appPath = isDevelopmentMode ? path.resolve(process.env.PWD, '..') : path.r shell.echo('🏗 Building the admin...'); -const build = shell.exec(`cd "${path.resolve(appPath, 'admin')}" && APP_PATH="${appPath}" npm run build`, { - silent -}); +shell.cd(path.resolve(appPath, 'admin')); +const build = shell.exec(`cross-env APP_PATH="${appPath}" npm run build`, {silent}); if (build.stderr && build.code !== 0) { console.error(build.stderr); @@ -43,25 +42,20 @@ if (process.env.npm_config_plugins === 'true') { .forEach(function (plugin) { shell.echo(`🔸 Plugin - ${_.upperFirst(plugin)}`); shell.echo('📦 Installing packages...'); - shell.exec(`cd "${path.resolve(plugins, plugin)}" && npm install`, { - silent - }); + shell.cd(path.resolve(plugins, plugin)); + shell.exec('npm install', {silent}); if (isDevelopmentMode) { - shell.exec(`cd "${path.resolve(plugins, plugin)}" && npm link strapi-helper-plugin`, { - silent - }); + shell.cd(path.resolve(plugins, plugin)); + shell.exec('npm link strapi-helper-plugin', {silent}); } else { - shell.exec(`cd "${path.resolve(plugins, plugin, 'node_modules', 'strapi-helper-plugin')}" && npm install`, { - silent - }); + shell.cd(path.resolve(plugins, plugin, 'node_modules', 'strapi-helper-plugin')); + shell.exec('npm install', {silent}); } shell.echo('🏗 Building...'); - - const build = shell.exec(`cd "${path.resolve(plugins, plugin)}" && APP_PATH="${appPath}" npm run build`, { - silent - }); + shell.cd(path.resolve(plugins, plugin)); + const build = shell.exec(`cross-env APP_PATH="${appPath}" npm run build`, {silent}); if (build.stderr && build.code !== 0) { console.error(build.stderr); diff --git a/packages/strapi-generate-admin/lib/after.js b/packages/strapi-generate-admin/lib/after.js index 6253ff67d3..99caa24e1d 100644 --- a/packages/strapi-generate-admin/lib/after.js +++ b/packages/strapi-generate-admin/lib/after.js @@ -4,8 +4,8 @@ * Module dependencies */ -const { exec } = require('child_process'); const path = require('path'); +const shell = require('shelljs'); const fs = require('fs-extra'); const { packageManager } = require('strapi-utils'); // eslint-disable-line import/no-unresolved @@ -26,13 +26,15 @@ module.exports = (scope, cb) => { // Install back-end admin `node_modules`. const cmd = packageManager.isStrapiInstalledWithNPM() ? 'npm install --production --ignore-scripts' : 'yarn install --production --ignore-scripts'; - exec(cmd, { - cwd: path.resolve(scope.rootPath, 'admin') - }, (err) => { - if (err) { - return cb(err); - } + + try { + shell.exec(cmd, { + cwd: path.resolve(scope.rootPath, 'admin'), + silent: true + }); cb(); - }); + } catch (e) { + cb(e); + } }; diff --git a/packages/strapi-generate-admin/lib/before.js b/packages/strapi-generate-admin/lib/before.js index 77f28df621..7070300bc2 100644 --- a/packages/strapi-generate-admin/lib/before.js +++ b/packages/strapi-generate-admin/lib/before.js @@ -15,7 +15,7 @@ const fs = require('fs-extra'); module.exports = function (scope, cb) { if (scope.developerMode) { fs.mkdirsSync(path.resolve(scope.rootPath)); - fs.symlinkSync(path.resolve(__dirname, '..', '..', 'strapi-admin'), path.resolve(scope.rootPath, 'admin'), 'dir'); + fs.symlinkSync(path.resolve(__dirname, '..', '..', 'strapi-admin'), path.resolve(scope.rootPath, 'admin'), 'junction'); } else { // Copy the admin files. fs.copySync(path.resolve(__dirname, '..', '..', 'strapi-admin'), path.resolve(scope.rootPath, 'admin'), { diff --git a/packages/strapi-generate-admin/package.json b/packages/strapi-generate-admin/package.json index f2ea8ff922..93439840cb 100644 --- a/packages/strapi-generate-admin/package.json +++ b/packages/strapi-generate-admin/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-admin", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate the default admin panel for a Strapi application.", "homepage": "http://strapi.io", "keywords": [ @@ -15,8 +15,9 @@ "dependencies": { "fs-extra": "^4.0.1", "lodash": "^4.17.5", - "strapi-admin": "3.0.0-alpha.23.1", - "strapi-utils": "3.0.0-alpha.23.1" + "shelljs": "^0.7.8", + "strapi-admin": "3.0.0-alpha.24.1", + "strapi-utils": "3.0.0-alpha.24.1" }, "author": { "email": "hi@strapi.io", diff --git a/packages/strapi-generate-api/package.json b/packages/strapi-generate-api/package.json index c70e5c26cb..37ad00e4f0 100644 --- a/packages/strapi-generate-api/package.json +++ b/packages/strapi-generate-api/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-api", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate an API for a Strapi application.", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-generate-api/templates/bookshelf/service.template b/packages/strapi-generate-api/templates/bookshelf/service.template index f20d20582f..a847f40253 100644 --- a/packages/strapi-generate-api/templates/bookshelf/service.template +++ b/packages/strapi-generate-api/templates/bookshelf/service.template @@ -121,7 +121,7 @@ module.exports = { const data = _.omit(values, <%= globalID %>.associations.map(ast => ast.alias)); // Create entry with no-relational data. - const entry = <%= globalID %>.forge(params).save(data); + const entry = await <%= globalID %>.forge(params).save(data); // Create relational data and return the entry. return <%= globalID %>.updateRelations(Object.assign(params, { values: relations })); diff --git a/packages/strapi-generate-controller/package.json b/packages/strapi-generate-controller/package.json index 8f81125507..553669eadf 100644 --- a/packages/strapi-generate-controller/package.json +++ b/packages/strapi-generate-controller/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-controller", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate a controller for a Strapi API.", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-generate-model/package.json b/packages/strapi-generate-model/package.json index 0794686eeb..061a4e5841 100644 --- a/packages/strapi-generate-model/package.json +++ b/packages/strapi-generate-model/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-model", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate a model for a Strapi API.", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-generate-new/files/.npmrc b/packages/strapi-generate-new/files/.npmrc new file mode 100644 index 0000000000..43c97e719a --- /dev/null +++ b/packages/strapi-generate-new/files/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/strapi-generate-new/lib/after.js b/packages/strapi-generate-new/lib/after.js index 50257d1fc8..958e0dc734 100644 --- a/packages/strapi-generate-new/lib/after.js +++ b/packages/strapi-generate-new/lib/after.js @@ -5,7 +5,6 @@ */ // Node.js core. -const { exec, execSync } = require('child_process'); const path = require('path'); // Public node modules. @@ -30,11 +29,6 @@ const trackSuccess = require('./success'); /* eslint-disable no-console */ /* eslint-disable prefer-template */ module.exports = (scope, cb) => { - console.log(`The app has been connected to the database ${green('successfully')}!`); - console.log(); - - trackSuccess('didConnectDatabase', scope); - console.log('🏗 Application generation:'); let loader = ora('Copy dashboard').start(); @@ -55,7 +49,7 @@ module.exports = (scope, cb) => { const othersDependencies = Object.keys(dependencies).filter(key => key.indexOf('strapi') === -1); // Add this check to know if we are in development mode so the creation is faster. const isStrapiInstalledWithNPM = packageManager.isStrapiInstalledWithNPM(); - const globalRootPath = execSync(packageManager.commands('root -g')); + const globalRootPath = shell.exec(packageManager.commands('root -g'), {silent: true}); // Verify if the dependencies are available into the global _.forEach(strapiDependencies, (key) => { @@ -151,11 +145,11 @@ module.exports = (scope, cb) => { installPlugin = installPlugin.then(() => { return new Promise(resolve => { loader = ora(`Install plugin ${cyan(defaultPlugin.name)}.`).start(); - exec(`node ${strapiBin} install ${defaultPlugin.name} ${scope.developerMode && defaultPlugin.core ? '--dev' : ''}`, (err) => { - if (err) { + shell.exec(`node ${strapiBin} install ${defaultPlugin.name} ${scope.developerMode && defaultPlugin.core ? '--dev' : ''}`, {silent: true}, (code, stdout, stderr) => { + if (code) { trackSuccess('didNotInstallProjectPlugins', scope); loader.warn(`An error occurred during ${defaultPlugin.name} plugin installation.`); - console.log(err); + console.log(stderr); return resolve(); } @@ -175,14 +169,14 @@ module.exports = (scope, cb) => { if (dependency.global) { try { fs.accessSync(dependency.path, fs.constants.R_OK | fs.constants.F_OK); - fs.symlinkSync(dependency.path, path.resolve(scope.rootPath, 'node_modules', dependency.key), 'dir'); + fs.symlinkSync(dependency.path, path.resolve(scope.rootPath, 'node_modules', dependency.key), 'junction'); } catch (e) { // Silent. } } else { try { fs.accessSync(path.resolve(scope.strapiRoot, 'node_modules', dependency.key), fs.constants.R_OK | fs.constants.F_OK); - fs.symlinkSync(path.resolve(scope.strapiRoot, 'node_modules', dependency.key), path.resolve(scope.rootPath, 'node_modules', dependency.key), 'dir'); + fs.symlinkSync(path.resolve(scope.strapiRoot, 'node_modules', dependency.key), path.resolve(scope.rootPath, 'node_modules', dependency.key), 'junction'); } catch (e) { // Silent. } @@ -201,7 +195,7 @@ module.exports = (scope, cb) => { console.log(`$ ${green('strapi start')}`); trackSuccess('didCreateProject', scope); - + cb(); }); } diff --git a/packages/strapi-generate-new/lib/before.js b/packages/strapi-generate-new/lib/before.js index cf496d937a..009132495c 100644 --- a/packages/strapi-generate-new/lib/before.js +++ b/packages/strapi-generate-new/lib/before.js @@ -8,12 +8,11 @@ const path = require('path'); const os = require('os'); const crypto = require('crypto'); -const exec = require('child_process').exec; // Public node modules. const _ = require('lodash'); -const {cyan} = require('chalk'); +const {cyan, green} = require('chalk'); const fs = require('fs-extra'); const inquirer = require('inquirer'); const shell = require('shelljs'); @@ -284,7 +283,11 @@ module.exports = (scope, cb) => { } console.log(); - console.log('⏳ Testing database connection...'); + console.log( + isQuick + ? '✅ Connected to the database' + : '⏳ Testing database connection...\r\nIt might take a minute, please have a coffee ☕️' + ); resolve(); }), @@ -310,19 +313,32 @@ module.exports = (scope, cb) => { scope.additionalsDependencies = ['strapi-hook-knex', 'knex']; } - exec(cmd, () => { + if (isQuick) { + scope.client.version = 'latest'; + + return resolve(); + } + + shell.exec(cmd, { silent: true }, () => { if (scope.client.module) { const lock = require(path.join(`${scope.tmpPath}`, '/node_modules/', `${scope.client.module}/package.json`)); scope.client.version = lock.version; if (scope.developerMode === true && scope.client.connector === 'strapi-hook-bookshelf') { - const knexVersion = require(path.join(`${scope.tmpPath}`,`/node_modules/`,`knex/package.json`)); + let knexVersion; + + try { + knexVersion = require(path.join(`${scope.tmpPath}`,'/node_modules/', 'knex', 'package.json')); + } catch (e) { + knexVersion = require(path.join(`${scope.tmpPath}`,'/node_modules/','strapi-hook-knex', 'node_modules', 'knex', 'package.json')); + } + scope.additionalsDependencies[1] = `knex@${knexVersion.version || 'latest'}`; } } if (scope.developerMode) { - exec(linkNodeModulesCommand, () => { + shell.exec(linkNodeModulesCommand, { silent: true }, () => { resolve(); }); } else { @@ -332,10 +348,30 @@ module.exports = (scope, cb) => { }) ]; + const connectedToTheDatabase = (withMessage = true) => { + console.log(); + + if (withMessage) { + console.log(`The app has been connected to the database ${green('successfully')}!`); + console.log(); + } + + trackSuccess('didConnectDatabase', scope); + + cb.success(); + }; + Promise.all(asyncFn) .then(() => { + // Bypass real connection test. + if (isQuick) { + return connectedToTheDatabase(false); + } + try { - require(path.join(`${scope.tmpPath}`, '/node_modules/', `${scope.client.connector}/lib/utils/connectivity.js`))(scope, cb.success, connectionValidation); + const connectivityFile = path.join(scope.tmpPath, 'node_modules', scope.client.connector, 'lib', 'utils', 'connectivity.js'); + + require(connectivityFile)(scope, connectedToTheDatabase, connectionValidation); } catch(err) { trackSuccess('didNotConnectDatabase', scope, err); console.log(err); diff --git a/packages/strapi-generate-new/package.json b/packages/strapi-generate-new/package.json index 3a731a0c68..888f01b079 100644 --- a/packages/strapi-generate-new/package.json +++ b/packages/strapi-generate-new/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-new", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate a new Strapi application.", "homepage": "http://strapi.io", "keywords": [ @@ -21,7 +21,8 @@ "node-machine-id": "^1.1.10", "ora": "^2.1.0", "request": "^2.88.0", - "strapi-utils": "3.0.0-alpha.23.1", + "shelljs": "^0.7.8", + "strapi-utils": "3.0.0-alpha.24.1", "uuid": "^3.1.0" }, "scripts": { diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/App/index.js b/packages/strapi-generate-plugin/files/admin/src/containers/App/index.js index fb2398a95c..ff6369ae2f 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/App/index.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/App/index.js @@ -13,7 +13,7 @@ import { Switch, Route } from 'react-router-dom'; import { bindActionCreators, compose } from 'redux'; // Utils -import { pluginId } from 'app'; +import pluginId from 'pluginId'; // Containers import HomePage from 'containers/HomePage'; @@ -21,6 +21,7 @@ import NotFoundPage from 'containers/NotFoundPage'; // When you're done studying the ExamplePage container, remove the following line and delete the ExamplePage container import ExamplePage from 'containers/ExamplePage'; +import reducer from './reducer'; class App extends React.Component { // When you're done studying the ExamplePage container, remove the following lines and delete the ExamplePage container @@ -44,7 +45,6 @@ class App extends React.Component { App.contextTypes = { plugins: PropTypes.object, - router: PropTypes.object.isRequired, updatePlugin: PropTypes.func, }; @@ -63,7 +63,9 @@ const mapStateToProps = createStructuredSelector({}); // Wrap the component to inject dispatch and state into it const withConnect = connect(mapStateToProps, mapDispatchToProps); +const withReducer = strapi.injectReducer({ key: 'global', reducer, pluginId }); export default compose( + withReducer, withConnect, )(App); diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/App/selectors.js b/packages/strapi-generate-plugin/files/admin/src/containers/App/selectors.js index 2393a073cd..f76ce3f0ef 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/App/selectors.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/App/selectors.js @@ -1,9 +1,10 @@ // import { createSelector } from 'reselect'; +// import pluginId from 'pluginId'; /** * Direct selector to the list state domain */ -// const selectGlobalDomain = () => state => state.get('global'); +// const selectGlobalDomain = () => state => state.get(`${pluginId}-global`); export {}; diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/constants.js b/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/constants.js index c7f7857e67..115ee3bbd1 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/constants.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/constants.js @@ -4,5 +4,7 @@ * */ -export const LOAD_DATA = 'ExamplePage/LOAD_DATA'; -export const LOADED_DATA = 'ExamplePage/LOADED_DATA'; +import pluginId from 'pluginId'; + +export const LOAD_DATA = `${pluginId}/ExamplePage/LOAD_DATA`; +export const LOADED_DATA = `${pluginId}/ExamplePage/LOADED_DATA`; diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/index.js b/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/index.js index a0b7057c63..54fd0530f4 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/index.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/index.js @@ -10,9 +10,7 @@ import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import { injectIntl } from 'react-intl'; import { bindActionCreators, compose } from 'redux'; - -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; +import pluginId from 'pluginId'; import Button from 'components/Button'; @@ -90,8 +88,8 @@ const mapStateToProps = createStructuredSelector({ const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'examplePage', reducer }); -const withSaga = injectSaga({ key: 'examplePage', saga }); +const withReducer = strapi.injectReducer({ key: 'examplePage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'examplePage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/selectors.js b/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/selectors.js index d35d2e404b..1ddaf47bb9 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/selectors.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/ExamplePage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from 'pluginId'; /** * Direct selector to the examplePage state domain */ -const selectExamplePageDomain = () => state => state.get('examplePage'); +const selectExamplePageDomain = () => state => state.get(`${pluginId}-examplePage`); /** * Default selector used by HomePage diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/constants.js b/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/constants.js index 3686db5138..6adcb7014c 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/constants.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/constants.js @@ -4,4 +4,6 @@ * */ -export const DEFAULT_ACTION = 'HomePage/DEFAULT_ACTION'; +import pluginId from 'pluginId'; + +export const DEFAULT_ACTION = `${pluginId}/HomePage/DEFAULT_ACTION`; diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/index.js b/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/index.js index e55bfef860..70cad54fe4 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/index.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/index.js @@ -10,9 +10,7 @@ import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import { injectIntl } from 'react-intl'; import { bindActionCreators, compose } from 'redux'; - -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; +import pluginId from 'pluginId'; // Selectors import selectHomePage from './selectors'; @@ -55,8 +53,8 @@ const mapStateToProps = createStructuredSelector({ const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'homePage', reducer }); -const withSaga = injectSaga({ key: 'homePage', saga }); +const withReducer = strapi.injectReducer({ key: 'homePage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/selectors.js b/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/selectors.js index cf3f854ff7..d51dccbae7 100644 --- a/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/selectors.js +++ b/packages/strapi-generate-plugin/files/admin/src/containers/HomePage/selectors.js @@ -1,9 +1,9 @@ import { createSelector } from 'reselect'; - +import pluginId from 'pluginId'; /** * Direct selector to the homePage state domain */ -const selectHomePageDomain = () => state => state.get('homePage'); +const selectHomePageDomain = () => state => state.get(`${pluginId}-homePage`); /** * Default selector used by HomePage diff --git a/packages/strapi-generate-plugin/files/admin/src/pluginId.js b/packages/strapi-generate-plugin/files/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-generate-plugin/files/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-generate-plugin/package.json b/packages/strapi-generate-plugin/package.json index e919fbdb3e..fc5b18c877 100644 --- a/packages/strapi-generate-plugin/package.json +++ b/packages/strapi-generate-plugin/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-plugin", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate an plugin for a Strapi application.", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-generate-policy/package.json b/packages/strapi-generate-policy/package.json index 3f96014fea..7605f7fae1 100644 --- a/packages/strapi-generate-policy/package.json +++ b/packages/strapi-generate-policy/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-policy", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate a policy for a Strapi API.", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-generate-service/package.json b/packages/strapi-generate-service/package.json index 6f9dac39fc..74518aed0e 100644 --- a/packages/strapi-generate-service/package.json +++ b/packages/strapi-generate-service/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate-service", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Generate a service for a Strapi API.", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-generate/package.json b/packages/strapi-generate/package.json index e0ab929b06..293382809b 100644 --- a/packages/strapi-generate/package.json +++ b/packages/strapi-generate/package.json @@ -1,6 +1,6 @@ { "name": "strapi-generate", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Master of ceremonies for the Strapi generators.", "homepage": "http://strapi.io", "keywords": [ @@ -17,7 +17,7 @@ "fs-extra": "^4.0.0", "lodash": "^4.17.5", "reportback": "^2.0.1", - "strapi-utils": "3.0.0-alpha.23.1" + "strapi-utils": "3.0.0-alpha.24.1" }, "author": { "name": "Strapi team", diff --git a/packages/strapi-helper-plugin/lib/internals/generators/container/class.js.hbs b/packages/strapi-helper-plugin/lib/internals/generators/container/class.js.hbs index eb2fbd9465..21c250def5 100644 --- a/packages/strapi-helper-plugin/lib/internals/generators/container/class.js.hbs +++ b/packages/strapi-helper-plugin/lib/internals/generators/container/class.js.hbs @@ -17,6 +17,7 @@ import { FormattedMessage } from 'react-intl'; import { createStructuredSelector } from 'reselect'; {{/if}} import { bindActionCreators, compose } from 'redux'; +// import pluginId from 'pluginId'; {{#if wantSaga}} import injectSaga from 'utils/injectSaga'; @@ -72,7 +73,7 @@ const withConnect = connect(mapStateToProps, mapDispatchToProps); /* Remove this line if the container doesn't have a route and * check the documentation to see how to create the container's store */ -const withReducer = injectReducer({ key: '{{ camelCase name }}', reducer }); +const withReducer = injectReducer({ key: '{{ camelCase name }}', reducer, pluginId }); {{else}} const withConnect = connect(null, mapDispatchToProps); {{/if}} @@ -81,7 +82,7 @@ const withConnect = connect(null, mapDispatchToProps); /* Remove the line below the container doesn't have a route and * check the documentation to see how to create the container's store */ -const withSaga = injectSaga({ key: '{{ camelCase name }}', saga }); +const withSaga = injectSaga({ key: '{{ camelCase name }}', saga, pluginId }); {{/if}} export default compose( diff --git a/packages/strapi-helper-plugin/lib/internals/generators/container/selectors.js.hbs b/packages/strapi-helper-plugin/lib/internals/generators/container/selectors.js.hbs index 2d0d62e1c2..17650bb3ed 100644 --- a/packages/strapi-helper-plugin/lib/internals/generators/container/selectors.js.hbs +++ b/packages/strapi-helper-plugin/lib/internals/generators/container/selectors.js.hbs @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from 'pluginId'; /** * Direct selector to the {{ camelCase name }} state domain */ -const select{{ properCase name }}Domain = () => (state) => state.get('{{ camelCase name }}'); +const select{{ properCase name }}Domain = () => (state) => state.get(`${pluginId}-{{ camelCase name }}`); /** * Other specific selectors diff --git a/packages/strapi-helper-plugin/lib/internals/generators/language/index.js b/packages/strapi-helper-plugin/lib/internals/generators/language/index.js index dd9561dad8..5ee89a274c 100644 --- a/packages/strapi-helper-plugin/lib/internals/generators/language/index.js +++ b/packages/strapi-helper-plugin/lib/internals/generators/language/index.js @@ -1,7 +1,7 @@ /** * Language Generator */ -const exec = require('child_process').exec; +const shell = require('shelljs'); module.exports = { description: 'Add a langauge', @@ -66,11 +66,12 @@ module.exports = { actions.push( () => { const cmd = 'npm run extract-intl'; - exec(cmd, (err, result, stderr) => { - if (err || stderr) { - throw err || stderr; + shell.exec(cmd, {silent: true}, (code, stdout, stderr) => { + if (code) { + throw stderr; } - process.stdout.write(result); + + process.stdout.write(stdout); }); } ); diff --git a/packages/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js b/packages/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js index e99c4a4d0f..ed26d3c605 100644 --- a/packages/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js +++ b/packages/strapi-helper-plugin/lib/internals/scripts/loadAdminConfigurations.js @@ -2,9 +2,10 @@ const path = require('path'); const shell = require('shelljs'); const pwd = shell.pwd(); + const isDevelopmentMode = path.resolve(pwd.stdout).indexOf('strapi-admin') !== -1; const isSetup = process.env.IS_MONOREPO || false; -const appPath = isDevelopmentMode ? path.resolve(process.env.PWD, '..') : path.resolve(pwd.stdout, '..'); +const appPath = isDevelopmentMode ? path.resolve(process.env.PWD || process.cwd(), '..') : path.resolve(pwd.stdout, '..'); // Load the app configurations only when : // - starting the app in dev mode @@ -15,9 +16,13 @@ if (!isSetup) { strapi.log.level = 'silent'; (async () => { - await strapi.load({ - environment: process.env.NODE_ENV, - }); + try { + await strapi.load({ + environment: process.env.NODE_ENV, + }); + } catch (e) { + // console.log(e); + } // Force exit process if an other process doen't exit during Strapi load. process.exit(); diff --git a/packages/strapi-helper-plugin/lib/internals/scripts/npmcheckversion.js b/packages/strapi-helper-plugin/lib/internals/scripts/npmcheckversion.js index 6461a75d92..eeda62a3b5 100644 --- a/packages/strapi-helper-plugin/lib/internals/scripts/npmcheckversion.js +++ b/packages/strapi-helper-plugin/lib/internals/scripts/npmcheckversion.js @@ -1,7 +1,7 @@ /* eslint-disable */ -var exec = require('child_process').exec; -exec('npm -v', function (err, stdout, stderr) { - if (err) throw err; +const shell = require('shelljs'); +shell.exec('npm -v', {silent: true}, function (code, stdout, stderr) { + if (code) throw stderr; if (parseFloat(stdout) < 3) { throw new Error('[ERROR: Strapi plugin] You need npm version @>=3'); process.exit(1); diff --git a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.base.babel.js b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.base.babel.js index 588528cbf5..2aeaab12a4 100644 --- a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.base.babel.js +++ b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.base.babel.js @@ -15,14 +15,14 @@ const isAdmin = process.env.IS_ADMIN === 'true'; const ExtractTextPlugin = require('extract-text-webpack-plugin'); const isSetup = process.env.IS_MONOREPO || false; -const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', ( isAdmin ? '' : '..' )); +const appPath = process.env.APP_PATH || path.resolve(process.env.PWD || process.cwd(), '..', ( isAdmin ? '' : '..' )); const adminPath = (() => { if (isAdmin && isSetup) { return path.resolve(appPath, 'strapi-admin'); } - return path.resolve(process.env.PWD); + return path.resolve(process.env.PWD || process.cwd()); })(); // Define remote and backend URLs. @@ -49,7 +49,7 @@ if (isAdmin && !isSetup) { let server = require(serverConfig); server = templateConfiguration(server); - if (process.env.PWD.indexOf('/admin') !== -1) { + if ((process.env.PWD || process.cwd()).indexOf('/admin') !== -1) { if (_.get(server, 'admin.build.host')) { URLs.host = _.get(server, 'admin.build.host', '/admin').replace(/\/$/, '') || '/'; } else { diff --git a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dev.babel.js b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dev.babel.js index ade7bcca97..5067375957 100644 --- a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dev.babel.js +++ b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dev.babel.js @@ -15,8 +15,8 @@ const postcssReporter = require('postcss-reporter'); const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); const isAdmin = process.env.IS_ADMIN === 'true'; -const isSetup = path.resolve(process.env.PWD, '..', '..') === path.resolve(process.env.INIT_CWD); -const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', isAdmin ? '' : '..'); +const isSetup = path.resolve(process.env.PWD || process.cwd(), '..', '..') === path.resolve(process.env.INIT_CWD); +const appPath = process.env.APP_PATH || path.resolve(process.env.PWD || process.cwd(), '..', isAdmin ? '' : '..'); const rootAdminpath = (() => { if (isSetup) { diff --git a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dll.babel.js b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dll.babel.js index b1062b1dcf..9a78f6cd47 100644 --- a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dll.babel.js +++ b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.dll.babel.js @@ -10,7 +10,7 @@ const webpack = require('webpack'); const isAdmin = process.env.IS_ADMIN === 'true'; const isSetup = process.env.IS_MONOREPO || false; -const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', isAdmin ? '' : '..'); +const appPath = process.env.APP_PATH || path.resolve(process.env.PWD || process.cwd(), '..', isAdmin ? '' : '..'); const rootAdminpath = (() => { if (isSetup) { diff --git a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js index 1c6be52f13..1cae20064e 100644 --- a/packages/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js +++ b/packages/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js @@ -16,10 +16,10 @@ const base = require('./webpack.base.babel'); const isAdmin = process.env.IS_ADMIN === 'true'; // const isSetup = path.resolve(process.env.PWD, '..', '..') === path.resolve(process.env.INIT_CWD); const isSetup = process.env.IS_MONOREPO || false; -const appPath = process.env.APP_PATH || path.resolve(process.env.PWD, '..', isAdmin ? '' : '..'); +const appPath = process.env.APP_PATH || path.resolve(process.env.PWD || process.cwd(), '..', isAdmin ? '' : '..'); const adminPath = (() => { if (isSetup) { - return isAdmin ? path.resolve(appPath, 'strapi-admin') : path.resolve(process.env.PWD, '..'); + return isAdmin ? path.resolve(appPath, 'strapi-admin') : path.resolve(process.env.PWD || process.cwd(), '..'); } return path.resolve(appPath, 'admin'); @@ -71,7 +71,7 @@ if (isAdmin && !isSetup) { try { const server = require(serverConfig); - if (process.env.PWD.indexOf('/admin') !== -1) { + if ((process.env.PWD || process.cwd()).indexOf('/admin') !== -1) { if (_.get(server, 'admin.build.host')) { publicPath = _.get(server, 'admin.build.host', '/admin').replace(/\/$/, '') || '/'; } else { @@ -128,7 +128,7 @@ const main = (() => { return path.join(appPath, 'admin', 'admin', 'src', 'app.js'); } - return path.join(process.env.PWD, 'node_modules', 'strapi-helper-plugin', 'lib', 'src', 'app.js'); + return path.join(process.env.PWD || process.cwd(), 'node_modules', 'strapi-helper-plugin', 'lib', 'src', 'app.js'); })(); module.exports = base({ diff --git a/packages/strapi-helper-plugin/lib/server/middlewares/frontendMiddleware.js b/packages/strapi-helper-plugin/lib/server/middlewares/frontendMiddleware.js index 19b6228af6..3d9db23d93 100644 --- a/packages/strapi-helper-plugin/lib/server/middlewares/frontendMiddleware.js +++ b/packages/strapi-helper-plugin/lib/server/middlewares/frontendMiddleware.js @@ -47,7 +47,7 @@ const addDevMiddlewares = (app, webpackConfig) => { /** * Front-end middleware */ -module.exports = (app) => { +module.exports = app => { const webpackConfig = require('../../internals/webpack/webpack.dev.babel'); // const webpackConfig = require(path.resolve(process.cwd(), 'node_modules', 'strapi-helper-plugin', 'internals', 'webpack', 'webpack.dev.babel')); diff --git a/packages/strapi-helper-plugin/lib/src/app.js b/packages/strapi-helper-plugin/lib/src/app.js index 24f2074753..c666f72f38 100644 --- a/packages/strapi-helper-plugin/lib/src/app.js +++ b/packages/strapi-helper-plugin/lib/src/app.js @@ -11,21 +11,18 @@ import './public-path.js'; // eslint-disable-line import/extensions import React from 'react'; import Loadable from 'react-loadable'; -import { Provider } from 'react-redux'; -import LoadingIndicatorPage from 'components/LoadingIndicatorPage'; -import configureStore from './store'; +import LoadingIndicatorPage from './components/LoadingIndicatorPage'; import { translationMessages } from './i18n'; - const LoadableApp = Loadable({ loader: () => import('containers/App'), loading: LoadingIndicatorPage, }); -const tryRequireRoot = (source) => { +const tryRequireRoot = source => { try { return require('../../../../admin/src/' + source + '.js').default; // eslint-disable-line prefer-template - } catch(err) { + } catch (err) { return null; } }; @@ -36,7 +33,7 @@ const pluginRequirements = tryRequireRoot('requirements'); const layout = (() => { try { return require('../../../../config/layout.js'); // eslint-disable-line import/no-unresolved - } catch(err) { + } catch (err) { return null; } })(); @@ -44,40 +41,30 @@ const layout = (() => { const injectedComponents = (() => { try { return require('injectedComponents').default; // eslint-disable-line import/no-unresolved - } catch(err) { + } catch (err) { return []; } -}); +})(); // Plugin identifier based on the package.json `name` value const pluginPkg = require('../../../../package.json'); -const pluginId = pluginPkg.name.replace( - /^strapi-plugin-/i, - '' -); +const pluginId = pluginPkg.name.replace(/^strapi-plugin-/i, ''); const pluginName = pluginPkg.strapi.name; const pluginDescription = pluginPkg.strapi.description || pluginPkg.description; const apiUrl = `${strapi.backendURL}/${pluginId}`; const router = strapi.router; // Create redux store with Strapi admin history -const store = configureStore({}, strapi.router, pluginName); +// const store = configureStore({}, strapi.router, pluginName); +const store = strapi.store; // Define the plugin root component function Comp(props) { return ( - - - + ); } -if (window.Cypress) { - window.__store__ = Object.assign(window.__store__ || {}, { - [pluginId]: store, - }); -} - // Hot reloadable translation json files if (module.hot) { // modules.hot.accept does not accept dynamic dependencies, diff --git a/packages/strapi-helper-plugin/lib/src/assets/icons/icon_layout.svg b/packages/strapi-helper-plugin/lib/src/assets/icons/icon_layout.svg new file mode 100644 index 0000000000..5c505a9000 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/assets/icons/icon_layout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/strapi-helper-plugin/lib/src/assets/icons/icon_layout_hover.svg b/packages/strapi-helper-plugin/lib/src/assets/icons/icon_layout_hover.svg new file mode 100644 index 0000000000..ad90546d65 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/assets/icons/icon_layout_hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/strapi-helper-plugin/lib/src/components/EmptyAttributesBlock/index.js b/packages/strapi-helper-plugin/lib/src/components/EmptyAttributesBlock/index.js index c84b9aec02..50aadaf4b8 100644 --- a/packages/strapi-helper-plugin/lib/src/components/EmptyAttributesBlock/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/EmptyAttributesBlock/index.js @@ -7,7 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import Button from 'components/Button'; +import Button from '../Button'; import styles from './styles.scss'; function EmptyAttributesBlock({ description, label, onClick, title, id }) { @@ -49,4 +49,4 @@ EmptyAttributesBlock.propTypes = { title: PropTypes.string, }; -export default EmptyAttributesBlock; \ No newline at end of file +export default EmptyAttributesBlock; diff --git a/packages/strapi-helper-plugin/lib/src/components/HeaderNav/index.js b/packages/strapi-helper-plugin/lib/src/components/HeaderNav/index.js index 8d54627c50..b0c212a115 100644 --- a/packages/strapi-helper-plugin/lib/src/components/HeaderNav/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/HeaderNav/index.js @@ -11,7 +11,7 @@ import { map } from 'lodash'; import PropTypes from 'prop-types'; // Utils -import { darken } from 'utils/colors'; +import { darken } from '../../utils/colors'; // Styles import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/IcoContainer/index.js b/packages/strapi-helper-plugin/lib/src/components/IcoContainer/index.js index a80156a5a4..3cb772ec9d 100644 --- a/packages/strapi-helper-plugin/lib/src/components/IcoContainer/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/IcoContainer/index.js @@ -2,7 +2,7 @@ import React from 'react'; import { map } from 'lodash'; import PropTypes from 'prop-types'; -import Ico from 'components/Ico'; +import Ico from '../Ico'; import styles from './styles.scss'; function IcoContainer({ icons }) { diff --git a/packages/strapi-helper-plugin/lib/src/components/ImgPreview/index.js b/packages/strapi-helper-plugin/lib/src/components/ImgPreview/index.js index ea8972e693..202b557d5f 100644 --- a/packages/strapi-helper-plugin/lib/src/components/ImgPreview/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/ImgPreview/index.js @@ -11,9 +11,9 @@ import PropTypes from 'prop-types'; import { get, has, isArray, isEmpty, startsWith, size } from 'lodash'; import cn from 'classnames'; -import BkgImg from 'assets/icons/icon_upload.svg'; -import ImgPreviewArrow from 'components/ImgPreviewArrow'; -import ImgPreviewHint from 'components/ImgPreviewHint'; +import BkgImg from '../../assets/icons/icon_upload.svg'; +import ImgPreviewArrow from '../ImgPreviewArrow'; +import ImgPreviewHint from '../ImgPreviewHint'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js index 512d7b11c0..01a91ad066 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputAddonWithErrors/index.js @@ -9,15 +9,15 @@ import PropTypes from 'prop-types'; import { isEmpty, isFunction } from 'lodash'; import cn from 'classnames'; -// Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputAddon from 'components/InputAddon'; -import InputSpacer from 'components/InputSpacer'; - // Utils -import validateInput from 'utils/inputsValidations'; +import validateInput from '../../utils/inputsValidations'; + +// Design +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputAddon from '../InputAddon'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputCheckbox/Loadable.js b/packages/strapi-helper-plugin/lib/src/components/InputCheckbox/Loadable.js index caed2adc89..b5d3ec9c3d 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputCheckbox/Loadable.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputCheckbox/Loadable.js @@ -1,6 +1,6 @@ import Loadable from 'react-loadable'; -import LoadingIndicator from 'components/LoadingIndicator'; +import LoadingIndicator from '../LoadingIndicator'; export default Loadable({ loader: () => import('./index'), diff --git a/packages/strapi-helper-plugin/lib/src/components/InputCheckboxWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputCheckboxWithErrors/index.js index d3d0c7ac36..9ada89ad99 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputCheckboxWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputCheckboxWithErrors/index.js @@ -11,10 +11,10 @@ import { isEmpty, isObject, isFunction } from 'lodash'; import cn from 'classnames'; // Design -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputCheckbox from 'components/InputCheckbox'; -import InputSpacer from 'components/InputSpacer'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputCheckbox from '../InputCheckbox'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputDate/Loadable.js b/packages/strapi-helper-plugin/lib/src/components/InputDate/Loadable.js index caed2adc89..b5d3ec9c3d 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputDate/Loadable.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputDate/Loadable.js @@ -1,6 +1,6 @@ import Loadable from 'react-loadable'; -import LoadingIndicator from 'components/LoadingIndicator'; +import LoadingIndicator from '../LoadingIndicator'; export default Loadable({ loader: () => import('./index'), diff --git a/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js index d2bed6485d..070930eab0 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputDateWithErrors/index.js @@ -9,15 +9,15 @@ import PropTypes from 'prop-types'; import { get, isEmpty, isFunction } from 'lodash'; import cn from 'classnames'; -// Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputDate from 'components/InputDate'; -import InputSpacer from 'components/InputSpacer'; - // Utils -import validateInput from 'utils/inputsValidations'; +import validateInput from '../../utils/inputsValidations'; + +// Design +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputDate from '../InputDate'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js index cd6da489fa..6974761caa 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputEmailWithErrors/index.js @@ -9,15 +9,15 @@ import PropTypes from 'prop-types'; import { isEmpty, isFunction } from 'lodash'; import cn from 'classnames'; -// Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputEmail from 'components/InputEmail'; -import InputSpacer from 'components/InputSpacer'; - // Utils -import validateInput from 'utils/inputsValidations'; +import validateInput from '../../utils/inputsValidations'; + +// Design +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputEmail from '../InputEmail'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputFile/index.js b/packages/strapi-helper-plugin/lib/src/components/InputFile/index.js index 5f3ca55f3c..035bfe1e7f 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputFile/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputFile/index.js @@ -11,8 +11,8 @@ import { FormattedMessage } from 'react-intl'; import { cloneDeep, isArray, isObject } from 'lodash'; import cn from 'classnames'; -import ImgPreview from 'components/ImgPreview'; -import InputFileDetails from 'components/InputFileDetails'; +import ImgPreview from '../ImgPreview'; +import InputFileDetails from '../InputFileDetails'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputFileWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputFileWithErrors/index.js index aeef4c354a..bcb36bb5fa 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputFileWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputFileWithErrors/index.js @@ -10,11 +10,11 @@ import cn from 'classnames'; import { differenceBy, isEmpty } from 'lodash'; // Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputFile from 'components/InputFile'; -import InputSpacer from 'components/InputSpacer'; -import InputErrors from 'components/InputErrors'; +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputFile from '../InputFile'; +import InputSpacer from '../InputSpacer'; +import InputErrors from '../InputErrors'; // Styles import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputNumber/Loadable.js b/packages/strapi-helper-plugin/lib/src/components/InputNumber/Loadable.js index caed2adc89..b5d3ec9c3d 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputNumber/Loadable.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputNumber/Loadable.js @@ -1,6 +1,6 @@ import Loadable from 'react-loadable'; -import LoadingIndicator from 'components/LoadingIndicator'; +import LoadingIndicator from '../LoadingIndicator'; export default Loadable({ loader: () => import('./index'), diff --git a/packages/strapi-helper-plugin/lib/src/components/InputNumber/index.js b/packages/strapi-helper-plugin/lib/src/components/InputNumber/index.js index c5fa4dce0e..5aafe09b9b 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputNumber/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputNumber/index.js @@ -29,6 +29,7 @@ function InputNumber(props) { onFocus={props.onFocus} placeholder={message} ref={props.inputRef} + step={!Number.isNaN(Number(props.step)) ? Number(props.step) : 1} style={props.style} tabIndex={props.tabIndex} type="number" @@ -49,6 +50,7 @@ InputNumber.defaultProps = { onBlur: () => {}, onFocus: () => {}, placeholder: 'app.utils.placeholder.defaultMessage', + step: 1, style: {}, tabIndex: '0', }; @@ -65,6 +67,7 @@ InputNumber.propTypes = { onChange: PropTypes.func.isRequired, onFocus: PropTypes.func, placeholder: PropTypes.string, + step: PropTypes.number, style: PropTypes.object, tabIndex: PropTypes.string, value: PropTypes.oneOfType([ diff --git a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js index 56668821b4..1208407f52 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputNumberWithErrors/index.js @@ -3,15 +3,15 @@ import PropTypes from 'prop-types'; import { isEmpty, isFunction } from 'lodash'; import cn from 'classnames'; -// Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputNumber from 'components/InputNumber'; -import InputSpacer from 'components/InputSpacer'; - // Utils -import validateInput from 'utils/inputsValidations'; +import validateInput from '../../utils/inputsValidations'; + +// Design +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputNumber from '../InputNumber'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; @@ -83,6 +83,7 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea placeholder, style, tabIndex, + step, value, } = this.props; const handleBlur = isFunction(onBlur) ? onBlur : this.handleBlur; @@ -121,6 +122,7 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea placeholder={placeholder} style={inputStyle} tabIndex={tabIndex} + step={step} value={value} /> import('./index'), diff --git a/packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js b/packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js index 2fa3b79c96..6577f6061e 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputSelect/index.js @@ -10,7 +10,7 @@ import { isEmpty, isObject, map } from 'lodash'; import cn from 'classnames'; // Design -import SelectOption from 'components/SelectOption'; +import SelectOption from '../SelectOption'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js index 0d27421897..20269e95af 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputSelectWithErrors/index.js @@ -10,10 +10,10 @@ import { get, isEmpty, isFunction } from 'lodash'; import cn from 'classnames'; // Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputSelect from 'components/InputSelect'; +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputSelect from '../InputSelect'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputText/Loadable.js b/packages/strapi-helper-plugin/lib/src/components/InputText/Loadable.js index caed2adc89..b5d3ec9c3d 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputText/Loadable.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputText/Loadable.js @@ -1,6 +1,6 @@ import Loadable from 'react-loadable'; -import LoadingIndicator from 'components/LoadingIndicator'; +import LoadingIndicator from '../LoadingIndicator'; export default Loadable({ loader: () => import('./index'), diff --git a/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js index 54e8547e61..da72bc0328 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputTextAreaWithErrors/index.js @@ -3,15 +3,15 @@ import PropTypes from 'prop-types'; import { isEmpty, isFunction } from 'lodash'; import cn from 'classnames'; -// Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputTextArea from 'components/InputTextArea'; -import InputSpacer from 'components/InputSpacer'; - // Utils -import validateInput from 'utils/inputsValidations'; +import validateInput from '../../utils/inputsValidations'; + +// Design +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputTextArea from '../InputTextArea'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js index 05b5990397..a4cec4ab42 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputTextWithErrors/index.js @@ -3,15 +3,15 @@ import PropTypes from 'prop-types'; import { isEmpty, isFunction } from 'lodash'; import cn from 'classnames'; -// Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputText from 'components/InputText'; -import InputSpacer from 'components/InputSpacer'; - // Utils -import validateInput from 'utils/inputsValidations'; +import validateInput from '../../utils/inputsValidations'; + +// Design +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputText from '../InputText'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js b/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js index b8740452f6..1ebe7f5ae3 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputToggleWithErrors/index.js @@ -9,11 +9,11 @@ import PropTypes from 'prop-types'; import cn from 'classnames'; import { isEmpty } from 'lodash'; // Design -import Label from 'components/Label'; -import InputDescription from 'components/InputDescription'; -import InputErrors from 'components/InputErrors'; -import InputToggle from 'components/InputToggle'; -import InputSpacer from 'components/InputSpacer'; +import Label from '../Label'; +import InputDescription from '../InputDescription'; +import InputErrors from '../InputErrors'; +import InputToggle from '../InputToggle'; +import InputSpacer from '../InputSpacer'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js index 8e7cfdf2c6..6558e1e2f4 100644 --- a/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/InputsIndex/index.js @@ -9,18 +9,18 @@ import PropTypes from 'prop-types'; import { isEmpty, isObject, merge } from 'lodash'; // Design -import InputAddonWithErrors from 'components/InputAddonWithErrors'; -import InputCheckboxWithErrors from 'components/InputCheckboxWithErrors'; -import InputDateWithErrors from 'components/InputDateWithErrors'; -import InputEmailWithErrors from 'components/InputEmailWithErrors'; -import InputFileWithErrors from 'components/InputFileWithErrors'; -import InputNumberWithErrors from 'components/InputNumberWithErrors'; -import InputSearchWithErrors from 'components/InputSearchWithErrors'; -import InputSelectWithErrors from 'components/InputSelectWithErrors'; -import InputPasswordWithErrors from 'components/InputPasswordWithErrors'; -import InputTextAreaWithErrors from 'components/InputTextAreaWithErrors'; -import InputTextWithErrors from 'components/InputTextWithErrors'; -import InputToggleWithErrors from 'components/InputToggleWithErrors'; +import InputAddonWithErrors from '../InputAddonWithErrors'; +import InputCheckboxWithErrors from '../InputCheckboxWithErrors'; +import InputDateWithErrors from '../InputDateWithErrors'; +import InputEmailWithErrors from '../InputEmailWithErrors'; +import InputFileWithErrors from '../InputFileWithErrors'; +import InputNumberWithErrors from '../InputNumberWithErrors'; +import InputSearchWithErrors from '../InputSearchWithErrors'; +import InputSelectWithErrors from '../InputSelectWithErrors'; +import InputPasswordWithErrors from '../InputPasswordWithErrors'; +import InputTextAreaWithErrors from '../InputTextAreaWithErrors'; +import InputTextWithErrors from '../InputTextWithErrors'; +import InputToggleWithErrors from '../InputToggleWithErrors'; const DefaultInputError = ({ type }) =>
Your input type: {type} does not exist
; diff --git a/packages/strapi-helper-plugin/lib/src/components/NavLink/index.js b/packages/strapi-helper-plugin/lib/src/components/NavLink/index.js new file mode 100644 index 0000000000..2399e38ab0 --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/NavLink/index.js @@ -0,0 +1,63 @@ +/** + * + * NavLink + * + */ + +import React from 'react'; +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; +import { isObject } from 'lodash'; +import cn from 'classnames'; + +import styles from './styles.scss'; + +function NavLink(props) { + let content; + + if (typeof props.message === 'string') { + content = props.message; + } else if (isObject(props.message) && props.message.id) { + content = ; + } else { + // Default value. + content = props.children; + } + + let icon = ; + + if (props.icon === 'layout') { + icon = ; + } + + return ( + + {icon} + {content} + + ); +} + +NavLink.defaultProps = { + children: '', + icon: '', + message: '', + url: '', +}; + +NavLink.propTypes = { + children: PropTypes.node, + icon: PropTypes.string, + message: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.string, + PropTypes.shape({ + id: PropTypes.string, + params: PropTypes.object, + }), + ]), + url: PropTypes.string, +}; + +export default NavLink; diff --git a/packages/strapi-helper-plugin/lib/src/components/NavLink/styles.scss b/packages/strapi-helper-plugin/lib/src/components/NavLink/styles.scss new file mode 100644 index 0000000000..58a491a5cd --- /dev/null +++ b/packages/strapi-helper-plugin/lib/src/components/NavLink/styles.scss @@ -0,0 +1,28 @@ +a.navLink { + display: block; + width: 100%; + text-decoration: none; + span, i { + color: #333740; + } + span { + font-size: 13px; + } + i { + width: 13px; + height: 11px; + margin-right: 10px; + } + .layout { + display: inline-block; + background-image: url('../../assets/icons/icon_layout.svg'); + } + &:hover { + span, i { + color: #007EFF; + } + .layout { + background-image: url('../../assets/icons/icon_layout_hover.svg'); + } + } +} \ No newline at end of file diff --git a/packages/strapi-helper-plugin/lib/src/components/NotFound/index.js b/packages/strapi-helper-plugin/lib/src/components/NotFound/index.js index 6c629fca70..acb081e380 100644 --- a/packages/strapi-helper-plugin/lib/src/components/NotFound/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/NotFound/index.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import Button from 'components/Button'; +import Button from '../Button'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/index.js b/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/index.js index 36623534aa..913ebbc47b 100644 --- a/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/index.js @@ -12,27 +12,78 @@ import cn from 'classnames'; import styles from './styles.scss'; +const DELAY = 1000; + class OverlayBlocker extends React.Component { constructor(props) { super(props); + this.state = { elapsed: 0, start: 0 }; this.overlayContainer = document.createElement('div'); document.body.appendChild(this.overlayContainer); } + componentDidUpdate(prevProps) { + const { isOpen } = this.props; + + if (prevProps.isOpen !== this.props.isOpen && isOpen) { + this.startTimer(); + } + + if (prevProps.isOpen !== isOpen && !isOpen) { + this.stopTimer(); + } + } + componentWillUnmount() { document.body.removeChild(this.overlayContainer); } + tick = () => { + const { elapsed } = this.state; + + if (elapsed > 15) { + clearInterval(this.timer); + + return; + } + + this.setState(prevState => ({ elapsed: (Math.round(Date.now() - prevState.start) / 1000) })); + } + + startTimer = () => { + this.setState({ start: Date.now() }); + this.timer = setInterval(this.tick, DELAY); + } + + stopTimer = () => { + this.setState({ elapsed: 0 }); + clearInterval(this.timer); + } + render() { - const { title, description, icon } = this.props; + let { title, description, icon } = this.props; + const { elapsed } = this.state; + + let button = ( + + ); + + if (elapsed > 15) { + button = null; + icon = 'fa fa-clock-o'; + description = 'components.OverlayBlocker.description.serverError'; + title = 'components.OverlayBlocker.title.serverError'; + } const content = this.props.children ? ( this.props.children ) : (
-
+
@@ -42,9 +93,7 @@ class OverlayBlocker extends React.Component {

- + {button}
); @@ -65,7 +114,7 @@ class OverlayBlocker extends React.Component { } OverlayBlocker.defaultProps = { - children: '', + children: null, description: 'components.OverlayBlocker.description', icon: 'fa fa-refresh', isOpen: false, diff --git a/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/styles.scss b/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/styles.scss index e365f100cf..5cbda16d99 100644 --- a/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/styles.scss +++ b/packages/strapi-helper-plugin/lib/src/components/OverlayBlocker/styles.scss @@ -23,6 +23,9 @@ color: #323740; margin-right: 20px; line-height: 9.3rem; +} + +.spin { > i { -webkit-animation:spin 4s linear infinite; -moz-animation:spin 4s linear infinite; diff --git a/packages/strapi-helper-plugin/lib/src/components/PageFooter/index.js b/packages/strapi-helper-plugin/lib/src/components/PageFooter/index.js index 56053b72a4..56e5df63a1 100644 --- a/packages/strapi-helper-plugin/lib/src/components/PageFooter/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/PageFooter/index.js @@ -10,7 +10,7 @@ import cn from 'classnames'; import { get } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import GlobalPagination from 'components/GlobalPagination'; +import GlobalPagination from '../GlobalPagination'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/PluginHeader/index.js b/packages/strapi-helper-plugin/lib/src/components/PluginHeader/index.js index 96af797042..ef20157df1 100644 --- a/packages/strapi-helper-plugin/lib/src/components/PluginHeader/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/PluginHeader/index.js @@ -8,8 +8,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import cn from 'classnames'; -import PluginHeaderTitle from 'components/PluginHeaderTitle'; -import PluginHeaderActions from 'components/PluginHeaderActions'; +import PluginHeaderTitle from '../PluginHeaderTitle'; +import PluginHeaderActions from '../PluginHeaderActions'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/PluginHeaderActions/index.js b/packages/strapi-helper-plugin/lib/src/components/PluginHeaderActions/index.js index 02f1bc0b06..544638b577 100644 --- a/packages/strapi-helper-plugin/lib/src/components/PluginHeaderActions/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/PluginHeaderActions/index.js @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { isArray, isFunction } from 'lodash'; -import Button from 'components/Button'; +import Button from '../Button'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/PluginHeaderTitle/index.js b/packages/strapi-helper-plugin/lib/src/components/PluginHeaderTitle/index.js index 83400fb626..ba373dc033 100644 --- a/packages/strapi-helper-plugin/lib/src/components/PluginHeaderTitle/index.js +++ b/packages/strapi-helper-plugin/lib/src/components/PluginHeaderTitle/index.js @@ -9,7 +9,7 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { isEmpty, isFunction, isObject } from 'lodash'; -import LoadingBar from 'components/LoadingBar'; +import LoadingBar from '../LoadingBar'; import styles from './styles.scss'; diff --git a/packages/strapi-helper-plugin/lib/src/components/PopUpWarning/Loadable.js b/packages/strapi-helper-plugin/lib/src/components/PopUpWarning/Loadable.js index caed2adc89..b5d3ec9c3d 100644 --- a/packages/strapi-helper-plugin/lib/src/components/PopUpWarning/Loadable.js +++ b/packages/strapi-helper-plugin/lib/src/components/PopUpWarning/Loadable.js @@ -1,6 +1,6 @@ import Loadable from 'react-loadable'; -import LoadingIndicator from 'components/LoadingIndicator'; +import LoadingIndicator from '../LoadingIndicator'; export default Loadable({ loader: () => import('./index'), diff --git a/packages/strapi-helper-plugin/lib/src/reducers.js b/packages/strapi-helper-plugin/lib/src/reducers.js deleted file mode 100644 index 675e54a67a..0000000000 --- a/packages/strapi-helper-plugin/lib/src/reducers.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Combine all reducers in this file and export the combined reducers. - * If we were to do this in store.js, reducers wouldn't be hot reloadable. - */ - -import { combineReducers } from 'redux-immutable'; -import { fromJS } from 'immutable'; -import { LOCATION_CHANGE } from 'react-router-redux'; - -import globalReducer from 'containers/App/reducer'; // eslint-disable-line - -/* - * routeReducer - * - * The reducer merges route location changes into our immutable state. - * The change is necessitated by moving to react-router-redux@4 - * - */ - -// Initial routing state -const routeInitialState = fromJS({ - locationBeforeTransitions: null, -}); - -/** - * Merge route into the global application state - */ -function routeReducer(state = routeInitialState, action) { - switch (action.type) { - /* istanbul ignore next */ - case LOCATION_CHANGE: - return state.merge({ - locationBeforeTransitions: action.payload, - }); - default: - return state; - } -} - -/** - * Creates the main reducer with the asynchronously loaded ones - */ -export default function createReducer(asyncReducers) { - return combineReducers({ - route: routeReducer, - global: globalReducer, - ...asyncReducers, - }); -} diff --git a/packages/strapi-helper-plugin/lib/src/routes.js b/packages/strapi-helper-plugin/lib/src/routes.js deleted file mode 100644 index 78a55a5afb..0000000000 --- a/packages/strapi-helper-plugin/lib/src/routes.js +++ /dev/null @@ -1,41 +0,0 @@ -// These are the pages you can go to. -// They are all wrapped in the App component, which should contain the navbar etc -// See http://blog.mxstbr.com/2016/01/react-apps-with-pages for more information -// about the code splitting business -import { camelCase, map } from 'lodash'; -import { getAsyncInjectors } from 'utils/asyncInjectors'; -import routes from 'routes.json'; // eslint-disable-line - -// Try to require a node module without throwing an error -const tryRequire = (path) => { - try { - return require(`containers/${path}.js`); // eslint-disable-line global-require - } catch (err) { - return null; - } -}; - -export default function createRoutes(store) { - // Create reusable async injectors using getAsyncInjectors factory - const { injectReducer, injectSagas } = getAsyncInjectors(store); // eslint-disable-line no-unused-vars - - // Inject app sagas - const appSagas = tryRequire('App/sagas'); - if (appSagas) injectSagas(appSagas.default); - - return map(routes, (route, key) => ({ - path: key === '/' ? '' : key, - name: route.name, - getComponent(nextState, cb) { - const reducer = tryRequire(`${route.container}/reducer`); // eslint-disable-line global-require - const sagas = tryRequire(`${route.container}/sagas`); // eslint-disable-line global-require - const component = tryRequire(`${route.container}/index`); // eslint-disable-line global-require - - process.nextTick(() => { - if (reducer) injectReducer(camelCase(route.container), reducer.default); - if (sagas) injectSagas(sagas.default); - cb(null, component.default); - }); - }, - })); -} diff --git a/packages/strapi-helper-plugin/lib/src/store.js b/packages/strapi-helper-plugin/lib/src/store.js deleted file mode 100644 index 9a51ddb25f..0000000000 --- a/packages/strapi-helper-plugin/lib/src/store.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Create the store with dynamic reducers - */ - -import { createStore, applyMiddleware, compose } from 'redux'; -import { fromJS } from 'immutable'; -import { routerMiddleware } from 'react-router-redux'; -import createSagaMiddleware from 'redux-saga'; -import createReducer from './reducers'; - -const sagaMiddleware = createSagaMiddleware(); - -export default function configureStore(initialState = {}, history, name) { - // Create the store with two middlewares - // 1. sagaMiddleware: Makes redux-sagas work - // 2. routerMiddleware: Syncs the location/URL path to the state - const middlewares = [ - sagaMiddleware, - routerMiddleware(history), - ]; - - const enhancers = [ - applyMiddleware(...middlewares), - ]; - - // If Redux DevTools Extension is installed use it, otherwise use Redux compose - /* eslint-disable no-underscore-dangle */ - const composeEnhancers = - process.env.NODE_ENV !== 'production' && - typeof window === 'object' && - window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ - ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ - // TODO Try to remove when `react-router-redux` is out of beta, LOCATION_CHANGE should not be fired more than once after hot reloading - // Prevent recomputing reducers for `replaceReducer` - shouldHotReload: false, - name: `Plugin - ${name}`, - }) - : compose; - /* eslint-enable */ - - const store = createStore( - createReducer(), - fromJS(initialState), - composeEnhancers(...enhancers), - ); - - // Extensions - store.runSaga = sagaMiddleware.run; - store.injectedReducers = {}; // Reducer registry - store.injectedSagas = {}; // Saga registry - - // Make reducers hot reloadable, see http://mxs.is/googmo - /* istanbul ignore next */ - if (module.hot) { - module.hot.accept('./reducers', () => { - store.replaceReducer(createReducer(store.injectedReducers)); - }); - } - - return store; -} diff --git a/packages/strapi-helper-plugin/lib/src/utils/Manager.js b/packages/strapi-helper-plugin/lib/src/utils/Manager.js index 8dfb050258..203529d566 100644 --- a/packages/strapi-helper-plugin/lib/src/utils/Manager.js +++ b/packages/strapi-helper-plugin/lib/src/utils/Manager.js @@ -14,7 +14,7 @@ class Manager { /** * Retrieve the bootstrap col index, name and type of a field - * @param {Number} index + * @param {Number} index * @returns {Object} */ getAttrInfos(index) { @@ -72,7 +72,7 @@ class Manager { /** * Retrieve a field default bootstrap col * NOTE: will change if we add the customisation of an input's width - * @param {String} type + * @param {String} type * @returns {Number} */ getBootStrapCol(type) { @@ -80,7 +80,7 @@ class Manager { case 'checkbox': case 'boolean': case 'date': - case 'bigint': + case 'biginteger': case 'decimal': case 'float': case 'integer': @@ -109,7 +109,7 @@ class Manager { } /** - * + * * Retrieve the last element of each line of a bootstrap grid and push it into an array * @returns {Array} */ @@ -138,7 +138,7 @@ class Manager { if (i < this.list.size - 1) { let { bootstrapCol: nextBootstrapCol, name: nextName, type: nextType } = this.getAttrInfos(i + 1); - + if (!nextType && nextName.includes('__col')) { nextBootstrapCol = parseInt(nextName.split('__')[1].split('-')[2], 10); } @@ -155,9 +155,9 @@ class Manager { } /** - * + * * Retrieve the field's type depending on its name - * @param {String} itemName + * @param {String} itemName * @returns {String} */ getType(itemName) { @@ -177,8 +177,8 @@ class Manager { /** * Retrieve the line bootstrap col sum - * @param {Number} leftBound - * @param {Number} rightBound + * @param {Number} leftBound + * @param {Number} rightBound * @returns {Number} */ @@ -237,7 +237,7 @@ class Manager { if (lineSize < 10 && i < this.arrayOfEndLineElements.length - 1) { const colsToAdd = this.getColsToAdd(12 - lineSize); newList = newList.insert(lastLineItem + sum, colsToAdd[0]); - + if (colsToAdd.length > 1) { newList = newList.insert(lastLineItem + sum, colsToAdd[1]); } @@ -249,4 +249,4 @@ class Manager { } } -module.exports = Manager; \ No newline at end of file +module.exports = Manager; diff --git a/packages/strapi-helper-plugin/lib/src/utils/asyncInjectors.js b/packages/strapi-helper-plugin/lib/src/utils/asyncInjectors.js deleted file mode 100644 index 248f8e05a9..0000000000 --- a/packages/strapi-helper-plugin/lib/src/utils/asyncInjectors.js +++ /dev/null @@ -1,72 +0,0 @@ -import { conformsTo, isEmpty, isFunction, isObject, isString } from 'lodash'; -import invariant from 'invariant'; -import warning from 'warning'; -import createReducer from 'reducers'; - -/** - * Validate the shape of redux store - */ -export function checkStore(store) { - const shape = { - dispatch: isFunction, - subscribe: isFunction, - getState: isFunction, - replaceReducer: isFunction, - runSaga: isFunction, - asyncReducers: isObject, - }; - invariant( - conformsTo(store, shape), - '(src/utils...) asyncInjectors: Expected a valid redux store' - ); -} - -/** - * Inject an asynchronously loaded reducer - */ -export function injectAsyncReducer(store, isValid) { - return function injectReducer(name, asyncReducer) { - if (!isValid) checkStore(store); - - invariant( - isString(name) && !isEmpty(name) && isFunction(asyncReducer), - '(src/utils...) injectAsyncReducer: Expected `asyncReducer` to be a reducer function' - ); - - store.asyncReducers[name] = asyncReducer; // eslint-disable-line no-param-reassign - store.replaceReducer(createReducer(store.asyncReducers)); - }; -} - -/** - * Inject an asynchronously loaded saga - */ -export function injectAsyncSagas(store, isValid) { - return function injectSagas(sagas) { - if (!isValid) checkStore(store); - - invariant( - Array.isArray(sagas), - '(src/utils...) injectAsyncSagas: Expected `sagas` to be an array of generator functions' - ); - - warning( - !isEmpty(sagas), - '(src/utils...) injectAsyncSagas: Received an empty `sagas` array' - ); - - sagas.map(store.runSaga); - }; -} - -/** - * Helper for creating injectors - */ -export function getAsyncInjectors(store) { - checkStore(store); - - return { - injectReducer: injectAsyncReducer(store, true), - injectSagas: injectAsyncSagas(store, true), - }; -} diff --git a/packages/strapi-helper-plugin/lib/src/utils/auth.js b/packages/strapi-helper-plugin/lib/src/utils/auth.js index e2316c2cb0..12afec93b5 100644 --- a/packages/strapi-helper-plugin/lib/src/utils/auth.js +++ b/packages/strapi-helper-plugin/lib/src/utils/auth.js @@ -21,7 +21,12 @@ const auth = { clearAppStorage() { if (localStorage) { + const videos = auth.get('videos'); + const onboarding = auth.get('onboarding'); + localStorage.clear(); + localStorage.setItem('videos', JSON.stringify(videos)); + localStorage.setItem('onboarding', onboarding); } if (sessionStorage) { @@ -73,7 +78,6 @@ const auth = { return null; }, - setToken(value = '', isLocalStorage = false, tokenKey = TOKEN_KEY) { return auth.set(value, tokenKey, isLocalStorage); }, diff --git a/packages/strapi-helper-plugin/lib/src/utils/checkStore.js b/packages/strapi-helper-plugin/lib/src/utils/checkStore.js deleted file mode 100644 index 29df88bc51..0000000000 --- a/packages/strapi-helper-plugin/lib/src/utils/checkStore.js +++ /dev/null @@ -1,23 +0,0 @@ -import conformsTo from 'lodash/conformsTo'; -import isFunction from 'lodash/isFunction'; -import isObject from 'lodash/isObject'; -import invariant from 'invariant'; - -/** - * Validate the shape of redux store - */ -export default function checkStore(store) { - const shape = { - dispatch: isFunction, - subscribe: isFunction, - getState: isFunction, - replaceReducer: isFunction, - runSaga: isFunction, - injectedReducers: isObject, - injectedSagas: isObject, - }; - invariant( - conformsTo(store, shape), - '(app/utils...) injectors: Expected a valid redux store' - ); -} diff --git a/packages/strapi-helper-plugin/lib/src/utils/injectReducer.js b/packages/strapi-helper-plugin/lib/src/utils/injectReducer.js deleted file mode 100644 index 4af84187f3..0000000000 --- a/packages/strapi-helper-plugin/lib/src/utils/injectReducer.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import hoistNonReactStatics from 'hoist-non-react-statics'; - -import getInjectors from './reducerInjectors'; - -/** - * Dynamically injects a reducer - * - * @param {string} key A key of the reducer - * @param {function} reducer A reducer that will be injected - * - */ -export default ({ key, reducer }) => (WrappedComponent) => { - class ReducerInjector extends React.Component { - static WrappedComponent = WrappedComponent; - static displayName = `withReducer(${(WrappedComponent.displayName || WrappedComponent.name || 'Component')})`; - static contextTypes = { - store: PropTypes.object.isRequired, - }; - - componentWillMount() { - const { injectReducer } = this.injectors; - - injectReducer(key, reducer); - } - - injectors = getInjectors(this.context.store); - - render() { - return ; - } - } - - return hoistNonReactStatics(ReducerInjector, WrappedComponent); -}; diff --git a/packages/strapi-helper-plugin/lib/src/utils/injectSaga.js b/packages/strapi-helper-plugin/lib/src/utils/injectSaga.js deleted file mode 100644 index 158b0e1732..0000000000 --- a/packages/strapi-helper-plugin/lib/src/utils/injectSaga.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import hoistNonReactStatics from 'hoist-non-react-statics'; - -import getInjectors from './sagaInjectors'; - -/** - * Dynamically injects a saga, passes component's props as saga arguments - * - * @param {string} key A key of the saga - * @param {function} saga A root saga that will be injected - * @param {string} [mode] By default (constants.RESTART_ON_REMOUNT) the saga will be started on component mount and - * cancelled with `task.cancel()` on component un-mount for improved performance. Another two options: - * - constants.DAEMON—starts the saga on component mount and never cancels it or starts again, - * - constants.ONCE_TILL_UNMOUNT—behaves like 'RESTART_ON_REMOUNT' but never runs it again. - * - */ -export default ({ key, saga, mode }) => (WrappedComponent) => { - class InjectSaga extends React.Component { - static WrappedComponent = WrappedComponent; - static displayName = `withSaga(${(WrappedComponent.displayName || WrappedComponent.name || 'Component')})`; - static contextTypes = { - store: PropTypes.object.isRequired, - }; - - componentWillMount() { - const { injectSaga } = this.injectors; - - injectSaga(key, { saga, mode }, this.props); - } - - componentWillUnmount() { - const { ejectSaga } = this.injectors; - - ejectSaga(key); - } - - injectors = getInjectors(this.context.store); - - render() { - return ; - } - } - - return hoistNonReactStatics(InjectSaga, WrappedComponent); -}; diff --git a/packages/strapi-helper-plugin/lib/src/utils/reducerInjectors.js b/packages/strapi-helper-plugin/lib/src/utils/reducerInjectors.js deleted file mode 100644 index a341eb49f3..0000000000 --- a/packages/strapi-helper-plugin/lib/src/utils/reducerInjectors.js +++ /dev/null @@ -1,30 +0,0 @@ -import invariant from 'invariant'; -import { isEmpty, isFunction, isString } from 'lodash'; - -import createReducer from '../reducers'; -import checkStore from './checkStore'; - -export function injectReducerFactory(store, isValid) { - return function injectReducer(key, reducer) { - if (!isValid) checkStore(store); - - invariant( - isString(key) && !isEmpty(key) && isFunction(reducer), - '(app/utils...) injectReducer: Expected `reducer` to be a reducer function' - ); - - // Check `store.injectedReducers[key] === reducer` for hot reloading when a key is the same but a reducer is different - if (Reflect.has(store.injectedReducers, key) && store.injectedReducers[key] === reducer) return; - - store.injectedReducers[key] = reducer; // eslint-disable-line no-param-reassign - store.replaceReducer(createReducer(store.injectedReducers)); - }; -} - -export default function getInjectors(store) { - checkStore(store); - - return { - injectReducer: injectReducerFactory(store, true), - }; -} diff --git a/packages/strapi-helper-plugin/lib/src/utils/request.js b/packages/strapi-helper-plugin/lib/src/utils/request.js index a83b1606e5..48bfa6233b 100644 --- a/packages/strapi-helper-plugin/lib/src/utils/request.js +++ b/packages/strapi-helper-plugin/lib/src/utils/request.js @@ -1,5 +1,5 @@ import 'whatwg-fetch'; -import auth from 'utils/auth'; +import auth from './auth'; /** * Parses the JSON returned by a network request @@ -20,7 +20,7 @@ function parseJSON(response) { * @return {object|undefined} Returns either the response, or throws an error */ function checkStatus(response, checkToken = true) { - if (response.status >= 200 && response.status < 300) { + if ((response.status >= 200 && response.status < 300) || response.status === 0) { return response; } @@ -41,21 +41,22 @@ function checkTokenValidity(response) { method: 'GET', headers: { 'Content-Type': 'application/json', - 'Authorization': `Bearer ${auth.getToken()}`, + Authorization: `Bearer ${auth.getToken()}`, }, }; if (auth.getToken()) { - return fetch(`${strapi.backendURL}/user/me`, options) - .then(() => { - if (response.status === 401) { - window.location = `${strapi.remoteURL}/plugins/users-permissions/auth/login`; + return fetch(`${strapi.backendURL}/user/me`, options).then(() => { + if (response.status === 401) { + window.location = `${ + strapi.remoteURL + }/plugins/users-permissions/auth/login`; - auth.clearAppStorage(); - } + auth.clearAppStorage(); + } - return checkStatus(response, false); - }); + return checkStatus(response, false); + }); } } @@ -72,12 +73,12 @@ function formatQueryParams(params) { } /** -* Server restart watcher -* @param response -* @returns {object} the response data -*/ + * Server restart watcher + * @param response + * @returns {object} the response data + */ function serverRestartWatcher(response) { - return new Promise((resolve) => { + return new Promise(resolve => { fetch(`${strapi.backendURL}/_health`, { method: 'HEAD', mode: 'no-cors', @@ -93,8 +94,7 @@ function serverRestartWatcher(response) { }) .catch(() => { setTimeout(() => { - return serverRestartWatcher(response) - .then(resolve); + return serverRestartWatcher(response).then(resolve); }, 100); }); }); @@ -108,22 +108,38 @@ function serverRestartWatcher(response) { * * @return {object} The response data */ -export default function request(url, options = {}, shouldWatchServerRestart = false, stringify = true ) { +export default function request(...args) { + let [url, options = {}, shouldWatchServerRestart, stringify = true, ...rest] = args; + let noAuth; + + try { + [{ noAuth }] = rest; + } catch(err) { + noAuth = false; + } + // Set headers if (!options.headers) { - options.headers = Object.assign({ - 'Content-Type': 'application/json', - }, options.headers, { - 'X-Forwarded-Host': 'strapi', - }); + options.headers = Object.assign( + { + 'Content-Type': 'application/json', + }, + options.headers, + { + 'X-Forwarded-Host': 'strapi', + }, + ); } const token = auth.getToken(); - if (token) { - options.headers = Object.assign({ - 'Authorization': `Bearer ${token}`, - }, options.headers); + if (token && !noAuth) { + options.headers = Object.assign( + { + Authorization: `Bearer ${token}`, + }, + options.headers, + ); } // Add parameters to url @@ -138,11 +154,11 @@ export default function request(url, options = {}, shouldWatchServerRestart = fa if (options && options.body && stringify) { options.body = JSON.stringify(options.body); } - + return fetch(url, options) .then(checkStatus) .then(parseJSON) - .then((response) => { + .then(response => { if (shouldWatchServerRestart) { // Display the global OverlayBlocker strapi.lockApp(shouldWatchServerRestart); diff --git a/packages/strapi-helper-plugin/lib/src/utils/sagaInjectors.js b/packages/strapi-helper-plugin/lib/src/utils/sagaInjectors.js deleted file mode 100644 index f7d524d539..0000000000 --- a/packages/strapi-helper-plugin/lib/src/utils/sagaInjectors.js +++ /dev/null @@ -1,86 +0,0 @@ -import isEmpty from 'lodash/isEmpty'; -import isFunction from 'lodash/isFunction'; -import isString from 'lodash/isString'; -import invariant from 'invariant'; -import conformsTo from 'lodash/conformsTo'; - -import checkStore from './checkStore'; -import { - DAEMON, - ONCE_TILL_UNMOUNT, - RESTART_ON_REMOUNT, -} from './constants'; - -const allowedModes = [RESTART_ON_REMOUNT, DAEMON, ONCE_TILL_UNMOUNT]; - -const checkKey = (key) => invariant( - isString(key) && !isEmpty(key), - '(app/utils...) injectSaga: Expected `key` to be a non empty string' -); - -const checkDescriptor = (descriptor) => { - const shape = { - saga: isFunction, - mode: (mode) => isString(mode) && allowedModes.includes(mode), - }; - invariant( - conformsTo(descriptor, shape), - '(app/utils...) injectSaga: Expected a valid saga descriptor' - ); -}; - -export function injectSagaFactory(store, isValid) { - return function injectSaga(key, descriptor = {}, args) { - if (!isValid) checkStore(store); - - const newDescriptor = { ...descriptor, mode: descriptor.mode || RESTART_ON_REMOUNT }; - const { saga, mode } = newDescriptor; - - checkKey(key); - checkDescriptor(newDescriptor); - - let hasSaga = Reflect.has(store.injectedSagas, key); - - if (process.env.NODE_ENV !== 'production') { - const oldDescriptor = store.injectedSagas[key]; - // enable hot reloading of daemon and once-till-unmount sagas - if (hasSaga && oldDescriptor.saga !== saga) { - oldDescriptor.task.cancel(); - hasSaga = false; - } - } - - if (!hasSaga || (hasSaga && mode !== DAEMON && mode !== ONCE_TILL_UNMOUNT)) { - store.injectedSagas[key] = { ...newDescriptor, task: store.runSaga(saga, args) }; // eslint-disable-line no-param-reassign - } - }; -} - -export function ejectSagaFactory(store, isValid) { - return function ejectSaga(key) { - if (!isValid) checkStore(store); - - checkKey(key); - - if (Reflect.has(store.injectedSagas, key)) { - const descriptor = store.injectedSagas[key]; - if (descriptor.mode !== DAEMON) { - descriptor.task.cancel(); - // Clean up in production; in development we need `descriptor.saga` for hot reloading - if (process.env.NODE_ENV === 'production') { - // Need some value to be able to detect `ONCE_TILL_UNMOUNT` sagas in `injectSaga` - store.injectedSagas[key] = 'done'; // eslint-disable-line no-param-reassign - } - } - } - }; -} - -export default function getInjectors(store) { - checkStore(store); - - return { - injectSaga: injectSagaFactory(store, true), - ejectSaga: ejectSagaFactory(store, true), - }; -} diff --git a/packages/strapi-helper-plugin/package.json b/packages/strapi-helper-plugin/package.json index f68f991eee..cfc4df47e5 100644 --- a/packages/strapi-helper-plugin/package.json +++ b/packages/strapi-helper-plugin/package.json @@ -1,6 +1,6 @@ { "name": "strapi-helper-plugin", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Helper for Strapi plugins development", "engines": { "node": ">= 10.0.0", @@ -27,9 +27,6 @@ "lint:admin" ], "devDependencies": { - "plop": "^2.2.0" - }, - "dependencies": { "add-asset-html-webpack-plugin": "^2.1.2", "babel-cli": "6.26.0", "babel-core": "6.26.0", @@ -42,35 +39,25 @@ "babel-plugin-transform-react-constant-elements": "6.23.0", "babel-plugin-transform-react-inline-elements": "6.22.0", "babel-plugin-transform-react-remove-prop-types": "0.4.18", - "babel-polyfill": "6.26.0", "babel-preset-env": "1.6.1", "babel-preset-react": "6.24.1", "babel-preset-react-hmre": "1.1.1", "babel-preset-stage-0": "6.24.1", - "bootstrap": "^4.0.0-alpha.6", "chalk": "^2.1.0", - "classnames": "^2.2.5", "copy-webpack-plugin": "^4.3.1", - "cross-env": "^5.0.5", "css-loader": "^0.28.5", + "cross-env": "^5.0.5", "exports-loader": "^0.6.4", - "express": "^4.15.4", "extract-text-webpack-plugin": "^3.0.0", + "express": "^4.15.4", "file-loader": "^0.11.2", - "history": "^4.6.3", "html-loader": "^0.5.1", "html-webpack-plugin": "^2.30.1", "image-webpack-loader": "^4.3.1", - "immutable": "^3.8.2", - "imports-loader": "^0.7.1", - "intl": "^1.2.5", - "invariant": "2.2.1", - "json-loader": "^0.5.7", - "lodash": "^4.17.5", "lodash-webpack-plugin": "^0.11.4", - "moment": "^2.16.0", "node-sass": "^4.5.3", "null-loader": "^0.1.1", + "plop": "^2.2.0", "postcss-cssnext": "^2.11.0", "postcss-focus": "^2.0.0", "postcss-loader": "^2.0.6", @@ -78,6 +65,27 @@ "postcss-smart-import": "^0.7.5", "precss": "^2.0.0", "prettier": "^1.5.3", + "rimraf": "^2.6.1", + "sass-loader": "^6.0.6", + "shelljs": "^0.7.8", + "style-loader": "^0.18.2", + "url-loader": "^1.1.1", + "webpack": "^3.5.5", + "webpack-bundle-analyzer": "^2.9.0", + "webpack-dev-middleware": "^1.12.0", + "webpack-hot-middleware": "^2.18.2" + }, + "dependencies": { + "babel-polyfill": "6.26.0", + "bootstrap": "^4.0.0-alpha.6", + "classnames": "^2.2.5", + "history": "^4.6.3", + "immutable": "^3.8.2", + "imports-loader": "^0.7.1", + "invariant": "2.2.1", + "json-loader": "^0.5.7", + "lodash": "^4.17.5", + "moment": "^2.16.0", "prop-types": "^15.5.10", "react": "^16.5.2", "react-copy-to-clipboard": "^5.0.1", @@ -97,16 +105,7 @@ "redux-immutable": "^4.0.0", "redux-saga": "^0.16.0", "reselect": "^3.0.1", - "rimraf": "^2.6.1", - "sass-loader": "^6.0.6", - "shelljs": "^0.7.8", - "style-loader": "^0.18.2", "styled-components": "^3.2.6", - "url-loader": "^1.1.1", - "webpack": "^3.5.5", - "webpack-bundle-analyzer": "^2.9.0", - "webpack-dev-middleware": "^1.12.0", - "webpack-hot-middleware": "^2.18.2", "whatwg-fetch": "^2.0.3" } } \ 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 3af1a28600..a4ae66f601 100644 --- a/packages/strapi-hook-bookshelf/lib/index.js +++ b/packages/strapi-hook-bookshelf/lib/index.js @@ -422,12 +422,12 @@ module.exports = function(strapi) { case 'email': type = 'varchar(255)'; break; - case 'biginteger': - type = definition.client === 'pg' ? 'bigint' : 'bigint(53)'; - break; case 'integer': type = definition.client === 'pg' ? 'integer' : 'int'; break; + case 'biginteger': + type = definition.client === 'pg' ? 'bigint' : 'bigint(53)'; + break; case 'float': type = definition.client === 'pg' ? 'double precision' : 'double'; break; @@ -471,7 +471,7 @@ module.exports = function(strapi) { const type = getType(attribute, attr); if (type) { - acc.push(`${quote}${attr}${quote} ${type}`); + acc.push(`${quote}${attr}${quote} ${type} ${attribute.required ? 'NOT' : ''} NULL `); } return acc; @@ -544,14 +544,12 @@ module.exports = function(strapi) { } }; - - if (!tableExist) { + const createTable = async (table) => { const defaultAttributeDifinitions = { mysql: [`id INT AUTO_INCREMENT NOT NULL PRIMARY KEY`], pg: [`id SERIAL NOT NULL PRIMARY KEY`], sqlite3: ['id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'] }; - let idAttributeBuilder = defaultAttributeDifinitions[definition.client]; if (definition.primaryKeyType === 'uuid' && definition.client === 'pg') { idAttributeBuilder = ['id uuid NOT NULL DEFAULT uuid_generate_v4() NOT NULL PRIMARY KEY']; @@ -566,13 +564,16 @@ module.exports = function(strapi) { ${columns} ) `); + }; + + if (!tableExist) { + await createTable(table); // Generate indexes. await generateIndexes(table, attributes); await storeTable(table, attributes); } else { - const columns = Object.keys(attributes); // Fetch existing column @@ -594,6 +595,14 @@ module.exports = function(strapi) { // Generate indexes for new attributes. await generateIndexes(table, columnsToAdd); + let previousAttributes; + try { + previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value); + } catch (err) { + await storeTable(table, attributes); + previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value); + } + // Generate and execute query to add missing column if (Object.keys(columnsToAdd).length > 0) { const columns = generateColumns(columnsToAdd, []); @@ -605,31 +614,28 @@ module.exports = function(strapi) { await Promise.all(queries.map(query => ORM.knex.raw(query))); } - let previousAttributes; - try { - previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value); - } catch (err) { - await storeTable(table, attributes); - previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value); - } + let sqlite3Change = false; // Execute query to update column type await Promise.all(columns.map(attribute => new Promise(async (resolve) => { if (JSON.stringify(previousAttributes[attribute]) === JSON.stringify(attributes[attribute])) { return resolve(); + } else { + sqlite3Change = true; } const type = getType(attributes[attribute], attribute); - if (type) { - const changeType = definition.client === 'pg' || definition.client === 'sqlite3' + if (type && definition.client !== 'sqlite3') { + const changeType = definition.client === 'pg' ? `ALTER COLUMN ${quote}${attribute}${quote} TYPE ${type} USING ${quote}${attribute}${quote}::${type}` : `CHANGE ${quote}${attribute}${quote} ${quote}${attribute}${quote} ${type} `; - const changeRequired = definition.client === 'pg' || definition.client === 'sqlite3' + const changeRequired = definition.client === 'pg' ? `ALTER COLUMN ${quote}${attribute}${quote} ${attributes[attribute].required ? 'SET' : 'DROP'} NOT NULL` : `CHANGE ${quote}${attribute}${quote} ${quote}${attribute}${quote} ${type} ${attributes[attribute].required ? 'NOT' : ''} NULL`; + await ORM.knex.raw(`ALTER TABLE ${quote}${table}${quote} ${changeType}`); await ORM.knex.raw(`ALTER TABLE ${quote}${table}${quote} ${changeRequired}`); } @@ -638,6 +644,29 @@ module.exports = function(strapi) { }) )); + if (sqlite3Change && definition.client === 'sqlite3') { + await createTable(`tmp_${table}`); + + try { + const attrs = Object.keys(attributes).filter(attribute => getType(attributes[attribute], attribute)).join(' ,'); + await ORM.knex.raw(`INSERT INTO ${quote}tmp_${table}${quote}(${attrs}) SELECT ${attrs} FROM ${quote}${table}${quote}`); + } catch (err) { + console.log('Warning!'); + console.log('We can\'t migrate your data due to the following error.'); + console.log(); + console.log(err); + console.log(); + console.log(`We created a new table "tmp_${table}" with your latest changes.`); + console.log(`We suggest you manually migrate your data from "${table}" to "tmp_${table}" and then to DROP and RENAME the tables.`); + + return false; + } + await ORM.knex.raw(`DROP TABLE ${quote}${table}${quote}`); + await ORM.knex.raw(`ALTER TABLE ${quote}tmp_${table}${quote} RENAME TO ${quote}${table}${quote}`); + + await generateIndexes(table, attributes); + } + await storeTable(table, attributes); } }; diff --git a/packages/strapi-hook-bookshelf/lib/utils/connectivity.js b/packages/strapi-hook-bookshelf/lib/utils/connectivity.js index 7360a992d3..c9e51e40b3 100644 --- a/packages/strapi-hook-bookshelf/lib/utils/connectivity.js +++ b/packages/strapi-hook-bookshelf/lib/utils/connectivity.js @@ -46,6 +46,7 @@ module.exports = (scope, success, error) => { if (err) { console.log(`Error removing connection test folder: ${scope.tmpPath}`); } + success(); }); }; diff --git a/packages/strapi-hook-bookshelf/package.json b/packages/strapi-hook-bookshelf/package.json index 54a835ad1d..6674d69235 100644 --- a/packages/strapi-hook-bookshelf/package.json +++ b/packages/strapi-hook-bookshelf/package.json @@ -1,6 +1,6 @@ { "name": "strapi-hook-bookshelf", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Bookshelf hook for the Strapi framework", "homepage": "http://strapi.io", "keywords": [ @@ -21,8 +21,8 @@ "lodash": "^4.17.5", "pluralize": "^6.0.0", "rimraf": "^2.6.2", - "strapi-hook-knex": "3.0.0-alpha.23.1", - "strapi-utils": "3.0.0-alpha.23.1" + "strapi-hook-knex": "3.0.0-alpha.24.1", + "strapi-utils": "3.0.0-alpha.24.1" }, "strapi": { "dependencies": [ diff --git a/packages/strapi-hook-ejs/package.json b/packages/strapi-hook-ejs/package.json index 3ba8ae3367..6fb4aca87b 100644 --- a/packages/strapi-hook-ejs/package.json +++ b/packages/strapi-hook-ejs/package.json @@ -1,6 +1,6 @@ { "name": "strapi-hook-ejs", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "EJS hook for the Strapi framework", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-hook-knex/lib/index.js b/packages/strapi-hook-knex/lib/index.js index b71b7ecce6..3c1c05899f 100644 --- a/packages/strapi-hook-knex/lib/index.js +++ b/packages/strapi-hook-knex/lib/index.js @@ -155,6 +155,10 @@ module.exports = strapi => { } catch (err) { fs.mkdirSync(fileDirectory); } + + // Force base directory. + // Note: it removes the warning logs when starting the administration in development mode. + options.connection.filename = path.resolve(strapi.config.appPath, options.connection.filename); // Disable warn log // .returning() is not supported by sqlite3 and will not have any effect. diff --git a/packages/strapi-hook-knex/package.json b/packages/strapi-hook-knex/package.json index 2bbb1491d0..fa08c25a2a 100644 --- a/packages/strapi-hook-knex/package.json +++ b/packages/strapi-hook-knex/package.json @@ -1,6 +1,6 @@ { "name": "strapi-hook-knex", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Knex hook for the Strapi framework", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-hook-mongoose/lib/index.js b/packages/strapi-hook-mongoose/lib/index.js index 2a37324363..92c095bd6f 100644 --- a/packages/strapi-hook-mongoose/lib/index.js +++ b/packages/strapi-hook-mongoose/lib/index.js @@ -127,6 +127,7 @@ module.exports = function (strapi) { findOneAndRemove: 'beforeDestroy', remove: 'beforeDestroy', update: 'beforeUpdate', + updateOne: 'beforeUpdate', find: 'beforeFetchAll', findOne: 'beforeFetch', save: 'beforeSave' @@ -202,6 +203,7 @@ module.exports = function (strapi) { findOneAndRemove: 'afterDestroy', remove: 'afterDestroy', update: 'afterUpdate', + updateOne: 'afterUpdate', find: 'afterFetchAll', findOne: 'afterFetch', save: 'afterSave' diff --git a/packages/strapi-hook-mongoose/package.json b/packages/strapi-hook-mongoose/package.json index be9799f444..5971c23d82 100644 --- a/packages/strapi-hook-mongoose/package.json +++ b/packages/strapi-hook-mongoose/package.json @@ -1,6 +1,6 @@ { "name": "strapi-hook-mongoose", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Mongoose hook for the Strapi framework", "homepage": "http://strapi.io", "keywords": [ @@ -20,7 +20,7 @@ "mongoose-float": "^1.0.3", "pluralize": "^6.0.0", "rimraf": "^2.6.2", - "strapi-utils": "3.0.0-alpha.23.1" + "strapi-utils": "3.0.0-alpha.24.1" }, "author": { "email": "hi@strapi.io", diff --git a/packages/strapi-hook-redis/package.json b/packages/strapi-hook-redis/package.json index adb61ab931..4b19d58f40 100644 --- a/packages/strapi-hook-redis/package.json +++ b/packages/strapi-hook-redis/package.json @@ -1,6 +1,6 @@ { "name": "strapi-hook-redis", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Redis hook for the Strapi framework", "homepage": "http://strapi.io", "keywords": [ @@ -19,7 +19,7 @@ "lodash": "^4.17.5", "rimraf": "^2.6.2", "stack-trace": "0.0.10", - "strapi-utils": "3.0.0-alpha.23.1" + "strapi-utils": "3.0.0-alpha.24.1" }, "author": { "email": "hi@strapi.io", diff --git a/packages/strapi-lint/lib/internals/shared/listChangedFiles.js b/packages/strapi-lint/lib/internals/shared/listChangedFiles.js index 9ddb6f56a5..12604cfbb8 100644 --- a/packages/strapi-lint/lib/internals/shared/listChangedFiles.js +++ b/packages/strapi-lint/lib/internals/shared/listChangedFiles.js @@ -5,10 +5,13 @@ 'use strict'; -const execFileSync = require('child_process').execFileSync; +const shell = require('shelljs'); const exec = (command, args) => { - console.log('> ' + [command].concat(args).join(' ')); + const cmd = [command].concat(args).join(' '); + + console.log(`> ${cmd}`); + const options = { cwd: process.cwd(), env: process.env, @@ -17,7 +20,7 @@ const exec = (command, args) => { }; try { - return execFileSync(command, args, options); + return shell.exec(cmd, {silent: true}); } catch (err) { return ''; } @@ -31,7 +34,7 @@ const execGitCmd = args => const listChangedFiles = () => { const mergeBase = execGitCmd(['merge-base', 'HEAD', 'master']); - + return new Set([ ...execGitCmd(['diff', '--name-only', '--diff-filter=ACMRTUB', mergeBase]), ...execGitCmd(['ls-files', '--others', '--exclude-standard']), diff --git a/packages/strapi-lint/package.json b/packages/strapi-lint/package.json index 8f63d47d6e..e02c468e84 100644 --- a/packages/strapi-lint/package.json +++ b/packages/strapi-lint/package.json @@ -1,6 +1,6 @@ { "name": "strapi-lint", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Strapi eslint and prettier configurations", "directories": { "lib": "lib" @@ -39,6 +39,7 @@ }, "dependencies": { "babel-eslint": "^8.2.3", - "prettier": "^1.12.1" + "prettier": "^1.12.1", + "shelljs": "^0.7.8" } } \ No newline at end of file diff --git a/packages/strapi-middleware-views/package.json b/packages/strapi-middleware-views/package.json index 8ebda346ce..186cef778b 100644 --- a/packages/strapi-middleware-views/package.json +++ b/packages/strapi-middleware-views/package.json @@ -1,6 +1,6 @@ { "name": "strapi-middleware-views", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Views middleware to enable server-side rendering for the Strapi framework", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-plugin-content-manager/admin/src/bootstrap.js b/packages/strapi-plugin-content-manager/admin/src/bootstrap.js index 524be693df..5b143db3ea 100644 --- a/packages/strapi-plugin-content-manager/admin/src/bootstrap.js +++ b/packages/strapi-plugin-content-manager/admin/src/bootstrap.js @@ -2,23 +2,26 @@ import { map, omit } from 'lodash'; import request from 'utils/request'; // This method is executed before the load of the plugin -const bootstrap = (plugin) => new Promise((resolve, reject) => { - request('/content-manager/models', { method: 'GET' }) - .then(models => { - const menu = [{ - name: 'Content Types', - links: map(omit(models.models.models, 'plugins'), (model, key) => ({ - label: model.labelPlural || model.label || key, - destination: key, - })), - }]; - plugin.leftMenuSections = menu; - resolve(plugin); - }) - .catch(e => { - strapi.notification.error('content-manager.error.model.fetch'); - reject(e); - }); -}); +const bootstrap = plugin => + new Promise((resolve, reject) => { + request('/content-manager/models', { method: 'GET' }) + .then(models => { + const menu = [ + { + name: 'Content Types', + links: map(omit(models.models.models, 'plugins'), (model, key) => ({ + label: model.labelPlural || model.label || key, + destination: key, + })), + }, + ]; + plugin.leftMenuSections = menu; + resolve(plugin); + }) + .catch(e => { + strapi.notification.error('content-manager.error.model.fetch'); + reject(e); + }); + }); export default bootstrap; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/AddFilterCTA/index.js b/packages/strapi-plugin-content-manager/admin/src/components/AddFilterCTA/index.js index 59af449773..9ba2517bee 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/AddFilterCTA/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/AddFilterCTA/index.js @@ -9,8 +9,8 @@ import { FormattedMessage } from 'react-intl'; import PropTypes from 'prop-types'; // Design -import Button from 'components/CustomButton'; import Logo from '../../assets/images/icon_filter.png'; +import Button from '../CustomButton'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/CustomDragLayer/index.js b/packages/strapi-plugin-content-manager/admin/src/components/CustomDragLayer/index.js index b3955a9168..03d9238e5c 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/CustomDragLayer/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/CustomDragLayer/index.js @@ -7,9 +7,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { DragLayer } from 'react-dnd'; import { flow } from 'lodash'; -import DragBox from 'components/DragBox'; -import SelectManyDraggedItem from 'components/SelectManyDraggedItem'; -import ItemTypes from 'utils/ItemTypes'; + +import ItemTypes from '../../utils/ItemTypes'; + +import DragBox from '../DragBox'; +import SelectManyDraggedItem from '../SelectManyDraggedItem'; + import styles from './styles.scss'; function getItemStyles(props) { @@ -79,4 +82,4 @@ CustomDragLayer.propTypes = { itemType: PropTypes.string, }; -export default flow([withDragLayer])(CustomDragLayer); \ No newline at end of file +export default flow([withDragLayer])(CustomDragLayer); diff --git a/packages/strapi-plugin-content-manager/admin/src/components/DragBox/index.js b/packages/strapi-plugin-content-manager/admin/src/components/DragBox/index.js index 4f4c340ce7..ba5361f11e 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/DragBox/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/DragBox/index.js @@ -5,9 +5,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import DraggedRemovedIcon from 'components/DraggedRemovedIcon'; -import GrabIcon from 'assets/images/icon_grab_blue.svg'; +import GrabIcon from '../../assets/images/icon_grab_blue.svg'; +import DraggedRemovedIcon from '../DraggedRemovedIcon'; + import styles from './styles.scss'; @@ -30,4 +31,4 @@ DragBox.propTypes = { name: PropTypes.string, }; -export default DragBox; \ No newline at end of file +export default DragBox; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/DraggableAttr/index.js b/packages/strapi-plugin-content-manager/admin/src/components/DraggableAttr/index.js index 8116d5b9bc..18f2250603 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/DraggableAttr/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/DraggableAttr/index.js @@ -14,13 +14,15 @@ import { getEmptyImage } from 'react-dnd-html5-backend'; import { flow } from 'lodash'; import PropTypes from 'prop-types'; import cn from 'classnames'; -import ClickOverHint from 'components/ClickOverHint'; -import DraggedRemovedIcon from 'components/DraggedRemovedIcon'; -import VariableEditIcon from 'components/VariableEditIcon'; -import ItemTypes from 'utils/ItemTypes'; -import GrabIconBlue from 'assets/images/icon_grab_blue.svg'; -import GrabIcon from 'assets/images/icon_grab.svg'; +import ItemTypes from '../../utils/ItemTypes'; + +import GrabIconBlue from '../../assets/images/icon_grab_blue.svg'; +import GrabIcon from '../../assets/images/icon_grab.svg'; + +import ClickOverHint from '../ClickOverHint'; +import DraggedRemovedIcon from '../DraggedRemovedIcon'; +import VariableEditIcon from '../VariableEditIcon'; import styles from './styles.scss'; @@ -207,4 +209,4 @@ const withDragSource = DragSource(ItemTypes.NORMAL, draggableAttrSource, (connec isDragging: monitor.isDragging(), })); -export default flow([withDropTarget, withDragSource])(DraggableAttr); \ No newline at end of file +export default flow([withDropTarget, withDragSource])(DraggableAttr); diff --git a/packages/strapi-plugin-content-manager/admin/src/components/Edit/index.js b/packages/strapi-plugin-content-manager/admin/src/components/Edit/index.js index 74d882ced4..592ccf6194 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/Edit/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/Edit/index.js @@ -18,15 +18,16 @@ import { // ./node_modules/strapi-helper-plugin/lib/src // or strapi/packages/strapi-helper-plugin/lib/src import Input from 'components/InputsIndex'; -import InputJSONWithErrors from 'components/InputJSONWithErrors'; -import WysiwygWithErrors from 'components/WysiwygWithErrors'; + +import InputJSONWithErrors from '../InputJSONWithErrors'; +import WysiwygWithErrors from '../WysiwygWithErrors'; import styles from './styles.scss'; const getInputType = (type = '') => { switch (type.toLowerCase()) { case 'boolean': return 'toggle'; - case 'bigint': + case 'biginteger': case 'decimal': case 'float': case 'integer': diff --git a/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/index.js b/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/index.js index 814c04f4d0..2bc41b8841 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/index.js @@ -9,8 +9,8 @@ import PropTypes from 'prop-types'; import { get } from 'lodash'; // Components. -import SelectOne from 'components/SelectOne'; -import SelectMany from 'components/SelectMany'; +import SelectOne from '../SelectOne'; +import SelectMany from '../SelectMany'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/EmptyAttributesView/index.js b/packages/strapi-plugin-content-manager/admin/src/components/EmptyAttributesView/index.js index 0d111dc046..78bf3eacca 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/EmptyAttributesView/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/EmptyAttributesView/index.js @@ -7,8 +7,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; + import Button from 'components/Button'; import PluginHeader from 'components/PluginHeader'; + import styles from './styles.scss'; function EmptyAttributesView({ currentModelName, history, modelEntries }) { diff --git a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Add.js b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Add.js index ab79870f4d..205e2baccf 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Add.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Add.js @@ -1,4 +1,4 @@ -import FilterOptionsCTA from 'components/FilterOptionsCTA'; +import FilterOptionsCTA from '../FilterOptionsCTA'; const Add = FilterOptionsCTA.extend` &:after { diff --git a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/InputWithAutoFocus.js b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/InputWithAutoFocus.js index 352eb7c074..286cdd873e 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/InputWithAutoFocus.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/InputWithAutoFocus.js @@ -20,7 +20,7 @@ const getInputType = (attrType) => { case 'datetime': return InputDate; case 'integer': - case 'bigint': + case 'biginteger': case 'decimal': case 'float': return InputNumber; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Remove.js b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Remove.js index 0598f6daff..dacc73bd0f 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Remove.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/Remove.js @@ -1,4 +1,4 @@ -import FilterOptionsCTA from 'components/FilterOptionsCTA'; +import FilterOptionsCTA from '../FilterOptionsCTA'; const Remove = FilterOptionsCTA.extend` &:after { diff --git a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/filterTypes.js b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/filterTypes.js index 50c0239173..880f7b50b8 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/filterTypes.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/FilterOptions/filterTypes.js @@ -47,6 +47,7 @@ const getFilters = (type) => { }, ]; case 'integer': + case 'biginteger': case 'float': case 'decimal': case 'date': diff --git a/packages/strapi-plugin-content-manager/admin/src/components/FiltersPickWrapper/index.js b/packages/strapi-plugin-content-manager/admin/src/components/FiltersPickWrapper/index.js index 4ee0db92d7..046954b0c1 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/FiltersPickWrapper/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/FiltersPickWrapper/index.js @@ -8,13 +8,14 @@ import moment from 'moment'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { isObject, size } from 'lodash'; -import FilterOptions from 'components/FilterOptions/Loadable'; // You can find these components in either // ./node_modules/strapi-helper-plugin/lib/src // or strapi/packages/strapi-helper-plugin/lib/src import PluginHeader from 'components/PluginHeader'; +import FilterOptions from '../FilterOptions/Loadable'; + import Div from './Div'; import Flex from './Flex'; import SpanStyled from './SpanStyled'; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/InputJSON/index.js b/packages/strapi-plugin-content-manager/admin/src/components/InputJSON/index.js index 402f87fe9a..de232eba62 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/InputJSON/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/InputJSON/index.js @@ -46,6 +46,7 @@ class InputJSON extends React.Component { lineNumbers: true, matchBrackets: true, mode: 'application/json', + readOnly: this.props.disabled, smartIndent: true, styleSelectedText: true, tabSize: 2, @@ -186,12 +187,14 @@ class InputJSON extends React.Component { } InputJSON.defaultProps = { + disabled: false, onBlur: () => {}, onChange: () => {}, value: null, }; InputJSON.propTypes = { + disabled: PropTypes.bool, name: PropTypes.string.isRequired, onBlur: PropTypes.func, onChange: PropTypes.func, diff --git a/packages/strapi-plugin-content-manager/admin/src/components/InputJSONWithErrors/index.js b/packages/strapi-plugin-content-manager/admin/src/components/InputJSONWithErrors/index.js index 9a57eb3019..e80a0bd187 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/InputJSONWithErrors/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/InputJSONWithErrors/index.js @@ -14,11 +14,12 @@ import Label from 'components/Label'; import InputDescription from 'components/InputDescription'; import InputErrors from 'components/InputErrors'; import InputSpacer from 'components/InputSpacer'; -import InputJSON from 'components/InputJSON'; // Utils import validateInput from 'utils/inputsValidations'; +import InputJSON from '../InputJSON'; + import styles from './styles.scss'; class InputJSONWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js b/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js index 4cc5097be4..8a38c669b2 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/Search/index.js @@ -9,7 +9,7 @@ import { isEmpty, upperFirst } from 'lodash'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import Logo from 'assets/images/icon_filter_blue.svg'; +import Logo from '../../assets/images/icon_filter_blue.svg'; import styles from './styles.scss'; const WAIT = 400; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/SortableItem.js b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/SortableItem.js index 24700fac26..c6b0f69e8d 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/SortableItem.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/SortableItem.js @@ -12,8 +12,11 @@ import { getEmptyImage } from 'react-dnd-html5-backend'; import PropTypes from 'prop-types'; import { flow, get } from 'lodash'; import cn from 'classnames'; -import SelectManyDraggedItem from 'components/SelectManyDraggedItem'; -import ItemTypes from 'utils/ItemTypes'; + +import ItemTypes from '../../utils/ItemTypes'; + +import SelectManyDraggedItem from '../SelectManyDraggedItem'; + import styles from './styles.scss'; const sortableItemSource = { @@ -145,4 +148,4 @@ SortableItem.propTypes = { onRemove: PropTypes.func.isRequired, }; -export default flow([withDropTarget, withDragSource])(SortableItem); \ No newline at end of file +export default flow([withDropTarget, withDragSource])(SortableItem); diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SelectManyDraggedItem/Content.js b/packages/strapi-plugin-content-manager/admin/src/components/SelectManyDraggedItem/Content.js index 33cb2ee859..a629ac1f7d 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SelectManyDraggedItem/Content.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/SelectManyDraggedItem/Content.js @@ -6,8 +6,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -import IconRemove from 'assets/images/icon_remove.svg'; -import styles from 'components/SelectMany/styles.scss'; + +import IconRemove from '../../assets/images/icon_remove.svg'; +import styles from '../SelectMany/styles.scss'; function Content({ index, item, onClick, onRemove }) { return ( @@ -45,4 +46,4 @@ Content.propTypes = { onRemove: PropTypes.func, }; -export default Content; \ No newline at end of file +export default Content; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SettingsRow/index.js b/packages/strapi-plugin-content-manager/admin/src/components/SettingsRow/index.js index 335f54ed91..071a108b9a 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SettingsRow/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/SettingsRow/index.js @@ -6,6 +6,7 @@ import React from 'react'; import { upperFirst } from 'lodash'; import PropTypes from 'prop-types'; + import IcoContainer from 'components/IcoContainer'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/Table/index.js b/packages/strapi-plugin-content-manager/admin/src/components/Table/index.js index c596fc0580..fbaeb66fd6 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/Table/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/Table/index.js @@ -8,11 +8,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { toString } from 'lodash'; -import TableDelete from 'components/TableDelete'; -import TableHeader from 'components/TableHeader'; -import TableRow from 'components/TableRow'; -import TableEmpty from 'components/TableEmpty'; -import TableLoading from 'components/TableLoading'; +import TableDelete from '../TableDelete'; +import TableHeader from '../TableHeader'; +import TableRow from '../TableRow'; +import TableEmpty from '../TableEmpty'; +import TableLoading from '../TableLoading'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/TableHeader/index.js b/packages/strapi-plugin-content-manager/admin/src/components/TableHeader/index.js index b8d95174e4..026e3744b2 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/TableHeader/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/TableHeader/index.js @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import cn from 'classnames'; -import CustomInputCheckbox from 'components/CustomInputCheckbox'; +import CustomInputCheckbox from '../CustomInputCheckbox'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/TableLoading/index.js b/packages/strapi-plugin-content-manager/admin/src/components/TableLoading/index.js index f67d418be4..5f260c0177 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/TableLoading/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/TableLoading/index.js @@ -4,6 +4,7 @@ */ import React from 'react'; import PropTypes from 'prop-types'; + import LoadingIndicator from 'components/LoadingIndicator'; import styles from './styles.scss'; @@ -23,4 +24,4 @@ TableLoading.propTypes = { colspan: PropTypes.number.isRequired, }; -export default TableLoading; \ No newline at end of file +export default TableLoading; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/TableRow/index.js b/packages/strapi-plugin-content-manager/admin/src/components/TableRow/index.js index f3cfae6241..aca98a62cc 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/TableRow/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/TableRow/index.js @@ -10,9 +10,10 @@ import moment from 'moment'; import { isEmpty, isNull, isObject, toLower, toString } from 'lodash'; import cn from 'classnames'; -import CustomInputCheckbox from 'components/CustomInputCheckbox'; import IcoContainer from 'components/IcoContainer'; +import CustomInputCheckbox from '../CustomInputCheckbox'; + import styles from './styles.scss'; class TableRow extends React.Component { diff --git a/packages/strapi-plugin-content-manager/admin/src/components/VariableDraggableAttr/index.js b/packages/strapi-plugin-content-manager/admin/src/components/VariableDraggableAttr/index.js index be42f9ee8c..4eb41b51be 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/VariableDraggableAttr/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/VariableDraggableAttr/index.js @@ -14,13 +14,15 @@ import { import { getEmptyImage } from 'react-dnd-html5-backend'; import { get, flow } from 'lodash'; import cn from 'classnames'; -import ClickOverHint from 'components/ClickOverHint'; -import DraggedRemovedIcon from 'components/DraggedRemovedIcon'; -import VariableEditIcon from 'components/VariableEditIcon'; -import ItemTypes from 'utils/ItemTypes'; -import GrabIconBlue from 'assets/images/icon_grab_blue.svg'; -import GrabIcon from 'assets/images/icon_grab.svg'; +import GrabIconBlue from '../../assets/images/icon_grab_blue.svg'; +import GrabIcon from '../../assets/images/icon_grab.svg'; + +import ItemTypes from '../../utils/ItemTypes'; + +import ClickOverHint from '../ClickOverHint'; +import DraggedRemovedIcon from '../DraggedRemovedIcon'; +import VariableEditIcon from '../VariableEditIcon'; import Carret from './Carret'; import styles from './styles.scss'; @@ -31,7 +33,7 @@ const getBootstrapClass = attrType => { case 'boolean': case 'toggle': case 'date': - case 'bigint': + case 'biginteger': case 'decimal': case 'float': case 'integer': diff --git a/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/index.js b/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/index.js index f8344a913b..017eeb2787 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/index.js @@ -16,11 +16,14 @@ import { import PropTypes from 'prop-types'; import { isEmpty, isNaN, replace, words } from 'lodash'; import cn from 'classnames'; -import Controls from 'components/WysiwygInlineControls'; -import Drop from 'components/WysiwygDropUpload'; -import WysiwygBottomControls from 'components/WysiwygBottomControls'; -import WysiwygEditor from 'components/WysiwygEditor'; + import request from 'utils/request'; + +import Controls from '../WysiwygInlineControls'; +import Drop from '../WysiwygDropUpload'; +import WysiwygBottomControls from '../WysiwygBottomControls'; +import WysiwygEditor from '../WysiwygEditor'; + import CustomSelect from './customSelect'; import PreviewControl from './previewControl'; import PreviewWysiwyg from './previewWysiwyg'; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/previewWysiwyg.js b/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/previewWysiwyg.js index 4903788722..018e566e16 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/previewWysiwyg.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/Wysiwyg/previewWysiwyg.js @@ -20,7 +20,7 @@ import { List, OrderedSet, Repeat, fromJS } from 'immutable'; import cn from 'classnames'; import { isEmpty, toArray } from 'lodash'; -import WysiwygEditor from 'components/WysiwygEditor'; +import WysiwygEditor from '../WysiwygEditor'; import converter from './converter'; import { findAtomicEntities, diff --git a/packages/strapi-plugin-content-manager/admin/src/components/WysiwygWithErrors/index.js b/packages/strapi-plugin-content-manager/admin/src/components/WysiwygWithErrors/index.js index 66cc8acee9..cd57f3025f 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/WysiwygWithErrors/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/WysiwygWithErrors/index.js @@ -14,11 +14,12 @@ import Label from 'components/Label'; import InputDescription from 'components/InputDescription'; import InputErrors from 'components/InputErrors'; import InputSpacer from 'components/InputSpacer'; -import Wysiwyg from 'components/Wysiwyg'; // Utils import validateInput from 'utils/inputsValidations'; +import Wysiwyg from '../Wysiwyg'; + import styles from './styles.scss'; class WysiwygWithErrors extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/App/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/App/index.js index 78c630c017..f6e547761f 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/App/index.js @@ -12,22 +12,24 @@ import { createStructuredSelector } from 'reselect'; import PropTypes from 'prop-types'; import { isEmpty, get } from 'lodash'; import { Switch, Route } from 'react-router-dom'; +import pluginId from 'pluginId'; -import injectSaga from 'utils/injectSaga'; import getQueryParameters from 'utils/getQueryParameters'; -import EditPage from 'containers/EditPage'; -import ListPage from 'containers/ListPage'; -import SettingsPage from 'containers/SettingsPage'; -import SettingPage from 'containers/SettingPage'; import LoadingIndicatorPage from 'components/LoadingIndicatorPage'; -import EmptyAttributesView from 'components/EmptyAttributesView'; +import EmptyAttributesView from '../../components/EmptyAttributesView'; + +import EditPage from '../EditPage'; +import ListPage from '../ListPage'; +import SettingsPage from '../SettingsPage'; +import SettingPage from '../SettingPage'; import { loadModels, } from './actions'; import { makeSelectLoading, makeSelectModelEntries, makeSelectSchema } from './selectors'; +import reducer from './reducer'; import saga from './sagas'; class App extends React.Component { @@ -39,12 +41,13 @@ class App extends React.Component { if (this.props.loading) { return ; } - + const { schema } = this.props; const currentModelName = this.props.location.pathname.split('/')[3]; const source = getQueryParameters(this.props.location.search, 'source'); const attrPath = source === 'content-manager' ? ['models', currentModelName, 'editDisplay', 'availableFields'] : ['models', 'plugins', source, currentModelName, 'editDisplay', 'availableFields']; + const relationsPath = source === 'content-manager' ? ['models', currentModelName, 'editDisplay', 'relations'] : ['models', 'plugins', source, currentModelName, 'editDisplay', 'relations']; - if (currentModelName && source && isEmpty(get(this.props.schema, attrPath))) { + if (currentModelName && source && isEmpty(get(schema, attrPath)) && isEmpty(get(schema, relationsPath))) { return ; } @@ -93,9 +96,11 @@ const mapStateToProps = createStructuredSelector({ }); const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withSaga = injectSaga({ key: 'global', saga }); +const withReducer = strapi.injectReducer({ key: 'global', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'global', saga, pluginId }); export default compose( + withReducer, withSaga, withConnect, )(App); diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/App/sagas.js b/packages/strapi-plugin-content-manager/admin/src/containers/App/sagas.js index d4521f1a9f..5d40628432 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/App/sagas.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/App/sagas.js @@ -49,7 +49,6 @@ export function* defaultSaga() { yield take(LOCATION_CHANGE); yield cancel(loadModelsWatcher); - yield cancel(loadedModelsWatcher); yield cancel(loadEntriesWatcher); } diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/App/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/App/selectors.js index a88074d4e5..f9dcfdd04c 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/App/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/App/selectors.js @@ -1,9 +1,9 @@ import { createSelector } from 'reselect'; - +import pluginId from '../../pluginId'; /** * Direct selector to the list state domain */ -const selectGlobalDomain = () => state => state.get('global'); +const selectGlobalDomain = () => state => state.get(`${pluginId}_global`); /** * Other specific selectors diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js index 3319a634c3..ac9f874c40 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/index.js @@ -23,6 +23,7 @@ import { import HTML5Backend from 'react-dnd-html5-backend'; import { DragDropContext } from 'react-dnd'; import cn from 'classnames'; + // You can find these components in either // ./node_modules/strapi-helper-plugin/lib/src // or strapi/packages/strapi-helper-plugin/lib/src @@ -31,19 +32,25 @@ import EmptyAttributesBlock from 'components/EmptyAttributesBlock'; import LoadingIndicator from 'components/LoadingIndicator'; import PluginHeader from 'components/PluginHeader'; import PopUpWarning from 'components/PopUpWarning'; -// Plugin's components -import CustomDragLayer from 'components/CustomDragLayer'; -import Edit from 'components/Edit'; -import EditRelations from 'components/EditRelations'; -// App selectors -import { makeSelectSchema } from 'containers/App/selectors'; -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; +import NavLink from 'components/NavLink'; + import getQueryParameters from 'utils/getQueryParameters'; -import { bindLayout } from 'utils/bindLayout'; import inputValidations from 'utils/inputsValidations'; -import { generateRedirectURI } from 'containers/ListPage/utils'; -import { checkFormValidity } from 'utils/formValidations'; + +import pluginId from '../../pluginId'; + +// Plugin's components +import CustomDragLayer from '../../components/CustomDragLayer'; +import Edit from '../../components/Edit'; +import EditRelations from '../../components/EditRelations'; + +import { bindLayout } from '../../utils/bindLayout'; +import { checkFormValidity } from '../../utils/formValidations'; + +// App selectors +import { makeSelectSchema } from '../App/selectors'; + +import { generateRedirectURI } from '../ListPage/utils'; import { addRelationItem, changeData, @@ -77,12 +84,16 @@ export class EditPage extends React.Component { this.initComponent(this.props); } - if (prevProps.editPage.submitSuccess !== this.props.editPage.submitSuccess) { + if ( + prevProps.editPage.submitSuccess !== this.props.editPage.submitSuccess + ) { if ( !isEmpty(this.props.location.search) && includes(this.props.location.search, '?redirectUrl') ) { - const redirectUrl = this.props.location.search.split('?redirectUrl=')[1]; + const redirectUrl = this.props.location.search.split( + '?redirectUrl=', + )[1]; this.props.history.push({ pathname: redirectUrl.split('?')[0], @@ -114,7 +125,10 @@ export class EditPage extends React.Component { * */ getLayout = () => - bindLayout.call(this, get(this.props.schema, ['layout', this.getModelName()], {})); + bindLayout.call( + this, + get(this.props.schema, ['layout', this.getModelName()], {}), + ); /** * @@ -124,11 +138,15 @@ export class EditPage extends React.Component { getAttributeValidations = name => get( this.props.editPage.formValidations, - [findIndex(this.props.editPage.formValidations, ['name', name]), 'validations'], + [ + findIndex(this.props.editPage.formValidations, ['name', name]), + 'validations', + ], {}, ); - getDisplayedFields = () => get(this.getSchema(), ['editDisplay', 'fields'], []); + getDisplayedFields = () => + get(this.getSchema(), ['editDisplay', 'fields'], []); /** * Retrieve the model @@ -136,7 +154,12 @@ export class EditPage extends React.Component { */ getModel = () => get(this.props.schema, ['models', this.getModelName()]) || - get(this.props.schema, ['models', 'plugins', this.getSource(), this.getModelName()]); + get(this.props.schema, [ + 'models', + 'plugins', + this.getSource(), + this.getModelName(), + ]); /** * Retrieve specific attribute @@ -161,8 +184,13 @@ export class EditPage extends React.Component { * @return {Object} */ getSchema = () => - this.getSource() !== 'content-manager' - ? get(this.props.schema, ['models', 'plugins', this.getSource(), this.getModelName()]) + this.getSource() !== pluginId + ? get(this.props.schema, [ + 'models', + 'plugins', + this.getSource(), + this.getModelName(), + ]) : get(this.props.schema, ['models', this.getModelName()]); getPluginHeaderTitle = () => { @@ -173,7 +201,7 @@ export class EditPage extends React.Component { const title = get(this.getSchema(), 'editDisplay.displayedField'); const valueToDisplay = get(this.props.editPage, ['initialRecord', title], null); - return isEmpty(valueToDisplay) ? null : truncate(valueToDisplay, { length: '24', separator: '.' }); + return isEmpty(toString(valueToDisplay)) ? null : truncate(valueToDisplay, { length: '24', separator: '.' }); }; /** @@ -182,6 +210,26 @@ export class EditPage extends React.Component { */ getSource = () => getQueryParameters(this.props.location.search, 'source'); + /** + * Get url base to create edit layout link + * @type {String} url base + */ + getContentManagerBaseUrl = () => { + let url = `/plugins/${pluginId}/ctm-configurations/edit-settings/`; + + if (this.getSource() === 'users-permissions') { + url = `${url}plugins/${this.getSource()}/`; + } + + return url; + }; + + /** + * Access url base from injected component to create edit model link + * @type {String} url base + */ + getContentTypeBuilderBaseUrl = () => '/plugins/content-type-builder/models/'; + /** * Initialize component */ @@ -195,27 +243,30 @@ export class EditPage extends React.Component { ); if (!this.isCreating()) { - const mainField = get(this.getModel(), 'info.mainField') || this.getModel().primaryKey; + const mainField = + get(this.getModel(), 'info.mainField') || this.getModel().primaryKey; this.props.getData(props.match.params.id, this.getSource(), mainField); } // Get all relations made with the upload plugin - const fileRelations = Object.keys(get(this.getSchema(), 'relations', {})).reduce( - (acc, current) => { - const association = get(this.getSchema(), ['relations', current], {}); + const fileRelations = Object.keys( + get(this.getSchema(), 'relations', {}), + ).reduce((acc, current) => { + const association = get(this.getSchema(), ['relations', current], {}); - if (association.plugin === 'upload' && association[association.type] === 'file') { - const relation = { - name: current, - multiple: association.nature === 'manyToManyMorph', - }; + if ( + association.plugin === 'upload' && + association[association.type] === 'file' + ) { + const relation = { + name: current, + multiple: association.nature === 'manyToManyMorph', + }; - acc.push(relation); - } - return acc; - }, - [], - ); + acc.push(relation); + } + return acc; + }, []); // Update the reducer so we can use it to create the appropriate FormData in the saga this.props.setFileRelations(fileRelations); @@ -240,7 +291,10 @@ export class EditPage extends React.Component { }); } - const errorIndex = findIndex(this.props.editPage.formErrors, ['name', target.name]); + const errorIndex = findIndex(this.props.editPage.formErrors, [ + 'name', + target.name, + ]); const errors = inputValidations( target.value, this.getAttributeValidations(target.name), @@ -292,18 +346,20 @@ export class EditPage extends React.Component { handleGoBack = () => this.props.history.goBack(); - handleRedirect = ({ model, id, source = 'content-manager' }) => { + handleRedirect = ({ model, id, source = pluginId }) => { /* eslint-disable */ switch (model) { case 'permission': case 'role': case 'file': // Exclude special models which are handled by plugins. - if (source !== 'content-manager') { + if (source !== pluginId) { break; } default: - const pathname = `${this.props.match.path.replace(':slug', model).replace(':id', id)}`; + const pathname = `${this.props.match.path + .replace(':slug', model) + .replace(':id', id)}`; this.props.history.push({ pathname, @@ -330,16 +386,22 @@ export class EditPage extends React.Component { this.props.setFormErrors(formErrors); }; - hasDisplayedRelations = () => { - return this.getDisplayedRelations().length > 0; - }; - hasDisplayedFields = () => { return get(this.getModel(), ['editDisplay', 'fields'], []).length > 0; }; isCreating = () => this.props.match.params.id === 'create'; + /** + * Check environment + * @type {boolean} current env is dev + */ + isDevEnvironment = () => { + const { currentEnvironment } = this.context; + + return currentEnvironment === 'development'; + }; + isRelationComponentNull = () => Object.keys(get(this.getSchema(), 'relations', {})).filter( relation => @@ -358,9 +420,31 @@ export class EditPage extends React.Component { return acc; }, {}); + /** + * Render the edit layout link + * @type {NavLink} + */ + layoutLink = () => { + // Retrieve URL + const url = `${this.getContentManagerBaseUrl()}${this.getModelName()}`; + // Link props to display + const message = { + message: { + id: `${pluginId}.containers.Edit.Link.Layout`, + }, + icon: 'layout', + }; + + return ( +
  • + +
  • + ); + }; + pluginHeaderActions = () => [ { - label: 'content-manager.containers.Edit.reset', + label: `${pluginId}.containers.Edit.reset`, kind: 'secondary', onClick: this.toggle, type: 'button', @@ -368,7 +452,7 @@ export class EditPage extends React.Component { }, { kind: 'primary', - label: 'content-manager.containers.Edit.submit', + label: `${pluginId}.containers.Edit.submit`, onClick: this.handleSubmit, type: 'submit', loader: this.props.editPage.showLoader, @@ -397,6 +481,55 @@ export class EditPage extends React.Component { /* eslint-enable indent */ }; + /** + * Retrieve external links from injected components + * @type {Array} List of external links to display + */ + retrieveLinksContainerComponent = () => { + // Should be retrieved from the global props (@soupette) + const { plugins } = this.context; + const appPlugins = plugins.toJS(); + const componentToInject = Object.keys(appPlugins).reduce((acc, current) => { + // Retrieve injected compos from plugin + // if compo can be injected in left.links area push the compo in the array + const currentPlugin = appPlugins[current]; + const injectedComponents = get(currentPlugin, 'injectedComponents', []); + + const compos = injectedComponents + .filter(compo => { + return ( + compo.plugin === `${pluginId}.editPage` && + compo.area === 'right.links' + ); + }) + .map(compo => { + const Component = compo.component; + + return ( +
  • + +
  • + ); + }); + + return [...acc, ...compos]; + }, []); + + return componentToInject; + }; + + shouldDisplayedRelations = () => { + return this.getDisplayedRelations().length > 0; + }; + + /** + * Right section to display if needed + * @type {boolean} + */ + shouldDisplayedRightSection = () => { + return this.shouldDisplayedRelations() || this.isDevEnvironment(); + }; + showLoaders = () => { const { editPage: { isLoading }, @@ -409,10 +542,21 @@ export class EditPage extends React.Component { ); }; - toggle = () => this.setState(prevState => ({ showWarning: !prevState.showWarning })); + toggle = () => + this.setState(prevState => ({ showWarning: !prevState.showWarning })); toggleDelete = () => - this.setState(prevState => ({ showWarningDelete: !prevState.showWarningDelete })); + this.setState(prevState => ({ + showWarningDelete: !prevState.showWarningDelete, + })); + + /** + * Render internal and external links + * @type {Array} List of all links to display + */ + renderNavLinks = () => { + return [this.layoutLink(), ...this.retrieveLinksContainerComponent()]; + }; renderEdit = () => { const { @@ -420,15 +564,19 @@ export class EditPage extends React.Component { location: { search }, } = this.props; const source = getQueryParameters(search, 'source'); - const basePath = '/plugins/content-manager/ctm-configurations'; + const basePath = `/plugins/${pluginId}/ctm-configurations/edit-settings`; const pathname = - source !== 'content-manager' + source !== pluginId ? `${basePath}/plugins/${source}/${this.getModelName()}` : `${basePath}/${this.getModelName()}`; if (this.showLoaders()) { return ( -
    +
    @@ -438,10 +586,14 @@ export class EditPage extends React.Component { if (!this.hasDisplayedFields()) { return ( -
    +
    this.props.history.push(pathname)} />
    @@ -449,7 +601,11 @@ export class EditPage extends React.Component { } return ( -
    +
    {this.renderEdit()} - {this.hasDisplayedRelations() && ( + {this.shouldDisplayedRightSection() && (
    -
    - {this.hasDisplayedRelations() && ( + {this.shouldDisplayedRelations() && ( +
    - )} -
    +
    + )} + + {this.isDevEnvironment() && ( +
    +
      {this.renderNavLinks()}
    +
    + )}
    )}
    @@ -542,6 +704,7 @@ export class EditPage extends React.Component { } EditPage.contextTypes = { + currentEnvironment: PropTypes.string, plugins: PropTypes.object, }; @@ -601,8 +764,8 @@ const withConnect = connect( mapDispatchToProps, ); -const withReducer = injectReducer({ key: 'editPage', reducer }); -const withSaga = injectSaga({ key: 'editPage', saga }); +const withReducer = strapi.injectReducer({ key: 'editPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'editPage', saga, pluginId }); export default compose( withReducer, 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 bee822f110..8255fedc6f 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 @@ -1,20 +1,21 @@ -import { LOCATION_CHANGE } from 'react-router-redux'; +// import { LOCATION_CHANGE } from 'react-router-redux'; import { findIndex, get, isArray, isEmpty, includes, isNumber, isString, map } from 'lodash'; import { all, call, - cancel, + // cancel, fork, put, select, - take, + // take, takeLatest, } from 'redux-saga/effects'; -import { makeSelectSchema } from 'containers/App/selectors'; // Utils. import cleanData from 'utils/cleanData'; import request from 'utils/request'; import templateObject from 'utils/templateObject'; + +import { makeSelectSchema } from '../App/selectors'; import { getDataSucceeded, setFormErrors, @@ -95,7 +96,7 @@ export function* submit() { cleanedData = record[current]; break; case 'date': - cleanedData = record[current]._isAMomentObject === true ? record[current].format('YYYY-MM-DD HH:mm:ss') : record[current]; + cleanedData = record[current] && record[current]._isAMomentObject === true ? record[current].format('YYYY-MM-DD HH:mm:ss') : record[current]; break; default: cleanedData = cleanData(record[current], 'value', 'id'); @@ -154,7 +155,7 @@ export function* submit() { yield put(submitSuccess()); } catch(err) { - if (isArray(err.response.payload.message)) { + if (isArray(get(err, 'response.payload.message'))) { const errors = err.response.payload.message.reduce((acc, current) => { const error = current.messages.reduce((acc, current) => { if (includes(current.id, 'Auth')) { @@ -185,13 +186,15 @@ export function* submit() { } function* defaultSaga() { - const loadDataWatcher = yield fork(takeLatest, GET_DATA, dataGet); + yield fork(takeLatest, GET_DATA, dataGet); + // TODO fix router (Other PR) + // const loadDataWatcher = yield fork(takeLatest, GET_DATA, dataGet); yield fork(takeLatest, DELETE_DATA, deleteData); yield fork(takeLatest, SUBMIT, submit); - yield take(LOCATION_CHANGE); + // yield take(LOCATION_CHANGE); - yield cancel(loadDataWatcher); + // yield cancel(loadDataWatcher); } export default defaultSaga; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js index f046579eaa..5b1dd5c760 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/selectors.js @@ -5,11 +5,12 @@ */ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the listPage state domain */ -const selectEditPageDomain = () => state => state.get('editPage'); +const selectEditPageDomain = () => state => state.get(`${pluginId}_editPage`); /** diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/styles.scss b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/styles.scss index 74019ded0c..7d76ea6fd0 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/styles.scss +++ b/packages/strapi-plugin-content-manager/admin/src/containers/EditPage/styles.scss @@ -1,17 +1,37 @@ -.containerFluid { /* stylelint-disable */ +.containerFluid { + /* stylelint-disable */ padding: 18px 30px; } -.main_wrapper{ +.main_wrapper { background: #ffffff; padding: 22px 10px; border-radius: 2px; - box-shadow: 0 2px 4px #E3E9F3; + box-shadow: 0 2px 4px #e3e9f3; } -.sub_wrapper{ +.sub_wrapper, +.links_wrapper { background: #ffffff; - padding: 0 20px 1px; border-radius: 2px; - box-shadow: 0 2px 4px #E3E9F3; + box-shadow: 0 2px 4px #e3e9f3; +} + +.sub_wrapper { + padding: 0 20px 1px; + margin-bottom: 28px; +} + +.links_wrapper { + ul { + list-style: none; + padding: 0; + } + li { + padding: 7px 20px; + border-top: 1px solid #f6f6f6; + &:first-of-type { + border-color: transparent; + } + } } diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Home/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/Home/index.js deleted file mode 100644 index bd2e801d0c..0000000000 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Home/index.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Home - */ - -import React from 'react'; -import { connect } from 'react-redux'; -import { createStructuredSelector } from 'reselect'; -import { FormattedMessage } from 'react-intl'; - -import PluginHeader from 'components/PluginHeader'; - -import styles from './styles.scss'; - -export class Home extends React.Component { - render() { - return ( -
    -
    - -

    - -

    -
    -
    - ); - } -} - -Home.propTypes = {}; - -export function mapDispatchToProps() { - return {}; -} - -const mapStateToProps = createStructuredSelector({}); - -// Wrap the component to inject dispatch and state into it -export default connect(mapStateToProps, mapDispatchToProps)(Home); diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Home/messages.json b/packages/strapi-plugin-content-manager/admin/src/containers/Home/messages.json deleted file mode 100644 index 409935166b..0000000000 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Home/messages.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "pluginHeaderDescription": { - "id": "contentManager.containers.Home.pluginHeaderDescription", - "defaultMessage": "A powerful UI to easily manage your data." - }, - "introduction": { - "id": "contentManager.containers.Home.introduction", - "defaultMessage": "To edit your content's entries go to the specific link in the left menu." - } -} \ No newline at end of file diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/Home/styles.scss b/packages/strapi-plugin-content-manager/admin/src/containers/Home/styles.scss deleted file mode 100644 index 689cab1129..0000000000 --- a/packages/strapi-plugin-content-manager/admin/src/containers/Home/styles.scss +++ /dev/null @@ -1,17 +0,0 @@ -/** - * styles.scss - * - * Home container styles - */ - - .containerFluid { /* stylelint-disable */ - padding: 18px 30px; - - p { - display: block; - margin: 0; - padding-bottom: 14px; - line-height: 18px; - text-align: left; - } -} diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/index.js index 356fd4f489..45853dcd3d 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/index.js @@ -9,12 +9,11 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { bindActionCreators, compose } from 'redux'; import { createStructuredSelector } from 'reselect'; -import { capitalize, findIndex, get, isUndefined, toInteger, upperFirst } from 'lodash'; +import { capitalize, findIndex, get, isEmpty, isUndefined, toInteger, upperFirst } from 'lodash'; import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; import { FormattedMessage } from 'react-intl'; import cn from 'classnames'; -// App selectors -import { makeSelectSchema } from 'containers/App/selectors'; + // You can find these components in either // ./node_modules/strapi-helper-plugin/lib/src // or strapi/packages/strapi-helper-plugin/lib/src @@ -22,17 +21,21 @@ import PageFooter from 'components/PageFooter'; import PluginHeader from 'components/PluginHeader'; import PopUpWarning from 'components/PopUpWarning'; import InputCheckbox from 'components/InputCheckbox'; -// Components from the plugin itself -import AddFilterCTA from 'components/AddFilterCTA'; -import FiltersPickWrapper from 'components/FiltersPickWrapper/Loadable'; -import Filter from 'components/Filter/Loadable'; -import Search from 'components/Search'; -import Table from 'components/Table'; -// Utils located in `strapi/packages/strapi-helper-plugin/lib/src/utils`; + import getQueryParameters from 'utils/getQueryParameters'; -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; import storeData from 'utils/storeData'; + +import pluginId from '../../pluginId'; +// Components from the plugin itself +import AddFilterCTA from '../../components/AddFilterCTA'; +import FiltersPickWrapper from '../../components/FiltersPickWrapper/Loadable'; +import Filter from '../../components/Filter/Loadable'; +import Search from '../../components/Search'; +import Table from '../../components/Table'; + +// App selectors +import { makeSelectSchema } from '../App/selectors'; + import Div from './Div'; import { addAttr, @@ -366,7 +369,13 @@ export class ListPage extends React.Component { showSearch = () => get(this.getCurrentModel(), ['search']); - showFilters = () => get(this.getCurrentModel(), ['filters']); + showFilters = () => { + if (isEmpty(get(this.getCurrentModel(), ['editDisplay', 'availableFields']))) { + return false; + } + + return get(this.getCurrentModel(), ['filters']); + } showBulkActions = () => get(this.getCurrentModel(), ['bulkActions']); @@ -681,7 +690,7 @@ const mapStateToProps = createStructuredSelector({ const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'listPage', reducer }); -const withSaga = injectSaga({ key: 'listPage', saga }); +const withReducer = strapi.injectReducer({ key: 'listPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'listPage', saga, pluginId }); export default compose(withReducer, withSaga, withConnect)(ListPage); diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/saga.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/saga.js index ed49fe770d..f2947beb74 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/saga.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/saga.js @@ -1,13 +1,13 @@ // Dependencies. -import { LOCATION_CHANGE } from 'react-router-redux'; +// import { LOCATION_CHANGE } from 'react-router-redux'; import { all, call, - cancel, + // cancel, fork, put, select, - take, + // take, takeLatest, } from 'redux-saga/effects'; // Utils. @@ -114,13 +114,16 @@ export function* dataDeleteAll({ entriesToDelete, model, source }) { // All sagas to be loaded function* defaultSaga() { - const loadDataWatcher = yield fork(takeLatest, GET_DATA, dataGet); + yield fork(takeLatest, GET_DATA, dataGet); + + // TODO fix router (Other PR) + // const loadDataWatcher = yield fork(takeLatest, GET_DATA, dataGet); yield fork(takeLatest, DELETE_DATA, dataDelete); yield fork(takeLatest, DELETE_SEVERAL_DATA, dataDeleteAll); - yield take(LOCATION_CHANGE); + // yield take(LOCATION_CHANGE); - yield cancel(loadDataWatcher); + // yield cancel(loadDataWatcher); } export default defaultSaga; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/selectors.js index 1a56324484..38cd096f66 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/selectors.js @@ -5,11 +5,12 @@ */ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the listPage state domain */ -const selectListPageDomain = () => state => state.get('listPage'); +const selectListPageDomain = () => state => state.get(`${pluginId}_listPage`); /** diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/index.js index 6d058947ef..460a36de25 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/index.js @@ -14,6 +14,21 @@ import { DragDropContext } from 'react-dnd'; import { FormattedMessage } from 'react-intl'; import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; import PropTypes from 'prop-types'; +import BackHeader from 'components/BackHeader'; +import HeaderNav from 'components/HeaderNav'; +import Input from 'components/InputsIndex'; +import InputSelect from 'components/InputSelect'; +import PluginHeader from 'components/PluginHeader'; +import PopUpWarning from 'components/PopUpWarning'; + +import pluginId from '../../pluginId'; + +import Block from '../../components/Block'; +import CustomDragLayer from '../../components/CustomDragLayer'; +import DraggableAttr from '../../components/DraggableAttr'; +import FormTitle from '../../components/FormTitle'; +import VariableDraggableAttr from '../../components/VariableDraggableAttr'; + import { beginMove, endMove, @@ -30,7 +45,7 @@ import { onReset, onSubmit, setLayout, -} from 'containers/App/actions'; +} from '../App/actions'; import { makeSelectAddedField, makeSelectDraggedItemName, @@ -40,22 +55,7 @@ import { makeSelectModifiedSchema, makeSelectShouldResetGrid, makeSelectSubmitSuccess, -} from 'containers/App/selectors'; - -import BackHeader from 'components/BackHeader'; -import Block from 'components/Block'; -import CustomDragLayer from 'components/CustomDragLayer'; -import DraggableAttr from 'components/DraggableAttr'; -import FormTitle from 'components/FormTitle'; -import HeaderNav from 'components/HeaderNav'; -import Input from 'components/InputsIndex'; -import InputSelect from 'components/InputSelect'; -import PluginHeader from 'components/PluginHeader'; -import PopUpWarning from 'components/PopUpWarning'; -import VariableDraggableAttr from 'components/VariableDraggableAttr'; - -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; +} from '../App/selectors'; import { onClickEditField, onClickEditListItem, onClickEditRelation } from './actions'; import reducer from './reducer'; @@ -1161,8 +1161,8 @@ const withConnect = connect( mapStateToProps, mapDispatchToProps, ); -const withReducer = injectReducer({ key: 'settingPage', reducer }); -const withSaga = injectSaga({ key: 'settingPage', saga }); +const withReducer = strapi.injectReducer({ key: 'settingPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'settingPage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/selectors.js index bb2fe4ec1d..71197db9d7 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/SettingPage/selectors.js @@ -4,11 +4,12 @@ */ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the settingPage state domain */ -const selectSettingPageDomain = () => state => state.get('settingPage'); +const selectSettingPageDomain = () => state => state.get(`${pluginId}_settingPage`); /** @@ -21,4 +22,4 @@ const makeSelectSettingPage = () => createSelector( ); -export default makeSelectSettingPage; \ No newline at end of file +export default makeSelectSettingPage; diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/index.js b/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/index.js index a5b5c23493..655210668f 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/index.js @@ -10,15 +10,19 @@ import { createStructuredSelector } from 'reselect'; import cn from 'classnames'; import { get, sortBy } from 'lodash'; import PropTypes from 'prop-types'; -import { onChange, onSubmit, onReset } from 'containers/App/actions'; -import { makeSelectModifiedSchema, makeSelectSubmitSuccess } from 'containers/App/selectors'; + import Input from 'components/InputsIndex'; import PluginHeader from 'components/PluginHeader'; import PopUpWarning from 'components/PopUpWarning'; -import Block from 'components/Block'; -import SettingsRow from 'components/SettingsRow'; -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; + +import Block from '../../components/Block'; +import SettingsRow from '../../components/SettingsRow'; + +import pluginId from '../../pluginId'; + +import { onChange, onSubmit, onReset } from '../App/actions'; +import { makeSelectModifiedSchema, makeSelectSubmitSuccess } from '../App/selectors'; + import reducer from './reducer'; import saga from './saga'; import styles from './styles.scss'; @@ -211,8 +215,8 @@ const mapStateToProps = createStructuredSelector({ submitSuccess: makeSelectSubmitSuccess(), }); const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'settingsPage', reducer }); -const withSaga = injectSaga({ key: 'settingsPage', saga }); +const withReducer = strapi.injectReducer({ key: 'settingsPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'settingsPage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/selectors.js b/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/selectors.js index 8153dd3770..e77bc84df6 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/selectors.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/SettingsPage/selectors.js @@ -4,11 +4,12 @@ */ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the settingsPage state domain */ -const selectSettingsPageDomain = () => state => state.get('settingsPage'); +const selectSettingsPageDomain = () => state => state.get(`${pluginId}_settingsPage`); /** @@ -21,4 +22,4 @@ const makeSelectSettingsPage = () => createSelector( ); -export default makeSelectSettingsPage; \ No newline at end of file +export default makeSelectSettingsPage; diff --git a/packages/strapi-plugin-content-manager/admin/src/pluginId.js b/packages/strapi-plugin-content-manager/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-plugin-content-manager/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-plugin-content-manager/admin/src/routes.json b/packages/strapi-plugin-content-manager/admin/src/routes.json deleted file mode 100644 index 11bdd48929..0000000000 --- a/packages/strapi-plugin-content-manager/admin/src/routes.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "/": { - "container": "Home" - }, - "/:slug": { - "container": "List" - }, - "/:slug/:id": { - "container": "Edit" - } -} \ No newline at end of file diff --git a/packages/strapi-plugin-content-manager/admin/src/translations/en.json b/packages/strapi-plugin-content-manager/admin/src/translations/en.json index 708d6d9427..146e577c60 100644 --- a/packages/strapi-plugin-content-manager/admin/src/translations/en.json +++ b/packages/strapi-plugin-content-manager/admin/src/translations/en.json @@ -37,6 +37,8 @@ "containers.Edit.returnList": "Return to list", "containers.Edit.seeDetails": "Details", "containers.Edit.submit": "Save", + "containers.Edit.Link.Layout": "Configure the layout", + "containers.Edit.Link.Fields": "Edit the fields", "containers.Home.introduction": "To edit your entries go to the specific link in the left menu. This plugin doesn't have a proper way to edit settings and it's still under active development.", "containers.Home.pluginHeaderDescription": "Manage your entries through a powerful and beautiful interface.", "containers.Home.pluginHeaderTitle": "Content Manager", @@ -121,4 +123,4 @@ "popUpWarning.warning.updateAllSettings": "This will modify all your settings", "success.record.delete": "Deleted", "success.record.save": "Saved" -} \ No newline at end of file +} diff --git a/packages/strapi-plugin-content-manager/admin/src/translations/fr.json b/packages/strapi-plugin-content-manager/admin/src/translations/fr.json index 7406974be9..daf6d3b046 100644 --- a/packages/strapi-plugin-content-manager/admin/src/translations/fr.json +++ b/packages/strapi-plugin-content-manager/admin/src/translations/fr.json @@ -35,6 +35,8 @@ "containers.Edit.returnList": "Retourner à la liste", "containers.Edit.seeDetails": "Détails", "containers.Edit.submit": "Valider", + "containers.Edit.Link.Layout": "Paramétrer la vue", + "containers.Edit.Link.Fields": "Éditer le modèle", "containers.Home.introduction": "Pour éditer du contenu, choisissez un type de données dans le menu de gauche.", "containers.Home.pluginHeaderDescription": "Créer et modifier votre type de contenu", "containers.Home.pluginHeaderTitle": "Type de contenu", @@ -120,4 +122,3 @@ "success.record.delete": "Supprimé", "success.record.save": "Sauvegardé" } - diff --git a/packages/strapi-plugin-content-manager/config/functions/bootstrap.js b/packages/strapi-plugin-content-manager/config/functions/bootstrap.js index 7302fb4eb9..36b073800a 100644 --- a/packages/strapi-plugin-content-manager/config/functions/bootstrap.js +++ b/packages/strapi-plugin-content-manager/config/functions/bootstrap.js @@ -9,27 +9,32 @@ const { getEditDisplayFieldsPath } = require('./utils/getters'); const splitted = str => str.split('.'); -const pickData = (model) => _.pick(model, [ - 'info', - 'connection', - 'collectionName', - 'attributes', - 'identity', - 'globalId', - 'globalName', - 'orm', - 'options', - 'loadedModel', - 'primaryKey', - 'associations' -]); +const pickData = model => + _.pick(model, [ + 'info', + 'connection', + 'collectionName', + 'attributes', + 'identity', + 'globalId', + 'globalName', + 'orm', + 'options', + 'loadedModel', + 'primaryKey', + 'associations', + ]); module.exports = async cb => { // Retrieve all layout files from the plugins config folder const pluginsLayout = Object.keys(strapi.plugins).reduce((acc, current) => { const models = _.get(strapi.plugins, [current, 'config', 'layout'], {}); Object.keys(models).forEach(model => { - const layout = _.get(strapi.plugins, [current, 'config', 'layout', model], {}); + const layout = _.get( + strapi.plugins, + [current, 'config', 'layout', model], + {} + ); acc[model] = layout; }); @@ -70,48 +75,59 @@ module.exports = async cb => { models: { plugins: {}, }, - layout: {} + layout: {}, }; // Populate the schema object const buildSchema = (model, name, plugin = false) => { // Model data - const schemaModel = Object.assign({ - label: _.upperFirst(name), - labelPlural: _.upperFirst(pluralize(name)), - orm: model.orm || 'mongoose', - search: true, - filters: true, - bulkActions: true, - pageEntries: 10, - defaultSort: model.primaryKey, - sort: 'ASC', - options: model.options, - editDisplay: { - availableFields: {}, - displayedField: model.primaryKey, - fields: [], - relations: [], + const schemaModel = Object.assign( + { + label: _.upperFirst(name), + labelPlural: _.upperFirst(pluralize(name)), + orm: model.orm || 'mongoose', + search: true, + filters: true, + bulkActions: true, + pageEntries: 10, + defaultSort: model.primaryKey, + sort: 'ASC', + options: model.options, + editDisplay: { + availableFields: {}, + displayedField: model.primaryKey, + fields: [], + relations: [], + }, }, - }, model); + model + ); const fieldsToRemove = []; // Fields (non relation) - const fields = _.mapValues(_.pickBy(model.attributes, attribute => - !attribute.model && !attribute.collection - ), (value, attribute) => { - const fieldClassName = _.get(tempLayout, [name, 'attributes', attribute, 'className'], ''); + const fields = _.mapValues( + _.pickBy( + model.attributes, + attribute => !attribute.model && !attribute.collection + ), + (value, attribute) => { + const fieldClassName = _.get( + tempLayout, + [name, 'attributes', attribute, 'className'], + '' + ); - if (fieldClassName === 'd-none') { - fieldsToRemove.push(attribute); + if (fieldClassName === 'd-none') { + fieldsToRemove.push(attribute); + } + + return { + label: _.upperFirst(attribute), + description: '', + type: value.type || 'string', + disabled: false, + }; } - - return { - label: _.upperFirst(attribute), - description: '', - type: value.type || 'string', - disabled: false, - }; - }); + ); // Don't display fields that are hidden by default like the resetPasswordToken for the model user fieldsToRemove.forEach(field => { @@ -129,7 +145,11 @@ module.exports = async cb => { const attrType = schemaModel.fields[attr].type; const sortable = attrType !== 'json' && attrType !== 'array'; - return Object.assign(schemaModel.fields[attr], { name: attr, sortable, searchable: sortable }); + return Object.assign(schemaModel.fields[attr], { + name: attr, + sortable, + searchable: sortable, + }); }) // Retrieve only the fourth first items .slice(0, 4); @@ -144,13 +164,24 @@ module.exports = async cb => { // This object will be used to customise the label and description and so on of an input. // TODO: maybe add the customBootstrapClass in it; - schemaModel.editDisplay.availableFields = Object.keys(schemaModel.fields).reduce((acc, current) => { + schemaModel.editDisplay.availableFields = Object.keys( + schemaModel.fields + ).reduce((acc, current) => { acc[current] = Object.assign( - _.pick(_.get(schemaModel, ['fields', current], {}), ['label', 'type', 'description', 'name']), + _.pick(_.get(schemaModel, ['fields', current], {}), [ + 'label', + 'type', + 'description', + 'name', + ]), { - editable: ['updatedAt', 'createdAt', 'updated_at', 'created_at'].indexOf(current) === -1, + editable: + ['updatedAt', 'createdAt', 'updated_at', 'created_at'].indexOf( + current + ) === -1, placeholder: '', - }); + } + ); return acc; }, {}); @@ -159,13 +190,37 @@ module.exports = async cb => { // Model relations schemaModel.relations = model.associations.reduce((acc, current) => { const label = _.upperFirst(current.alias); - const displayedAttribute = current.plugin ? // Value to modified to custom what's displayed in the react-select - _.get(pluginsModel, [current.plugin, 'models', current.model || current.collection, 'info', 'mainField']) || - _.findKey(_.get(pluginsModel, [current.plugin, 'models', current.model || current.collection, 'attributes']), { type : 'string'}) || - 'id' : - _.get(models, [current.model || current.collection, 'info', 'mainField']) || - _.findKey(_.get(models, [current.model || current.collection, 'attributes']), { type : 'string'}) || - 'id'; + const displayedAttribute = current.plugin // Value to modified to custom what's displayed in the react-select + ? _.get(pluginsModel, [ + current.plugin, + 'models', + current.model || current.collection, + 'info', + 'mainField', + ]) || + _.findKey( + _.get(pluginsModel, [ + current.plugin, + 'models', + current.model || current.collection, + 'attributes', + ]), + { type: 'string' } + ) || + 'id' + : _.get(models, [ + current.model || current.collection, + 'info', + 'mainField', + ]) || + _.findKey( + _.get(models, [ + current.model || current.collection, + 'attributes', + ]), + { type: 'string' } + ) || + 'id'; acc[current.alias] = { ...current, @@ -176,37 +231,55 @@ module.exports = async cb => { return acc; }, {}); - const relationsArray = Object.keys(schemaModel.relations).filter(relation => { - const isUploadRelation = _.get(schemaModel, ['relations', relation, 'plugin'], '') === 'upload'; - const isMorphSide = _.get(schemaModel, ['relations', relation, 'nature'], '').toLowerCase().includes('morp') && _.get(schemaModel, ['relations', relation, relation]) !== undefined; + const relationsArray = Object.keys(schemaModel.relations).filter( + relation => { + const isUploadRelation = + _.get(schemaModel, ['relations', relation, 'plugin'], '') === + 'upload'; + const isMorphSide = + _.get(schemaModel, ['relations', relation, 'nature'], '') + .toLowerCase() + .includes('morp') && + _.get(schemaModel, ['relations', relation, relation]) !== undefined; - return !isUploadRelation && !isMorphSide; - }); - - const uploadRelations = Object.keys(schemaModel.relations).reduce((acc, current) => { - if (_.get(schemaModel, ['relations', current, 'plugin']) === 'upload') { - const model = _.get(schemaModel, ['relations', current]); - - acc[current] = { - description: '', - editable: true, - label: _.upperFirst(current), - multiple: _.has(model, 'collection'), - name: current, - placeholder: '', - type: 'file', - disabled: false, - }; + return !isUploadRelation && !isMorphSide; } + ); - return acc; - }, {}); + const uploadRelations = Object.keys(schemaModel.relations).reduce( + (acc, current) => { + if ( + _.get(schemaModel, ['relations', current, 'plugin']) === 'upload' + ) { + const model = _.get(schemaModel, ['relations', current]); - schemaModel.editDisplay.availableFields = _.merge(schemaModel.editDisplay.availableFields, uploadRelations); + acc[current] = { + description: '', + editable: true, + label: _.upperFirst(current), + multiple: _.has(model, 'collection'), + name: current, + placeholder: '', + type: 'file', + disabled: false, + }; + } + + return acc; + }, + {} + ); + + schemaModel.editDisplay.availableFields = _.merge( + schemaModel.editDisplay.availableFields, + uploadRelations + ); schemaModel.editDisplay.relations = relationsArray; } - schemaModel.editDisplay.fields = Object.keys(schemaModel.editDisplay.availableFields); + schemaModel.editDisplay.fields = Object.keys( + schemaModel.editDisplay.availableFields + ); if (plugin) { return _.set(schema.models.plugins, `${plugin}.${name}`, schemaModel); @@ -231,7 +304,7 @@ module.exports = async cb => { const pluginStore = strapi.store({ environment: '', type: 'plugin', - name: 'content-manager' + name: 'content-manager', }); try { @@ -264,24 +337,42 @@ module.exports = async cb => { const schemaApis = getApis(schema.models); // Array of apis to add - const apisToAdd = schemaApis.filter(api => prevSchemaApis.indexOf(api) === -1).map(splitted); + const apisToAdd = schemaApis + .filter(api => prevSchemaApis.indexOf(api) === -1) + .map(splitted); // Array of apis to remove - const apisToRemove = prevSchemaApis.filter(api => schemaApis.indexOf(api) === -1).map(splitted); + const apisToRemove = prevSchemaApis + .filter(api => schemaApis.indexOf(api) === -1) + .map(splitted); // Retrieve the same apis by name - const sameApis = schemaApis.filter(api => prevSchemaApis.indexOf(api) !== -1).map(splitted); + const sameApis = schemaApis + .filter(api => prevSchemaApis.indexOf(api) !== -1) + .map(splitted); // Retrieve all the field's path of the current unchanged api name const schemaSameApisKeys = _.flattenDeep(getApisKeys(schema, sameApis)); // Retrieve all the field's path of the previous unchanged api name - const prevSchemaSameApisKeys = _.flattenDeep(getApisKeys(prevSchema, sameApis)); + const prevSchemaSameApisKeys = _.flattenDeep( + getApisKeys(prevSchema, sameApis) + ); // Determine for the same api if we need to add some fields - const sameApisAttrToAdd = schemaSameApisKeys.filter(attr => prevSchemaSameApisKeys.indexOf(attr) === -1).map(splitted); + const sameApisAttrToAdd = schemaSameApisKeys + .filter(attr => prevSchemaSameApisKeys.indexOf(attr) === -1) + .map(splitted); // Special case for the relations - const prevSchemaSameApisUploadRelations = _.flattenDeep(getApisUploadRelations(prevSchema, sameApis)); - const schemaSameApisUploadRelations = _.flattenDeep(getApisUploadRelations(schema, sameApis)); - const sameApisUploadRelationsToAdd = schemaSameApisUploadRelations.filter(attr => prevSchemaSameApisUploadRelations.indexOf(attr) === -1).map(splitted); + const prevSchemaSameApisUploadRelations = _.flattenDeep( + getApisUploadRelations(prevSchema, sameApis) + ); + const schemaSameApisUploadRelations = _.flattenDeep( + getApisUploadRelations(schema, sameApis) + ); + const sameApisUploadRelationsToAdd = schemaSameApisUploadRelations + .filter(attr => prevSchemaSameApisUploadRelations.indexOf(attr) === -1) + .map(splitted); // Determine the fields to remove for the unchanged api name - const sameApisAttrToRemove = prevSchemaSameApisKeys.filter(attr => schemaSameApisKeys.indexOf(attr) === -1).map(splitted); + const sameApisAttrToRemove = prevSchemaSameApisKeys + .filter(attr => schemaSameApisKeys.indexOf(attr) === -1) + .map(splitted); // Remove api apisToRemove.map(apiPath => { @@ -296,7 +387,8 @@ module.exports = async cb => { // Check default sort and change it if needed _.unset(prevSchema.models, attrPath); // Retrieve the api path in the schema Object - const apiPath = attrPath.length > 3 ? _.take(attrPath, 3) : _.take(attrPath, 1); + const apiPath = + attrPath.length > 3 ? _.take(attrPath, 3) : _.take(attrPath, 1); // Retrieve the listDisplay path in the schema Object const listDisplayPath = apiPath.concat('listDisplay'); const prevListDisplay = _.get(prevSchema.models, listDisplayPath); @@ -310,7 +402,11 @@ module.exports = async cb => { // If the user has deleted the default sort attribute in the content type builder // Replace it by new generated one from the current schema if (_.includes(currentAttr, defaultSort)) { - _.set(prevSchema.models, defaultSortPath, _.get(schema.models, defaultSortPath)); + _.set( + prevSchema.models, + defaultSortPath, + _.get(schema.models, defaultSortPath) + ); } // If the user has deleted the edit view displayed field (name in the header) @@ -320,20 +416,28 @@ module.exports = async cb => { } // Update the displayed fields - const updatedListDisplay = prevListDisplay.filter(obj => obj.name !== currentAttr.join()); + const updatedListDisplay = prevListDisplay.filter( + obj => obj.name !== currentAttr.join() + ); // Retrieve the model's displayed fields for the `EditPage` const fieldsPath = getEditDisplayFieldsPath(attrPath); // Retrieve the previous settings const prevEditDisplayFields = _.get(prevSchema.models, fieldsPath); // Update the fields - const updatedEditDisplayFields = prevEditDisplayFields.filter(field => field !== currentAttr.join()); + const updatedEditDisplayFields = prevEditDisplayFields.filter( + field => field !== currentAttr.join() + ); // Set the new layout _.set(prevSchema.models, fieldsPath, updatedEditDisplayFields); if (updatedListDisplay.length === 0) { // Update it with the one from the generated schema - _.set(prevSchema.models, listDisplayPath, _.get(schema.models, listDisplayPath, [])); + _.set( + prevSchema.models, + listDisplayPath, + _.get(schema.models, listDisplayPath, []) + ); } else { _.set(prevSchema.models, listDisplayPath, updatedListDisplay); } @@ -343,7 +447,10 @@ 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, options } = _.get(prevSchema, 'generalSettings'); + const { search, filters, bulkActions, pageEntries, options } = _.get( + prevSchema, + 'generalSettings' + ); _.set(api, 'options', options); _.set(api, 'filters', filters); @@ -374,7 +481,13 @@ module.exports = async cb => { sameApis.forEach(apiPath => { // This doesn't keep the prevSettings for the relations, the user will have to reset it. // We might have to improve this if we want the order of the relations to be kept - ['relations', 'loadedModel', 'associations', 'attributes', ['editDisplay', 'relations']] + [ + 'relations', + 'loadedModel', + 'associations', + 'attributes', + ['editDisplay', 'relations'], + ] .map(key => apiPath.concat(key)) .forEach(keyPath => { const newValue = _.get(schema.models, keyPath); @@ -388,22 +501,29 @@ module.exports = async cb => { const attr = _.get(schema.models, attrPath); _.set(prevSchema.models, attrPath, attr); - const fieldsPath = [..._.take(attrPath, attrPath.length -2), 'fields']; + const fieldsPath = [..._.take(attrPath, attrPath.length - 2), 'fields']; const currentFields = _.get(prevSchema.models, fieldsPath, []); currentFields.push(attr.name); _.set(prevSchema.models, fieldsPath, currentFields); }); - schemaApis.map((model) => { + schemaApis.map(model => { const isPlugin = model.includes('plugins.'); - _.set(prevSchema.models[model], 'info', _.get(!isPlugin ? strapi.models[model] : strapi[model], 'info')); - _.set(prevSchema.models[model], 'options', _.get(!isPlugin ? strapi.models[model] : strapi[model], 'options')); + _.set( + prevSchema.models[model], + 'info', + _.get(!isPlugin ? strapi.models[model] : strapi[model], 'info') + ); + _.set( + prevSchema.models[model], + 'options', + _.get(!isPlugin ? strapi.models[model] : strapi[model], 'options') + ); }); await pluginStore.set({ key: 'schema', value: prevSchema }); - - } catch(err) { - console.log('error', err); + } catch (err) { + console.log('error', err); // eslint-disable-line no-console } cb(); diff --git a/packages/strapi-plugin-content-manager/config/queries/bookshelf.js b/packages/strapi-plugin-content-manager/config/queries/bookshelf.js index 39dae2ad91..c8fb0d1b01 100644 --- a/packages/strapi-plugin-content-manager/config/queries/bookshelf.js +++ b/packages/strapi-plugin-content-manager/config/queries/bookshelf.js @@ -58,7 +58,7 @@ module.exports = { const searchInt = Object.keys(this._attributes) .filter(attribute => attribute !== this.primaryKey && !associations.includes(attribute)) - .filter(attribute => ['integer', 'decimal', 'float'].includes(this._attributes[attribute].type)); + .filter(attribute => ['integer','biginteger', 'decimal', 'float'].includes(this._attributes[attribute].type)); const searchBool = Object.keys(this._attributes) .filter(attribute => attribute !== this.primaryKey && !associations.includes(attribute)) @@ -129,11 +129,11 @@ module.exports = { const searchNoText = Object.keys(this._attributes) .filter(attribute => attribute !== this.primaryKey && !associations.includes(attribute)) - .filter(attribute => !['string', 'text', 'boolean', 'integer', 'decimal', 'float'].includes(this._attributes[attribute].type)); + .filter(attribute => !['string', 'text', 'boolean', 'integer', 'biginteger', 'decimal', 'float'].includes(this._attributes[attribute].type)); const searchInt = Object.keys(this._attributes) .filter(attribute => attribute !== this.primaryKey && !associations.includes(attribute)) - .filter(attribute => ['integer', 'decimal', 'float'].includes(this._attributes[attribute].type)); + .filter(attribute => ['integer', 'biginteger', 'decimal', 'float'].includes(this._attributes[attribute].type)); const searchBool = Object.keys(this._attributes) .filter(attribute => attribute !== this.primaryKey && !associations.includes(attribute)) diff --git a/packages/strapi-plugin-content-manager/config/queries/mongoose.js b/packages/strapi-plugin-content-manager/config/queries/mongoose.js index a3dabbdb35..f8099f6cef 100644 --- a/packages/strapi-plugin-content-manager/config/queries/mongoose.js +++ b/packages/strapi-plugin-content-manager/config/queries/mongoose.js @@ -22,6 +22,7 @@ module.exports = { const $or = Object.keys(this.attributes).reduce((acc, curr) => { switch (this.attributes[curr].type) { case 'integer': + case 'biginteger': case 'float': case 'decimal': if (!_.isNaN(_.toNumber(params.search))) { @@ -57,6 +58,7 @@ module.exports = { const $or = Object.keys(this.attributes).reduce((acc, curr) => { switch (this.attributes[curr].type) { case 'integer': + case 'biginteger': case 'float': case 'decimal': if (!_.isNaN(_.toNumber(params.search))) { diff --git a/packages/strapi-plugin-content-manager/package.json b/packages/strapi-plugin-content-manager/package.json index 227edb829f..87205bf477 100644 --- a/packages/strapi-plugin-content-manager/package.json +++ b/packages/strapi-plugin-content-manager/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-content-manager", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "A powerful UI to easily manage your data.", "strapi": { "name": "Content Manager", @@ -12,9 +12,9 @@ "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "cross-env ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development PLUGIN=true node ./node_modules/strapi-helper-plugin/lib/server", "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", @@ -26,7 +26,7 @@ "draft-js": "^0.10.5", "react-select": "^1.2.1", "showdown": "^1.8.6", - "strapi-helper-plugin": "3.0.0-alpha.23.1" + "strapi-helper-plugin": "3.0.0-alpha.24.1" }, "dependencies": { "pluralize": "^7.0.0" diff --git a/packages/strapi-plugin-content-manager/test/front/integration/createPage_specs.js b/packages/strapi-plugin-content-manager/test/front/integration/createPage_specs.js index 0a757df1ef..b44685fa9d 100644 --- a/packages/strapi-plugin-content-manager/test/front/integration/createPage_specs.js +++ b/packages/strapi-plugin-content-manager/test/front/integration/createPage_specs.js @@ -67,7 +67,7 @@ describe('Testing Content Manager createPages', function() { .wait(1000) .window() .its('__store__') - .its('content-manager') + .its('store'); }); }); @@ -196,11 +196,11 @@ describe('Testing Content Manager createPages', function() { .wait(2000) .window() .its('__store__') - .its('content-manager') + .its('store') .then(pluginStore => { const records = pluginStore .getState() - .getIn(['listPage', 'records', 'tag']) + .getIn(['content-manager_listPage', 'records', 'tag']) .toJS(); expect(records).to.have.length(0); @@ -411,7 +411,7 @@ describe('Testing Content Manager createPages', function() { .then(pluginStore => { const category = pluginStore .getState() - .getIn(['editPage', 'record', 'category']) + .getIn(['content-manager_editPage', 'record', 'category']) expect(category).to.equal(null); }); @@ -420,7 +420,7 @@ describe('Testing Content Manager createPages', function() { .then(pluginStore => { const category = pluginStore .getState() - .getIn(['editPage', 'record', 'category', 'name']) + .getIn(['content-manager_editPage', 'record', 'category', 'name']) expect(category).to.equal('french food'); }) @@ -428,7 +428,7 @@ describe('Testing Content Manager createPages', function() { .then(pluginStore => { const category = pluginStore .getState() - .getIn(['editPage', 'record', 'category', 'name']) + .getIn(['content-manager_editPage', 'record', 'category', 'name']) expect(category).to.equal('french food'); }); @@ -440,4 +440,4 @@ describe('Testing Content Manager createPages', function() { .deleteAllModelData('product', jwt); }); }); -}); \ No newline at end of file +}); diff --git a/packages/strapi-plugin-content-type-builder/admin/src/InjectedComponents/ContentManager/EditViewLink.js b/packages/strapi-plugin-content-type-builder/admin/src/InjectedComponents/ContentManager/EditViewLink.js new file mode 100644 index 0000000000..b1aea77fba --- /dev/null +++ b/packages/strapi-plugin-content-type-builder/admin/src/InjectedComponents/ContentManager/EditViewLink.js @@ -0,0 +1,26 @@ +/** + * + * EditViewLink + * + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import NavLink from 'components/NavLink'; + +// Create link from content-type-builder to content-manager +function EditViewLink(props) { + // Retrieve URL from props + const base = `${props.getContentTypeBuilderBaseUrl()}${props.getModelName()}`; + const url = props.getSource() === 'users-permissions' ? `${base}&source=${props.getSource()}` : base; + + return ; +} + +EditViewLink.propTypes = { + getContentTypeBuilderBaseUrl: PropTypes.func.isRequired, + getModelName: PropTypes.func.isRequired, + getSource: PropTypes.func.isRequired, +}; + +export default EditViewLink; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js index ac8030a6fd..e7849d8748 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js @@ -42,6 +42,7 @@ class AttributeRow extends React.Component { string: IcoString, text: IcoText, integer: IcoNumber, + biginteger: IcoNumber, float: IcoNumber, decimal: IcoNumber, email: IcoEmail, diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenu/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenu/index.js index e960430a13..7eadacc0f5 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenu/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenu/index.js @@ -14,7 +14,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { map } from 'lodash'; -import PluginLeftMenuSection from 'components/PluginLeftMenuSection'; +import PluginLeftMenuSection from '../PluginLeftMenuSection'; import styles from './styles.scss'; class PluginLeftMenu extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenuSection/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenuSection/index.js index 7f80b6012f..85f8e7210b 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenuSection/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/PluginLeftMenuSection/index.js @@ -12,7 +12,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { map } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import PluginLeftMenuLink from 'components/PluginLeftMenuLink'; +import PluginLeftMenuLink from '../PluginLeftMenuLink'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpForm/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpForm/index.js index 824193d82d..5b110054ed 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpForm/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpForm/index.js @@ -10,7 +10,7 @@ import { FormattedMessage } from 'react-intl'; import { get, map, includes, split, isEmpty, findIndex } from 'lodash'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import Input from 'components/InputsIndex'; -import PopUpHeaderNavLink from 'components/PopUpHeaderNavLink'; +import PopUpHeaderNavLink from '../PopUpHeaderNavLink'; import styles from './styles.scss'; /* eslint-disable react/jsx-wrap-multilines */ diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpRelations/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpRelations/index.js index 48b13a7491..9c79570f15 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpRelations/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/PopUpRelations/index.js @@ -12,9 +12,9 @@ import pluralize from 'pluralize'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import Input from 'components/InputsIndex'; -import PopUpHeaderNavLink from 'components/PopUpHeaderNavLink'; -import RelationBox from 'components/RelationBox'; -import RelationNaturePicker from 'components/RelationNaturePicker'; +import PopUpHeaderNavLink from '../PopUpHeaderNavLink'; +import RelationBox from '../RelationBox'; +import RelationNaturePicker from '../RelationNaturePicker'; import styles from './styles.scss'; /* eslint-disable jsx-a11y/tabindex-no-positive */ diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/RelationNaturePicker/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/RelationNaturePicker/index.js index ff5b2442ee..0c2f56be58 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/RelationNaturePicker/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/RelationNaturePicker/index.js @@ -10,8 +10,6 @@ import { map, startCase } from 'lodash'; import pluralize from 'pluralize'; import { FormattedMessage } from 'react-intl'; -import RelationIco from 'components/RelationIco'; - import OneWay from '../../assets/images/one_way.svg'; import OneWaySelected from '../../assets/images/one_way_selected.svg'; import ManyToMany from '../../assets/images/many_to_many.svg'; @@ -23,6 +21,8 @@ import OneToManySelected from '../../assets/images/one_to_many_selected.svg'; import OneToOne from '../../assets/images/one_to_one.svg'; import OneToOneSelected from '../../assets/images/one_to_one_selected.svg'; +import RelationIco from '../RelationIco'; + import styles from './styles.scss'; class RelationNaturePicker extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/TableList/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/TableList/index.js index 959d642bec..442aabcde7 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/TableList/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/TableList/index.js @@ -10,7 +10,7 @@ import { map } from 'lodash'; import { FormattedMessage } from 'react-intl'; import Button from 'components/Button'; -import TableListRow from 'components/TableListRow'; +import TableListRow from '../TableListRow'; import styles from './styles.scss'; class TableList extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/TableListRow/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/TableListRow/index.js index 370944d703..1d1f7fd13e 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/TableListRow/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/TableListRow/index.js @@ -11,8 +11,8 @@ import { FormattedMessage } from 'react-intl'; import IcoContainer from 'components/IcoContainer'; import ListRow from 'components/ListRow'; import PopUpWarning from 'components/PopUpWarning'; -import styles from 'components/TableList/styles.scss'; import { router } from 'app'; +import styles from '../TableList/styles.scss'; /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable react/jsx-curly-brace-presence */ diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/index.js index af53dc9825..b44151a33d 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/index.js @@ -12,24 +12,24 @@ import { bindActionCreators, compose } from 'redux'; import { createStructuredSelector } from 'reselect'; import { Switch, Route, withRouter } from 'react-router-dom'; import PropTypes from 'prop-types'; -import { pluginId } from 'app'; -import HomePage from 'containers/HomePage'; -import ModelPage from 'containers/ModelPage'; -import NotFoundPage from 'containers/NotFoundPage'; -import formSaga from 'containers/Form/sagas'; -import formReducer from 'containers/Form/reducer'; +import pluginId from '../../pluginId'; + +import HomePage from '../HomePage'; +import ModelPage from '../ModelPage'; +import NotFoundPage from '../NotFoundPage'; +import formSaga from '../Form/sagas'; +import formReducer from '../Form/reducer'; // Other containers actions -import { makeSelectShouldRefetchContentType } from 'containers/Form/selectors'; +import { makeSelectShouldRefetchContentType } from '../Form/selectors'; // Utils -import injectSaga from 'utils/injectSaga'; -import injectReducer from 'utils/injectReducer'; import { storeData } from '../../utils/storeData'; import styles from './styles.scss'; import { modelsFetch } from './actions'; +import reducer from './reducer'; import saga from './sagas'; /* eslint-disable consistent-return */ @@ -92,10 +92,13 @@ const mapStateToProps = createStructuredSelector({ }); const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withSaga = injectSaga({ key: 'global', saga }); -const withFormReducer = injectReducer({ key: 'form', reducer: formReducer }); -const withFormSaga = injectSaga({ key: 'form', saga: formSaga }); +const withReducer = strapi.injectReducer({ key: 'global', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'global', saga, pluginId }); +const withFormReducer = strapi.injectReducer({ key: 'form', reducer: formReducer, pluginId }); +const withFormSaga = strapi.injectSaga({ key: 'form', saga: formSaga, pluginId }); + export default compose( + withReducer, withFormReducer, withFormSaga, withSaga, diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/selectors.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/selectors.js index f9b6cb77a8..91e1622b16 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/App/selectors.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/App/selectors.js @@ -1,10 +1,11 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the list state domain */ -const selectGlobalDomain = () => state => state.get('global'); +const selectGlobalDomain = () => state => state.get(`${pluginId}_global`); const makeSelectLoading = () => createSelector( selectGlobalDomain(), diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json index 38d1808991..e526d2b283 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json @@ -259,6 +259,7 @@ "value": "integer", "items": [ { "name": "content-type-builder.form.attribute.item.number.type.integer", "value": "integer" }, + { "name": "content-type-builder.form.attribute.item.number.type.biginteger", "value": "biginteger" }, { "name": "content-type-builder.form.attribute.item.number.type.float", "value": "float" }, { "name": "content-type-builder.form.attribute.item.number.type.decimal", "value": "decimal" } ], diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/index.js index 4d61e66ddd..7dbfd6e0ef 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/index.js @@ -32,13 +32,13 @@ import PropTypes from 'prop-types'; import moment from 'moment'; import { router } from 'app'; -import { temporaryContentTypeFieldsUpdated, storeTemporaryMenu } from 'containers/App/actions'; -import { addAttributeToContentType, addAttributeRelationToContentType, editContentTypeAttribute, editContentTypeAttributeRelation, updateContentType } from 'containers/ModelPage/actions'; +import { temporaryContentTypeFieldsUpdated, storeTemporaryMenu } from '../App/actions'; +import { addAttributeToContentType, addAttributeRelationToContentType, editContentTypeAttribute, editContentTypeAttributeRelation, updateContentType } from '../ModelPage/actions'; -import AttributeCard from 'components/AttributeCard'; -import InputCheckboxWithNestedInputs from 'components/InputCheckboxWithNestedInputs'; -import PopUpForm from 'components/PopUpForm'; -import PopUpRelations from 'components/PopUpRelations'; +import AttributeCard from '../../components/AttributeCard'; +import InputCheckboxWithNestedInputs from '../../components/InputCheckboxWithNestedInputs'; +import PopUpForm from '../../components/PopUpForm'; +import PopUpRelations from '../../components/PopUpRelations'; // Utils import { checkFormValidity } from '../../utils/formValidations'; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/selectors.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/selectors.js index 716acc94f3..5aa0f66979 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/selectors.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the form state domain */ -const selectFormDomain = () => state => state.get('form'); +const selectFormDomain = () => state => state.get(`${pluginId}_form`); /** * Other specific selectors diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/index.js index 2cf75dc960..2d11bceac3 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/index.js @@ -12,19 +12,19 @@ import { size } from 'lodash'; import Helmet from 'react-helmet'; import PropTypes from 'prop-types'; import { router } from 'app'; +import pluginId from '../../pluginId'; -import { makeSelectLoading, makeSelectMenu, makeSelectModels } from 'containers/App/selectors'; -import { deleteContentType } from 'containers/App/actions'; +import { makeSelectLoading, makeSelectMenu, makeSelectModels } from '../App/selectors'; +import { deleteContentType } from '../App/actions'; -import Form from 'containers/Form'; +import Form from '../Form'; // Design -import ContentHeader from 'components/ContentHeader'; -import EmptyContentTypeView from 'components/EmptyContentTypeView'; -import TableList from 'components/TableList'; +import ContentHeader from '../../components/ContentHeader'; +import EmptyContentTypeView from '../../components/EmptyContentTypeView'; +import TableList from '../../components/TableList'; -import injectSaga from 'utils/injectSaga'; -import injectReducer from 'utils/injectReducer'; +// Utils import { storeData } from '../../utils/storeData'; import selectHomePage from './selectors'; @@ -140,8 +140,8 @@ function mapDispatchToProps(dispatch) { } const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'homePage', reducer }); -const withSaga = injectSaga({ key: 'homePage', saga }); +const withReducer = strapi.injectReducer({ key: 'homePage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/selectors.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/selectors.js index 2e0aa89903..04830b5b25 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/selectors.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/HomePage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the homePage state domain */ -const selectHomePageDomain = () => state => state.get('homePage'); +const selectHomePageDomain = () => state => state.get(`${pluginId}_homePage`); /** * Other specific selectors diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js index e2486a91d6..be749f3993 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js @@ -13,18 +13,23 @@ import { FormattedMessage } from 'react-intl'; import { NavLink } from 'react-router-dom'; import PropTypes from 'prop-types'; import { router } from 'app'; -// Global selectors -import { makeSelectMenu } from 'containers/App/selectors'; -import { makeSelectContentTypeUpdated } from 'containers/Form/selectors'; -import AttributeRow from 'components/AttributeRow'; -import ContentHeader from 'components/ContentHeader'; + import EmptyAttributesBlock from 'components/EmptyAttributesBlock'; -import Form from 'containers/Form'; -import List from 'components/List'; -import PluginLeftMenu from 'components/PluginLeftMenu'; -import forms from 'containers/Form/forms.json'; -import injectSaga from 'utils/injectSaga'; -import injectReducer from 'utils/injectReducer'; + +import pluginId from '../../pluginId'; + +import AttributeRow from '../../components/AttributeRow'; +import ContentHeader from '../../components/ContentHeader'; +import List from '../../components/List'; +import PluginLeftMenu from '../../components/PluginLeftMenu'; +import Form from '../Form'; + +import forms from '../Form/forms.json'; + +// Global selectors +import { makeSelectMenu } from '../App/selectors'; +import { makeSelectContentTypeUpdated } from '../Form/selectors'; + import { storeData } from '../../utils/storeData'; import { cancelChanges, @@ -41,7 +46,7 @@ import styles from './styles.scss'; // Array of attributes that the ctb can handle at the moment const availableAttributes = Object.keys(forms.attribute); -availableAttributes.push('integer', 'decimal', 'float'); +availableAttributes.push('integer', 'biginteger', 'decimal', 'float'); /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable react/jsx-wrap-multilines */ @@ -164,6 +169,7 @@ export class ModelPage extends React.Component { // eslint-disable-line react/pr switch (attribute.params.type) { case 'integer': + case 'biginteger': case 'float': case 'decimal': attributeType = 'number'; @@ -355,8 +361,8 @@ function mapDispatchToProps(dispatch) { } const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withSaga = injectSaga({ key: 'modelPage', saga }); -const withReducer = injectReducer({ key: 'modelPage', reducer }); +const withSaga = strapi.injectSaga({ key: 'modelPage', saga, pluginId }); +const withReducer = strapi.injectReducer({ key: 'modelPage', reducer, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js index 0c5dbb00db..cee2a0c40a 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js @@ -1,4 +1,4 @@ -import { LOCATION_CHANGE } from 'react-router-redux'; +// import { LOCATION_CHANGE } from 'react-router-redux'; import { capitalize, cloneDeep, @@ -13,14 +13,22 @@ import { unset, } from 'lodash'; import pluralize from 'pluralize'; -import { takeLatest, call, take, put, fork, cancel, select } from 'redux-saga/effects'; +import { + takeLatest, + call, + // take, + put, + fork, + // cancel, + select, +} from 'redux-saga/effects'; import request from 'utils/request'; -import { temporaryContentTypePosted } from 'containers/App/actions'; - import { storeData } from '../../utils/storeData'; +import { temporaryContentTypePosted } from '../App/actions'; + import { MODEL_FETCH, SUBMIT } from './constants'; import { modelFetchSucceeded, @@ -139,13 +147,18 @@ export function* submitChanges(action) { } function* defaultSaga() { - const loadModelWatcher = yield fork(takeLatest, MODEL_FETCH, fetchModel); - const loadSubmitChanges = yield fork(takeLatest, SUBMIT, submitChanges); + yield fork(takeLatest, MODEL_FETCH, fetchModel); + yield fork(takeLatest, SUBMIT, submitChanges); - yield take(LOCATION_CHANGE); + // TODO fix Router (Other PR); + + // const loadModelWatcher = yield fork(takeLatest, MODEL_FETCH, fetchModel); + // const loadSubmitChanges = yield fork(takeLatest, SUBMIT, submitChanges); - yield cancel(loadModelWatcher); - yield cancel(loadSubmitChanges); + // yield take(LOCATION_CHANGE); + + // yield cancel(loadModelWatcher); + // yield cancel(loadSubmitChanges); } export default defaultSaga; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/selectors.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/selectors.js index 908ebfecb6..0980be8207 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/selectors.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the modelPage state domain */ -const selectModelPageDomain = () => state => state.get('modelPage'); +const selectModelPageDomain = () => state => state.get(`${pluginId}_modelPage`); /** * Other specific selectors diff --git a/packages/strapi-plugin-content-type-builder/admin/src/injectedComponents.js b/packages/strapi-plugin-content-type-builder/admin/src/injectedComponents.js index 109fa8b38c..38447d36dc 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/injectedComponents.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/injectedComponents.js @@ -1 +1,16 @@ -export default []; \ No newline at end of file +import Link from './InjectedComponents/ContentManager/EditViewLink'; + +export default [ + { + plugin: 'content-manager.editPage', + area: 'right.links', + component: Link, + key: 'content-type-builder.link', + props: { + message: { + id: 'content-manager.containers.Edit.Link.Fields', + }, + icon: 'fa-cog', + }, + }, +]; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/pluginId.js b/packages/strapi-plugin-content-type-builder/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-plugin-content-type-builder/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/routes.json b/packages/strapi-plugin-content-type-builder/admin/src/routes.json deleted file mode 100644 index dea2205e9a..0000000000 --- a/packages/strapi-plugin-content-type-builder/admin/src/routes.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "/": { - "name": "homePage", - "container": "HomePage" - }, - "/models/:modelName": { - "name": "modelPage", - "container": "ModelPage" - } -} diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json index 9f18df4e65..2239d410f4 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json @@ -7,6 +7,7 @@ "attribute.enumeration": "Enumeration", "attribute.float": "Float", "attribute.integer": "integer", + "attribute.biginteger": "big integer", "attribute.json": "JSON", "attribute.media": "Media", "attribute.password": "Password", @@ -54,6 +55,7 @@ "form.attribute.item.number.type.decimal": "decimal (ex: 2.22)", "form.attribute.item.number.type.float": "float (ex: 3.33333333)", "form.attribute.item.number.type.integer": "integer (ex: 10)", + "form.attribute.item.number.type.biginteger": "big integer (ex: 123456789)", "form.attribute.item.requiredField": "Required field", "form.attribute.item.requiredField.description": "You won't be able to create an entry if this field is empty", "form.attribute.item.settings.name": "Settings", diff --git a/packages/strapi-plugin-content-type-builder/package.json b/packages/strapi-plugin-content-type-builder/package.json index 2ea35ec0b5..3606d22118 100644 --- a/packages/strapi-plugin-content-type-builder/package.json +++ b/packages/strapi-plugin-content-type-builder/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-content-type-builder", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Strapi plugin to create content type (API).", "strapi": { "name": "Content Type Builder", @@ -8,15 +8,15 @@ "description": "content-type-builder.plugin.description" }, "scripts": { - "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", + "analyze:clean": "cross-env rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/lib/server", - "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "cross-env rimraf admin/build", + "start": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/lib/server", + "generate": "node ./node_modules/plop/plop.js --plopfile node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "echo \"Error: no test specified\"", "prepublishOnly": "IS_MONOREPO=true npm run build" @@ -24,11 +24,11 @@ "dependencies": { "immutable": "^3.8.2", "pluralize": "^7.0.0", - "strapi-generate": "3.0.0-alpha.23.1", - "strapi-generate-api": "3.0.0-alpha.23.1" + "strapi-generate": "3.0.0-alpha.24.1", + "strapi-generate-api": "3.0.0-alpha.24.1" }, "devDependencies": { - "strapi-helper-plugin": "3.0.0-alpha.23.1" + "strapi-helper-plugin": "3.0.0-alpha.24.1" }, "author": { "name": "Strapi team", diff --git a/packages/strapi-plugin-content-type-builder/test/front/integration/createApi_specs.js b/packages/strapi-plugin-content-type-builder/test/front/integration/createApi_specs.js index 5611fc04be..412eca6ce7 100644 --- a/packages/strapi-plugin-content-type-builder/test/front/integration/createApi_specs.js +++ b/packages/strapi-plugin-content-type-builder/test/front/integration/createApi_specs.js @@ -167,11 +167,11 @@ describe('Test CTB', () => { cy.window() .its('__store__') - .its('content-manager') + .its('store') .then(pluginStore => { const displayedFields = pluginStore .getState() - .getIn(['global', 'schema', 'models', 'product', 'editDisplay', 'fields']) + .getIn(['content-manager_global', 'schema', 'models', 'product', 'editDisplay', 'fields']) .toJS(); expect(displayedFields).to.include.members([ diff --git a/packages/strapi-plugin-content-type-builder/utils/Manager.js b/packages/strapi-plugin-content-type-builder/utils/Manager.js index 662d0e1d85..99e85579d0 100644 --- a/packages/strapi-plugin-content-type-builder/utils/Manager.js +++ b/packages/strapi-plugin-content-type-builder/utils/Manager.js @@ -88,10 +88,10 @@ class Manager { case 'checkbox': case 'boolean': case 'date': - case 'bigint': case 'decimal': case 'float': case 'integer': + case 'biginteger': case 'number': return 4; case 'json': @@ -250,4 +250,4 @@ class Manager { } } -module.exports = Manager; \ No newline at end of file +module.exports = Manager; diff --git a/packages/strapi-plugin-documentation/admin/src/components/Row/ButtonContainer.js b/packages/strapi-plugin-documentation/admin/src/components/Row/ButtonContainer.js index 0bdb656d78..1a5c98c67c 100755 --- a/packages/strapi-plugin-documentation/admin/src/components/Row/ButtonContainer.js +++ b/packages/strapi-plugin-documentation/admin/src/components/Row/ButtonContainer.js @@ -2,8 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import cn from 'classnames'; + import Button from 'components/Button'; -import openWithNewTab from 'utils/openWithNewTab'; +import openWithNewTab from '../../utils/openWithNewTab'; import styles from './styles.scss'; const ButtonContainer = ({ currentDocVersion, isHeader, onClick, onClickDelete, version }) => { @@ -42,4 +43,4 @@ ButtonContainer.propTypes = { version: PropTypes.string, }; -export default ButtonContainer; \ No newline at end of file +export default ButtonContainer; diff --git a/packages/strapi-plugin-documentation/admin/src/containers/App/actions.js b/packages/strapi-plugin-documentation/admin/src/containers/App/actions.js deleted file mode 100755 index a5002ad023..0000000000 --- a/packages/strapi-plugin-documentation/admin/src/containers/App/actions.js +++ /dev/null @@ -1,5 +0,0 @@ -/* - * - * App actions - * - */ diff --git a/packages/strapi-plugin-documentation/admin/src/containers/App/constants.js b/packages/strapi-plugin-documentation/admin/src/containers/App/constants.js deleted file mode 100755 index f62c609507..0000000000 --- a/packages/strapi-plugin-documentation/admin/src/containers/App/constants.js +++ /dev/null @@ -1,5 +0,0 @@ -/* - * - * App constants - * - */ diff --git a/packages/strapi-plugin-documentation/admin/src/containers/App/index.js b/packages/strapi-plugin-documentation/admin/src/containers/App/index.js index 724b9fd864..15f97bd26c 100755 --- a/packages/strapi-plugin-documentation/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-documentation/admin/src/containers/App/index.js @@ -6,41 +6,22 @@ */ import React from 'react'; -import { connect } from 'react-redux'; -import { createStructuredSelector } from 'reselect'; import { Switch, Route } from 'react-router-dom'; -import { bindActionCreators, compose } from 'redux'; // Utils -import { pluginId } from 'app'; +import pluginId from '../../pluginId'; // Containers -import HomePage from 'containers/HomePage'; -import NotFoundPage from 'containers/NotFoundPage'; +import HomePage from '../HomePage'; +import NotFoundPage from '../NotFoundPage'; -class App extends React.Component { - render() { - return ( -
    - - - - -
    - ); - } +function App() { + return ( +
    + + + + +
    + ); } -App.propTypes = {}; - -export function mapDispatchToProps(dispatch) { - return bindActionCreators({}, dispatch); -} - -const mapStateToProps = createStructuredSelector({}); - -// Wrap the component to inject dispatch and state into it -const withConnect = connect( - mapStateToProps, - mapDispatchToProps, -); - -export default compose(withConnect)(App); +export default App; diff --git a/packages/strapi-plugin-documentation/admin/src/containers/App/reducer.js b/packages/strapi-plugin-documentation/admin/src/containers/App/reducer.js deleted file mode 100755 index 38026c39cd..0000000000 --- a/packages/strapi-plugin-documentation/admin/src/containers/App/reducer.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * - * App reducer - * - */ - -import { fromJS } from 'immutable'; - -const initialState = fromJS({}); - -function appReducer(state = initialState, action) { - switch (action.type) { - default: - return state; - } -} - -export default appReducer; diff --git a/packages/strapi-plugin-documentation/admin/src/containers/App/selectors.js b/packages/strapi-plugin-documentation/admin/src/containers/App/selectors.js deleted file mode 100755 index 2393a073cd..0000000000 --- a/packages/strapi-plugin-documentation/admin/src/containers/App/selectors.js +++ /dev/null @@ -1,9 +0,0 @@ -// import { createSelector } from 'reselect'; - -/** - * Direct selector to the list state domain - */ - -// const selectGlobalDomain = () => state => state.get('global'); - -export {}; diff --git a/packages/strapi-plugin-documentation/admin/src/containers/HomePage/index.js b/packages/strapi-plugin-documentation/admin/src/containers/HomePage/index.js index f32711a7d3..5015a2044e 100755 --- a/packages/strapi-plugin-documentation/admin/src/containers/HomePage/index.js +++ b/packages/strapi-plugin-documentation/admin/src/containers/HomePage/index.js @@ -12,19 +12,23 @@ import { CopyToClipboard } from 'react-copy-to-clipboard'; import { bindActionCreators, compose } from 'redux'; import { get, isEmpty } from 'lodash'; import cn from 'classnames'; + // Components import PluginHeader from 'components/PluginHeader'; import PopUpWarning from 'components/PopUpWarning'; -import Block from 'components/Block'; -import Row from 'components/Row'; import LoadingIndicatorPage from 'components/LoadingIndicatorPage'; import Input from 'components/InputsIndex'; -import { pluginId } from 'app'; + // Utils import auth from 'utils/auth'; -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; -import openWithNewTab from 'utils/openWithNewTab'; + +import pluginId from '../../pluginId'; + +import Block from '../../components/Block'; +import Row from '../../components/Row'; + +import openWithNewTab from '../../utils/openWithNewTab'; + // Actions import { getDocInfos, @@ -245,8 +249,8 @@ const withConnect = connect( mapStateToProps, mapDispatchToProps, ); -const withReducer = injectReducer({ key: 'homePage', reducer }); -const withSaga = injectSaga({ key: 'homePage', saga }); +const withReducer = strapi.injectReducer({ key: 'homePage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-documentation/admin/src/containers/HomePage/saga.js b/packages/strapi-plugin-documentation/admin/src/containers/HomePage/saga.js index 7f76f2129b..bcb8eabeef 100755 --- a/packages/strapi-plugin-documentation/admin/src/containers/HomePage/saga.js +++ b/packages/strapi-plugin-documentation/admin/src/containers/HomePage/saga.js @@ -47,7 +47,7 @@ function* submit() { }, init); }; const body = createBody(cloneDeep(form)); - console.log({ form, body }); + if (body.restrictedAccess && body.password === '') { return yield put( setFormErrors({ password: [{ id: 'components.Input.error.validation.required' }] }), diff --git a/packages/strapi-plugin-documentation/admin/src/containers/HomePage/selectors.js b/packages/strapi-plugin-documentation/admin/src/containers/HomePage/selectors.js index 9230835001..08b848bb45 100755 --- a/packages/strapi-plugin-documentation/admin/src/containers/HomePage/selectors.js +++ b/packages/strapi-plugin-documentation/admin/src/containers/HomePage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the homePage state domain */ -const selectHomePageDomain = () => state => state.get('homePage'); +const selectHomePageDomain = () => state => state.get(`${pluginId}_homePage`); /** * Default selector used by HomePage @@ -30,4 +31,4 @@ const makeSelectVersionToDelete = () => createSelector( ); export default selectHomePage; -export { makeSelectForm, makeSelectVersionToDelete, makeSelectPrefix }; \ No newline at end of file +export { makeSelectForm, makeSelectVersionToDelete, makeSelectPrefix }; diff --git a/packages/strapi-plugin-documentation/admin/src/pluginId.js b/packages/strapi-plugin-documentation/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-plugin-documentation/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-plugin-documentation/package.json b/packages/strapi-plugin-documentation/package.json index f2bc48d4b3..a35b59a298 100755 --- a/packages/strapi-plugin-documentation/package.json +++ b/packages/strapi-plugin-documentation/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-documentation", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "This is the description of the plugin.", "strapi": { "name": "Documentation", @@ -8,15 +8,15 @@ "description": "Create an OpenAPI Document and visualize your API with SWAGGER UI." }, "scripts": { - "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", + "analyze:clean": "rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/lib/server", - "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "rimraf admin/build", + "start": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/lib/server", + "generate": "node ./node_modules/plop/plop.js --plopfile node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "lint": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/eslint --ignore-path .gitignore --ignore-pattern '/admin/build/' --config ./node_modules/strapi-helper-plugin/lib/internals/eslint/.eslintrc.json admin", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "npm run lint", @@ -29,7 +29,9 @@ "swagger-ui-dist": "^3.18.3-republish2" }, "devDependencies": { - "strapi-helper-plugin": "3.0.0-alpha.23.1" + "cross-env": "^5.2.0", + "rimraf": "^2.6.3", + "strapi-helper-plugin": "3.0.0-alpha.24.1" }, "author": { "name": "soupette", diff --git a/packages/strapi-plugin-documentation/services/Documentation.js b/packages/strapi-plugin-documentation/services/Documentation.js index 2291b70533..189aef6baa 100755 --- a/packages/strapi-plugin-documentation/services/Documentation.js +++ b/packages/strapi-plugin-documentation/services/Documentation.js @@ -514,7 +514,7 @@ module.exports = { const getter = currentAssociation.plugin !== undefined ? ['plugins', currentAssociation.plugin, 'models', name, 'attributes'] - : ['models', name, 'attributes']; + : ['models', name.toLowerCase(), 'attributes']; const associationAttributes = _.get(strapi, getter); const associationSchema = this.generateAssociationSchema(associationAttributes, getter); @@ -1313,6 +1313,7 @@ module.exports = { case 'double': return 'number'; case 'integer': + case 'biginteger': case 'long': return 'integer'; default: diff --git a/packages/strapi-plugin-email/admin/src/containers/App/index.js b/packages/strapi-plugin-email/admin/src/containers/App/index.js index 2c1fcd23b4..5f3cadd4e9 100644 --- a/packages/strapi-plugin-email/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-email/admin/src/containers/App/index.js @@ -8,11 +8,10 @@ import React from 'react'; import { Switch, Route } from 'react-router-dom'; -// Utils -import { pluginId } from 'app'; +import pluginId from '../../pluginId'; // Containers -import ConfigPage from 'containers/ConfigPage'; +import ConfigPage from '../ConfigPage'; function App() { return ( diff --git a/packages/strapi-plugin-email/admin/src/containers/App/reducer.js b/packages/strapi-plugin-email/admin/src/containers/App/reducer.js deleted file mode 100644 index 38026c39cd..0000000000 --- a/packages/strapi-plugin-email/admin/src/containers/App/reducer.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * - * App reducer - * - */ - -import { fromJS } from 'immutable'; - -const initialState = fromJS({}); - -function appReducer(state = initialState, action) { - switch (action.type) { - default: - return state; - } -} - -export default appReducer; diff --git a/packages/strapi-plugin-email/admin/src/containers/App/selectors.js b/packages/strapi-plugin-email/admin/src/containers/App/selectors.js deleted file mode 100644 index 2393a073cd..0000000000 --- a/packages/strapi-plugin-email/admin/src/containers/App/selectors.js +++ /dev/null @@ -1,9 +0,0 @@ -// import { createSelector } from 'reselect'; - -/** - * Direct selector to the list state domain - */ - -// const selectGlobalDomain = () => state => state.get('global'); - -export {}; diff --git a/packages/strapi-plugin-email/admin/src/containers/ConfigPage/index.js b/packages/strapi-plugin-email/admin/src/containers/ConfigPage/index.js index 1c6e4f2e1a..c7ca5dbf5d 100644 --- a/packages/strapi-plugin-email/admin/src/containers/ConfigPage/index.js +++ b/packages/strapi-plugin-email/admin/src/containers/ConfigPage/index.js @@ -17,14 +17,10 @@ import ContainerFluid from 'components/ContainerFluid'; import HeaderNav from 'components/HeaderNav'; import PluginHeader from 'components/PluginHeader'; -// Plugin's components -import EditForm from 'components/EditForm'; +import pluginId from '../../pluginId'; -// You can find these utils in either -// ./node_modules/strapi-helper-plugin/lib/src -// or strapi/packages/strapi-helper-plugin/lib/src -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; +// Plugin's components +import EditForm from '../../components/EditForm'; import { getSettings, @@ -180,8 +176,8 @@ const mapStateToProps = selectConfigPage(); const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'configPage', reducer }); -const withSaga = injectSaga({ key: 'configPage', saga }); +const withReducer = strapi.injectReducer({ key: 'configPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'configPage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-email/admin/src/containers/ConfigPage/selectors.js b/packages/strapi-plugin-email/admin/src/containers/ConfigPage/selectors.js index 57fc3910e6..2659d39aa5 100644 --- a/packages/strapi-plugin-email/admin/src/containers/ConfigPage/selectors.js +++ b/packages/strapi-plugin-email/admin/src/containers/ConfigPage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the configPage state domain */ -const selectConfigPageDomain = () => state => state.get('configPage'); +const selectConfigPageDomain = () => state => state.get(`${pluginId}_configPage`); /** * Default selector used by ConfigPage diff --git a/packages/strapi-plugin-email/admin/src/pluginId.js b/packages/strapi-plugin-email/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-plugin-email/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-plugin-email/config/functions/bootstrap.js b/packages/strapi-plugin-email/config/functions/bootstrap.js index fa2b34617b..7fb453ac7d 100644 --- a/packages/strapi-plugin-email/config/functions/bootstrap.js +++ b/packages/strapi-plugin-email/config/functions/bootstrap.js @@ -30,6 +30,20 @@ module.exports = async cb => { return _.startsWith(node_module, 'strapi-provider-email') || _.startsWith(node_module, 'strapi-email'); }); + node_modules.filter((node_module) => { + return node_module.startsWith('@'); + }) + .forEach((orga) => { + const node_modules = fs.readdirSync(path.join(basePath, 'node_modules', orga)); + + node_modules.forEach((node_module) => { + // DEPRECATED strapi-email-* will be remove in next version + if (_.startsWith(node_module, 'strapi-provider-email') || _.startsWith(node_module, 'strapi-email')) { + emails.push(`${orga}/${node_module}`); + } + }); + }); + // mount all providers to get configs _.forEach(emails, (node_module) => { strapi.plugins.email.config.providers.push( diff --git a/packages/strapi-plugin-email/package.json b/packages/strapi-plugin-email/package.json index e78a046bff..fd1f722587 100644 --- a/packages/strapi-plugin-email/package.json +++ b/packages/strapi-plugin-email/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-email", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "This is the description of the plugin.", "strapi": { "name": "Email", @@ -8,25 +8,26 @@ "description": "email.plugin.description" }, "scripts": { - "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", + "analyze:clean": "rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/lib/server", - "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "rimraf admin/build", + "start": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/lib/server", + "generate": "node ./node_modules/plop/plop.js --plopfile node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "echo \"Error: no test specified\"", "prepublishOnly": "IS_MONOREPO=true npm run build" }, "dependencies": { - "strapi-provider-email-sendmail": "3.0.0-alpha.23.1" + "strapi-provider-email-sendmail": "3.0.0-alpha.24.1" }, "devDependencies": { "react-copy-to-clipboard": "5.0.1", - "strapi-helper-plugin": "3.0.0-alpha.23.1" + "rimraf": "^2.6.3", + "strapi-helper-plugin": "3.0.0-alpha.24.1" }, "author": { "name": "Strapi team", diff --git a/packages/strapi-plugin-graphql/package.json b/packages/strapi-plugin-graphql/package.json index 4c62ecaacc..5729cb670f 100644 --- a/packages/strapi-plugin-graphql/package.json +++ b/packages/strapi-plugin-graphql/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-graphql", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "This is the description of the plugin.", "strapi": { "name": "graphql", @@ -8,15 +8,15 @@ "description": "Description of graphql plugin." }, "scripts": { - "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", + "analyze:clean": "rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean && npm run test", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/lib/server", - "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "rimraf admin/build", + "start": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/lib/server", + "generate": "node ./node_modules/plop/plop.js --plopfile node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "echo \"Error: no test specified\"" }, @@ -24,14 +24,18 @@ "apollo-server-koa": "^2.0.7", "dataloader": "^1.4.0", "glob": "^7.1.3", - "graphql": "^14.0.2", + "graphql": "^14.1.0", "graphql-depth-limit": "^1.1.0", "graphql-playground-middleware-koa": "^1.6.4", "graphql-tools": "^3.1.1", "graphql-type-datetime": "^0.2.2", "graphql-type-json": "^0.2.1", "pluralize": "^7.0.0", - "strapi-utils": "3.0.0-alpha.23.1" + "strapi-utils": "3.0.0-alpha.24.1" + }, + "devDependencies": { + "cross-env": "^5.2.0", + "rimraf": "^2.6.3" }, "author": { "name": "A Strapi developer", @@ -50,4 +54,4 @@ "npm": ">= 6.0.0" }, "license": "MIT" -} \ No newline at end of file +} diff --git a/packages/strapi-plugin-graphql/services/Query.js b/packages/strapi-plugin-graphql/services/Query.js index e4804b7784..48332cbbe9 100644 --- a/packages/strapi-plugin-graphql/services/Query.js +++ b/packages/strapi-plugin-graphql/services/Query.js @@ -19,10 +19,12 @@ module.exports = { * @return Object */ - convertToParams: params => { + convertToParams: (params, primaryKey) => { return Object.keys(params).reduce((acc, current) => { return Object.assign(acc, { - [`_${current}`]: params[current], + [`${ + primaryKey === current || "id" === current ? "" : "_" + }${current}`]: params[current] }); }, {}); }, @@ -260,7 +262,7 @@ module.exports = { Object.defineProperties(ctx, { query: { value: { - ...this.convertToParams(_.omit(_options, 'where')), + ...this.convertToParams(_.omit(_options, 'where'), model.primaryKey), ..._options.where, // Avoid population. _populate: model.associations.filter(a => !a.dominant && _.isEmpty(a.model)).map(a => a.alias), @@ -269,7 +271,7 @@ module.exports = { configurable: true }, params: { - value: this.convertToParams(this.amountLimiting(_options)), + value: this.convertToParams(this.amountLimiting(_options), model.primaryKey), writable: true, configurable: true } diff --git a/packages/strapi-plugin-graphql/services/Types.js b/packages/strapi-plugin-graphql/services/Types.js index 2e1e5f9834..7ccfdc2abf 100644 --- a/packages/strapi-plugin-graphql/services/Types.js +++ b/packages/strapi-plugin-graphql/services/Types.js @@ -41,6 +41,7 @@ module.exports = { type = 'Boolean'; break; case 'integer': + case 'biginteger': type = 'Int'; break; case 'decimal': diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/EditForm/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/EditForm/index.js index 4da4ec28dd..8c050f85e2 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/EditForm/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/EditForm/index.js @@ -8,8 +8,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { map } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import Button from 'components/Button'; -import EditFormSection from 'components/EditFormSection'; +import Button from '../Button'; +import EditFormSection from '../EditFormSection'; import styles from './styles.scss'; /* eslint-disable react/require-default-props */ diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSection/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSection/index.js index e23a14cde4..cbbffa216f 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSection/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSection/index.js @@ -9,9 +9,9 @@ import PropTypes from 'prop-types'; import { map, isEmpty } from 'lodash'; import { FormattedMessage } from 'react-intl'; // HOC Form -import WithFormSection from 'components/WithFormSection'; +import WithFormSection from '../WithFormSection'; // nested form -import EditFormSectionNested from 'components/EditFormSectionNested'; +import EditFormSectionNested from '../EditFormSectionNested'; /* eslint-disable react/require-default-props */ class EditFormSection extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionNested/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionNested/index.js index 3454b3da21..c9f8bf6c24 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionNested/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionNested/index.js @@ -9,8 +9,8 @@ import PropTypes from 'prop-types'; import { has, map, forEach } from 'lodash'; // HOC -import EditFormSectionSubNested from 'components/EditFormSectionSubNested'; -import WithFormSection from 'components/WithFormSection'; +import EditFormSectionSubNested from '../EditFormSectionSubNested'; +import WithFormSection from '../WithFormSection'; /* eslint-disable react/require-default-props */ class EditFormSectionNested extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionSubNested/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionSubNested/index.js index 5693f58a1f..d1d47846d4 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionSubNested/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/EditFormSectionSubNested/index.js @@ -7,7 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { map } from 'lodash'; -import WithFormSection from 'components/WithFormSection'; +import WithFormSection from '../WithFormSection'; /* eslint-disable react/require-default-props */ class EditFormSectionSubNested extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/HeaderNav/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/HeaderNav/index.js index 7c7912ca6d..e2065e7f76 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/HeaderNav/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/HeaderNav/index.js @@ -8,9 +8,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { NavLink } from 'react-router-dom'; import { join, map, take } from 'lodash'; -import EditForm from 'components/EditForm'; -import List from 'components/List'; + import { darken } from '../../utils/colors'; + +import EditForm from '../EditForm'; +import List from '../List'; import styles from './styles.scss'; /* eslint-disable react/require-default-props */ diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/InputNumber/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/InputNumber/index.js index ecc2e7cd47..a263c53f83 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/InputNumber/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/InputNumber/index.js @@ -31,7 +31,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { isEmpty, includes, map, mapKeys, isObject, reject, union, uniqBy } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import WithInput from 'components/WithInput'; +import WithInput from '../WithInput'; /* eslint-disable react/require-default-props */ class InputNumber extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/InputPassword/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/InputPassword/index.js index 44b930c844..cfaa6689a4 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/InputPassword/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/InputPassword/index.js @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { isEmpty, includes, mapKeys, reject, map, isObject, size } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import WithInput from 'components/WithInput'; +import WithInput from '../WithInput'; /* eslint-disable react/require-default-props */ class InputPassword extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/InputText/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/InputText/index.js index 84a18a2f46..a4109884bb 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/InputText/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/InputText/index.js @@ -31,7 +31,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { isEmpty, includes, mapKeys, reject, map, isObject, union, findIndex, uniqBy, size } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import WithInput from 'components/WithInput'; +import WithInput from '../WithInput'; /* eslint-disable react/require-default-props */ class InputText extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/List/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/List/index.js index d1e3ac1b87..098ebc311d 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/List/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/List/index.js @@ -21,8 +21,8 @@ import { map } from 'lodash'; import { FormattedMessage } from 'react-intl'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -import ButtonPrimaryHotline from 'components/Button'; -import PopUpForm from 'components/PopUpForm'; +import ButtonPrimaryHotline from '../Button'; +import PopUpForm from '../PopUpForm'; import styles from './styles.scss'; /* eslint-disable react/require-default-props */ diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenu/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenu/index.js index 6067240221..b6cdade1be 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenu/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenu/index.js @@ -7,7 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { map } from 'lodash'; -import PluginLeftMenuSection from 'components/PluginLeftMenuSection'; +import PluginLeftMenuSection from '../PluginLeftMenuSection'; import styles from './styles.scss'; class PluginLeftMenu extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenuSection/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenuSection/index.js index 32df106f89..8b9a665270 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenuSection/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/PluginLeftMenuSection/index.js @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { map } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import PluginLeftMenuLink from 'components/PluginLeftMenuLink'; +import PluginLeftMenuLink from '../PluginLeftMenuLink'; import styles from './styles.scss'; /* eslint-disable react/require-default-props */ diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/PopUpForm/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/PopUpForm/index.js index e97874cd39..64119720fc 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/PopUpForm/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/PopUpForm/index.js @@ -7,7 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { map } from 'lodash'; -import WithFormSection from 'components/WithFormSection'; +import WithFormSection from '../WithFormSection'; import styles from './styles.scss'; /* eslint-disable react/require-default-props */ diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/RowDatabase/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/RowDatabase/index.js index 6fc724193f..36363783b1 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/RowDatabase/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/RowDatabase/index.js @@ -10,9 +10,10 @@ import { FormattedMessage } from 'react-intl'; // modal import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; -import PopUpForm from 'components/PopUpForm'; import PopUpWarning from 'components/PopUpWarning'; -import styles from 'components/List/styles.scss'; + +import PopUpForm from '../PopUpForm'; +import styles from '../List/styles.scss'; /* eslint-disable react/require-default-props */ class RowDatabase extends React.Component { // eslint-disable-line react/prefer-stateless-function diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/RowLanguage/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/RowLanguage/index.js index 1103df5559..e5400484db 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/RowLanguage/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/RowLanguage/index.js @@ -8,10 +8,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { find, get, join, isObject } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import PopUpWarning from 'components/PopUpWarning'; + // utils import getFlag, { formatLanguageLocale } from '../../utils/getFlag'; +import PopUpWarning from 'components/PopUpWarning'; + /* eslint-disable react/require-default-props */ class RowLanguage extends React.Component { // eslint-disable-line react/prefer-stateless-function constructor(props) { diff --git a/packages/strapi-plugin-settings-manager/admin/src/components/WithFormSection/index.js b/packages/strapi-plugin-settings-manager/admin/src/components/WithFormSection/index.js index ba76b82c07..f90e955026 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/components/WithFormSection/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/components/WithFormSection/index.js @@ -8,12 +8,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { findIndex, forEach, has, isObject , join, pullAt, split, includes} from 'lodash'; -import InputNumber from 'components/InputNumber'; -import InputText from 'components/InputText'; -import InputToggle from 'components/InputToggle'; -import InputPassword from 'components/InputPassword'; -import InputSelect from 'components/InputSelect'; -import InputEnum from 'components/InputEnum'; +import InputNumber from '../InputNumber'; +import InputText from '../InputText'; +import InputToggle from '../InputToggle'; +import InputPassword from '../InputPassword'; +import InputSelect from '../InputSelect'; +import InputEnum from '../InputEnum'; import config from './config.json'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-settings-manager/admin/src/containers/App/index.js b/packages/strapi-plugin-settings-manager/admin/src/containers/App/index.js index 4df01e3935..86538147a1 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/containers/App/index.js @@ -14,16 +14,16 @@ import 'flag-icon-css/css/flag-icon.css'; import 'react-select/dist/react-select.css'; import { Switch, Route } from 'react-router-dom'; import { isEmpty } from 'lodash'; -import { pluginId } from 'app'; -import injectSaga from 'utils/injectSaga'; +import pluginId from '../../pluginId'; -import HomePage from 'containers/HomePage'; +import HomePage from '../HomePage'; import { menuFetch, environmentsFetch } from './actions'; import { makeSelectLoading, makeSelectSections } from './selectors'; import styles from './styles.scss'; +import reducer from './reducer'; import saga from './sagas'; /* eslint-disable react/require-default-props */ @@ -95,9 +95,11 @@ const mapStateToProps = createStructuredSelector({ // Wrap the component to inject dispatch and state into it const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withSaga = injectSaga({ key: 'global', saga }); +const withReducer = strapi.injectReducer({ key: 'global', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'global', saga, pluginId }); export default compose( + withReducer, withSaga, withConnect, )(App); diff --git a/packages/strapi-plugin-settings-manager/admin/src/containers/App/selectors.js b/packages/strapi-plugin-settings-manager/admin/src/containers/App/selectors.js index d254d456c6..943115ca07 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/containers/App/selectors.js +++ b/packages/strapi-plugin-settings-manager/admin/src/containers/App/selectors.js @@ -1,10 +1,11 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the list state domain */ -const selectGlobalDomain = () => state => state.get('global'); +const selectGlobalDomain = () => state => state.get(`${pluginId}_global`); const selectLocationState = () => { let prevRoutingState; diff --git a/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/index.js b/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/index.js index 25073ec930..801dc6f58b 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/index.js +++ b/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/index.js @@ -9,7 +9,6 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { bindActionCreators, compose } from 'redux'; import { createStructuredSelector } from 'reselect'; - import { endsWith, find, @@ -30,27 +29,25 @@ import Helmet from 'react-helmet'; import Select from 'react-select'; import { router } from 'app'; +import pluginId from '../../pluginId'; // design -import ContentHeader from 'components/ContentHeader'; -import EditForm from 'components/EditForm'; -import HeaderNav from 'components/HeaderNav'; -import List from 'components/List'; -import RowDatabase from 'components/RowDatabase'; -import SelectOptionLanguage from 'components/SelectOptionLanguage'; -import RowLanguage from 'components/RowLanguage'; -import PluginLeftMenu from 'components/PluginLeftMenu'; - -// App selectors -import { makeSelectSections, makeSelectEnvironments } from 'containers/App/selectors'; +import ContentHeader from '../../components/ContentHeader'; +import EditForm from '../../components/EditForm'; +import HeaderNav from '../../components/HeaderNav'; +import List from '../../components/List'; +import RowDatabase from '../../components/RowDatabase'; +import SelectOptionLanguage from '../../components/SelectOptionLanguage'; +import RowLanguage from '../../components/RowLanguage'; +import PluginLeftMenu from '../../components/PluginLeftMenu'; // utils import unknowFlag from 'assets/images/unknow_flag.png'; -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; import supportedFlags from 'utils/supportedFlags.json'; import { checkFormValidity, getRequiredInputsDb } from '../../utils/inputValidations'; import getFlag, { formatLanguageLocale } from '../../utils/getFlag'; import sendUpdatedParams from '../../utils/sendUpdatedParams'; +// App selectors +import { makeSelectSections, makeSelectEnvironments } from '../App/selectors'; import selectHomePage from './selectors'; import { cancelChanges, @@ -564,8 +561,8 @@ HomePage.propTypes = { const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'homePage', reducer }); -const withSaga = injectSaga({ key: 'homePage', saga }); +const withReducer = strapi.injectReducer({ key: 'homePage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/sagas.js b/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/sagas.js index a325f8cc3d..ee1d6b7d66 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/sagas.js +++ b/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/sagas.js @@ -1,6 +1,15 @@ -import { LOCATION_CHANGE } from 'react-router-redux'; +// import { LOCATION_CHANGE } from 'react-router-redux'; import { forEach, set, map, replace } from 'lodash'; -import { all, call, take, put, fork, cancel, select, takeLatest } from 'redux-saga/effects'; +import { + all, + call, + // take, + put, + fork, + // cancel, + select, + takeLatest, +} from 'redux-saga/effects'; import request from 'utils/request'; // selectors import { makeSelectModifiedData } from './selectors'; @@ -240,28 +249,40 @@ export function* fetchSpecificDatabase(action) { // Individual exports for testing export function* defaultSaga() { - const loadConfigWatcher = yield fork(takeLatest, CONFIG_FETCH, fetchConfig); - const loadLanguagesWatcher = yield fork(takeLatest, LANGUAGES_FETCH, fetchLanguages); - const editConfigWatcher = yield fork(takeLatest, EDIT_SETTINGS, settingsEdit); - const postLanguageWatcher = yield fork(takeLatest, NEW_LANGUAGE_POST, postLanguage); - const deleteLanguageWatcher = yield fork(takeLatest, LANGUAGE_DELETE, deleteLanguage); - const loadDatabasesWatcher = yield fork(takeLatest, DATABASES_FETCH, fetchDatabases); - const postDatabaseWatcher = yield fork(takeLatest, NEW_DATABASE_POST, postDatabase); - const deleteDatabaseWatcher = yield fork(takeLatest, DATABASE_DELETE, deleteDatabase); - const fetchSpecificDatabaseWatcher = yield fork(takeLatest, SPECIFIC_DATABASE_FETCH, fetchSpecificDatabase); - const editDatabaseWatcher = yield fork(takeLatest, DATABASE_EDIT, editDatabase); + yield fork(takeLatest, CONFIG_FETCH, fetchConfig); + yield fork(takeLatest, LANGUAGES_FETCH, fetchLanguages); + yield fork(takeLatest, EDIT_SETTINGS, settingsEdit); + yield fork(takeLatest, NEW_LANGUAGE_POST, postLanguage); + yield fork(takeLatest, LANGUAGE_DELETE, deleteLanguage); + yield fork(takeLatest, DATABASES_FETCH, fetchDatabases); + yield fork(takeLatest, NEW_DATABASE_POST, postDatabase); + yield fork(takeLatest, DATABASE_DELETE, deleteDatabase); + yield fork(takeLatest, SPECIFIC_DATABASE_FETCH, fetchSpecificDatabase); + yield fork(takeLatest, DATABASE_EDIT, editDatabase); - yield take(LOCATION_CHANGE); - yield cancel(loadConfigWatcher); - yield cancel(loadLanguagesWatcher); - yield cancel(editConfigWatcher); - yield cancel(postLanguageWatcher); - yield cancel(deleteLanguageWatcher); - yield cancel(loadDatabasesWatcher); - yield cancel(postDatabaseWatcher); - yield cancel(deleteDatabaseWatcher); - yield cancel(fetchSpecificDatabaseWatcher); - yield cancel(editDatabaseWatcher); + // TODO Fix router (Other PR) + // const loadConfigWatcher = yield fork(takeLatest, CONFIG_FETCH, fetchConfig); + // const loadLanguagesWatcher = yield fork(takeLatest, LANGUAGES_FETCH, fetchLanguages); + // const editConfigWatcher = yield fork(takeLatest, EDIT_SETTINGS, settingsEdit); + // const postLanguageWatcher = yield fork(takeLatest, NEW_LANGUAGE_POST, postLanguage); + // const deleteLanguageWatcher = yield fork(takeLatest, LANGUAGE_DELETE, deleteLanguage); + // const loadDatabasesWatcher = yield fork(takeLatest, DATABASES_FETCH, fetchDatabases); + // const postDatabaseWatcher = yield fork(takeLatest, NEW_DATABASE_POST, postDatabase); + // const deleteDatabaseWatcher = yield fork(takeLatest, DATABASE_DELETE, deleteDatabase); + // const fetchSpecificDatabaseWatcher = yield fork(takeLatest, SPECIFIC_DATABASE_FETCH, fetchSpecificDatabase); + // const editDatabaseWatcher = yield fork(takeLatest, DATABASE_EDIT, editDatabase); + + // yield take(LOCATION_CHANGE); + // yield cancel(loadConfigWatcher); + // yield cancel(loadLanguagesWatcher); + // yield cancel(editConfigWatcher); + // yield cancel(postLanguageWatcher); + // yield cancel(deleteLanguageWatcher); + // yield cancel(loadDatabasesWatcher); + // yield cancel(postDatabaseWatcher); + // yield cancel(deleteDatabaseWatcher); + // yield cancel(fetchSpecificDatabaseWatcher); + // yield cancel(editDatabaseWatcher); } // All sagas to be loaded diff --git a/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/selectors.js b/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/selectors.js index 83359a5007..2a0c25ea98 100644 --- a/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/selectors.js +++ b/packages/strapi-plugin-settings-manager/admin/src/containers/HomePage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the home state domain */ -const selectHomePageDomain = () => state => state.get('homePage'); +const selectHomePageDomain = () => state => state.get(`${pluginId}_homePage`); /** * Other specific selectors diff --git a/packages/strapi-plugin-settings-manager/admin/src/pluginId.js b/packages/strapi-plugin-settings-manager/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-plugin-settings-manager/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-plugin-settings-manager/admin/src/routes.json b/packages/strapi-plugin-settings-manager/admin/src/routes.json deleted file mode 100644 index 7c3d038f8c..0000000000 --- a/packages/strapi-plugin-settings-manager/admin/src/routes.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "(/:slug(/:env))": { - "name": "homePage", - "container": "HomePage" - } -} diff --git a/packages/strapi-plugin-settings-manager/package.json b/packages/strapi-plugin-settings-manager/package.json index bf994342d9..7894dc912b 100644 --- a/packages/strapi-plugin-settings-manager/package.json +++ b/packages/strapi-plugin-settings-manager/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-settings-manager", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Strapi plugin to manage settings.", "strapi": { "name": "Settings Manager", @@ -8,24 +8,29 @@ "description": "settings-manager.plugin.description" }, "scripts": { - "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", + "analyze:clean": "rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/lib/server", - "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "rimraf admin/build", + "start": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/lib/server", + "generate": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "lint": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/eslint --ignore-path .gitignore --ignore-pattern '/admin/build/' --config ./node_modules/strapi-helper-plugin/lib/internals/eslint/.eslintrc.json admin", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "npm run lint", "prepublishOnly": "IS_MONOREPO=true npm run build" }, "devDependencies": { + "cross-env": "^5.2.0", "flag-icon-css": "^2.8.0", "react-select": "^1.0.0-rc.5", - "strapi-helper-plugin": "3.0.0-alpha.23.1" + "rimraf": "^2.6.3", + "strapi-helper-plugin": "3.0.0-alpha.24.1" + }, + "dependencies": { + "shelljs": "^0.7.8" }, "author": { "name": "Strapi team", diff --git a/packages/strapi-plugin-settings-manager/services/SettingsManager.js b/packages/strapi-plugin-settings-manager/services/SettingsManager.js index 091708d60e..be1640e6a3 100644 --- a/packages/strapi-plugin-settings-manager/services/SettingsManager.js +++ b/packages/strapi-plugin-settings-manager/services/SettingsManager.js @@ -3,7 +3,8 @@ const fs = require('fs'); const path = require('path'); const _ = require('lodash'); -const exec = require('child_process').spawnSync; + +const shell = require('shelljs'); module.exports = { menu: { @@ -963,12 +964,12 @@ module.exports = { if (connector && !installedConnector) { strapi.log.info(`Installing ${connector} dependency ...`); - exec('npm', ['install', `${connector}@${strapi.config.info.strapi}`]); + shell.exec(`npm install ${connector}@${strapi.config.info.strapi}`, {silent: true}); } if (client && !installedClient) { strapi.log.info(`Installing ${client} dependency ...`); - exec('npm', ['install', client]); + shell.exec(`npm install ${client}`, {silent: true}); } }, diff --git a/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js b/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js index 36277ff464..e996694374 100644 --- a/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js +++ b/packages/strapi-plugin-upload/admin/src/components/EditForm/index.js @@ -72,6 +72,7 @@ class EditForm extends React.Component { name="sizeLimit" onChange={this.props.onChange} type="number" + step={0.01} value={get(this.props.modifiedData, 'sizeLimit', 1) / 1000} />
    diff --git a/packages/strapi-plugin-upload/admin/src/components/Li/index.js b/packages/strapi-plugin-upload/admin/src/components/Li/index.js index 3a0f90bc9a..48858f9425 100644 --- a/packages/strapi-plugin-upload/admin/src/components/Li/index.js +++ b/packages/strapi-plugin-upload/admin/src/components/Li/index.js @@ -11,10 +11,11 @@ import { CopyToClipboard } from 'react-copy-to-clipboard'; import cn from 'classnames'; import moment from 'moment'; -import FileIcon from 'components/FileIcon'; import IcoContainer from 'components/IcoContainer'; import PopUpWarning from 'components/PopUpWarning'; +import FileIcon from '../FileIcon'; + import styles from './styles.scss'; /* eslint-disable react/no-string-refs */ diff --git a/packages/strapi-plugin-upload/admin/src/components/List/index.js b/packages/strapi-plugin-upload/admin/src/components/List/index.js index 24cc674fa6..55ae206378 100644 --- a/packages/strapi-plugin-upload/admin/src/components/List/index.js +++ b/packages/strapi-plugin-upload/admin/src/components/List/index.js @@ -9,8 +9,8 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import cn from 'classnames'; -import Li from 'components/Li'; -import ListHeader from 'components/ListHeader'; +import Li from '../Li'; +import ListHeader from '../ListHeader'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-upload/admin/src/containers/App/index.js b/packages/strapi-plugin-upload/admin/src/containers/App/index.js index 0c90f21f39..8618e70da1 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/App/index.js @@ -8,13 +8,12 @@ import React from 'react'; import { Switch, Route } from 'react-router-dom'; -// Utils -import { pluginId } from 'app'; +import pluginId from '../../pluginId'; // Containers -import ConfigPage from 'containers/ConfigPage'; -import HomePage from 'containers/HomePage'; -import NotFoundPage from 'containers/NotFoundPage'; +import ConfigPage from '../ConfigPage'; +import HomePage from '../HomePage'; +import NotFoundPage from '../NotFoundPage'; function App() { return ( diff --git a/packages/strapi-plugin-upload/admin/src/containers/App/reducer.js b/packages/strapi-plugin-upload/admin/src/containers/App/reducer.js deleted file mode 100644 index 38026c39cd..0000000000 --- a/packages/strapi-plugin-upload/admin/src/containers/App/reducer.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * - * App reducer - * - */ - -import { fromJS } from 'immutable'; - -const initialState = fromJS({}); - -function appReducer(state = initialState, action) { - switch (action.type) { - default: - return state; - } -} - -export default appReducer; diff --git a/packages/strapi-plugin-upload/admin/src/containers/App/selectors.js b/packages/strapi-plugin-upload/admin/src/containers/App/selectors.js deleted file mode 100644 index 2393a073cd..0000000000 --- a/packages/strapi-plugin-upload/admin/src/containers/App/selectors.js +++ /dev/null @@ -1,9 +0,0 @@ -// import { createSelector } from 'reselect'; - -/** - * Direct selector to the list state domain - */ - -// const selectGlobalDomain = () => state => state.get('global'); - -export {}; diff --git a/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/actions.js b/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/actions.js index ae3839a3da..e13fef19b2 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/actions.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/actions.js @@ -40,7 +40,7 @@ export function onCancel() { export function onChange({ target }) { const keys = ['modifiedData'].concat(target.name.split('.')); - const value = target.name === 'sizeLimit' ? parseInt(target.value, 10) * 1000 : target.value; + const value = target.name === 'sizeLimit' ? Number(target.value) * 1000 : target.value; return { type: ON_CHANGE, diff --git a/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/index.js b/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/index.js index 5c9b61b0ad..74c84dece9 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/index.js @@ -17,14 +17,10 @@ import ContainerFluid from 'components/ContainerFluid'; import HeaderNav from 'components/HeaderNav'; import PluginHeader from 'components/PluginHeader'; -// Plugin's components -import EditForm from 'components/EditForm'; +import pluginId from '../../pluginId'; -// You can find these utils in either -// ./node_modules/strapi-helper-plugin/lib/src -// or strapi/packages/strapi-helper-plugin/lib/src -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; +// Plugin's components +import EditForm from '../../components/EditForm'; import { getSettings, @@ -180,8 +176,8 @@ const mapStateToProps = selectConfigPage(); const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'configPage', reducer }); -const withSaga = injectSaga({ key: 'configPage', saga }); +const withReducer = strapi.injectReducer({ key: 'configPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'configPage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/selectors.js b/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/selectors.js index 57fc3910e6..2659d39aa5 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/selectors.js +++ b/packages/strapi-plugin-upload/admin/src/containers/ConfigPage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the configPage state domain */ -const selectConfigPageDomain = () => state => state.get('configPage'); +const selectConfigPageDomain = () => state => state.get(`${pluginId}_configPage`); /** * Default selector used by ConfigPage diff --git a/packages/strapi-plugin-upload/admin/src/containers/HomePage/index.js b/packages/strapi-plugin-upload/admin/src/containers/HomePage/index.js index 979b80dc67..74d2caea9c 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/HomePage/index.js +++ b/packages/strapi-plugin-upload/admin/src/containers/HomePage/index.js @@ -21,15 +21,15 @@ import InputSearch from 'components/InputSearch'; import PageFooter from 'components/PageFooter'; import PluginHeader from 'components/PluginHeader'; -// Plugin's component -import EntriesNumber from 'components/EntriesNumber'; -import List from 'components/List'; -import PluginInputFile from 'components/PluginInputFile'; - // Utils import getQueryParameters from 'utils/getQueryParameters'; -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; + +import pluginId from '../../pluginId'; + +// Plugin's component +import EntriesNumber from '../../components/EntriesNumber'; +import List from '../../components/List'; +import PluginInputFile from '../../components/PluginInputFile'; // Actions import { @@ -221,8 +221,8 @@ const mapStateToProps = selectHomePage(); const withConnect = connect(mapStateToProps, mapDispatchToProps); -const withReducer = injectReducer({ key: 'homePage', reducer }); -const withSaga = injectSaga({ key: 'homePage', saga }); +const withReducer = strapi.injectReducer({ key: 'homePage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-upload/admin/src/containers/HomePage/saga.js b/packages/strapi-plugin-upload/admin/src/containers/HomePage/saga.js index cf3e24469f..76b4e67d88 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/HomePage/saga.js +++ b/packages/strapi-plugin-upload/admin/src/containers/HomePage/saga.js @@ -1,7 +1,16 @@ -import { LOCATION_CHANGE } from 'react-router-redux'; +// import { LOCATION_CHANGE } from 'react-router-redux'; import { Map } from 'immutable'; import { isEmpty } from 'lodash'; -import { all, call, fork, put, select, take, takeLatest } from 'redux-saga/effects'; +import { + all, + call, + // cancel, + fork, + put, + select, + // take, + takeLatest, +} from 'redux-saga/effects'; import request from 'utils/request'; import { @@ -106,11 +115,13 @@ export function* defaultSaga() { yield fork(takeLatest, ON_DROP, uploadFiles); yield fork(takeLatest, ON_SEARCH, search); - const loadDataWatcher = yield fork(takeLatest, GET_DATA, dataGet); + yield fork(takeLatest, GET_DATA, dataGet); + // TODO: Fix router (Other PR) + // const loadDataWatcher = yield fork(takeLatest, GET_DATA, dataGet); - yield take(LOCATION_CHANGE); + // yield take(LOCATION_CHANGE); - yield cancel(loadDataWatcher); + // yield cancel(loadDataWatcher); } // All sagas to be loaded diff --git a/packages/strapi-plugin-upload/admin/src/containers/HomePage/selectors.js b/packages/strapi-plugin-upload/admin/src/containers/HomePage/selectors.js index 1d6af0726a..56d7b4d6b0 100644 --- a/packages/strapi-plugin-upload/admin/src/containers/HomePage/selectors.js +++ b/packages/strapi-plugin-upload/admin/src/containers/HomePage/selectors.js @@ -1,9 +1,11 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; + /** * Direct selector to the homePage state domain */ -const selectHomePageDomain = () => state => state.get('homePage'); +const selectHomePageDomain = () => state => state.get(`${pluginId}_homePage`); /** * Default selector used by HomePage diff --git a/packages/strapi-plugin-upload/admin/src/pluginId.js b/packages/strapi-plugin-upload/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-plugin-upload/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-plugin-upload/config/functions/bootstrap.js b/packages/strapi-plugin-upload/config/functions/bootstrap.js index d437af25e2..fc8451c011 100644 --- a/packages/strapi-plugin-upload/config/functions/bootstrap.js +++ b/packages/strapi-plugin-upload/config/functions/bootstrap.js @@ -30,6 +30,20 @@ module.exports = async cb => { return _.startsWith(node_module, 'strapi-provider-upload') || _.startsWith(node_module, 'strapi-upload'); }); + node_modules.filter((node_module) => { + return node_module.startsWith('@'); + }) + .forEach((orga) => { + const node_modules = fs.readdirSync(path.join(basePath, 'node_modules', orga)); + + node_modules.forEach((node_module) => { + // DEPRECATED strapi-email-* will be remove in next version + if (_.startsWith(node_module, 'strapi-provider-upload') || _.startsWith(node_module, 'strapi-upload')) { + uploads.push(`${orga}/${node_module}`); + } + }); + }); + // mount all providers to get configs _.forEach(uploads, (node_module) => { strapi.plugins.upload.config.providers.push( diff --git a/packages/strapi-plugin-upload/package.json b/packages/strapi-plugin-upload/package.json index 74bb062789..f256d568f3 100644 --- a/packages/strapi-plugin-upload/package.json +++ b/packages/strapi-plugin-upload/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-upload", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "This is the description of the plugin.", "strapi": { "name": "Files Upload", @@ -8,26 +8,26 @@ "description": "Description of upload plugin." }, "scripts": { - "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", + "analyze:clean": "rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/lib/server", - "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "rimraf admin/build", + "start": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/lib/server", + "generate": "node ./node_modules/plop/plop.js --plopfile node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "echo \"Error: no test specified\"", "prepublishOnly": "IS_MONOREPO=true npm run build" }, "dependencies": { - "strapi-provider-upload-local": "3.0.0-alpha.23.1", + "strapi-provider-upload-local": "3.0.0-alpha.24.1", "stream-to-array": "^2.3.0", "uuid": "^3.2.1" }, "devDependencies": { - "strapi-helper-plugin": "3.0.0-alpha.23.1" + "strapi-helper-plugin": "3.0.0-alpha.24.1" }, "author": { "name": "A Strapi developer", diff --git a/packages/strapi-plugin-upload/services/Upload.js b/packages/strapi-plugin-upload/services/Upload.js index d164830de7..c8ab83ae5f 100644 --- a/packages/strapi-plugin-upload/services/Upload.js +++ b/packages/strapi-plugin-upload/services/Upload.js @@ -125,9 +125,10 @@ module.exports = { }, fetch: params => { + params.id = params._id || params.id; return strapi .query('file', 'upload') - .findOne(_.pick(params, ['_id', 'id'])); + .findOne(_.pick(params, ['id'])); }, fetchAll: params => { diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js index 8d8dc7cb64..e8e118b8f3 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/Controller/index.js @@ -10,7 +10,7 @@ import { get, map, some } from 'lodash'; import cn from 'classnames'; import { FormattedMessage } from 'react-intl'; -import InputCheckbox from 'components/InputCheckboxPlugin'; +import InputCheckbox from '../InputCheckboxPlugin'; import styles from './styles.scss'; class Controller extends React.Component { diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchContainer/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchContainer/index.js index 32ead2d40e..147e01f76f 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchContainer/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/InputSearchContainer/index.js @@ -11,7 +11,7 @@ import cn from 'classnames'; import PropTypes from 'prop-types'; import Label from 'components/Label'; -import InputSearchLi from 'components/InputSearchLi'; +import InputSearchLi from '../InputSearchLi'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/List/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/List/index.js index a404d56e7f..88e40084df 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/List/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/List/index.js @@ -16,7 +16,7 @@ import LoadingIndicator from 'components/LoadingIndicator'; // Design import Button from 'components/Button'; -import ListRow from 'components/ListRow'; +import ListRow from '../ListRow'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/Plugin/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/Plugin/index.js index 5d2f8fc8f0..f6940a339a 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/Plugin/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/Plugin/index.js @@ -10,7 +10,7 @@ import { Collapse } from 'reactstrap'; import { capitalize, get, isEmpty, map } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import Controller from 'components/Controller'; +import Controller from '../Controller'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/Plugins/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/Plugins/index.js index 1fd809986b..b7a524923f 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/Plugins/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/Plugins/index.js @@ -9,7 +9,8 @@ import { FormattedMessage } from 'react-intl'; import { has, map } from 'lodash'; import PropTypes from 'prop-types'; import cn from 'classnames'; -import Plugin from 'components/Plugin'; + +import Plugin from '../Plugin'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-users-permissions/admin/src/components/Policies/index.js b/packages/strapi-plugin-users-permissions/admin/src/components/Policies/index.js index bb60ed2953..357140ab31 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/components/Policies/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/components/Policies/index.js @@ -10,8 +10,8 @@ import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { get, isEmpty, map, takeRight, toLower, without } from 'lodash'; -import BoundRoute from 'components/BoundRoute'; import Input from 'components/InputsIndex'; +import BoundRoute from '../BoundRoute'; import styles from './styles.scss'; diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/App/actions.js b/packages/strapi-plugin-users-permissions/admin/src/containers/App/actions.js deleted file mode 100644 index a5002ad023..0000000000 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/App/actions.js +++ /dev/null @@ -1,5 +0,0 @@ -/* - * - * App actions - * - */ diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/App/constants.js b/packages/strapi-plugin-users-permissions/admin/src/containers/App/constants.js deleted file mode 100644 index f62c609507..0000000000 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/App/constants.js +++ /dev/null @@ -1,5 +0,0 @@ -/* - * - * App constants - * - */ diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/App/index.js b/packages/strapi-plugin-users-permissions/admin/src/containers/App/index.js index 16efbef769..766f36fd31 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/App/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/App/index.js @@ -7,19 +7,14 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { createStructuredSelector } from 'reselect'; import { Switch, Route } from 'react-router-dom'; -import { bindActionCreators, compose } from 'redux'; - -// Utils -import { pluginId } from 'app'; +import pluginId from '../../pluginId'; // Containers -import AuthPage from 'containers/AuthPage'; -import EditPage from 'containers/EditPage'; -import HomePage from 'containers/HomePage'; -import NotFoundPage from 'containers/NotFoundPage'; +import AuthPage from '../AuthPage'; +import EditPage from '../EditPage'; +import HomePage from '../HomePage'; +import NotFoundPage from '../NotFoundPage'; class App extends React.Component { componentDidMount() { @@ -59,18 +54,4 @@ App.propTypes = { location: PropTypes.object.isRequired, }; -export function mapDispatchToProps(dispatch) { - return bindActionCreators( - {}, - dispatch, - ); -} - -const mapStateToProps = createStructuredSelector({}); - -// Wrap the component to inject dispatch and state into it -const withConnect = connect(mapStateToProps, mapDispatchToProps); - -export default compose( - withConnect, -)(App); +export default App; diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/App/reducer.js b/packages/strapi-plugin-users-permissions/admin/src/containers/App/reducer.js deleted file mode 100644 index 38026c39cd..0000000000 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/App/reducer.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * - * App reducer - * - */ - -import { fromJS } from 'immutable'; - -const initialState = fromJS({}); - -function appReducer(state = initialState, action) { - switch (action.type) { - default: - return state; - } -} - -export default appReducer; diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/App/selectors.js b/packages/strapi-plugin-users-permissions/admin/src/containers/App/selectors.js deleted file mode 100644 index 59c3cfbba0..0000000000 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/App/selectors.js +++ /dev/null @@ -1,7 +0,0 @@ -// import { createSelector } from 'reselect'; - -/** - * Direct selector to the list state domain - */ - -// const selectGlobalDomain = () => state => state.get('global'); diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/index.js b/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/index.js index 757283664a..4eef86c52a 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/index.js @@ -13,17 +13,17 @@ import { FormattedMessage } from 'react-intl'; import { findIndex, get, isBoolean, isEmpty, map, replace } from 'lodash'; import cn from 'classnames'; -// Logo -import LogoStrapi from 'assets/images/logo_strapi.png'; - // Design import Button from 'components/Button'; import Input from 'components/InputsIndex'; // Utils import auth from 'utils/auth'; -import injectSaga from 'utils/injectSaga'; -import injectReducer from 'utils/injectReducer'; + +import pluginId from '../../pluginId'; + +// Logo +import LogoStrapi from '../../assets/images/logo_strapi.png'; import { hideLoginErrorsInput, @@ -328,16 +328,8 @@ function mapDispatchToProps(dispatch) { } const withConnect = connect(mapStateToProps, mapDispatchToProps); - -/* Remove this line if the container doesn't have a route and -* check the documentation to see how to create the container's store -*/ -const withReducer = injectReducer({ key: 'authPage', reducer }); - -/* Remove the line below the container doesn't have a route and -* check the documentation to see how to create the container's store -*/ -const withSaga = injectSaga({ key: 'authPage', saga }); +const withReducer = strapi.injectReducer({ key: 'authPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'authPage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/selectors.js b/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/selectors.js index 4029f19277..570ceefc3d 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/selectors.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/AuthPage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the authPage state domain */ -const selectAuthPageDomain = () => (state) => state.get('authPage'); +const selectAuthPageDomain = () => (state) => state.get(`${pluginId}_authPage`); /** * Default selector used by AuthPage diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js index 894027dc90..024a44ec0b 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/index.js @@ -16,15 +16,14 @@ import cn from 'classnames'; // Design import BackHeader from 'components/BackHeader'; import Input from 'components/InputsIndex'; -import InputSearch from 'components/InputSearchContainer'; import LoadingIndicator from 'components/LoadingIndicator'; import LoadingIndicatorPage from 'components/LoadingIndicatorPage'; import PluginHeader from 'components/PluginHeader'; -import Plugins from 'components/Plugins'; -import Policies from 'components/Policies'; -import injectSaga from 'utils/injectSaga'; -import injectReducer from 'utils/injectReducer'; +import InputSearch from '../../components/InputSearchContainer'; +import Plugins from '../../components/Plugins'; +import Policies from '../../components/Policies'; +import pluginId from '../../pluginId'; // Actions import { @@ -326,16 +325,8 @@ function mapDispatchToProps(dispatch) { } const withConnect = connect(mapStateToProps, mapDispatchToProps); - -/* Remove this line if the container doesn't have a route and -* check the documentation to see how to create the container's store -*/ -const withReducer = injectReducer({ key: 'editPage', reducer }); - -/* Remove the line below the container doesn't have a route and -* check the documentation to see how to create the container's store -*/ -const withSaga = injectSaga({ key: 'editPage', saga }); +const withReducer = strapi.injectReducer({ key: 'editPage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'editPage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/selectors.js b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/selectors.js index ae0bb87c3a..5a6b175669 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/selectors.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/EditPage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the editPage state domain */ -const selectEditPageDomain = () => (state) => state.get('editPage'); +const selectEditPageDomain = () => (state) => state.get(`${pluginId}_editPage`); /** * Default selector used by EditPage diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/index.js b/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/index.js index 8778e163b5..b965c52062 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/index.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/index.js @@ -12,16 +12,15 @@ import { bindActionCreators, compose } from 'redux'; import cn from 'classnames'; import { clone, get, includes, isEqual, isEmpty } from 'lodash'; -// Design -import EditForm from 'components/EditForm'; import HeaderNav from 'components/HeaderNav'; -import List from 'components/List'; import PluginHeader from 'components/PluginHeader'; -import PopUpForm from 'components/PopUpForm'; -// Utils -import injectReducer from 'utils/injectReducer'; -import injectSaga from 'utils/injectSaga'; +import pluginId from '../../pluginId'; + +// Design +import EditForm from '../../components/EditForm'; +import List from '../../components/List'; +import PopUpForm from '../../components/PopUpForm'; // Selectors import selectHomePage from './selectors'; @@ -279,9 +278,8 @@ function mapDispatchToProps(dispatch) { const mapStateToProps = selectHomePage(); const withConnect = connect(mapStateToProps, mapDispatchToProps); - -const withReducer = injectReducer({ key: 'homePage', reducer }); -const withSaga = injectSaga({ key: 'homePage', saga }); +const withReducer = strapi.injectReducer({ key: 'homePage', reducer, pluginId }); +const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId }); export default compose( withReducer, diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/saga.js b/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/saga.js index c5ff308f0e..35656cd206 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/saga.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/saga.js @@ -1,6 +1,14 @@ -import { LOCATION_CHANGE } from 'react-router-redux'; +// import { LOCATION_CHANGE } from 'react-router-redux'; import { findIndex, get } from 'lodash'; -import { takeLatest, put, fork, take, cancel, select, call } from 'redux-saga/effects'; +import { + takeLatest, + put, + fork, + // take, + // cancel, + select, + call, +} from 'redux-saga/effects'; import request from 'utils/request'; @@ -75,13 +83,15 @@ export function* submitData(action) { } // Individual exports for testing export function* defaultSaga() { - const loadDataWatcher = yield fork(takeLatest, FETCH_DATA, dataFetch); + // const loadDataWatcher = yield fork(takeLatest, FETCH_DATA, dataFetch); + yield fork(takeLatest, FETCH_DATA, dataFetch); yield fork(takeLatest, DELETE_DATA, dataDelete); yield fork(takeLatest, SUBMIT, submitData); - yield take(LOCATION_CHANGE); - yield cancel(loadDataWatcher); + // TODO: Fix router (Other PR) + // yield take(LOCATION_CHANGE); + // yield cancel(loadDataWatcher); } // All sagas to be loaded diff --git a/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/selectors.js b/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/selectors.js index 34abcc4fcf..69379663a6 100644 --- a/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/selectors.js +++ b/packages/strapi-plugin-users-permissions/admin/src/containers/HomePage/selectors.js @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import pluginId from '../../pluginId'; /** * Direct selector to the homePage state domain */ -const selectHomePageDomain = () => state => state.get('homePage'); +const selectHomePageDomain = () => state => state.get(`${pluginId}_homePage`); /** * Default selector used by HomePage diff --git a/packages/strapi-plugin-users-permissions/admin/src/pluginId.js b/packages/strapi-plugin-users-permissions/admin/src/pluginId.js new file mode 100644 index 0000000000..1b059ddba7 --- /dev/null +++ b/packages/strapi-plugin-users-permissions/admin/src/pluginId.js @@ -0,0 +1,7 @@ +const pluginPkg = require('../../package.json'); +const pluginId = pluginPkg.name.replace( + /^strapi-plugin-/i, + '' +); + +module.exports = pluginId; diff --git a/packages/strapi-plugin-users-permissions/config/policies/permissions.js b/packages/strapi-plugin-users-permissions/config/policies/permissions.js index a0af4f8b69..2f81c03fa1 100644 --- a/packages/strapi-plugin-users-permissions/config/policies/permissions.js +++ b/packages/strapi-plugin-users-permissions/config/policies/permissions.js @@ -32,11 +32,11 @@ module.exports = async (ctx, next) => { name: 'users-permissions' }); - if (_.get(await store.get({key: 'advanced'}), 'email_confirmation') && ctx.state.user.confirmed !== true) { + if (_.get(await store.get({key: 'advanced'}), 'email_confirmation') && !ctx.state.user.confirmed) { return handleErrors(ctx, 'Your account email is not confirmed.', 'unauthorized'); } - if (ctx.state.user.blocked === true) { + if (ctx.state.user.blocked) { return handleErrors(ctx, 'Your account has been blocked by the administrator.', 'unauthorized'); } } @@ -74,4 +74,4 @@ const handleErrors = (ctx, err = undefined, type) => { } return ctx[type](err); -}; \ No newline at end of file +}; diff --git a/packages/strapi-plugin-users-permissions/config/queries/mongoose.js b/packages/strapi-plugin-users-permissions/config/queries/mongoose.js index 8c74435b9b..2d28c570fe 100644 --- a/packages/strapi-plugin-users-permissions/config/queries/mongoose.js +++ b/packages/strapi-plugin-users-permissions/config/queries/mongoose.js @@ -11,9 +11,10 @@ module.exports = { .lean(); }, - count: async function (params = {}) { + count: async function (params = {where: {}}) { return Number(await this - .countDocuments(params)); + .countDocuments() + .where(params.where)); }, findOne: async function (params, populate) { diff --git a/packages/strapi-plugin-users-permissions/controllers/Auth.js b/packages/strapi-plugin-users-permissions/controllers/Auth.js index 64cb49459f..c5c61134a3 100644 --- a/packages/strapi-plugin-users-permissions/controllers/Auth.js +++ b/packages/strapi-plugin-users-permissions/controllers/Auth.js @@ -56,12 +56,12 @@ module.exports = { if (!user) { return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.invalid' }] }] : 'Identifier or password invalid.'); } - - if (_.get(await store.get({key: 'advanced'}), 'email_confirmation') && user.confirmed !== true) { + + if (_.get(await store.get({key: 'advanced'}), 'email_confirmation') && !user.confirmed) { return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.confirmed' }] }] : 'Your account email is not confirmed.'); } - if (user.blocked === true) { + if (user.blocked) { return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.blocked' }] }] : 'Your account has been blocked by the administrator.'); } @@ -196,7 +196,7 @@ module.exports = { settings.object = await strapi.plugins['users-permissions'].services.userspermissions.template(settings.object, { USER: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken', 'role', 'provider']) }); - + try { // Send an email to the user. await strapi.plugins['email'].services.email.send({ @@ -332,7 +332,7 @@ module.exports = { } ctx.send({ - jwt, + jwt: !settings.email_confirmation ? jwt : undefined, user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken']) }); } catch(err) { @@ -345,7 +345,12 @@ module.exports = { emailConfirmation: async (ctx) => { const params = ctx.query; - const user = await strapi.plugins['users-permissions'].services.jwt.verify(params.confirmation); + let user; + try { + user = await strapi.plugins['users-permissions'].services.jwt.verify(params.confirmation); + } catch (err) { + return ctx.badRequest(null, 'This confirmation token is invalid.'); + } await strapi.plugins['users-permissions'].services.user.edit(_.pick(user, ['_id', 'id']), {confirmed: true}); diff --git a/packages/strapi-plugin-users-permissions/models/User.settings.json b/packages/strapi-plugin-users-permissions/models/User.settings.json index 69b7aafe1c..a5a3baa206 100644 --- a/packages/strapi-plugin-users-permissions/models/User.settings.json +++ b/packages/strapi-plugin-users-permissions/models/User.settings.json @@ -51,4 +51,4 @@ } }, "collectionName": "users-permissions_user" -} \ No newline at end of file +} diff --git a/packages/strapi-plugin-users-permissions/package.json b/packages/strapi-plugin-users-permissions/package.json index 8977fcdd68..0101ada403 100644 --- a/packages/strapi-plugin-users-permissions/package.json +++ b/packages/strapi-plugin-users-permissions/package.json @@ -1,6 +1,6 @@ { "name": "strapi-plugin-users-permissions", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Protect your API with a full-authentication process based on JWT", "strapi": { "name": "Roles & Permissions", @@ -8,15 +8,15 @@ "description": "users-permissions.plugin.description" }, "scripts": { - "analyze:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf stats.json", + "analyze:clean": "rimraf stats.json", "preanalyze": "npm run analyze:clean", "analyze": "node ./node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js", "prebuild": "npm run build:clean", - "build:dev": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=production node node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", - "build:clean": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/rimraf admin/build", - "start": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/cross-env NODE_ENV=development node ./node_modules/strapi-helper-plugin/lib/server", - "generate": "node ./node_modules/strapi-helper-plugin/node_modules/plop --plopfile ./node_modules/strapi-helper-plugin/lib/internals/generators/index.js", + "build:dev": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build": "cross-env NODE_ENV=production node_modules/strapi-helper-plugin/node_modules/.bin/webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress", + "build:clean": "rimraf admin/build", + "start": "cross-env NODE_ENV=development ./node_modules/strapi-helper-plugin/lib/server", + "generate": "node ./node_modules/plop/plop.js --plopfile node_modules/strapi-helper-plugin/lib/internals/generators/index.js", "prettier": "node ./node_modules/strapi-helper-plugin/node_modules/.bin/prettier --single-quote --trailing-comma es5 --write \"{admin,__{tests,mocks}__}/**/*.js\"", "test": "echo \"Error: no test specified\"", "prepublishOnly": "IS_MONOREPO=true npm run build" @@ -29,11 +29,11 @@ "koa2-ratelimit": "^0.6.1", "purest": "^2.0.1", "request": "^2.83.0", - "strapi-utils": "3.0.0-alpha.23.1", + "strapi-utils": "3.0.0-alpha.24.1", "uuid": "^3.1.0" }, "devDependencies": { - "strapi-helper-plugin": "3.0.0-alpha.23.1" + "strapi-helper-plugin": "3.0.0-alpha.24.1" }, "author": { "name": "Strapi team", diff --git a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js index d3b4d6ec1d..3762db7cd7 100644 --- a/packages/strapi-plugin-users-permissions/services/UsersPermissions.js +++ b/packages/strapi-plugin-users-permissions/services/UsersPermissions.js @@ -182,7 +182,8 @@ module.exports = { for (let i = 0; i < roles.length; ++i) { roles[i].id = roles[i].id || roles[i]._id; - roles[i].nb_users = await strapi.query('user', 'users-permissions').count({ role: roles[i].id }); + + roles[i].nb_users = await strapi.query('user', 'users-permissions').count(strapi.utils.models.convertParams('user', { role: roles[i].id })); } return roles; diff --git a/packages/strapi-provider-email-amazon-ses/package.json b/packages/strapi-provider-email-amazon-ses/package.json index 741a05f3ee..ef44310860 100644 --- a/packages/strapi-provider-email-amazon-ses/package.json +++ b/packages/strapi-provider-email-amazon-ses/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-email-amazon-ses", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Amazon SES provider for strapi email", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-provider-email-mailgun/lib/index.js b/packages/strapi-provider-email-mailgun/lib/index.js index 51cce55d9b..c76dc64b96 100644 --- a/packages/strapi-provider-email-mailgun/lib/index.js +++ b/packages/strapi-provider-email-mailgun/lib/index.js @@ -55,7 +55,8 @@ module.exports = { to: options.to, subject: options.subject, text: options.text, - html: options.html + html: options.html, + ...(options.attachment && { attachment: options.attachment }) }; msg['h:Reply-To'] = options.replyTo; diff --git a/packages/strapi-provider-email-mailgun/package.json b/packages/strapi-provider-email-mailgun/package.json index d3b4cdcf11..43608877a5 100644 --- a/packages/strapi-provider-email-mailgun/package.json +++ b/packages/strapi-provider-email-mailgun/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-email-mailgun", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Mailgun provider for strapi email plugin", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-provider-email-sendgrid/package.json b/packages/strapi-provider-email-sendgrid/package.json index 971a4289e7..2538f7df9e 100644 --- a/packages/strapi-provider-email-sendgrid/package.json +++ b/packages/strapi-provider-email-sendgrid/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-email-sendgrid", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Sendgrid provider for strapi email", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-provider-email-sendmail/package.json b/packages/strapi-provider-email-sendmail/package.json index 36690d0812..7cb8f0a38b 100644 --- a/packages/strapi-provider-email-sendmail/package.json +++ b/packages/strapi-provider-email-sendmail/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-email-sendmail", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Sendmail provider for strapi email", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-provider-upload-aws-s3/package.json b/packages/strapi-provider-upload-aws-s3/package.json index 749f548689..800a60fd64 100644 --- a/packages/strapi-provider-upload-aws-s3/package.json +++ b/packages/strapi-provider-upload-aws-s3/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-upload-aws-s3", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "AWS S3 provider for strapi upload", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-provider-upload-cloudinary/package.json b/packages/strapi-provider-upload-cloudinary/package.json index f1e105e714..36f28a8cda 100644 --- a/packages/strapi-provider-upload-cloudinary/package.json +++ b/packages/strapi-provider-upload-cloudinary/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-upload-cloudinary", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Cloudinary provider for strapi upload", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-provider-upload-local/package.json b/packages/strapi-provider-upload-local/package.json index 248fe80794..738a0dfbb2 100644 --- a/packages/strapi-provider-upload-local/package.json +++ b/packages/strapi-provider-upload-local/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-upload-local", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Local provider for strapi upload", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi-provider-upload-rackspace/package.json b/packages/strapi-provider-upload-rackspace/package.json index 5179abf6e5..5438292f5f 100644 --- a/packages/strapi-provider-upload-rackspace/package.json +++ b/packages/strapi-provider-upload-rackspace/package.json @@ -1,6 +1,6 @@ { "name": "strapi-provider-upload-rackspace", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Rackspace provider for strapi upload", "main": "./lib", "scripts": { diff --git a/packages/strapi-utils/package.json b/packages/strapi-utils/package.json index eb0f7ae5b5..41d0eb7519 100644 --- a/packages/strapi-utils/package.json +++ b/packages/strapi-utils/package.json @@ -1,6 +1,6 @@ { "name": "strapi-utils", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "Shared utilities for the Strapi packages", "homepage": "http://strapi.io", "keywords": [ diff --git a/packages/strapi/bin/strapi-install.js b/packages/strapi/bin/strapi-install.js index 9720d6e2c0..3b0e55b0d1 100644 --- a/packages/strapi/bin/strapi-install.js +++ b/packages/strapi/bin/strapi-install.js @@ -7,14 +7,13 @@ */ // Node.js core. -const { exec } = require('child_process'); const path = require('path'); const fs = require('fs-extra'); -const shell = require('shelljs'); // Public const {cyan} = require('chalk'); const ora = require('ora'); +const shell = require('shelljs'); // Logger. const { cli, packageManager } = require('strapi-utils'); @@ -49,7 +48,7 @@ module.exports = function (plugin, cliArguments) { if (cliArguments.dev) { try { - fs.symlinkSync(path.resolve(__dirname, '..', '..', pluginID), path.resolve(process.cwd(), pluginPath), 'dir'); + fs.symlinkSync(path.resolve(__dirname, '..', '..', pluginID), path.resolve(process.cwd(), pluginPath), 'junction'); loader.succeed(`The ${cyan(plugin)} plugin has been successfully installed.`); process.exit(0); @@ -71,8 +70,8 @@ module.exports = function (plugin, cliArguments) { } const cmd = isStrapiInstalledWithNPM ? `npm install ${pluginID}@${packageJSON.version} --ignore-scripts --no-save --prefix ${pluginPath}` : `yarn --cwd ${pluginPath} add ${pluginID}@${packageJSON.version} --ignore-scripts --no-save`; - exec(cmd, (err) => { - if (err) { + shell.exec(cmd, {silent: true}, (code) => { + if (code) { loader.fail(`An error occurred during plugin installation. \nPlease make sure this plugin is available on npm: https://www.npmjs.com/package/${pluginID}`); process.exit(1); } diff --git a/packages/strapi/bin/strapi-new.js b/packages/strapi/bin/strapi-new.js index 16a281f9fc..f335ef51b1 100644 --- a/packages/strapi/bin/strapi-new.js +++ b/packages/strapi/bin/strapi-new.js @@ -7,6 +7,7 @@ */ // Node.js core. +const child_process = require('child_process'); const os = require('os'); const path = require('path'); @@ -30,7 +31,7 @@ const packageJSON = require('../package.json'); */ module.exports = function (name, cliArguments) { - console.log('🚀 Start creating your Strapi application. It might take a minute, please take a coffee ☕️'); + console.log('🚀 Starting to create your Strapi application.'); const developerMode = cliArguments.dev !== undefined; @@ -84,9 +85,9 @@ module.exports = function (name, cliArguments) { const error = (error) => { fetch('https://analytics.strapi.io/track', { method: 'POST', - body: JSON.stringify({ - event: 'didNotStartAutomatically', - deviceId: machineIdSync(), + body: JSON.stringify({ + event: 'didNotStartAutomatically', + deviceId: machineIdSync(), properties: { error, os: os.type() @@ -113,11 +114,32 @@ module.exports = function (name, cliArguments) { try { // Enter inside the project folder. shell.cd(scope.rootPath); - // Launch the server. - shell.exec('strapi start', { - stdio: 'inherit' + // Empty log. + console.log(); + // Create interface for windows user to let them quit the program. + if (process.platform === "win32") { + const rl = require("readline").createInterface({ + input: process.stdin, + output: process.stdout + }); + + rl.on("SIGINT", function () { + process.emit("SIGINT"); + }); + } + // Listen Ctrl+C / SIGINT event to close the process. + process.on("SIGINT", function () { + process.exit(); }); + // Launch the server. + const child = child_process.exec('strapi start', { stdio: 'inherit' }); + // Display child process logs in the parent process. + child.stdout.pipe(process.stdout); + child.stderr.pipe(process.stderr); + + // shell.exec('strapi start'); } catch (e) { + console.log(e); error(e); } } diff --git a/packages/strapi/bin/strapi-update.js b/packages/strapi/bin/strapi-update.js index deceb7ef94..fba77047d5 100644 --- a/packages/strapi/bin/strapi-update.js +++ b/packages/strapi/bin/strapi-update.js @@ -9,10 +9,10 @@ // Node.js core. const fs = require('fs'); const path = require('path'); -const exec = require('child_process').exec; // Public node modules. const _ = require('lodash'); +const shell = require('shelljs'); // Logger. const logger = require('strapi-utils').logger; @@ -45,8 +45,8 @@ module.exports = function () { try { process.chdir(path.resolve(__dirname, '..', 'node_modules', 'strapi-generate-' + name)); logger.debug('Pulling the latest updates of `strapi-generate-' + name + '`.'); - exec('git pull ' + info.remote + ' ' + info.branch, err => { - if (err) { + shell.exec(`git pull ${info.remote} ${info.branch}`, (code) => { + if (code) { logger.error('Impossible to update `strapi-generate-' + name + '`.'); } else { logger.info('Successfully updated `strapi-generate-' + name + '`.'); @@ -55,18 +55,18 @@ module.exports = function () { } catch (err) { process.chdir(path.resolve(__dirname, '..', 'node_modules')); logger.debug('Cloning the `strapi-generate-' + name + '` repository for the first time...'); - exec('git clone ' + info.repository + ' strapi-generate-' + name, err => { - if (err) { + shell.exec(`git clone ${info.repository} strapi-generate-${name}`, (code, stdout, stderr) => { + if (code) { logger.error('Impossible to clone the `strapi-generate-' + name + '` repository.'); - console.log(err); + console.log(stderr); } else { logger.info('Successfully cloned the `strapi-generate-' + name + '` repository.'); process.chdir(path.resolve(__dirname, '..', 'node_modules', 'strapi-generate-' + name)); logger.debug('Installing dependencies for `strapi-generate-' + name + '`...'); - exec('npm install', err => { - if (err) { + shell.exec('npm install', (code, stdout, stderr) => { + if (code) { logger.error('Impossible to install dependencies for `strapi-generate-' + name + '`.'); - console.log(err); + console.log(stderr); } else { logger.info('Successfully installed dependencies for `strapi-generate-' + name + '`.'); } diff --git a/packages/strapi/lib/utils/openBrowser.js b/packages/strapi/lib/utils/openBrowser.js index 212cb6acf4..d0dd4faec5 100644 --- a/packages/strapi/lib/utils/openBrowser.js +++ b/packages/strapi/lib/utils/openBrowser.js @@ -82,8 +82,7 @@ function startBrowserProcess(browser, url) { }); return true; } catch (err) { - console.log(err); - // Ignore errors. + strapi.log.error('Failed to open Google Chrome with AppleScript'); } } @@ -154,4 +153,4 @@ async function openBrowser() { } } -module.exports = openBrowser; \ No newline at end of file +module.exports = openBrowser; diff --git a/packages/strapi/lib/utils/post-install.js b/packages/strapi/lib/utils/post-install.js index a5b8b9c6ae..5b650ef056 100644 --- a/packages/strapi/lib/utils/post-install.js +++ b/packages/strapi/lib/utils/post-install.js @@ -5,12 +5,12 @@ */ // Node.js core -const exec = require('child_process').execSync; const path = require('path'); const fs = require('fs'); // Public node modules. const _ = require('lodash'); +const shell = require('shelljs'); // Define files/dir paths const pluginsDirPath = path.join(process.cwd(), 'plugins'); @@ -35,9 +35,8 @@ try { // Check if path is existing. fs.accessSync(adminDirPath, fs.constants.R_OK | fs.constants.W_OK); - const install = exec(`cd "${adminDirPath}" && ${installCmd}`, { - silent: true - }); + shell.cd(adminDirPath); + const install = shell.exec(installCmd, {silent: true}); if (install.stderr && install.code !== 0) { console.error(install.stderr); @@ -71,9 +70,8 @@ try { console.log('📦 Installing packages...'); try { - const install = exec(`cd "${pluginPath}" && ${installCmd}`, { - silent: true - }); + shell.cd(pluginPath); + const install = shell.exec(installCmd, {silent: true}); if (install.stderr && install.code !== 0) { console.error(install.stderr); diff --git a/packages/strapi/package.json b/packages/strapi/package.json index d4d83c2d0e..6fb1f1da9a 100644 --- a/packages/strapi/package.json +++ b/packages/strapi/package.json @@ -1,6 +1,6 @@ { "name": "strapi", - "version": "3.0.0-alpha.23.1", + "version": "3.0.0-alpha.24.1", "description": "An open source solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier.", "homepage": "http://strapi.io", "keywords": [ @@ -62,16 +62,16 @@ "semver": "^5.4.1", "shelljs": "^0.8.3", "stack-trace": "0.0.10", - "strapi-generate": "3.0.0-alpha.23.1", - "strapi-generate-admin": "3.0.0-alpha.23.1", - "strapi-generate-api": "3.0.0-alpha.23.1", - "strapi-generate-controller": "3.0.0-alpha.23.1", - "strapi-generate-model": "3.0.0-alpha.23.1", - "strapi-generate-new": "3.0.0-alpha.23.1", - "strapi-generate-plugin": "3.0.0-alpha.23.1", - "strapi-generate-policy": "3.0.0-alpha.23.1", - "strapi-generate-service": "3.0.0-alpha.23.1", - "strapi-utils": "3.0.0-alpha.23.1" + "strapi-generate": "3.0.0-alpha.24.1", + "strapi-generate-admin": "3.0.0-alpha.24.1", + "strapi-generate-api": "3.0.0-alpha.24.1", + "strapi-generate-controller": "3.0.0-alpha.24.1", + "strapi-generate-model": "3.0.0-alpha.24.1", + "strapi-generate-new": "3.0.0-alpha.24.1", + "strapi-generate-plugin": "3.0.0-alpha.24.1", + "strapi-generate-policy": "3.0.0-alpha.24.1", + "strapi-generate-service": "3.0.0-alpha.24.1", + "strapi-utils": "3.0.0-alpha.24.1" }, "scripts": { "postinstall": "node lib/utils/success.js" diff --git a/scripts/setup.js b/scripts/setup.js index cb0617d2a0..a35e1923ad 100644 --- a/scripts/setup.js +++ b/scripts/setup.js @@ -189,7 +189,7 @@ const buildPlugins = async () => { const name = pckgName === 'admin' ? pckgName : `plugin-${pckgName}`; asyncWatcher( `🏗 Building ${name}...`, - `cd ../strapi-${name} && IS_MONOREPO=true npm run build`, + `cd ../strapi-${name} && cross-env IS_MONOREPO=true npm run build`, false, resolve, ); @@ -209,7 +209,7 @@ const setup = async () => { const pluginName = name === 'admin' ? name : `plugin-${name}`; shell.cd(`../strapi-${pluginName}`); - return watcher(`🏗 Building ${pluginName}...`, 'IS_MONOREPO=true npm run build'); + return watcher(`🏗 Building ${pluginName}...`, 'cross-env IS_MONOREPO=true npm run build'); }); } } @@ -225,4 +225,4 @@ const setup = async () => { ); }; -setup(); +setup(); \ No newline at end of file diff --git a/test/start.js b/test/start.js index fbcea91e7e..3cd8dab484 100644 --- a/test/start.js +++ b/test/start.js @@ -114,7 +114,7 @@ const main = async () => { await clean(); await generate(database); await start(); - // await cypressTest(); + await cypressTest(); // await test(); process.kill(appStart.pid); } catch (e) { @@ -123,7 +123,7 @@ const main = async () => { } }; - // await testProcess(databases.mongo); + await testProcess(databases.mongo); // await testProcess(databases.postgres); // await testProcess(databases.mysql); // await testProcess(databases.sqlite);