From ac53e9ab286a6410a7fb96150767718ee76a1d97 Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 5 Jul 2024 18:16:39 +0700 Subject: [PATCH 1/6] fix: optimistically add report field for all expense reports when creating report field Signed-off-by: dominictb --- src/libs/actions/Policy/ReportFields.ts | 37 +++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/Policy/ReportFields.ts b/src/libs/actions/Policy/ReportFields.ts index 220432cbc3c6..46d85d1e0d20 100644 --- a/src/libs/actions/Policy/ReportFields.ts +++ b/src/libs/actions/Policy/ReportFields.ts @@ -1,4 +1,4 @@ -import type {NullishDeep, OnyxCollection} from 'react-native-onyx'; +import type {NullishDeep, OnyxCollection, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; import type {CreateWorkspaceReportFieldParams} from '@libs/API/parameters'; @@ -10,7 +10,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {WorkspaceReportFieldsForm} from '@src/types/form/WorkspaceReportFieldsForm'; import INPUT_IDS from '@src/types/form/WorkspaceReportFieldsForm'; -import type {Policy, PolicyReportField} from '@src/types/onyx'; +import type {Policy, PolicyReportField, Report} from '@src/types/onyx'; import type {OnyxData} from '@src/types/onyx/Request'; let listValues: string[]; @@ -27,6 +27,13 @@ Onyx.connect({ }, }); +let allReports: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: (value) => (allReports = value), +}); + const allPolicies: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.POLICY, @@ -136,7 +143,7 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR const previousFieldList = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]?.fieldList ?? {}; const fieldID = generateFieldID(name); const fieldKey = ReportUtils.getReportFieldKey(fieldID); - const newReportField: PolicyReportField = { + const newReportField: Omit = { name, type, defaultValue: initialValue, @@ -145,11 +152,16 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR fieldID, orderWeight: Object.keys(previousFieldList).length + 1, deletable: false, - value: type === CONST.REPORT_FIELD_TYPES.LIST ? CONST.REPORT_FIELD_TYPES.LIST : null, keys: [], externalIDs: [], isTax: false, }; + + const optimisticReportFieldDataForPolicy: PolicyReportField = { + ...newReportField, + value: type === CONST.REPORT_FIELD_TYPES.LIST ? CONST.REPORT_FIELD_TYPES.LIST : null, + }; + const onyxData: OnyxData = { optimisticData: [ { @@ -157,7 +169,7 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR onyxMethod: Onyx.METHOD.MERGE, value: { fieldList: { - [fieldKey]: newReportField, + [fieldKey]: optimisticReportFieldDataForPolicy, }, pendingFields: { [fieldKey]: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, @@ -196,6 +208,21 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR }, ], }; + + const policyExpenseReports = Object.values(allReports ?? {}).filter((report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE) as Report[]; + + onyxData.optimisticData?.push( + ...(policyExpenseReports.map((report) => ({ + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, + onyxMethod: Onyx.METHOD.MERGE, + value: { + fieldList: { + [fieldKey]: newReportField, + }, + }, + })) as OnyxUpdate[]), + ); + const parameters: CreateWorkspaceReportFieldParams = { policyID, reportFields: JSON.stringify([newReportField]), From d2e90b530a6de7a601b78830c59e66aa18f071ba Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 5 Jul 2024 18:31:06 +0700 Subject: [PATCH 2/6] fix: prettier Signed-off-by: dominictb --- src/libs/actions/Policy/ReportFields.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/Policy/ReportFields.ts b/src/libs/actions/Policy/ReportFields.ts index 46d85d1e0d20..e14fd9bfd772 100644 --- a/src/libs/actions/Policy/ReportFields.ts +++ b/src/libs/actions/Policy/ReportFields.ts @@ -213,14 +213,14 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR onyxData.optimisticData?.push( ...(policyExpenseReports.map((report) => ({ - key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, - onyxMethod: Onyx.METHOD.MERGE, - value: { - fieldList: { - [fieldKey]: newReportField, - }, + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, + onyxMethod: Onyx.METHOD.MERGE, + value: { + fieldList: { + [fieldKey]: newReportField, }, - })) as OnyxUpdate[]), + }, + })) as OnyxUpdate[]), ); const parameters: CreateWorkspaceReportFieldParams = { From 4a9b051c906195e1772e4e039fea5fdae7d087cd Mon Sep 17 00:00:00 2001 From: dominictb Date: Tue, 9 Jul 2024 16:43:34 +0700 Subject: [PATCH 3/6] fix: polish implementation Signed-off-by: dominictb --- src/libs/actions/Policy/ReportField.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/Policy/ReportField.ts b/src/libs/actions/Policy/ReportField.ts index a3db5a74d5c5..43a950207834 100644 --- a/src/libs/actions/Policy/ReportField.ts +++ b/src/libs/actions/Policy/ReportField.ts @@ -4,6 +4,7 @@ import * as API from '@libs/API'; import type {CreateWorkspaceReportFieldParams, PolicyReportFieldsReplace} from '@libs/API/parameters'; import {WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; +import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import {generateFieldID} from '@libs/WorkspaceReportFieldsUtils'; import CONST from '@src/CONST'; @@ -28,13 +29,6 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection; -Onyx.connect({ - key: ONYXKEYS.COLLECTION.REPORT, - waitForCollectionCallback: true, - callback: (value) => (allReports = value), -}); - const allPolicies: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.POLICY, @@ -143,7 +137,7 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR const previousFieldList = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]?.fieldList ?? {}; const fieldID = generateFieldID(name); const fieldKey = ReportUtils.getReportFieldKey(fieldID); - const newReportField: OnyxValueWithOfflineFeedback = { + const newReportField: Omit, 'value'> = { name, type, defaultValue: initialValue, @@ -203,8 +197,9 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR }, ], }; - - const policyExpenseReports = Object.values(allReports ?? {}).filter((report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE) as Report[]; + const policyExpenseReports = Object.values(ReportConnection.getAllReports() ?? {}).filter( + (report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE, + ) as Report[]; onyxData.optimisticData?.push( ...(policyExpenseReports.map((report) => ({ From b205b8c3efcfe59d90e522858f381eaf7326a9d8 Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 11 Jul 2024 22:38:56 +0700 Subject: [PATCH 4/6] fix: fix TS issue Signed-off-by: dominictb --- src/libs/actions/Policy/ReportField.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy/ReportField.ts b/src/libs/actions/Policy/ReportField.ts index 61c514f660d6..837dda688fbd 100644 --- a/src/libs/actions/Policy/ReportField.ts +++ b/src/libs/actions/Policy/ReportField.ts @@ -1,5 +1,5 @@ import cloneDeep from 'lodash/cloneDeep'; -import type {NullishDeep, OnyxCollection} from 'react-native-onyx'; +import type {NullishDeep, OnyxCollection, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; import type { From 42321d38db7b5b0d9314dbd82b773cdd56297500 Mon Sep 17 00:00:00 2001 From: dominictb Date: Sat, 13 Jul 2024 15:41:51 +0700 Subject: [PATCH 5/6] fix: update TS typing issue Signed-off-by: dominictb --- src/libs/actions/Policy/ReportField.ts | 54 +++++++++++++------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/libs/actions/Policy/ReportField.ts b/src/libs/actions/Policy/ReportField.ts index 837dda688fbd..fb180b4b4ac7 100644 --- a/src/libs/actions/Policy/ReportField.ts +++ b/src/libs/actions/Policy/ReportField.ts @@ -164,19 +164,36 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR value: type === CONST.REPORT_FIELD_TYPES.LIST ? CONST.REPORT_FIELD_TYPES.LIST : null, }; - const onyxData: OnyxData = { - optimisticData: [ - { - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - onyxMethod: Onyx.METHOD.MERGE, - value: { - fieldList: { - [fieldKey]: {...optimisticReportFieldDataForPolicy, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, - }, - errorFields: null, + const policyExpenseReports = Object.values(ReportConnection.getAllReports() ?? {}).filter( + (report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE, + ) as Report[]; + + const onyxOperationsToAddExpenseReportFields = policyExpenseReports.map((report) => ({ + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, + onyxMethod: Onyx.METHOD.MERGE, + value: { + fieldList: { + [fieldKey]: {...newReportField, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + }, + }, + })); + + const optimisticData = [ + ...onyxOperationsToAddExpenseReportFields, + { + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + onyxMethod: Onyx.METHOD.MERGE, + value: { + fieldList: { + [fieldKey]: {...optimisticReportFieldDataForPolicy, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, }, + errorFields: null, }, - ], + }, + ] as OnyxUpdate[]; + + const onyxData: OnyxData = { + optimisticData, successData: [ { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, @@ -204,21 +221,6 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR }, ], }; - const policyExpenseReports = Object.values(ReportConnection.getAllReports() ?? {}).filter( - (report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE, - ) as Report[]; - - onyxData.optimisticData?.push( - ...(policyExpenseReports.map((report) => ({ - key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, - onyxMethod: Onyx.METHOD.MERGE, - value: { - fieldList: { - [fieldKey]: newReportField, - }, - }, - })) as OnyxUpdate[]), - ); const parameters: CreateWorkspaceReportFieldParams = { policyID, From d0b136f1e23d13997eb7ec29d6456eb6b5395448 Mon Sep 17 00:00:00 2001 From: dominictb Date: Mon, 22 Jul 2024 17:05:24 +0700 Subject: [PATCH 6/6] fix: remove report field optimistic data in case of failure --- src/libs/actions/Policy/ReportField.ts | 59 +++++++++++++++----------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/libs/actions/Policy/ReportField.ts b/src/libs/actions/Policy/ReportField.ts index 394ca1f65e38..9217519035a2 100644 --- a/src/libs/actions/Policy/ReportField.ts +++ b/src/libs/actions/Policy/ReportField.ts @@ -183,18 +183,7 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR (report) => report?.policyID === policyID && report.type === CONST.REPORT.TYPE.EXPENSE, ) as Report[]; - const onyxOperationsToAddExpenseReportFields = policyExpenseReports.map((report) => ({ - key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, - onyxMethod: Onyx.METHOD.MERGE, - value: { - fieldList: { - [fieldKey]: {...newReportField, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, - }, - }, - })); - const optimisticData = [ - ...onyxOperationsToAddExpenseReportFields, { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, onyxMethod: Onyx.METHOD.MERGE, @@ -205,6 +194,39 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR errorFields: null, }, }, + ...policyExpenseReports.map((report) => ({ + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, + onyxMethod: Onyx.METHOD.MERGE, + value: { + fieldList: { + [fieldKey]: {...newReportField, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + }, + }, + })), + ] as OnyxUpdate[]; + + const failureData = [ + { + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + onyxMethod: Onyx.METHOD.MERGE, + value: { + fieldList: { + [fieldKey]: null, + }, + errorFields: { + [fieldKey]: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.reportFields.genericFailureMessage'), + }, + }, + }, + ...policyExpenseReports.map((report) => ({ + key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, + onyxMethod: Onyx.METHOD.MERGE, + value: { + fieldList: { + [fieldKey]: null, + }, + }, + })), ] as OnyxUpdate[]; const onyxData: OnyxData = { @@ -221,20 +243,7 @@ function createReportField(policyID: string, {name, type, initialValue}: CreateR }, }, ], - failureData: [ - { - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - onyxMethod: Onyx.METHOD.MERGE, - value: { - fieldList: { - [fieldKey]: null, - }, - errorFields: { - [fieldKey]: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.reportFields.genericFailureMessage'), - }, - }, - }, - ], + failureData, }; const parameters: CreateWorkspaceReportFieldParams = {