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

Use new UpdatePolicyRoomName api command #10237

Merged
merged 36 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
162ef4e
Create updatePolicyRoomName for api refactor
neil-marcellini Aug 3, 2022
0e38b5a
Use reportName param for WAF
neil-marcellini Aug 8, 2022
303a0a3
Use new updatePolicyRoomName command
neil-marcellini Aug 8, 2022
f265e7e
Add offline feedback / errors for policy room name
neil-marcellini Aug 9, 2022
124f8f5
Merge branch 'main' into neil-UpdatePolicyRoomName
neil-marcellini Aug 9, 2022
15fbbf8
Use rbr pending action update constant
neil-marcellini Aug 9, 2022
e657bd8
Fix JSDoc param type
neil-marcellini Aug 9, 2022
2fd2a55
Pass policyRoomName to UpdatePolicyRoomName
neil-marcellini Aug 9, 2022
7bdd021
Merge branch 'main' into neil-UpdatePolicyRoomName
neil-marcellini Aug 11, 2022
1847e5a
Check report errors and errorFields also
neil-marcellini Aug 11, 2022
f4a7b45
Add brick road indicator to header view
neil-marcellini Aug 11, 2022
f952838
Create hasReportNameError
neil-marcellini Aug 11, 2022
a77f503
Use hasReportNameError in HeaderView
neil-marcellini Aug 11, 2022
b7ad9f8
Fix hasReportNameError
neil-marcellini Aug 11, 2022
5070cbd
Allow empty string brickRoadIndicator
neil-marcellini Aug 11, 2022
20fdbdb
Brick road indicator on report details settings
neil-marcellini Aug 11, 2022
b388315
Use empty string for empty brickRoadIndicator
neil-marcellini Aug 11, 2022
292c524
Allow the error message to use the full row
neil-marcellini Aug 11, 2022
b493390
Name the onClose callback for what it does
neil-marcellini Aug 11, 2022
837f5db
Remove redundant comments
neil-marcellini Aug 11, 2022
45fa867
Remove deprecated rename report
neil-marcellini Aug 11, 2022
2a0683e
Remove policy room renamed growl
neil-marcellini Aug 11, 2022
3693e27
Rename to match api command name
neil-marcellini Aug 11, 2022
1bfae69
Merge branch 'main' into neil-UpdatePolicyRoomName
neil-marcellini Aug 11, 2022
acb83ab
Simplify brickRoadIndicator comment
neil-marcellini Aug 12, 2022
d33ef6a
Rename error vars that are specific to the report
neil-marcellini Aug 12, 2022
e4cbb45
Add a key to menu items for brick road indicator
neil-marcellini Aug 12, 2022
2eea06a
Remove unused props
neil-marcellini Aug 12, 2022
2a3c71f
Make default brickRoadIndicator match prop type
neil-marcellini Aug 12, 2022
924afb9
Clear reportName errors optimistically
neil-marcellini Aug 12, 2022
e0497af
Set roomNameInputRef inline for simplicity
neil-marcellini Aug 12, 2022
04cd7b4
Fix resetting the room name input on native
neil-marcellini Aug 12, 2022
06dd5d8
Use minimum vertical space for RBR error text
neil-marcellini Aug 12, 2022
eddd6ce
Add accessed report fields to JSDoc
neil-marcellini Aug 15, 2022
106ad15
Use constants for report details menu items
neil-marcellini Aug 15, 2022
4c150ff
Use constant
neil-marcellini Aug 15, 2022
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
6 changes: 6 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,12 @@ const CONST = {
BRICK_ROAD_INDICATOR_STATUS: {
ERROR: 'error',
},
REPORT_DETAILS_MENU_ITEM: {
MEMBERS: 'member',
SETTINGS: 'settings',
INVITE: 'invite',
LEAVE_ROOM: 'leaveRoom',
},
};

