Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component refactor: migrate WorkspaceNewRoomPage to function component #22015

Merged
merged 7 commits into from
Jul 3, 2023
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 106 additions & 110 deletions src/pages/workspace/WorkspaceNewRoomPage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, {useState, useCallback} from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import {withOnyx} from 'react-native-onyx';
Expand Down Expand Up @@ -65,136 +65,132 @@ const defaultProps = {
allPolicyMembers: {},
};

alexxxwork marked this conversation as resolved.
Show resolved Hide resolved
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 [visibilityDescription, setVisibilityDescription] = useState(props.translate('newRoomPage.restrictedDescription'));

/**
* @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});
}
const updateVisibilityDescription = useCallback(
(visibility) => {
const newVisibilityDescription = props.translate(`newRoomPage.${visibility}Description`);
if (newVisibilityDescription === visibilityDescription) {
return;
}
setVisibilityDescription({newVisibilityDescription});
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[visibilityDescription],
);
alexxxwork marked this conversation as resolved.
Show resolved Hide resolved

/**
* @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';
}

return errors;
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],
);

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this block can be moved to the top

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it can't because of useCallback and useMemo - they shouldn't be called conditionally

Copy link
Contributor

@fedirjh fedirjh Jul 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha that make sense. Let's keep it as it is.

alexxxwork marked this conversation as resolved.
Show resolved Hide resolved
}

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}
// Workspaces are policies with type === 'free'
const workspaceOptions = _.map(
_.filter(props.policies, (policy) => policy && policy.type === CONST.POLICY.TYPE.FREE),
(policy) => ({label: policy.name, key: policy.id, value: policy.id}),
);
alexxxwork marked this conversation as resolved.
Show resolved Hide resolved

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

return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
shouldEnablePickerAvoiding={false}
>
<HeaderWithBackButton title={props.translate('newRoomPage.newRoom')} />
<Form
formID={ONYXKEYS.FORMS.NEW_ROOM_FORM}
submitButtonText={props.translate('newRoomPage.createRoom')}
scrollContextEnabled
style={[styles.mh5, styles.mt5, styles.flexGrow1]}
alexxxwork marked this conversation as resolved.
Show resolved Hide resolved
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={props.translate('workspace.common.workspace')}
placeholder={{value: '', label: props.translate('newRoomPage.selectAWorkspace')}}
items={workspaceOptions}
/>
</View>
<View style={styles.mb2}>
<Picker
inputID="visibility"
label={props.translate('newRoomPage.visibility')}
items={visibilityOptions}
onValueChange={updateVisibilityDescription}
defaultValue={CONST.REPORT.VISIBILITY.RESTRICTED}
/>
</View>
<Text style={[styles.textLabel, styles.colorMuted]}>{visibilityDescription}</Text>
</Form>
</ScreenWrapper>
);
}

WorkspaceNewRoomPage.propTypes = propTypes;
WorkspaceNewRoomPage.defaultProps = defaultProps;
WorkspaceNewRoomPage.displayName = 'WorkspaceNewRoomPage';

export default compose(
withOnyx({
Expand Down