From adeeb36d665726cbd7171aa1745e5f0de06d933f Mon Sep 17 00:00:00 2001 From: Francois Laithier Date: Fri, 22 Aug 2025 11:46:06 -0700 Subject: [PATCH] Revert "Merge pull request #67412 from callstack-internal/duplicate-workspace" This reverts commit 8f4897f001a2f8977480fb8fd9ba9cfb723dcd74, reversing changes made to 485a092e3c00483f259420b593e4403045abe5b6. --- src/ONYXKEYS.ts | 7 - src/ROUTES.ts | 8 - src/SCREENS.ts | 2 - src/components/WorkspaceConfirmationForm.tsx | 32 +- src/hooks/useWorkspaceConfirmationAvatar.tsx | 28 -- src/languages/de.ts | 18 - src/languages/en.ts | 18 - src/languages/es.ts | 18 - src/languages/fr.ts | 18 - src/languages/it.ts | 22 +- src/languages/ja.ts | 18 - src/languages/nl.ts | 18 - src/languages/pl.ts | 20 +- src/languages/pt-BR.ts | 18 - src/languages/zh-hans.ts | 18 - .../parameters/DuplicateWorkspaceParams.ts | 20 - src/libs/API/parameters/index.ts | 1 - src/libs/API/types.ts | 2 - .../ModalStackNavigators/index.tsx | 7 - .../Navigators/RightModalNavigator.tsx | 4 - src/libs/Navigation/linkingConfig/config.ts | 6 - src/libs/Navigation/types.ts | 11 - src/libs/actions/Policy/Policy.ts | 305 +-------------- src/libs/getFirstAlphaNumericCharacter.ts | 8 - src/pages/workspace/WorkspacesListPage.tsx | 52 +-- src/pages/workspace/WorkspacesListRow.tsx | 17 +- .../duplicate/WorkspaceDuplicateForm.tsx | 162 -------- .../duplicate/WorkspaceDuplicatePage.tsx | 36 -- .../WorkspaceDuplicateSelectFeaturesForm.tsx | 351 ------------------ .../WorkspaceDuplicateSelectFeaturesPage.tsx | 33 -- src/pages/workspace/duplicate/utils.ts | 79 ---- src/types/form/WorkspaceDuplicateForm.tsx | 18 - src/types/form/index.ts | 1 - src/types/onyx/DuplicateWorkspace.ts | 22 -- src/types/onyx/index.ts | 2 - 35 files changed, 34 insertions(+), 1366 deletions(-) delete mode 100644 src/hooks/useWorkspaceConfirmationAvatar.tsx delete mode 100644 src/libs/API/parameters/DuplicateWorkspaceParams.ts delete mode 100644 src/libs/getFirstAlphaNumericCharacter.ts delete mode 100644 src/pages/workspace/duplicate/WorkspaceDuplicateForm.tsx delete mode 100644 src/pages/workspace/duplicate/WorkspaceDuplicatePage.tsx delete mode 100644 src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx delete mode 100644 src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesPage.tsx delete mode 100644 src/pages/workspace/duplicate/utils.ts delete mode 100644 src/types/form/WorkspaceDuplicateForm.tsx delete mode 100644 src/types/onyx/DuplicateWorkspace.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index a70273e8d4332..57bf7fb6f0231 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -466,9 +466,6 @@ const ONYXKEYS = { NVP_PRIVATE_CANCELLATION_DETAILS: 'nvp_private_cancellationDetails', - /** Stores the information about duplicated workspace */ - DUPLICATE_WORKSPACE: 'duplicateWorkspace', - /** Stores the information about currently edited advanced approval workflow */ APPROVAL_WORKFLOW: 'approvalWorkflow', @@ -686,8 +683,6 @@ const ONYXKEYS = { WORKSPACE_CATEGORY_FORM: 'workspaceCategoryForm', WORKSPACE_CONFIRMATION_FORM: 'workspaceConfirmationForm', WORKSPACE_CONFIRMATION_FORM_DRAFT: 'workspaceConfirmationFormDraft', - WORKSPACE_DUPLICATE_FORM: 'workspaceDuplicateForm', - WORKSPACE_DUPLICATE_FORM_DRAFT: 'workspaceDuplicateFormDraft', WORKSPACE_CATEGORY_FORM_DRAFT: 'workspaceCategoryFormDraft', WORKSPACE_CATEGORY_DESCRIPTION_HINT_FORM: 'workspaceCategoryDescriptionHintForm', WORKSPACE_CATEGORY_DESCRIPTION_HINT_FORM_DRAFT: 'workspaceCategoryDescriptionHintFormDraft', @@ -894,7 +889,6 @@ type OnyxFormValuesMapping = { [ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: FormTypes.WorkspaceSettingsForm; [ONYXKEYS.FORMS.WORKSPACE_CATEGORY_FORM]: FormTypes.WorkspaceCategoryForm; [ONYXKEYS.FORMS.WORKSPACE_CONFIRMATION_FORM]: FormTypes.WorkspaceConfirmationForm; - [ONYXKEYS.FORMS.WORKSPACE_DUPLICATE_FORM]: FormTypes.WorkspaceDuplicateForm; [ONYXKEYS.FORMS.ONBOARDING_WORKSPACE_DETAILS_FORM]: FormTypes.WorkspaceConfirmationForm; [ONYXKEYS.FORMS.WORKSPACE_TAG_FORM]: FormTypes.WorkspaceTagForm; [ONYXKEYS.FORMS.WORKSPACE_TAX_CUSTOM_NAME]: FormTypes.WorkspaceTaxCustomName; @@ -1196,7 +1190,6 @@ type OnyxValuesMapping = { [ONYXKEYS.ADD_NEW_COMPANY_CARD]: OnyxTypes.AddNewCompanyCardFeed; [ONYXKEYS.ASSIGN_CARD]: OnyxTypes.AssignCard; [ONYXKEYS.MOBILE_SELECTION_MODE]: boolean; - [ONYXKEYS.DUPLICATE_WORKSPACE]: OnyxTypes.DuplicateWorkspace; [ONYXKEYS.NVP_FIRST_DAY_FREE_TRIAL]: string; [ONYXKEYS.NVP_LAST_DAY_FREE_TRIAL]: string; [ONYXKEYS.NVP_BILLING_FUND_ID]: number; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index fc327c404852f..d3ec33acb3709 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1876,14 +1876,6 @@ const ROUTES = { return getUrlWithBackToParam(`workspaces/${policyID}/per-diem`, backTo); }, }, - WORKSPACE_DUPLICATE: { - route: 'workspace/:policyID/duplicate', - getRoute: (policyID: string, backTo?: string) => getUrlWithBackToParam(`workspace/${policyID}/duplicate`, backTo), - }, - WORKSPACE_DUPLICATE_SELECT_FEATURES: { - route: 'workspace/:policyID/duplicate/select-features', - getRoute: (policyID: string, backTo?: string) => getUrlWithBackToParam(`workspace/${policyID}/duplicate/select-features`, backTo), - }, WORKSPACE_RECEIPT_PARTNERS: { route: 'workspaces/:policyID/receipt-partners', getRoute: (policyID: string | undefined, backTo?: string) => { diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 4d9043da65a09..9a7c01be8fbb4 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -192,7 +192,6 @@ const SCREENS = { REPORT_DETAILS: 'Report_Details', REPORT_CHANGE_WORKSPACE: 'ReportChangeWorkspace', WORKSPACE_CONFIRMATION: 'Workspace_Confirmation', - WORKSPACE_DUPLICATE: 'Workspace_Duplicate', REPORT_SETTINGS: 'Report_Settings', REPORT_DESCRIPTION: 'Report_Description', PARTICIPANTS: 'Participants', @@ -389,7 +388,6 @@ const SCREENS = { }, WORKSPACE_CONFIRMATION: {ROOT: 'Workspace_Confirmation_Root'}, - WORKSPACE_DUPLICATE: {ROOT: 'Workspace_Duplicate_Root', SELECT_FEATURES: 'Workspace_Duplicate_Select_Features'}, WORKSPACES_LIST: 'Workspaces_List', diff --git a/src/components/WorkspaceConfirmationForm.tsx b/src/components/WorkspaceConfirmationForm.tsx index 31a933b66fde4..d789e153755f0 100644 --- a/src/components/WorkspaceConfirmationForm.tsx +++ b/src/components/WorkspaceConfirmationForm.tsx @@ -4,11 +4,9 @@ import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWorkspaceConfirmationAvatar from '@hooks/useWorkspaceConfirmationAvatar'; import {generateDefaultWorkspaceName, generatePolicyID} from '@libs/actions/Policy/Policy'; import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; import {addErrorMessage} from '@libs/ErrorUtils'; -import getFirstAlphaNumericCharacter from '@libs/getFirstAlphaNumericCharacter'; import Navigation from '@libs/Navigation/Navigation'; import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils'; import {isRequiredFulfilled} from '@libs/ValidationUtils'; @@ -16,6 +14,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import INPUT_IDS from '@src/types/form/WorkspaceConfirmationForm'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; +import Avatar from './Avatar'; import AvatarWithImagePicker from './AvatarWithImagePicker'; import CurrencyPicker from './CurrencyPicker'; import FormProvider from './Form/FormProvider'; @@ -27,6 +26,13 @@ import ScrollView from './ScrollView'; import Text from './Text'; import TextInput from './TextInput'; +function getFirstAlphaNumericCharacter(str = '') { + return str + .normalize('NFD') + .replace(/[^0-9a-z]/gi, '') + .toUpperCase()[0]; +} + type WorkspaceConfirmationSubmitFunctionParams = { name: string; currency: string; @@ -94,12 +100,22 @@ function WorkspaceConfirmationForm({onSubmit, policyOwnerEmail = '', onBackButto const stashedLocalAvatarImage = workspaceAvatar?.avatarUri ?? undefined; - const DefaultAvatar = useWorkspaceConfirmationAvatar({ - policyID, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing cannot be used if left side can be empty string - source: stashedLocalAvatarImage || getDefaultWorkspaceAvatar(workspaceNameFirstCharacter), - name: workspaceNameFirstCharacter, - }); + const DefaultAvatar = useCallback( + () => ( + + ), + [workspaceAvatar?.avatarUri, workspaceNameFirstCharacter, styles.alignSelfCenter, styles.avatarXLarge, policyID], + ); return ( <> diff --git a/src/hooks/useWorkspaceConfirmationAvatar.tsx b/src/hooks/useWorkspaceConfirmationAvatar.tsx deleted file mode 100644 index 90967f4a92e96..0000000000000 --- a/src/hooks/useWorkspaceConfirmationAvatar.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, {useCallback} from 'react'; -import Avatar from '@components/Avatar'; -import * as Expensicons from '@components/Icon/Expensicons'; -import type {AvatarSource} from '@libs/UserUtils'; -import CONST from '@src/CONST'; -import useThemeStyles from './useThemeStyles'; - -function useWorkspaceConfirmationAvatar({policyID, source, name}: {policyID: string | undefined; source: AvatarSource; name: string}) { - const styles = useThemeStyles(); - - return useCallback( - () => ( - - ), - [name, policyID, source, styles.alignSelfCenter, styles.avatarXLarge], - ); -} - -export default useWorkspaceConfirmationAvatar; diff --git a/src/languages/de.ts b/src/languages/de.ts index 5c0fe3af7ba2b..0b679990bc6d0 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -320,7 +320,6 @@ const translations = { count: 'Zählen', cancel: 'Abbrechen', dismiss: 'Verwerfen', - proceed: 'Fortfahren', yes: 'Ja', no: 'No', ok: 'OK', @@ -3461,14 +3460,12 @@ const translations = { customField1: 'Benutzerdefiniertes Feld 1', customField2: 'Benutzerdefiniertes Feld 2', customFieldHint: 'Fügen Sie benutzerdefinierten Code hinzu, der für alle Ausgaben dieses Mitglieds gilt.', - reports: 'Berichte', reportFields: 'Berichtsfelder', reportTitle: 'Berichtstitel', reportField: 'Berichtsfeld', taxes: 'Steuern', bills: 'Rechnungen', invoices: 'Rechnungen', - perDiem: 'Per diem', travel: 'Reisen', members: 'Mitglieder', accounting: 'Buchhaltung', @@ -3481,7 +3478,6 @@ const translations = { testTransactions: 'Transaktionen testen', issueAndManageCards: 'Karten ausstellen und verwalten', reconcileCards: 'Karten abstimmen', - selectAll: 'Alle auswählen', selected: () => ({ one: '1 ausgewählt', other: (count: number) => `${count} ausgewählt`, @@ -3495,8 +3491,6 @@ const translations = { memberNotFound: 'Mitglied nicht gefunden. Um ein neues Mitglied zum Arbeitsbereich einzuladen, verwenden Sie bitte die Einladungsschaltfläche oben.', notAuthorized: `Sie haben keinen Zugriff auf diese Seite. Wenn Sie versuchen, diesem Arbeitsbereich beizutreten, bitten Sie einfach den Besitzer des Arbeitsbereichs, Sie als Mitglied hinzuzufügen. Etwas anderes? Kontaktieren Sie ${CONST.EMAIL.CONCIERGE}.`, goToWorkspace: 'Zum Arbeitsbereich gehen', - duplicateWorkspace: 'Arbeitsbereich duplizieren', - duplicateWorkspacePrefix: 'Duplizieren', goToWorkspaces: 'Zu Arbeitsbereichen gehen', clearFilter: 'Filter löschen', workspaceName: 'Arbeitsbereichsname', @@ -4905,18 +4899,6 @@ const translations = { taxCode: 'Steuercode', updateTaxCodeFailureMessage: 'Beim Aktualisieren des Steuercodes ist ein Fehler aufgetreten, bitte versuchen Sie es erneut.', }, - duplicateWorkspace: { - title: 'Benennen Sie Ihren neuen Arbeitsbereich', - selectFeatures: 'Auswählen der zu kopierenden Features', - whichFeatures: 'Welche Funktionen möchten Sie in Ihren neuen Arbeitsbereich kopieren?', - confirmDuplicate: '\n\nMöchten Sie fortfahren?', - categories: 'Kategorien und Ihre Auto-Kategorisierungsregeln', - reimbursementAccount: 'Erstattungskonto', - delayedSubmission: 'verspätete Einreichung', - welcomeNote: 'Bitte beginnen Sie mit der Nutzung meines neuen Arbeitsbereichs', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `Sie sind dabei, ${newWorkspaceName ?? ''} zu erstellen und mit ${totalMembers ?? 0} Mitgliedern aus dem ursprünglichen Arbeitsbereich zu teilen.`, - }, emptyWorkspace: { title: 'Sie haben keine Arbeitsbereiche', subtitle: 'Verfolgen Sie Belege, erstatten Sie Ausgaben, verwalten Sie Reisen, senden Sie Rechnungen und mehr.', diff --git a/src/languages/en.ts b/src/languages/en.ts index f1dd43658dfb5..a436b5a5d4e2b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -312,7 +312,6 @@ const translations = { count: 'Count', cancel: 'Cancel', dismiss: 'Dismiss', - proceed: 'Proceed', yes: 'Yes', no: 'No', ok: 'OK', @@ -3458,14 +3457,12 @@ const translations = { customField1: 'Custom field 1', customField2: 'Custom field 2', customFieldHint: 'Add custom coding that applies to all spend from this member.', - reports: 'Reports', reportFields: 'Report fields', reportTitle: 'Report title', reportField: 'Report field', taxes: 'Taxes', bills: 'Bills', invoices: 'Invoices', - perDiem: 'Per diem', travel: 'Travel', members: 'Members', accounting: 'Accounting', @@ -3478,7 +3475,6 @@ const translations = { testTransactions: 'Test transactions', issueAndManageCards: 'Issue and manage cards', reconcileCards: 'Reconcile cards', - selectAll: 'Select all', selected: () => ({ one: '1 selected', other: (count: number) => `${count} selected`, @@ -3492,8 +3488,6 @@ const translations = { memberNotFound: 'Member not found. To invite a new member to the workspace, please use the invite button above.', notAuthorized: `You don't have access to this page. If you're trying to join this workspace, just ask the workspace owner to add you as a member. Something else? Reach out to ${CONST.EMAIL.CONCIERGE}.`, goToWorkspace: 'Go to workspace', - duplicateWorkspace: 'Duplicate Workspace', - duplicateWorkspacePrefix: 'Duplicate', goToWorkspaces: 'Go to workspaces', clearFilter: 'Clear filter', workspaceName: 'Workspace name', @@ -4888,18 +4882,6 @@ const translations = { taxCode: 'Tax code', updateTaxCodeFailureMessage: 'An error occurred while updating the tax code, please try again', }, - duplicateWorkspace: { - title: 'Name your new workspace', - selectFeatures: 'Select features to copy', - whichFeatures: 'Which features do you want to copy over to your new workspace?', - confirmDuplicate: '\n\nDo you want to continue?', - categories: 'categories and your auto-categorization rules', - reimbursementAccount: 'reimbursement account', - welcomeNote: 'Please start using my new workspace', - delayedSubmission: 'delayed submission', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `You’re about to create and share ${newWorkspaceName ?? ''} with ${totalMembers ?? 0} members from the original workspace.`, - }, emptyWorkspace: { title: 'You have no workspaces', subtitle: 'Track receipts, reimburse expenses, manage travel, send invoices, and more.', diff --git a/src/languages/es.ts b/src/languages/es.ts index 082eb66a269f7..ab5b7d735ab71 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -302,7 +302,6 @@ const translations = { count: 'Contar', cancel: 'Cancelar', dismiss: 'Descartar', - proceed: 'Proceed', yes: 'Sí', no: 'No', ok: 'OK', @@ -3446,13 +3445,11 @@ const translations = { customField1: 'Campo personalizado 1', customField2: 'Campo personalizado 2', customFieldHint: 'Añade una codificación personalizada que se aplique a todos los gastos de este miembro.', - reports: 'Informes', reportFields: 'Campos de informe', reportTitle: 'El título del informe.', taxes: 'Impuestos', bills: 'Pagar facturas', invoices: 'Facturas', - perDiem: 'Per diem', travel: 'Viajes', members: 'Miembros', accounting: 'Contabilidad', @@ -3465,7 +3462,6 @@ const translations = { testTransactions: 'Transacciones de prueba', issueAndManageCards: 'Emitir y gestionar tarjetas', reconcileCards: 'Reconciliar tarjetas', - selectAll: 'Seleccionar todo', selected: () => ({ one: '1 seleccionado', other: (count: number) => `${count} seleccionados`, @@ -3479,8 +3475,6 @@ const translations = { memberNotFound: 'Miembro no encontrado. Para invitar a un nuevo miembro al espacio de trabajo, por favor, utiliza el botón invitar que está arriba.', notAuthorized: `No tienes acceso a esta página. Si estás intentando unirte a este espacio de trabajo, pide al dueño del espacio de trabajo que te añada como miembro. ¿Necesitas algo más? Comunícate con ${CONST.EMAIL.CONCIERGE}`, goToWorkspace: 'Ir al espacio de trabajo', - duplicateWorkspace: 'Duplicar espacio de trabajo', - duplicateWorkspacePrefix: 'Duplicar', goToWorkspaces: 'Ir a espacios de trabajo', clearFilter: 'Borrar filtro', workspaceName: 'Nombre del espacio de trabajo', @@ -4898,18 +4892,6 @@ const translations = { taxCode: 'Código de impuesto', updateTaxCodeFailureMessage: 'Se produjo un error al actualizar el código tributario, inténtelo nuevamente', }, - duplicateWorkspace: { - title: 'Nombra tu nuevo espacio de trabajo', - selectFeatures: 'Selecciona las funciones a copiar', - whichFeatures: '¿Qué funciones deseas copiar a tu nuevo espacio de trabajo?', - confirmDuplicate: '\n\n¿Quieres continuar?', - categories: 'categorías y tus reglas de auto-categorización', - reimbursementAccount: 'cuenta de reembolso', - delayedSubmission: 'presentación retrasada', - welcomeNote: 'Por favor, comience a utilizar mi nuevo espacio de trabajo.', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `Estás a punto de crear y compartir ${newWorkspaceName ?? ''} con ${totalMembers ?? 0} miembros del espacio de trabajo original.`, - }, emptyWorkspace: { title: 'No tienes espacios de trabajo', subtitle: 'Organiza recibos, reembolsa gastos, gestiona viajes, envía facturas y mucho más.', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index aef6f5e511866..20ac165a9497b 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -320,7 +320,6 @@ const translations = { count: 'Compter', cancel: 'Annuler', dismiss: 'Ignorer', - proceed: 'Procéder', yes: 'Oui', no: 'No', ok: "D'accord", @@ -3469,14 +3468,12 @@ const translations = { customField1: 'Champ personnalisé 1', customField2: 'Champ personnalisé 2', customFieldHint: "Ajoutez un codage personnalisé qui s'applique à toutes les dépenses de ce membre.", - reports: 'Rapports', reportFields: 'Champs de rapport', reportTitle: 'Titre du rapport', reportField: 'Champ de rapport', taxes: 'Taxes', bills: 'Bills', invoices: 'Factures', - perDiem: 'Per diem', travel: 'Voyage', members: 'Membres', accounting: 'Comptabilité', @@ -3489,7 +3486,6 @@ const translations = { testTransactions: 'Tester les transactions', issueAndManageCards: 'Émettre et gérer des cartes', reconcileCards: 'Rapprocher les cartes', - selectAll: 'Sélectionner tout', selected: () => ({ one: '1 sélectionné', other: (count: number) => `${count} sélectionné(s)`, @@ -3503,8 +3499,6 @@ const translations = { memberNotFound: "Membre introuvable. Pour inviter un nouveau membre à l'espace de travail, veuillez utiliser le bouton d'invitation ci-dessus.", notAuthorized: `Vous n'avez pas accès à cette page. Si vous essayez de rejoindre cet espace de travail, demandez simplement au propriétaire de l'espace de travail de vous ajouter en tant que membre. Autre chose ? Contactez ${CONST.EMAIL.CONCIERGE}.`, goToWorkspace: "Aller à l'espace de travail", - duplicateWorkspace: 'Dupliquer l’espace de travail', - duplicateWorkspacePrefix: 'Dupliquer', goToWorkspaces: 'Aller aux espaces de travail', clearFilter: 'Effacer le filtre', workspaceName: "Nom de l'espace de travail", @@ -4921,18 +4915,6 @@ const translations = { taxCode: 'Code fiscal', updateTaxCodeFailureMessage: "Une erreur s'est produite lors de la mise à jour du code fiscal, veuillez réessayer.", }, - duplicateWorkspace: { - title: 'Nombra tu nuevo espacio de trabajo', - selectFeatures: 'Selecciona las funciones que quieres copiar', - whichFeatures: '¿Qué funciones quieres copiar a tu nuevo espacio de trabajo?', - confirmDuplicate: '\n\nVoulez-vous continuer?', - categories: 'Categorías y tus reglas de categorización automática', - reimbursementAccount: 'Cuenta de reembolso', - delayedSubmission: 'Envío retrasado', - welcomeNote: 'Empieza a usar mi nuevo espacio de trabajo', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `Vous êtes sur le point de créer et de partager ${newWorkspaceName ?? ''} avec ${totalMembers ?? 0} membres de l'espace de travail d'origine.`, - }, emptyWorkspace: { title: "Vous n'avez aucun espace de travail", subtitle: 'Suivez les reçus, remboursez les dépenses, gérez les déplacements, envoyez des factures, et plus encore.', diff --git a/src/languages/it.ts b/src/languages/it.ts index f3e31b20fa10a..7582da608e59e 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -320,7 +320,6 @@ const translations = { count: 'Contare', cancel: 'Annulla', dismiss: 'Ignora', - proceed: 'Proceed', yes: 'Sì', no: 'No', ok: 'OK', @@ -3474,14 +3473,12 @@ const translations = { customField1: 'Campo personalizzato 1', customField2: 'Campo personalizzato 2', customFieldHint: 'Aggiungi una codifica personalizzata che si applica a tutte le spese di questo membro.', - reports: 'Rapporti', reportFields: 'Campi del rapporto', reportTitle: 'Titolo del rapporto', - reportField: 'Campo del rapporto', + reportField: 'Campo del report', taxes: 'Tasse', bills: 'Fatture', invoices: 'Fatture', - perDiem: 'Per diem', travel: 'Viaggio', members: 'Membri', accounting: 'Contabilità', @@ -3494,7 +3491,6 @@ const translations = { testTransactions: 'Transazioni di prova', issueAndManageCards: 'Emetti e gestisci carte', reconcileCards: 'Riconcilia carte', - selectAll: 'Seleziona tutto', selected: () => ({ one: '1 selezionato', other: (count: number) => `${count} selezionati`, @@ -3508,9 +3504,7 @@ const translations = { memberNotFound: 'Membro non trovato. Per invitare un nuovo membro al workspace, utilizza il pulsante di invito sopra.', notAuthorized: `Non hai accesso a questa pagina. Se stai cercando di unirti a questo spazio di lavoro, chiedi semplicemente al proprietario dello spazio di lavoro di aggiungerti come membro. Qualcos'altro? Contatta ${CONST.EMAIL.CONCIERGE}.`, goToWorkspace: 'Vai allo spazio di lavoro', - duplicateWorkspace: 'Area di lavoro duplicata', - duplicateWorkspacePrefix: 'Duplicate', - goToWorkspaces: 'Duplicato', + goToWorkspaces: 'Vai agli spazi di lavoro', clearFilter: 'Cancella filtro', workspaceName: 'Nome del workspace', workspaceOwner: 'Proprietario', @@ -4920,18 +4914,6 @@ const translations = { taxCode: 'Codice fiscale', updateTaxCodeFailureMessage: "Si è verificato un errore durante l'aggiornamento del codice fiscale, riprova.", }, - duplicateWorkspace: { - title: 'Assegna un nome al tuo nuovo spazio di lavoro', - selectFeatures: 'Seleziona le funzionalità da copiare', - whichFeatures: 'Quali funzionalità vuoi copiare nel tuo nuovo spazio di lavoro?', - confirmDuplicate: '\n\nVuoi continuare?', - categories: 'Categorie e regole di categorizzazione automatica', - reimbursementAccount: 'Account di rimborso', - delayedSubmission: 'Invio ritardato', - welcomeNote: 'Inizia a utilizzare il mio nuovo spazio di lavoro', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `Stai per creare e condividere ${newWorkspaceName ?? ''} con ${totalMembers ?? 0} membri dall'area di lavoro originale.`, - }, emptyWorkspace: { title: 'Non hai spazi di lavoro', subtitle: 'Traccia ricevute, rimborsa spese, gestisci viaggi, invia fatture e altro ancora.', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 50d094fe98214..9d07d3cac601a 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -320,7 +320,6 @@ const translations = { count: 'カウント', cancel: 'キャンセル', dismiss: '却下する', - proceed: 'Proceed', yes: 'はい', no: 'いいえ', ok: 'OK', @@ -3474,14 +3473,12 @@ const translations = { customField1: 'カスタムフィールド1', customField2: 'カスタムフィールド2', customFieldHint: 'このメンバーのすべての支出に適用されるカスタムコーディングを追加します。', - reports: 'レポート', reportFields: 'レポートフィールド', reportTitle: 'レポートタイトル', reportField: 'レポートフィールド', taxes: '税金', bills: '請求書', invoices: '請求書', - perDiem: 'Per diem', travel: '旅行', members: 'メンバー', accounting: '会計', @@ -3494,7 +3491,6 @@ const translations = { testTransactions: 'トランザクションをテストする', issueAndManageCards: 'カードの発行と管理', reconcileCards: 'カードを照合する', - selectAll: 'すべて選択', selected: () => ({ one: '1 件選択済み', other: (count: number) => `${count} 件選択済み`, @@ -3508,8 +3504,6 @@ const translations = { memberNotFound: 'メンバーが見つかりません。新しいメンバーをワークスペースに招待するには、上の招待ボタンを使用してください。', notAuthorized: `このページにアクセスする権限がありません。このワークスペースに参加しようとしている場合は、ワークスペースのオーナーにメンバーとして追加してもらってください。他に何かお困りですか?${CONST.EMAIL.CONCIERGE}にお問い合わせください。`, goToWorkspace: 'ワークスペースに移動', - duplicateWorkspace: 'ワークスペースの複製', - duplicateWorkspacePrefix: '重複', goToWorkspaces: 'ワークスペースに移動', clearFilter: 'フィルターをクリア', workspaceName: 'ワークスペース名', @@ -4899,18 +4893,6 @@ const translations = { taxCode: '税コード', updateTaxCodeFailureMessage: '税コードの更新中にエラーが発生しました。もう一度お試しください。', }, - duplicateWorkspace: { - title: '新しいワークスペースに名前を付けてください', - selectFeatures: 'コピーする機能を選択してください', - whichFeatures: '新しいワークスペースにコピーする機能はどれですか?', - confirmDuplicate: '\n\n続行しますか?', - categories: 'カテゴリと自動分類ルール', - reimbursementAccount: '払い戻し口座', - delayedSubmission: '遅延送信', - welcomeNote: '新しいワークスペースの使用を開始してください', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `${newWorkspaceName ?? ''} を作成し、元のワークスペースの ${totalMembers ?? 0} 人のメンバーと共有しようとしています。`, - }, emptyWorkspace: { title: 'ワークスペースがありません', subtitle: '領収書の管理、経費精算、出張管理、請求書の送信などができます。', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index aabcb2c71b101..3848078458175 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -320,7 +320,6 @@ const translations = { count: 'Aantal', cancel: 'Annuleren', dismiss: 'Verwijderen', - proceed: 'Proceed', yes: 'Ja', no: 'No', ok: 'OK', @@ -3481,14 +3480,12 @@ const translations = { customField1: 'Aangepast veld 1', customField2: 'Aangepast veld 2', customFieldHint: 'Voeg aangepaste codering toe die van toepassing is op alle uitgaven van dit lid.', - reports: 'Rapporten', reportFields: 'Rapportvelden', reportTitle: 'Rapporttitel', reportField: 'Rapportveld', taxes: 'Belastingen', bills: 'Rekeningen', invoices: 'Facturen', - perDiem: 'Per diem', travel: 'Reis', members: 'Leden', accounting: 'Boekhouding', @@ -3501,7 +3498,6 @@ const translations = { testTransactions: 'Testtransacties', issueAndManageCards: 'Kaarten uitgeven en beheren', reconcileCards: 'Reconcileer kaarten', - selectAll: 'Alles selecteren', selected: () => ({ one: '1 geselecteerd', other: (count: number) => `${count} geselecteerd`, @@ -3515,8 +3511,6 @@ const translations = { memberNotFound: 'Lid niet gevonden. Om een nieuw lid aan de werkruimte toe te voegen, gebruik de uitnodigingsknop hierboven.', notAuthorized: `Je hebt geen toegang tot deze pagina. Als je probeert lid te worden van deze werkruimte, vraag dan de eigenaar van de werkruimte om je als lid toe te voegen. Iets anders? Neem contact op met ${CONST.EMAIL.CONCIERGE}.`, goToWorkspace: 'Ga naar werkruimte', - duplicateWorkspace: 'Dubbele werkruimte', - duplicateWorkspacePrefix: 'Duplicaat', goToWorkspaces: 'Ga naar werkruimtes', clearFilter: 'Filter wissen', workspaceName: 'Werkruimte naam', @@ -4922,18 +4916,6 @@ const translations = { taxCode: 'Belastingcode', updateTaxCodeFailureMessage: 'Er is een fout opgetreden bij het bijwerken van de belastingcode, probeer het opnieuw.', }, - duplicateWorkspace: { - title: 'Geef je nieuwe werkruimte een naam', - selectFeatures: 'Selecteer te kopiëren functies', - whichFeatures: 'Welke functies wil je kopiëren naar je nieuwe werkruimte?', - confirmDuplicate: '\n\nWil je doorgaan?', - categories: 'categorieën en je regels voor automatische categorisatie', - reimbursementAccount: 'vergoedingsrekening', - delayedSubmission: 'vertraagde indiening', - welcomeNote: 'Ga aan de slag met mijn nieuwe werkruimte', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `Je staat op het punt om ${newWorkspaceName ?? ''} te maken en te delen met ${totalMembers ?? 0} leden uit de oorspronkelijke werkruimte.`, - }, emptyWorkspace: { title: 'Je hebt geen werkruimtes', subtitle: 'Beheer bonnetjes, vergoed uitgaven, regel reizen, verstuur facturen en meer.', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index d1acfbcd4ad87..71413a9ef6235 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -320,7 +320,6 @@ const translations = { count: 'Liczba', cancel: 'Anuluj', dismiss: 'Odrzuć', - proceed: 'Proceed', yes: 'Tak', no: 'Nie', ok: 'OK', @@ -3474,15 +3473,13 @@ const translations = { customField1: 'Pole niestandardowe 1', customField2: 'Pole niestandardowe 2', customFieldHint: 'Dodaj niestandardowe kodowanie, które dotyczy wszystkich wydatków tego członka.', - reports: 'Raporty', reportFields: 'Pola raportu', reportTitle: 'Tytuł raportu', reportField: 'Pole raportu', taxes: 'Podatki', bills: 'Rachunki', invoices: 'Faktury', - perDiem: 'Per diem', - travel: 'Podróże', + travel: 'Podróżować', members: 'Członkowie', accounting: 'Księgowość', receiptPartners: 'Partnerzy paragonów', @@ -3494,7 +3491,6 @@ const translations = { testTransactions: 'Przetestuj transakcje', issueAndManageCards: 'Wydawaj i zarządzaj kartami', reconcileCards: 'Uzgodnij karty', - selectAll: 'Wybierz wszystkie', selected: () => ({ one: '1 wybrano', other: (count: number) => `${count} wybrano`, @@ -3508,8 +3504,6 @@ const translations = { memberNotFound: 'Nie znaleziono członka. Aby zaprosić nowego członka do przestrzeni roboczej, użyj przycisku zaproszenia powyżej.', notAuthorized: `Nie masz dostępu do tej strony. Jeśli próbujesz dołączyć do tego miejsca pracy, poproś właściciela miejsca pracy o dodanie Cię jako członka. Coś innego? Skontaktuj się z ${CONST.EMAIL.CONCIERGE}.`, goToWorkspace: 'Przejdź do przestrzeni roboczej', - duplicateWorkspace: 'Duplikat obszaru roboczego', - duplicateWorkspacePrefix: 'Duplikat', goToWorkspaces: 'Przejdź do przestrzeni roboczych', clearFilter: 'Wyczyść filtr', workspaceName: 'Nazwa przestrzeni roboczej', @@ -4911,18 +4905,6 @@ const translations = { taxCode: 'Kod podatkowy', updateTaxCodeFailureMessage: 'Wystąpił błąd podczas aktualizacji kodu podatkowego, spróbuj ponownie.', }, - duplicateWorkspace: { - title: 'Nazwij swój nowy obszar roboczy', - selectFeatures: 'Wybierz funkcje do skopiowania', - whichFeatures: 'Które funkcje chcesz skopiować do nowego obszaru roboczego?', - confirmDuplicate: '\n\nCzy chcesz kontynuować?', - categories: 'kategorie i zasady automatycznej kategoryzacji', - reimbursementAccount: 'konto zwrotu', - delayedSubmission: 'opóźnione przesłanie', - welcomeNote: 'Proszę rozpocząć korzystanie z mojego nowego obszaru roboczego', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `Zamierzasz utworzyć i udostępnić ${newWorkspaceName ?? ''} członkom ${totalMembers ?? 0} z oryginalnej przestrzeni roboczej.`, - }, emptyWorkspace: { title: 'Nie masz żadnych przestrzeni roboczych', subtitle: 'Śledź paragony, zwracaj wydatki, zarządzaj podróżami, wysyłaj faktury i nie tylko.', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 593093dcf978a..491de76466919 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -320,7 +320,6 @@ const translations = { count: 'Contagem', cancel: 'Cancelar', dismiss: 'Dispensar', - proceed: 'Proceed', yes: 'Sim', no: 'Não', ok: 'OK', @@ -3479,14 +3478,12 @@ const translations = { customField1: 'Campo personalizado 1', customField2: 'Campo personalizado 2', customFieldHint: 'Adicione uma codificação personalizada que se aplique a todos os gastos deste membro.', - reports: 'Relatórios', reportFields: 'Campos do relatório', reportTitle: 'Título do relatório', reportField: 'Campo de relatório', taxes: 'Impostos', bills: 'Faturas', invoices: 'Faturas', - perDiem: 'Per diem', travel: 'Viagem', members: 'Membros', accounting: 'Contabilidade', @@ -3499,7 +3496,6 @@ const translations = { testTransactions: 'Testar transações', issueAndManageCards: 'Emitir e gerenciar cartões', reconcileCards: 'Conciliar cartões', - selectAll: 'Selecionar todos', selected: () => ({ one: '1 selecionado', other: (count: number) => `${count} selecionado(s)`, @@ -3513,8 +3509,6 @@ const translations = { memberNotFound: 'Membro não encontrado. Para convidar um novo membro para o espaço de trabalho, por favor, use o botão de convite acima.', notAuthorized: `Você não tem acesso a esta página. Se você está tentando entrar neste espaço de trabalho, basta pedir ao proprietário do espaço de trabalho para adicioná-lo como membro. Algo mais? Entre em contato com ${CONST.EMAIL.CONCIERGE}.`, goToWorkspace: 'Ir para o espaço de trabalho', - duplicateWorkspace: 'Espaço de trabalho duplicado', - duplicateWorkspacePrefix: 'Duplicado', goToWorkspaces: 'Ir para espaços de trabalho', clearFilter: 'Limpar filtro', workspaceName: 'Nome do espaço de trabalho', @@ -4917,18 +4911,6 @@ const translations = { taxCode: 'Código fiscal', updateTaxCodeFailureMessage: 'Ocorreu um erro ao atualizar o código de imposto, por favor, tente novamente.', }, - duplicateWorkspace: { - title: 'Nomeie seu novo espaço de trabalho', - selectFeatures: 'Selecione os recursos a serem copiados', - whichFeatures: 'Quais recursos você deseja copiar para o seu novo espaço de trabalho?', - confirmDuplicate: '\n\nVocê quer continuar?', - categories: 'categorias e suas regras de categorização automática', - reimbursementAccount: 'conta de reembolso', - delayedSubmission: 'envio atrasado', - welcomeNote: 'Comece a usar meu novo espaço de trabalho', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `Você está prestes a criar e compartilhar ${newWorkspaceName ?? ''} com ${totalMembers ?? 0} membros do espaço de trabalho original.`, - }, emptyWorkspace: { title: 'Você não tem espaços de trabalho', subtitle: 'Acompanhe recibos, reembolse despesas, gerencie viagens, envie faturas e muito mais.', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 20f9408013821..3a1dd75d268fb 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -320,7 +320,6 @@ const translations = { count: '计数', cancel: '取消', dismiss: '忽略', - proceed: 'Proceed', yes: '是的', no: '不', ok: '好的', @@ -3430,14 +3429,12 @@ const translations = { customField1: '自定义字段 1', customField2: '自定义字段2', customFieldHint: '添加适用于该成员所有支出的自定义编码。', - reports: '报告', reportFields: '报告字段', reportTitle: '报告标题', reportField: '报告字段', taxes: '税款', bills: '账单', invoices: '发票', - perDiem: 'Per diem', travel: '旅行', members: '成员', accounting: '会计', @@ -3450,7 +3447,6 @@ const translations = { testTransactions: '测试交易', issueAndManageCards: '发行和管理卡片', reconcileCards: '对账卡片', - selectAll: '全选', selected: () => ({ one: '1 已选择', other: (count: number) => `已选择${count}个`, @@ -3464,8 +3460,6 @@ const translations = { memberNotFound: '未找到成员。要邀请新成员加入工作区,请使用上面的邀请按钮。', notAuthorized: `您无权访问此页面。如果您正在尝试加入此工作区,请请求工作区所有者将您添加为成员。还有其他问题?请联系${CONST.EMAIL.CONCIERGE}。`, goToWorkspace: '前往工作区', - duplicateWorkspace: '重复工作区', - duplicateWorkspacePrefix: '复制', goToWorkspaces: '前往工作区', clearFilter: '清除筛选器', workspaceName: '工作区名称', @@ -4833,18 +4827,6 @@ const translations = { taxCode: '税码', updateTaxCodeFailureMessage: '更新税码时发生错误,请重试', }, - duplicateWorkspace: { - title: '命名您的新工作区', - selectFeatures: '选择要复制的功能', - whichFeatures: '您想要将哪些功能复制到您的新工作区?', - confirmDuplicate: '\n\n您想继续吗?', - categories: '类别和您的自动分类规则', - reimbursementAccount: '报销账户', - delayedSubmission: '延迟提交', - welcomeNote: '请开始使用我的新工作区', - confirmTitle: ({newWorkspaceName, totalMembers}: {newWorkspaceName?: string; totalMembers?: number}) => - `您即将创建并与原始工作区中的 ${totalMembers ?? 0} 名成员共享 ${newWorkspaceName ?? ''}。`, - }, emptyWorkspace: { title: '您没有任何工作区', subtitle: '跟踪收据、报销费用、管理差旅、发送发票等。', diff --git a/src/libs/API/parameters/DuplicateWorkspaceParams.ts b/src/libs/API/parameters/DuplicateWorkspaceParams.ts deleted file mode 100644 index 8dc8966550d5a..0000000000000 --- a/src/libs/API/parameters/DuplicateWorkspaceParams.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type {FileObject} from '@pages/media/AttachmentModalScreen/types'; - -type DuplicateWorkspaceParams = { - policyID: string; - targetPolicyID: string; - policyName: string; - parts: string; - announceChatReportID: string; - adminsChatReportID: string; - welcomeNote: string; - expenseChatReportID: string; - adminsCreatedReportActionID: string; - expenseCreatedReportActionID: string; - announceChatReportActionID: string; - customUnitID: string; - customUnitRateID: string; - file?: FileObject; -}; - -export default DuplicateWorkspaceParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 335dedcbedf02..484ce96f5d7be 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -80,7 +80,6 @@ export type {default as SignInWithSupportAuthTokenParams} from './SignInWithSupp export type {default as UnlinkLoginParams} from './UnlinkLoginParams'; export type {default as UpdateAutomaticTimezoneParams} from './UpdateAutomaticTimezoneParams'; export type {default as UpdateChatPriorityModeParams} from './UpdateChatPriorityModeParams'; -export type {default as DuplicateWorkspaceParams} from './DuplicateWorkspaceParams'; export type {default as UpdateDateOfBirthParams} from './UpdateDateOfBirthParams'; export type {default as UpdateDisplayNameParams} from './UpdateDisplayNameParams'; export type {default as UpdateChatNameParams} from './UpdateChatNameParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 9f01ed916b9c5..3e7631872854b 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -147,7 +147,6 @@ const WRITE_COMMANDS = { UPDATE_WORKSPACE_DESCRIPTION: 'UpdateWorkspaceDescription', UPDATE_WORKSPACE_MEMBERS_ROLE: 'UpdateWorkspaceMembersRole', CREATE_WORKSPACE: 'CreateWorkspace', - DUPLICATE_POLICY: 'DuplicatePolicy', CREATE_WORKSPACE_FROM_IOU_PAYMENT: 'CreateWorkspaceFromIOUPayment', UPDATE_POLICY_MEMBERS_CUSTOM_FIELDS: 'UpdatePolicyMembersCustomFields', SET_WORKSPACE_CATEGORIES_ENABLED: 'SetWorkspaceCategoriesEnabled', @@ -842,7 +841,6 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SEND_INVOICE]: Parameters.SendInvoiceParams; [WRITE_COMMANDS.PAY_INVOICE]: Parameters.PayInvoiceParams; [WRITE_COMMANDS.MARK_AS_CASH]: Parameters.MarkAsCashParams; - [WRITE_COMMANDS.DUPLICATE_POLICY]: Parameters.DuplicateWorkspaceParams; [WRITE_COMMANDS.MERGE_DUPLICATES]: Parameters.MergeDuplicatesParams; [WRITE_COMMANDS.RESOLVE_DUPLICATES]: Parameters.ResolveDuplicatesParams; [WRITE_COMMANDS.MERGE_TRANSACTION]: Parameters.MergeTransactionParams; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 529a488538250..09d14e538af6b 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -41,7 +41,6 @@ import type { TravelNavigatorParamList, WalletStatementNavigatorParamList, WorkspaceConfirmationNavigatorParamList, - WorkspaceDuplicateNavigatorParamList, } from '@navigation/types'; import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; @@ -186,11 +185,6 @@ const WorkspaceConfirmationModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/WorkspaceConfirmationPage').default, }); -const WorkspaceDuplicateModalStackNavigator = createModalStackNavigator({ - [SCREENS.WORKSPACE_DUPLICATE.ROOT]: () => require('../../../../pages/workspace/duplicate/WorkspaceDuplicatePage').default, - [SCREENS.WORKSPACE_DUPLICATE.SELECT_FEATURES]: () => require('../../../../pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesPage').default, -}); - const TaskModalStackNavigator = createModalStackNavigator({ [SCREENS.TASK.TITLE]: () => require('../../../../pages/tasks/TaskTitlePage').default, [SCREENS.TASK.ASSIGNEE]: () => require('../../../../pages/tasks/TaskAssigneeSelectorModal').default, @@ -863,7 +857,6 @@ export { MissingPersonalDetailsModalStackNavigator, DebugModalStackNavigator, WorkspaceConfirmationModalStackNavigator, - WorkspaceDuplicateModalStackNavigator, ConsoleModalStackNavigator, AddUnreportedExpenseModalStackNavigator, ScheduleCallModalStackNavigator, diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx index 6dc900dd2fb07..0d2eaca5a5693 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.tsx @@ -148,10 +148,6 @@ function RightModalNavigator({navigation, route}: RightModalNavigatorProps) { name={SCREENS.RIGHT_MODAL.WORKSPACE_CONFIRMATION} component={ModalStackNavigators.WorkspaceConfirmationModalStackNavigator} /> - ['config'] = { [SCREENS.WORKSPACE_CONFIRMATION.ROOT]: ROUTES.WORKSPACE_CONFIRMATION.route, }, }, - [SCREENS.RIGHT_MODAL.WORKSPACE_DUPLICATE]: { - screens: { - [SCREENS.WORKSPACE_DUPLICATE.ROOT]: ROUTES.WORKSPACE_DUPLICATE.route, - [SCREENS.WORKSPACE_DUPLICATE.SELECT_FEATURES]: ROUTES.WORKSPACE_DUPLICATE_SELECT_FEATURES.route, - }, - }, [SCREENS.RIGHT_MODAL.NEW_TASK]: { screens: { [SCREENS.NEW_TASK.ROOT]: ROUTES.NEW_TASK.route, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index eaa7219e0f00a..9d1cb460d5e5b 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -1571,15 +1571,6 @@ type WorkspaceConfirmationNavigatorParamList = { }; }; -type WorkspaceDuplicateNavigatorParamList = { - [SCREENS.WORKSPACE_DUPLICATE.ROOT]: { - policyID: string; - }; - [SCREENS.WORKSPACE_DUPLICATE.SELECT_FEATURES]: { - policyID: string; - }; -}; - type NewTaskNavigatorParamList = { [SCREENS.NEW_TASK.ROOT]: { backTo?: Routes; @@ -1774,7 +1765,6 @@ type RightModalNavigatorParamList = { [SCREENS.RIGHT_MODAL.ROOM_MEMBERS]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.MONEY_REQUEST]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.WORKSPACE_CONFIRMATION]: NavigatorScreenParams; - [SCREENS.RIGHT_MODAL.WORKSPACE_DUPLICATE]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.NEW_TASK]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.TEACHERS_UNITE]: NavigatorScreenParams; [SCREENS.RIGHT_MODAL.TASK_DETAILS]: NavigatorScreenParams; @@ -2380,7 +2370,6 @@ export type { WorkspaceSplitNavigatorParamList, MigratedUserModalNavigatorParamList, WorkspaceConfirmationNavigatorParamList, - WorkspaceDuplicateNavigatorParamList, TwoFactorAuthNavigatorParamList, ConsoleNavigatorParamList, ScheduleCallParamList, diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 43753df64464c..3174782a94243 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -15,7 +15,6 @@ import type { DeleteWorkspaceParams, DisablePolicyBillableModeParams, DowngradeToTeamParams, - DuplicateWorkspaceParams, EnablePolicyAutoApprovalOptionsParams, EnablePolicyAutoReimbursementLimitParams, EnablePolicyCompanyCardsParams, @@ -69,7 +68,6 @@ import type SetPolicyCashExpenseModeParams from '@libs/API/parameters/SetPolicyC import type UpdatePolicyMembersCustomFieldsParams from '@libs/API/parameters/UpdatePolicyMembersCustomFieldsParams'; import type {ApiRequestCommandParameters} from '@libs/API/types'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; -import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; @@ -83,7 +81,7 @@ import * as NumberUtils from '@libs/NumberUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; -import {getMemberAccountIDsForWorkspace, goBackWhenEnableFeature, isControlPolicy, navigateToExpensifyCardPage} from '@libs/PolicyUtils'; +import {goBackWhenEnableFeature, isControlPolicy, navigateToExpensifyCardPage} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import type {PolicySelector} from '@pages/home/sidebar/FloatingActionButtonAndPopover'; import type {Feature} from '@pages/OnboardingInterestedFeatures/types'; @@ -97,7 +95,6 @@ import CONST from '@src/CONST'; import type {OnboardingAccounting} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type { - DuplicateWorkspace, IntroSelected, InvitedEmailsToAccountIDs, LastPaymentMethod, @@ -170,15 +167,6 @@ type BuildPolicyDataOptions = { lastUsedPaymentMethod?: LastPaymentMethodType; }; -type DuplicatePolicyDataOptions = { - policyName: string; - policyID?: string; - targetPolicyID?: string; - welcomeNote: string; - parts: Record; - file?: File | CustomRNImageManipulatorResult; -}; - const allPolicies: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.POLICY, @@ -1759,14 +1747,6 @@ function removeWorkspace(policyID: string) { Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, null); } -function setDuplicateWorkspaceData(data: Partial) { - Onyx.merge(ONYXKEYS.DUPLICATE_WORKSPACE, {...data}); -} - -function clearDuplicateWorkspace() { - Onyx.set(ONYXKEYS.DUPLICATE_WORKSPACE, {}); -} - /** * Generate a policy name based on an email and policy list. * @param [email] the email to base the workspace name on. If not passed, will use the logged-in user's email instead @@ -2488,286 +2468,6 @@ function createDraftWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policy return params; } -function buildDuplicatePolicyData(policy: Policy, options: DuplicatePolicyDataOptions) { - const {policyName = '', policyID = generatePolicyID(), file, welcomeNote, parts, targetPolicyID = generatePolicyID()} = options; - - const { - adminsChatReportID, - adminsChatData, - adminsReportActionData, - adminsCreatedReportActionID, - expenseChatReportID, - expenseChatData, - expenseReportActionData, - expenseCreatedReportActionID, - pendingChatMembers, - } = ReportUtils.buildOptimisticWorkspaceChats(targetPolicyID, policyName); - const isMemberOptionSelected = parts?.people; - const isReportsOptionSelected = parts?.reports; - const isConnectionsOptionSelected = parts?.connections; - const isCategoriesOptionSelected = parts?.categories; - const isTaxesOptionSelected = parts?.taxes; - const isTagsOptionSelected = parts?.tags; - const isInvoicesOptionSelected = parts?.invoices; - const isCustomUnitsOptionSelected = parts?.customUnits; - const isRulesOptionSelected = parts?.expenses; - const isWorkflowsOptionSelected = parts?.exportLayouts; - const policyMemberAccountIDs = isMemberOptionSelected ? Object.values(getMemberAccountIDsForWorkspace(policy?.employeeList, false, false)) : []; - const {customUnitID, customUnitRateID} = buildOptimisticDistanceRateCustomUnits(policy?.outputCurrency); - - const optimisticAnnounceChat = ReportUtils.buildOptimisticAnnounceChat(targetPolicyID, [...policyMemberAccountIDs]); - const announceRoomChat = optimisticAnnounceChat.announceChatData; - - const optimisticCategoriesData = buildOptimisticPolicyCategories(targetPolicyID, Object.values(CONST.POLICY.DEFAULT_CATEGORIES)); - - // WARNING: The data below should be kept in sync with the API so we create the policy with the correct configuration. - const optimisticData: OnyxUpdate[] = [ - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.POLICY}${targetPolicyID}`, - value: { - ...policy, - areCategoriesEnabled: isCategoriesOptionSelected, - areTagsEnabled: isTagsOptionSelected, - areDistanceRatesEnabled: isCustomUnitsOptionSelected, - areInvoicesEnabled: isInvoicesOptionSelected, - areRulesEnabled: isRulesOptionSelected, - areWorkflowsEnabled: isWorkflowsOptionSelected, - areReportFieldsEnabled: isReportsOptionSelected, - areConnectionsEnabled: isConnectionsOptionSelected, - tax: isTaxesOptionSelected ? policy?.tax : undefined, - employeeList: isMemberOptionSelected ? policy.employeeList : {[policy.owner]: policy?.employeeList?.[policy.owner]}, - id: targetPolicyID, - name: policyName, - fieldList: isReportsOptionSelected ? policy?.fieldList : undefined, - connections: isConnectionsOptionSelected ? policy?.connections : undefined, - customUnits: isCustomUnitsOptionSelected ? policy?.customUnits : undefined, - taxRates: isTaxesOptionSelected ? policy?.taxRates : undefined, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - pendingFields: { - autoReporting: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - approvalMode: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - reimbursementChoice: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - name: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - outputCurrency: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - address: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - description: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - type: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - areReportFieldsEnabled: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - avatarURL: file?.uri, - originalFileName: file?.name, - }, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${expenseChatReportID}`, - value: { - isOptimisticReport: true, - }, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, - value: { - pendingFields: { - addWorkspaceRoom: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - ...adminsChatData, - }, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${adminsChatReportID}`, - value: { - pendingChatMembers, - }, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, - value: adminsReportActionData, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, - value: { - pendingFields: { - addWorkspaceRoom: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - ...expenseChatData, - }, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, - value: expenseReportActionData, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${targetPolicyID}`, - value: null, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_DRAFT}${expenseChatReportID}`, - value: null, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_DRAFT}${adminsChatReportID}`, - value: null, - }, - ...announceRoomChat.onyxOptimisticData, - ]; - - const successData: OnyxUpdate[] = [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${targetPolicyID}`, - value: { - pendingAction: null, - pendingFields: { - autoReporting: null, - approvalMode: null, - reimbursementChoice: null, - name: null, - outputCurrency: null, - address: null, - description: null, - type: null, - areReportFieldsEnabled: null, - }, - }, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, - value: { - pendingFields: { - addWorkspaceRoom: null, - }, - pendingAction: null, - }, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${adminsChatReportID}`, - value: { - isOptimisticReport: false, - pendingChatMembers: [], - }, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, - value: { - [adminsCreatedReportActionID]: { - pendingAction: null, - }, - }, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, - value: { - pendingFields: { - addWorkspaceRoom: null, - }, - pendingAction: null, - }, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_METADATA}${expenseChatReportID}`, - value: { - isOptimisticReport: false, - }, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, - value: { - [expenseCreatedReportActionID]: { - pendingAction: null, - }, - }, - }, - ...announceRoomChat.onyxSuccessData, - ]; - - const failureData: OnyxUpdate[] = [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${targetPolicyID}`, - value: {employeeList: null}, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, - value: null, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, - value: null, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseChatReportID}`, - value: null, - }, - { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`, - value: null, - }, - ...announceRoomChat.onyxFailureData, - ]; - - if (optimisticCategoriesData.optimisticData) { - optimisticData.push(...optimisticCategoriesData.optimisticData); - } - - if (optimisticCategoriesData.failureData) { - failureData.push(...optimisticCategoriesData.failureData); - } - - if (optimisticCategoriesData.successData) { - successData.push(...optimisticCategoriesData.successData); - } - - // We need to clone the file to prevent non-indexable errors. - const clonedFile = file ? createFile(file as File) : undefined; - - const params: DuplicateWorkspaceParams = { - policyID, - targetPolicyID, - adminsChatReportID, - expenseChatReportID, - policyName, - adminsCreatedReportActionID, - expenseCreatedReportActionID, - announceChatReportID: optimisticAnnounceChat.announceChatReportID, - announceChatReportActionID: optimisticAnnounceChat.announceChatReportActionID, - customUnitID, - parts: JSON.stringify(parts), - welcomeNote, - customUnitRateID, - file: clonedFile, - }; - - return {successData, optimisticData, failureData, params}; -} - -function duplicateWorkspace(policy: Policy, options: DuplicatePolicyDataOptions): DuplicateWorkspaceParams { - const {optimisticData, failureData, successData, params} = buildDuplicatePolicyData(policy, options); - - API.write(WRITE_COMMANDS.DUPLICATE_POLICY, params, {optimisticData, successData, failureData}); - - return params; -} - function openPolicyWorkflowsPage(policyID: string) { if (!policyID) { Log.warn('openPolicyWorkflowsPage invalid params', {policyID}); @@ -6250,8 +5950,6 @@ export { setPolicyMaxExpenseAge, updateCustomRules, setPolicyProhibitedExpense, - setDuplicateWorkspaceData, - clearDuplicateWorkspace, setPolicyBillableMode, disableWorkspaceBillableExpenses, setWorkspaceEReceiptsEnabled, @@ -6270,7 +5968,6 @@ export { clearQuickbooksOnlineAutoSyncErrorField, setIsForcedToChangeCurrency, removePolicyReceiptPartnersConnection, - duplicateWorkspace, openPolicyReceiptPartnersPage, setIsComingFromGlobalReimbursementsFlow, setPolicyAttendeeTrackingEnabled, diff --git a/src/libs/getFirstAlphaNumericCharacter.ts b/src/libs/getFirstAlphaNumericCharacter.ts deleted file mode 100644 index 94d7f5e43e1fc..0000000000000 --- a/src/libs/getFirstAlphaNumericCharacter.ts +++ /dev/null @@ -1,8 +0,0 @@ -function getFirstAlphaNumericCharacter(str = '') { - return str - .normalize('NFD') - .replace(/[^0-9a-z]/gi, '') - .toUpperCase()[0]; -} - -export default getFirstAlphaNumericCharacter; diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index 4cf5ca1e24e86..30ba4462c6f45 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -1,6 +1,6 @@ -import {useIsFocused, useRoute} from '@react-navigation/native'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import {FlatList, InteractionManager, View} from 'react-native'; +import {useRoute} from '@react-navigation/native'; +import React, {useCallback, useMemo, useState} from 'react'; +import {FlatList, View} from 'react-native'; import type {ValueOf} from 'type-fest'; import Button from '@components/Button'; import ConfirmModal from '@components/ConfirmModal'; @@ -35,16 +35,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import {isConnectionInProgress} from '@libs/actions/connections'; -import { - calculateBillNewDot, - clearDeleteWorkspaceError, - clearDuplicateWorkspace, - clearErrors, - deleteWorkspace, - leaveWorkspace, - removeWorkspace, - updateDefaultPolicy, -} from '@libs/actions/Policy/Policy'; +import {calculateBillNewDot, clearDeleteWorkspaceError, clearErrors, deleteWorkspace, leaveWorkspace, removeWorkspace, updateDefaultPolicy} from '@libs/actions/Policy/Policy'; import {callFunctionIfActionIsAllowed, isSupportAuthToken} from '@libs/actions/Session'; import {filterInactiveCards} from '@libs/CardUtils'; import interceptAnonymousUser from '@libs/interceptAnonymousUser'; @@ -106,7 +97,6 @@ function WorkspacesListPage() { const StyleUtils = useStyleUtils(); const {translate, localeCompare} = useLocalize(); const {isOffline} = useNetwork(); - const isFocused = useIsFocused(); const {shouldUseNarrowLayout, isMediumScreenWidth} = useResponsiveLayout(); const [allConnectionSyncProgresses] = useOnyx(ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS, {canBeMissing: true}); const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true}); @@ -117,7 +107,6 @@ function WorkspacesListPage() { const [lastPaymentMethod] = useOnyx(ONYXKEYS.NVP_LAST_PAYMENT_METHOD, {canBeMissing: true}); const shouldShowLoadingIndicator = isLoadingApp && !isOffline; const route = useRoute>(); - const [duplicateWorkspace] = useOnyx(ONYXKEYS.DUPLICATE_WORKSPACE, {canBeMissing: false}); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [policyIDToDelete, setPolicyIDToDelete] = useState(); @@ -137,7 +126,6 @@ function WorkspacesListPage() { selector: filterInactiveCards, canBeMissing: true, }); - const flatlistRef = useRef(null); const [lastAccessedWorkspacePolicyID] = useOnyx(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, {canBeMissing: true}); // This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850 @@ -178,8 +166,6 @@ function WorkspacesListPage() { const isAdmin = isPolicyAdmin(item as unknown as PolicyType, session?.email); const isOwner = item.ownerAccountID === session?.accountID; const isDefault = activePolicyID === item.policyID; - const shouldAnimateInHighlight = duplicateWorkspace?.policyID === item.policyID; - const threeDotsMenuItems: PopoverMenuItem[] = [ { icon: Expensicons.Building, @@ -228,14 +214,6 @@ function WorkspacesListPage() { }); } - if (isAdmin) { - threeDotsMenuItems.push({ - icon: Expensicons.Copy, - text: translate('workspace.common.duplicateWorkspace'), - onSelected: () => (item.policyID ? Navigation.navigate(ROUTES.WORKSPACE_DUPLICATE.getRoute(item.policyID, ROUTES.WORKSPACES_LIST.route)) : undefined), - }); - } - if (!isDefault && !item?.isJoinRequestPending) { threeDotsMenuItems.push({ icon: Expensicons.Star, @@ -268,7 +246,6 @@ function WorkspacesListPage() { workspaceIcon={item.icon} ownerAccountID={item.ownerAccountID} workspaceType={item.type} - shouldAnimateInHighlight={shouldAnimateInHighlight} isJoinRequestPending={item?.isJoinRequestPending} rowStyles={hovered && styles.hoveredComponentBG} layoutWidth={isLessThanMediumScreen ? CONST.LAYOUT_WIDTH.NARROW : CONST.LAYOUT_WIDTH.WIDE} @@ -289,7 +266,6 @@ function WorkspacesListPage() { styles.mb2, styles.mh5, styles.ph5, - duplicateWorkspace?.policyID, styles.hoveredComponentBG, translate, styles.offlineFeedback.deleted, @@ -381,19 +357,6 @@ function WorkspacesListPage() { const sortWorkspace = useCallback((workspaceItems: WorkspaceItem[]) => workspaceItems.sort((a, b) => localeCompare(a.title, b.title)), [localeCompare]); const [inputValue, setInputValue, filteredWorkspaces] = useSearchResults(workspaces, filterWorkspace, sortWorkspace); - useEffect(() => { - if (isEmptyObject(duplicateWorkspace) || !filteredWorkspaces.length || !isFocused) { - return; - } - const duplicateWorkspaceIndex = filteredWorkspaces.findIndex((workspace) => workspace.policyID === duplicateWorkspace.policyID); - if (duplicateWorkspaceIndex > 0) { - flatlistRef.current?.scrollToIndex({index: duplicateWorkspaceIndex, animated: false}); - InteractionManager.runAfterInteractions(() => { - clearDuplicateWorkspace(); - }); - } - }, [duplicateWorkspace, isFocused, filteredWorkspaces]); - const listHeaderComponent = ( <> {isLessThanMediumScreen && } @@ -513,14 +476,7 @@ function WorkspacesListPage() { {!shouldUseNarrowLayout && {getHeaderButton()}} {shouldUseNarrowLayout && {getHeaderButton()}} { - flatlistRef.current?.scrollToOffset({ - offset: info.averageItemLength * info.index, - animated: true, - }); - }} renderItem={getMenuItem} ListHeaderComponent={listHeaderComponent} keyboardShouldPersistTaps="handled" diff --git a/src/pages/workspace/WorkspacesListRow.tsx b/src/pages/workspace/WorkspacesListRow.tsx index 201eb01f6cce9..80a1762dba96e 100644 --- a/src/pages/workspace/WorkspacesListRow.tsx +++ b/src/pages/workspace/WorkspacesListRow.tsx @@ -2,7 +2,6 @@ import {Str} from 'expensify-common'; import React, {useEffect, useRef} from 'react'; import {View} from 'react-native'; import type {StyleProp, ViewStyle} from 'react-native'; -import Animated from 'react-native-reanimated'; import type {ValueOf} from 'type-fest'; import Avatar from '@components/Avatar'; import Badge from '@components/Badge'; @@ -17,7 +16,6 @@ import Tooltip from '@components/Tooltip'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import WorkspacesListRowDisplayName from '@components/WorkspacesListRowDisplayName'; -import useAnimatedHighlightStyle from '@hooks/useAnimatedHighlightStyle'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; @@ -76,9 +74,6 @@ type WorkspacesListRowProps = WithCurrentUserPersonalDetailsProps & { /** Whether the bill is loading */ isLoadingBill?: boolean; - /** Whether the list item is highlighted */ - shouldAnimateInHighlight?: boolean; - /** Function to reset loading spinner icon index */ resetLoadingSpinnerIconIndex?: () => void; }; @@ -121,7 +116,6 @@ function WorkspacesListRow({ rowStyles, style, brickRoadIndicator, - shouldAnimateInHighlight, shouldDisableThreeDotsMenu, isJoinRequestPending, policyID, @@ -132,17 +126,10 @@ function WorkspacesListRow({ const styles = useThemeStyles(); const {translate} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); - const theme = useTheme(); const isNarrow = layoutWidth === CONST.LAYOUT_WIDTH.NARROW; const ownerDetails = ownerAccountID && getPersonalDetailsByIDs({accountIDs: [ownerAccountID], currentUserAccountID: currentUserPersonalDetails.accountID}).at(0); const threeDotsMenuRef = useRef<{hidePopoverMenu: () => void; isPopupMenuVisible: boolean}>(null); - const animatedHighlightStyle = useAnimatedHighlightStyle({ - borderRadius: variables.componentBorderRadius, - shouldHighlight: !!shouldAnimateInHighlight, - highlightColor: theme.messageHighlightBG, - backgroundColor: theme.highlightBG, - }); useEffect(() => { if (isLoadingBill) { @@ -213,7 +200,7 @@ function WorkspacesListRow({ ); return ( - + @@ -286,7 +273,7 @@ function WorkspacesListRow({ {!isNarrow && ThreeDotMenuOrPendingIcon} - + ); } diff --git a/src/pages/workspace/duplicate/WorkspaceDuplicateForm.tsx b/src/pages/workspace/duplicate/WorkspaceDuplicateForm.tsx deleted file mode 100644 index 3b19e8101c1d1..0000000000000 --- a/src/pages/workspace/duplicate/WorkspaceDuplicateForm.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import React, {useCallback, useState} from 'react'; -import {View} from 'react-native'; -import AvatarWithImagePicker from '@components/AvatarWithImagePicker'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapper from '@components/Form/InputWrapper'; -import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import * as Expensicons from '@components/Icon/Expensicons'; -import ScrollView from '@components/ScrollView'; -import Text from '@components/Text'; -import TextInput from '@components/TextInput'; -import useAutoFocusInput from '@hooks/useAutoFocusInput'; -import useLocalize from '@hooks/useLocalize'; -import usePolicy from '@hooks/usePolicy'; -import useThemeStyles from '@hooks/useThemeStyles'; -import useWorkspaceConfirmationAvatar from '@hooks/useWorkspaceConfirmationAvatar'; -import {generatePolicyID, setDuplicateWorkspaceData} from '@libs/actions/Policy/Policy'; -import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; -import {addErrorMessage} from '@libs/ErrorUtils'; -import getFirstAlphaNumericCharacter from '@libs/getFirstAlphaNumericCharacter'; -import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils'; -import {isRequiredFulfilled} from '@libs/ValidationUtils'; -import Navigation from '@navigation/Navigation'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import INPUT_IDS from '@src/types/form/WorkspaceDuplicateForm'; - -type WorkspaceDuplicateFormProps = { - policyID?: string; -}; - -function WorkspaceDuplicateForm({policyID}: WorkspaceDuplicateFormProps) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const {inputCallbackRef} = useAutoFocusInput(); - const policy = usePolicy(policyID); - const defaultWorkspaceName = `${policy?.name} (${translate('workspace.common.duplicateWorkspacePrefix')})`; - - const validate = useCallback( - (values: FormOnyxValues) => { - const errors: FormInputErrors = {}; - const name = values.name.trim(); - - if (!isRequiredFulfilled(name)) { - errors.name = translate('workspace.editor.nameIsRequiredError'); - } else if ([...name].length > CONST.TITLE_CHARACTER_LIMIT) { - // Uses the spread syntax to count the number of Unicode code points instead of the number of UTF-16 - // code units. - addErrorMessage(errors, 'name', translate('common.error.characterLimitExceedCounter', {length: [...name].length, limit: CONST.TITLE_CHARACTER_LIMIT})); - } - - return errors; - }, - [translate], - ); - - const onSubmit = useCallback( - ({name, avatarFile}: {name?: string; avatarFile?: File | CustomRNImageManipulatorResult}) => { - if (!policyID) { - return; - } - const newPolicyID = generatePolicyID(); - setDuplicateWorkspaceData({policyID: newPolicyID, name, file: avatarFile}); - Navigation.navigate(ROUTES.WORKSPACE_DUPLICATE_SELECT_FEATURES.getRoute(policyID, ROUTES.WORKSPACES_LIST.route)); - }, - [policyID], - ); - - const [workspaceNameFirstCharacter, setWorkspaceNameFirstCharacter] = useState(defaultWorkspaceName ?? ''); - - const [workspaceAvatar, setWorkspaceAvatar] = useState<{avatarUri: string | null; avatarFileName?: string | null; avatarFileType?: string | null}>({ - avatarUri: null, - avatarFileName: null, - avatarFileType: null, - }); - const [avatarFile, setAvatarFile] = useState(); - - const stashedLocalAvatarImage = workspaceAvatar?.avatarUri ?? undefined; - - const DefaultAvatar = useWorkspaceConfirmationAvatar({ - policyID, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing cannot be used if left side can be empty string - source: stashedLocalAvatarImage || getDefaultWorkspaceAvatar(workspaceNameFirstCharacter), - name: workspaceNameFirstCharacter, - }); - - return ( - <> - - - - {translate('workspace.duplicateWorkspace.title')} - - { - setAvatarFile(image); - setWorkspaceAvatar({avatarUri: image.uri ?? '', avatarFileName: image.name ?? '', avatarFileType: image.type}); - }} - onImageRemoved={() => { - setAvatarFile(undefined); - setWorkspaceAvatar({avatarUri: null, avatarFileName: null, avatarFileType: null}); - }} - size={CONST.AVATAR_SIZE.X_LARGE} - avatarStyle={[styles.avatarXLarge, styles.alignSelfCenter]} - shouldDisableViewPhoto - editIcon={Expensicons.Camera} - editIconStyle={styles.smallEditIconAccount} - type={CONST.ICON_TYPE_WORKSPACE} - style={[styles.w100, styles.alignItemsCenter, styles.mv4, styles.mb6, styles.alignSelfCenter, styles.ph5]} - DefaultAvatar={DefaultAvatar} - editorMaskImage={Expensicons.ImageCropSquareMask} - /> - - onSubmit({ - name: val[INPUT_IDS.NAME], - avatarFile, - }) - } - enabledWhenOffline - addBottomSafeAreaPadding - > - - { - if (getFirstAlphaNumericCharacter(str) === getFirstAlphaNumericCharacter(workspaceNameFirstCharacter)) { - return; - } - setWorkspaceNameFirstCharacter(str); - }} - ref={inputCallbackRef} - /> - - - - - ); -} - -WorkspaceDuplicateForm.displayName = 'WorkspaceDuplicateForm'; - -export default WorkspaceDuplicateForm; diff --git a/src/pages/workspace/duplicate/WorkspaceDuplicatePage.tsx b/src/pages/workspace/duplicate/WorkspaceDuplicatePage.tsx deleted file mode 100644 index e9485b5000497..0000000000000 --- a/src/pages/workspace/duplicate/WorkspaceDuplicatePage.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import {useRoute} from '@react-navigation/native'; -import React, {useEffect} from 'react'; -import ScreenWrapper from '@components/ScreenWrapper'; -import type {PlatformStackRouteProp} from '@navigation/PlatformStackNavigation/types'; -import type {WorkspaceDuplicateNavigatorParamList} from '@navigation/types'; -import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; -import {clearDuplicateWorkspace} from '@userActions/Policy/Policy'; -import CONST from '@src/CONST'; -import type SCREENS from '@src/SCREENS'; -import WorkspaceDuplicateForm from './WorkspaceDuplicateForm'; - -function WorkspaceDuplicatePage() { - const route = useRoute>(); - const policyID = route?.params?.policyID; - - useEffect(clearDuplicateWorkspace, []); - - return ( - - - - - - ); -} - -WorkspaceDuplicatePage.displayName = 'WorkspaceDuplicatePage'; - -export default WorkspaceDuplicatePage; diff --git a/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx b/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx deleted file mode 100644 index f3d548dce060a..0000000000000 --- a/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx +++ /dev/null @@ -1,351 +0,0 @@ -import React, {useCallback, useEffect, useMemo, useState} from 'react'; -import {View} from 'react-native'; -import ConfirmModal from '@components/ConfirmModal'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import SelectionList from '@components/SelectionList'; -import MultiSelectListItem from '@components/SelectionList/MultiSelectListItem'; -import type {ListItem} from '@components/SelectionList/types'; -import Text from '@components/Text'; -import useLocalize from '@hooks/useLocalize'; -import useOnyx from '@hooks/useOnyx'; -import usePolicy from '@hooks/usePolicy'; -import useThemeStyles from '@hooks/useThemeStyles'; -import {getDistanceRateCustomUnit, getMemberAccountIDsForWorkspace, getPerDiemCustomUnit} from '@libs/PolicyUtils'; -import {getReportFieldsByPolicyID} from '@libs/ReportUtils'; -import Navigation from '@navigation/Navigation'; -import {openPolicyCategoriesPage} from '@userActions/Policy/Category'; -import {openPolicyDistanceRatesPage} from '@userActions/Policy/DistanceRate'; -import {openWorkspaceMembersPage} from '@userActions/Policy/Member'; -import {openPolicyPerDiemPage} from '@userActions/Policy/PerDiem'; -import {duplicateWorkspace as duplicateWorkspaceAction, openPolicyTaxesPage, openPolicyWorkflowsPage} from '@userActions/Policy/Policy'; -import {openPolicyReportFieldsPage} from '@userActions/Policy/ReportField'; -import {openPolicyTagsPage} from '@userActions/Policy/Tag'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import type {Rate} from '@src/types/onyx/Policy'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import {getAllValidConnectedIntegration, getWorkflowRules, getWorkspaceRules} from './utils'; - -type WorkspaceDuplicateFormProps = { - policyID?: string; -}; -const DEFAULT_SELECT_ALL = 'selectAll'; - -function WorkspaceDuplicateSelectFeaturesForm({policyID}: WorkspaceDuplicateFormProps) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const policy = usePolicy(policyID); - const [duplicateWorkspace] = useOnyx(ONYXKEYS.DUPLICATE_WORKSPACE, {canBeMissing: false}); - const [isDuplicateModalOpen, setIsDuplicateModalOpen] = useState(false); - const allIds = getMemberAccountIDsForWorkspace(policy?.employeeList); - const totalMembers = Object.keys(allIds).length; - const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, {canBeMissing: false}); - const totalTags = Object.keys(policyTags ?? {}).length ?? 0; - const taxesLength = Object.keys(policy?.taxRates?.taxes ?? {}).length ?? 0; - const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, {canBeMissing: true}); - const categoriesCount = Object.keys(policyCategories ?? {}).length; - const [selectedItems, setSelectedItems] = useState([]); - const reportFields = Object.keys(getReportFieldsByPolicyID(policyID)).length ?? 0; - const customUnits = getPerDiemCustomUnit(policy); - const customUnitRates: Record = customUnits?.rates ?? {}; - const allRates = Object.values(customUnitRates)?.length; - const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST, {canBeMissing: true}); - - const accountingIntegrations = Object.values(CONST.POLICY.CONNECTIONS.NAME); - const connectedIntegration = getAllValidConnectedIntegration(policy, accountingIntegrations); - - const customUnit = getDistanceRateCustomUnit(policy); - const ratesCount = Object.keys(customUnit?.rates ?? {}).length; - const invoiceCompany = - policy?.invoice?.companyName && policy?.invoice?.companyWebsite - ? `${policy?.invoice?.companyName}, ${policy?.invoice?.companyWebsite}` - : (policy?.invoice?.companyName ?? policy?.invoice?.companyWebsite ?? ''); - - const [street1, street2] = (policy?.address?.addressStreet ?? '').split('\n'); - const formattedAddress = - !isEmptyObject(policy) && !isEmptyObject(policy.address) - ? `, ${street1?.trim()}, ${street2 ? `${street2.trim()}, ` : ''}${policy.address.city}, ${policy.address.state} ${policy.address.zipCode ?? ''}` - : ''; - - const items = useMemo(() => { - const rules = getWorkspaceRules(policy, translate); - const workflows = getWorkflowRules(policy, translate); - - const result = [ - { - translation: translate('workspace.common.selectAll'), - value: DEFAULT_SELECT_ALL, - }, - { - translation: translate('workspace.common.profile'), - value: 'overview', - alternateText: `${policy?.outputCurrency} ${translate('common.currency')}, ${formattedAddress}`, - }, - totalMembers > 1 - ? { - translation: translate('workspace.common.members'), - value: 'members', - alternateText: totalMembers ? `${totalMembers} ${translate('workspace.common.members').toLowerCase()}` : undefined, - } - : undefined, - reportFields > 0 - ? { - translation: translate('workspace.common.reports'), - value: 'reports', - alternateText: reportFields ? `${reportFields} ${translate('workspace.common.reportFields').toLowerCase()}` : undefined, - } - : undefined, - connectedIntegration && connectedIntegration?.length > 0 - ? { - translation: translate('workspace.common.accounting'), - value: 'accounting', - alternateText: connectedIntegration.map((connectionName) => CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]).join(', '), - } - : undefined, - totalTags > 0 - ? { - translation: translate('workspace.common.tags'), - value: 'tags', - alternateText: totalTags ? `${totalTags} ${translate('workspace.common.tags').toLowerCase()}` : undefined, - } - : undefined, - categoriesCount > 0 - ? { - translation: translate('workspace.common.categories'), - value: 'categories', - alternateText: categoriesCount ? `${categoriesCount} ${translate('workspace.duplicateWorkspace.categories').toLowerCase()}` : undefined, - } - : undefined, - taxesLength > 0 - ? { - translation: translate('workspace.common.taxes'), - value: 'taxes', - alternateText: taxesLength ? `${taxesLength} ${translate('workspace.common.taxes').toLowerCase()}` : undefined, - } - : undefined, - workflows && workflows?.length > 0 - ? { - translation: translate('workspace.common.workflows'), - value: 'workflows', - alternateText: workflows?.join(', '), - } - : undefined, - rules && rules.length > 0 - ? { - translation: translate('workspace.common.rules'), - value: 'rules', - alternateText: rules.length - ? `${rules.length} ${translate('workspace.common.workspace').toLowerCase()} ${translate('workspace.common.rules').toLowerCase()}: ${rules.join(', ')}` - : undefined, - } - : undefined, - ratesCount > 0 - ? { - translation: translate('workspace.common.distanceRates'), - value: 'distanceRates', - alternateText: ratesCount ? `${ratesCount} ${translate('iou.rates').toLowerCase()}` : undefined, - } - : undefined, - allRates > 0 - ? { - translation: translate('workspace.common.perDiem'), - value: 'perDiem', - alternateText: allRates ? `${allRates} ${translate('workspace.common.perDiem').toLowerCase()}` : undefined, - } - : undefined, - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - (bankAccountList && Object.keys(bankAccountList).length) || !!invoiceCompany - ? { - translation: translate('workspace.common.invoices'), - value: 'invoices', - alternateText: bankAccountList ? `${Object.keys(bankAccountList).length} ${translate('common.bankAccounts').toLowerCase()}, ${invoiceCompany}` : invoiceCompany, - } - : undefined, - ]; - - return result.filter((item): item is NonNullable => !!item); - }, [ - policy, - translate, - formattedAddress, - totalMembers, - reportFields, - connectedIntegration, - totalTags, - categoriesCount, - taxesLength, - ratesCount, - allRates, - bankAccountList, - invoiceCompany, - ]); - - const listData: ListItem[] = useMemo(() => { - return items.map((option) => { - const alternateText = option?.alternateText ? option.alternateText.trim().replace(/,$/, '') : undefined; - return { - text: option.translation, - keyForList: option.value, - isSelected: selectedItems.includes(option.value), - alternateText, - }; - }); - }, [items, selectedItems]); - - const fetchWorkspaceRelatedData = useCallback(() => { - if (!policyID) { - return; - } - openWorkspaceMembersPage(policyID, Object.keys(allIds ?? {})); - openPolicyCategoriesPage(policyID); - openPolicyDistanceRatesPage(policyID); - openPolicyPerDiemPage(policyID); - openPolicyReportFieldsPage(policyID); - openPolicyTagsPage(policyID); - openPolicyTaxesPage(policyID); - openPolicyWorkflowsPage(policyID); - }, [policyID, allIds]); - - const confirmDuplicate = useCallback(() => { - if (!policy || !duplicateWorkspace?.name || !duplicateWorkspace?.policyID) { - return; - } - duplicateWorkspaceAction(policy, { - policyName: duplicateWorkspace.name, - policyID: policy.id, - targetPolicyID: duplicateWorkspace.policyID, - welcomeNote: `${translate('workspace.duplicateWorkspace.welcomeNote')} ${duplicateWorkspace.name}`, - parts: { - people: selectedItems.includes('members'), - reports: selectedItems.includes('reports'), - connections: selectedItems.includes('accounting'), - categories: selectedItems.includes('categories'), - tags: selectedItems.includes('tags'), - taxes: selectedItems.includes('taxes'), - reimbursements: selectedItems.includes('invoices'), - expenses: selectedItems.includes('rules'), - customUnits: selectedItems.includes('distanceRates'), - invoices: selectedItems.includes('invoices'), - exportLayouts: selectedItems.includes('workflows'), - }, - file: duplicateWorkspace?.file, - }); - Navigation.closeRHPFlow(); - }, [duplicateWorkspace?.file, duplicateWorkspace?.name, duplicateWorkspace?.policyID, policy, selectedItems, translate]); - - const confirmDuplicateAndHideModal = useCallback(() => { - setIsDuplicateModalOpen(false); - if (!policy || !duplicateWorkspace?.name || !duplicateWorkspace?.policyID) { - return; - } - confirmDuplicate(); - }, [confirmDuplicate, duplicateWorkspace?.name, duplicateWorkspace?.policyID, policy]); - - const onConfirmSelectList = useCallback(() => { - if (!totalMembers || totalMembers < 2 || !selectedItems.includes('members')) { - confirmDuplicate(); - return; - } - setIsDuplicateModalOpen(true); - }, [confirmDuplicate, selectedItems, totalMembers]); - - const updateSelectedItems = useCallback( - (listItem: ListItem) => { - if (listItem.isSelected) { - if (listItem.keyForList === DEFAULT_SELECT_ALL) { - setSelectedItems([]); - return; - } - setSelectedItems(selectedItems.filter((i) => i !== listItem.keyForList && i !== DEFAULT_SELECT_ALL)); - return; - } - if (listItem.keyForList === DEFAULT_SELECT_ALL) { - setSelectedItems(items.map((i) => i.value)); - return; - } - - const newItem = items.find((i) => i.value === listItem.keyForList)?.value; - - if (newItem) { - const newSelectedItems = [...selectedItems, newItem]; - const featuresOptions = items.filter((i) => i.value !== DEFAULT_SELECT_ALL); - const allItemsSelected = featuresOptions.length === newSelectedItems.length; - - if (allItemsSelected) { - setSelectedItems([...newSelectedItems, DEFAULT_SELECT_ALL]); - } else { - setSelectedItems(newSelectedItems); - } - } - }, - [items, selectedItems], - ); - - useEffect(() => { - if (!items.length) { - return; - } - setSelectedItems(items.map((i) => i.value)); - // eslint-disable-next-line react-compiler/react-compiler - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [items.length]); - - useEffect(() => { - fetchWorkspaceRelatedData(); - // eslint-disable-next-line react-compiler/react-compiler - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return ( - <> - Navigation.goBack(ROUTES.WORKSPACE_DUPLICATE.getRoute(policyID, ROUTES.WORKSPACES_LIST.route)) : undefined} - title={translate('workspace.common.duplicateWorkspace')} - /> - <> - - {translate('workspace.duplicateWorkspace.selectFeatures')} - {translate('workspace.duplicateWorkspace.whichFeatures')} - - - - - - setIsDuplicateModalOpen(false)} - prompt={ - - - {translate('workspace.duplicateWorkspace.confirmTitle', { - newWorkspaceName: duplicateWorkspace?.name, - totalMembers, - })} - - {translate('workspace.duplicateWorkspace.confirmDuplicate')} - - } - confirmText={translate('common.proceed')} - cancelText={translate('common.cancel')} - success - /> - - ); -} - -WorkspaceDuplicateSelectFeaturesForm.displayName = 'WorkspaceDuplicateSelectFeaturesForm'; - -export default WorkspaceDuplicateSelectFeaturesForm; diff --git a/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesPage.tsx b/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesPage.tsx deleted file mode 100644 index 0359e4ef47dd4..0000000000000 --- a/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesPage.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import {useRoute} from '@react-navigation/native'; -import React from 'react'; -import ScreenWrapper from '@components/ScreenWrapper'; -import type {PlatformStackRouteProp} from '@navigation/PlatformStackNavigation/types'; -import type {WorkspaceDuplicateNavigatorParamList} from '@navigation/types'; -import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; -import CONST from '@src/CONST'; -import type SCREENS from '@src/SCREENS'; -import WorkspaceDuplicateSelectFeaturesForm from './WorkspaceDuplicateSelectFeaturesForm'; - -function WorkspaceDuplicateSelectFeaturesPage() { - const route = useRoute>(); - const policyID = route?.params?.policyID; - - return ( - - - - - - ); -} - -WorkspaceDuplicateSelectFeaturesPage.displayName = 'WorkspaceDuplicateSelectFeaturesPage'; - -export default WorkspaceDuplicateSelectFeaturesPage; diff --git a/src/pages/workspace/duplicate/utils.ts b/src/pages/workspace/duplicate/utils.ts deleted file mode 100644 index aa4a78b79e705..0000000000000 --- a/src/pages/workspace/duplicate/utils.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type {LocaleContextProps} from '@components/LocaleContextProvider'; -import {getCorrectedAutoReportingFrequency, getWorkflowApprovalsUnavailable, hasVBBA} from '@libs/PolicyUtils'; -import {getAutoReportingFrequencyDisplayNames} from '@pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage'; -import type {AutoReportingFrequencyKey} from '@pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage'; -import {isAuthenticationError} from '@userActions/connections'; -import CONST from '@src/CONST'; -import type {Policy} from '@src/types/onyx'; -import type {ConnectionName} from '@src/types/onyx/Policy'; - -function getWorkspaceRules(policy: Policy | undefined, translate: LocaleContextProps['translate']) { - const workflowApprovalsUnavailable = getWorkflowApprovalsUnavailable(policy); - const autoPayApprovedReportsUnavailable = !policy?.areWorkflowsEnabled || policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES || !hasVBBA(policy?.id); - const total: string[] = []; - if (policy?.maxExpenseAmountNoReceipt !== CONST.DISABLED_MAX_EXPENSE_VALUE) { - total.push(translate('workspace.rules.individualExpenseRules.receiptRequiredAmount')); - } - if (policy?.maxExpenseAmount !== CONST.DISABLED_MAX_EXPENSE_VALUE) { - total.push(translate('workspace.rules.individualExpenseRules.maxExpenseAmount')); - } - if (policy?.maxExpenseAge !== CONST.DISABLED_MAX_EXPENSE_VALUE) { - total.push(translate('workspace.rules.individualExpenseRules.maxExpenseAge')); - } - if (policy?.defaultBillable) { - total.push(translate('workspace.rules.individualExpenseRules.billable')); - } - if (policy?.prohibitedExpenses && Object.values(policy?.prohibitedExpenses).find((value) => value)) { - total.push(translate('workspace.rules.individualExpenseRules.prohibitedExpenses')); - } - if (policy?.eReceipts) { - total.push(translate('workspace.rules.individualExpenseRules.eReceipts')); - } - if (policy?.isAttendeeTrackingEnabled) { - total.push(translate('workspace.rules.individualExpenseRules.attendeeTracking')); - } - if (policy?.preventSelfApproval && !workflowApprovalsUnavailable) { - total.push(translate('workspace.rules.expenseReportRules.preventSelfApprovalsTitle')); - } - if (policy?.shouldShowAutoApprovalOptions && !workflowApprovalsUnavailable) { - total.push(translate('workspace.rules.expenseReportRules.autoApproveCompliantReportsTitle')); - } - if (policy?.shouldShowAutoReimbursementLimitOption && !autoPayApprovedReportsUnavailable) { - total.push(translate('workspace.rules.expenseReportRules.autoPayApprovedReportsTitle')); - } - - return total.length > 0 ? total : null; -} - -function getWorkflowRules(policy: Policy | undefined, translate: LocaleContextProps['translate']) { - const total: string[] = []; - const {bankAccountID} = policy?.achAccount ?? {}; - const hasDelayedSubmissionError = !!(policy?.errorFields?.autoReporting ?? policy?.errorFields?.autoReportingFrequency); - const hasApprovalError = !!policy?.errorFields?.approvalMode; - const shouldShowBankAccount = !!bankAccountID && policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - - if (policy?.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT && !hasDelayedSubmissionError) { - const title = - getAutoReportingFrequencyDisplayNames(translate)[(getCorrectedAutoReportingFrequency(policy) as AutoReportingFrequencyKey) ?? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY]; - total.push(`${title} ${translate('workspace.duplicateWorkspace.delayedSubmission')}`); - } - if ([CONST.POLICY.APPROVAL_MODE.BASIC, CONST.POLICY.APPROVAL_MODE.ADVANCED].some((approvalMode) => approvalMode === policy?.approvalMode) && !hasApprovalError) { - total.push(translate('common.approvals')); - } - if (policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO) { - if (shouldShowBankAccount) { - total.push(`1 ${translate('workspace.duplicateWorkspace.reimbursementAccount')}`); - } else { - total.push(translate('common.payments')); - } - } - return total.length > 0 ? total : null; -} - -function getAllValidConnectedIntegration(policy: Policy | undefined, accountingIntegrations?: ConnectionName[]) { - return (accountingIntegrations ?? Object.values(CONST.POLICY.CONNECTIONS.NAME)).filter( - (integration) => !!policy?.connections?.[integration] && !isAuthenticationError(policy, integration), - ); -} - -export {getWorkspaceRules, getWorkflowRules, getAllValidConnectedIntegration}; diff --git a/src/types/form/WorkspaceDuplicateForm.tsx b/src/types/form/WorkspaceDuplicateForm.tsx deleted file mode 100644 index 348e2e3500e84..0000000000000 --- a/src/types/form/WorkspaceDuplicateForm.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import type {ValueOf} from 'type-fest'; -import type Form from './Form'; - -const INPUT_IDS = { - NAME: 'name', -} as const; - -type InputID = ValueOf; - -type WorkspaceDuplicateForm = Form< - InputID, - { - [INPUT_IDS.NAME]: string; - } ->; - -export type {WorkspaceDuplicateForm}; -export default INPUT_IDS; diff --git a/src/types/form/index.ts b/src/types/form/index.ts index c96d8a41918d9..feffe56baea8f 100644 --- a/src/types/form/index.ts +++ b/src/types/form/index.ts @@ -34,7 +34,6 @@ export type {ReportVirtualCardFraudForm} from './ReportVirtualCardFraudForm'; export type {DebugReportForm} from './DebugReportForm'; export type {DebugReportActionForm} from './DebugReportActionForm'; export type {DebugTransactionForm} from './DebugTransactionForm'; -export type {WorkspaceDuplicateForm} from './WorkspaceDuplicateForm'; export type {DebugTransactionViolationForm} from './DebugTransactionViolationForm'; export type {RequestPhysicalCardForm} from './RequestPhysicalCardForm'; export type {RoomNameForm} from './RoomNameForm'; diff --git a/src/types/onyx/DuplicateWorkspace.ts b/src/types/onyx/DuplicateWorkspace.ts deleted file mode 100644 index 453cdfb441a59..0000000000000 --- a/src/types/onyx/DuplicateWorkspace.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; -import type * as OnyxCommon from './OnyxCommon'; - -/** Model of plaid data */ -type DuplicateWorkspace = { - /** New policy ID */ - policyID?: string; - - /** New workspace name */ - name?: string; - - /** Workspace avatar */ - file?: File | CustomRNImageManipulatorResult; - - /** Whether the data is being fetched from server */ - isLoading?: boolean; - - /** Error messages to show in UI */ - errors?: OnyxCommon.Errors; -}; - -export default DuplicateWorkspace; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 9e189f01d7445..9d13fb18e1f9f 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -28,7 +28,6 @@ import type DismissedProductTraining from './DismissedProductTraining'; import type DismissedReferralBanners from './DismissedReferralBanners'; import type Download from './Download'; import type DraftReportComments from './DraftReportComments'; -import type DuplicateWorkspace from './DuplicateWorkspace'; import type ExpensifyCardBankAccountMetadata from './ExpensifyCardBankAccountMetadata'; import type ExpensifyCardSettings from './ExpensifyCardSettings'; import type ExportTemplate from './ExportTemplate'; @@ -146,7 +145,6 @@ export type { CurrencyList, CustomStatusDraft, DismissedReferralBanners, - DuplicateWorkspace, Download, WorkspaceCardsList, ExpensifyCardSettings,