diff --git a/frontend/src/components/draft-list-view/draft-list-item.js b/frontend/src/components/draft-list-view/draft-list-item.js index 18f437160a..c526f5e062 100644 --- a/frontend/src/components/draft-list-view/draft-list-item.js +++ b/frontend/src/components/draft-list-view/draft-list-item.js @@ -1,15 +1,18 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import { siteRoot, lang } from '../../utils/constants'; -import { Utils } from '../../utils/utils'; -import MenuControl from '../menu-control'; import moment from 'moment'; +import PropTypes from 'prop-types'; +import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap'; +import { gettext, siteRoot, lang } from '../../utils/constants'; +import { Utils } from '../../utils/utils'; moment.locale(lang); const propTypes = { - isItemFreezed: PropTypes.bool.isRequired, - onMenuToggleClick: PropTypes.func.isRequired, draft: PropTypes.object.isRequired, + isItemFreezed: PropTypes.bool.isRequired, + onFreezedItem: PropTypes.func.isRequired, + onUnfreezedItem: PropTypes.func.isRequired, + onDeleteHandler: PropTypes.func.isRequired, + onReviewHandler: PropTypes.func.isRequired, }; class DraftListItem extends React.Component { @@ -17,16 +20,17 @@ class DraftListItem extends React.Component { constructor(props) { super(props); this.state = { - isMenuControlShow: false, - highlight: '', + isMenuIconShow: false, + isItemMenuShow: false, + highlight: false, }; } onMouseEnter = () => { if (!this.props.isItemFreezed) { this.setState({ - isMenuControlShow: true, - highlight: 'tr-highlight' + isMenuIconShow: true, + highlight: true, }); } } @@ -34,16 +38,40 @@ class DraftListItem extends React.Component { onMouseLeave = () => { if (!this.props.isItemFreezed) { this.setState({ - isMenuControlShow: false, - highlight: '' + isMenuIconShow: false, + highlight: false, }); } } - onMenuToggleClick = (e) => { - e.nativeEvent.stopImmediatePropagation(); - let draft = this.props.draft; - this.props.onMenuToggleClick(e, draft); + onDropdownToggleClick = (e) => { + e.preventDefault(); + this.toggleOperationMenu(e); + } + + toggleOperationMenu = (e) => { + e.stopPropagation(); + this.setState( + {isItemMenuShow: !this.state.isItemMenuShow }, () => { + if (this.state.isItemMenuShow) { + this.props.onFreezedItem(); + } else { + this.setState({ + highlight: false, + isMenuIconShow: false, + }); + this.props.onUnfreezedItem(); + } + } + ); + } + + onDeleteHandler = () => { + this.props.onDeleteHandler(this.props.draft); + } + + onReviewHandler = () => { + this.props.onReviewHandler(this.props.draft); } render() { @@ -59,7 +87,7 @@ class DraftListItem extends React.Component { let iconUrl = Utils.getFileIconUrl(fileName); return ( - + {fileName} @@ -74,14 +102,23 @@ class DraftListItem extends React.Component { } {localTime} - - { - this.props.draft.review_status !== 'open' && - - } + + {(this.props.draft.review_status !== 'open' && this.state.isMenuIconShow) && ( + + + + {gettext('Delete')} + {gettext('Ask for review')} + + + )} ); diff --git a/frontend/src/components/draft-list-view/draft-list-view.js b/frontend/src/components/draft-list-view/draft-list-view.js index 28251cf647..b20ddb5409 100644 --- a/frontend/src/components/draft-list-view/draft-list-view.js +++ b/frontend/src/components/draft-list-view/draft-list-view.js @@ -4,13 +4,28 @@ import { gettext } from '../../utils/constants'; import DraftListItem from './draft-list-item'; const propTypes = { - isItemFreezed: PropTypes.bool.isRequired, draftList: PropTypes.array.isRequired, - onMenuToggleClick: PropTypes.func.isRequired, + onDeleteHandler: PropTypes.func.isRequired, + onReviewHandler: PropTypes.func.isRequired, }; class DraftListView extends React.Component { + constructor(props) { + super(props); + this.state = { + isItemFreezed: false, + }; + } + + onFreezedItem = () => { + this.setState({isItemFreezed: true}); + } + + onUnfreezedItem = () => { + this.setState({isItemFreezed: false}); + } + render() { let drafts = this.props.draftList; return ( @@ -31,8 +46,11 @@ class DraftListView extends React.Component { ); })} diff --git a/frontend/src/pages/drafts/draft-content.js b/frontend/src/pages/drafts/draft-content.js index da8f79583b..5262852fe8 100644 --- a/frontend/src/pages/drafts/draft-content.js +++ b/frontend/src/pages/drafts/draft-content.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import { siteRoot, gettext } from '../../utils/constants'; import editUtilties from '../../utils/editor-utilties'; import { Utils } from '../../utils/utils'; @@ -6,38 +6,22 @@ import PropTypes from 'prop-types'; import toaster from '../../components/toast'; import Loading from '../../components/loading'; import DraftListView from '../../components/draft-list-view/draft-list-view'; -import DraftListMenu from '../../components/draft-list-view/draft-list-menu'; const propTypes = { - updateDraftsList: PropTypes.func.isRequired, isLoadingDraft: PropTypes.bool.isRequired, - draftList: PropTypes.arrayOf(PropTypes.object), + updateDraftsList: PropTypes.func.isRequired, + draftList: PropTypes.array.isRequired, getDrafts: PropTypes.func.isRequired, }; class DraftContent extends React.Component { - - constructor(props) { - super(props); - this.state = { - isMenuShow: false, - menuPosition: {top:'', left: ''}, - currentDraft: null, - isItemFreezed: false, - }; - } componentDidMount() { this.props.getDrafts(); - document.addEventListener('click', this.onHideContextMenu); } - componentWillUnmount() { - document.removeEventListener('click', this.onHideContextMenu); - } - - onDeleteHandler = () => { - let draft = this.state.currentDraft; + onDeleteHandler = (draft) => { + // let draft = this.state.currentDraft; let draft_name = Utils.getFileName(draft.draft_file_path); editUtilties.deleteDraft(draft.id).then(res => { this.props.updateDraftsList(draft.id); @@ -51,6 +35,17 @@ class DraftContent extends React.Component { }); } + onReviewHandler = (draft) => { + editUtilties.createDraftReview(draft.id).then(res => { + const w = window.open(); + w.location = siteRoot + 'drafts/review/' + res.data.id; + }).catch((error) => { + if (error.response.status == '409') { + toaster.danger(gettext('Review already exists.')); + } + }); + } + onPublishHandler = () => { let draft = this.state.currentDraft; let draft_name = Utils.getFileName(draft.draft_file_path); @@ -65,75 +60,28 @@ class DraftContent extends React.Component { toaster.danger(msg_s); }); } - - onReviewHandler = () => { - let draft = this.state.currentDraft; - - editUtilties.createDraftReview(draft.id).then(res => { - const w = window.open(); - w.location = siteRoot + 'drafts/review/' + res.data.id; - }).catch((error) => { - if (error.response.status == '409') { - toaster.danger(gettext('Review already exists.')); - } - }); - } - - onMenuToggleClick = (e, draft) => { - if (this.state.isMenuShow) { - this.onHideContextMenu(); - } else { - this.onShowContextMenu(e, draft); - } - } - - onShowContextMenu = (e, draft) => { - let left = e.clientX - 8*16; - let top = e.clientY + 10; - let position = {top: top, left: left}; - this.setState({ - isMenuShow: true, - menuPosition: position, - currentDraft: draft, - isItemFreezed: true - }); - } - - onHideContextMenu = () => { - this.setState({ - isMenuShow: false, - currentDraft: null, - isItemFreezed: false - }); - } render() { return (
- {this.props.isLoadingDraft && } - {(!this.props.isLoadingDraft && this.props.draftList.length !==0) && - - } - {(!this.props.isLoadingDraft && this.props.draftList.length === 0) && -
-

{gettext('No draft yet')}

-

{gettext('Draft is a way to let you collaborate with others on files. You can create a draft from a file, edit the draft and then ask for a review. The original file will be updated only after the draft be reviewed.')}

-
- } - {this.state.isMenuShow && - - } + {this.props.isLoadingDraft && } + {!this.props.isLoadingDraft && ( + + {this.props.draftList.length === 0 && ( +
+

{gettext('No draft yet')}

+

{gettext('Draft is a way to let you collaborate with others on files. You can create a draft from a file, edit the draft and then ask for a review. The original file will be updated only after the draft be reviewed.')}

+
+ )} + {this.props.draftList.length !==0 && ( + + )} +
+ )}
); }