-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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: categorize all expense switch is not disabled #39036
Changes from 12 commits
299e1e6
67322e1
547f69b
3874d9c
830640c
85cd494
7520ddf
eceebef
a19beb1
6367292
9eaf74a
6b05057
a45c9a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -60,6 +60,7 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout'; | |||
import Log from '@libs/Log'; | ||||
import Navigation from '@libs/Navigation/Navigation'; | ||||
import * as NumberUtils from '@libs/NumberUtils'; | ||||
import * as OptionsListUtils from '@libs/OptionsListUtils'; | ||||
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; | ||||
import * as PhoneNumber from '@libs/PhoneNumber'; | ||||
import * as PolicyUtils from '@libs/PolicyUtils'; | ||||
|
@@ -2872,27 +2873,29 @@ function createWorkspaceFromIOUPayment(iouReport: Report | EmptyObject): string | |||
|
||||
function setWorkspaceCategoryEnabled(policyID: string, categoriesToUpdate: Record<string, {name: string; enabled: boolean}>) { | ||||
const policyCategories = allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`] ?? {}; | ||||
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; | ||||
const optimisticPolicyCategoriesData = { | ||||
...Object.keys(categoriesToUpdate).reduce<PolicyCategories>((acc, key) => { | ||||
acc[key] = { | ||||
...policyCategories[key], | ||||
...categoriesToUpdate[key], | ||||
errors: null, | ||||
pendingFields: { | ||||
enabled: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, | ||||
}, | ||||
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, | ||||
}; | ||||
|
||||
return acc; | ||||
}, {}), | ||||
}; | ||||
const shouldDisableRequiresCategory = !OptionsListUtils.hasEnabledOptions({...policyCategories, ...optimisticPolicyCategoriesData}); | ||||
const onyxData: OnyxData = { | ||||
optimisticData: [ | ||||
{ | ||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, | ||||
value: { | ||||
...Object.keys(categoriesToUpdate).reduce<PolicyCategories>((acc, key) => { | ||||
acc[key] = { | ||||
...policyCategories[key], | ||||
...categoriesToUpdate[key], | ||||
errors: null, | ||||
pendingFields: { | ||||
enabled: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, | ||||
}, | ||||
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, | ||||
}; | ||||
|
||||
return acc; | ||||
}, {}), | ||||
}, | ||||
value: optimisticPolicyCategoriesData, | ||||
}, | ||||
], | ||||
successData: [ | ||||
|
@@ -2938,6 +2941,37 @@ function setWorkspaceCategoryEnabled(policyID: string, categoriesToUpdate: Recor | |||
}, | ||||
], | ||||
}; | ||||
if (shouldDisableRequiresCategory) { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we do the same for App/src/libs/actions/Policy.ts Line 3439 in 5986481
Screen.Recording.2024-04-02.at.9.55.11.at.night.movThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated to do the same when deleting category There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice catch! |
||||
onyxData.optimisticData?.push({ | ||||
tienifr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, | ||||
value: { | ||||
requiresCategory: false, | ||||
pendingFields: { | ||||
requiresCategory: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, | ||||
}, | ||||
}, | ||||
}); | ||||
onyxData.successData?.push({ | ||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, | ||||
value: { | ||||
pendingFields: { | ||||
requiresCategory: null, | ||||
}, | ||||
}, | ||||
}); | ||||
onyxData.failureData?.push({ | ||||
tienifr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, | ||||
value: { | ||||
requiresCategory: policy?.requiresCategory, | ||||
pendingFields: { | ||||
requiresCategory: null, | ||||
}, | ||||
}, | ||||
}); | ||||
} | ||||
|
||||
const parameters = { | ||||
policyID, | ||||
|
@@ -3437,15 +3471,21 @@ function clearCategoryErrors(policyID: string, categoryName: string) { | |||
} | ||||
|
||||
function deleteWorkspaceCategories(policyID: string, categoryNamesToDelete: string[]) { | ||||
const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; | ||||
const policyCategories = allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`] ?? {}; | ||||
const optimisticPolicyCategoriesData = categoryNamesToDelete.reduce<Record<string, Partial<PolicyCategory>>>((acc, categoryName) => { | ||||
acc[categoryName] = {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE}; | ||||
return acc; | ||||
}, {}); | ||||
const shouldDisableRequiresCategory = !OptionsListUtils.hasEnabledOptions( | ||||
Object.values(policyCategories).filter((category) => !categoryNamesToDelete.includes(category.name) && category.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE), | ||||
); | ||||
const onyxData: OnyxData = { | ||||
optimisticData: [ | ||||
{ | ||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, | ||||
value: categoryNamesToDelete.reduce<Record<string, Partial<PolicyCategory>>>((acc, categoryName) => { | ||||
acc[categoryName] = {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE}; | ||||
return acc; | ||||
}, {}), | ||||
value: optimisticPolicyCategoriesData, | ||||
}, | ||||
], | ||||
successData: [ | ||||
|
@@ -3472,6 +3512,37 @@ function deleteWorkspaceCategories(policyID: string, categoryNamesToDelete: stri | |||
}, | ||||
], | ||||
}; | ||||
if (shouldDisableRequiresCategory) { | ||||
onyxData.optimisticData?.push({ | ||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, | ||||
value: { | ||||
requiresCategory: false, | ||||
pendingFields: { | ||||
requiresCategory: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, | ||||
}, | ||||
}, | ||||
}); | ||||
onyxData.successData?.push({ | ||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, | ||||
value: { | ||||
pendingFields: { | ||||
requiresCategory: null, | ||||
}, | ||||
}, | ||||
}); | ||||
onyxData.failureData?.push({ | ||||
onyxMethod: Onyx.METHOD.MERGE, | ||||
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, | ||||
value: { | ||||
requiresCategory: policy?.requiresCategory, | ||||
pendingFields: { | ||||
requiresCategory: null, | ||||
}, | ||||
}, | ||||
}); | ||||
} | ||||
|
||||
const parameters = { | ||||
policyID, | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import type {StackScreenProps} from '@react-navigation/stack'; | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import type {OnyxEntry} from 'react-native-onyx'; | ||
import {withOnyx} from 'react-native-onyx'; | ||
import HeaderWithBackButton from '@components/HeaderWithBackButton'; | ||
import OfflineWithFeedback from '@components/OfflineWithFeedback'; | ||
import ScreenWrapper from '@components/ScreenWrapper'; | ||
|
@@ -9,23 +11,32 @@ import Text from '@components/Text'; | |
import useLocalize from '@hooks/useLocalize'; | ||
import useThemeStyles from '@hooks/useThemeStyles'; | ||
import {setWorkspaceRequiresCategory} from '@libs/actions/Policy'; | ||
import * as OptionsListUtils from '@libs/OptionsListUtils'; | ||
import type {SettingsNavigatorParamList} from '@navigation/types'; | ||
import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; | ||
import FeatureEnabledAccessOrNotFoundWrapper from '@pages/workspace/FeatureEnabledAccessOrNotFoundWrapper'; | ||
import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; | ||
import CONST from '@src/CONST'; | ||
import ONYXKEYS from '@src/ONYXKEYS'; | ||
import type SCREENS from '@src/SCREENS'; | ||
import type * as OnyxTypes from '@src/types/onyx'; | ||
|
||
type WorkspaceCategoriesSettingsPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.CATEGORIES_SETTINGS>; | ||
type WorkspaceCategoriesSettingsPageOnyxProps = { | ||
/** Collection of categories attached to a policy */ | ||
policyCategories: OnyxEntry<OnyxTypes.PolicyCategories>; | ||
}; | ||
|
||
function WorkspaceCategoriesSettingsPage({route}: WorkspaceCategoriesSettingsPageProps) { | ||
type WorkspaceCategoriesSettingsPageProps = WorkspaceCategoriesSettingsPageOnyxProps & StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.CATEGORIES_SETTINGS>; | ||
|
||
function WorkspaceCategoriesSettingsPage({route, policyCategories}: WorkspaceCategoriesSettingsPageProps) { | ||
const styles = useThemeStyles(); | ||
const {translate} = useLocalize(); | ||
|
||
const updateWorkspaceRequiresCategory = (value: boolean) => { | ||
setWorkspaceRequiresCategory(route.params.policyID, value); | ||
}; | ||
|
||
const hasEnabledOptions = OptionsListUtils.hasEnabledOptions(policyCategories ?? {}, false); | ||
return ( | ||
<AdminPolicyAccessOrNotFoundWrapper policyID={route.params.policyID}> | ||
<PaidPolicyAccessOrNotFoundWrapper policyID={route.params.policyID}> | ||
|
@@ -53,7 +64,7 @@ function WorkspaceCategoriesSettingsPage({route}: WorkspaceCategoriesSettingsPag | |
isOn={policy?.requiresCategory ?? false} | ||
accessibilityLabel={translate('workspace.categories.requiresCategory')} | ||
onToggle={updateWorkspaceRequiresCategory} | ||
disabled={!policy?.areCategoriesEnabled} | ||
disabled={!policy?.areCategoriesEnabled || !hasEnabledOptions} | ||
/> | ||
</View> | ||
</View> | ||
|
@@ -69,4 +80,8 @@ function WorkspaceCategoriesSettingsPage({route}: WorkspaceCategoriesSettingsPag | |
|
||
WorkspaceCategoriesSettingsPage.displayName = 'WorkspaceCategoriesSettingsPage'; | ||
|
||
export default WorkspaceCategoriesSettingsPage; | ||
export default withOnyx<WorkspaceCategoriesSettingsPageProps, WorkspaceCategoriesSettingsPageOnyxProps>({ | ||
policyCategories: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we're back at it again 🙂 #37508 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. Previously, I said that:
It is because we can use |
||
key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route.params.policyID}`, | ||
}, | ||
})(WorkspaceCategoriesSettingsPage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need
shouldContainPendingDeleteOption
? Don't we always want to include those?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do not use
shouldContainPendingDeleteOption
: Assume that all our categories are enabled. If we go offline and then delete all our categories, thehasEnabledOptions
still returnstrue
, which leads to the user still can toggle the "Required categories" switchThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, but that's what I meant. Don't we always want to filter our pending delete categories when checking for hasEnabledOptions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated based on this suggestion