Skip to content

Commit

Permalink
Merge pull request #35830 from tienifr/fix/33992
Browse files Browse the repository at this point in the history
Fix: Room visibility can’t be changed after a room is created
  • Loading branch information
jasperhuangg authored Feb 21, 2024
2 parents df70349 + 20a749a commit cf2b35f
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ const ROUTES = {
route: 'r/:reportID/settings/who-can-post',
getRoute: (reportID: string) => `r/${reportID}/settings/who-can-post` as const,
},
REPORT_SETTINGS_VISIBILITY: {
route: 'r/:reportID/settings/visibility',
getRoute: (reportID: string) => `r/${reportID}/settings/visibility` as const,
},
SPLIT_BILL_DETAILS: {
route: 'r/:reportID/split/:reportActionID',
getRoute: (reportID: string, reportActionID: string) => `r/${reportID}/split/${reportActionID}` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ const SCREENS = {
ROOM_NAME: 'Report_Settings_Room_Name',
NOTIFICATION_PREFERENCES: 'Report_Settings_Notification_Preferences',
WRITE_CAPABILITY: 'Report_Settings_Write_Capability',
VISIBILITY: 'Report_Settings_Visibility',
},

NEW_TASK: {
Expand Down
8 changes: 8 additions & 0 deletions src/libs/API/parameters/UpdateRoomVisibilityParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type {RoomVisibility} from '@src/types/onyx/Report';

type UpdateRoomVisibilityParams = {
reportID: string;
visibility: RoomVisibility;
};

export default UpdateRoomVisibilityParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export type {default as DeleteCommentParams} from './DeleteCommentParams';
export type {default as UpdateCommentParams} from './UpdateCommentParams';
export type {default as UpdateReportNotificationPreferenceParams} from './UpdateReportNotificationPreferenceParams';
export type {default as UpdateRoomDescriptionParams} from './UpdateRoomDescriptionParams';
export type {default as UpdateRoomVisibilityParams} from './UpdateRoomVisibilityParams';
export type {default as UpdateReportWriteCapabilityParams} from './UpdateReportWriteCapabilityParams';
export type {default as AddWorkspaceRoomParams} from './AddWorkspaceRoomParams';
export type {default as UpdatePolicyRoomNameParams} from './UpdatePolicyRoomNameParams';
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const WRITE_COMMANDS = {
DELETE_COMMENT: 'DeleteComment',
UPDATE_COMMENT: 'UpdateComment',
UPDATE_REPORT_NOTIFICATION_PREFERENCE: 'UpdateReportNotificationPreference',
UPDATE_ROOM_VISIBILITY: 'UpdateRoomVisibility',
UPDATE_ROOM_DESCRIPTION: 'UpdateRoomDescription',
UPDATE_REPORT_WRITE_CAPABILITY: 'UpdateReportWriteCapability',
ADD_WORKSPACE_ROOM: 'AddWorkspaceRoom',
Expand Down Expand Up @@ -226,6 +227,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.DELETE_COMMENT]: Parameters.DeleteCommentParams;
[WRITE_COMMANDS.UPDATE_COMMENT]: Parameters.UpdateCommentParams;
[WRITE_COMMANDS.UPDATE_REPORT_NOTIFICATION_PREFERENCE]: Parameters.UpdateReportNotificationPreferenceParams;
[WRITE_COMMANDS.UPDATE_ROOM_VISIBILITY]: Parameters.UpdateRoomVisibilityParams;
[WRITE_COMMANDS.UPDATE_ROOM_DESCRIPTION]: Parameters.UpdateRoomDescriptionParams;
[WRITE_COMMANDS.UPDATE_REPORT_WRITE_CAPABILITY]: Parameters.UpdateReportWriteCapabilityParams;
[WRITE_COMMANDS.ADD_WORKSPACE_ROOM]: Parameters.AddWorkspaceRoomParams;
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ const ReportSettingsModalStackNavigator = createModalStackNavigator<ReportSettin
[SCREENS.REPORT_SETTINGS.ROOM_NAME]: () => require('../../../pages/settings/Report/RoomNamePage').default as React.ComponentType,
[SCREENS.REPORT_SETTINGS.NOTIFICATION_PREFERENCES]: () => require('../../../pages/settings/Report/NotificationPreferencePage').default as React.ComponentType,
[SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: () => require('../../../pages/settings/Report/WriteCapabilityPage').default as React.ComponentType,
[SCREENS.REPORT_SETTINGS.VISIBILITY]: () => require('../../../pages/settings/Report/VisibilityPage').default as React.ComponentType,
});

const TaskModalStackNavigator = createModalStackNavigator<TaskDetailsNavigatorParamList>({
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: {
path: ROUTES.REPORT_SETTINGS_WRITE_CAPABILITY.route,
},
[SCREENS.REPORT_SETTINGS.VISIBILITY]: {
path: ROUTES.REPORT_SETTINGS_VISIBILITY.route,
},
},
},
[SCREENS.RIGHT_MODAL.REPORT_DESCRIPTION]: {
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ type ReportSettingsNavigatorParamList = {
[SCREENS.REPORT_SETTINGS.ROOM_NAME]: undefined;
[SCREENS.REPORT_SETTINGS.NOTIFICATION_PREFERENCES]: undefined;
[SCREENS.REPORT_SETTINGS.WRITE_CAPABILITY]: undefined;
[SCREENS.REPORT_SETTINGS.VISIBILITY]: {
reportID: string;
};
};

type ReportDescriptionNavigatorParamList = {
Expand Down
8 changes: 8 additions & 0 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4525,6 +4525,13 @@ function canEditWriteCapability(report: OnyxEntry<Report>, policy: OnyxEntry<Pol
return PolicyUtils.isPolicyAdmin(policy) && !isAdminRoom(report) && !isArchivedRoom(report) && !isThread(report);
}

/**
* @param policy - the workspace the report is on, null if the user isn't a member of the workspace
*/
function canEditRoomVisibility(report: OnyxEntry<Report>, policy: OnyxEntry<Policy>): boolean {
return PolicyUtils.isPolicyAdmin(policy) && !isArchivedRoom(report);
}

/**
* Returns the onyx data needed for the task assignee chat
*/
Expand Down Expand Up @@ -5215,6 +5222,7 @@ export {
getAvailableReportFields,
reportFieldsEnabled,
getAllAncestorReportActionIDs,
canEditRoomVisibility,
canEditPolicyDescription,
getPolicyDescriptionText,
};
Expand Down
36 changes: 35 additions & 1 deletion src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import type {
UpdateReportWriteCapabilityParams,
UpdateRoomDescriptionParams,
} from '@libs/API/parameters';
import type UpdateRoomVisibilityParams from '@libs/API/parameters/UpdateRoomVisibilityParams';
import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as CollectionUtils from '@libs/CollectionUtils';
import DateUtils from '@libs/DateUtils';
Expand Down Expand Up @@ -68,7 +69,7 @@ import type {Route} from '@src/ROUTES';
import ROUTES from '@src/ROUTES';
import type {PersonalDetails, PersonalDetailsList, PolicyReportField, RecentlyUsedReportFields, ReportActionReactions, ReportMetadata, ReportUserIsTyping} from '@src/types/onyx';
import type {Decision, OriginalMessageIOU} from '@src/types/onyx/OriginalMessage';
import type {NotificationPreference, WriteCapability} from '@src/types/onyx/Report';
import type {NotificationPreference, RoomVisibility, WriteCapability} from '@src/types/onyx/Report';
import type Report from '@src/types/onyx/Report';
import type {Message, ReportActionBase, ReportActions} from '@src/types/onyx/ReportAction';
import type ReportAction from '@src/types/onyx/ReportAction';
Expand Down Expand Up @@ -1442,6 +1443,38 @@ function updateNotificationPreference(
}
}

function updateRoomVisibility(reportID: string, previousValue: RoomVisibility | undefined, newValue: RoomVisibility, navigate: boolean, report: OnyxEntry<Report> | EmptyObject = {}) {
if (previousValue === newValue) {
if (navigate && !isEmptyObject(report) && report.reportID) {
ReportUtils.goBackToDetailsPage(report);
}
return;
}

const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {visibility: newValue},
},
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {visibility: previousValue},
},
];

