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

fix: Update the default copy in the Description section of the workspace profile AND update the copy in the last step of the workspace invite flow. #55700

Merged
merged 4 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 2 additions & 3 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ import type {
WaitingOnBankAccountParams,
WalletProgramParams,
WelcomeEnterMagicCodeParams,
WelcomeNoteParams,
WelcomeToRoomParams,
WeSentYouMagicSignInLinkParams,
WorkspaceLockedPlanTypeParams,
Expand Down Expand Up @@ -2641,8 +2640,8 @@ const translations = {
moreFeatures: 'More features',
requested: 'Requested',
distanceRates: 'Distance rates',
welcomeNote: ({workspaceName}: WelcomeNoteParams) =>
`You've been invited to ${workspaceName || 'a workspace'}! Get the most out of Expensify by downloading the app at use.expensify.com/download.`,
defaultDescription: 'One place for all your receipts and expenses.',
welcomeNote: 'Please use Expensify to submit your receipts for reimbursement, thanks!',
subscription: 'Subscription',
markAsExported: 'Mark as manually entered',
exportIntegrationSelected: ({connectionName}: ExportIntegrationSelectedParams) => `Export to ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]}`,
Expand Down
5 changes: 2 additions & 3 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ import type {
WaitingOnBankAccountParams,
WalletProgramParams,
WelcomeEnterMagicCodeParams,
WelcomeNoteParams,
WelcomeToRoomParams,
WeSentYouMagicSignInLinkParams,
WorkspaceLockedPlanTypeParams,
Expand Down Expand Up @@ -2664,8 +2663,8 @@ const translations = {
moreFeatures: 'Más características',
requested: 'Solicitado',
distanceRates: 'Tasas de distancia',
welcomeNote: ({workspaceName}: WelcomeNoteParams) =>
`¡Has sido invitado a ${workspaceName || 'un espacio de trabajo'}! Saca el máximo provecho de Expensify descargando la aplicación en use.expensify.com/download.`,
defaultDescription: 'Un solo lugar para todos tus recibos y gastos.',
welcomeNote: `Por favor, utiliza Expensify para enviar tus recibos para reembolso, ¡gracias!`,
subscription: 'Suscripción',
markAsExported: 'Marcar como introducido manualmente',
exportIntegrationSelected: ({connectionName}: ExportIntegrationSelectedParams) => `Exportar a ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]}`,
Expand Down
3 changes: 0 additions & 3 deletions src/languages/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,6 @@ type UserIsAlreadyMemberParams = {login: string; name: string};

type GoToRoomParams = {roomName: string};

type WelcomeNoteParams = {workspaceName: string};

type RoomNameReservedErrorParams = {reservedName: string};

type RenamedRoomActionParams = {oldName: string; newName: string};
Expand Down Expand Up @@ -773,7 +771,6 @@ export type {
WalletProgramParams,
WeSentYouMagicSignInLinkParams,
WelcomeEnterMagicCodeParams,
WelcomeNoteParams,
WelcomeToRoomParams,
ZipCodeExampleFormatParams,
ChangeFieldParams,
Expand Down
10 changes: 2 additions & 8 deletions src/pages/workspace/WorkspaceInviteMessagePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {setWorkspaceInviteMessageDraft} from '@libs/actions/Policy/Policy';
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import {getAvatarsForAccountIDs} from '@libs/OptionsListUtils';
import Parser from '@libs/Parser';
import {getMemberAccountIDsForWorkspace, goBackFromInvalidPolicy} from '@libs/PolicyUtils';
import updateMultilineInputRange from '@libs/updateMultilineInputRange';
import type {SettingsNavigatorParamList} from '@navigation/types';
Expand Down Expand Up @@ -75,14 +74,9 @@ function WorkspaceInviteMessagePage({policy, route, currentUserPersonalDetails}:
// workspaceInviteMessageDraft can be an empty string
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
workspaceInviteMessageDraft ??
// policy?.description can be an empty string
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
(Parser.htmlToMarkdown(policy?.description ?? '') ||
translate('workspace.common.welcomeNote', {
workspaceName: policy?.name ?? '',
}))
translate('workspace.common.welcomeNote')
);
}, [workspaceInviteMessageDraft, policy, translate, formData]);
}, [workspaceInviteMessageDraft, translate, formData]);

useEffect(() => {
if (isOnyxLoading) {
Expand Down
15 changes: 5 additions & 10 deletions src/pages/workspace/WorkspaceProfileDescriptionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import TextInput from '@components/TextInput';
import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import {updateWorkspaceDescription} from '@libs/actions/Policy/Policy';
import {addErrorMessage} from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import Parser from '@libs/Parser';
import updateMultilineInputRange from '@libs/updateMultilineInputRange';
import variables from '@styles/variables';
import * as Policy from '@userActions/Policy/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper';
Expand All @@ -31,12 +31,7 @@ function WorkspaceProfileDescriptionPage({policy}: Props) {
Parser.htmlToMarkdown(
// policy?.description can be an empty string
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
policy?.description ||
Parser.replace(
translate('workspace.common.welcomeNote', {
workspaceName: policy?.name ?? '',
}),
),
policy?.description || Parser.replace(translate('workspace.common.defaultDescription')),
),
);

Expand All @@ -49,7 +44,7 @@ function WorkspaceProfileDescriptionPage({policy}: Props) {
const errors = {};

if (values.description.length > CONST.DESCRIPTION_LIMIT) {
ErrorUtils.addErrorMessage(errors, 'description', translate('common.error.characterLimitExceedCounter', {length: values.description.length, limit: CONST.DESCRIPTION_LIMIT}));
addErrorMessage(errors, 'description', translate('common.error.characterLimitExceedCounter', {length: values.description.length, limit: CONST.DESCRIPTION_LIMIT}));
}

return errors;
Expand All @@ -63,7 +58,7 @@ function WorkspaceProfileDescriptionPage({policy}: Props) {
return;
}

Policy.updateWorkspaceDescription(policy.id, values.description.trim(), policy.description ?? '');
updateWorkspaceDescription(policy.id, values.description.trim(), policy.description ?? '');
Keyboard.dismiss();
Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.goBack());
},
Expand Down
53 changes: 24 additions & 29 deletions src/pages/workspace/WorkspaceProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ import usePermissions from '@hooks/usePermissions';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeIllustrations from '@hooks/useThemeIllustrations';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import {clearInviteDraft} from '@libs/actions/Policy/Member';
import {clearAvatarErrors, clearPolicyErrorField, deleteWorkspace, deleteWorkspaceAvatar, openPolicyProfilePage, updateWorkspaceAvatar} from '@libs/actions/Policy/Policy';
import {getLatestErrorField} from '@libs/ErrorUtils';
import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute';
import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import type {FullScreenNavigatorParamList, RootStackParamList, State} from '@libs/Navigation/types';
import Parser from '@libs/Parser';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ReportUtils from '@libs/ReportUtils';
import {getUserFriendlyWorkspaceType, getWorkspaceAccountID, isPolicyAdmin as isPolicyAdminPolicyUtils, isPolicyOwner} from '@libs/PolicyUtils';
import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils';
import StringUtils from '@libs/StringUtils';
import * as UserUtils from '@libs/UserUtils';
import * as Member from '@userActions/Policy/Member';
import * as Policy from '@userActions/Policy/Policy';
import {getFullSizeAvatar} from '@libs/UserUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
Expand All @@ -55,13 +55,13 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac

// When we create a new workspace, the policy prop will be empty on the first render. Therefore, we have to use policyDraft until policy has been set in Onyx.
const policy = policyDraft?.id ? policyDraft : policyProp;
const isPolicyAdmin = PolicyUtils.isPolicyAdmin(policy);
const isPolicyAdmin = isPolicyAdminPolicyUtils(policy);
const outputCurrency = policy?.outputCurrency ?? '';
const currencySymbol = currencyList?.[outputCurrency]?.symbol ?? '';
const formattedCurrency = !isEmptyObject(policy) && !isEmptyObject(currencyList) ? `${outputCurrency} - ${currencySymbol}` : '';

// We need this to update translation for deleting a workspace when it has third party card feeds or expensify card assigned.
const workspaceAccountID = policy?.id ? PolicyUtils.getWorkspaceAccountID(policy.id) : CONST.DEFAULT_NUMBER_ID;
const workspaceAccountID = policy?.id ? getWorkspaceAccountID(policy.id) : CONST.DEFAULT_NUMBER_ID;
const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`);
const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`);
const hasCardFeedOrExpensifyCard =
Expand Down Expand Up @@ -114,22 +114,17 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
const policyDescription =
// policy?.description can be an empty string
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
policy?.description ||
Parser.replace(
translate('workspace.common.welcomeNote', {
workspaceName: policy?.name ?? '',
}),
);
const readOnly = !PolicyUtils.isPolicyAdmin(policy);
const isOwner = PolicyUtils.isPolicyOwner(policy, currentUserAccountID);
policy?.description || Parser.replace(translate('workspace.common.defaultDescription'));
const readOnly = !isPolicyAdminPolicyUtils(policy);
const isOwner = isPolicyOwner(policy, currentUserAccountID);
const imageStyle: StyleProp<ImageStyle> = shouldUseNarrowLayout ? [styles.mhv12, styles.mhn5, styles.mbn5] : [styles.mhv8, styles.mhn8, styles.mbn5];
const shouldShowAddress = !readOnly || !!formattedAddress;

const fetchPolicyData = useCallback(() => {
if (policyDraft?.id) {
return;
}
Policy.openPolicyProfilePage(route.params.policyID);
openPolicyProfilePage(route.params.policyID);
}, [policyDraft?.id, route.params.policyID]);

useNetwork({onReconnect: fetchPolicyData});
Expand All @@ -148,7 +143,7 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
containerStyles={styles.avatarXLarge}
imageStyles={[styles.avatarXLarge, styles.alignSelfCenter]}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- nullish coalescing cannot be used if left side can be empty string
source={policy?.avatarURL || ReportUtils.getDefaultWorkspaceAvatar(policyName)}
source={policy?.avatarURL || getDefaultWorkspaceAvatar(policyName)}
fallbackIcon={Expensicons.FallbackWorkspaceAvatar}
size={CONST.AVATAR_SIZE.XLARGE}
name={policyName}
Expand All @@ -166,7 +161,7 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
return;
}

Policy.deleteWorkspace(policy.id, policyName);
deleteWorkspace(policy.id, policyName);
setIsDeleteModalOpen(false);

// If the workspace being deleted is the active workspace, switch to the "All Workspaces" view
Expand Down Expand Up @@ -232,13 +227,13 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
if (!policy?.id) {
return;
}
Policy.updateWorkspaceAvatar(policy.id, file as File);
updateWorkspaceAvatar(policy.id, file as File);
}}
onImageRemoved={() => {
if (!policy?.id) {
return;
}
Policy.deleteWorkspaceAvatar(policy.id);
deleteWorkspaceAvatar(policy.id);
}}
editorMaskImage={Expensicons.ImageCropSquareMask}
pendingAction={policy?.pendingFields?.avatarURL}
Expand All @@ -247,9 +242,9 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
if (!policy?.id) {
return;
}
Policy.clearAvatarErrors(policy.id);
clearAvatarErrors(policy.id);
}}
previewSource={UserUtils.getFullSizeAvatar(policy?.avatarURL ?? '')}
previewSource={getFullSizeAvatar(policy?.avatarURL ?? '')}
headerTitle={translate('workspace.common.workspaceAvatar')}
originalFileName={policy?.originalFileName}
disabled={readOnly}
Expand All @@ -270,12 +265,12 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
{(!StringUtils.isEmptyString(policy?.description ?? '') || !readOnly) && (
<OfflineWithFeedback
pendingAction={policy?.pendingFields?.description}
errors={ErrorUtils.getLatestErrorField(policy ?? {}, CONST.POLICY.COLLECTION_KEYS.DESCRIPTION)}
errors={getLatestErrorField(policy ?? {}, CONST.POLICY.COLLECTION_KEYS.DESCRIPTION)}
onClose={() => {
if (!policy?.id) {
return;
}
Policy.clearPolicyErrorField(policy.id, CONST.POLICY.COLLECTION_KEYS.DESCRIPTION);
clearPolicyErrorField(policy.id, CONST.POLICY.COLLECTION_KEYS.DESCRIPTION);
}}
>
<MenuItemWithTopDescription
Expand All @@ -291,12 +286,12 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
)}
<OfflineWithFeedback
pendingAction={policy?.pendingFields?.outputCurrency}
errors={ErrorUtils.getLatestErrorField(policy ?? {}, CONST.POLICY.COLLECTION_KEYS.GENERAL_SETTINGS)}
errors={getLatestErrorField(policy ?? {}, CONST.POLICY.COLLECTION_KEYS.GENERAL_SETTINGS)}
onClose={() => {
if (!policy?.id) {
return;
}
Policy.clearPolicyErrorField(policy.id, CONST.POLICY.COLLECTION_KEYS.GENERAL_SETTINGS);
clearPolicyErrorField(policy.id, CONST.POLICY.COLLECTION_KEYS.GENERAL_SETTINGS);
}}
errorRowStyles={[styles.mt2]}
>
Expand Down Expand Up @@ -331,7 +326,7 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
<OfflineWithFeedback pendingAction={policy?.pendingFields?.type}>
<View>
<MenuItemWithTopDescription
title={PolicyUtils.getUserFriendlyWorkspaceType(policy.type)}
title={getUserFriendlyWorkspaceType(policy.type)}
description={translate('workspace.common.planType')}
shouldShowRightIcon
wrapperStyle={styles.sectionMenuItemTopDescription}
Expand All @@ -347,7 +342,7 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
accessibilityLabel={translate('common.invite')}
text={translate('common.invite')}
onPress={() => {
Member.clearInviteDraft(route.params.policyID);
clearInviteDraft(route.params.policyID);
Navigation.navigate(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID, Navigation.getActiveRouteWithoutParams()));
}}
icon={Expensicons.UserPlus}
Expand Down
Loading