fix: refactor ConfirmModal usage to useConfirmModal in workspaces tag page#82984
fix: refactor ConfirmModal usage to useConfirmModal in workspaces tag page#82984roryabraham merged 3 commits intoExpensify:mainfrom
Conversation
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
@ZhenjaHorbach Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Screen.Recording.2026-02-21.at.17.13.15.mov@ZhenjaHorbach i can't reproduce this bug in our PR |
| setImportedSpreadsheetIsImportingMultiLevelTags(false); | ||
| if (hasVisibleTags && isMultiLevelTags) { | ||
| setIsSwitchSingleToMultipleLevelTagWarningModalVisible(true); | ||
| const {action} = await showConfirmModal({ |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
This showConfirmModal block (with switchSingleToMultiLevelTagPrompt, including the cleanPolicyTags + Navigation.setNavigationActionToMicrotaskQueue confirm action) is duplicated from the startMultiLevelTagImportFlow callback above (~line 176). Both occurrences have identical modal options and identical confirm/cancel handling.
Extract a helper function, e.g.:
const showSwitchSingleToMultiLevelTagWarning = useCallback(async () => {
const {action} = await showConfirmModal({
title: translate('workspace.tags.switchSingleToMultiLevelTagWarning.title'),
prompt: switchSingleToMultiLevelTagPrompt,
confirmText: translate('workspace.tags.switchSingleToMultiLevelTagWarning.title'),
cancelText: translate('common.cancel'),
danger: true,
});
if (action === ModalActions.CONFIRM) {
cleanPolicyTags(policyID);
Navigation.setNavigationActionToMicrotaskQueue(() => {
Navigation.navigate(
isQuickSettingsFlow
? ROUTES.SETTINGS_TAGS_IMPORT.getRoute(policyID, ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo))
: ROUTES.WORKSPACE_TAGS_IMPORT.getRoute(policyID),
);
});
} else {
setImportedSpreadsheetIsImportingMultiLevelTags(false);
}
}, [/* deps */]);Then call showSwitchSingleToMultiLevelTagWarning() in both places.
Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
| setIsCannotDeleteOrDisableLastTagModalVisible(true); | ||
| showConfirmModal({ | ||
| title: translate('workspace.tags.cannotDeleteOrDisableAllTags.title'), | ||
| prompt: translate('workspace.tags.cannotDeleteOrDisableAllTags.description'), |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
This identical showConfirmModal block for "cannotDeleteOrDisableAllTags" is repeated 4 times in this file (in the tagList useMemo toggle handlers and in getHeaderButtons delete/disable handlers). The "cannotMakeAllTagsOptional" block is also repeated 2 times. Similarly, the "offline" modal block is repeated 2 times.
Extract helper functions to eliminate this duplication:
const showCannotDeleteOrDisableModal = useCallback(() => {
showConfirmModal({
title: translate('workspace.tags.cannotDeleteOrDisableAllTags.title'),
prompt: translate('workspace.tags.cannotDeleteOrDisableAllTags.description'),
confirmText: translate('common.buttonConfirm'),
shouldShowCancelButton: false,
});
}, [showConfirmModal, translate]);
const showCannotMakeOptionalModal = useCallback(() => {
showConfirmModal({
title: translate('workspace.tags.cannotMakeAllTagsOptional.title'),
prompt: translate('workspace.tags.cannotMakeAllTagsOptional.description'),
confirmText: translate('common.buttonConfirm'),
shouldShowCancelButton: false,
});
}, [showConfirmModal, translate]);
const showOfflineModal = useCallback(() => {
showConfirmModal({
title: translate('common.youAppearToBeOffline'),
prompt: translate('common.thisFeatureRequiresInternet'),
confirmText: translate('common.buttonConfirm'),
shouldShowCancelButton: false,
shouldHandleNavigationBack: true,
});
}, [showConfirmModal, translate]);Then call these helpers instead of repeating the full blocks.
Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
| onSelected: () => { | ||
| if (isDisablingOrDeletingLastEnabledTag(currentPolicyTag, selectedTagsObject)) { | ||
| setIsCannotDeleteOrDisableLastTagModalVisible(true); | ||
| showConfirmModal({ |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
This "cannotDeleteOrDisableAllTags" showConfirmModal block is duplicated here and in the tagList useMemo toggle handler above (~line 141). The same pattern also appears 4 times in WorkspaceTagsPage.tsx and 2 times in TagSettingsPage.tsx.
Consider extracting a shared helper (either file-local or shared across these tag pages) to avoid repeating the same modal configuration:
const showCannotDeleteOrDisableModal = useCallback(() => {
showConfirmModal({
title: translate('workspace.tags.cannotDeleteOrDisableAllTags.title'),
prompt: translate('workspace.tags.cannotDeleteOrDisableAllTags.description'),
confirmText: translate('common.buttonConfirm'),
shouldShowCancelButton: false,
});
}, [showConfirmModal, translate]);Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
|
PR doesn’t need product input as a refactor PR. Unassigning and unsubscribing myself. |
|
friendly bump here @ZhenjaHorbach |
Yeah 2026-03-02.14.15.38.mov |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb Chrome2026-02-06.13.45.31.mov2026-02-06.13.46.29.mov2026-02-06.13.47.09.mov2026-02-06.13.50.41.moviOS: HybridAppiOS: mWeb Safari2026-02-06.13.45.31.mov2026-02-06.13.46.29.mov2026-02-06.13.47.09.mov2026-02-06.13.50.41.movMacOS: Chrome / Safari2026-02-02.16.04.00.mov2026-02-02.16.06.41.mov2026-02-02.16.07.33.mov2026-02-02.16.08.08.mov |
| startMultiLevelTagImportFlow(); | ||
| setShouldRunPostUpgradeFlow(false); | ||
| }, [shouldRunPostUpgradeFlow, policy, startMultiLevelTagImportFlow]), | ||
| const overrideMultiTagPrompt = useMemo( |
There was a problem hiding this comment.
This component is compiling with React Compiler on main, so we shouldn't use any manual memoization here.
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 @roryabraham has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/roryabraham in version: 9.3.28-0 🚀
|
|
🚀 Deployed to staging by https://github.com/roryabraham in version: 9.3.30-0 🚀
|
|
🚀 Deployed to production by https://github.com/blimpich in version: 9.3.30-3 🚀
|
Explanation of Change
Refactor ConfirmModal usage to useConfirmModal in the following files:
Fixed Issues
$ #76690
#82456
PROPOSAL:
Tests
delete tagoptionDelete tag warningmodal is displayedTagis deleteddeleteoptionDelete tag warningmodal is displayedTagis deletedMulti-level tagsCannot delete or disable all tagsis displayedOffline tests
Same as tests
QA Steps
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
android-resize.mp4
android.mov
Android: mWeb Chrome
android-mweb-resize.mp4
android-mweb.mov
iOS: Native
ios-resize.mp4
ios.mov
iOS: mWeb Safari
ios-mweb-resize.mp4
ios-mwbe.mov
MacOS: Chrome / Safari
result.mp4
web.mov