Skip to content
32 changes: 22 additions & 10 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -619,21 +619,33 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/workflows',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/workflows` as const,
},
WORKSPACE_WORKFLOWS_PAYER: {
route: 'workspace/:policyID/settings/workflows/payer',
getRoute: (policyId: string) => `workspace/${policyId}/settings/workflows/payer` as const,
WORKSPACE_WORKFLOWS_APPROVALS_NEW: {
route: 'settings/workspaces/:policyID/workflows/approvals/new',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/workflows/approvals/new` as const,
},
WORKSPACE_WORKFLOWS_APPROVALS_EDIT: {
route: 'settings/workspaces/:policyID/workflows/approvals/:firstApproverEmail/edit',
getRoute: (policyID: string, firstApproverEmail: string) => `settings/workspaces/${policyID}/workflows/approvals/${encodeURIComponent(firstApproverEmail)}/edit` as const,
},
WORKSPACE_WORKFLOWS_APPROVALS_EXPENSES_FROM: {
route: 'settings/workspaces/:policyID/workflows/approvals/expenses-from',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/workflows/approvals/expenses-from` as const,
},
WORKSPACE_WORKFLOWS_APPROVER: {
route: 'settings/workspaces/:policyID/settings/workflows/approver',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/settings/workflows/approver` as const,
WORKSPACE_WORKFLOWS_APPROVALS_APPROVER: {
route: 'settings/workspaces/:policyID/workflows/approvals/approver',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/workflows/approvals/approver` as const,
},
WORKSPACE_WORKFLOWS_PAYER: {
route: 'settings/workspaces/:policyID/workflows/payer',
getRoute: (policyId: string) => `settings/workspaces/${policyId}/workflows/payer` as const,
},
WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY: {
route: 'settings/workspaces/:policyID/settings/workflows/auto-reporting-frequency',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/settings/workflows/auto-reporting-frequency` as const,
route: 'settings/workspaces/:policyID/workflows/auto-reporting-frequency',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/workflows/auto-reporting-frequency` as const,
},
WORKSPACE_WORKFLOWS_AUTOREPORTING_MONTHLY_OFFSET: {
route: 'settings/workspaces/:policyID/settings/workflows/auto-reporting-frequency/monthly-offset',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/settings/workflows/auto-reporting-frequency/monthly-offset` as const,
route: 'settings/workspaces/:policyID/workflows/auto-reporting-frequency/monthly-offset',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/workflows/auto-reporting-frequency/monthly-offset` as const,
},
WORKSPACE_CARD: {
route: 'settings/workspaces/:policyID/card',
Expand Down
5 changes: 4 additions & 1 deletion src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,10 @@ const SCREENS = {
ADDRESS: 'Workspace_Profile_Address',
WORKFLOWS: 'Workspace_Workflows',
WORKFLOWS_PAYER: 'Workspace_Workflows_Payer',
WORKFLOWS_APPROVER: 'Workspace_Workflows_Approver',
WORKFLOWS_APPROVALS_NEW: 'Workspace_Approvals_New',
WORKFLOWS_APPROVALS_EDIT: 'Workspace_Approvals_Edit',
WORKFLOWS_APPROVALS_EXPENSES_FROM: 'Workspace_Workflows_Approvals_Expenses_From',
WORKFLOWS_APPROVALS_APPROVER: 'Workspace_Workflows_Approvals_Approver',
WORKFLOWS_AUTO_REPORTING_FREQUENCY: 'Workspace_Workflows_Auto_Reporting_Frequency',
WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET: 'Workspace_Workflows_Auto_Reporting_Monthly_Offset',
DESCRIPTION: 'Workspace_Profile_Description',
Expand Down
9 changes: 5 additions & 4 deletions src/components/FocusTrap/WIDE_LAYOUT_INACTIVE_SCREENS.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';

// Screens that should not have active focus trap when rendered on wide screen in order to allow Tab navigation in LHP and RHP
/**
* Screens displayed in the BottomTab and CentralPane displayed side by side that should not have active
* focus trap when rendered on a wide screen to allow navigation between them using the keyboard
*/
const WIDE_LAYOUT_INACTIVE_SCREENS: string[] = [
Comment thread
blazejkustra marked this conversation as resolved.
NAVIGATORS.BOTTOM_TAB_NAVIGATOR,
SCREENS.HOME,
Expand All @@ -14,13 +17,11 @@ const WIDE_LAYOUT_INACTIVE_SCREENS: string[] = [
SCREENS.SETTINGS.ABOUT,
SCREENS.SETTINGS.WORKSPACES,
SCREENS.SETTINGS.SUBSCRIPTION.ROOT,
SCREENS.WORKSPACE.ACCOUNTING.ROOT,
SCREENS.WORKSPACE.INITIAL,
SCREENS.WORKSPACE.PROFILE,
SCREENS.WORKSPACE.CARD,
SCREENS.WORKSPACE.WORKFLOWS,
SCREENS.WORKSPACE.WORKFLOWS_APPROVER,
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY,
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET,
SCREENS.WORKSPACE.REIMBURSE,
SCREENS.WORKSPACE.BILLS,
SCREENS.WORKSPACE.INVOICES,
Expand Down
9 changes: 9 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,15 @@ export default {
autoReportingFrequencyErrorMessage: "Submission frequency couldn't be changed. Please try again or contact support.",
monthlyOffsetErrorMessage: "Monthly frequency couldn't be changed. Please try again or contact support.",
},
workflowsCreateApprovalsPage: {
title: 'Add approval workflow',
},
workflowsEditApprovalsPage: {
title: 'Edit approval workflow',
},
workflowsExpensesFromPage: {
title: 'Expenses from',
},
workflowsApprovalPage: {
genericErrorMessage: "The approver couldn't be changed. Please try again or contact support.",
},
Expand Down
9 changes: 9 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,15 @@ export default {
autoReportingFrequencyErrorMessage: 'La frecuencia de envío no pudo ser cambiada. Por favor, inténtelo de nuevo o contacte al soporte.',
monthlyOffsetErrorMessage: 'La frecuencia mensual no pudo ser cambiada. Por favor, inténtelo de nuevo o contacte al soporte.',
},
workflowsCreateApprovalsPage: {
title: 'Añadir flujo de aprobación',
},
workflowsEditApprovalsPage: {
title: 'Edicion flujo de aprobación',
},
workflowsExpensesFromPage: {
title: 'Gastos de',
},
workflowsApprovalPage: {
genericErrorMessage: 'El aprobador no pudo ser cambiado. Por favor, inténtelo de nuevo o contacte al soporte.',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,11 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.RATE_AND_UNIT_RATE]: () => require<ReactComponentModule>('../../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage').default,
[SCREENS.WORKSPACE.RATE_AND_UNIT_UNIT]: () => require<ReactComponentModule>('../../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage/UnitPage').default,
[SCREENS.WORKSPACE.INVITE]: () => require<ReactComponentModule>('../../../../pages/workspace/WorkspaceInvitePage').default,
[SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: () => require<ReactComponentModule>('../../../../pages/workspace/workflows/WorkspaceWorkflowsApproverPage').default,
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_NEW]: () => require<ReactComponentModule>('../../../../pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsCreatePage').default,
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EDIT]: () => require<ReactComponentModule>('../../../../pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsEditPage').default,
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EXPENSES_FROM]: () =>
require<ReactComponentModule>('../../../../pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsExpensesFromPage').default,
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_APPROVER]: () => require<ReactComponentModule>('../../../../pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsApproverPage').default,
[SCREENS.WORKSPACE.INVITE_MESSAGE]: () => require<ReactComponentModule>('../../../../pages/workspace/WorkspaceInviteMessagePage').default,
[SCREENS.WORKSPACE.WORKFLOWS_PAYER]: () => require<ReactComponentModule>('../../../../pages/workspace/workflows/WorkspaceWorkflowsPayerPage').default,
[SCREENS.WORKSPACE.NAME]: () => require<ReactComponentModule>('../../../../pages/workspace/WorkspaceNamePage').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.OWNER_CHANGE_ERROR,
],
[SCREENS.WORKSPACE.WORKFLOWS]: [
SCREENS.WORKSPACE.WORKFLOWS_APPROVER,
SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_NEW,
SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EDIT,
SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EXPENSES_FROM,
SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_APPROVER,
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY,
SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET,
SCREENS.WORKSPACE.WORKFLOWS_PAYER,
Expand Down
13 changes: 11 additions & 2 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,17 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.INVITE]: {
path: ROUTES.WORKSPACE_INVITE.route,
},
[SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: {
path: ROUTES.WORKSPACE_WORKFLOWS_APPROVER.route,
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_NEW]: {
path: ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_NEW.route,
},
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EDIT]: {
path: ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_EDIT.route,
},
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EXPENSES_FROM]: {
path: ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_EXPENSES_FROM.route,
},
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_APPROVER]: {
path: ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_APPROVER.route,
},
[SCREENS.WORKSPACE.INVITE_MESSAGE]: {
path: ROUTES.WORKSPACE_INVITE_MESSAGE.route,
Expand Down
12 changes: 11 additions & 1 deletion src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,17 @@ type FullScreenNavigatorParamList = {
[SCREENS.WORKSPACE.WORKFLOWS]: {
policyID: string;
};
[SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: {
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_NEW]: {
policyID: string;
};
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EDIT]: {
policyID: string;
firstApproverEmail: string;
};
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EXPENSES_FROM]: {
policyID: string;
};
[SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_APPROVER]: {
policyID: string;
};
[SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: {
Expand Down
5 changes: 4 additions & 1 deletion src/pages/workspace/withPolicy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ type PolicyRoute = RouteProp<
| typeof SCREENS.WORKSPACE.INVITE_MESSAGE
| typeof SCREENS.WORKSPACE.WORKFLOWS_PAYER
| typeof SCREENS.WORKSPACE.WORKFLOWS
| typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVER
| typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_NEW
| typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EDIT
| typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_EXPENSES_FROM
| typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_APPROVER
| typeof SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET
| typeof SCREENS.WORKSPACE.TRAVEL
| typeof SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function WorkspaceWorkflowsPage({policy, betas, route}: WorkspaceWorkflowsPagePr
titleStyle={styles.textLabelSupportingNormal}
descriptionTextStyle={styles.textNormalThemeText}
description={policyApproverName ?? ''}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_APPROVER.getRoute(route.params.policyID))}
shouldShowRightIcon
wrapperStyle={containerStyle}
hoverAndPressStyle={[styles.mr0, styles.br2]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ import type SCREENS from '@src/SCREENS';
import type {PersonalDetailsList, PolicyEmployee} from '@src/types/onyx';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

type WorkspaceWorkflowsApproverPageOnyxProps = {
type WorkspaceWorkflowsApprovalsApproverPageOnyxProps = {
/** All of the personal details for everyone */
personalDetails: OnyxEntry<PersonalDetailsList>;
};

type WorkspaceWorkflowsApproverPageProps = WorkspaceWorkflowsApproverPageOnyxProps &
type WorkspaceWorkflowsApprovalsApproverPageProps = WorkspaceWorkflowsApprovalsApproverPageOnyxProps &
WithPolicyAndFullscreenLoadingProps &
StackScreenProps<FullScreenNavigatorParamList, typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVER>;
StackScreenProps<FullScreenNavigatorParamList, typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_APPROVER>;
type MemberOption = Omit<ListItem, 'accountID'> & {accountID: number};
type MembersSection = SectionListData<MemberOption, Section<MemberOption>>;

function WorkspaceWorkflowsApproverPage({policy, personalDetails, isLoadingReportData = true, route}: WorkspaceWorkflowsApproverPageProps) {
function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoadingReportData = true, route}: WorkspaceWorkflowsApprovalsApproverPageProps) {
const {translate} = useLocalize();
const policyName = policy?.name ?? '';
const [searchTerm, setSearchTerm] = useState('');
Expand Down Expand Up @@ -154,17 +154,20 @@ function WorkspaceWorkflowsApproverPage({policy, personalDetails, isLoadingRepor
Navigation.goBack();
};

// eslint-disable-next-line rulesdir/no-negated-variables
const shouldShowNotFoundView = (isEmptyObject(policy) && !isLoadingReportData) || !PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPendingDeletePolicy(policy);

return (
<AccessOrNotFoundWrapper
policyID={route.params.policyID}
Comment thread
blazejkustra marked this conversation as resolved.
featureName={CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED}
>
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID={WorkspaceWorkflowsApproverPage.displayName}
testID={WorkspaceWorkflowsApprovalsApproverPage.displayName}
>
<FullPageNotFoundView
shouldShow={(isEmptyObject(policy) && !isLoadingReportData) || !PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPendingDeletePolicy(policy)}
shouldShow={shouldShowNotFoundView}
subtitleKey={isEmptyObject(policy) ? undefined : 'workspace.common.notAuthorized'}
onBackButtonPress={PolicyUtils.goBackFromInvalidPolicy}
onLinkPress={PolicyUtils.goBackFromInvalidPolicy}
Expand All @@ -191,6 +194,6 @@ function WorkspaceWorkflowsApproverPage({policy, personalDetails, isLoadingRepor
);
}

WorkspaceWorkflowsApproverPage.displayName = 'WorkspaceWorkflowsApproverPage';
WorkspaceWorkflowsApprovalsApproverPage.displayName = 'WorkspaceWorkflowsApprovalsApproverPage';

export default withPolicyAndFullscreenLoading(WorkspaceWorkflowsApproverPage);
export default withPolicyAndFullscreenLoading(WorkspaceWorkflowsApprovalsApproverPage);
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import useLocalize from '@hooks/useLocalize';
import Navigation from '@libs/Navigation/Navigation';
import type {FullScreenNavigatorParamList} from '@libs/Navigation/types';
import * as PolicyUtils from '@libs/PolicyUtils';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading';
import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
import CONST from '@src/CONST';
import type SCREENS from '@src/SCREENS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';

type WorkspaceWorkflowsApprovalsCreatePageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps<FullScreenNavigatorParamList, typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_NEW>;

function WorkspaceWorkflowsApprovalsCreatePage({policy, isLoadingReportData = true, route}: WorkspaceWorkflowsApprovalsCreatePageProps) {
const {translate} = useLocalize();

// eslint-disable-next-line rulesdir/no-negated-variables
const shouldShowNotFoundView = (isEmptyObject(policy) && !isLoadingReportData) || !PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPendingDeletePolicy(policy);

return (
<AccessOrNotFoundWrapper
policyID={route.params.policyID}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
policyID={route.params.policyID}
policyID={route?.params?.policyID ?? '-1'}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you suggest that @DylanDylann? route.params.policyID is a string, so I don't think we need optional chaining here. I just added a small fix, maybe this was causing your IDE to show an error?

featureName={CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED}
>
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID={WorkspaceWorkflowsApprovalsCreatePage.displayName}
>
<FullPageNotFoundView
shouldShow={shouldShowNotFoundView}
subtitleKey={isEmptyObject(policy) ? undefined : 'workspace.common.notAuthorized'}
onBackButtonPress={PolicyUtils.goBackFromInvalidPolicy}
onLinkPress={PolicyUtils.goBackFromInvalidPolicy}
>
<HeaderWithBackButton
title={translate('workflowsCreateApprovalsPage.title')}
onBackButtonPress={Navigation.goBack}
/>
</FullPageNotFoundView>
</ScreenWrapper>
</AccessOrNotFoundWrapper>
);
}

WorkspaceWorkflowsApprovalsCreatePage.displayName = 'WorkspaceWorkflowsApprovalsCreatePage';

export default withPolicyAndFullscreenLoading(WorkspaceWorkflowsApprovalsCreatePage);
Loading