Skip to content

Commit

Permalink
Merge pull request #22015 from alexxxwork/issue-16307
Browse files Browse the repository at this point in the history
Component refactor: migrate WorkspaceNewRoomPage to function component
  • Loading branch information
yuwenmemon authored Jul 3, 2023
2 parents f8306e3 + a1848cb commit ddbd4bb
Showing 1 changed file with 125 additions and 134 deletions.
259 changes: 125 additions & 134 deletions src/pages/workspace/WorkspaceNewRoomPage.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react';
import React, {useState, useCallback, useMemo, useEffect} from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import * as Report from '../../libs/actions/Report';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import compose from '../../libs/compose';
import useLocalize from '../../hooks/useLocalize';
import HeaderWithBackButton from '../../components/HeaderWithBackButton';
import Navigation from '../../libs/Navigation/Navigation';
import ScreenWrapper from '../../components/ScreenWrapper';
Expand Down Expand Up @@ -55,8 +54,6 @@ const propTypes = {

/** A collection of objects for all policies which key policy member objects by accountIDs */
allPolicyMembers: PropTypes.objectOf(PropTypes.objectOf(policyMemberPropType)),

...withLocalizePropTypes,
};
const defaultProps = {
betas: [],
Expand All @@ -65,151 +62,145 @@ const defaultProps = {
allPolicyMembers: {},
};

class WorkspaceNewRoomPage extends React.Component {
constructor(props) {
super(props);

this.state = {
visibilityDescription: this.props.translate('newRoomPage.restrictedDescription'),
};

this.validate = this.validate.bind(this);
this.submit = this.submit.bind(this);
this.updateVisibilityDescription = this.updateVisibilityDescription.bind(this);
}
function WorkspaceNewRoomPage(props) {
const {translate} = useLocalize();
const [visibility, setVisibility] = useState(CONST.REPORT.VISIBILITY.RESTRICTED);
const visibilityDescription = useMemo(() => translate(`newRoomPage.${visibility}Description`), [translate, visibility]);

/**
* @param {Object} values - form input values passed by the Form component
*/
submit(values) {
const policyMembers = _.map(_.keys(this.props.allPolicyMembers[`${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${values.policyID}`]), (accountID) => Number(accountID));
const submit = (values) => {
const policyMembers = _.map(_.keys(props.allPolicyMembers[`${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${values.policyID}`]), (accountID) => Number(accountID));
Report.addPolicyReport(values.policyID, values.roomName, values.visibility, policyMembers);
}

/**
* @param {String} visibility - form input value passed by the Form component
*/
updateVisibilityDescription(visibility) {
const visibilityDescription = this.props.translate(`newRoomPage.${visibility}Description`);
if (visibilityDescription === this.state.visibilityDescription) {
return;
}
this.setState({visibilityDescription});
}
};

/**
* @param {Object} values - form input values passed by the Form component
* @returns {Boolean}
*/
validate(values) {
const errors = {};

if (!values.roomName || values.roomName === CONST.POLICY.ROOM_PREFIX) {
// We error if the user doesn't enter a room name or left blank
ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.pleaseEnterRoomName');
} else if (values.roomName !== CONST.POLICY.ROOM_PREFIX && !ValidationUtils.isValidRoomName(values.roomName)) {
// We error if the room name has invalid characters
ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomNameInvalidError');
} else if (ValidationUtils.isReservedRoomName(values.roomName)) {
// Certain names are reserved for default rooms and should not be used for policy rooms.
ErrorUtils.addErrorMessage(errors, 'roomName', ['newRoomPage.roomNameReservedError', {reservedName: values.roomName}]);
} else if (ValidationUtils.isExistingRoomName(values.roomName, this.props.reports, values.policyID)) {
// Certain names are reserved for default rooms and should not be used for policy rooms.
ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomAlreadyExistsError');
}

if (!values.policyID) {
errors.policyID = 'newRoomPage.pleaseSelectWorkspace';
const validate = useCallback(
(values) => {
const errors = {};

if (!values.roomName || values.roomName === CONST.POLICY.ROOM_PREFIX) {
// We error if the user doesn't enter a room name or left blank
ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.pleaseEnterRoomName');
} else if (values.roomName !== CONST.POLICY.ROOM_PREFIX && !ValidationUtils.isValidRoomName(values.roomName)) {
// We error if the room name has invalid characters
ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomNameInvalidError');
} else if (ValidationUtils.isReservedRoomName(values.roomName)) {
// Certain names are reserved for default rooms and should not be used for policy rooms.
ErrorUtils.addErrorMessage(errors, 'roomName', ['newRoomPage.roomNameReservedError', {reservedName: values.roomName}]);
} else if (ValidationUtils.isExistingRoomName(values.roomName, props.reports, values.policyID)) {
// Certain names are reserved for default rooms and should not be used for policy rooms.
ErrorUtils.addErrorMessage(errors, 'roomName', 'newRoomPage.roomAlreadyExistsError');
}

if (!values.policyID) {
errors.policyID = 'newRoomPage.pleaseSelectWorkspace';
}

return errors;
},
[props.reports],
);

// Workspaces are policies with type === 'free'
const workspaceOptions = useMemo(
() =>
_.map(
_.filter(props.policies, (policy) => policy && policy.type === CONST.POLICY.TYPE.FREE),
(policy) => ({label: policy.name, key: policy.id, value: policy.id}),
),
[props.policies],
);

const visibilityOptions = useMemo(
() =>
_.map(
_.filter(_.values(CONST.REPORT.VISIBILITY), (visibilityOption) => visibilityOption !== CONST.REPORT.VISIBILITY.PUBLIC_ANNOUNCE),
(visibilityOption) => ({
label: translate(`newRoomPage.visibilityOptions.${visibilityOption}`),
value: visibilityOption,
description: translate(`newRoomPage.${visibilityOption}Description`),
}),
),
[translate],
);

useEffect(() => {
if (Permissions.canUsePolicyRooms(props.betas)) {
return;
}
Log.info('Not showing create Policy Room page since user is not on policy rooms beta');
Navigation.dismissModal();
}, [props.betas]);

return errors;
if (!Permissions.canUsePolicyRooms(props.betas)) {
return null;
}

render() {
if (!Permissions.canUsePolicyRooms(this.props.betas)) {
Log.info('Not showing create Policy Room page since user is not on policy rooms beta');
Navigation.dismissModal();
return null;
}

// Workspaces are policies with type === 'free'
const workspaceOptions = _.map(
_.filter(this.props.policies, (policy) => policy && policy.type === CONST.POLICY.TYPE.FREE),
(policy) => ({label: policy.name, key: policy.id, value: policy.id}),
);

const visibilityOptions = _.map(
_.filter(_.values(CONST.REPORT.VISIBILITY), (visibilityOption) => visibilityOption !== CONST.REPORT.VISIBILITY.PUBLIC_ANNOUNCE),
(visibilityOption) => ({
label: this.props.translate(`newRoomPage.visibilityOptions.${visibilityOption}`),
value: visibilityOption,
description: this.props.translate(`newRoomPage.${visibilityOption}Description`),
}),
);

return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
shouldEnablePickerAvoiding={false}
return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
shouldEnablePickerAvoiding={false}
>
<HeaderWithBackButton title={translate('newRoomPage.newRoom')} />
<Form
formID={ONYXKEYS.FORMS.NEW_ROOM_FORM}
submitButtonText={translate('newRoomPage.createRoom')}
scrollContextEnabled
style={[styles.mh5, styles.flexGrow1]}
validate={validate}
onSubmit={submit}
enabledWhenOffline
>
<HeaderWithBackButton title={this.props.translate('newRoomPage.newRoom')} />
<Form
formID={ONYXKEYS.FORMS.NEW_ROOM_FORM}
submitButtonText={this.props.translate('newRoomPage.createRoom')}
scrollContextEnabled
style={[styles.mh5, styles.mt5, styles.flexGrow1]}
validate={this.validate}
onSubmit={this.submit}
enabledWhenOffline
>
<View style={styles.mb5}>
<RoomNameInput
inputID="roomName"
autoFocus
shouldDelayFocus={shouldDelayFocus}
/>
</View>
<View style={styles.mb5}>
<Picker
inputID="policyID"
label={this.props.translate('workspace.common.workspace')}
placeholder={{value: '', label: this.props.translate('newRoomPage.selectAWorkspace')}}
items={workspaceOptions}
/>
</View>
<View style={styles.mb2}>
<Picker
inputID="visibility"
label={this.props.translate('newRoomPage.visibility')}
items={visibilityOptions}
onValueChange={this.updateVisibilityDescription}
defaultValue={CONST.REPORT.VISIBILITY.RESTRICTED}
/>
</View>
<Text style={[styles.textLabel, styles.colorMuted]}>{this.state.visibilityDescription}</Text>
</Form>
</ScreenWrapper>
);
}
<View style={styles.mb5}>
<RoomNameInput
inputID="roomName"
autoFocus
shouldDelayFocus={shouldDelayFocus}
/>
</View>
<View style={styles.mb5}>
<Picker
inputID="policyID"
label={translate('workspace.common.workspace')}
placeholder={{value: '', label: translate('newRoomPage.selectAWorkspace')}}
items={workspaceOptions}
/>
</View>
<View style={styles.mb2}>
<Picker
inputID="visibility"
label={translate('newRoomPage.visibility')}
items={visibilityOptions}
onValueChange={setVisibility}
defaultValue={CONST.REPORT.VISIBILITY.RESTRICTED}
/>
</View>
<Text style={[styles.textLabel, styles.colorMuted]}>{visibilityDescription}</Text>
</Form>
</ScreenWrapper>
);
}

WorkspaceNewRoomPage.propTypes = propTypes;
WorkspaceNewRoomPage.defaultProps = defaultProps;

export default compose(
withOnyx({
betas: {
key: ONYXKEYS.BETAS,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
reports: {
key: ONYXKEYS.COLLECTION.REPORT,
},
allPolicyMembers: {
key: ONYXKEYS.COLLECTION.POLICY_MEMBERS,
},
}),
withLocalize,
)(WorkspaceNewRoomPage);
WorkspaceNewRoomPage.displayName = 'WorkspaceNewRoomPage';

export default withOnyx({
betas: {
key: ONYXKEYS.BETAS,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
reports: {
key: ONYXKEYS.COLLECTION.REPORT,
},
allPolicyMembers: {
key: ONYXKEYS.COLLECTION.POLICY_MEMBERS,
},
})(WorkspaceNewRoomPage);

0 comments on commit ddbd4bb

Please sign in to comment.