From 6a640fe342eb99365ab3698b360842311e913efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 13:50:03 +0100 Subject: [PATCH 001/102] add workflows icon --- assets/images/workflows.svg | 1 + src/components/Icon/Expensicons.ts | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 assets/images/workflows.svg diff --git a/assets/images/workflows.svg b/assets/images/workflows.svg new file mode 100644 index 000000000000..24156c66eb69 --- /dev/null +++ b/assets/images/workflows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index 252d13259aea..d81158544906 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -135,6 +135,7 @@ import User from '@assets/images/user.svg'; import Users from '@assets/images/users.svg'; import Wallet from '@assets/images/wallet.svg'; import Workspace from '@assets/images/workspace-default-avatar.svg'; +import Workflows from '@assets/images/workflows.svg'; import Wrench from '@assets/images/wrench.svg'; import Zoom from '@assets/images/zoom.svg'; import LoungeAccess from './svgs/LoungeAccessIcon'; @@ -270,6 +271,7 @@ export { User, Users, Wallet, + Workflows, Workspace, Zoom, Twitter, From 32219ced45a3e78c47a6c34b877b9546529ec0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 13:50:17 +0100 Subject: [PATCH 002/102] add workflow translation keys --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index f24b0e3e2438..16ee8a24db1a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1533,6 +1533,7 @@ export default { workspace: { common: { card: 'Cards', + workflows: 'Workflows', workspace: 'Workspace', edit: 'Edit workspace', delete: 'Delete workspace', diff --git a/src/languages/es.ts b/src/languages/es.ts index 3238e7fa94b0..9a0e33c266b8 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1555,6 +1555,7 @@ export default { workspace: { common: { card: 'Tarjetas', + workflows: 'Flujos de trabajo', workspace: 'Espacio de trabajo', edit: 'Editar espacio de trabajo', delete: 'Eliminar espacio de trabajo', From c189537471ac5120384fa766084d0e3e3f43b54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 13:50:51 +0100 Subject: [PATCH 003/102] add workflows route --- src/ROUTES.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 5a2ab8cfc7de..7645c75cb119 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -456,6 +456,10 @@ const ROUTES = { route: 'workspace/:policyID/settings/currency', getRoute: (policyID: string) => `workspace/${policyID}/settings/currency` as const, }, + WORKSPACE_WORKFLOWS: { + route: 'workspace/:policyID/workflows', + getRoute: (policyID: string) => `workspace/${policyID}/workflows` as const, + }, WORKSPACE_CARD: { route: 'workspace/:policyID/card', getRoute: (policyID: string) => `workspace/${policyID}/card` as const, From ed7f4e38fcd7bf2e77e66ffebb7ad613288ae15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 13:51:01 +0100 Subject: [PATCH 004/102] add workflows screen --- src/SCREENS.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 1d7c77bf129c..8c07b6be8811 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -205,6 +205,7 @@ const SCREENS = { INVITE: 'Workspace_Invite', INVITE_MESSAGE: 'Workspace_Invite_Message', CURRENCY: 'Workspace_Profile_Currency', + WORKFLOWS: 'Workspace_Workflows', NAME: 'Workspace_Profile_Name', }, From 6062cea63e0720759548a74d0f71dd4e4a38aa18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 13:51:27 +0100 Subject: [PATCH 005/102] add workflows to central pane --- .../CentralPaneNavigator/BaseCentralPaneNavigator.tsx | 1 + src/libs/Navigation/linkingConfig/config.ts | 3 +++ src/libs/Navigation/types.ts | 3 +++ 3 files changed, 7 insertions(+) diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx index 087e963b3892..204bb361d6e6 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx @@ -17,6 +17,7 @@ const workspaceSettingsScreens = { [SCREENS.SETTINGS.WORKSPACES]: () => require('../../../../../pages/workspace/WorkspacesListPage').default as React.ComponentType, [SCREENS.WORKSPACE.PROFILE]: () => require('../../../../../pages/workspace/WorkspaceProfilePage').default as React.ComponentType, [SCREENS.WORKSPACE.CARD]: () => require('../../../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType, + [SCREENS.WORKSPACE.WORKFLOWS]: () => require('../../../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType, [SCREENS.WORKSPACE.REIMBURSE]: () => require('../../../../../pages/workspace/reimburse/WorkspaceReimbursePage').default as React.ComponentType, [SCREENS.WORKSPACE.BILLS]: () => require('../../../../../pages/workspace/bills/WorkspaceBillsPage').default as React.ComponentType, [SCREENS.WORKSPACE.INVOICES]: () => require('../../../../../pages/workspace/invoices/WorkspaceInvoicesPage').default as React.ComponentType, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index ab218adc3879..23091cfebba5 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -46,6 +46,9 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.CARD]: { path: ROUTES.WORKSPACE_CARD.route, }, + [SCREENS.WORKSPACE.WORKFLOWS]: { + path: ROUTES.WORKSPACE_WORKFLOWS.route, + }, [SCREENS.WORKSPACE.REIMBURSE]: { path: ROUTES.WORKSPACE_REIMBURSE.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index bbdb03ab3df8..2f06eee954d9 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -59,6 +59,9 @@ type CentralPaneNavigatorParamList = { [SCREENS.WORKSPACE.CARD]: { policyID: string; }; + [SCREENS.WORKSPACE.WORKFLOWS]: { + policyID: string; + }; [SCREENS.WORKSPACE.REIMBURSE]: { policyID: string; }; From ab54b30a40b0dfa39686bcc5691b995980229736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 13:51:38 +0100 Subject: [PATCH 006/102] add workflows to menu items --- src/pages/workspace/WorkspaceInitialPage.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 3f7bfc92d48d..803504824b72 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -100,6 +100,12 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy); const protectedMenuItems: WorkspaceMenuItem[] = [ + { + translationKey: 'workspace.common.workflows', + icon: Expensicons.Workflows, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.WORKFLOWS, + }, { translationKey: 'workspace.common.card', icon: Expensicons.ExpensifyCard, From e4b2d68060521b4866f353808034b2c86047cff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 17:13:43 +0100 Subject: [PATCH 007/102] add translations for workflows page --- src/languages/en.ts | 11 +++++++++++ src/languages/es.ts | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index 16ee8a24db1a..39b73b4bcbe6 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -987,6 +987,17 @@ export default { }, cardDetailsLoadingFailure: 'An error occurred while loading the card details. Please check your internet connection and try again.', }, + workflowsPage: + { + workflowTitle: 'Spend workflow', + workflowDescription: 'Configure a workflow from the moment spend occurs, including approval and payment.', + delaySubmissionTitle: 'Delay submissions', + delaySubmissionDescription: 'Set a slower cadence to receive expense submissions.', + addApprovalsTitle: 'Add approval', + addApprovalsDescription: 'Set a slower cadence to receive expense submissions in real time.', + makeOrTrackPaymentsTitle: 'Make or track payments', + makeOrTrackPaymentsDescription: 'Add an authorized payer for payments made in Expensify, or simply track payments made elsewhere.', + }, reportFraudPage: { title: 'Report virtual card fraud', description: 'If your virtual card details have been stolen or compromised, we’ll permanently deactivate your existing card and provide you with a new virtual card and number.', diff --git a/src/languages/es.ts b/src/languages/es.ts index 9a0e33c266b8..7c3d04549a5d 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -982,6 +982,17 @@ export default { }, cardDetailsLoadingFailure: 'Se ha producido un error al cargar los datos de la tarjeta. Comprueba tu conexión a Internet e inténtalo de nuevo.', }, + workflowsPage: + { + workflowTitle: 'Flujo de trabajo de gastos', + workflowDescription: 'Configure un flujo de trabajo desde el momento en que se produce el gasto, incluida la aprobación y el pago.', + delaySubmissionTitle: 'Retrasar las presentaciones', + delaySubmissionDescription: 'Establezca una cadencia más lenta para recibir los envíos de gastos.', + addApprovalsTitle: 'Añadir aprobación', + addApprovalsDescription: 'Establezca una cadencia más lenta para recibir los envíos de gastos en tiempo real.', + makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', + makeOrTrackPaymentsDescription: 'Añada un pagador autorizado para los pagos realizados en Expensify, o simplemente realice un seguimiento de los pagos realizados en otro lugar.', + }, reportFraudPage: { title: 'Reportar fraude con la tarjeta virtual', description: @@ -1556,6 +1567,7 @@ export default { common: { card: 'Tarjetas', workflows: 'Flujos de trabajo', + spendWorkflow: 'Flujo de trabajo de gastos', workspace: 'Espacio de trabajo', edit: 'Editar espacio de trabajo', delete: 'Eliminar espacio de trabajo', From 67ce9fa1b1041e788483e3b6b4ba95c9eaf7e591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 17:14:04 +0100 Subject: [PATCH 008/102] add styles for workflows --- src/styles/index.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/styles/index.ts b/src/styles/index.ts index 1bea3d298cd4..811dd6af592a 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4337,6 +4337,27 @@ const styles = (theme: ThemeColors) => updateRequiredViewTextContainer: { width: variables.updateTextViewContainerWidth, }, + workspaceWorkflowsIcon: { + height: 48, + width: 48, + marginRight: 12, + }, + workspaceWorkflowsContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + workspaceWorkflowsHeading: { + fontSize: 15, + fontWeight: '700', + }, + workspaceWorkflowsWrapperText: { + flexDirection: 'column', + }, + workspaceWorkflowsSubtitle: { + fontSize: 13, + color: theme.textSupporting, + marginTop: 3, + } } satisfies Styles); type ThemeStyles = ReturnType; From 4b8418633246e88a9dec587529b9993d84ba6f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 17:14:22 +0100 Subject: [PATCH 009/102] add workflows related icons --- .../simple-illustrations/simple-illustration__approval.svg | 1 + .../simple-illustration__receipt-envelope.svg | 1 + .../simple-illustration__wallet-alt.svg | 1 + src/components/Icon/Illustrations.ts | 6 ++++++ 4 files changed, 9 insertions(+) create mode 100644 assets/images/simple-illustrations/simple-illustration__approval.svg create mode 100644 assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg create mode 100644 assets/images/simple-illustrations/simple-illustration__wallet-alt.svg diff --git a/assets/images/simple-illustrations/simple-illustration__approval.svg b/assets/images/simple-illustrations/simple-illustration__approval.svg new file mode 100644 index 000000000000..8816849fa39e --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__approval.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg b/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg new file mode 100644 index 000000000000..d16bea869771 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg new file mode 100644 index 000000000000..6cce2acd04f6 --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts index 51422e7b4a49..23a8e6eba151 100644 --- a/src/components/Icon/Illustrations.ts +++ b/src/components/Icon/Illustrations.ts @@ -62,6 +62,9 @@ import ThumbsUpStars from '@assets/images/simple-illustrations/simple-illustrati import TrackShoe from '@assets/images/simple-illustrations/simple-illustration__track-shoe.svg'; import TrashCan from '@assets/images/simple-illustrations/simple-illustration__trashcan.svg'; import TreasureChest from '@assets/images/simple-illustrations/simple-illustration__treasurechest.svg'; +import Approval from '@assets/images/simple-illustrations/simple-illustration__approval.svg'; +import ReceiptEnvelope from '@assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg'; +import WalletAlt from '@assets/images/simple-illustrations/simple-illustration__wallet-alt.svg'; export { Abracadabra, @@ -128,4 +131,7 @@ export { LockClosed, Gears, QrCode, + ReceiptEnvelope, + Approval, + WalletAlt, }; From 657f637072a394ee24d4cc6fe7abd45874b95481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 17:14:59 +0100 Subject: [PATCH 010/102] add workflows --- src/CONST.ts | 1 + src/libs/Navigation/linkingConfig/TAB_TO_CENTRAL_PANE_MAPPING.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/CONST.ts b/src/CONST.ts index eae4b8ec7a2b..4a5d15ec8428 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1513,6 +1513,7 @@ const CONST = { WORKSPACE_INVOICES: 'WorkspaceSendInvoices', WORKSPACE_TRAVEL: 'WorkspaceBookTravel', WORKSPACE_MEMBERS: 'WorkspaceManageMembers', + WORKSPACE_WORKFLOWS: 'WorkspaceWorkflows', WORKSPACE_BANK_ACCOUNT: 'WorkspaceBankAccount', }, get EXPENSIFY_EMAILS() { diff --git a/src/libs/Navigation/linkingConfig/TAB_TO_CENTRAL_PANE_MAPPING.ts b/src/libs/Navigation/linkingConfig/TAB_TO_CENTRAL_PANE_MAPPING.ts index 446fb479ea09..f17a9f526800 100755 --- a/src/libs/Navigation/linkingConfig/TAB_TO_CENTRAL_PANE_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/TAB_TO_CENTRAL_PANE_MAPPING.ts @@ -7,6 +7,7 @@ const TAB_TO_CENTRAL_PANE_MAPPING: Record = { [SCREENS.WORKSPACE.INITIAL]: [ SCREENS.WORKSPACE.PROFILE, SCREENS.WORKSPACE.CARD, + SCREENS.WORKSPACE.WORKFLOWS, SCREENS.WORKSPACE.REIMBURSE, SCREENS.WORKSPACE.BILLS, SCREENS.WORKSPACE.INVOICES, From b62413fd79ad5a4a6d88b71186394477477fc2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 17:15:17 +0100 Subject: [PATCH 011/102] create workspace workflows main page --- .../workflows/WorkspaceWorkflowsPage.tsx | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx new file mode 100644 index 000000000000..79afb996a497 --- /dev/null +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -0,0 +1,54 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React from 'react'; +import {View} from 'react-native'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import type {CentralPaneNavigatorParamList} from '@navigation/types'; +import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; +import CONST from '@src/CONST'; +import type SCREENS from '@src/SCREENS'; +import Text from '@components/Text'; +import Section from '@components/Section'; +import * as Illustrations from '@components/Icon/Illustrations'; + +type WorkspaceWorkflowsPageProps = StackScreenProps; + +function WorkspaceWorkflowsPage({route}: WorkspaceWorkflowsPageProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const {isSmallScreenWidth} = useWindowDimensions(); + + return ( + + {(_, policyID: string) => ( + +
+ + {translate('workflowsPage.workflowDescription')} + + + + + {translate('workflowsPage.delaySubmissionTitle')} + {translate('workflowsPage.delaySubmissionDescription')} + + + + +
+
+ )} +
+ ); +} + +WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; + +export default WorkspaceWorkflowsPage; From 4c41b30e0091baf84f714bf1c8b17ac1dbf256f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 12 Feb 2024 17:15:28 +0100 Subject: [PATCH 012/102] use workspace workflows main page --- .../CentralPaneNavigator/BaseCentralPaneNavigator.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx index 204bb361d6e6..ef5b46968f58 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.tsx @@ -17,7 +17,7 @@ const workspaceSettingsScreens = { [SCREENS.SETTINGS.WORKSPACES]: () => require('../../../../../pages/workspace/WorkspacesListPage').default as React.ComponentType, [SCREENS.WORKSPACE.PROFILE]: () => require('../../../../../pages/workspace/WorkspaceProfilePage').default as React.ComponentType, [SCREENS.WORKSPACE.CARD]: () => require('../../../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType, - [SCREENS.WORKSPACE.WORKFLOWS]: () => require('../../../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType, + [SCREENS.WORKSPACE.WORKFLOWS]: () => require('../../../../../pages/workspace/workflows/WorkspaceWorkflowsPage').default as React.ComponentType, [SCREENS.WORKSPACE.REIMBURSE]: () => require('../../../../../pages/workspace/reimburse/WorkspaceReimbursePage').default as React.ComponentType, [SCREENS.WORKSPACE.BILLS]: () => require('../../../../../pages/workspace/bills/WorkspaceBillsPage').default as React.ComponentType, [SCREENS.WORKSPACE.INVOICES]: () => require('../../../../../pages/workspace/invoices/WorkspaceInvoicesPage').default as React.ComponentType, From 6cc2a08cd5629aba19f932d7a242841977110168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 13 Feb 2024 16:34:28 +0100 Subject: [PATCH 013/102] create ToggleSettingsOptionRow component --- .../workflows/ToggleSettingsOptionRow.tsx | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx new file mode 100644 index 000000000000..94c07d0bfdc8 --- /dev/null +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -0,0 +1,51 @@ +import Switch from "@components/Switch"; +import Text from "@components/Text"; +import useLocalize from "@hooks/useLocalize"; +import useThemeStyles from "@hooks/useThemeStyles"; +import { TranslationPaths } from "@src/languages/types"; +import React, { useState } from "react"; +import { View } from "react-native"; +import { SvgProps } from "react-native-svg"; + +export type OptionType = { + Illustration: React.ElementType; + title: string; + subtitle: string; + onToggle: (isEnabled: boolean) => void; + subMenuItems?: React.ReactNode; +}; + +const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMenuItems }: OptionType) => { + const [isEnabled, setIsEnabled] = useState(false); + const { translate } = useLocalize(); + const styles = useThemeStyles(); + + const toggleSwitch = () => { + setIsEnabled(previousState => !previousState); + onToggle(!isEnabled); + }; + + return ( + + + + + + + {title} + {subtitle} + + + + + + {isEnabled && subMenuItems} + + ); + }; + + export default ToggleSettingOptionRow; \ No newline at end of file From c3120df261e09c418f0e276cedc3a8fa4978ca9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 13 Feb 2024 16:35:05 +0100 Subject: [PATCH 014/102] add new workflows styles --- src/styles/index.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/styles/index.ts b/src/styles/index.ts index 811dd6af592a..7d07f6fd36ac 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4342,9 +4342,14 @@ const styles = (theme: ThemeColors) => width: 48, marginRight: 12, }, - workspaceWorkflowsContainer: { + workspaceWorkflowContent: { + flexDirection: 'row', + alignItems: 'center', + }, + workspaceWorkflowContainer: { flexDirection: 'row', alignItems: 'center', + justifyContent: 'space-between', }, workspaceWorkflowsHeading: { fontSize: 15, @@ -4352,12 +4357,17 @@ const styles = (theme: ThemeColors) => }, workspaceWorkflowsWrapperText: { flexDirection: 'column', + maxWidth: 486, }, workspaceWorkflowsSubtitle: { fontSize: 13, color: theme.textSupporting, marginTop: 3, - } + }, + workspaceWorkflowsIllustrationContainer: { + justifyContent: 'center', + alignItems: 'center', + }, } satisfies Styles); type ThemeStyles = ReturnType; From 1adba7ecf11df07565bd6d482385dd8c303902bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 13 Feb 2024 16:35:24 +0100 Subject: [PATCH 015/102] use a --- .../workflows/WorkspaceWorkflowsPage.tsx | 82 ++++++++++++++++--- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 79afb996a497..6a18ec780d43 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,6 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; -import {View} from 'react-native'; +import {FlatList, View} from 'react-native'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -11,14 +11,76 @@ import type SCREENS from '@src/SCREENS'; import Text from '@components/Text'; import Section from '@components/Section'; import * as Illustrations from '@components/Icon/Illustrations'; +import ToggleSettingOptionRow, { OptionType } from './ToggleSettingsOptionRow'; +import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; type WorkspaceWorkflowsPageProps = StackScreenProps; -function WorkspaceWorkflowsPage({route}: WorkspaceWorkflowsPageProps) { +const WorkspaceWorkflowsPage: React.FC = ({route}) => { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); + const items: OptionType[] = [ + { + Illustration: Illustrations.ReceiptEnvelope, // Replace with actual component + title: translate('workflowsPage.delaySubmissionTitle'), + subtitle: translate('workflowsPage.delaySubmissionDescription'), + onToggle: (isEnabled: boolean) => { + // TODO + }, + subMenuItems: ( + {}} + shouldShowRightIcon={true} + /> + ), + }, + { + Illustration: Illustrations.Approval, + title: translate('workflowsPage.addApprovalsTitle'), + subtitle: translate('workflowsPage.addApprovalsDescription'), + onToggle: (isEnabled: boolean) => { + // TODO + }, + subMenuItems: ( + {}} + shouldShowRightIcon={true} + /> + ), + }, + { + Illustration: Illustrations.WalletAlt, + title: translate('workflowsPage.makeOrTrackPaymentsTitle'), + subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), + onToggle: (isEnabled: boolean) => { + // TODO + }, + subMenuItems: ( + {}} + shouldShowRightIcon={true} + /> + ), + }, + ]; + + const renderItem = ({ item }: { item: OptionType }) => ( + + + + ); + return ( {(_, policyID: string) => ( -
+
{translate('workflowsPage.workflowDescription')} - - - - - {translate('workflowsPage.delaySubmissionTitle')} - {translate('workflowsPage.delaySubmissionDescription')} - - - + item.title} + />
From f13759880581586b68214a3162c7c8b8097aa082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 14 Feb 2024 08:47:39 +0100 Subject: [PATCH 016/102] add workflows icon --- .../simple-illustrations/simple-illustration__workflows.svg | 1 + src/components/Icon/Illustrations.ts | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 assets/images/simple-illustrations/simple-illustration__workflows.svg diff --git a/assets/images/simple-illustrations/simple-illustration__workflows.svg b/assets/images/simple-illustrations/simple-illustration__workflows.svg new file mode 100644 index 000000000000..47d30d54310f --- /dev/null +++ b/assets/images/simple-illustrations/simple-illustration__workflows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts index 211ae16f40cf..a69859974fc5 100644 --- a/src/components/Icon/Illustrations.ts +++ b/src/components/Icon/Illustrations.ts @@ -66,6 +66,7 @@ import TreasureChest from '@assets/images/simple-illustrations/simple-illustrati import Approval from '@assets/images/simple-illustrations/simple-illustration__approval.svg'; import ReceiptEnvelope from '@assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg'; import WalletAlt from '@assets/images/simple-illustrations/simple-illustration__wallet-alt.svg'; +import Workflows from '@assets/images/simple-illustrations/simple-illustration__workflows.svg'; export { Abracadabra, @@ -136,4 +137,5 @@ export { ReceiptEnvelope, Approval, WalletAlt, + Workflows, }; From 6de537f022f587b7c58e5805ea11db0a84d89615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 14 Feb 2024 08:59:10 +0100 Subject: [PATCH 017/102] remove unneeded imports --- src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 94c07d0bfdc8..b04d1937ba58 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,8 +1,6 @@ import Switch from "@components/Switch"; import Text from "@components/Text"; -import useLocalize from "@hooks/useLocalize"; import useThemeStyles from "@hooks/useThemeStyles"; -import { TranslationPaths } from "@src/languages/types"; import React, { useState } from "react"; import { View } from "react-native"; import { SvgProps } from "react-native-svg"; @@ -17,7 +15,6 @@ export type OptionType = { const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMenuItems }: OptionType) => { const [isEnabled, setIsEnabled] = useState(false); - const { translate } = useLocalize(); const styles = useThemeStyles(); const toggleSwitch = () => { From 763c8ff572430936aff93506e2aeb3d284928391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 14 Feb 2024 08:59:32 +0100 Subject: [PATCH 018/102] add icon property --- src/pages/workspace/WorkspacePageWithSections.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index 17163346473f..eabfcf147573 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -23,6 +23,7 @@ import type {Policy, ReimbursementAccount, User} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; +import IconAsset from '@src/types/utils/IconAsset'; type WorkspacePageWithSectionsOnyxProps = { /** From Onyx */ @@ -46,6 +47,9 @@ type WorkspacePageWithSectionsProps = WithPolicyAndFullscreenLoadingProps & /** Content to be added as fixed footer */ footer?: ReactNode; + /** The icon to display in the header */ + icon?: IconAsset; + /** The guides call task ID to associate with the workspace page being shown */ guidesCallTaskID: string; @@ -83,6 +87,7 @@ function WorkspacePageWithSections({ backButtonRoute, children = () => null, footer = null, + icon = undefined, guidesCallTaskID = '', headerText, policy, @@ -155,6 +160,7 @@ function WorkspacePageWithSections({ guidesCallTaskID={guidesCallTaskID} shouldShowBackButton={isSmallScreenWidth || shouldShowBackButton} onBackButtonPress={() => Navigation.goBack(backButtonRoute ?? ROUTES.WORKSPACE_INITIAL.getRoute(policyID))} + icon={icon ?? undefined} /> {(isLoading || firstRender.current) && shouldShowLoading ? ( From 8335949017a7bebbc85b5fdaa71fb4c118ae7a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 14 Feb 2024 08:59:42 +0100 Subject: [PATCH 019/102] use workflows icon --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 6a18ec780d43..740e3b300614 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -85,6 +85,7 @@ const WorkspaceWorkflowsPage: React.FC = ({route}) Date: Wed, 14 Feb 2024 18:18:35 +0100 Subject: [PATCH 020/102] add new workflows translation keys --- src/languages/en.ts | 11 ++++++++++- src/languages/es.ts | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index f36ffefe8fb7..d35b377a376e 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -998,7 +998,16 @@ export default { workflowDescription: 'Configure a workflow from the moment spend occurs, including approval and payment.', delaySubmissionTitle: 'Delay submissions', delaySubmissionDescription: 'Set a slower cadence to receive expense submissions.', - addApprovalsTitle: 'Add approval', + submissionFrequency: 'Submission frequency', + weeklyFrequency: 'Weekly', + monthlyFrequency: 'Monthly', + twiceAMonthFrequency: 'Twice a month', + byTripFrequency: 'By trip', + manuallyFrequency: 'Manually', + dailyFrequency: 'Daily', + addApprovalsTitle: 'Add approvals', + approver: 'Approver', + connectBankAccount: 'Connect bank account', addApprovalsDescription: 'Set a slower cadence to receive expense submissions in real time.', makeOrTrackPaymentsTitle: 'Make or track payments', makeOrTrackPaymentsDescription: 'Add an authorized payer for payments made in Expensify, or simply track payments made elsewhere.', diff --git a/src/languages/es.ts b/src/languages/es.ts index b6c73e2e53d7..e43a857d5087 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -994,7 +994,16 @@ export default { workflowDescription: 'Configure un flujo de trabajo desde el momento en que se produce el gasto, incluida la aprobación y el pago.', delaySubmissionTitle: 'Retrasar las presentaciones', delaySubmissionDescription: 'Establezca una cadencia más lenta para recibir los envíos de gastos.', - addApprovalsTitle: 'Añadir aprobación', + addApprovalsTitle: 'Añadir aprobacións', + approver: 'Aprobador', + submissionFrequency: 'Frecuencia de envío', + weeklyFrequency: 'Semanal', + monthlyFrequency: 'Mensual', + twiceAMonthFrequency: 'Dos veces al mes', + byTripFrequency: 'Por viaje', + manuallyFrequency: 'Manualmente', + dailyFrequency: 'Diario', + connectBankAccount: 'Conectar cuenta bancaria', addApprovalsDescription: 'Establezca una cadencia más lenta para recibir los envíos de gastos en tiempo real.', makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', makeOrTrackPaymentsDescription: 'Añada un pagador autorizado para los pagos realizados en Expensify, o simplemente realice un seguimiento de los pagos realizados en otro lugar.', From 93dc0630be927d9bfc01956677a881b6e3c7b9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 14 Feb 2024 18:18:49 +0100 Subject: [PATCH 021/102] update workflows styles --- src/styles/index.ts | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/styles/index.ts b/src/styles/index.ts index 0d0d454fcb28..7076dd455e47 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4453,10 +4453,11 @@ const styles = (theme: ThemeColors) => workspaceWorkflowContent: { flexDirection: 'row', alignItems: 'center', + flex: 1, }, workspaceWorkflowContainer: { flexDirection: 'row', - alignItems: 'center', + alignItems: 'flex-start', justifyContent: 'space-between', }, workspaceWorkflowsHeading: { @@ -4465,16 +4466,29 @@ const styles = (theme: ThemeColors) => }, workspaceWorkflowsWrapperText: { flexDirection: 'column', - maxWidth: 486, + flex: 1, }, workspaceWorkflowsSubtitle: { fontSize: 13, color: theme.textSupporting, marginTop: 3, }, - workspaceWorkflowsIllustrationContainer: { - justifyContent: 'center', - alignItems: 'center', + workspaceWorkflowsSubMenuContainer: { + ...spacing.ph8, + ...spacing.mhn8, + width: 'auto', + marginLeft: 29 + }, + workspaceWorkflowsSubMenuTitle: { + color: theme.textSupporting, + fontSize: 13, + lineHeight: 16, + fontWeight: '400', + }, + workspaceWorkflowsSubMenuDescription: { + color: theme.text, + fontSize: 15, + lineHeight: 20 }, } satisfies Styles); From 343c2de0418053d2be2ff3fc5be8def6fcfa2f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 14 Feb 2024 18:18:59 +0100 Subject: [PATCH 022/102] render sub items correctly --- .../workflows/ToggleSettingsOptionRow.tsx | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index b04d1937ba58..8365b2b65f57 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -23,24 +23,30 @@ const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMe }; return ( - - - - + + + + + + + + {title} + {subtitle} + - - {title} - {subtitle} + + - - - - {isEnabled && subMenuItems} + {isEnabled && ( + + {subMenuItems} + + )} ); }; From 23727e274af21680ee94dc3a02e95491050c57c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 14 Feb 2024 18:19:58 +0100 Subject: [PATCH 023/102] use correct subitems component --- .../workflows/WorkspaceWorkflowsPage.tsx | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 740e3b300614..78029917ebd5 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -12,11 +12,13 @@ import Text from '@components/Text'; import Section from '@components/Section'; import * as Illustrations from '@components/Icon/Illustrations'; import ToggleSettingOptionRow, { OptionType } from './ToggleSettingsOptionRow'; -import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import MenuItem from '@components/MenuItem'; +import compose from '@libs/compose'; +import withPolicy, {WithPolicyProps} from '@pages/workspace/withPolicy'; -type WorkspaceWorkflowsPageProps = StackScreenProps; +type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; -const WorkspaceWorkflowsPage: React.FC = ({route}) => { +function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); @@ -27,14 +29,18 @@ const WorkspaceWorkflowsPage: React.FC = ({route}) title: translate('workflowsPage.delaySubmissionTitle'), subtitle: translate('workflowsPage.delaySubmissionDescription'), onToggle: (isEnabled: boolean) => { - // TODO + // TODO call API routes && set onyx optimistic data }, subMenuItems: ( - {}} - shouldShowRightIcon={true} - /> + {}} + shouldShowRightIcon={true} + wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + /> ), }, { @@ -42,13 +48,17 @@ const WorkspaceWorkflowsPage: React.FC = ({route}) title: translate('workflowsPage.addApprovalsTitle'), subtitle: translate('workflowsPage.addApprovalsDescription'), onToggle: (isEnabled: boolean) => { - // TODO + // TODO call API routes && set onyx optimistic data }, subMenuItems: ( - {}} shouldShowRightIcon={true} + wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} /> ), }, @@ -57,13 +67,15 @@ const WorkspaceWorkflowsPage: React.FC = ({route}) title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: (isEnabled: boolean) => { - // TODO + // TODO call API routes && set onyx optimistic data }, subMenuItems: ( - {}} shouldShowRightIcon={true} + wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} /> ), }, @@ -110,4 +122,6 @@ const WorkspaceWorkflowsPage: React.FC = ({route}) WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; -export default WorkspaceWorkflowsPage; +export default compose( + withPolicy, +)(WorkspaceWorkflowsPage); From 18624a8f26ce12ef3622d654e861deb753e812fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 15 Feb 2024 08:43:25 +0100 Subject: [PATCH 024/102] update workflows translations --- src/languages/en.ts | 4 ++-- src/languages/es.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index d35b377a376e..ebc4204c80e8 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -997,7 +997,7 @@ export default { workflowTitle: 'Spend workflow', workflowDescription: 'Configure a workflow from the moment spend occurs, including approval and payment.', delaySubmissionTitle: 'Delay submissions', - delaySubmissionDescription: 'Set a slower cadence to receive expense submissions.', + delaySubmissionDescription: 'Expenses are shared right away for better spend visibility. Set a slower cadence if needed.', submissionFrequency: 'Submission frequency', weeklyFrequency: 'Weekly', monthlyFrequency: 'Monthly', @@ -1008,7 +1008,7 @@ export default { addApprovalsTitle: 'Add approvals', approver: 'Approver', connectBankAccount: 'Connect bank account', - addApprovalsDescription: 'Set a slower cadence to receive expense submissions in real time.', + addApprovalsDescription: 'Require additional approval before authorizing a payment.', makeOrTrackPaymentsTitle: 'Make or track payments', makeOrTrackPaymentsDescription: 'Add an authorized payer for payments made in Expensify, or simply track payments made elsewhere.', }, diff --git a/src/languages/es.ts b/src/languages/es.ts index e43a857d5087..a471752f5c3b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -993,7 +993,7 @@ export default { workflowTitle: 'Flujo de trabajo de gastos', workflowDescription: 'Configure un flujo de trabajo desde el momento en que se produce el gasto, incluida la aprobación y el pago.', delaySubmissionTitle: 'Retrasar las presentaciones', - delaySubmissionDescription: 'Establezca una cadencia más lenta para recibir los envíos de gastos.', + delaySubmissionDescription: 'Los gastos se comparten de inmediato para una mejor visibilidad del gasto. Establece una cadencia más lenta si es necesario.', addApprovalsTitle: 'Añadir aprobacións', approver: 'Aprobador', submissionFrequency: 'Frecuencia de envío', @@ -1004,7 +1004,7 @@ export default { manuallyFrequency: 'Manualmente', dailyFrequency: 'Diario', connectBankAccount: 'Conectar cuenta bancaria', - addApprovalsDescription: 'Establezca una cadencia más lenta para recibir los envíos de gastos en tiempo real.', + addApprovalsDescription: 'Requiere una aprobación adicional antes de autorizar un pago.', makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', makeOrTrackPaymentsDescription: 'Añada un pagador autorizado para los pagos realizados en Expensify, o simplemente realice un seguimiento de los pagos realizados en otro lugar.', }, From 906dbdd26c48f8cfdf4d5712c050804a717f9727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 15 Feb 2024 15:10:00 +0100 Subject: [PATCH 025/102] update svg so it takes less space on the left x axis --- .../simple-illustration__receipt-envelope.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg b/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg index d16bea869771..61d63f506a9b 100644 --- a/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg +++ b/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 7224a43c5b26256ac1ce36649c883b233d70ddc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 15 Feb 2024 15:10:16 +0100 Subject: [PATCH 026/102] add new workflows styles --- src/styles/index.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/styles/index.ts b/src/styles/index.ts index 7076dd455e47..b04d51b6a66f 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4449,6 +4449,8 @@ const styles = (theme: ThemeColors) => height: 48, width: 48, marginRight: 12, + zIndex: 2, + paddingBottom: 15, }, workspaceWorkflowContent: { flexDirection: 'row', @@ -4490,6 +4492,14 @@ const styles = (theme: ThemeColors) => fontSize: 15, lineHeight: 20 }, + workspaceWorkflowsTimelineOverride: { + backgroundColor: theme.cardBG, + zIndex: 1, + height: 19, + width: 19, + position: 'absolute', + left:0, + }, } satisfies Styles); type ThemeStyles = ReturnType; From c3c3b4b4e27f77c532b2ea796a91ab1e750cc3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 15 Feb 2024 15:11:04 +0100 Subject: [PATCH 027/102] take into account vertical timeline below icons --- .../workflows/ToggleSettingsOptionRow.tsx | 63 ++++++++++++------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 8365b2b65f57..b5f15e7eef63 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,9 +1,10 @@ import Switch from "@components/Switch"; import Text from "@components/Text"; -import useThemeStyles from "@hooks/useThemeStyles"; +import getIsSmallScreenWidth from "@libs/getIsSmallScreenWidth"; import React, { useState } from "react"; import { View } from "react-native"; import { SvgProps } from "react-native-svg"; +import useThemeStyles from "@hooks/useThemeStyles"; export type OptionType = { Illustration: React.ElementType; @@ -11,9 +12,10 @@ export type OptionType = { subtitle: string; onToggle: (isEnabled: boolean) => void; subMenuItems?: React.ReactNode; + isEndOptionRow?: boolean; }; -const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMenuItems }: OptionType) => { +const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow }: OptionType) => { const [isEnabled, setIsEnabled] = useState(false); const styles = useThemeStyles(); @@ -21,33 +23,46 @@ const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMe setIsEnabled(previousState => !previousState); onToggle(!isEnabled); }; - + const isSmallScreenWidth = getIsSmallScreenWidth(); + return ( - - - - - + + + + + + {!isEndOptionRow && ( + + )} + + {title} + {subtitle} + - - {title} - {subtitle} + + - - - + {isEnabled && ( + + {subMenuItems} + + )} - {isEnabled && ( - - {subMenuItems} - - )} - ); }; From 79a20fe5ae4cfbe95d8a7caa8cbfd4d6518b8d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 15 Feb 2024 15:11:30 +0100 Subject: [PATCH 028/102] take into account timeline edge case --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 78029917ebd5..9cd77e87dd76 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -78,6 +78,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} /> ), + isEndOptionRow: true, }, ]; @@ -89,6 +90,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subtitle={item.subtitle} onToggle={item.onToggle} subMenuItems={item.subMenuItems} + isEndOptionRow={item.isEndOptionRow} /> ); @@ -111,7 +113,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { data={items} renderItem={renderItem} keyExtractor={(item: OptionType) => item.title} - /> + />
From f7ccbc321793bc3d585f3425fc132a4b5f9a6b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 08:10:28 +0100 Subject: [PATCH 029/102] add approval keys --- src/types/onyx/Policy.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index e63e87adfa2a..b40163910cf5 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -138,9 +138,15 @@ type Policy = { /** Whether policy is updating */ isPolicyUpdating?: boolean; + /** The approver of the policy */ + approver: string; + /** The approval mode set up on this policy */ approvalMode?: ValueOf; + /** Whether the auto approval is enabled */ + isAutoApprovalEnabled: boolean; + /** Whether transactions should be billable by default */ defaultBillable?: boolean; From 00dec0566ba546d6e30a2ae3c6c5e253555b6284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 08:11:18 +0100 Subject: [PATCH 030/102] add method to check if it's a collect policy --- src/libs/PolicyUtils.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 90dfa8fde339..2e261cf26384 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -108,6 +108,8 @@ function isExpensifyGuideTeam(email: string): boolean { */ const isPolicyAdmin = (policy: OnyxEntry | EmptyObject): boolean => policy?.role === CONST.POLICY.ROLE.ADMIN; +const isCollectPolicy = (policy: OnyxEntry | EmptyObject): boolean => policy?.type === CONST.POLICY.TYPE.TEAM; + const isPolicyMember = (policyID: string, policies: OnyxCollection): boolean => Object.values(policies ?? {}).some((policy) => policy?.id === policyID); /** @@ -250,6 +252,7 @@ export { isExpensifyTeam, isExpensifyGuideTeam, isInstantSubmitEnabled, + isCollectPolicy, isPolicyAdmin, isSubmitAndClose, getMemberAccountIDsForWorkspace, From c594e299cd664dee69ed9e17cb1575746eb3da0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 08:11:28 +0100 Subject: [PATCH 031/102] restrict workflows to collect policy --- src/pages/workspace/WorkspaceInitialPage.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index cf67a18ae4e1..f2b83703a999 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -96,16 +96,10 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r const hasMembersError = PolicyUtils.hasPolicyMemberError(policyMembers); const hasGeneralSettingsError = !isEmptyObject(policy?.errorFields?.generalSettings ?? {}) || !isEmptyObject(policy?.errorFields?.avatar ?? {}); - const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy); + const isCollectPolicy = PolicyUtils.isCollectPolicy(policy); const protectedMenuItems: WorkspaceMenuItem[] = [ - { - translationKey: 'workspace.common.workflows', - icon: Expensicons.Workflows, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.WORKFLOWS, - }, { translationKey: 'workspace.common.card', icon: Expensicons.ExpensifyCard, @@ -153,6 +147,13 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: !isEmptyObject(reimbursementAccount?.errors) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, }, ]; + const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = [{ + translationKey: 'workspace.common.workflows', + icon: Expensicons.Workflows, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.WORKFLOWS, + }, + ]; const menuItems: WorkspaceMenuItem[] = [ { @@ -162,6 +163,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, + ...(isCollectPolicy ? protectedCollectPolicyMenuItems : []), ...(shouldShowProtectedItems ? protectedMenuItems : []), ]; From 8df6c6ab4de5f6f7719f858ada6ac3a5cf423df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 08:12:04 +0100 Subject: [PATCH 032/102] add workspace workflows related api commands --- src/libs/API/types.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index f5d99d8cf40e..cbca447e725d 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -8,6 +8,8 @@ import type UpdateBeneficialOwnersForBankAccountParams from './parameters/Update type ApiRequest = ValueOf; const WRITE_COMMANDS = { + SET_WORKSPACE_AUTO_REPORTING: 'SetWorkspaceAutoReporting', + SET_WORKSPACE_APPROVAL_MODE: 'SetWorkspaceApprovalMode', DISMISS_REFERRAL_BANNER: 'DismissReferralBanner', UPDATE_PREFERRED_LOCALE: 'UpdatePreferredLocale', RECONNECT_APP: 'ReconnectApp', From 78b608da70a96747f5983bd2eccd9801a5a673c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 08:12:38 +0100 Subject: [PATCH 033/102] add workspace workflows related api commands types --- src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts | 6 ++++++ src/libs/API/parameters/SetWorkspaceAutoReportingParams.ts | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts create mode 100644 src/libs/API/parameters/SetWorkspaceAutoReportingParams.ts diff --git a/src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts b/src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts new file mode 100644 index 000000000000..6f5b88e36532 --- /dev/null +++ b/src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts @@ -0,0 +1,6 @@ +type SetWorkspaceApprovalModeParams = { + policyID: string + value: string, +}; + +export default SetWorkspaceApprovalModeParams; diff --git a/src/libs/API/parameters/SetWorkspaceAutoReportingParams.ts b/src/libs/API/parameters/SetWorkspaceAutoReportingParams.ts new file mode 100644 index 000000000000..a87817986ffa --- /dev/null +++ b/src/libs/API/parameters/SetWorkspaceAutoReportingParams.ts @@ -0,0 +1,6 @@ +type SetWorkspaceAutoReportingParams = { + policyID: string; + enabled: boolean; +}; + +export default SetWorkspaceAutoReportingParams; From 7d35834d4db1cf005418c6d46182f2a5a9a5bf7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 08:13:57 +0100 Subject: [PATCH 034/102] handle workspace auto reporting and approval mode --- src/libs/actions/Policy.ts | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index d492f77fcdce..c9fd181b28cd 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -52,6 +52,8 @@ import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {Attributes, CustomUnit, Rate, Unit} from '@src/types/onyx/Policy'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import SetWorkspaceAutoReportingParams from '@libs/API/parameters/SetWorkspaceAutoReportingParams'; +import SetWorkspaceApprovalModeParams from '@libs/API/parameters/SetWorkspaceApprovalModeParams'; type AnnounceRoomMembersOnyxData = { onyxOptimisticData: OnyxUpdate[]; @@ -378,6 +380,42 @@ function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[] return announceRoomMembers; } +function setWorkspaceAutoReporting(policyID: string, isEnabled: boolean) { + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + autoReporting: true, + }, + }, + ]; + + const params: SetWorkspaceAutoReportingParams = {policyID, enabled: isEnabled}; + API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING, params, {optimisticData}); +} + +function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: "BASIC" | "OPTIONAL") { + const isAutoApprovalEnabled = approvalMode === "BASIC"; + + const value = JSON.stringify({ + approver: approver, + approvalMode: approvalMode, + isAutoApprovalEnabled: isAutoApprovalEnabled, + }); + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: JSON.parse(value), + }, + ]; + + const params: SetWorkspaceApprovalModeParams = {policyID, value}; + API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData}); +} + + /** * Build optimistic data for removing users from the announcement room */ @@ -2069,4 +2107,6 @@ export { buildOptimisticPolicyRecentlyUsedTags, createDraftInitialWorkspace, setWorkspaceInviteMessageDraft, + setWorkspaceAutoReporting, + setWorkspaceApprovalMode, }; From 6ee9bbf46b0eb60f5f659511b71e2ac36d410f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 08:14:29 +0100 Subject: [PATCH 035/102] handle submission and approval api calls --- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 9cd77e87dd76..d7d969ada4e5 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -15,6 +15,9 @@ import ToggleSettingOptionRow, { OptionType } from './ToggleSettingsOptionRow'; import MenuItem from '@components/MenuItem'; import compose from '@libs/compose'; import withPolicy, {WithPolicyProps} from '@pages/workspace/withPolicy'; +import * as Policy from '@userActions/Policy'; +import Navigation from '@libs/Navigation/Navigation'; +import ROUTES from '@src/ROUTES'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -29,7 +32,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { title: translate('workflowsPage.delaySubmissionTitle'), subtitle: translate('workflowsPage.delaySubmissionDescription'), onToggle: (isEnabled: boolean) => { - // TODO call API routes && set onyx optimistic data + Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); }, subMenuItems: ( {}} + // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(route.params.policyID))} shouldShowRightIcon={true} wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} /> @@ -48,7 +51,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { title: translate('workflowsPage.addApprovalsTitle'), subtitle: translate('workflowsPage.addApprovalsDescription'), onToggle: (isEnabled: boolean) => { - // TODO call API routes && set onyx optimistic data + Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? 'BASIC' : 'OPTIONAL'); }, subMenuItems: ( {}} + // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} shouldShowRightIcon={true} wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} /> @@ -73,7 +76,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { {}} + // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} shouldShowRightIcon={true} wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} /> From 5942299adb141b8a7a7848c82a3d8de9fb696d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 09:08:03 +0100 Subject: [PATCH 036/102] update translation for workflows title --- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index ebc4204c80e8..0d0343bf40f8 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -994,7 +994,7 @@ export default { }, workflowsPage: { - workflowTitle: 'Spend workflow', + workflowTitle: 'Spend', workflowDescription: 'Configure a workflow from the moment spend occurs, including approval and payment.', delaySubmissionTitle: 'Delay submissions', delaySubmissionDescription: 'Expenses are shared right away for better spend visibility. Set a slower cadence if needed.', diff --git a/src/languages/es.ts b/src/languages/es.ts index a471752f5c3b..3c55f594b5b1 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -990,7 +990,7 @@ export default { }, workflowsPage: { - workflowTitle: 'Flujo de trabajo de gastos', + workflowTitle: 'Gasto', workflowDescription: 'Configure un flujo de trabajo desde el momento en que se produce el gasto, incluida la aprobación y el pago.', delaySubmissionTitle: 'Retrasar las presentaciones', delaySubmissionDescription: 'Los gastos se comparten de inmediato para una mejor visibilidad del gasto. Establece una cadencia más lenta si es necesario.', From 17b63b030f410e68eed812f33122875b2500a14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 11:57:28 +0100 Subject: [PATCH 037/102] remove useless css property --- src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index b5f15e7eef63..99f849aca1ea 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -36,7 +36,6 @@ const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMe position: 'absolute', width: 6, backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', - backgroundPosition: 'top, right, bottom, left', backgroundSize: '5px 15px', backgroundRepeat: 'repeat-y', top: isSmallScreenWidth ? '32%' : '12%', From 167b35baf5d030f502c86f1df36fceff34a0519c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 11:58:20 +0100 Subject: [PATCH 038/102] new style for workflows subitems hover --- src/styles/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/styles/index.ts b/src/styles/index.ts index b04d51b6a66f..d4fa61877a71 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4500,6 +4500,11 @@ const styles = (theme: ThemeColors) => position: 'absolute', left:0, }, + workspaceWorkflowsSubItemHover: { + borderRadius: 8, + marginRight: 0, + transition: 'all 0.3s ease-in-out', + } } satisfies Styles); type ThemeStyles = ReturnType; From 53e6b6c387fe4539e9bbd790761257e6af0e3102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 11:58:45 +0100 Subject: [PATCH 039/102] use new style for hover on sub items --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index d7d969ada4e5..fb19f3bc64b8 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -43,6 +43,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(route.params.policyID))} shouldShowRightIcon={true} wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} /> ), }, @@ -62,6 +63,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} shouldShowRightIcon={true} wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} /> ), }, @@ -69,7 +71,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Illustration: Illustrations.WalletAlt, title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), - onToggle: (isEnabled: boolean) => { + onToggle: (_isEnabled: boolean) => { // TODO call API routes && set onyx optimistic data }, subMenuItems: ( @@ -79,6 +81,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} shouldShowRightIcon={true} wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} /> ), isEndOptionRow: true, @@ -107,9 +110,9 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_WORKFLOWS} shouldShowOfflineIndicatorInWideScreen > - {(_, policyID: string) => ( + {(_hasVBA?: boolean, _policyID?: string) => ( -
+
{translate('workflowsPage.workflowDescription')} Date: Fri, 16 Feb 2024 12:04:44 +0100 Subject: [PATCH 040/102] fix typo --- src/styles/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/styles/index.ts b/src/styles/index.ts index d51457260713..ab73f8a81858 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4632,8 +4632,7 @@ const styles = (theme: ThemeColors) => borderRadius: 8, marginRight: 0, transition: 'all 0.3s ease-in-out', - } - + }, workspaceTitleStyle: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, fontWeight: '500', From d5a100d0d5c5123bc95151e759e4292cef9390eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 14:08:45 +0100 Subject: [PATCH 041/102] fix lint --- src/libs/API/parameters/index.ts | 2 + src/libs/actions/Policy.ts | 10 ++-- .../workspace/WorkspacePageWithSections.tsx | 2 - .../workflows/ToggleSettingsOptionRow.tsx | 11 +++-- .../workflows/WorkspaceWorkflowsPage.tsx | 46 +++++++++---------- 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index ada3b84e6cf4..f61e74033cd5 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -142,3 +142,5 @@ export type {default as PayMoneyRequestParams} from './PayMoneyRequestParams'; export type {default as CancelPaymentParams} from './CancelPaymentParams'; export type {default as AcceptACHContractForBankAccount} from './AcceptACHContractForBankAccount'; export type {default as UpdateWorkspaceDescriptionParams} from './UpdateWorkspaceDescriptionParams'; +export type {default as SetWorkspaceAutoReportingParams} from './SetWorkspaceAutoReportingParams'; +export type {default as SetWorkspaceApprovalModeParams} from './SetWorkspaceApprovalModeParams'; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index e734057623bc..a38b467b2d64 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -23,6 +23,8 @@ import type { UpdateWorkspaceCustomUnitAndRateParams, UpdateWorkspaceDescriptionParams, UpdateWorkspaceGeneralSettingsParams, + SetWorkspaceAutoReportingParams, + SetWorkspaceApprovalModeParams, } from '@libs/API/parameters'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import DateUtils from '@libs/DateUtils'; @@ -53,8 +55,6 @@ import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {Attributes, CustomUnit, Rate, Unit} from '@src/types/onyx/Policy'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import SetWorkspaceAutoReportingParams from '@libs/API/parameters/SetWorkspaceAutoReportingParams'; -import SetWorkspaceApprovalModeParams from '@libs/API/parameters/SetWorkspaceApprovalModeParams'; type AnnounceRoomMembersOnyxData = { onyxOptimisticData: OnyxUpdate[]; @@ -400,9 +400,9 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo const isAutoApprovalEnabled = approvalMode === "BASIC"; const value = JSON.stringify({ - approver: approver, - approvalMode: approvalMode, - isAutoApprovalEnabled: isAutoApprovalEnabled, + approver, + approvalMode, + isAutoApprovalEnabled, }); const optimisticData: OnyxUpdate[] = [ { diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index c486aa7cad1f..1401e5d5695a 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -24,7 +24,6 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; -import IconAsset from '@src/types/utils/IconAsset'; type WorkspacePageWithSectionsOnyxProps = { /** From Onyx */ @@ -109,7 +108,6 @@ function WorkspacePageWithSections({ shouldShowLoading = true, shouldShowOfflineIndicatorInWideScreen = false, shouldShowNonAdmin = false, - icon, }: WorkspacePageWithSectionsProps) { const styles = useThemeStyles(); useNetwork({onReconnect: () => fetchData(shouldSkipVBBACall)}); diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 99f849aca1ea..c5e31da48e29 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -3,10 +3,10 @@ import Text from "@components/Text"; import getIsSmallScreenWidth from "@libs/getIsSmallScreenWidth"; import React, { useState } from "react"; import { View } from "react-native"; -import { SvgProps } from "react-native-svg"; +import type { SvgProps } from "react-native-svg"; import useThemeStyles from "@hooks/useThemeStyles"; -export type OptionType = { +type OptionType = { Illustration: React.ElementType; title: string; subtitle: string; @@ -15,7 +15,7 @@ export type OptionType = { isEndOptionRow?: boolean; }; -const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow }: OptionType) => { +function ToggleSettingOptionRow({ Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow }: OptionType) { const [isEnabled, setIsEnabled] = useState(false); const styles = useThemeStyles(); @@ -63,6 +63,7 @@ const ToggleSettingOptionRow = ({ Illustration, title, subtitle, onToggle, subMe )} ); - }; +}; - export default ToggleSettingOptionRow; \ No newline at end of file +export type {OptionType}; +export default ToggleSettingOptionRow; \ No newline at end of file diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index fb19f3bc64b8..42c3e923846e 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -11,13 +11,12 @@ import type SCREENS from '@src/SCREENS'; import Text from '@components/Text'; import Section from '@components/Section'; import * as Illustrations from '@components/Icon/Illustrations'; -import ToggleSettingOptionRow, { OptionType } from './ToggleSettingsOptionRow'; -import MenuItem from '@components/MenuItem'; -import compose from '@libs/compose'; -import withPolicy, {WithPolicyProps} from '@pages/workspace/withPolicy'; import * as Policy from '@userActions/Policy'; -import Navigation from '@libs/Navigation/Navigation'; -import ROUTES from '@src/ROUTES'; +import MenuItem from '@components/MenuItem'; +import withPolicy from '@pages/workspace/withPolicy'; +import type { WithPolicyProps } from '@pages/workspace/withPolicy'; +import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; +import type { OptionType } from './ToggleSettingsOptionRow'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -28,24 +27,23 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const items: OptionType[] = [ { - Illustration: Illustrations.ReceiptEnvelope, // Replace with actual component - title: translate('workflowsPage.delaySubmissionTitle'), - subtitle: translate('workflowsPage.delaySubmissionDescription'), - onToggle: (isEnabled: boolean) => { - Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); - }, - subMenuItems: ( - { + Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); + }, + subMenuItems: ( + Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(route.params.policyID))} - shouldShowRightIcon={true} + shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} - /> - ), + /> + ), }, { Illustration: Illustrations.Approval, @@ -61,7 +59,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { descriptionTextStyle={styles.workspaceWorkflowsSubMenuDescription} description={policy?.owner ?? ''} // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} - shouldShowRightIcon={true} + shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} /> @@ -71,7 +69,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Illustration: Illustrations.WalletAlt, title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), - onToggle: (_isEnabled: boolean) => { + onToggle: () => { // TODO call API routes && set onyx optimistic data }, subMenuItems: ( @@ -79,7 +77,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { descriptionTextStyle={[styles.workspaceWorkflowsSubMenuDescription, styles.textSupporting]} description={translate('workflowsPage.connectBankAccount')} // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} - shouldShowRightIcon={true} + shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} /> @@ -110,7 +108,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_WORKFLOWS} shouldShowOfflineIndicatorInWideScreen > - {(_hasVBA?: boolean, _policyID?: string) => ( + {() => (
@@ -130,6 +128,4 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; -export default compose( - withPolicy, -)(WorkspaceWorkflowsPage); +export default withPolicy(WorkspaceWorkflowsPage); From 9530b17f35d7a26db701aa7690a3e5c44eedfa86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 14:33:49 +0100 Subject: [PATCH 042/102] fix typechecks --- src/languages/es.ts | 1 - src/libs/API/types.ts | 2 ++ src/pages/workspace/WorkspacePageWithSections.tsx | 3 --- src/types/onyx/Policy.ts | 4 ++-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 7c22164ddb25..e14a8d9aed9a 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1714,7 +1714,6 @@ export default { common: { card: 'Tarjetas', workflows: 'Flujos de trabajo', - spendWorkflow: 'Flujo de trabajo de gastos', workspace: 'Espacio de trabajo', edit: 'Editar espacio de trabajo', delete: 'Eliminar espacio de trabajo', diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 26acf21230a7..0a49bb604cf2 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -288,6 +288,8 @@ type WriteCommandParameters = { [WRITE_COMMANDS.CANCEL_PAYMENT]: Parameters.CancelPaymentParams; [WRITE_COMMANDS.ACCEPT_ACH_CONTRACT_FOR_BANK_ACCOUNT]: Parameters.AcceptACHContractForBankAccount; [WRITE_COMMANDS.UPDATE_WORKSPACE_DESCRIPTION]: Parameters.UpdateWorkspaceDescriptionParams; + [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING]: Parameters.SetWorkspaceAutoReportingParams; + [WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE]: Parameters.SetWorkspaceApprovalModeParams; }; const READ_COMMANDS = { diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index 1401e5d5695a..71b7cf747887 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -47,9 +47,6 @@ type WorkspacePageWithSectionsProps = WithPolicyAndFullscreenLoadingProps & /** Content to be added as fixed footer */ footer?: ReactNode; - /** The icon to display in the header */ - icon?: IconAsset; - /** The guides call task ID to associate with the workspace page being shown */ guidesCallTaskID: string; diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 87be13b5b1c3..27629d4fa4c1 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -139,13 +139,13 @@ type Policy = { isPolicyUpdating?: boolean; /** The approver of the policy */ - approver: string; + approver?: string; /** The approval mode set up on this policy */ approvalMode?: ValueOf; /** Whether the auto approval is enabled */ - isAutoApprovalEnabled: boolean; + isAutoApprovalEnabled?: boolean; /** Whether transactions should be billable by default */ defaultBillable?: boolean; From fe6cd8c1dc76f49885090a48576937a35de9212e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 14:40:15 +0100 Subject: [PATCH 043/102] fix prettier --- src/components/Icon/Expensicons.ts | 2 +- src/components/Icon/Illustrations.ts | 4 +- src/languages/en.ts | 3 +- src/languages/es.ts | 3 +- .../SetWorkspaceApprovalModeParams.ts | 4 +- src/libs/actions/Policy.ts | 9 +- src/pages/workspace/WorkspaceInitialPage.tsx | 11 +-- .../workflows/ToggleSettingsOptionRow.tsx | 66 +++++++------- .../workflows/WorkspaceWorkflowsPage.tsx | 90 ++++++++++--------- src/styles/index.ts | 18 ++-- 10 files changed, 105 insertions(+), 105 deletions(-) diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index b5bc3d6faa72..b67eded12855 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -142,8 +142,8 @@ import Users from '@assets/images/users.svg'; import VolumeHigh from '@assets/images/volume-high.svg'; import VolumeLow from '@assets/images/volume-low.svg'; import Wallet from '@assets/images/wallet.svg'; -import Workspace from '@assets/images/workspace-default-avatar.svg'; import Workflows from '@assets/images/workflows.svg'; +import Workspace from '@assets/images/workspace-default-avatar.svg'; import Wrench from '@assets/images/wrench.svg'; import Zoom from '@assets/images/zoom.svg'; import LoungeAccess from './svgs/LoungeAccessIcon'; diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts index 0ff999d94e4f..908589e0e78d 100644 --- a/src/components/Icon/Illustrations.ts +++ b/src/components/Icon/Illustrations.ts @@ -27,6 +27,7 @@ import TadaBlue from '@assets/images/product-illustrations/tada--blue.svg'; import TadaYellow from '@assets/images/product-illustrations/tada--yellow.svg'; import TeleScope from '@assets/images/product-illustrations/telescope.svg'; import ToddBehindCloud from '@assets/images/product-illustrations/todd-behind-cloud.svg'; +import Approval from '@assets/images/simple-illustrations/simple-illustration__approval.svg'; import BankArrow from '@assets/images/simple-illustrations/simple-illustration__bank-arrow.svg'; import BigRocket from '@assets/images/simple-illustrations/simple-illustration__bigrocket.svg'; import PinkBill from '@assets/images/simple-illustrations/simple-illustration__bill.svg'; @@ -56,6 +57,7 @@ import OpenSafe from '@assets/images/simple-illustrations/simple-illustration__o import PalmTree from '@assets/images/simple-illustrations/simple-illustration__palmtree.svg'; import Profile from '@assets/images/simple-illustrations/simple-illustration__profile.svg'; import QRCode from '@assets/images/simple-illustrations/simple-illustration__qr-code.svg'; +import ReceiptEnvelope from '@assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg'; import ReceiptWrangler from '@assets/images/simple-illustrations/simple-illustration__receipt-wrangler.svg'; import SanFrancisco from '@assets/images/simple-illustrations/simple-illustration__sanfrancisco.svg'; import ShieldYellow from '@assets/images/simple-illustrations/simple-illustration__shield.svg'; @@ -64,8 +66,6 @@ import ThumbsUpStars from '@assets/images/simple-illustrations/simple-illustrati import TrackShoe from '@assets/images/simple-illustrations/simple-illustration__track-shoe.svg'; import TrashCan from '@assets/images/simple-illustrations/simple-illustration__trashcan.svg'; import TreasureChest from '@assets/images/simple-illustrations/simple-illustration__treasurechest.svg'; -import Approval from '@assets/images/simple-illustrations/simple-illustration__approval.svg'; -import ReceiptEnvelope from '@assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg'; import WalletAlt from '@assets/images/simple-illustrations/simple-illustration__wallet-alt.svg'; import Workflows from '@assets/images/simple-illustrations/simple-illustration__workflows.svg'; diff --git a/src/languages/en.ts b/src/languages/en.ts index f66ce7c5821d..713e4b722dfb 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1016,8 +1016,7 @@ export default { }, cardDetailsLoadingFailure: 'An error occurred while loading the card details. Please check your internet connection and try again.', }, - workflowsPage: - { + workflowsPage: { workflowTitle: 'Spend', workflowDescription: 'Configure a workflow from the moment spend occurs, including approval and payment.', delaySubmissionTitle: 'Delay submissions', diff --git a/src/languages/es.ts b/src/languages/es.ts index e14a8d9aed9a..cdbecda8bf34 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1012,8 +1012,7 @@ export default { }, cardDetailsLoadingFailure: 'Se ha producido un error al cargar los datos de la tarjeta. Comprueba tu conexión a Internet e inténtalo de nuevo.', }, - workflowsPage: - { + workflowsPage: { workflowTitle: 'Gasto', workflowDescription: 'Configure un flujo de trabajo desde el momento en que se produce el gasto, incluida la aprobación y el pago.', delaySubmissionTitle: 'Retrasar las presentaciones', diff --git a/src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts b/src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts index 6f5b88e36532..df84fbabbf95 100644 --- a/src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts +++ b/src/libs/API/parameters/SetWorkspaceApprovalModeParams.ts @@ -1,6 +1,6 @@ type SetWorkspaceApprovalModeParams = { - policyID: string - value: string, + policyID: string; + value: string; }; export default SetWorkspaceApprovalModeParams; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index a38b467b2d64..8c8e165cd9ae 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -19,12 +19,12 @@ import type { OpenWorkspaceMembersPageParams, OpenWorkspaceParams, OpenWorkspaceReimburseViewParams, + SetWorkspaceApprovalModeParams, + SetWorkspaceAutoReportingParams, UpdateWorkspaceAvatarParams, UpdateWorkspaceCustomUnitAndRateParams, UpdateWorkspaceDescriptionParams, UpdateWorkspaceGeneralSettingsParams, - SetWorkspaceAutoReportingParams, - SetWorkspaceApprovalModeParams, } from '@libs/API/parameters'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import DateUtils from '@libs/DateUtils'; @@ -396,8 +396,8 @@ function setWorkspaceAutoReporting(policyID: string, isEnabled: boolean) { API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING, params, {optimisticData}); } -function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: "BASIC" | "OPTIONAL") { - const isAutoApprovalEnabled = approvalMode === "BASIC"; +function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: 'BASIC' | 'OPTIONAL') { + const isAutoApprovalEnabled = approvalMode === 'BASIC'; const value = JSON.stringify({ approver, @@ -416,7 +416,6 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData}); } - /** * Build optimistic data for removing users from the announcement room */ diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index f2b83703a999..3d1287c46920 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -147,11 +147,12 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: !isEmptyObject(reimbursementAccount?.errors) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, }, ]; - const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = [{ - translationKey: 'workspace.common.workflows', - icon: Expensicons.Workflows, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.WORKFLOWS, + const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = [ + { + translationKey: 'workspace.common.workflows', + icon: Expensicons.Workflows, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.WORKFLOWS, }, ]; diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index c5e31da48e29..de538cfda519 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,10 +1,10 @@ -import Switch from "@components/Switch"; -import Text from "@components/Text"; -import getIsSmallScreenWidth from "@libs/getIsSmallScreenWidth"; -import React, { useState } from "react"; -import { View } from "react-native"; -import type { SvgProps } from "react-native-svg"; -import useThemeStyles from "@hooks/useThemeStyles"; +import React, {useState} from 'react'; +import {View} from 'react-native'; +import type {SvgProps} from 'react-native-svg'; +import Switch from '@components/Switch'; +import Text from '@components/Text'; +import useThemeStyles from '@hooks/useThemeStyles'; +import getIsSmallScreenWidth from '@libs/getIsSmallScreenWidth'; type OptionType = { Illustration: React.ElementType; @@ -15,34 +15,36 @@ type OptionType = { isEndOptionRow?: boolean; }; -function ToggleSettingOptionRow({ Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow }: OptionType) { +function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow}: OptionType) { const [isEnabled, setIsEnabled] = useState(false); const styles = useThemeStyles(); - + const toggleSwitch = () => { - setIsEnabled(previousState => !previousState); - onToggle(!isEnabled); + setIsEnabled((previousState) => !previousState); + onToggle(!isEnabled); }; const isSmallScreenWidth = getIsSmallScreenWidth(); return ( - - + + - - - {!isEndOptionRow && ( - - )} + + + {!isEndOptionRow && ( + + )} {title} {subtitle} @@ -56,14 +58,10 @@ function ToggleSettingOptionRow({ Illustration, title, subtitle, onToggle, subMe /> - {isEnabled && ( - - {subMenuItems} - - )} + {isEnabled && {subMenuItems}} ); -}; +} export type {OptionType}; -export default ToggleSettingOptionRow; \ No newline at end of file +export default ToggleSettingOptionRow; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 42c3e923846e..43daced72467 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,22 +1,22 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; import {FlatList, View} from 'react-native'; +import * as Illustrations from '@components/Icon/Illustrations'; +import MenuItem from '@components/MenuItem'; +import Section from '@components/Section'; +import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; +import withPolicy from '@pages/workspace/withPolicy'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; +import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; -import Text from '@components/Text'; -import Section from '@components/Section'; -import * as Illustrations from '@components/Icon/Illustrations'; -import * as Policy from '@userActions/Policy'; -import MenuItem from '@components/MenuItem'; -import withPolicy from '@pages/workspace/withPolicy'; -import type { WithPolicyProps } from '@pages/workspace/withPolicy'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; -import type { OptionType } from './ToggleSettingsOptionRow'; +import type {OptionType} from './ToggleSettingsOptionRow'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -34,15 +34,15 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); }, subMenuItems: ( - + ), }, { @@ -53,45 +53,45 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? 'BASIC' : 'OPTIONAL'); }, subMenuItems: ( - Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} - shouldShowRightIcon - wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} - hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} - /> + Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} + shouldShowRightIcon + wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} + /> ), - }, - { + }, + { Illustration: Illustrations.WalletAlt, title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { - // TODO call API routes && set onyx optimistic data + // TODO call API routes && set onyx optimistic data }, subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} - shouldShowRightIcon - wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} - hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} - /> + descriptionTextStyle={[styles.workspaceWorkflowsSubMenuDescription, styles.textSupporting]} + description={translate('workflowsPage.connectBankAccount')} + // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} + shouldShowRightIcon + wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} + /> ), isEndOptionRow: true, - }, + }, ]; - const renderItem = ({ item }: { item: OptionType }) => ( + const renderItem = ({item}: {item: OptionType}) => ( - {() => ( -
+
{translate('workflowsPage.workflowDescription')} item.title} - /> + />
diff --git a/src/styles/index.ts b/src/styles/index.ts index ab73f8a81858..36dff530494f 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4581,7 +4581,7 @@ const styles = (theme: ThemeColors) => paddingBottom: 15, }, workspaceWorkflowContent: { - flexDirection: 'row', + flexDirection: 'row', alignItems: 'center', flex: 1, }, @@ -4607,7 +4607,7 @@ const styles = (theme: ThemeColors) => ...spacing.ph8, ...spacing.mhn8, width: 'auto', - marginLeft: 29 + marginLeft: 29, }, workspaceWorkflowsSubMenuTitle: { color: theme.textSupporting, @@ -4618,15 +4618,15 @@ const styles = (theme: ThemeColors) => workspaceWorkflowsSubMenuDescription: { color: theme.text, fontSize: 15, - lineHeight: 20 + lineHeight: 20, }, workspaceWorkflowsTimelineOverride: { - backgroundColor: theme.cardBG, - zIndex: 1, - height: 19, - width: 19, - position: 'absolute', - left:0, + backgroundColor: theme.cardBG, + zIndex: 1, + height: 19, + width: 19, + position: 'absolute', + left: 0, }, workspaceWorkflowsSubItemHover: { borderRadius: 8, From ddc71355247ff3d63b90145952a4b5404dcdefd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 14:48:26 +0100 Subject: [PATCH 044/102] better naming for collect policy menu items --- src/pages/workspace/WorkspaceInitialPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 3d1287c46920..aaaca8f74be8 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -147,7 +147,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: !isEmptyObject(reimbursementAccount?.errors) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, }, ]; - const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = [ + const collectPolicyMenuItems: WorkspaceMenuItem[] = [ { translationKey: 'workspace.common.workflows', icon: Expensicons.Workflows, @@ -164,7 +164,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, - ...(isCollectPolicy ? protectedCollectPolicyMenuItems : []), + ...(isCollectPolicy ? collectPolicyMenuItems : []), ...(shouldShowProtectedItems ? protectedMenuItems : []), ]; From 1b6b0e7da0cbbcf6b10b5381e927a1bb9a2ca864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 16 Feb 2024 16:47:57 +0100 Subject: [PATCH 045/102] fix padding and positioning --- src/styles/index.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/styles/index.ts b/src/styles/index.ts index 36dff530494f..f1dcd73d873a 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4587,7 +4587,7 @@ const styles = (theme: ThemeColors) => }, workspaceWorkflowContainer: { flexDirection: 'row', - alignItems: 'flex-start', + alignItems: 'center', justifyContent: 'space-between', }, workspaceWorkflowsHeading: { @@ -4607,7 +4607,11 @@ const styles = (theme: ThemeColors) => ...spacing.ph8, ...spacing.mhn8, width: 'auto', - marginLeft: 29, + marginLeft: 44, + paddingVertical: 12, + paddingRight: 9, + paddingLeft: 16, + marginRight: 0, }, workspaceWorkflowsSubMenuTitle: { color: theme.textSupporting, @@ -4631,7 +4635,6 @@ const styles = (theme: ThemeColors) => workspaceWorkflowsSubItemHover: { borderRadius: 8, marginRight: 0, - transition: 'all 0.3s ease-in-out', }, workspaceTitleStyle: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, From 127facc6a10ac87f0f67d8a9808733079464251e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 10:26:31 +0100 Subject: [PATCH 046/102] use windowDimensions() and remove inline style --- .../workflows/ToggleSettingsOptionRow.tsx | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index de538cfda519..f1ca9dad2fc3 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,10 +1,10 @@ import React, {useState} from 'react'; -import {View} from 'react-native'; +import {View, ViewStyle} from 'react-native'; import type {SvgProps} from 'react-native-svg'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; -import getIsSmallScreenWidth from '@libs/getIsSmallScreenWidth'; +import useWindowDimensions from '@hooks/useWindowDimensions'; type OptionType = { Illustration: React.ElementType; @@ -23,7 +23,19 @@ function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMen setIsEnabled((previousState) => !previousState); onToggle(!isEnabled); }; - const isSmallScreenWidth = getIsSmallScreenWidth(); + const { isSmallScreenWidth } = useWindowDimensions(); + + // Define dot style for menu items based on screen width + const getDynamicDotStyle = (isEnabled: boolean) => ({ + position: 'absolute', + width: 6, + backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', + backgroundSize: '5px 15px', + backgroundRepeat: 'repeat-y', + top: isSmallScreenWidth ? '32%' : '12%', + bottom: isEnabled ? '-180%' : '-100%', + left: isSmallScreenWidth ? '6%' : '2.45%', + } as ViewStyle); return ( @@ -31,20 +43,7 @@ function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMen - {!isEndOptionRow && ( - - )} + {!isEndOptionRow && } {title} {subtitle} From 612548ea1c4cb6434b3d30cb57ee1a7dbe8d7131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 10:50:09 +0100 Subject: [PATCH 047/102] add a new property to keep track of previous toggle state --- .../workspace/workflows/ToggleSettingsOptionRow.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index f1ca9dad2fc3..d2e120d9ac09 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, {useEffect, useState} from 'react'; import {View, ViewStyle} from 'react-native'; import type {SvgProps} from 'react-native-svg'; import Switch from '@components/Switch'; @@ -10,12 +10,13 @@ type OptionType = { Illustration: React.ElementType; title: string; subtitle: string; + hasBeenToggled: boolean; onToggle: (isEnabled: boolean) => void; subMenuItems?: React.ReactNode; isEndOptionRow?: boolean; }; -function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow}: OptionType) { +function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: OptionType) { const [isEnabled, setIsEnabled] = useState(false); const styles = useThemeStyles(); @@ -37,6 +38,10 @@ function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMen left: isSmallScreenWidth ? '6%' : '2.45%', } as ViewStyle); + useEffect(() => { + setIsEnabled(hasBeenToggled); + }, []); + return ( @@ -57,7 +62,7 @@ function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMen /> - {isEnabled && {subMenuItems}} + {isEnabled && subMenuItems} ); } From 2cdcba8e0d94792c2a23955005d68977999cf147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 10:50:33 +0100 Subject: [PATCH 048/102] handle toggle states on refresh --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 43daced72467..08d16b750e63 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -44,6 +44,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} /> ), + hasBeenToggled: policy?.harvesting?.enabled ?? false }, { Illustration: Illustrations.Approval, @@ -64,6 +65,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} /> ), + hasBeenToggled: policy?.isAutoApprovalEnabled ?? false, }, { Illustration: Illustrations.WalletAlt, @@ -83,6 +85,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { /> ), isEndOptionRow: true, + hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented }, ]; @@ -95,6 +98,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { onToggle={item.onToggle} subMenuItems={item.subMenuItems} isEndOptionRow={item.isEndOptionRow} + hasBeenToggled={item.hasBeenToggled} /> ); From 350dab48e3da5ab9bd97d99f41fcf3bc0b6392e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 11:22:23 +0100 Subject: [PATCH 049/102] use icon component --- .../workflows/ToggleSettingsOptionRow.tsx | 16 +++++++++------- .../workflows/WorkspaceWorkflowsPage.tsx | 8 ++++---- src/styles/index.ts | 2 -- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index d2e120d9ac09..d90bab4a7143 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,13 +1,15 @@ import React, {useEffect, useState} from 'react'; -import {View, ViewStyle} from 'react-native'; +import {View} from 'react-native'; +import type {ViewStyle} from 'react-native'; import type {SvgProps} from 'react-native-svg'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import Icon from '@components/Icon'; type OptionType = { - Illustration: React.ElementType; + icon: React.FC; title: string; subtitle: string; hasBeenToggled: boolean; @@ -16,7 +18,7 @@ type OptionType = { isEndOptionRow?: boolean; }; -function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: OptionType) { +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: OptionType) { const [isEnabled, setIsEnabled] = useState(false); const styles = useThemeStyles(); @@ -27,26 +29,26 @@ function ToggleSettingOptionRow({Illustration, title, subtitle, onToggle, subMen const { isSmallScreenWidth } = useWindowDimensions(); // Define dot style for menu items based on screen width - const getDynamicDotStyle = (isEnabled: boolean) => ({ + const getDynamicDotStyle = (enabled: boolean) => ({ position: 'absolute', width: 6, backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', backgroundSize: '5px 15px', backgroundRepeat: 'repeat-y', top: isSmallScreenWidth ? '32%' : '12%', - bottom: isEnabled ? '-180%' : '-100%', + bottom: enabled ? '-180%' : '-100%', left: isSmallScreenWidth ? '6%' : '2.45%', } as ViewStyle); useEffect(() => { setIsEnabled(hasBeenToggled); - }, []); + }, [hasBeenToggled]); return ( - + {!isEndOptionRow && } diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 08d16b750e63..a891499f3b57 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -27,7 +27,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const items: OptionType[] = [ { - Illustration: Illustrations.ReceiptEnvelope, + icon: Illustrations.ReceiptEnvelope, title: translate('workflowsPage.delaySubmissionTitle'), subtitle: translate('workflowsPage.delaySubmissionDescription'), onToggle: (isEnabled: boolean) => { @@ -47,7 +47,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hasBeenToggled: policy?.harvesting?.enabled ?? false }, { - Illustration: Illustrations.Approval, + icon: Illustrations.Approval, title: translate('workflowsPage.addApprovalsTitle'), subtitle: translate('workflowsPage.addApprovalsDescription'), onToggle: (isEnabled: boolean) => { @@ -68,7 +68,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hasBeenToggled: policy?.isAutoApprovalEnabled ?? false, }, { - Illustration: Illustrations.WalletAlt, + icon: Illustrations.WalletAlt, title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { @@ -92,7 +92,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const renderItem = ({item}: {item: OptionType}) => ( width: variables.updateTextViewContainerWidth, }, workspaceWorkflowsIcon: { - height: 48, - width: 48, marginRight: 12, zIndex: 2, paddingBottom: 15, From de670a4e8e690098f62dda32c1829c71261a7de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 11:33:51 +0100 Subject: [PATCH 050/102] remove unneeded style --- src/styles/index.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/styles/index.ts b/src/styles/index.ts index 7f3e4da43f4c..ab51c657cbfc 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4630,10 +4630,6 @@ const styles = (theme: ThemeColors) => position: 'absolute', left: 0, }, - workspaceWorkflowsSubItemHover: { - borderRadius: 8, - marginRight: 0, - }, workspaceTitleStyle: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, fontWeight: '500', From e51a3ea8fd714e21793f3e33a2ec34b4dcf3e8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 11:34:07 +0100 Subject: [PATCH 051/102] use existing classes for styling --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index a891499f3b57..a3c0986526c4 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -41,7 +41,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { description={translate('workflowsPage.weeklyFrequency')} shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} - hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} + hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), hasBeenToggled: policy?.harvesting?.enabled ?? false @@ -62,7 +62,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} - hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} + hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), hasBeenToggled: policy?.isAutoApprovalEnabled ?? false, @@ -81,7 +81,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} - hoverAndPressStyle={styles.workspaceWorkflowsSubItemHover} + hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), isEndOptionRow: true, From 6e6190f52d1a75c828be267d6614fc8b54c6bf0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 11:40:20 +0100 Subject: [PATCH 052/102] fix style --- .../workflows/ToggleSettingsOptionRow.tsx | 32 +++++++++++-------- .../workflows/WorkspaceWorkflowsPage.tsx | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index d90bab4a7143..6084667d1f61 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -2,11 +2,11 @@ import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; import type {ViewStyle} from 'react-native'; import type {SvgProps} from 'react-native-svg'; +import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import Icon from '@components/Icon'; type OptionType = { icon: React.FC; @@ -26,19 +26,20 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, setIsEnabled((previousState) => !previousState); onToggle(!isEnabled); }; - const { isSmallScreenWidth } = useWindowDimensions(); + const {isSmallScreenWidth} = useWindowDimensions(); // Define dot style for menu items based on screen width - const getDynamicDotStyle = (enabled: boolean) => ({ - position: 'absolute', - width: 6, - backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', - backgroundSize: '5px 15px', - backgroundRepeat: 'repeat-y', - top: isSmallScreenWidth ? '32%' : '12%', - bottom: enabled ? '-180%' : '-100%', - left: isSmallScreenWidth ? '6%' : '2.45%', - } as ViewStyle); + const getDynamicDotStyle = (enabled: boolean) => + ({ + position: 'absolute', + width: 6, + backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', + backgroundSize: '5px 15px', + backgroundRepeat: 'repeat-y', + top: isSmallScreenWidth ? '32%' : '12%', + bottom: enabled ? '-180%' : '-100%', + left: isSmallScreenWidth ? '6%' : '2.45%', + } as ViewStyle); useEffect(() => { setIsEnabled(hasBeenToggled); @@ -48,7 +49,12 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, - + {!isEndOptionRow && } diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index a3c0986526c4..b1b720519da2 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -44,7 +44,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), - hasBeenToggled: policy?.harvesting?.enabled ?? false + hasBeenToggled: policy?.harvesting?.enabled ?? false, }, { icon: Illustrations.Approval, From 890fcb0057533be8a203409fb7d8556d0e900969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:12:37 +0100 Subject: [PATCH 053/102] add issues for todos --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index b1b720519da2..510a66dd2dd1 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -38,6 +38,8 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { title={translate('workflowsPage.submissionFrequency')} titleStyle={styles.workspaceWorkflowsSubMenuTitle} descriptionTextStyle={styles.workspaceWorkflowsSubMenuDescription} + // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 description={translate('workflowsPage.weeklyFrequency')} shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} @@ -60,6 +62,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { descriptionTextStyle={styles.workspaceWorkflowsSubMenuDescription} description={policy?.owner ?? ''} // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} hoverAndPressStyle={[styles.mr0, styles.br2]} @@ -72,13 +75,14 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { - // TODO call API routes && set onyx optimistic data + // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} hoverAndPressStyle={[styles.mr0, styles.br2]} From 8602b32bc32a423bf38f163787e2272621d70963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:15:50 +0100 Subject: [PATCH 054/102] use useMemo() for performance --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 510a66dd2dd1..7310f6ce65b6 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React from 'react'; +import { useMemo } from 'react'; import {FlatList, View} from 'react-native'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; @@ -25,7 +25,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); - const items: OptionType[] = [ + const items: OptionType[] = useMemo(() => ([ { icon: Illustrations.ReceiptEnvelope, title: translate('workflowsPage.delaySubmissionTitle'), @@ -91,7 +91,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { isEndOptionRow: true, hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented }, - ]; + ]), [policy, route.params.policyID, styles, translate]); const renderItem = ({item}: {item: OptionType}) => ( From 64053f6d981d0a37fa5e02215cd70730597ffea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:25:03 +0100 Subject: [PATCH 055/102] add helpers for policy types --- src/libs/PolicyUtils.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index d93a761d1163..09ad08e9cb85 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -110,6 +110,10 @@ const isPolicyAdmin = (policy: OnyxEntry | EmptyObject): boolean => poli const isCollectPolicy = (policy: OnyxEntry | EmptyObject): boolean => policy?.type === CONST.POLICY.TYPE.TEAM; +const isFreePolicy = (policy: OnyxEntry | EmptyObject): boolean => policy?.type === CONST.POLICY.TYPE.FREE; + +const isControlPolicy = (policy: OnyxEntry | EmptyObject): boolean => policy?.type === CONST.POLICY.TYPE.CORPORATE; + const isPolicyMember = (policyID: string, policies: OnyxCollection): boolean => Object.values(policies ?? {}).some((policy) => policy?.id === policyID); /** @@ -261,6 +265,8 @@ export { isExpensifyGuideTeam, isInstantSubmitEnabled, isCollectPolicy, + isFreePolicy, + isControlPolicy, isPolicyAdmin, isSubmitAndClose, getMemberAccountIDsForWorkspace, From b4e67d54dda5abb3b1532dbd2a2c5e211f4c2a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:25:38 +0100 Subject: [PATCH 056/102] change display logic for control/collect policies (more features menu item) --- src/pages/workspace/WorkspaceInitialPage.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index aaaca8f74be8..3b415c8a6fe0 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -98,6 +98,8 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r const hasGeneralSettingsError = !isEmptyObject(policy?.errorFields?.generalSettings ?? {}) || !isEmptyObject(policy?.errorFields?.avatar ?? {}); const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy); const isCollectPolicy = PolicyUtils.isCollectPolicy(policy); + const isControlPolicy = PolicyUtils.isControlPolicy(policy); + const isFreePolicy = PolicyUtils.isFreePolicy(policy); const protectedMenuItems: WorkspaceMenuItem[] = [ { @@ -147,7 +149,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: !isEmptyObject(reimbursementAccount?.errors) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, }, ]; - const collectPolicyMenuItems: WorkspaceMenuItem[] = [ + const moreFeaturesMenuItems: WorkspaceMenuItem[] = [ { translationKey: 'workspace.common.workflows', icon: Expensicons.Workflows, @@ -164,8 +166,8 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, - ...(isCollectPolicy ? collectPolicyMenuItems : []), - ...(shouldShowProtectedItems ? protectedMenuItems : []), + ...(shouldShowProtectedItems && isCollectPolicy || isControlPolicy ? moreFeaturesMenuItems : []), + ...(shouldShowProtectedItems && isFreePolicy ? protectedMenuItems : []), ]; const prevPolicy = usePrevious(policy); From 395faf23a561872620712a769a8fcae4722cdcfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:31:47 +0100 Subject: [PATCH 057/102] fix import --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 7310f6ce65b6..2e87c8098ba0 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import { useMemo } from 'react'; +import React, { useMemo } from 'react'; import {FlatList, View} from 'react-native'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; From 1fd4e707a904ebb25b504c7b358d475c11bde388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:39:51 +0100 Subject: [PATCH 058/102] use styleUtils --- .../workflows/ToggleSettingsOptionRow.tsx | 18 ++++-------------- src/styles/utils/index.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 6084667d1f61..cb06be97e2c1 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,6 +1,7 @@ import React, {useEffect, useState} from 'react'; import {View} from 'react-native'; import type {ViewStyle} from 'react-native'; +import useStyleUtils from '@hooks/useStyleUtils'; import type {SvgProps} from 'react-native-svg'; import Icon from '@components/Icon'; import Switch from '@components/Switch'; @@ -21,25 +22,14 @@ type OptionType = { function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: OptionType) { const [isEnabled, setIsEnabled] = useState(false); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const toggleSwitch = () => { - setIsEnabled((previousState) => !previousState); + setIsEnabled(!isEnabled); onToggle(!isEnabled); }; const {isSmallScreenWidth} = useWindowDimensions(); - // Define dot style for menu items based on screen width - const getDynamicDotStyle = (enabled: boolean) => - ({ - position: 'absolute', - width: 6, - backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', - backgroundSize: '5px 15px', - backgroundRepeat: 'repeat-y', - top: isSmallScreenWidth ? '32%' : '12%', - bottom: enabled ? '-180%' : '-100%', - left: isSmallScreenWidth ? '6%' : '2.45%', - } as ViewStyle); useEffect(() => { setIsEnabled(hasBeenToggled); @@ -56,7 +46,7 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, additionalStyles={styles.workspaceWorkflowsIcon} /> - {!isEndOptionRow && } + {!isEndOptionRow && } {title} {subtitle} diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index a0edb7fd4e23..fc64556199de 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1474,6 +1474,18 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ }, getFullscreenCenteredContentStyles: () => [StyleSheet.absoluteFill, styles.justifyContentCenter, styles.alignItemsCenter], + + getWorkspaceWorkflowsDotStyle: (enabled: boolean, isSmallScreenWidth: boolean) => + ({ + position: 'absolute', + width: 6, + backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', + backgroundSize: '5px 15px', + backgroundRepeat: 'repeat-y', + top: isSmallScreenWidth ? '32%' : '12%', + bottom: enabled ? '-180%' : '-100%', + left: isSmallScreenWidth ? '6%' : '2.45%', + }), }); type StyleUtilsType = ReturnType; From 6e66ace77035c3f299cfceb895154574001bbedb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:40:18 +0100 Subject: [PATCH 059/102] fix spanish translations --- src/languages/es.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index cdbecda8bf34..c0fc0e8fcc18 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1014,22 +1014,22 @@ export default { }, workflowsPage: { workflowTitle: 'Gasto', - workflowDescription: 'Configure un flujo de trabajo desde el momento en que se produce el gasto, incluida la aprobación y el pago.', - delaySubmissionTitle: 'Retrasar las presentaciones', + workflowDescription: 'Configure un flujo de trabajo desde el momento en que se produce el gasto, incluida la aprobación y el pago', + delaySubmissionTitle: 'Retrasar envíos', delaySubmissionDescription: 'Los gastos se comparten de inmediato para una mejor visibilidad del gasto. Establece una cadencia más lenta si es necesario.', - addApprovalsTitle: 'Añadir aprobacións', - approver: 'Aprobador', - submissionFrequency: 'Frecuencia de envío', + submissionFrequency: 'Frecuencia de envíos', weeklyFrequency: 'Semanal', monthlyFrequency: 'Mensual', twiceAMonthFrequency: 'Dos veces al mes', byTripFrequency: 'Por viaje', - manuallyFrequency: 'Manualmente', - dailyFrequency: 'Diario', + manuallyFrequency: 'Manual', + dailyFrequency: 'Diaria', + addApprovalsTitle: 'Requerir aprobaciones', + approver: 'Aprobador', connectBankAccount: 'Conectar cuenta bancaria', addApprovalsDescription: 'Requiere una aprobación adicional antes de autorizar un pago.', makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', - makeOrTrackPaymentsDescription: 'Añada un pagador autorizado para los pagos realizados en Expensify, o simplemente realice un seguimiento de los pagos realizados en otro lugar.', + makeOrTrackPaymentsDescription: 'Añade un pagador autorizado para los pagos realizados en Expensify, o simplemente realiza un seguimiento de los pagos realizados en otro lugar., }, reportFraudPage: { title: 'Reportar fraude con la tarjeta virtual', From 9e60d5001f07053bbaa7db03f8fd62075828f374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 16:46:36 +0100 Subject: [PATCH 060/102] fix typo --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index c0fc0e8fcc18..4758717189f8 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1029,7 +1029,7 @@ export default { connectBankAccount: 'Conectar cuenta bancaria', addApprovalsDescription: 'Requiere una aprobación adicional antes de autorizar un pago.', makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', - makeOrTrackPaymentsDescription: 'Añade un pagador autorizado para los pagos realizados en Expensify, o simplemente realiza un seguimiento de los pagos realizados en otro lugar., + makeOrTrackPaymentsDescription: 'Añade un pagador autorizado para los pagos realizados en Expensify, o simplemente realiza un seguimiento de los pagos realizados en otro lugar.', }, reportFraudPage: { title: 'Reportar fraude con la tarjeta virtual', From 3051a27e49fde74ed7e3d7ab7bff82230ad5d844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 17:35:16 +0100 Subject: [PATCH 061/102] create workflows style utils --- src/styles/utils/index.ts | 77 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index fc64556199de..3dc5927b7f6f 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -25,6 +25,7 @@ import getNavigationModalCardStyle from './getNavigationModalCardStyles'; import getSignInBgStyles from './getSignInBgStyles'; import {compactContentContainerStyles} from './optionRowStyles'; import positioning from './positioning'; +import spacing from './spacing'; import type { AllStyles, AvatarSize, @@ -1474,7 +1475,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ }, getFullscreenCenteredContentStyles: () => [StyleSheet.absoluteFill, styles.justifyContentCenter, styles.alignItemsCenter], - + getWorkspaceWorkflowsDotStyle: (enabled: boolean, isSmallScreenWidth: boolean) => ({ position: 'absolute', @@ -1486,6 +1487,80 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ bottom: enabled ? '-180%' : '-100%', left: isSmallScreenWidth ? '6%' : '2.45%', }), + + getWorkflowsStyle: (type: string): Object => { + switch (type) { + case 'icon': + return { + marginRight: 12, + zIndex: 2, + paddingBottom: 15, + }; + case 'content': + return { + flexDirection: 'row', + alignItems: 'center', + flex: 1, + }; + case 'container': + return { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }; + case 'heading': + return { + fontSize: 15, + fontWeight: '700', + }; + case 'wrapperText': + return { + flexDirection: 'column', + flex: 1, + }; + case 'subtitle': + return { + fontSize: 13, + color: defaultTheme.textSupporting, + marginTop: 3, + }; + case 'subMenuContainer': + return { + ...spacing.ph8, + ...spacing.mhn8, + width: 'auto', + marginLeft: 44, + paddingVertical: 12, + paddingRight: 9, + paddingLeft: 16, + marginRight: 0, + }; + case 'subMenuTitle': + return { + color: defaultTheme.textSupporting, + fontSize: 13, + lineHeight: 16, + fontWeight: '400', + }; + case 'subMenuDescription': + return { + color: defaultTheme.text, + fontSize: 15, + lineHeight: 20, + }; + case 'timelineOverride': + return { + backgroundColor: defaultTheme.cardBG, + zIndex: 1, + height: 19, + width: 19, + position: 'absolute', + left: 0, + }; + default: + return {}; + } + }, }); type StyleUtilsType = ReturnType; From c2a75444168b4ded23da20720e02129cd993df85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 17:35:51 +0100 Subject: [PATCH 062/102] use workflows style utils --- .../workflows/ToggleSettingsOptionRow.tsx | 14 ++++++------- .../workflows/WorkspaceWorkflowsPage.tsx | 20 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index cb06be97e2c1..3543f1d72581 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -37,19 +37,19 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, return ( - - + + - + {!isEndOptionRow && } - - {title} - {subtitle} + + {title} + {subtitle} diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 2e87c8098ba0..ccb26563ce16 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -17,6 +17,7 @@ import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {OptionType} from './ToggleSettingsOptionRow'; +import useStyleUtils from '@hooks/useStyleUtils'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -24,6 +25,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); + const StyleUtils = useStyleUtils(); const items: OptionType[] = useMemo(() => ([ { @@ -36,13 +38,13 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 description={translate('workflowsPage.weeklyFrequency')} shouldShowRightIcon - wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + wrapperStyle={StyleUtils.getWorkflowsStyle('subMenuContainer')} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), @@ -58,13 +60,13 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 shouldShowRightIcon - wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + wrapperStyle={StyleUtils.getWorkflowsStyle('subMenuContainer')} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), @@ -79,19 +81,19 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon - wrapperStyle={styles.workspaceWorkflowsSubMenuContainer} + wrapperStyle={StyleUtils.getWorkflowsStyle('subMenuContainer')} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), isEndOptionRow: true, hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented }, - ]), [policy, route.params.policyID, styles, translate]); + ]), [policy, route.params.policyID, styles, translate, StyleUtils]); const renderItem = ({item}: {item: OptionType}) => ( From 007d5388377b9d52374243a12d0a9e73c7ff665e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Mon, 19 Feb 2024 17:47:22 +0100 Subject: [PATCH 063/102] use correct naming for props --- .../workflows/ToggleSettingsOptionRow.tsx | 15 +++++---------- .../workflows/WorkspaceWorkflowsPage.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 3543f1d72581..e84484a98f17 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,4 +1,4 @@ -import React, {useEffect, useState} from 'react'; +import React, {useState} from 'react'; import {View} from 'react-native'; import type {ViewStyle} from 'react-native'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -9,7 +9,7 @@ import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; -type OptionType = { +type ToggleSettingOptionRowProps = { icon: React.FC; title: string; subtitle: string; @@ -19,8 +19,8 @@ type OptionType = { isEndOptionRow?: boolean; }; -function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: OptionType) { - const [isEnabled, setIsEnabled] = useState(false); +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: ToggleSettingOptionRowProps) { + const [isEnabled, setIsEnabled] = useState(hasBeenToggled); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -30,11 +30,6 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, }; const {isSmallScreenWidth} = useWindowDimensions(); - - useEffect(() => { - setIsEnabled(hasBeenToggled); - }, [hasBeenToggled]); - return ( @@ -65,5 +60,5 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, ); } -export type {OptionType}; +export type {ToggleSettingOptionRowProps}; export default ToggleSettingOptionRow; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index ccb26563ce16..9fe10bff8419 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -16,7 +16,7 @@ import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; -import type {OptionType} from './ToggleSettingsOptionRow'; +import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; import useStyleUtils from '@hooks/useStyleUtils'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -27,7 +27,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {isSmallScreenWidth} = useWindowDimensions(); const StyleUtils = useStyleUtils(); - const items: OptionType[] = useMemo(() => ([ + const items: ToggleSettingOptionRowProps[] = useMemo(() => ([ { icon: Illustrations.ReceiptEnvelope, title: translate('workflowsPage.delaySubmissionTitle'), @@ -95,7 +95,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, ]), [policy, route.params.policyID, styles, translate, StyleUtils]); - const renderItem = ({item}: {item: OptionType}) => ( + const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( item.title} + keyExtractor={(item: ToggleSettingOptionRowProps) => item.title} />
From f87ab42ccf0bcd539ef67d76f7507387f928fbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 20 Feb 2024 10:08:41 +0100 Subject: [PATCH 064/102] use paid group policy check --- src/pages/workspace/WorkspaceInitialPage.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 3b415c8a6fe0..c9a995e3cc06 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -97,8 +97,6 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r const hasMembersError = PolicyUtils.hasPolicyMemberError(policyMembers); const hasGeneralSettingsError = !isEmptyObject(policy?.errorFields?.generalSettings ?? {}) || !isEmptyObject(policy?.errorFields?.avatar ?? {}); const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy); - const isCollectPolicy = PolicyUtils.isCollectPolicy(policy); - const isControlPolicy = PolicyUtils.isControlPolicy(policy); const isFreePolicy = PolicyUtils.isFreePolicy(policy); const protectedMenuItems: WorkspaceMenuItem[] = [ @@ -166,7 +164,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, - ...(shouldShowProtectedItems && isCollectPolicy || isControlPolicy ? moreFeaturesMenuItems : []), + ...(shouldShowProtectedItems && PolicyUtils.isPaidGroupPolicy(policy) ? moreFeaturesMenuItems : []), ...(shouldShowProtectedItems && isFreePolicy ? protectedMenuItems : []), ]; From 7ccb5806e286bc0bc2cbdcf435dc8c70c6db884b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 20 Feb 2024 10:29:42 +0100 Subject: [PATCH 065/102] clean up paid group policy check --- src/pages/workspace/WorkspaceInitialPage.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index c9a995e3cc06..eb0d360a12b0 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -98,6 +98,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r const hasGeneralSettingsError = !isEmptyObject(policy?.errorFields?.generalSettings ?? {}) || !isEmptyObject(policy?.errorFields?.avatar ?? {}); const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy); const isFreePolicy = PolicyUtils.isFreePolicy(policy); + const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); const protectedMenuItems: WorkspaceMenuItem[] = [ { @@ -164,8 +165,8 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, - ...(shouldShowProtectedItems && PolicyUtils.isPaidGroupPolicy(policy) ? moreFeaturesMenuItems : []), - ...(shouldShowProtectedItems && isFreePolicy ? protectedMenuItems : []), + ...(isPaidGroupPolicy && shouldShowProtectedItems ? moreFeaturesMenuItems : []), + ...(isFreePolicy && shouldShowProtectedItems ? protectedMenuItems : []), ]; const prevPolicy = usePrevious(policy); From f83b9c11961093d2f44bee928630ec1be816d050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 20 Feb 2024 11:17:37 +0100 Subject: [PATCH 066/102] fix ios console error --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 9fe10bff8419..c6a61f2f2bf5 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -111,7 +111,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { return ( Date: Tue, 20 Feb 2024 11:32:19 +0100 Subject: [PATCH 067/102] fix icons display --- .../simple-illustrations/simple-illustration__approval.svg | 2 +- .../simple-illustration__receipt-envelope.svg | 2 +- .../simple-illustrations/simple-illustration__wallet-alt.svg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/images/simple-illustrations/simple-illustration__approval.svg b/assets/images/simple-illustrations/simple-illustration__approval.svg index 8816849fa39e..bdef2436958b 100644 --- a/assets/images/simple-illustrations/simple-illustration__approval.svg +++ b/assets/images/simple-illustrations/simple-illustration__approval.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg b/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg index 61d63f506a9b..fc7082e9932c 100644 --- a/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg +++ b/assets/images/simple-illustrations/simple-illustration__receipt-envelope.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg index 6cce2acd04f6..54b56e8d4e17 100644 --- a/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg +++ b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 9795e5fbc78ae1811b0952a9bf8481c71ad369ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 20 Feb 2024 13:43:33 +0100 Subject: [PATCH 068/102] working workflows dots for react native --- assets/images/dot.svg | 3 +++ .../workflows/ToggleSettingsOptionRow.tsx | 23 ++++++++++++++++++- src/styles/utils/index.ts | 13 +++++------ 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 assets/images/dot.svg diff --git a/assets/images/dot.svg b/assets/images/dot.svg new file mode 100644 index 000000000000..1146c88a01b8 --- /dev/null +++ b/assets/images/dot.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index e84484a98f17..453b80f3148b 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -8,6 +8,8 @@ import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import ImageSVG from '@components/ImageSVG'; +import Dot from '@assets/images/dot.svg'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -30,6 +32,22 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, }; const {isSmallScreenWidth} = useWindowDimensions(); + + const VerticalDots = ({count}: {count: number}) => { + return ( + + {Array.from({length: count}, (_, index) => ( + ))} + + ); + }; + return ( @@ -41,7 +59,9 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, additionalStyles={StyleUtils.getWorkflowsStyle('icon')} /> - {!isEndOptionRow && } + {!isEndOptionRow && ( + + )} {title} {subtitle} @@ -62,3 +82,4 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, export type {ToggleSettingOptionRowProps}; export default ToggleSettingOptionRow; + diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 3dc5927b7f6f..247afaaa9cb2 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1480,12 +1480,11 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ ({ position: 'absolute', width: 6, - backgroundImage: 'radial-gradient(circle at 2.5px, #1A3D32 1.25px, rgba(255, 255, 255, 0) 2.5px)', - backgroundSize: '5px 15px', - backgroundRepeat: 'repeat-y', top: isSmallScreenWidth ? '32%' : '12%', - bottom: enabled ? '-180%' : '-100%', - left: isSmallScreenWidth ? '6%' : '2.45%', + bottom: enabled ? '-140%' : '-80%', + left: isSmallScreenWidth ? '8%' : '4%', + display: 'flex', + justifyContent: 'space-between', }), getWorkflowsStyle: (type: string): Object => { @@ -1552,8 +1551,8 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ return { backgroundColor: defaultTheme.cardBG, zIndex: 1, - height: 19, - width: 19, + height: 29, + width: 29, position: 'absolute', left: 0, }; From c674033cc08266ab39c3c7f378c763dd02ccce86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Tue, 20 Feb 2024 13:58:19 +0100 Subject: [PATCH 069/102] fix lint --- .../workflows/ToggleSettingsOptionRow.tsx | 26 +++++++++---------- .../workflows/WorkspaceWorkflowsPage.tsx | 2 +- src/styles/utils/index.ts | 3 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 453b80f3148b..adfb202443cf 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -32,21 +32,21 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, }; const {isSmallScreenWidth} = useWindowDimensions(); - - const VerticalDots = ({count}: {count: number}) => { + function VerticalDots({count}: {count: number}) { return ( - - {Array.from({length: count}, (_, index) => ( - ))} - + + {Array.from({length: count}, () => ( + + ))} + ); - }; + } return ( diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index c6a61f2f2bf5..3ac6dd68e1c2 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -15,9 +15,9 @@ import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSection import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; +import useStyleUtils from '@hooks/useStyleUtils'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; -import useStyleUtils from '@hooks/useStyleUtils'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 247afaaa9cb2..aaa3ce0f44ba 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1487,7 +1487,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ justifyContent: 'space-between', }), - getWorkflowsStyle: (type: string): Object => { + getWorkflowsStyle: (type: string): Record => { switch (type) { case 'icon': return { @@ -1569,3 +1569,4 @@ const DefaultStyleUtils = createStyleUtils(defaultTheme, defaultStyles); export default createStyleUtils; export {DefaultStyleUtils}; export type {StyleUtilsType, AvatarSizeName}; + From f4377195834c8a9d2ea8cd2242b695078642733e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 14:05:57 +0100 Subject: [PATCH 070/102] fix subtitle display --- src/styles/utils/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index aaa3ce0f44ba..405b463cf1df 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1522,6 +1522,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ fontSize: 13, color: defaultTheme.textSupporting, marginTop: 3, + marginRight: 10, }; case 'subMenuContainer': return { From 7648bfef8b995da9b8f1d1b0f29a0bb0ffd29502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 15:22:37 +0100 Subject: [PATCH 071/102] increase icon size --- .../simple-illustrations/simple-illustration__wallet-alt.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg index 54b56e8d4e17..502a216f82e6 100644 --- a/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg +++ b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 3224dcabf2557964276bc3b88beef139804026ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 15:22:44 +0100 Subject: [PATCH 072/102] remove dots --- assets/images/dot.svg | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 assets/images/dot.svg diff --git a/assets/images/dot.svg b/assets/images/dot.svg deleted file mode 100644 index 1146c88a01b8..000000000000 --- a/assets/images/dot.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file From 195cc803d5216b8d6e42c4fd9e15ef12d716f7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 15:23:15 +0100 Subject: [PATCH 073/102] clean up styles --- .../workflows/ToggleSettingsOptionRow.tsx | 69 ++++++++------- .../workflows/WorkspaceWorkflowsPage.tsx | 44 ++++++++-- src/styles/index.ts | 57 ------------ src/styles/utils/index.ts | 86 ------------------- 4 files changed, 75 insertions(+), 181 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index adfb202443cf..215897651123 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,15 +1,13 @@ import React, {useState} from 'react'; import {View} from 'react-native'; -import type {ViewStyle} from 'react-native'; -import useStyleUtils from '@hooks/useStyleUtils'; import type {SvgProps} from 'react-native-svg'; import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import ImageSVG from '@components/ImageSVG'; -import Dot from '@assets/images/dot.svg'; +import { Styles } from '@styles/index'; +import {defaultTheme } from '@styles/theme'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -24,7 +22,6 @@ type ToggleSettingOptionRowProps = { function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: ToggleSettingOptionRowProps) { const [isEnabled, setIsEnabled] = useState(hasBeenToggled); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); const toggleSwitch = () => { setIsEnabled(!isEnabled); @@ -32,39 +29,51 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, }; const {isSmallScreenWidth} = useWindowDimensions(); - function VerticalDots({count}: {count: number}) { - return ( - - {Array.from({length: count}, () => ( - - ))} - - ); - } + // Since these styles are only used in this component we define them here + const workflowsStyles = { + container: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + content: { + flexDirection: 'row', + alignItems: 'center', + flex: 1, + }, + icon: { + marginRight: 12, + zIndex: 2, + paddingBottom: 15, + }, + wrapperText: { + flexDirection: 'column', + flex: 1, + }, + heading: { + fontSize: 15, + fontWeight: '700', + }, + subtitle: { + fontSize: 13, + color: defaultTheme.textSupporting, + marginTop: 3, + }, + } satisfies Styles; return ( - - + + - - {!isEndOptionRow && ( - - )} - - {title} - {subtitle} + + {title} + {subtitle} diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 3ac6dd68e1c2..f6972f0fac1f 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -18,6 +18,9 @@ import type SCREENS from '@src/SCREENS'; import useStyleUtils from '@hooks/useStyleUtils'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; +import {defaultTheme } from '@styles/theme'; +import spacing from '@styles/utils/spacing'; +import { Styles } from '@styles/index'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -27,6 +30,31 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {isSmallScreenWidth} = useWindowDimensions(); const StyleUtils = useStyleUtils(); + // Since these styles are only used in this component we define them here + const workflowsStyles = { + subMenuContainer: { + ...spacing.ph8, + ...spacing.mhn8, + width: 'auto', + marginLeft: 44, + paddingVertical: 12, + paddingRight: 9, + paddingLeft: 16, + marginRight: 0, + }, + subMenuTitle: { + color: defaultTheme.textSupporting, + fontSize: 13, + lineHeight: 16, + fontWeight: '400', + }, + subMenuDescription: { + color: defaultTheme.text, + fontSize: 15, + lineHeight: 20, + }, + } satisfies Styles; + const items: ToggleSettingOptionRowProps[] = useMemo(() => ([ { icon: Illustrations.ReceiptEnvelope, @@ -38,13 +66,13 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 description={translate('workflowsPage.weeklyFrequency')} shouldShowRightIcon - wrapperStyle={StyleUtils.getWorkflowsStyle('subMenuContainer')} + wrapperStyle={workflowsStyles.subMenuContainer} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), @@ -60,13 +88,13 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 shouldShowRightIcon - wrapperStyle={StyleUtils.getWorkflowsStyle('subMenuContainer')} + wrapperStyle={workflowsStyles.subMenuContainer} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), @@ -81,12 +109,12 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon - wrapperStyle={StyleUtils.getWorkflowsStyle('subMenuContainer')} + wrapperStyle={workflowsStyles.subMenuContainer} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), diff --git a/src/styles/index.ts b/src/styles/index.ts index ab51c657cbfc..30c5657620ad 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4573,63 +4573,6 @@ const styles = (theme: ThemeColors) => updateRequiredViewTextContainer: { width: variables.updateTextViewContainerWidth, }, - workspaceWorkflowsIcon: { - marginRight: 12, - zIndex: 2, - paddingBottom: 15, - }, - workspaceWorkflowContent: { - flexDirection: 'row', - alignItems: 'center', - flex: 1, - }, - workspaceWorkflowContainer: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, - workspaceWorkflowsHeading: { - fontSize: 15, - fontWeight: '700', - }, - workspaceWorkflowsWrapperText: { - flexDirection: 'column', - flex: 1, - }, - workspaceWorkflowsSubtitle: { - fontSize: 13, - color: theme.textSupporting, - marginTop: 3, - }, - workspaceWorkflowsSubMenuContainer: { - ...spacing.ph8, - ...spacing.mhn8, - width: 'auto', - marginLeft: 44, - paddingVertical: 12, - paddingRight: 9, - paddingLeft: 16, - marginRight: 0, - }, - workspaceWorkflowsSubMenuTitle: { - color: theme.textSupporting, - fontSize: 13, - lineHeight: 16, - fontWeight: '400', - }, - workspaceWorkflowsSubMenuDescription: { - color: theme.text, - fontSize: 15, - lineHeight: 20, - }, - workspaceWorkflowsTimelineOverride: { - backgroundColor: theme.cardBG, - zIndex: 1, - height: 19, - width: 19, - position: 'absolute', - left: 0, - }, workspaceTitleStyle: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, fontWeight: '500', diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 405b463cf1df..4efe61fddea1 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1475,92 +1475,6 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ }, getFullscreenCenteredContentStyles: () => [StyleSheet.absoluteFill, styles.justifyContentCenter, styles.alignItemsCenter], - - getWorkspaceWorkflowsDotStyle: (enabled: boolean, isSmallScreenWidth: boolean) => - ({ - position: 'absolute', - width: 6, - top: isSmallScreenWidth ? '32%' : '12%', - bottom: enabled ? '-140%' : '-80%', - left: isSmallScreenWidth ? '8%' : '4%', - display: 'flex', - justifyContent: 'space-between', - }), - - getWorkflowsStyle: (type: string): Record => { - switch (type) { - case 'icon': - return { - marginRight: 12, - zIndex: 2, - paddingBottom: 15, - }; - case 'content': - return { - flexDirection: 'row', - alignItems: 'center', - flex: 1, - }; - case 'container': - return { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }; - case 'heading': - return { - fontSize: 15, - fontWeight: '700', - }; - case 'wrapperText': - return { - flexDirection: 'column', - flex: 1, - }; - case 'subtitle': - return { - fontSize: 13, - color: defaultTheme.textSupporting, - marginTop: 3, - marginRight: 10, - }; - case 'subMenuContainer': - return { - ...spacing.ph8, - ...spacing.mhn8, - width: 'auto', - marginLeft: 44, - paddingVertical: 12, - paddingRight: 9, - paddingLeft: 16, - marginRight: 0, - }; - case 'subMenuTitle': - return { - color: defaultTheme.textSupporting, - fontSize: 13, - lineHeight: 16, - fontWeight: '400', - }; - case 'subMenuDescription': - return { - color: defaultTheme.text, - fontSize: 15, - lineHeight: 20, - }; - case 'timelineOverride': - return { - backgroundColor: defaultTheme.cardBG, - zIndex: 1, - height: 29, - width: 29, - position: 'absolute', - left: 0, - }; - default: - return {}; - } - }, }); type StyleUtilsType = ReturnType; From 587772cb0b808266ca86fff0c4ea94694692b7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 15:45:18 +0100 Subject: [PATCH 074/102] handle user theme preference --- .../workflows/ToggleSettingsOptionRow.tsx | 14 +++++++------- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 14 ++++++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 215897651123..7198c767d229 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -5,9 +5,9 @@ import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; -import useWindowDimensions from '@hooks/useWindowDimensions'; import { Styles } from '@styles/index'; import {defaultTheme } from '@styles/theme'; +import { ThemeColors } from '@styles/theme/types'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -17,17 +17,17 @@ type ToggleSettingOptionRowProps = { onToggle: (isEnabled: boolean) => void; subMenuItems?: React.ReactNode; isEndOptionRow?: boolean; + theme?: ThemeColors; }; -function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isEndOptionRow, hasBeenToggled}: ToggleSettingOptionRowProps) { +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled, theme}: ToggleSettingOptionRowProps) { const [isEnabled, setIsEnabled] = useState(hasBeenToggled); const styles = useThemeStyles(); - + const ICON_SIZE = 48; const toggleSwitch = () => { setIsEnabled(!isEnabled); onToggle(!isEnabled); }; - const {isSmallScreenWidth} = useWindowDimensions(); // Since these styles are only used in this component we define them here const workflowsStyles = { @@ -56,7 +56,7 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, }, subtitle: { fontSize: 13, - color: defaultTheme.textSupporting, + color: theme?.textSupporting || defaultTheme.textSupporting, marginTop: 3, }, } satisfies Styles; @@ -67,8 +67,8 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index f6972f0fac1f..b782d8c02ed5 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -18,9 +18,11 @@ import type SCREENS from '@src/SCREENS'; import useStyleUtils from '@hooks/useStyleUtils'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; -import {defaultTheme } from '@styles/theme'; +import darkTheme from '@styles/theme/themes/dark'; +import lightTheme from '@styles/theme/themes/light'; import spacing from '@styles/utils/spacing'; import { Styles } from '@styles/index'; +import useThemePreference from '@hooks/useThemePreference'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -29,7 +31,9 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); const StyleUtils = useStyleUtils(); - + const themePreference = useThemePreference(); + const themeToUse = useMemo(() => themePreference === CONST.THEME.DARK ? darkTheme : lightTheme, [themePreference]); + // Since these styles are only used in this component we define them here const workflowsStyles = { subMenuContainer: { @@ -41,15 +45,16 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { paddingRight: 9, paddingLeft: 16, marginRight: 0, + marginTop: 14, }, subMenuTitle: { - color: defaultTheme.textSupporting, + color: themeToUse.textSupporting, fontSize: 13, lineHeight: 16, fontWeight: '400', }, subMenuDescription: { - color: defaultTheme.text, + color: themeToUse.text, fontSize: 15, lineHeight: 20, }, @@ -133,6 +138,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subMenuItems={item.subMenuItems} isEndOptionRow={item.isEndOptionRow} hasBeenToggled={item.hasBeenToggled} + theme={themeToUse} /> ); From 4dfeae8cddda90bfca4492e39f8b86a7938c938f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 15:46:21 +0100 Subject: [PATCH 075/102] help readability --- src/styles/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/index.ts b/src/styles/index.ts index 30c5657620ad..0d206be6f27e 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4578,6 +4578,7 @@ const styles = (theme: ThemeColors) => fontWeight: '500', fontSize: variables.workspaceProfileName, }, + } satisfies Styles); type ThemeStyles = ReturnType; From e95d7753840e2ac757c4b5f36d22d55f6c89d963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 15:54:26 +0100 Subject: [PATCH 076/102] fix workflows policy actions --- src/libs/actions/Policy.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 8c8e165cd9ae..931bc4f776ff 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -381,38 +381,39 @@ function buildAnnounceRoomMembersOnyxData(policyID: string, accountIDs: number[] return announceRoomMembers; } -function setWorkspaceAutoReporting(policyID: string, isEnabled: boolean) { +function setWorkspaceAutoReporting(policyID: string, enabled: boolean) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - autoReporting: true, + autoReporting: enabled, }, }, ]; - const params: SetWorkspaceAutoReportingParams = {policyID, enabled: isEnabled}; + const params: SetWorkspaceAutoReportingParams = {policyID, enabled}; API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING, params, {optimisticData}); } function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: 'BASIC' | 'OPTIONAL') { const isAutoApprovalEnabled = approvalMode === 'BASIC'; - const value = JSON.stringify({ + const value = { approver, approvalMode, isAutoApprovalEnabled, - }); + }; + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: JSON.parse(value), + value: value, }, ]; - const params: SetWorkspaceApprovalModeParams = {policyID, value}; + const params: SetWorkspaceApprovalModeParams = {policyID, value: JSON.stringify(value)}; API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData}); } From 3ca09f601593269ba3c36272c5884340a1f2d75d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 16:19:37 +0100 Subject: [PATCH 077/102] fix lint --- src/libs/actions/Policy.ts | 2 +- .../workflows/ToggleSettingsOptionRow.tsx | 13 ++++------ .../workflows/WorkspaceWorkflowsPage.tsx | 24 +++++++------------ src/styles/utils/index.ts | 1 - 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 931bc4f776ff..9723851e543f 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -409,7 +409,7 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: value, + value, }, ]; diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 7198c767d229..be9177759c9f 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -5,9 +5,8 @@ import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; -import { Styles } from '@styles/index'; -import {defaultTheme } from '@styles/theme'; -import { ThemeColors } from '@styles/theme/types'; +import type { Styles } from '@styles/index'; +import useTheme from '@hooks/useTheme'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -16,13 +15,12 @@ type ToggleSettingOptionRowProps = { hasBeenToggled: boolean; onToggle: (isEnabled: boolean) => void; subMenuItems?: React.ReactNode; - isEndOptionRow?: boolean; - theme?: ThemeColors; }; -function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled, theme}: ToggleSettingOptionRowProps) { +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled}: ToggleSettingOptionRowProps) { const [isEnabled, setIsEnabled] = useState(hasBeenToggled); const styles = useThemeStyles(); + const theme = useTheme(); const ICON_SIZE = 48; const toggleSwitch = () => { setIsEnabled(!isEnabled); @@ -56,7 +54,7 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, }, subtitle: { fontSize: 13, - color: theme?.textSupporting || defaultTheme.textSupporting, + color: theme.textSupporting, marginTop: 3, }, } satisfies Styles; @@ -91,4 +89,3 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, export type {ToggleSettingOptionRowProps}; export default ToggleSettingOptionRow; - diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index b782d8c02ed5..126f0500f4d7 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -15,14 +15,12 @@ import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSection import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; -import useStyleUtils from '@hooks/useStyleUtils'; +import useTheme from '@hooks/useTheme'; +// eslint-disable-next-line no-restricted-imports +import spacing from '@styles/utils/spacing'; +import type { Styles } from '@styles/index'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; -import darkTheme from '@styles/theme/themes/dark'; -import lightTheme from '@styles/theme/themes/light'; -import spacing from '@styles/utils/spacing'; -import { Styles } from '@styles/index'; -import useThemePreference from '@hooks/useThemePreference'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -30,9 +28,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); - const StyleUtils = useStyleUtils(); - const themePreference = useThemePreference(); - const themeToUse = useMemo(() => themePreference === CONST.THEME.DARK ? darkTheme : lightTheme, [themePreference]); + const theme = useTheme(); // Since these styles are only used in this component we define them here const workflowsStyles = { @@ -48,13 +44,13 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { marginTop: 14, }, subMenuTitle: { - color: themeToUse.textSupporting, + color: theme.textSupporting, fontSize: 13, lineHeight: 16, fontWeight: '400', }, subMenuDescription: { - color: themeToUse.text, + color: theme.text, fontSize: 15, lineHeight: 20, }, @@ -126,8 +122,8 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { isEndOptionRow: true, hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented }, - ]), [policy, route.params.policyID, styles, translate, StyleUtils]); - + ]), [policy, route.params.policyID, styles, translate, workflowsStyles.subMenuContainer, workflowsStyles.subMenuDescription, workflowsStyles.subMenuTitle]); + const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( ); diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 4efe61fddea1..c756dd2fed3f 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -25,7 +25,6 @@ import getNavigationModalCardStyle from './getNavigationModalCardStyles'; import getSignInBgStyles from './getSignInBgStyles'; import {compactContentContainerStyles} from './optionRowStyles'; import positioning from './positioning'; -import spacing from './spacing'; import type { AllStyles, AvatarSize, From c57b1dd1278e25e269e145b3f7884f7d3ee6e36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 16:25:55 +0100 Subject: [PATCH 078/102] fix icon display --- .../simple-illustrations/simple-illustration__wallet-alt.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg index 502a216f82e6..33d1fc0fa044 100644 --- a/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg +++ b/assets/images/simple-illustrations/simple-illustration__wallet-alt.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 1a61957a316ad46c7afce964b348f0025d6589d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 16:31:02 +0100 Subject: [PATCH 079/102] add margin as in figma --- src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index be9177759c9f..df87a0bc5adc 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -56,6 +56,7 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, fontSize: 13, color: theme.textSupporting, marginTop: 3, + marginRight: 20, }, } satisfies Styles; From f0aab68fd41986e99d74f10c5fe7b11072158e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 17:10:32 +0100 Subject: [PATCH 080/102] fix default approver display name --- .../workflows/WorkspaceWorkflowsPage.tsx | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 126f0500f4d7..22f8bc6bccaa 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,7 +1,9 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import {FlatList, View} from 'react-native'; import * as Illustrations from '@components/Icon/Illustrations'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import MenuItem from '@components/MenuItem'; import Section from '@components/Section'; import Text from '@components/Text'; @@ -30,6 +32,18 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {isSmallScreenWidth} = useWindowDimensions(); const theme = useTheme(); + const [policyOwnerDisplayName, setPolicyOwnerDisplayName] = useState(''); + + useEffect(() => { + if (!policy?.ownerAccountID) { + return; + } + const ownerPersonalDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([policy.ownerAccountID], CONST.EMPTY_OBJECT), false); + if (ownerPersonalDetails.length > 0 && ownerPersonalDetails[0].displayName) { + setPolicyOwnerDisplayName(ownerPersonalDetails[0].displayName); + } + }, [policy]); + // Since these styles are only used in this component we define them here const workflowsStyles = { subMenuContainer: { @@ -91,7 +105,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { title={translate('workflowsPage.approver')} titleStyle={workflowsStyles.subMenuTitle} descriptionTextStyle={workflowsStyles.subMenuDescription} - description={policy?.owner ?? ''} + description={policyOwnerDisplayName ?? ''} // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 shouldShowRightIcon @@ -122,7 +136,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { isEndOptionRow: true, hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented }, - ]), [policy, route.params.policyID, styles, translate, workflowsStyles.subMenuContainer, workflowsStyles.subMenuDescription, workflowsStyles.subMenuTitle]); + ]), [policy, route.params.policyID, styles, translate, workflowsStyles.subMenuContainer, workflowsStyles.subMenuDescription, workflowsStyles.subMenuTitle, policyOwnerDisplayName]); const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( @@ -170,3 +184,4 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; export default withPolicy(WorkspaceWorkflowsPage); + From 5b4914789287ada163aad3e3564fa10f99eab43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Wed, 21 Feb 2024 17:19:43 +0100 Subject: [PATCH 081/102] fix prettier --- .../workflows/ToggleSettingsOptionRow.tsx | 6 +- .../workflows/WorkspaceWorkflowsPage.tsx | 154 +++++++++--------- src/styles/index.ts | 1 - src/styles/utils/index.ts | 1 - 4 files changed, 81 insertions(+), 81 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index df87a0bc5adc..deb467ae0c76 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -4,9 +4,9 @@ import type {SvgProps} from 'react-native-svg'; import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; -import useThemeStyles from '@hooks/useThemeStyles'; -import type { Styles } from '@styles/index'; import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import type {Styles} from '@styles/index'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -51,7 +51,7 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, heading: { fontSize: 15, fontWeight: '700', - }, + }, subtitle: { fontSize: 13, color: theme.textSupporting, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 22f8bc6bccaa..390afc7be492 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,26 +1,26 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, {useEffect, useMemo, useState} from 'react'; import {FlatList, View} from 'react-native'; import * as Illustrations from '@components/Icon/Illustrations'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import MenuItem from '@components/MenuItem'; import Section from '@components/Section'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; +import type {Styles} from '@styles/index'; +// eslint-disable-next-line no-restricted-imports +import spacing from '@styles/utils/spacing'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; -import useTheme from '@hooks/useTheme'; -// eslint-disable-next-line no-restricted-imports -import spacing from '@styles/utils/spacing'; -import type { Styles } from '@styles/index'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; @@ -30,12 +30,12 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); - const theme = useTheme(); - + const theme = useTheme(); + const [policyOwnerDisplayName, setPolicyOwnerDisplayName] = useState(''); useEffect(() => { - if (!policy?.ownerAccountID) { + if (!policy?.ownerAccountID) { return; } const ownerPersonalDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([policy.ownerAccountID], CONST.EMPTY_OBJECT), false); @@ -70,74 +70,77 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, } satisfies Styles; - const items: ToggleSettingOptionRowProps[] = useMemo(() => ([ - { - icon: Illustrations.ReceiptEnvelope, - title: translate('workflowsPage.delaySubmissionTitle'), - subtitle: translate('workflowsPage.delaySubmissionDescription'), - onToggle: (isEnabled: boolean) => { - Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); + const items: ToggleSettingOptionRowProps[] = useMemo( + () => [ + { + icon: Illustrations.ReceiptEnvelope, + title: translate('workflowsPage.delaySubmissionTitle'), + subtitle: translate('workflowsPage.delaySubmissionDescription'), + onToggle: (isEnabled: boolean) => { + Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); + }, + subMenuItems: ( + Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 + description={translate('workflowsPage.weeklyFrequency')} + shouldShowRightIcon + wrapperStyle={workflowsStyles.subMenuContainer} + hoverAndPressStyle={[styles.mr0, styles.br2]} + /> + ), + hasBeenToggled: policy?.harvesting?.enabled ?? false, }, - subMenuItems: ( - Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} - // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 - description={translate('workflowsPage.weeklyFrequency')} - shouldShowRightIcon - wrapperStyle={workflowsStyles.subMenuContainer} - hoverAndPressStyle={[styles.mr0, styles.br2]} - /> - ), - hasBeenToggled: policy?.harvesting?.enabled ?? false, - }, - { - icon: Illustrations.Approval, - title: translate('workflowsPage.addApprovalsTitle'), - subtitle: translate('workflowsPage.addApprovalsDescription'), - onToggle: (isEnabled: boolean) => { - Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? 'BASIC' : 'OPTIONAL'); + { + icon: Illustrations.Approval, + title: translate('workflowsPage.addApprovalsTitle'), + subtitle: translate('workflowsPage.addApprovalsDescription'), + onToggle: (isEnabled: boolean) => { + Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? 'BASIC' : 'OPTIONAL'); + }, + subMenuItems: ( + Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 + shouldShowRightIcon + wrapperStyle={workflowsStyles.subMenuContainer} + hoverAndPressStyle={[styles.mr0, styles.br2]} + /> + ), + hasBeenToggled: policy?.isAutoApprovalEnabled ?? false, }, - subMenuItems: ( - Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} - // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 - shouldShowRightIcon - wrapperStyle={workflowsStyles.subMenuContainer} - hoverAndPressStyle={[styles.mr0, styles.br2]} - /> - ), - hasBeenToggled: policy?.isAutoApprovalEnabled ?? false, - }, - { - icon: Illustrations.WalletAlt, - title: translate('workflowsPage.makeOrTrackPaymentsTitle'), - subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), - onToggle: () => { - // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 - }, - subMenuItems: ( - Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} + { + icon: Illustrations.WalletAlt, + title: translate('workflowsPage.makeOrTrackPaymentsTitle'), + subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), + onToggle: () => { // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 - shouldShowRightIcon - wrapperStyle={workflowsStyles.subMenuContainer} - hoverAndPressStyle={[styles.mr0, styles.br2]} - /> - ), - isEndOptionRow: true, - hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented - }, - ]), [policy, route.params.policyID, styles, translate, workflowsStyles.subMenuContainer, workflowsStyles.subMenuDescription, workflowsStyles.subMenuTitle, policyOwnerDisplayName]); - + }, + subMenuItems: ( + Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 + shouldShowRightIcon + wrapperStyle={workflowsStyles.subMenuContainer} + hoverAndPressStyle={[styles.mr0, styles.br2]} + /> + ), + isEndOptionRow: true, + hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented + }, + ], + [policy, route.params.policyID, styles, translate, workflowsStyles.subMenuContainer, workflowsStyles.subMenuDescription, workflowsStyles.subMenuTitle, policyOwnerDisplayName], + ); + const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( fontWeight: '500', fontSize: variables.workspaceProfileName, }, - } satisfies Styles); type ThemeStyles = ReturnType; diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index c756dd2fed3f..a0edb7fd4e23 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1483,4 +1483,3 @@ const DefaultStyleUtils = createStyleUtils(defaultTheme, defaultStyles); export default createStyleUtils; export {DefaultStyleUtils}; export type {StyleUtilsType, AvatarSizeName}; - From 8b5e067d1f41535ebb093e0832d39ee22973bd81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 09:11:21 +0100 Subject: [PATCH 082/102] use app styles --- .../workflows/ToggleSettingsOptionRow.tsx | 59 ++++++------------- .../workflows/WorkspaceWorkflowsPage.tsx | 53 ++++------------- src/styles/index.ts | 17 ++++++ src/styles/utils/spacing.ts | 8 +++ 4 files changed, 55 insertions(+), 82 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index deb467ae0c76..eaf67557a016 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -4,9 +4,7 @@ import type {SvgProps} from 'react-native-svg'; import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; -import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import type {Styles} from '@styles/index'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -20,59 +18,36 @@ type ToggleSettingOptionRowProps = { function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled}: ToggleSettingOptionRowProps) { const [isEnabled, setIsEnabled] = useState(hasBeenToggled); const styles = useThemeStyles(); - const theme = useTheme(); const ICON_SIZE = 48; const toggleSwitch = () => { setIsEnabled(!isEnabled); onToggle(!isEnabled); }; - // Since these styles are only used in this component we define them here - const workflowsStyles = { - container: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, - content: { - flexDirection: 'row', - alignItems: 'center', - flex: 1, - }, - icon: { - marginRight: 12, - zIndex: 2, - paddingBottom: 15, - }, - wrapperText: { - flexDirection: 'column', - flex: 1, - }, - heading: { - fontSize: 15, - fontWeight: '700', - }, - subtitle: { - fontSize: 13, - color: theme.textSupporting, - marginTop: 3, - marginRight: 20, - }, - } satisfies Styles; - return ( - - + + - - {title} - {subtitle} + + {title} + {subtitle} diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 390afc7be492..52706cb261d3 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -6,7 +6,6 @@ import MenuItem from '@components/MenuItem'; import Section from '@components/Section'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; -import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -15,9 +14,6 @@ import type {CentralPaneNavigatorParamList} from '@navigation/types'; import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; -import type {Styles} from '@styles/index'; -// eslint-disable-next-line no-restricted-imports -import spacing from '@styles/utils/spacing'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; @@ -30,7 +26,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); - const theme = useTheme(); const [policyOwnerDisplayName, setPolicyOwnerDisplayName] = useState(''); @@ -44,31 +39,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { } }, [policy]); - // Since these styles are only used in this component we define them here - const workflowsStyles = { - subMenuContainer: { - ...spacing.ph8, - ...spacing.mhn8, - width: 'auto', - marginLeft: 44, - paddingVertical: 12, - paddingRight: 9, - paddingLeft: 16, - marginRight: 0, - marginTop: 14, - }, - subMenuTitle: { - color: theme.textSupporting, - fontSize: 13, - lineHeight: 16, - fontWeight: '400', - }, - subMenuDescription: { - color: theme.text, - fontSize: 15, - lineHeight: 20, - }, - } satisfies Styles; + const containerStyle = [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4]; const items: ToggleSettingOptionRowProps[] = useMemo( () => [ @@ -82,13 +53,14 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 description={translate('workflowsPage.weeklyFrequency')} shouldShowRightIcon - wrapperStyle={workflowsStyles.subMenuContainer} + wrapperStyle={containerStyle} + // wrapperStyle={workflowsStyles.subMenuContainer} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), @@ -104,13 +76,13 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 shouldShowRightIcon - wrapperStyle={workflowsStyles.subMenuContainer} + wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), @@ -125,20 +97,20 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon - wrapperStyle={workflowsStyles.subMenuContainer} + wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), isEndOptionRow: true, - hasBeenToggled: false, // TODO make it dynamic when VBBA action is implemented + hasBeenToggled: false, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, ], - [policy, route.params.policyID, styles, translate, workflowsStyles.subMenuContainer, workflowsStyles.subMenuDescription, workflowsStyles.subMenuTitle, policyOwnerDisplayName], + [policy, route.params.policyID, styles, translate, policyOwnerDisplayName], ); const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( @@ -187,3 +159,4 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; export default withPolicy(WorkspaceWorkflowsPage); + diff --git a/src/styles/index.ts b/src/styles/index.ts index a02a82fffce6..3b36f6c87169 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -400,6 +400,11 @@ const styles = (theme: ThemeColors) => fontSize: variables.fontSizeNormal, }, + textNormalThemeText : { + color: theme.text, + fontSize: variables.fontSizeNormal, + }, + textLarge: { fontSize: variables.fontSizeLarge, }, @@ -1235,6 +1240,13 @@ const styles = (theme: ThemeColors) => color: theme.textSupporting, }, + textLabelSupportingNormal: { + fontFamily: FontUtils.fontFamily.platform.EXP_NEUE, + fontSize: variables.fontSizeLabel, + color: theme.textSupporting, + fontWeight: FontUtils.fontWeight.normal, + }, + textLabelError: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE, fontSize: variables.fontSizeLabel, @@ -4578,6 +4590,11 @@ const styles = (theme: ThemeColors) => updateRequiredViewTextContainer: { width: variables.updateTextViewContainerWidth, }, + + widthAuto: { + width: 'auto', + }, + workspaceTitleStyle: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, fontWeight: '500', diff --git a/src/styles/utils/spacing.ts b/src/styles/utils/spacing.ts index b4a6296507a4..e08c461aae2c 100644 --- a/src/styles/utils/spacing.ts +++ b/src/styles/utils/spacing.ts @@ -179,6 +179,10 @@ export default { marginLeft: 40, }, + ml11: { + marginLeft: 44, + }, + ml18: { marginLeft: 72, }, @@ -477,6 +481,10 @@ export default { paddingLeft: 12, }, + pl4: { + paddingLeft: 16, + }, + pl5: { paddingLeft: 20, }, From 69e823e99f380418802c2394a942b0036431eb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 09:13:32 +0100 Subject: [PATCH 083/102] fix prettier --- .../workflows/ToggleSettingsOptionRow.tsx | 28 ++++++++++++------- .../workflows/WorkspaceWorkflowsPage.tsx | 3 +- src/styles/index.ts | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index eaf67557a016..49e970f45c1f 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -38,16 +38,24 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, }} /> - {title} - {subtitle} + + {title} + + + {subtitle} + diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 52706cb261d3..575a31ae7525 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -110,7 +110,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hasBeenToggled: false, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, ], - [policy, route.params.policyID, styles, translate, policyOwnerDisplayName], + [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle], ); const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( @@ -159,4 +159,3 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; export default withPolicy(WorkspaceWorkflowsPage); - diff --git a/src/styles/index.ts b/src/styles/index.ts index 3b36f6c87169..adb8dec21056 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -400,7 +400,7 @@ const styles = (theme: ThemeColors) => fontSize: variables.fontSizeNormal, }, - textNormalThemeText : { + textNormalThemeText: { color: theme.text, fontSize: variables.fontSizeNormal, }, From b7069fbea3b313cae81c2df9dfb96b3b4d4aa0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 09:20:53 +0100 Subject: [PATCH 084/102] use useMemo --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 575a31ae7525..81d6bca143d5 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -39,8 +39,8 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { } }, [policy]); - const containerStyle = [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4]; - + const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); + const items: ToggleSettingOptionRowProps[] = useMemo( () => [ { From 2980a924e18c80843a107b5d8f160c8fb6e8dd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 09:28:00 +0100 Subject: [PATCH 085/102] fix prettier --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 81d6bca143d5..71dd14c0d18d 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -40,7 +40,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, [policy]); const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); - + const items: ToggleSettingOptionRowProps[] = useMemo( () => [ { From cd548b592d74b6ce80328d8cd2787fb59d69dbf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 15:07:20 +0100 Subject: [PATCH 086/102] add additional style for offline styling use case --- src/components/Switch.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index fd9d9ae315ff..b0dedc01b086 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -1,5 +1,5 @@ import React, {useEffect, useRef} from 'react'; -import {Animated} from 'react-native'; +import {Animated, ViewStyle} from 'react-native'; import useThemeStyles from '@hooks/useThemeStyles'; import useNativeDriver from '@libs/useNativeDriver'; import CONST from '@src/CONST'; @@ -14,6 +14,8 @@ type SwitchProps = { /** Accessibility label for the switch */ accessibilityLabel: string; + + additionalStyle?: ViewStyle; }; const OFFSET_X = { @@ -21,7 +23,7 @@ const OFFSET_X = { ON: 20, }; -function Switch({isOn, onToggle, accessibilityLabel}: SwitchProps) { +function Switch({isOn, onToggle, accessibilityLabel, additionalStyle}: SwitchProps) { const styles = useThemeStyles(); const offsetX = useRef(new Animated.Value(isOn ? OFFSET_X.ON : OFFSET_X.OFF)); @@ -35,7 +37,7 @@ function Switch({isOn, onToggle, accessibilityLabel}: SwitchProps) { return ( onToggle(!isOn)} onLongPress={() => onToggle(!isOn)} role={CONST.ROLE.SWITCH} From b52a759a988a5f0de4434ade3928455e0986a8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 15:08:49 +0100 Subject: [PATCH 087/102] handle offline workflows --- .../workflows/ToggleSettingsOptionRow.tsx | 9 +++++++++ .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 14 +++++++++----- src/styles/index.ts | 4 ++++ src/styles/utils/index.ts | 6 ++++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 49e970f45c1f..1414b86afc06 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -5,6 +5,7 @@ import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; +import useNetwork from '@hooks/useNetwork'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -17,9 +18,16 @@ type ToggleSettingOptionRowProps = { function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled}: ToggleSettingOptionRowProps) { const [isEnabled, setIsEnabled] = useState(hasBeenToggled); + const [shouldShowOfflineStyle, setShouldShowOfflineStyle] = useState(false); const styles = useThemeStyles(); + const {isOffline} = useNetwork(); const ICON_SIZE = 48; const toggleSwitch = () => { + if (isEnabled && isOffline) { + setShouldShowOfflineStyle(true); + } else { + setShouldShowOfflineStyle(false); + } setIsEnabled(!isEnabled); onToggle(!isEnabled); }; @@ -63,6 +71,7 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, accessibilityLabel={subtitle} onToggle={toggleSwitch} isOn={isEnabled} + additionalStyle={shouldShowOfflineStyle ? styles.buttonOpacityDisabled : styles.opacity1} /> diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 71dd14c0d18d..735497a7fc5e 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -19,13 +19,17 @@ import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; +import useNetwork from '@hooks/useNetwork'; +import useStyleUtils from '@hooks/useStyleUtils'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const {isSmallScreenWidth} = useWindowDimensions(); + const {isOffline} = useNetwork(); const [policyOwnerDisplayName, setPolicyOwnerDisplayName] = useState(''); @@ -54,7 +58,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 description={translate('workflowsPage.weeklyFrequency')} @@ -77,7 +81,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 @@ -97,8 +101,8 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon @@ -110,7 +114,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hasBeenToggled: false, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, ], - [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle], + [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle, isOffline], ); const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( diff --git a/src/styles/index.ts b/src/styles/index.ts index adb8dec21056..31f25ff4147e 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -492,6 +492,10 @@ const styles = (theme: ThemeColors) => opacity: 0, }, + opacitySemiTransparent: { + opacity: 0.5, + }, + opacity1: { opacity: 1, }, diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index a0edb7fd4e23..e5eb9aa9347f 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1474,6 +1474,11 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ }, getFullscreenCenteredContentStyles: () => [StyleSheet.absoluteFill, styles.justifyContentCenter, styles.alignItemsCenter], + + getWorkspaceWorkflowsOfflineDescriptionStyle: (descriptionTextStyle: TextStyle|TextStyle[]): StyleProp => ({ + ...StyleSheet.flatten(descriptionTextStyle), + opacity: styles.opacitySemiTransparent.opacity, + }), }); type StyleUtilsType = ReturnType; @@ -1483,3 +1488,4 @@ const DefaultStyleUtils = createStyleUtils(defaultTheme, defaultStyles); export default createStyleUtils; export {DefaultStyleUtils}; export type {StyleUtilsType, AvatarSizeName}; + From 804a68f4350c33f3aa711aefaa9f1f2e58b5788f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 15:11:19 +0100 Subject: [PATCH 088/102] lint and prettier --- src/components/Switch.tsx | 3 ++- .../workspace/workflows/ToggleSettingsOptionRow.tsx | 2 +- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 12 +++++++----- src/styles/utils/index.ts | 3 +-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index b0dedc01b086..7bcd30347c8b 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -1,5 +1,6 @@ import React, {useEffect, useRef} from 'react'; -import {Animated, ViewStyle} from 'react-native'; +import {Animated} from 'react-native'; +import type {ViewStyle} from 'react-native'; import useThemeStyles from '@hooks/useThemeStyles'; import useNativeDriver from '@libs/useNativeDriver'; import CONST from '@src/CONST'; diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 1414b86afc06..8c4068f9bd6d 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -4,8 +4,8 @@ import type {SvgProps} from 'react-native-svg'; import Icon from '@components/Icon'; import Switch from '@components/Switch'; import Text from '@components/Text'; -import useThemeStyles from '@hooks/useThemeStyles'; import useNetwork from '@hooks/useNetwork'; +import useThemeStyles from '@hooks/useThemeStyles'; type ToggleSettingOptionRowProps = { icon: React.FC; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 735497a7fc5e..da204a580ce4 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -6,6 +6,8 @@ import MenuItem from '@components/MenuItem'; import Section from '@components/Section'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; +import useNetwork from '@hooks/useNetwork'; +import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -19,8 +21,6 @@ import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; -import useNetwork from '@hooks/useNetwork'; -import useStyleUtils from '@hooks/useStyleUtils'; type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; @@ -101,8 +101,10 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { }, subMenuItems: ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon @@ -114,7 +116,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hasBeenToggled: false, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, ], - [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle, isOffline], + [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle, isOffline, StyleUtils], ); const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index e5eb9aa9347f..82159c9d6661 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1475,7 +1475,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ getFullscreenCenteredContentStyles: () => [StyleSheet.absoluteFill, styles.justifyContentCenter, styles.alignItemsCenter], - getWorkspaceWorkflowsOfflineDescriptionStyle: (descriptionTextStyle: TextStyle|TextStyle[]): StyleProp => ({ + getWorkspaceWorkflowsOfflineDescriptionStyle: (descriptionTextStyle: TextStyle | TextStyle[]): StyleProp => ({ ...StyleSheet.flatten(descriptionTextStyle), opacity: styles.opacitySemiTransparent.opacity, }), @@ -1488,4 +1488,3 @@ const DefaultStyleUtils = createStyleUtils(defaultTheme, defaultStyles); export default createStyleUtils; export {DefaultStyleUtils}; export type {StyleUtilsType, AvatarSizeName}; - From 4e1a7a8ccd4e4b1f1c5d6c6a740a273924224ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Thu, 22 Feb 2024 17:59:29 +0100 Subject: [PATCH 089/102] remove old code --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index da204a580ce4..db9fbbf0e61e 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -64,7 +64,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { description={translate('workflowsPage.weeklyFrequency')} shouldShowRightIcon wrapperStyle={containerStyle} - // wrapperStyle={workflowsStyles.subMenuContainer} hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), From adb4c63c504fe532b98cde893f3b6bcfacf894fe Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 23 Feb 2024 01:06:00 +0530 Subject: [PATCH 090/102] fixes offline behaviour --- src/libs/actions/Policy.ts | 51 +++++++++- src/pages/workspace/WorkspaceInitialPage.tsx | 2 +- .../workspace/WorkspacePageWithSections.tsx | 6 +- .../workflows/ToggleSettingsOptionRow.tsx | 92 +++++++++---------- .../workflows/WorkspaceWorkflowsPage.tsx | 28 +++--- 5 files changed, 111 insertions(+), 68 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index e847f772f867..3a0584df249f 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -390,12 +390,34 @@ function setWorkspaceAutoReporting(policyID: string, enabled: boolean) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { autoReporting: enabled, + pendingFields: {isAutoApprovalEnabled: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + }, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + autoReporting: !enabled, + pendingFields: {isAutoApprovalEnabled: null}, + }, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: {isAutoApprovalEnabled: null}, }, }, ]; const params: SetWorkspaceAutoReportingParams = {policyID, enabled}; - API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING, params, {optimisticData}); + API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING, params, {optimisticData, failureData, successData}); } function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: 'BASIC' | 'OPTIONAL') { @@ -411,12 +433,35 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value, + value: { + ...value, + pendingFields: {approvalMode: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + }, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: {approvalMode: null}, + }, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: {approvalMode: null}, + }, }, ]; const params: SetWorkspaceApprovalModeParams = {policyID, value: JSON.stringify(value)}; - API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData}); + API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } /** diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index c23096bc1208..af8f709dc03f 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -173,7 +173,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, - ...(isPaidGroupPolicy && shouldShowProtectedItems ? protectedCollectPolicyMenuItems : []), + ...(!isPaidGroupPolicy && shouldShowProtectedItems ? protectedCollectPolicyMenuItems : []), ...(isFreeGroupPolicy && shouldShowProtectedItems ? protectedFreePolicyMenuItems : []), ]; diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index 8a6eff9f2ecf..af515397f2c3 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -68,6 +68,9 @@ type WorkspacePageWithSectionsProps = WithPolicyAndFullscreenLoadingProps & /** Whether to show this page to non admin policy members */ shouldShowNonAdmin?: boolean; + /** Whether to show the not found page */ + shouldShowNotFoundPage?: boolean; + /** Policy values needed in the component */ policy: OnyxEntry; @@ -105,6 +108,7 @@ function WorkspacePageWithSections({ shouldShowLoading = true, shouldShowOfflineIndicatorInWideScreen = false, shouldShowNonAdmin = false, + shouldShowNotFoundPage = false, }: WorkspacePageWithSectionsProps) { const styles = useThemeStyles(); const policyID = route.params?.policyID ?? ''; @@ -136,7 +140,7 @@ function WorkspacePageWithSections({ const shouldShow = useMemo(() => { // If the policy object doesn't exist or contains only error data, we shouldn't display it. - if ((isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors))) && isEmptyObject(policyDraft)) { + if (((isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors))) && isEmptyObject(policyDraft)) || shouldShowNotFoundPage) { return true; } diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 8c4068f9bd6d..252f36d381fe 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,11 +1,12 @@ -import React, {useState} from 'react'; -import {View} from 'react-native'; -import type {SvgProps} from 'react-native-svg'; +import React, { useState } from 'react'; +import { View } from 'react-native'; +import type { SvgProps } from 'react-native-svg'; import Icon from '@components/Icon'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; import Switch from '@components/Switch'; import Text from '@components/Text'; -import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; +import type { PendingAction } from '@src/types/onyx/OnyxCommon'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -14,71 +15,64 @@ type ToggleSettingOptionRowProps = { hasBeenToggled: boolean; onToggle: (isEnabled: boolean) => void; subMenuItems?: React.ReactNode; + pendingAction?: PendingAction; }; +const ICON_SIZE = 48; -function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled}: ToggleSettingOptionRowProps) { +function ToggleSettingOptionRow({ icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled, pendingAction }: ToggleSettingOptionRowProps) { const [isEnabled, setIsEnabled] = useState(hasBeenToggled); - const [shouldShowOfflineStyle, setShouldShowOfflineStyle] = useState(false); const styles = useThemeStyles(); - const {isOffline} = useNetwork(); - const ICON_SIZE = 48; const toggleSwitch = () => { - if (isEnabled && isOffline) { - setShouldShowOfflineStyle(true); - } else { - setShouldShowOfflineStyle(false); - } setIsEnabled(!isEnabled); onToggle(!isEnabled); }; return ( - - - - - - - {title} - - + + + + - {subtitle} - + /> + + + {title} + + + {subtitle} + + - - + {isEnabled && subMenuItems} - {isEnabled && subMenuItems} - + ); } -export type {ToggleSettingOptionRowProps}; +export type { ToggleSettingOptionRowProps }; export default ToggleSettingOptionRow; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index db9fbbf0e61e..00416be9dedb 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useEffect, useMemo, useState} from 'react'; +import React, {useMemo} from 'react'; import {FlatList, View} from 'react-native'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; @@ -11,6 +11,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import withPolicy from '@pages/workspace/withPolicy'; @@ -19,6 +20,7 @@ import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSection import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import type SCREENS from '@src/SCREENS'; +import type {PendingAction} from '@src/types/onyx/OnyxCommon'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; @@ -31,17 +33,8 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {isSmallScreenWidth} = useWindowDimensions(); const {isOffline} = useNetwork(); - const [policyOwnerDisplayName, setPolicyOwnerDisplayName] = useState(''); - - useEffect(() => { - if (!policy?.ownerAccountID) { - return; - } - const ownerPersonalDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([policy.ownerAccountID], CONST.EMPTY_OBJECT), false); - if (ownerPersonalDetails.length > 0 && ownerPersonalDetails[0].displayName) { - setPolicyOwnerDisplayName(ownerPersonalDetails[0].displayName); - } - }, [policy]); + const ownerPersonalDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([policy?.ownerAccountID ?? 0], CONST.EMPTY_OBJECT), false); + const policyOwnerDisplayName = ownerPersonalDetails[0].displayName; const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); @@ -58,7 +51,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY).getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368332 description={translate('workflowsPage.weeklyFrequency')} @@ -68,6 +61,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { /> ), hasBeenToggled: policy?.harvesting?.enabled ?? false, + pendingAction: policy?.pendingFields?.isAutoApprovalEnabled as PendingAction, }, { icon: Illustrations.Approval, @@ -80,7 +74,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 @@ -90,6 +84,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { /> ), hasBeenToggled: policy?.isAutoApprovalEnabled ?? false, + pendingAction: policy?.pendingFields?.approvalMode as PendingAction, }, { icon: Illustrations.WalletAlt, @@ -127,10 +122,14 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { onToggle={item.onToggle} subMenuItems={item.subMenuItems} hasBeenToggled={item.hasBeenToggled} + pendingAction={item.pendingAction} /> ); + const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); + const shouldPageVisible = useMemo(() => isPaidGroupPolicy && !!policy?.ownerAccountID, [isPaidGroupPolicy, policy?.ownerAccountID]); + return ( {() => ( From d476c6326d1eaec4d69e75e43cc689754ed0fc01 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 23 Feb 2024 01:24:02 +0530 Subject: [PATCH 091/102] fixes lint and type issues --- .../workspace/WorkspacePageWithSections.tsx | 4 +- .../workflows/ToggleSettingsOptionRow.tsx | 12 +++--- .../workflows/WorkspaceWorkflowsPage.tsx | 37 +++++++++---------- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index af515397f2c3..dced3bb8768b 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -42,7 +42,7 @@ type WorkspacePageWithSectionsProps = WithPolicyAndFullscreenLoadingProps & headerText: string; /** Main content of the page */ - children: (hasVBA: boolean, policyID: string, isUsingECard: boolean) => ReactNode; + children: ((hasVBA: boolean, policyID: string, isUsingECard: boolean) => ReactNode) | ReactNode; /** Content to be added as fixed footer */ footer?: ReactNode; @@ -118,7 +118,7 @@ function WorkspacePageWithSections({ const achState = reimbursementAccount?.achData?.state ?? ''; const isUsingECard = user?.isUsingExpensifyCard ?? false; const hasVBA = achState === BankAccount.STATE.OPEN; - const content = children(hasVBA, policyID, isUsingECard); + const content = typeof children === 'function' ? children(hasVBA, policyID, isUsingECard) : children; const {isSmallScreenWidth} = useWindowDimensions(); const firstRender = useRef(true); diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 252f36d381fe..9ed3f2ec688c 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -1,12 +1,12 @@ -import React, { useState } from 'react'; -import { View } from 'react-native'; -import type { SvgProps } from 'react-native-svg'; +import React, {useState} from 'react'; +import {View} from 'react-native'; +import type {SvgProps} from 'react-native-svg'; import Icon from '@components/Icon'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; -import type { PendingAction } from '@src/types/onyx/OnyxCommon'; +import type {PendingAction} from '@src/types/onyx/OnyxCommon'; type ToggleSettingOptionRowProps = { icon: React.FC; @@ -19,7 +19,7 @@ type ToggleSettingOptionRowProps = { }; const ICON_SIZE = 48; -function ToggleSettingOptionRow({ icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled, pendingAction }: ToggleSettingOptionRowProps) { +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled, pendingAction}: ToggleSettingOptionRowProps) { const [isEnabled, setIsEnabled] = useState(hasBeenToggled); const styles = useThemeStyles(); const toggleSwitch = () => { @@ -74,5 +74,5 @@ function ToggleSettingOptionRow({ icon, title, subtitle, onToggle, subMenuItems, ); } -export type { ToggleSettingOptionRowProps }; +export type {ToggleSettingOptionRowProps}; export default ToggleSettingOptionRow; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 00416be9dedb..585eb2a94110 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -128,7 +128,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { ); const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); - const shouldPageVisible = useMemo(() => isPaidGroupPolicy && !!policy?.ownerAccountID, [isPaidGroupPolicy, policy?.ownerAccountID]); return ( - {() => ( - -
- - {translate('workflowsPage.workflowDescription')} - item.title} - /> - -
-
- )} + +
+ + {translate('workflowsPage.workflowDescription')} + item.title} + /> + +
+
); } From 03481e38ed2570f3271e06b90350e25353658b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 08:56:19 +0100 Subject: [PATCH 092/102] put back the paid group policy check --- src/pages/workspace/WorkspaceInitialPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index af8f709dc03f..c23096bc1208 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -173,7 +173,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, - ...(!isPaidGroupPolicy && shouldShowProtectedItems ? protectedCollectPolicyMenuItems : []), + ...(isPaidGroupPolicy && shouldShowProtectedItems ? protectedCollectPolicyMenuItems : []), ...(isFreeGroupPolicy && shouldShowProtectedItems ? protectedFreePolicyMenuItems : []), ]; From 884d00ea1fb6bbf2ee2b1e2b1d83087d02eff30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 16:20:01 +0100 Subject: [PATCH 093/102] rename hasBeenToggled to clearer name --- .../workspace/workflows/ToggleSettingsOptionRow.tsx | 6 +++--- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 9ed3f2ec688c..5e116f68c99b 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -12,15 +12,15 @@ type ToggleSettingOptionRowProps = { icon: React.FC; title: string; subtitle: string; - hasBeenToggled: boolean; + isActive: boolean; onToggle: (isEnabled: boolean) => void; subMenuItems?: React.ReactNode; pendingAction?: PendingAction; }; const ICON_SIZE = 48; -function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, hasBeenToggled, pendingAction}: ToggleSettingOptionRowProps) { - const [isEnabled, setIsEnabled] = useState(hasBeenToggled); +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isActive, pendingAction}: ToggleSettingOptionRowProps) { + const [isEnabled, setIsEnabled] = useState(isActive); const styles = useThemeStyles(); const toggleSwitch = () => { setIsEnabled(!isEnabled); diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 585eb2a94110..7a2d34947f26 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -34,8 +34,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const {isOffline} = useNetwork(); const ownerPersonalDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([policy?.ownerAccountID ?? 0], CONST.EMPTY_OBJECT), false); - const policyOwnerDisplayName = ownerPersonalDetails[0].displayName; - + const policyOwnerDisplayName = ownerPersonalDetails[0]?.displayName; const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); const items: ToggleSettingOptionRowProps[] = useMemo( @@ -60,7 +59,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), - hasBeenToggled: policy?.harvesting?.enabled ?? false, + isActive: policy?.harvesting?.enabled ?? false, pendingAction: policy?.pendingFields?.isAutoApprovalEnabled as PendingAction, }, { @@ -83,7 +82,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { hoverAndPressStyle={[styles.mr0, styles.br2]} /> ), - hasBeenToggled: policy?.isAutoApprovalEnabled ?? false, + isActive: policy?.isAutoApprovalEnabled ?? false, pendingAction: policy?.pendingFields?.approvalMode as PendingAction, }, { @@ -107,7 +106,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { /> ), isEndOptionRow: true, - hasBeenToggled: false, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 + isActive: false, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, ], [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle, isOffline, StyleUtils], @@ -121,7 +120,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { subtitle={item.subtitle} onToggle={item.onToggle} subMenuItems={item.subMenuItems} - hasBeenToggled={item.hasBeenToggled} + isActive={item.isActive} pendingAction={item.pendingAction} />
From e612ec39fa388854072e5fc93c0778bf99d45333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 16:20:20 +0100 Subject: [PATCH 094/102] use consts for workspace approval mode --- src/libs/actions/Policy.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 3a0584df249f..7bdb762363e0 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -6,6 +6,7 @@ import lodashClone from 'lodash/clone'; import lodashUnion from 'lodash/union'; import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; import * as API from '@libs/API'; import type { AddMembersToWorkspaceParams, @@ -420,8 +421,8 @@ function setWorkspaceAutoReporting(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING, params, {optimisticData, failureData, successData}); } -function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: 'BASIC' | 'OPTIONAL') { - const isAutoApprovalEnabled = approvalMode === 'BASIC'; +function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMode: ValueOf) { + const isAutoApprovalEnabled = approvalMode === CONST.POLICY.APPROVAL_MODE.BASIC; const value = { approver, From ba73d0d0bfa430a2c5220d1dee94a3fb02640164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 17:41:23 +0100 Subject: [PATCH 095/102] remove unneeded prop --- src/components/Switch.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index 7bcd30347c8b..8f9d967bdfbf 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -15,8 +15,6 @@ type SwitchProps = { /** Accessibility label for the switch */ accessibilityLabel: string; - - additionalStyle?: ViewStyle; }; const OFFSET_X = { @@ -24,7 +22,7 @@ const OFFSET_X = { ON: 20, }; -function Switch({isOn, onToggle, accessibilityLabel, additionalStyle}: SwitchProps) { +function Switch({isOn, onToggle, accessibilityLabel}: SwitchProps) { const styles = useThemeStyles(); const offsetX = useRef(new Animated.Value(isOn ? OFFSET_X.ON : OFFSET_X.OFF)); @@ -38,7 +36,7 @@ function Switch({isOn, onToggle, accessibilityLabel, additionalStyle}: SwitchPro return ( onToggle(!isOn)} onLongPress={() => onToggle(!isOn)} role={CONST.ROLE.SWITCH} From fae8db32901c337f738abcd7979c48eadac82600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 17:43:57 +0100 Subject: [PATCH 096/102] remove useless type --- src/components/Switch.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index 8f9d967bdfbf..fd9d9ae315ff 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -1,6 +1,5 @@ import React, {useEffect, useRef} from 'react'; import {Animated} from 'react-native'; -import type {ViewStyle} from 'react-native'; import useThemeStyles from '@hooks/useThemeStyles'; import useNativeDriver from '@libs/useNativeDriver'; import CONST from '@src/CONST'; From 6f83c0b9a510b58c55a8452ce58bdd4748a54b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 17:53:13 +0100 Subject: [PATCH 097/102] use const --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 7a2d34947f26..4f30d14add37 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -67,7 +67,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { title: translate('workflowsPage.addApprovalsTitle'), subtitle: translate('workflowsPage.addApprovalsDescription'), onToggle: (isEnabled: boolean) => { - Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? 'BASIC' : 'OPTIONAL'); + Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? CONST.POLICY.APPROVAL_MODE.BASIC : CONST.POLICY.APPROVAL_MODE.BASIC); }, subMenuItems: ( Date: Fri, 23 Feb 2024 17:54:39 +0100 Subject: [PATCH 098/102] fix typo --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 4f30d14add37..1f7d4e1c5f75 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -67,7 +67,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { title: translate('workflowsPage.addApprovalsTitle'), subtitle: translate('workflowsPage.addApprovalsDescription'), onToggle: (isEnabled: boolean) => { - Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? CONST.POLICY.APPROVAL_MODE.BASIC : CONST.POLICY.APPROVAL_MODE.BASIC); + Policy.setWorkspaceApprovalMode(route.params.policyID, policy?.owner ?? '', isEnabled ? CONST.POLICY.APPROVAL_MODE.BASIC : CONST.POLICY.APPROVAL_MODE.OPTIONAL); }, subMenuItems: ( Date: Fri, 23 Feb 2024 17:59:45 +0100 Subject: [PATCH 099/102] add jsdoc --- src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 5e116f68c99b..62f32992601a 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -9,12 +9,19 @@ import useThemeStyles from '@hooks/useThemeStyles'; import type {PendingAction} from '@src/types/onyx/OnyxCommon'; type ToggleSettingOptionRowProps = { + /** Icon to be shown for the option */ icon: React.FC; + /** Title of the option */ title: string; + /** Subtitle of the option */ subtitle: string; + /** Whether the option is enabled or not */ isActive: boolean; + /** Callback to be called when the switch is toggled */ onToggle: (isEnabled: boolean) => void; + /** SubMenuItems will be shown when the option is enabled */ subMenuItems?: React.ReactNode; + /** If there is a pending action, we will grey out the option */ pendingAction?: PendingAction; }; const ICON_SIZE = 48; From fc0aa465b1208de79b4d2726681ff5c807de9bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 18:12:11 +0100 Subject: [PATCH 100/102] add todo comment --- src/styles/utils/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index 8fc8a83f357d..21af5398232f 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1486,6 +1486,7 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ ...(isDisabled && styles.buttonOpacityDisabled), }), + // TODO: remove it when we'll implement the callback to handle this toggle in Expensify/Expensify#368335 getWorkspaceWorkflowsOfflineDescriptionStyle: (descriptionTextStyle: TextStyle | TextStyle[]): StyleProp => ({ ...StyleSheet.flatten(descriptionTextStyle), opacity: styles.opacitySemiTransparent.opacity, From 6b5810519d1c63ed9814dc3d297a8be83fac7ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucien=20Akchot=C3=A9?= Date: Fri, 23 Feb 2024 18:39:28 +0100 Subject: [PATCH 101/102] add policy admin check for not found page --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 1f7d4e1c5f75..9160d5a6ad3a 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -127,7 +127,8 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { ); const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); - + const isPolicyAdmin = PolicyUtils.isPolicyAdmin(policy); + return (
Date: Fri, 23 Feb 2024 18:44:56 +0100 Subject: [PATCH 102/102] fix prettier --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 9160d5a6ad3a..d1cb3e066d99 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -128,7 +128,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); const isPolicyAdmin = PolicyUtils.isPolicyAdmin(policy); - + return (