From d8e5d0403b359de546b63defd950c2e1a9e43efc Mon Sep 17 00:00:00 2001 From: Aurelsicoko Date: Mon, 30 Jul 2018 16:33:50 +0200 Subject: [PATCH] Update design, behavior and add link for selectMany --- .../admin/src/assets/images/icon_grab.svg | 34 ++++++ .../admin/src/assets/images/icon_remove.svg | 19 ++++ .../src/components/EditRelations/index.js | 6 +- .../src/components/EditRelations/styles.scss | 12 +-- .../admin/src/components/SelectMany/index.js | 54 +++++----- .../src/components/SelectMany/styles.scss | 101 +++++++++++++++++- .../admin/src/containers/EditPage/index.js | 77 ++++++++----- .../admin/src/containers/ListPage/index.js | 5 +- .../admin/src/containers/ListPage/utils.js | 9 ++ .../package.json | 2 +- .../config/policies/permissions.js | 2 + .../middlewares/users-permissions/index.js | 8 ++ .../models/User.settings.json | 4 + 13 files changed, 257 insertions(+), 76 deletions(-) create mode 100644 packages/strapi-plugin-content-manager/admin/src/assets/images/icon_grab.svg create mode 100644 packages/strapi-plugin-content-manager/admin/src/assets/images/icon_remove.svg diff --git a/packages/strapi-plugin-content-manager/admin/src/assets/images/icon_grab.svg b/packages/strapi-plugin-content-manager/admin/src/assets/images/icon_grab.svg new file mode 100644 index 0000000000..da187b6f13 --- /dev/null +++ b/packages/strapi-plugin-content-manager/admin/src/assets/images/icon_grab.svg @@ -0,0 +1,34 @@ + + + + Icon grab + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/strapi-plugin-content-manager/admin/src/assets/images/icon_remove.svg b/packages/strapi-plugin-content-manager/admin/src/assets/images/icon_remove.svg new file mode 100644 index 0000000000..594f147935 --- /dev/null +++ b/packages/strapi-plugin-content-manager/admin/src/assets/images/icon_remove.svg @@ -0,0 +1,19 @@ + + + + Icon remove + Created with Sketch. + + + + + + + + + + + + + + \ No newline at end of file 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 96bf90c636..14b002eac0 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 @@ -5,7 +5,6 @@ */ import React from 'react'; -import { FormattedMessage } from 'react-intl'; import PropTypes from 'prop-types'; import { get, map } from 'lodash'; @@ -26,9 +25,6 @@ const filterRelationsUpload = (data) => Object.keys(data).reduce((acc, current) function EditRelations(props) { return (
- - {(message) =>

{message}

} -
{map(filterRelationsUpload(props.schema.relations), (relation, key) => { if (relation.nature.toLowerCase().includes('morph') && relation[key]) return ''; @@ -43,6 +39,7 @@ function EditRelations(props) { schema={props.schema} setRecordAttribute={props.changeData} location={props.location} + onRedirect={props.onRedirect} /> ); })} @@ -59,6 +56,7 @@ EditRelations.propTypes = { changeData: PropTypes.func.isRequired, currentModelName: PropTypes.string.isRequired, location: PropTypes.object.isRequired, + onRedirect: PropTypes.func.isRequired, record: PropTypes.object, schema: PropTypes.object, }; diff --git a/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/styles.scss b/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/styles.scss index 7c0056c788..efa65641f8 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/styles.scss +++ b/packages/strapi-plugin-content-manager/admin/src/components/EditRelations/styles.scss @@ -1,13 +1,3 @@ .editFormRelations { /* stylelint-disable */ - h3{ - height: 41px; - margin: 0 -25px 14px; - padding: 0 25px; - background: #F3F3F3; - line-height: 41px; - border-radius: 2px 2px 0 0; - letter-spacing: 0.03rem; - font-size: 1.3rem; - font-weight: bold; - } + padding: 19px 0 20px; } diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/index.js b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/index.js index 36ce4ff9dc..13c7572c5f 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/index.js +++ b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/index.js @@ -6,48 +6,41 @@ import React from 'react'; import Select from 'react-select'; -import {SortableContainer, SortableElement, SortableHandle, arrayMove} from 'react-sortable-hoc'; - +import { SortableContainer, SortableElement, arrayMove } from 'react-sortable-hoc'; import PropTypes from 'prop-types'; - import { cloneDeep, isArray, isNull, isUndefined, get, findIndex, includes } from 'lodash'; -import IcoContainer from 'components/IcoContainer'; -import Ico from 'components/Ico'; - +// Utils. import request from 'utils/request'; import templateObject from 'utils/templateObject'; +// CSS. import 'react-select/dist/react-select.css'; + +// Icons. +import IconRemove from '../../assets/images/icon_remove.svg'; + import styles from './styles.scss'; -const DragHandle = SortableHandle(() => ); - -const SortableItem = SortableElement(({idx, onRemove, value}) => { - const icons = [ - { - icoType: 'trash', - onClick: () => onRemove(idx), - }, - ]; +const SortableItem = SortableElement(({idx, onRemove, item, onClick}) => { return (
  • - - - {value} - - - - +
    +
    + onClick(item)}>{item.label} +
    +
    + Remove Icon onRemove(idx)} /> +
  • ); }); -const SortableList = SortableContainer(({items, onRemove}) => { +const SortableList = SortableContainer(({items, onRemove, onClick}) => { return ( ); @@ -178,6 +171,15 @@ class SelectMany extends React.Component { this.props.setRecordAttribute({ target }); } + // Redirect to the edit page + handleClick = (item = {}) => { + this.props.onRedirect({ + model: this.props.relation.collection || this.props.relation.model, + id: item.value.id || item.value._id, + source: this.props.relation.plugin, + }); + } + render() { const description = this.props.relation.description ? (

    {this.props.relation.description}

    @@ -217,7 +219,8 @@ class SelectMany extends React.Component { } onSortEnd={this.handleSortEnd} onRemove={this.handleRemove} - useDragHandle + distance={1} + onClick={this.handleClick} />
    ); @@ -226,6 +229,7 @@ class SelectMany extends React.Component { } SelectMany.propTypes = { + onRedirect: PropTypes.func.isRequired, record: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]).isRequired, relation: PropTypes.object.isRequired, setRecordAttribute: PropTypes.func.isRequired, diff --git a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/styles.scss b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/styles.scss index f89e4b7d45..5d87d5133d 100644 --- a/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/styles.scss +++ b/packages/strapi-plugin-content-manager/admin/src/components/SelectMany/styles.scss @@ -7,7 +7,7 @@ } label + div{ - margin: 5px 0 26px; + margin: 3px 0 26px; &:focus{ outline: none; @@ -27,7 +27,7 @@ } .sortableList { - + margin-top: -21px; padding-left: 0 !important; list-style: none !important; @@ -36,14 +36,105 @@ .sortableListItem { display: flex; flex-wrap: nowrap; + align-content: center; justify-content: space-between; - > span { - display: flex; - overflow: hidden; + height: 27px; + + + &:hover{ + cursor: pointer; + + } + + &:active{ + .dragHandle{ + cursor: pointer; + + > span { + background: #AED4FB; + } + } + } + + .dragHandle{ + outline: none; + text-decoration: none; + margin-top: -1px; + + > span { + vertical-align: middle; + position: relative; + display: inline-block; + width: 6px; + height: 1px; + padding: 0px !important; + background: #B3B5B9; + overflow: visible !important; + transition: background .25s ease-out; + + &:before, &:after{ + content: ''; + display: inline-block; + width: 6px; + height: 1px; + background: inherit; + } + + &:before{ + position: absolute; + top: -2px; + left: 0; + } + + &:after{ + position: absolute; + bottom: -2px; + left: 0; + } + } + + } + + > div { span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } + + &:first-of-type{ + display: flex; + align-items: center; + transition: color .25s ease-out; + + &:hover{ + .dragHandle{ + > span { + background: #007EFF; + } + } + + color: #007EFF; + } + + span { + &:last-of-type{ + padding-left: 10px; + } + } + } + + &:last-of-type{ + display: inline-block; + height: 100%; + line-height: 27px; + text-align: right; + padding-right: 0px; + + img{ + display: inline-block; + height: 14px; + } + } } } \ No newline at end of file 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 798ea607e6..af9afc1fa0 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 @@ -32,6 +32,7 @@ import injectSaga from 'utils/injectSaga'; 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'; @@ -54,35 +55,15 @@ import styles from './styles.scss'; export class EditPage extends React.Component { componentDidMount() { - this.props.initModelProps(this.getModelName(), this.isCreating(), this.getSource(), this.getModelAttributes()); - - if (!this.isCreating()) { - const mainField = get(this.getModel(), 'info.mainField') || this.getModel().primaryKey; - this.props.getData(this.props.match.params.id, this.getSource(), mainField); - } else { - this.props.getLayout(this.getSource()); - } - - // 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], {}); - - if (association.plugin === 'upload' && association[association.type] === 'file') { - const relation = { - name: current, - multiple: association.nature === 'manyToManyMorph', - }; - - 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); + this.initComponent(this.props); } componentDidUpdate(prevProps) { + if (prevProps.location.pathname !== this.props.location.pathname) { + this.props.resetProps(); + this.initComponent(this.props); + } + 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]; @@ -165,6 +146,38 @@ export class EditPage extends React.Component { */ getSource = () => getQueryParameters(this.props.location.search, 'source'); + /** + * Initialize component + */ + initComponent = (props) => { + this.props.initModelProps(this.getModelName(), this.isCreating(), this.getSource(), this.getModelAttributes()); + + if (!this.isCreating()) { + const mainField = get(this.getModel(), 'info.mainField') || this.getModel().primaryKey; + this.props.getData(props.match.params.id, this.getSource(), mainField); + } else { + this.props.getLayout(this.getSource()); + } + + // 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], {}); + + if (association.plugin === 'upload' && association[association.type] === 'file') { + const relation = { + name: current, + multiple: association.nature === 'manyToManyMorph', + }; + + 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); + } + handleBlur = ({ target }) => { const defaultValue = get(this.getModelAttribute(target.name), 'default'); @@ -209,6 +222,15 @@ export class EditPage extends React.Component { this.props.changeData({ target }); } + handleRedirect = ({ model, id, source = 'content-manager'}) => { + const pathname = `${this.props.match.path.replace(':slug', model).replace(':id', id)}`; + + this.props.history.push({ + pathname, + search: `?source=${source}&redirectURI=${generateRedirectURI({ model, search: `?source=${source}` })}`, + }); + } + handleSubmit = (e) => { e.preventDefault(); const formErrors = checkFormValidity(this.generateFormFromRecord(), this.props.editPage.formValidations); @@ -267,7 +289,7 @@ export class EditPage extends React.Component { render() { const { editPage } = this.props; - + console.log(this.props); return (
    @@ -309,6 +331,7 @@ export class EditPage extends React.Component { changeData={this.props.changeData} record={editPage.record} schema={this.getSchema()} + onRedirect={this.handleRedirect} /> )}
    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 07d392eb55..5d1d14d0b1 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 @@ -62,6 +62,7 @@ import { generateFiltersFromSearch, generateSearchFromFilters, generateSearchFromParams, + generateRedirectURI, } from './utils'; import styles from './styles.scss'; @@ -157,9 +158,7 @@ export class ListPage extends React.Component { * Generate the redirect URI when editing an entry * @type {String} */ - generateRedirectURI = () => ( - `?redirectUrl=/plugins/content-manager/${this.getCurrentModelName().toLowerCase()}${this.generateSearch()}` - ); + generateRedirectURI = generateRedirectURI.bind(this); generateSearch = () => { const { diff --git a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/utils.js b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/utils.js index 67346e92bb..6ce34da080 100644 --- a/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/utils.js +++ b/packages/strapi-plugin-content-manager/admin/src/containers/ListPage/utils.js @@ -50,8 +50,17 @@ const generateSearchFromParams = params => return acc; }, ''); + /** +* Generate the redirect URI when editing an entry +* @type {String} +*/ +const generateRedirectURI = function ({ model, search } = {}) { + return `?redirectUrl=/plugins/content-manager/${(model || this.getCurrentModelName()).toLowerCase()}${(search || this.generateSearch())}`; +}; + export { generateFiltersFromSearch, generateSearchFromFilters, generateSearchFromParams, + generateRedirectURI, }; diff --git a/packages/strapi-plugin-content-manager/package.json b/packages/strapi-plugin-content-manager/package.json index 64957c1b93..b215588a7b 100755 --- a/packages/strapi-plugin-content-manager/package.json +++ b/packages/strapi-plugin-content-manager/package.json @@ -24,7 +24,7 @@ "devDependencies": { "react-select": "^1.0.0-rc.5", "react-sortable-hoc": "^0.8.3", - "strapi-helper-plugin": "3.0.0-alpha.12.5" + "strapi-helper-plugin": "3.0.0-alpha.12.6" }, "author": { "name": "Strapi team", diff --git a/packages/strapi-plugin-users-permissions/config/policies/permissions.js b/packages/strapi-plugin-users-permissions/config/policies/permissions.js index 3407b5ee41..4750be2291 100644 --- a/packages/strapi-plugin-users-permissions/config/policies/permissions.js +++ b/packages/strapi-plugin-users-permissions/config/policies/permissions.js @@ -1,6 +1,8 @@ module.exports = async (ctx, next) => { let role; + console.log("ljqskljdkls"); + if (ctx.request && ctx.request.header && ctx.request.header.authorization) { try { const { _id, id } = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx); diff --git a/packages/strapi-plugin-users-permissions/middlewares/users-permissions/index.js b/packages/strapi-plugin-users-permissions/middlewares/users-permissions/index.js index 7e9d41dd19..03da8be28b 100644 --- a/packages/strapi-plugin-users-permissions/middlewares/users-permissions/index.js +++ b/packages/strapi-plugin-users-permissions/middlewares/users-permissions/index.js @@ -14,6 +14,14 @@ module.exports = strapi => { }, initialize: function(cb) { + console.log(); + _.forEach(strapi.admin.config.routes, value => { + if (_.get(value.config, 'policies')) { + value.config.policies.unshift('plugins.users-permissions.permissions'); + } + }); + + _.forEach(strapi.config.routes, value => { if (_.get(value.config, 'policies')) { value.config.policies.unshift('plugins.users-permissions.permissions'); diff --git a/packages/strapi-plugin-users-permissions/models/User.settings.json b/packages/strapi-plugin-users-permissions/models/User.settings.json index da72db76e3..3299fa48f4 100644 --- a/packages/strapi-plugin-users-permissions/models/User.settings.json +++ b/packages/strapi-plugin-users-permissions/models/User.settings.json @@ -38,6 +38,10 @@ "via": "users", "plugin": "users-permissions", "configurable": false + }, + "products": { + "collection": "product", + "via": "users" } } } \ No newline at end of file