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/push page ws name #30733

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e109a14
feat - add Push-to-Page method for workspace-settings name page & rem…
b4s36t4 Nov 1, 2023
14f1094
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Nov 1, 2023
0faaadf
remove comments
b4s36t4 Nov 1, 2023
16efcdf
fix lint
b4s36t4 Nov 1, 2023
69da7f3
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Nov 8, 2023
913846a
fix type
b4s36t4 Nov 8, 2023
f727c79
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Nov 14, 2023
f395a83
update onyxkey order & remove old keys
b4s36t4 Nov 14, 2023
dc94197
fix lint error
b4s36t4 Nov 14, 2023
0587255
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Nov 21, 2023
e0e97c1
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Nov 26, 2023
82a850a
fix styling for ws settings page
b4s36t4 Nov 26, 2023
b5efd07
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Dec 1, 2023
8690189
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Dec 5, 2023
7a58027
remove unused import
b4s36t4 Dec 5, 2023
2153829
fix type
b4s36t4 Dec 5, 2023
2063898
fix lint & ts issue
b4s36t4 Dec 5, 2023
9268f6d
add styles according to profile page
b4s36t4 Dec 5, 2023
3bf796f
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Dec 8, 2023
0d2dd81
fix issues
b4s36t4 Dec 8, 2023
7911882
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Dec 11, 2023
b4fed07
fix lint
b4s36t4 Dec 11, 2023
b71d943
fix order
b4s36t4 Dec 11, 2023
1288a0b
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Dec 23, 2023
775e6ec
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Dec 23, 2023
db6569f
update changes
b4s36t4 Dec 23, 2023
8aac1e3
run prettier
b4s36t4 Dec 23, 2023
ab24401
Merge branch 'main' of github.com:Expensify/App into feat/push-page-w…
b4s36t4 Jan 7, 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
8 changes: 4 additions & 4 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ const ONYXKEYS = {
FORMS: {
ADD_DEBIT_CARD_FORM: 'addDebitCardForm',
ADD_DEBIT_CARD_FORM_DRAFT: 'addDebitCardFormDraft',
WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
WORKSPACE_SETTINGS_FORM_DRAFT: 'workspaceSettingsFormDraft',
WORKSPACE_EDIT_NAME: 'workspaceEditName',
WORKSPACE_EDIT_NAME_DRAFT: 'workspaceEditNameDraft',
WORKSPACE_RATE_AND_UNIT_FORM: 'workspaceRateAndUnitForm',
WORKSPACE_RATE_AND_UNIT_FORM_DRAFT: 'workspaceRateAndUnitFormDraft',
CLOSE_ACCOUNT_FORM: 'closeAccount',
Expand Down Expand Up @@ -466,8 +466,8 @@ type OnyxValues = {
// Forms
[ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: OnyxTypes.AddDebitCardForm;
[ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM_DRAFT]: OnyxTypes.AddDebitCardForm;
[ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM_DRAFT]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WORKSPACE_EDIT_NAME]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WORKSPACE_EDIT_NAME_DRAFT]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM_DRAFT]: OnyxTypes.Form;
[ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM]: OnyxTypes.Form;
Expand Down
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,10 @@ const ROUTES = {
route: 'workspace/:policyID/settings/currency',
getRoute: (policyID: string) => `workspace/${policyID}/settings/currency` as const,
},
WORKSPACE_SETTINGS_NAME: {
route: 'workspace/:policyID/settings/name',
getRoute: (policyID: string) => `workspace/${policyID}/settings/name` as const,
},
WORKSPACE_CARD: {
route: 'workspace/:policyID/card',
getRoute: (policyID: string) => `workspace/${policyID}/card` as const,
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ const SCREENS = {
INVITE: 'Workspace_Invite',
INVITE_MESSAGE: 'Workspace_Invite_Message',
CURRENCY: 'Workspace_Settings_Currency',
NAME: 'Workspace_Settings_Name',
},

EDIT_REQUEST: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.INITIAL]: () => require('../../../pages/workspace/WorkspaceInitialPage').default as React.ComponentType,
[SCREENS.WORKSPACE.SETTINGS]: () => require('../../../pages/workspace/WorkspaceSettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.CURRENCY]: () => require('../../../pages/workspace/WorkspaceSettingsCurrencyPage').default as React.ComponentType,
[SCREENS.WORKSPACE.NAME]: () => require('../../../pages/workspace/WorkspaceSettingsNamePage').default as React.ComponentType,
[SCREENS.WORKSPACE.CARD]: () => require('../../../pages/workspace/card/WorkspaceCardPage').default as React.ComponentType,
[SCREENS.WORKSPACE.REIMBURSE]: () => require('../../../pages/workspace/reimburse/WorkspaceReimbursePage').default as React.ComponentType,
[SCREENS.WORKSPACE.RATE_AND_UNIT]: () => require('../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage').default as React.ComponentType,
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/linkingConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ const linkingConfig: LinkingOptions<RootStackParamList> = {
[SCREENS.WORKSPACE.CURRENCY]: {
path: ROUTES.WORKSPACE_SETTINGS_CURRENCY.route,
},
[SCREENS.WORKSPACE.NAME]: {
path: ROUTES.WORKSPACE_SETTINGS_NAME.route,
},
[SCREENS.WORKSPACE.CARD]: {
path: ROUTES.WORKSPACE_CARD.route,
},
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.INITIAL]: undefined;
[SCREENS.WORKSPACE.SETTINGS]: undefined;
[SCREENS.WORKSPACE.CURRENCY]: undefined;
[SCREENS.WORKSPACE.NAME]: undefined;
[SCREENS.WORKSPACE.CARD]: {
policyID: string;
};
Expand Down
144 changes: 144 additions & 0 deletions src/pages/workspace/WorkspaceSettingsNamePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import {useFocusEffect} from '@react-navigation/native';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useCallback, useRef} from 'react';
import {Keyboard, View} from 'react-native';
import _ from 'underscore';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import FormProvider from '@components/Form/FormProvider';
import InputWrapper from '@components/Form/InputWrapper';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import TextInput from '@components/TextInput/index';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Browser from '@libs/Browser';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ValidationUtils from '@libs/ValidationUtils';
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import {policyDefaultProps, policyPropTypes} from './withPolicy';
import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading';

const propTypes = {
isLoadingReportData: PropTypes.bool,
...policyPropTypes,
};

const defaultProps = {
isLoadingReportData: true,
...policyDefaultProps,
};

function WorkSpaceSettingsNamePage({policy, isLoadingReportData}) {
const {translate} = useLocalize();

const styles = useThemeStyles();
const focusTimeoutRef = useRef();

const inputRef = useRef();

const onBackButtonPress = useCallback(() => Navigation.goBack(ROUTES.WORKSPACE_SETTINGS.getRoute(policy.id)), [policy.id]);

const validate = useCallback((values) => {
const errors = {};
const name = values.name.trim();

if (!ValidationUtils.isRequiredFulfilled(name)) {
errors.name = 'workspace.editor.nameIsRequiredError';
} else if ([...name].length > CONST.WORKSPACE_NAME_CHARACTER_LIMIT) {
// Uses the spread syntax to count the number of Unicode code points instead of the number of UTF-16
// code units.
errors.name = 'workspace.editor.nameIsTooLongError';
}

return errors;
}, []);

const submit = useCallback(
(values) => {
if (policy.isPolicyUpdating) {
return;
}
Policy.updateGeneralSettings(policy.id, values.name, policy.outputCurrency);
Keyboard.dismiss();
Navigation.goBack(ROUTES.WORKSPACE_SETTINGS.getRoute(policy.id));
},
[policy.id, policy.isPolicyUpdating, policy.outputCurrency],
);

useFocusEffect(
useCallback(() => {
focusTimeoutRef.current = setTimeout(() => {
if (inputRef.current) {
inputRef.current.focus();
}
return () => {
if (!focusTimeoutRef.current) {
return;
}
clearTimeout(focusTimeoutRef.current);
};
}, CONST.ANIMATED_TRANSITION);
}, []),
);

return (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
testID={WorkSpaceSettingsNamePage.displayName}
shouldEnableMaxHeight
>
<FullPageNotFoundView
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)}
shouldShow={(_.isEmpty(policy) && !isLoadingReportData) || !PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPendingDeletePolicy(policy)}
subtitleKey={_.isEmpty(policy) ? undefined : 'workspace.common.notAuthorized'}
>
<HeaderWithBackButton
title={translate('workspace.editor.nameInputLabel')}
onBackButtonPress={onBackButtonPress}
/>
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
formID={ONYXKEYS.FORMS.WORKSPACE_EDIT_NAME}
validate={validate}
onSubmit={submit}
submitButtonText={translate('common.save')}
enabledWhenOffline
shouldValidateOnBlur
shouldValidateOnChange
>
<View style={[styles.mb4]}>
<InputWrapper
InputComponent={TextInput}
accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT}
inputID="name"
name="name"
submitOnEnter={!Browser.isMobile()}
textAlignVertical="top"
maxLength={CONST.WORKSPACE_NAME_CHARACTER_LIMIT}
label={translate('workspace.editor.nameInputLabel')}
accessibilityLabel={translate('workspace.editor.nameInputLabel')}
defaultValue={lodashGet(policy, 'name', '')}
ref={(el) => {
if (!el) {
return;
}
inputRef.current = el;
}}
/>
</View>
</FormProvider>
</FullPageNotFoundView>
</ScreenWrapper>
);
}