const parameters: UpdateRoomVisibilityParams = {reportID, visibility: newValue};

API.write(WRITE_COMMANDS.UPDATE_ROOM_VISIBILITY, parameters, {optimisticData, failureData});
if (navigate && !isEmptyObject(report)) {
ReportUtils.goBackToDetailsPage(report);
}
}

/**
* This will subscribe to an existing thread, or create a new one and then subsribe to it if necessary
*
Expand Down Expand Up @@ -2926,4 +2959,5 @@ export {
updateReportField,
updateReportName,
resolveActionableMentionWhisper,
updateRoomVisibility,
};
17 changes: 13 additions & 4 deletions src/pages/settings/Report/ReportSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ function ReportSettingsPage({report, policies}: ReportSettingsPageProps) {

const writeCapabilityText = translate(`writeCapabilityPage.writeCapability.${writeCapability}`);
const shouldAllowWriteCapabilityEditing = useMemo(() => ReportUtils.canEditWriteCapability(report, linkedWorkspace), [report, linkedWorkspace]);
const shouldAllowChangeVisibility = useMemo(() => ReportUtils.canEditRoomVisibility(report, linkedWorkspace), [report, linkedWorkspace]);

const shouldShowNotificationPref = !isMoneyRequestReport && report?.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;
const roomNameLabel = translate(isMoneyRequestReport ? 'workspace.editor.nameInputLabel' : 'newRoomPage.roomName');
Expand Down Expand Up @@ -141,8 +142,17 @@ function ReportSettingsPage({report, policies}: ReportSettingsPageProps) {
/>
</View>
)}
{report?.visibility !== undefined && (
<View style={[styles.pv3]}>
</View>
{report?.visibility !== undefined &&
(shouldAllowChangeVisibility ? (
<MenuItemWithTopDescription
shouldShowRightIcon
title={translate(`newRoomPage.visibilityOptions.${report.visibility}`)}
description={translate('newRoomPage.visibility')}
onPress={() => Navigation.navigate(ROUTES.REPORT_SETTINGS_VISIBILITY.getRoute(report.reportID))}
/>
) : (
<View style={[styles.pv3, styles.ph5]}>
<Text
style={[styles.textLabelSupporting, styles.lh16, styles.mb1]}
numberOfLines={1}
Expand All @@ -157,8 +167,7 @@ function ReportSettingsPage({report, policies}: ReportSettingsPageProps) {
</Text>
<Text style={[styles.textLabelSupporting, styles.mt1]}>{translate(`newRoomPage.${report.visibility}Description`)}</Text>
</View>
)}
</View>
))}
</ScrollView>
</FullPageNotFoundView>
</ScreenWrapper>
Expand Down
96 changes: 96 additions & 0 deletions src/pages/settings/Report/VisibilityPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback, useMemo, useState} from 'react';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import ConfirmModal from '@components/ConfirmModal';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
import useLocalize from '@hooks/useLocalize';
import type {ReportSettingsNavigatorParamList} from '@libs/Navigation/types';
import * as ReportUtils from '@libs/ReportUtils';
import type {WithReportOrNotFoundProps} from '@pages/home/report/withReportOrNotFound';
import withReportOrNotFound from '@pages/home/report/withReportOrNotFound';
import * as ReportActions from '@userActions/Report';
import CONST from '@src/CONST';
import type SCREENS from '@src/SCREENS';
import type {RoomVisibility} from '@src/types/onyx/Report';

type VisibilityProps = WithReportOrNotFoundProps & StackScreenProps<ReportSettingsNavigatorParamList, typeof SCREENS.REPORT_SETTINGS.VISIBILITY>;

function VisibilityPage({report}: VisibilityProps) {
const [showConfirmModal, setShowConfirmModal] = useState(false);

const shouldDisableVisibility = ReportUtils.isArchivedRoom(report);
const {translate} = useLocalize();

const visibilityOptions = useMemo(
() =>
Object.values(CONST.REPORT.VISIBILITY)
.filter((visibilityOption) => visibilityOption !== CONST.REPORT.VISIBILITY.PUBLIC_ANNOUNCE)
.map((visibilityOption) => ({
text: translate(`newRoomPage.visibilityOptions.${visibilityOption}`),
value: visibilityOption,
alternateText: translate(`newRoomPage.${visibilityOption}Description`),
keyForList: visibilityOption,
isSelected: visibilityOption === report?.visibility,
})),
[translate, report?.visibility],
);

const changeVisibility = useCallback(
(newVisibility: RoomVisibility) => {
if (!report) {
return;
}
ReportActions.updateRoomVisibility(report.reportID, report.visibility, newVisibility, true, report);
},
[report],
);

const hideModal = useCallback(() => {
setShowConfirmModal(false);
}, []);

return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID={VisibilityPage.displayName}
>
<FullPageNotFoundView shouldShow={shouldDisableVisibility}>
<HeaderWithBackButton
title={translate('newRoomPage.visibility')}
onBackButtonPress={() => ReportUtils.goBackToDetailsPage(report)}
/>
<SelectionList

Check failure on line 64 in src/pages/settings/Report/VisibilityPage.tsx

View workflow job for this annotation

GitHub Actions / typecheck / typecheck

Property 'ListItem' is missing in type '{ shouldPreventDefaultFocusOnSelectRow: true; sections: { data: { text: string; value: "public" | "public_announce" | "private" | "restricted"; alternateText: string; keyForList: "public" | "public_announce" | "private" | "restricted"; isSelected: boolean; }[]; }[]; onSelectRow: (option: { ...; }) => void; initially...' but required in type '{ sections: SectionListData<{ text: string; value: "public" | "public_announce" | "private" | "restricted"; alternateText: string; keyForList: "public" | "public_announce" | "private" | "restricted"; isSelected: boolean; }, Section<...>>[]; ... 34 more ...; onLayout?: ((event: LayoutChangeEvent) => void) | undefined...'.
shouldPreventDefaultFocusOnSelectRow
sections={[{data: visibilityOptions}]}
onSelectRow={(option) => {
if (option.value === CONST.REPORT.VISIBILITY.PUBLIC) {
setShowConfirmModal(true);
return;
}
changeVisibility(option.value);
}}
initiallyFocusedOptionKey={visibilityOptions.find((visibility) => visibility.isSelected)?.keyForList}
/>
<ConfirmModal
isVisible={showConfirmModal}
onConfirm={() => {
changeVisibility(CONST.REPORT.VISIBILITY.PUBLIC);
hideModal();
}}
onCancel={hideModal}
title={translate('common.areYouSure')}
prompt={translate('newRoomPage.publicDescription')}
confirmText={translate('common.yes')}
cancelText={translate('common.no')}
danger
/>
</FullPageNotFoundView>
</ScreenWrapper>
);
}

VisibilityPage.displayName = 'VisibilityPage';

export default withReportOrNotFound()(VisibilityPage);
6 changes: 4 additions & 2 deletions src/types/onyx/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ type NotificationPreference = ValueOf<typeof CONST.REPORT.NOTIFICATION_PREFERENC

type WriteCapability = ValueOf<typeof CONST.REPORT.WRITE_CAPABILITIES>;

type RoomVisibility = ValueOf<typeof CONST.REPORT.VISIBILITY>;

type Note = {
note: string;
errors?: OnyxCommon.Errors;
Expand Down Expand Up @@ -110,7 +112,7 @@ type Report = {
openOnAdminRoom?: boolean;

/** The report visibility */
visibility?: ValueOf<typeof CONST.REPORT.VISIBILITY>;
visibility?: RoomVisibility;

/** Report cached total */
cachedTotal?: string;
Expand Down Expand Up @@ -178,4 +180,4 @@ type Report = {

export default Report;

export type {NotificationPreference, WriteCapability, Note};
export type {NotificationPreference, RoomVisibility, WriteCapability, Note};

0 comments on commit cf2b35f

Please sign in to comment.