From 66b3bd37ebcd39b61389733291a2b7536a508c92 Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Tue, 14 Sep 2021 01:44:18 +0530 Subject: [PATCH 1/5] fix: workspace edit page --- src/libs/actions/Policy.js | 29 +++++++++++----------- src/pages/workspace/WorkspaceEditorPage.js | 6 +++-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 61463368d2b2..754854ac621a 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -247,6 +247,15 @@ function uploadAvatar(file) { }); } +/** + * Sets local values for the policy + * @param {String} policyID + * @param {Object} values + */ +function updateLocalPolicyValues(policyID, values) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, values); +} + /** * Sets the name of the policy * @@ -257,30 +266,20 @@ function update(policyID, values) { API.UpdatePolicy({policyID, value: JSON.stringify(values), lastModified: null}) .then((policyResponse) => { if (policyResponse.jsonCode !== 200) { - // Show the user feedback - const errorMessage = translateLocal('workspace.editor.genericFailureMessage'); - Growl.error(errorMessage, 5000); - return; + throw new Error(); } - const updatedValues = {...values, ...{isPolicyUpdating: false}}; - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, updatedValues); + updateLocalPolicyValues(policyID, {...values, isPolicyUpdating: false}); Navigation.dismissModal(); }).catch(() => { + updateLocalPolicyValues(policyID, {isPolicyUpdating: false}); + + // Show the user feedback const errorMessage = translateLocal('workspace.editor.genericFailureMessage'); Growl.error(errorMessage, 5000); }); } -/** - * Sets local values for the policy - * @param {String} policyID - * @param {Object} values - */ -function updateLocalPolicyValues(policyID, values) { - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, values); -} - export { getPolicySummaries, getPolicyList, diff --git a/src/pages/workspace/WorkspaceEditorPage.js b/src/pages/workspace/WorkspaceEditorPage.js index bc4a6091de71..5258f063967d 100644 --- a/src/pages/workspace/WorkspaceEditorPage.js +++ b/src/pages/workspace/WorkspaceEditorPage.js @@ -95,8 +95,10 @@ class WorkspaceEditorPage extends React.Component { } const isButtonDisabled = policy.isAvatarUploading - || (this.state.avatarURL === this.props.policy.avatarURL - && this.state.name === this.props.policy.name); + || (this.state.avatarURL === this.props.policy.avatarURL + && this.state.name === this.props.policy.name) + || _.isEmpty(this.state.name.trim()); + return ( Date: Wed, 15 Sep 2021 05:45:25 +0530 Subject: [PATCH 2/5] refactor Edit Workspace --- src/pages/workspace/WorkspaceEditorPage.js | 27 ++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/WorkspaceEditorPage.js b/src/pages/workspace/WorkspaceEditorPage.js index 5258f063967d..6799f77cb6a0 100644 --- a/src/pages/workspace/WorkspaceEditorPage.js +++ b/src/pages/workspace/WorkspaceEditorPage.js @@ -11,7 +11,7 @@ import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize import Navigation from '../../libs/Navigation/Navigation'; import Permissions from '../../libs/Permissions'; import styles from '../../styles/styles'; -import TextInputWithLabel from '../../components/TextInputWithLabel'; +import ExpensiTextInput from '../../components/ExpensiTextInput'; import Button from '../../components/Button'; import Text from '../../components/Text'; import compose from '../../libs/compose'; @@ -41,6 +41,7 @@ class WorkspaceEditorPage extends React.Component { this.state = { name: props.policy.name, + nameError: '', avatarURL: props.policy.avatarURL, previewAvatarURL: props.policy.avatarURL, }; @@ -68,6 +69,15 @@ class WorkspaceEditorPage extends React.Component { } submit() { + if (this.props.policy.isAvatarUploading) { + return; + } + if (_.isEmpty(this.state.name.trim())) { + this.setState({ + nameError: `${this.props.translate('workspace.editor.nameInputLabel')} ${this.props.translate('common.isRequiredField')}`, + }); + return; + } updateLocalPolicyValues(this.props.policy.id, {isPolicyUpdating: true}); // Wait for the upload avatar promise to finish before updating the policy @@ -94,10 +104,7 @@ class WorkspaceEditorPage extends React.Component { return null; } - const isButtonDisabled = policy.isAvatarUploading - || (this.state.avatarURL === this.props.policy.avatarURL - && this.state.name === this.props.policy.name) - || _.isEmpty(this.state.name.trim()); + const isButtonDisabled = this.state.avatarURL === this.props.policy.avatarURL && this.state.name === this.props.policy.name; return ( @@ -120,18 +127,24 @@ class WorkspaceEditorPage extends React.Component { fill={defaultTheme.iconSuccessFill} /> )} - style={[styles.mb3]} + style={[styles.mb5]} anchorPosition={{top: 172, right: 18}} isUsingDefaultAvatar={!this.state.previewAvatarURL} onImageSelected={this.onImageSelected} onImageRemoved={this.onImageRemoved} /> - this.setState({name})} onSubmitEditting={this.submit} + errorText={this.state.nameError} + onBlur={() => { + if (!_.isEmpty(this.state.name.trim())) { + this.setState({nameError: ''}); + } + }} /> {this.props.translate('workspace.editor.nameInputHelpText')} From 1547ae33a49eef09c0a76b4e47abe344970f6f7a Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Tue, 19 Oct 2021 00:54:02 +0530 Subject: [PATCH 3/5] fix: reset to the default image when Upload image failed --- src/libs/actions/Policy.js | 6 ++---- src/pages/workspace/WorkspaceSettingsPage.js | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 76398b389f28..6d2eb256c5ba 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -286,10 +286,8 @@ function uploadAvatar(file) { return API.User_UploadAvatar({file}) .then((response) => { if (response.jsonCode !== 200) { - // Show the user feedback - const errorMessage = translateLocal('workspace.editor.avatarUploadFailureMessage'); - Growl.error(errorMessage, 5000); - return; + // Let the component handle the issue. + throw new Error(); } return response.s3url; diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 2067bbfca135..cef0533a49a7 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -100,6 +100,7 @@ class WorkspaceSettingsPage extends React.Component { this.uploadAvatarPromise = Policy.uploadAvatar(image).then(url => new Promise((resolve) => { this.setState({avatarURL: url}, resolve); })).catch(() => { + this.setState({previewAvatarURL: ''}); Growl.error(this.props.translate('workspace.editor.avatarUploadFailureMessage')); }).finally(() => Policy.updateLocalPolicyValues(this.props.policy.id, {isAvatarUploading: false})); } From 43be7d8756f884a09dc766e5fcdb6007116db34b Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Tue, 19 Oct 2021 02:21:11 +0530 Subject: [PATCH 4/5] fix: block form submission when name is null --- src/pages/workspace/WorkspaceSettingsPage.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index cef0533a49a7..092f15f31d05 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -66,6 +66,7 @@ class WorkspaceSettingsPage extends React.Component { this.uploadAvatar = this.uploadAvatar.bind(this); this.removeAvatar = this.removeAvatar.bind(this); this.getCurrencyItems = this.getCurrencyItems.bind(this); + this.validate = this.validate.bind(this); this.uploadAvatarPromise = Promise.resolve(); } @@ -106,7 +107,7 @@ class WorkspaceSettingsPage extends React.Component { } submit() { - if (this.props.policy.isAvatarUploading) { + if (this.props.policy.isAvatarUploading || !this.validate()) { return; } const name = this.state.name.trim(); @@ -121,6 +122,14 @@ class WorkspaceSettingsPage extends React.Component { Growl.success(this.props.translate('workspace.common.growlMessageOnSave')); } + validate() { + const errors = {}; + if (!this.state.name.trim().length) { + errors.nameError = true; + } + return _.size(errors) === 0; + } + render() { const {policy} = this.props; From a7aa14fec91351fb8d82f74930b8297a8aa153cf Mon Sep 17 00:00:00 2001 From: Rajat Parashar Date: Wed, 20 Oct 2021 22:28:29 +0530 Subject: [PATCH 5/5] fix: stuck Image Upload --- src/pages/workspace/WorkspaceSettingsPage.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index e506ea177486..a67e9e478783 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -75,6 +75,10 @@ class WorkspaceSettingsPage extends React.Component { getCurrencyList(); } + componentWillUnmount() { + Policy.updateLocalPolicyValues(this.props.policy.id, {isAvatarUploading: false}); + } + /** * @returns {Object[]} */