diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js
index bc570df3c591..ade400cb2862 100644
--- a/src/pages/workspace/WorkspaceMembersPage.js
+++ b/src/pages/workspace/WorkspaceMembersPage.js
@@ -23,8 +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 Hoverable from '../../components/Hoverable';
import withPolicy, {policyPropTypes, policyDefaultProps} from './withPolicy';
import CONST from '../../CONST';
import OfflineWithFeedback from '../../components/OfflineWithFeedback';
@@ -32,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 */
@@ -61,7 +60,7 @@ class WorkspaceMembersPage extends React.Component {
this.state = {
selectedEmployees: [],
isRemoveMembersConfirmModalVisible: false,
- showTooltipForLogin: '',
+ errors: {},
};
this.renderItem = this.renderItem.bind(this);
@@ -77,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;
@@ -110,6 +113,10 @@ class WorkspaceMembersPage extends React.Component {
* Remove selected users from the workspace
*/
removeUsers() {
+ if (!_.isEmpty(this.state.errors)) {
+ return;
+ }
+
// Remove the admin from the list
const membersToRemove = _.without(this.state.selectedEmployees, this.props.session.email);
Policy.removeMembers(membersToRemove, this.props.route.params.policyID);
@@ -123,6 +130,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});
}
@@ -137,15 +148,14 @@ 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);
this.setState(prevState => ({
- selectedEmployees: removableMembers.length !== prevState.selectedEmployees.length
+ selectedEmployees: !_.every(removableMembers, member => _.contains(prevState.selectedEmployees, member))
? removableMembers
: [],
- }));
+ }), () => this.validate());
}
/**
@@ -156,49 +166,16 @@ 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;
}
- // 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 {
this.addUser(login);
}
-
- 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;
}
/**
@@ -209,7 +186,7 @@ class WorkspaceMembersPage extends React.Component {
addUser(login) {
this.setState(prevState => ({
selectedEmployees: [...prevState.selectedEmployees, login],
- }));
+ }), () => this.validate());
}
/**
@@ -220,7 +197,7 @@ class WorkspaceMembersPage extends React.Component {
removeUser(login) {
this.setState(prevState => ({
selectedEmployees: _.without(prevState.selectedEmployees, login),
- }));
+ }), () => this.validate());
}
/**
@@ -229,7 +206,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 {
@@ -237,6 +213,19 @@ class WorkspaceMembersPage extends React.Component {
}
}
+ validate() {
+ const errors = {};
+ _.each(this.state.selectedEmployees, (member) => {
+ if (member !== this.props.policy.owner && member !== this.props.session.email) {
+ return;
+ }
+
+ errors[member] = this.props.translate('workspace.people.error.cannotRemove');
+ });
+
+ this.setState({errors});
+ }
+
/**
* 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
@@ -252,48 +241,44 @@ 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;
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')}
+ />
+
+ 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
- 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 || item.role === 'admin') && (
-
-
-
- {this.props.translate('common.admin')}
-
-
+
+ {(this.props.session.email === item.login || item.role === 'admin') && (
+
+
+
+ {this.props.translate('common.admin')}
+
- )}
-
-
+
+ )}
+
+ {!_.isEmpty(this.state.errors[item.login]) && (
+
+ )}
);
}
@@ -365,7 +350,7 @@ class WorkspaceMembersPage extends React.Component {
_.contains(this.state.selectedEmployees, member))}
onPress={() => this.toggleAllUsers()}
/>