diff --git a/news/4970.feature b/news/4970.feature new file mode 100644 index 0000000000..93a3827caf --- /dev/null +++ b/news/4970.feature @@ -0,0 +1 @@ +Refactor ContentsRenameModal -@Tishasoumya-02 \ No newline at end of file diff --git a/src/components/manage/Contents/ContentsRenameModal.jsx b/src/components/manage/Contents/ContentsRenameModal.jsx index aa6f16573f..dde32df8f0 100644 --- a/src/components/manage/Contents/ContentsRenameModal.jsx +++ b/src/components/manage/Contents/ContentsRenameModal.jsx @@ -1,15 +1,10 @@ -/** - * Contents rename modal. - * @module components/manage/Contents/ContentsRenameModal - */ - -import React, { Component } from 'react'; +import React, { useCallback, useEffect } from 'react'; import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { compose } from 'redux'; +import { useDispatch, useSelector } from 'react-redux'; import { concat, merge, map } from 'lodash'; -import { defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, useIntl } from 'react-intl'; +import { usePrevious } from '@plone/volto/helpers'; import { updateContent } from '@plone/volto/actions'; import { ModalForm } from '@plone/volto/components'; @@ -40,140 +35,94 @@ const messages = defineMessages({ }, }); -/** - * ContentsRenameModal class. - * @class ContentsRenameModal - * @extends Component - */ -class ContentsRenameModal extends Component { - /** - * Property types. - * @property {Object} propTypes Property types. - * @static - */ - static propTypes = { - updateContent: PropTypes.func.isRequired, - items: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string, - title: PropTypes.string, - url: PropTypes.string, - }), - ).isRequired, - request: PropTypes.shape({ - loading: PropTypes.bool, - loaded: PropTypes.bool, - }).isRequired, - open: PropTypes.bool.isRequired, - onOk: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, - }; - - /** - * Constructor - * @method constructor - * @param {Object} props Component properties - * @constructs ContentsUploadModal - */ - constructor(props) { - super(props); - this.onSubmit = this.onSubmit.bind(this); - } +const ContentsRenameModal = (props) => { + const { onOk, open, items, onCancel } = props; + const intl = useIntl(); + const dispatch = useDispatch(); + const request = useSelector((state) => state.content.update); + const prevrequestloading = usePrevious(request.loading); - /** - * Component will receive props - * @method componentWillReceiveProps - * @param {Object} nextProps Next properties - * @returns {undefined} - */ - UNSAFE_componentWillReceiveProps(nextProps) { - if (this.props.request.loading && nextProps.request.loaded) { - this.props.onOk(); + useEffect(() => { + if (prevrequestloading && request.loaded) { + onOk(); } - } + }, [onOk, prevrequestloading, request.loaded]); - /** - * Submit handler - * @method onSubmit - * @param {Object} data Form data - * @returns {undefined} - */ - onSubmit(data) { - this.props.updateContent( - map(this.props.items, (item) => item.url), - map(this.props.items, (item, index) => ({ - id: data[`${index}_id`], - title: data[`${index}_title`], - })), - ); - } + const onSubmit = useCallback( + (data) => { + dispatch( + updateContent( + map(items, (item) => item.url), + map(items, (item, index) => ({ + id: data[`${index}_id`], + title: data[`${index}_title`], + })), + ), + ); + }, + [items, dispatch], + ); - /** - * Render method. - * @method render - * @returns {string} Markup for the component. - */ - render() { - return ( - this.props.open && ( - ({ - [`${index}_title`]: item.title, - [`${index}_id`]: item.id, - })), - )} - title={this.props.intl.formatMessage(messages.renameItems)} - schema={{ - fieldsets: [ - { - id: 'default', - title: this.props.intl.formatMessage(messages.default), - fields: concat( - ...map(this.props.items, (item, index) => [ - `${index}_title`, - `${index}_id`, - ]), - ), + return ( + open && ( + ({ + [`${index}_title`]: item.title, + [`${index}_id`]: item.id, + })), + )} + title={intl.formatMessage(messages.renameItems)} + schema={{ + fieldsets: [ + { + id: 'default', + title: intl.formatMessage(messages.default), + fields: concat( + ...map(items, (item, index) => [ + `${index}_title`, + `${index}_id`, + ]), + ), + }, + ], + properties: merge( + ...map(items, (item, index) => ({ + [`${index}_title`]: { + title: intl.formatMessage(messages.title), + type: 'string', + description: '', }, - ], - properties: merge( - ...map(this.props.items, (item, index) => ({ - [`${index}_title`]: { - title: this.props.intl.formatMessage(messages.title), - type: 'string', - description: '', - }, - [`${index}_id`]: { - title: this.props.intl.formatMessage(messages.shortName), - type: 'id', - description: this.props.intl.formatMessage( - messages.shortNameDescription, - ), - }, - })), - ), - required: [], - }} - /> - ) - ); - } -} + [`${index}_id`]: { + title: intl.formatMessage(messages.shortName), + type: 'id', + description: intl.formatMessage(messages.shortNameDescription), + }, + })), + ), + required: [], + }} + /> + ) + ); +}; -export default compose( - injectIntl, - connect( - (state) => ({ - request: state.content.update, +ContentsRenameModal.propTypes = { + items: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string, + title: PropTypes.string, + url: PropTypes.string, }), - { updateContent }, - ), -)(ContentsRenameModal); + ).isRequired, + open: PropTypes.bool.isRequired, + onOk: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, +}; + +export default ContentsRenameModal; diff --git a/src/components/manage/Contents/ContentsRenameModal.stories.jsx b/src/components/manage/Contents/ContentsRenameModal.stories.jsx new file mode 100644 index 0000000000..6483236510 --- /dev/null +++ b/src/components/manage/Contents/ContentsRenameModal.stories.jsx @@ -0,0 +1,61 @@ +import { injectIntl } from 'react-intl'; +import React from 'react'; +import ContentsRenameModalComponent from './ContentsRenameModal'; +import { RealStoreWrapper as Wrapper } from '@plone/volto/storybook'; + +const IntlContentRenameModalComponent = injectIntl( + ContentsRenameModalComponent, +); + +function StoryComponent(args) { + return ( + +
+ {}} + onCancel={() => {}} + items={[ + { + ...args, + url: '/blog', + }, + ]} + /> + + ); +} + +export const ContentRenameModal = StoryComponent.bind({}); + +ContentRenameModal.args = { + open: true, + id: 'blogs', + title: 'Plone Blog', +}; + +export default { + title: 'Public components/Contents/Content Rename Modal', + component: ContentRenameModal, + decorators: [ + (Story) => ( +
+ +
+ ), + ], + argTypes: {}, +};