From 0f7f6855193225af163e91793674a428e1157198 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 16 Jan 2023 17:15:53 -0700 Subject: [PATCH 01/19] rm canBeRemoved var --- src/pages/workspace/WorkspaceMembersPage.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index bc570df3c591..cf8b8d03a344 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -252,19 +252,18 @@ class WorkspaceMembersPage extends React.Component { renderItem({ item, }) { - const canBeRemoved = this.props.policy.owner !== item.login && this.props.session.email !== item.login && item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; + // const canBeRemoved = this.props.policy.owner !== item.login && this.props.session.email !== item.login && item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; return ( this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> this.willTooltipShowForLogin(item.login, true)} onHoverOut={() => this.setState({showTooltipForLogin: ''})}> this.toggleUser(item.login, item.pendingAction)} activeOpacity={0.7} > this.toggleUser(item.login, item.pendingAction)} toggleTooltip={this.state.showTooltipForLogin === item.login} text={this.props.translate('workspace.people.error.cannotRemove')} @@ -273,7 +272,6 @@ class WorkspaceMembersPage extends React.Component { this.toggleUser(item.login, item.pendingAction)} boldStyle - isDisabled={!canBeRemoved} option={{ text: Str.removeSMSDomain(item.displayName), alternateText: Str.removeSMSDomain(item.login), From d177feb339207613d5bee3194dac33fcd722d1dd Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 16 Jan 2023 17:20:14 -0700 Subject: [PATCH 02/19] rm willTooltipShowForLogin --- src/pages/workspace/WorkspaceMembersPage.js | 101 +++++++------------- 1 file changed, 34 insertions(+), 67 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index cf8b8d03a344..e6ffaaa14aac 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -24,7 +24,6 @@ import personalDetailsPropType from '../personalDetailsPropType'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions'; import OptionRow from '../../components/OptionRow'; import CheckboxWithTooltip from '../../components/CheckboxWithTooltip'; -import Hoverable from '../../components/Hoverable'; import withPolicy, {policyPropTypes, policyDefaultProps} from './withPolicy'; import CONST from '../../CONST'; import OfflineWithFeedback from '../../components/OfflineWithFeedback'; @@ -156,7 +155,7 @@ class WorkspaceMembersPage extends React.Component { * */ toggleUser(login, pendingAction) { - if (this.willTooltipShowForLogin(login) || pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { + if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { return; } @@ -170,37 +169,6 @@ class WorkspaceMembersPage extends React.Component { this.setState({showTooltipForLogin: ''}); } - /** - * Shows the tooltip for non removable members - * - * @param {String} login - * @param {Boolean} wasHovered - * @returns {Boolean} Return true if the tooltip was displayed so we can use the state of it in other functions. - */ - willTooltipShowForLogin(login, wasHovered = false) { - const isSmallOrMediumScreen = this.props.isSmallScreenWidth || this.props.isMediumScreenWidth; - - // Small screens only show the tooltip on press, so ignore hovered event on those cases. - if (wasHovered && isSmallOrMediumScreen) { - return false; - } - - const canBeRemoved = this.props.policy.owner !== login && this.props.session.email !== login; - if (!canBeRemoved) { - this.setState({ - showTooltipForLogin: login, - }, () => { - // Immediately reset the login to deactivate the tooltip trigger, otherwise, the tooltip will not open again on further interactions on small screens. - if (!isSmallOrMediumScreen) { - return; - } - this.setState({showTooltipForLogin: ''}); - }); - } - - return !canBeRemoved; - } - /** * Add user from the selectedEmployees list * @@ -253,45 +221,44 @@ class WorkspaceMembersPage extends React.Component { item, }) { // const canBeRemoved = this.props.policy.owner !== item.login && this.props.session.email !== item.login && item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; + // const canBeRemoved = this.props.policy.owner !== login && this.props.session.email !== login; return ( this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> - this.willTooltipShowForLogin(item.login, true)} onHoverOut={() => this.setState({showTooltipForLogin: ''})}> - this.toggleUser(item.login, item.pendingAction)} + activeOpacity={0.7} + > + this.toggleUser(item.login, item.pendingAction)} - activeOpacity={0.7} - > - this.toggleUser(item.login, item.pendingAction)} - toggleTooltip={this.state.showTooltipForLogin === item.login} - text={this.props.translate('workspace.people.error.cannotRemove')} + toggleTooltip={this.state.showTooltipForLogin === item.login} + text={this.props.translate('workspace.people.error.cannotRemove')} + /> + + this.toggleUser(item.login, item.pendingAction)} + boldStyle + option={{ + text: Str.removeSMSDomain(item.displayName), + alternateText: Str.removeSMSDomain(item.login), + participantsList: [item], + icons: [item.avatar], + keyForList: item.login, + }} /> - - this.toggleUser(item.login, item.pendingAction)} - boldStyle - 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 || item.role === 'admin') && ( - - - - {this.props.translate('common.admin')} - - + + {(this.props.session.email === item.login || item.role === 'admin') && ( + + + + {this.props.translate('common.admin')} + - )} - - + + )} + ); } From be59dc3ec1b9b74f3ef43c9d621a82a116e99f9d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 16 Jan 2023 17:23:03 -0700 Subject: [PATCH 03/19] rm showTooltipForLogin state --- src/pages/workspace/WorkspaceMembersPage.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index e6ffaaa14aac..db158e8ff52b 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -60,7 +60,6 @@ class WorkspaceMembersPage extends React.Component { this.state = { selectedEmployees: [], isRemoveMembersConfirmModalVisible: false, - showTooltipForLogin: '', }; this.renderItem = this.renderItem.bind(this); @@ -136,7 +135,6 @@ class WorkspaceMembersPage extends React.Component { * Add or remove all users from the selectedEmployees list */ toggleAllUsers() { - this.setState({showTooltipForLogin: ''}); let policyMemberList = lodashGet(this.props, 'policyMemberList', {}); policyMemberList = _.filter(_.keys(policyMemberList), policyMember => policyMemberList[policyMember].pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); const removableMembers = _.without(policyMemberList, this.props.session.email, this.props.policy.owner); @@ -165,8 +163,6 @@ class WorkspaceMembersPage extends React.Component { } else { this.addUser(login); } - - this.setState({showTooltipForLogin: ''}); } /** @@ -233,7 +229,6 @@ class WorkspaceMembersPage extends React.Component { style={[styles.peopleRowCell]} isChecked={_.contains(this.state.selectedEmployees, item.login)} onPress={() => this.toggleUser(item.login, item.pendingAction)} - toggleTooltip={this.state.showTooltipForLogin === item.login} text={this.props.translate('workspace.people.error.cannotRemove')} /> From dcf6a1ddc363df4e0ddbd9188aa119fe6f3610f9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 14:31:30 -0700 Subject: [PATCH 04/19] clean up CheckboxWithTooltip --- src/pages/workspace/WorkspaceMembersPage.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index db158e8ff52b..85bf6563ab23 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -23,7 +23,6 @@ import ConfirmModal from '../../components/ConfirmModal'; import personalDetailsPropType from '../personalDetailsPropType'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions'; import OptionRow from '../../components/OptionRow'; -import CheckboxWithTooltip from '../../components/CheckboxWithTooltip'; import withPolicy, {policyPropTypes, policyDefaultProps} from './withPolicy'; import CONST from '../../CONST'; import OfflineWithFeedback from '../../components/OfflineWithFeedback'; @@ -137,10 +136,9 @@ class WorkspaceMembersPage extends React.Component { toggleAllUsers() { let policyMemberList = lodashGet(this.props, 'policyMemberList', {}); policyMemberList = _.filter(_.keys(policyMemberList), policyMember => policyMemberList[policyMember].pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); - const removableMembers = _.without(policyMemberList, this.props.session.email, this.props.policy.owner); this.setState(prevState => ({ - selectedEmployees: removableMembers.length !== prevState.selectedEmployees.length - ? removableMembers + selectedEmployees: policyMemberList.length !== prevState.selectedEmployees.length + ? policyMemberList : [], })); } @@ -157,7 +155,7 @@ class WorkspaceMembersPage extends React.Component { return; } - // Add or remove the user if the checkbox is enabled and is clickable. + // Add or remove the user if the checkbox is enabled if (_.contains(this.state.selectedEmployees, login)) { this.removeUser(login); } else { @@ -193,7 +191,6 @@ class WorkspaceMembersPage extends React.Component { * @param {Object} item */ dismissError(item) { - // TODO: login here also probably will need to change when connecting this to the real api if (item.pendingAction === 'delete') { Policy.clearDeleteMemberError(this.props.route.params.policyID, item.login); } else { @@ -225,11 +222,10 @@ class WorkspaceMembersPage extends React.Component { onPress={() => this.toggleUser(item.login, item.pendingAction)} activeOpacity={0.7} > - this.toggleUser(item.login, item.pendingAction)} - text={this.props.translate('workspace.people.error.cannotRemove')} /> Date: Tue, 17 Jan 2023 14:38:52 -0700 Subject: [PATCH 05/19] clean up removableMembers --- src/pages/workspace/WorkspaceMembersPage.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 85bf6563ab23..721ca8a9d824 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -256,12 +256,8 @@ class WorkspaceMembersPage extends React.Component { render() { const policyMemberList = lodashGet(this.props, 'policyMemberList', {}); - const removableMembers = []; let data = []; _.each(policyMemberList, (policyMember, email) => { - if (email !== this.props.session.email && email !== this.props.policy.owner && policyMember.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { - removableMembers.push(email); - } const details = lodashGet(this.props.personalDetails, email, {displayName: email, login: email, avatar: Expensicons.FallbackAvatar}); data.push({ ...policyMember, @@ -321,7 +317,7 @@ class WorkspaceMembersPage extends React.Component { this.toggleAllUsers()} /> From e2a92560eacec717a1af228d3921acb84a9640f9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 14:42:50 -0700 Subject: [PATCH 06/19] fix select all logic --- src/pages/workspace/WorkspaceMembersPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 721ca8a9d824..95be40589bea 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -317,7 +317,7 @@ class WorkspaceMembersPage extends React.Component { this.toggleAllUsers()} /> From b6d28d3ec914915ff057ac9908e59808c4e60f93 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 14:45:21 -0700 Subject: [PATCH 07/19] rm filter in submit function --- src/pages/workspace/WorkspaceMembersPage.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 95be40589bea..18cdc986d7d6 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -107,9 +107,7 @@ class WorkspaceMembersPage extends React.Component { * Remove selected users from the workspace */ removeUsers() { - // Remove the admin from the list - const membersToRemove = _.without(this.state.selectedEmployees, this.props.session.email); - Policy.removeMembers(membersToRemove, this.props.route.params.policyID); + Policy.removeMembers(this.state.selectedEmployees, this.props.route.params.policyID); this.setState({ selectedEmployees: [], isRemoveMembersConfirmModalVisible: false, From d31d4be0ea022970354cf2a94f43f47e25324d2d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 14:47:26 -0700 Subject: [PATCH 08/19] rm comment and create validate --- src/pages/workspace/WorkspaceMembersPage.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 18cdc986d7d6..432269998a9f 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -211,8 +211,6 @@ class WorkspaceMembersPage extends React.Component { renderItem({ item, }) { - // const canBeRemoved = this.props.policy.owner !== item.login && this.props.session.email !== item.login && item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; - // const canBeRemoved = this.props.policy.owner !== login && this.props.session.email !== login; return ( this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> { + if (member) + }); + // this.props.policy.owner !== item.login && this.props.session.email !== item.login && item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; + } + render() { const policyMemberList = lodashGet(this.props, 'policyMemberList', {}); let data = []; From 689a4bc268bc69cbad758d36b30d461dd3da1189 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 15:05:57 -0700 Subject: [PATCH 09/19] create setWorkspaceMemberErrors --- src/libs/actions/Policy.js | 14 ++++++++++++++ src/pages/workspace/WorkspaceMembersPage.js | 17 ++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 5a2de0e7e1f6..17c5a234fdef 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -426,6 +426,19 @@ function setWorkspaceErrors(policyID, errors) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errors}); } +/** + * @param {String} policyID + * @param {String} member + * @param {Object} errors + */ +function setWorkspaceMemberErrors(policyID, member, errors) { + if (!allPolicies[policyID]) { + return; + } + + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, {[member]: {errors}}); +} + /** * @param {String} policyID * @param {String} customUnitID @@ -994,4 +1007,5 @@ export { openWorkspaceMembersPage, openWorkspaceInvitePage, removeWorkspace, + setWorkspaceMemberErrors, }; diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 432269998a9f..95f271da6fc1 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -107,6 +107,7 @@ class WorkspaceMembersPage extends React.Component { * Remove selected users from the workspace */ removeUsers() { + this.validate(); Policy.removeMembers(this.state.selectedEmployees, this.props.route.params.policyID); this.setState({ selectedEmployees: [], @@ -196,6 +197,15 @@ class WorkspaceMembersPage extends React.Component { } } + validate() { + _.each(this.state.selectedEmployees, (member) => { + if (member === this.props.policy.owner) { + const error = this.props.translate('workspace.people.error.cannotRemove'); + setWorkspaceMemberError(member, error); + } + }); + } + /** * Do not move this or make it an anonymous function it is a method * so it will not be recreated each time we render an item @@ -250,13 +260,6 @@ class WorkspaceMembersPage extends React.Component { ); } - validate() { - _.each(this.state.selectedEmployees, member => { - if (member) - }); - // this.props.policy.owner !== item.login && this.props.session.email !== item.login && item.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; - } - render() { const policyMemberList = lodashGet(this.props, 'policyMemberList', {}); let data = []; From a3a73371656038cc8b7d0180f4e9d0b7d0bfec2b Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 15:32:40 -0700 Subject: [PATCH 10/19] fix setWorkspaceMemberErrors --- src/libs/actions/Policy.js | 7 +++--- src/pages/workspace/WorkspaceMembersPage.js | 25 ++++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 17c5a234fdef..101c13e66073 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -428,15 +428,14 @@ function setWorkspaceErrors(policyID, errors) { /** * @param {String} policyID - * @param {String} member * @param {Object} errors */ -function setWorkspaceMemberErrors(policyID, member, errors) { - if (!allPolicies[policyID]) { +function setWorkspaceMemberErrors(policyID, errors) { + if (!allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]) { return; } - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, {[member]: {errors}}); + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, errors); } /** diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 95f271da6fc1..fa42077e3875 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -30,6 +30,7 @@ import {withNetwork} from '../../components/OnyxProvider'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import networkPropTypes from '../../components/networkPropTypes'; import * as Expensicons from '../../components/Icon/Expensicons'; +import DateUtils from '../../libs/DateUtils'; const propTypes = { /** The personal details of the person who is logged in */ @@ -108,11 +109,11 @@ class WorkspaceMembersPage extends React.Component { */ removeUsers() { this.validate(); - Policy.removeMembers(this.state.selectedEmployees, this.props.route.params.policyID); - this.setState({ - selectedEmployees: [], - isRemoveMembersConfirmModalVisible: false, - }); + // Policy.removeMembers(this.state.selectedEmployees, this.props.route.params.policyID); + // this.setState({ + // selectedEmployees: [], + // isRemoveMembersConfirmModalVisible: false, + // }); } /** @@ -198,12 +199,20 @@ class WorkspaceMembersPage extends React.Component { } validate() { + const onyxUpdate = {}; _.each(this.state.selectedEmployees, (member) => { - if (member === this.props.policy.owner) { - const error = this.props.translate('workspace.people.error.cannotRemove'); - setWorkspaceMemberError(member, error); + if (member !== this.props.policy.owner && member !== this.props.session.email) { + return; } + + onyxUpdate[member] = { + errors: { + [DateUtils.getMicroseconds()]: this.props.translate('workspace.people.error.cannotRemove') + }, + }; }); + + Policy.setWorkspaceMemberErrors(this.props.route.params.policyID, onyxUpdate); } /** From 2237a6bc8189e8f768d2eff477dabc7bbb341f36 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 15:35:06 -0700 Subject: [PATCH 11/19] rm setWorkspaceMemberErrors --- src/libs/actions/Policy.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 101c13e66073..5a2de0e7e1f6 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -426,18 +426,6 @@ function setWorkspaceErrors(policyID, errors) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errors}); } -/** - * @param {String} policyID - * @param {Object} errors - */ -function setWorkspaceMemberErrors(policyID, errors) { - if (!allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]) { - return; - } - - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, errors); -} - /** * @param {String} policyID * @param {String} customUnitID @@ -1006,5 +994,4 @@ export { openWorkspaceMembersPage, openWorkspaceInvitePage, removeWorkspace, - setWorkspaceMemberErrors, }; From 8cd37dbd1cc76a61abf61e3676b9e3838f240c2a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 15:58:16 -0700 Subject: [PATCH 12/19] revert changes to select all checkbox --- src/pages/workspace/WorkspaceMembersPage.js | 40 +++++++++++---------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index fa42077e3875..af2a2fd1ccfb 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -30,7 +30,6 @@ import {withNetwork} from '../../components/OnyxProvider'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import networkPropTypes from '../../components/networkPropTypes'; import * as Expensicons from '../../components/Icon/Expensicons'; -import DateUtils from '../../libs/DateUtils'; const propTypes = { /** The personal details of the person who is logged in */ @@ -108,12 +107,15 @@ class WorkspaceMembersPage extends React.Component { * Remove selected users from the workspace */ removeUsers() { - this.validate(); - // Policy.removeMembers(this.state.selectedEmployees, this.props.route.params.policyID); - // this.setState({ - // selectedEmployees: [], - // isRemoveMembersConfirmModalVisible: false, - // }); + // @TODO: return early if errors + + // Remove the admin from the list + const membersToRemove = _.without(this.state.selectedEmployees, this.props.session.email); + Policy.removeMembers(membersToRemove, this.props.route.params.policyID); + this.setState({ + selectedEmployees: [], + isRemoveMembersConfirmModalVisible: false, + }); } /** @@ -136,9 +138,10 @@ class WorkspaceMembersPage extends React.Component { toggleAllUsers() { let policyMemberList = lodashGet(this.props, 'policyMemberList', {}); policyMemberList = _.filter(_.keys(policyMemberList), policyMember => policyMemberList[policyMember].pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); + const removableMembers = _.without(policyMemberList, this.props.session.email, this.props.policy.owner); this.setState(prevState => ({ - selectedEmployees: policyMemberList.length !== prevState.selectedEmployees.length - ? policyMemberList + selectedEmployees: removableMembers.length !== prevState.selectedEmployees.length + ? removableMembers : [], })); } @@ -151,6 +154,7 @@ class WorkspaceMembersPage extends React.Component { * */ toggleUser(login, pendingAction) { + // @TODO: call validate here if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { return; } @@ -198,21 +202,16 @@ class WorkspaceMembersPage extends React.Component { } } + // @TODO: implement method validate() { - const onyxUpdate = {}; + const error = {}; _.each(this.state.selectedEmployees, (member) => { if (member !== this.props.policy.owner && member !== this.props.session.email) { return; } - onyxUpdate[member] = { - errors: { - [DateUtils.getMicroseconds()]: this.props.translate('workspace.people.error.cannotRemove') - }, - }; + return error; }); - - Policy.setWorkspaceMemberErrors(this.props.route.params.policyID, onyxUpdate); } /** @@ -233,6 +232,7 @@ class WorkspaceMembersPage extends React.Component { return ( this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> this.toggleUser(item.login, item.pendingAction)} activeOpacity={0.7} @@ -271,8 +271,12 @@ class WorkspaceMembersPage extends React.Component { render() { const policyMemberList = lodashGet(this.props, 'policyMemberList', {}); + const removableMembers = []; let data = []; _.each(policyMemberList, (policyMember, email) => { + if (email !== this.props.session.email && email !== this.props.policy.owner && policyMember.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { + removableMembers.push(email); + } const details = lodashGet(this.props.personalDetails, email, {displayName: email, login: email, avatar: Expensicons.FallbackAvatar}); data.push({ ...policyMember, @@ -332,7 +336,7 @@ class WorkspaceMembersPage extends React.Component { this.toggleAllUsers()} /> From 52dd36fdf58543958d775cc7d2340da044ff22e0 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 16:00:07 -0700 Subject: [PATCH 13/19] early return if errors are not empty --- src/pages/workspace/WorkspaceMembersPage.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index af2a2fd1ccfb..1a75ebbbec21 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -59,6 +59,7 @@ class WorkspaceMembersPage extends React.Component { this.state = { selectedEmployees: [], isRemoveMembersConfirmModalVisible: false, + errors: {}, }; this.renderItem = this.renderItem.bind(this); @@ -107,7 +108,9 @@ class WorkspaceMembersPage extends React.Component { * Remove selected users from the workspace */ removeUsers() { - // @TODO: return early if errors + if (!_.isEmpty(this.state.errors)) { + return; + } // Remove the admin from the list const membersToRemove = _.without(this.state.selectedEmployees, this.props.session.email); @@ -232,8 +235,7 @@ class WorkspaceMembersPage extends React.Component { return ( this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> this.toggleUser(item.login, item.pendingAction)} activeOpacity={0.7} > From 6d0ef22f4b1fb9726d2c11e65d45d5680913bca6 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 16:07:02 -0700 Subject: [PATCH 14/19] add early return for delete modal --- src/pages/workspace/WorkspaceMembersPage.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 1a75ebbbec21..626b861deb8e 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -125,6 +125,10 @@ class WorkspaceMembersPage extends React.Component { * Show the modal to confirm removal of the selected members */ askForConfirmationToRemove() { + if (!_.isEmpty(this.state.errors)) { + return; + } + this.setState({isRemoveMembersConfirmModalVisible: true}); } @@ -157,7 +161,6 @@ class WorkspaceMembersPage extends React.Component { * */ toggleUser(login, pendingAction) { - // @TODO: call validate here if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { return; } @@ -168,6 +171,8 @@ class WorkspaceMembersPage extends React.Component { } else { this.addUser(login); } + + this.validate(); } /** @@ -205,16 +210,17 @@ class WorkspaceMembersPage extends React.Component { } } - // @TODO: implement method validate() { - const error = {}; + const errors = {}; _.each(this.state.selectedEmployees, (member) => { if (member !== this.props.policy.owner && member !== this.props.session.email) { return; } - return error; + errors[member] = this.props.translate('workspace.people.error.cannotRemove'); }); + + this.setState({errors}); } /** @@ -233,6 +239,7 @@ class WorkspaceMembersPage extends React.Component { item, }) { return ( + // @TODO: display error this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> Date: Tue, 17 Jan 2023 16:21:52 -0700 Subject: [PATCH 15/19] display error message --- src/pages/workspace/WorkspaceMembersPage.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 626b861deb8e..65fdb9429685 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -30,6 +30,7 @@ import {withNetwork} from '../../components/OnyxProvider'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import networkPropTypes from '../../components/networkPropTypes'; import * as Expensicons from '../../components/Icon/Expensicons'; +import FormHelpMessage from '../../components/FormHelpMessage'; const propTypes = { /** The personal details of the person who is logged in */ @@ -171,8 +172,6 @@ class WorkspaceMembersPage extends React.Component { } else { this.addUser(login); } - - this.validate(); } /** @@ -183,7 +182,7 @@ class WorkspaceMembersPage extends React.Component { addUser(login) { this.setState(prevState => ({ selectedEmployees: [...prevState.selectedEmployees, login], - })); + }), () => this.validate()); } /** @@ -194,7 +193,7 @@ class WorkspaceMembersPage extends React.Component { removeUser(login) { this.setState(prevState => ({ selectedEmployees: _.without(prevState.selectedEmployees, login), - })); + }), () => this.validate()); } /** @@ -239,7 +238,6 @@ class WorkspaceMembersPage extends React.Component { item, }) { return ( - // @TODO: display error this.dismissError(item)} pendingAction={item.pendingAction} errors={item.errors}> )} + {!_.isEmpty(this.state.errors[item.login]) && ( + + )} ); } From b85e275de98b0e56dc4ba6001093230247f52d13 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 16:28:16 -0700 Subject: [PATCH 16/19] keep select all checked if admin is selected --- src/pages/workspace/WorkspaceMembersPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 65fdb9429685..41a3f206c8f4 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -346,7 +346,7 @@ class WorkspaceMembersPage extends React.Component { = removableMembers.length && removableMembers.length !== 0} onPress={() => this.toggleAllUsers()} /> From 6ec1826da556bec4d02b5e61131cad8fd8205e9a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 16:38:05 -0700 Subject: [PATCH 17/19] fix logic for select all --- src/pages/workspace/WorkspaceMembersPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 41a3f206c8f4..159e757012f4 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -346,7 +346,7 @@ class WorkspaceMembersPage extends React.Component { = removableMembers.length && removableMembers.length !== 0} + isChecked={removableMembers.length !== 0 && _.every(removableMembers, member => _.contains(this.state.selectedEmployees, member))} onPress={() => this.toggleAllUsers()} /> From e9f4cd3f3232db549f0934d3d751a6fcc30778df Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 16:54:01 -0700 Subject: [PATCH 18/19] fix toggleAllusers logic --- src/pages/workspace/WorkspaceMembersPage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 159e757012f4..83e395674c3f 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -148,10 +148,10 @@ class WorkspaceMembersPage extends React.Component { policyMemberList = _.filter(_.keys(policyMemberList), policyMember => policyMemberList[policyMember].pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); const removableMembers = _.without(policyMemberList, this.props.session.email, this.props.policy.owner); this.setState(prevState => ({ - selectedEmployees: removableMembers.length !== prevState.selectedEmployees.length + selectedEmployees: !_.every(removableMembers, member => _.contains(prevState.selectedEmployees, member)) ? removableMembers : [], - })); + }), () => this.validate()); } /** From b545c9386e5f9c320f1027789cdbedb72732ef74 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Jan 2023 17:00:26 -0700 Subject: [PATCH 19/19] validate if preferred locale changes --- src/pages/workspace/WorkspaceMembersPage.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index 83e395674c3f..ade400cb2862 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -76,6 +76,10 @@ class WorkspaceMembersPage extends React.Component { } componentDidUpdate(prevProps) { + if (prevProps.preferredLocale !== this.props.preferredLocale) { + this.validate(); + } + const isReconnecting = prevProps.network.isOffline && !this.props.network.isOffline; if (!isReconnecting) { return;