diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 903496458043..72082dea3daf 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -689,12 +689,12 @@ const ROUTES = { getRoute: (policyID: string, orderWeight: number) => `settings/workspaces/${policyID}/tags/${orderWeight}/edit` as const, }, WORKSPACE_TAG_EDIT: { - route: 'settings/workspace/:policyID/tag/:tagName/edit', - getRoute: (policyID: string, tagName: string) => `settings/workspace/${policyID}/tag/${encodeURIComponent(tagName)}/edit` as const, + route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName/edit', + getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}/edit` as const, }, WORKSPACE_TAG_SETTINGS: { - route: 'settings/workspaces/:policyID/tag/:tagName', - getRoute: (policyID: string, tagName: string) => `settings/workspaces/${policyID}/tag/${encodeURIComponent(tagName)}` as const, + route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName', + getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}` as const, }, WORKSPACE_TAG_LIST_VIEW: { route: 'settings/workspaces/:policyID/tag-list/:orderWeight', diff --git a/src/components/BlockingViews/BlockingView.tsx b/src/components/BlockingViews/BlockingView.tsx index 363342778fc0..912637d265f3 100644 --- a/src/components/BlockingViews/BlockingView.tsx +++ b/src/components/BlockingViews/BlockingView.tsx @@ -36,6 +36,9 @@ type BaseBlockingViewProps = { /** Render custom subtitle */ CustomSubtitle?: React.ReactElement; + + /** Additional styles to apply to the container */ + containerStyle?: StyleProp; }; type BlockingViewIconProps = { @@ -81,6 +84,7 @@ function BlockingView({ animationStyles = [], animationWebStyle = {}, CustomSubtitle, + containerStyle, }: BlockingViewProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -117,7 +121,7 @@ function BlockingView({ }, [styles, subtitleText, shouldEmbedLinkWithSubtitle, CustomSubtitle]); return ( - + {animation && ( ( headerContent, footerContent, listFooterContent, + listEmptyContent, showScrollIndicator = true, showLoadingPlaceholder = false, showConfirmButton = false, @@ -103,6 +104,7 @@ function BaseSelectionList( const itemFocusTimeoutRef = useRef(null); const [currentPage, setCurrentPage] = useState(1); const isTextInputFocusedRef = useRef(false); + const isEmptyList = sections.length === 0; const incrementPage = () => setCurrentPage((prev) => prev + 1); @@ -692,8 +694,11 @@ function BaseSelectionList( testID="selection-list" onLayout={onSectionListLayout} style={(!maxToRenderPerBatch || (shouldHideListOnInitialRender && isInitialSectionListRender)) && styles.opacity0} + ListHeaderComponent={listHeaderContent} ListFooterComponent={listFooterContent ?? ShowMoreButtonInstance} - ListHeaderComponent={listHeaderContent && listHeaderContent} + ListEmptyComponent={listEmptyContent} + contentContainerStyle={isEmptyList && listEmptyContent ? styles.flexGrow1 : undefined} + scrollEnabled={!isEmptyList || !listEmptyContent} onEndReached={onEndReached} onEndReachedThreshold={onEndReachedThreshold} /> diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts index 99aa96d4edbe..ae6dfed8fc32 100644 --- a/src/components/SelectionList/types.ts +++ b/src/components/SelectionList/types.ts @@ -359,6 +359,9 @@ type BaseSelectionListProps = Partial & { /** Custom content to display in the footer of list component. If present ShowMore button won't be displayed */ listFooterContent?: React.JSX.Element | null; + /** Content to display if the list is empty */ + listEmptyContent?: React.JSX.Element | null; + /** Whether to use dynamic maxToRenderPerBatch depending on the visible number of elements */ shouldUseDynamicMaxToRenderPerBatch?: boolean; diff --git a/src/components/SelectionScreen.tsx b/src/components/SelectionScreen.tsx index a2ab477accef..34ec10fb00c2 100644 --- a/src/components/SelectionScreen.tsx +++ b/src/components/SelectionScreen.tsx @@ -26,6 +26,9 @@ type SelectionScreenProps = { /** Custom content to display in the header */ headerContent?: React.ReactNode; + /** Content to display if the list is empty */ + listEmptyContent?: React.JSX.Element | null; + /** Sections for the section list */ sections: Array>; @@ -58,6 +61,7 @@ function SelectionScreen({ displayName, title, headerContent, + listEmptyContent, sections, listItem, initiallyFocusedOptionKey, @@ -92,6 +96,7 @@ function SelectionScreen({ showScrollIndicator shouldShowTooltips={false} initiallyFocusedOptionKey={initiallyFocusedOptionKey} + listEmptyContent={listEmptyContent} /> diff --git a/src/languages/en.ts b/src/languages/en.ts index bac16f8c7356..3827b3dbe05f 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1981,11 +1981,16 @@ export default { exportPreferredExporterNote: 'This can be any workspace admin, but must be a Domain Admin if you set different export accounts for individual company cards in Domain Settings.', exportPreferredExporterSubNote: 'Once set, the preferred exporter will see reports for export in their account.', exportOutOfPocketExpensesDescription: 'Set how out-of-pocket expenses export to QuickBooks Online.', + exportCheckDescription: "We'll create a single itemized check for each Expensify report. You can write the check from your bank account of choice (below).", + exportJournalEntryDescription: "We'll create a single itemized journal entry for each Expensify report. You can post the offset entry to your account of choice (below).", exportVendorBillDescription: "We'll create a single itemized vendor bill for each Expensify report. If the period of the bill is closed, we'll post to the 1st of the next open period. You can add the vendor bill to your A/P account of choice (below).", - accountsPayable: 'Accounts payable', account: 'Account', + accountDescription: 'This is your chosen account to post the journal entry offset for each report.', + accountsPayable: 'Accounts payable', accountsPayableDescription: 'This is your chosen A/P account, against which vendor bills for each report are created.', + bankAccount: 'Bank account', + bankAccountDescription: 'This is your chosen bank account to write checks from.', optionBelow: 'Choose an option below:', companyCardsLocationEnabledDescription: 'Note: QuickBooks Online does not support a field for Locations as Tags on Vendor Bills exports. As you import Locations from, this this export option is unavailable.', @@ -2035,6 +2040,8 @@ export default { [`${CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.CHECK}Error`]: 'Check is not available when locations are enabled. Please select a different export option.', [`${CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY}Error`]: 'Journal entry is not available when taxes enabled. please select a different export option.', }, + noAccountsFound: 'No accounts found', + noAccountsFoundDescription: 'Add the account in Quickbooks Online and sync the connection again', }, xero: { organization: 'Xero organization', @@ -2113,6 +2120,8 @@ export default { }, exportPreferredExporterNote: 'This can be any workspace admin, but must be a domain admin if you set different export accounts for individual company cards in domain settings.', exportPreferredExporterSubNote: 'Once set, the preferred exporter will see reports for export in their account.', + noAccountsFound: 'No accounts found', + noAccountsFoundDescription: 'Add the account in Xero and sync the connection again', }, type: { free: 'Free', diff --git a/src/languages/es.ts b/src/languages/es.ts index d637c225632d..d3889d70e5cb 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2000,11 +2000,14 @@ export default { exportInvoicesDescription: 'Las facturas se exportarán a esta cuenta en QuickBooks Online.', exportCompanyCardsDescription: 'Establece cómo se exportan las compras con tarjeta de empresa a QuickBooks Online.', account: 'Cuenta', + accountDescription: 'Esta es la cuenta elegida para contabilizar la compensación de la entrada de diario de cada informe.', vendor: 'Proveedor', defaultVendor: 'Proveedor predeterminado', defaultVendorDescription: 'Establece un proveedor predeterminado que se aplicará a todas las transacciones con tarjeta de crédito al momento de exportarlas.', accountsPayable: 'Cuentas por pagar', accountsPayableDescription: 'Esta es la cuenta de cuentas por pagar elegida, contra la cual se crean las facturas de proveedores para cada informe.', + bankAccount: 'Cuenta bancaria', + bankAccountDescription: 'Esta es la cuenta bancaria elegida para emitir cheques.', optionBelow: 'Elija una opción a continuación:', companyCardsLocationEnabledDescription: 'Nota: QuickBooks Online no admite un campo para Ubicaciones como etiquetas en las exportaciones de facturas de proveedores. A medida que importa ubicaciones, esta opción de exportación no está disponible.', @@ -2012,6 +2015,9 @@ export default { 'Puede ser cualquier administrador del espacio de trabajo, pero debe ser un administrador de dominio si configura diferentes cuentas de exportación para tarjetas de empresa individuales en la configuración del dominio.', exportPreferredExporterSubNote: 'Una vez configurado, el exportador preferido verá los informes para exportar en tu cuenta.', exportOutOfPocketExpensesDescription: 'Establezca cómo se exportan los gastos de bolsillo a QuickBooks Online.', + exportCheckDescription: 'Crearemos un único cheque desglosado para cada informe de Expensify. Puedes emitir el cheque desde la cuenta bancaria que elijas (más abajo).', + exportJournalEntryDescription: + 'Crearemos una única entrada de diario desglosada para cada informe de Expensify. Puedes enviar la compensación de la entrada de diario a la cuenta que elijas (más abajo).', exportVendorBillDescription: 'Crearemos una única factura de proveedor detallada para cada informe de Expensify. Si el período de la factura está cerrado, lo publicaremos en el día 1 del siguiente período abierto. Puede agregar la factura del proveedor a la cuenta A/P de tu elección (a continuación).', outOfPocketTaxEnabledDescription: @@ -2067,6 +2073,8 @@ export default { [`${CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY}Error`]: 'El asiento de diario no está disponible cuando los impuestos están habilitados. seleccione una opción de exportación diferente.', }, + noAccountsFound: 'No se ha encontrado ninguna cuenta', + noAccountsFoundDescription: 'Añade la cuenta en Quickbooks Online y sincroniza de nuevo la conexión', }, xero: { organization: 'Organización Xero', @@ -2149,6 +2157,8 @@ export default { exportPreferredExporterNote: 'Puede ser cualquier administrador del espacio de trabajo, pero debe ser un administrador de dominio si configura diferentes cuentas de exportación para tarjetas de empresa individuales en la configuración del dominio.', exportPreferredExporterSubNote: 'Una vez configurado, el exportador preferido verá los informes para exportar en su cuenta.', + noAccountsFound: 'No se ha encontrado ninguna cuenta', + noAccountsFoundDescription: 'Añade la cuenta en Xero y sincroniza de nuevo la conexión', }, type: { free: 'Gratis', diff --git a/src/libs/API/parameters/SetPolicyTagsEnabled.ts b/src/libs/API/parameters/SetPolicyTagsEnabled.ts index 86720b84bf8b..67928a3227e3 100644 --- a/src/libs/API/parameters/SetPolicyTagsEnabled.ts +++ b/src/libs/API/parameters/SetPolicyTagsEnabled.ts @@ -5,6 +5,11 @@ type SetPolicyTagsEnabled = { * Array<{name: string; enabled: boolean}> */ tags: string; + /** + * When the tags are imported as multi level tags, the index of the top + * most tag list item + */ + tagListIndex: number; }; export default SetPolicyTagsEnabled; diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 4a629e323687..8691129a0d5e 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -428,12 +428,14 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.TAG_EDIT]: { path: ROUTES.WORKSPACE_TAG_EDIT.route, parse: { + orderWeight: Number, tagName: (tagName: string) => decodeURIComponent(tagName), }, }, [SCREENS.WORKSPACE.TAG_SETTINGS]: { path: ROUTES.WORKSPACE_TAG_SETTINGS.route, parse: { + orderWeight: Number, tagName: (tagName: string) => decodeURIComponent(tagName), }, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 3a7b8be32a01..8de794726570 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -221,6 +221,7 @@ type SettingsNavigatorParamList = { }; [SCREENS.WORKSPACE.TAG_SETTINGS]: { policyID: string; + orderWeight: number; tagName: string; }; [SCREENS.WORKSPACE.TAG_LIST_VIEW]: { @@ -233,6 +234,7 @@ type SettingsNavigatorParamList = { }; [SCREENS.WORKSPACE.TAG_EDIT]: { policyID: string; + orderWeight: number; tagName: string; }; [SCREENS.WORKSPACE.TAXES_SETTINGS]: { @@ -801,7 +803,6 @@ type FullScreenNavigatorParamList = { }; [SCREENS.WORKSPACE.TAGS]: { policyID: string; - tagName: string; }; [SCREENS.WORKSPACE.TAXES]: { policyID: string; diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index a4e0af63512b..94c6d21344bb 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -11,6 +11,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type SetPolicyTagsEnabled from '@libs/API/parameters/SetPolicyTagsEnabled'; import type {Policy, PolicyTag, PolicyTagList, PolicyTags, RecentlyUsedTags, Report} from '@src/types/onyx'; import type {OnyxValueWithOfflineFeedback} from '@src/types/onyx/OnyxCommon'; import type {Attributes, Rate} from '@src/types/onyx/Policy'; @@ -177,8 +178,8 @@ function createPolicyTag(policyID: string, tagName: string) { API.write(WRITE_COMMANDS.CREATE_POLICY_TAG, parameters, onyxData); } -function setWorkspaceTagEnabled(policyID: string, tagsToUpdate: Record) { - const policyTag = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[0] ?? {}; +function setWorkspaceTagEnabled(policyID: string, tagsToUpdate: Record, tagListIndex: number) { + const policyTag = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[tagListIndex] ?? {}; const onyxData: OnyxData = { optimisticData: [ @@ -258,9 +259,10 @@ function setWorkspaceTagEnabled(policyID: string, tagsToUpdate: Record tagsToUpdate[key])), + tagListIndex, }; API.write(WRITE_COMMANDS.SET_POLICY_TAGS_ENABLED, parameters, onyxData); diff --git a/src/pages/workspace/WorkspaceNewRoomPage.tsx b/src/pages/workspace/WorkspaceNewRoomPage.tsx index 5716812ced16..6ec4552646ad 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.tsx +++ b/src/pages/workspace/WorkspaceNewRoomPage.tsx @@ -227,8 +227,8 @@ function WorkspaceNewRoomPage({policies, reports, formState, session, activePoli <> ({horizontal: 0, vertical: 0}); const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false); + const [datetimeToRelative, setDateTimeToRelative] = useState(''); const threeDotsMenuContainerRef = useRef(null); const isSyncInProgress = !!connectionSyncProgress?.stageInProgress && connectionSyncProgress.stageInProgress !== CONST.POLICY.CONNECTIONS.SYNC_STAGE_NAME.JOB_DONE; @@ -117,6 +119,8 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF const accountingIntegrations = Object.values(CONST.POLICY.CONNECTIONS.NAME).filter((name) => !(name === CONST.POLICY.CONNECTIONS.NAME.XERO && !canUseXeroIntegration)); const connectedIntegration = accountingIntegrations.find((integration) => !!policy?.connections?.[integration]) ?? connectionSyncProgress?.connectionName; const policyID = policy?.id ?? ''; + const successfulDate = policy?.connections?.quickbooksOnline?.lastSync?.successfulDate; + const formattedDate = useMemo(() => (successfulDate ? new Date(successfulDate) : new Date()), [successfulDate]); const policyConnectedToXero = connectedIntegration === CONST.POLICY.CONNECTIONS.NAME.XERO; @@ -141,6 +145,10 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF [translate, policyID, isOffline], ); + useEffect(() => { + setDateTimeToRelative(formatDistanceToNow(formattedDate, {addSuffix: true})); + }, [formattedDate]); + const connectionsMenuItems: MenuItemProps[] = useMemo(() => { if (isEmptyObject(policy?.connections) && !isSyncInProgress) { return accountingIntegrations.map((integration) => { @@ -169,10 +177,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress, isConnectionDataF wrapperStyle: [styles.sectionMenuItemTopDescription], shouldShowRightComponent: true, title: integrationData?.title, - - description: isSyncInProgress - ? translate('workspace.accounting.connections.syncStageName', connectionSyncProgress.stageInProgress) - : translate('workspace.accounting.lastSync'), + description: isSyncInProgress ? translate('workspace.accounting.connections.syncStageName', connectionSyncProgress.stageInProgress) : datetimeToRelative, rightComponent: isSyncInProgress ? ( ( + + ), + [translate, styles.pb10], + ); + return ( diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx index 4c1eba8f2167..0478a91379a4 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx @@ -1,6 +1,8 @@ import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; +import BlockingView from '@components/BlockingViews/BlockingView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; @@ -13,6 +15,7 @@ import Navigation from '@libs/Navigation/Navigation'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -59,6 +62,20 @@ function QuickbooksInvoiceAccountSelectPage({policy}: WithPolicyConnectionsProps [policyID], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx index 892a84f9dfde..7457d225e4df 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx @@ -1,5 +1,7 @@ import React, {useCallback, useMemo} from 'react'; +import BlockingView from '@components/BlockingViews/BlockingView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; @@ -12,6 +14,7 @@ import Navigation from '@navigation/Navigation'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {Account} from '@src/types/onyx/Policy'; @@ -62,6 +65,20 @@ function QuickbooksCompanyCardExpenseAccountSelectPage({policy}: WithPolicyConne [nonReimbursableExpensesAccount, policyID], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( {translate(`workspace.qbo.accounts.${nonReimbursableExpensesExportDestination}AccountDescription`)} ) : null } - sections={[{data}]} + sections={data.length ? [{data}] : []} ListItem={RadioListItem} onSelectRow={selectExportAccount} shouldDebounceRowSelect initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} + listEmptyContent={listEmptyContent} /> diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx index 5f72beb8d89f..4c114cc48422 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx @@ -1,5 +1,7 @@ import React, {useCallback, useMemo} from 'react'; +import BlockingView from '@components/BlockingViews/BlockingView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; @@ -12,6 +14,7 @@ import Navigation from '@navigation/Navigation'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {Account} from '@src/types/onyx/Policy'; @@ -48,6 +51,20 @@ function QuickbooksExportInvoiceAccountSelectPage({policy}: WithPolicyConnection [receivableAccount, policyID], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( {translate('workspace.qbo.exportInvoicesDescription')}} - sections={[{data}]} + sections={data.length ? [{data}] : []} ListItem={RadioListItem} onSelectRow={selectExportInvoice} shouldDebounceRowSelect initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} + listEmptyContent={listEmptyContent} /> diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx index 5264f6c0c45e..79f62934bcd4 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx @@ -1,5 +1,7 @@ import React, {useCallback, useMemo} from 'react'; +import BlockingView from '@components/BlockingViews/BlockingView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; @@ -12,6 +14,7 @@ import Navigation from '@navigation/Navigation'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -34,7 +37,7 @@ function QuickbooksNonReimbursableDefaultVendorSelectPage({policy}: WithPolicyCo keyForList: vendor.name, isSelected: vendor.id === nonReimbursableBillDefaultVendor, })) ?? []; - return [{data}]; + return data.length ? [{data}] : []; }, [nonReimbursableBillDefaultVendor, vendors]); const selectVendor = useCallback( @@ -47,6 +50,20 @@ function QuickbooksNonReimbursableDefaultVendorSelectPage({policy}: WithPolicyCo [nonReimbursableBillDefaultVendor, policyID], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( mode.isSelected)?.keyForList} + initiallyFocusedOptionKey={sections[0]?.data.find((mode) => mode.isSelected)?.keyForList} + listEmptyContent={listEmptyContent} /> diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx index e9944a289922..1d85d85c133d 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx @@ -1,5 +1,7 @@ import React, {useCallback, useMemo} from 'react'; +import BlockingView from '@components/BlockingViews/BlockingView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import RadioListItem from '@components/SelectionList/RadioListItem'; @@ -12,6 +14,7 @@ import Navigation from '@navigation/Navigation'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {Account} from '@src/types/onyx/Policy'; @@ -27,18 +30,41 @@ function QuickbooksOutOfPocketExpenseAccountSelectPage({policy}: WithPolicyConne const {reimbursableExpensesExportDestination, reimbursableExpensesAccount} = policy?.connections?.quickbooksOnline?.config ?? {}; + const [title, description] = useMemo(() => { + let titleText: string | undefined; + let descriptionText: string | undefined; + switch (reimbursableExpensesExportDestination) { + case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.CHECK: + titleText = translate('workspace.qbo.bankAccount'); + descriptionText = translate('workspace.qbo.bankAccountDescription'); + break; + case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY: + titleText = translate('workspace.qbo.account'); + descriptionText = translate('workspace.qbo.accountDescription'); + break; + case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL: + titleText = translate('workspace.qbo.accountsPayable'); + descriptionText = translate('workspace.qbo.accountsPayableDescription'); + break; + default: + break; + } + + return [titleText, descriptionText]; + }, [translate, reimbursableExpensesExportDestination]); + const data: CardListItem[] = useMemo(() => { let accounts: Account[]; switch (reimbursableExpensesExportDestination) { case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.CHECK: accounts = bankAccounts ?? []; break; - case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL: - accounts = accountPayable ?? []; - break; case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY: accounts = journalEntryAccounts ?? []; break; + case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL: + accounts = accountPayable ?? []; + break; default: accounts = []; } @@ -63,6 +89,20 @@ function QuickbooksOutOfPocketExpenseAccountSelectPage({policy}: WithPolicyConne [reimbursableExpensesAccount, policyID], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( - + {translate('workspace.qbo.accountsPayableDescription')}} - sections={[{data}]} + headerContent={{description}} + sections={data.length ? [{data}] : []} ListItem={RadioListItem} onSelectRow={selectExportAccount} shouldDebounceRowSelect initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} + listEmptyContent={listEmptyContent} /> diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseConfigurationPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseConfigurationPage.tsx index 861f7d416902..aa521ddc7465 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseConfigurationPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseConfigurationPage.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useMemo} from 'react'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -24,6 +24,28 @@ function QuickbooksOutOfPocketExpenseConfigurationPage({policy}: WithPolicyConne const shouldShowTaxError = isTaxesEnabled && reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY; const shouldShowLocationError = isLocationEnabled && reimbursableExpensesExportDestination !== CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY; const hasErrors = Boolean(errorFields?.reimbursableExpensesExportDestination) || shouldShowTaxError || shouldShowLocationError; + const [exportHintText, accountDescription] = useMemo(() => { + let hintText: string | undefined; + let description: string | undefined; + switch (reimbursableExpensesExportDestination) { + case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.CHECK: + hintText = isLocationEnabled ? undefined : translate('workspace.qbo.exportCheckDescription'); + description = translate('workspace.qbo.bankAccount'); + break; + case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY: + hintText = isTaxesEnabled ? undefined : translate('workspace.qbo.exportJournalEntryDescription'); + description = translate('workspace.qbo.account'); + break; + case CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL: + hintText = isLocationEnabled ? undefined : translate('workspace.qbo.exportVendorBillDescription'); + description = translate('workspace.qbo.accountsPayable'); + break; + default: + break; + } + + return [hintText, description]; + }, [translate, reimbursableExpensesExportDestination, isLocationEnabled, isTaxesEnabled]); return ( Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_EXPORT_OUT_OF_POCKET_EXPENSES_SELECT.getRoute(policyID))} brickRoadIndicator={hasErrors ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} shouldShowRightIcon - hintText={ - reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL && !isLocationEnabled - ? translate('workspace.qbo.exportVendorBillDescription') - : undefined - } + hintText={exportHintText} /> {isLocationEnabled && {translate('workspace.qbo.outOfPocketLocationEnabledDescription')}} @@ -58,7 +76,7 @@ function QuickbooksOutOfPocketExpenseConfigurationPage({policy}: WithPolicyConne Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_EXPORT_OUT_OF_POCKET_EXPENSES_ACCOUNT_SELECT.getRoute(policyID))} brickRoadIndicator={errorFields?.exportAccount ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} shouldShowRightIcon diff --git a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx index 11ac106f516c..34fcd46af5c2 100644 --- a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx +++ b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx @@ -1,5 +1,7 @@ import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; +import BlockingView from '@components/BlockingViews/BlockingView'; +import * as Illustrations from '@components/Icon/Illustrations'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {SelectorType} from '@components/SelectionScreen'; import SelectionScreen from '@components/SelectionScreen'; @@ -10,6 +12,7 @@ import * as Connections from '@libs/actions/connections'; import Navigation from '@libs/Navigation/Navigation'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -54,13 +57,27 @@ function XeroBillPaymentAccountSelectorPage({policy}: WithPolicyConnectionsProps [policyID], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID))} title="workspace.xero.advancedConfig.xeroBillPaymentAccount" + listEmptyContent={listEmptyContent} /> ); } diff --git a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx index ba7749fef4f2..bc6e4f54d80a 100644 --- a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx +++ b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx @@ -1,5 +1,7 @@ import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; +import BlockingView from '@components/BlockingViews/BlockingView'; +import * as Illustrations from '@components/Icon/Illustrations'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {SelectorType} from '@components/SelectionScreen'; import SelectionScreen from '@components/SelectionScreen'; @@ -10,6 +12,7 @@ import * as Connections from '@libs/actions/connections'; import Navigation from '@libs/Navigation/Navigation'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -54,13 +57,27 @@ function XeroInvoiceAccountSelectorPage({policy}: WithPolicyConnectionsProps) { [policyID], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID))} title="workspace.xero.advancedConfig.xeroInvoiceCollectionAccount" + listEmptyContent={listEmptyContent} /> ); } diff --git a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx index 897ed0b37d78..f818c5b3fba6 100644 --- a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx +++ b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx @@ -1,5 +1,7 @@ import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; +import BlockingView from '@components/BlockingViews/BlockingView'; +import * as Illustrations from '@components/Icon/Illustrations'; import RadioListItem from '@components/SelectionList/RadioListItem'; import type {SelectorType} from '@components/SelectionScreen'; import SelectionScreen from '@components/SelectionScreen'; @@ -10,6 +12,7 @@ import * as Connections from '@libs/actions/connections'; import Navigation from '@libs/Navigation/Navigation'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import variables from '@styles/variables'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -56,19 +59,34 @@ function XeroBankAccountSelectPage({policy}: WithPolicyConnectionsProps) { [policyID, initiallyFocusedOptionKey], ); + const listEmptyContent = useMemo( + () => ( + + ), + [translate, styles.pb10], + ); + return ( Navigation.goBack(ROUTES.POLICY_ACCOUNTING_XERO_EXPORT.getRoute(policyID))} title="workspace.xero.xeroBankAccount" + listEmptyContent={listEmptyContent} /> ); } diff --git a/src/pages/workspace/tags/EditTagPage.tsx b/src/pages/workspace/tags/EditTagPage.tsx index 36c484274adc..a6b3b5dd6657 100644 --- a/src/pages/workspace/tags/EditTagPage.tsx +++ b/src/pages/workspace/tags/EditTagPage.tsx @@ -41,7 +41,7 @@ function EditTagPage({route, policyTags}: EditTagPageProps) { (values: FormOnyxValues) => { const errors: FormInputErrors = {}; const tagName = values.tagName.trim(); - const {tags} = PolicyUtils.getTagList(policyTags, 0); + const {tags} = PolicyUtils.getTagList(policyTags, route.params.orderWeight); if (!ValidationUtils.isRequiredFulfilled(tagName)) { errors.tagName = 'workspace.tags.tagRequiredError'; } else if (tags?.[tagName] && currentTagName !== tagName) { @@ -50,7 +50,7 @@ function EditTagPage({route, policyTags}: EditTagPageProps) { return errors; }, - [currentTagName, policyTags], + [route.params.orderWeight, currentTagName, policyTags], ); const editTag = useCallback( diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index 646b0d20e9fa..a4f6940814dd 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -38,7 +38,7 @@ type TagSettingsPageProps = TagSettingsPageOnyxProps & StackScreenProps PolicyUtils.getTagList(policyTags, 0), [policyTags]); + const policyTag = useMemo(() => PolicyUtils.getTagList(policyTags, route.params.orderWeight), [policyTags, route.params.orderWeight]); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID}`); const {windowWidth} = useWindowDimensions(); @@ -66,11 +66,11 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) }; const updateWorkspaceTagEnabled = (value: boolean) => { - setWorkspaceTagEnabled(route.params.policyID, {[currentPolicyTag.name]: {name: currentPolicyTag.name, enabled: value}}); + setWorkspaceTagEnabled(route.params.policyID, {[currentPolicyTag.name]: {name: currentPolicyTag.name, enabled: value}}, policyTag.orderWeight); }; const navigateToEditTag = () => { - Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(route.params.policyID, currentPolicyTag.name)); + Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); }; const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0; diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 84640f63b063..1e7bc3f6d101 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -155,11 +155,11 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { }; const navigateToTagSettings = (tag: TagListItem) => { - if (tag.orderWeight != null) { + if (tag.orderWeight !== undefined) { Navigation.navigate(ROUTES.WORKSPACE_TAG_LIST_VIEW.getRoute(policyID, tag.orderWeight)); return; } - Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, tag.value)); + Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, 0, tag.value)); }; const selectedTagsArray = Object.keys(selectedTags).filter((key) => selectedTags[key]); @@ -239,7 +239,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.DISABLE, onSelected: () => { setSelectedTags({}); - Tag.setWorkspaceTagEnabled(policyID, tagsToDisable); + Tag.setWorkspaceTagEnabled(policyID, tagsToDisable, 0); }, }); } @@ -251,7 +251,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.ENABLE, onSelected: () => { setSelectedTags({}); - Tag.setWorkspaceTagEnabled(policyID, tagsToEnable); + Tag.setWorkspaceTagEnabled(policyID, tagsToEnable, 0); }, }); } diff --git a/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx index f0f9f700cb37..15e9e605e8d4 100644 --- a/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx @@ -13,6 +13,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Tag from '@libs/actions/Policy/Tag'; import Navigation from '@libs/Navigation/Navigation'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; @@ -32,7 +33,7 @@ function WorkspaceTagsSettingsPage({route, policyTags}: WorkspaceTagsSettingsPag const styles = useThemeStyles(); const {translate} = useLocalize(); const [policyTagLists, isMultiLevelTags] = useMemo(() => [PolicyUtils.getTagLists(policyTags), PolicyUtils.isMultiLevelTags(policyTags)], [policyTags]); - + const hasEnabledOptions = OptionsListUtils.hasEnabledOptions(Object.values(policyTags ?? {}).flatMap(({tags}) => Object.values(tags))); const updateWorkspaceRequiresTag = useCallback( (value: boolean) => { Tag.setPolicyRequiresTag(route.params.policyID, value); @@ -66,6 +67,7 @@ function WorkspaceTagsSettingsPage({route, policyTags}: WorkspaceTagsSettingsPag isOn={policy?.requiresTag ?? false} accessibilityLabel={translate('workspace.tags.requiresTag')} onToggle={updateWorkspaceRequiresTag} + disabled={!policy?.areTagsEnabled || !hasEnabledOptions} /> diff --git a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx index d28415b1b372..1b91777a22ad 100644 --- a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx @@ -117,7 +117,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) { ); const navigateToTagSettings = (tag: TagListItem) => { - Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, tag.value)); + Navigation.navigate(ROUTES.WORKSPACE_TAG_SETTINGS.getRoute(policyID, route.params.orderWeight, tag.value)); }; const selectedTagsArray = Object.keys(selectedTags).filter((key) => selectedTags[key]); @@ -175,7 +175,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) { value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.DISABLE, onSelected: () => { setSelectedTags({}); - Tag.setWorkspaceTagEnabled(policyID, tagsToDisable); + Tag.setWorkspaceTagEnabled(policyID, tagsToDisable, route.params.orderWeight); }, }); } @@ -187,7 +187,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) { value: CONST.POLICY.TAGS_BULK_ACTION_TYPES.ENABLE, onSelected: () => { setSelectedTags({}); - Tag.setWorkspaceTagEnabled(policyID, tagsToEnable); + Tag.setWorkspaceTagEnabled(policyID, tagsToEnable, route.params.orderWeight); }, }); } diff --git a/src/styles/utils/spacing.ts b/src/styles/utils/spacing.ts index 4584a38e8171..c963594684cb 100644 --- a/src/styles/utils/spacing.ts +++ b/src/styles/utils/spacing.ts @@ -601,6 +601,10 @@ export default { paddingBottom: 56, }, + pb10: { + paddingBottom: 40, + }, + pb20: { paddingBottom: 80, }, diff --git a/src/styles/variables.ts b/src/styles/variables.ts index f6415a1df774..6f1cac46d729 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -128,8 +128,8 @@ export default { borderTopWidth: 1, emptyLHNIconWidth: 24, // iconSizeSmall + 4*2 horizontal margin emptyLHNIconHeight: 16, - emptyWorkspaceIconWidth: 84, - emptyWorkspaceIconHeight: 84, + emptyListIconWidth: 136, + emptyListIconHeight: 144, modalTopIconWidth: 200, modalTopIconHeight: 164, modalTopBigIconHeight: 244, diff --git a/tests/actions/PolicyTagTest.ts b/tests/actions/PolicyTagTest.ts index 102466b7ed9f..ad473633d876 100644 --- a/tests/actions/PolicyTagTest.ts +++ b/tests/actions/PolicyTagTest.ts @@ -395,7 +395,7 @@ describe('actions/Policy', () => { Onyx.set(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${fakePolicy.id}`, fakePolicyTags); }) .then(() => { - Tag.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate); + Tag.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate, 0); return waitForBatchedUpdates(); }) .then( @@ -468,7 +468,7 @@ describe('actions/Policy', () => { .then(() => { mockFetch?.fail?.(); - Tag.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate); + Tag.setWorkspaceTagEnabled(fakePolicy.id, tagsToUpdate, 0); return waitForBatchedUpdates(); }) .then(mockFetch?.resume)