WorkSpaceSettingsNamePage.displayName = 'WorkspaceSettingsNamePage';
WorkSpaceSettingsNamePage.propTypes = propTypes;
WorkSpaceSettingsNamePage.defaultProps = defaultProps;

export default withPolicyAndFullscreenLoading(WorkSpaceSettingsNamePage);
84 changes: 19 additions & 65 deletions src/pages/workspace/WorkspaceSettingsPage.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useCallback} from 'react';
import {Keyboard, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import Avatar from '@components/Avatar';
import AvatarWithImagePicker from '@components/AvatarWithImagePicker';
import FormProvider from '@components/Form/FormProvider';
import InputWrapper from '@components/Form/InputWrapper';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import {withNetwork} from '@components/OnyxProvider';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import compose from '@libs/compose';
import Navigation from '@libs/Navigation/Navigation';
import * as ReportUtils from '@libs/ReportUtils';
import * as UserUtils from '@libs/UserUtils';
import * as ValidationUtils from '@libs/ValidationUtils';
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -62,36 +57,10 @@ function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) {

const formattedCurrency = !_.isEmpty(policy) && !_.isEmpty(currencyList) ? `${policy.outputCurrency} - ${currencyList[policy.outputCurrency].symbol}` : '';

const submit = useCallback(
(values) => {
if (policy.isPolicyUpdating) {
return;
}

Policy.updateGeneralSettings(policy.id, values.name.trim(), policy.outputCurrency);
Keyboard.dismiss();
Navigation.goBack(ROUTES.WORKSPACE_INITIAL.getRoute(policy.id));
},
[policy.id, policy.isPolicyUpdating, policy.outputCurrency],
);

const validate = useCallback((values) => {
const errors = {};
const name = values.name.trim();

if (!ValidationUtils.isRequiredFulfilled(name)) {
errors.name = 'workspace.editor.nameIsRequiredError';
} else if ([...name].length > CONST.WORKSPACE_NAME_CHARACTER_LIMIT) {
// Uses the spread syntax to count the number of Unicode code points instead of the number of UTF-16
// code units.
errors.name = 'workspace.editor.nameIsTooLongError';
}

return errors;
}, []);

const onPressCurrency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_SETTINGS_CURRENCY.getRoute(policy.id)), [policy.id]);