export default CONST;
3 changes: 0 additions & 3 deletions src/ONYXKEYS.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ export default {
// Are we loading the create policy room command
IS_LOADING_CREATE_POLICY_ROOM: 'isLoadingCratePolicyRoom',

// Are we loading the rename policy room command
IS_LOADING_RENAME_POLICY_ROOM: 'isLoadingRenamePolicyRoom',

// Is Keyboard shortcuts modal open?
IS_SHORTCUTS_MODAL_OPEN: 'isShortcutsModalOpen',

Expand Down
6 changes: 3 additions & 3 deletions src/components/MenuItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const defaultProps = {
onPress: () => {},
interactive: true,
fallbackIcon: Expensicons.FallbackAvatar,
brickRoadIndicator: undefined,
brickRoadIndicator: '',
};

const MenuItem = props => (
Expand Down Expand Up @@ -132,11 +132,11 @@ const MenuItem = props => (
</Text>
</View>
)}
{props.brickRoadIndicator && (
{Boolean(props.brickRoadIndicator) && (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Treat this as a boolean in case it's an empty string.

<View style={[styles.alignItemsCenter, styles.justifyContentCenter]}>
<Icon
src={Expensicons.DotIndicator}
fill={props.brickRoadIndicator === 'error' ? colors.red : colors.green}
fill={props.brickRoadIndicator === CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR ? colors.red : colors.green}
height={variables.iconSizeSmall}
width={variables.iconSizeSmall}
/>
Expand Down
10 changes: 9 additions & 1 deletion src/components/RoomNameInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ const propTypes = {
/** ID of the policy */
id: PropTypes.string,
}).isRequired,

/** A ref forwarded to the TextInput */
forwardedRef: PropTypes.func,
};

const defaultProps = {
Expand All @@ -51,6 +54,7 @@ const defaultProps = {
disabled: false,
errorText: '',
...fullPolicyDefaultProps,
forwardedRef: () => {},
};

class RoomNameInput extends Component {
Expand Down Expand Up @@ -91,6 +95,7 @@ class RoomNameInput extends Component {
render() {
return (
<TextInput
ref={this.props.forwardedRef}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a ref so the input value can be cleared from the parent.

disabled={this.props.disabled}
label={this.props.translate('newRoomPage.roomName')}
prefixCharacter={CONST.POLICY.ROOM_PREFIX}
Expand Down Expand Up @@ -118,4 +123,7 @@ export default compose(
key: ONYXKEYS.COLLECTION.POLICY,
},
}),
)(RoomNameInput);
)(React.forwardRef((props, ref) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<RoomNameInput {...props} forwardedRef={ref} />
)));
5 changes: 2 additions & 3 deletions src/components/menuItemPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,8 @@ const propTypes = {
/** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */
fallbackIcon: PropTypes.func,

/** If we need to show a brick road indicator or not. For now only value allowed is `error`,
* but we will add `success` later for manual requests */
brickRoadIndicator: PropTypes.oneOf(['error']),
/** The type of brick road indicator to show. */
brickRoadIndicator: PropTypes.oneOf([CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR, '']),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The empty string is the empty value so that functions that get the brick road indicator property can always return a string.

};

export default propTypes;
1 change: 0 additions & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,6 @@ export default {
restrictedDescription: 'People in your workspace can find this room',
privateDescription: 'People invited to this room can find it',
createRoom: 'Create Room',
policyRoomRenamed: 'Policy room renamed!',
roomAlreadyExistsError: 'A room with this name already exists',
roomNameReservedError: 'A room on this workspace already uses this name',
pleaseEnterRoomName: 'Please enter a room name',
Expand Down
1 change: 0 additions & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,6 @@ export default {
restrictedDescription: 'Sólo las personas en tu espacio de trabajo pueden encontrar esta sala',
privateDescription: 'Sólo las personas que están invitadas a esta sala pueden encontrarla',
createRoom: 'Crea una sala de chat',
policyRoomRenamed: '¡Espacio de trabajo renombrado!',
roomAlreadyExistsError: 'Ya existe una sala con este nombre',
roomNameReservedError: 'Una sala en este espacio de trabajo ya usa este nombre',
pleaseEnterRoomName: 'Por favor escribe el nombre de una sala',
Expand Down
14 changes: 11 additions & 3 deletions src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,26 @@ function hasReportDraftComment(report, reportsWithDraft = {}) {
}

/**
* If the report or the report actions have errors, return
* CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR, otherwise an empty string.
*
* @param {Object} report
* @param {Object} reportActions
* @returns {String}
*/
function getBrickRoadIndicatorStatusForReport(report, reportActions) {
const reportErrors = lodashGet(report, 'errors', {});
const reportErrorFields = lodashGet(report, 'errorFields', {});
const reportID = lodashGet(report, 'reportID');
const reportsActions = lodashGet(reportActions, `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {});
if (_.isEmpty(reportsActions)) {

const hasReportFieldErrors = _.some(reportErrorFields, fieldErrors => !_.isEmpty(fieldErrors));
const hasReportActionErrors = _.some(reportsActions, action => !_.isEmpty(action.errors));

if (_.isEmpty(reportErrors) && !hasReportFieldErrors && !hasReportActionErrors) {
return '';
}

return _.find(reportsActions, action => !_.isEmpty(action.errors)) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : '';
return CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR;
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,14 @@ function generateReportID() {
return Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER - 98000000)) + 98000000;
}

/**
* @param {Object} report
* @returns {Boolean}
*/
function hasReportNameError(report) {
return !_.isEmpty(lodashGet(report, 'errorFields.reportName', {}));
}

export {
getReportParticipantsTitle,
isReportMessageAttachment,
Expand Down Expand Up @@ -552,4 +560,5 @@ export {
getReportName,
navigateToDetailsPage,
generateReportID,
hasReportNameError,
};
79 changes: 58 additions & 21 deletions src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -1377,30 +1377,66 @@ function createPolicyRoom(policyID, reportName, visibility) {
}

/**
* Renames a user created Policy Room.
* @param {String} reportID
* @param {String} reportName
* @param {Object} policyRoomReport
neil-marcellini marked this conversation as resolved.
Show resolved Hide resolved
* @param {Number} policyRoomReport.reportID
* @param {String} policyRoomReport.reportName
* @param {String} policyRoomName The updated name for the policy room
*/
function renameReport(reportID, reportName) {
Onyx.set(ONYXKEYS.IS_LOADING_RENAME_POLICY_ROOM, true);
DeprecatedAPI.RenameReport({reportID, reportName})
.then((response) => {
if (response.jsonCode === CONST.JSON_CODE.UNABLE_TO_RETRY) {
Growl.error(Localize.translateLocal('newRoomPage.growlMessageOnRenameError'));
return;
}
function updatePolicyRoomName(policyRoomReport, policyRoomName) {
const reportID = policyRoomReport.reportID;
const previousName = policyRoomReport.reportName;
const optimisticData = [
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
reportName: policyRoomName,
pendingFields: {
reportName: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
},
errorFields: {
reportName: null,
},
},
},
];
const successData = [
{

if (response.jsonCode !== CONST.JSON_CODE.SUCCESS) {
Growl.error(response.message);
return;
}
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
pendingFields: {
reportName: null,
},
neil-marcellini marked this conversation as resolved.
Show resolved Hide resolved
},
},
];
const failureData = [
{

Growl.success(Localize.translateLocal('newRoomPage.policyRoomRenamed'));
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
reportName: previousName,
},
},
];
API.write('UpdatePolicyRoomName', {reportID, policyRoomName}, {optimisticData, successData, failureData});
}

// Update the report name so that the LHN and header display the updated name
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {reportName});
})
.finally(() => Onyx.set(ONYXKEYS.IS_LOADING_RENAME_POLICY_ROOM, false));
/**
* @param {Number} reportID The reportID of the policy room.
*/
function clearPolicyRoomNameErrors(reportID) {
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {
errorFields: {
reportName: null,
},
pendingFields: {
reportName: null,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm gonna guess that we are setting the reportName to null instead of the errorFields and pendingFields to null because we might have other report errors shown and we don't want to clear them all? Let me know if that sounds right.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, that's exactly it.

});
}

/**
Expand Down Expand Up @@ -1547,12 +1583,13 @@ export {
setReportWithDraft,
fetchInitialActions,
createPolicyRoom,
renameReport,
setIsComposerFullSize,
markCommentAsUnread,
readNewestAction,
readOldestAction,
openReport,
openPaymentDetailsPage,
createOptimisticReport,
updatePolicyRoomName,
clearPolicyRoomNameErrors,
};
14 changes: 0 additions & 14 deletions src/libs/deprecatedAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -622,19 +622,6 @@ function CreatePolicyRoom(parameters) {
return Network.post(commandName, parameters);
}

/**
* Renames a user-created policy room
* @param {Object} parameters
* @param {String} parameters.reportID
* @param {String} parameters.reportName
* @return {Promise}
*/
function RenameReport(parameters) {
const commandName = 'RenameReport';
requireParameters(['reportID', 'reportName'], parameters, commandName);
return Network.post(commandName, parameters);
}

/**
* Transfer Wallet balance and takes either the bankAccoundID or fundID
* @param {Object} parameters
Expand Down Expand Up @@ -668,7 +655,6 @@ export {
CreateChatReport,
CreateLogin,
CreatePolicyRoom,
RenameReport,
DeleteLogin,
DeleteBankAccount,
Get,
Expand Down
19 changes: 14 additions & 5 deletions src/pages/ReportDetailsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import * as Expensicons from '../components/Icon/Expensicons';
import ROUTES from '../ROUTES';
import MenuItem from '../components/MenuItem';
import Text from '../components/Text';
import CONST from '../CONST';

const propTypes = {
...withLocalizePropTypes,
Expand Down Expand Up @@ -73,6 +74,7 @@ class ReportDetailsPage extends Component {

// All nonarchived chats should let you see their members
this.menuItems.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.MEMBERS,
translationKey: 'common.members',
icon: Expensicons.Users,
subtitle: props.report.participants.length,
Expand All @@ -81,6 +83,7 @@ class ReportDetailsPage extends Component {

if (ReportUtils.isPolicyExpenseChat(this.props.report) || ReportUtils.isChatRoom(this.props.report)) {
this.menuItems.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.SETTINGS,
translationKey: 'common.settings',
icon: Expensicons.Gear,
action: () => { Navigation.navigate(ROUTES.getReportSettingsRoute(props.report.reportID)); },
Expand All @@ -89,11 +92,13 @@ class ReportDetailsPage extends Component {

if (ReportUtils.isUserCreatedPolicyRoom(this.props.report)) {
this.menuItems.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.INVITE,
translationKey: 'common.invite',
icon: Expensicons.Plus,
action: () => { /* Placeholder for when inviting other users is built in */ },
},
{
key: CONST.REPORT_DETAILS_MENU_ITEM.LEAVE_ROOM,
translationKey: 'common.leaveRoom',
icon: Expensicons.Exit,
action: () => { /* Placeholder for when leaving rooms is built in */ },
Expand Down Expand Up @@ -155,17 +160,21 @@ class ReportDetailsPage extends Component {
</View>
</View>
{_.map(this.menuItems, (item) => {
const keyTitle = item.translationKey ? this.props.translate(item.translationKey) : item.title;
const brickRoadIndicator = (
ReportUtils.hasReportNameError(this.props.report)
&& item.key === CONST.REPORT_DETAILS_MENU_ITEM.SETTINGS
)
? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR
: '';
return (
<MenuItem
key={keyTitle}
title={keyTitle}
key={item.key}
title={this.props.translate(item.translationKey)}
subtitle={item.subtitle}
icon={item.icon}
onPress={item.action}
iconStyles={item.iconStyles}
iconFill={item.iconFill}
shouldShowRightIcon
brickRoadIndicator={brickRoadIndicator}
/>
);
})}
Expand Down
Loading