Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Provide education/confirmation before creating workspaces in New Workspace flows #52164

Merged
merged 29 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
02d6985
fix: Provide education/confirmation before creating workspaces in New…
Krishna2323 Oct 30, 2024
96a77e8
minor updates.
Krishna2323 Oct 30, 2024
4945d1d
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Nov 7, 2024
f283a18
updated ONYXKEYS file.
Krishna2323 Nov 7, 2024
d442d2f
minor updates.
Krishna2323 Nov 7, 2024
ecb779c
Merge branch 'main' into krishna2323/issue/51504
Krishna2323 Nov 12, 2024
d0f4880
fix lint issues.
Krishna2323 Nov 12, 2024
cf5608e
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Nov 23, 2024
53d7650
add file and currency parameter.
Krishna2323 Nov 25, 2024
57cdb7e
minor update.
Krishna2323 Nov 25, 2024
dda2aed
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Nov 25, 2024
b471f61
Merge branch 'main' into krishna2323/issue/51504
Krishna2323 Nov 26, 2024
7677be8
minor update.
Krishna2323 Nov 26, 2024
0249a28
fix: ESLint check.
Krishna2323 Nov 26, 2024
5c0405e
fix native crash.
Krishna2323 Nov 27, 2024
e426f86
update mask image for avatar picker.
Krishna2323 Nov 27, 2024
77d31cd
fix avatar flickering issue.
Krishna2323 Nov 27, 2024
5774b63
Merge branch 'main' into krishna2323/issue/51504
Krishna2323 Nov 28, 2024
4e9198e
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Nov 29, 2024
a2b2bfc
minor update.
Krishna2323 Nov 30, 2024
7401996
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Nov 30, 2024
77eed20
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Dec 2, 2024
5367713
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Dec 4, 2024
0f88dec
make WorkspaceConfirmationPage scrollable.
Krishna2323 Dec 4, 2024
a228f9c
place the submit button to bottom.
Krishna2323 Dec 4, 2024
dd904a7
fix text not visible on android.
Krishna2323 Dec 4, 2024
b86f8cc
Merge branch 'Expensify:main' into krishna2323/issue/51504
Krishna2323 Dec 5, 2024
0107362
fix padding-top issue on confirm button.
Krishna2323 Dec 5, 2024
4a7359d
Merge branch 'main' into krishna2323/issue/51504
Krishna2323 Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,8 @@ const ONYXKEYS = {
ADD_PAYMENT_CARD_FORM_DRAFT: 'addPaymentCardFormDraft',
WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
WORKSPACE_CATEGORY_FORM: 'workspaceCategoryForm',
WORKSPACE_CONFIRMATION_FORM: 'workspaceConfirmationForm',
WORKSPACE_CONFIRMATION_FORM_DRAFT: 'workspaceConfirmationFormDraft',
WORKSPACE_CATEGORY_FORM_DRAFT: 'workspaceCategoryFormDraft',
WORKSPACE_CATEGORY_DESCRIPTION_HINT_FORM: 'workspaceCategoryDescriptionHintForm',
WORKSPACE_CATEGORY_DESCRIPTION_HINT_FORM_DRAFT: 'workspaceCategoryDescriptionHintFormDraft',
Expand Down Expand Up @@ -733,6 +735,7 @@ type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.ADD_PAYMENT_CARD_FORM]: FormTypes.AddPaymentCardForm;
[ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: FormTypes.WorkspaceSettingsForm;
[ONYXKEYS.FORMS.WORKSPACE_CATEGORY_FORM]: FormTypes.WorkspaceCategoryForm;
[ONYXKEYS.FORMS.WORKSPACE_CONFIRMATION_FORM]: FormTypes.WorkspaceConfirmationForm;
[ONYXKEYS.FORMS.WORKSPACE_TAG_FORM]: FormTypes.WorkspaceTagForm;
[ONYXKEYS.FORMS.WORKSPACE_TAX_CUSTOM_NAME]: FormTypes.WorkspaceTaxCustomName;
[ONYXKEYS.FORMS.WORKSPACE_COMPANY_CARD_FEED_NAME]: FormTypes.WorkspaceCompanyCardFeedName;
Expand Down
2 changes: 1 addition & 1 deletion src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1387,8 +1387,8 @@ const ROUTES = {
},
WELCOME_VIDEO_ROOT: 'onboarding/welcome-video',
EXPLANATION_MODAL_ROOT: 'onboarding/explanation',
WORKSPACE_CONFIRMATION: 'workspace/confirmation',
MIGRATED_USER_WELCOME_MODAL: 'onboarding/migrated-user-welcome',

TRANSACTION_RECEIPT: {
route: 'r/:reportID/transaction/:transactionID/receipt',
getRoute: (reportID: string, transactionID: string, readonly = false, isFromReviewDuplicates = false) =>
Expand Down
3 changes: 3 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ const SCREENS = {
DETAILS: 'Details',
PROFILE: 'Profile',
REPORT_DETAILS: 'Report_Details',
WORKSPACE_CONFIRMATION: 'Workspace_Confirmation',
REPORT_SETTINGS: 'Report_Settings',
REPORT_DESCRIPTION: 'Report_Description',
PARTICIPANTS: 'Participants',
Expand Down Expand Up @@ -317,6 +318,8 @@ const SCREENS = {
EXPORT: 'Report_Details_Export',
},

WORKSPACE_CONFIRMATION: {ROOT: 'Workspace_Confirmation_Root'},

WORKSPACE: {
ACCOUNTING: {
ROOT: 'Policy_Accounting',
Expand Down
87 changes: 87 additions & 0 deletions src/components/CurrencyPicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, {forwardRef, useState} from 'react';
import type {ForwardedRef} from 'react';
import {View} from 'react-native';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import CurrencySelectionListWithOnyx from './CurrencySelectionList';
import HeaderWithBackButton from './HeaderWithBackButton';
import MenuItemWithTopDescription from './MenuItemWithTopDescription';
import Modal from './Modal';
import ScreenWrapper from './ScreenWrapper';
import type {ValuePickerItem, ValuePickerProps} from './ValuePicker/types';

type CurrencyPickerProps = {
selectedCurrency?: string;
};
function CurrencyPicker({selectedCurrency, label, errorText = '', value, onInputChange, furtherDetails}: ValuePickerProps & CurrencyPickerProps, forwardedRef: ForwardedRef<View>) {
const StyleUtils = useStyleUtils();
const styles = useThemeStyles();
const [isPickerVisible, setIsPickerVisible] = useState(false);

const showPickerModal = () => {
setIsPickerVisible(true);
};

const hidePickerModal = () => {
setIsPickerVisible(false);
};

const updateInput = (item: ValuePickerItem) => {
if (item.value !== selectedCurrency) {
onInputChange?.(item.value);
}
hidePickerModal();
};

const descStyle = !selectedCurrency || selectedCurrency.length === 0 ? StyleUtils.getFontSizeStyle(variables.fontSizeLabel) : null;

return (
<View>
<MenuItemWithTopDescription
ref={forwardedRef}
shouldShowRightIcon
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
title={value || ''}
descriptionTextStyle={descStyle}
description={label}
onPress={showPickerModal}
furtherDetails={furtherDetails}
brickRoadIndicator={errorText ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
errorText={errorText}
/>

<Modal
type={CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED}
isVisible={isPickerVisible}
onClose={() => hidePickerModal}
onModalHide={hidePickerModal}
hideModalContentWhileAnimating
useNativeDriver
onBackdropPress={hidePickerModal}
>
<ScreenWrapper
style={styles.pb0}
includePaddingTop={false}
includeSafeAreaPaddingBottom={false}
testID={label ?? 'TEST'}
>
<HeaderWithBackButton
title={label}
onBackButtonPress={hidePickerModal}
/>
<CurrencySelectionListWithOnyx
onSelect={(item) => updateInput({value: item.currencyCode})}
searchInputLabel="Currency"
initiallySelectedCurrencyCode={selectedCurrency}
/>
</ScreenWrapper>
</Modal>
</View>
);
}

CurrencyPicker.displayName = 'CurrencyPicker';

export default forwardRef(CurrencyPicker);
3 changes: 2 additions & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3716,7 +3716,7 @@ const translations = {
},
emptyWorkspace: {
title: 'Create a workspace',
subtitle: 'Create a workspace to track receipts, reimburse expenses, send invoices, and more -- all at the speed of chat.',
subtitle: 'Create a workspace to track receipts, reimburse expenses, send invoices, and more all at the speed of chat.',
createAWorkspaceCTA: 'Get Started',
features: {
trackAndCollect: 'Track and collect receipts',
Expand All @@ -3734,6 +3734,7 @@ const translations = {
new: {
newWorkspace: 'New workspace',
getTheExpensifyCardAndMore: 'Get the Expensify Card and more',
confirmWorkspace: 'Confirm Workspace',
},
people: {
genericFailureMessage: 'An error occurred removing a member from the workspace, please try again.',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3779,6 +3779,7 @@ const translations = {
new: {
newWorkspace: 'Nuevo espacio de trabajo',
getTheExpensifyCardAndMore: 'Consigue la Tarjeta Expensify y más',
confirmWorkspace: 'Confirmar espacio de trabajo',
},
people: {
genericFailureMessage: 'Se ha producido un error al intentar eliminar a un miembro del espacio de trabajo. Por favor, inténtalo más tarde.',
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/parameters/CreateWorkspaceParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type CreateWorkspaceParams = {
customUnitID: string;
customUnitRateID: string;
engagementChoice?: string;
currency: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please make this one optional, you have made this param as optional in the util function or vice versa

Copy link
Contributor Author

Choose a reason for hiding this comment

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

currency will be always returned from buildOptimisticDistanceRateCustomUnits, so I don't think we need to make this optional but we don't have any default currency in the util functions so we need to make them optional.

Copy link
Contributor

Choose a reason for hiding this comment

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

makes sense to me!

file?: File;
};

export default CreateWorkspaceParams;
7 changes: 7 additions & 0 deletions src/libs/CurrencyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Onyx from 'react-native-onyx';
import CONST from '@src/CONST';
import type {OnyxValues} from '@src/ONYXKEYS';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Currency} from '@src/types/onyx';
import BaseLocaleListener from './Localize/LocaleListener/BaseLocaleListener';
import * as NumberFormatUtils from './NumberFormatUtils';

Expand Down Expand Up @@ -30,6 +31,11 @@ function getCurrencyDecimals(currency: string = CONST.CURRENCY.USD): number {
return decimals ?? 2;
}

function getCurrency(currency: string = CONST.CURRENCY.USD): Currency | null {
const currencyItem = currencyList?.[currency];
return currencyItem;
}

/**
* Returns the currency's minor unit quantity
* e.g. Cent in USD
Expand Down Expand Up @@ -216,5 +222,6 @@ export {
convertToDisplayStringWithoutCurrency,
isValidCurrencyCode,
convertToShortDisplayString,
getCurrency,
sanitizeCurrencyCode,
};
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import type {
TransactionDuplicateNavigatorParamList,
TravelNavigatorParamList,
WalletStatementNavigatorParamList,
WorkspaceConfirmationNavigatorParamList,
} from '@navigation/types';
import type {Screen} from '@src/SCREENS';
import SCREENS from '@src/SCREENS';
Expand Down Expand Up @@ -129,6 +130,10 @@ const ReportSettingsModalStackNavigator = createModalStackNavigator<ReportSettin
[SCREENS.REPORT_SETTINGS.VISIBILITY]: () => require<ReactComponentModule>('../../../../pages/settings/Report/VisibilityPage').default,
});

const WorkspaceConfirmationModalStackNavigator = createModalStackNavigator<WorkspaceConfirmationNavigatorParamList>({
[SCREENS.WORKSPACE_CONFIRMATION.ROOT]: () => require<ReactComponentModule>('../../../../pages/workspace/WorkspaceConfirmationPage').default,
});

const TaskModalStackNavigator = createModalStackNavigator<TaskDetailsNavigatorParamList>({
[SCREENS.TASK.TITLE]: () => require<ReactComponentModule>('../../../../pages/tasks/TaskTitlePage').default,
[SCREENS.TASK.ASSIGNEE]: () => require<ReactComponentModule>('../../../../pages/tasks/TaskAssigneeSelectorModal').default,
Expand Down Expand Up @@ -715,4 +720,5 @@ export {
SearchSavedSearchModalStackNavigator,
MissingPersonalDetailsModalStackNavigator,
DebugModalStackNavigator,
WorkspaceConfirmationModalStackNavigator,
};
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ function RightModalNavigator({navigation, route}: RightModalNavigatorProps) {
name={SCREENS.RIGHT_MODAL.MONEY_REQUEST}
component={ModalStackNavigators.MoneyRequestModalStackNavigator}
/>
<Stack.Screen
name={SCREENS.RIGHT_MODAL.WORKSPACE_CONFIRMATION}
component={ModalStackNavigators.WorkspaceConfirmationModalStackNavigator}
/>
<Stack.Screen
name={SCREENS.RIGHT_MODAL.NEW_TASK}
component={ModalStackNavigators.NewTaskModalStackNavigator}
Expand Down
5 changes: 5 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,11 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
},
},
},
[SCREENS.RIGHT_MODAL.WORKSPACE_CONFIRMATION]: {
screens: {
[SCREENS.WORKSPACE_CONFIRMATION.ROOT]: ROUTES.WORKSPACE_CONFIRMATION,
},
},
[SCREENS.RIGHT_MODAL.NEW_TASK]: {
screens: {
[SCREENS.NEW_TASK.ROOT]: ROUTES.NEW_TASK.route,
Expand Down
6 changes: 6 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,10 @@ type MoneyRequestNavigatorParamList = {
};
};

type WorkspaceConfirmationNavigatorParamList = {
[SCREENS.WORKSPACE_CONFIRMATION.ROOT]: undefined;
};

type NewTaskNavigatorParamList = {
[SCREENS.NEW_TASK.ROOT]: {
backTo?: Routes;
Expand Down Expand Up @@ -1382,6 +1386,7 @@ type RightModalNavigatorParamList = {
[SCREENS.RIGHT_MODAL.PARTICIPANTS]: NavigatorScreenParams<ParticipantsNavigatorParamList>;
[SCREENS.RIGHT_MODAL.ROOM_MEMBERS]: NavigatorScreenParams<RoomMembersNavigatorParamList>;
[SCREENS.RIGHT_MODAL.MONEY_REQUEST]: NavigatorScreenParams<MoneyRequestNavigatorParamList>;
[SCREENS.RIGHT_MODAL.WORKSPACE_CONFIRMATION]: NavigatorScreenParams<WorkspaceConfirmationNavigatorParamList>;
[SCREENS.RIGHT_MODAL.NEW_TASK]: NavigatorScreenParams<NewTaskNavigatorParamList>;
[SCREENS.RIGHT_MODAL.TEACHERS_UNITE]: NavigatorScreenParams<TeachersUniteNavigatorParamList>;
[SCREENS.RIGHT_MODAL.TASK_DETAILS]: NavigatorScreenParams<TaskDetailsNavigatorParamList>;
Expand Down Expand Up @@ -1771,5 +1776,6 @@ export type {
RestrictedActionParamList,
MissingPersonalDetailsParamList,
DebugParamList,
WorkspaceConfirmationNavigatorParamList,
MigratedUserModalNavigatorParamList,
};
23 changes: 17 additions & 6 deletions src/libs/actions/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,18 +367,29 @@ function endSignOnTransition() {
* @param [transitionFromOldDot] Optional, if the user is transitioning from old dot
* @param [makeMeAdmin] Optional, leave the calling account as an admin on the policy
* @param [backTo] An optional return path. If provided, it will be URL-encoded and appended to the resulting URL.
* @param [policyID] Optional, Policy id.
* @param [file],file
*/
function createWorkspaceWithPolicyDraftAndNavigateToIt(policyOwnerEmail = '', policyName = '', transitionFromOldDot = false, makeMeAdmin = false, backTo = '') {
const policyID = Policy.generatePolicyID();
Policy.createDraftInitialWorkspace(policyOwnerEmail, policyName, policyID, makeMeAdmin);
function createWorkspaceWithPolicyDraftAndNavigateToIt(
policyOwnerEmail = '',
policyName = '',
transitionFromOldDot = false,
makeMeAdmin = false,
backTo = '',
policyID = '',
currency?: string,
file?: File,
) {
const genereatedPolicyID = Policy.generatePolicyID();
Policy.createDraftInitialWorkspace(policyOwnerEmail, policyName, policyID || genereatedPolicyID, makeMeAdmin, currency, file);

Navigation.isNavigationReady()
.then(() => {
if (transitionFromOldDot) {
// We must call goBack() to remove the /transition route from history
Navigation.goBack();
}
savePolicyDraftByNewWorkspace(policyID, policyName, policyOwnerEmail, makeMeAdmin);
savePolicyDraftByNewWorkspace(policyID, policyName, policyOwnerEmail, makeMeAdmin, currency, file);
Navigation.navigate(ROUTES.WORKSPACE_INITIAL.getRoute(policyID, backTo));
})
.then(endSignOnTransition);
Expand All @@ -392,8 +403,8 @@ function createWorkspaceWithPolicyDraftAndNavigateToIt(policyOwnerEmail = '', po
* @param [policyOwnerEmail] Optional, the email of the account to make the owner of the policy
* @param [makeMeAdmin] Optional, leave the calling account as an admin on the policy
*/
function savePolicyDraftByNewWorkspace(policyID?: string, policyName?: string, policyOwnerEmail = '', makeMeAdmin = false) {
Policy.createWorkspace(policyOwnerEmail, makeMeAdmin, policyName, policyID);
function savePolicyDraftByNewWorkspace(policyID?: string, policyName?: string, policyOwnerEmail = '', makeMeAdmin = false, currency = '', file?: File) {
Policy.createWorkspace(policyOwnerEmail, makeMeAdmin, policyName, policyID, '', currency, file);
}

/**
Expand Down
Loading
Loading