Skip to content

Commit 97db8ac

Browse files
authored
Merge pull request Expensify#80448 from Tony-MK/Tags-Violations
Tags violations
2 parents e9f46ac + 0d2656a commit 97db8ac

3 files changed

Lines changed: 59 additions & 29 deletions

File tree

src/libs/actions/Policy/Tag.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,33 +121,35 @@ function updateImportSpreadsheetData(tagsLength: number): OnyxData<typeof ONYXKE
121121
}
122122

123123
function createPolicyTag(
124-
policyID: string,
124+
policyData: PolicyData,
125125
tagName: string,
126-
policyTags: PolicyTagLists = {},
127126
setupTagsTaskReport?: OnyxEntry<Report>,
128127
setupCategoriesAndTagsTaskReport?: OnyxEntry<Report>,
129128
policyHasCustomCategories?: boolean,
130129
) {
130+
const {policy, tags: policyTags} = policyData;
131+
const policyID = policy?.id;
131132
const policyTag = PolicyUtils.getTagLists(policyTags)?.at(0) ?? ({} as PolicyTagList);
132133
const newTagName = PolicyUtils.escapeTagName(tagName);
134+
const tagListsOptimisticData = {
135+
[policyTag.name]: {
136+
tags: {
137+
[newTagName]: {
138+
name: newTagName,
139+
enabled: true,
140+
errors: null,
141+
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
142+
},
143+
},
144+
},
145+
};
133146

134147
const onyxData: OnyxData<typeof ONYXKEYS.COLLECTION.POLICY_TAGS> = {
135148
optimisticData: [
136149
{
137150
onyxMethod: Onyx.METHOD.MERGE,
138151
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
139-
value: {
140-
[policyTag.name]: {
141-
tags: {
142-
[newTagName]: {
143-
name: newTagName,
144-
enabled: true,
145-
errors: null,
146-
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
147-
},
148-
},
149-
},
150-
},
152+
value: tagListsOptimisticData,
151153
},
152154
],
153155
successData: [
@@ -183,6 +185,8 @@ function createPolicyTag(
183185
],
184186
};
185187

188+
pushTransactionViolationsOnyxData(onyxData, policyData, {}, {}, tagListsOptimisticData);
189+
186190
const parameters = {
187191
policyID,
188192
tags: JSON.stringify([{name: newTagName}]),
@@ -202,10 +206,12 @@ function createPolicyTag(
202206
function importPolicyTags(policyID: string, tags: PolicyTag[]) {
203207
const onyxData = updateImportSpreadsheetData(tags.length);
204208

209+
// eslint-disable-next-line @typescript-eslint/naming-convention
210+
const optimisticTags = tags.map((tag) => ({name: tag.name, enabled: tag.enabled, 'GL Code': tag['GL Code']}));
211+
205212
const parameters = {
206213
policyID,
207-
// eslint-disable-next-line @typescript-eslint/naming-convention
208-
tags: JSON.stringify(tags.map((tag) => ({name: tag.name, enabled: tag.enabled, 'GL Code': tag['GL Code']}))),
214+
tags: JSON.stringify(optimisticTags),
209215
};
210216

211217
API.write(WRITE_COMMANDS.IMPORT_TAGS_SPREADSHEET, parameters, onyxData);

src/pages/workspace/tags/WorkspaceCreateTagPage.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import useAutoFocusInput from '@hooks/useAutoFocusInput';
1010
import useLocalize from '@hooks/useLocalize';
1111
import useOnboardingTaskInformation from '@hooks/useOnboardingTaskInformation';
1212
import useOnyx from '@hooks/useOnyx';
13+
import usePolicyData from '@hooks/usePolicyData';
1314
import useThemeStyles from '@hooks/useThemeStyles';
1415
import {addErrorMessage} from '@libs/ErrorUtils';
1516
import Navigation from '@libs/Navigation/Navigation';
@@ -31,8 +32,8 @@ type WorkspaceCreateTagPageProps =
3132

3233
function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) {
3334
const policyID = route.params.policyID;
34-
const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, {canBeMissing: true});
35-
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, {canBeMissing: true});
35+
const policyData = usePolicyData(policyID);
36+
const {tags: policyTagLists, categories: policyCategories} = policyData;
3637
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {canBeMissing: true});
3738
const setupTagsTaskReportID = introSelected?.setupTags;
3839
const [setupTagsTaskReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${setupTagsTaskReportID}`, {canBeMissing: true});
@@ -49,7 +50,7 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) {
4950
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_TAG_FORM>) => {
5051
const errors: FormInputErrors<typeof ONYXKEYS.FORMS.WORKSPACE_TAG_FORM> = {};
5152
const tagName = escapeTagName(values.tagName.trim());
52-
const {tags} = getTagList(policyTags, 0);
53+
const {tags} = getTagList(policyTagLists, 0);
5354

5455
if (!isRequiredFulfilled(tagName)) {
5556
errors.tagName = translate('workspace.tags.tagRequiredError');
@@ -64,16 +65,16 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) {
6465

6566
return errors;
6667
},
67-
[policyTags, translate],
68+
[policyTagLists, translate],
6869
);
6970

7071
const createTag = useCallback(
7172
(values: FormOnyxValues<typeof ONYXKEYS.FORMS.WORKSPACE_TAG_FORM>) => {
72-
createPolicyTag(policyID, values.tagName.trim(), policyTags, setupTagsTaskReport, setupCategoriesAndTagsTaskReport, policyHasCustomCategories);
73+
createPolicyTag(policyData, values.tagName.trim(), setupTagsTaskReport, setupCategoriesAndTagsTaskReport, policyHasCustomCategories);
7374
Keyboard.dismiss();
7475
Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : undefined);
7576
},
76-
[policyID, policyTags, isQuickSettingsFlow, backTo, setupTagsTaskReport, setupCategoriesAndTagsTaskReport, policyHasCustomCategories],
77+
[policyID, policyData, isQuickSettingsFlow, backTo, setupTagsTaskReport, setupCategoriesAndTagsTaskReport, policyHasCustomCategories],
7778
);
7879

7980
return (

tests/actions/PolicyTagTest.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,16 @@ describe('actions/Policy', () => {
288288
const newTagName = 'new tag';
289289
const fakePolicyTags = createRandomPolicyTags(tagListName);
290290

291+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy);
292+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakePolicyTags);
293+
291294
mockFetch.pause();
292295
await waitForBatchedUpdates();
293296

297+
const {result: policyData} = renderHook(() => usePolicyData(fakePolicy.id), {wrapper: OnyxListItemProvider});
298+
294299
// When creating a new tag
295-
createPolicyTag(fakePolicy.id, newTagName, fakePolicyTags);
300+
createPolicyTag(policyData.current, newTagName);
296301
await waitForBatchedUpdates();
297302

298303
// Then the tag should appear optimistically with pending state so the user sees immediate feedback
@@ -322,12 +327,17 @@ describe('actions/Policy', () => {
322327
const newTagName = 'new tag';
323328
const fakePolicyTags = createRandomPolicyTags(tagListName);
324329

330+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy);
331+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakePolicyTags);
332+
325333
mockFetch.pause();
326334
await waitForBatchedUpdates();
327335
mockFetch.fail();
328336

337+
const {result: policyData} = renderHook(() => usePolicyData(fakePolicy.id), {wrapper: OnyxListItemProvider});
338+
329339
// When the API fails
330-
createPolicyTag(fakePolicy.id, newTagName, fakePolicyTags);
340+
createPolicyTag(policyData.current, newTagName);
331341
await waitForBatchedUpdates();
332342
mockFetch.resume();
333343
await waitForBatchedUpdates();
@@ -345,11 +355,15 @@ describe('actions/Policy', () => {
345355

346356
const newTagName = 'new tag';
347357

358+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy);
359+
348360
mockFetch.pause();
349361
await waitForBatchedUpdates();
350362

363+
const {result: policyData} = renderHook(() => usePolicyData(fakePolicy.id), {wrapper: OnyxListItemProvider});
364+
351365
// When adding the first tag
352-
createPolicyTag(fakePolicy.id, newTagName, {});
366+
createPolicyTag(policyData.current, newTagName);
353367
await waitForBatchedUpdates();
354368

355369
// Then the tag should be created in a new list with pending state so the user sees immediate feedback
@@ -389,6 +403,7 @@ describe('actions/Policy', () => {
389403

390404
mockFetch.pause();
391405

406+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${fakePolicy.id}`, fakePolicy);
392407
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakePolicyTags);
393408
await waitForBatchedUpdates();
394409

@@ -398,8 +413,10 @@ describe('actions/Policy', () => {
398413
expect(result.current[0]).toBeDefined();
399414
});
400415

416+
const {result: policyData} = renderHook(() => usePolicyData(fakePolicy.id), {wrapper: OnyxListItemProvider});
417+
401418
// When using data from useOnyx hook
402-
createPolicyTag(fakePolicy.id, newTagName, result.current[0] ?? {});
419+
createPolicyTag(policyData.current, newTagName);
403420
await waitForBatchedUpdates();
404421

405422
// Then the tag should appear optimistically with pending state so the user sees immediate feedback
@@ -2243,7 +2260,9 @@ describe('actions/Policy', () => {
22432260
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakeTags);
22442261
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${fakeTaskReportID}`, fakeTaskReport);
22452262

2246-
createPolicyTag(fakePolicy.id, newTagName, fakeTags, fakeTaskReport, undefined, false);
2263+
const {result: policyData} = renderHook(() => usePolicyData(fakePolicy.id), {wrapper: OnyxListItemProvider});
2264+
2265+
createPolicyTag(policyData.current, newTagName, fakeTaskReport);
22472266

22482267
await waitForBatchedUpdates();
22492268

@@ -2276,7 +2295,9 @@ describe('actions/Policy', () => {
22762295
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakeTags);
22772296
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${fakeTaskReportID}`, fakeTaskReport);
22782297

2279-
createPolicyTag(fakePolicy.id, newTagName, fakeTags, undefined, fakeTaskReport, true);
2298+
const {result: policyData} = renderHook(() => usePolicyData(fakePolicy.id), {wrapper: OnyxListItemProvider});
2299+
2300+
createPolicyTag(policyData.current, newTagName, undefined, fakeTaskReport, true);
22802301

22812302
await waitForBatchedUpdates();
22822303

@@ -2309,7 +2330,9 @@ describe('actions/Policy', () => {
23092330
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakeTags);
23102331
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${fakeTaskReportID}`, fakeTaskReport);
23112332

2312-
createPolicyTag(fakePolicy.id, newTagName, fakeTags, undefined, fakeTaskReport, false);
2333+
const {result: policyData} = renderHook(() => usePolicyData(fakePolicy.id), {wrapper: OnyxListItemProvider});
2334+
2335+
createPolicyTag(policyData.current, newTagName, undefined, fakeTaskReport, false);
23132336

23142337
await waitForBatchedUpdates();
23152338

0 commit comments

Comments
 (0)