diff --git a/assets/images/user-shield.svg b/assets/images/user-shield.svg new file mode 100644 index 000000000000..f1f4ad1d1ab4 --- /dev/null +++ b/assets/images/user-shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/chunks/expensify-icons.chunk.ts b/src/components/Icon/chunks/expensify-icons.chunk.ts index ecbe3a94184f..e51dac50bbc5 100644 --- a/src/components/Icon/chunks/expensify-icons.chunk.ts +++ b/src/components/Icon/chunks/expensify-icons.chunk.ts @@ -226,6 +226,7 @@ import UserEye from '@assets/images/user-eye.svg'; import UserLock from '@assets/images/user-lock.svg'; import UserMinus from '@assets/images/user-minus.svg'; import UserPlus from '@assets/images/user-plus.svg'; +import UserShield from '@assets/images/user-shield.svg'; import User from '@assets/images/user.svg'; import Users from '@assets/images/users.svg'; import VideoSlash from '@assets/images/video-slash.svg'; @@ -475,6 +476,7 @@ const Expensicons = { ArrowCircleClockwise, LuggageWithLines, TreasureChestGreenWithSparkle, + UserShield, }; // Create the ExpensifyIcons object from the imported Expensicons diff --git a/src/languages/de.ts b/src/languages/de.ts index 0435786599d5..3215829bc794 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -3136,6 +3136,7 @@ ${ errorMessageInvalidPhone: `Bitte gib eine gültige Telefonnummer ohne Klammern oder Bindestriche ein. Wenn du außerhalb der USA bist, gib bitte deine Ländervorwahl an (z. B. ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'Ungültige E-Mail', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} ist bereits Mitglied von ${name}`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} ist bereits ein Admin von ${name}`, }, onfidoStep: { acceptTerms: 'Indem Sie mit der Anfrage zur Aktivierung Ihres Expensify Wallets fortfahren, bestätigen Sie, dass Sie gelesen, verstanden und akzeptiert haben', @@ -7993,6 +7994,7 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`, resetDomainInfo: `Diese Aktion ist dauerhaft und die folgenden Daten werden gelöscht:
Alle Konten, Workspaces, Berichte, Ausgaben und anderen Daten bleiben erhalten.

Hinweis: Sie können diese Domain aus Ihrer Domainliste entfernen, indem Sie die zugehörige E-Mail aus Ihren Kontaktmethoden löschen.`, }, members: {title: 'Mitglieder', findMember: 'Mitglied suchen'}, + domainAdmins: 'Domain-Admins', }, gps: { tooltip: 'GPS-Verfolgung läuft! Wenn du fertig bist, stoppe die Verfolgung unten.', diff --git a/src/languages/en.ts b/src/languages/en.ts index 499f8242eeef..666a41abaf2c 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3120,6 +3120,7 @@ const translations = { errorMessageInvalidPhone: `Please enter a valid phone number without brackets or dashes. If you're outside the US, please include your country code (e.g. ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'Invalid email', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} is already a member of ${name}`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} is already an admin of ${name}`, }, onfidoStep: { acceptTerms: 'By continuing with the request to activate your Expensify Wallet, you confirm that you have read, understand, and accept', @@ -7891,6 +7892,7 @@ const translations = { subtitle: 'Require members on your domain to log in via single sign-on, restrict workspace creation, and more.', enable: 'Enable', }, + domainAdmins: 'Domain admins', admins: { title: 'Admins', findAdmin: 'Find admin', diff --git a/src/languages/es.ts b/src/languages/es.ts index f6e01534cf6a..01914cebb35a 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2854,6 +2854,7 @@ ${amount} para ${merchant} - ${date}`, errorMessageInvalidPhone: `Por favor, introduce un número de teléfono válido sin paréntesis o guiones. Si reside fuera de Estados Unidos, por favor incluye el prefijo internacional (p. ej. ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'Correo electrónico inválido', userIsAlreadyMember: ({login, name}) => `${login} ya es miembro de ${name}`, + userIsAlreadyAnAdmin: ({login, name}) => `${login} ya es administrador de ${name}`, }, onfidoStep: { acceptTerms: 'Al continuar con la solicitud para activar tu Billetera Expensify, confirma que ha leído, comprende y acepta ', @@ -8063,6 +8064,7 @@ ${amount} para ${merchant} - ${date}`, subtitle: 'Solicita que los miembros de tu dominio inicien sesión mediante inicio de sesión único, restringe la creación de espacios de trabajo y más.', enable: 'Habilitar', }, + domainAdmins: 'Administradores de dominio', admins: { title: 'Administradores', findAdmin: 'Encontrar administrador', @@ -8072,7 +8074,7 @@ ${amount} para ${merchant} - ${date}`, settings: 'Configuración', consolidatedDomainBilling: 'Facturación consolidada del dominio', consolidatedDomainBillingDescription: (domainName: string) => - `Cuando está habilitada, el contacto principal pagará todos los espacios de trabajo propiedad de los miembros de ${domainName} y recibirá todos los recibos de facturación.`, + `Cuando está habilitada, el contacto principal pagará todos los espacios de trabajo de los miembros de ${domainName} y recibirá todos los recibos de facturación.`, consolidatedDomainBillingError: 'No se pudo cambiar la facturación consolidada del dominio. Por favor, inténtalo de nuevo más tarde.', addAdmin: 'Añadir administrador', invite: 'Invitar', @@ -8081,11 +8083,11 @@ ${amount} para ${merchant} - ${date}`, cantRevokeAdminAccess: 'No se puede revocar el acceso de administrador del contacto técnico', error: { removeAdmin: 'No se pudo eliminar a este usuario como administrador. Por favor, inténtalo de nuevo.', - removeDomain: 'No se pudo eliminar este dominio. Inténtalo de nuevo.', + removeDomain: 'No se pudo eliminar este dominio. Por favor inténtalo de nuevo.', removeDomainNameInvalid: 'Introduce el nombre de tu dominio para restablecerlo.', }, resetDomain: 'Restablecer dominio', - resetDomainExplanation: ({domainName}: {domainName?: string}) => `Escribe ${domainName} para confirmar el restablecimiento del dominio.`, + resetDomainExplanation: ({domainName}: {domainName?: string}) => `Por favor escribe ${domainName} para confirmar el restablecimiento del dominio.`, enterDomainName: 'Introduce aquí tu nombre de dominio', resetDomainInfo: `Esta acción es permanente y se eliminarán los siguientes datos:
Todas las cuentas, espacios de trabajo, informes, gastos y otros datos se conservarán.