const onPressPolicyName = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_SETTINGS_NAME.getRoute(policy.id)), [policy.id]);

const policyName = lodashGet(policy, 'name', '');

return (
Expand All @@ -102,15 +71,7 @@ function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) {
shouldShowLoading={false}
>
{(hasVBA) => (
<FormProvider
formID={ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM}
submitButtonText={translate('workspace.editor.save')}
style={[styles.flexGrow1, styles.ph5]}
scrollContextEnabled
validate={validate}
onSubmit={submit}
enabledWhenOffline
>
<>
<AvatarWithImagePicker
source={lodashGet(policy, 'avatar')}
size={CONST.AVATAR_SIZE.LARGE}
Expand Down Expand Up @@ -142,31 +103,24 @@ function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) {
originalFileName={policy.originalFileName}
/>
<OfflineWithFeedback pendingAction={lodashGet(policy, 'pendingFields.generalSettings')}>
<InputWrapper
InputComponent={TextInput}
role={CONST.ROLE.PRESENTATION}
inputID="name"
label={translate('workspace.editor.nameInputLabel')}
accessibilityLabel={translate('workspace.editor.nameInputLabel')}
defaultValue={policy.name}
maxLength={CONST.WORKSPACE_NAME_CHARACTER_LIMIT}
containerStyles={[styles.mt4]}
spellCheck={false}
<MenuItemWithTopDescription
title={policy.name}
description={translate('workspace.editor.nameInputLabel')}
shouldShowRightIcon
onPress={onPressPolicyName}
/>
<View style={[styles.mt4, styles.mhn5]}>
<MenuItemWithTopDescription
title={formattedCurrency}
description={translate('workspace.editor.currencyInputLabel')}
shouldShowRightIcon
disabled={hasVBA}
onPress={onPressCurrency}
/>
<Text style={[styles.textLabel, styles.colorMuted, styles.mt2, styles.mh5]}>
{hasVBA ? translate('workspace.editor.currencyInputDisabledText') : translate('workspace.editor.currencyInputHelpText')}
</Text>
</View>
<MenuItemWithTopDescription
title={formattedCurrency}
description={translate('workspace.editor.currencyInputLabel')}
shouldShowRightIcon
disabled={hasVBA}
onPress={onPressCurrency}
/>
<Text style={[styles.textLabel, styles.colorMuted, styles.mt2, styles.mh5]}>
{hasVBA ? translate('workspace.editor.currencyInputDisabledText') : translate('workspace.editor.currencyInputHelpText')}
</Text>
</OfflineWithFeedback>
</FormProvider>
</>
)}
</WorkspacePageWithSections>
);
Expand Down
Loading