From 9dec198c228ccc86d668f3456e0f17a8133c7586 Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 13 Jun 2024 14:23:36 +0700 Subject: [PATCH 1/4] feat: disable distance rates if feature is disabled Signed-off-by: dominictb --- src/libs/actions/Policy/DistanceRate.ts | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/libs/actions/Policy/DistanceRate.ts b/src/libs/actions/Policy/DistanceRate.ts index f3f8dfb4f3c7..a37a3a15e2ff 100644 --- a/src/libs/actions/Policy/DistanceRate.ts +++ b/src/libs/actions/Policy/DistanceRate.ts @@ -88,6 +88,47 @@ function openPolicyDistanceRatesPage(policyID?: string) { } function enablePolicyDistanceRates(policyID: string, enabled: boolean) { + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const customUnitID = Object.keys(policy?.customUnits ?? {})[0]; + const customUnit = customUnitID ? policy?.customUnits?.[customUnitID] : undefined; + + console.log(customUnit); + + let onyxUpdatesToDisableDistanceRates: OnyxUpdate | undefined; + + if(!enabled) { + const rateEntries = Object.entries(customUnit?.rates ?? {}); + // find the rate to be enabled after disabling the distance rate feature + // first check the default rate + let rateEntryToBeEnabled = rateEntries.find((rate) => rate[1]?.name === 'Default Rate'); + // if the default rate is not enabled/doesn't exist, we'll switch to the first enabled rate + if(!rateEntryToBeEnabled?.[1] || !rateEntryToBeEnabled[1].enabled) { + rateEntryToBeEnabled = rateEntries.find((rate) => !!rate[1]?.enabled); + } + // if no rate is enabled, we'll switch to the first rate + if(!rateEntryToBeEnabled?.[1]) { + rateEntryToBeEnabled = rateEntries[0]; + } + + onyxUpdatesToDisableDistanceRates = { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + [customUnitID]: { + rates: Object.fromEntries(rateEntries.map((rateEntry) => { + const [rateID, rate] = rateEntry; + return [rateID, { + ...rate, + enabled: rateID === rateEntryToBeEnabled[0], + }]; + })) + }, + }, + }, + }; + } + const onyxData: OnyxData = { optimisticData: [ { @@ -126,6 +167,11 @@ function enablePolicyDistanceRates(policyID: string, enabled: boolean) { ], }; + if(onyxUpdatesToDisableDistanceRates) { + onyxData.optimisticData?.push(onyxUpdatesToDisableDistanceRates); + onyxData.successData?.push(onyxUpdatesToDisableDistanceRates); + } + const parameters: EnablePolicyDistanceRatesParams = {policyID, enabled}; API.write(WRITE_COMMANDS.ENABLE_POLICY_DISTANCE_RATES, parameters, onyxData); From e851a7d95f66b552cd3146645d81453926382c2b Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 13 Jun 2024 15:12:45 +0700 Subject: [PATCH 2/4] chore: disable all tags/categories if feature is disabled Signed-off-by: dominictb --- src/libs/actions/Policy/Category.ts | 28 +++++++++ src/libs/actions/Policy/DistanceRate.ts | 84 ++++++++++++------------- src/libs/actions/Policy/Tag.ts | 66 ++++++++++++------- 3 files changed, 111 insertions(+), 67 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 5db8be5b8a5a..02b229b01df9 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -482,6 +482,30 @@ function deleteWorkspaceCategories(policyID: string, categoryNamesToDelete: stri } function enablePolicyCategories(policyID: string, enabled: boolean) { + const onyxUpdatesToDisableCategories: OnyxUpdate[] = []; + if (!enabled) { + onyxUpdatesToDisableCategories.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, + value: Object.fromEntries( + Object.entries(allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`] ?? {}).map(([categoryName]) => [ + categoryName, + { + enabled: false, + }, + ]), + ), + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + requiresCategory: false, + }, + }, + ); + } const onyxData: OnyxData = { optimisticData: [ { @@ -520,6 +544,10 @@ function enablePolicyCategories(policyID: string, enabled: boolean) { ], }; + if (onyxUpdatesToDisableCategories.length > 0) { + onyxData.optimisticData?.push(...onyxUpdatesToDisableCategories); + } + const parameters: EnablePolicyCategoriesParams = {policyID, enabled}; API.write(WRITE_COMMANDS.ENABLE_POLICY_CATEGORIES, parameters, onyxData); diff --git a/src/libs/actions/Policy/DistanceRate.ts b/src/libs/actions/Policy/DistanceRate.ts index a37a3a15e2ff..dbd45c7cbf7f 100644 --- a/src/libs/actions/Policy/DistanceRate.ts +++ b/src/libs/actions/Policy/DistanceRate.ts @@ -88,47 +88,6 @@ function openPolicyDistanceRatesPage(policyID?: string) { } function enablePolicyDistanceRates(policyID: string, enabled: boolean) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; - const customUnitID = Object.keys(policy?.customUnits ?? {})[0]; - const customUnit = customUnitID ? policy?.customUnits?.[customUnitID] : undefined; - - console.log(customUnit); - - let onyxUpdatesToDisableDistanceRates: OnyxUpdate | undefined; - - if(!enabled) { - const rateEntries = Object.entries(customUnit?.rates ?? {}); - // find the rate to be enabled after disabling the distance rate feature - // first check the default rate - let rateEntryToBeEnabled = rateEntries.find((rate) => rate[1]?.name === 'Default Rate'); - // if the default rate is not enabled/doesn't exist, we'll switch to the first enabled rate - if(!rateEntryToBeEnabled?.[1] || !rateEntryToBeEnabled[1].enabled) { - rateEntryToBeEnabled = rateEntries.find((rate) => !!rate[1]?.enabled); - } - // if no rate is enabled, we'll switch to the first rate - if(!rateEntryToBeEnabled?.[1]) { - rateEntryToBeEnabled = rateEntries[0]; - } - - onyxUpdatesToDisableDistanceRates = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - customUnits: { - [customUnitID]: { - rates: Object.fromEntries(rateEntries.map((rateEntry) => { - const [rateID, rate] = rateEntry; - return [rateID, { - ...rate, - enabled: rateID === rateEntryToBeEnabled[0], - }]; - })) - }, - }, - }, - }; - } - const onyxData: OnyxData = { optimisticData: [ { @@ -167,9 +126,46 @@ function enablePolicyDistanceRates(policyID: string, enabled: boolean) { ], }; - if(onyxUpdatesToDisableDistanceRates) { - onyxData.optimisticData?.push(onyxUpdatesToDisableDistanceRates); - onyxData.successData?.push(onyxUpdatesToDisableDistanceRates); + if (!enabled) { + const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const customUnitID = Object.keys(policy?.customUnits ?? {})[0]; + const customUnit = customUnitID ? policy?.customUnits?.[customUnitID] : undefined; + + const rateEntries = Object.entries(customUnit?.rates ?? {}); + // find the rate to be enabled after disabling the distance rate feature + // first check the default rate + let rateEntryToBeEnabled = rateEntries.find((rate) => rate[1]?.name === 'Default Rate'); + // if the default rate is not enabled/doesn't exist, we'll switch to the first enabled rate + if (!rateEntryToBeEnabled?.[1] || !rateEntryToBeEnabled[1].enabled) { + rateEntryToBeEnabled = rateEntries.find((rate) => !!rate[1]?.enabled); + } + // if no rate is enabled, we'll switch to the first rate + if (!rateEntryToBeEnabled?.[1]) { + rateEntryToBeEnabled = rateEntries[0]; + } + + onyxData.optimisticData?.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + customUnits: { + [customUnitID]: { + rates: Object.fromEntries( + rateEntries.map((rateEntry) => { + const [rateID, rate] = rateEntry; + return [ + rateID, + { + ...rate, + enabled: rateID === rateEntryToBeEnabled[0], + }, + ]; + }), + ), + }, + }, + }, + }); } const parameters: EnablePolicyDistanceRatesParams = {policyID, enabled}; diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 85080d741011..6223b6585e3b 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -1,21 +1,21 @@ -import type {NullishDeep, OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; -import type {EnablePolicyTagsParams, OpenPolicyTagsPageParams, RenamePolicyTaglistParams, RenamePolicyTagsParams, SetPolicyTagsEnabled} from '@libs/API/parameters'; -import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; +import type { EnablePolicyTagsParams, OpenPolicyTagsPageParams, RenamePolicyTaglistParams, RenamePolicyTagsParams, SetPolicyTagsEnabled } from '@libs/API/parameters'; +import { READ_COMMANDS, WRITE_COMMANDS } from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; -import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import Log from '@libs/Log'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; +import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Policy, PolicyTag, PolicyTagList, PolicyTags, RecentlyUsedTags, Report} from '@src/types/onyx'; -import type {OnyxValueWithOfflineFeedback} from '@src/types/onyx/OnyxCommon'; -import type {Attributes, Rate} from '@src/types/onyx/Policy'; -import type {OnyxData} from '@src/types/onyx/Request'; -import {navigateWhenEnableFeature} from './Policy'; +import type { Policy, PolicyTag, PolicyTagList, PolicyTags, RecentlyUsedTags, Report } from '@src/types/onyx'; +import type { OnyxValueWithOfflineFeedback } from '@src/types/onyx/OnyxCommon'; +import type { Attributes, Rate } from '@src/types/onyx/Policy'; +import type { OnyxData } from '@src/types/onyx/Request'; +import type { NullishDeep, OnyxCollection, OnyxEntry } from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import { navigateWhenEnableFeature } from './Policy'; type NewCustomUnit = { customUnitID: string; @@ -478,7 +478,8 @@ function enablePolicyTags(policyID: string, enabled: boolean) { }, ], }; - const policyTagList = allPolicyTags?.[policyID]; + + const policyTagList = allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`]; if (!policyTagList) { const defaultTagList: PolicyTagList = { Tag: { @@ -498,7 +499,34 @@ function enablePolicyTags(policyID: string, enabled: boolean) { key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, value: null, }); - } + } else if (!enabled) { + const policyTag = PolicyUtils.getTagLists(policyTagList)[0]; + onyxData.optimisticData?.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, + value: { + [policyTag.name]: { + tags: Object.fromEntries( + Object.keys(policyTag.tags).map((tagName) => [ + tagName, + { + enabled: false, + }, + ]), + ), + }, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + requiresTag: false, + }, + }, + ); + } const parameters: EnablePolicyTagsParams = {policyID, enabled}; @@ -612,16 +640,8 @@ function setPolicyRequiresTag(policyID: string, requiresTag: boolean) { } export { - openPolicyTagsPage, - buildOptimisticPolicyRecentlyUsedTags, - setPolicyRequiresTag, - renamePolicyTaglist, - enablePolicyTags, - createPolicyTag, - renamePolicyTag, - clearPolicyTagErrors, - deletePolicyTags, - setWorkspaceTagEnabled, + buildOptimisticPolicyRecentlyUsedTags, clearPolicyTagErrors, createPolicyTag, deletePolicyTags, enablePolicyTags, openPolicyTagsPage, renamePolicyTag, renamePolicyTaglist, setPolicyRequiresTag, setWorkspaceTagEnabled }; -export type {NewCustomUnit}; + export type { NewCustomUnit }; + From c44cbc3920a64dc1d23684a4f9ef90b8a96e907f Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 13 Jun 2024 15:41:17 +0700 Subject: [PATCH 3/4] fix: prettier Signed-off-by: dominictb --- src/libs/actions/Policy/Category.ts | 10 ++-- src/libs/actions/Policy/Tag.ts | 82 ++++++++++++++++------------- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 02b229b01df9..ef00bb5390d0 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -490,11 +490,11 @@ function enablePolicyCategories(policyID: string, enabled: boolean) { key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, value: Object.fromEntries( Object.entries(allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`] ?? {}).map(([categoryName]) => [ - categoryName, - { - enabled: false, - }, - ]), + categoryName, + { + enabled: false, + }, + ]), ), }, { diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 6223b6585e3b..406b76c93c3b 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -1,21 +1,21 @@ +import type {NullishDeep, OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; -import type { EnablePolicyTagsParams, OpenPolicyTagsPageParams, RenamePolicyTaglistParams, RenamePolicyTagsParams, SetPolicyTagsEnabled } from '@libs/API/parameters'; -import { READ_COMMANDS, WRITE_COMMANDS } from '@libs/API/types'; +import type {EnablePolicyTagsParams, OpenPolicyTagsPageParams, RenamePolicyTaglistParams, RenamePolicyTagsParams, SetPolicyTagsEnabled} from '@libs/API/parameters'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; +import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import Log from '@libs/Log'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; -import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type { Policy, PolicyTag, PolicyTagList, PolicyTags, RecentlyUsedTags, Report } from '@src/types/onyx'; -import type { OnyxValueWithOfflineFeedback } from '@src/types/onyx/OnyxCommon'; -import type { Attributes, Rate } from '@src/types/onyx/Policy'; -import type { OnyxData } from '@src/types/onyx/Request'; -import type { NullishDeep, OnyxCollection, OnyxEntry } from 'react-native-onyx'; -import Onyx from 'react-native-onyx'; -import { navigateWhenEnableFeature } from './Policy'; +import type {Policy, PolicyTag, PolicyTagList, PolicyTags, RecentlyUsedTags, Report} from '@src/types/onyx'; +import type {OnyxValueWithOfflineFeedback} from '@src/types/onyx/OnyxCommon'; +import type {Attributes, Rate} from '@src/types/onyx/Policy'; +import type {OnyxData} from '@src/types/onyx/Request'; +import {navigateWhenEnableFeature} from './Policy'; type NewCustomUnit = { customUnitID: string; @@ -500,33 +500,33 @@ function enablePolicyTags(policyID: string, enabled: boolean) { value: null, }); } else if (!enabled) { - const policyTag = PolicyUtils.getTagLists(policyTagList)[0]; - onyxData.optimisticData?.push( - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, - value: { - [policyTag.name]: { - tags: Object.fromEntries( - Object.keys(policyTag.tags).map((tagName) => [ - tagName, - { - enabled: false, - }, - ]), - ), - }, + const policyTag = PolicyUtils.getTagLists(policyTagList)[0]; + onyxData.optimisticData?.push( + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, + value: { + [policyTag.name]: { + tags: Object.fromEntries( + Object.keys(policyTag.tags).map((tagName) => [ + tagName, + { + enabled: false, + }, + ]), + ), }, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - requiresTag: false, - }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + requiresTag: false, }, - ); - } + }, + ); + } const parameters: EnablePolicyTagsParams = {policyID, enabled}; @@ -640,8 +640,16 @@ function setPolicyRequiresTag(policyID: string, requiresTag: boolean) { } export { - buildOptimisticPolicyRecentlyUsedTags, clearPolicyTagErrors, createPolicyTag, deletePolicyTags, enablePolicyTags, openPolicyTagsPage, renamePolicyTag, renamePolicyTaglist, setPolicyRequiresTag, setWorkspaceTagEnabled + buildOptimisticPolicyRecentlyUsedTags, + clearPolicyTagErrors, + createPolicyTag, + deletePolicyTags, + enablePolicyTags, + openPolicyTagsPage, + renamePolicyTag, + renamePolicyTaglist, + setPolicyRequiresTag, + setWorkspaceTagEnabled, }; - export type { NewCustomUnit }; - +export type {NewCustomUnit}; From 0bbe02165173314ecbec85347f3ecc2477716c44 Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 20 Jun 2024 11:50:40 +0700 Subject: [PATCH 4/4] fix: always enable the default first rate entry --- src/libs/actions/Policy/DistanceRate.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/libs/actions/Policy/DistanceRate.ts b/src/libs/actions/Policy/DistanceRate.ts index af92de5d2a1b..c10e4d87484c 100644 --- a/src/libs/actions/Policy/DistanceRate.ts +++ b/src/libs/actions/Policy/DistanceRate.ts @@ -133,16 +133,7 @@ function enablePolicyDistanceRates(policyID: string, enabled: boolean) { const rateEntries = Object.entries(customUnit?.rates ?? {}); // find the rate to be enabled after disabling the distance rate feature - // first check the default rate - let rateEntryToBeEnabled = rateEntries.find((rate) => rate[1]?.name === 'Default Rate'); - // if the default rate is not enabled/doesn't exist, we'll switch to the first enabled rate - if (!rateEntryToBeEnabled?.[1] || !rateEntryToBeEnabled[1].enabled) { - rateEntryToBeEnabled = rateEntries.find((rate) => !!rate[1]?.enabled); - } - // if no rate is enabled, we'll switch to the first rate - if (!rateEntryToBeEnabled?.[1]) { - rateEntryToBeEnabled = rateEntries[0]; - } + const rateEntryToBeEnabled = rateEntries[0]; onyxData.optimisticData?.push({ onyxMethod: Onyx.METHOD.MERGE,