diff --git a/src/languages/de.ts b/src/languages/de.ts index 3155c1121aeb..e7e92effb3a9 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -9188,8 +9188,11 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`, makeDefault: 'Als Standard festlegen', neverMind: 'Vergiss es', permissions: 'Gruppenberechtigungen', - StrictlyEnforceWorkspaceRules: 'Workspace-Regeln strikt durchsetzen', - StrictlyEnforceWorkspaceRulesDescription: 'Alle Workspace-Regeln müssen erfüllt sein, bevor ein Bericht eingereicht wird. Manuelle Ausnahmen sind nicht zulässig.', + strictlyEnforceWorkspaceRules: 'Workspace-Regeln strikt durchsetzen', + strictlyEnforceWorkspaceRulesDescription: 'Alle Workspace-Regeln müssen erfüllt sein, bevor ein Bericht eingereicht wird. Manuelle Ausnahmen sind nicht zulässig.', + restrictExpenseWorkspaceCreation: 'Erstellen/Entfernen von Ausgaben-Workspaces einschränken', + restrictExpenseWorkspaceCreationDescription: + 'Verhindert, dass Mitglieder einen Ausgaben-Workspace erstellen oder sich selbst aus einem Ausgaben-Workspace entfernen können. Dies ist nützlich, um zu verhindern, dass Personen Expensify verwenden, um Berichte für die Nutzung außerhalb deiner Domain einzureichen, wenn es mit einer strikten Workspace-Durchsetzung kombiniert wird.', }, }, proactiveAppReview: { diff --git a/src/languages/en.ts b/src/languages/en.ts index d72c81fcd005..b68d37355bcc 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -9182,8 +9182,11 @@ const translations = { makeDefault: 'Make default', neverMind: 'Never mind', permissions: 'Group permissions', - StrictlyEnforceWorkspaceRules: 'Strictly enforce workspace rules', - StrictlyEnforceWorkspaceRulesDescription: 'All workspace rules must be met before submitting a report. No manual exceptions allowed.', + strictlyEnforceWorkspaceRules: 'Strictly enforce workspace rules', + strictlyEnforceWorkspaceRulesDescription: 'All workspace rules must be met before submitting a report. No manual exceptions allowed.', + restrictExpenseWorkspaceCreation: 'Restrict expense workspace creation/removal', + restrictExpenseWorkspaceCreationDescription: + 'Prevent members from being able to create an expense workspace or remove themselves from an expense workspace. This is useful for preventing people from using Expensify to submit reports for use outside your domain when combined with strict workspace enforcement.', }, }, }; diff --git a/src/languages/es.ts b/src/languages/es.ts index 563f683569d6..41573774b0ed 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -9413,8 +9413,11 @@ ${amount} para ${merchant} - ${date}`, makeDefault: 'Establecer como predeterminado', neverMind: 'No importa', permissions: 'Permisos de grupo', - StrictlyEnforceWorkspaceRules: 'Hacer cumplir estrictamente las reglas del espacio de trabajo', - StrictlyEnforceWorkspaceRulesDescription: 'Todas las reglas del espacio de trabajo deben cumplirse antes de enviar un informe. No se permiten excepciones manuales.', + strictlyEnforceWorkspaceRules: 'Hacer cumplir estrictamente las reglas del espacio de trabajo', + strictlyEnforceWorkspaceRulesDescription: 'Todas las reglas del espacio de trabajo deben cumplirse antes de enviar un informe. No se permiten excepciones manuales.', + restrictExpenseWorkspaceCreation: 'Restringir la creación/eliminación de espacios de trabajo de gastos', + restrictExpenseWorkspaceCreationDescription: + 'Evita que los miembros creen un espacio de trabajo de gastos o se eliminen a sí mismos de uno. Esto, cuando se combina con la aplicación estricta de espacios de trabajo, es útil para evitar que se utilice Expensify para enviar informes destinados a usarse fuera de tu dominio.', }, }, gps: { diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 7abc57151e0c..cedb15df6c4d 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -9211,9 +9211,12 @@ Voici un *reçu test* pour vous montrer comment ça fonctionne :`, makeDefault: 'Définir par défaut', neverMind: 'Peu importe', permissions: 'Autorisations du groupe', - StrictlyEnforceWorkspaceRules: 'Appliquer strictement les règles de l’espace de travail', - StrictlyEnforceWorkspaceRulesDescription: + strictlyEnforceWorkspaceRules: 'Appliquer strictement les règles de l’espace de travail', + strictlyEnforceWorkspaceRulesDescription: 'Toutes les règles de l’espace de travail doivent être respectées avant de soumettre un rapport. Aucune exception manuelle n’est autorisée.', + restrictExpenseWorkspaceCreation: 'Restreindre la création/suppression d’espaces de travail de dépenses', + restrictExpenseWorkspaceCreationDescription: + 'Empêchez les membres de pouvoir créer un espace de travail de dépenses ou de se retirer d’un espace de travail de dépenses. Ceci est utile pour empêcher les gens d’utiliser Expensify afin de soumettre des rapports destinés à un usage hors de votre domaine, lorsqu’il est combiné à une application stricte des espaces de travail.', }, }, proactiveAppReview: { diff --git a/src/languages/it.ts b/src/languages/it.ts index 8177b4f94e59..e1dee624642d 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -9178,8 +9178,11 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`, makeDefault: 'Imposta come predefinito', neverMind: 'Lascia perdere', permissions: 'Autorizzazioni del gruppo', - StrictlyEnforceWorkspaceRules: 'Applica rigorosamente le regole dello spazio di lavoro', - StrictlyEnforceWorkspaceRulesDescription: 'Tutte le regole dello spazio di lavoro devono essere soddisfatte prima di inviare un rapporto. Non sono consentite eccezioni manuali.', + strictlyEnforceWorkspaceRules: 'Applica rigorosamente le regole dello spazio di lavoro', + strictlyEnforceWorkspaceRulesDescription: 'Tutte le regole dello spazio di lavoro devono essere soddisfatte prima di inviare un rapporto. Non sono consentite eccezioni manuali.', + restrictExpenseWorkspaceCreation: 'Limita la creazione/rimozione dell’area di lavoro spese', + restrictExpenseWorkspaceCreationDescription: + 'Impedisci ai membri di poter creare un’area di lavoro spese o di rimuoversi da un’area di lavoro spese. Questo è utile per impedire alle persone di utilizzare Expensify per inviare report destinati a un uso al di fuori del tuo dominio, se combinato con un’applicazione rigorosa dell’area di lavoro.', }, }, proactiveAppReview: { diff --git a/src/languages/ja.ts b/src/languages/ja.ts index a9fe29cc2205..e4c0fa2aff03 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -9064,8 +9064,11 @@ ${reportName} makeDefault: 'デフォルトに設定', neverMind: 'やめておく', permissions: 'グループの権限', - StrictlyEnforceWorkspaceRules: 'ワークスペースのルールを厳密に適用する', - StrictlyEnforceWorkspaceRulesDescription: 'レポートを送信する前にすべてのワークスペースのルールを満たす必要があります。手動による例外は許可されていません。', + strictlyEnforceWorkspaceRules: 'ワークスペースのルールを厳密に適用する', + strictlyEnforceWorkspaceRulesDescription: 'レポートを送信する前にすべてのワークスペースのルールを満たす必要があります。手動による例外は許可されていません。', + restrictExpenseWorkspaceCreation: '経費ワークスペースの作成/削除を制限する', + restrictExpenseWorkspaceCreationDescription: + 'メンバーが経費ワークスペースを作成したり、経費ワークスペースから自分自身を削除したりできないようにします。これは、厳格なワークスペース適用と組み合わせることで、ドメイン外での使用を目的としたレポートの提出に Expensify が利用されるのを防ぐのに役立ちます。', }, }, proactiveAppReview: { diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 6d05bd5e5a61..ce208b2e36f1 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -9150,9 +9150,12 @@ Hier is een *proefbon* om je te laten zien hoe het werkt:`, makeDefault: 'Standaard maken', neverMind: 'Laat maar', permissions: 'Groepsmachtigingen', - StrictlyEnforceWorkspaceRules: 'Werkruimteregels strikt afdwingen', - StrictlyEnforceWorkspaceRulesDescription: + strictlyEnforceWorkspaceRules: 'Werkruimteregels strikt afdwingen', + strictlyEnforceWorkspaceRulesDescription: 'Aan alle werkruimteregels moet worden voldaan voordat een rapport kan worden ingediend. Handmatige uitzonderingen zijn niet toegestaan.', + restrictExpenseWorkspaceCreation: 'Aanmaken/verwijderen van onkostenwerkruimte beperken', + restrictExpenseWorkspaceCreationDescription: + 'Voorkom dat leden een onkostenwerkruimte kunnen aanmaken of zichzelf uit een onkostenwerkruimte kunnen verwijderen. Dit is nuttig om te voorkomen dat mensen Expensify gebruiken om rapporten in te dienen voor gebruik buiten jouw domein, wanneer dit wordt gecombineerd met strikte werkruimtehandhaving.', }, }, proactiveAppReview: { diff --git a/src/languages/pl.ts b/src/languages/pl.ts index 8acda084368f..84b52f6d9283 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -9132,8 +9132,11 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`, makeDefault: 'Ustaw jako domyślną', neverMind: 'Nieważne', permissions: 'Uprawnienia grupy', - StrictlyEnforceWorkspaceRules: 'Ściśle egzekwuj reguły przestrzeni roboczej', - StrictlyEnforceWorkspaceRulesDescription: 'Przed przesłaniem raportu muszą zostać spełnione wszystkie reguły przestrzeni roboczej. Ręczne wyjątki są niedozwolone.', + strictlyEnforceWorkspaceRules: 'Ściśle egzekwuj reguły przestrzeni roboczej', + strictlyEnforceWorkspaceRulesDescription: 'Przed przesłaniem raportu muszą zostać spełnione wszystkie reguły przestrzeni roboczej. Ręczne wyjątki są niedozwolone.', + restrictExpenseWorkspaceCreation: 'Ogranicz tworzenie/usuwanie przestrzeni roboczej wydatków', + restrictExpenseWorkspaceCreationDescription: + 'Uniemożliw członkom tworzenie przestrzeni roboczej wydatków lub usuwanie siebie z przestrzeni roboczej wydatków. Jest to przydatne, aby zapobiec używaniu Expensify do przesyłania raportów przeznaczonych do użytku poza Twoją domeną, w połączeniu ze ścisłym egzekwowaniem przestrzeni roboczej.', }, }, proactiveAppReview: { diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index d115ad394ccd..779a8e898151 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -9140,8 +9140,11 @@ Aqui está um *comprovante de teste* para mostrar como funciona:`, makeDefault: 'Tornar padrão', neverMind: 'Deixa pra lá', permissions: 'Permissões do grupo', - StrictlyEnforceWorkspaceRules: 'Aplicar rigorosamente as regras do espaço de trabalho', - StrictlyEnforceWorkspaceRulesDescription: 'Todas as regras do espaço de trabalho devem ser atendidas antes de enviar um relatório. Não são permitidas exceções manuais.', + strictlyEnforceWorkspaceRules: 'Aplicar rigorosamente as regras do espaço de trabalho', + strictlyEnforceWorkspaceRulesDescription: 'Todas as regras do espaço de trabalho devem ser atendidas antes de enviar um relatório. Não são permitidas exceções manuais.', + restrictExpenseWorkspaceCreation: 'Restringir a criação/remoção de espaços de trabalho de despesas', + restrictExpenseWorkspaceCreationDescription: + 'Impede que os membros possam criar um espaço de trabalho de despesas ou se removerem de um espaço de trabalho de despesas. Isso é útil para impedir que as pessoas usem o Expensify para enviar relatórios destinados ao uso fora do seu domínio, quando combinado com a aplicação rigorosa de espaços de trabalho.', }, }, proactiveAppReview: { diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index ac075e0f64f1..5639423764c8 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -8905,8 +8905,11 @@ ${reportName} makeDefault: '设为默认', neverMind: '算了', permissions: '群组权限', - StrictlyEnforceWorkspaceRules: '严格执行工作空间规则', - StrictlyEnforceWorkspaceRulesDescription: '提交报告前必须满足所有工作空间规则。不允许手动例外。', + strictlyEnforceWorkspaceRules: '严格执行工作空间规则', + strictlyEnforceWorkspaceRulesDescription: '提交报告前必须满足所有工作空间规则。不允许手动例外。', + restrictExpenseWorkspaceCreation: '限制创建/删除费用工作区', + restrictExpenseWorkspaceCreationDescription: + '阻止成员创建费用工作区或将自己从费用工作区中移除。当与严格的工作区执行相结合时,这有助于防止他人使用 Expensify 提交用于您域外的报表。', }, }, proactiveAppReview: {title: '喜欢全新的 Expensify 吗?', description: '请告诉我们,这样我们就能帮助您让报销体验变得更好。', positiveButton: '太棒了!', negativeButton: '不太是'}, diff --git a/src/libs/actions/Domain.ts b/src/libs/actions/Domain.ts index b049782c89fd..1b793bc2de30 100644 --- a/src/libs/actions/Domain.ts +++ b/src/libs/actions/Domain.ts @@ -1836,7 +1836,7 @@ function updateDomainSecurityGroup( groupID: string, currentSecurityGroup: DomainSecurityGroup, newSettingValue: Partial, - settingsName: keyof Pick, + settingsName: keyof Pick, ) { const SECURITY_GROUP_KEY = `${CONST.DOMAIN.DOMAIN_SECURITY_GROUP_PREFIX}${groupID}`; const newSecurityGroup = {...currentSecurityGroup, ...newSettingValue}; diff --git a/src/pages/domain/Groups/DomainGroupDetailsPage.tsx b/src/pages/domain/Groups/DomainGroupDetailsPage.tsx index c0384685c577..f59b274ab00d 100644 --- a/src/pages/domain/Groups/DomainGroupDetailsPage.tsx +++ b/src/pages/domain/Groups/DomainGroupDetailsPage.tsx @@ -19,6 +19,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import DefaultGroupToggle from './DefaultGroupToggle'; +import RestrictExpenseWorkspaceCreationToggle from './RestrictExpenseWorkspaceCreationToggle'; import StrictlyEnforceWorkspaceRulesToggle from './StrictlyEnforceWorkspaceRulesToggle'; type DomainGroupDetailsPageProps = PlatformStackScreenProps; @@ -71,6 +72,10 @@ function DomainGroupDetailsPage({route}: DomainGroupDetailsPageProps) { domainAccountID={domainAccountID} groupID={groupID} /> + diff --git a/src/pages/domain/Groups/RestrictExpenseWorkspaceCreationToggle.tsx b/src/pages/domain/Groups/RestrictExpenseWorkspaceCreationToggle.tsx new file mode 100644 index 000000000000..ee5372d1a7ce --- /dev/null +++ b/src/pages/domain/Groups/RestrictExpenseWorkspaceCreationToggle.tsx @@ -0,0 +1,59 @@ +import {domainSecurityGroupSettingErrorsSelector, domainSecurityGroupSettingPendingActionSelector, selectGroupByID} from '@selectors/Domain'; +import React from 'react'; +import {View} from 'react-native'; +import useLocalize from '@hooks/useLocalize'; +import useOnyx from '@hooks/useOnyx'; +import useThemeStyles from '@hooks/useThemeStyles'; +import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; +import {clearDomainSecurityGroupSettingError, updateDomainSecurityGroup} from '@userActions/Domain'; +import ONYXKEYS from '@src/ONYXKEYS'; + +type RestrictExpenseWorkspaceCreationToggleProps = { + /** The account ID of the domain */ + domainAccountID: number; + + /** The ID of the security group */ + groupID: string; +}; + +function RestrictExpenseWorkspaceCreationToggle({domainAccountID, groupID}: RestrictExpenseWorkspaceCreationToggleProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const [group] = useOnyx(`${ONYXKEYS.COLLECTION.DOMAIN}${domainAccountID}`, { + selector: selectGroupByID(groupID), + }); + + const [enableRestrictedPolicyCreationPendingAction] = useOnyx(`${ONYXKEYS.COLLECTION.DOMAIN_PENDING_ACTIONS}${domainAccountID}`, { + selector: domainSecurityGroupSettingPendingActionSelector('enableRestrictedPolicyCreation', groupID), + }); + const [enableRestrictedPolicyCreationErrors] = useOnyx(`${ONYXKEYS.COLLECTION.DOMAIN_ERRORS}${domainAccountID}`, { + selector: domainSecurityGroupSettingErrorsSelector('enableRestrictedPolicyCreationErrors', groupID), + }); + + const isEnabled = !!group?.enableRestrictedPolicyCreation; + + return ( + + { + if (!group) { + return; + } + updateDomainSecurityGroup(domainAccountID, groupID, group, {enableRestrictedPolicyCreation: enabled}, 'enableRestrictedPolicyCreation'); + }} + wrapperStyle={[styles.ph5]} + pendingAction={enableRestrictedPolicyCreationPendingAction} + errors={enableRestrictedPolicyCreationErrors} + onCloseError={() => clearDomainSecurityGroupSettingError(domainAccountID, groupID, 'enableRestrictedPolicyCreationErrors')} + /> + + ); +} + +export default RestrictExpenseWorkspaceCreationToggle; diff --git a/src/pages/domain/Groups/StrictlyEnforceWorkspaceRulesToggle.tsx b/src/pages/domain/Groups/StrictlyEnforceWorkspaceRulesToggle.tsx index 02eeee68e264..07cb1aacf164 100644 --- a/src/pages/domain/Groups/StrictlyEnforceWorkspaceRulesToggle.tsx +++ b/src/pages/domain/Groups/StrictlyEnforceWorkspaceRulesToggle.tsx @@ -9,7 +9,10 @@ import {clearDomainSecurityGroupSettingError, updateDomainSecurityGroup} from '@ import ONYXKEYS from '@src/ONYXKEYS'; type StrictlyEnforceWorkspaceRulesToggleProps = { + /** The account ID of the domain */ domainAccountID: number; + + /** The ID of the security group */ groupID: string; }; @@ -33,9 +36,9 @@ function StrictlyEnforceWorkspaceRulesToggle({domainAccountID, groupID}: Strictl return ( { diff --git a/src/types/onyx/DomainErrors.ts b/src/types/onyx/DomainErrors.ts index fa5c41552269..5ccc08962e3c 100644 --- a/src/types/onyx/DomainErrors.ts +++ b/src/types/onyx/DomainErrors.ts @@ -54,6 +54,11 @@ type DomainSecurityGroupErrors = { * Errors related to the strictly enforce workspace rules setting */ enableStrictPolicyRulesErrors?: OnyxCommon.Errors; + + /** + * Errors related to the restricted expense workspace creation + */ + enableRestrictedPolicyCreationErrors?: OnyxCommon.Errors; }; /** diff --git a/src/types/onyx/DomainPendingActions.ts b/src/types/onyx/DomainPendingActions.ts index d2598277f869..49b30b46cdd7 100644 --- a/src/types/onyx/DomainPendingActions.ts +++ b/src/types/onyx/DomainPendingActions.ts @@ -54,6 +54,11 @@ type DomainSecurityGroupPendingActions = { * Pending action for the default security group ID */ defaultSecurityGroupID?: OnyxCommon.PendingAction; + + /** + * Pending action for the restricted expense workspace creation + */ + enableRestrictedPolicyCreation?: OnyxCommon.PendingAction; }; /**