From 07e64270454b92d9b9b2d1317bb2cf9db0fba189 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Mon, 25 Nov 2024 04:28:18 +0530 Subject: [PATCH 1/5] feat: There is no way to identify the primary workspace, making it appear essentially random. Signed-off-by: krishna2323 --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 1 + src/libs/actions/Policy/Policy.ts | 29 ++++++++++++++++++++++ src/pages/workspace/WorkspacesListPage.tsx | 24 +++++++++++++++++- src/pages/workspace/WorkspacesListRow.tsx | 19 ++++++++++++++ 7 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 3e1ea7f0d7cc..c7686588106d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2471,6 +2471,7 @@ const translations = { other: (count: number) => `${count} selected`, }), settlementFrequency: 'Settlement frequency', + defaultNote: `Receipts sent to ${CONST.EMAIL.RECEIPTS} will appear in this workspace.`, deleteConfirmation: 'Are you sure you want to delete this workspace?', deleteWithCardsConfirmation: 'Are you sure you want to delete this workspace? This will remove all card feeds and assigned cards.', unavailable: 'Unavailable workspace', diff --git a/src/languages/es.ts b/src/languages/es.ts index d28a19fbb1be..eb70b0377b43 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2494,6 +2494,7 @@ const translations = { other: (count: number) => `${count} seleccionados`, }), settlementFrequency: 'Frecuencia de liquidación', + defaultNote: `Los recibos enviados a ${CONST.EMAIL.RECEIPTS} aparecerán en este espacio de trabajo.`, deleteConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo?', deleteWithCardsConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo? Se eliminarán todos los datos de las tarjetas y las tarjetas asignadas.', unavailable: 'Espacio de trabajo no disponible', diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 61b0c68f874f..4dcadb487124 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -122,6 +122,7 @@ export type {default as VerifyIdentityParams} from './VerifyIdentityParams'; export type {default as AcceptWalletTermsParams} from './AcceptWalletTermsParams'; export type {default as ChronosRemoveOOOEventParams} from './ChronosRemoveOOOEventParams'; export type {default as TransferWalletBalanceParams} from './TransferWalletBalanceParams'; +export type {default as UpdateActivePolicyParams} from './UpdateActivePolicyParams'; export type {default as DeleteWorkspaceParams} from './DeleteWorkspaceParams'; export type {default as CreateWorkspaceParams} from './CreateWorkspaceParams'; export type {default as UpdateWorkspaceGeneralSettingsParams} from './UpdateWorkspaceGeneralSettingsParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index d7258f1dd49e..037a87d5d5ac 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -297,6 +297,7 @@ const WRITE_COMMANDS = { CATEGORIZE_TRACKED_EXPENSE: 'CategorizeTrackedExpense', SHARE_TRACKED_EXPENSE: 'ShareTrackedExpense', LEAVE_POLICY: 'LeavePolicy', + UPDATE_ACTIVE_POLICY: 'UpdateActivePolicy', DISMISS_VIOLATION: 'DismissViolation', ACCEPT_SPOTNANA_TERMS: 'AcceptSpotnanaTerms', SEND_INVOICE: 'SendInvoice', diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 628e0918aa54..2f9353ab874b 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -49,6 +49,7 @@ import type { SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspacePayerParams, SetWorkspaceReimbursementParams, + UpdateActivePolicyParams, UpdateInvoiceCompanyNameParams, UpdateInvoiceCompanyWebsiteParams, UpdatePolicyAddressParams, @@ -788,6 +789,33 @@ function leaveWorkspace(policyID: string) { API.write(WRITE_COMMANDS.LEAVE_POLICY, params, {optimisticData, successData, failureData}); } +function updateDefaultPolicy(newPolicyID: string, oldPolicyID: string) { + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, + value: newPolicyID, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.NVP_ACTIVE_POLICY_ID, + value: oldPolicyID, + }, + ]; + + const parameters: UpdateActivePolicyParams = { + policyID: newPolicyID, + }; + + API.write(WRITE_COMMANDS.UPDATE_ACTIVE_POLICY, parameters, { + optimisticData, + failureData, + }); +} + function addBillingCardAndRequestPolicyOwnerChange( policyID: string, cardData: { @@ -4652,6 +4680,7 @@ export { verifySetupIntentAndRequestPolicyOwnerChange, updateInvoiceCompanyName, updateInvoiceCompanyWebsite, + updateDefaultPolicy, }; export type {NewCustomUnit}; diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index 67369bf7bd88..e8aee28a2207 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -112,6 +112,7 @@ function WorkspacesListPage() { const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); const [reports] = useOnyx(ONYXKEYS.COLLECTION.REPORT); const [session] = useOnyx(ONYXKEYS.SESSION); + const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); const {activeWorkspaceID, setActiveWorkspaceID} = useActiveWorkspace(); @@ -153,6 +154,7 @@ function WorkspacesListPage() { ({item, index}: GetMenuItem) => { const isAdmin = PolicyUtils.isPolicyAdmin(item as unknown as PolicyType, session?.email); const isOwner = item.ownerAccountID === session?.accountID; + const isDefault = activePolicyID === item.policyID; // Menu options to navigate to the chat report of #admins and #announce room. // For navigation, the chat report ids may be unavailable due to the missing chat reports in Onyx. // In such cases, let us use the available chat report ids from the policy. @@ -195,6 +197,14 @@ function WorkspacesListPage() { }); } + if (!isDefault && !item?.isJoinRequestPending) { + threeDotsMenuItems.push({ + icon: Expensicons.Star, + text: 'Set as default workspace', + onSelected: () => Policy.updateDefaultPolicy(item.policyID ?? '-1', activePolicyID ?? '-1'), + }); + } + return ( )} ); }, - [isLessThanMediumScreen, styles.mb2, styles.mh5, styles.ph5, styles.hoveredComponentBG, translate, styles.offlineFeedback.deleted, session?.accountID, session?.email], + [ + isLessThanMediumScreen, + styles.mb2, + styles.mh5, + styles.ph5, + styles.hoveredComponentBG, + translate, + styles.offlineFeedback.deleted, + session?.accountID, + session?.email, + activePolicyID, + ], ); const listHeaderComponent = useCallback(() => { diff --git a/src/pages/workspace/WorkspacesListRow.tsx b/src/pages/workspace/WorkspacesListRow.tsx index 5569d4fb3d70..352915d516fa 100644 --- a/src/pages/workspace/WorkspacesListRow.tsx +++ b/src/pages/workspace/WorkspacesListRow.tsx @@ -10,6 +10,7 @@ import * as Illustrations from '@components/Icon/Illustrations'; import type {PopoverMenuItem} from '@components/PopoverMenu'; import Text from '@components/Text'; import ThreeDotsMenu from '@components/ThreeDotsMenu'; +import Tooltip from '@components/Tooltip'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import WorkspacesListRowDisplayName from '@components/WorkspacesListRowDisplayName'; @@ -64,6 +65,9 @@ type WorkspacesListRowProps = WithCurrentUserPersonalDetailsProps & { /** ID of the policy */ policyID?: string; + + /** is policy defualt */ + isDefault?: boolean; }; type BrickRoadIndicatorIconProps = { @@ -107,6 +111,7 @@ function WorkspacesListRow({ shouldDisableThreeDotsMenu, isJoinRequestPending, policyID, + isDefault, }: WorkspacesListRowProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -150,6 +155,20 @@ function WorkspacesListRow({ /> )} + {!!isDefault && ( + + + + + + )} {!isJoinRequestPending && ( From 2c85e769a261beb320ac77764f29db5f3a965752 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Mon, 25 Nov 2024 04:38:44 +0530 Subject: [PATCH 2/5] add translation. Signed-off-by: krishna2323 --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/pages/workspace/WorkspacesListPage.tsx | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index c7686588106d..2e1d26d3d980 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2471,6 +2471,7 @@ const translations = { other: (count: number) => `${count} selected`, }), settlementFrequency: 'Settlement frequency', + setAsDefault: 'Set as default workspace', defaultNote: `Receipts sent to ${CONST.EMAIL.RECEIPTS} will appear in this workspace.`, deleteConfirmation: 'Are you sure you want to delete this workspace?', deleteWithCardsConfirmation: 'Are you sure you want to delete this workspace? This will remove all card feeds and assigned cards.', diff --git a/src/languages/es.ts b/src/languages/es.ts index eb70b0377b43..9b7204fb9d10 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2494,6 +2494,7 @@ const translations = { other: (count: number) => `${count} seleccionados`, }), settlementFrequency: 'Frecuencia de liquidación', + setAsDefault: 'Establecer como espacio de trabajo predeterminado', defaultNote: `Los recibos enviados a ${CONST.EMAIL.RECEIPTS} aparecerán en este espacio de trabajo.`, deleteConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo?', deleteWithCardsConfirmation: '¿Estás seguro de que quieres eliminar este espacio de trabajo? Se eliminarán todos los datos de las tarjetas y las tarjetas asignadas.', diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index e8aee28a2207..e64bd74fc188 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -200,7 +200,7 @@ function WorkspacesListPage() { if (!isDefault && !item?.isJoinRequestPending) { threeDotsMenuItems.push({ icon: Expensicons.Star, - text: 'Set as default workspace', + text: translate('workspace.common.setAsDefault'), onSelected: () => Policy.updateDefaultPolicy(item.policyID ?? '-1', activePolicyID ?? '-1'), }); } From 9a0c39929fc42c954b6c09d1d0e733431f8a8774 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Mon, 25 Nov 2024 04:47:31 +0530 Subject: [PATCH 3/5] add UpdateActivePolicyParams file. Signed-off-by: krishna2323 --- src/libs/API/parameters/UpdateActivePolicyParams.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/libs/API/parameters/UpdateActivePolicyParams.ts diff --git a/src/libs/API/parameters/UpdateActivePolicyParams.ts b/src/libs/API/parameters/UpdateActivePolicyParams.ts new file mode 100644 index 000000000000..627fc8f37e53 --- /dev/null +++ b/src/libs/API/parameters/UpdateActivePolicyParams.ts @@ -0,0 +1,5 @@ +type UpdateActivePolicyParams = { + policyID: string; +}; + +export default UpdateActivePolicyParams; From f674894d9366be2118c324470a2f6beb6f53b22e Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 12 Dec 2024 11:57:01 +0530 Subject: [PATCH 4/5] use SetNameValuePair for updating active policy. Signed-off-by: krishna2323 --- src/libs/API/parameters/SetNameValuePairParams.ts | 2 +- src/libs/API/parameters/UpdateActivePolicyParams.ts | 5 ----- src/libs/API/parameters/index.ts | 1 - src/libs/API/types.ts | 1 - src/libs/actions/Policy/Policy.ts | 9 +++++---- 5 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 src/libs/API/parameters/UpdateActivePolicyParams.ts diff --git a/src/libs/API/parameters/SetNameValuePairParams.ts b/src/libs/API/parameters/SetNameValuePairParams.ts index bc83d431224b..e09ea4cae69f 100644 --- a/src/libs/API/parameters/SetNameValuePairParams.ts +++ b/src/libs/API/parameters/SetNameValuePairParams.ts @@ -1,6 +1,6 @@ type SetNameValuePairParams = { name: string; - value: boolean; + value: boolean | string; }; export default SetNameValuePairParams; diff --git a/src/libs/API/parameters/UpdateActivePolicyParams.ts b/src/libs/API/parameters/UpdateActivePolicyParams.ts deleted file mode 100644 index 627fc8f37e53..000000000000 --- a/src/libs/API/parameters/UpdateActivePolicyParams.ts +++ /dev/null @@ -1,5 +0,0 @@ -type UpdateActivePolicyParams = { - policyID: string; -}; - -export default UpdateActivePolicyParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index ee44ebae1163..c89f98825eed 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -122,7 +122,6 @@ export type {default as VerifyIdentityParams} from './VerifyIdentityParams'; export type {default as AcceptWalletTermsParams} from './AcceptWalletTermsParams'; export type {default as ChronosRemoveOOOEventParams} from './ChronosRemoveOOOEventParams'; export type {default as TransferWalletBalanceParams} from './TransferWalletBalanceParams'; -export type {default as UpdateActivePolicyParams} from './UpdateActivePolicyParams'; export type {default as DeleteWorkspaceParams} from './DeleteWorkspaceParams'; export type {default as CreateWorkspaceParams} from './CreateWorkspaceParams'; export type {default as UpdateWorkspaceGeneralSettingsParams} from './UpdateWorkspaceGeneralSettingsParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 9ce8f4e1eca7..f632abd13105 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -299,7 +299,6 @@ const WRITE_COMMANDS = { CATEGORIZE_TRACKED_EXPENSE: 'CategorizeTrackedExpense', SHARE_TRACKED_EXPENSE: 'ShareTrackedExpense', LEAVE_POLICY: 'LeavePolicy', - UPDATE_ACTIVE_POLICY: 'UpdateActivePolicy', DISMISS_VIOLATION: 'DismissViolation', ACCEPT_SPOTNANA_TERMS: 'AcceptSpotnanaTerms', SEND_INVOICE: 'SendInvoice', diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 5e10d249440d..7d7e4ced2def 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -37,6 +37,7 @@ import type { OpenWorkspaceInvitePageParams, OpenWorkspaceParams, RequestExpensifyCardLimitIncreaseParams, + SetNameValuePairParams, SetPolicyAutomaticApprovalLimitParams, SetPolicyAutomaticApprovalRateParams, SetPolicyAutoReimbursementLimitParams, @@ -50,7 +51,6 @@ import type { SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspacePayerParams, SetWorkspaceReimbursementParams, - UpdateActivePolicyParams, UpdateInvoiceCompanyNameParams, UpdateInvoiceCompanyWebsiteParams, UpdatePolicyAddressParams, @@ -810,11 +810,12 @@ function updateDefaultPolicy(newPolicyID: string, oldPolicyID: string) { }, ]; - const parameters: UpdateActivePolicyParams = { - policyID: newPolicyID, + const parameters: SetNameValuePairParams = { + name: ONYXKEYS.NVP_ACTIVE_POLICY_ID, + value: newPolicyID, }; - API.write(WRITE_COMMANDS.UPDATE_ACTIVE_POLICY, parameters, { + API.write(WRITE_COMMANDS.SET_NAME_VALUE_PAIR, parameters, { optimisticData, failureData, }); From 0bee7bae3849ca8afcbeb7fd8e76d3192d865bc4 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Fri, 20 Dec 2024 23:37:10 +0530 Subject: [PATCH 5/5] fix eslint. Signed-off-by: krishna2323 --- src/libs/PolicyUtils.ts | 2 +- src/libs/actions/Policy/Policy.ts | 10 ++++++++-- src/pages/workspace/WorkspacesListPage.tsx | 8 ++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 4982e8660dec..55928afd6941 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1093,7 +1093,7 @@ function getCurrentTaxID(policy: OnyxEntry, taxID: string): string | und return Object.keys(policy?.taxRates?.taxes ?? {}).find((taxIDKey) => policy?.taxRates?.taxes?.[taxIDKey].previousTaxCode === taxID || taxIDKey === taxID); } -function getWorkspaceAccountID(policyID: string) { +function getWorkspaceAccountID(policyID?: string) { const policy = getPolicy(policyID); if (!policy) { diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index ed0d8a523ec4..c7444f9443b0 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -726,7 +726,10 @@ function clearWorkspaceReimbursementErrors(policyID: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimbursementChoice: null}}); } -function leaveWorkspace(policyID: string) { +function leaveWorkspace(policyID?: string) { + if (!policyID) { + return; + } const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; const workspaceChats = ReportUtils.getAllWorkspaceReports(policyID); @@ -810,7 +813,10 @@ function leaveWorkspace(policyID: string) { API.write(WRITE_COMMANDS.LEAVE_POLICY, params, {optimisticData, successData, failureData}); } -function updateDefaultPolicy(newPolicyID: string, oldPolicyID: string) { +function updateDefaultPolicy(newPolicyID?: string, oldPolicyID?: string) { + if (!newPolicyID) { + return; + } const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index 4463c1939dbc..c870bdd2ba0d 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -123,7 +123,7 @@ function WorkspacesListPage() { const isLessThanMediumScreen = isMediumScreenWidth || shouldUseNarrowLayout; // We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned. - const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyIDToDelete ?? '-1'); + const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyIDToDelete); const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`); const policyToDelete = PolicyUtils.getPolicy(policyIDToDelete); @@ -182,7 +182,7 @@ function WorkspacesListPage() { setIsSupportalActionRestrictedModalOpen(true); return; } - setPolicyIDToDelete(item.policyID ?? '-1'); + setPolicyIDToDelete(item.policyID); setPolicyNameToDelete(item.title); setIsDeleteModalOpen(true); }, @@ -194,7 +194,7 @@ function WorkspacesListPage() { threeDotsMenuItems.push({ icon: Expensicons.Exit, text: translate('common.leave'), - onSelected: Session.checkIfActionIsAllowed(() => Policy.leaveWorkspace(item.policyID ?? '-1')), + onSelected: Session.checkIfActionIsAllowed(() => Policy.leaveWorkspace(item.policyID)), }); } @@ -218,7 +218,7 @@ function WorkspacesListPage() { threeDotsMenuItems.push({ icon: Expensicons.Star, text: translate('workspace.common.setAsDefault'), - onSelected: () => Policy.updateDefaultPolicy(item.policyID ?? '-1', activePolicyID ?? '-1'), + onSelected: () => Policy.updateDefaultPolicy(item.policyID, activePolicyID), }); }