diff --git a/src/pages/settings/Report/DynamicNotificationPreferencePage.tsx b/src/pages/settings/Report/DynamicNotificationPreferencePage.tsx index be52750d7d5d..cdb222db5961 100644 --- a/src/pages/settings/Report/DynamicNotificationPreferencePage.tsx +++ b/src/pages/settings/Report/DynamicNotificationPreferencePage.tsx @@ -22,7 +22,7 @@ import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {ValueOf} from 'type-fest'; -import React, {useCallback} from 'react'; +import React, {useCallback, useState} from 'react'; type DynamicNotificationPreferencePageProps = WithReportOrNotFoundProps; @@ -32,6 +32,9 @@ function DynamicNotificationPreferencePage({report}: DynamicNotificationPreferen const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails(); const isMoneyRequest = isMoneyRequestReport(report); const currentNotificationPreference = getReportNotificationPreference(report); + + const [draftNotificationPreference, setDraftNotificationPreference] = useState | undefined>(undefined); + const selectedNotificationPreference = draftNotificationPreference ?? currentNotificationPreference; const shouldDisableNotificationPreferences = isArchivedNonExpenseReport(report, isReportArchived) || isSelfDM(report) || (!isMoneyRequest && isHiddenForCurrentUser(currentNotificationPreference)); const notificationPreferenceOptions = Object.values(CONST.REPORT.NOTIFICATION_PREFERENCE) @@ -40,7 +43,7 @@ function DynamicNotificationPreferencePage({report}: DynamicNotificationPreferen value: preference, text: translate(`notificationPreferencesPage.notificationPreferences.${preference}`), keyForList: preference, - isSelected: preference === currentNotificationPreference, + isSelected: preference === selectedNotificationPreference, })); const backPath = useDynamicBackPath(DYNAMIC_ROUTES.NOTIFICATION_PREFERENCES.path); @@ -48,13 +51,17 @@ function DynamicNotificationPreferencePage({report}: DynamicNotificationPreferen Navigation.goBack(backPath); }, [backPath]); - const updateNotificationPreferenceForReportAction = useCallback( - (value: ValueOf) => { - updateNotificationPreference(report.reportID, currentNotificationPreference, value, currentUserAccountID, undefined, undefined); - goBack(); - }, - [report.reportID, currentNotificationPreference, currentUserAccountID, goBack], - ); + const saveNotificationPreference = () => { + updateNotificationPreference(report.reportID, currentNotificationPreference, selectedNotificationPreference, currentUserAccountID, undefined, undefined); + goBack(); + }; + + const confirmButtonOptions = { + showButton: true, + text: translate('common.save'), + onConfirm: saveNotificationPreference, + isDisabled: selectedNotificationPreference === currentNotificationPreference, + }; return ( updateNotificationPreferenceForReportAction(option.value)} + onSelectRow={(option) => setDraftNotificationPreference(option.value)} + confirmButtonOptions={confirmButtonOptions} shouldSingleExecuteRowSelect - initiallyFocusedItemKey={notificationPreferenceOptions.find((locale) => locale.isSelected)?.keyForList} + initiallyFocusedItemKey={currentNotificationPreference} + addBottomSafeAreaPadding /> diff --git a/src/pages/settings/Report/DynamicVisibilityPage.tsx b/src/pages/settings/Report/DynamicVisibilityPage.tsx index 0370bd7c6831..172a5dd9441b 100644 --- a/src/pages/settings/Report/DynamicVisibilityPage.tsx +++ b/src/pages/settings/Report/DynamicVisibilityPage.tsx @@ -23,7 +23,7 @@ import CONST from '@src/CONST'; import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {RoomVisibility} from '@src/types/onyx/Report'; -import React, {useMemo} from 'react'; +import React, {useMemo, useState} from 'react'; type DynamicVisibilityProps = WithReportOrNotFoundProps; @@ -35,6 +35,9 @@ function DynamicVisibilityPage({report}: DynamicVisibilityProps) { const {showConfirmModal} = useConfirmModal(); + const [draftVisibility, setDraftVisibility] = useState(undefined); + const selectedVisibility = draftVisibility ?? report?.visibility; + const visibilityOptions = useMemo( () => Object.values(CONST.REPORT.VISIBILITY) @@ -44,36 +47,43 @@ function DynamicVisibilityPage({report}: DynamicVisibilityProps) { value: visibilityOption, alternateText: translate(`newRoomPage.${visibilityOption}Description`), keyForList: visibilityOption, - isSelected: visibilityOption === report?.visibility, + isSelected: visibilityOption === selectedVisibility, })), - [translate, report?.visibility], + [translate, selectedVisibility], ); const goBack = () => { Navigation.goBack(backPath); }; - const changeVisibility = (newVisibility: RoomVisibility) => { - if (!report) { + const saveVisibility = async () => { + if (!report || !selectedVisibility) { return; } - updateRoomVisibility(report.reportID, report.visibility, newVisibility); + + // Selecting Public is a sensitive change, so it still has to be confirmed before we persist it. + if (selectedVisibility === CONST.REPORT.VISIBILITY.PUBLIC) { + const result = await showConfirmModal({ + title: translate('common.areYouSure'), + prompt: translate('newRoomPage.publicDescription'), + confirmText: translate('common.yes'), + cancelText: translate('common.no'), + shouldShowCancelButton: true, + danger: true, + }); + if (result.action !== ModalActions.CONFIRM) { + return; + } + } + updateRoomVisibility(report.reportID, report.visibility, selectedVisibility); setNavigationActionToMicrotaskQueue(goBack); }; - const showPublicVisibilityModal = async () => { - const result = await showConfirmModal({ - title: translate('common.areYouSure'), - prompt: translate('newRoomPage.publicDescription'), - confirmText: translate('common.yes'), - cancelText: translate('common.no'), - shouldShowCancelButton: true, - danger: true, - }); - if (result.action !== ModalActions.CONFIRM) { - return; - } - changeVisibility(CONST.REPORT.VISIBILITY.PUBLIC); + const confirmButtonOptions = { + showButton: true, + text: translate('common.save'), + onConfirm: saveVisibility, + isDisabled: selectedVisibility === report?.visibility, }; return ( @@ -89,16 +99,12 @@ function DynamicVisibilityPage({report}: DynamicVisibilityProps) { { - if (option.value === CONST.REPORT.VISIBILITY.PUBLIC) { - showPublicVisibilityModal(); - return; - } - changeVisibility(option.value); - }} + onSelectRow={(option) => setDraftVisibility(option.value)} + confirmButtonOptions={confirmButtonOptions} shouldSingleExecuteRowSelect - initiallyFocusedItemKey={visibilityOptions.find((visibility) => visibility.isSelected)?.keyForList} + initiallyFocusedItemKey={report?.visibility} ListItem={SingleSelectListItem} + addBottomSafeAreaPadding /> diff --git a/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx b/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx index d4457a75d1f0..e1f828b9852e 100644 --- a/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx +++ b/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx @@ -17,23 +17,25 @@ import type {WithReportOrNotFoundProps} from '@pages/inbox/report/withReportOrNo import CONST from '@src/CONST'; import {DYNAMIC_ROUTES} from '@src/ROUTES'; +import type {WriteCapability} from '@src/types/onyx/Report'; -import type {ValueOf} from 'type-fest'; - -import React, {useCallback} from 'react'; +import React, {useState} from 'react'; type DynamicWriteCapabilityPageProps = WithReportOrNotFoundProps; function DynamicWriteCapabilityPage({report, policy}: DynamicWriteCapabilityPageProps) { const backPath = useDynamicBackPath(DYNAMIC_ROUTES.REPORT_SETTINGS_WRITE_CAPABILITY.path); const {translate} = useLocalize(); + const currentWriteCapability = report?.writeCapability ?? CONST.REPORT.WRITE_CAPABILITIES.ALL; + + const [draftWriteCapability, setDraftWriteCapability] = useState(undefined); + const selectedWriteCapability = draftWriteCapability ?? currentWriteCapability; const writeCapabilityOptions = Object.values(CONST.REPORT.WRITE_CAPABILITIES).map((value) => ({ value, text: translate(`writeCapabilityPage.writeCapability.${value}`), keyForList: value, - isSelected: value === (report?.writeCapability ?? CONST.REPORT.WRITE_CAPABILITIES.ALL), + isSelected: value === selectedWriteCapability, })); - const selectedOptionKey = writeCapabilityOptions.find((locale) => locale.isSelected)?.keyForList; const isReportArchived = useReportIsArchived(report.reportID); const isAbleToEdit = canEditWriteCapability(report, policy, isReportArchived); @@ -41,13 +43,17 @@ function DynamicWriteCapabilityPage({report, policy}: DynamicWriteCapabilityPage Navigation.goBack(backPath); }; - const updateWriteCapability = useCallback( - (newValue: ValueOf) => { - updateWriteCapabilityUtil(report, newValue); - goBack(); - }, - [report, goBack], - ); + const saveWriteCapability = () => { + updateWriteCapabilityUtil(report, selectedWriteCapability); + goBack(); + }; + + const confirmButtonOptions = { + showButton: true, + text: translate('common.save'), + onConfirm: saveWriteCapability, + isDisabled: selectedWriteCapability === currentWriteCapability, + }; return ( updateWriteCapability(option.value)} + onSelectRow={(option) => setDraftWriteCapability(option.value)} + confirmButtonOptions={confirmButtonOptions} shouldSingleExecuteRowSelect - initiallyFocusedItemKey={selectedOptionKey} + initiallyFocusedItemKey={currentWriteCapability} + addBottomSafeAreaPadding />