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

Add copilot section to security page and add copilot #47353

Merged
merged 105 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
277f2bf
add lang
rushatgabhane Aug 13, 2024
4178a21
add copilot section
rushatgabhane Aug 13, 2024
b4c6799
add icon
rushatgabhane Aug 13, 2024
b87ac4d
display copilots
rushatgabhane Aug 13, 2024
487ce45
display delegators
rushatgabhane Aug 13, 2024
46562f7
hide behind beta
rushatgabhane Aug 13, 2024
634d36a
Merge branch 'account-switcher' into show-copilot
rushatgabhane Aug 13, 2024
3d0c4b2
add user plus icon
rushatgabhane Aug 14, 2024
e91d487
Merge branch 'account-switcher' into show-copilot
rushatgabhane Aug 14, 2024
7dbcd0e
switch delegates and delegators
rushatgabhane Aug 14, 2024
ad09ebf
show full or limited
rushatgabhane Aug 14, 2024
d0f7217
fix interactivity
rushatgabhane Aug 14, 2024
9921cc6
hide delegates if they dont exist
rushatgabhane Aug 14, 2024
bbbc5ab
Merge branch 'account-switcher' into show-copilot
rushatgabhane Aug 14, 2024
04f63f0
Merge branch 'account-switcher' into show-copilot
rushatgabhane Aug 14, 2024
636551d
Merge branch 'account-switcher' into show-copilot
rushatgabhane Aug 14, 2024
0b07897
create add copilot page
rushatgabhane Aug 15, 2024
4973a9b
Merge branch 'account-switcher' into show-copilot
rushatgabhane Aug 15, 2024
79b90ff
create add delegate command
rushatgabhane Aug 15, 2024
234f6ac
cleanup
rushatgabhane Aug 15, 2024
811dfac
merge
rushatgabhane Aug 15, 2024
b05c19e
handle undefined
rushatgabhane Aug 15, 2024
d3315a6
add navigation for add delegate page
rushatgabhane Aug 15, 2024
b773ee6
merge
rushatgabhane Aug 25, 2024
7cc14d5
update routes for role select page
rushatgabhane Aug 25, 2024
71a3533
add role select page options
rushatgabhane Aug 26, 2024
62cbae8
fix route types
rushatgabhane Aug 26, 2024
f5fe988
add lang
rushatgabhane Aug 26, 2024
c6e4242
add lang
rushatgabhane Aug 26, 2024
db4d5be
add confirm delegate page
rushatgabhane Aug 26, 2024
0d4af25
navigate to confirm delegate page
rushatgabhane Aug 26, 2024
6cb8bf6
add mv6
rushatgabhane Aug 26, 2024
6cd3d8c
add submit button
rushatgabhane Aug 26, 2024
8707a05
rm dead code
rushatgabhane Aug 26, 2024
29bc5c8
cleanup
rushatgabhane Aug 26, 2024
2811a5f
refactor to use header page layout
rushatgabhane Aug 26, 2024
34a1485
add gap6
rushatgabhane Aug 26, 2024
96a2f42
add fallback navigation
rushatgabhane Aug 26, 2024
6665309
cleanup
rushatgabhane Aug 26, 2024
d7d9709
cleanup
rushatgabhane Aug 26, 2024
177e7f3
rm unused import
rushatgabhane Aug 26, 2024
27905f2
rm unused
rushatgabhane Aug 26, 2024
f5447b8
fix type
rushatgabhane Aug 26, 2024
93d526d
undo perm
rushatgabhane Aug 26, 2024
ef39580
use delegate as param
rushatgabhane Aug 26, 2024
f99fc89
Merge branch 'account-switcher' into show-copilot
rushatgabhane Aug 29, 2024
33e0f78
Merge branch 'main' into show-copilot
rushatgabhane Aug 29, 2024
47f81cb
fix lang
rushatgabhane Aug 29, 2024
d7fc432
cleanup
rushatgabhane Aug 29, 2024
5b68626
rm extra padding for acc swticher
rushatgabhane Aug 29, 2024
f445776
add validate code page skeleton
rushatgabhane Sep 3, 2024
9f8c3d3
Merge branch 'main' of github.com:rushatgabhane/exfy into show-copilot
rushatgabhane Sep 3, 2024
649c1be
add basic magic code form that without error handling
rushatgabhane Sep 3, 2024
5409da8
rm green dot and fix lang
rushatgabhane Sep 3, 2024
6f2a633
move verify button to bottom
rushatgabhane Sep 3, 2024
9f3c104
add to central pane rhp
rushatgabhane Sep 3, 2024
b95786c
fix style
rushatgabhane Sep 3, 2024
9de1866
add error fields
rushatgabhane Sep 4, 2024
d4cd875
undo perm
rushatgabhane Sep 4, 2024
dad63e0
Merge branch 'main' of github.com:rushatgabhane/exfy into show-copilot
rushatgabhane Sep 4, 2024
5c3ad4a
dismiss modal on success
rushatgabhane Sep 4, 2024
13d4aa4
exclude existing delegates
rushatgabhane Sep 4, 2024
5b0689c
convert to use error fields
rushatgabhane Sep 4, 2024
f3e5cd8
handle error fields
rushatgabhane Sep 4, 2024
70f415b
clear errors
rushatgabhane Sep 4, 2024
cdd83ea
use memo
rushatgabhane Sep 4, 2024
7de8ae3
disable when offline
rushatgabhane Sep 5, 2024
e221c01
pr feedback
rushatgabhane Sep 5, 2024
98d5685
add safe area padding style
rushatgabhane Sep 5, 2024
bd0ba6b
fix error field name
rushatgabhane Sep 5, 2024
6e2e11f
Update src/pages/settings/Security/SecuritySettingsPage.tsx
rushatgabhane Sep 6, 2024
b8830c4
rm filter
rushatgabhane Sep 6, 2024
962ac9c
add safe area padding
rushatgabhane Sep 6, 2024
24119c8
add safe area padding
rushatgabhane Sep 6, 2024
3efb821
add margin bottom
rushatgabhane Sep 6, 2024
ec8d513
add 20px more margin
rushatgabhane Sep 6, 2024
7275b65
filter pending delegates
rushatgabhane Sep 6, 2024
c302fdf
add safe area bottom padding
rushatgabhane Sep 6, 2024
9392cc8
add failed delegate
rushatgabhane Sep 6, 2024
0591eb8
show errors
rushatgabhane Sep 6, 2024
1627104
add pending actions
rushatgabhane Sep 6, 2024
27e858d
added ability to dimiss error
rushatgabhane Sep 6, 2024
ba47bae
clear delegate errors on type
rushatgabhane Sep 6, 2024
6a79941
show disabled opacity if pending actions
rushatgabhane Sep 6, 2024
8607b5e
update existing delegate if present
rushatgabhane Sep 6, 2024
582f153
remove pending delegate
rushatgabhane Sep 6, 2024
a20bbef
rm console
rushatgabhane Sep 6, 2024
5a516b2
cleanup
rushatgabhane Sep 6, 2024
e4f8dd3
clear delegate errs
rushatgabhane Sep 6, 2024
b184413
Merge branch 'main' into show-copilot
rushatgabhane Sep 6, 2024
ba7973d
Update src/languages/es.ts
rushatgabhane Sep 6, 2024
4d0a93e
fix lint
rushatgabhane Sep 6, 2024
85b8a79
Merge branch 'main' into show-copilot
rushatgabhane Sep 6, 2024
7409e30
add alternate text number of lines prop to selection list
rushatgabhane Sep 6, 2024
54762a6
add user to invite
rushatgabhane Sep 6, 2024
e02d63b
add optimistic account ID for new users
rushatgabhane Sep 6, 2024
37ab2f1
handle fallback avatars and filter optimistic ids
rushatgabhane Sep 6, 2024
a98b360
handle user that is not expensify user
rushatgabhane Sep 6, 2024
74d5b1b
format phone number
rushatgabhane Sep 7, 2024
0d70524
add learn more url
rushatgabhane Sep 7, 2024
d4606fc
Merge branch 'main' of github.com:rushatgabhane/exfy into show-copilot
rushatgabhane Sep 10, 2024
7ff29a6
use login instead of accountID as url param
rushatgabhane Sep 10, 2024
8935513
fix ts errors
rushatgabhane Sep 10, 2024
44af36e
Merge branch 'main' of github.com:rushatgabhane/exfy into show-copilot
rushatgabhane Sep 10, 2024
aa5dabe
fix lint
rushatgabhane Sep 10, 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
11 changes: 11 additions & 0 deletions assets/images/user-plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ const CONST = {
"https://help.expensify.com/articles/expensify-classic/connections/sage-intacct/Sage-Intacct-Troubleshooting#:~:text=First%20make%20sure%20that%20you,your%20company's%20Web%20Services%20authorizations.",
PRICING: `https://www.expensify.com/pricing`,
CUSTOM_REPORT_NAME_HELP_URL: 'https://help.expensify.com/articles/expensify-classic/spending-insights/Custom-Templates',
COPILOT_HELP_URL: 'https://help.expensify.com/articles/expensify-classic/copilots-and-delegates/Assign-or-remove-a-Copilot',
// Use Environment.getEnvironmentURL to get the complete URL with port number
DEV_NEW_EXPENSIFY_URL: 'https://dev.new.expensify.com:',
OLDDOT_URLS: {
Expand Down Expand Up @@ -4084,8 +4085,8 @@ const CONST = {
GETCODE: 'GETCODE',
},
DELEGATE_ROLE: {
SUBMITTER: 'submitter',
ALL: 'all',
SUBMITTER: 'submitter',
},
DELEGATE_ROLE_HELPDOT_ARTICLE_LINK: 'https://help.expensify.com/expensify-classic/hubs/copilots-and-delegates/',
STRIPE_GBP_AUTH_STATUSES: {
Expand Down
13 changes: 13 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,19 @@ const ROUTES = {
SETTINGS_WORKSPACES: 'settings/workspaces',
SETTINGS_SECURITY: 'settings/security',
SETTINGS_CLOSE: 'settings/security/closeAccount',
SETTINGS_ADD_DELEGATE: 'settings/security/delegate',
SETTINGS_DELEGATE_ROLE: {
route: 'settings/security/delegate/:login/role/:role',
getRoute: (login: string, role?: string) => `settings/security/delegate/${encodeURIComponent(login)}/role/${role}` as const,
},
SETTINGS_DELEGATE_CONFIRM: {
route: 'settings/security/delegate/:login/role/:role/confirm',
getRoute: (login: string, role: string) => `settings/security/delegate/${encodeURIComponent(login)}/role/${role}/confirm` as const,
},
SETTINGS_DELEGATE_MAGIC_CODE: {
route: 'settings/security/delegate/:login/role/:role/magic-code',
getRoute: (login: string, role: string) => `settings/security/delegate/${encodeURIComponent(login)}/role/${role}/magic-code` as const,
},
SETTINGS_ABOUT: 'settings/about',
SETTINGS_APP_DOWNLOAD_LINKS: 'settings/about/app-download-links',
SETTINGS_WALLET: 'settings/wallet',
Expand Down
6 changes: 6 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ const SCREENS = {
CHANGE_PAYMENT_CURRENCY: 'Settings_Subscription_Change_Payment_Currency',
REQUEST_EARLY_CANCELLATION: 'Settings_Subscription_RequestEarlyCancellation',
},
DELEGATE: {
ADD_DELEGATE: 'Settings_Delegate_Add',
DELEGATE_ROLE: 'Settings_Delegate_Role',
DELEGATE_CONFIRM: 'Settings_Delegate_Confirm',
DELEGATE_MAGIC_CODE: 'Settings_Delegate_Magic_Code',
},
},
SAVE_THE_WORLD: {
ROOT: 'SaveTheWorld_Root',
Expand Down
15 changes: 9 additions & 6 deletions src/components/AccountSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {clearDelegatorErrors, connect, disconnect} from '@libs/actions/Delegate';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils';
import variables from '@styles/variables';
import * as Modal from '@userActions/Modal';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PersonalDetails} from '@src/types/onyx';
import type {Errors} from '@src/types/onyx/OnyxCommon';
import Avatar from './Avatar';
import ConfirmModal from './ConfirmModal';
import Icon from './Icon';
Expand Down Expand Up @@ -46,7 +47,8 @@ function AccountSwitcher() {
const isActingAsDelegate = !!account?.delegatedAccess?.delegate ?? false;
const canSwitchAccounts = canUseNewDotCopilot && (delegators.length > 0 || isActingAsDelegate);

const createBaseMenuItem = (personalDetails: PersonalDetails | undefined, error?: TranslationPaths, additionalProps: MenuItemWithLink = {}): MenuItemWithLink => {
const createBaseMenuItem = (personalDetails: PersonalDetails | undefined, errors?: Errors, additionalProps: MenuItemWithLink = {}): MenuItemWithLink => {
const error = Object.values(errors ?? {})[0] ?? '';
return {
title: personalDetails?.displayName ?? personalDetails?.login,
description: Str.removeSMSDomain(personalDetails?.login ?? ''),
Expand All @@ -55,7 +57,7 @@ function AccountSwitcher() {
iconType: CONST.ICON_TYPE_AVATAR,
outerWrapperStyle: shouldUseNarrowLayout ? {} : styles.accountSwitcherPopover,
numberOfLinesDescription: 1,
errorText: error ? translate(error) : '',
errorText: error ?? '',
shouldShowRedDotIndicator: !!error,
errorTextStyle: styles.mt2,
...additionalProps,
Expand All @@ -81,7 +83,7 @@ function AccountSwitcher() {
}

const delegatePersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(delegateEmail);
const error = account?.delegatedAccess?.error;
const error = ErrorUtils.getLatestErrorField(account?.delegatedAccess, 'connect');

return [
createBaseMenuItem(delegatePersonalDetails, error, {
Expand All @@ -100,7 +102,8 @@ function AccountSwitcher() {

const delegatorMenuItems: MenuItemProps[] = delegators
.filter(({email}) => email !== currentUserPersonalDetails.login)
.map(({email, role, error}, index) => {
.map(({email, role, errorFields}, index) => {
const error = ErrorUtils.getLatestErrorField({errorFields}, 'connect');
const personalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(email);
return createBaseMenuItem(personalDetails, error, {
badgeText: translate('delegate.role', role),
Expand Down Expand Up @@ -177,7 +180,7 @@ function AccountSwitcher() {
anchorPosition={styles.accountSwitcherAnchorPosition}
>
<View style={styles.pb4}>
<Text style={[styles.createMenuHeaderText, styles.ph5, styles.pb2, styles.pt4]}>{translate('delegate.switchAccount')}</Text>
<Text style={[styles.createMenuHeaderText, styles.ph5, styles.pb3, !shouldUseNarrowLayout && styles.pt4]}>{translate('delegate.switchAccount')}</Text>
<MenuItemList
menuItems={menuItems()}
shouldUseSingleExecution
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ import Unlock from '@assets/images/unlock.svg';
import UploadAlt from '@assets/images/upload-alt.svg';
import Upload from '@assets/images/upload.svg';
import UserCheck from '@assets/images/user-check.svg';
import UserPlus from '@assets/images/user-plus.svg';
import User from '@assets/images/user.svg';
import Users from '@assets/images/users.svg';
import VolumeHigh from '@assets/images/volume-high.svg';
Expand Down Expand Up @@ -391,6 +392,7 @@ export {
CalendarSolid,
Filter,
CaretUpDown,
UserPlus,
Feed,
Table,
SpreadsheetComputer,
Expand Down
41 changes: 31 additions & 10 deletions src/components/MenuItemList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import type {GestureResponderEvent, View} from 'react-native';
import useSingleExecution from '@hooks/useSingleExecution';
import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
import type * as OnyxCommon from '@src/types/onyx/OnyxCommon';
import type {MenuItemProps} from './MenuItem';
import MenuItem from './MenuItem';
import OfflineWithFeedback from './OfflineWithFeedback';

type MenuItemLink = string | (() => Promise<string>);

Expand All @@ -14,6 +16,18 @@ type MenuItemWithLink = MenuItemProps & {

/** A unique key for the menu item */
key?: string;

/** The pending action for the menu item */
pendingAction?: OnyxCommon.PendingAction | null;

/** A function to dismiss the pending action */
onPendingActionDismiss?: () => void;

/** The error for the menu item */
error?: OnyxCommon.Errors | null;

/** Whether we should force opacity */
shouldForceOpacity?: boolean;
};

type MenuItemListProps = {
Expand Down Expand Up @@ -45,16 +59,23 @@ function MenuItemList({menuItems = [], shouldUseSingleExecution = false}: MenuIt
return (
<>
{menuItems.map((menuItemProps) => (
<MenuItem
key={menuItemProps.key ?? menuItemProps.title}
onSecondaryInteraction={menuItemProps.link !== undefined ? (e) => secondaryInteraction(menuItemProps.link, e) : undefined}
ref={popoverAnchor}
shouldBlockSelection={!!menuItemProps.link}
// eslint-disable-next-line react/jsx-props-no-spreading
{...menuItemProps}
disabled={!!menuItemProps.disabled || isExecuting}
onPress={shouldUseSingleExecution ? singleExecution(menuItemProps.onPress) : menuItemProps.onPress}
/>
<OfflineWithFeedback
Copy link
Contributor

Choose a reason for hiding this comment

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

You forgot to move the key prop to this component so it prints an error in console now

Copy link
Member Author

Choose a reason for hiding this comment

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

sorry i don't understand. OfflineWithFeedback should be passed key as a prop?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yup, since you wrapped MenuItem with OfflineWithFeedback, you have to move the key prop from MenuItem to OfflineWithFeedback

Screenshot 2024-09-18 at 22 58 37

Copy link
Member Author

Choose a reason for hiding this comment

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

nice catch, let me send a PR

pendingAction={menuItemProps.pendingAction}
onClose={menuItemProps.onPendingActionDismiss}
errors={menuItemProps.error}
shouldForceOpacity={menuItemProps.shouldForceOpacity}
>
Copy link
Contributor

Choose a reason for hiding this comment

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

Is using OfflineWithFeedback here going to cause any weirdness in other menus?

Copy link
Member Author

@rushatgabhane rushatgabhane Sep 6, 2024

Choose a reason for hiding this comment

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

no because they won't be passing children will passed as they are when pendingAction is undefined

<MenuItem
key={menuItemProps.key ?? menuItemProps.title}
onSecondaryInteraction={menuItemProps.link !== undefined ? (e) => secondaryInteraction(menuItemProps.link, e) : undefined}
ref={popoverAnchor}
shouldBlockSelection={!!menuItemProps.link}
// eslint-disable-next-line react/jsx-props-no-spreading
{...menuItemProps}
disabled={!!menuItemProps.disabled || isExecuting}
onPress={shouldUseSingleExecution ? singleExecution(menuItemProps.onPress) : menuItemProps.onPress}
/>
</OfflineWithFeedback>
))}
</>
);
Expand Down
6 changes: 5 additions & 1 deletion src/components/OfflineWithFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ type OfflineWithFeedbackProps = ChildrenProps & {

/** Whether we should render the error message above the children */
shouldDisplayErrorAbove?: boolean;

/** Whether we should force opacity */
shouldForceOpacity?: boolean;
};

type StrikethroughProps = Partial<ChildrenProps> & {style: AllStyles[]};
Expand All @@ -78,6 +81,7 @@ function OfflineWithFeedback({
shouldShowErrorMessages = true,
style,
shouldDisplayErrorAbove = false,
shouldForceOpacity = false,
...rest
}: OfflineWithFeedbackProps) {
const styles = useThemeStyles();
Expand All @@ -89,7 +93,7 @@ function OfflineWithFeedback({
const isOfflinePendingAction = !!isOffline && !!pendingAction;
const isUpdateOrDeleteError = hasErrors && (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE);
const isAddError = hasErrors && pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD;
const needsOpacity = !shouldDisableOpacity && ((isOfflinePendingAction && !isUpdateOrDeleteError) || isAddError);
const needsOpacity = (!shouldDisableOpacity && ((isOfflinePendingAction && !isUpdateOrDeleteError) || isAddError)) || shouldForceOpacity;
const needsStrikeThrough = !shouldDisableStrikeThrough && isOffline && pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;
const hideChildren = shouldHideOnDelete && !isOffline && pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && !hasErrors;
let children = rest.children;
Expand Down
2 changes: 2 additions & 0 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function BaseSelectionList<TItem extends ListItem>(
listHeaderWrapperStyle,
isRowMultilineSupported = false,
isAlternateTextMultilineSupported = false,
alternateTextNumberOfLines = 2,
textInputRef,
headerMessageStyle,
shouldHideListOnInitialRender = true,
Expand Down Expand Up @@ -467,6 +468,7 @@ function BaseSelectionList<TItem extends ListItem>(
keyForList={item.keyForList ?? ''}
isMultilineSupported={isRowMultilineSupported}
isAlternateTextMultilineSupported={isAlternateTextMultilineSupported}
alternateTextNumberOfLines={alternateTextNumberOfLines}
onFocus={() => {
if (isDisabled) {
return;
Expand Down
3 changes: 2 additions & 1 deletion src/components/SelectionList/RadioListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function RadioListItem<TItem extends ListItem>({
rightHandSideComponent,
isMultilineSupported = false,
isAlternateTextMultilineSupported = false,
alternateTextNumberOfLines = 2,
onFocus,
shouldSyncFocus,
}: RadioListItemProps<TItem>) {
Expand Down Expand Up @@ -71,7 +72,7 @@ function RadioListItem<TItem extends ListItem>({
isAlternateTextMultilineSupported ? styles.preWrap : styles.pre,
isAlternateTextMultilineSupported ? {maxWidth: alternateTextMaxWidth} : null,
]}
numberOfLines={isAlternateTextMultilineSupported ? 2 : 1}
numberOfLines={isAlternateTextMultilineSupported ? alternateTextNumberOfLines : 1}
/>
)}
</View>
Expand Down
6 changes: 6 additions & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ type CommonListItemProps<TItem extends ListItem> = {
/** Whether to wrap the alternate text up to 2 lines */
isAlternateTextMultilineSupported?: boolean;

/** Number of lines to show for alternate text */
alternateTextNumberOfLines?: number;

/** Handles what to do when the item is focused */
onFocus?: () => void;

Expand Down Expand Up @@ -489,6 +492,9 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
/** Whether to wrap the alternate text up to 2 lines */
isAlternateTextMultilineSupported?: boolean;

/** Number of lines to show for alternate text */
alternateTextNumberOfLines?: number;

/** Ref for textInput */
textInputRef?: MutableRefObject<TextInput | null> | ((ref: TextInput | null) => void);

Expand Down
23 changes: 21 additions & 2 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {CONST as COMMON_CONST, Str} from 'expensify-common';
import {startCase} from 'lodash';
import CONST from '@src/CONST';
import type {Country} from '@src/CONST';
import type {DelegateRole} from '@src/types/onyx/Account';
import type {ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName} from '@src/types/onyx/Policy';
import type {
AccountOwnerParams,
Expand Down Expand Up @@ -4654,7 +4653,12 @@ export default {
},
delegate: {
switchAccount: 'Switch accounts:',
role: (role: DelegateRole): string => {
copilotDelegatedAccess: 'Copilot: Delegated access',
copilotDelegatedAccessDescription: 'Allow other members to access your account.',
addCopilot: 'Add copilot',
membersCanAccessYourAccount: 'These members can access your account:',
youCanAccessTheseAccounts: 'You can access these accounts via the account switcher:',
role: (role?: string): string => {
switch (role) {
case CONST.DELEGATE_ROLE.ALL:
return 'Full';
Expand All @@ -4665,6 +4669,21 @@ export default {
}
},
genericError: 'Oops, something went wrong. Please try again.',
accessLevel: 'Access level',
confirmCopilot: 'Confirm your copilot below.',
accessLevelDescription: 'Choose an access level below. Both Full and Limited access allow copilots to view all conversations and expenses.',
roleDescription: (role?: string): string => {
switch (role) {
case CONST.DELEGATE_ROLE.ALL:
return 'Allow another member to take all actions in your account, on your behalf. Includes chat, submissions, approvals, payments, settings updates, and more.';
case CONST.DELEGATE_ROLE.SUBMITTER:
return 'Allow another member to take most actions in your account, on your behalf. Excludes approvals, payments, rejections, and holds.';
default:
return '';
}
},
makeSureItIsYou: "Let's make sure it's you",
enterMagicCode: ({contactMethod}: EnterMagicCodeParams) => `Please enter the magic code sent to ${contactMethod} to add a copilot.`,
notAllowed: 'Not so fast...',
notAllowedMessageStart: ({accountOwnerEmail}: AccountOwnerParams) => `You don't have permission to take this action for ${accountOwnerEmail} as a`,
notAllowedMessageHyperLinked: ' limited access',
Expand Down
23 changes: 21 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {Str} from 'expensify-common';
import CONST from '@src/CONST';
import type {DelegateRole} from '@src/types/onyx/Account';
import type {ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName} from '@src/types/onyx/Policy';
import type {
AccountOwnerParams,
Expand Down Expand Up @@ -5171,7 +5170,12 @@ export default {
},
delegate: {
switchAccount: 'Cambiar de cuenta:',
role: (role: DelegateRole): string => {
copilotDelegatedAccess: 'Copilot: Acceso delegado',
copilotDelegatedAccessDescription: 'Permitir que otros miembros accedan a tu cuenta.',
addCopilot: 'Agregar copiloto',
membersCanAccessYourAccount: 'Estos miembros pueden acceder a tu cuenta:',
youCanAccessTheseAccounts: 'Puedes acceder a estas cuentas a través del conmutador de cuentas:',
role: (role?: string): string => {
switch (role) {
case CONST.DELEGATE_ROLE.ALL:
return 'Completo';
Expand All @@ -5182,6 +5186,21 @@ export default {
}
},
genericError: '¡Ups! Ha ocurrido un error. Por favor, inténtalo de nuevo.',
accessLevel: 'Nivel de acceso',
confirmCopilot: 'Confirma tu copiloto a continuación.',
accessLevelDescription: 'Elige un nivel de acceso a continuación. Tanto el acceso Completo como el Limitado permiten a los copilotos ver todas las conversaciones y gastos.',
roleDescription: (role?: string): string => {
switch (role) {
case CONST.DELEGATE_ROLE.ALL:
return 'Permite a otro miembro realizar todas las acciones en tu cuenta, en tu nombre. Incluye chat, presentaciones, aprobaciones, pagos, actualizaciones de configuración y más.';
case CONST.DELEGATE_ROLE.SUBMITTER:
return 'Permite a otro miembro realizar la mayoría de las acciones en tu cuenta, en tu nombre. Excluye aprobaciones, pagos, rechazos y retenciones.';
default:
return '';
}
},
makeSureItIsYou: 'Vamos a asegurarnos de que eres tú',
enterMagicCode: ({contactMethod}: EnterMagicCodeParams) => `Por favor, introduce el código mágico enviado a ${contactMethod} para agregar un copiloto.`,
notAllowed: 'No tan rápido...',
notAllowedMessageStart: ({accountOwnerEmail}: AccountOwnerParams) => `No tienes permiso para realizar esta acción para ${accountOwnerEmail}`,
notAllowedMessageHyperLinked: ' copiloto con acceso',
Expand Down
9 changes: 9 additions & 0 deletions src/libs/API/parameters/AddDelegateParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {DelegateRole} from '@src/types/onyx/Account';

type AddDelegateParams = {
delegate: string;
role: DelegateRole;
validateCode: string;
};

export default AddDelegateParams;
Loading
Loading