diff --git a/src/components/SpendRules/SpendRulesSection.tsx b/src/components/SpendRules/SpendRulesSection.tsx
index 6378179a01f5..9a2ac9ac433f 100644
--- a/src/components/SpendRules/SpendRulesSection.tsx
+++ b/src/components/SpendRules/SpendRulesSection.tsx
@@ -32,10 +32,9 @@ import ROUTES from '@src/ROUTES';
type SpendRulesSectionProps = {
policyID: string;
- canWriteRules: boolean;
};
-function SpendRulesSection({policyID, canWriteRules}: SpendRulesSectionProps) {
+function SpendRulesSection({policyID}: SpendRulesSectionProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
@@ -159,8 +158,7 @@ function SpendRulesSection({policyID, canWriteRules}: SpendRulesSectionProps) {
accessibilityLabel={`${descriptionLabel}. ${blockLabel} ${defaultRuleTitle}`}
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.RULES.SPEND_RULE_ITEM}
onPress={showBuiltInProtectionModal}
- shouldShowRightIcon={canWriteRules}
- interactive={canWriteRules}
+ shouldShowRightIcon
/>
{isLoadingCardRules ? (
@@ -180,12 +178,11 @@ function SpendRulesSection({policyID, canWriteRules}: SpendRulesSectionProps) {
pendingAction={rule.pendingAction}
>
- {!isLoading && canWriteCompanyCards && (isFeedConnectionBroken || hasFeedErrors) && (
+ {!isLoading && (isFeedConnectionBroken || hasFeedErrors) && (
void;
};
-function WorkspaceCompanyCardTableRow({
- item,
- policyID,
- CardFeedIcon,
- shouldUseNarrowTableLayout,
- rowIndex,
- isAssigningCardDisabled,
- canWriteCompanyCards,
- onAssignCard,
-}: WorkspaceCompanyCardTableRowProps) {
+function WorkspaceCompanyCardTableRow({item, policyID, CardFeedIcon, shouldUseNarrowTableLayout, rowIndex, isAssigningCardDisabled, onAssignCard}: WorkspaceCompanyCardTableRowProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {isOffline} = useNetwork();
@@ -106,28 +94,20 @@ function WorkspaceCompanyCardTableRow({
? {width: variables.cardAvatarWidth, height: variables.cardAvatarHeight}
: {width: variables.cardAvatarWidthSmall, height: variables.cardAvatarHeightSmall};
- const canOpenCardDetails = !!assignedCard?.accountID && !!assignedCard?.fundID && assignedCard?.cardID !== undefined;
- const canAssignCard = !isAssigned && canWriteCompanyCards && !isAssigningCardDisabled;
- const canPressRow = canOpenCardDetails || canAssignCard;
-
const handleRowPress = () => {
if (!assignedCard) {
- if (!canAssignCard) {
- return;
- }
onAssignCard(cardName, encryptedCardNumber);
return;
}
- const {cardID, fundID} = assignedCard;
- if (!canOpenCardDetails || cardID === undefined || !fundID) {
+ if (!assignedCard?.accountID || !assignedCard?.fundID) {
return;
}
- const feedName = getCardFeedWithDomainID(assignedCard?.bank as CompanyCardFeed, fundID);
+ const feedName = getCardFeedWithDomainID(assignedCard?.bank as CompanyCardFeed, assignedCard.fundID);
- return Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARD_DETAILS.getRoute(policyID, feedName as CompanyCardFeedWithDomainID, cardID.toString()));
+ return Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARD_DETAILS.getRoute(policyID, feedName as CompanyCardFeedWithDomainID, assignedCard.cardID.toString()));
};
return (
@@ -135,7 +115,7 @@ function WorkspaceCompanyCardTableRow({
interactive
rowIndex={rowIndex}
isLoading={isDeleting}
- disabled={isCardDeleted || !canPressRow}
+ disabled={isCardDeleted || isAssigningCardDisabled}
skeletonReasonAttributes={reasonAttributes}
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.COMPANY_CARDS.TABLE_ITEM}
LoadingComponent={WorkspaceCompanyCardsTableSkeleton}
@@ -195,7 +175,7 @@ function WorkspaceCompanyCardTableRow({
)}
- {!isAssigned && canWriteCompanyCards && (
+ {!isAssigned && (
)}
- {canPressRow && (
-
- )}
+
>
)}
diff --git a/src/components/Tables/WorkspaceCompanyCardsTable/index.tsx b/src/components/Tables/WorkspaceCompanyCardsTable/index.tsx
index b56af8ba7bc5..fddd8b5c2640 100644
--- a/src/components/Tables/WorkspaceCompanyCardsTable/index.tsx
+++ b/src/components/Tables/WorkspaceCompanyCardsTable/index.tsx
@@ -51,9 +51,6 @@ type WorkspaceCompanyCardsTableProps = {
/** Whether to disable assign card button */
isAssigningCardDisabled: boolean;
- /** Whether the current member can edit company cards */
- canWriteCompanyCards: boolean;
-
/** On assign card callback */
onAssignCard: (cardID: string, encryptedCardNumber: string) => void;
@@ -71,7 +68,6 @@ function WorkspaceCompanyCardsTable({
companyCards,
onAssignCard,
isAssigningCardDisabled,
- canWriteCompanyCards,
onReloadPage,
onReloadFeed,
}: WorkspaceCompanyCardsTableProps) {
@@ -296,7 +292,6 @@ function WorkspaceCompanyCardsTable({
CardFeedIcon={cardFeedIcon}
onAssignCard={onAssignCard}
isAssigningCardDisabled={isAssigningCardDisabled}
- canWriteCompanyCards={canWriteCompanyCards}
shouldUseNarrowTableLayout={shouldUseNarrowTableLayout}
/>
);
@@ -340,7 +335,6 @@ function WorkspaceCompanyCardsTable({
policyID={policyID}
feedName={feedName}
showTableControls={showTableControls}
- canWriteCompanyCards={canWriteCompanyCards}
CardFeedIcon={cardFeedIcon}
/>
@@ -401,7 +395,6 @@ function WorkspaceCompanyCardsTable({
)}
diff --git a/src/hooks/usePolicyFeatureWriteAccess.ts b/src/hooks/usePolicyFeatureWriteAccess.ts
deleted file mode 100644
index ed2cf02243c1..000000000000
--- a/src/hooks/usePolicyFeatureWriteAccess.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import {canMemberWrite} from '@libs/PolicyUtils';
-import type {PolicyFeature} from '@libs/PolicyUtils';
-import type {OnyxInputOrEntry, Policy} from '@src/types/onyx';
-import useConfirmModal from './useConfirmModal';
-import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
-import useLocalize from './useLocalize';
-
-function usePolicyFeatureWriteAccess(policy: OnyxInputOrEntry, feature: PolicyFeature) {
- const {translate} = useLocalize();
- const {showConfirmModal} = useConfirmModal();
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
- const canWrite = canMemberWrite(policy, currentUserLogin, feature);
-
- const showReadOnlyModal = () => {
- showConfirmModal({
- title: translate('workspace.common.readOnlyActionTitle'),
- prompt: translate('workspace.common.readOnlyActionPrompt'),
- confirmText: translate('common.buttonConfirm'),
- shouldShowCancelButton: false,
- });
- };
-
- const getReadOnlyDisabledAction = (disabledAction?: () => void | Promise) => {
- if (!canWrite) {
- return showReadOnlyModal;
- }
-
- return disabledAction;
- };
-
- return {canWrite, showReadOnlyModal, getReadOnlyDisabledAction};
-}
-
-export default usePolicyFeatureWriteAccess;
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 73a59da66d08..2ef9678af1c7 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -4414,8 +4414,6 @@ ${amount} für ${merchant} – ${date}`,
cardAdminAlternateText: 'Arbeitsbereichskarten verwalten.',
peopleAdminAlternateText: 'Mitglieder und Genehmigungsabläufe verwalten.',
paymentsAdminAlternateText: 'Workflow-Zahlungen verwalten.',
- readOnlyActionTitle: 'Nicht so schnell …',
- readOnlyActionPrompt: 'Ihre Arbeitsbereichsrolle kann diese Einstellungen anzeigen, aber nicht bearbeiten.',
},
createdForClient: {
title: 'Du hast einen Workspace für deinen Kunden erstellt!',
diff --git a/src/languages/en.ts b/src/languages/en.ts
index ef149ad0c94d..f9f5f69df835 100644
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -4399,8 +4399,6 @@ const translations = {
unavailable: 'Unavailable workspace',
memberNotFound: 'Member not found. To invite a new member to the workspace, please use the invite button above.',
notAuthorized: `You don't have access to this page. If you're trying to join this workspace, just ask the workspace owner to add you as a member. Something else? Reach out to ${CONST.EMAIL.CONCIERGE}.`,
- readOnlyActionTitle: 'Not so fast...',
- readOnlyActionPrompt: "Your workspace role can view these settings, but can't edit them.",
goToWorkspace: 'Go to workspace',
duplicateWorkspace: 'Duplicate workspace',
duplicateWorkspacePrefix: 'Duplicate',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 810476825385..1bc0734e1be7 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -4199,8 +4199,6 @@ ${amount} para ${merchant} - ${date}`,
unavailable: 'Espacio de trabajo no disponible',
memberNotFound: 'Miembro no encontrado. Para invitar a un nuevo miembro al espacio de trabajo, por favor, utiliza el botón invitar que está arriba.',
notAuthorized: `No tienes acceso a esta página. Si estás intentando unirte a este espacio de trabajo, pide al dueño del espacio de trabajo que te añada como miembro. ¿Necesitas algo más? Comunícate con ${CONST.EMAIL.CONCIERGE}`,
- readOnlyActionTitle: 'No tan rápido...',
- readOnlyActionPrompt: 'Tu rol en el espacio de trabajo puede ver estos ajustes, pero no puede editarlos.',
goToWorkspace: 'Ir al espacio de trabajo',
duplicateWorkspace: 'Duplicar espacio de trabajo',
duplicateWorkspacePrefix: 'Duplicar',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 57360072a731..efd418be962a 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -2978,7 +2978,7 @@ ${amount} pour ${merchant} - ${date}`,
phoneOrEmail: 'Téléphone ou e-mail',
error: {
agentSignInBlocked:
- 'Les comptes d’agent ne permettent pas de se connecter directement. Pour utiliser un agent, connectez-vous avec votre propre compte et accédez-y via Copilot.',
+ 'Les comptes d\u2019agent ne permettent pas de se connecter directement. Pour utiliser un agent, connectez-vous avec votre propre compte et accédez-y via Copilot.',
invalidFormatEmailLogin: 'L’adresse e-mail saisie est invalide. Veuillez corriger le format et réessayer.',
},
cannotGetAccountDetails: 'Impossible de récupérer les détails du compte. Veuillez essayer de vous reconnecter.',
@@ -4425,8 +4425,6 @@ ${amount} pour ${merchant} - ${date}`,
cardAdminAlternateText: 'Gérer les cartes de l’espace de travail.',
peopleAdminAlternateText: 'Gérez les membres et les workflows d’approbation.',
paymentsAdminAlternateText: 'Gérer les paiements de workflow.',
- readOnlyActionTitle: 'Pas si vite...',
- readOnlyActionPrompt: 'Votre rôle dans cet espace de travail peut afficher ces paramètres, mais ne peut pas les modifier.',
},
createdForClient: {
title: 'Vous avez créé un espace de travail pour votre client !',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 051aedcc4544..183bac3e38c5 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -4399,8 +4399,6 @@ ${amount} per ${merchant} - ${date}`,
cardAdminAlternateText: 'Gestisci le carte dello spazio di lavoro.',
peopleAdminAlternateText: 'Gestisci i membri e i flussi di approvazione.',
paymentsAdminAlternateText: 'Gestisci i pagamenti del flusso di lavoro.',
- readOnlyActionTitle: 'Non così in fretta...',
- readOnlyActionPrompt: 'Il tuo ruolo nello spazio di lavoro può visualizzare queste impostazioni, ma non può modificarle.',
},
createdForClient: {
title: 'Hai creato uno spazio di lavoro per il tuo cliente!',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 6c670e1a9122..e303f09ee8df 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -4368,8 +4368,6 @@ ${integrationName === CONST.ONBOARDING_ACCOUNTING_MAPPING.other ? 'あなたの'
cardAdminAlternateText: 'ワークスペースカードを管理します。',
peopleAdminAlternateText: 'メンバーと承認ワークフローを管理します。',
paymentsAdminAlternateText: 'ワークフローの支払いを管理します。',
- readOnlyActionTitle: 'ちょっと待ってください…',
- readOnlyActionPrompt: 'このワークスペースでのあなたのロールは、これらの設定を表示できますが、編集することはできません。',
},
createdForClient: {
title: 'クライアントのワークスペースを作成しました!',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index c46fe4664738..de98d8bd216a 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -4395,8 +4395,6 @@ ${amount} voor ${merchant} - ${date}`,
cardAdminAlternateText: 'Werkruimtekaarten beheren.',
peopleAdminAlternateText: 'Beheer leden en goedkeuringsworkflows.',
paymentsAdminAlternateText: 'Workflowsbetalingen beheren.',
- readOnlyActionTitle: 'Niet zo snel...',
- readOnlyActionPrompt: 'Je rol in de workspace kan deze instellingen bekijken, maar niet bewerken.',
},
createdForClient: {
title: 'Je hebt een werkruimte voor je klant aangemaakt!',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index b16eea888463..7d94f069f5c6 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -4387,8 +4387,6 @@ ${amount} dla ${merchant} - ${date}`,
cardAdminAlternateText: 'Zarządzaj kartami przestrzeni roboczej.',
peopleAdminAlternateText: 'Zarządzaj członkami i procesami akceptacji.',
paymentsAdminAlternateText: 'Zarządzaj płatnościami w przepływie pracy.',
- readOnlyActionTitle: 'Nie tak szybko…',
- readOnlyActionPrompt: 'Twoja rola w przestrzeni roboczej może wyświetlać te ustawienia, ale nie może ich edytować.',
},
createdForClient: {
title: 'Utworzyłeś przestrzeń roboczą dla swojego klienta!',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 71ba13605cd2..2576f18100ef 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -4389,8 +4389,6 @@ ${amount} para ${merchant} - ${date}`,
cardAdminAlternateText: 'Gerenciar cartões do workspace.',
peopleAdminAlternateText: 'Gerencie membros e fluxos de aprovação.',
paymentsAdminAlternateText: 'Gerencie pagamentos de fluxo de trabalho.',
- readOnlyActionTitle: 'Calma aí...',
- readOnlyActionPrompt: 'Sua função no workspace pode ver essas configurações, mas não pode editá-las.',
},
createdForClient: {
title: 'Você criou um espaço de trabalho para seu cliente!',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 970ae5c097bc..6032a1f29c6b 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -4290,8 +4290,6 @@ ${amount},商户:${merchant} - 日期:${date}`,
cardAdminAlternateText: '管理工作区卡片。',
peopleAdminAlternateText: '管理成员和审批流程。',
paymentsAdminAlternateText: '管理工作流付款。',
- readOnlyActionTitle: '别急……',
- readOnlyActionPrompt: '你的工作区角色可以查看这些设置,但不能编辑。',
},
createdForClient: {
title: '您已为客户创建了工作区!',
diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts
index 729a50566a02..38a83c73463b 100644
--- a/src/libs/PolicyUtils.ts
+++ b/src/libs/PolicyUtils.ts
@@ -174,18 +174,8 @@ const ROLE_PERMISSION_BUNDLES: Record controlPolicyOnlyRole === role);
-}
-
function hasPolicyFeaturePermission(policy: OnyxInputOrEntry, login: string, feature: PolicyFeature, requiredAccess: PolicyFeatureAccess): boolean {
- const role = getPolicyRole(policy, login, !login);
- if (isControlPolicyOnlyRole(role) && (!policy || !isControlPolicy(policy))) {
- return false;
- }
-
+ const role = getPolicyRole(policy, login, false);
const access = role ? ROLE_PERMISSION_BUNDLES[role]?.[feature] : undefined;
if (requiredAccess === CONST.POLICY.POLICY_FEATURE_ACCESS.READ) {
diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
index 0fa296a87b49..722c933fe9bf 100644
--- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx
+++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx
@@ -187,8 +187,7 @@ function AccessOrNotFoundWrapper({
const {isOffline} = useNetwork();
const isReportArchived = useReportIsArchived(report?.reportID);
- const accessVariantsToCheck = policyFeature ? accessVariants.filter((variant) => variant !== CONST.POLICY.ACCESS_VARIANTS.ADMIN) : accessVariants;
- const isPageAccessible = accessVariantsToCheck.reduce((acc, variant) => {
+ const isPageAccessible = accessVariants.reduce((acc, variant) => {
const accessFunction = ACCESS_VARIANTS[variant];
if (variant === CONST.IOU.ACCESS_VARIANTS.CREATE) {
return acc && accessFunction(policy, login, report, allPolicies ?? null, betas, iouType, isReportArchived, isRestrictedToPreferredPolicy);
diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx
index 2f2747ad4aee..931c5ff34dac 100644
--- a/src/pages/workspace/WorkspaceInitialPage.tsx
+++ b/src/pages/workspace/WorkspaceInitialPage.tsx
@@ -35,7 +35,7 @@ import goBackFromWorkspaceSettingPages from '@libs/Navigation/helpers/goBackFrom
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import {
- canMemberRead,
+ canEditWorkspaceSettings,
canPolicyAccessFeature,
shouldShowPolicy as checkIfShouldShowPolicy,
goBackFromInvalidPolicy,
@@ -48,7 +48,6 @@ import {
shouldShowSyncError,
shouldShowTaxRateError,
} from '@libs/PolicyUtils';
-import type {PolicyFeature} from '@libs/PolicyUtils';
import {getDefaultWorkspaceAvatar} from '@libs/ReportUtils';
import type WORKSPACE_TO_RHP from '@navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP';
import type {WorkspaceSplitNavigatorParamList} from '@navigation/types';
@@ -139,22 +138,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
const policyName = policy?.name ?? '';
const hasPolicyCreationError = policy?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && !isEmptyObject(policy.errors);
- const canReadPolicyFeature = (policyFeature: PolicyFeature) => canMemberRead(policy, currentUserLogin ?? '', policyFeature);
- const canReadMoreFeatures = canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
- const shouldShowProtectedItems = [
- CONST.POLICY.POLICY_FEATURE.REPORT_FIELDS,
- CONST.POLICY.POLICY_FEATURE.ACCOUNTING,
- CONST.POLICY.POLICY_FEATURE.CATEGORIES,
- CONST.POLICY.POLICY_FEATURE.TAGS,
- CONST.POLICY.POLICY_FEATURE.TAXES,
- CONST.POLICY.POLICY_FEATURE.WORKFLOWS,
- CONST.POLICY.POLICY_FEATURE.RULES,
- CONST.POLICY.POLICY_FEATURE.DISTANCE_RATES,
- CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD,
- CONST.POLICY.POLICY_FEATURE.COMPANY_CARDS,
- CONST.POLICY.POLICY_FEATURE.PER_DIEM,
- CONST.POLICY.POLICY_FEATURE.MORE_FEATURES,
- ].some(canReadPolicyFeature);
+ const shouldShowProtectedItems = canEditWorkspaceSettings(policy);
const accountingConnectionNames = CONST.POLICY.CONNECTIONS.ACCOUNTING_CONNECTION_NAMES;
const hasSyncError = shouldShowSyncError(policy, isConnectionInProgress(connectionSyncProgress, policy), accountingConnectionNames);
@@ -264,17 +248,15 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
}
if (isGroupPolicy(policy) && shouldShowProtectedItems) {
- if (canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.REPORT_FIELDS)) {
- workspaceMenuItems.push({
- translationKey: 'common.reports',
- icon: expensifyIcons.Document,
- action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_REPORTS.getRoute(policyID)))),
- screenName: SCREENS.WORKSPACE.REPORTS,
- sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.INITIAL.REPORTS,
- });
- }
+ workspaceMenuItems.push({
+ translationKey: 'common.reports',
+ icon: expensifyIcons.Document,
+ action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_REPORTS.getRoute(policyID)))),
+ screenName: SCREENS.WORKSPACE.REPORTS,
+ sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.INITIAL.REPORTS,
+ });
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.ACCOUNTING)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.accounting',
icon: expensifyIcons.Sync,
@@ -286,7 +268,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.IS_HR_ENABLED] && canReadMoreFeatures) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.IS_HR_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.hr',
icon: expensifyIcons.Users,
@@ -297,7 +279,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RECEIPT_PARTNERS_ENABLED] && canReadMoreFeatures) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RECEIPT_PARTNERS_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.receiptPartners',
brickRoadIndicator: shouldShowEnterCredentialsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
@@ -309,7 +291,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.CATEGORIES)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.categories',
icon: expensifyIcons.Folder,
@@ -321,7 +303,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.TAGS)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.tags',
icon: expensifyIcons.Tag,
@@ -332,7 +314,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.TAXES)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.taxes',
icon: expensifyIcons.Coins,
@@ -344,7 +326,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.WORKFLOWS)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.workflows',
icon: expensifyIcons.Workflows,
@@ -356,7 +338,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.RULES)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.rules',
icon: expensifyIcons.Feed,
@@ -367,7 +349,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.DISTANCE_RATES)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.distanceRates',
icon: expensifyIcons.Car,
@@ -378,7 +360,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.IS_TRAVEL_ENABLED] && canReadMoreFeatures) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.IS_TRAVEL_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.travel',
icon: expensifyIcons.LuggageWithLines,
@@ -389,7 +371,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.expensifyCard',
icon: expensifyIcons.ExpensifyCard,
@@ -400,7 +382,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.COMPANY_CARDS)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'workspace.common.companyCards',
icon: expensifyIcons.CreditCard,
@@ -412,7 +394,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_PER_DIEM_RATES_ENABLED] && canReadPolicyFeature(CONST.POLICY.POLICY_FEATURE.PER_DIEM)) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_PER_DIEM_RATES_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'common.perDiem',
icon: expensifyIcons.CalendarSolid,
@@ -423,7 +405,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.IS_TIME_TRACKING_ENABLED] && canReadMoreFeatures) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.IS_TIME_TRACKING_ENABLED]) {
workspaceMenuItems.push({
translationKey: 'iou.time',
icon: expensifyIcons.Clock,
@@ -434,7 +416,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_INVOICES_ENABLED] && canReadMoreFeatures) {
+ if (policyFeatureStates?.[CONST.POLICY.MORE_FEATURES.ARE_INVOICES_ENABLED]) {
const currencyCode = policy?.outputCurrency ?? CONST.CURRENCY.USD;
workspaceMenuItems.push({
translationKey: 'workspace.common.invoices',
@@ -447,15 +429,13 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac
});
}
- if (canReadMoreFeatures) {
- workspaceMenuItems.push({
- translationKey: 'workspace.common.moreFeatures',
- icon: expensifyIcons.Gear,
- action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)))),
- screenName: SCREENS.WORKSPACE.MORE_FEATURES,
- sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.INITIAL.MORE_FEATURES,
- });
- }
+ workspaceMenuItems.push({
+ translationKey: 'workspace.common.moreFeatures',
+ icon: expensifyIcons.Gear,
+ action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)))),
+ screenName: SCREENS.WORKSPACE.MORE_FEATURES,
+ sentryLabel: CONST.SENTRY_LABEL.WORKSPACE.INITIAL.MORE_FEATURES,
+ });
}
// Close RHP if we land on a route that no longer exists in the menu
diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx
index 6ae64c3fab70..3a504c2c3d87 100644
--- a/src/pages/workspace/WorkspaceMembersPage.tsx
+++ b/src/pages/workspace/WorkspaceMembersPage.tsx
@@ -1036,7 +1036,6 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers
shouldUseHeadlineHeader={!selectionModeHeader}
shouldShowOfflineIndicatorInWideScreen
shouldShowNonAdmin
- policyFeature={CONST.POLICY.POLICY_FEATURE.MEMBERS}
onBackButtonPress={() => {
if (isMobileSelectionModeEnabled) {
setSelectedEmployees([]);
diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage/index.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage/index.tsx
index 4af0dd3129fb..bf4ef474e74e 100644
--- a/src/pages/workspace/WorkspaceMoreFeaturesPage/index.tsx
+++ b/src/pages/workspace/WorkspaceMoreFeaturesPage/index.tsx
@@ -15,7 +15,6 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePolicyData from '@hooks/usePolicyData';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceDocumentTitle from '@hooks/useWorkspaceDocumentTitle';
@@ -125,7 +124,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
const isSmartLimitEnabled = isSmartLimitEnabledUtil(workspaceCards);
const settings = getCardSettings(cardSettings);
const paymentBankAccountID = settings?.paymentBankAccountID;
- const {canWrite: canWriteMoreFeatures, getReadOnlyDisabledAction} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
const warnAccountingManagesOrganizeFeature = async () => {
if (!hasAccountingConnection || !policyID) {
@@ -243,7 +241,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
{
if (!policyID) {
return;
@@ -301,8 +298,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.receiptPartners.subtitle')}
isActive={policy?.receiptPartners?.enabled ?? false}
pendingAction={policy?.pendingFields?.receiptPartners}
- disabled={!canWriteMoreFeatures || isUberConnected}
- disabledAction={getReadOnlyDisabledAction(warnReceiptPartnersStillConnected)}
+ disabled={isUberConnected}
+ disabledAction={warnReceiptPartnersStillConnected}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -329,8 +326,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.hr.subtitle')}
isActive={((policy?.isHREnabled === true || isAnyHRConnected(policy)) && canPolicyAccessFeature(policy, CONST.POLICY.MORE_FEATURES.IS_HR_ENABLED)) ?? false}
pendingAction={policy?.pendingFields?.isHREnabled}
- disabled={!canWriteMoreFeatures || isAnyHRConnected(policy)}
- disabledAction={getReadOnlyDisabledAction(warnDisconnectHRFirst)}
+ disabled={isAnyHRConnected(policy)}
+ disabledAction={warnDisconnectHRFirst}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -359,8 +356,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.categories.subtitle')}
isActive={policy?.areCategoriesEnabled ?? false}
pendingAction={policy?.pendingFields?.areCategoriesEnabled}
- disabled={!canWriteMoreFeatures || hasAccountingConnection}
- disabledAction={getReadOnlyDisabledAction(warnAccountingManagesOrganizeFeature)}
+ disabled={hasAccountingConnection}
+ disabledAction={warnAccountingManagesOrganizeFeature}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -380,8 +377,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.tags.subtitle')}
isActive={policy?.areTagsEnabled ?? false}
pendingAction={policy?.pendingFields?.areTagsEnabled}
- disabled={!canWriteMoreFeatures || hasAccountingConnection}
- disabledAction={getReadOnlyDisabledAction(warnAccountingManagesOrganizeFeature)}
+ disabled={hasAccountingConnection}
+ disabledAction={warnAccountingManagesOrganizeFeature}
onToggle={(isEnabled) => {
enablePolicyTags(policyData, isEnabled);
}}
@@ -398,8 +395,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.taxes.subtitle')}
isActive={(policy?.tax?.trackingEnabled ?? false) || isSyncTaxEnabled}
pendingAction={policy?.pendingFields?.tax}
- disabled={!canWriteMoreFeatures || hasAccountingConnection}
- disabledAction={getReadOnlyDisabledAction(warnAccountingManagesOrganizeFeature)}
+ disabled={hasAccountingConnection}
+ disabledAction={warnAccountingManagesOrganizeFeature}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -426,8 +423,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.workflows.subtitle')}
isActive={policy?.areWorkflowsEnabled ?? false}
pendingAction={policy?.pendingFields?.areWorkflowsEnabled}
- disabled={!canWriteMoreFeatures || isSmartLimitEnabled}
- disabledAction={getReadOnlyDisabledAction(promptDisableSmartLimitForWorkflows)}
+ disabled={isSmartLimitEnabled}
+ disabledAction={promptDisableSmartLimitForWorkflows}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -447,8 +444,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.rules.subtitle')}
isActive={policy?.areRulesEnabled ?? false}
pendingAction={policy?.pendingFields?.areRulesEnabled}
- disabled={!canWriteMoreFeatures}
- disabledAction={getReadOnlyDisabledAction()}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -477,8 +472,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.distanceRates.subtitle')}
isActive={policy?.areDistanceRatesEnabled ?? false}
pendingAction={policy?.pendingFields?.areDistanceRatesEnabled}
- disabled={!canWriteMoreFeatures}
- disabledAction={getReadOnlyDisabledAction()}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -498,8 +491,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.travel.subtitle')}
isActive={policy?.isTravelEnabled ?? false}
pendingAction={policy?.pendingFields?.isTravelEnabled}
- disabled={!canWriteMoreFeatures}
- disabledAction={getReadOnlyDisabledAction()}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -522,8 +513,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.expensifyCard.subtitle')}
isActive={policy?.areExpensifyCardsEnabled ?? false}
pendingAction={policy?.pendingFields?.areExpensifyCardsEnabled}
- disabled={!canWriteMoreFeatures || (!!policy?.areExpensifyCardsEnabled && !!paymentBankAccountID) || !isEmptyObject(cardsList)}
- disabledAction={getReadOnlyDisabledAction(promptDisableExpensifyCardViaConcierge)}
+ disabled={(!!policy?.areExpensifyCardsEnabled && !!paymentBankAccountID) || !isEmptyObject(cardsList)}
+ disabledAction={promptDisableExpensifyCardViaConcierge}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -546,8 +537,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.companyCards.subtitle')}
isActive={policy?.areCompanyCardsEnabled ?? false}
pendingAction={policy?.pendingFields?.areCompanyCardsEnabled}
- disabled={!canWriteMoreFeatures || !isEmptyObject(getCompanyFeeds(cardFeeds))}
- disabledAction={getReadOnlyDisabledAction(promptDisableCompanyCardsViaConcierge)}
+ disabled={!isEmptyObject(getCompanyFeeds(cardFeeds))}
+ disabledAction={promptDisableCompanyCardsViaConcierge}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -570,8 +561,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.perDiem.subtitle')}
isActive={(policy?.arePerDiemRatesEnabled && canPolicyAccessFeature(policy, CONST.POLICY.MORE_FEATURES.ARE_PER_DIEM_RATES_ENABLED)) ?? false}
pendingAction={policy?.pendingFields?.arePerDiemRatesEnabled}
- disabled={!canWriteMoreFeatures}
- disabledAction={getReadOnlyDisabledAction()}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -597,8 +586,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.timeTracking.subtitle')}
isActive={isTimeTrackingEnabled(policy)}
pendingAction={policy?.pendingFields?.isTimeTrackingEnabled}
- disabled={!canWriteMoreFeatures}
- disabledAction={getReadOnlyDisabledAction()}
onToggle={(isEnabled) => {
if (!policyID) {
return;
@@ -621,8 +608,6 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
subtitle={translate('workspace.moreFeatures.invoices.subtitle')}
isActive={policy?.areInvoicesEnabled ?? false}
pendingAction={policy?.pendingFields?.areInvoicesEnabled}
- disabled={!canWriteMoreFeatures}
- disabledAction={getReadOnlyDisabledAction()}
onToggle={(isEnabled) => {
if (!policyID) {
return;
diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx
index db793e439585..fd5f0aabfeb1 100644
--- a/src/pages/workspace/WorkspaceOverviewPage.tsx
+++ b/src/pages/workspace/WorkspaceOverviewPage.tsx
@@ -677,7 +677,6 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa
shouldUseScrollView
shouldShowOfflineIndicatorInWideScreen
shouldShowNonAdmin
- policyFeature={CONST.POLICY.POLICY_FEATURE.OVERVIEW}
icon={illustrationIcons.Building}
shouldShowNotFoundPage={policy === undefined}
onBackButtonPress={handleBackButtonPress}
diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx
index e54dad9d8e57..e36789e0e562 100644
--- a/src/pages/workspace/WorkspacePageWithSections.tsx
+++ b/src/pages/workspace/WorkspacePageWithSections.tsx
@@ -172,7 +172,7 @@ function WorkspacePageWithSections({
const shouldShowPolicy = useMemo(() => shouldShowPolicyUtil(policy, false, currentUserLogin), [policy, currentUserLogin]);
let hasAccessToPolicyFeature: boolean | undefined;
if (policyFeature) {
- hasAccessToPolicyFeature = canMemberRead(policy, currentUserLogin ?? '', policyFeature);
+ hasAccessToPolicyFeature = currentUserLogin ? canMemberRead(policy, currentUserLogin, policyFeature) : false;
}
const isPendingDelete = isPendingDeletePolicy(policy);
const prevIsPendingDelete = isPendingDeletePolicy(prevPolicy);
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index 872cd5a8b9bd..a0aa45009347 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -19,7 +19,6 @@ import Text from '@components/Text';
import TextLink from '@components/TextLink';
import ThreeDotsMenu from '@components/ThreeDotsMenu';
import type ThreeDotsMenuProps from '@components/ThreeDotsMenu/types';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useEnvironment from '@hooks/useEnvironment';
import useExpensifyCardFeeds from '@hooks/useExpensifyCardFeeds';
import useHasReusablePoliciesConnectedTo from '@hooks/useHasReusablePoliciesConnectedTo';
@@ -39,7 +38,6 @@ import {isExpensifyCardFullySetUp} from '@libs/CardUtils';
import {getOldDotURLFromEnvironment} from '@libs/Environment/Environment';
import {
areSettingsInErrorFields,
- canMemberWrite,
findCurrentXeroOrganization,
getConnectedIntegration,
getCurrentSageIntacctEntityName,
@@ -87,7 +85,6 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
const oldDotEnvironmentURL = getOldDotURLFromEnvironment(environment);
const {isOffline} = useNetwork();
const {isBetaEnabled} = usePermissions();
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false);
const [datetimeToRelative, setDateTimeToRelative] = useState('');
@@ -116,7 +113,6 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
const syncingAccountingIntegration = accountingIntegrations.find((integration) => integration === connectionSyncProgress?.connectionName);
const connectedIntegration = getConnectedIntegration(policy, accountingIntegrations) ?? syncingAccountingIntegration;
const hasAccountingConnection = hasAccountingConnections(policy);
- const canWriteAccounting = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.ACCOUNTING);
const synchronizationError = connectedIntegration && getSynchronizationErrorMessage(policy, connectedIntegration, isSyncInProgress, translate, styles);
const isSageIntacct = connectedIntegration === CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT;
@@ -208,7 +204,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
useFocusEffect(
useCallback(() => {
- if (!newConnectionName || !isControlPolicy(policy) || !canWriteAccounting) {
+ if (!newConnectionName || !isControlPolicy(policy)) {
return;
}
@@ -217,7 +213,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
integrationToDisconnect,
shouldDisconnectIntegrationBeforeConnecting,
});
- }, [newConnectionName, integrationToDisconnect, shouldDisconnectIntegrationBeforeConnecting, policy, startIntegrationFlow, canWriteAccounting]),
+ }, [newConnectionName, integrationToDisconnect, shouldDisconnectIntegrationBeforeConnecting, policy, startIntegrationFlow]),
);
useEffect(() => {
@@ -248,15 +244,14 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
title: getCurrentXeroOrganizationName(policy),
wrapperStyle: [styles.sectionMenuItemTopDescription],
titleStyle: styles.fontWeightNormal,
- shouldShowRightIcon: canWriteAccounting && tenants.length > 1,
+ shouldShowRightIcon: tenants.length > 1,
shouldShowDescriptionOnTop: true,
- interactive: canWriteAccounting,
- onPress:
- canWriteAccounting && tenants.length > 1
- ? () => {
- Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.getRoute(policyID, currentXeroOrganization?.id));
- }
- : undefined,
+ onPress: () => {
+ if (!(tenants.length > 1)) {
+ return;
+ }
+ Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.getRoute(policyID, currentXeroOrganization?.id));
+ },
pendingAction: settingsPendingAction([CONST.XERO_CONFIG.TENANT_ID], policy?.connections?.xero?.config?.pendingFields),
brickRoadIndicator: areSettingsInErrorFields([CONST.XERO_CONFIG.TENANT_ID], policy?.connections?.xero?.config?.errorFields)
? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR
@@ -271,17 +266,16 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
title: policy?.connections?.netsuite?.options?.config?.subsidiary ?? '',
wrapperStyle: [styles.sectionMenuItemTopDescription],
titleStyle: styles.fontWeightNormal,
- shouldShowRightIcon: canWriteAccounting && netSuiteSubsidiaryList?.length > 1,
+ shouldShowRightIcon: netSuiteSubsidiaryList?.length > 1,
shouldShowDescriptionOnTop: true,
- interactive: canWriteAccounting,
pendingAction: policy?.connections?.netsuite?.options?.config?.pendingFields?.subsidiary,
brickRoadIndicator: policy?.connections?.netsuite?.options?.config?.errorFields?.subsidiary ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
- onPress:
- canWriteAccounting && netSuiteSubsidiaryList?.length > 1
- ? () => {
- Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_SUBSIDIARY_SELECTOR.getRoute(policyID));
- }
- : undefined,
+ onPress: () => {
+ if (!(netSuiteSubsidiaryList?.length > 1)) {
+ return;
+ }
+ Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_SUBSIDIARY_SELECTOR.getRoute(policyID));
+ },
};
case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT:
return !sageIntacctEntityList.length
@@ -292,12 +286,16 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
title: getCurrentSageIntacctEntityName(policy, translate('workspace.common.topLevel')),
wrapperStyle: [styles.sectionMenuItemTopDescription],
titleStyle: styles.fontWeightNormal,
- shouldShowRightIcon: canWriteAccounting,
+ shouldShowRightIcon: true,
shouldShowDescriptionOnTop: true,
- interactive: canWriteAccounting,
pendingAction: policy?.connections?.intacct?.config?.pendingFields?.entity,
brickRoadIndicator: policy?.connections?.intacct?.config?.errorFields?.entity ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
- onPress: canWriteAccounting ? () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_ENTITY.getRoute(policyID)) : undefined,
+ onPress: () => {
+ if (!sageIntacctEntityList.length) {
+ return;
+ }
+ Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_ENTITY.getRoute(policyID));
+ },
};
case CONST.POLICY.CONNECTIONS.NAME.QBO:
return !policy?.connections?.quickbooksOnline?.config?.companyName
@@ -314,25 +312,10 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
default:
return undefined;
}
- }, [
- canWriteAccounting,
- connectedIntegration,
- currentXeroOrganization?.id,
- policy,
- policyID,
- styles.fontWeightNormal,
- styles.sectionMenuItemTopDescription,
- tenants.length,
- translate,
- icons.ArrowRight,
- ]);
+ }, [connectedIntegration, currentXeroOrganization?.id, policy, policyID, styles.fontWeightNormal, styles.sectionMenuItemTopDescription, tenants.length, translate, icons.ArrowRight]);
const connectionsMenuItems: MenuItemData[] = useMemo(() => {
if (!hasAccountingConnection && !isSyncInProgress && policyID) {
- if (!canWriteAccounting) {
- return [];
- }
-
return accountingIntegrations
.map((integration) => {
const integrationData = getAccountingIntegrationData(
@@ -422,86 +405,58 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
connectionMessage = translate('workspace.accounting.lastSync', datetimeToRelative);
}
- const configurationOptions = canWriteAccounting
- ? [
- {
- icon: icons.Pencil,
- iconRight: icons.ArrowRight,
- shouldShowRightIcon: true,
- title: translate('workspace.accounting.import'),
- wrapperStyle: [styles.sectionMenuItemTopDescription],
- onPress: integrationData?.onImportPagePress,
- brickRoadIndicator: areSettingsInErrorFields(integrationData?.subscribedImportSettings, integrationData?.errorFields)
- ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR
- : undefined,
- pendingAction: settingsPendingAction(integrationData?.subscribedImportSettings, integrationData?.pendingFields),
- },
- {
- icon: icons.Send,
- iconRight: icons.ArrowRight,
- shouldShowRightIcon: true,
- title: translate('workspace.accounting.export'),
- wrapperStyle: [styles.sectionMenuItemTopDescription],
- onPress: integrationData?.onExportPagePress,
- brickRoadIndicator:
- areSettingsInErrorFields(integrationData?.subscribedExportSettings, integrationData?.errorFields) || shouldShowQBOReimbursableExportDestinationAccountError(policy)
- ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR
- : undefined,
- pendingAction: settingsPendingAction(integrationData?.subscribedExportSettings, integrationData?.pendingFields),
- },
- ...(shouldShowCardReconciliationOption && integrationData?.onCardReconciliationPagePress
- ? [
- {
- icon: icons.ExpensifyCard,
- iconRight: icons.ArrowRight,
- shouldShowRightIcon: true,
- title: translate('workspace.accounting.cardReconciliation'),
- wrapperStyle: [styles.sectionMenuItemTopDescription],
- onPress: integrationData?.onCardReconciliationPagePress,
- },
- ]
- : []),
- {
- icon: icons.Gear,
- iconRight: icons.ArrowRight,
- shouldShowRightIcon: true,
- title: translate('workspace.accounting.advanced'),
- wrapperStyle: [styles.sectionMenuItemTopDescription],
- onPress: integrationData?.onAdvancedPagePress,
- brickRoadIndicator: areSettingsInErrorFields(integrationData?.subscribedAdvancedSettings, integrationData?.errorFields)
- ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR
- : undefined,
- pendingAction: settingsPendingAction(integrationData?.subscribedAdvancedSettings, integrationData?.pendingFields),
- },
- ]
- : [];
+ const configurationOptions = [
+ {
+ icon: icons.Pencil,
+ iconRight: icons.ArrowRight,
+ shouldShowRightIcon: true,
+ title: translate('workspace.accounting.import'),
+ wrapperStyle: [styles.sectionMenuItemTopDescription],
+ onPress: integrationData?.onImportPagePress,
+ brickRoadIndicator: areSettingsInErrorFields(integrationData?.subscribedImportSettings, integrationData?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
+ pendingAction: settingsPendingAction(integrationData?.subscribedImportSettings, integrationData?.pendingFields),
+ },
+ {
+ icon: icons.Send,
+ iconRight: icons.ArrowRight,
+ shouldShowRightIcon: true,
+ title: translate('workspace.accounting.export'),
+ wrapperStyle: [styles.sectionMenuItemTopDescription],
+ onPress: integrationData?.onExportPagePress,
+ brickRoadIndicator:
+ areSettingsInErrorFields(integrationData?.subscribedExportSettings, integrationData?.errorFields) || shouldShowQBOReimbursableExportDestinationAccountError(policy)
+ ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR
+ : undefined,
+ pendingAction: settingsPendingAction(integrationData?.subscribedExportSettings, integrationData?.pendingFields),
+ },
+ ...(shouldShowCardReconciliationOption && integrationData?.onCardReconciliationPagePress
+ ? [
+ {
+ icon: icons.ExpensifyCard,
+ iconRight: icons.ArrowRight,
+ shouldShowRightIcon: true,
+ title: translate('workspace.accounting.cardReconciliation'),
+ wrapperStyle: [styles.sectionMenuItemTopDescription],
+ onPress: integrationData?.onCardReconciliationPagePress,
+ },
+ ]
+ : []),
+ {
+ icon: icons.Gear,
+ iconRight: icons.ArrowRight,
+ shouldShowRightIcon: true,
+ title: translate('workspace.accounting.advanced'),
+ wrapperStyle: [styles.sectionMenuItemTopDescription],
+ onPress: integrationData?.onAdvancedPagePress,
+ brickRoadIndicator: areSettingsInErrorFields(integrationData?.subscribedAdvancedSettings, integrationData?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined,
+ pendingAction: settingsPendingAction(integrationData?.subscribedAdvancedSettings, integrationData?.pendingFields),
+ },
+ ];
const syncActivityReasonAttributes: SkeletonSpanReasonAttributes = {
context: 'PolicyAccountingPage.connectionsMenuItems',
isSyncInProgress,
};
- let rightComponent;
- if (isSyncInProgress) {
- rightComponent = (
-
- );
- } else if (canWriteAccounting) {
- rightComponent = (
-
- );
- }
-
return [
{
...iconProps,
@@ -513,7 +468,22 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
errorTextStyle: [styles.mt5],
shouldShowRedDotIndicator: true,
description: connectionMessage,
- rightComponent,
+ rightComponent: isSyncInProgress ? (
+
+ ) : (
+
+ ),
},
...(isEmptyObject(integrationSpecificMenuItems) || shouldShowSynchronizationError || !hasAccountingConnection ? [] : [integrationSpecificMenuItems]),
...(!hasAccountingConnection || !isConnectionVerified || connectedIntegration === CONST.POLICY.CONNECTIONS.NAME.CERTINIA ? [] : configurationOptions),
@@ -553,11 +523,10 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
hasReusablePoliciesConnectedToSageIntacct,
hasReusablePoliciesConnectedToCertinia,
hasReusablePoliciesConnectedToQBD,
- canWriteAccounting,
]);
const otherIntegrationsItems = useMemo(() => {
- if (!canWriteAccounting || (!hasAccountingConnection && !isSyncInProgress) || !policyID) {
+ if ((!hasAccountingConnection && !isSyncInProgress) || !policyID) {
return;
}
const otherIntegrations = accountingIntegrations.filter(
@@ -631,7 +600,6 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
startIntegrationFlow,
popoverAnchorRefs,
accountingIcons,
- canWriteAccounting,
]);
const [chatTextLink, chatReportID] = useMemo(() => {
@@ -655,7 +623,6 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.ACCOUNTING}
>
)}
- {!!account?.guideDetails?.email && !hasAccountingConnections(policy) && canWriteAccounting && (
+ {!!account?.guideDetails?.email && !hasAccountingConnections(policy) && (
([]);
- const canSelectMultiple = canWriteCategories && (isSmallScreenWidth ? isMobileSelectionModeEnabled : true);
+ const canSelectMultiple = isSmallScreenWidth ? isMobileSelectionModeEnabled : true;
const isControlPolicyWithWideLayout = !shouldUseNarrowLayout && isControlPolicy(policy);
const shouldShowApproverColumn = isControlPolicyWithWideLayout && !!policy?.areRulesEnabled;
const icons = useMemoizedLazyExpensifyIcons(['Checkmark', 'Close', 'Download', 'Gear', 'Plus', 'Table', 'Trashcan']);
@@ -182,10 +180,6 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
const updateWorkspaceCategoryEnabled = useCallback(
(value: boolean, categoryName: string) => {
- if (!canWriteCategories) {
- showReadOnlyModal();
- return;
- }
setWorkspaceCategoryEnabled({
policyData,
categoriesToUpdate: {[categoryName]: {name: categoryName, enabled: value}},
@@ -217,8 +211,6 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
setupCategoriesAndTagsHasOutstandingChildTask,
setupCategoriesAndTagsParentReportAction,
policyHasTags,
- canWriteCategories,
- showReadOnlyModal,
],
);
@@ -281,8 +273,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
{
if (isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])) {
@@ -291,15 +282,14 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
}
updateWorkspaceCategoryEnabled(newValue, value.name);
}}
- showLockIcon={!canWriteCategories || isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])}
+ showLockIcon={isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])}
/>
>
) : (
{
if (isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])) {
@@ -308,7 +298,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
}
updateWorkspaceCategoryEnabled(newValue, value.name);
}}
- showLockIcon={!canWriteCategories || isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])}
+ showLockIcon={isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])}
/>
),
});
@@ -327,8 +317,6 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
glCodeTextStyle,
switchContainerStyle,
shouldShowApproverColumn,
- canWriteCategories,
- showReadOnlyModal,
styles.alignItemsCenter,
styles.flexRow,
styles.mr3,
@@ -373,8 +361,8 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
// Show GL Code column only on wide screens for control policies. Approver column additionally requires rules to be enabled
if (isControlPolicyWithWideLayout) {
- const header = (
-
+ return (
+
{translate('common.name')}
@@ -386,17 +374,11 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
{translate('common.approver')}
)}
-
+
{translate('common.enabled')}
);
-
- if (canSelectMultiple) {
- return header;
- }
-
- return {header};
}
return (
@@ -404,15 +386,12 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
canSelectMultiple={canSelectMultiple}
leftHeaderText={translate('common.name')}
rightHeaderText={translate('common.enabled')}
- shouldShowRightCaret={canWriteCategories}
+ shouldShowRightCaret
/>
);
};
const navigateToCategorySettings = (category: ListItem) => {
- if (!canWriteCategories) {
- return;
- }
if (isSmallScreenWidth && isMobileSelectionModeEnabled) {
toggleCategory(category);
return;
@@ -481,15 +460,13 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
const secondaryActions = useMemo(() => {
const menuItems = [];
- if (canWriteCategories) {
- menuItems.push({
- icon: icons.Gear,
- text: translate('common.settings'),
- onSelected: navigateToCategoriesSettings,
- value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
- });
- }
- if (canWriteCategories && !policyHasAccountingConnections) {
+ menuItems.push({
+ icon: icons.Gear,
+ text: translate('common.settings'),
+ onSelected: navigateToCategoriesSettings,
+ value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
+ });
+ if (!policyHasAccountingConnections) {
menuItems.push({
icon: icons.Table,
text: translate('spreadsheet.importSpreadsheet'),
@@ -528,7 +505,6 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
icons.Table,
translate,
navigateToCategoriesSettings,
- canWriteCategories,
policyHasAccountingConnections,
hasVisibleCategories,
navigateToImportSpreadsheet,
@@ -539,15 +515,11 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
const shouldDisplayButtonsInSeparateLine = useShouldDisplayButtonsInSeparateLine();
const getHeaderButtons = () => {
- if (!canWriteCategories && secondaryActions.length === 0) {
- return null;
- }
-
const options: Array>> = [];
const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0;
const selectedCategoriesObject = selectedCategories.map((key) => policyCategories?.[key]);
- if (canWriteCategories && (isSmallScreenWidth ? canSelectMultiple : selectedCategories.length > 0)) {
+ if (isSmallScreenWidth ? canSelectMultiple : selectedCategories.length > 0) {
if (!isThereAnyAccountingConnection) {
options.push({
icon: icons.Trashcan,
@@ -666,7 +638,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
/>
);
}
- const shouldShowAddCategory = canWriteCategories && !policyHasAccountingConnections && hasVisibleCategories;
+ const shouldShowAddCategory = !policyHasAccountingConnections && hasVisibleCategories;
return (
{shouldShowAddCategory && (
@@ -679,18 +651,16 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
style={[shouldDisplayButtonsInSeparateLine && styles.flex1]}
/>
)}
- {secondaryActions.length > 0 && (
- {}}
- shouldAlwaysShowDropdownMenu
- customText={translate('common.more')}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.CATEGORIES.MORE_DROPDOWN}
- options={secondaryActions}
- isSplitButton={false}
- wrapperStyle={shouldShowAddCategory || !shouldDisplayButtonsInSeparateLine ? styles.flexGrow0 : styles.flexGrow1}
- />
- )}
+ {}}
+ shouldAlwaysShowDropdownMenu
+ customText={translate('common.more')}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.CATEGORIES.MORE_DROPDOWN}
+ options={secondaryActions}
+ isSplitButton={false}
+ wrapperStyle={shouldShowAddCategory || !shouldDisplayButtonsInSeparateLine ? styles.flexGrow0 : styles.flexGrow1}
+ />
);
};
@@ -747,7 +717,6 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyId}
featureName={CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.CATEGORIES}
>
{!shouldDisplayButtonsInSeparateLine && getHeaderButtons()}
- {shouldDisplayButtonsInSeparateLine && !!getHeaderButtons() && {getHeaderButtons()}}
+ {shouldDisplayButtonsInSeparateLine && {getHeaderButtons()}}
{(!hasVisibleCategories || isLoading) && headerContent}
{isLoading && (
item && canWriteCategories && toggleCategory(item)}
- onSelectAll={canWriteCategories && filteredCategoryList.length > 0 ? toggleAllCategories : undefined}
+ onTurnOnSelectionMode={(item) => item && toggleCategory(item)}
+ onSelectAll={filteredCategoryList.length > 0 ? toggleAllCategories : undefined}
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}
- turnOnSelectionModeOnLongPress={canWriteCategories && isSmallScreenWidth}
+ turnOnSelectionModeOnLongPress={isSmallScreenWidth}
customListHeader={getCustomListHeader()}
customListHeaderContent={headerContent}
canSelectMultiple={canSelectMultiple}
@@ -808,7 +777,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
onDismissError={dismissError}
showScrollIndicator={false}
shouldHeaderBeInsideList
- shouldShowRightCaret={canWriteCategories}
+ shouldShowRightCaret
/>
)}
{!hasVisibleCategories && !isLoading && inputValue.length === 0 && (
diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardDetailsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardDetailsPage.tsx
index 28ea2757b44b..c8b1fa1731c9 100644
--- a/src/pages/workspace/companyCards/WorkspaceCompanyCardDetailsPage.tsx
+++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardDetailsPage.tsx
@@ -20,7 +20,6 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePolicy from '@hooks/usePolicy';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useThemeIllustrations from '@hooks/useThemeIllustrations';
import useThemeStyles from '@hooks/useThemeStyles';
import {isUsingStagingApi} from '@libs/ApiUtils';
@@ -71,7 +70,6 @@ function WorkspaceCompanyCardDetailsPage({route}: WorkspaceCompanyCardDetailsPag
const {showConfirmModal} = useConfirmModal();
const policy = usePolicy(policyID);
- const {canWrite: canWriteCompanyCards} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.COMPANY_CARDS);
const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`);
const [customCardNames] = useOnyx(ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES);
const [shouldUseStagingServer = isUsingStagingApi()] = useOnyx(ONYXKEYS.SHOULD_USE_STAGING_SERVER);
@@ -141,7 +139,6 @@ function WorkspaceCompanyCardDetailsPage({route}: WorkspaceCompanyCardDetailsPag
clearCompanyCardErrorField(domainOrWorkspaceAccountID, cardID, bank, 'lastScrape', true)}
>
- {canWriteCompanyCards && (
-
- )}
+
Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARD_EDIT_CARD_NAME.getRoute(policyID, cardID, feedName))}
- interactive={canWriteCompanyCards}
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.COMPANY_CARDS.CARD_NAME}
/>
@@ -241,9 +235,8 @@ function WorkspaceCompanyCardDetailsPage({route}: WorkspaceCompanyCardDetailsPag
Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARD_EXPORT.getRoute(policyID, cardID, feedName, backTo))}
- interactive={canWriteCompanyCards}
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.COMPANY_CARDS.CARD_EXPORT}
/>
@@ -257,14 +250,13 @@ function WorkspaceCompanyCardDetailsPage({route}: WorkspaceCompanyCardDetailsPag
Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARD_EDIT_TRANSACTION_START_DATE.getRoute(policyID, cardID, feedName))}
- interactive={canWriteCompanyCards}
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.COMPANY_CARDS.TRANSACTION_START_DATE}
/>
- {canWriteCompanyCards && shouldShowBreakConnection && (
+ {shouldShowBreakConnection && (
)}
- {canWriteCompanyCards && (
- {
- showConfirmModal({
- shouldSetModalVisibility: false,
- title: translate('workspace.moreFeatures.companyCards.unassignCard'),
- prompt: translate('workspace.moreFeatures.companyCards.unassignCardDescription'),
- confirmText: translate('workspace.moreFeatures.companyCards.unassign'),
- cancelText: translate('common.cancel'),
- danger: true,
- }).then((result) => {
- if (result.action !== ModalActions.CONFIRM) {
- return;
- }
+ {
+ showConfirmModal({
+ shouldSetModalVisibility: false,
+ title: translate('workspace.moreFeatures.companyCards.unassignCard'),
+ prompt: translate('workspace.moreFeatures.companyCards.unassignCardDescription'),
+ confirmText: translate('workspace.moreFeatures.companyCards.unassign'),
+ cancelText: translate('common.cancel'),
+ danger: true,
+ }).then((result) => {
+ if (result.action !== ModalActions.CONFIRM) {
+ return;
+ }
- unassignCard();
- });
- }}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.COMPANY_CARDS.UNASSIGN_CARD}
- />
- )}
+ unassignCard();
+ });
+ }}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.COMPANY_CARDS.UNASSIGN_CARD}
+ />
diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardPageEmptyState.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardPageEmptyState.tsx
index ac05c1072760..9caa5e85a424 100644
--- a/src/pages/workspace/companyCards/WorkspaceCompanyCardPageEmptyState.tsx
+++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardPageEmptyState.tsx
@@ -25,10 +25,9 @@ import WorkspaceCompanyCardExpensifyCardPromotionBanner from './WorkspaceCompany
type WorkspaceCompanyCardPageEmptyStateProps = {
policyID: string;
shouldShowGBDisclaimer?: boolean;
- canWriteCompanyCards?: boolean;
};
-function WorkspaceCompanyCardPageEmptyState({policyID, shouldShowGBDisclaimer, canWriteCompanyCards = true}: WorkspaceCompanyCardPageEmptyStateProps) {
+function WorkspaceCompanyCardPageEmptyState({policyID, shouldShowGBDisclaimer}: WorkspaceCompanyCardPageEmptyStateProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const {shouldUseNarrowLayout} = useResponsiveLayout();
@@ -115,9 +114,9 @@ function WorkspaceCompanyCardPageEmptyState({policyID, shouldShowGBDisclaimer, c
menuItems={companyCardFeatures as FeatureListItem[]}
title={translate('workspace.moreFeatures.companyCards.feed.title')}
subtitle={translate('workspace.moreFeatures.companyCards.feed.subtitle')}
- ctaText={canWriteCompanyCards ? translate('workspace.companyCards.addCards') : undefined}
- ctaAccessibilityLabel={canWriteCompanyCards ? translate('workspace.companyCards.addCards') : undefined}
- onCtaPress={canWriteCompanyCards ? handleCtaPress : undefined}
+ ctaText={translate('workspace.companyCards.addCards')}
+ ctaAccessibilityLabel={translate('workspace.companyCards.addCards')}
+ onCtaPress={handleCtaPress}
illustrationBackgroundColor={colors.blue800}
illustration={getCompanyCardIllustration()}
illustrationStyle={styles.getEmptyStateCompanyCardsIllustration(shouldUseNarrowLayout)}
diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx
index 044a1a613957..95cb27e2b37c 100644
--- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx
+++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx
@@ -3,7 +3,6 @@ import DecisionModal from '@components/DecisionModal';
import WorkspaceCompanyCardsTable from '@components/Tables/WorkspaceCompanyCardsTable';
import useAssignCard from '@hooks/useAssignCard';
import useCompanyCards from '@hooks/useCompanyCards';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
@@ -13,7 +12,7 @@ import useWorkspaceDocumentTitle from '@hooks/useWorkspaceDocumentTitle';
import {getDomainOrWorkspaceAccountID} from '@libs/CardUtils';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types';
-import {canMemberWrite, getMemberAccountIDsForWorkspace} from '@libs/PolicyUtils';
+import {getMemberAccountIDsForWorkspace} from '@libs/PolicyUtils';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections';
import {openPolicyCompanyCardsFeed, openPolicyCompanyCardsPage} from '@userActions/CompanyCards';
@@ -26,7 +25,6 @@ type WorkspaceCompanyCardsPageProps = PlatformStackScreenProps
diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx
index 49692d9c450e..fb7c2edf4d94 100644
--- a/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx
+++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx
@@ -24,7 +24,6 @@ import useMobileSelectionMode from '@hooks/useMobileSelectionMode';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePolicy from '@hooks/usePolicy';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useSearchBackPress from '@hooks/useSearchBackPress';
import useSearchResults from '@hooks/useSearchResults';
@@ -74,9 +73,8 @@ function PolicyDistanceRatesPage({
const policy = usePolicy(policyID);
useWorkspaceDocumentTitle(policy?.name, 'workspace.common.distanceRates');
const isMobileSelectionModeEnabled = useMobileSelectionMode();
- const {canWrite: canWriteDistanceRates, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.DISTANCE_RATES);
- const canSelectMultiple = canWriteDistanceRates && (shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true);
+ const canSelectMultiple = shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true;
const {asset: CarIce} = useMemoizedLazyAsset(() => loadIllustration('CarIce' as IllustrationName));
const customUnit = useMemo(() => getDistanceRateCustomUnit(policy), [policy]);
const customUnitRates: Record = useMemo(() => customUnit?.rates ?? {}, [customUnit?.rates]);
@@ -211,10 +209,6 @@ function PolicyDistanceRatesPage({
const updateDistanceRateEnabled = useCallback(
(value: boolean, rateID: string) => {
- if (!canWriteDistanceRates) {
- showReadOnlyModal();
- return;
- }
if (!customUnit) {
return;
}
@@ -226,7 +220,7 @@ function PolicyDistanceRatesPage({
showWarningModal();
}
},
- [canDisableOrDeleteRate, canWriteDistanceRates, customUnit, policyID, showReadOnlyModal, showWarningModal],
+ [canDisableOrDeleteRate, customUnit, policyID, showWarningModal],
);
const unitTranslation = translate(`common.${customUnit?.attributes?.unit ?? CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES}`);
@@ -259,23 +253,13 @@ function PolicyDistanceRatesPage({
isOn={!!value?.enabled}
accessibilityLabel={value?.name ?? ''}
onToggle={(newValue: boolean) => updateDistanceRateEnabled(newValue, value.customUnitRateID)}
- showLockIcon={!canWriteDistanceRates || !canDisableOrDeleteRate(value.customUnitRateID)}
- disabled={!canWriteDistanceRates || value.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE}
- disabledAction={!canWriteDistanceRates ? showReadOnlyModal : undefined}
+ showLockIcon={!canDisableOrDeleteRate(value.customUnitRateID)}
+ disabled={value.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE}
/>
),
};
}),
- [
- canDisableOrDeleteRate,
- canWriteDistanceRates,
- customUnitRates,
- unitTranslation,
- customUnit?.pendingFields?.attributes,
- policy?.pendingAction,
- showReadOnlyModal,
- updateDistanceRateEnabled,
- ],
+ [canDisableOrDeleteRate, customUnitRates, unitTranslation, customUnit?.pendingFields?.attributes, policy?.pendingAction, updateDistanceRateEnabled],
);
const filterRate = useCallback((rate: RateForList, searchInput: string) => {
@@ -294,9 +278,6 @@ function PolicyDistanceRatesPage({
}, [policyID]);
const openRateDetails = (rate: RateForList) => {
- if (!canWriteDistanceRates) {
- return;
- }
Navigation.navigate(ROUTES.WORKSPACE_DISTANCE_RATE_DETAILS.getRoute(policyID, rate.value));
};
@@ -373,7 +354,7 @@ function PolicyDistanceRatesPage({
canSelectMultiple={canSelectMultiple}
leftHeaderText={translate('workspace.distanceRates.rate')}
rightHeaderText={translate('common.enabled')}
- shouldShowRightCaret={canWriteDistanceRates}
+ shouldShowRightCaret
/>
);
};
@@ -443,7 +424,7 @@ function PolicyDistanceRatesPage({
const shouldDisplayButtonsInSeparateLine = useShouldDisplayButtonsInSeparateLine();
- const headerButtons = canWriteDistanceRates ? (
+ const headerButtons = (
{(shouldUseNarrowLayout ? !isMobileSelectionModeEnabled : selectedDistanceRates.length === 0) ? (
<>
@@ -482,7 +463,7 @@ function PolicyDistanceRatesPage({
/>
)}
- ) : null;
+ );
const selectionModeHeader = isMobileSelectionModeEnabled && shouldUseNarrowLayout;
@@ -509,7 +490,6 @@ function PolicyDistanceRatesPage({
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.DISTANCE_RATES}
>
{!shouldDisplayButtonsInSeparateLine && headerButtons}
- {shouldDisplayButtonsInSeparateLine && !!headerButtons && {headerButtons}}
+ {shouldDisplayButtonsInSeparateLine && {headerButtons}}
{isLoading && (
item && canWriteDistanceRates && toggleRate(item)}
- onSelectAll={canWriteDistanceRates && filteredDistanceRatesList.length > 0 ? toggleAllRates : undefined}
+ onTurnOnSelectionMode={(item) => item && toggleRate(item)}
+ onSelectAll={filteredDistanceRatesList.length > 0 ? toggleAllRates : undefined}
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}
customListHeaderContent={headerContent}
canSelectMultiple={canSelectMultiple}
@@ -560,9 +540,9 @@ function PolicyDistanceRatesPage({
onDismissError={dismissError}
shouldShowListEmptyContent={false}
showScrollIndicator={false}
- turnOnSelectionModeOnLongPress={canWriteDistanceRates}
+ turnOnSelectionModeOnLongPress
shouldHeaderBeInsideList
- shouldShowRightCaret={canWriteDistanceRates}
+ shouldShowRightCaret
/>
)}
diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx
index 1b2d2afb3f38..9d2e2f63e839 100644
--- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx
+++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx
@@ -8,7 +8,6 @@ import getBankIcon from '@components/Icon/BankIcons';
import MenuItem from '@components/MenuItem';
import ScreenWrapper from '@components/ScreenWrapper';
import Text from '@components/Text';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useDefaultFundID from '@hooks/useDefaultFundID';
import useExpensifyCardUkEuSupported from '@hooks/useExpensifyCardUkEuSupported';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
@@ -20,7 +19,6 @@ import {getLastFourDigits} from '@libs/BankAccountUtils';
import {getEligibleBankAccountsForCard, getEligibleBankAccountsForUkEuCard} from '@libs/CardUtils';
import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
-import {canMemberWrite} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
@@ -41,8 +39,6 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA
const policyID = route?.params?.policyID;
const policy = usePolicy(policyID);
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
- const canWriteExpensifyCard = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD);
const isUkEuCurrencySupported = useExpensifyCardUkEuSupported(policyID);
@@ -142,8 +138,6 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD}
- shouldBeBlocked={!canWriteExpensifyCard}
>
{
@@ -129,7 +127,7 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
useEffect(() => fetchCardDetails(), [fetchCardDetails]);
useEffect(() => {
- if (!canWriteExpensifyCard) {
+ if (!isAdmin) {
return;
}
if (!defaultFundID || defaultFundID === CONST.DEFAULT_NUMBER_ID) {
@@ -143,7 +141,7 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
}
openPolicyExpensifyCardsPage(policyID, defaultFundID);
- }, [canWriteExpensifyCard, defaultFundID, fundCardSettings?.hasOnceLoaded, fundCardSettings?.isLoading, policyID]);
+ }, [defaultFundID, fundCardSettings?.hasOnceLoaded, fundCardSettings?.isLoading, isAdmin, policyID]);
const deactivateCard = async () => {
const {action} = await showConfirmModal({
@@ -215,7 +213,7 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
[spendRulesSummary],
);
- const canManageCardFreeze = canWriteExpensifyCard && !!card;
+ const canManageCardFreeze = isAdmin && !!card;
const scarfOverlayStyle = useMemo(
() => ({
top: 0,
@@ -258,7 +256,6 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD}
>
{canManageCardFreeze && isCardFrozen(card) ? (
Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.EXPENSIFY_CARD_NAME.path))}
- interactive={canWriteExpensifyCard}
/>
Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.EXPENSIFY_CARD_LIMIT_TYPE.path))}
- interactive={canWriteExpensifyCard}
hintText={getCardHintText(card?.nameValuePairs?.validFrom, card?.nameValuePairs?.validThru, cardholder?.timezone?.selected, translate)}
/>
@@ -370,9 +365,8 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.EXPENSIFY_CARD_LIMIT.path))}
- interactive={canWriteExpensifyCard}
/>
@@ -382,18 +376,17 @@ function WorkspaceExpensifyCardDetailsPage({route}: WorkspaceExpensifyCardDetail
descriptionTextStyle={[styles.fontSizeLabel]}
titleComponent={spendRulesTitleComponent}
onPress={navigateToSpendRules}
- interactive={canWriteExpensifyCard}
accessibilityLabel={spendRulesSummary.join('. ')}
/>
)}
- {!isProduction && canWriteExpensifyCard && (
+ {!isProduction && isAdmin && (
)}
- {canWriteExpensifyCard && !isDeactivated && (
+ {!isDeactivated && (
(undefined);
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
const {primaryFeeds, otherFeeds} = useExpensifyCardFeedsForFeedSelector(policyID);
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
- const policy = usePolicy(policyID);
- const canWriteExpensifyCard = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD);
const getIssueCardFundID = () => {
if (primaryFeeds.length === 0) {
@@ -189,7 +183,7 @@ function WorkspaceExpensifyCardFeedSelectorPage({route}: WorkspaceExpensifyCardF
const primaryListData = primaryFeeds.map((entry) => toListItem(entry, false));
- const issueNewCardAndOtherFeedsFooter = canWriteExpensifyCard ? (
+ const issueNewCardAndOtherFeedsFooter = (
)}
- ) : undefined;
+ );
return (
Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_SETTINGS.getRoute(policyID)),
- value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
- },
- ]
- : [];
+ const secondaryActions = [
+ {
+ icon: icons.Gear,
+ text: translate('common.settings'),
+ onSelected: () => Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_SETTINGS.getRoute(policyID)),
+ value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
+ },
+ ];
const getHeaderButtons = () => {
const headerButtonsRowStyle = [
styles.flexRow,
@@ -201,7 +196,7 @@ function WorkspaceExpensifyCardListPage({route, cardsList, fundID}: WorkspaceExp
return (
- {!isCardListEmpty && canWriteExpensifyCard && (
+ {!isCardListEmpty && (
)}
- {secondaryActions.length > 0 && (
- {}}
- customText={translate('common.more')}
- options={secondaryActions}
- isSplitButton={false}
- shouldUseOptionIcon
- wrapperStyle={isCardListEmpty && !isInLandscapeMode ? styles.flexGrow1 : styles.flexGrow0}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.EXPENSIFY_CARD.MORE_DROPDOWN}
- />
- )}
+ {}}
+ customText={translate('common.more')}
+ options={secondaryActions}
+ isSplitButton={false}
+ shouldUseOptionIcon
+ wrapperStyle={isCardListEmpty && !isInLandscapeMode ? styles.flexGrow1 : styles.flexGrow0}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.EXPENSIFY_CARD.MORE_DROPDOWN}
+ />
);
};
@@ -319,7 +312,6 @@ function WorkspaceExpensifyCardListPage({route, cardsList, fundID}: WorkspaceExp
Navigation.goBack();
return true;
};
- const shouldShowHeaderButtons = selectedCardIDs.length > 0 || canWriteExpensifyCard;
useAndroidBackButtonHandler(handleBackButtonPress);
@@ -339,9 +331,9 @@ function WorkspaceExpensifyCardListPage({route, cardsList, fundID}: WorkspaceExp
shouldDisplayHelpButton
onBackButtonPress={handleBackButtonPress}
>
- {!shouldShowSelector && !shouldDisplayButtonsInSeparateLine && isBankAccountVerified && shouldShowHeaderButtons && getHeaderButtons()}
+ {!shouldShowSelector && !shouldDisplayButtonsInSeparateLine && isBankAccountVerified && getHeaderButtons()}
- {!shouldShowSelector && shouldDisplayButtonsInSeparateLine && isBankAccountVerified && shouldShowHeaderButtons && {getHeaderButtons()}}
+ {!shouldShowSelector && shouldDisplayButtonsInSeparateLine && isBankAccountVerified && {getHeaderButtons()}}
{shouldShowSelector && (
- {isBankAccountVerified && (canWriteExpensifyCard || secondaryActions.length > 0) && getHeaderButtons()}
+ {isBankAccountVerified && getHeaderButtons()}
)}
{isCardListEmpty ? (
) : (
{renderContent()}
diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx
index fd6c99d86919..063813a70834 100644
--- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx
+++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx
@@ -7,7 +7,6 @@ import {useLockedAccountActions, useLockedAccountState} from '@components/Locked
import {ModalActions} from '@components/Modal/Global/ModalContext';
import Text from '@components/Text';
import useConfirmModal from '@hooks/useConfirmModal';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useExpensifyCardUkEuSupported from '@hooks/useExpensifyCardUkEuSupported';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
@@ -21,7 +20,6 @@ import {getEligibleBankAccountsForCard, getEligibleBankAccountsForUkEuCard} from
import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types';
-import {canMemberWrite} from '@libs/PolicyUtils';
import {hasInProgressUSDVBBA} from '@libs/ReimbursementAccountUtils';
import Navigation from '@navigation/Navigation';
import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading';
@@ -52,8 +50,6 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif
const {showDelegateNoAccessModal} = useDelegateNoAccessActions();
const {isAccountLocked} = useLockedAccountState();
const {showLockedAccountModal} = useLockedAccountActions();
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
- const canWriteExpensifyCard = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD);
// Dismiss the "Update to USD" modal if the currency changes to USD externally (e.g. from another device)
const isCurrencyModalOpen = useRef(false);
@@ -124,7 +120,6 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif
route={route}
showLoadingAsFirstRender={false}
shouldShowOfflineIndicatorInWideScreen
- policyFeature={CONST.POLICY.POLICY_FEATURE.EXPENSIFY_CARD}
addBottomSafeAreaPadding
>
@@ -132,7 +127,7 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif
menuItems={isUkEuCurrencySupported ? expensifyCardFeatures.slice(1) : expensifyCardFeatures}
title={translate('workspace.moreFeatures.expensifyCard.feed.title')}
subtitle={translate('workspace.moreFeatures.expensifyCard.feed.subTitle')}
- ctaText={canWriteExpensifyCard ? translate(isSetupUnfinished ? 'workspace.expensifyCard.finishSetup' : 'workspace.expensifyCard.issueNewCard') : undefined}
+ ctaText={translate(isSetupUnfinished ? 'workspace.expensifyCard.finishSetup' : 'workspace.expensifyCard.issueNewCard')}
ctaAccessibilityLabel={translate('workspace.moreFeatures.expensifyCard.feed.ctaTitle')}
onCtaPress={() => {
if (isDelegateAccessRestricted) {
diff --git a/src/pages/workspace/hr/HRProviderCard.tsx b/src/pages/workspace/hr/HRProviderCard.tsx
index 04f14d9ec2a8..418f0bd153cd 100644
--- a/src/pages/workspace/hr/HRProviderCard.tsx
+++ b/src/pages/workspace/hr/HRProviderCard.tsx
@@ -30,12 +30,9 @@ type HRProviderCardProps = {
/** Callback invoked when the user taps the "Connect" button for an unconnected provider. */
handleConnect: () => void;
-
- /** Whether the current user can edit this HR connection. */
- canWriteMoreFeatures: boolean;
};
-function HRProviderCard({card, policy, handleConnect, canWriteMoreFeatures}: HRProviderCardProps) {
+function HRProviderCard({card, policy, handleConnect}: HRProviderCardProps) {
const {translate, datetimeToRelative} = useLocalize();
const styles = useThemeStyles();
const {isOffline} = useNetwork();
@@ -87,10 +84,8 @@ function HRProviderCard({card, policy, handleConnect, canWriteMoreFeatures}: HRP
},
];
- let rightInset: React.ReactNode;
- if (!canWriteMoreFeatures) {
- rightInset = null;
- } else if (!card.isConnected) {
+ let rightInset;
+ if (!card.isConnected) {
rightInset = (
@@ -148,10 +143,9 @@ function HRProviderCard({card, policy, handleConnect, canWriteMoreFeatures}: HRP
description={translate('workspace.hr.approvalMode')}
title={card.approvalModeLabel}
style={[styles.sectionMenuItemTopDescription, styles.mt2]}
- shouldShowRightIcon={canWriteMoreFeatures}
+ shouldShowRightIcon
brickRoadIndicator={card.config?.errorFields?.approvalMode ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
onPress={() => Navigation.navigate(approvalModeRoute)}
- interactive={canWriteMoreFeatures}
/>
)}
@@ -165,10 +159,9 @@ function HRProviderCard({card, policy, handleConnect, canWriteMoreFeatures}: HRP
description={translate('workspace.hr.finalApprover')}
title={card.finalApproverDisplayName}
style={styles.sectionMenuItemTopDescription}
- shouldShowRightIcon={canWriteMoreFeatures}
+ shouldShowRightIcon
brickRoadIndicator={card.config?.errorFields?.finalApprover ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
onPress={() => Navigation.navigate(finalApproverRoute)}
- interactive={canWriteMoreFeatures}
/>
)}
diff --git a/src/pages/workspace/hr/WorkspaceHRPage.tsx b/src/pages/workspace/hr/WorkspaceHRPage.tsx
index c1f5db0dfdf7..1f41debc53be 100644
--- a/src/pages/workspace/hr/WorkspaceHRPage.tsx
+++ b/src/pages/workspace/hr/WorkspaceHRPage.tsx
@@ -8,7 +8,6 @@ import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Section from '@components/Section';
import useConfirmModal from '@hooks/useConfirmModal';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useHRSyncResultsModal from '@hooks/useHRSyncResultsModal';
import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
@@ -25,7 +24,6 @@ import {openPolicyHRPage} from '@libs/actions/PolicyConnections';
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types';
-import {canMemberWrite} from '@libs/PolicyUtils';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import variables from '@styles/variables';
import CONST from '@src/CONST';
@@ -49,7 +47,6 @@ function WorkspaceHRPage({
const StyleUtils = useStyleUtils();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const policy = usePolicy(policyID);
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`);
const icons = useMemoizedLazyExpensifyIcons(['GustoSquare', 'TriNetSquare']);
const illustrations = useMemoizedLazyIllustrations(['NewUser']);
@@ -87,8 +84,6 @@ function WorkspaceHRPage({
connectedCards.sort(byName);
disconnectedCards.sort(byName);
- const canWriteMoreFeatures = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
-
const handleConnect = (setupLink: string | undefined) => {
if (!setupLink) {
return;
@@ -114,7 +109,6 @@ function WorkspaceHRPage({
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.CONTROL]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.IS_HR_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.MORE_FEATURES}
>
handleConnect(card.setupLink)}
- canWriteMoreFeatures={canWriteMoreFeatures}
/>
))}
{connectedCards.length === 0 &&
@@ -163,7 +156,6 @@ function WorkspaceHRPage({
card={card}
policy={policy}
handleConnect={() => handleConnect(card.setupLink)}
- canWriteMoreFeatures={canWriteMoreFeatures}
/>
))}
@@ -181,7 +173,6 @@ function WorkspaceHRPage({
card={card}
policy={policy}
handleConnect={() => handleConnect(card.setupLink)}
- canWriteMoreFeatures={canWriteMoreFeatures}
/>
))}
diff --git a/src/pages/workspace/invoices/WorkspaceInvoiceVBASection.tsx b/src/pages/workspace/invoices/WorkspaceInvoiceVBASection.tsx
index fcc2cc730053..81833f80be25 100644
--- a/src/pages/workspace/invoices/WorkspaceInvoiceVBASection.tsx
+++ b/src/pages/workspace/invoices/WorkspaceInvoiceVBASection.tsx
@@ -29,15 +29,12 @@ import ROUTES from '@src/ROUTES';
type WorkspaceInvoiceVBASectionProps = {
/** The policy ID currently being configured */
policyID: string;
-
- /** Whether the current user can edit miscellaneous settings. */
- canWriteMoreFeatures: boolean;
};
type CurrencyType = TupleToUnion;
// TODO: can be refactored to use ThreeDotsMenu component instead handling the popover and positioning
-function WorkspaceInvoiceVBASection({policyID, canWriteMoreFeatures}: WorkspaceInvoiceVBASectionProps) {
+function WorkspaceInvoiceVBASection({policyID}: WorkspaceInvoiceVBASectionProps) {
const icons = useMemoizedLazyExpensifyIcons(['Star', 'Trashcan']);
const styles = useThemeStyles();
const {shouldUseNarrowLayout} = useResponsiveLayout();
@@ -245,8 +242,7 @@ function WorkspaceInvoiceVBASection({policyID, canWriteMoreFeatures}: WorkspaceI
shouldSkipDefaultAccountValidation={!isSupportedGlobalReimbursement}
invoiceTransferBankAccountID={transferBankAccountID}
activePaymentMethodID={transferBankAccountID}
- threeDotsMenuItems={canWriteMoreFeatures ? threeDotsMenuItems : undefined}
- shouldShowAddBankAccount={canWriteMoreFeatures}
+ threeDotsMenuItems={threeDotsMenuItems}
style={[styles.mt5, shouldUseNarrowLayout ? styles.mhn5 : styles.mhn8]}
listItemStyle={shouldUseNarrowLayout ? styles.ph5 : styles.ph8}
policyID={policyID}
diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesPage.tsx b/src/pages/workspace/invoices/WorkspaceInvoicesPage.tsx
index 21dd4aad469f..85d49ca58bff 100644
--- a/src/pages/workspace/invoices/WorkspaceInvoicesPage.tsx
+++ b/src/pages/workspace/invoices/WorkspaceInvoicesPage.tsx
@@ -1,6 +1,5 @@
import React from 'react';
import {View} from 'react-native';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import usePolicy from '@hooks/usePolicy';
@@ -8,7 +7,6 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceDocumentTitle from '@hooks/useWorkspaceDocumentTitle';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
-import {canMemberWrite} from '@libs/PolicyUtils';
import type {WorkspaceSplitNavigatorParamList} from '@navigation/types';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections';
@@ -26,15 +24,12 @@ function WorkspaceInvoicesPage({route}: WorkspaceInvoicesPageProps) {
const styles = useThemeStyles();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const illustrations = useMemoizedLazyIllustrations(['InvoiceBlue']);
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
- const canWriteMoreFeatures = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
return (
{(policyID?: string) => (
{!!policyID && }
- {!!policyID && (
-
- )}
- {!!policyID && (
-
- )}
+ {!!policyID && }
+ {!!policyID && }
)}
diff --git a/src/pages/workspace/invoices/WorkspaceInvoicingDetailsSection.tsx b/src/pages/workspace/invoices/WorkspaceInvoicingDetailsSection.tsx
index 0efbd4742e75..06bdec66f9a1 100644
--- a/src/pages/workspace/invoices/WorkspaceInvoicingDetailsSection.tsx
+++ b/src/pages/workspace/invoices/WorkspaceInvoicingDetailsSection.tsx
@@ -13,12 +13,9 @@ import ROUTES from '@src/ROUTES';
type WorkspaceInvoicingDetailsSectionProps = {
/** The current policy ID */
policyID: string;
-
- /** Whether the current user can edit miscellaneous settings. */
- canWriteMoreFeatures: boolean;
};
-function WorkspaceInvoicingDetailsSection({policyID, canWriteMoreFeatures}: WorkspaceInvoicingDetailsSectionProps) {
+function WorkspaceInvoicingDetailsSection({policyID}: WorkspaceInvoicingDetailsSectionProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {shouldUseNarrowLayout} = useResponsiveLayout();
@@ -38,22 +35,20 @@ function WorkspaceInvoicingDetailsSection({policyID, canWriteMoreFeatures}: Work
>
Navigation.navigate(ROUTES.WORKSPACE_INVOICES_COMPANY_NAME.getRoute(policyID))}
- interactive={canWriteMoreFeatures}
style={horizontalPadding}
/>
Navigation.navigate(ROUTES.WORKSPACE_INVOICES_COMPANY_WEBSITE.getRoute(policyID))}
- interactive={canWriteMoreFeatures}
style={horizontalPadding}
/>
diff --git a/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx b/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx
index c99ba9190b8f..a9e21cb185f4 100644
--- a/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx
+++ b/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx
@@ -18,7 +18,6 @@ import SelectionListWithModal from '@components/SelectionListWithModal';
import Text from '@components/Text';
import useCleanupSelectedOptions from '@hooks/useCleanupSelectedOptions';
import useConfirmModal from '@hooks/useConfirmModal';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useGenericEmptyStateIllustration from '@hooks/useGenericEmptyStateIllustration';
import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
@@ -38,7 +37,7 @@ import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types';
import {hasEnabledOptions} from '@libs/OptionsListUtils';
-import {canMemberWrite, getPerDiemCustomUnit} from '@libs/PolicyUtils';
+import {getPerDiemCustomUnit} from '@libs/PolicyUtils';
import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
import tokenizedSearch from '@libs/tokenizedSearch';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
@@ -129,8 +128,6 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
const policyID = route.params.policyID;
const backTo = route.params?.backTo;
const policy = usePolicy(policyID);
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
- const canWritePerDiem = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.PER_DIEM);
useWorkspaceDocumentTitle(policy?.name, 'workspace.common.perDiem');
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`);
const isMobileSelectionModeEnabled = useMobileSelectionMode();
@@ -146,7 +143,7 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
return [customUnits, allRates, allSubRatesMemo];
}, [policy]);
- const canSelectMultiple = canWritePerDiem && (shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true);
+ const canSelectMultiple = shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true;
const fetchPerDiem = useCallback(() => {
openPolicyPerDiemPage(policyID);
@@ -259,9 +256,6 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
}, [policyID]);
const openSubRateDetails = (rate: PolicyOption) => {
- if (!canWritePerDiem) {
- return;
- }
if (isSmallScreenWidth && isMobileSelectionModeEnabled) {
toggleSubRate(rate);
return;
@@ -289,7 +283,7 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
const secondaryActions = useMemo(() => {
const menuItems = [];
- if (canWritePerDiem && policy?.areCategoriesEnabled && hasEnabledOptions(policyCategories ?? {})) {
+ if (policy?.areCategoriesEnabled && hasEnabledOptions(policyCategories ?? {})) {
menuItems.push({
icon: expensifyIcons.Gear,
text: translate('common.settings'),
@@ -297,20 +291,18 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
});
}
- if (canWritePerDiem) {
- menuItems.push({
- icon: expensifyIcons.Table,
- text: translate('spreadsheet.importSpreadsheet'),
- onSelected: () => {
- if (isOffline) {
- showOfflineModal();
- return;
- }
- Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID));
- },
- value: CONST.POLICY.SECONDARY_ACTIONS.IMPORT_SPREADSHEET,
- });
- }
+ menuItems.push({
+ icon: expensifyIcons.Table,
+ text: translate('spreadsheet.importSpreadsheet'),
+ onSelected: () => {
+ if (isOffline) {
+ showOfflineModal();
+ return;
+ }
+ Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID));
+ },
+ value: CONST.POLICY.SECONDARY_ACTIONS.IMPORT_SPREADSHEET,
+ });
if (hasVisibleSubRates) {
menuItems.push({
icon: expensifyIcons.Download,
@@ -339,7 +331,6 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
showOfflineModal,
policy?.areCategoriesEnabled,
policyCategories,
- canWritePerDiem,
translate,
hasVisibleSubRates,
openSettings,
@@ -389,10 +380,6 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
);
}
- if (secondaryActions.length === 0) {
- return null;
- }
-
return (
{!shouldDisplayButtonsInSeparateLine && getHeaderButtons()}
- {!!getHeaderButtons() && shouldDisplayButtonsInSeparateLine && {getHeaderButtons()}}
+ {shouldDisplayButtonsInSeparateLine && {getHeaderButtons()}}
{(!hasVisibleSubRates || isLoading) && headerContent}
{isLoading && (
item.subRateID)}
- onSelectAll={canWritePerDiem && filteredSubRatesList.length > 0 ? toggleAllSubRates : undefined}
+ onSelectAll={filteredSubRatesList.length > 0 ? toggleAllSubRates : undefined}
style={{listItemTitleContainerStyles: styles.flex3}}
- onTurnOnSelectionMode={(item) => canWritePerDiem && item && toggleSubRate(item)}
+ onTurnOnSelectionMode={(item) => item && toggleSubRate(item)}
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}
customListHeaderContent={headerContent}
shouldShowListEmptyContent={false}
showScrollIndicator={false}
turnOnSelectionModeOnLongPress
shouldHeaderBeInsideList
- shouldShowRightCaret={canWritePerDiem}
+ shouldShowRightCaret
/>
)}
{!hasVisibleSubRates && !isLoading && (
@@ -521,23 +507,19 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
title={translate('workspace.perDiem.emptyList.title')}
subtitle={translate('workspace.perDiem.emptyList.subtitle')}
headerStyles={styles.emptyStateCardIllustrationContainer}
- buttons={
- canWritePerDiem
- ? [
- {
- buttonText: translate('spreadsheet.importSpreadsheet'),
- buttonAction: () => {
- if (isOffline) {
- showOfflineModal();
- return;
- }
- Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID));
- },
- success: true,
- },
- ]
- : []
- }
+ buttons={[
+ {
+ buttonText: translate('spreadsheet.importSpreadsheet'),
+ buttonAction: () => {
+ if (isOffline) {
+ showOfflineModal();
+ return;
+ }
+ Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM_IMPORT.getRoute(policyID));
+ },
+ success: true,
+ },
+ ]}
/>
)}
diff --git a/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx b/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx
index f55908bc5f2a..cb034fa156a0 100644
--- a/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx
+++ b/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx
@@ -18,7 +18,6 @@ import {useMemoizedLazyAsset, useMemoizedLazyExpensifyIcons} from '@hooks/useLaz
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import usePolicy from '@hooks/usePolicy';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import usePrevious from '@hooks/usePrevious';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -61,7 +60,6 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps
const {asset: ReceiptPartners} = useMemoizedLazyAsset(() => loadIllustration('ReceiptPartners' as IllustrationName));
// Track focus and connection change to route to the invite flow once after successful connection
const prevIsUberConnected = usePrevious(isUberConnected);
- const {canWrite: canWriteMoreFeatures, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
const startIntegrationFlow = useCallback(
({name}: {name: string}) => {
@@ -91,11 +89,11 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps
// When Uber connection status flips from false -> true, navigate to the invite flow once
useEffect(() => {
- if (!isUberConnected || prevIsUberConnected || !canWriteMoreFeatures) {
+ if (!isUberConnected || prevIsUberConnected) {
return;
}
Navigation.navigate(ROUTES.WORKSPACE_RECEIPT_PARTNERS_INVITE.getRoute(policyID, CONST.POLICY.RECEIPT_PARTNERS.NAME.UBER));
- }, [prevIsUberConnected, isUberConnected, policyID, canWriteMoreFeatures]);
+ }, [prevIsUberConnected, isUberConnected, policyID]);
const calculateAndSetThreeDotsMenuPosition = useCallback(() => {
if (shouldUseNarrowLayout) {
@@ -176,7 +174,7 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps
if (!integrationData) {
return undefined;
}
- const overflowMenu = canWriteMoreFeatures ? getOverflowMenu(integration) : [];
+ const overflowMenu = getOverflowMenu(integration);
const iconProps = integrationData?.icon
? {
@@ -186,32 +184,6 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps
: {};
const isUber = integration === CONST.POLICY.RECEIPT_PARTNERS.NAME.UBER;
- let rightComponent: React.ReactNode;
- if (canWriteMoreFeatures && (isUberConnected || shouldShowEnterCredentialsError)) {
- rightComponent = (
-
-
-
- );
- } else if (canWriteMoreFeatures) {
- rightComponent = (
-
@@ -336,9 +323,6 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps
switchAccessibilityLabel={translate('workspace.receiptPartners.uber.autoRemove')}
onToggle={toggleWorkspaceUberAutoRemove}
isActive={isAutoRemove}
- disabled={!canWriteMoreFeatures}
- disabledAction={showReadOnlyModal}
- showLockIcon={!canWriteMoreFeatures}
/>
@@ -347,28 +331,23 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps
- Navigation.navigate(
- ROUTES.WORKSPACE_RECEIPT_PARTNERS_CHANGE_BILLING_ACCOUNT.getRoute(policyID, CONST.POLICY.RECEIPT_PARTNERS.NAME.UBER),
- )
- : undefined
+ onPress={() =>
+ Navigation.navigate(
+ ROUTES.WORKSPACE_RECEIPT_PARTNERS_CHANGE_BILLING_ACCOUNT.getRoute(policyID, CONST.POLICY.RECEIPT_PARTNERS.NAME.UBER),
+ )
}
/>
)}
- {canWriteMoreFeatures && (
- Navigation.navigate(ROUTES.WORKSPACE_RECEIPT_PARTNERS_INVITE_EDIT.getRoute(policyID, CONST.POLICY.RECEIPT_PARTNERS.NAME.UBER))}
- />
- )}
+ Navigation.navigate(ROUTES.WORKSPACE_RECEIPT_PARTNERS_INVITE_EDIT.getRoute(policyID, CONST.POLICY.RECEIPT_PARTNERS.NAME.UBER))}
+ />
>
)}
diff --git a/src/pages/workspace/reports/WorkspaceReportsPage.tsx b/src/pages/workspace/reports/WorkspaceReportsPage.tsx
index 5480f9d12c74..517fed78a904 100644
--- a/src/pages/workspace/reports/WorkspaceReportsPage.tsx
+++ b/src/pages/workspace/reports/WorkspaceReportsPage.tsx
@@ -22,7 +22,6 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePolicy from '@hooks/usePolicy';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceDocumentTitle from '@hooks/useWorkspaceDocumentTitle';
@@ -68,7 +67,6 @@ function WorkspaceReportFieldsPage({
const {translate, localeCompare} = useLocalize();
const policy = usePolicy(policyID);
const {showConfirmModal} = useConfirmModal();
- const {canWrite: canWriteReportFields, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.REPORT_FIELDS);
useWorkspaceDocumentTitle(policy?.name, 'workspace.common.reports');
const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`);
const isSyncInProgress = isConnectionInProgress(connectionSyncProgress, policy);
@@ -124,10 +122,6 @@ function WorkspaceReportFieldsPage({
: [];
const navigateToReportFieldsSettings = (reportField: ReportFieldForList) => {
- if (!canWriteReportFields) {
- return;
- }
-
Navigation.navigate(ROUTES.WORKSPACE_REPORT_FIELDS_SETTINGS.getRoute(policyID, reportField.fieldID));
};
@@ -155,8 +149,8 @@ function WorkspaceReportFieldsPage({
onPress={() => navigateToReportFieldsSettings(item)}
description={item.text}
disabled={item.isDisabled}
- shouldShowRightIcon={!item.isDisabled && canWriteReportFields}
- interactive={!item.isDisabled && canWriteReportFields}
+ shouldShowRightIcon={!item.isDisabled}
+ interactive={!item.isDisabled}
rightLabel={item.rightLabel}
descriptionTextStyle={[styles.popoverMenuText, styles.textStrong]}
/>
@@ -206,7 +200,6 @@ function WorkspaceReportFieldsPage({
Navigation.navigate(ROUTES.REPORTS_DEFAULT_TITLE.getRoute(policyID))}
- interactive={canWriteReportFields}
/>
@@ -332,7 +320,7 @@ function WorkspaceReportFieldsPage({
maintainVisibleContentPosition={{disabled: true}}
/>
- {!hasAccountingConnections && canWriteReportFields && (
+ {!hasAccountingConnections && (
Navigation.navigate(ROUTES.WORKSPACE_CREATE_REPORT_FIELD.getRoute(policyID))}
title={translate('workspace.reportFields.addField')}
diff --git a/src/pages/workspace/rules/ExpenseReportRulesSection.tsx b/src/pages/workspace/rules/ExpenseReportRulesSection.tsx
index deed2cf60094..fe9d4a8ad7a7 100644
--- a/src/pages/workspace/rules/ExpenseReportRulesSection.tsx
+++ b/src/pages/workspace/rules/ExpenseReportRulesSection.tsx
@@ -16,12 +16,9 @@ import ROUTES from '@src/ROUTES';
type ExpenseReportRulesSectionProps = {
policyID: string;
- canWriteApprovals: boolean;
- canWritePayments: boolean;
- showReadOnlyModal: () => void;
};
-function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayments, showReadOnlyModal}: ExpenseReportRulesSectionProps) {
+function ExpenseReportRulesSection({policyID}: ExpenseReportRulesSectionProps) {
const {convertToDisplayString} = useCurrencyListActions();
const {translate} = useLocalize();
const styles = useThemeStyles();
@@ -48,9 +45,8 @@ function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayment
shouldParseSubtitle: workflowApprovalsUnavailable,
switchAccessibilityLabel: translate('workspace.rules.expenseReportRules.preventSelfApprovalsTitle'),
isActive: policy?.preventSelfApproval,
- disabled: workflowApprovalsUnavailable || !canWriteApprovals,
- disabledAction: !canWriteApprovals ? showReadOnlyModal : undefined,
- showLockIcon: workflowApprovalsUnavailable || !canWriteApprovals,
+ disabled: workflowApprovalsUnavailable,
+ showLockIcon: workflowApprovalsUnavailable,
pendingAction: policy?.pendingFields?.preventSelfApproval ?? policy?.pendingAction,
onToggle: (isEnabled: boolean) => {
if (isEnabled && !isControlPolicy(policy)) {
@@ -71,9 +67,8 @@ function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayment
shouldParseSubtitle: workflowApprovalsUnavailable,
switchAccessibilityLabel: translate('workspace.rules.expenseReportRules.autoApproveCompliantReportsTitle'),
isActive: policy?.shouldShowAutoApprovalOptions && !workflowApprovalsUnavailable,
- disabled: workflowApprovalsUnavailable || !canWriteApprovals,
- disabledAction: !canWriteApprovals ? showReadOnlyModal : undefined,
- showLockIcon: workflowApprovalsUnavailable || !canWriteApprovals,
+ disabled: workflowApprovalsUnavailable,
+ showLockIcon: workflowApprovalsUnavailable,
pendingAction: policy?.pendingFields?.shouldShowAutoApprovalOptions ?? policy?.pendingAction,
onToggle: (isEnabled: boolean) => {
if (isEnabled && !isControlPolicy(policy)) {
@@ -93,10 +88,9 @@ function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayment
Navigation.navigate(ROUTES.RULES_AUTO_APPROVE_REPORTS_UNDER.getRoute(policyID))}
- interactive={canWriteApprovals}
/>
,
Navigation.navigate(ROUTES.RULES_RANDOM_REPORT_AUDIT.getRoute(policyID))}
- interactive={canWriteApprovals}
/>
,
],
@@ -133,9 +126,8 @@ function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayment
enablePolicyAutoReimbursementLimit(policyID, isEnabled, policy?.shouldShowAutoReimbursementLimitOption, policy?.autoReimbursement?.limit);
},
- disabled: autoPayApprovedReportsUnavailable || !canWritePayments,
- disabledAction: !canWritePayments ? showReadOnlyModal : undefined,
- showLockIcon: autoPayApprovedReportsUnavailable || !canWritePayments,
+ disabled: autoPayApprovedReportsUnavailable,
+ showLockIcon: autoPayApprovedReportsUnavailable,
isActive: policy?.shouldShowAutoReimbursementLimitOption && !autoPayApprovedReportsUnavailable,
pendingAction: policy?.pendingFields?.shouldShowAutoReimbursementLimitOption ?? policy?.pendingAction,
subMenuItems: [
@@ -150,10 +142,9 @@ function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayment
Navigation.navigate(ROUTES.RULES_AUTO_PAY_REPORTS_UNDER.getRoute(policyID))}
- interactive={canWritePayments}
/>
,
],
@@ -169,7 +160,7 @@ function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayment
subtitleTextStyles={policy?.pendingAction ? styles.opacitySemiTransparent : undefined}
subtitleMuted
>
- {optionItems.map(({title, subtitle, shouldParseSubtitle, isActive, subMenuItems, showLockIcon, disabled, disabledAction, onToggle, pendingAction}, index) => {
+ {optionItems.map(({title, subtitle, shouldParseSubtitle, isActive, subMenuItems, showLockIcon, disabled, onToggle, pendingAction}, index) => {
const showBorderBottom = index !== optionItems.length - 1;
return (
@@ -185,7 +176,6 @@ function ExpenseReportRulesSection({policyID, canWriteApprovals, canWritePayment
isActive={!!isActive}
showLockIcon={showLockIcon}
disabled={disabled}
- disabledAction={disabledAction}
subMenuItems={subMenuItems}
onToggle={onToggle}
pendingAction={pendingAction}
diff --git a/src/pages/workspace/rules/IndividualExpenseRulesSection.tsx b/src/pages/workspace/rules/IndividualExpenseRulesSection.tsx
index acdd3e9f39bb..15da61a2f56e 100644
--- a/src/pages/workspace/rules/IndividualExpenseRulesSection.tsx
+++ b/src/pages/workspace/rules/IndividualExpenseRulesSection.tsx
@@ -23,8 +23,6 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject';
type IndividualExpenseRulesSectionProps = {
policyID: string;
- canWriteRules: boolean;
- showReadOnlyModal: () => void;
};
type IndividualExpenseRulesSectionSubtitleProps = {
@@ -62,7 +60,7 @@ function IndividualExpenseRulesSectionSubtitle({policy, translate, environmentUR
return ;
}
-function IndividualExpenseRulesSection({policyID, canWriteRules, showReadOnlyModal}: IndividualExpenseRulesSectionProps) {
+function IndividualExpenseRulesSection({policyID}: IndividualExpenseRulesSectionProps) {
const {convertToDisplayString} = useCurrencyListActions();
const {translate} = useLocalize();
const styles = useThemeStyles();
@@ -225,12 +223,11 @@ function IndividualExpenseRulesSection({policyID, canWriteRules, showReadOnlyMod
key={translate(item.descriptionTranslationKey)}
>
@@ -240,16 +237,15 @@ function IndividualExpenseRulesSection({policyID, canWriteRules, showReadOnlyMod
title={translate('workspace.rules.individualExpenseRules.requireCompanyCard')}
subtitle={translate('workspace.rules.individualExpenseRules.requireCompanyCardDescription')}
switchAccessibilityLabel={translate('workspace.rules.individualExpenseRules.requireCompanyCard')}
- disabled={!canWriteRules || disableRequireCompanyCardToggle}
- disabledAction={!canWriteRules ? showReadOnlyModal : undefined}
- showLockIcon={!canWriteRules || disableRequireCompanyCardToggle}
+ disabled={disableRequireCompanyCardToggle}
+ showLockIcon={disableRequireCompanyCardToggle}
disabledText={translate('workspace.rules.individualExpenseRules.requireCompanyCardDisabledTooltip')}
wrapperStyle={[styles.mt3]}
titleStyle={styles.pv2}
subtitleStyle={styles.pt1}
isActive={requireCompanyCardsEnabled}
pendingAction={policy?.pendingFields?.requireCompanyCardsEnabled}
- onToggle={() => (canWriteRules && policy ? setPolicyRequireCompanyCardsEnabled(policy, !requireCompanyCardsEnabled) : undefined)}
+ onToggle={() => (policy ? setPolicyRequireCompanyCardsEnabled(policy, !requireCompanyCardsEnabled) : undefined)}
/>
(canWriteRules ? setWorkspaceEReceiptsEnabled(policyID, !areEReceiptsEnabled, policy?.eReceipts) : undefined)}
+ disabled={policyCurrency !== CONST.CURRENCY.USD}
+ onToggle={() => setWorkspaceEReceiptsEnabled(policyID, !areEReceiptsEnabled, policy?.eReceipts)}
pendingAction={policy?.pendingFields?.eReceipts}
/>
(canWriteRules ? handleAttendeeTrackingToggle(!isAttendeeTrackingEnabledForPolicy) : undefined)}
+ onToggle={() => handleAttendeeTrackingToggle(!isAttendeeTrackingEnabledForPolicy)}
pendingAction={policy?.pendingFields?.isAttendeeTrackingEnabled}
/>
diff --git a/src/pages/workspace/rules/MerchantRulesSection.tsx b/src/pages/workspace/rules/MerchantRulesSection.tsx
index 96df1e452f0a..341e4c723cd8 100644
--- a/src/pages/workspace/rules/MerchantRulesSection.tsx
+++ b/src/pages/workspace/rules/MerchantRulesSection.tsx
@@ -27,7 +27,6 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject';
type MerchantRulesSectionProps = {
policyID: string;
- canWriteRules: boolean;
};
type FieldLabels = {
@@ -70,7 +69,7 @@ function getRuleDescription(rule: CodingRule, translate: ReturnType (index === 0 ? action : action.charAt(0).toLowerCase() + action.slice(1))).join(', ');
}
-function MerchantRulesSection({policyID, canWriteRules}: MerchantRulesSectionProps) {
+function MerchantRulesSection({policyID}: MerchantRulesSectionProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const theme = useTheme();
@@ -172,9 +171,8 @@ function MerchantRulesSection({policyID, canWriteRules}: MerchantRulesSectionPro
wrapperStyle={[styles.borderedContentCard, styles.ph4, styles.pv4]}
descriptionTextStyle={[styles.textNormalThemeText, {lineHeight: variables.fontSizeNormalHeight}]}
titleStyle={[styles.textLabelSupporting, styles.fontSizeLabel]}
- shouldShowRightIcon={canWriteRules}
+ shouldShowRightIcon
onPress={() => Navigation.navigate(ROUTES.RULES_MERCHANT_EDIT.getRoute(policyID, rule.ruleID))}
- interactive={canWriteRules}
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.RULES.MERCHANT_RULE_ITEM}
disabled={rule.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE}
/>
@@ -184,18 +182,16 @@ function MerchantRulesSection({policyID, canWriteRules}: MerchantRulesSectionPro
})}
)}
- {canWriteRules && (
- Navigation.navigate(ROUTES.RULES_MERCHANT_NEW.getRoute(policyID))}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.RULES.ADD_MERCHANT_RULE}
- />
- )}
+ Navigation.navigate(ROUTES.RULES_MERCHANT_NEW.getRoute(policyID))}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.RULES.ADD_MERCHANT_RULE}
+ />
);
}
diff --git a/src/pages/workspace/rules/PolicyRulesPage.tsx b/src/pages/workspace/rules/PolicyRulesPage.tsx
index 0e32fd505301..85ce7b8c2a67 100644
--- a/src/pages/workspace/rules/PolicyRulesPage.tsx
+++ b/src/pages/workspace/rules/PolicyRulesPage.tsx
@@ -8,7 +8,6 @@ import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import usePermissions from '@hooks/usePermissions';
import usePolicy from '@hooks/usePolicy';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceDocumentTitle from '@hooks/useWorkspaceDocumentTitle';
@@ -39,7 +38,6 @@ function PolicyRulesPage({route}: PolicyRulesPageProps) {
const styles = useThemeStyles();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const illustrations = useMemoizedLazyIllustrations(['Rules']);
- const {canWrite: canWriteRules, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.RULES);
const {isBetaEnabled} = usePermissions();
const isCustomAgentBetaEnabled = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT);
const [isAgentsRulesBannerDismissed = false] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {selector: agentsRulesBannerDismissedSelector});
@@ -57,7 +55,6 @@ function PolicyRulesPage({route}: PolicyRulesPageProps) {
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED}
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
- policyFeature={CONST.POLICY.POLICY_FEATURE.RULES}
>
)}
-
-
- {!!policy?.areExpensifyCardsEnabled && (
-
- )}
+
+
+ {!!policy?.areExpensifyCardsEnabled && }
diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
index 5958431edc3f..a0e3d9de6593 100644
--- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx
+++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx
@@ -31,7 +31,6 @@ import useMobileSelectionMode from '@hooks/useMobileSelectionMode';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePolicyData from '@hooks/usePolicyData';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useSearchBackPress from '@hooks/useSearchBackPress';
import useSearchResults from '@hooks/useSearchResults';
@@ -119,8 +118,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
[policy, policyTags],
);
- const {canWrite: canWriteTags, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.TAGS);
- const canSelectMultiple = canWriteTags && !hasDependentTags && (shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true);
+ const canSelectMultiple = !hasDependentTags && (shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true);
const isControlPolicyWithWideLayout = !shouldUseNarrowLayout && isControlPolicy(policy);
const shouldShowApproverColumn = isControlPolicyWithWideLayout && !isMultiLevelTags && !!policy?.areRulesEnabled;
const fetchTags = useCallback(() => {
@@ -219,26 +217,16 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
const updateWorkspaceTagEnabled = useCallback(
(value: boolean, tagName: string) => {
- if (!canWriteTags) {
- showReadOnlyModal();
- return;
- }
-
setWorkspaceTagEnabled(policyData, {[tagName]: {name: tagName, enabled: value}}, 0);
},
- [canWriteTags, policyData, showReadOnlyModal],
+ [policyData],
);
const updateWorkspaceRequiresTag = useCallback(
(value: boolean, orderWeight: number) => {
- if (!canWriteTags) {
- showReadOnlyModal();
- return;
- }
-
setPolicyTagsRequired(policyData, value, orderWeight);
},
- [canWriteTags, policyData, showReadOnlyModal],
+ [policyData],
);
const glCodeContainerStyle = useMemo(() => [styles.flex1], [styles.flex1]);
const glCodeTextStyle = useMemo(() => [styles.alignSelfStart], [styles.alignSelfStart]);
@@ -250,16 +238,23 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
const areTagsEnabled = !!Object.values(policyTagList?.tags ?? {}).some((tag) => tag.enabled);
const isSwitchDisabled = !policyTagList.required && !areTagsEnabled;
const isSwitchEnabled = policyTagList.required && areTagsEnabled;
- let rightElement;
- if (hasDependentTags) {
- rightElement = canWriteTags ? (
+ if (policyTagList.required && !areTagsEnabled) {
+ updateWorkspaceRequiresTag(false, policyTagList.orderWeight);
+ }
+ return {
+ value: policyTagList.name,
+ orderWeight: policyTagList.orderWeight,
+ text: getCleanedTagName(policyTagList.name),
+ alternateText: !hasDependentTags ? translate('workspace.tags.tagCount', {count: Object.keys(policyTagList?.tags ?? {}).length}) : '',
+ keyForList: getCleanedTagName(policyTagList.name),
+ pendingAction: getPendingAction(policyTagList),
+ enabled: true,
+ required: policyTagList.required,
+ isDisabledCheckbox: isSwitchDisabled,
+ rightElement: hasDependentTags ? (
) : (
- {translate('workspace.tags.tagCount', {count: Object.keys(policyTagList?.tags ?? {}).length})}
- );
- } else {
- rightElement = (
- );
- }
-
- if (canWriteTags && policyTagList.required && !areTagsEnabled) {
- updateWorkspaceRequiresTag(false, policyTagList.orderWeight);
- }
- return {
- value: policyTagList.name,
- orderWeight: policyTagList.orderWeight,
- text: getCleanedTagName(policyTagList.name),
- alternateText: !hasDependentTags ? translate('workspace.tags.tagCount', {count: Object.keys(policyTagList?.tags ?? {}).length}) : '',
- keyForList: getCleanedTagName(policyTagList.name),
- pendingAction: getPendingAction(policyTagList),
- enabled: true,
- required: policyTagList.required,
- isDisabledCheckbox: isSwitchDisabled,
- rightElement,
+ ),
};
});
}
@@ -350,8 +328,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
{
if (isDisablingOrDeletingLastEnabledTag(policyTagLists.at(0), [tag])) {
@@ -365,15 +342,14 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
}
updateWorkspaceTagEnabled(newValue, tag.name);
}}
- showLockIcon={!canWriteTags || isDisablingOrDeletingLastEnabledTag(policyTagLists.at(0), [tag])}
+ showLockIcon={isDisablingOrDeletingLastEnabledTag(policyTagLists.at(0), [tag])}
/>
>
) : (
{
if (isDisablingOrDeletingLastEnabledTag(policyTagLists.at(0), [tag])) {
@@ -387,7 +363,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
}
updateWorkspaceTagEnabled(newValue, tag.name);
}}
- showLockIcon={!canWriteTags || isDisablingOrDeletingLastEnabledTag(policyTagLists.at(0), [tag])}
+ showLockIcon={isDisablingOrDeletingLastEnabledTag(policyTagLists.at(0), [tag])}
/>
),
};
@@ -410,8 +386,6 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
styles.alignItemsCenter,
styles.flexRow,
styles.mr3,
- canWriteTags,
- showReadOnlyModal,
]);
const filterTag = useCallback((tag: TagListItem, searchInput: string) => {
@@ -461,15 +435,15 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
canSelectMultiple={false}
leftHeaderText={translate('common.name')}
rightHeaderText={translate('common.count')}
- shouldShowRightCaret={canWriteTags}
+ shouldShowRightCaret
/>
);
}
// Show GL Code column only on wide screens for control policies. Approver column additionally requires rules to be enabled
if (isControlPolicyWithWideLayout && !isMultiLevelTags) {
- const header = (
-
+ return (
+
{translate('common.name')}
@@ -481,17 +455,11 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
{translate('common.approver')}
)}
-
+
{translate('common.enabled')}
);
-
- if (canSelectMultiple) {
- return header;
- }
-
- return {header};
}
return (
@@ -499,7 +467,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
canSelectMultiple={canSelectMultiple}
leftHeaderText={translate('common.name')}
rightHeaderText={translate(isMultiLevelTags ? 'common.required' : 'common.enabled')}
- shouldShowRightCaret={canWriteTags}
+ shouldShowRightCaret
/>
);
};
@@ -513,10 +481,6 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
};
const navigateToTagSettings = (tag: TagListItem) => {
- if (!canWriteTags) {
- return;
- }
-
if (isSmallScreenWidth && isMobileSelectionModeEnabled) {
toggleTag(tag);
return;
@@ -568,16 +532,14 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
const hasAccountingConnections = hasAccountingConnectionsPolicyUtils(policy);
const secondaryActions = useMemo(() => {
const menuItems = [];
- if (canWriteTags) {
- menuItems.push({
- icon: expensifyIcons.Gear,
- text: translate('common.settings'),
- onSelected: navigateToTagsSettings,
- value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
- });
- }
+ menuItems.push({
+ icon: expensifyIcons.Gear,
+ text: translate('common.settings'),
+ onSelected: navigateToTagsSettings,
+ value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
+ });
- if (canWriteTags && !hasAccountingConnections) {
+ if (!hasAccountingConnections) {
menuItems.push({
icon: expensifyIcons.Table,
text: translate('spreadsheet.importSpreadsheet'),
@@ -639,21 +601,16 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
hasDependentTags,
expensifyIcons,
showConfirmModal,
- canWriteTags,
]);
const shouldDisplayButtonsInSeparateLine = useShouldDisplayButtonsInSeparateLine();
const getHeaderButtons = () => {
- if (!canWriteTags && secondaryActions.length === 0) {
- return null;
- }
-
const selectedTagsObject = selectedTags.map((key) => policyTagLists.at(0)?.tags?.[key]);
const selectedTagLists = selectedTags.map((selectedTag) => policyTagLists.find((policyTagList) => policyTagList.name === selectedTag));
- if (!canWriteTags || (shouldUseNarrowLayout ? !isMobileSelectionModeEnabled : selectedTags.length === 0)) {
- const hasPrimaryActions = canWriteTags && !hasAccountingConnections && !isMultiLevelTags && hasVisibleTags;
+ if (shouldUseNarrowLayout ? !isMobileSelectionModeEnabled : selectedTags.length === 0) {
+ const hasPrimaryActions = !hasAccountingConnections && !isMultiLevelTags && hasVisibleTags;
return (
{hasPrimaryActions && (
@@ -666,18 +623,16 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
style={[shouldDisplayButtonsInSeparateLine && styles.flex1]}
/>
)}
- {secondaryActions.length > 0 && (
- {}}
- shouldAlwaysShowDropdownMenu
- customText={translate('common.more')}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAGS.MORE_DROPDOWN}
- options={secondaryActions}
- isSplitButton={false}
- wrapperStyle={isInLandscapeMode || hasPrimaryActions ? styles.flexGrow0 : styles.flexGrow1}
- />
- )}
+ {}}
+ shouldAlwaysShowDropdownMenu
+ customText={translate('common.more')}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAGS.MORE_DROPDOWN}
+ options={secondaryActions}
+ isSplitButton={false}
+ wrapperStyle={isInLandscapeMode || hasPrimaryActions ? styles.flexGrow0 : styles.flexGrow1}
+ />
);
}
@@ -907,7 +862,6 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
policyID={policyID}
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
featureName={CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.TAGS}
>
{!shouldDisplayButtonsInSeparateLine && getHeaderButtons()}
- {shouldDisplayButtonsInSeparateLine && !!getHeaderButtons() && {getHeaderButtons()}}
+ {shouldDisplayButtonsInSeparateLine && {getHeaderButtons()}}
{(!hasVisibleTags || isLoading) && headerContent}
{isLoading && (
0 ? toggleAllTags : undefined}
+ onSelectAll={filteredTagList.length > 0 ? toggleAllTags : undefined}
customListHeader={filteredTagList.length > 0 ? getCustomListHeader() : undefined}
onDismissError={(item) => !hasDependentTags && clearPolicyTagErrors({policyID, tagName: item.value, tagListIndex: 0, policyTags})}
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}
- onTurnOnSelectionMode={(item) => item && canWriteTags && toggleTag(item)}
- turnOnSelectionModeOnLongPress={canWriteTags && !hasDependentTags}
+ onTurnOnSelectionMode={(item) => item && toggleTag(item)}
+ turnOnSelectionModeOnLongPress={!hasDependentTags}
shouldSingleExecuteRowSelect={!canSelectMultiple}
customListHeaderContent={headerContent}
shouldShowListEmptyContent={false}
@@ -970,7 +924,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
onSelectionButtonPress={toggleTag}
isSelected={isTagSelected}
shouldHeaderBeInsideList
- shouldShowRightCaret={canWriteTags}
+ shouldShowRightCaret
/>
)}
{!hasVisibleTags && !isLoading && (
@@ -981,7 +935,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
subtitleText={subtitleText}
headerStyles={styles.emptyStateCardIllustrationContainer}
buttons={
- canWriteTags && !hasAccountingConnections
+ !hasAccountingConnections
? [
{
icon: expensifyIcons.Table,
diff --git a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
index cc2e92ffaea2..231f3e039260 100644
--- a/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
+++ b/src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
@@ -23,7 +23,6 @@ import useLocalize from '@hooks/useLocalize';
import useMobileSelectionMode from '@hooks/useMobileSelectionMode';
import useNetwork from '@hooks/useNetwork';
import usePolicyData from '@hooks/usePolicyData';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useSearchBackPress from '@hooks/useSearchBackPress';
import useSearchResults from '@hooks/useSearchResults';
@@ -83,7 +82,6 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
const hasDependentTags = useMemo(() => hasDependentTagsPolicyUtils(policy, policyTags), [policy, policyTags]);
const isMultiLevelTags = isMultiLevelTagsPolicyUtils(policyTags);
const currentPolicyTag = policyTags?.[currentTagListName];
- const {canWrite: canWriteTags, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.TAGS);
const isQuickSettingsFlow = route.name === SCREENS.SETTINGS_TAGS.DYNAMIC_SETTINGS_TAG_LIST_VIEW;
const backPath = useDynamicBackPath(DYNAMIC_ROUTES.SETTINGS_TAG_LIST_VIEW.path);
const fetchTags = useCallback(() => {
@@ -96,14 +94,11 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
const {isOffline} = useNetwork({onReconnect: fetchTags});
const canSelectMultiple = useMemo(() => {
- if (!canWriteTags) {
- return false;
- }
if (hasDependentTags) {
return false;
}
return isSmallScreenWidth ? isMobileSelectionModeEnabled : true;
- }, [canWriteTags, hasDependentTags, isSmallScreenWidth, isMobileSelectionModeEnabled]);
+ }, [hasDependentTags, isSmallScreenWidth, isMobileSelectionModeEnabled]);
useEffect(() => {
if (isFocused) {
@@ -124,60 +119,47 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
const updateWorkspaceTagEnabled = useCallback(
(value: boolean, tagName: string) => {
- if (!canWriteTags) {
- showReadOnlyModal();
- return;
- }
-
setWorkspaceTagEnabled(policyData, {[tagName]: {name: tagName, enabled: value}}, orderWeight);
},
- [canWriteTags, policyData, orderWeight, showReadOnlyModal],
+ [policyData, orderWeight],
);
const tagList = useMemo(
() =>
- Object.values(currentPolicyTag?.tags ?? {}).map((tag) => {
- let rightElement;
- if (hasDependentTags && canWriteTags) {
- rightElement = ;
- } else if (!hasDependentTags) {
- rightElement = (
- {
- if (isDisablingOrDeletingLastEnabledTag(currentPolicyTag, [tag])) {
- showConfirmModal({
- title: translate('workspace.tags.cannotDeleteOrDisableAllTags.title'),
- prompt: translate('workspace.tags.cannotDeleteOrDisableAllTags.description'),
- confirmText: translate('common.buttonConfirm'),
- shouldShowCancelButton: false,
- });
- return;
- }
- updateWorkspaceTagEnabled(newValue, tag.name);
- }}
- showLockIcon={!canWriteTags || isDisablingOrDeletingLastEnabledTag(currentPolicyTag, [tag])}
- />
- );
- }
-
- return {
- value: tag.name,
- text: hasDependentTags ? tag.name : getCleanedTagName(tag.name),
- keyForList: hasDependentTags ? `${tag.name}-${tag.rules?.parentTagsFilter ?? ''}` : tag.name,
- isSelected: selectedTags.includes(tag.name) && canSelectMultiple,
- pendingAction: tag.pendingAction,
- rules: tag.rules,
- errors: tag.errors ?? undefined,
- enabled: tag.enabled,
- isDisabled: tag.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE,
- rightElement,
- };
- }),
- [currentPolicyTag, hasDependentTags, canWriteTags, selectedTags, canSelectMultiple, translate, updateWorkspaceTagEnabled, showConfirmModal, showReadOnlyModal],
+ Object.values(currentPolicyTag?.tags ?? {}).map((tag) => ({
+ value: tag.name,
+ text: hasDependentTags ? tag.name : getCleanedTagName(tag.name),
+ keyForList: hasDependentTags ? `${tag.name}-${tag.rules?.parentTagsFilter ?? ''}` : tag.name,
+ isSelected: selectedTags.includes(tag.name) && canSelectMultiple,
+ pendingAction: tag.pendingAction,
+ rules: tag.rules,
+ errors: tag.errors ?? undefined,
+ enabled: tag.enabled,
+ isDisabled: tag.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE,
+ rightElement: hasDependentTags ? (
+
+ ) : (
+ {
+ if (isDisablingOrDeletingLastEnabledTag(currentPolicyTag, [tag])) {
+ showConfirmModal({
+ title: translate('workspace.tags.cannotDeleteOrDisableAllTags.title'),
+ prompt: translate('workspace.tags.cannotDeleteOrDisableAllTags.description'),
+ confirmText: translate('common.buttonConfirm'),
+ shouldShowCancelButton: false,
+ });
+ return;
+ }
+ updateWorkspaceTagEnabled(newValue, tag.name);
+ }}
+ showLockIcon={isDisablingOrDeletingLastEnabledTag(currentPolicyTag, [tag])}
+ />
+ ),
+ })),
+ [currentPolicyTag, hasDependentTags, selectedTags, canSelectMultiple, translate, updateWorkspaceTagEnabled, showConfirmModal],
);
const filterTag = useCallback((tag: TagListItem, searchInput: string) => {
@@ -227,16 +209,12 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
canSelectMultiple={canSelectMultiple}
leftHeaderText={translate('common.name')}
rightHeaderText={hasDependentTags ? undefined : translate('common.enabled')}
- shouldShowRightCaret={canWriteTags}
+ shouldShowRightCaret
/>
);
};
const navigateToTagSettings = (tag: TagListItem) => {
- if (!canWriteTags) {
- return;
- }
-
Navigation.navigate(
isQuickSettingsFlow
? createDynamicRoute(DYNAMIC_ROUTES.SETTINGS_TAG_SETTINGS.getRoute(orderWeight, tag.value))
@@ -258,7 +236,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
) : undefined;
const getHeaderButtons = () => {
- if (!canWriteTags || (!isSmallScreenWidth && selectedTags.length === 0) || (isSmallScreenWidth && !isMobileSelectionModeEnabled)) {
+ if ((!isSmallScreenWidth && selectedTags.length === 0) || (isSmallScreenWidth && !isMobileSelectionModeEnabled)) {
return null;
}
@@ -356,15 +334,11 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
);
};
- if (canWriteTags && !!currentPolicyTag?.required && !Object.values(currentPolicyTag?.tags ?? {}).some((tag) => tag.enabled)) {
+ if (!!currentPolicyTag?.required && !Object.values(currentPolicyTag?.tags ?? {}).some((tag) => tag.enabled)) {
setPolicyTagsRequired(policyData, false, orderWeight);
}
const navigateToEditTag = () => {
- if (!canWriteTags) {
- return;
- }
-
Navigation.navigate(
isQuickSettingsFlow
? createDynamicRoute(DYNAMIC_ROUTES.SETTINGS_TAGS_EDIT.getRoute(currentPolicyTag?.orderWeight ?? 0))
@@ -379,7 +353,6 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
policyID={policyID}
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
featureName={CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.TAGS}
>
{!shouldDisplayButtonsInSeparateLine && getHeaderButtons()}
- {shouldDisplayButtonsInSeparateLine && !!getHeaderButtons() && {getHeaderButtons()}}
+ {shouldDisplayButtonsInSeparateLine && {getHeaderButtons()}}
{!hasDependentTags && (
{
- if (!canWriteTags) {
- showReadOnlyModal();
- return;
- }
-
if (!isMultiLevelTags) {
showConfirmModal({
title: translate('workspace.tags.cannotMakeTagListRequired.title'),
@@ -435,9 +403,8 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
pendingAction={currentPolicyTag.pendingFields?.required}
errors={currentPolicyTag?.errorFields?.required ?? undefined}
onCloseError={() => clearPolicyTagListErrorField({policyID, tagListIndex: orderWeight, errorField: 'required', policyTags})}
- disabled={!canWriteTags || (!currentPolicyTag?.required && !Object.values(currentPolicyTag?.tags ?? {}).some((tag) => tag.enabled))}
- disabledAction={!canWriteTags ? showReadOnlyModal : undefined}
- showLockIcon={!canWriteTags || !isMultiLevelTags || isMakingLastRequiredTagListOptional(policy, policyTags, [currentPolicyTag])}
+ disabled={!currentPolicyTag?.required && !Object.values(currentPolicyTag?.tags ?? {}).some((tag) => tag.enabled)}
+ showLockIcon={!isMultiLevelTags || isMakingLastRequiredTagListOptional(policy, policyTags, [currentPolicyTag])}
/>
)}
@@ -451,8 +418,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
title={getCleanedTagName(currentPolicyTag.name)}
description={translate(`workspace.tags.customTagName`)}
onPress={navigateToEditTag}
- shouldShowRightIcon={canWriteTags}
- interactive={canWriteTags}
+ shouldShowRightIcon
/>
{isLoading && (
@@ -468,11 +434,11 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
ListItem={TableListItem}
selectedItems={selectedTags}
customListHeader={getCustomListHeader()}
- onSelectAll={canWriteTags && filteredTagList.length > 0 ? toggleAllTags : undefined}
+ onSelectAll={filteredTagList.length > 0 ? toggleAllTags : undefined}
onDismissError={(item) => clearPolicyTagErrors({policyID, tagName: item.value, tagListIndex: orderWeight, policyTags})}
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}
- onTurnOnSelectionMode={(item) => item && canWriteTags && toggleTag(item)}
- turnOnSelectionModeOnLongPress={canWriteTags && !hasDependentTags}
+ onTurnOnSelectionMode={(item) => item && toggleTag(item)}
+ turnOnSelectionModeOnLongPress={!hasDependentTags}
customListHeaderContent={listHeaderContent}
canSelectMultiple={canSelectMultiple}
selectAllAccessibilityLabel={translate('accessibilityHints.selectAllTags')}
@@ -480,7 +446,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
shouldShowListEmptyContent={false}
onSelectionButtonPress={toggleTag}
shouldHeaderBeInsideList
- shouldShowRightCaret={canWriteTags}
+ shouldShowRightCaret
showScrollIndicator
/>
)}
diff --git a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
index f7daed31c66c..7c8316821549 100644
--- a/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
+++ b/src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
@@ -22,7 +22,6 @@ import useLocalize from '@hooks/useLocalize';
import useMobileSelectionMode from '@hooks/useMobileSelectionMode';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useSearchBackPress from '@hooks/useSearchBackPress';
import useSearchResults from '@hooks/useSearchResults';
@@ -73,7 +72,6 @@ function WorkspaceTaxesPage({
const [selectedTaxesIDs, setSelectedTaxesIDs] = useState([]);
const {showConfirmModal} = useConfirmModal();
const isMobileSelectionModeEnabled = useMobileSelectionMode();
- const {canWrite: canWriteTaxes, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.TAXES);
const defaultExternalID = policy?.taxRates?.defaultExternalID;
const foreignTaxDefault = policy?.taxRates?.foreignTaxDefault;
const hasAccountingConnections = hasAccountingConnectionsPolicyUtils(policy);
@@ -85,7 +83,7 @@ function WorkspaceTaxesPage({
const connectedIntegration = getConnectedIntegration(policy) ?? syncingAccountingIntegration;
const isConnectionVerified = connectedIntegration && !isConnectionUnverified(policy, connectedIntegration);
const currentConnectionName = getCurrentConnectionName(policy);
- const canSelectMultiple = canWriteTaxes && (shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true);
+ const canSelectMultiple = shouldUseNarrowLayout ? isMobileSelectionModeEnabled : true;
const enabledRatesCount = selectedTaxesIDs.filter((taxID) => !policy?.taxRates?.taxes[taxID]?.isDisabled).length;
const disabledRatesCount = selectedTaxesIDs.length - enabledRatesCount;
@@ -156,13 +154,9 @@ function WorkspaceTaxesPage({
const updateWorkspaceTaxEnabled = useCallback(
(value: boolean, taxID: string) => {
- if (!canWriteTaxes) {
- showReadOnlyModal();
- return;
- }
setPolicyTaxesEnabled(policy, [taxID], value);
},
- [canWriteTaxes, policy, showReadOnlyModal],
+ [policy],
);
const taxesList = useMemo(() => {
@@ -170,7 +164,7 @@ function WorkspaceTaxesPage({
return [];
}
return Object.entries(policy.taxRates?.taxes ?? {}).map(([key, value]) => {
- const canEditTaxRate = canWriteTaxes && policy && canEditTaxRatePolicyUtils(policy, key);
+ const canEditTaxRate = policy && canEditTaxRatePolicyUtils(policy, key);
return {
text: value.name,
@@ -184,15 +178,13 @@ function WorkspaceTaxesPage({
updateWorkspaceTaxEnabled(newValue, key)}
/>
),
};
});
- }, [canWriteTaxes, policy, showReadOnlyModal, textForDefault, translate, updateWorkspaceTaxEnabled]);
+ }, [policy, textForDefault, translate, updateWorkspaceTaxEnabled]);
const filterTax = useCallback((tax: ListItem, searchInput: string) => {
const results = tokenizedSearch([tax], searchInput, (option) => [option.text ?? '', option.alternateText ?? '']);
@@ -248,7 +240,7 @@ function WorkspaceTaxesPage({
canSelectMultiple={canSelectMultiple}
leftHeaderText={translate('common.name')}
rightHeaderText={translate('common.enabled')}
- shouldShowRightCaret={canWriteTaxes}
+ shouldShowRightCaret
/>
);
};
@@ -277,9 +269,6 @@ function WorkspaceTaxesPage({
if (!taxRate.keyForList) {
return;
}
- if (!canWriteTaxes) {
- return;
- }
if (isSmallScreenWidth && isMobileSelectionModeEnabled) {
toggleTax(taxRate);
return;
@@ -348,7 +337,7 @@ function WorkspaceTaxesPage({
deleteTaxes,
]);
- const shouldShowBulkActionsButton = canWriteTaxes && (shouldUseNarrowLayout ? isMobileSelectionModeEnabled : selectedTaxesIDs.length > 0);
+ const shouldShowBulkActionsButton = shouldUseNarrowLayout ? isMobileSelectionModeEnabled : selectedTaxesIDs.length > 0;
const secondaryActions = useMemo(
() => [
@@ -362,54 +351,42 @@ function WorkspaceTaxesPage({
[icons.Gear, policyID, translate],
);
- const getHeaderButtons = () => {
- if (!canWriteTaxes) {
- return null;
- }
-
- if (!shouldShowBulkActionsButton) {
- return (
-
- {!hasAccountingConnections && (
- Navigation.navigate(ROUTES.WORKSPACE_TAX_CREATE.getRoute(policyID))}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAXES.ADD_BUTTON}
- icon={icons.Plus}
- text={translate('workspace.taxes.addRate')}
- style={[shouldDisplayButtonsInSeparateLine && styles.flex1]}
- />
- )}
- {}}
- shouldUseOptionIcon
- customText={translate('common.more')}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAXES.MORE_DROPDOWN}
- options={secondaryActions}
- isSplitButton={false}
- wrapperStyle={hasAccountingConnections ? styles.flexGrow1 : styles.flexGrow0}
- />
-
- );
- }
-
- return (
-
+ const headerButtons = !shouldShowBulkActionsButton ? (
+
+ {!hasAccountingConnections && (
+ Navigation.navigate(ROUTES.WORKSPACE_TAX_CREATE.getRoute(policyID))}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAXES.ADD_BUTTON}
+ icon={icons.Plus}
+ text={translate('workspace.taxes.addRate')}
+ style={[shouldDisplayButtonsInSeparateLine && styles.flex1]}
+ />
+ )}
+ {}}
- options={dropdownMenuOptions}
- buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM}
- customText={translate('workspace.common.selected', {count: selectedTaxesIDs.length})}
- shouldAlwaysShowDropdownMenu
+ shouldUseOptionIcon
+ customText={translate('common.more')}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAXES.MORE_DROPDOWN}
+ options={secondaryActions}
isSplitButton={false}
- style={[shouldDisplayButtonsInSeparateLine && styles.flexGrow1, shouldDisplayButtonsInSeparateLine && styles.mb3]}
- isDisabled={!selectedTaxesIDs.length}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAXES.BULK_ACTIONS_DROPDOWN}
+ wrapperStyle={hasAccountingConnections ? styles.flexGrow1 : styles.flexGrow0}
/>
- );
- };
-
- const headerButtons = getHeaderButtons();
+
+ ) : (
+
+ onPress={() => {}}
+ options={dropdownMenuOptions}
+ buttonSize={CONST.DROPDOWN_BUTTON_SIZE.MEDIUM}
+ customText={translate('workspace.common.selected', {count: selectedTaxesIDs.length})}
+ shouldAlwaysShowDropdownMenu
+ isSplitButton={false}
+ style={[shouldDisplayButtonsInSeparateLine && styles.flexGrow1, shouldDisplayButtonsInSeparateLine && styles.mb3]}
+ isDisabled={!selectedTaxesIDs.length}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.TAXES.BULK_ACTIONS_DROPDOWN}
+ />
+ );
const selectionModeHeader = isMobileSelectionModeEnabled && shouldUseNarrowLayout;
@@ -443,7 +420,6 @@ function WorkspaceTaxesPage({
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.TAXES}
>
{!shouldDisplayButtonsInSeparateLine && headerButtons}
- {shouldDisplayButtonsInSeparateLine && !!headerButtons && {headerButtons}}
+ {shouldDisplayButtonsInSeparateLine && {headerButtons}}
{isLoading && (
canWriteTaxes && item && toggleTax(item)}
- onSelectAll={canWriteTaxes && filteredTaxesList.length > 0 ? toggleAllTaxes : undefined}
+ onTurnOnSelectionMode={(item) => item && toggleTax(item)}
+ onSelectAll={filteredTaxesList.length > 0 ? toggleAllTaxes : undefined}
onDismissError={(item) => (item.keyForList ? clearTaxRateError(policyID, item.keyForList, item.pendingAction) : undefined)}
shouldPreventDefaultFocusOnSelectRow={!canUseTouchScreen()}
customListHeader={getCustomListHeader()}
@@ -493,9 +469,9 @@ function WorkspaceTaxesPage({
shouldShowListEmptyContent={false}
onSelectionButtonPress={toggleTax}
showScrollIndicator={false}
- turnOnSelectionModeOnLongPress={canWriteTaxes}
+ turnOnSelectionModeOnLongPress
shouldHeaderBeInsideList
- shouldShowRightCaret={canWriteTaxes}
+ shouldShowRightCaret
/>
diff --git a/src/pages/workspace/timeTracking/WorkspaceTimeTrackingDefaultRateSection.tsx b/src/pages/workspace/timeTracking/WorkspaceTimeTrackingDefaultRateSection.tsx
index 6bc9c4011c3b..011b69899999 100644
--- a/src/pages/workspace/timeTracking/WorkspaceTimeTrackingDefaultRateSection.tsx
+++ b/src/pages/workspace/timeTracking/WorkspaceTimeTrackingDefaultRateSection.tsx
@@ -12,7 +12,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import {policyTimeTrackingSelector} from '@src/selectors/Policy';
-function WorkspaceTimeTrackingDefaultRateSection({policyID, canWriteMoreFeatures}: {policyID: string; canWriteMoreFeatures: boolean}) {
+function WorkspaceTimeTrackingDefaultRateSection({policyID}: {policyID: string}) {
const {convertToDisplayString} = useCurrencyListActions();
const {translate} = useLocalize();
const styles = useThemeStyles();
@@ -33,11 +33,10 @@ function WorkspaceTimeTrackingDefaultRateSection({policyID, canWriteMoreFeatures
Navigation.navigate(ROUTES.WORKSPACE_TIME_TRACKING_DEFAULT_RATE.getRoute(policyID))}
- interactive={canWriteMoreFeatures}
style={styles.sectionMenuItemTopDescription}
/>
diff --git a/src/pages/workspace/timeTracking/WorkspaceTimeTrackingPage.tsx b/src/pages/workspace/timeTracking/WorkspaceTimeTrackingPage.tsx
index 37baab2806d0..70a4d4bd44cb 100644
--- a/src/pages/workspace/timeTracking/WorkspaceTimeTrackingPage.tsx
+++ b/src/pages/workspace/timeTracking/WorkspaceTimeTrackingPage.tsx
@@ -1,6 +1,5 @@
import React from 'react';
import {View} from 'react-native';
-import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import usePolicy from '@hooks/usePolicy';
@@ -8,7 +7,6 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceDocumentTitle from '@hooks/useWorkspaceDocumentTitle';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
-import {canMemberWrite} from '@libs/PolicyUtils';
import type {WorkspaceSplitNavigatorParamList} from '@navigation/types';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections';
@@ -26,15 +24,12 @@ function WorkspaceTimeTrackingPage({route}: WorkspaceTimeTrackingPageProps) {
const styles = useThemeStyles();
const illustrations = useMemoizedLazyIllustrations(['Clock']);
const {shouldUseNarrowLayout} = useResponsiveLayout();
- const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
- const canWriteMoreFeatures = canMemberWrite(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
return (
-
+
diff --git a/src/pages/workspace/travel/BookOrManageYourTrip.tsx b/src/pages/workspace/travel/BookOrManageYourTrip.tsx
index 33cf4b986915..e1d3c2100a54 100644
--- a/src/pages/workspace/travel/BookOrManageYourTrip.tsx
+++ b/src/pages/workspace/travel/BookOrManageYourTrip.tsx
@@ -5,7 +5,6 @@ import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import usePermissions from '@hooks/usePermissions';
import usePolicy from '@hooks/usePolicy';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useThemeStyles from '@hooks/useThemeStyles';
import {setPolicyTravelSettings} from '@libs/actions/Policy/Travel';
import {openTravelDotLink} from '@libs/openTravelDotLink';
@@ -21,7 +20,6 @@ function GetStartedTravel({policyID}: GetStartedTravelProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const policy = usePolicy(policyID);
- const {canWrite: canWriteMoreFeatures, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
const icons = useMemoizedLazyExpensifyIcons(['LuggageWithLines', 'NewWindow']);
const {isBetaEnabled} = usePermissions();
const isTravelInvoicingEnabled = isBetaEnabled(CONST.BETAS.TRAVEL_INVOICING);
@@ -50,17 +48,15 @@ function GetStartedTravel({policyID}: GetStartedTravelProps) {
subtitleMuted
isCentralPane
>
- {canWriteMoreFeatures && (
-
- )}
+
diff --git a/src/pages/workspace/travel/GetStartedTravel.tsx b/src/pages/workspace/travel/GetStartedTravel.tsx
index 2f7fb33bf0a8..f26c689c5836 100644
--- a/src/pages/workspace/travel/GetStartedTravel.tsx
+++ b/src/pages/workspace/travel/GetStartedTravel.tsx
@@ -9,10 +9,9 @@ import CONST from '@src/CONST';
type GetStartedTravelProps = {
policyID: string;
- canWriteMoreFeatures: boolean;
};
-function GetStartedTravel({policyID, canWriteMoreFeatures}: GetStartedTravelProps) {
+function GetStartedTravel({policyID}: GetStartedTravelProps) {
const handleCtaPress = () => {};
const {translate} = useLocalize();
@@ -31,15 +30,13 @@ function GetStartedTravel({policyID, canWriteMoreFeatures}: GetStartedTravelProp
illustrationContainerStyle={[styles.emptyStateCardIllustrationContainer, styles.justifyContentCenter]}
titleStyles={styles.textHeadlineH1}
footer={
- canWriteMoreFeatures ? (
-
- ) : undefined
+
}
/>
);
diff --git a/src/pages/workspace/travel/PolicyTravelPage.tsx b/src/pages/workspace/travel/PolicyTravelPage.tsx
index 731a2e4e370b..399907b90f79 100644
--- a/src/pages/workspace/travel/PolicyTravelPage.tsx
+++ b/src/pages/workspace/travel/PolicyTravelPage.tsx
@@ -12,7 +12,6 @@ import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePermissions from '@hooks/usePermissions';
import usePolicy from '@hooks/usePolicy';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceAccountID from '@hooks/useWorkspaceAccountID';
@@ -51,7 +50,6 @@ function WorkspaceTravelPage({
const {login: currentUserLogin} = useCurrentUserPersonalDetails();
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
- const {canWrite: canWriteMoreFeatures} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
const fetchTravelData = useCallback(() => {
openPolicyTravelPage(policyID, workspaceAccountID);
@@ -83,12 +81,7 @@ function WorkspaceTravelPage({
case CONST.TRAVEL.STEPS.REVIEWING_REQUEST:
return ;
default:
- return (
-
- );
+ return ;
}
})();
@@ -106,7 +99,6 @@ function WorkspaceTravelPage({
policyID={policyID}
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
featureName={CONST.POLICY.MORE_FEATURES.IS_TRAVEL_ENABLED}
- policyFeature={CONST.POLICY.POLICY_FEATURE.MORE_FEATURES}
>
- {step === CONST.TRAVEL.STEPS.BOOK_OR_MANAGE_YOUR_TRIP && canWriteMoreFeatures && (
+ {step === CONST.TRAVEL.STEPS.BOOK_OR_MANAGE_YOUR_TRIP && (
{}}
diff --git a/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx b/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx
index bfaccc82199c..e4a6bc1b354f 100644
--- a/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx
+++ b/src/pages/workspace/travel/WorkspaceTravelInvoicingSection.tsx
@@ -13,7 +13,6 @@ import {useCurrencyListActions} from '@hooks/useCurrencyList';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceAccountID from '@hooks/useWorkspaceAccountID';
import {
@@ -83,7 +82,6 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec
const [cardOnWaitlist] = useOnyx(`${ONYXKEYS.COLLECTION.NVP_EXPENSIFY_ON_CARD_WAITLIST}${policyID}`);
const [account] = useOnyx(ONYXKEYS.ACCOUNT);
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);
- const {canWrite: canWriteMoreFeatures, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES);
const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);
const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT);
const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS);
@@ -284,16 +282,6 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec
return ;
};
- const getToggleDisabledAction = () => {
- if (!canWriteMoreFeatures) {
- return showReadOnlyModal;
- }
- if (isOnWaitlist) {
- return () => Navigation.navigate(ROUTES.WORKSPACE_TRAVEL_SETTINGS_ACCOUNT.getRoute(policyID));
- }
- return undefined;
- };
-
const travelInvoicingSubMenuItems = (
<>
{hasTravelProvisioningErrors && (
@@ -323,7 +311,7 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec
)}
- {shouldShowPayButton && canWriteMoreFeatures && (
+ {shouldShowPayButton && (
Navigation.navigate(ROUTES.WORKSPACE_TRAVEL_SETTINGS_ACCOUNT.getRoute(policyID))}
- interactive={canWriteMoreFeatures}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
titleStyle={settlementAccountNumber ? styles.textNormalThemeText : styles.colorMuted}
descriptionTextStyle={styles.textLabelSupportingNormal}
- shouldShowRightIcon={canWriteMoreFeatures}
+ shouldShowRightIcon
brickRoadIndicator={hasSettlementAccountError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
/>
@@ -370,11 +357,10 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec
description={translate('workspace.moreFeatures.travel.travelInvoicing.travelInvoicingSection.subsections.settlementFrequencyLabel')}
title={localizedFrequency}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_TRAVEL_SETTINGS_FREQUENCY.getRoute(policyID))}
- interactive={canWriteMoreFeatures}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
titleStyle={styles.textNormalThemeText}
descriptionTextStyle={styles.textLabelSupportingNormal}
- shouldShowRightIcon={canWriteMoreFeatures}
+ shouldShowRightIcon
brickRoadIndicator={hasSettlementFrequencyError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
/>
@@ -389,11 +375,10 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec
description={translate('workspace.moreFeatures.travel.travelInvoicing.travelInvoicingSection.subsections.monthlySpendLimitLabel')}
title={formattedMonthlyLimit}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_TRAVEL_SETTINGS_MONTHLY_LIMIT.getRoute(policyID))}
- interactive={canWriteMoreFeatures}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
titleStyle={styles.textNormalThemeText}
descriptionTextStyle={styles.textLabelSupportingNormal}
- shouldShowRightIcon={canWriteMoreFeatures}
+ shouldShowRightIcon
brickRoadIndicator={hasMonthlyLimitError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
/>
@@ -410,9 +395,8 @@ function WorkspaceTravelInvoicingSection({policyID}: WorkspaceTravelInvoicingSec
switchAccessibilityLabel={translate('workspace.moreFeatures.travel.travelInvoicing.travelInvoicingSection.subtitle')}
onToggle={handleToggle}
isActive={isTravelInvoicingEnabled}
- disabled={!canWriteMoreFeatures || isLoading || isOnWaitlist}
- disabledAction={getToggleDisabledAction()}
- showLockIcon={!canWriteMoreFeatures || isOnWaitlist}
+ disabled={isLoading || isOnWaitlist}
+ disabledAction={isOnWaitlist ? () => Navigation.navigate(ROUTES.WORKSPACE_TRAVEL_SETTINGS_ACCOUNT.getRoute(policyID)) : undefined}
pendingAction={togglePendingAction}
errors={toggleErrors}
onCloseError={() => clearTravelInvoicingErrors(workspaceAccountID)}
diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx
index a82725d842da..0732e7f1b09c 100644
--- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx
+++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx
@@ -32,7 +32,6 @@ import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
import usePermissions from '@hooks/usePermissions';
-import usePolicyFeatureWriteAccess from '@hooks/usePolicyFeatureWriteAccess';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useSearchResults from '@hooks/useSearchResults';
import useTheme from '@hooks/useTheme';
@@ -60,7 +59,7 @@ import {getPaymentMethodDescription} from '@libs/PaymentUtils';
import {getDisplayNameOrDefault, getPersonalDetailByEmail} from '@libs/PersonalDetailsUtils';
import {
canAccessSubmitWorkspaceFeatures,
- canMemberRead,
+ canEditWorkspaceSettings,
getCorrectedAutoReportingFrequency,
hasDynamicExternalWorkflow,
isControlPolicy,
@@ -148,7 +147,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
const delegateAccountID = useDelegateAccountID();
- const {accountID: currentUserAccountID, email: currentUserEmail = '', login: currentUserLogin = ''} = useCurrentUserPersonalDetails();
+ const {accountID: currentUserAccountID, email: currentUserEmail = ''} = useCurrentUserPersonalDetails();
const isUserReimburser = policy?.achAccount?.reimburser !== undefined && account?.primaryLogin !== undefined && policy?.achAccount?.reimburser === account?.primaryLogin;
const {
approvalWorkflows: rawApprovalWorkflows,
@@ -158,7 +157,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
policy,
personalDetails: personalDetails ?? {},
localeCompare,
- currentUserLogin,
+ currentUserLogin: currentUserEmail,
});
const approvalWorkflows = useDeferredAgentWorkflowReconciliation(rawApprovalWorkflows, policy, route.params.policyID);
@@ -197,10 +196,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
const {isOffline} = useNetwork({onReconnect: fetchData});
const isPolicyAdmin = isPolicyAdminUtil(policy);
- const canReadWorkflows = canMemberRead(policy, currentUserLogin, CONST.POLICY.POLICY_FEATURE.WORKFLOWS);
- const {canWrite: canWriteWorkflows, showReadOnlyModal} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.WORKFLOWS);
- const {canWrite: canWriteApprovals} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.WORKFLOWS_APPROVALS);
- const {canWrite: canWritePayments} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.WORKFLOWS_PAYMENTS);
const {isAccountLocked} = useLockedAccountState();
const {showLockedAccountModal} = useLockedAccountActions();
@@ -388,16 +383,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
title: translate('workflowsPage.submissionFrequency'),
subtitle: translate('workflowsPage.submissionFrequencyDescription'),
switchAccessibilityLabel: translate('workflowsPage.submissionFrequencyDescription'),
- onToggle: (isEnabled: boolean) => {
- if (!canWriteWorkflows) {
- showReadOnlyModal();
- return;
- }
- if (!policy) {
- return;
- }
- setWorkspaceAutoHarvesting(policy, isEnabled);
- },
+ onToggle: (isEnabled: boolean) => (policy ? setWorkspaceAutoHarvesting(policy, isEnabled) : undefined),
subMenuItems: (
@@ -417,19 +402,12 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
pendingAction: policy?.pendingFields?.autoReporting ?? policy?.pendingFields?.autoReportingFrequency,
errors: getLatestErrorField(policy ?? {}, CONST.POLICY.COLLECTION_KEYS.AUTOREPORTING),
onCloseError: () => clearPolicyErrorField(route.params.policyID, CONST.POLICY.COLLECTION_KEYS.AUTOREPORTING),
- disabled: !canWriteWorkflows,
- disabledAction: showReadOnlyModal,
- showLockIcon: !canWriteWorkflows,
},
{
title: translate('workflowsPage.addApprovalsTitle'),
subtitle: approvalOptionSubtitle,
switchAccessibilityLabel: isSmartLimitEnabled ? translate('workspace.moreFeatures.workflows.disableApprovalPrompt') : translate('workflowsPage.addApprovalsDescription'),
onToggle: (isEnabled: boolean) => {
- if (!canWriteApprovals) {
- showReadOnlyModal();
- return;
- }
if (isHRConnected) {
return;
}
@@ -504,7 +482,7 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_EDIT.getRoute(route.params.policyID, workflow.routingFirstApproverEmail))
}
@@ -517,14 +495,14 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
}}
canAddAgent={!shouldBlockApprovalWorkflowEditing && isPolicyAdmin}
currency={policy?.outputCurrency}
- isDisabled={shouldBlockApprovalWorkflowEditing || !canWriteApprovals}
+ isDisabled={shouldBlockApprovalWorkflowEditing}
hrProviderName={isHRConnected ? hrProviderName : undefined}
isHRAdvancedMode={isHRAdvancedModeEnabled}
hrFinalApproverEmail={isHRAdvancedModeEnabled ? hrFinalApproverEmail : undefined}
/>
))}
- {!shouldBlockApprovalWorkflowEditing && canWriteApprovals && (
+ {!shouldBlockApprovalWorkflowEditing && (
),
- disabled: !canWriteApprovals || isSmartLimitEnabled || isDEWEnabled || isHRConnected || canAccessSubmit2026Features,
- disabledAction: canWriteApprovals ? getAddApprovalsToggleDisabledAction() : showReadOnlyModal,
- showLockIcon: !canWriteApprovals,
+ disabled: isSmartLimitEnabled || isDEWEnabled || isHRConnected || canAccessSubmit2026Features,
+ disabledAction: getAddApprovalsToggleDisabledAction(),
isActive:
isHRConnected ||
isDEWEnabled ||
@@ -554,10 +531,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'),
switchAccessibilityLabel: translate('workflowsPage.makeOrTrackPaymentsDescription'),
onToggle: (isEnabled: boolean) => {
- if (!canWritePayments) {
- showReadOnlyModal();
- return;
- }
if (isEnabled && canAccessSubmit2026Features) {
Navigation.navigate(
ROUTES.WORKSPACE_UPGRADE.getRoute(
@@ -601,33 +574,29 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
{
- if (isAccountLocked) {
- showLockedAccountModal();
- return;
- }
- // User who is reimburser can initiate unlocking process
- if (state === CONST.BANK_ACCOUNT.STATE.LOCKED && bankAccountID && isUserReimburser) {
- pressLockedBankAccount(bankAccountID, translate, conciergeReportID ?? undefined, delegateAccountID);
- navigateToConciergeChat(conciergeReportID ?? undefined, introSelected, currentUserAccountID, isSelfTourViewed, betas);
- return;
- }
-
- // User who is not reimburser can't initiate unlocking process but can connect new account
- if (state === CONST.BANK_ACCOUNT.STATE.LOCKED && bankAccountID && !isUserReimburser) {
- // If user has existing accounts and no bank account setup in progress we should show screen to choose an existing account
- if (hasValidExistingAccounts && !shouldShowContinueModal) {
- Navigation.navigate(ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(route.params.policyID));
- return;
- }
- }
-
- navigateToBankAccountRoute({policyID: route.params.policyID, backTo: ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID)});
- }
- : undefined
- }
+ onPress={() => {
+ if (isAccountLocked) {
+ showLockedAccountModal();
+ return;
+ }
+ // User who is reimburser can initiate unlocking process
+ if (state === CONST.BANK_ACCOUNT.STATE.LOCKED && bankAccountID && isUserReimburser) {
+ pressLockedBankAccount(bankAccountID, translate, conciergeReportID ?? undefined, delegateAccountID);
+ navigateToConciergeChat(conciergeReportID ?? undefined, introSelected, currentUserAccountID, isSelfTourViewed, betas);
+ return;
+ }
+
+ // User who is not reimburser can't initiate unlocking process but can connect new account
+ if (state === CONST.BANK_ACCOUNT.STATE.LOCKED && bankAccountID && !isUserReimburser) {
+ // If user has existing accounts and no bank account setup in progress we should show screen to choose an existing account
+ if (hasValidExistingAccounts && !shouldShowContinueModal) {
+ Navigation.navigate(ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(route.params.policyID));
+ return;
+ }
+ }
+
+ navigateToBankAccountRoute({policyID: route.params.policyID, backTo: ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID)});
+ }}
displayInDefaultIconColor
icon={bankIcon.icon}
iconHeight={bankIcon.iconHeight ?? bankIcon.iconSize}
@@ -641,60 +610,57 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
badgeIcon={isAccountInSetupState || (isBusinessBankAccountLocked && isPolicyAdmin) ? expensifyIcons.DotIndicator : undefined}
isBadgeSuccess={isAccountInSetupState}
isBadgeError={isBusinessBankAccountLocked && isPolicyAdmin}
- shouldShowRightIcon={canWritePayments}
- interactive={canWritePayments}
+ shouldShowRightIcon
shouldGreyOutWhenDisabled={!policy?.pendingFields?.reimbursementChoice}
wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt3, styles.mbn3]}
brickRoadIndicator={hasReimburserError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
/>
) : (
- canWritePayments && (
- {
- if (isAccountLocked) {
- showLockedAccountModal();
- return;
- }
- if (!isCurrencySupportedForGlobalReimbursement((policy?.outputCurrency ?? '') as CurrencyType)) {
- showConfirmModal({
- title: translate('workspace.bankAccount.workspaceCurrencyNotSupported'),
- prompt: updateWorkspaceCurrencyPrompt,
- confirmText: translate('workspace.bankAccount.updateWorkspaceCurrency'),
- cancelText: translate('common.cancel'),
- }).then((result) => {
- if (result.action !== ModalActions.CONFIRM) {
- return;
- }
- confirmCurrencyChangeAndHideModal();
- });
-
- return;
- }
- if (!shouldShowBankAccount && hasValidExistingAccounts && !shouldShowContinueModal) {
- Navigation.navigate(
- ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(
- route.params.policyID,
- ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID),
- ),
- );
- return;
- }
- navigateToBankAccountRoute({policyID: route.params.policyID, backTo: ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID)});
- }}
- icon={expensifyIcons.Plus}
- iconHeight={20}
- iconWidth={20}
- shouldShowRightIcon
- disabled={isOffline || !isPolicyAdmin}
- shouldGreyOutWhenDisabled={!policy?.pendingFields?.reimbursementChoice}
- sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.WORKFLOWS.ADD_BANK_ACCOUNT}
- wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt3, styles.mbn3]}
- brickRoadIndicator={hasReimburserError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
- />
- )
+ {
+ if (isAccountLocked) {
+ showLockedAccountModal();
+ return;
+ }
+ if (!isCurrencySupportedForGlobalReimbursement((policy?.outputCurrency ?? '') as CurrencyType)) {
+ showConfirmModal({
+ title: translate('workspace.bankAccount.workspaceCurrencyNotSupported'),
+ prompt: updateWorkspaceCurrencyPrompt,
+ confirmText: translate('workspace.bankAccount.updateWorkspaceCurrency'),
+ cancelText: translate('common.cancel'),
+ }).then((result) => {
+ if (result.action !== ModalActions.CONFIRM) {
+ return;
+ }
+ confirmCurrencyChangeAndHideModal();
+ });
+
+ return;
+ }
+ if (!shouldShowBankAccount && hasValidExistingAccounts && !shouldShowContinueModal) {
+ Navigation.navigate(
+ ROUTES.BANK_ACCOUNT_CONNECT_EXISTING_BUSINESS_BANK_ACCOUNT.getRoute(
+ route.params.policyID,
+ ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID),
+ ),
+ );
+ return;
+ }
+ navigateToBankAccountRoute({policyID: route.params.policyID, backTo: ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID)});
+ }}
+ icon={expensifyIcons.Plus}
+ iconHeight={20}
+ iconWidth={20}
+ shouldShowRightIcon
+ disabled={isOffline || !isPolicyAdmin}
+ shouldGreyOutWhenDisabled={!policy?.pendingFields?.reimbursementChoice}
+ sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.WORKFLOWS.ADD_BANK_ACCOUNT}
+ wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt3, styles.mbn3]}
+ brickRoadIndicator={hasReimburserError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
+ />
)}
{shouldShowBankAccount && (
Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_PAYER.getRoute(route.params.policyID))}
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.WORKFLOWS.AUTHORIZED_PAYER}
- shouldShowRightIcon={canWritePayments}
- interactive={canWritePayments}
+ shouldShowRightIcon
wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt3, styles.mbn3]}
brickRoadIndicator={hasReimburserError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
/>
@@ -725,9 +690,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
pendingAction: policy?.pendingFields?.reimbursementChoice,
errors: getLatestErrorField(policy ?? {}, CONST.POLICY.COLLECTION_KEYS.REIMBURSEMENT_CHOICE),
onCloseError: () => clearPolicyErrorField(route.params.policyID, CONST.POLICY.COLLECTION_KEYS.REIMBURSEMENT_CHOICE),
- disabled: !canWritePayments,
- disabledAction: showReadOnlyModal,
- showLockIcon: !canWritePayments,
},
];
}, [
@@ -782,10 +744,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
confirmCurrencyChangeAndHideModal,
delegateAccountID,
canAccessSubmit2026Features,
- canWriteApprovals,
- canWritePayments,
- canWriteWorkflows,
- showReadOnlyModal,
handleAddAgentPress,
]);
@@ -810,7 +768,6 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
onCloseError={item.onCloseError}
disabled={item.disabled}
disabledAction={item.disabledAction}
- showLockIcon={item.showLockIcon}
/>
);
@@ -822,15 +779,13 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) {
{optionItems.map(renderOptionItem)}
-
+
diff --git a/tests/ui/WorkspaceMoreFeaturesPageTest.tsx b/tests/ui/WorkspaceMoreFeaturesPageTest.tsx
index 3c5b26e75e44..a702b2f8afec 100644
--- a/tests/ui/WorkspaceMoreFeaturesPageTest.tsx
+++ b/tests/ui/WorkspaceMoreFeaturesPageTest.tsx
@@ -96,34 +96,23 @@ const renderPage = (initialParams: WorkspaceSplitNavigatorParamList[typeof SCREE
,
);
-const TEST_USER_LOGIN = 'test@user.com';
-
/** Build a minimal admin policy for use as Onyx fixture. Lock states are driven by mocked hooks/utils, not policy fields. */
-const buildPolicy = (overrides: Partial> = {}) => {
- const role = overrides.role ?? CONST.POLICY.ROLE.ADMIN;
-
- return {
- ...LHNTestUtils.getFakePolicy(),
- role,
- type: CONST.POLICY.TYPE.CORPORATE,
- employeeList: {
- [TEST_USER_LOGIN]: {
- role,
- },
- },
- areWorkflowsEnabled: true,
- areConnectionsEnabled: false,
- areCategoriesEnabled: true,
- areTagsEnabled: false,
- areReportFieldsEnabled: false,
- areExpensifyCardsEnabled: false,
- areCompanyCardsEnabled: false,
- areDistanceRatesEnabled: false,
- areRulesEnabled: false,
- isTravelEnabled: false,
- ...overrides,
- };
-};
+const buildPolicy = (overrides: Partial> = {}) => ({
+ ...LHNTestUtils.getFakePolicy(),
+ role: CONST.POLICY.ROLE.ADMIN,
+ type: CONST.POLICY.TYPE.CORPORATE,
+ areWorkflowsEnabled: true,
+ areConnectionsEnabled: false,
+ areCategoriesEnabled: true,
+ areTagsEnabled: false,
+ areReportFieldsEnabled: false,
+ areExpensifyCardsEnabled: false,
+ areCompanyCardsEnabled: false,
+ areDistanceRatesEnabled: false,
+ areRulesEnabled: false,
+ isTravelEnabled: false,
+ ...overrides,
+});
const isSmartLimitEnabledMock = jest.mocked(CardUtils.isSmartLimitEnabled);
const getCompanyFeedsMock = jest.mocked(CardUtils.getCompanyFeeds);
diff --git a/tests/unit/PolicyUtilsTest.ts b/tests/unit/PolicyUtilsTest.ts
index a5fc32827fa0..5b27e991b683 100644
--- a/tests/unit/PolicyUtilsTest.ts
+++ b/tests/unit/PolicyUtilsTest.ts
@@ -248,7 +248,7 @@ describe('PolicyUtils', () => {
const memberLogin = 'member@test.com';
const buildPolicy = (role: Policy['role']): Policy =>
({
- ...createRandomPolicy(1, CONST.POLICY.TYPE.CORPORATE),
+ ...createRandomPolicy(1, CONST.POLICY.TYPE.TEAM),
role,
employeeList: {
[memberLogin]: {