Nota: Puedes eliminar este dominio de tu lista de dominios eliminando el correo electrónico asociado de tus métodos de contacto.`, }, diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 7d6154bb1a9e..7a47c96c9133 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -3143,6 +3143,7 @@ ${ errorMessageInvalidPhone: `Veuillez saisir un numéro de téléphone valide sans parenthèses ni tirets. Si vous êtes en dehors des États-Unis, veuillez inclure votre indicatif de pays (p. ex. ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'Adresse e-mail invalide', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} est déjà membre de ${name}`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} est déjà administrateur de ${name}`, }, onfidoStep: { acceptTerms: 'En poursuivant la demande d’activation de votre Expensify Wallet, vous confirmez que vous avez lu, compris et accepté', @@ -7999,6 +8000,7 @@ Voici un *reçu test* pour vous montrer comment cela fonctionne :`, resetDomainInfo: `Cette action est définitive et les données suivantes seront supprimées :
Tous les comptes, espaces de travail, rapports, dépenses et autres données seront conservés.

Remarque : Vous pouvez supprimer ce domaine de votre liste de domaines en retirant l'adresse e-mail associée de vos méthodes de contact.`, }, members: {title: 'Membres', findMember: 'Rechercher un membre'}, + domainAdmins: 'Administrateurs de domaine', }, gps: { tooltip: 'Suivi GPS en cours ! Quand vous avez terminé, arrêtez le suivi ci-dessous.', diff --git a/src/languages/it.ts b/src/languages/it.ts index f9ee62edcf4d..aa7c83a8d743 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -3127,6 +3127,7 @@ ${ errorMessageInvalidPhone: `Per favore inserisci un numero di telefono valido senza parentesi o trattini. Se ti trovi fuori dagli Stati Uniti, includi il prefisso del tuo paese (ad es. ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'Email non valido', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} è già un membro di ${name}`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} è già un amministratore di ${name}`, }, onfidoStep: { acceptTerms: 'Continuando con la richiesta di attivare il tuo Expensify Wallet, confermi di aver letto, compreso e accettato', @@ -7981,6 +7982,7 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`, resetDomainInfo: `Questa azione è permanente e i seguenti dati verranno eliminati:
Tutti gli account, gli spazi di lavoro, i report, le spese e gli altri dati rimarranno.

Nota: puoi rimuovere questo dominio dall'elenco dei tuoi domini eliminando l'email associata dalle tue modalità di contatto.`, }, members: {title: 'Membri', findMember: 'Trova membro'}, + domainAdmins: 'Amministratori di dominio', }, gps: { tooltip: 'Monitoraggio GPS in corso! Quando hai finito, interrompi il monitoraggio qui sotto.', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index bd83649364ce..fe29c69b0617 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -3117,6 +3117,7 @@ ${ errorMessageInvalidPhone: `かっこやハイフンを使わずに有効な電話番号を入力してください。米国外にいる場合は、国コードを含めて入力してください(例:${CONST.EXAMPLE_PHONE_NUMBER})。`, errorMessageInvalidEmail: '無効なメールアドレス', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} はすでに ${name} のメンバーです`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} はすでに ${name} の管理者です`, }, onfidoStep: { acceptTerms: 'Expensifyウォレットの有効化リクエストを続行することにより、あなたは次の内容を読み、理解し、承諾したことを確認します', @@ -7915,6 +7916,7 @@ Expensify の使い方をお見せするための*テストレシート*がこ resetDomainInfo: `この操作は永久的であり、次のデータが削除されます:
すべてのアカウント、ワークスペース、レポート、経費、およびその他のデータは保持されます。

