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

Fix: Room visibility can’t be changed after a room is created #35830

Merged
merged 9 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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
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 @@ -289,6 +289,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 @@ -4527,6 +4527,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 @@ -5160,6 +5167,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
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};
Loading