From 74422170370cefab92bc5b38d51a87376cb6bcf5 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 20 Feb 2022 10:08:10 +0530 Subject: [PATCH 001/126] feat: Add keyboard nav prop --- src/components/PopoverMenu/popoverMenuPropTypes.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/PopoverMenu/popoverMenuPropTypes.js b/src/components/PopoverMenu/popoverMenuPropTypes.js index 402b63418d1b..3ed64a18d7a9 100644 --- a/src/components/PopoverMenu/popoverMenuPropTypes.js +++ b/src/components/PopoverMenu/popoverMenuPropTypes.js @@ -49,6 +49,9 @@ const propTypes = { /** Whether disable the animations */ disableAnimation: PropTypes.bool, + + /** Enable keyboard navigation for menu items */ + allowKeyboardNavigation: PropTypes.bool, }; const defaultProps = { @@ -56,6 +59,7 @@ const defaultProps = { animationOut: 'fadeOut', headerText: undefined, disableAnimation: true, + allowKeyboardNavigation: false, }; export {propTypes, defaultProps}; From 7b4f2c4062ee17f91e7e1030f0cf9b6251a36888 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 20 Feb 2022 10:08:26 +0530 Subject: [PATCH 002/126] feat: MenuItem focused handling --- src/components/PopoverMenu/BasePopoverMenu.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 32551ba203d0..e0f7a77bf4cc 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -48,7 +48,7 @@ class BasePopoverMenu extends PureComponent { )} - {_.map(this.props.menuItems, item => ( + {_.map(this.props.menuItems, (item, index) => ( this.props.onItemSelected(item)} + focused={index === this.state.activeMenuIndex} /> ))} From 04c7aa60c918027821766d6a9a7d1abce6e166e9 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 20 Feb 2022 10:12:49 +0530 Subject: [PATCH 003/126] feat: Added keyboard nav handling to BasePopover --- src/components/PopoverMenu/BasePopoverMenu.js | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index e0f7a77bf4cc..a60732e28eb8 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -26,6 +26,75 @@ const defaultProps = { }; class BasePopoverMenu extends PureComponent { + constructor(props) { + super(props); + this.state = { + activeMenuIndex: -1, + }; + } + + componentDidMount() { + if (!this.props.allowKeyboardNavigation) { + return; + } + this.setupEventHandlers(); + } + + componentWillUnmount() { + if (!this.props.allowKeyboardNavigation) { + return; + } + this.cleanupEventHandlers(); + } + + setupEventHandlers() { + if (!document) { + return; + } + + this.keyDownHandler = (keyBoardEvent) => { + if (keyBoardEvent.key.startsWith('Arrow')) { + this.highlightActiveMenu(keyBoardEvent.key); + return; + } + + if (keyBoardEvent.key === 'Enter' && this.state.activeMenuIndex !== -1) { + this.props.onItemSelected(this.props.menuItems[this.state.activeMenuIndex]); + } + }; + } + + highlightActiveMenu(arrowKey) { + let activeMenuIndex = this.state.activeMenuIndex; + if (arrowKey !== 'ArrowDown' && arrowKey !== 'ArrowUp') { + return; + } + + if (arrowKey === 'ArrowDown') { + if (activeMenuIndex === -1 || activeMenuIndex === this.props.menuItems.length - 1) { + activeMenuIndex = 0; + } else { + activeMenuIndex += 1; + } + } + + if (arrowKey === 'ArrowUp') { + if (activeMenuIndex === -1 || activeMenuIndex === 0) { + activeMenuIndex = this.props.menuItems.length - 1; + } else { + activeMenuIndex -= 1; + } + } + this.setState(() => ({activeMenuIndex})); + } + + cleanupEventHandlers() { + if (!document) { + return; + } + document.removeEventListener('keydown', this.keyDownHandler, true); + } + render() { return ( Date: Sun, 20 Feb 2022 10:13:05 +0530 Subject: [PATCH 004/126] feat: Force disabled keyboard nav to native popover --- src/components/PopoverMenu/index.native.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/PopoverMenu/index.native.js b/src/components/PopoverMenu/index.native.js index 7cb8722e0d29..b4b8377d2868 100644 --- a/src/components/PopoverMenu/index.native.js +++ b/src/components/PopoverMenu/index.native.js @@ -28,6 +28,7 @@ class PopoverMenu extends Component { this.selectItem(item)} /> From 22c2ec43e4ddd8412bb75ddcfe9ae597a2fe21c0 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 20 Feb 2022 10:17:42 +0530 Subject: [PATCH 005/126] feat: Added border color focus and nav to compose actions --- src/components/PopoverMenu/BasePopoverMenu.js | 1 + src/pages/home/report/ReportActionCompose.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index a60732e28eb8..e7ef644c1975 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -127,6 +127,7 @@ class BasePopoverMenu extends PureComponent { description={item.description} onPress={() => this.props.onItemSelected(item)} focused={index === this.state.activeMenuIndex} + wrapperStyle={index === this.state.activeMenuIndex ? styles.borderColorFocus : {}} /> ))} diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index c25817ed821a..ae2a182b32f9 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -457,6 +457,7 @@ class ReportActionCompose extends React.Component { onClose={() => this.setMenuVisibility(false)} onItemSelected={() => this.setMenuVisibility(false)} anchorPosition={styles.createMenuPositionReportActionCompose} + allowKeyboardNavigation animationIn="fadeInUp" animationOut="fadeOutDown" menuItems={[ From 8e56baba11b1fce4f1318de9634b635433992517 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 20 Feb 2022 10:59:06 +0530 Subject: [PATCH 006/126] feat: Added separate styles for menu Item --- src/components/PopoverMenu/BasePopoverMenu.js | 4 ++-- src/styles/styles.js | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index e7ef644c1975..1af979820289 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -51,7 +51,6 @@ class BasePopoverMenu extends PureComponent { if (!document) { return; } - this.keyDownHandler = (keyBoardEvent) => { if (keyBoardEvent.key.startsWith('Arrow')) { this.highlightActiveMenu(keyBoardEvent.key); @@ -62,6 +61,7 @@ class BasePopoverMenu extends PureComponent { this.props.onItemSelected(this.props.menuItems[this.state.activeMenuIndex]); } }; + document.addEventListener('keydown', this.keyDownHandler, true); } highlightActiveMenu(arrowKey) { @@ -127,7 +127,7 @@ class BasePopoverMenu extends PureComponent { description={item.description} onPress={() => this.props.onItemSelected(item)} focused={index === this.state.activeMenuIndex} - wrapperStyle={index === this.state.activeMenuIndex ? styles.borderColorFocus : {}} + wrapperStyle={index === this.state.activeMenuIndex ? styles.focusedPopoverMenuItem : {}} /> ))} diff --git a/src/styles/styles.js b/src/styles/styles.js index efa5ab09f0f6..62c48a791b82 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1065,6 +1065,12 @@ const styles = { width: '100%', }, + focusedPopoverMenuItem: { + borderWidth: 1, + borderRadius: 0, + borderColor: themeColors.borderFocus, + }, + popoverMenuIcon: { width: variables.componentSizeNormal, height: variables.componentSizeNormal, From 375193f6eb9c6ce00cd03a932e5e4b727f3d85a6 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 20 Feb 2022 17:44:19 +0530 Subject: [PATCH 007/126] feat: Reset activeMenuIndex on Popver close --- src/components/PopoverMenu/BasePopoverMenu.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 1af979820289..078b3672163a 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -31,6 +31,7 @@ class BasePopoverMenu extends PureComponent { this.state = { activeMenuIndex: -1, }; + this.onModalHide = this.onModalHide.bind(this); } componentDidMount() { @@ -47,6 +48,11 @@ class BasePopoverMenu extends PureComponent { this.cleanupEventHandlers(); } + onModalHide() { + this.setState({activeMenuIndex: -1}); + this.props.onMenuHide(); + } + setupEventHandlers() { if (!document) { return; @@ -101,7 +107,7 @@ class BasePopoverMenu extends PureComponent { anchorPosition={this.props.anchorPosition} onClose={this.props.onClose} isVisible={this.props.isVisible} - onModalHide={this.props.onMenuHide} + onModalHide={this.onModalHide} animationIn={this.props.animationIn} animationOut={this.props.animationOut} disableAnimation={this.props.disableAnimation} From 0832d6bbe89e8c6d7f6ac1d54a860a8837f37ee3 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 20 Feb 2022 22:18:35 +0530 Subject: [PATCH 008/126] feat: Removed side borders --- src/styles/styles.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/styles/styles.js b/src/styles/styles.js index 62c48a791b82..ab7a1f46e505 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1068,6 +1068,8 @@ const styles = { focusedPopoverMenuItem: { borderWidth: 1, borderRadius: 0, + borderRightWidth: 0, + borderLeftWidth: 0, borderColor: themeColors.borderFocus, }, From fe073c34429b1a84c1e39a8b9b85193d0e265d5b Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Mon, 21 Mar 2022 21:11:18 +0530 Subject: [PATCH 009/126] fix: removed keyboard flag from native popover --- src/components/PopoverMenu/index.native.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/PopoverMenu/index.native.js b/src/components/PopoverMenu/index.native.js index b4b8377d2868..7cb8722e0d29 100644 --- a/src/components/PopoverMenu/index.native.js +++ b/src/components/PopoverMenu/index.native.js @@ -28,7 +28,6 @@ class PopoverMenu extends Component { this.selectItem(item)} /> From 12f03aac2820e676b41068c8d9cabf911a37f05a Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Mon, 21 Mar 2022 21:11:37 +0530 Subject: [PATCH 010/126] feat: added transparent border for non focused items --- src/components/PopoverMenu/BasePopoverMenu.js | 2 +- src/styles/styles.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 078b3672163a..79d7f75680c8 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -133,7 +133,7 @@ class BasePopoverMenu extends PureComponent { description={item.description} onPress={() => this.props.onItemSelected(item)} focused={index === this.state.activeMenuIndex} - wrapperStyle={index === this.state.activeMenuIndex ? styles.focusedPopoverMenuItem : {}} + wrapperStyle={[styles.unfocusedPopoverMenuItem, index === this.state.activeMenuIndex ? styles.focusedPopoverMenuItem : {}]} /> ))} diff --git a/src/styles/styles.js b/src/styles/styles.js index 42168875cee6..0a787bdbfbc4 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1054,11 +1054,15 @@ const styles = { }, focusedPopoverMenuItem: { + borderColor: themeColors.borderFocus, + }, + + unfocusedPopoverMenuItem: { borderWidth: 1, borderRadius: 0, borderRightWidth: 0, borderLeftWidth: 0, - borderColor: themeColors.borderFocus, + borderColor: 'transparent', }, popoverMenuIcon: { From ba9773079626299f4616fc92a560f93dcbc16247 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Mon, 21 Mar 2022 21:21:27 +0530 Subject: [PATCH 011/126] feat: add onFocus to MenuItem Pressable --- src/components/MenuItem.js | 4 ++++ src/components/menuItemPropTypes.js | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 6c5c20eb008e..0a5f702ecce6 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -38,6 +38,7 @@ const defaultProps = { subtitle: undefined, iconType: 'icon', onPress: () => {}, + onFocus: () => {}, interactive: true, }; @@ -50,6 +51,9 @@ const MenuItem = props => ( props.onPress(e); }} + onFocus={(e) => { + props.onFocus(e); + }} style={({hovered, pressed}) => ([ styles.popoverMenuItem, StyleUtils.getButtonBackgroundColorStyle(getButtonState(props.focused || hovered, pressed, props.success, props.disabled, props.interactive)), diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index 0ad5a43498af..58635b9d799d 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -13,6 +13,9 @@ const propTypes = { /** Function to fire when component is pressed */ onPress: PropTypes.func, + /** Function to fire when component is focused */ + onFocus: PropTypes.func, + /** Icon to display on the left side of component */ icon: PropTypes.oneOfType([PropTypes.elementType, PropTypes.string]), From 7fa16c4fd9faf213148dfff5fc78b1c872c84a1b Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Mon, 21 Mar 2022 21:21:37 +0530 Subject: [PATCH 012/126] feat: set activeMenuIndex on tab --- src/components/PopoverMenu/BasePopoverMenu.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 79d7f75680c8..5e8124f3e704 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -133,6 +133,7 @@ class BasePopoverMenu extends PureComponent { description={item.description} onPress={() => this.props.onItemSelected(item)} focused={index === this.state.activeMenuIndex} + onFocus={() => this.setState({activeMenuIndex: index})} wrapperStyle={[styles.unfocusedPopoverMenuItem, index === this.state.activeMenuIndex ? styles.focusedPopoverMenuItem : {}]} /> ))} From 41d2ddfef8d82136791b60b4b6bf209282844242 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Tue, 19 Jul 2022 03:32:11 +0530 Subject: [PATCH 013/126] fix: rollback basepopover changes --- src/components/PopoverMenu/BasePopoverMenu.js | 82 +------------------ src/pages/home/report/ReportActionCompose.js | 73 +++++++++-------- 2 files changed, 39 insertions(+), 116 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 5e8124f3e704..32551ba203d0 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -26,88 +26,13 @@ const defaultProps = { }; class BasePopoverMenu extends PureComponent { - constructor(props) { - super(props); - this.state = { - activeMenuIndex: -1, - }; - this.onModalHide = this.onModalHide.bind(this); - } - - componentDidMount() { - if (!this.props.allowKeyboardNavigation) { - return; - } - this.setupEventHandlers(); - } - - componentWillUnmount() { - if (!this.props.allowKeyboardNavigation) { - return; - } - this.cleanupEventHandlers(); - } - - onModalHide() { - this.setState({activeMenuIndex: -1}); - this.props.onMenuHide(); - } - - setupEventHandlers() { - if (!document) { - return; - } - this.keyDownHandler = (keyBoardEvent) => { - if (keyBoardEvent.key.startsWith('Arrow')) { - this.highlightActiveMenu(keyBoardEvent.key); - return; - } - - if (keyBoardEvent.key === 'Enter' && this.state.activeMenuIndex !== -1) { - this.props.onItemSelected(this.props.menuItems[this.state.activeMenuIndex]); - } - }; - document.addEventListener('keydown', this.keyDownHandler, true); - } - - highlightActiveMenu(arrowKey) { - let activeMenuIndex = this.state.activeMenuIndex; - if (arrowKey !== 'ArrowDown' && arrowKey !== 'ArrowUp') { - return; - } - - if (arrowKey === 'ArrowDown') { - if (activeMenuIndex === -1 || activeMenuIndex === this.props.menuItems.length - 1) { - activeMenuIndex = 0; - } else { - activeMenuIndex += 1; - } - } - - if (arrowKey === 'ArrowUp') { - if (activeMenuIndex === -1 || activeMenuIndex === 0) { - activeMenuIndex = this.props.menuItems.length - 1; - } else { - activeMenuIndex -= 1; - } - } - this.setState(() => ({activeMenuIndex})); - } - - cleanupEventHandlers() { - if (!document) { - return; - } - document.removeEventListener('keydown', this.keyDownHandler, true); - } - render() { return ( )} - {_.map(this.props.menuItems, (item, index) => ( + {_.map(this.props.menuItems, item => ( this.props.onItemSelected(item)} - focused={index === this.state.activeMenuIndex} - onFocus={() => this.setState({activeMenuIndex: index})} - wrapperStyle={[styles.unfocusedPopoverMenuItem, index === this.state.activeMenuIndex ? styles.focusedPopoverMenuItem : {}]} /> ))} diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 5148c16922e4..dec9eab90b84 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -7,7 +7,7 @@ import { } from 'react-native'; import _ from 'underscore'; import lodashGet from 'lodash/get'; -import {withOnyx} from 'react-native-onyx'; +import { withOnyx } from 'react-native-onyx'; import lodashIntersection from 'lodash/intersection'; import styles from '../../../styles/styles'; import themeColors from '../../../styles/themes/default'; @@ -21,11 +21,11 @@ import ReportTypingIndicator from './ReportTypingIndicator'; import AttachmentModal from '../../../components/AttachmentModal'; import compose from '../../../libs/compose'; import PopoverMenu from '../../../components/PopoverMenu'; -import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; +import withWindowDimensions, { windowDimensionsPropTypes } from '../../../components/withWindowDimensions'; import withDrawerState from '../../../components/withDrawerState'; import CONST from '../../../CONST'; import canFocusInputOnScreenFocus from '../../../libs/canFocusInputOnScreenFocus'; -import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import withLocalize, { withLocalizePropTypes } from '../../../components/withLocalize'; import Permissions from '../../../libs/Permissions'; import Navigation from '../../../libs/Navigation/Navigation'; import ROUTES from '../../../ROUTES'; @@ -34,8 +34,8 @@ import * as ReportUtils from '../../../libs/ReportUtils'; import ReportActionComposeFocusManager from '../../../libs/ReportActionComposeFocusManager'; import participantPropTypes from '../../../components/participantPropTypes'; import ParticipantLocalTime from './ParticipantLocalTime'; -import {withPersonalDetails} from '../../../components/OnyxProvider'; -import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../../components/withCurrentUserPersonalDetails'; +import { withPersonalDetails } from '../../../components/OnyxProvider'; +import withCurrentUserPersonalDetails, { withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps } from '../../../components/withCurrentUserPersonalDetails'; import * as User from '../../../libs/actions/User'; import Tooltip from '../../../components/Tooltip'; import EmojiPickerButton from '../../../components/EmojiPicker/EmojiPickerButton'; @@ -189,7 +189,7 @@ class ReportActionCompose extends React.Component { } onSelectionChange(e) { - this.setState({selection: e.nativeEvent.selection}); + this.setState({ selection: e.nativeEvent.selection }); } /** @@ -198,11 +198,11 @@ class ReportActionCompose extends React.Component { * @param {Boolean} shouldHighlight */ setIsFocused(shouldHighlight) { - this.setState({isFocused: shouldHighlight}); + this.setState({ isFocused: shouldHighlight }); } setIsFullComposerAvailable(isFullComposerAvailable) { - this.setState({isFullComposerAvailable}); + this.setState({ isFullComposerAvailable }); } /** @@ -211,7 +211,7 @@ class ReportActionCompose extends React.Component { * @param {Boolean} shouldClear */ setTextInputShouldClear(shouldClear) { - this.setState({textInputShouldClear: shouldClear}); + this.setState({ textInputShouldClear: shouldClear }); } /** @@ -220,7 +220,7 @@ class ReportActionCompose extends React.Component { * @param {Boolean} isMenuVisible */ setMenuVisibility(isMenuVisible) { - this.setState({isMenuVisible}); + this.setState({ isMenuVisible }); } /** @@ -298,7 +298,7 @@ class ReportActionCompose extends React.Component { if (this.props.isComposerFullSize) { maxLines = CONST.COMPOSER.MAX_LINES_FULL; } - this.setState({maxLines}); + this.setState({ maxLines }); } /** @@ -370,7 +370,7 @@ class ReportActionCompose extends React.Component { * @param {String} newComment */ updateComment(newComment) { - this.textInput.setNativeProps({text: newComment}); + this.textInput.setNativeProps({ text: newComment }); this.setState({ isCommentEmpty: !!newComment.match(/^(\s|`)*$/), }); @@ -418,7 +418,7 @@ class ReportActionCompose extends React.Component { ); if (reportActionKey !== -1 && this.props.reportActions[reportActionKey]) { - const {reportActionID, message} = this.props.reportActions[reportActionKey]; + const { reportActionID, message } = this.props.reportActions[reportActionKey]; Report.saveReportActionDraft(this.props.reportID, reportActionID, _.last(message).html); } } @@ -440,10 +440,10 @@ class ReportActionCompose extends React.Component { if (this.props.isComposerFullSize) { Report.setIsComposerFullSize(this.props.reportID, false); } - this.setState({isFullComposerAvailable: false}); + this.setState({ isFullComposerAvailable: false }); // Important to reset the selection on Submit action - this.textInput.setNativeProps({selection: {start: 0, end: 0}}); + this.textInput.setNativeProps({ selection: { start: 0, end: 0 } }); return trimmedComment; } @@ -471,7 +471,8 @@ class ReportActionCompose extends React.Component { return null; } - const reportParticipants = _.without(lodashGet(this.props.report, 'participants', []), this.props.myPersonalDetails.login); + console.log('My Personal Details', this.props.personalDetails); + const reportParticipants = _.without(lodashGet(this.props.report, 'participants', []), this.props.personalDetails.login); const participantsWithoutExpensifyEmails = _.difference(reportParticipants, CONST.EXPENSIFY_EMAILS); const reportRecipient = this.props.personalDetails[participantsWithoutExpensifyEmails[0]]; @@ -506,10 +507,10 @@ class ReportActionCompose extends React.Component { this.setTextInputShouldClear(false); }} > - {({displayFileInModal}) => ( + {({ displayFileInModal }) => ( <> - {({openPicker}) => ( + {({ openPicker }) => ( <> this.setMenuVisibility(false)} anchorPosition={styles.createMenuPositionReportActionCompose} menuItems={[...this.getIOUOptions(reportParticipants), - { - icon: Expensicons.Paperclip, - text: this.props.translate('reportActionCompose.addAttachment'), - onSelected: () => { - openPicker({ - onPicked: (file) => { - displayFileInModal({file}); - }, - }); - }, + { + icon: Expensicons.Paperclip, + text: this.props.translate('reportActionCompose.addAttachment'), + onSelected: () => { + openPicker({ + onPicked: (file) => { + displayFileInModal({ file }); + }, + }); }, + }, ]} /> @@ -598,16 +599,16 @@ class ReportActionCompose extends React.Component { return; } - this.setState({isDraggingOver: true}); + this.setState({ isDraggingOver: true }); }} onDragOver={(e, isOriginComposer) => { if (!isOriginComposer) { return; } - this.setState({isDraggingOver: true}); + this.setState({ isDraggingOver: true }); }} - onDragLeave={() => this.setState({isDraggingOver: false})} + onDragLeave={() => this.setState({ isDraggingOver: false })} onDrop={(e) => { e.preventDefault(); @@ -616,15 +617,15 @@ class ReportActionCompose extends React.Component { return; } - displayFileInModal({file}); - this.setState({isDraggingOver: false}); + displayFileInModal({ file }); + this.setState({ isDraggingOver: false }); }} style={[styles.textInputCompose, this.props.isComposerFullSize ? styles.textInputFullCompose : styles.flex4]} defaultValue={this.props.comment} maxLines={this.state.maxLines} onFocus={() => this.setIsFocused(true)} onBlur={() => this.setIsFocused(false)} - onPasteFile={file => displayFileInModal({file})} + onPasteFile={file => displayFileInModal({ file })} shouldClear={this.state.textInputShouldClear} onClear={() => this.setTextInputShouldClear(false)} isDisabled={isComposeDisabled || isBlockedFromConcierge} @@ -693,7 +694,7 @@ export default compose( key: ONYXKEYS.BETAS, }, comment: { - key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, + key: ({ reportID }) => `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, }, modal: { key: ONYXKEYS.MODAL, @@ -702,4 +703,4 @@ export default compose( key: ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE, }, }), -)(ReportActionCompose); \ No newline at end of file +)(ReportActionCompose); From eed19be4ae8e7ad2c65b396b16f9d9bc50a5dd1f Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sun, 24 Jul 2022 22:47:44 +0530 Subject: [PATCH 014/126] style: indent and space fixes --- src/pages/home/report/ReportActionCompose.js | 64 ++++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 956632723d59..c2cf3b9262b3 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -7,7 +7,7 @@ import { } from 'react-native'; import _ from 'underscore'; import lodashGet from 'lodash/get'; -import { withOnyx } from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import lodashIntersection from 'lodash/intersection'; import styles from '../../../styles/styles'; import themeColors from '../../../styles/themes/default'; @@ -21,11 +21,11 @@ import ReportTypingIndicator from './ReportTypingIndicator'; import AttachmentModal from '../../../components/AttachmentModal'; import compose from '../../../libs/compose'; import PopoverMenu from '../../../components/PopoverMenu'; -import withWindowDimensions, { windowDimensionsPropTypes } from '../../../components/withWindowDimensions'; +import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; import withDrawerState from '../../../components/withDrawerState'; import CONST from '../../../CONST'; import canFocusInputOnScreenFocus from '../../../libs/canFocusInputOnScreenFocus'; -import withLocalize, { withLocalizePropTypes } from '../../../components/withLocalize'; +import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; import Permissions from '../../../libs/Permissions'; import Navigation from '../../../libs/Navigation/Navigation'; import ROUTES from '../../../ROUTES'; @@ -189,7 +189,7 @@ class ReportActionCompose extends React.Component { } onSelectionChange(e) { - this.setState({ selection: e.nativeEvent.selection }); + this.setState({selection: e.nativeEvent.selection}); } /** @@ -198,11 +198,11 @@ class ReportActionCompose extends React.Component { * @param {Boolean} shouldHighlight */ setIsFocused(shouldHighlight) { - this.setState({ isFocused: shouldHighlight }); + this.setState({isFocused: shouldHighlight}); } setIsFullComposerAvailable(isFullComposerAvailable) { - this.setState({ isFullComposerAvailable }); + this.setState({isFullComposerAvailable}); } /** @@ -211,7 +211,7 @@ class ReportActionCompose extends React.Component { * @param {Boolean} shouldClear */ setTextInputShouldClear(shouldClear) { - this.setState({ textInputShouldClear: shouldClear }); + this.setState({textInputShouldClear: shouldClear}); } /** @@ -220,7 +220,7 @@ class ReportActionCompose extends React.Component { * @param {Boolean} isMenuVisible */ setMenuVisibility(isMenuVisible) { - this.setState({ isMenuVisible }); + this.setState({isMenuVisible}); } /** @@ -298,7 +298,7 @@ class ReportActionCompose extends React.Component { if (this.props.isComposerFullSize) { maxLines = CONST.COMPOSER.MAX_LINES_FULL; } - this.setState({ maxLines }); + this.setState({maxLines}); } /** @@ -370,7 +370,7 @@ class ReportActionCompose extends React.Component { * @param {String} newComment */ updateComment(newComment) { - this.textInput.setNativeProps({ text: newComment }); + this.textInput.setNativeProps({text: newComment}); this.setState({ isCommentEmpty: !!newComment.match(/^(\s|`)*$/), }); @@ -418,7 +418,7 @@ class ReportActionCompose extends React.Component { ); if (reportActionKey !== -1 && this.props.reportActions[reportActionKey]) { - const { reportActionID, message } = this.props.reportActions[reportActionKey]; + const {reportActionID, message} = this.props.reportActions[reportActionKey]; Report.saveReportActionDraft(this.props.reportID, reportActionID, _.last(message).html); } } @@ -440,10 +440,10 @@ class ReportActionCompose extends React.Component { if (this.props.isComposerFullSize) { Report.setIsComposerFullSize(this.props.reportID, false); } - this.setState({ isFullComposerAvailable: false }); + this.setState({isFullComposerAvailable: false}); // Important to reset the selection on Submit action - this.textInput.setNativeProps({ selection: { start: 0, end: 0 } }); + this.textInput.setNativeProps({selection: {start: 0, end: 0}}); return trimmedComment; } @@ -506,10 +506,10 @@ class ReportActionCompose extends React.Component { this.setTextInputShouldClear(false); }} > - {({ displayFileInModal }) => ( + {({displayFileInModal}) => ( <> - {({ openPicker }) => ( + {({openPicker}) => ( <> this.setMenuVisibility(false)} anchorPosition={styles.createMenuPositionReportActionCompose} menuItems={[...this.getIOUOptions(reportParticipants), - { - icon: Expensicons.Paperclip, - text: this.props.translate('reportActionCompose.addAttachment'), - onSelected: () => { - openPicker({ - onPicked: (file) => { - displayFileInModal({ file }); - }, - }); + { + icon: Expensicons.Paperclip, + text: this.props.translate('reportActionCompose.addAttachment'), + onSelected: () => { + openPicker({ + onPicked: (file) => { + displayFileInModal({file}); + }, + }); + }, }, - }, ]} /> @@ -598,16 +598,16 @@ class ReportActionCompose extends React.Component { return; } - this.setState({ isDraggingOver: true }); + this.setState({isDraggingOver: true}); }} onDragOver={(e, isOriginComposer) => { if (!isOriginComposer) { return; } - this.setState({ isDraggingOver: true }); + this.setState({isDraggingOver: true}); }} - onDragLeave={() => this.setState({ isDraggingOver: false })} + onDragLeave={() => this.setState({isDraggingOver: false})} onDrop={(e) => { e.preventDefault(); @@ -616,15 +616,15 @@ class ReportActionCompose extends React.Component { return; } - displayFileInModal({ file }); - this.setState({ isDraggingOver: false }); + displayFileInModal({file}); + this.setState({isDraggingOver: false}); }} style={[styles.textInputCompose, this.props.isComposerFullSize ? styles.textInputFullCompose : styles.flex4]} defaultValue={this.props.comment} maxLines={this.state.maxLines} onFocus={() => this.setIsFocused(true)} onBlur={() => this.setIsFocused(false)} - onPasteFile={file => displayFileInModal({ file })} + onPasteFile={file => displayFileInModal({file})} shouldClear={this.state.textInputShouldClear} onClear={() => this.setTextInputShouldClear(false)} isDisabled={isComposeDisabled || isBlockedFromConcierge} @@ -694,7 +694,7 @@ export default compose( key: ONYXKEYS.BETAS, }, comment: { - key: ({ reportID }) => `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, + key: ({reportID}) => `${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`, }, modal: { key: ONYXKEYS.MODAL, From e22971580787bfc72bb3e3b95171b90a6be0c909 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Fri, 19 Aug 2022 00:40:04 +0530 Subject: [PATCH 015/126] added onLayout to textinput perent component & used dynamic height in textinput component --- src/components/TextInput/BaseTextInput.js | 13 +++++++++++++ src/styles/styles.js | 1 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/TextInput/BaseTextInput.js b/src/components/TextInput/BaseTextInput.js index a083af0f2e16..c170564f72f6 100644 --- a/src/components/TextInput/BaseTextInput.js +++ b/src/components/TextInput/BaseTextInput.js @@ -14,6 +14,7 @@ import * as Expensicons from '../Icon/Expensicons'; import Text from '../Text'; import * as styleConst from './styleConst'; import * as StyleUtils from '../../styles/StyleUtils'; +import variables from '../../styles/variables'; import getSecureEntryKeyboardType from '../../libs/getSecureEntryKeyboardType'; class BaseTextInput extends Component { @@ -30,6 +31,7 @@ class BaseTextInput extends Component { passwordHidden: props.secureTextEntry, textInputWidth: 0, prefixWidth: 0, + height: variables.componentSizeLarge, // Value should be kept in state for the autoGrow feature to work - https://github.com/Expensify/App/pull/8232#issuecomment-1077282006 value, @@ -212,6 +214,16 @@ class BaseTextInput extends Component { > ( + this.setState({ + height: event.nativeEvent.layout.height, + }) + ), + } : null} style={[ textInputContainerStyles, @@ -264,6 +276,7 @@ class BaseTextInput extends Component { !hasLabel && styles.pv0, this.props.prefixCharacter && StyleUtils.getPaddingLeft(this.state.prefixWidth + styles.pl1.paddingLeft), this.props.secureTextEntry && styles.secureInput, + !this.props.multiline && {height: this.state.height}, ]} multiline={this.props.multiline} maxLength={this.props.maxLength} diff --git a/src/styles/styles.js b/src/styles/styles.js index 9baa3463ecd4..f459fbda4139 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -737,7 +737,6 @@ const styles = { paddingBottom: 8, paddingHorizontal: 11, borderWidth: 0, - borderRadius: variables.componentBorderRadiusNormal, }, textInputMultiline: { From 23a62075bcfd41c6a81947aec158e3dcc13bbbea Mon Sep 17 00:00:00 2001 From: Rocio Perez-Cano Date: Tue, 23 Aug 2022 15:05:38 +0200 Subject: [PATCH 016/126] Use legal names for updating wallet --- src/libs/actions/Wallet.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Wallet.js b/src/libs/actions/Wallet.js index 529f95fa90bf..dae0259236ac 100644 --- a/src/libs/actions/Wallet.js +++ b/src/libs/actions/Wallet.js @@ -173,8 +173,8 @@ function updatePersonalDetails(personalDetails) { const ssn = personalDetails.ssn || ''; const phoneNumber = personalDetails.phoneNumber || ''; API.write('UpdatePersonalDetailsForWallet', { - firstName, - lastName, + legalFirstName: firstName, + legalLastName: lastName, dob, addressStreet, addressCity, From cec8a809a5511a358f38163134052c152634a008 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 00:30:52 +0530 Subject: [PATCH 017/126] fix: remove unwanted prop --- src/components/PopoverMenu/popoverMenuPropTypes.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/PopoverMenu/popoverMenuPropTypes.js b/src/components/PopoverMenu/popoverMenuPropTypes.js index 3ed64a18d7a9..402b63418d1b 100644 --- a/src/components/PopoverMenu/popoverMenuPropTypes.js +++ b/src/components/PopoverMenu/popoverMenuPropTypes.js @@ -49,9 +49,6 @@ const propTypes = { /** Whether disable the animations */ disableAnimation: PropTypes.bool, - - /** Enable keyboard navigation for menu items */ - allowKeyboardNavigation: PropTypes.bool, }; const defaultProps = { @@ -59,7 +56,6 @@ const defaultProps = { animationOut: 'fadeOut', headerText: undefined, disableAnimation: true, - allowKeyboardNavigation: false, }; export {propTypes, defaultProps}; From dd040c07e9b3ff98ba7d0cc26e7199383bdc1cdf Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 00:57:39 +0530 Subject: [PATCH 018/126] feat: added ArrowKeyFocusManager for MenuItems --- src/components/PopoverMenu/BasePopoverMenu.js | 45 ++++++++++++++----- .../PopoverMenu/popoverMenuPropTypes.js | 4 ++ src/pages/home/report/ReportActionCompose.js | 1 + 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 32551ba203d0..c753ad714701 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -10,6 +10,7 @@ import { propTypes as createMenuPropTypes, defaultProps as defaultCreateMenuPropTypes, } from './popoverMenuPropTypes'; +import ArrowKeyFocusManager from '../ArrowKeyFocusManager'; import Text from '../Text'; const propTypes = { @@ -26,6 +27,21 @@ const defaultProps = { }; class BasePopoverMenu extends PureComponent { + constructor(props) { + super(props); + this.state = { + focusedIndex: -1, + }; + this.updateFocusedIndex = this.updateFocusedIndex.bind(this); + } + + /** + * @param {Number} index + */ + updateFocusedIndex(index) { + this.setState({focusedIndex: index}); + } + render() { return ( )} - {_.map(this.props.menuItems, item => ( - this.props.onItemSelected(item)} - /> - ))} + { }} + > + {_.map(this.props.menuItems, (item, menuIndex) => ( + this.props.onItemSelected(item)} + /> + ))} + ); diff --git a/src/components/PopoverMenu/popoverMenuPropTypes.js b/src/components/PopoverMenu/popoverMenuPropTypes.js index 402b63418d1b..ae5724232575 100644 --- a/src/components/PopoverMenu/popoverMenuPropTypes.js +++ b/src/components/PopoverMenu/popoverMenuPropTypes.js @@ -49,6 +49,9 @@ const propTypes = { /** Whether disable the animations */ disableAnimation: PropTypes.bool, + + /** Whether to allow arrow key actions on the list */ + enableArrowKeysActions: PropTypes.bool, }; const defaultProps = { @@ -56,6 +59,7 @@ const defaultProps = { animationOut: 'fadeOut', headerText: undefined, disableAnimation: true, + enableArrowKeysActions: false, }; export {propTypes, defaultProps}; diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 2b9384f2db67..0a05afd0977a 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -573,6 +573,7 @@ class ReportActionCompose extends React.Component { this.setMenuVisibility(false)} onItemSelected={() => this.setMenuVisibility(false)} From cc56815ec7393cd436e89f1f66eff630312d56a8 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 01:34:26 +0530 Subject: [PATCH 019/126] feat: focus when the index match --- src/components/PopoverMenu/BasePopoverMenu.js | 3 ++- src/styles/styles.js | 12 ------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index c753ad714701..397efd7c4b5f 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -77,8 +77,9 @@ class BasePopoverMenu extends PureComponent { iconHeight={item.iconHeight} title={item.text} description={item.description} - focused={this.state.focusedIndex === menuIndex} onPress={() => this.props.onItemSelected(item)} + onFocus={() => this.updateFocusedIndex(menuIndex)} + focused={this.state.focusedIndex === menuIndex} /> ))} diff --git a/src/styles/styles.js b/src/styles/styles.js index c267f6b19bb9..36a4d7eaea40 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1110,18 +1110,6 @@ const styles = { width: '100%', }, - focusedPopoverMenuItem: { - borderColor: themeColors.borderFocus, - }, - - unfocusedPopoverMenuItem: { - borderWidth: 1, - borderRadius: 0, - borderRightWidth: 0, - borderLeftWidth: 0, - borderColor: 'transparent', - }, - popoverMenuIcon: { width: variables.componentSizeNormal, height: variables.componentSizeNormal, From 3734c99034025d7b120ecaca2be92f066ccd1bdb Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 01:36:21 +0530 Subject: [PATCH 020/126] refactor: remove unused onfocus prop --- src/components/menuItemPropTypes.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index e2ca89e33fe8..65f0dbf48d03 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -16,9 +16,6 @@ const propTypes = { /** Function to fire when component is pressed */ onPress: PropTypes.func, - /** Function to fire when component is focused */ - onFocus: PropTypes.func, - /** Icon to display on the left side of component */ icon: PropTypes.oneOfType([PropTypes.elementType, PropTypes.string]), From 4bc3cc2db5d0849c2b3d4f83ade30671c965254d Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 02:43:21 +0530 Subject: [PATCH 021/126] feat: add enter handler --- src/components/PopoverMenu/BasePopoverMenu.js | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 397efd7c4b5f..66dbe70834f7 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -12,6 +12,8 @@ import { } from './popoverMenuPropTypes'; import ArrowKeyFocusManager from '../ArrowKeyFocusManager'; import Text from '../Text'; +import KeyboardShortcut from '../../libs/KeyboardShortcut'; +import CONST from '../../CONST'; const propTypes = { /** Callback fired when the menu is completely closed */ @@ -35,6 +37,25 @@ class BasePopoverMenu extends PureComponent { this.updateFocusedIndex = this.updateFocusedIndex.bind(this); } + componentDidMount() { + if (!this.props.enableArrowKeysActions) { + return; + } + + const shortcutConfig = CONST.KEYBOARD_SHORTCUTS.ENTER; + this.unsubscribeEnterKey = KeyboardShortcut.subscribe(shortcutConfig.shortcutKey, () => { + this.props.onItemSelected(this.props.menuItems[this.state.focusedIndex]); + this.updateFocusedIndex(-1); + }, shortcutConfig.descriptionKey, shortcutConfig.modifiers, true); + } + + componentWillUnmount() { + if (!this.unsubscribeEnterKey) { + return; + } + this.unsubscribeEscapeKey(); + } + /** * @param {Number} index */ @@ -78,7 +99,6 @@ class BasePopoverMenu extends PureComponent { title={item.text} description={item.description} onPress={() => this.props.onItemSelected(item)} - onFocus={() => this.updateFocusedIndex(menuIndex)} focused={this.state.focusedIndex === menuIndex} /> ))} From ff0a77f05ea32a14d9d364a8f28ffd1b43494819 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 02:48:16 +0530 Subject: [PATCH 022/126] feat: attach listener only to isVisible popup --- src/components/PopoverMenu/BasePopoverMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 66dbe70834f7..79665d991790 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -38,7 +38,7 @@ class BasePopoverMenu extends PureComponent { } componentDidMount() { - if (!this.props.enableArrowKeysActions) { + if (!this.props.enableArrowKeysActions && !this.props.isVisible) { return; } From abe25ff3255992d6ec0e4f561c98b6401fe50565 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 03:01:32 +0530 Subject: [PATCH 023/126] fix: reset index on closure and other scenarios --- src/components/PopoverMenu/BasePopoverMenu.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 79665d991790..6631b567d930 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -50,6 +50,16 @@ class BasePopoverMenu extends PureComponent { } componentWillUnmount() { + this.removeKeyboardShorcuts(); + } + + onModalHide() { + this.removeKeyboardShorcuts(); + this.updateFocusedIndex(-1); + this.props.onMenuHide(); + } + + removeKeyboardShorcuts() { if (!this.unsubscribeEnterKey) { return; } @@ -60,6 +70,9 @@ class BasePopoverMenu extends PureComponent { * @param {Number} index */ updateFocusedIndex(index) { + if (!this.props.enableArrowKeysActions) { + return; + } this.setState({focusedIndex: index}); } @@ -69,7 +82,7 @@ class BasePopoverMenu extends PureComponent { anchorPosition={this.props.anchorPosition} onClose={this.props.onClose} isVisible={this.props.isVisible} - onModalHide={this.props.onMenuHide} + onModalHide={this.onModalHide} animationIn={this.props.animationIn} animationOut={this.props.animationOut} disableAnimation={this.props.disableAnimation} @@ -88,7 +101,7 @@ class BasePopoverMenu extends PureComponent { { }} + onFocusedIndexChanged={this.updateFocusedIndex} > {_.map(this.props.menuItems, (item, menuIndex) => ( Date: Wed, 24 Aug 2022 03:02:43 +0530 Subject: [PATCH 024/126] fix: correct function name --- src/components/PopoverMenu/BasePopoverMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 6631b567d930..9f233faddea9 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -63,7 +63,7 @@ class BasePopoverMenu extends PureComponent { if (!this.unsubscribeEnterKey) { return; } - this.unsubscribeEscapeKey(); + this.unsubscribeEnterKey(); } /** From 79e80eabcd65829a58736ada1d082a3999b35d80 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 03:04:43 +0530 Subject: [PATCH 025/126] fix: added method binding --- src/components/PopoverMenu/BasePopoverMenu.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 9f233faddea9..4487c4d75274 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -35,6 +35,8 @@ class BasePopoverMenu extends PureComponent { focusedIndex: -1, }; this.updateFocusedIndex = this.updateFocusedIndex.bind(this); + this.removeKeyboardShorcuts = this.removeKeyboardShorcuts.bind(this); + this.onModalHide = this.onModalHide.bind(this); } componentDidMount() { @@ -44,6 +46,9 @@ class BasePopoverMenu extends PureComponent { const shortcutConfig = CONST.KEYBOARD_SHORTCUTS.ENTER; this.unsubscribeEnterKey = KeyboardShortcut.subscribe(shortcutConfig.shortcutKey, () => { + if (this.state.focusedIndex === -1) { + return; + } this.props.onItemSelected(this.props.menuItems[this.state.focusedIndex]); this.updateFocusedIndex(-1); }, shortcutConfig.descriptionKey, shortcutConfig.modifiers, true); From 953fbb048b3e7a9013be069c8404b0485727a7a8 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 03:06:43 +0530 Subject: [PATCH 026/126] fix: remove remove key function on modal hide --- src/components/PopoverMenu/BasePopoverMenu.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 4487c4d75274..a37cc39ac4ec 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -59,7 +59,6 @@ class BasePopoverMenu extends PureComponent { } onModalHide() { - this.removeKeyboardShorcuts(); this.updateFocusedIndex(-1); this.props.onMenuHide(); } From 52bf45618c5ebe090c7a84fa9c0f0427f61d3995 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 03:06:43 +0530 Subject: [PATCH 027/126] fix: remove remove key function on modal hide --- src/components/PopoverMenu/BasePopoverMenu.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 4487c4d75274..07dc672ffd3b 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -50,7 +50,7 @@ class BasePopoverMenu extends PureComponent { return; } this.props.onItemSelected(this.props.menuItems[this.state.focusedIndex]); - this.updateFocusedIndex(-1); + this.updateFocusedIndex(-1); // Reset the focusedIndex on selecting any menu }, shortcutConfig.descriptionKey, shortcutConfig.modifiers, true); } @@ -59,8 +59,7 @@ class BasePopoverMenu extends PureComponent { } onModalHide() { - this.removeKeyboardShorcuts(); - this.updateFocusedIndex(-1); + this.updateFocusedIndex(-1); // Reset the focusedIndex on modal hide this.props.onMenuHide(); } From 241e5ffd84954a1bb82832cc8fc9665624e6e35f Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 04:17:25 +0530 Subject: [PATCH 028/126] refactor: remove extra methods --- src/components/PopoverMenu/BasePopoverMenu.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 07dc672ffd3b..bc2d32d4f13c 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -35,8 +35,6 @@ class BasePopoverMenu extends PureComponent { focusedIndex: -1, }; this.updateFocusedIndex = this.updateFocusedIndex.bind(this); - this.removeKeyboardShorcuts = this.removeKeyboardShorcuts.bind(this); - this.onModalHide = this.onModalHide.bind(this); } componentDidMount() { @@ -55,15 +53,6 @@ class BasePopoverMenu extends PureComponent { } componentWillUnmount() { - this.removeKeyboardShorcuts(); - } - - onModalHide() { - this.updateFocusedIndex(-1); // Reset the focusedIndex on modal hide - this.props.onMenuHide(); - } - - removeKeyboardShorcuts() { if (!this.unsubscribeEnterKey) { return; } @@ -86,7 +75,10 @@ class BasePopoverMenu extends PureComponent { anchorPosition={this.props.anchorPosition} onClose={this.props.onClose} isVisible={this.props.isVisible} - onModalHide={this.onModalHide} + onModalHide={() => { + this.updateFocusedIndex(-1); // Reset the focusedIndex on modal hide + this.props.onMenuHide(); + }} animationIn={this.props.animationIn} animationOut={this.props.animationOut} disableAnimation={this.props.disableAnimation} From 3bbd0b565a7fcbc2896cbd0e283893807acf96d8 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Aug 2022 04:20:51 +0530 Subject: [PATCH 029/126] refactor: rename the flag to enable key actions --- src/components/PopoverMenu/BasePopoverMenu.js | 4 ++-- src/components/PopoverMenu/popoverMenuPropTypes.js | 4 ++-- src/pages/home/report/ReportActionCompose.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index bc2d32d4f13c..2d2b542c7427 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -38,7 +38,7 @@ class BasePopoverMenu extends PureComponent { } componentDidMount() { - if (!this.props.enableArrowKeysActions && !this.props.isVisible) { + if (!this.props.shouldEnableArrowKeysActions && !this.props.isVisible) { return; } @@ -63,7 +63,7 @@ class BasePopoverMenu extends PureComponent { * @param {Number} index */ updateFocusedIndex(index) { - if (!this.props.enableArrowKeysActions) { + if (!this.props.shouldEnableArrowKeysActions) { return; } this.setState({focusedIndex: index}); diff --git a/src/components/PopoverMenu/popoverMenuPropTypes.js b/src/components/PopoverMenu/popoverMenuPropTypes.js index ae5724232575..3ea1b3b1f630 100644 --- a/src/components/PopoverMenu/popoverMenuPropTypes.js +++ b/src/components/PopoverMenu/popoverMenuPropTypes.js @@ -51,7 +51,7 @@ const propTypes = { disableAnimation: PropTypes.bool, /** Whether to allow arrow key actions on the list */ - enableArrowKeysActions: PropTypes.bool, + shouldEnableArrowKeysActions: PropTypes.bool, }; const defaultProps = { @@ -59,7 +59,7 @@ const defaultProps = { animationOut: 'fadeOut', headerText: undefined, disableAnimation: true, - enableArrowKeysActions: false, + shouldEnableArrowKeysActions: false, }; export {propTypes, defaultProps}; diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 0a05afd0977a..fd5332ccacd2 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -573,7 +573,7 @@ class ReportActionCompose extends React.Component { this.setMenuVisibility(false)} onItemSelected={() => this.setMenuVisibility(false)} From 2e792055537aafcdbd64cbb8d401313e08cb1ead Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Thu, 25 Aug 2022 09:42:07 +0530 Subject: [PATCH 030/126] refactor: moved inline function to class method --- src/components/PopoverMenu/BasePopoverMenu.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 2d2b542c7427..c8ecdf1b1d09 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -35,6 +35,7 @@ class BasePopoverMenu extends PureComponent { focusedIndex: -1, }; this.updateFocusedIndex = this.updateFocusedIndex.bind(this); + this.resetFocusAndHideModal = this.resetFocusAndHideModal.bind(this); } componentDidMount() { @@ -69,16 +70,18 @@ class BasePopoverMenu extends PureComponent { this.setState({focusedIndex: index}); } + resetFocusAndHideModal() { + this.updateFocusedIndex(-1); // Reset the focusedIndex on modal hide + this.props.onMenuHide(); + } + render() { return ( { - this.updateFocusedIndex(-1); // Reset the focusedIndex on modal hide - this.props.onMenuHide(); - }} + onModalHide={this.resetFocusAndHideModal} animationIn={this.props.animationIn} animationOut={this.props.animationOut} disableAnimation={this.props.disableAnimation} From 607e5c5c2771cbc5a2959ebece4c616dad6210e4 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 25 Aug 2022 14:05:05 +0800 Subject: [PATCH 031/126] add copy --- src/languages/en.js | 1 + src/languages/es.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/languages/en.js b/src/languages/en.js index df85199e1c15..8ff452062147 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -830,6 +830,7 @@ export default { captureNoVBACopyAfterEmail: ' and download the Expensify App to track cash expenses on the go.', unlockNoVBACopy: 'Connect a bank account to reimburse your workspace members online.', fastReimbursementsVBACopy: 'You\'re all set to reimburse receipts from your bank account!', + updateCustomUnitError: "Your changes couldn't be saved. The workspace was modified while you were offline, please try again.", }, bills: { manageYourBills: 'Manage your bills', diff --git a/src/languages/es.js b/src/languages/es.js index 9bd3a33f6b58..2e202a3ef66c 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -832,6 +832,7 @@ export default { captureNoVBACopyAfterEmail: ' y descarga la App de Expensify para controlar tus gastos en efectivo sobre la marcha.', unlockNoVBACopy: 'Conecta una cuenta bancaria para reembolsar online a los miembros de tu espacio de trabajo.', fastReimbursementsVBACopy: '¡Todo listo para reembolsar recibos desde tu cuenta bancaria!', + updateCustomUnitError: 'Los cambios no han podido ser guardados. El espacio de trabajo ha sido modificado mientras estabas desconectado, por favor inténtalo de nuevo.', }, bills: { manageYourBills: 'Gestiona tus facturas', From 55af930f942802fb1ac59e8a9ce109875b4e51cf Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 25 Aug 2022 14:05:35 +0800 Subject: [PATCH 032/126] update setCustomUnitRate --- src/libs/actions/Policy.js | 82 +++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 23 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 1d0c5c596a4c..16e188ce0ad4 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -13,6 +13,8 @@ import ROUTES from '../../ROUTES'; import * as OptionsListUtils from '../OptionsListUtils'; import * as Report from './Report'; import * as Pusher from '../Pusher/pusher'; +import DateUtils from '../DateUtils'; +import * as API from '../API'; const allPolicies = {}; Onyx.connect({ @@ -467,34 +469,68 @@ function setCustomUnit(policyID, values) { /** * @param {String} policyID + * @param {Object} currentCustomUnitRate * @param {String} customUnitID * @param {Object} values */ -function setCustomUnitRate(policyID, customUnitID, values) { - DeprecatedAPI.Policy_CustomUnitRate_Update({ - policyID: policyID.toString(), - customUnitID: customUnitID.toString(), - customUnitRate: JSON.stringify(values), - lastModified: null, - }) - .then((response) => { - if (response.jsonCode !== 200) { - throw new Error(); - } - - updateLocalPolicyValues(policyID, { - customUnit: { - rate: { - id: values.customUnitRateID, - name: values.name, - value: Number(values.rate), +function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { + const optimisticData = [ + { + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + rates: { + [values.customUnitRateID]: { + ...values, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, }, }, - }); - }).catch(() => { - // Show the user feedback - Growl.error(Localize.translateLocal('workspace.editor.genericFailureMessage'), 5000); - }); + }, + }, + ]; + + const successData = [ + { + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + rates: { + [values.customUnitRateID]: { + pendingAction: null, + }, + }, + }, + }, + }, + ]; + + const failureData = [ + { + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + rates: { + [currentCustomUnitRate.customUnitRateID]: { + ...currentCustomUnitRate, + error: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('workspace.reimburse.updateCustomUnitError'), + }, + }, + }, + }, + }, + }, + ]; + + // Note remember to not pass lastModified as null as per convo + API.write('UpdateWorkspaceCustomUnit', { + policyID: policyID, + customUnit: JSON.stringify(values), + }, {optimisticData, successData, failureData}); } /** From 4cbb5d4979f6c93d01761795d22894f9a98df834 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 25 Aug 2022 14:13:08 +0800 Subject: [PATCH 033/126] update setCustomUnitRate --- src/libs/actions/Policy.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 16e188ce0ad4..72fde2134552 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -526,10 +526,10 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values }, ]; - // Note remember to not pass lastModified as null as per convo - API.write('UpdateWorkspaceCustomUnit', { - policyID: policyID, - customUnit: JSON.stringify(values), + API.write('SetWorkspaceCustomUnitRate', { + policyID, + customUnitID, + customUnitRate: JSON.stringify(values), }, {optimisticData, successData, failureData}); } From 40ea3c9cca574c69fc1c2e2ba03747831aeec076 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Fri, 26 Aug 2022 02:22:48 +0530 Subject: [PATCH 034/126] fix: attach and remove listeners on hide/show --- src/components/PopoverMenu/BasePopoverMenu.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index c8ecdf1b1d09..efc59c52c2b2 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -36,9 +36,23 @@ class BasePopoverMenu extends PureComponent { }; this.updateFocusedIndex = this.updateFocusedIndex.bind(this); this.resetFocusAndHideModal = this.resetFocusAndHideModal.bind(this); + this.removeKeyboardListener = this.removeKeyboardListener.bind(this); + this.attachKeyboardListener = this.attachKeyboardListener.bind(this); } componentDidMount() { + this.attachKeyboardListener(); + } + + componentDidUpdate() { + this.attachKeyboardListener(); + } + + componentWillUnmount() { + this.removeKeyboardListener(); + } + + attachKeyboardListener() { if (!this.props.shouldEnableArrowKeysActions && !this.props.isVisible) { return; } @@ -53,7 +67,7 @@ class BasePopoverMenu extends PureComponent { }, shortcutConfig.descriptionKey, shortcutConfig.modifiers, true); } - componentWillUnmount() { + removeKeyboardListener() { if (!this.unsubscribeEnterKey) { return; } @@ -72,6 +86,7 @@ class BasePopoverMenu extends PureComponent { resetFocusAndHideModal() { this.updateFocusedIndex(-1); // Reset the focusedIndex on modal hide + this.removeKeyboardListener(); this.props.onMenuHide(); } From b6a9503d44c863778c0595cbebe76bd4d0065ee2 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Fri, 26 Aug 2022 02:30:21 +0530 Subject: [PATCH 035/126] fix: change maxIndex < 1 check --- src/components/ArrowKeyFocusManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ArrowKeyFocusManager.js b/src/components/ArrowKeyFocusManager.js index dcb915d46bcd..46cff9371656 100644 --- a/src/components/ArrowKeyFocusManager.js +++ b/src/components/ArrowKeyFocusManager.js @@ -26,7 +26,7 @@ class ArrowKeyFocusManager extends Component { const arrowDownConfig = CONST.KEYBOARD_SHORTCUTS.ARROW_DOWN; this.unsubscribeArrowUpKey = KeyboardShortcut.subscribe(arrowUpConfig.shortcutKey, () => { - if (this.props.maxIndex < 1) { + if (this.props.maxIndex < 0) { return; } @@ -41,7 +41,7 @@ class ArrowKeyFocusManager extends Component { }, arrowUpConfig.descriptionKey, arrowUpConfig.modifiers, true); this.unsubscribeArrowDownKey = KeyboardShortcut.subscribe(arrowDownConfig.shortcutKey, () => { - if (this.props.maxIndex < 1) { + if (this.props.maxIndex < 0) { return; } From 332eec09b917c7526c1d54304909ea876e064d9b Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Fri, 26 Aug 2022 02:35:19 +0530 Subject: [PATCH 036/126] fix: condition to remove multiple attacher listener --- src/components/PopoverMenu/BasePopoverMenu.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index efc59c52c2b2..5933323f967d 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -53,7 +53,7 @@ class BasePopoverMenu extends PureComponent { } attachKeyboardListener() { - if (!this.props.shouldEnableArrowKeysActions && !this.props.isVisible) { + if (!this.props.shouldEnableArrowKeysActions || !this.props.isVisible || this.unsubscribeEnterKey) { return; } @@ -72,6 +72,7 @@ class BasePopoverMenu extends PureComponent { return; } this.unsubscribeEnterKey(); + this.unsubscribeEnterKey = null; } /** From e5b20c7363a068e55cccb01e51a4770ba023bf3b Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 26 Aug 2022 09:59:41 +0200 Subject: [PATCH 037/126] Add createOptimisticWorkspaceChat method --- src/libs/actions/Report.js | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 4cf9102acfd7..7d57357f8d23 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -702,6 +702,44 @@ function createOptimisticReport(participantList) { }; } +function createOptimisticWorkspaceChat(policyID, ownerEmail) { + const announceReportID = ReportUtils.generateReportID(); + const announceChatData = { + chatType: CONST.CHAT_TYPE.POLICY_ANNOUNCE, + policyID: policyID, + reportID: announceReportID, + reportName: CONST.CHAT_NAME_POLICY_ANNOUNCE, + }; + + const adminReportID = ReportUtils.generateReportID(); + const adminChatData = { + chatType: CONST.CHAT_TYPE.POLICY_ADMINS, + policyID: policyID, + reportID: adminReportID, + reportName: CONST.CHAT_NAME_POLICY_ADMINS, + }; + + const expenseReportID = ReportUtils.generateReportID(); + const expenseChatData = { + chatType: CONST.CHAT_TYPE.POLICY_EXPENSE_CHAT, + isOwnPolicyExpenseChat: true, + ownerEmail: ownerEmail, + policyID: policyID, + reportID: expenseReportID, + reportName: CONST.CHAT_NAME_POLICY_EXPENSE, + }; + + return { + announceReportID, + announceChatData, + adminReportID, + adminChatData, + expenseReportID, + expenseChatData + } + +} + /** * @param {Number} reportID * @param {String} [text] @@ -1614,6 +1652,7 @@ export { openReport, openPaymentDetailsPage, createOptimisticReport, + createOptimisticWorkspaceChat, updatePolicyRoomName, clearPolicyRoomNameErrors, }; From 37d846bdc49d36ee99c16770759f2e379f1e7113 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 26 Aug 2022 10:03:36 +0200 Subject: [PATCH 038/126] Start new method CreateWorkspace --- src/libs/actions/Policy.js | 11 +++++++++++ src/libs/actions/Report.js | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 5cfa9bc35b07..b7ffab54daf6 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -690,6 +690,17 @@ function generatePolicyID() { return _.times(16, () => Math.floor(Math.random() * 16).toString(16)).join('').toUpperCase(); } +function createWorkspace() { + API.write('CreateWorkspace', { + policyID, + announceChatReportID, + adminsChatReportID, + expenseChatReportID, + }, { + optimisticData, successData, failureData + }); +} + export { getPolicyList, loadFullPolicy, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 7d57357f8d23..8232eacbde9e 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -702,7 +702,7 @@ function createOptimisticReport(participantList) { }; } -function createOptimisticWorkspaceChat(policyID, ownerEmail) { +function createOptimisticWorkspaceChats(policyID, ownerEmail) { const announceReportID = ReportUtils.generateReportID(); const announceChatData = { chatType: CONST.CHAT_TYPE.POLICY_ANNOUNCE, @@ -1652,7 +1652,7 @@ export { openReport, openPaymentDetailsPage, createOptimisticReport, - createOptimisticWorkspaceChat, + createOptimisticWorkspaceChats, updatePolicyRoomName, clearPolicyRoomNameErrors, }; From 92639f0a372781fde99eb0f6308883f11a7a3e81 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 26 Aug 2022 13:30:05 +0200 Subject: [PATCH 039/126] add optimistic data --- src/libs/actions/Policy.js | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index b7ffab54daf6..871a026a7c4d 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -690,14 +690,47 @@ function generatePolicyID() { return _.times(16, () => Math.floor(Math.random() * 16).toString(16)).join('').toUpperCase(); } -function createWorkspace() { +function createWorkspace(ownerEmail) { + const workspaceChats = Report.createOptimisticWorkspaceChats(policyID, ownerEmail); + API.write('CreateWorkspace', { policyID, announceChatReportID, adminsChatReportID, expenseChatReportID, }, { - optimisticData, successData, failureData + optimisticData: [{ + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + id: policyID, + type: CONST.POLICY.TYPE.FREE, + name: generateDefaultWorkspaceName(), + role: CONST.POLICY.ROLE.ADMIN, + outputCurrency: 'USD', + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, + value: getSimplifiedEmployeeList({ + 'email': ownerEmail, + 'role': CONST.POLICY.ROLE.ADMIN + }) + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.announceChatID}`, + value: workspaceChats.announceChatData, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.adminChatID}`, + value: workspaceChats.adminChatData, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.expenseChatID}`, + value: workspaceChats.expenseChatData, + }], }); } From c70ccd54b1ed2cad4a223958a28263b566184223 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 26 Aug 2022 13:37:04 +0200 Subject: [PATCH 040/126] success / failure onyx data --- src/libs/actions/Policy.js | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 871a026a7c4d..439c85bb4697 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -705,7 +705,7 @@ function createWorkspace(ownerEmail) { value: { id: policyID, type: CONST.POLICY.TYPE.FREE, - name: generateDefaultWorkspaceName(), + name: 'Default', role: CONST.POLICY.ROLE.ADMIN, outputCurrency: 'USD', pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, @@ -730,7 +730,35 @@ function createWorkspace(ownerEmail) { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.expenseChatID}`, value: workspaceChats.expenseChatData, - }], + }], + successData: [{ + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingAction: null + } + }], + failureData: [{ + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: null + }, { + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, + value: null + }, { + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.announceChatID}`, + value: null, + }, { + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.adminChatID}`, + value: null, + }, { + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.expenseChatID}`, + value: null, + }]; }); } From eea0963cc85fd5c71fc919ef366057028c6c65af Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 26 Aug 2022 17:08:25 +0200 Subject: [PATCH 041/126] use keys --- src/libs/actions/Policy.js | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 439c85bb4697..0c7f00d50fda 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -691,13 +691,21 @@ function generatePolicyID() { } function createWorkspace(ownerEmail) { - const workspaceChats = Report.createOptimisticWorkspaceChats(policyID, ownerEmail); + const policyID = generatePolicyID(); + const { + announceReportID, + announceChatData, + adminReportID, + adminChatData, + expenseReportID, + expenseChatData + } = Report.createOptimisticWorkspaceChats(policyID, ownerEmail); API.write('CreateWorkspace', { policyID, - announceChatReportID, - adminsChatReportID, - expenseChatReportID, + announceReportID, + adminReportID, + expenseReportID, }, { optimisticData: [{ onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -720,16 +728,16 @@ function createWorkspace(ownerEmail) { }) }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.announceChatID}`, - value: workspaceChats.announceChatData, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceReportID}`, + value: announceChatData, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.adminChatID}`, - value: workspaceChats.adminChatData, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminReportID}`, + value: adminChatData, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.expenseChatID}`, - value: workspaceChats.expenseChatData, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReportID}`, + value: expenseChatData, }], successData: [{ onyxMethod: CONST.ONYX.METHOD.SET, @@ -748,17 +756,17 @@ function createWorkspace(ownerEmail) { value: null }, { onyxMethod: CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.announceChatID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceReportID}`, value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.adminChatID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminReportID}`, value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChats.expenseChatID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReportID}`, value: null, - }]; + }] }); } @@ -788,4 +796,5 @@ export { deleteWorkspaceAvatar, clearAvatarErrors, generatePolicyID, + createWorkspace, }; From 15e8f830adc9bf3698ef507b39237ad4a3ff6ca6 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 26 Aug 2022 17:42:12 +0200 Subject: [PATCH 042/126] remove unused copy --- src/languages/en.js | 2 -- src/languages/es.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 5702841f6023..52205cb11948 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -781,7 +781,6 @@ export default { issueAndManageCards: 'Issue and manage cards', reconcileCards: 'Reconcile cards', settlementFrequency: 'Settlement frequency', - growlMessageOnCreate: 'Workspace created', growlMessageOnSave: 'Your workspace settings were successfully saved!', deleteConfirmation: 'Are you sure you want to delete this workspace?', growlMessageOnDelete: 'Workspace deleted', @@ -791,7 +790,6 @@ export default { new: { newWorkspace: 'New workspace', getTheExpensifyCardAndMore: 'Get the Expensify Card and more', - genericFailureMessage: 'An error occurred creating the workspace, please try again.', }, people: { genericFailureMessage: 'An error occurred removing a user from the workspace, please try again.', diff --git a/src/languages/es.js b/src/languages/es.js index cf30581f648a..3dff0e2912d6 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -783,7 +783,6 @@ export default { issueAndManageCards: 'Emitir y gestionar tarjetas', reconcileCards: 'Reconciliar tarjetas', settlementFrequency: 'Frecuencia de liquidación', - growlMessageOnCreate: 'El espacio de trabajo ha sido creado', growlMessageOnSave: '¡La configuración del espacio de trabajo se ha guardado correctamente!', growlMessageOnDelete: 'Espacio de trabajo eliminado', deleteConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo?', @@ -793,7 +792,6 @@ export default { new: { newWorkspace: 'Nuevo espacio de trabajo', getTheExpensifyCardAndMore: 'Consigue la Tarjeta Expensify y más', - genericFailureMessage: 'Se ha producido un error al intentar crear el espacio de trabajo. Por favor, inténtalo de nuevo.', }, people: { genericFailureMessage: 'Se ha producido un error al intentar eliminar a un usuario del espacio de trabajo. Por favor inténtalo más tarde.', From 80b2fbbd7740859d6c569c1e94fd83112e9849ba Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 26 Aug 2022 17:42:33 +0200 Subject: [PATCH 043/126] replace all usages of old Policy.create --- src/libs/actions/App.js | 4 +- src/libs/actions/Policy.js | 82 ++----------------- .../SidebarScreen/BaseSidebarScreen.js | 2 +- src/pages/workspace/WorkspaceInitialPage.js | 10 +-- 4 files changed, 17 insertions(+), 81 deletions(-) diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index d11396535ef7..d5e739c84146 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -155,7 +155,7 @@ function reconnectApp() { * will occur. * When the exitTo route is 'workspace/new', we create a new - * workspace and navigate to it via Policy.createAndGetPolicyList. + * workspace and navigate to it * * We subscribe to the session using withOnyx in the AuthScreens and * pass it in as a parameter. withOnyx guarantees that the value has been read @@ -183,7 +183,7 @@ function setUpPoliciesAndNavigate(session, currentPath) { && Str.startsWith(currentPath, Str.normalizeUrl(ROUTES.TRANSITION_FROM_OLD_DOT)) && exitTo === ROUTES.WORKSPACE_NEW; if (shouldCreateFreePolicy) { - Policy.createAndGetPolicyList(); + Policy.createWorkspace(); return; } if (!isLoggingInAsNewUser && exitTo) { diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 0c7f00d50fda..31ee920819f4 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -104,60 +104,6 @@ function updateAllPolicies(policyCollection) { }); } -/** - * Merges the passed in login into the specified policy - * - * @param {String} [name] - * @param {Boolean} [shouldAutomaticallyReroute] - * @returns {Promise} - */ -function create(name = '') { - Onyx.set(ONYXKEYS.IS_CREATING_WORKSPACE, true); - let res = null; - return DeprecatedAPI.Policy_Create({type: CONST.POLICY.TYPE.FREE, policyName: name}) - .then((response) => { - Onyx.set(ONYXKEYS.IS_CREATING_WORKSPACE, false); - if (response.jsonCode !== 200) { - // Show the user feedback - const errorMessage = Localize.translateLocal('workspace.new.genericFailureMessage'); - Growl.error(errorMessage, 5000); - return; - } - Growl.show(Localize.translateLocal('workspace.common.growlMessageOnCreate'), CONST.GROWL.SUCCESS, 3000); - res = response; - - // Fetch the default reports and the policyExpenseChat reports on the policy - Report.fetchChatReportsByIDs([response.policy.chatReportIDAdmins, response.policy.chatReportIDAnnounce, response.ownerPolicyExpenseChatID]); - - // We are awaiting this merge so that we can guarantee our policy is available to any React components connected to the policies collection before we navigate to a new route. - return Promise.all( - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${response.policyID}`, { - id: response.policyID, - type: response.policy.type, - name: response.policy.name, - role: CONST.POLICY.ROLE.ADMIN, - outputCurrency: response.policy.outputCurrency, - }), - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${response.policyID}`, getSimplifiedEmployeeList(response.policy.employeeList)), - ); - }) - .then(() => Promise.resolve(lodashGet(res, 'policyID'))); -} - -/** - * @param {String} policyID - */ -function navigateToPolicy(policyID) { - Navigation.navigate(policyID ? ROUTES.getWorkspaceInitialRoute(policyID) : ROUTES.HOME); -} - -/** - * @param {String} [name] - */ -function createAndNavigate(name = '') { - create(name).then(navigateToPolicy); -} - /** * Delete the policy * @@ -220,19 +166,6 @@ function getPolicyList() { }); } -function createAndGetPolicyList() { - let newPolicyID; - create() - .then((policyID) => { - newPolicyID = policyID; - return getPolicyList(); - }) - .then(() => { - Navigation.dismissModal(); - navigateToPolicy(newPolicyID); - }); -} - /** * @param {String} policyID */ @@ -690,7 +623,11 @@ function generatePolicyID() { return _.times(16, () => Math.floor(Math.random() * 16).toString(16)).join('').toUpperCase(); } -function createWorkspace(ownerEmail) { +/** + * Optimistically creates a new workspace and default workspace chats + * @param {*} ownerEmail + */ +function createWorkspace() { const policyID = generatePolicyID(); const { announceReportID, @@ -699,7 +636,7 @@ function createWorkspace(ownerEmail) { adminChatData, expenseReportID, expenseChatData - } = Report.createOptimisticWorkspaceChats(policyID, ownerEmail); + } = Report.createOptimisticWorkspaceChats(policyID, sessionEmail); API.write('CreateWorkspace', { policyID, @@ -723,7 +660,7 @@ function createWorkspace(ownerEmail) { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, value: getSimplifiedEmployeeList({ - 'email': ownerEmail, + 'email': sessionEmail, 'role': CONST.POLICY.ROLE.ADMIN }) }, { @@ -768,6 +705,8 @@ function createWorkspace(ownerEmail) { value: null, }] }); + + Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policyID)); } export { @@ -776,7 +715,6 @@ export { removeMembers, invite, isAdminOfFreePolicy, - create, uploadAvatar, update, setWorkspaceErrors, @@ -784,8 +722,6 @@ export { hasCustomUnitsError, hideWorkspaceAlertMessage, deletePolicy, - createAndNavigate, - createAndGetPolicyList, updateWorkspaceCustomUnit, setCustomUnitRate, updateLastAccessedWorkspace, diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index a939c5bf4e19..1c5540c82fff 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -170,7 +170,7 @@ class BaseSidebarScreen extends Component { iconHeight: 40, text: this.props.translate('workspace.new.newWorkspace'), description: this.props.translate('workspace.new.getTheExpensifyCardAndMore'), - onSelected: () => Policy.createAndNavigate(), + onSelected: () => Policy.createWorkspace(), }, ] : []), ]} diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index d2c4695f4977..a1466629ad3b 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -20,7 +20,7 @@ import compose from '../../libs/compose'; import Avatar from '../../components/Avatar'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; -import * as PolicyActions from '../../libs/actions/Policy'; +import * as Policy from '../../libs/actions/Policy'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; import policyMemberPropType from '../policyMemberPropType'; @@ -70,14 +70,14 @@ class WorkspaceInitialPage extends React.Component { * Call the delete policy and hide the modal */ confirmDeleteAndHideModal() { - PolicyActions.deletePolicy(this.props.policy.id); + Policy.deletePolicy(this.props.policy.id); this.toggleDeleteModal(false); } render() { const policy = this.props.policy; - const hasMembersError = PolicyActions.hasPolicyMemberError(this.props.policyMemberList); - const hasCustomUnitsError = PolicyActions.hasCustomUnitsError(this.props.policy); + const hasMembersError = Policy.hasPolicyMemberError(this.props.policyMemberList); + const hasCustomUnitsError = Policy.hasCustomUnitsError(this.props.policy); const menuItems = [ { translationKey: 'workspace.common.settings', @@ -138,7 +138,7 @@ class WorkspaceInitialPage extends React.Component { { icon: Expensicons.Plus, text: this.props.translate('workspace.new.newWorkspace'), - onSelected: () => PolicyActions.createAndNavigate(), + onSelected: () => Policy.createWorkspace(), }, { icon: Expensicons.Trashcan, text: this.props.translate('workspace.common.delete'), From 065909a5b92c0e8bf86117fd58816a506c6a8204 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 29 Aug 2022 21:34:23 +0800 Subject: [PATCH 044/126] WIP, online updates work, but need to figure out issue with data shape before continuing with errors --- src/CONST.js | 1 + src/components/OfflineWithFeedback.js | 1 + src/libs/actions/Policy.js | 38 ++++++++++++------- .../reimburse/WorkspaceReimburseView.js | 26 +++++++------ 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index a6b7586c217b..0456d3fc745f 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -663,6 +663,7 @@ const CONST = { ADMIN: 'admin', }, ROOM_PREFIX: '#', + CUSTOM_UNIT_RATE_BASE_OFFSET: 100, }, TERMS: { diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index 27dcefd9a15e..57566f0a1e40 100644 --- a/src/components/OfflineWithFeedback.js +++ b/src/components/OfflineWithFeedback.js @@ -86,6 +86,7 @@ const OfflineWithFeedback = (props) => { .keys() .sortBy() .map(key => props.errors[key]) + .uniq() .value(); // Apply strikethrough to children if needed, but skip it if we are not going to render them diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 4132186a0ceb..aca54479494d 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -491,12 +491,16 @@ function setWorkspaceErrors(policyID, errors) { * @param {String} policyID * @param {Number} customUnitID */ -function removeUnitError(policyID, customUnitID) { +function clearCustomUnitErrors(policyID, customUnitID) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { customUnits: { [customUnitID]: { errors: null, pendingAction: null, + rates: [{ + errors: null, + pendingAction: null, + }], }, }, }); @@ -587,17 +591,21 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { * @param {Object} values */ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { + console.log(">>>>", policyID, customUnitID, values.customUnitRateID); const optimisticData = [ { onyxMethod: 'merge', key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - rates: { - [values.customUnitRateID]: { - ...values, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - }, + [customUnitID]: { + rates: [ + { + ...values, + errors: null, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + ], }, }, }, @@ -610,10 +618,12 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - rates: { - [values.customUnitRateID]: { + [customUnitID]: { + rates: [{ + ...values, pendingAction: null, - }, + errors: null, + }], }, }, }, @@ -626,13 +636,13 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - rates: { - [currentCustomUnitRate.customUnitRateID]: { + [customUnitID]: { + rates: [{ ...currentCustomUnitRate, - error: { + errors: { [DateUtils.getMicroseconds()]: Localize.translateLocal('workspace.reimburse.updateCustomUnitError'), }, - }, + }], }, }, }, @@ -734,7 +744,7 @@ export { uploadAvatar, update, setWorkspaceErrors, - removeUnitError, + clearCustomUnitErrors, hasCustomUnitsError, hideWorkspaceAlertMessage, deletePolicy, diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 8307fe49dbed..3a9f2b3cdc24 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -64,9 +64,7 @@ class WorkspaceReimburseView extends React.Component { unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''), unitName: lodashGet(distanceCustomUnit, 'name', ''), unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'), - rateID: lodashGet(distanceCustomUnit, 'rates[0].customUnitRateID', ''), - rateName: lodashGet(distanceCustomUnit, 'rates[0].name', ''), - rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates[0].rate', 0) / 100), + rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates[0].rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), outputCurrency: lodashGet(props, 'policy.outputCurrency', ''), }; @@ -151,11 +149,12 @@ class WorkspaceReimburseView extends React.Component { rateValue: numValue.toFixed(3), }); - Policy.setCustomUnitRate(this.props.policyID, this.state.unitID, { - customUnitRateID: this.state.rateID, - name: this.state.rateName, - rate: numValue.toFixed(3) * 100, - }, null); + const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); + const currentCustomUnitRate = lodashGet(distanceCustomUnit, 'rates[0]', {}); + Policy.setCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { + ..._.omit(currentCustomUnitRate, 'rate'), + rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, + }); } render() { @@ -194,9 +193,14 @@ class WorkspaceReimburseView extends React.Component { {this.props.translate('workspace.reimburse.trackDistanceCopy')} Policy.removeUnitError(this.props.policyID, this.state.unitID)} + errors={{ + ...lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'errors']), + ...lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates[0]', 'errors']), + }} + pendingAction={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'pendingAction']) + || lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates[0]', 'pendingAction'])} + onClose={() => Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID)} + errorRowStyles={[styles.flex1]} > From c5495c07c28e7188703e920d06c26c44759de1c7 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Mon, 29 Aug 2022 16:07:10 -0400 Subject: [PATCH 045/126] sync policy members when opening workspace invite page --- src/libs/actions/Policy.js | 9 +++++++++ src/pages/workspace/WorkspaceInvitePage.js | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 0c34c41400af..b28621d84bb5 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -745,6 +745,14 @@ function openWorkspaceMembersPage(policyID, clientPolicyMembers) { API.read('OpenWorkspaceMembersPage', {policyID, clientPolicyMembers}); } +function openWorkspaceInvitePage(policyID, clientPolicyMembers) { + if (!policyID) { + return; + } + + API.read('OpenWorkspaceInvitePage', {policyID, clientPolicyMembers}); +} + export { getPolicyList, loadFullPolicy, @@ -772,4 +780,5 @@ export { clearAvatarErrors, generatePolicyID, openWorkspaceMembersPage, + openWorkspaceInvitePage, }; diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index bf44055c9c9b..f1446de62634 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -84,6 +84,9 @@ class WorkspaceInvitePage extends React.Component { componentDidMount() { this.clearErrors(); + + const clientPolicyMembers = _.keys(this.props.policyMemberList); + Policy.openWorkspaceInvitePage(this.props.policy.id, clientPolicyMembers); } getExcludedUsers() { From 7fb1dfa1685367c8bd4f6e373a17adb976f3b67f Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Mon, 29 Aug 2022 16:10:02 -0400 Subject: [PATCH 046/126] sync policy members on reconnect --- src/pages/workspace/WorkspaceInvitePage.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index f1446de62634..862b5b2a3ac5 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -21,6 +21,7 @@ import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndica import * as Link from '../../libs/actions/Link'; import Text from '../../components/Text'; import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; +import {withNetwork} from '../../components/OnyxProvider'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -89,6 +90,16 @@ class WorkspaceInvitePage extends React.Component { Policy.openWorkspaceInvitePage(this.props.policy.id, clientPolicyMembers); } + componentDidUpdate(prevProps) { + const isReconnecting = prevProps.network.isOffline && !this.props.network.isOffline; + if (!isReconnecting) { + return; + } + + const clientPolicyMembers = _.keys(this.props.policyMemberList); + Policy.openWorkspaceInvitePage(this.props.policy.id, clientPolicyMembers); + } + getExcludedUsers() { const policyMemberList = _.keys(lodashGet(this.props, 'policyMemberList', {})); return [...CONST.EXPENSIFY_EMAILS, ...policyMemberList]; @@ -337,6 +348,7 @@ WorkspaceInvitePage.defaultProps = defaultProps; export default compose( withLocalize, withFullPolicy, + withNetwork(), withOnyx({ personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, From 06327cdca336a4ce4e167542a51e67cba5f98059 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Mon, 29 Aug 2022 16:24:05 -0400 Subject: [PATCH 047/126] use FullPageNotFoundView when the policy isn't found --- src/pages/workspace/WorkspaceInvitePage.js | 123 +++++++++++---------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index 862b5b2a3ac5..cd45d7d0fb41 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -22,6 +22,7 @@ import * as Link from '../../libs/actions/Link'; import Text from '../../components/Text'; import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; import {withNetwork} from '../../components/OnyxProvider'; +import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -244,22 +245,23 @@ class WorkspaceInvitePage extends React.Component { return ( {({didScreenTransitionEnd}) => ( - <> - { - this.clearErrors(); - Navigation.dismissModal(); - }} - shouldShowGetAssistanceButton - guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_MEMBERS} - shouldShowBackButton - onBackButtonPress={() => Navigation.goBack()} - /> - - {!didScreenTransitionEnd && } - {didScreenTransitionEnd && ( + + <> + { + this.clearErrors(); + Navigation.dismissModal(); + }} + shouldShowGetAssistanceButton + guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_MEMBERS} + shouldShowBackButton + onBackButtonPress={() => Navigation.goBack()} + /> + + {!didScreenTransitionEnd && } + {didScreenTransitionEnd && ( - )} - - - - this.setState({welcomeNote: text})} + )} + + + + this.setState({welcomeNote: text})} + /> + + {}} + message={this.props.policy.alertMessage} + containerStyles={[styles.flexReset, styles.mb0, styles.flexGrow0, styles.flexShrink0, styles.flexBasisAuto]} /> + { + e.preventDefault(); + Link.openExternalLink(CONST.PRIVACY_URL); + }} + accessibilityRole="link" + href={CONST.PRIVACY_URL} + style={[styles.mh5, styles.mv2, styles.alignSelfStart]} + > + {({hovered, pressed}) => ( + + + {this.props.translate('common.privacyPolicy')} + + + )} + - {}} - message={this.props.policy.alertMessage} - containerStyles={[styles.flexReset, styles.mb0, styles.flexGrow0, styles.flexShrink0, styles.flexBasisAuto]} - /> - { - e.preventDefault(); - Link.openExternalLink(CONST.PRIVACY_URL); - }} - accessibilityRole="link" - href={CONST.PRIVACY_URL} - style={[styles.mh5, styles.mv2, styles.alignSelfStart]} - > - {({hovered, pressed}) => ( - - - {this.props.translate('common.privacyPolicy')} - - - )} - - - + + )} ); From 87e141d5af6c453497fa32406d578fb853abd3e6 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Mon, 29 Aug 2022 16:25:20 -0400 Subject: [PATCH 048/126] prevent setting properties for policies that don't exist --- src/libs/actions/Policy.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index b28621d84bb5..5ab620982b8d 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -550,6 +550,10 @@ function uploadAvatar(policyID, file) { * @param {Object} errors */ function setWorkspaceErrors(policyID, errors) { + if (!allPolicies[policyID]) { + return; + } + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errors: null}); Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errors}); } @@ -573,6 +577,10 @@ function removeUnitError(policyID, customUnitID) { * @param {String} policyID */ function hideWorkspaceAlertMessage(policyID) { + if (!allPolicies[policyID]) { + return; + } + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {alertMessage: ''}); } From 131144fd4a6b5a00b917b65b7a770d0f97a54590 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 11:21:14 +0800 Subject: [PATCH 049/126] merge main --- src/libs/actions/Policy.js | 106 +++++++++++------- .../reimburse/WorkspaceReimburseView.js | 12 +- 2 files changed, 73 insertions(+), 45 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 4aaebf3532e2..66c912fc88df 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -50,6 +50,21 @@ function getSimplifiedEmployeeList(employeeList) { .value(); } +/** + * For whatever reason, we store customUnit rates in an array, even though there's only ever a single rate per custom unit. + * This flattens the array of rates so that we store the single rate directly. + * + * @param {Object} fullPolicyOrPolicySummary + * @param {Object} [fullPolicyOrPolicySummary.value.customUnits] + */ +function getSimplifiedCustomUnits(fullPolicyOrPolicySummary) { + const customUnits = lodashGet(fullPolicyOrPolicySummary, 'value.customUnits', {}); + _.forEach(customUnits, (customUnit, customUnitID) => { + customUnits[customUnitID].rates = lodashGet(customUnit, 'rates[0]', {}); + }); + return customUnits; +} + /** * Takes a full policy that is returned from the policyList and simplifies it so we are only storing * the pieces of data that we need to in Onyx @@ -60,6 +75,8 @@ function getSimplifiedEmployeeList(employeeList) { * @param {String} fullPolicyOrPolicySummary.role * @param {String} fullPolicyOrPolicySummary.type * @param {String} fullPolicyOrPolicySummary.outputCurrency + * @param {String} [fullPolicyOrPolicySummary.avatar] + * @param {String} [fullPolicyOrPolicySummary.value.avatar] * @param {String} [fullPolicyOrPolicySummary.avatarURL] * @param {String} [fullPolicyOrPolicySummary.value.avatarURL] * @param {Object} [fullPolicyOrPolicySummary.value.employeeList] @@ -78,9 +95,12 @@ function getSimplifiedPolicyObject(fullPolicyOrPolicySummary, isFromFullPolicy) outputCurrency: fullPolicyOrPolicySummary.outputCurrency, // "GetFullPolicy" and "GetPolicySummaryList" returns different policy objects. If policy is retrieved by "GetFullPolicy", - // avatarUrl will be nested within the key "value" - avatarURL: fullPolicyOrPolicySummary.avatarURL || lodashGet(fullPolicyOrPolicySummary, 'value.avatarURL', ''), - customUnits: lodashGet(fullPolicyOrPolicySummary, 'value.customUnits', {}), + // avatar will be nested within the key "value" + avatar: fullPolicyOrPolicySummary.avatar + || lodashGet(fullPolicyOrPolicySummary, 'value.avatar', '') + || fullPolicyOrPolicySummary.avatarURL + || lodashGet(fullPolicyOrPolicySummary, 'value.avatarURL', ''), + customUnits: getSimplifiedCustomUnits(fullPolicyOrPolicySummary), }; } @@ -112,9 +132,11 @@ function updateAllPolicies(policyCollection) { * @returns {Promise} */ function create(name = '') { + Onyx.set(ONYXKEYS.IS_CREATING_WORKSPACE, true); let res = null; return DeprecatedAPI.Policy_Create({type: CONST.POLICY.TYPE.FREE, policyName: name}) .then((response) => { + Onyx.set(ONYXKEYS.IS_CREATING_WORKSPACE, false); if (response.jsonCode !== 200) { // Show the user feedback const errorMessage = Localize.translateLocal('workspace.new.genericFailureMessage'); @@ -357,6 +379,40 @@ function updateLocalPolicyValues(policyID, values) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, values); } +/** + * Updates a workspace avatar image + * + * @param {String} policyID + * @param {File|Object} file + */ +function updateWorkspaceAvatar(policyID, file) { + const optimisticData = [{ + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + avatar: file.uri, + errorFields: { + avatar: null, + }, + pendingFields: { + avatar: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + }, + }]; + const failureData = [{ + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + avatar: allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`].avatar, + pendingFields: { + avatar: null, + }, + }, + }]; + + API.write('UpdateWorkspaceAvatar', {policyID, file}, {optimisticData, failureData}); +} + /** * Deletes the avatar image for the workspace * @param {String} policyID @@ -368,12 +424,12 @@ function deleteWorkspaceAvatar(policyID) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingFields: { - avatarURL: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + avatar: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, errorFields: { - avatarURL: null, + avatar: null, }, - avatarURL: '', + avatar: '', }, }, ]; @@ -383,10 +439,7 @@ function deleteWorkspaceAvatar(policyID) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingFields: { - avatarURL: null, - }, - errorFields: { - avatarURL: null, + avatar: null, }, }, }, @@ -397,10 +450,10 @@ function deleteWorkspaceAvatar(policyID) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingFields: { - avatarURL: null, + avatar: null, }, errorFields: { - avatarURL: { + avatar: { [DateUtils.getMicroseconds()]: Localize.translateLocal('avatarWithImagePicker.deleteWorkspaceError'), }, }, @@ -417,10 +470,10 @@ function deleteWorkspaceAvatar(policyID) { function clearAvatarErrors(policyID) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { errorFields: { - avatarURL: null, + avatar: null, }, pendingFields: { - avatarURL: null, + avatar: null, }, }); } @@ -522,29 +575,6 @@ function clearWorkspaceGeneralSettingsErrors(policyID) { }); } -/** - * Uploads the avatar image to S3 bucket and updates the policy with new avatarURL - * - * @param {String} policyID - * @param {Object} file - */ -function uploadAvatar(policyID, file) { - updateLocalPolicyValues(policyID, {isAvatarUploading: true}); - DeprecatedAPI.User_UploadAvatar({file}) - .then((response) => { - if (response.jsonCode === 200) { - // Update the policy with the new avatarURL as soon as we get it - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {avatarURL: response.s3url, isAvatarUploading: false}); - update(policyID, {avatarURL: response.s3url}, true); - return; - } - - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {isAvatarUploading: false}); - const errorMessage = Localize.translateLocal('workspace.editor.avatarUploadFailureMessage'); - Growl.error(errorMessage, 5000); - }); -} - /** * @param {String} policyID * @param {Object} errors @@ -798,7 +828,6 @@ export { invite, isAdminOfFreePolicy, create, - uploadAvatar, update, setWorkspaceErrors, clearCustomUnitErrors, @@ -816,6 +845,7 @@ export { updateGeneralSettings, clearWorkspaceGeneralSettingsErrors, deleteWorkspaceAvatar, + updateWorkspaceAvatar, clearAvatarErrors, generatePolicyID, }; diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 3a9f2b3cdc24..735da9140984 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -40,13 +40,11 @@ const propTypes = { attributes: PropTypes.shape({ unit: PropTypes.string, }), - rates: PropTypes.arrayOf( - PropTypes.shape({ - customUnitRateID: PropTypes.string, - name: PropTypes.string, - rate: PropTypes.number, - }), - ), + rates: PropTypes.shape({ + customUnitRateID: PropTypes.string, + name: PropTypes.string, + rate: PropTypes.number, + }), }), ), outputCurrency: PropTypes.string, From 5cff69a1f1f56b86e2ba6d18ccf412a7d5d74730 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 11:24:38 +0800 Subject: [PATCH 050/126] remove unused --- src/libs/actions/Policy.js | 66 ++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 66c912fc88df..01a03c3b8e67 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -95,11 +95,8 @@ function getSimplifiedPolicyObject(fullPolicyOrPolicySummary, isFromFullPolicy) outputCurrency: fullPolicyOrPolicySummary.outputCurrency, // "GetFullPolicy" and "GetPolicySummaryList" returns different policy objects. If policy is retrieved by "GetFullPolicy", - // avatar will be nested within the key "value" - avatar: fullPolicyOrPolicySummary.avatar - || lodashGet(fullPolicyOrPolicySummary, 'value.avatar', '') - || fullPolicyOrPolicySummary.avatarURL - || lodashGet(fullPolicyOrPolicySummary, 'value.avatarURL', ''), + // avatarUrl will be nested within the key "value" + avatarURL: fullPolicyOrPolicySummary.avatarURL || lodashGet(fullPolicyOrPolicySummary, 'value.avatarURL', ''), customUnits: getSimplifiedCustomUnits(fullPolicyOrPolicySummary), }; } @@ -390,12 +387,12 @@ function updateWorkspaceAvatar(policyID, file) { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - avatar: file.uri, + avatarURL: file.uri, errorFields: { - avatar: null, + avatarURL: null, }, pendingFields: { - avatar: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + avatarURL: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, }]; @@ -424,12 +421,12 @@ function deleteWorkspaceAvatar(policyID) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingFields: { - avatar: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + avatarURL: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, errorFields: { - avatar: null, + avatarURL: null, }, - avatar: '', + avatarURL: '', }, }, ]; @@ -439,7 +436,10 @@ function deleteWorkspaceAvatar(policyID) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingFields: { - avatar: null, + avatarURL: null, + }, + errorFields: { + avatarURL: null, }, }, }, @@ -450,10 +450,10 @@ function deleteWorkspaceAvatar(policyID) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingFields: { - avatar: null, + avatarURL: null, }, errorFields: { - avatar: { + avatarURL: { [DateUtils.getMicroseconds()]: Localize.translateLocal('avatarWithImagePicker.deleteWorkspaceError'), }, }, @@ -470,10 +470,10 @@ function deleteWorkspaceAvatar(policyID) { function clearAvatarErrors(policyID) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { errorFields: { - avatar: null, + avatarURL: null, }, pendingFields: { - avatar: null, + avatarURL: null, }, }); } @@ -575,6 +575,29 @@ function clearWorkspaceGeneralSettingsErrors(policyID) { }); } +/** + * Uploads the avatar image to S3 bucket and updates the policy with new avatarURL + * + * @param {String} policyID + * @param {Object} file + */ +function uploadAvatar(policyID, file) { + updateLocalPolicyValues(policyID, {isAvatarUploading: true}); + DeprecatedAPI.User_UploadAvatar({file}) + .then((response) => { + if (response.jsonCode === 200) { + // Update the policy with the new avatarURL as soon as we get it + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {avatarURL: response.s3url, isAvatarUploading: false}); + update(policyID, {avatarURL: response.s3url}, true); + return; + } + + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {isAvatarUploading: false}); + const errorMessage = Localize.translateLocal('workspace.editor.avatarUploadFailureMessage'); + Growl.error(errorMessage, 5000); + }); +} + /** * @param {String} policyID * @param {Object} errors @@ -603,16 +626,6 @@ function clearCustomUnitErrors(policyID, customUnitID) { }); } -/** - * Checks if we have any errors stored within the policy custom units. - * @param {Object} policy - * @returns {Boolean} - */ -function hasCustomUnitsError(policy) { - const unitsWithErrors = _.filter(lodashGet(policy, 'customUnits', {}), customUnit => (lodashGet(customUnit, 'errors', null))); - return !_.isEmpty(unitsWithErrors); -} - /** * @param {String} policyID */ @@ -831,7 +844,6 @@ export { update, setWorkspaceErrors, clearCustomUnitErrors, - hasCustomUnitsError, hideWorkspaceAlertMessage, deletePolicy, createAndNavigate, From d0b13930484d1c4859e001bd564bbcbf95b581e4 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 11:25:16 +0800 Subject: [PATCH 051/126] remove unused --- src/libs/actions/Policy.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 01a03c3b8e67..f37853b2073b 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -129,11 +129,9 @@ function updateAllPolicies(policyCollection) { * @returns {Promise} */ function create(name = '') { - Onyx.set(ONYXKEYS.IS_CREATING_WORKSPACE, true); let res = null; return DeprecatedAPI.Policy_Create({type: CONST.POLICY.TYPE.FREE, policyName: name}) .then((response) => { - Onyx.set(ONYXKEYS.IS_CREATING_WORKSPACE, false); if (response.jsonCode !== 200) { // Show the user feedback const errorMessage = Localize.translateLocal('workspace.new.genericFailureMessage'); From ef7611179a408b9c844db338e335bfba05b89e9f Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 11:25:39 +0800 Subject: [PATCH 052/126] remove unused --- src/libs/actions/Policy.js | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index f37853b2073b..921a273cd12a 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -374,40 +374,6 @@ function updateLocalPolicyValues(policyID, values) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, values); } -/** - * Updates a workspace avatar image - * - * @param {String} policyID - * @param {File|Object} file - */ -function updateWorkspaceAvatar(policyID, file) { - const optimisticData = [{ - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - avatarURL: file.uri, - errorFields: { - avatarURL: null, - }, - pendingFields: { - avatarURL: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - }, - }, - }]; - const failureData = [{ - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - avatar: allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`].avatar, - pendingFields: { - avatar: null, - }, - }, - }]; - - API.write('UpdateWorkspaceAvatar', {policyID, file}, {optimisticData, failureData}); -} - /** * Deletes the avatar image for the workspace * @param {String} policyID @@ -855,7 +821,6 @@ export { updateGeneralSettings, clearWorkspaceGeneralSettingsErrors, deleteWorkspaceAvatar, - updateWorkspaceAvatar, clearAvatarErrors, generatePolicyID, }; From d2a0ea329008dff2930f698f2fd0fb2108965760 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 11:28:43 +0800 Subject: [PATCH 053/126] flatten customUnit rate array --- src/libs/actions/Policy.js | 21 ++++++++----------- .../reimburse/WorkspaceReimburseView.js | 8 +++---- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 921a273cd12a..559706a67908 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -665,7 +665,6 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { * @param {Object} values */ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { - console.log(">>>>", policyID, customUnitID, values.customUnitRateID); const optimisticData = [ { onyxMethod: 'merge', @@ -673,13 +672,11 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values value: { customUnits: { [customUnitID]: { - rates: [ - { - ...values, - errors: null, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - }, - ], + rates: { + ...values, + errors: null, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, }, }, }, @@ -693,11 +690,11 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values value: { customUnits: { [customUnitID]: { - rates: [{ + rates: { ...values, pendingAction: null, errors: null, - }], + }, }, }, }, @@ -711,12 +708,12 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values value: { customUnits: { [customUnitID]: { - rates: [{ + rates: { ...currentCustomUnitRate, errors: { [DateUtils.getMicroseconds()]: Localize.translateLocal('workspace.reimburse.updateCustomUnitError'), }, - }], + }, }, }, }, diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 735da9140984..1ad2eacbdda4 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -62,7 +62,7 @@ class WorkspaceReimburseView extends React.Component { unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''), unitName: lodashGet(distanceCustomUnit, 'name', ''), unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'), - rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates[0].rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), + rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates.rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), outputCurrency: lodashGet(props, 'policy.outputCurrency', ''), }; @@ -148,7 +148,7 @@ class WorkspaceReimburseView extends React.Component { }); const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); - const currentCustomUnitRate = lodashGet(distanceCustomUnit, 'rates[0]', {}); + const currentCustomUnitRate = lodashGet(distanceCustomUnit, 'rates', {}); Policy.setCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { ..._.omit(currentCustomUnitRate, 'rate'), rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, @@ -193,10 +193,10 @@ class WorkspaceReimburseView extends React.Component { Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID)} errorRowStyles={[styles.flex1]} > From 942416fbf987717f2d16b7560a30c3d857baacbe Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 11:37:47 +0800 Subject: [PATCH 054/126] flatten customUnit rate array --- src/libs/actions/Policy.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 559706a67908..1e72f0a644e4 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -581,10 +581,10 @@ function clearCustomUnitErrors(policyID, customUnitID) { [customUnitID]: { errors: null, pendingAction: null, - rates: [{ + rates: { errors: null, pendingAction: null, - }], + }, }, }, }); @@ -693,7 +693,6 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values rates: { ...values, pendingAction: null, - errors: null, }, }, }, From 46eb7b5edcd93f4b1a4086bb53a61bc3c98c1dc0 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 11:46:55 +0800 Subject: [PATCH 055/126] fix linter error --- src/libs/actions/Policy.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 1e72f0a644e4..74868d04351b 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -56,6 +56,7 @@ function getSimplifiedEmployeeList(employeeList) { * * @param {Object} fullPolicyOrPolicySummary * @param {Object} [fullPolicyOrPolicySummary.value.customUnits] + * @returns {Object} */ function getSimplifiedCustomUnits(fullPolicyOrPolicySummary) { const customUnits = lodashGet(fullPolicyOrPolicySummary, 'value.customUnits', {}); @@ -801,6 +802,7 @@ export { invite, isAdminOfFreePolicy, create, + uploadAvatar, update, setWorkspaceErrors, clearCustomUnitErrors, From f2dbc3219828ff94dad29e86529e256348ee5687 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 12:05:21 +0800 Subject: [PATCH 056/126] update comment --- src/libs/actions/Policy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 74868d04351b..55a77c61cef8 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -51,7 +51,7 @@ function getSimplifiedEmployeeList(employeeList) { } /** - * For whatever reason, we store customUnit rates in an array, even though there's only ever a single rate per custom unit. + * We pass customUnit rates from PHP as an array, even though there's only ever a single rate per custom unit. * This flattens the array of rates so that we store the single rate directly. * * @param {Object} fullPolicyOrPolicySummary From ae0d448fc2b55b1f7cdfa989c3099b0f80e1b2ff Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Tue, 30 Aug 2022 10:03:02 +0530 Subject: [PATCH 057/126] refactor: changed conditions for keyboard listeners --- src/components/PopoverMenu/BasePopoverMenu.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index 5933323f967d..e23467ae35d5 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -40,12 +40,17 @@ class BasePopoverMenu extends PureComponent { this.attachKeyboardListener = this.attachKeyboardListener.bind(this); } - componentDidMount() { - this.attachKeyboardListener(); - } + componentDidUpdate(prevProps) { + if (this.props.shouldEnableArrowKeysActions === prevProps.shouldEnableArrowKeysActions + && this.props.isVisible === prevProps.isVisible) { + return; + } - componentDidUpdate() { - this.attachKeyboardListener(); + if (this.props.shouldEnableArrowKeysActions && this.props.isVisible) { + this.attachKeyboardListener(); + } else { + this.removeKeyboardListener(); + } } componentWillUnmount() { @@ -53,10 +58,6 @@ class BasePopoverMenu extends PureComponent { } attachKeyboardListener() { - if (!this.props.shouldEnableArrowKeysActions || !this.props.isVisible || this.unsubscribeEnterKey) { - return; - } - const shortcutConfig = CONST.KEYBOARD_SHORTCUTS.ENTER; this.unsubscribeEnterKey = KeyboardShortcut.subscribe(shortcutConfig.shortcutKey, () => { if (this.state.focusedIndex === -1) { @@ -72,7 +73,6 @@ class BasePopoverMenu extends PureComponent { return; } this.unsubscribeEnterKey(); - this.unsubscribeEnterKey = null; } /** From 230cf4267ced8a1c5c0665757bf199ee559999e3 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:00:07 +0800 Subject: [PATCH 058/126] revert unused --- src/libs/actions/Policy.js | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 55a77c61cef8..8ca92267e5a3 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -50,22 +50,6 @@ function getSimplifiedEmployeeList(employeeList) { .value(); } -/** - * We pass customUnit rates from PHP as an array, even though there's only ever a single rate per custom unit. - * This flattens the array of rates so that we store the single rate directly. - * - * @param {Object} fullPolicyOrPolicySummary - * @param {Object} [fullPolicyOrPolicySummary.value.customUnits] - * @returns {Object} - */ -function getSimplifiedCustomUnits(fullPolicyOrPolicySummary) { - const customUnits = lodashGet(fullPolicyOrPolicySummary, 'value.customUnits', {}); - _.forEach(customUnits, (customUnit, customUnitID) => { - customUnits[customUnitID].rates = lodashGet(customUnit, 'rates[0]', {}); - }); - return customUnits; -} - /** * Takes a full policy that is returned from the policyList and simplifies it so we are only storing * the pieces of data that we need to in Onyx @@ -98,7 +82,7 @@ function getSimplifiedPolicyObject(fullPolicyOrPolicySummary, isFromFullPolicy) // "GetFullPolicy" and "GetPolicySummaryList" returns different policy objects. If policy is retrieved by "GetFullPolicy", // avatarUrl will be nested within the key "value" avatarURL: fullPolicyOrPolicySummary.avatarURL || lodashGet(fullPolicyOrPolicySummary, 'value.avatarURL', ''), - customUnits: getSimplifiedCustomUnits(fullPolicyOrPolicySummary), + customUnits: lodashGet(fullPolicyOrPolicySummary, 'value.customUnits', {}), }; } From 7f7cadd7c58a59106b3c9f535a29138bb33e619e Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:11:16 +0800 Subject: [PATCH 059/126] key by ID to get rates --- src/libs/actions/Policy.js | 22 ++++++++++++------- .../reimburse/WorkspaceReimburseView.js | 10 +++++---- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 8ca92267e5a3..4f0d46a2afbd 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -650,6 +650,7 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { * @param {Object} values */ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { + const customUnitRateID = lodashGet(values, 'customUnitRateID', ''); const optimisticData = [ { onyxMethod: 'merge', @@ -658,9 +659,11 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values customUnits: { [customUnitID]: { rates: { - ...values, - errors: null, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + [customUnitRateID]: { + ...values, + errors: null, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, }, }, }, @@ -676,8 +679,9 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values customUnits: { [customUnitID]: { rates: { - ...values, - pendingAction: null, + [customUnitRateID]: { + pendingAction: null, + }, }, }, }, @@ -693,9 +697,11 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values customUnits: { [customUnitID]: { rates: { - ...currentCustomUnitRate, - errors: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('workspace.reimburse.updateCustomUnitError'), + [customUnitRateID]: { + ...currentCustomUnitRate, + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('workspace.reimburse.updateCustomUnitError'), + }, }, }, }, diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 1ad2eacbdda4..8c5766056d93 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -57,12 +57,14 @@ class WorkspaceReimburseView extends React.Component { constructor(props) { super(props); const distanceCustomUnit = _.find(lodashGet(props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); + const customUnitRates = lodashGet(distanceCustomUnit, 'rates', {}); this.state = { unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''), + unitRateID: _.first(_.keys(customUnitRates)), unitName: lodashGet(distanceCustomUnit, 'name', ''), unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'), - rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates.rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), + rateValue: this.getRateDisplayValue(lodashGet(customUnitRates, this.state.unitRateID, 'rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), outputCurrency: lodashGet(props, 'policy.outputCurrency', ''), }; @@ -148,7 +150,7 @@ class WorkspaceReimburseView extends React.Component { }); const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); - const currentCustomUnitRate = lodashGet(distanceCustomUnit, 'rates', {}); + const currentCustomUnitRate = lodashGet(distanceCustomUnit, 'rates', this.state.unitRateID, {}); Policy.setCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { ..._.omit(currentCustomUnitRate, 'rate'), rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, @@ -193,10 +195,10 @@ class WorkspaceReimburseView extends React.Component { Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID)} errorRowStyles={[styles.flex1]} > From 0ced3e574663e8d7dc3a9fde45e8ab0288d18dda Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:13:16 +0800 Subject: [PATCH 060/126] access directly --- src/libs/actions/Policy.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 4f0d46a2afbd..3ac63f0acc49 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -650,7 +650,6 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { * @param {Object} values */ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { - const customUnitRateID = lodashGet(values, 'customUnitRateID', ''); const optimisticData = [ { onyxMethod: 'merge', @@ -659,7 +658,7 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values customUnits: { [customUnitID]: { rates: { - [customUnitRateID]: { + [values.customUnitRateID]: { ...values, errors: null, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, @@ -679,7 +678,7 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values customUnits: { [customUnitID]: { rates: { - [customUnitRateID]: { + [values.customUnitRateID]: { pendingAction: null, }, }, From 651ab0a14f99d745d06f8dec21f53c7b82bef68c Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:14:35 +0800 Subject: [PATCH 061/126] cleanup --- src/libs/actions/Policy.js | 11 +++++++---- .../workspace/reimburse/WorkspaceReimburseView.js | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 3ac63f0acc49..34b25b4f58a8 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -558,17 +558,20 @@ function setWorkspaceErrors(policyID, errors) { /** * @param {String} policyID - * @param {Number} customUnitID + * @param {String} customUnitID + * @param {String} customUnitRateID */ -function clearCustomUnitErrors(policyID, customUnitID) { +function clearCustomUnitErrors(policyID, customUnitID, customUnitRateID) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { customUnits: { [customUnitID]: { errors: null, pendingAction: null, rates: { - errors: null, - pendingAction: null, + [customUnitRateID]: { + errors: null, + pendingAction: null, + }, }, }, }, diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 8c5766056d93..fb71c14a42b4 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -199,7 +199,7 @@ class WorkspaceReimburseView extends React.Component { }} pendingAction={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'pendingAction']) || lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates', this.state.unitRateID, 'pendingAction'])} - onClose={() => Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID)} + onClose={() => Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID, this.state.unitRateID)} errorRowStyles={[styles.flex1]} > From 1e93077ad908c9b575735980e704f7f9cacc8bc8 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:15:30 +0800 Subject: [PATCH 062/126] cleanup --- src/libs/actions/Policy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 34b25b4f58a8..8d8b44648f8e 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -699,7 +699,7 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values customUnits: { [customUnitID]: { rates: { - [customUnitRateID]: { + [currentCustomUnitRate.customUnitRateID]: { ...currentCustomUnitRate, errors: { [DateUtils.getMicroseconds()]: Localize.translateLocal('workspace.reimburse.updateCustomUnitError'), From c6a23044da1bfda8ee659df4563f9c293765618c Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:16:03 +0800 Subject: [PATCH 063/126] fix propTypes --- .../workspace/reimburse/WorkspaceReimburseView.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index fb71c14a42b4..064b6b156adb 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -40,11 +40,13 @@ const propTypes = { attributes: PropTypes.shape({ unit: PropTypes.string, }), - rates: PropTypes.shape({ - customUnitRateID: PropTypes.string, - name: PropTypes.string, - rate: PropTypes.number, - }), + rates: PropTypes.objectOf( + PropTypes.shape({ + customUnitRateID: PropTypes.string, + name: PropTypes.string, + rate: PropTypes.number, + }), + ), }), ), outputCurrency: PropTypes.string, From 71447ecaeac3b3f68a23601ec152f32e5d7f1c7a Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:28:18 +0800 Subject: [PATCH 064/126] update customUnitRate accessing --- src/pages/workspace/reimburse/WorkspaceReimburseView.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 064b6b156adb..64eb75825347 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -59,14 +59,14 @@ class WorkspaceReimburseView extends React.Component { constructor(props) { super(props); const distanceCustomUnit = _.find(lodashGet(props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); - const customUnitRates = lodashGet(distanceCustomUnit, 'rates', {}); + const customUnitRate = _.find(lodashGet(distanceCustomUnit, 'rates', {}), rate => rate.name === 'Default Rate'); this.state = { unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''), - unitRateID: _.first(_.keys(customUnitRates)), + unitRateID: lodashGet(customUnitRate, 'customUnitRateID', ''), unitName: lodashGet(distanceCustomUnit, 'name', ''), unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'), - rateValue: this.getRateDisplayValue(lodashGet(customUnitRates, this.state.unitRateID, 'rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), + rateValue: this.getRateDisplayValue(lodashGet(customUnitRate, 'rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), outputCurrency: lodashGet(props, 'policy.outputCurrency', ''), }; From 1da0a2a2a9f40892f1d5794bcb4ae8b7f748e5ec Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:28:52 +0800 Subject: [PATCH 065/126] remove unused --- src/pages/workspace/reimburse/WorkspaceReimburseView.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 64eb75825347..2e1723c927a8 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -202,7 +202,6 @@ class WorkspaceReimburseView extends React.Component { pendingAction={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'pendingAction']) || lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates', this.state.unitRateID, 'pendingAction'])} onClose={() => Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID, this.state.unitRateID)} - errorRowStyles={[styles.flex1]} > From 55252de2c80d011c56749fc72dd5636dee0b2437 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Tue, 30 Aug 2022 16:30:26 +0800 Subject: [PATCH 066/126] cleanup --- .../workspace/reimburse/WorkspaceReimburseView.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 2e1723c927a8..ddb79e01866a 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -152,7 +152,7 @@ class WorkspaceReimburseView extends React.Component { }); const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); - const currentCustomUnitRate = lodashGet(distanceCustomUnit, 'rates', this.state.unitRateID, {}); + const currentCustomUnitRate = lodashGet(distanceCustomUnit, ['rates', this.state.unitRateID], {}); Policy.setCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { ..._.omit(currentCustomUnitRate, 'rate'), rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, @@ -196,11 +196,11 @@ class WorkspaceReimburseView extends React.Component { Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID, this.state.unitRateID)} > From 4591cef217d923e838dd1f570ae367482c1891f7 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 31 Aug 2022 21:50:14 +0800 Subject: [PATCH 067/126] add comment --- src/components/OfflineWithFeedback.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index 18aaac61e0d1..9d3aea05e2da 100644 --- a/src/components/OfflineWithFeedback.js +++ b/src/components/OfflineWithFeedback.js @@ -87,6 +87,9 @@ const OfflineWithFeedback = (props) => { .keys() .sortBy() .map(key => props.errors[key]) + + // Using uniq here since some fields are wrapped by the same OfflineWithFeedback component (e.g. WorkspaceReimburseView) + // and can potentially pass the same error. .uniq() .value(); From f862e26dde00a89c59c642e11bd0931b19ab4b73 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 31 Aug 2022 21:51:54 +0800 Subject: [PATCH 068/126] use update instead of set --- src/libs/actions/Policy.js | 6 +++--- src/pages/workspace/reimburse/WorkspaceReimburseView.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 13a1a28f8075..bfeacdf67590 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -673,7 +673,7 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { * @param {String} customUnitID * @param {Object} values */ -function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { +function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { const optimisticData = [ { onyxMethod: 'merge', @@ -733,7 +733,7 @@ function setCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values }, ]; - API.write('SetWorkspaceCustomUnitRate', { + API.write('UpdateWorkspaceCustomUnitRate', { policyID, customUnitID, customUnitRate: JSON.stringify(values), @@ -872,7 +872,7 @@ export { createAndNavigate, createAndGetPolicyList, updateWorkspaceCustomUnit, - setCustomUnitRate, + updateCustomUnitRate, updateLastAccessedWorkspace, subscribeToPolicyEvents, clearDeleteMemberError, diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 451d3053749c..502cfed04d38 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -152,7 +152,7 @@ class WorkspaceReimburseView extends React.Component { const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); const currentCustomUnitRate = lodashGet(distanceCustomUnit, ['rates', this.state.unitRateID], {}); - Policy.setCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { + Policy.updateCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { ..._.omit(currentCustomUnitRate, 'rate'), rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, }); From 7aa9ab619ac7cf565a1924fcd908915fb91ba51c Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 31 Aug 2022 22:14:53 +0800 Subject: [PATCH 069/126] remove _.omit --- src/pages/workspace/reimburse/WorkspaceReimburseView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 502cfed04d38..8fc712e3b63f 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -153,7 +153,7 @@ class WorkspaceReimburseView extends React.Component { const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); const currentCustomUnitRate = lodashGet(distanceCustomUnit, ['rates', this.state.unitRateID], {}); Policy.updateCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { - ..._.omit(currentCustomUnitRate, 'rate'), + ...currentCustomUnitRate, rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, }); } From 74ff01e295a1bdbc1418d106358a569c16c42642 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 31 Aug 2022 22:17:41 +0800 Subject: [PATCH 070/126] round to 3 decimal places before multiplying and passing to Policy action --- src/pages/workspace/reimburse/WorkspaceReimburseView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 8fc712e3b63f..f958ee7c33ea 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -154,7 +154,7 @@ class WorkspaceReimburseView extends React.Component { const currentCustomUnitRate = lodashGet(distanceCustomUnit, ['rates', this.state.unitRateID], {}); Policy.updateCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { ...currentCustomUnitRate, - rate: numValue * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, + rate: numValue.toFixed(3) * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, }); } From 49f7118076d206a5c6b8d9471cf9e33794d49f55 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 31 Aug 2022 22:18:14 +0800 Subject: [PATCH 071/126] remove defaults --- src/pages/workspace/reimburse/WorkspaceReimburseView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index f958ee7c33ea..10c5e3073ae5 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -198,8 +198,8 @@ class WorkspaceReimburseView extends React.Component { ...lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'errors'], {}), ...lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates', this.state.unitRateID, 'errors'], {}), }} - pendingAction={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'pendingAction'], '') - || lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates', this.state.unitRateID, 'pendingAction'], '')} + pendingAction={lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'pendingAction']) + || lodashGet(this.props, ['policy', 'customUnits', this.state.unitID, 'rates', this.state.unitRateID, 'pendingAction'])} onClose={() => Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID, this.state.unitRateID)} > From be512f51495ee2f02dc02b3e591ea48a02aa9a25 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Wed, 31 Aug 2022 22:20:02 +0800 Subject: [PATCH 072/126] use onyxRates instead of rates --- .../workspace/reimburse/WorkspaceReimburseView.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 10c5e3073ae5..09c7c71dfba3 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -39,7 +39,7 @@ const propTypes = { attributes: PropTypes.shape({ unit: PropTypes.string, }), - rates: PropTypes.objectOf( + onyxRates: PropTypes.objectOf( PropTypes.shape({ customUnitRateID: PropTypes.string, name: PropTypes.string, @@ -58,7 +58,7 @@ class WorkspaceReimburseView extends React.Component { constructor(props) { super(props); const distanceCustomUnit = _.find(lodashGet(props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); - const customUnitRate = _.find(lodashGet(distanceCustomUnit, 'rates', {}), rate => rate.name === 'Default Rate'); + const customUnitRate = _.find(lodashGet(distanceCustomUnit, 'onyxRates', {}), rate => rate.name === 'Default Rate'); this.state = { unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''), @@ -151,7 +151,7 @@ class WorkspaceReimburseView extends React.Component { }); const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); - const currentCustomUnitRate = lodashGet(distanceCustomUnit, ['rates', this.state.unitRateID], {}); + const currentCustomUnitRate = lodashGet(distanceCustomUnit, ['onyxRates', this.state.unitRateID], {}); Policy.updateCustomUnitRate(this.props.policyID, currentCustomUnitRate, this.state.unitID, { ...currentCustomUnitRate, rate: numValue.toFixed(3) * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET, @@ -196,10 +196,10 @@ class WorkspaceReimburseView extends React.Component { Policy.clearCustomUnitErrors(this.props.policyID, this.state.unitID, this.state.unitRateID)} > From 0c591d1a95b7f7b6f7835df032fc91f504cf600f Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Thu, 1 Sep 2022 11:54:30 +0800 Subject: [PATCH 073/126] use onyxRates instead of rates --- src/libs/actions/Policy.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index bfeacdf67590..9f42a4d08856 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -588,7 +588,7 @@ function clearCustomUnitErrors(policyID, customUnitID, customUnitRateID) { [customUnitID]: { errors: null, pendingAction: null, - rates: { + onyxRates: { [customUnitRateID]: { errors: null, pendingAction: null, @@ -681,7 +681,7 @@ function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, val value: { customUnits: { [customUnitID]: { - rates: { + onyxRates: { [values.customUnitRateID]: { ...values, errors: null, @@ -701,7 +701,7 @@ function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, val value: { customUnits: { [customUnitID]: { - rates: { + onyxRates: { [values.customUnitRateID]: { pendingAction: null, }, @@ -719,7 +719,7 @@ function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, val value: { customUnits: { [customUnitID]: { - rates: { + onyxRates: { [currentCustomUnitRate.customUnitRateID]: { ...currentCustomUnitRate, errors: { From c7077790f21319980235b40829c807cec345327f Mon Sep 17 00:00:00 2001 From: Han MingYun Date: Thu, 1 Sep 2022 21:57:47 +0800 Subject: [PATCH 074/126] 10535: set the outline style based on outline width --- src/styles/addOutlineWidth/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/addOutlineWidth/index.js b/src/styles/addOutlineWidth/index.js index db9ba66fe087..a25bc887dc10 100644 --- a/src/styles/addOutlineWidth/index.js +++ b/src/styles/addOutlineWidth/index.js @@ -17,6 +17,7 @@ function withOutlineWidth(obj, val, error = false) { return { ...obj, outlineWidth: val, + outlineStyle: val ? 'auto' : 'none', boxShadow: val !== 0 ? `0px 0px 0px ${val}px ${error ? themeDefault.badgeDangerBG : themeDefault.borderFocus}` : 'none', }; } From 390ed23326bd11d0a0bed94b7944d0ee9974ce33 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Thu, 1 Sep 2022 17:24:09 +0200 Subject: [PATCH 075/126] new constants for chat names --- src/CONST.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CONST.js b/src/CONST.js index 4b0bd6f4a502..033bb950f2a3 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -281,6 +281,10 @@ const CONST = { POLICY_ROOM: 'policyRoom', POLICY_EXPENSE_CHAT: 'policyExpenseChat', }, + WORKSPACE_CHAT_ROOMS: { + ANNOUNCE: '#announce', + ADMINS: '#admins', + }, STATE_NUM: { OPEN: 0, PROCESSING: 1, From 322faee6a92710459a5cff9b8cd2ff577773ec27 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Thu, 1 Sep 2022 17:24:27 +0200 Subject: [PATCH 076/126] remove old api command and use new parameters --- src/libs/actions/Policy.js | 29 ++++++++++++++++------------- src/libs/actions/Report.js | 31 +++++++++++++++---------------- src/libs/deprecatedAPI.js | 12 ------------ 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index b46ede04f4ad..27293529732d 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -751,19 +751,22 @@ function generatePolicyID() { function createWorkspace() { const policyID = generatePolicyID(); const { - announceReportID, + announceChatReportID, announceChatData, - adminReportID, + adminsChatReportID, adminChatData, - expenseReportID, + expenseChatReportID, expenseChatData } = Report.createOptimisticWorkspaceChats(policyID, sessionEmail); + const workspaceName = generateDefaultWorkspaceName(); API.write('CreateWorkspace', { policyID, - announceReportID, - adminReportID, - expenseReportID, + announceChatReportID, + adminsChatReportID, + expenseChatReportID, + policyName: workspaceName, + type: CONST.POLICY.TYPE.FREE, }, { optimisticData: [{ onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -771,7 +774,7 @@ function createWorkspace() { value: { id: policyID, type: CONST.POLICY.TYPE.FREE, - name: 'Default', + name: workspaceName, role: CONST.POLICY.ROLE.ADMIN, outputCurrency: 'USD', pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, @@ -786,15 +789,15 @@ function createWorkspace() { }) }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${announceReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: announceChatData, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${adminReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: adminChatData, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: expenseChatData, }], successData: [{ @@ -814,15 +817,15 @@ function createWorkspace() { value: null }, { onyxMethod: CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${announceReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${adminReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: null, }] }); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 9e1bf6c852dc..53c9e4480b40 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -650,41 +650,40 @@ function createOptimisticChatReport(participantList) { } function createOptimisticWorkspaceChats(policyID, ownerEmail) { - const announceReportID = ReportUtils.generateReportID(); + const announceChatReportID = ReportUtils.generateReportID(); const announceChatData = { - chatType: CONST.CHAT_TYPE.POLICY_ANNOUNCE, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID: policyID, - reportID: announceReportID, - reportName: CONST.CHAT_NAME_POLICY_ANNOUNCE, + reportID: announceChatReportID, + reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, }; - const adminReportID = ReportUtils.generateReportID(); + const adminsChatReportID = ReportUtils.generateReportID(); const adminChatData = { - chatType: CONST.CHAT_TYPE.POLICY_ADMINS, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, policyID: policyID, - reportID: adminReportID, - reportName: CONST.CHAT_NAME_POLICY_ADMINS, + reportID: adminsChatReportID, + reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ADMINS, }; - const expenseReportID = ReportUtils.generateReportID(); + const expenseChatReportID = ReportUtils.generateReportID(); const expenseChatData = { - chatType: CONST.CHAT_TYPE.POLICY_EXPENSE_CHAT, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, isOwnPolicyExpenseChat: true, ownerEmail: ownerEmail, policyID: policyID, - reportID: expenseReportID, - reportName: CONST.CHAT_NAME_POLICY_EXPENSE, + reportID: expenseChatReportID, + reportName: '', }; return { - announceReportID, + announceChatReportID, announceChatData, - adminReportID, + adminsChatReportID, adminChatData, - expenseReportID, + expenseChatReportID, expenseChatData } - } /** diff --git a/src/libs/deprecatedAPI.js b/src/libs/deprecatedAPI.js index 26a25ff2c9e7..dffae4360b76 100644 --- a/src/libs/deprecatedAPI.js +++ b/src/libs/deprecatedAPI.js @@ -478,17 +478,6 @@ function User_IsUsingExpensifyCard() { return Network.post('User_IsUsingExpensifyCard', {}); } -/** - * @param {Object} parameters - * @param {String} [parameters.type] - * @param {String} [parameters.policyName] - * @returns {Promise} - */ -function Policy_Create(parameters) { - const commandName = 'Policy_Create'; - return Network.post(commandName, parameters); -} - /** * @param {Object} parameters * @param {String} parameters.policyID @@ -640,7 +629,6 @@ export { Wallet_GetOnfidoSDKToken, TransferWalletBalance, GetLocalCurrency, - Policy_Create, Policy_CustomUnitRate_Update, Policy_Employees_Remove, PreferredLocale_Update, From 346167dbae1dd93b464054cc4bda4c6b1632facb Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Thu, 1 Sep 2022 19:01:43 +0200 Subject: [PATCH 077/126] update POLICY_MEMBER_LIST --- src/libs/actions/Policy.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 27293529732d..8b18a5e552b8 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -776,6 +776,7 @@ function createWorkspace() { type: CONST.POLICY.TYPE.FREE, name: workspaceName, role: CONST.POLICY.ROLE.ADMIN, + owner: sessionEmail, outputCurrency: 'USD', pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -783,10 +784,7 @@ function createWorkspace() { { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, - value: getSimplifiedEmployeeList({ - 'email': sessionEmail, - 'role': CONST.POLICY.ROLE.ADMIN - }) + value: getSimplifiedEmployeeList([{'email': sessionEmail, 'role': CONST.POLICY.ROLE.ADMIN}]) }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, From 9d76d0b1bdc9b7bcf288897ee234578e189a9ae4 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Thu, 1 Sep 2022 19:25:37 +0200 Subject: [PATCH 078/126] lints --- src/libs/actions/Policy.js | 19 +++++++++---------- src/libs/actions/Report.js | 38 +++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 2e7d921d31ff..e137f6d36570 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -738,7 +738,7 @@ function generatePolicyID() { } /** - * Optimistically creates a new workspace and default workspace chats + * Optimistically creates a new workspace and default workspace chats * @param {*} ownerEmail */ function createWorkspace() { @@ -749,10 +749,9 @@ function createWorkspace() { adminsChatReportID, adminChatData, expenseChatReportID, - expenseChatData + expenseChatData, } = Report.createOptimisticWorkspaceChats(policyID, sessionEmail); const workspaceName = generateDefaultWorkspaceName(); - API.write('CreateWorkspace', { policyID, announceChatReportID, @@ -771,13 +770,13 @@ function createWorkspace() { role: CONST.POLICY.ROLE.ADMIN, owner: sessionEmail, outputCurrency: 'USD', - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, - value: getSimplifiedEmployeeList([{'email': sessionEmail, 'role': CONST.POLICY.ROLE.ADMIN}]) + value: getSimplifiedEmployeeList([{email: sessionEmail, role: CONST.POLICY.ROLE.ADMIN}]), }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, @@ -795,17 +794,17 @@ function createWorkspace() { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - pendingAction: null - } + pendingAction: null, + }, }], failureData: [{ onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: null + value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, - value: null + value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, @@ -818,7 +817,7 @@ function createWorkspace() { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: null, - }] + }], }); Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policyID)); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 53c9e4480b40..82344b179cef 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -652,28 +652,28 @@ function createOptimisticChatReport(participantList) { function createOptimisticWorkspaceChats(policyID, ownerEmail) { const announceChatReportID = ReportUtils.generateReportID(); const announceChatData = { - chatType: CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, - policyID: policyID, - reportID: announceChatReportID, - reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, + policyID, + reportID: announceChatReportID, + reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, }; - + const adminsChatReportID = ReportUtils.generateReportID(); const adminChatData = { - chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, - policyID: policyID, - reportID: adminsChatReportID, - reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ADMINS, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + policyID, + reportID: adminsChatReportID, + reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ADMINS, }; - - const expenseChatReportID = ReportUtils.generateReportID(); + + const expenseChatReportID = ReportUtils.generateReportID(); const expenseChatData = { - chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, - isOwnPolicyExpenseChat: true, - ownerEmail: ownerEmail, - policyID: policyID, - reportID: expenseChatReportID, - reportName: '', + chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, + isOwnPolicyExpenseChat: true, + ownerEmail, + policyID, + reportID: expenseChatReportID, + reportName: '', }; return { @@ -682,8 +682,8 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { adminsChatReportID, adminChatData, expenseChatReportID, - expenseChatData - } + expenseChatData, + }; } /** From 14044429b21f69a6373fc93baba22e629080564f Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 2 Sep 2022 12:46:36 +0200 Subject: [PATCH 079/126] add pending action to chats --- src/libs/actions/Policy.js | 18 ++++++++++++++++++ src/libs/actions/Report.js | 3 +++ 2 files changed, 21 insertions(+) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index e137f6d36570..4e4b151ac4f5 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -796,6 +796,24 @@ function createWorkspace() { value: { pendingAction: null, }, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, + value: { + pendingAction: null, + }, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, + value: { + pendingAction: null, + }, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, + value: { + pendingAction: null, + }, }], failureData: [{ onyxMethod: CONST.ONYX.METHOD.SET, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 82344b179cef..797ba015d438 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -656,6 +656,7 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { policyID, reportID: announceChatReportID, reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }; const adminsChatReportID = ReportUtils.generateReportID(); @@ -664,6 +665,7 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { policyID, reportID: adminsChatReportID, reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ADMINS, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }; const expenseChatReportID = ReportUtils.generateReportID(); @@ -674,6 +676,7 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { policyID, reportID: expenseChatReportID, reportName: '', + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }; return { From 271b76eb364c2f4a05c828bf5f95a359924fbdf2 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 2 Sep 2022 13:40:59 +0200 Subject: [PATCH 080/126] address js docs and also add rest of default workspace chat apramters --- src/libs/actions/Policy.js | 1 - src/libs/actions/Report.js | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 4e4b151ac4f5..c86713161789 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -739,7 +739,6 @@ function generatePolicyID() { /** * Optimistically creates a new workspace and default workspace chats - * @param {*} ownerEmail */ function createWorkspace() { const policyID = generatePolicyID(); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 2fcfeda92d19..38b9bddd9b84 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -616,6 +616,11 @@ function createOptimisticChatReport(participantList) { }; } +/** + * @param {String} policyID + * @param {String} ownerEmail + * @returns {Object} + */ function createOptimisticWorkspaceChats(policyID, ownerEmail) { const announceChatReportID = ReportUtils.generateReportID(); const announceChatData = { @@ -624,6 +629,23 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { reportID: announceChatReportID, reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + hasOutstandingIOU: false, + isOwnPolicyExpenseChat: false, + isPinned: false, + lastActorEmail: '', + lastMessageHtml: '', + lastMessageText: null, + lastReadSequenceNumber: 0, + lastMessageTimestamp: 0, + lastVisitedTimestamp: 0, + maxSequenceNumber: 0, + notificationPreference: '', + oldPolicyName: '', + ownerEmail: '__FAKE__', + participants: [ownerEmail], + stateNum: 0, + statusNum: 0, + visibility: undefined, }; const adminsChatReportID = ReportUtils.generateReportID(); @@ -633,6 +655,23 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { reportID: adminsChatReportID, reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ADMINS, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + hasOutstandingIOU: false, + isOwnPolicyExpenseChat: false, + isPinned: false, + lastActorEmail: '', + lastMessageHtml: '', + lastMessageText: null, + lastReadSequenceNumber: 0, + lastMessageTimestamp: 0, + lastVisitedTimestamp: 0, + maxSequenceNumber: 0, + notificationPreference: '', + oldPolicyName: '', + ownerEmail: '__FAKE__', + participants: [ownerEmail], + stateNum: 0, + statusNum: 0, + visibility: undefined, }; const expenseChatReportID = ReportUtils.generateReportID(); @@ -644,6 +683,21 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { reportID: expenseChatReportID, reportName: '', pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + hasOutstandingIOU: false, + isPinned: false, + lastActorEmail: '', + lastMessageHtml: '', + lastMessageText: null, + lastReadSequenceNumber: 0, + lastMessageTimestamp: 0, + lastVisitedTimestamp: 0, + maxSequenceNumber: 0, + notificationPreference: '', + oldPolicyName: '', + participants: [ownerEmail], + stateNum: 0, + statusNum: 0, + visibility: undefined, }; return { From 8085eb4ef648fc0c3673b833bb26e4195ddb1a60 Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Fri, 2 Sep 2022 21:47:43 +0530 Subject: [PATCH 081/126] removed ternary condition --- src/components/TextInput/BaseTextInput.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/TextInput/BaseTextInput.js b/src/components/TextInput/BaseTextInput.js index 42d7a2af0e33..d537269cf4f4 100644 --- a/src/components/TextInput/BaseTextInput.js +++ b/src/components/TextInput/BaseTextInput.js @@ -222,13 +222,13 @@ class BaseTextInput extends Component { // When multiline is not supplied, calculating textinput height using onLayout // eslint-disable-next-line react/jsx-props-no-spreading - {...!this.props.multiline ? { + {...!this.props.multiline && { onLayout: event => ( this.setState({ height: event.nativeEvent.layout.height, }) ), - } : null} + }} style={[ textInputContainerStyles, From 8a227c4a90c61d3c700663fc1b312bcec089d847 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Sat, 3 Sep 2022 23:06:22 +0530 Subject: [PATCH 082/126] refactor: make keyboard actions available by default --- src/components/PopoverMenu/BasePopoverMenu.js | 8 ++------ src/components/PopoverMenu/popoverMenuPropTypes.js | 4 ---- src/pages/home/report/ReportActionCompose.js | 1 - 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/components/PopoverMenu/BasePopoverMenu.js b/src/components/PopoverMenu/BasePopoverMenu.js index e23467ae35d5..52d876c48792 100644 --- a/src/components/PopoverMenu/BasePopoverMenu.js +++ b/src/components/PopoverMenu/BasePopoverMenu.js @@ -41,12 +41,11 @@ class BasePopoverMenu extends PureComponent { } componentDidUpdate(prevProps) { - if (this.props.shouldEnableArrowKeysActions === prevProps.shouldEnableArrowKeysActions - && this.props.isVisible === prevProps.isVisible) { + if (this.props.isVisible === prevProps.isVisible) { return; } - if (this.props.shouldEnableArrowKeysActions && this.props.isVisible) { + if (this.props.isVisible) { this.attachKeyboardListener(); } else { this.removeKeyboardListener(); @@ -79,9 +78,6 @@ class BasePopoverMenu extends PureComponent { * @param {Number} index */ updateFocusedIndex(index) { - if (!this.props.shouldEnableArrowKeysActions) { - return; - } this.setState({focusedIndex: index}); } diff --git a/src/components/PopoverMenu/popoverMenuPropTypes.js b/src/components/PopoverMenu/popoverMenuPropTypes.js index 3ea1b3b1f630..402b63418d1b 100644 --- a/src/components/PopoverMenu/popoverMenuPropTypes.js +++ b/src/components/PopoverMenu/popoverMenuPropTypes.js @@ -49,9 +49,6 @@ const propTypes = { /** Whether disable the animations */ disableAnimation: PropTypes.bool, - - /** Whether to allow arrow key actions on the list */ - shouldEnableArrowKeysActions: PropTypes.bool, }; const defaultProps = { @@ -59,7 +56,6 @@ const defaultProps = { animationOut: 'fadeOut', headerText: undefined, disableAnimation: true, - shouldEnableArrowKeysActions: false, }; export {propTypes, defaultProps}; diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index d77d52a07b23..61369be57010 100755 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -571,7 +571,6 @@ class ReportActionCompose extends React.Component { this.setMenuVisibility(false)} onItemSelected={() => this.setMenuVisibility(false)} From 60e10848ca0c226d7214602fa72b8ce959e9c6ea Mon Sep 17 00:00:00 2001 From: Mohammad Luthfi Fathur Rahman Date: Sun, 4 Sep 2022 11:36:47 +0700 Subject: [PATCH 083/126] format the text plain pasted --- src/components/Composer/index.js | 34 +++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index a7c1d0045170..fe4df01b5dd5 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -3,6 +3,7 @@ import {StyleSheet} from 'react-native'; import PropTypes from 'prop-types'; import _ from 'underscore'; import ExpensiMark from 'expensify-common/lib/ExpensiMark'; +import Str from 'expensify-common/lib/str'; import RNTextInput from '../RNTextInput'; import withLocalize, {withLocalizePropTypes} from '../withLocalize'; import Growl from '../../libs/Growl'; @@ -130,6 +131,7 @@ class Composer extends React.Component { }, }; this.dragNDropListener = this.dragNDropListener.bind(this); + this.paste = this.paste.bind(this); this.handlePaste = this.handlePaste.bind(this); this.handlePastedHTML = this.handlePastedHTML.bind(this); this.handleWheel = this.handleWheel.bind(this); @@ -233,15 +235,12 @@ class Composer extends React.Component { } /** - * Manually place the pasted HTML into Composer - * - * @param {String} html - pasted HTML + * Set pasted text to clipboard + * @param {String} text */ - handlePastedHTML(html) { - const parser = new ExpensiMark(); - const markdownText = parser.htmlToMarkdown(html); + paste(text) { try { - document.execCommand('insertText', false, markdownText); + document.execCommand('insertText', false, text); this.updateNumberOfLines(); // Pointer will go out of sight when a large paragraph is pasted on the web. Refocusing the input keeps the cursor in view. @@ -251,6 +250,17 @@ class Composer extends React.Component { } catch (e) {} } + /** + * Manually place the pasted HTML into Composer + * + * @param {String} html - pasted HTML + */ + handlePastedHTML(html) { + const parser = new ExpensiMark(); + + this.paste(parser.htmlToMarkdown(html)); + } + /** * Check the paste event for an attachment, parse the data and call onPasteFile from props with the selected file, * Otherwise, convert pasted HTML to Markdown and set it on the composer. @@ -258,13 +268,16 @@ class Composer extends React.Component { * @param {ClipboardEvent} event */ handlePaste(event) { + if (event) { + event.preventDefault(); + } + const {files, types} = event.clipboardData; const TEXT_HTML = 'text/html'; // If paste contains files, then trigger file management if (files.length > 0) { // Prevent the default so we do not post the file name into the text box - event.preventDefault(); this.props.onPasteFile(event.clipboardData.files[0]); return; } @@ -273,7 +286,6 @@ class Composer extends React.Component { if (types.includes(TEXT_HTML)) { const pastedHTML = event.clipboardData.getData(TEXT_HTML); - event.preventDefault(); const domparser = new DOMParser(); const embeddedImages = domparser.parseFromString(pastedHTML, TEXT_HTML).images; @@ -309,7 +321,11 @@ class Composer extends React.Component { } this.handlePastedHTML(pastedHTML); + return; } + + const plainText = event.clipboardData.getData('text/plain'); + this.paste(Str.htmlDecode(plainText)); } /** From c6a741947177b6a20e5acdfd0d17974fe3a6248a Mon Sep 17 00:00:00 2001 From: Luthfi Date: Mon, 5 Sep 2022 07:35:49 +0700 Subject: [PATCH 084/126] Update src/components/Composer/index.js Co-authored-by: Manan --- src/components/Composer/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index fe4df01b5dd5..ec54c6e00ebb 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -257,7 +257,6 @@ class Composer extends React.Component { */ handlePastedHTML(html) { const parser = new ExpensiMark(); - this.paste(parser.htmlToMarkdown(html)); } From 3ddc1ef5b59419034ceaa024304627aad8f5ccba Mon Sep 17 00:00:00 2001 From: Luthfi Date: Mon, 5 Sep 2022 08:48:22 +0700 Subject: [PATCH 085/126] remove condition of params --- src/components/Composer/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index ec54c6e00ebb..37c951ca84dd 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -267,9 +267,7 @@ class Composer extends React.Component { * @param {ClipboardEvent} event */ handlePaste(event) { - if (event) { - event.preventDefault(); - } + event.preventDefault(); const {files, types} = event.clipboardData; const TEXT_HTML = 'text/html'; From 39c5042941e50c8aaebcfb448c95d18938caccd6 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 5 Sep 2022 10:00:08 +0100 Subject: [PATCH 086/126] fix stuff messed up in merge --- src/pages/workspace/reimburse/WorkspaceReimburseView.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 7a327dce43b7..3c92334818e0 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -98,13 +98,13 @@ class WorkspaceReimburseView extends React.Component { .values() .findWhere({name: CONST.CUSTOM_UNITS.NAME_DISTANCE}) .value(); - + const customUnitRate = _.find(lodashGet(distanceCustomUnit, 'onyxRates', {}), rate => rate.name === 'Default Rate'); this.setState({ unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''), unitName: lodashGet(distanceCustomUnit, 'name', ''), unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'), - unitRateID: lodashGet(distanceCustomUnit, 'rates[0].customUnitRateID', ''), - rateValue: this.getRateDisplayValue(lodashGet(distanceCustomUnit, 'rates[0].rate', 0) / 100), + unitRateID: lodashGet(customUnitRate, 'customUnitRateID'), + rateValue: this.getRateDisplayValue(lodashGet(customUnitRate, 'rate', 0) / 100), }); } From dbaaa36a01ed2e97814097534ffe78ae0c9742d7 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 5 Sep 2022 10:25:30 +0100 Subject: [PATCH 087/126] rename rateValue => unitRateValue --- .../reimburse/WorkspaceReimburseView.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 3c92334818e0..29c04b7b8921 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -66,10 +66,10 @@ class WorkspaceReimburseView extends React.Component { this.state = { unitID: lodashGet(distanceCustomUnit, 'customUnitID', ''), - unitRateID: lodashGet(customUnitRate, 'customUnitRateID', ''), unitName: lodashGet(distanceCustomUnit, 'name', ''), unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'), - rateValue: this.getRateDisplayValue(lodashGet(customUnitRate, 'rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), + unitRateID: lodashGet(customUnitRate, 'customUnitRateID', ''), + unitRateValue: this.getRateDisplayValue(lodashGet(customUnitRate, 'rate', 0) / CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET), outputCurrency: lodashGet(props, 'policy.outputCurrency', ''), }; @@ -104,7 +104,7 @@ class WorkspaceReimburseView extends React.Component { unitName: lodashGet(distanceCustomUnit, 'name', ''), unitValue: lodashGet(distanceCustomUnit, 'attributes.unit', 'mi'), unitRateID: lodashGet(customUnitRate, 'customUnitRateID'), - rateValue: this.getRateDisplayValue(lodashGet(customUnitRate, 'rate', 0) / 100), + unitRateValue: this.getRateDisplayValue(lodashGet(customUnitRate, 'rate', 0) / 100), }); } @@ -129,10 +129,10 @@ class WorkspaceReimburseView extends React.Component { const isInvalidRateValue = value !== '' && !CONST.REGEX.RATE_VALUE.test(value); this.setState(prevState => ({ - rateValue: !isInvalidRateValue ? value : prevState.rateValue, + unitRateValue: !isInvalidRateValue ? value : prevState.unitRateValue, }), () => { // Set the corrected value with a delay and sync to the server - this.updateRateValueDebounced(this.state.rateValue); + this.updateRateValueDebounced(this.state.unitRateValue); }); } @@ -155,7 +155,7 @@ class WorkspaceReimburseView extends React.Component { return; } - this.updateRateValueDebounced(this.state.rateValue); + this.updateRateValueDebounced(this.state.unitRateValue); } updateRateValue(value) { @@ -166,7 +166,7 @@ class WorkspaceReimburseView extends React.Component { } this.setState({ - rateValue: numValue.toFixed(3), + unitRateValue: numValue.toFixed(3), }); const distanceCustomUnit = _.find(lodashGet(this.props, 'policy.customUnits', {}), unit => unit.name === 'Distance'); @@ -228,7 +228,7 @@ class WorkspaceReimburseView extends React.Component { label={this.props.translate('workspace.reimburse.trackDistanceRate')} placeholder={this.state.outputCurrency} onChangeText={value => this.setRate(value)} - value={this.state.rateValue} + value={this.state.unitRateValue} autoCompleteType="off" autoCorrect={false} keyboardType={CONST.KEYBOARD_TYPE.DECIMAL_PAD} From c55d97b27817d5a0859847064a984e7a52891ef8 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 5 Sep 2022 10:42:23 +0100 Subject: [PATCH 088/126] fix stuff messed up in merge --- src/components/DotIndicatorMessage.js | 4 ++++ src/components/OfflineWithFeedback.js | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 2b073627ef51..53a2ec337809 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -45,6 +45,10 @@ const DotIndicatorMessage = (props) => { .keys() .sortBy() .map(key => props.messages[key]) + + // Using uniq here since some fields are wrapped by the same OfflineWithFeedback component (e.g. WorkspaceReimburseView) + // and can potentially pass the same error. + .uniq() .value(); return ( diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index 754161ce71c4..54d6bc0ab9be 100644 --- a/src/components/OfflineWithFeedback.js +++ b/src/components/OfflineWithFeedback.js @@ -81,15 +81,6 @@ const OfflineWithFeedback = (props) => { const needsStrikeThrough = props.network.isOffline && props.pendingAction === 'delete'; const hideChildren = !props.network.isOffline && props.pendingAction === 'delete' && !hasErrors; let children = props.children; - const sortedErrors = _.chain(props.errors) - .keys() - .sortBy() - .map(key => props.errors[key]) - - // Using uniq here since some fields are wrapped by the same OfflineWithFeedback component (e.g. WorkspaceReimburseView) - // and can potentially pass the same error. - .uniq() - .value(); // Apply strikethrough to children if needed, but skip it if we are not going to render them if (needsStrikeThrough && !hideChildren) { From 555a48978f9e3bf5bb2b34507589a9496981651f Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 5 Sep 2022 11:30:07 +0100 Subject: [PATCH 089/126] rename variables --- src/libs/actions/Policy.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 85c72767f1b4..d921fd41fae3 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -610,17 +610,17 @@ function hideWorkspaceAlertMessage(policyID) { /** * @param {String} policyID * @param {Object} currentCustomUnit - * @param {Object} values The new custom unit values + * @param {Object} newCustomUnit */ -function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { +function updateWorkspaceCustomUnit(policyID, currentCustomUnit, newCustomUnit) { const optimisticData = [ { onyxMethod: 'merge', key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - [values.customUnitID]: { - ...values, + [newCustomUnit.customUnitID]: { + ...newCustomUnit, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, @@ -634,7 +634,7 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { customUnits: { - [values.customUnitID]: { + [newCustomUnit.customUnitID]: { pendingAction: null, errors: null, }, @@ -664,7 +664,7 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { API.write('UpdateWorkspaceCustomUnit', { policyID, - customUnit: JSON.stringify(values), + customUnit: JSON.stringify(newCustomUnit), }, {optimisticData, successData, failureData}); } @@ -672,9 +672,9 @@ function updateWorkspaceCustomUnit(policyID, currentCustomUnit, values) { * @param {String} policyID * @param {Object} currentCustomUnitRate * @param {String} customUnitID - * @param {Object} values + * @param {Object} newCustomUnitRate */ -function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, values) { +function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, newCustomUnitRate) { const optimisticData = [ { onyxMethod: 'merge', @@ -683,8 +683,8 @@ function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, val customUnits: { [customUnitID]: { onyxRates: { - [values.customUnitRateID]: { - ...values, + [newCustomUnitRate.customUnitRateID]: { + ...newCustomUnitRate, errors: null, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, @@ -703,7 +703,7 @@ function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, val customUnits: { [customUnitID]: { onyxRates: { - [values.customUnitRateID]: { + [newCustomUnitRate.customUnitRateID]: { pendingAction: null, }, }, @@ -737,7 +737,7 @@ function updateCustomUnitRate(policyID, currentCustomUnitRate, customUnitID, val API.write('UpdateWorkspaceCustomUnitRate', { policyID, customUnitID, - customUnitRate: JSON.stringify(values), + customUnitRate: JSON.stringify(newCustomUnitRate), }, {optimisticData, successData, failureData}); } From c446f9d0ee396132041eef2b703fde73f70aa1fe Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Mon, 5 Sep 2022 16:19:14 +0530 Subject: [PATCH 090/126] fix: update threedots menu popover visibility logic --- src/components/ThreeDotsMenu/index.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/components/ThreeDotsMenu/index.js b/src/components/ThreeDotsMenu/index.js index 294d15fef3ac..a6e9f9f123cc 100644 --- a/src/components/ThreeDotsMenu/index.js +++ b/src/components/ThreeDotsMenu/index.js @@ -54,19 +54,20 @@ class ThreeDotsMenu extends Component { constructor(props) { super(props); - this.togglePopupMenu = this.togglePopupMenu.bind(this); + this.hidePopoverMenu = this.hidePopoverMenu.bind(this); + this.showPopoverMenu = this.showPopoverMenu.bind(this); this.state = { isPopupMenuVisible: false, }; + this.button = null; } - /** - * Toggles the popup menu visibility - */ - togglePopupMenu() { - this.setState(prevState => ({ - isPopupMenuVisible: !prevState.isPopupMenuVisible, - })); + showPopoverMenu() { + this.setState({isPopupMenuVisible: true}); + } + + hidePopoverMenu() { + this.setState({isPopupMenuVisible: false}); } render() { @@ -76,11 +77,12 @@ class ThreeDotsMenu extends Component { { - this.togglePopupMenu(); + this.showPopoverMenu(); if (this.props.onIconPress) { this.props.onIconPress(); } }} + ref={el => this.button = el} style={[styles.touchableButtonImage, ...this.props.iconStyles]} > this.togglePopupMenu()} + onItemSelected={this.hidePopoverMenu} menuItems={this.props.menuItems} /> From 5d8a5d40bec0d13e5f115b2c7a718788cb2d3d54 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 5 Sep 2022 17:03:28 +0530 Subject: [PATCH 091/126] upgrade eslint-config-expensify to 2.0.30 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a2d2c0e6b82..5c98b0ae224e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -130,7 +130,7 @@ "electron-notarize": "^1.2.1", "electron-reloader": "^1.2.1", "eslint": "^7.6.0", - "eslint-config-expensify": "2.0.29", + "eslint-config-expensify": "2.0.30", "eslint-loader": "^4.0.2", "eslint-plugin-jest": "^24.1.0", "eslint-plugin-jsx-a11y": "^6.6.1", @@ -20246,9 +20246,9 @@ } }, "node_modules/eslint-config-expensify": { - "version": "2.0.29", - "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.29.tgz", - "integrity": "sha512-oUIWZFF+lilWFgPrdAs4V5PjOnQrCAG3rg9t5KrusR8jvYRx6xo/8jn2bXrJp7FMdnx+4gpNAhKNtsuZTsCjag==", + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.30.tgz", + "integrity": "sha512-SmZTvgUXTRmE4PRlSVDP1LgSZzrxZCgRaKJYiGso+oWl7GcB0HADmrS4nARQswfd4SWqRDy8zsY+j7+GuG8f1A==", "dev": true, "dependencies": { "@lwc/eslint-plugin-lwc": "^0.11.0", @@ -57196,9 +57196,9 @@ } }, "eslint-config-expensify": { - "version": "2.0.29", - "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.29.tgz", - "integrity": "sha512-oUIWZFF+lilWFgPrdAs4V5PjOnQrCAG3rg9t5KrusR8jvYRx6xo/8jn2bXrJp7FMdnx+4gpNAhKNtsuZTsCjag==", + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.30.tgz", + "integrity": "sha512-SmZTvgUXTRmE4PRlSVDP1LgSZzrxZCgRaKJYiGso+oWl7GcB0HADmrS4nARQswfd4SWqRDy8zsY+j7+GuG8f1A==", "dev": true, "requires": { "@lwc/eslint-plugin-lwc": "^0.11.0", diff --git a/package.json b/package.json index 32a8e7f4a8e7..6abaa5fc6ba4 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "electron-notarize": "^1.2.1", "electron-reloader": "^1.2.1", "eslint": "^7.6.0", - "eslint-config-expensify": "2.0.29", + "eslint-config-expensify": "2.0.30", "eslint-loader": "^4.0.2", "eslint-plugin-jest": "^24.1.0", "eslint-plugin-jsx-a11y": "^6.6.1", From 5e297476d5ac1ed10f4151b3bbce0adb5f944d4c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 5 Sep 2022 17:17:03 +0530 Subject: [PATCH 092/126] fix display name lint error --- src/components/AddPaymentMethodMenu.js | 1 + src/components/AddressSearch.js | 1 + src/components/CheckboxWithLabel.js | 1 - src/components/DotIndicatorMessage.js | 1 + .../HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js | 1 - src/components/HeaderWithCloseButton.js | 1 - src/components/MultipleAvatars.js | 2 ++ src/components/PDFView/index.js | 1 - src/components/PlaidLink/index.native.js | 2 ++ src/components/SafeArea/index.ios.js | 1 + src/components/ScreenWrapper/index.android.js | 1 + src/components/ScreenWrapper/index.js | 1 + src/components/TestToolMenu.js | 2 ++ src/components/TestToolRow.js | 2 ++ src/components/ThreeDotsMenu/index.js | 2 +- src/components/WalletStatementModal/index.js | 2 +- src/components/WalletStatementModal/index.native.js | 2 +- src/pages/AddPersonalBankAccountPage.js | 1 - src/pages/EnablePayments/ActivateStep.js | 2 +- src/pages/ReportSettingsPage.js | 1 - src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js | 1 - src/pages/settings/InitialSettingsPage.js | 1 - src/pages/settings/Payments/AddPayPalMePage.js | 1 - src/pages/settings/Profile/ProfilePage.js | 1 - src/pages/settings/Security/CloseAccountPage.js | 1 - src/pages/signin/ResendValidationForm.js | 1 + src/pages/wallet/WalletStatementPage.js | 2 +- src/pages/workspace/WorkspaceInitialPage.js | 1 - src/pages/workspace/reimburse/WorkspaceReimburseView.js | 1 - 29 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/components/AddPaymentMethodMenu.js b/src/components/AddPaymentMethodMenu.js index 1727cc719a19..c450642df1c8 100644 --- a/src/components/AddPaymentMethodMenu.js +++ b/src/components/AddPaymentMethodMenu.js @@ -67,6 +67,7 @@ const AddPaymentMethodMenu = props => ( AddPaymentMethodMenu.propTypes = propTypes; AddPaymentMethodMenu.defaultProps = defaultProps; +AddPaymentMethodMenu.displayName = 'AddPaymentMethodMenu'; export default compose( withWindowDimensions, diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js index 6e0ebb9718ee..1b749cc72be4 100644 --- a/src/components/AddressSearch.js +++ b/src/components/AddressSearch.js @@ -237,6 +237,7 @@ const AddressSearch = (props) => { AddressSearch.propTypes = propTypes; AddressSearch.defaultProps = defaultProps; +AddressSearch.displayName = 'AddressSearch'; export default withLocalize(React.forwardRef((props, ref) => ( // eslint-disable-next-line react/jsx-props-no-spreading diff --git a/src/components/CheckboxWithLabel.js b/src/components/CheckboxWithLabel.js index 38074a39342b..6ac3180e174c 100644 --- a/src/components/CheckboxWithLabel.js +++ b/src/components/CheckboxWithLabel.js @@ -127,7 +127,6 @@ class CheckboxWithLabel extends React.Component { CheckboxWithLabel.propTypes = propTypes; CheckboxWithLabel.defaultProps = defaultProps; -CheckboxWithLabel.displayName = 'CheckboxWithLabel'; export default React.forwardRef((props, ref) => ( // eslint-disable-next-line react/jsx-props-no-spreading diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 2b073627ef51..be4c8bbed682 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -63,6 +63,7 @@ const DotIndicatorMessage = (props) => { DotIndicatorMessage.propTypes = propTypes; DotIndicatorMessage.defaultProps = defaultProps; +DotIndicatorMessage.displayName = 'DotIndicatorMessage'; export default DotIndicatorMessage; diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index 6b911a720aff..4e8013c7ccc9 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -52,6 +52,5 @@ class PreRenderer extends React.Component { } PreRenderer.propTypes = htmlRendererPropTypes; -PreRenderer.displayName = 'PreRenderer'; export default withLocalize(PreRenderer); diff --git a/src/components/HeaderWithCloseButton.js b/src/components/HeaderWithCloseButton.js index 8b83e61ac279..27ab5dbbe890 100755 --- a/src/components/HeaderWithCloseButton.js +++ b/src/components/HeaderWithCloseButton.js @@ -220,7 +220,6 @@ class HeaderWithCloseButton extends Component { HeaderWithCloseButton.propTypes = propTypes; HeaderWithCloseButton.defaultProps = defaultProps; -HeaderWithCloseButton.displayName = 'HeaderWithCloseButton'; export default compose( withLocalize, diff --git a/src/components/MultipleAvatars.js b/src/components/MultipleAvatars.js index 0bd2bb5da688..f29abef842e1 100644 --- a/src/components/MultipleAvatars.js +++ b/src/components/MultipleAvatars.js @@ -101,4 +101,6 @@ const MultipleAvatars = (props) => { MultipleAvatars.defaultProps = defaultProps; MultipleAvatars.propTypes = propTypes; +MultipleAvatars.displayName = 'MultipleAvatars'; + export default memo(MultipleAvatars); diff --git a/src/components/PDFView/index.js b/src/components/PDFView/index.js index 74b2ec33747d..2341ef137a58 100644 --- a/src/components/PDFView/index.js +++ b/src/components/PDFView/index.js @@ -85,6 +85,5 @@ class PDFView extends PureComponent { PDFView.propTypes = propTypes; PDFView.defaultProps = defaultProps; -PDFView.displayName = 'PDFView'; export default withWindowDimensions(PDFView); diff --git a/src/components/PlaidLink/index.native.js b/src/components/PlaidLink/index.native.js index e30e9072a6f6..2fa8f6260779 100644 --- a/src/components/PlaidLink/index.native.js +++ b/src/components/PlaidLink/index.native.js @@ -32,4 +32,6 @@ const PlaidLink = (props) => { PlaidLink.propTypes = plaidLinkPropTypes; PlaidLink.defaultProps = plaidLinkDefaultProps; +PlaidLink.displayName = 'PlaidLink'; + export default PlaidLink; diff --git a/src/components/SafeArea/index.ios.js b/src/components/SafeArea/index.ios.js index ead107f90a22..3d84c4620677 100644 --- a/src/components/SafeArea/index.ios.js +++ b/src/components/SafeArea/index.ios.js @@ -13,5 +13,6 @@ SafeArea.propTypes = { /** App content */ children: PropTypes.node.isRequired, }; +SafeArea.displayName = 'SafeArea'; export default SafeArea; diff --git a/src/components/ScreenWrapper/index.android.js b/src/components/ScreenWrapper/index.android.js index aee674422f6b..e4b64a51bb40 100644 --- a/src/components/ScreenWrapper/index.android.js +++ b/src/components/ScreenWrapper/index.android.js @@ -15,5 +15,6 @@ defaultProps.keyboardAvoidingViewBehavior = 'height'; ScreenWrapper.propTypes = propTypes; ScreenWrapper.defaultProps = defaultProps; +ScreenWrapper.displayName = 'ScreenWrapper'; export default ScreenWrapper; diff --git a/src/components/ScreenWrapper/index.js b/src/components/ScreenWrapper/index.js index 29c537442985..187e75159561 100644 --- a/src/components/ScreenWrapper/index.js +++ b/src/components/ScreenWrapper/index.js @@ -12,5 +12,6 @@ const ScreenWrapper = props => ( ); ScreenWrapper.propTypes = propTypes; ScreenWrapper.defaultProps = defaultProps; +ScreenWrapper.displayName = 'ScreenWrapper'; export default ScreenWrapper; diff --git a/src/components/TestToolMenu.js b/src/components/TestToolMenu.js index f04ae6a26b92..1654854799d2 100644 --- a/src/components/TestToolMenu.js +++ b/src/components/TestToolMenu.js @@ -76,6 +76,8 @@ const TestToolMenu = props => ( TestToolMenu.propTypes = propTypes; TestToolMenu.defaultProps = defaultProps; +TestToolMenu.displayName = 'TestToolMenu'; + export default compose( withNetwork(), withOnyx({ diff --git a/src/components/TestToolRow.js b/src/components/TestToolRow.js index 80405a898bb0..505dfefa2172 100644 --- a/src/components/TestToolRow.js +++ b/src/components/TestToolRow.js @@ -26,4 +26,6 @@ const TestToolRow = props => ( ); TestToolRow.propTypes = propTypes; +TestToolRow.displayName = 'TestToolRow'; + export default TestToolRow; diff --git a/src/components/ThreeDotsMenu/index.js b/src/components/ThreeDotsMenu/index.js index 294d15fef3ac..168425d3d792 100644 --- a/src/components/ThreeDotsMenu/index.js +++ b/src/components/ThreeDotsMenu/index.js @@ -104,7 +104,7 @@ class ThreeDotsMenu extends Component { ThreeDotsMenu.propTypes = propTypes; ThreeDotsMenu.defaultProps = defaultProps; -ThreeDotsMenu.displayName = 'ThreeDotsMenu'; + export default withLocalize(ThreeDotsMenu); export {ThreeDotsMenuItemPropTypes}; diff --git a/src/components/WalletStatementModal/index.js b/src/components/WalletStatementModal/index.js index 60d57fc5c14b..762bed5b6296 100644 --- a/src/components/WalletStatementModal/index.js +++ b/src/components/WalletStatementModal/index.js @@ -66,7 +66,7 @@ class WalletStatementModal extends React.Component { WalletStatementModal.propTypes = walletStatementPropTypes; WalletStatementModal.defaultProps = walletStatementDefaultProps; -WalletStatementModal.displayName = 'WalletStatementModal'; + export default compose( withLocalize, withOnyx({ diff --git a/src/components/WalletStatementModal/index.native.js b/src/components/WalletStatementModal/index.native.js index 01feae5fa021..9c525a12420c 100644 --- a/src/components/WalletStatementModal/index.native.js +++ b/src/components/WalletStatementModal/index.native.js @@ -59,7 +59,7 @@ class WalletStatementModal extends React.Component { WalletStatementModal.propTypes = walletStatementPropTypes; WalletStatementModal.defaultProps = walletStatementDefaultProps; -WalletStatementModal.displayName = 'WalletStatementModal'; + export default compose( withLocalize, withOnyx({ diff --git a/src/pages/AddPersonalBankAccountPage.js b/src/pages/AddPersonalBankAccountPage.js index dc5245702c88..525b20760d75 100644 --- a/src/pages/AddPersonalBankAccountPage.js +++ b/src/pages/AddPersonalBankAccountPage.js @@ -209,7 +209,6 @@ class AddPersonalBankAccountPage extends React.Component { AddPersonalBankAccountPage.propTypes = propTypes; AddPersonalBankAccountPage.defaultProps = defaultProps; -AddPersonalBankAccountPage.displayName = 'AddPersonalBankAccountPage'; export default compose( withLocalize, diff --git a/src/pages/EnablePayments/ActivateStep.js b/src/pages/EnablePayments/ActivateStep.js index c02d6451a659..94454e8ce78a 100644 --- a/src/pages/EnablePayments/ActivateStep.js +++ b/src/pages/EnablePayments/ActivateStep.js @@ -88,5 +88,5 @@ class ActivateStep extends React.Component { ActivateStep.propTypes = propTypes; ActivateStep.defaultProps = defaultProps; -ActivateStep.displayName = 'ActivateStep'; + export default withLocalize(ActivateStep); diff --git a/src/pages/ReportSettingsPage.js b/src/pages/ReportSettingsPage.js index cc041cbe13e7..9efc59dc940e 100644 --- a/src/pages/ReportSettingsPage.js +++ b/src/pages/ReportSettingsPage.js @@ -288,7 +288,6 @@ class ReportSettingsPage extends Component { ReportSettingsPage.propTypes = propTypes; ReportSettingsPage.defaultProps = defaultProps; -ReportSettingsPage.displayName = 'ReportSettingsPage'; export default compose( withLocalize, diff --git a/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js b/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js index 273061aa4e3c..9d0571ab16df 100755 --- a/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js +++ b/src/pages/iou/steps/IOUParticipantsPage/IOUParticipantsSplit.js @@ -236,7 +236,6 @@ class IOUParticipantsSplit extends Component { } } -IOUParticipantsSplit.displayName = 'IOUParticipantsSplit'; IOUParticipantsSplit.propTypes = propTypes; IOUParticipantsSplit.defaultProps = defaultProps; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index df2fbd8afe0b..5e1357bbdcf5 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -279,7 +279,6 @@ class InitialSettingsPage extends React.Component { InitialSettingsPage.propTypes = propTypes; InitialSettingsPage.defaultProps = defaultProps; -InitialSettingsPage.displayName = 'InitialSettingsPage'; export default compose( withLocalize, diff --git a/src/pages/settings/Payments/AddPayPalMePage.js b/src/pages/settings/Payments/AddPayPalMePage.js index 2e8bdff1d8e7..8fd4d262a487 100644 --- a/src/pages/settings/Payments/AddPayPalMePage.js +++ b/src/pages/settings/Payments/AddPayPalMePage.js @@ -103,7 +103,6 @@ class AddPayPalMePage extends React.Component { AddPayPalMePage.propTypes = propTypes; AddPayPalMePage.defaultProps = defaultProps; -AddPayPalMePage.displayName = 'AddPayPalMePage'; export default compose( withLocalize, diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js index 458a17d1713a..431d65ac9379 100755 --- a/src/pages/settings/Profile/ProfilePage.js +++ b/src/pages/settings/Profile/ProfilePage.js @@ -298,7 +298,6 @@ class ProfilePage extends Component { ProfilePage.propTypes = propTypes; ProfilePage.defaultProps = defaultProps; -ProfilePage.displayName = 'ProfilePage'; export default compose( withLocalize, diff --git a/src/pages/settings/Security/CloseAccountPage.js b/src/pages/settings/Security/CloseAccountPage.js index 96e8aa70be4a..f6e411d29135 100644 --- a/src/pages/settings/Security/CloseAccountPage.js +++ b/src/pages/settings/Security/CloseAccountPage.js @@ -143,7 +143,6 @@ class CloseAccountPage extends Component { CloseAccountPage.propTypes = propTypes; CloseAccountPage.defaultProps = defaultProps; -CloseAccountPage.displayName = 'CloseAccountPage'; export default compose( withLocalize, diff --git a/src/pages/signin/ResendValidationForm.js b/src/pages/signin/ResendValidationForm.js index 00f1c1d629a1..38f0cc781cb5 100755 --- a/src/pages/signin/ResendValidationForm.js +++ b/src/pages/signin/ResendValidationForm.js @@ -100,6 +100,7 @@ const ResendValidationForm = (props) => { ResendValidationForm.propTypes = propTypes; ResendValidationForm.defaultProps = defaultProps; +ResendValidationForm.displayName = 'ResendValidationForm'; export default compose( withLocalize, diff --git a/src/pages/wallet/WalletStatementPage.js b/src/pages/wallet/WalletStatementPage.js index d1056ec5c21a..572aa672bff4 100644 --- a/src/pages/wallet/WalletStatementPage.js +++ b/src/pages/wallet/WalletStatementPage.js @@ -120,7 +120,7 @@ class WalletStatementPage extends React.Component { WalletStatementPage.propTypes = propTypes; WalletStatementPage.defaultProps = defaultProps; -WalletStatementPage.displayName = 'WalletStatementPage'; + export default compose( withLocalize, withOnyx({ diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 08610ce151b9..1f21f9c0ac49 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -245,7 +245,6 @@ class WorkspaceInitialPage extends React.Component { WorkspaceInitialPage.propTypes = propTypes; WorkspaceInitialPage.defaultProps = defaultProps; -WorkspaceInitialPage.displayName = 'WorkspaceInitialPage'; export default compose( withLocalize, diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index e4899ce9426b..8e120246f666 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -289,7 +289,6 @@ class WorkspaceReimburseView extends React.Component { } WorkspaceReimburseView.propTypes = propTypes; -WorkspaceReimburseView.displayName = 'WorkspaceReimburseView'; export default compose( withFullPolicy, From b09b2d36b90317326be19db2eb62e2deb3bc2a8e Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 5 Sep 2022 14:02:47 +0100 Subject: [PATCH 093/126] add optimistic reportActions --- src/CONST.js | 1 + src/libs/actions/Policy.js | 37 +++++++++-- src/libs/actions/Report.js | 122 +++++++++++++++++++++++++++++++++---- 3 files changed, 144 insertions(+), 16 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 7f91e24fa7f0..412c9412b903 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -268,6 +268,7 @@ const CONST = { MESSAGE: { TYPE: { COMMENT: 'COMMENT', + TEXT: 'TEXT', }, }, TYPE: { diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index c86713161789..aef73f439376 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -742,15 +742,18 @@ function generatePolicyID() { */ function createWorkspace() { const policyID = generatePolicyID(); + const workspaceName = generateDefaultWorkspaceName(); const { announceChatReportID, announceChatData, + announceReportActionData, adminsChatReportID, - adminChatData, + adminsChatData, + adminsReportActionData, expenseChatReportID, expenseChatData, - } = Report.createOptimisticWorkspaceChats(policyID, sessionEmail); - const workspaceName = generateDefaultWorkspaceName(); + expenseReportActionData, + } = Report.createOptimisticWorkspaceChats(policyID, workspaceName); API.write('CreateWorkspace', { policyID, announceChatReportID, @@ -775,19 +778,31 @@ function createWorkspace() { { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, - value: getSimplifiedEmployeeList([{email: sessionEmail, role: CONST.POLICY.ROLE.ADMIN}]), + value: {[sessionEmail]: {}}, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: announceChatData, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, + value: announceReportActionData, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, - value: adminChatData, + value: adminsChatData, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, + value: adminsReportActionData, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: expenseChatData, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, + value: expenseReportActionData, }], successData: [{ onyxMethod: CONST.ONYX.METHOD.SET, @@ -826,14 +841,26 @@ function createWorkspace() { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: null, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, + value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: null, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, + value: null, }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: null, + }, { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, + value: null, }], }); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 38b9bddd9b84..54a9103dbe6f 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -618,10 +618,10 @@ function createOptimisticChatReport(participantList) { /** * @param {String} policyID - * @param {String} ownerEmail + * @param {String} policyName * @returns {Object} */ -function createOptimisticWorkspaceChats(policyID, ownerEmail) { +function createOptimisticWorkspaceChats(policyID, policyName) { const announceChatReportID = ReportUtils.generateReportID(); const announceChatData = { chatType: CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, @@ -631,6 +631,7 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, hasOutstandingIOU: false, isOwnPolicyExpenseChat: false, + isLoadingReportActions: false, isPinned: false, lastActorEmail: '', lastMessageHtml: '', @@ -640,16 +641,47 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { lastVisitedTimestamp: 0, maxSequenceNumber: 0, notificationPreference: '', - oldPolicyName: '', + oldPolicyName: policyName, ownerEmail: '__FAKE__', - participants: [ownerEmail], + participants: [currentUserEmail], stateNum: 0, statusNum: 0, visibility: undefined, }; + const announceReportActionData = { + 0: { + actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + message: [ + { + type: CONST.REPORT.MESSAGE.TYPE.TEXT, + style: "strong", + text: announceChatData.ownerEmail, + }, + { + type: CONST.REPORT.MESSAGE.TYPE.TEXT, + style: "normal", + text: " created this report", + }, + ], + person: [ + { + style: 'strong', + text: lodashGet(personalDetails, [currentUserEmail, 'displayName'], currentUserEmail), + type: 'TEXT', + }, + ], + automatic: false, + sequenceNumber: 0, + avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), + timestamp: moment().unix(), + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + shouldShow: true, + } + }; const adminsChatReportID = ReportUtils.generateReportID(); - const adminChatData = { + const adminsChatData = { chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, policyID, reportID: adminsChatReportID, @@ -657,6 +689,7 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, hasOutstandingIOU: false, isOwnPolicyExpenseChat: false, + isLoadingReportActions: false, isPinned: false, lastActorEmail: '', lastMessageHtml: '', @@ -666,19 +699,51 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { lastVisitedTimestamp: 0, maxSequenceNumber: 0, notificationPreference: '', - oldPolicyName: '', + oldPolicyName: policyName, ownerEmail: '__FAKE__', - participants: [ownerEmail], + participants: [currentUserEmail], stateNum: 0, statusNum: 0, visibility: undefined, }; + const adminsReportActionData = { + 0: { + actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + message: [ + { + type: CONST.REPORT.MESSAGE.TYPE.TEXT, + style: "strong", + text: adminsChatData.ownerEmail, + }, + { + type: CONST.REPORT.MESSAGE.TYPE.TEXT, + style: "normal", + text: " created this report", + }, + ], + person: [ + { + style: 'strong', + text: lodashGet(personalDetails, [currentUserEmail, 'displayName'], currentUserEmail), + type: 'TEXT', + }, + ], + automatic: false, + sequenceNumber: 0, + avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), + timestamp: moment().unix(), + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + shouldShow: true, + } + }; + const expenseChatReportID = ReportUtils.generateReportID(); const expenseChatData = { chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, isOwnPolicyExpenseChat: true, - ownerEmail, + ownerEmail: currentUserEmail, policyID, reportID: expenseChatReportID, reportName: '', @@ -693,20 +758,55 @@ function createOptimisticWorkspaceChats(policyID, ownerEmail) { lastVisitedTimestamp: 0, maxSequenceNumber: 0, notificationPreference: '', - oldPolicyName: '', - participants: [ownerEmail], + oldPolicyName: policyName, + participants: [currentUserEmail], stateNum: 0, statusNum: 0, visibility: undefined, }; + const expenseReportActionData = { + 0: { + actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + message: [ + { + type: CONST.REPORT.MESSAGE.TYPE.TEXT, + style: "strong", + text: "You", + }, + { + type: CONST.REPORT.MESSAGE.TYPE.TEXT, + style: "normal", + text: " created this report", + }, + ], + person: [ + { + style: 'strong', + text: lodashGet(personalDetails, [currentUserEmail, 'displayName'], currentUserEmail), + type: 'TEXT', + }, + ], + automatic: false, + sequenceNumber: 0, + avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), + timestamp: moment().unix(), + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + shouldShow: true, + } + }; + return { announceChatReportID, announceChatData, + announceReportActionData, adminsChatReportID, - adminChatData, + adminsChatData, + adminsReportActionData, expenseChatReportID, expenseChatData, + expenseReportActionData, }; } From 8fbb052c1ef5d9a25f6505b144f1e39f9845bb10 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 5 Sep 2022 15:28:41 +0100 Subject: [PATCH 094/126] fix lint --- src/libs/actions/Report.js | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 54a9103dbe6f..657ec0d4de4a 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -655,13 +655,13 @@ function createOptimisticWorkspaceChats(policyID, policyName) { message: [ { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: "strong", + style: 'strong', text: announceChatData.ownerEmail, }, { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: "normal", - text: " created this report", + style: 'normal', + text: ' created this report', }, ], person: [ @@ -675,9 +675,8 @@ function createOptimisticWorkspaceChats(policyID, policyName) { sequenceNumber: 0, avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), timestamp: moment().unix(), - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, shouldShow: true, - } + }, }; const adminsChatReportID = ReportUtils.generateReportID(); @@ -714,13 +713,13 @@ function createOptimisticWorkspaceChats(policyID, policyName) { message: [ { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: "strong", + style: 'strong', text: adminsChatData.ownerEmail, }, { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: "normal", - text: " created this report", + style: 'normal', + text: ' created this report', }, ], person: [ @@ -734,9 +733,8 @@ function createOptimisticWorkspaceChats(policyID, policyName) { sequenceNumber: 0, avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), timestamp: moment().unix(), - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, shouldShow: true, - } + }, }; const expenseChatReportID = ReportUtils.generateReportID(); @@ -772,13 +770,13 @@ function createOptimisticWorkspaceChats(policyID, policyName) { message: [ { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: "strong", - text: "You", + style: 'strong', + text: 'You', }, { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: "normal", - text: " created this report", + style: 'normal', + text: ' created this report', }, ], person: [ @@ -792,9 +790,8 @@ function createOptimisticWorkspaceChats(policyID, policyName) { sequenceNumber: 0, avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), timestamp: moment().unix(), - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, shouldShow: true, - } + }, }; return { From 7da11ba4ee5f30a2f9e242570f925416685d0886 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 08:04:14 +0100 Subject: [PATCH 095/126] add methods for reportActions and workspace chats --- src/libs/actions/Report.js | 69 +++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 657ec0d4de4a..168f89a8a0bd 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -588,13 +588,19 @@ function fetchAllReports( * Creates an optimistic chat report with a randomly generated reportID and as much information as we currently have * * @param {Array} participantList + * @param {String} reportName + * @param {String} chatType + * @param {String} policyID + * @param {String} ownerEmail + * @param {Boolean} isOwnPolicyExpenseChat + * @param {String} oldPolicyName * @returns {Object} */ -function createOptimisticChatReport(participantList) { +function createOptimisticChatReport(participantList, reportName = 'Chat Report', chatType = '', policyID = '_FAKE_', ownerEmail = '__FAKE__', isOwnPolicyExpenseChat = false, oldPolicyName = '') { return { - chatType: '', + chatType, hasOutstandingIOU: false, - isOwnPolicyExpenseChat: false, + isOwnPolicyExpenseChat, isPinned: false, lastActorEmail: '', lastMessageHtml: '', @@ -604,12 +610,12 @@ function createOptimisticChatReport(participantList) { lastVisitedTimestamp: 0, maxSequenceNumber: 0, notificationPreference: '', - oldPolicyName: '', - ownerEmail: '__FAKE__', + oldPolicyName, + ownerEmail, participants: participantList, - policyID: '_FAKE_', + policyID, reportID: ReportUtils.generateReportID(), - reportName: 'Chat Report', + reportName, stateNum: 0, statusNum: 0, visibility: undefined, @@ -617,38 +623,11 @@ function createOptimisticChatReport(participantList) { } /** - * @param {String} policyID - * @param {String} policyName - * @returns {Object} + * Returns the necessary reportAction onyx data to indicate that the chat has been created optimistically + * @param {String} ownerEmail */ -function createOptimisticWorkspaceChats(policyID, policyName) { - const announceChatReportID = ReportUtils.generateReportID(); - const announceChatData = { - chatType: CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, - policyID, - reportID: announceChatReportID, - reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - hasOutstandingIOU: false, - isOwnPolicyExpenseChat: false, - isLoadingReportActions: false, - isPinned: false, - lastActorEmail: '', - lastMessageHtml: '', - lastMessageText: null, - lastReadSequenceNumber: 0, - lastMessageTimestamp: 0, - lastVisitedTimestamp: 0, - maxSequenceNumber: 0, - notificationPreference: '', - oldPolicyName: policyName, - ownerEmail: '__FAKE__', - participants: [currentUserEmail], - stateNum: 0, - statusNum: 0, - visibility: undefined, - }; - const announceReportActionData = { + function createOptimisticCreatedReportAction(ownerEmail) { + return { 0: { actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, @@ -656,7 +635,7 @@ function createOptimisticWorkspaceChats(policyID, policyName) { { type: CONST.REPORT.MESSAGE.TYPE.TEXT, style: 'strong', - text: announceChatData.ownerEmail, + text: ownerEmail === currentUserEmail ? 'You' : ownerEmail, }, { type: CONST.REPORT.MESSAGE.TYPE.TEXT, @@ -678,6 +657,17 @@ function createOptimisticWorkspaceChats(policyID, policyName) { shouldShow: true, }, }; +} + +/** + * @param {String} policyID + * @param {String} policyName + * @returns {Object} + */ +function createOptimisticWorkspaceChats(policyID, policyName) { + const announceChatData = createOptimisticChatReport([currentUserEmail], CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID, '', false, policyName); + const announceChatReportID = announceChatData.reportID; + const announceReportActionData = createOptimisticCreatedReportAction(announceChatData.ownerEmail); const adminsChatReportID = ReportUtils.generateReportID(); const adminsChatData = { @@ -1732,6 +1722,7 @@ export { openPaymentDetailsPage, createOptimisticWorkspaceChats, createOptimisticChatReport, + createOptimisticCreatedReportAction, updatePolicyRoomName, clearPolicyRoomNameErrors, }; From 9cc127e779726e824ea0b9494c185d79a069d3ab Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 08:24:28 +0100 Subject: [PATCH 096/126] clean up method regarding optimistic generation --- src/libs/actions/Policy.js | 5 +- src/libs/actions/Report.js | 123 +++---------------------------------- 2 files changed, 12 insertions(+), 116 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index aef73f439376..6e5a4cb83c1d 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -743,6 +743,7 @@ function generatePolicyID() { function createWorkspace() { const policyID = generatePolicyID(); const workspaceName = generateDefaultWorkspaceName(); + const { announceChatReportID, announceChatData, @@ -778,7 +779,9 @@ function createWorkspace() { { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, - value: {[sessionEmail]: {}}, + value: { + [sessionEmail]: {role: CONST.POLICY.ROLE.ADMIN} + }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 168f89a8a0bd..d8ba1fc0ded5 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -645,9 +645,9 @@ function createOptimisticChatReport(participantList, reportName = 'Chat Report', ], person: [ { + type: CONST.REPORT.MESSAGE.TYPE.TEXT, style: 'strong', text: lodashGet(personalDetails, [currentUserEmail, 'displayName'], currentUserEmail), - type: 'TEXT', }, ], automatic: false, @@ -665,124 +665,17 @@ function createOptimisticChatReport(participantList, reportName = 'Chat Report', * @returns {Object} */ function createOptimisticWorkspaceChats(policyID, policyName) { - const announceChatData = createOptimisticChatReport([currentUserEmail], CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID, '', false, policyName); + const announceChatData = createOptimisticChatReport([currentUserEmail], CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID, null, false, policyName); const announceChatReportID = announceChatData.reportID; const announceReportActionData = createOptimisticCreatedReportAction(announceChatData.ownerEmail); - const adminsChatReportID = ReportUtils.generateReportID(); - const adminsChatData = { - chatType: CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, - policyID, - reportID: adminsChatReportID, - reportName: CONST.REPORT.WORKSPACE_CHAT_ROOMS.ADMINS, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - hasOutstandingIOU: false, - isOwnPolicyExpenseChat: false, - isLoadingReportActions: false, - isPinned: false, - lastActorEmail: '', - lastMessageHtml: '', - lastMessageText: null, - lastReadSequenceNumber: 0, - lastMessageTimestamp: 0, - lastVisitedTimestamp: 0, - maxSequenceNumber: 0, - notificationPreference: '', - oldPolicyName: policyName, - ownerEmail: '__FAKE__', - participants: [currentUserEmail], - stateNum: 0, - statusNum: 0, - visibility: undefined, - }; - - const adminsReportActionData = { - 0: { - actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - message: [ - { - type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: 'strong', - text: adminsChatData.ownerEmail, - }, - { - type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: 'normal', - text: ' created this report', - }, - ], - person: [ - { - style: 'strong', - text: lodashGet(personalDetails, [currentUserEmail, 'displayName'], currentUserEmail), - type: 'TEXT', - }, - ], - automatic: false, - sequenceNumber: 0, - avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), - timestamp: moment().unix(), - shouldShow: true, - }, - }; - - const expenseChatReportID = ReportUtils.generateReportID(); - const expenseChatData = { - chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, - isOwnPolicyExpenseChat: true, - ownerEmail: currentUserEmail, - policyID, - reportID: expenseChatReportID, - reportName: '', - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - hasOutstandingIOU: false, - isPinned: false, - lastActorEmail: '', - lastMessageHtml: '', - lastMessageText: null, - lastReadSequenceNumber: 0, - lastMessageTimestamp: 0, - lastVisitedTimestamp: 0, - maxSequenceNumber: 0, - notificationPreference: '', - oldPolicyName: policyName, - participants: [currentUserEmail], - stateNum: 0, - statusNum: 0, - visibility: undefined, - }; + const adminsChatData = createOptimisticChatReport([currentUserEmail], CONST.REPORT.WORKSPACE_CHAT_ROOMS.ADMINS, CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, policyID, null, false, policyName); + const adminsChatReportID = adminsChatData.reportID; + const adminsReportActionData = createOptimisticCreatedReportAction(adminsChatData.ownerEmail); - const expenseReportActionData = { - 0: { - actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - message: [ - { - type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: 'strong', - text: 'You', - }, - { - type: CONST.REPORT.MESSAGE.TYPE.TEXT, - style: 'normal', - text: ' created this report', - }, - ], - person: [ - { - style: 'strong', - text: lodashGet(personalDetails, [currentUserEmail, 'displayName'], currentUserEmail), - type: 'TEXT', - }, - ], - automatic: false, - sequenceNumber: 0, - avatar: lodashGet(personalDetails, [currentUserEmail, 'avatar'], ReportUtils.getDefaultAvatar(currentUserEmail)), - timestamp: moment().unix(), - shouldShow: true, - }, - }; + const expenseChatData = createOptimisticChatReport([currentUserEmail], '', CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, policyID, currentUserEmail, true, policyName); + const expenseChatReportID = expenseChatData.reportID; + const expenseReportActionData = createOptimisticCreatedReportAction(expenseChatData.ownerEmail); return { announceChatReportID, From d8192d065e9654ffc9e1432cd2f0f13184504961 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 08:44:52 +0100 Subject: [PATCH 097/126] indenting / fix bug with notifications --- src/libs/actions/Policy.js | 71 ++++++++++++++++++++++---------------- src/libs/actions/Report.js | 2 ++ 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 6e5a4cb83c1d..98e08331ef6f 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -762,7 +762,8 @@ function createWorkspace() { expenseChatReportID, policyName: workspaceName, type: CONST.POLICY.TYPE.FREE, - }, { + }, + { optimisticData: [{ onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, @@ -780,29 +781,37 @@ function createWorkspace() { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, value: { - [sessionEmail]: {role: CONST.POLICY.ROLE.ADMIN} + [sessionEmail]: { + role: CONST.POLICY.ROLE.ADMIN, + } }, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: announceChatData, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, value: announceReportActionData, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: adminsChatData, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, value: adminsReportActionData, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: expenseChatData, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, value: expenseReportActionData, @@ -810,57 +819,59 @@ function createWorkspace() { successData: [{ onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - pendingAction: null, - }, - }, { + value: {pendingAction: null}, + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, - value: { - pendingAction: null, - }, - }, { + value: {pendingAction: null}, + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, - value: { - pendingAction: null, - }, - }, { + value: {pendingAction: null}, + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, - value: { - pendingAction: null, - }, + value: {pendingAction: null}, }], failureData: [{ onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: null, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, value: null, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: null, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, value: null, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: null, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, value: null, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: null, - }, { + }, + { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, value: null, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index d8ba1fc0ded5..55d9c8916dee 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -631,6 +631,8 @@ function createOptimisticChatReport(participantList, reportName = 'Chat Report', 0: { actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + actorEmail: currentUserEmail, + actorAccountID: currentUserAccountID, message: [ { type: CONST.REPORT.MESSAGE.TYPE.TEXT, From f9d2feb4131bc1eabdb266700fec0a98ef58507e Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 08:50:05 +0100 Subject: [PATCH 098/126] Update Policy.js --- src/libs/actions/Policy.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 98e08331ef6f..3fe2983116e4 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -783,6 +783,7 @@ function createWorkspace() { value: { [sessionEmail]: { role: CONST.POLICY.ROLE.ADMIN, + errors: [], } }, }, From bf881d72ff845be5db6fefe78c8ff85d6a632766 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 08:52:33 +0100 Subject: [PATCH 099/126] style fixes --- src/libs/actions/Policy.js | 36 ++++++++++++++++++------------------ src/libs/actions/Report.js | 5 +++-- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 3fe2983116e4..1fe299b3c4cd 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -762,7 +762,7 @@ function createWorkspace() { expenseChatReportID, policyName: workspaceName, type: CONST.POLICY.TYPE.FREE, - }, + }, { optimisticData: [{ onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -784,34 +784,34 @@ function createWorkspace() { [sessionEmail]: { role: CONST.POLICY.ROLE.ADMIN, errors: [], - } + }, }, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: announceChatData, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, value: announceReportActionData, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: adminsChatData, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, value: adminsReportActionData, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: expenseChatData, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, @@ -821,17 +821,17 @@ function createWorkspace() { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: {pendingAction: null}, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: {pendingAction: null}, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: {pendingAction: null}, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, @@ -841,37 +841,37 @@ function createWorkspace() { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: null, - }, + }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, value: null, - }, + }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, value: null, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, value: null, - }, + }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, value: null, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, value: null, - }, + }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, value: null, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 55d9c8916dee..f7a0afcfc154 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -624,9 +624,10 @@ function createOptimisticChatReport(participantList, reportName = 'Chat Report', /** * Returns the necessary reportAction onyx data to indicate that the chat has been created optimistically - * @param {String} ownerEmail + * @param {String} ownerEmail + * @returns {Object} */ - function createOptimisticCreatedReportAction(ownerEmail) { +function createOptimisticCreatedReportAction(ownerEmail) { return { 0: { actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, From 6e199911b80868e665ed5a9a1a8b590da04cfc41 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 09:02:45 +0100 Subject: [PATCH 100/126] Update Policy.js --- src/libs/actions/Policy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 1fe299b3c4cd..fe9f0eb45cef 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -783,7 +783,7 @@ function createWorkspace() { value: { [sessionEmail]: { role: CONST.POLICY.ROLE.ADMIN, - errors: [], + errors: {}, }, }, }, From ef6ba9a41ad50a05e2d4669985de097407d6e033 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 09:52:32 +0100 Subject: [PATCH 101/126] fix bug with name dissapearing --- src/libs/actions/Policy.js | 2 +- src/pages/workspace/withFullPolicy.js | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index fe9f0eb45cef..dbbb99f519e1 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -818,7 +818,7 @@ function createWorkspace() { value: expenseReportActionData, }], successData: [{ - onyxMethod: CONST.ONYX.METHOD.SET, + onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: {pendingAction: null}, }, diff --git a/src/pages/workspace/withFullPolicy.js b/src/pages/workspace/withFullPolicy.js index 224fdaf77364..45f608d685b2 100644 --- a/src/pages/workspace/withFullPolicy.js +++ b/src/pages/workspace/withFullPolicy.js @@ -59,9 +59,6 @@ const fullPolicyPropTypes = { /** The URL for the policy avatar */ avatar: PropTypes.string, - /** A list of emails for the employees on the policy */ - employeeList: PropTypes.arrayOf(PropTypes.string), - /** Errors on the policy keyed by microtime */ errors: PropTypes.objectOf(PropTypes.string), From d12210a20214e695cf3693c82cccd91fab86f900 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 09:54:59 +0100 Subject: [PATCH 102/126] fix long line lints --- src/libs/actions/Report.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index f7a0afcfc154..cb47177eefa4 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -596,7 +596,15 @@ function fetchAllReports( * @param {String} oldPolicyName * @returns {Object} */ -function createOptimisticChatReport(participantList, reportName = 'Chat Report', chatType = '', policyID = '_FAKE_', ownerEmail = '__FAKE__', isOwnPolicyExpenseChat = false, oldPolicyName = '') { +function createOptimisticChatReport( + participantList, + reportName = 'Chat Report', + chatType = '', + policyID = '_FAKE_', + ownerEmail = '__FAKE__', + isOwnPolicyExpenseChat = false, + oldPolicyName = '', +) { return { chatType, hasOutstandingIOU: false, @@ -668,7 +676,15 @@ function createOptimisticCreatedReportAction(ownerEmail) { * @returns {Object} */ function createOptimisticWorkspaceChats(policyID, policyName) { - const announceChatData = createOptimisticChatReport([currentUserEmail], CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, policyID, null, false, policyName); + const announceChatData = createOptimisticChatReport( + [currentUserEmail], + CONST.REPORT.WORKSPACE_CHAT_ROOMS.ANNOUNCE, + CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, + policyID, + null, + false, + policyName, + ); const announceChatReportID = announceChatData.reportID; const announceReportActionData = createOptimisticCreatedReportAction(announceChatData.ownerEmail); From fc99b6e32dd067eecb1a2951980648c3109533eb Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 10:12:04 +0100 Subject: [PATCH 103/126] fix bug with intermittent screen now showing up --- src/libs/actions/Policy.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index dbbb99f519e1..b976a97b1ddf 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -755,7 +755,11 @@ function createWorkspace() { expenseChatData, expenseReportActionData, } = Report.createOptimisticWorkspaceChats(policyID, workspaceName); - API.write('CreateWorkspace', { + + // We need to use makeRequestWithSideEffects as we try to redirect to the policy right after creation + // The policy hasn't been merged in Onyx data at this point, leading to an intermittent Not Found screen + // eslint-disable-next-line rulesdir/no-api-side-effects-method + API.makeRequestWithSideEffects('CreateWorkspace', { policyID, announceChatReportID, adminsChatReportID, @@ -877,9 +881,9 @@ function createWorkspace() { key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, value: null, }], + }).then(() => { + Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policyID)); }); - - Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policyID)); } function openWorkspaceReimburseView(policyID) { From baa523093b3cd92b1f02a0fca515faf5068d9811 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 6 Sep 2022 10:12:25 +0100 Subject: [PATCH 104/126] Update Policy.js --- src/libs/actions/Policy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index b976a97b1ddf..af7759706c71 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -757,7 +757,7 @@ function createWorkspace() { } = Report.createOptimisticWorkspaceChats(policyID, workspaceName); // We need to use makeRequestWithSideEffects as we try to redirect to the policy right after creation - // The policy hasn't been merged in Onyx data at this point, leading to an intermittent Not Found screen + // The policy hasn't been merged in Onyx data at this point, leading to an intermittent Not Found screen // eslint-disable-next-line rulesdir/no-api-side-effects-method API.makeRequestWithSideEffects('CreateWorkspace', { policyID, From 34a4d8b2f458cde1217fc97870cab0ec2bbec5d1 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Tue, 6 Sep 2022 11:14:34 +0100 Subject: [PATCH 105/126] added network prop types --- src/pages/workspace/WorkspaceInvitePage.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index cd45d7d0fb41..bedc39ad798f 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -23,6 +23,7 @@ import Text from '../../components/Text'; import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; import {withNetwork} from '../../components/OnyxProvider'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; +import networkPropTypes from '../../components/networkPropTypes'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -54,6 +55,7 @@ const propTypes = { ...fullPolicyPropTypes, ...withLocalizePropTypes, + ...networkPropTypes, }; const defaultProps = fullPolicyDefaultProps; From 4d840cc2d07580abad4258dc54317a5f8b6cb7b0 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Tue, 6 Sep 2022 11:40:58 +0100 Subject: [PATCH 106/126] use policy ID in route --- src/libs/actions/Policy.js | 4 ---- src/pages/workspace/WorkspaceInvitePage.js | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index f57f988754b8..7fb83b8d8bb6 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -822,10 +822,6 @@ function openWorkspaceMembersPage(policyID, clientMemberEmails) { } function openWorkspaceInvitePage(policyID, clientPolicyMembers) { - if (!policyID) { - return; - } - API.read('OpenWorkspaceInvitePage', {policyID, clientPolicyMembers}); } diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index bedc39ad798f..dbefba433b49 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -90,7 +90,7 @@ class WorkspaceInvitePage extends React.Component { this.clearErrors(); const clientPolicyMembers = _.keys(this.props.policyMemberList); - Policy.openWorkspaceInvitePage(this.props.policy.id, clientPolicyMembers); + Policy.openWorkspaceInvitePage(this.props.route.params.policyID, clientPolicyMembers); } componentDidUpdate(prevProps) { @@ -100,7 +100,7 @@ class WorkspaceInvitePage extends React.Component { } const clientPolicyMembers = _.keys(this.props.policyMemberList); - Policy.openWorkspaceInvitePage(this.props.policy.id, clientPolicyMembers); + Policy.openWorkspaceInvitePage(this.props.route.params.policyID, clientPolicyMembers); } getExcludedUsers() { From b3616c2b38ef22fae33c0f35b5094eef8a663a93 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Tue, 6 Sep 2022 11:52:00 +0100 Subject: [PATCH 107/126] use clientMemberEmails param and fix array parsing --- src/libs/actions/Policy.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 7fb83b8d8bb6..a2e5924fd431 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -821,8 +821,11 @@ function openWorkspaceMembersPage(policyID, clientMemberEmails) { }); } -function openWorkspaceInvitePage(policyID, clientPolicyMembers) { - API.read('OpenWorkspaceInvitePage', {policyID, clientPolicyMembers}); +function openWorkspaceInvitePage(policyID, clientMemberEmails) { + API.read('OpenWorkspaceInvitePage', { + policyID, + clientMemberEmails: JSON.stringify(clientMemberEmails), + }); } export { From 281b7bbfa8a9fba61992741f84c9e6bcb2a6d0e7 Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Tue, 6 Sep 2022 11:58:14 +0100 Subject: [PATCH 108/126] Fix two bugs found with checklists 1. Improve large PRs with over 100 comments 2. Only run on pull requests --- .../contributorChecklist.js | 60 +++++++++---------- .../javascript/contributorChecklist/index.js | 60 +++++++++---------- .github/workflows/testChecklists.yml | 2 +- 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/.github/actions/javascript/contributorChecklist/contributorChecklist.js b/.github/actions/javascript/contributorChecklist/contributorChecklist.js index b0c1f9a885d6..5c5da39afd81 100644 --- a/.github/actions/javascript/contributorChecklist/contributorChecklist.js +++ b/.github/actions/javascript/contributorChecklist/contributorChecklist.js @@ -1,5 +1,6 @@ const core = require('@actions/core'); const github = require('@actions/github'); +const _ = require('underscore'); const GitHubUtils = require('../../../libs/GithubUtils'); /* eslint-disable max-len */ @@ -99,40 +100,39 @@ const completedContributorPlusChecklist = `- [x] I have verified the author chec const issue = github.context.payload.issue ? github.context.payload.issue.number : github.context.payload.pull_request.number; const combinedData = []; -function printUncheckedItems(result) { - const checklist = result.split('\n'); +function getPullRequestBody() { + return GitHubUtils.octokit.pulls.get({ + owner: GitHubUtils.GITHUB_OWNER, + repo: GitHubUtils.APP_REPO, + pull_number: issue, + }).then(({data: pullRequestComment}) => pullRequestComment.body); +} - checklist.forEach((line) => { - // Provide a search string with the first 30 characters to figure out if the checkbox item is in the checklist - const lineSearchString = line.replace('- [ ] ', '').slice(0, 30); - if (line.includes('- [ ]') && (completedContributorChecklist.includes(lineSearchString) || completedContributorPlusChecklist.includes(lineSearchString))) { - console.log(`Unchecked checklist item: ${line}`); - } - }); +function getAllReviewComments() { + return GitHubUtils.paginate(GitHubUtils.octokit.pulls.listReviews, { + owner: GitHubUtils.GITHUB_OWNER, + repo: GitHubUtils.APP_REPO, + pull_number: issue, + per_page: 100, + }, response => _.map(response.data, review => review.body)); } -// Get all user text from the pull request, review comments, and pull request comments -GitHubUtils.octokit.pulls.get({ - owner: GitHubUtils.GITHUB_OWNER, - repo: GitHubUtils.APP_REPO, - pull_number: issue, -}).then(({data: pullRequestComment}) => { - combinedData.push(pullRequestComment.body); -}).then(() => GitHubUtils.octokit.pulls.listReviews({ - owner: GitHubUtils.GITHUB_OWNER, - repo: GitHubUtils.APP_REPO, - pull_number: issue, -})).then(({data: pullRequestReviewComments}) => { - pullRequestReviewComments.forEach(pullRequestReviewComment => combinedData.push(pullRequestReviewComment.body)); -}) - .then(() => GitHubUtils.octokit.issues.listComments({ +function getAllComments() { + return GitHubUtils.paginate(GitHubUtils.octokit.issues.listComments, { owner: GitHubUtils.GITHUB_OWNER, repo: GitHubUtils.APP_REPO, issue_number: issue, per_page: 100, - })) - .then(({data: pullRequestComments}) => { - pullRequestComments.forEach(pullRequestComment => combinedData.push(pullRequestComment.body)); + }, response => _.map(response.data, comment => comment.body)); +} + +getPullRequestBody() + .then(pullRequestBody => combinedData.push(pullRequestBody)) + .then(() => getAllReviewComments()) + .then(reviewComments => combinedData.push(...reviewComments)) + .then(() => getAllComments()) + .then(comments => combinedData.push(...comments)) + .then(() => { let contributorChecklistComplete = false; let contributorPlusChecklistComplete = false; @@ -143,23 +143,21 @@ GitHubUtils.octokit.pulls.get({ if (comment.includes(completedContributorChecklist.replace(whitespace, ''))) { contributorChecklistComplete = true; - } else if (comment.includes('- [')) { - printUncheckedItems(combinedData[i]); } if (comment.includes(completedContributorPlusChecklist.replace(whitespace, ''))) { contributorPlusChecklistComplete = true; - } else if (comment.includes('- [')) { - printUncheckedItems(combinedData[i]); } } if (!contributorChecklistComplete) { + console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); core.setFailed('Contributor checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } if (!contributorPlusChecklistComplete) { + console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); core.setFailed('Contributor plus checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } diff --git a/.github/actions/javascript/contributorChecklist/index.js b/.github/actions/javascript/contributorChecklist/index.js index fb5607e4253d..932594155e29 100644 --- a/.github/actions/javascript/contributorChecklist/index.js +++ b/.github/actions/javascript/contributorChecklist/index.js @@ -10,6 +10,7 @@ module.exports = const core = __nccwpck_require__(2186); const github = __nccwpck_require__(5438); +const _ = __nccwpck_require__(3571); const GitHubUtils = __nccwpck_require__(7999); /* eslint-disable max-len */ @@ -109,40 +110,39 @@ const completedContributorPlusChecklist = `- [x] I have verified the author chec const issue = github.context.payload.issue ? github.context.payload.issue.number : github.context.payload.pull_request.number; const combinedData = []; -function printUncheckedItems(result) { - const checklist = result.split('\n'); +function getPullRequestBody() { + return GitHubUtils.octokit.pulls.get({ + owner: GitHubUtils.GITHUB_OWNER, + repo: GitHubUtils.APP_REPO, + pull_number: issue, + }).then(({data: pullRequestComment}) => pullRequestComment.body); +} - checklist.forEach((line) => { - // Provide a search string with the first 30 characters to figure out if the checkbox item is in the checklist - const lineSearchString = line.replace('- [ ] ', '').slice(0, 30); - if (line.includes('- [ ]') && (completedContributorChecklist.includes(lineSearchString) || completedContributorPlusChecklist.includes(lineSearchString))) { - console.log(`Unchecked checklist item: ${line}`); - } - }); +function getAllReviewComments() { + return GitHubUtils.paginate(GitHubUtils.octokit.pulls.listReviews, { + owner: GitHubUtils.GITHUB_OWNER, + repo: GitHubUtils.APP_REPO, + pull_number: issue, + per_page: 100, + }, response => _.map(response.data, review => review.body)); } -// Get all user text from the pull request, review comments, and pull request comments -GitHubUtils.octokit.pulls.get({ - owner: GitHubUtils.GITHUB_OWNER, - repo: GitHubUtils.APP_REPO, - pull_number: issue, -}).then(({data: pullRequestComment}) => { - combinedData.push(pullRequestComment.body); -}).then(() => GitHubUtils.octokit.pulls.listReviews({ - owner: GitHubUtils.GITHUB_OWNER, - repo: GitHubUtils.APP_REPO, - pull_number: issue, -})).then(({data: pullRequestReviewComments}) => { - pullRequestReviewComments.forEach(pullRequestReviewComment => combinedData.push(pullRequestReviewComment.body)); -}) - .then(() => GitHubUtils.octokit.issues.listComments({ +function getAllComments() { + return GitHubUtils.paginate(GitHubUtils.octokit.issues.listComments, { owner: GitHubUtils.GITHUB_OWNER, repo: GitHubUtils.APP_REPO, issue_number: issue, per_page: 100, - })) - .then(({data: pullRequestComments}) => { - pullRequestComments.forEach(pullRequestComment => combinedData.push(pullRequestComment.body)); + }, response => _.map(response.data, comment => comment.body)); +} + +getPullRequestBody() + .then(pullRequestBody => combinedData.push(pullRequestBody)) + .then(() => getAllReviewComments()) + .then(reviewComments => combinedData.push(...reviewComments)) + .then(() => getAllComments()) + .then(comments => combinedData.push(...comments)) + .then(() => { let contributorChecklistComplete = false; let contributorPlusChecklistComplete = false; @@ -153,23 +153,21 @@ GitHubUtils.octokit.pulls.get({ if (comment.includes(completedContributorChecklist.replace(whitespace, ''))) { contributorChecklistComplete = true; - } else if (comment.includes('- [')) { - printUncheckedItems(combinedData[i]); } if (comment.includes(completedContributorPlusChecklist.replace(whitespace, ''))) { contributorPlusChecklistComplete = true; - } else if (comment.includes('- [')) { - printUncheckedItems(combinedData[i]); } } if (!contributorChecklistComplete) { + console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); core.setFailed('Contributor checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } if (!contributorPlusChecklistComplete) { + console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); core.setFailed('Contributor plus checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } diff --git a/.github/workflows/testChecklists.yml b/.github/workflows/testChecklists.yml index a242f4e5f943..def0e7a4a76b 100644 --- a/.github/workflows/testChecklists.yml +++ b/.github/workflows/testChecklists.yml @@ -10,7 +10,7 @@ jobs: checklist: runs-on: ubuntu-latest # Only run when a comment, PR, or PR review comment contains a checklist item - if: ${{ github.actor != 'OSBotify' || (github.event.issue.pull_request && github.event_name == 'issue_comment' && contains(github.event.comment.body, '- [') || github.event_name == 'pull_request_review' && contains(github.event.review.body, '- [') || github.event_name == 'pull_request' && contains(github.event.pull_request.body, '- [')) }} + if: github.actor != 'OSBotify' && (contains(github.event.issue.pull_request.url, 'http') && github.event_name == 'issue_comment' && contains(github.event.comment.body, '- [') || github.event_name == 'pull_request_review' && contains(github.event.review.body, '- [') || github.event_name == 'pull_request' && contains(github.event.pull_request.body, '- [')) steps: - name: contributorChecklist.js uses: Expensify/App/.github/actions/javascript/contributorChecklist@main From 0fc725011ec76708fdd7ae1a8352b4fb4858066b Mon Sep 17 00:00:00 2001 From: jayeshmangwani Date: Tue, 6 Sep 2022 16:34:20 +0530 Subject: [PATCH 109/126] removed spread operator from onLayout --- src/components/TextInput/BaseTextInput.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/TextInput/BaseTextInput.js b/src/components/TextInput/BaseTextInput.js index d537269cf4f4..eec708d91113 100644 --- a/src/components/TextInput/BaseTextInput.js +++ b/src/components/TextInput/BaseTextInput.js @@ -221,14 +221,7 @@ class BaseTextInput extends Component { ( - this.setState({ - height: event.nativeEvent.layout.height, - }) - ), - }} + onLayout={event => !this.props.multiline && this.setState({height: event.nativeEvent.layout.height})} style={[ textInputContainerStyles, From a81040b104e9ac44e58cc47c35843c988da29674 Mon Sep 17 00:00:00 2001 From: Andrew Rosiclair Date: Tue, 6 Sep 2022 12:08:47 +0100 Subject: [PATCH 110/126] lint --- src/libs/actions/Policy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index a2e5924fd431..ea1d0f32697e 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -823,7 +823,7 @@ function openWorkspaceMembersPage(policyID, clientMemberEmails) { function openWorkspaceInvitePage(policyID, clientMemberEmails) { API.read('OpenWorkspaceInvitePage', { - policyID, + policyID, clientMemberEmails: JSON.stringify(clientMemberEmails), }); } From e5b888843a2ab9514c3d589e289c898e83e20d56 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Tue, 6 Sep 2022 12:32:37 +0000 Subject: [PATCH 111/126] Update version to 1.1.97-3 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4dcc674c352d..d2fdd9f36df3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -155,8 +155,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001019702 - versionName "1.1.97-2" + versionCode 1001019703 + versionName "1.1.97-3" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() if (isNewArchitectureEnabled()) { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index f2f5c64fe627..2e639bb7da1d 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.97.2 + 1.1.97.3 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index ba7ee1904a98..7dc667bb5cdc 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.97.2 + 1.1.97.3 diff --git a/package-lock.json b/package-lock.json index a207e1e33376..6d95f5b4b838 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.1.97-2", + "version": "1.1.97-3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.1.97-2", + "version": "1.1.97-3", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 083cf0cf1cb9..8e539460aca2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.97-2", + "version": "1.1.97-3", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 7e34c849c2fc2986aaa95a9743442881054d3aee Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Tue, 6 Sep 2022 13:47:49 +0100 Subject: [PATCH 112/126] Be explicit in which types to run on --- .github/workflows/testChecklists.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/testChecklists.yml b/.github/workflows/testChecklists.yml index def0e7a4a76b..530c37fa692b 100644 --- a/.github/workflows/testChecklists.yml +++ b/.github/workflows/testChecklists.yml @@ -2,7 +2,9 @@ name: Contributor Checklist on: issue_comment: + types: [created, edited, deleted] pull_request_review: + types: [submitted, edited, dismissed] pull_request: types: [opened, edited, synchronize] From 124aee8f2f94969ec34d257b36cf5bf86f64ff75 Mon Sep 17 00:00:00 2001 From: rory Date: Tue, 6 Sep 2022 14:29:16 +0100 Subject: [PATCH 113/126] Update pull request template for console warning --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c3245e9dc200..3585d0f52e40 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -103,7 +103,7 @@ The Contributor+ will copy/paste it into a new comment and complete it after the - [ ] Android / Chrome - [ ] MacOS / Chrome - [ ] MacOS / Desktop -- [ ] I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed) +- [ ] If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack - [ ] I verified proper code patterns were followed (see [Reviewing the code](https://github.com/Expensify/App/blob/main/contributingGuides/PR_REVIEW_GUIDELINES.md#reviewing-the-code)) - [ ] I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. `toggleReport` and not `onIconClick`). - [ ] I verified that comments were added to code that is not self explanatory From ed76b94a5a6a298927a2ce3d2a532987cbc4a063 Mon Sep 17 00:00:00 2001 From: sobitneupane <073bct543.sobit@pcampus.edu.np> Date: Tue, 6 Sep 2022 19:45:36 +0545 Subject: [PATCH 114/126] Remove extension from fileName --- src/components/AttachmentModal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AttachmentModal.js b/src/components/AttachmentModal.js index e5235244b719..64999e9005db 100755 --- a/src/components/AttachmentModal.js +++ b/src/components/AttachmentModal.js @@ -120,7 +120,7 @@ class AttachmentModal extends PureComponent { const fileName = fullFileName.trim(); const splitFileName = fileName.split('.'); const fileExtension = splitFileName.pop(); - return {fileName, fileExtension}; + return {fileName: splitFileName.join('.'), fileExtension}; } /** From 8b750b2454007dd0953f5da91701010164ff4702 Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Tue, 6 Sep 2022 15:30:56 +0100 Subject: [PATCH 115/126] Try to use event array --- .github/workflows/testChecklists.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/testChecklists.yml b/.github/workflows/testChecklists.yml index 530c37fa692b..83ad7462475d 100644 --- a/.github/workflows/testChecklists.yml +++ b/.github/workflows/testChecklists.yml @@ -1,12 +1,6 @@ name: Contributor Checklist -on: - issue_comment: - types: [created, edited, deleted] - pull_request_review: - types: [submitted, edited, dismissed] - pull_request: - types: [opened, edited, synchronize] +on: [issue_comment, pull_request_review, pull_request] jobs: checklist: From 8d11a680435492ea1341b54152e19bd80278e468 Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Tue, 6 Sep 2022 16:22:29 +0100 Subject: [PATCH 116/126] Split up C and C+ checklists into two different tests --- .../javascript/contributorChecklist/action.yml | 3 +++ .../contributorChecklist/contributorChecklist.js | 10 ++++++---- .../javascript/contributorChecklist/index.js | 10 ++++++---- .github/workflows/contributorChecklists.yml | 14 ++++++++++++++ .github/workflows/contributorPlusChecklists.yml | 14 ++++++++++++++ .github/workflows/testChecklists.yml | 14 -------------- 6 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/contributorChecklists.yml create mode 100644 .github/workflows/contributorPlusChecklists.yml delete mode 100644 .github/workflows/testChecklists.yml diff --git a/.github/actions/javascript/contributorChecklist/action.yml b/.github/actions/javascript/contributorChecklist/action.yml index 16a6dbea0b04..787fac8182ce 100644 --- a/.github/actions/javascript/contributorChecklist/action.yml +++ b/.github/actions/javascript/contributorChecklist/action.yml @@ -4,6 +4,9 @@ inputs: GITHUB_TOKEN: description: Auth token for New Expensify Github required: true + CHECKLIST: + description: The checklist to look for, either 'contributor' or 'contributorPlus' + required: true runs: using: 'node16' main: './index.js' diff --git a/.github/actions/javascript/contributorChecklist/contributorChecklist.js b/.github/actions/javascript/contributorChecklist/contributorChecklist.js index 5c5da39afd81..9ff8c0f5da32 100644 --- a/.github/actions/javascript/contributorChecklist/contributorChecklist.js +++ b/.github/actions/javascript/contributorChecklist/contributorChecklist.js @@ -97,6 +97,8 @@ const completedContributorPlusChecklist = `- [x] I have verified the author chec - [x] If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected. - [x] I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.`; +// True if we are validating a contributor checklist, otherwise we are validating a contributor+ checklist +const verifyingContributorChecklist = core.getInput('CHECKLIST', {required: true}) === 'contributor'; const issue = github.context.payload.issue ? github.context.payload.issue.number : github.context.payload.pull_request.number; const combinedData = []; @@ -150,17 +152,17 @@ getPullRequestBody() } } - if (!contributorChecklistComplete) { + if (verifyingContributorChecklist && !contributorChecklistComplete) { console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); core.setFailed('Contributor checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } - if (!contributorPlusChecklistComplete) { + if (!verifyingContributorChecklist && !contributorPlusChecklistComplete) { console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); - core.setFailed('Contributor plus checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); + core.setFailed('Contributor+ checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } - console.log('All checklists are complete 🎉'); + console.log(`${verifyingContributorChecklist ? 'Contributor' : 'Contributor+'} is complete 🎉`); }); diff --git a/.github/actions/javascript/contributorChecklist/index.js b/.github/actions/javascript/contributorChecklist/index.js index 932594155e29..d9b200078e20 100644 --- a/.github/actions/javascript/contributorChecklist/index.js +++ b/.github/actions/javascript/contributorChecklist/index.js @@ -107,6 +107,8 @@ const completedContributorPlusChecklist = `- [x] I have verified the author chec - [x] If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected. - [x] I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.`; +// True if we are validating a contributor checklist, otherwise we are validating a contributor+ checklist +const verifyingContributorChecklist = core.getInput('CHECKLIST', {required: true}) === 'contributor'; const issue = github.context.payload.issue ? github.context.payload.issue.number : github.context.payload.pull_request.number; const combinedData = []; @@ -160,19 +162,19 @@ getPullRequestBody() } } - if (!contributorChecklistComplete) { + if (verifyingContributorChecklist && !contributorChecklistComplete) { console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); core.setFailed('Contributor checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } - if (!contributorPlusChecklistComplete) { + if (!verifyingContributorChecklist && !contributorPlusChecklistComplete) { console.log('Make sure you are using the most up to date checklist found here: https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md'); - core.setFailed('Contributor plus checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); + core.setFailed('Contributor+ checklist is not completely filled out. Please check every box to verify you\'ve thought about the item.'); return; } - console.log('All checklists are complete 🎉'); + console.log(`${verifyingContributorChecklist ? 'Contributor' : 'Contributor+'} is complete 🎉`); }); diff --git a/.github/workflows/contributorChecklists.yml b/.github/workflows/contributorChecklists.yml new file mode 100644 index 000000000000..692ba8944956 --- /dev/null +++ b/.github/workflows/contributorChecklists.yml @@ -0,0 +1,14 @@ +name: Contributor Checklist + +on: pull_request + +jobs: + checklist: + runs-on: ubuntu-latest + if: github.actor != 'OSBotify' && (github.event_name == 'pull_request' && contains(github.event.pull_request.body, '- [')) + steps: + - name: contributorChecklist.js + uses: Expensify/App/.github/actions/javascript/contributorChecklist@andrew-checklist-3 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CHECKLIST: 'contributor' diff --git a/.github/workflows/contributorPlusChecklists.yml b/.github/workflows/contributorPlusChecklists.yml new file mode 100644 index 000000000000..5acffb511386 --- /dev/null +++ b/.github/workflows/contributorPlusChecklists.yml @@ -0,0 +1,14 @@ +name: Contributor+ Checklist + +on: issue_comment + +jobs: + checklist: + runs-on: ubuntu-latest + if: github.actor != 'OSBotify' && (contains(github.event.issue.pull_request.url, 'http') && github.event_name == 'issue_comment' && contains(github.event.comment.body, '- [')) + steps: + - name: contributorChecklist.js + uses: Expensify/App/.github/actions/javascript/contributorChecklist@andrew-checklist-3 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CHECKLIST: 'contributorPlus' diff --git a/.github/workflows/testChecklists.yml b/.github/workflows/testChecklists.yml deleted file mode 100644 index 83ad7462475d..000000000000 --- a/.github/workflows/testChecklists.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Contributor Checklist - -on: [issue_comment, pull_request_review, pull_request] - -jobs: - checklist: - runs-on: ubuntu-latest - # Only run when a comment, PR, or PR review comment contains a checklist item - if: github.actor != 'OSBotify' && (contains(github.event.issue.pull_request.url, 'http') && github.event_name == 'issue_comment' && contains(github.event.comment.body, '- [') || github.event_name == 'pull_request_review' && contains(github.event.review.body, '- [') || github.event_name == 'pull_request' && contains(github.event.pull_request.body, '- [')) - steps: - - name: contributorChecklist.js - uses: Expensify/App/.github/actions/javascript/contributorChecklist@main - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4c84ee9c3a5b9205ec25b8ad267328f20454584f Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Tue, 6 Sep 2022 16:32:36 +0100 Subject: [PATCH 117/126] Update success message --- .../javascript/contributorChecklist/contributorChecklist.js | 2 +- .github/actions/javascript/contributorChecklist/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/javascript/contributorChecklist/contributorChecklist.js b/.github/actions/javascript/contributorChecklist/contributorChecklist.js index 9ff8c0f5da32..62036078d24c 100644 --- a/.github/actions/javascript/contributorChecklist/contributorChecklist.js +++ b/.github/actions/javascript/contributorChecklist/contributorChecklist.js @@ -164,5 +164,5 @@ getPullRequestBody() return; } - console.log(`${verifyingContributorChecklist ? 'Contributor' : 'Contributor+'} is complete 🎉`); + console.log(`${verifyingContributorChecklist ? 'Contributor' : 'Contributor+'} checklist is complete 🎉`); }); diff --git a/.github/actions/javascript/contributorChecklist/index.js b/.github/actions/javascript/contributorChecklist/index.js index d9b200078e20..1041b6906cfd 100644 --- a/.github/actions/javascript/contributorChecklist/index.js +++ b/.github/actions/javascript/contributorChecklist/index.js @@ -174,7 +174,7 @@ getPullRequestBody() return; } - console.log(`${verifyingContributorChecklist ? 'Contributor' : 'Contributor+'} is complete 🎉`); + console.log(`${verifyingContributorChecklist ? 'Contributor' : 'Contributor+'} checklist is complete 🎉`); }); From 70f277183d1c97364b6e6b53d3d389e7d7d99187 Mon Sep 17 00:00:00 2001 From: Jules Rosser Date: Tue, 6 Sep 2022 17:17:42 +0100 Subject: [PATCH 118/126] update iOS cert and provisioning profile --- ios/Certificates.p12.gpg | Bin 3323 -> 3356 bytes ...hat_expensify_appstore.mobileprovision.gpg | Bin 8008 -> 8124 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ios/Certificates.p12.gpg b/ios/Certificates.p12.gpg index 7a7ec35e4dcdbbde22c4cd5075663db038323da9..c4a68891f6e421ef7a38bb038e57b39e3a7cc525 100644 GIT binary patch literal 3356 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 FPXy}kWm5nE diff --git a/ios/chat_expensify_appstore.mobileprovision.gpg b/ios/chat_expensify_appstore.mobileprovision.gpg index 7dca07c8c0e438120b267ca0388a3eb04afdde73..d083c5449b223ebee06a978f4cc65d4b09b1d567 100644 GIT binary patch literal 8124 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 literal 8008 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 Date: Tue, 6 Sep 2022 16:36:56 +0000 Subject: [PATCH 119/126] Update version to 1.1.97-4 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index d2fdd9f36df3..c9d156afc122 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -155,8 +155,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001019703 - versionName "1.1.97-3" + versionCode 1001019704 + versionName "1.1.97-4" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() if (isNewArchitectureEnabled()) { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 2e639bb7da1d..fcc229635f36 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.97.3 + 1.1.97.4 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 7dc667bb5cdc..cfc97f8196dc 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.97.3 + 1.1.97.4 diff --git a/package-lock.json b/package-lock.json index 6d95f5b4b838..5cc92c4e9e8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.1.97-3", + "version": "1.1.97-4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.1.97-3", + "version": "1.1.97-4", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 8e539460aca2..d0b07bdb7596 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.97-3", + "version": "1.1.97-4", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From fa29c0a7e95d33f0bfcbaf7d17deb1d07cb5765d Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 7 Sep 2022 08:58:54 +0000 Subject: [PATCH 120/126] Update version to 1.1.97-5 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index c9d156afc122..f8b8bf43b4f5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -155,8 +155,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001019704 - versionName "1.1.97-4" + versionCode 1001019705 + versionName "1.1.97-5" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() if (isNewArchitectureEnabled()) { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index fcc229635f36..8763678bdb8c 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.97.4 + 1.1.97.5 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index cfc97f8196dc..e5880d917383 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.97.4 + 1.1.97.5 diff --git a/package-lock.json b/package-lock.json index 5cc92c4e9e8b..819081067bb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.1.97-4", + "version": "1.1.97-5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.1.97-4", + "version": "1.1.97-5", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index d0b07bdb7596..47be580e4fc9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.97-4", + "version": "1.1.97-5", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 2106ab0ed9d207cf9294f8adc924afbe50c3d817 Mon Sep 17 00:00:00 2001 From: rory Date: Wed, 7 Sep 2022 10:20:41 +0100 Subject: [PATCH 121/126] Fetch full PR object --- .../getPullRequestDetails/getPullRequestDetails.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js b/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js index cf3f27ee662c..ed7b81ce6b2b 100644 --- a/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js +++ b/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js @@ -87,8 +87,12 @@ if (pullRequestNumber) { ...DEFAULT_PAYLOAD, state: 'all', }) - .then(({data}) => { - const matchingPR = _.find(data, PR => PR.user.login === user && titleRegex.test(PR.title)); + .then(({data}) => _.find(data, PR => PR.user.login === user && titleRegex.test(PR.title)).number) + .then(matchingPRNum => GithubUtils.octokit.pulls.get({ + ...DEFAULT_PAYLOAD, + pull_number: matchingPRNum, + })) + .then((matchingPR) => { outputMergeCommitHash(matchingPR); outputMergeActor(matchingPR); }); From 60c0cdac49d09885501c2b0153bdd2659efdef8f Mon Sep 17 00:00:00 2001 From: rory Date: Wed, 7 Sep 2022 10:31:51 +0100 Subject: [PATCH 122/126] Destructure data from second response --- .../getPullRequestDetails/getPullRequestDetails.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js b/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js index ed7b81ce6b2b..15ee2869a14d 100644 --- a/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js +++ b/.github/actions/javascript/getPullRequestDetails/getPullRequestDetails.js @@ -92,8 +92,8 @@ if (pullRequestNumber) { ...DEFAULT_PAYLOAD, pull_number: matchingPRNum, })) - .then((matchingPR) => { - outputMergeCommitHash(matchingPR); - outputMergeActor(matchingPR); + .then(({data}) => { + outputMergeCommitHash(data); + outputMergeActor(data); }); } From 412657828bbc5576bbd249e9c8febc4cfc1eb21c Mon Sep 17 00:00:00 2001 From: rory Date: Wed, 7 Sep 2022 10:34:48 +0100 Subject: [PATCH 123/126] Rebuild GH actions --- .../actions/javascript/getPullRequestDetails/index.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/actions/javascript/getPullRequestDetails/index.js b/.github/actions/javascript/getPullRequestDetails/index.js index 692751956bbf..b06196149058 100644 --- a/.github/actions/javascript/getPullRequestDetails/index.js +++ b/.github/actions/javascript/getPullRequestDetails/index.js @@ -97,10 +97,14 @@ if (pullRequestNumber) { ...DEFAULT_PAYLOAD, state: 'all', }) + .then(({data}) => _.find(data, PR => PR.user.login === user && titleRegex.test(PR.title)).number) + .then(matchingPRNum => GithubUtils.octokit.pulls.get({ + ...DEFAULT_PAYLOAD, + pull_number: matchingPRNum, + })) .then(({data}) => { - const matchingPR = _.find(data, PR => PR.user.login === user && titleRegex.test(PR.title)); - outputMergeCommitHash(matchingPR); - outputMergeActor(matchingPR); + outputMergeCommitHash(data); + outputMergeActor(data); }); } From 7e600e1a9acc53213fe43df98146cb6dea0d6796 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 7 Sep 2022 09:44:09 +0000 Subject: [PATCH 124/126] Update version to 1.1.97-6 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index f8b8bf43b4f5..170451cd13e3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -155,8 +155,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001019705 - versionName "1.1.97-5" + versionCode 1001019706 + versionName "1.1.97-6" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() if (isNewArchitectureEnabled()) { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 8763678bdb8c..74fd0ce42628 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.97.5 + 1.1.97.6 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index e5880d917383..5b51b470c02b 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.97.5 + 1.1.97.6 diff --git a/package-lock.json b/package-lock.json index 819081067bb3..e7149e986ca0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.1.97-5", + "version": "1.1.97-6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.1.97-5", + "version": "1.1.97-6", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 47be580e4fc9..bdf639bd3b01 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.97-5", + "version": "1.1.97-6", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From f3c0ddcf7dfafa845aca595625990b67f395710e Mon Sep 17 00:00:00 2001 From: Jules Rosser Date: Wed, 7 Sep 2022 15:06:12 +0100 Subject: [PATCH 125/126] commit useless change and attempt to workaround a workflow blocking issue --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75f7d621bacc..c0f9e32884d9 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Alternatively, you can also set up debugger using [Flipper](https://fbflipper.co Our React Native Android app now uses the `Hermes` JS engine which requires your browser for remote debugging. These instructions are specific to Chrome since that's what the Hermes documentation provided. 1. Navigate to `chrome://inspect` 2. Use the `Configure...` button to add the Metro server address (typically `localhost:8081`, check your `Metro` output) -3. You should now see a "Hermes React Native" target with an "inspect" link which can be used to bring up a debugger. If you don't see the "inspect" link, make sure the Metro server is running. +3. You should now see a "Hermes React Native" target with an "inspect" link which can be used to bring up a debugger. If you don't see the "inspect" link, make sure the Metro server is running 4. You can now use the Chrome debug tools. See [React Native Debugging Hermes](https://reactnative.dev/docs/hermes#debugging-hermes-using-google-chromes-devtools) ## Web From 0f2231e76517d23eea1e7ac23d63b71238d47ef9 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 7 Sep 2022 14:22:28 +0000 Subject: [PATCH 126/126] Update version to 1.1.97-7 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 170451cd13e3..7e22a8623b0e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -155,8 +155,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001019706 - versionName "1.1.97-6" + versionCode 1001019707 + versionName "1.1.97-7" buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() if (isNewArchitectureEnabled()) { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 74fd0ce42628..289ba96a2413 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.1.97.6 + 1.1.97.7 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 5b51b470c02b..11549d1d5412 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.1.97.6 + 1.1.97.7 diff --git a/package-lock.json b/package-lock.json index e7149e986ca0..50eaad994c61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.1.97-6", + "version": "1.1.97-7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.1.97-6", + "version": "1.1.97-7", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index bdf639bd3b01..85672217086e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.1.97-6", + "version": "1.1.97-7", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",