注:関連付けられているメールアドレスを連絡先方法から削除することで、このドメインをドメイン一覧から消去できます。`, }, members: {title: 'メンバー', findMember: 'メンバーを検索'}, + domainAdmins: 'ドメイン管理者', }, gps: { tooltip: 'GPS 追跡を進行中です!完了したら、下で追跡を停止してください。', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index fb2e969231aa..0bd1db31f0a1 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -3125,6 +3125,7 @@ ${ errorMessageInvalidPhone: `Voer een geldig telefoonnummer in zonder haakjes of streepjes. Als u zich buiten de VS bevindt, voeg dan uw landcode toe (bijv. ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'Ongeldig e-mailadres', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} is al lid van ${name}`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} is al een beheerder van ${name}`, }, onfidoStep: { acceptTerms: 'Door door te gaan met het verzoek om uw Expensify Wallet te activeren, bevestigt u dat u hebt gelezen, begrijpt en accepteert', @@ -7966,6 +7967,7 @@ Hier is een *testbon* om je te laten zien hoe het werkt:`, resetDomainInfo: `Deze actie is definitief en de volgende gegevens worden verwijderd:
Alle accounts, werkruimten, rapporten, uitgaven en andere gegevens blijven behouden.

Opmerking: je kunt dit domein uit je domeinenlijst verwijderen door het gekoppelde e-mailadres uit je contactmethoden te verwijderen.`, }, members: {title: 'Leden', findMember: 'Lid zoeken'}, + domainAdmins: 'Domeinbeheerders', }, gps: { tooltip: 'GPS-tracking bezig! Als je klaar bent, stop dan hieronder met tracken.', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index bd6ee37a9491..0711a507364b 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -3119,6 +3119,7 @@ ${ errorMessageInvalidPhone: `Wprowadź prawidłowy numer telefonu bez nawiasów i myślników. Jeśli jesteś poza USA, dołącz kod kraju (np. ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'Nieprawidłowy adres e-mail', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} jest już członkiem ${name}`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} jest już administratorem ${name}`, }, onfidoStep: { acceptTerms: 'Kontynuując żądanie aktywacji portfela Expensify, potwierdzasz, że przeczytałeś, rozumiesz i akceptujesz', @@ -7947,6 +7948,7 @@ Oto *paragon testowy*, który pokazuje, jak to działa:`, resetDomainInfo: `Ta akcja jest trwała i następujące dane zostaną usunięte:
Wszystkie konta, przestrzenie robocze, raporty, wydatki i inne dane pozostaną bez zmian.

Uwaga: Możesz usunąć tę domenę z listy swoich domen, usuwając powiązany adres e-mail z metod kontaktu.`, }, members: {title: 'Członkowie', findMember: 'Znajdź członka'}, + domainAdmins: 'Administratorzy domeny', }, gps: { tooltip: 'Śledzenie GPS w toku! Gdy skończysz, zatrzymaj śledzenie poniżej.', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index bf36748958ed..c6389302c56e 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -3119,6 +3119,7 @@ ${ errorMessageInvalidPhone: `Insira um número de telefone válido sem parênteses ou traços. Se você estiver fora dos EUA, inclua o código do seu país (por exemplo, ${CONST.EXAMPLE_PHONE_NUMBER}).`, errorMessageInvalidEmail: 'E-mail inválido', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} já é membro de ${name}`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} já é um administrador de ${name}`, }, onfidoStep: { acceptTerms: 'Ao prosseguir com o pedido para ativar sua Carteira Expensify, você confirma que leu, compreende e aceita', @@ -7952,6 +7953,7 @@ Aqui está um *recibo de teste* para mostrar como funciona:`, resetDomainInfo: `Esta ação é permanente e os seguintes dados serão excluídos:
Todas as contas, workspaces, relatórios, despesas e outros dados permanecerão.

Observação: Você pode remover este domínio da sua lista de domínios excluindo o e-mail associado dos seus métodos de contato.`, }, members: {title: 'Membros', findMember: 'Encontrar membro'}, + domainAdmins: 'Administradores de domínio', }, gps: { tooltip: 'Rastreamento por GPS em andamento! Quando terminar, pare o rastreamento abaixo.', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index b269e25c841c..0d6387227ee3 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -3076,6 +3076,7 @@ ${ errorMessageInvalidPhone: `请输入不带括号或短横线的有效电话号码。如果您在美国以外,请包含您的国家区号(例如:${CONST.EXAMPLE_PHONE_NUMBER})。`, errorMessageInvalidEmail: '无效的邮箱', userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} 已经是 ${name} 的成员`, + userIsAlreadyAnAdmin: ({login, name}: UserIsAlreadyMemberParams) => `${login} 已经是 ${name} 的管理员`, }, onfidoStep: { acceptTerms: '通过继续申请激活您的 Expensify Wallet,即表示您确认已阅读、理解并接受', @@ -7764,6 +7765,7 @@ ${reportName} resetDomainInfo: `此操作是永久性的,并且以下数据将被删除:
所有账户、工作区、报表、费用以及其他数据将会保留。

注意:您可以通过从联系方法中移除关联的邮箱,将此域名从您的域名列表中清除。`, }, members: {title: '成员', findMember: '查找成员'}, + domainAdmins: '域管理员', }, gps: { tooltip: 'GPS 跟踪进行中!完成后,请在下方停止跟踪。', diff --git a/src/libs/Navigation/AppNavigator/Navigators/DomainSplitNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/DomainSplitNavigator.tsx index 649f911492e0..3c19114a877d 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/DomainSplitNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/DomainSplitNavigator.tsx @@ -30,7 +30,7 @@ function DomainSplitNavigator({route, navigation}: PlatformStackScreenProps diff --git a/src/pages/domain/Admins/DomainAddAdminPage.tsx b/src/pages/domain/Admins/DomainAddAdminPage.tsx index 2540dcbefbbe..b3439dae3b86 100644 --- a/src/pages/domain/Admins/DomainAddAdminPage.tsx +++ b/src/pages/domain/Admins/DomainAddAdminPage.tsx @@ -53,7 +53,7 @@ function DomainAddAdminPage({route}: DomainAddAdminProps) { const didInvite = useRef(false); const domainName = domainEmail ? Str.extractEmailDomain(domainEmail) : undefined; - const {searchTerm, setSearchTerm, availableOptions, toggleSelection, areOptionsInitialized, onListEndReached} = useSearchSelector({ + const {searchTerm, debouncedSearchTerm, setSearchTerm, availableOptions, toggleSelection, areOptionsInitialized, onListEndReached} = useSearchSelector({ selectionMode: CONST.SEARCH_SELECTOR.SELECTION_MODE_SINGLE, searchContext: CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_MEMBER_INVITE, includeRecentReports: false, @@ -64,8 +64,8 @@ function DomainAddAdminPage({route}: DomainAddAdminProps) { }); useEffect(() => { - searchInServer(searchTerm); - }, [searchTerm]); + searchInServer(debouncedSearchTerm); + }, [debouncedSearchTerm]); const inviteUser = () => { if (didInvite.current || !currentlySelectedUser || !currentlySelectedUser.accountID || !currentlySelectedUser.login || !domainName) { @@ -116,6 +116,19 @@ function DomainAddAdminPage({route}: DomainAddAdminProps) { /> ); + const headerMessage = () => { + const searchValue = debouncedSearchTerm.trim().toLowerCase(); + if (!availableOptions.userToInvite && CONST.EXPENSIFY_EMAILS_OBJECT[searchValue]) { + return translate('messages.errorMessageInvalidEmail'); + } + + const searchedUserPersonalDetails = availableOptions.personalDetails.find(({login}) => login?.toLowerCase() === searchValue); + if (!availableOptions.userToInvite && searchedUserPersonalDetails?.accountID && adminIDs?.includes(searchedUserPersonalDetails.accountID)) { + return translate('messages.userIsAlreadyAnAdmin', {login: searchValue, name: domainName ?? ''}); + } + return getHeaderMessage(filteredOptions.length > 0 || !!currentlySelectedUser, !!availableOptions.userToInvite, searchValue, countryCode, false); + }; + return ( 0 || !!currentlySelectedUser, - !!availableOptions.userToInvite, - searchTerm.trim().toLowerCase(), - countryCode, - false, - )} + headerMessage={headerMessage()} ListItem={InviteMemberListItem} textInputLabel={translate('selectionList.nameEmailOrPhoneNumber')} textInputValue={searchTerm} diff --git a/src/pages/domain/Admins/DomainAdminDetailsPage.tsx b/src/pages/domain/Admins/DomainAdminDetailsPage.tsx index eacb2df24358..76656a6f6d80 100644 --- a/src/pages/domain/Admins/DomainAdminDetailsPage.tsx +++ b/src/pages/domain/Admins/DomainAdminDetailsPage.tsx @@ -7,7 +7,6 @@ import useConfirmModal from '@hooks/useConfirmModal'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; -import useThemeStyles from '@hooks/useThemeStyles'; import {getDisplayNameOrDefault} from '@libs/PersonalDetailsUtils'; import Navigation from '@navigation/Navigation'; import type {PlatformStackScreenProps} from '@navigation/PlatformStackNavigation/types'; @@ -24,7 +23,6 @@ type DomainAdminDetailsPageProps = PlatformStackScreenProps {domainHasOnlyOneAdmin && ( Navigation.navigate(ROUTES.DOMAIN_RESET_DOMAIN.getRoute(domainAccountID, accountID))} @@ -85,7 +82,6 @@ function DomainAdminDetailsPage({route}: DomainAdminDetailsPageProps) { {children} Navigation.navigate(ROUTES.PROFILE.getRoute(accountID, Navigation.getActiveRoute()))} diff --git a/src/pages/domain/DomainInitialPage.tsx b/src/pages/domain/DomainInitialPage.tsx index f98f1fcdeccd..17ccaeb839f0 100644 --- a/src/pages/domain/DomainInitialPage.tsx +++ b/src/pages/domain/DomainInitialPage.tsx @@ -1,6 +1,6 @@ import {findFocusedRoute, useNavigationState} from '@react-navigation/native'; import {Str} from 'expensify-common'; -import React, {useCallback, useEffect, useMemo} from 'react'; +import React, {useCallback, useEffect} from 'react'; import {View} from 'react-native'; import type {ValueOf} from 'type-fest'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; @@ -46,7 +46,7 @@ type DomainMenuItem = { type DomainInitialPageProps = PlatformStackScreenProps; function DomainInitialPage({route}: DomainInitialPageProps) { - const icons = useMemoizedLazyExpensifyIcons(['UserLock']); + const icons = useMemoizedLazyExpensifyIcons(['UserLock', 'UserShield']); const styles = useThemeStyles(); const waitForNavigate = useWaitForNavigation(); const {singleExecution, isExecuting} = useSingleExecution(); @@ -60,18 +60,20 @@ function DomainInitialPage({route}: DomainInitialPageProps) { const domainName = domain?.email ? Str.extractEmailDomain(domain.email) : undefined; const [isAdmin] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_ADMIN_ACCESS}${domainAccountID}`, {canBeMissing: false}); - const domainMenuItems: DomainMenuItem[] = useMemo(() => { - const menuItems: DomainMenuItem[] = [ - { - translationKey: 'domain.saml', - icon: icons.UserLock, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.DOMAIN_SAML.getRoute(domainAccountID)))), - screenName: SCREENS.DOMAIN.SAML, - }, - ]; - - return menuItems; - }, [domainAccountID, singleExecution, waitForNavigate, icons.UserLock]); + const domainMenuItems: DomainMenuItem[] = [ + { + translationKey: 'domain.domainAdmins', + icon: icons.UserShield, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.DOMAIN_ADMINS.getRoute(domainAccountID)))), + screenName: SCREENS.DOMAIN.ADMINS, + }, + { + translationKey: 'domain.saml', + icon: icons.UserLock, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.DOMAIN_SAML.getRoute(domainAccountID)))), + screenName: SCREENS.DOMAIN.SAML, + }, + ]; const fetchDomainData = useCallback(() => { if (!domainName) {