From 29ac710d43c08a9cdbbf8ca4c6878c780301df9b Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Fri, 22 Jul 2022 16:57:56 -0600 Subject: [PATCH 01/11] Add indicator to avatar --- src/ONYXKEYS.js | 1 + src/components/AvatarWithIndicator.js | 148 +++++++--------------- src/components/OfflineWithFeedback.js | 1 + src/pages/settings/InitialSettingsPage.js | 22 ++-- src/styles/styles.js | 13 +- 5 files changed, 70 insertions(+), 115 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 40675a1a6a89..867447e1b530 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -104,6 +104,7 @@ export default { REPORTS_WITH_DRAFT: 'reportWithDraft_', REPORT_IS_COMPOSER_FULL_SIZE: 'reportIsComposerFullSize_', IS_LOADING_REPORT_ACTIONS: 'isLoadingReportActions_', + POLICY_MEMBER_LIST: 'policyMemberList_', }, // Indicates which locale should be used diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index aa37769156e3..69a521946b9f 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -1,126 +1,74 @@ -import React, {PureComponent} from 'react'; -import { - View, StyleSheet, Animated, -} from 'react-native'; +import _ from 'underscore'; +import React from 'react'; +import {StyleSheet, View} from 'react-native'; import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; import Avatar from './Avatar'; -import themeColors from '../styles/themes/default'; import styles from '../styles/styles'; +import Tooltip from './Tooltip'; +import ONYXKEYS from '../ONYXKEYS'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; -import SpinningIndicatorAnimation from '../styles/animation/SpinningIndicatorAnimation'; -import Tooltip from './Tooltip'; -import withLocalize, {withLocalizePropTypes} from './withLocalize'; +import colors from '../styles/colors'; +import variables from '../styles/variables'; const propTypes = { - /** Is user active? */ - isActive: PropTypes.bool, - /** URL for the avatar */ source: PropTypes.string.isRequired, /** Avatar size */ size: PropTypes.string, - // Whether we show the sync indicator - isSyncing: PropTypes.bool, - /** To show a tooltip on hover */ tooltipText: PropTypes.string, - ...withLocalizePropTypes, + /** The employee list of all policies (coming from Onyx) */ + policiesMemberList: PropTypes.arrayOf(PropTypes.object), }; const defaultProps = { - isActive: false, size: 'default', - isSyncing: false, tooltipText: '', + policiesMemberList: [], }; -class AvatarWithIndicator extends PureComponent { - constructor(props) { - super(props); - - this.animation = new SpinningIndicatorAnimation(); - } - - componentDidMount() { - if (!this.props.isSyncing) { - return; - } - - this.animation.start(); - } - - componentDidUpdate(prevProps) { - if (!prevProps.isSyncing && this.props.isSyncing) { - this.animation.start(); - } else if (prevProps.isSyncing && !this.props.isSyncing) { - this.animation.stop(); - } - } - - componentWillUnmount() { - this.animation.stop(); - } - - /** - * Returns user status as text - * - * @returns {String} - */ - userStatus() { - if (this.props.isSyncing) { - return this.props.translate('profilePage.syncing'); - } - - if (this.props.isActive) { - return this.props.translate('profilePage.online'); - } - - if (!this.props.isActive) { - return this.props.translate('profilePage.offline'); - } - } - - render() { - const indicatorStyles = [ - styles.alignItemsCenter, - styles.justifyContentCenter, - this.props.size === 'large' ? styles.statusIndicatorLarge : styles.statusIndicator, - this.props.isActive ? styles.statusIndicatorOnline : styles.statusIndicatorOffline, - this.animation.getSyncingStyles(), - ]; - - return ( - - - - - - - {this.props.isSyncing && ( - - )} - - - - ); - } -} +const AvatarWithIndicator = (props) => { + const indicatorStyles = [ + styles.alignItemsCenter, + styles.justifyContentCenter, + styles.avatarWithIndicator.errorDot, + ]; + const isLarge = props.size === 'large'; + const hasError = _.chain(props.policiesMemberList).flatten().some(member => !_.isEmpty(member.erros)).value(); + return ( + + + + {hasError && ( + + + + )} + + + ); +}; AvatarWithIndicator.defaultProps = defaultProps; AvatarWithIndicator.propTypes = propTypes; -export default withLocalize(AvatarWithIndicator); +AvatarWithIndicator.displayName = 'AvatarWithIndicator'; + +export default withOnyx({ + policiesMemberList: { + key: ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST, + }, +})(AvatarWithIndicator); diff --git a/src/components/OfflineWithFeedback.js b/src/components/OfflineWithFeedback.js index 196a4da3d403..2422e4745b73 100644 --- a/src/components/OfflineWithFeedback.js +++ b/src/components/OfflineWithFeedback.js @@ -124,6 +124,7 @@ const OfflineWithFeedback = (props) => { OfflineWithFeedback.propTypes = propTypes; OfflineWithFeedback.defaultProps = defaultProps; +OfflineWithFeedback.displayName = 'OfflineWithFeedback'; export default compose( withLocalize, diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 6d1996630d5c..2f31096a3cf6 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -9,7 +9,8 @@ import themeColors from '../../styles/themes/default'; import Text from '../../components/Text'; import * as Session from '../../libs/actions/Session'; import ONYXKEYS from '../../ONYXKEYS'; -import AvatarWithIndicator from '../../components/AvatarWithIndicator'; +import Tooltip from '../../components/Tooltip'; +import Avatar from '../../components/Avatar'; import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; import Navigation from '../../libs/Navigation/Navigation'; import * as Expensicons from '../../components/Icon/Expensicons'; @@ -21,16 +22,11 @@ import compose from '../../libs/compose'; import CONST from '../../CONST'; import DateUtils from '../../libs/DateUtils'; import Permissions from '../../libs/Permissions'; -import networkPropTypes from '../../components/networkPropTypes'; -import {withNetwork} from '../../components/OnyxProvider'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; const propTypes = { /* Onyx Props */ - /** Information about the network */ - network: networkPropTypes.isRequired, - /** The session of the logged in person */ session: PropTypes.shape({ /** Email of the logged in person */ @@ -151,12 +147,13 @@ const InitialSettingsPage = (props) => { - + + + @@ -205,7 +202,6 @@ InitialSettingsPage.displayName = 'InitialSettingsPage'; export default compose( withLocalize, - withNetwork(), withCurrentUserPersonalDetails, withOnyx({ session: { diff --git a/src/styles/styles.js b/src/styles/styles.js index f23c94d23526..670e8956a654 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1005,8 +1005,17 @@ const styles = { backgroundColor: themeColors.online, }, - statusIndicatorOffline: { - backgroundColor: themeColors.offline, + avatarWithIndicator: { + errorDot: { + // borderColor: themeColors.sidebar, + // borderWidth: 2, + position: 'absolute', + right: -1, + bottom: -1, + height: 12, + width: 12, + zIndex: 10, + }, }, floatingActionButton: { From 27125bab5d1ab32fe31630c3e67f9ad124b04ea3 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Fri, 22 Jul 2022 17:21:45 -0600 Subject: [PATCH 02/11] Add RBR to workspace page (kind of) --- src/components/AvatarWithIndicator.js | 2 +- src/pages/workspace/WorkspaceInitialPage.js | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index 69a521946b9f..f2d02872e77d 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -39,7 +39,7 @@ const AvatarWithIndicator = (props) => { styles.avatarWithIndicator.errorDot, ]; const isLarge = props.size === 'large'; - const hasError = _.chain(props.policiesMemberList).flatten().some(member => !_.isEmpty(member.erros)).value(); + const hasError = _.chain(props.policiesMemberList).flatten().some(member => !_.isEmpty(member.errors)).value(); return ( diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 9cb442edb586..a66564a74250 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -1,6 +1,7 @@ import _ from 'underscore'; import React from 'react'; import {View, ScrollView, Pressable} from 'react-native'; +import {withOnyx} from 'react-native-onyx'; import Navigation from '../../libs/Navigation/Navigation'; import ROUTES from '../../ROUTES'; import styles from '../../styles/styles'; @@ -20,13 +21,21 @@ import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndica import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; import * as PolicyActions from '../../libs/actions/Policy'; import CONST from '../../CONST'; +import ONYXKEYS from '../../ONYXKEYS'; +import PropTypes from 'prop-types'; const propTypes = { ...fullPolicyPropTypes, ...withLocalizePropTypes, + + /** The employee list of this policy (coming from Onyx) */ + policyMemberList: PropTypes.arrayOf(PropTypes.object), }; -const defaultProps = fullPolicyDefaultProps; +const defaultProps = { + ...fullPolicyDefaultProps, + policyMemberList: [], +}; class WorkspaceInitialPage extends React.Component { constructor(props) { @@ -69,6 +78,7 @@ class WorkspaceInitialPage extends React.Component { if (_.isEmpty(policy)) { return ; } + const hasMembersError = _.chain(this.props.policyMemberList).some(member => !_.isEmpty(member.errors)).value(); const menuItems = [ { @@ -105,6 +115,7 @@ class WorkspaceInitialPage extends React.Component { translationKey: 'workspace.common.members', icon: Expensicons.Users, action: () => Navigation.navigate(ROUTES.getWorkspaceMembersRoute(policy.id)), + error: hasMembersError, }, { translationKey: 'workspace.common.bankAccount', @@ -202,6 +213,7 @@ class WorkspaceInitialPage extends React.Component { iconRight={item.iconRight} onPress={() => item.action()} shouldShowRightIcon + brickRoadIndicator={item.error ? 'error' : null} /> ))} @@ -228,4 +240,9 @@ WorkspaceInitialPage.displayName = 'WorkspaceInitialPage'; export default compose( withLocalize, withFullPolicy, + withOnyx({ + policyMemberList: { + key: ({policy}) => `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policy.id}`, + }, + }), )(WorkspaceInitialPage); From 983d1922b2fd3e8a9e4359df7bba220a2d9e6753 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Mon, 25 Jul 2022 17:11:13 -0600 Subject: [PATCH 03/11] Add more RBR for policy members --- src/components/AvatarWithIndicator.js | 17 +--- src/components/MenuItem.js | 13 +++ src/libs/actions/Policy.js | 29 +++++++ src/pages/workspace/WorkspaceMembersPage.js | 90 ++++++++++++--------- src/styles/styles.js | 7 +- 5 files changed, 104 insertions(+), 52 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index f2d02872e77d..c691dd25036f 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -7,10 +7,6 @@ import Avatar from './Avatar'; import styles from '../styles/styles'; import Tooltip from './Tooltip'; import ONYXKEYS from '../ONYXKEYS'; -import Icon from './Icon'; -import * as Expensicons from './Icon/Expensicons'; -import colors from '../styles/colors'; -import variables from '../styles/variables'; const propTypes = { /** URL for the avatar */ @@ -23,7 +19,7 @@ const propTypes = { tooltipText: PropTypes.string, /** The employee list of all policies (coming from Onyx) */ - policiesMemberList: PropTypes.arrayOf(PropTypes.object), + policiesMemberList: PropTypes.object, }; const defaultProps = { @@ -36,7 +32,7 @@ const AvatarWithIndicator = (props) => { const indicatorStyles = [ styles.alignItemsCenter, styles.justifyContentCenter, - styles.avatarWithIndicator.errorDot, + props.size === 'large' ? styles.statusIndicatorLarge : styles.statusIndicator, ]; const isLarge = props.size === 'large'; const hasError = _.chain(props.policiesMemberList).flatten().some(member => !_.isEmpty(member.errors)).value(); @@ -49,14 +45,7 @@ const AvatarWithIndicator = (props) => { size={props.size} /> {hasError && ( - - - + )} diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 0be18a83a916..e01fe1011bc5 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -14,6 +14,8 @@ import Badge from './Badge'; import CONST from '../CONST'; import menuItemPropTypes from './menuItemPropTypes'; import SelectCircle from './SelectCircle'; +import colors from '../styles/colors'; +import variables from '../styles/variables'; const propTypes = { ...menuItemPropTypes, @@ -40,6 +42,7 @@ const defaultProps = { onPress: () => {}, interactive: true, fallbackIcon: Expensicons.FallbackAvatar, + brickRoadIndicator: undefined, }; const MenuItem = props => ( @@ -130,6 +133,16 @@ const MenuItem = props => ( )} + {props.brickRoadIndicator && ( + + + + )} {props.shouldShowRightIcon && ( this.willTooltipShowForLogin(item.login, true)} onHoverOut={() => this.setState({showTooltipForLogin: ''})}> - this.toggleUser(item.login)} - activeOpacity={0.7} - > - this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> + this.willTooltipShowForLogin(item.login, true)} onHoverOut={() => this.setState({showTooltipForLogin: ''})}> + this.toggleUser(item.login)} - toggleTooltip={this.state.showTooltipForLogin === item.login} - text={this.props.translate('workspace.people.error.cannotRemove')} - /> - - this.toggleUser(item.login)} - forceTextUnreadStyle - isDisabled={!canBeRemoved} - option={{ - text: Str.removeSMSDomain(item.displayName), - alternateText: Str.removeSMSDomain(item.login), - participantsList: [item], - icons: [item.avatar], - keyForList: item.login, - }} + activeOpacity={0.7} + > + this.toggleUser(item.login)} + toggleTooltip={this.state.showTooltipForLogin === item.login} + text={this.props.translate('workspace.people.error.cannotRemove')} /> - - {this.props.session.email === item.login && ( - - - - {this.props.translate('common.admin')} - - + + this.toggleUser(item.login)} + forceTextUnreadStyle + isDisabled={!canBeRemoved} + option={{ + text: Str.removeSMSDomain(item.displayName), + alternateText: Str.removeSMSDomain(item.login), + participantsList: [item], + icons: [item.avatar], + keyForList: item.login, + }} + /> - )} - - + {this.props.session.email === item.login && ( + + + + {this.props.translate('common.admin')} + + + + )} + + + ); } @@ -252,6 +269,7 @@ class WorkspaceMembersPage extends React.Component { .map(email => this.props.personalDetails[email]) .filter() .sortBy(person => person.displayName.toLowerCase()) + .map(person => ({...person, pendingAction: 'delete', errors: {1: 'caca'}})) // TODO: remove this hardcoded values .value(); const policyID = lodashGet(this.props.route, 'params.policyID'); const policyName = lodashGet(this.props.policy, 'name'); diff --git a/src/styles/styles.js b/src/styles/styles.js index 670e8956a654..2ce772e488cc 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -979,6 +979,7 @@ const styles = { statusIndicator: { borderColor: themeColors.sidebar, + backgroundColor: themeColors.buttonDangerBG, borderRadius: 6, borderWidth: 2, position: 'absolute', @@ -991,6 +992,7 @@ const styles = { statusIndicatorLarge: { borderColor: themeColors.componentBG, + backgroundColor: themeColors.buttonDangerBG, borderRadius: 8, borderWidth: 2, position: 'absolute', @@ -1007,8 +1009,9 @@ const styles = { avatarWithIndicator: { errorDot: { - // borderColor: themeColors.sidebar, - // borderWidth: 2, + borderColor: themeColors.sidebar, + borderRadius: 6, + borderWidth: 2, position: 'absolute', right: -1, bottom: -1, From 4b3db1c3f48e6554d54d2100a59470aa295f6918 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Wed, 27 Jul 2022 16:40:12 -0600 Subject: [PATCH 04/11] Fix proptypes and some code that uses them --- src/components/AvatarWithIndicator.js | 8 +++++--- src/pages/workspace/WorkspaceInitialPage.js | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index c691dd25036f..eb78475ee7da 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -19,13 +19,13 @@ const propTypes = { tooltipText: PropTypes.string, /** The employee list of all policies (coming from Onyx) */ - policiesMemberList: PropTypes.object, + policiesMemberList: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.object)), }; const defaultProps = { size: 'default', tooltipText: '', - policiesMemberList: [], + policiesMemberList: {}, }; const AvatarWithIndicator = (props) => { @@ -35,7 +35,9 @@ const AvatarWithIndicator = (props) => { props.size === 'large' ? styles.statusIndicatorLarge : styles.statusIndicator, ]; const isLarge = props.size === 'large'; - const hasError = _.chain(props.policiesMemberList).flatten().some(member => !_.isEmpty(member.errors)).value(); + + // TODO: this is in a utility method + const hasError = _.some(props.policiesMemberList, policyMembers => _.some(policyMembers, member => !_.isEmpty(member.errors))); return ( diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index a66564a74250..978064c286bf 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -2,6 +2,7 @@ import _ from 'underscore'; import React from 'react'; import {View, ScrollView, Pressable} from 'react-native'; import {withOnyx} from 'react-native-onyx'; +import PropTypes from 'prop-types'; import Navigation from '../../libs/Navigation/Navigation'; import ROUTES from '../../ROUTES'; import styles from '../../styles/styles'; @@ -22,7 +23,6 @@ import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './wit import * as PolicyActions from '../../libs/actions/Policy'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; -import PropTypes from 'prop-types'; const propTypes = { ...fullPolicyPropTypes, @@ -78,8 +78,9 @@ class WorkspaceInitialPage extends React.Component { if (_.isEmpty(policy)) { return ; } - const hasMembersError = _.chain(this.props.policyMemberList).some(member => !_.isEmpty(member.errors)).value(); + // TODO: this is in a utility method + const hasMembersError = _.some(this.props.policyMemberList, member => !_.isEmpty(member.errors)); const menuItems = [ { translationKey: 'workspace.common.settings', From 78fa8535c2e92b5e940a182db7052897ac0aab9e Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Wed, 27 Jul 2022 16:54:37 -0600 Subject: [PATCH 05/11] Fix more proptypes --- src/components/AvatarWithIndicator.js | 2 +- src/pages/workspace/WorkspaceInitialPage.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index eb78475ee7da..5c36636b8864 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -19,7 +19,7 @@ const propTypes = { tooltipText: PropTypes.string, /** The employee list of all policies (coming from Onyx) */ - policiesMemberList: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.object)), + policiesMemberList: PropTypes.objectOf(PropTypes.object), }; const defaultProps = { diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 978064c286bf..d8e8ab608bf8 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -29,12 +29,12 @@ const propTypes = { ...withLocalizePropTypes, /** The employee list of this policy (coming from Onyx) */ - policyMemberList: PropTypes.arrayOf(PropTypes.object), + policyMemberList: PropTypes.objectOf(PropTypes.object), }; const defaultProps = { ...fullPolicyDefaultProps, - policyMemberList: [], + policyMemberList: {}, }; class WorkspaceInitialPage extends React.Component { From 4ca144dc62495d690c39721e14deff08acc39097 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Thu, 28 Jul 2022 16:53:00 -0600 Subject: [PATCH 06/11] Use utility and common props --- src/components/AvatarWithIndicator.js | 3 ++- src/libs/DateUtils.js | 1 + src/libs/actions/Policy.js | 3 --- src/pages/policyMemberPropType.js | 3 +++ src/pages/workspace/WorkspaceInitialPage.js | 3 ++- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index 5c36636b8864..b0edcc48506b 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -7,6 +7,7 @@ import Avatar from './Avatar'; import styles from '../styles/styles'; import Tooltip from './Tooltip'; import ONYXKEYS from '../ONYXKEYS'; +import policyMemberPropType from '../pages/policyMemberPropType'; const propTypes = { /** URL for the avatar */ @@ -19,7 +20,7 @@ const propTypes = { tooltipText: PropTypes.string, /** The employee list of all policies (coming from Onyx) */ - policiesMemberList: PropTypes.objectOf(PropTypes.object), + policiesMemberList: PropTypes.objectOf(policyMemberPropType), }; const defaultProps = { diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 0c432888b3b8..17400070f92f 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -11,6 +11,7 @@ import CONST from '../CONST'; import * as Localize from './Localize'; import * as PersonalDetails from './actions/PersonalDetails'; import * as CurrentDate from './actions/CurrentDate'; +window.Onyx = Onyx; let currentUserEmail; Onyx.connect({ diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index cf095de36218..80849b26f6ec 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -594,10 +594,7 @@ export { setCustomUnitRate, updateLastAccessedWorkspace, subscribeToPolicyEvents, -<<<<<<< HEAD clearDeleteMemberError, clearAddMemberError, -======= hasPolicyMemberError, ->>>>>>> main }; diff --git a/src/pages/policyMemberPropType.js b/src/pages/policyMemberPropType.js index 0e5c39e02369..67f0845625ee 100644 --- a/src/pages/policyMemberPropType.js +++ b/src/pages/policyMemberPropType.js @@ -9,4 +9,7 @@ export default PropTypes.shape({ * {: 'error message', : 'error message 2'} */ errors: PropTypes.objectOf(PropTypes.string), + + /** Is this action pending? */ + pending: PropTypes.string, }); diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index d8e8ab608bf8..fe9e4388e0b6 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -23,13 +23,14 @@ import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './wit import * as PolicyActions from '../../libs/actions/Policy'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; +import policyMemberPropType from '../policyMemberPropType'; const propTypes = { ...fullPolicyPropTypes, ...withLocalizePropTypes, /** The employee list of this policy (coming from Onyx) */ - policyMemberList: PropTypes.objectOf(PropTypes.object), + policyMemberList: PropTypes.objectOf(policyMemberPropType), }; const defaultProps = { From 093002525f39f3c19bcca951d8047e48d2fd6455 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Thu, 28 Jul 2022 16:54:00 -0600 Subject: [PATCH 07/11] Remove test code --- src/libs/DateUtils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/DateUtils.js b/src/libs/DateUtils.js index 17400070f92f..0c432888b3b8 100644 --- a/src/libs/DateUtils.js +++ b/src/libs/DateUtils.js @@ -11,7 +11,6 @@ import CONST from '../CONST'; import * as Localize from './Localize'; import * as PersonalDetails from './actions/PersonalDetails'; import * as CurrentDate from './actions/CurrentDate'; -window.Onyx = Onyx; let currentUserEmail; Onyx.connect({ From f122f033246dc4e88e0eb5dafc395564d515dd60 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Fri, 29 Jul 2022 13:34:06 -0600 Subject: [PATCH 08/11] Use utility method, remove hardcoded values --- src/components/AvatarWithIndicator.js | 8 ++++---- src/pages/workspace/WorkspaceInitialPage.js | 4 ++-- src/pages/workspace/WorkspaceMembersPage.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index b0edcc48506b..ab00e997dfca 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -8,6 +8,7 @@ import styles from '../styles/styles'; import Tooltip from './Tooltip'; import ONYXKEYS from '../ONYXKEYS'; import policyMemberPropType from '../pages/policyMemberPropType'; +import {hasPolicyMemberError} from '../libs/actions/Policy'; const propTypes = { /** URL for the avatar */ @@ -30,15 +31,14 @@ const defaultProps = { }; const AvatarWithIndicator = (props) => { + const isLarge = props.size === 'large'; const indicatorStyles = [ styles.alignItemsCenter, styles.justifyContentCenter, - props.size === 'large' ? styles.statusIndicatorLarge : styles.statusIndicator, + isLarge ? styles.statusIndicatorLarge : styles.statusIndicator, ]; - const isLarge = props.size === 'large'; - // TODO: this is in a utility method - const hasError = _.some(props.policiesMemberList, policyMembers => _.some(policyMembers, member => !_.isEmpty(member.errors))); + const hasError = _.some(props.policiesMemberList, policyMembers => hasPolicyMemberError(policyMembers)); return ( diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index fe9e4388e0b6..1fe30a56b5fb 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -24,6 +24,7 @@ import * as PolicyActions from '../../libs/actions/Policy'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; import policyMemberPropType from '../policyMemberPropType'; +import {hasPolicyMemberError} from '../../libs/actions/Policy'; const propTypes = { ...fullPolicyPropTypes, @@ -80,8 +81,7 @@ class WorkspaceInitialPage extends React.Component { return ; } - // TODO: this is in a utility method - const hasMembersError = _.some(this.props.policyMemberList, member => !_.isEmpty(member.errors)); + const hasMembersError = hasPolicyMemberError(this.props.policyMemberList); const menuItems = [ { translationKey: 'workspace.common.settings', diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 4c102e356fe2..8f10c91b1992 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -269,7 +269,7 @@ class WorkspaceMembersPage extends React.Component { .map(email => this.props.personalDetails[email]) .filter() .sortBy(person => person.displayName.toLowerCase()) - .map(person => ({...person, pendingAction: 'delete', errors: {1: 'caca'}})) // TODO: remove this hardcoded values + .map(person => ({...person})) // TODO: here we will add the pendingAction and errors prop .value(); const policyID = lodashGet(this.props.route, 'params.policyID'); const policyName = lodashGet(this.props.policy, 'name'); From 75a6ed4ca7f57c63e6e5918b9a2a451338a210b5 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Fri, 29 Jul 2022 13:46:08 -0600 Subject: [PATCH 09/11] Fix lint errors --- src/components/AvatarWithIndicator.js | 4 ++-- src/pages/workspace/WorkspaceInitialPage.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index ab00e997dfca..45514d436509 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -8,7 +8,7 @@ import styles from '../styles/styles'; import Tooltip from './Tooltip'; import ONYXKEYS from '../ONYXKEYS'; import policyMemberPropType from '../pages/policyMemberPropType'; -import {hasPolicyMemberError} from '../libs/actions/Policy'; +import * as Policy from '../libs/actions/Policy'; const propTypes = { /** URL for the avatar */ @@ -38,7 +38,7 @@ const AvatarWithIndicator = (props) => { isLarge ? styles.statusIndicatorLarge : styles.statusIndicator, ]; - const hasError = _.some(props.policiesMemberList, policyMembers => hasPolicyMemberError(policyMembers)); + const hasError = _.some(props.policiesMemberList, policyMembers => Policy.hasPolicyMemberError(policyMembers)); return ( diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 1fe30a56b5fb..66d0d76eea7d 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -24,7 +24,7 @@ import * as PolicyActions from '../../libs/actions/Policy'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; import policyMemberPropType from '../policyMemberPropType'; -import {hasPolicyMemberError} from '../../libs/actions/Policy'; +import * as Policy from '../../libs/actions/Policy'; const propTypes = { ...fullPolicyPropTypes, @@ -81,7 +81,7 @@ class WorkspaceInitialPage extends React.Component { return ; } - const hasMembersError = hasPolicyMemberError(this.props.policyMemberList); + const hasMembersError = Policy.hasPolicyMemberError(this.props.policyMemberList); const menuItems = [ { translationKey: 'workspace.common.settings', From 56dbe687dd5dd3f739821b722b03a7b989cf2bcf Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Fri, 29 Jul 2022 14:26:11 -0600 Subject: [PATCH 10/11] Lint again --- src/pages/workspace/WorkspaceInitialPage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 66d0d76eea7d..eb0c60ab9703 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -24,7 +24,6 @@ import * as PolicyActions from '../../libs/actions/Policy'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; import policyMemberPropType from '../policyMemberPropType'; -import * as Policy from '../../libs/actions/Policy'; const propTypes = { ...fullPolicyPropTypes, @@ -81,7 +80,7 @@ class WorkspaceInitialPage extends React.Component { return ; } - const hasMembersError = Policy.hasPolicyMemberError(this.props.policyMemberList); + const hasMembersError = PolicyActions.hasPolicyMemberError(this.props.policyMemberList); const menuItems = [ { translationKey: 'workspace.common.settings', From c3ccb288b2d2bb4c69d3bf88d9f0fdc1079a1926 Mon Sep 17 00:00:00 2001 From: Ionatan Wiznia Date: Mon, 1 Aug 2022 13:26:58 -0600 Subject: [PATCH 11/11] Address comments from review --- src/components/AvatarWithIndicator.js | 4 ++-- src/pages/policyMemberPropType.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index 45514d436509..765ca641a3f4 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -38,7 +38,7 @@ const AvatarWithIndicator = (props) => { isLarge ? styles.statusIndicatorLarge : styles.statusIndicator, ]; - const hasError = _.some(props.policiesMemberList, policyMembers => Policy.hasPolicyMemberError(policyMembers)); + const hasPolicyMemberError = _.some(props.policiesMemberList, policyMembers => Policy.hasPolicyMemberError(policyMembers)); return ( @@ -47,7 +47,7 @@ const AvatarWithIndicator = (props) => { source={props.source} size={props.size} /> - {hasError && ( + {hasPolicyMemberError && ( )} diff --git a/src/pages/policyMemberPropType.js b/src/pages/policyMemberPropType.js index 67f0845625ee..22a4d355fbfb 100644 --- a/src/pages/policyMemberPropType.js +++ b/src/pages/policyMemberPropType.js @@ -11,5 +11,5 @@ export default PropTypes.shape({ errors: PropTypes.objectOf(PropTypes.string), /** Is this action pending? */ - pending: PropTypes.string, + pendingAction: PropTypes.string, });