Skip to content

Commit ef783f8

Browse files
authored
Merge pull request #78921 from mukhrr/fix/78639
2 parents 2a8057a + 167675d commit ef783f8

File tree

10 files changed

+500
-66
lines changed

10 files changed

+500
-66
lines changed

src/libs/ReportUtils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11613,6 +11613,8 @@ function prepareOnboardingOnyxData({
1161311613

1161411614
let createWorkspaceTaskReportID;
1161511615
let addExpenseApprovalsTaskReportID;
11616+
let setupTagsTaskReportID;
11617+
let setupCategoriesAndTagsTaskReportID;
1161611618
const tasksData = onboardingMessage.tasks
1161711619
.filter((task) => {
1161811620
if (engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM) {
@@ -11694,6 +11696,12 @@ function prepareOnboardingOnyxData({
1169411696
if (task.type === CONST.ONBOARDING_TASK_TYPE.ADD_EXPENSE_APPROVALS) {
1169511697
addExpenseApprovalsTaskReportID = currentTask.reportID;
1169611698
}
11699+
if (task.type === CONST.ONBOARDING_TASK_TYPE.SETUP_TAGS) {
11700+
setupTagsTaskReportID = currentTask.reportID;
11701+
}
11702+
if (task.type === CONST.ONBOARDING_TASK_TYPE.SETUP_CATEGORIES_AND_TAGS) {
11703+
setupCategoriesAndTagsTaskReportID = currentTask.reportID;
11704+
}
1169711705

1169811706
return {
1169911707
task,
@@ -11901,6 +11909,8 @@ function prepareOnboardingOnyxData({
1190111909
choice: engagementChoice,
1190211910
createWorkspace: createWorkspaceTaskReportID,
1190311911
addExpenseApprovals: addExpenseApprovalsTaskReportID,
11912+
setupTags: setupTagsTaskReportID,
11913+
setupCategoriesAndTags: setupCategoriesAndTagsTaskReportID,
1190411914
},
1190511915
},
1190611916
);
@@ -11970,6 +11980,7 @@ function prepareOnboardingOnyxData({
1197011980
choice: null,
1197111981
createWorkspace: null,
1197211982
addExpenseApprovals: null,
11983+
setupCategoriesAndTags: null,
1197311984
},
1197411985
},
1197511986
);

src/libs/actions/Policy/Category.ts

Lines changed: 90 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,40 @@ import type {ApprovalRule, ExpenseRule, MccGroup} from '@src/types/onyx/Policy';
3939
import type {PolicyCategoryExpenseLimitType} from '@src/types/onyx/PolicyCategory';
4040
import type {OnyxData} from '@src/types/onyx/Request';
4141

42+
type CreatePolicyCategoryParams = {
43+
policyID: string;
44+
categoryName: string;
45+
isSetupCategoriesTaskParentReportArchived: boolean;
46+
setupCategoryTaskReport: OnyxEntry<Report>;
47+
setupCategoryTaskParentReport: OnyxEntry<Report>;
48+
currentUserAccountID: number;
49+
hasOutstandingChildTask: boolean;
50+
parentReportAction: OnyxEntry<ReportAction>;
51+
setupCategoriesAndTagsTaskReport?: OnyxEntry<Report>;
52+
setupCategoriesAndTagsTaskParentReport?: OnyxEntry<Report>;
53+
isSetupCategoriesAndTagsTaskParentReportArchived?: boolean;
54+
setupCategoriesAndTagsHasOutstandingChildTask?: boolean;
55+
setupCategoriesAndTagsParentReportAction?: OnyxEntry<ReportAction>;
56+
policyHasTags?: boolean;
57+
};
58+
59+
type SetWorkspaceCategoryEnabledParams = {
60+
policyData: PolicyData;
61+
categoriesToUpdate: Record<string, {name: string; enabled: boolean}>;
62+
isSetupCategoriesTaskParentReportArchived: boolean;
63+
setupCategoryTaskReport: OnyxEntry<Report>;
64+
setupCategoryTaskParentReport: OnyxEntry<Report>;
65+
currentUserAccountID: number;
66+
hasOutstandingChildTask: boolean;
67+
parentReportAction: OnyxEntry<ReportAction> | undefined;
68+
setupCategoriesAndTagsTaskReport?: OnyxEntry<Report>;
69+
setupCategoriesAndTagsTaskParentReport?: OnyxEntry<Report>;
70+
isSetupCategoriesAndTagsTaskParentReportArchived?: boolean;
71+
setupCategoriesAndTagsHasOutstandingChildTask?: boolean;
72+
setupCategoriesAndTagsParentReportAction?: OnyxEntry<ReportAction>;
73+
policyHasTags?: boolean;
74+
};
75+
4276
function appendSetupCategoriesOnboardingData(
4377
onyxData: OnyxData<
4478
typeof ONYXKEYS.COLLECTION.POLICY_CATEGORIES | typeof ONYXKEYS.COLLECTION.POLICY_CATEGORIES_DRAFT | typeof ONYXKEYS.COLLECTION.REPORT | typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS
@@ -328,16 +362,22 @@ function getPolicyCategories(policyID: string) {
328362
API.read(READ_COMMANDS.GET_POLICY_CATEGORIES, params);
329363
}
330364

331-
function setWorkspaceCategoryEnabled(
332-
policyData: PolicyData,
333-
categoriesToUpdate: Record<string, {name: string; enabled: boolean}>,
334-
isSetupCategoriesTaskParentReportArchived: boolean,
335-
setupCategoryTaskReport: OnyxEntry<Report>,
336-
setupCategoryTaskParentReport: OnyxEntry<Report>,
337-
currentUserAccountID: number,
338-
hasOutstandingChildTask: boolean,
339-
parentReportAction: OnyxEntry<ReportAction> | undefined,
340-
) {
365+
function setWorkspaceCategoryEnabled({
366+
policyData,
367+
categoriesToUpdate,
368+
isSetupCategoriesTaskParentReportArchived,
369+
setupCategoryTaskReport,
370+
setupCategoryTaskParentReport,
371+
currentUserAccountID,
372+
hasOutstandingChildTask,
373+
parentReportAction,
374+
setupCategoriesAndTagsTaskReport,
375+
setupCategoriesAndTagsTaskParentReport,
376+
isSetupCategoriesAndTagsTaskParentReportArchived,
377+
setupCategoriesAndTagsHasOutstandingChildTask,
378+
setupCategoriesAndTagsParentReportAction,
379+
policyHasTags,
380+
}: SetWorkspaceCategoryEnabledParams) {
341381
const policyID = policyData.policy?.id;
342382
const policyCategoriesOptimisticData = {
343383
...Object.keys(categoriesToUpdate).reduce<PolicyCategories>((acc, key) => {
@@ -414,6 +454,18 @@ function setWorkspaceCategoryEnabled(
414454
parentReportAction,
415455
);
416456

457+
if (setupCategoriesAndTagsTaskReport && policyHasTags) {
458+
appendSetupCategoriesOnboardingData(
459+
onyxData,
460+
setupCategoriesAndTagsTaskReport,
461+
setupCategoriesAndTagsTaskParentReport,
462+
isSetupCategoriesAndTagsTaskParentReportArchived ?? false,
463+
currentUserAccountID,
464+
setupCategoriesAndTagsHasOutstandingChildTask ?? false,
465+
setupCategoriesAndTagsParentReportAction,
466+
);
467+
}
468+
417469
const parameters = {
418470
policyID,
419471
categories: JSON.stringify(Object.keys(categoriesToUpdate).map((key) => categoriesToUpdate[key])),
@@ -620,16 +672,22 @@ function removePolicyCategoryReceiptsRequired(policyData: PolicyData, categoryNa
620672
API.write(WRITE_COMMANDS.REMOVE_POLICY_CATEGORY_RECEIPTS_REQUIRED, parameters, onyxData);
621673
}
622674

623-
function createPolicyCategory(
624-
policyID: string,
625-
categoryName: string,
626-
isSetupCategoriesTaskParentReportArchived: boolean,
627-
setupCategoryTaskReport: OnyxEntry<Report>,
628-
setupCategoryTaskParentReport: OnyxEntry<Report>,
629-
currentUserAccountID: number,
630-
hasOutstandingChildTask: boolean,
631-
parentReportAction: OnyxEntry<ReportAction>,
632-
) {
675+
function createPolicyCategory({
676+
policyID,
677+
categoryName,
678+
isSetupCategoriesTaskParentReportArchived,
679+
setupCategoryTaskReport,
680+
setupCategoryTaskParentReport,
681+
currentUserAccountID,
682+
hasOutstandingChildTask,
683+
parentReportAction,
684+
setupCategoriesAndTagsTaskReport,
685+
setupCategoriesAndTagsTaskParentReport,
686+
isSetupCategoriesAndTagsTaskParentReportArchived,
687+
setupCategoriesAndTagsHasOutstandingChildTask,
688+
setupCategoriesAndTagsParentReportAction,
689+
policyHasTags,
690+
}: CreatePolicyCategoryParams) {
633691
const onyxData = buildOptimisticPolicyCategories(policyID, [categoryName]);
634692
appendSetupCategoriesOnboardingData(
635693
onyxData,
@@ -640,6 +698,18 @@ function createPolicyCategory(
640698
hasOutstandingChildTask,
641699
parentReportAction,
642700
);
701+
// Complete the combined "Set up categories and tags" task only if tags already exist
702+
if (setupCategoriesAndTagsTaskReport && policyHasTags) {
703+
appendSetupCategoriesOnboardingData(
704+
onyxData,
705+
setupCategoriesAndTagsTaskReport,
706+
setupCategoriesAndTagsTaskParentReport,
707+
isSetupCategoriesAndTagsTaskParentReportArchived ?? false,
708+
currentUserAccountID,
709+
setupCategoriesAndTagsHasOutstandingChildTask ?? false,
710+
setupCategoriesAndTagsParentReportAction,
711+
);
712+
}
643713
const parameters = {
644714
policyID,
645715
categories: JSON.stringify([{name: categoryName}]),

src/libs/actions/Policy/Tag.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ import {goBackWhenEnableFeature} from '@libs/PolicyUtils';
2929
import {pushTransactionViolationsOnyxData} from '@libs/ReportUtils';
3030
import {getTagArrayFromName} from '@libs/TransactionUtils';
3131
import type {PolicyTagList} from '@pages/workspace/tags/types';
32+
import {completeTask} from '@userActions/Task';
3233
import CONST from '@src/CONST';
3334
import ONYXKEYS from '@src/ONYXKEYS';
34-
import type {ImportedSpreadsheet, Policy, PolicyTag, PolicyTagLists, PolicyTags, RecentlyUsedTags} from '@src/types/onyx';
35+
import type {ImportedSpreadsheet, Policy, PolicyTag, PolicyTagLists, PolicyTags, RecentlyUsedTags, Report} from '@src/types/onyx';
3536
import type {OnyxValueWithOfflineFeedback} from '@src/types/onyx/OnyxCommon';
3637
import type {ApprovalRule} from '@src/types/onyx/Policy';
3738
import type {OnyxData} from '@src/types/onyx/Request';
@@ -126,7 +127,14 @@ function updateImportSpreadsheetData(tagsLength: number): OnyxData<typeof ONYXKE
126127
return onyxData;
127128
}
128129

129-
function createPolicyTag(policyID: string, tagName: string, policyTags: PolicyTagLists = {}) {
130+
function createPolicyTag(
131+
policyID: string,
132+
tagName: string,
133+
policyTags: PolicyTagLists = {},
134+
setupTagsTaskReport?: OnyxEntry<Report>,
135+
setupCategoriesAndTagsTaskReport?: OnyxEntry<Report>,
136+
policyHasCustomCategories?: boolean,
137+
) {
130138
const policyTag = PolicyUtils.getTagLists(policyTags)?.at(0) ?? ({} as PolicyTagList);
131139
const newTagName = PolicyUtils.escapeTagName(tagName);
132140

@@ -188,6 +196,19 @@ function createPolicyTag(policyID: string, tagName: string, policyTags: PolicyTa
188196
};
189197

190198
API.write(WRITE_COMMANDS.CREATE_POLICY_TAG, parameters, onyxData);
199+
200+
if (setupTagsTaskReport && (setupTagsTaskReport.stateNum !== CONST.REPORT.STATE_NUM.APPROVED || setupTagsTaskReport.statusNum !== CONST.REPORT.STATUS_NUM.APPROVED)) {
201+
completeTask(setupTagsTaskReport, false, false, undefined);
202+
}
203+
204+
// Complete the combined "Set up categories and tags" task only if categories already exist
205+
if (
206+
setupCategoriesAndTagsTaskReport &&
207+
policyHasCustomCategories &&
208+
(setupCategoriesAndTagsTaskReport.stateNum !== CONST.REPORT.STATE_NUM.APPROVED || setupCategoriesAndTagsTaskReport.statusNum !== CONST.REPORT.STATUS_NUM.APPROVED)
209+
) {
210+
completeTask(setupCategoriesAndTagsTaskReport, false, false, undefined);
211+
}
191212
}
192213

193214
function importPolicyTags(policyID: string, tags: PolicyTag[]) {

src/pages/workspace/categories/CategorySettingsPage.tsx

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {useIsFocused} from '@react-navigation/native';
2-
import React, {useEffect, useMemo, useState} from 'react';
2+
import React, {useCallback, useEffect, useMemo, useState} from 'react';
33
import {View} from 'react-native';
44
import ConfirmModal from '@components/ConfirmModal';
55
import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -15,6 +15,7 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'
1515
import useEnvironment from '@hooks/useEnvironment';
1616
import useLocalize from '@hooks/useLocalize';
1717
import useOnboardingTaskInformation from '@hooks/useOnboardingTaskInformation';
18+
import useOnyx from '@hooks/useOnyx';
1819
import usePolicyData from '@hooks/usePolicyData';
1920
import useThemeStyles from '@hooks/useThemeStyles';
2021
import {formatRequiredFieldsTitle} from '@libs/AttendeeUtils';
@@ -25,12 +26,13 @@ import Navigation from '@libs/Navigation/Navigation';
2526
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
2627
import {isDisablingOrDeletingLastEnabledCategory} from '@libs/OptionsListUtils';
2728
import {getPersonalDetailByEmail} from '@libs/PersonalDetailsUtils';
28-
import {getWorkflowApprovalsUnavailable, isControlPolicy} from '@libs/PolicyUtils';
29+
import {getTagLists, getWorkflowApprovalsUnavailable, isControlPolicy} from '@libs/PolicyUtils';
2930
import type {SettingsNavigatorParamList} from '@navigation/types';
3031
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
3132
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
3233
import {clearCategoryErrors, deleteWorkspaceCategories, setWorkspaceCategoryEnabled} from '@userActions/Policy/Category';
3334
import CONST from '@src/CONST';
35+
import ONYXKEYS from '@src/ONYXKEYS';
3436
import ROUTES from '@src/ROUTES';
3537
import SCREENS from '@src/SCREENS';
3638

@@ -70,6 +72,21 @@ function CategorySettingsPage({
7072
parentReportAction,
7173
} = useOnboardingTaskInformation(CONST.ONBOARDING_TASK_TYPE.SETUP_CATEGORIES);
7274

75+
const {
76+
taskReport: setupCategoriesAndTagsTaskReport,
77+
taskParentReport: setupCategoriesAndTagsTaskParentReport,
78+
isOnboardingTaskParentReportArchived: isSetupCategoriesAndTagsTaskParentReportArchived,
79+
hasOutstandingChildTask: setupCategoriesAndTagsHasOutstandingChildTask,
80+
parentReportAction: setupCategoriesAndTagsParentReportAction,
81+
} = useOnboardingTaskInformation(CONST.ONBOARDING_TASK_TYPE.SETUP_CATEGORIES_AND_TAGS);
82+
83+
const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, {canBeMissing: true});
84+
85+
const policyHasTags = useMemo(() => {
86+
const tagLists = getTagLists(policyTags);
87+
return tagLists.some((tagList) => Object.keys(tagList.tags ?? {}).length > 0);
88+
}, [policyTags]);
89+
7390
const navigateBack = () => {
7491
Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_CATEGORIES_ROOT.getRoute(policyID, backTo) : undefined);
7592
};
@@ -138,26 +155,47 @@ function CategorySettingsPage({
138155
return policyCategory?.pendingFields?.areCommentsRequired;
139156
}, [policyCategory?.pendingFields, policy?.isAttendeeTrackingEnabled]);
140157

141-
if (!policyCategory) {
142-
return <NotFoundPage />;
143-
}
144-
145-
const updateWorkspaceCategoryEnabled = (value: boolean) => {
146-
if (shouldPreventDisableOrDelete) {
147-
setIsCannotDeleteOrDisableLastCategoryModalVisible(true);
148-
return;
149-
}
150-
setWorkspaceCategoryEnabled(
158+
const updateWorkspaceCategoryEnabled = useCallback(
159+
(value: boolean) => {
160+
if (shouldPreventDisableOrDelete) {
161+
setIsCannotDeleteOrDisableLastCategoryModalVisible(true);
162+
return;
163+
}
164+
setWorkspaceCategoryEnabled({
165+
policyData,
166+
categoriesToUpdate: {[policyCategory.name]: {name: policyCategory.name, enabled: value}},
167+
isSetupCategoriesTaskParentReportArchived: isSetupCategoryTaskParentReportArchived,
168+
setupCategoryTaskReport,
169+
setupCategoryTaskParentReport,
170+
currentUserAccountID: currentUserPersonalDetails.accountID,
171+
hasOutstandingChildTask,
172+
parentReportAction,
173+
setupCategoriesAndTagsTaskReport,
174+
setupCategoriesAndTagsTaskParentReport,
175+
isSetupCategoriesAndTagsTaskParentReportArchived,
176+
setupCategoriesAndTagsHasOutstandingChildTask,
177+
setupCategoriesAndTagsParentReportAction,
178+
policyHasTags,
179+
});
180+
},
181+
[
182+
shouldPreventDisableOrDelete,
151183
policyData,
152-
{[policyCategory.name]: {name: policyCategory.name, enabled: value}},
184+
policyCategory.name,
153185
isSetupCategoryTaskParentReportArchived,
154186
setupCategoryTaskReport,
155187
setupCategoryTaskParentReport,
156188
currentUserPersonalDetails.accountID,
157189
hasOutstandingChildTask,
158190
parentReportAction,
159-
);
160-
};
191+
setupCategoriesAndTagsTaskReport,
192+
setupCategoriesAndTagsTaskParentReport,
193+
isSetupCategoriesAndTagsTaskParentReportArchived,
194+
setupCategoriesAndTagsHasOutstandingChildTask,
195+
setupCategoriesAndTagsParentReportAction,
196+
policyHasTags,
197+
],
198+
);
161199

162200
const navigateToEditCategory = () => {
163201
Navigation.navigate(
@@ -184,6 +222,10 @@ function CategorySettingsPage({
184222
const workflowApprovalsUnavailable = getWorkflowApprovalsUnavailable(policy);
185223
const approverDisabled = !policy?.areWorkflowsEnabled || workflowApprovalsUnavailable;
186224

225+
if (!policyCategory) {
226+
return <NotFoundPage />;
227+
}
228+
187229
return (
188230
<AccessOrNotFoundWrapper
189231
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}

0 commit comments

Comments
 (0)