diff --git a/src/components/DragAndDrop/index.js b/src/components/DragAndDrop/index.js index b35c43126c98..09ce3c07dd1d 100644 --- a/src/components/DragAndDrop/index.js +++ b/src/components/DragAndDrop/index.js @@ -17,6 +17,9 @@ const propTypes = { /** Guard for accepting drops in drop zone. Drag event is passed to this function as first parameter. This prop is necessary to be inlined to satisfy the linter */ shouldAcceptDrop: PropTypes.func, + /** Whether drag & drop should be disabled */ + disabled: PropTypes.bool, + /** Rendered child component */ children: PropTypes.node.isRequired, }; @@ -33,6 +36,7 @@ const defaultProps = { } return false; }, + disabled: false, }; export default class DragAndDrop extends React.Component { @@ -52,6 +56,32 @@ export default class DragAndDrop extends React.Component { } componentDidMount() { + if (this.props.disabled) { + return; + } + this.addEventListeners(); + } + + componentDidUpdate(prevProps) { + const isDisabled = this.props.disabled; + if (isDisabled === prevProps.disabled) { + return; + } + if (isDisabled) { + this.removeEventListeners(); + } else { + this.addEventListeners(); + } + } + + componentWillUnmount() { + if (this.props.disabled) { + return; + } + this.removeEventListeners(); + } + + addEventListeners() { this.dropZone = document.getElementById(this.props.dropZoneId); this.dropZoneRect = this.calculateDropZoneClientReact(); document.addEventListener('dragover', this.dropZoneDragListener); @@ -61,7 +91,7 @@ export default class DragAndDrop extends React.Component { window.addEventListener('resize', this.throttledDragNDropWindowResizeListener); } - componentWillUnmount() { + removeEventListeners() { document.removeEventListener('dragover', this.dropZoneDragListener); document.removeEventListener('dragenter', this.dropZoneDragListener); document.removeEventListener('dragleave', this.dropZoneDragListener); diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index eb55a8996e08..5b665c525b38 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -236,7 +236,10 @@ class ReportScreen extends React.Component { placeholder={( <> - + + + + )} > @@ -312,9 +315,10 @@ class ReportScreen extends React.Component { {/* Note: The report should be allowed to mount even if the initial report actions are not loaded. If we prevent rendering the report while they are loading then we'll unnecessarily unmount the ReportActionsView which will clear the new marker lines initial state. */} {(!this.isReportReadyForDisplay() || isLoadingInitialReportActions) && ( - + <> + + + )} diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index f49f3ccb8bbb..82f376dfad1c 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -88,7 +88,10 @@ const propTypes = { isFocused: PropTypes.bool.isRequired, /** Is the composer full size */ - isComposerFullSize: PropTypes.bool.isRequired, + isComposerFullSize: PropTypes.bool, + + /** Whether user interactions should be disabled */ + disabled: PropTypes.bool, // The NVP describing a user's block status blockedFromConcierge: PropTypes.shape({ @@ -539,7 +542,7 @@ class ReportActionCompose extends React.Component { {shouldShowReportRecipientLocalTime && } e.preventDefault()} style={styles.composerSizeButton} - disabled={isBlockedFromConcierge} + disabled={isBlockedFromConcierge || this.props.disabled} > @@ -591,7 +594,7 @@ class ReportActionCompose extends React.Component { // Keep focus on the composer when Expand button is clicked. onMouseDown={e => e.preventDefault()} style={styles.composerSizeButton} - disabled={isBlockedFromConcierge} + disabled={isBlockedFromConcierge || this.props.disabled} > @@ -608,7 +611,7 @@ class ReportActionCompose extends React.Component { this.setMenuVisibility(true); }} style={styles.chatItemAttachButton} - disabled={isBlockedFromConcierge} + disabled={isBlockedFromConcierge || this.props.disabled} > @@ -654,6 +657,7 @@ class ReportActionCompose extends React.Component { this.setState({isDraggingOver: false}); }} + disabled={this.props.disabled} > this.setTextInputShouldClear(false)} - isDisabled={isComposeDisabled || isBlockedFromConcierge} + isDisabled={isComposeDisabled || isBlockedFromConcierge || this.props.disabled} selection={this.state.selection} onSelectionChange={this.onSelectionChange} isFullComposerAvailable={this.state.isFullComposerAvailable} @@ -686,7 +690,7 @@ class ReportActionCompose extends React.Component { {canUseTouchScreen() && this.props.isMediumScreenWidth ? null : ( this.focus(true)} onEmojiSelected={this.addEmojiToTextBox} /> @@ -702,7 +706,7 @@ class ReportActionCompose extends React.Component { // Keep focus on the composer when Send message is clicked. // eslint-disable-next-line react/jsx-props-no-multi-spaces onMouseDown={e => e.preventDefault()} - disabled={this.state.isCommentEmpty || isBlockedFromConcierge || hasExceededMaxCommentLength} + disabled={this.state.isCommentEmpty || isBlockedFromConcierge || this.props.disabled || hasExceededMaxCommentLength} hitSlop={{ top: 3, right: 3, bottom: 3, left: 3, }} diff --git a/src/pages/home/report/ReportFooter.js b/src/pages/home/report/ReportFooter.js index 779337e489bc..29fea5e2ed19 100644 --- a/src/pages/home/report/ReportFooter.js +++ b/src/pages/home/report/ReportFooter.js @@ -21,16 +21,16 @@ import reportPropTypes from '../../reportPropTypes'; const propTypes = { /** Report object for the current report */ - report: reportPropTypes.isRequired, + report: reportPropTypes, /** Report actions for the current report */ - reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)).isRequired, + reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)), /** Offline status */ isOffline: PropTypes.bool.isRequired, /** Callback fired when the comment is submitted */ - onSubmitComment: PropTypes.func.isRequired, + onSubmitComment: PropTypes.func, /** Any errors associated with an attempt to create a chat */ // eslint-disable-next-line react/forbid-prop-types @@ -42,13 +42,20 @@ const propTypes = { /** Whether the composer input should be shown */ shouldShowComposeInput: PropTypes.bool, + /** Whether user interactions should be disabled */ + shouldDisableCompose: PropTypes.bool, + ...windowDimensionsPropTypes, }; const defaultProps = { - shouldShowComposeInput: true, + report: {reportID: '0'}, + reportActions: {}, + onSubmitComment: () => {}, errors: {}, pendingAction: null, + shouldShowComposeInput: true, + shouldDisableCompose: false, }; class ReportFooter extends React.Component { @@ -99,6 +106,7 @@ class ReportFooter extends React.Component { reportActions={this.props.reportActions} report={this.props.report} isComposerFullSize={this.props.isComposerFullSize} + disabled={this.props.shouldDisableCompose} />