diff --git a/apps/web/src/app/(portal)/admin/modules/grants/grants-matrix.test.tsx b/apps/web/src/app/(portal)/admin/modules/grants/grants-matrix.test.tsx index 9f1d2a0..0d9fb5a 100644 --- a/apps/web/src/app/(portal)/admin/modules/grants/grants-matrix.test.tsx +++ b/apps/web/src/app/(portal)/admin/modules/grants/grants-matrix.test.tsx @@ -13,7 +13,7 @@ const messages: Record> = { title: 'Freigaben-Matrix', searchPlaceholder: 'Module oder Gruppen durchsuchen...', emptyModules: - 'Es sind noch keine Module für diesen Mandanten aktiviert. Aktiviere zuerst ein Modul unter Module.', + 'Es sind noch keine Module aktiviert. Aktiviere zuerst ein Modul unter Module.', emptyModulesLink: 'Zu Module', adminNote: 'ADMIN und SUPER_ADMIN haben immer Zugriff auf alle aktiven Module — diese Matrix betrifft nur die Rolle USER.', @@ -153,7 +153,7 @@ describe('AdminModuleGrantsPage (Permission-Matrix)', () => { render(); await waitFor(() => { - expect(screen.getByText(/keine Module für diesen Mandanten aktiviert/)).toBeInTheDocument(); + expect(screen.getByText(/noch keine Module aktiviert/)).toBeInTheDocument(); }); const link = screen.getByText('Zu Module'); expect(link.closest('a')).toHaveAttribute('href', '/admin/modules'); diff --git a/apps/web/src/app/(portal)/marketplace/components/TenantContextSelector.tsx b/apps/web/src/app/(portal)/marketplace/components/TenantContextSelector.tsx index 30a7e9d..9a311de 100644 --- a/apps/web/src/app/(portal)/marketplace/components/TenantContextSelector.tsx +++ b/apps/web/src/app/(portal)/marketplace/components/TenantContextSelector.tsx @@ -34,7 +34,8 @@ export function TenantContextSelector() { .finally(() => setLoading(false)); }, [isSuperAdmin]); - if (!isSuperAdmin) return null; + // Nur bei mehreren Organisationen sinnvoll; im Ein-Firmen-Betrieb ausgeblendet. + if (!isSuperAdmin || (!loading && tenants.length <= 1)) return null; return (
diff --git a/apps/web/src/app/(portal)/marketplace/marketplace-filters.test.tsx b/apps/web/src/app/(portal)/marketplace/marketplace-filters.test.tsx index bd77efb..4454094 100644 --- a/apps/web/src/app/(portal)/marketplace/marketplace-filters.test.tsx +++ b/apps/web/src/app/(portal)/marketplace/marketplace-filters.test.tsx @@ -25,7 +25,7 @@ vi.mock('next-intl', () => ({ errorLoad: 'Module konnten nicht geladen werden.', toastActivated: 'Modul erfolgreich aktiviert', accessDenied: 'Zugriff verweigert', - tenantContextLabel: 'Mandanten-Kontext', + tenantContextLabel: 'Organisation', }; let result = translations[key] ?? key; if (params) { diff --git a/apps/web/src/app/(portal)/marketplace/tenant-selector.test.tsx b/apps/web/src/app/(portal)/marketplace/tenant-selector.test.tsx index 96fd626..8127dbf 100644 --- a/apps/web/src/app/(portal)/marketplace/tenant-selector.test.tsx +++ b/apps/web/src/app/(portal)/marketplace/tenant-selector.test.tsx @@ -27,7 +27,7 @@ vi.mock('next-intl', () => ({ toastActivated: 'Modul erfolgreich aktiviert', toastDeactivated: 'Modul erfolgreich deaktiviert', accessDenied: 'Zugriff verweigert', - tenantContextLabel: 'Mandanten-Kontext', + tenantContextLabel: 'Organisation', deactivateDialogTitle: 'Modul deaktivieren', deactivateDialogBody: 'Moechten Sie {moduleName} fuer diesen Mandanten deaktivieren?', deactivateDialogConfirm: 'Deaktivieren', @@ -118,6 +118,21 @@ describe('TenantContextSelector', () => { expect(screen.getByText('Tenant Beta')).toBeInTheDocument(); }); + it('blendet die Auswahl bei nur einer Organisation aus', async () => { + mockAuthStore.mockImplementation( + (selector: (state: { user: { id: string; username: string; displayName: string; role: string; tenantId: string } }) => unknown) => + selector({ + user: { id: 'u1', username: 'superadmin', displayName: 'Super', role: 'SUPER_ADMIN', tenantId: 't1' }, + }), + ); + vi.stubGlobal( + 'fetch', + vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve([mockTenants[0]]) })), + ); + const { container } = render(); + await waitFor(() => expect(container.innerHTML).toBe('')); + }); + it('renders nothing for ADMIN and does not load the tenant list', () => { mockAuthStore.mockImplementation( (selector: (state: { user: { id: string; username: string; displayName: string; role: string; tenantId: string } }) => unknown) => diff --git a/apps/web/src/components/admin/welcome-mail-template-editor.test.tsx b/apps/web/src/components/admin/welcome-mail-template-editor.test.tsx index b32c846..f246b93 100644 --- a/apps/web/src/components/admin/welcome-mail-template-editor.test.tsx +++ b/apps/web/src/components/admin/welcome-mail-template-editor.test.tsx @@ -120,7 +120,7 @@ describe('WelcomeMailTemplateEditor', () => { ]) { expect(within(box).getByRole('button', { name: `${token} einfügen` })).toBeTruthy(); } - expect(within(box).getByText('Name Ihres Mandanten')).toBeTruthy(); + expect(within(box).getByText('Name Ihrer Organisation')).toBeTruthy(); expect(within(box).getByText('max.mustermann@example.com')).toBeTruthy(); }); diff --git a/apps/web/src/messages/de.json b/apps/web/src/messages/de.json index 851e5a9..3e452a6 100644 --- a/apps/web/src/messages/de.json +++ b/apps/web/src/messages/de.json @@ -555,7 +555,7 @@ "viaGroupsColumn": "Über Gruppe(n)", "directColumn": "Direkt", "noInheritance": "–", - "noActiveModules": "Für diesen Mandanten sind keine Module aktiviert.", + "noActiveModules": "Es sind keine Module aktiviert.", "directCheckboxLabel": "{module} direkt für {user} {granted, select, true {freigeben} other {entziehen}}", "directLevelLabel": "Stufe der direkten Freigabe von {module} für {user}", "manageMarker": "Verwalten", @@ -751,7 +751,7 @@ }, "welcomeMail": { "title": "Willkommensmail", - "description": "Hier legen Sie fest, mit welchen Worten Tessera neue Benutzer begrüßt. Die Vorlage gilt für Ihren Mandanten und wird bei jeder Willkommensmail aus der Benutzerverwaltung verwendet.", + "description": "Hier legen Sie fest, mit welchen Worten Tessera neue Benutzer begrüßt. Die Vorlage gilt für alle Benutzer und wird bei jeder Willkommensmail aus der Benutzerverwaltung verwendet.", "loading": "Vorlage wird geladen …", "fixed": { "title": "Was Sie anpassen können – und was immer drin bleibt", @@ -832,7 +832,7 @@ "example": "https://tessera.example.com" }, "firma": { - "meaning": "Name Ihres Mandanten", + "meaning": "Name Ihrer Organisation", "example": "Beispiel GmbH" } } @@ -846,13 +846,13 @@ "frameTitle": "Vorschau der Willkommensmail", "error": "Die Vorschau konnte nicht erstellt werden.", "blocked": "Die Vorschau wird aktualisiert, sobald alle Felder in Ordnung sind.", - "sampleHint": "Die Vorschau verwendet Beispielwerte (Max Mustermann) und den Namen Ihres Mandanten. Der Link „Passwort festlegen“ ist in der Vorschau nur ein Beispiel." + "sampleHint": "Die Vorschau verwendet Beispielwerte (Max Mustermann) und den Namen Ihrer Organisation. Der Link „Passwort festlegen“ ist in der Vorschau nur ein Beispiel." } } }, "adminModules": { "title": "Modulverwaltung", - "description": "Module für Ihren Mandanten aktivieren oder deaktivieren", + "description": "Module aktivieren oder deaktivieren", "activate": "Aktivieren", "deactivate": "Deaktivieren", "activated": "Aktiviert", @@ -868,7 +868,7 @@ "grants": { "title": "Freigaben-Matrix", "searchPlaceholder": "Module oder Gruppen durchsuchen...", - "emptyModules": "Es sind noch keine Module für diesen Mandanten aktiviert. Aktiviere zuerst ein Modul unter Module.", + "emptyModules": "Es sind noch keine Module aktiviert. Aktiviere zuerst ein Modul unter Module.", "emptyModulesLink": "Zu Module", "levelExplanation": "„Benutzen“: Das Modul öffnen und damit arbeiten. „Verwalten“: zusätzlich die Einstellungen dieses Moduls ändern. Freigaben vergeben und Module aktivieren dürfen weiterhin nur Administratoren. Hat jemand über mehrere Wege Zugriff, gilt die höhere Stufe.", "adminNote": "Administratoren haben immer Zugriff auf alle aktiven Module und dürfen deren Einstellungen ändern – diese Matrix betrifft nur Benutzer ohne Administratorrechte.", @@ -964,7 +964,7 @@ "notFoundDescription": "Das angeforderte Modul existiert nicht oder ist nicht aktiviert.", "backToCategory": "Zurück zur Kategorie", "allModules": "Module", - "allModulesDescription": "Verfügbare Module für Ihren Mandanten", + "allModulesDescription": "Verfügbare Module", "noActiveModules": "Keine Module aktiviert. Bitten Sie Ihren Administrator, Module zu aktivieren.", "accessDenied": { "title": "Kein Zugriff auf dieses Modul", @@ -1194,7 +1194,7 @@ }, "marketplace": { "title": "Marktplatz", - "subtitle": "Entdecken und aktivieren Sie Module für Ihren Mandanten", + "subtitle": "Entdecken und aktivieren Sie Module", "activate": "Modul aktivieren", "deactivate": "Deaktivieren", "searchPlaceholder": "Module suchen...", @@ -1212,13 +1212,13 @@ "toastActivateError": "Aktivierung fehlgeschlagen. Bitte versuchen Sie es erneut.", "toastDeactivateError": "Deaktivierung fehlgeschlagen. Bitte versuchen Sie es erneut.", "deactivateDialogTitle": "Modul deaktivieren", - "deactivateDialogBody": "Möchten Sie {moduleName} für diesen Mandanten deaktivieren? Das Modul wird aus der Seitenleiste entfernt.", + "deactivateDialogBody": "Möchten Sie {moduleName} deaktivieren? Das Modul wird aus der Seitenleiste entfernt.", "deactivateDialogConfirm": "Deaktivieren", "deactivateDialogCancel": "Abbrechen", - "tenantContextLabel": "Mandanten-Kontext", + "tenantContextLabel": "Organisation", "backToMarketplace": "Zurück zum Marktplatz", "detailVersion": "Version {version}", - "detailStatusActive": "Aktiviert für diesen Mandanten", + "detailStatusActive": "Aktiviert", "detailStatusInactive": "Nicht aktiviert", "accessDenied": "Zugriff verweigert", "statusNoAccess": "Kein Zugriff", @@ -1528,7 +1528,7 @@ "settings": { "title": "Ausschreibungs-Radar — Einstellungen", "rssSectionTitle": "RSS-Feeds", - "rssSectionBody": "Öffentliche, plattformweite RSS-Quellen (z. B. service.bund.de oder eine subreport-elvis-Kommunalfeed) — gilt für alle Mandanten gleich, nicht pro Mandant konfigurierbar.", + "rssSectionBody": "Öffentliche, plattformweite RSS-Quellen (z. B. service.bund.de oder eine subreport-elvis-Kommunalfeed) — gilt für alle gleich.", "rssSectionUserNote": "Persönliche Feeds legen Sie auf „Meine Quellen\" an.", "accessDeniedText": "Diese Seite verwaltet plattformweite Einstellungen und ist Administratoren vorbehalten.", "digestIntervalLabel": "Digest-Intervall", @@ -1611,7 +1611,7 @@ }, "mySources": { "title": "Meine Quellen", - "intro": "Ausschreibungen, die aus Ihrem Postfach hereinkommen, erscheinen danach in der Trefferliste aller Kolleginnen und Kollegen Ihres Mandanten — es gibt keine getrennte Sichtbarkeit je Postfach.", + "intro": "Ausschreibungen, die aus Ihrem Postfach hereinkommen, erscheinen danach in der Trefferliste aller Kolleginnen und Kollegen — es gibt keine getrennte Sichtbarkeit je Postfach.", "mailboxSectionTitle": "Mein Postfach", "feedsSectionTitle": "Meine Feeds", "notificationSectionTitle": "Benachrichtigung", diff --git a/apps/web/src/messages/en.json b/apps/web/src/messages/en.json index 9de225f..dcd25a1 100644 --- a/apps/web/src/messages/en.json +++ b/apps/web/src/messages/en.json @@ -555,7 +555,7 @@ "viaGroupsColumn": "Via Group(s)", "directColumn": "Direct", "noInheritance": "–", - "noActiveModules": "No modules are activated for this tenant.", + "noActiveModules": "No modules are activated.", "directCheckboxLabel": "{granted, select, true {Grant} other {Revoke}} {module} directly for {user}", "directLevelLabel": "Level of the direct grant of {module} for {user}", "manageMarker": "Manage", @@ -751,7 +751,7 @@ }, "welcomeMail": { "title": "Welcome email", - "description": "Choose the words Tessera uses to greet new users. The template applies to your tenant and is used for every welcome email sent from user management.", + "description": "Choose the words Tessera uses to greet new users. The template applies to all users and is used for every welcome email sent from user management.", "loading": "Loading template …", "fixed": { "title": "What you can change – and what always stays", @@ -832,7 +832,7 @@ "example": "https://tessera.example.com" }, "firma": { - "meaning": "Name of your tenant", + "meaning": "Name of your organization", "example": "Example Ltd" } } @@ -846,13 +846,13 @@ "frameTitle": "Welcome email preview", "error": "The preview could not be created.", "blocked": "The preview updates as soon as all fields are valid.", - "sampleHint": "The preview uses sample values (Max Mustermann) and the name of your tenant. The “Set password” link is only an example in the preview." + "sampleHint": "The preview uses sample values (Max Mustermann) and the name of your organization. The “Set password” link is only an example in the preview." } } }, "adminModules": { "title": "Module Management", - "description": "Activate or deactivate modules for your tenant", + "description": "Activate or deactivate modules", "activate": "Activate", "deactivate": "Deactivate", "activated": "Activated", @@ -868,7 +868,7 @@ "grants": { "title": "Grants Matrix", "searchPlaceholder": "Search modules or groups...", - "emptyModules": "No modules are activated for this tenant yet. Activate a module under Modules first.", + "emptyModules": "No modules are activated yet. Activate a module under Modules first.", "emptyModulesLink": "Go to Modules", "levelExplanation": "“Use”: open the module and work with it. “Manage”: additionally change the settings of this module. Only administrators may grant access and activate modules. If someone has access through several routes, the higher level applies.", "adminNote": "Administrators always have access to all active modules and may change their settings — this matrix only affects users without administrator rights.", @@ -964,7 +964,7 @@ "notFoundDescription": "The requested module does not exist or is not activated.", "backToCategory": "Back to category", "allModules": "Modules", - "allModulesDescription": "Available modules for your tenant", + "allModulesDescription": "Available modules", "noActiveModules": "No modules activated. Ask your administrator to enable modules.", "accessDenied": { "title": "No Access to This Module", @@ -1194,7 +1194,7 @@ }, "marketplace": { "title": "Marketplace", - "subtitle": "Discover and activate modules for your tenant", + "subtitle": "Discover and activate modules", "activate": "Activate Module", "deactivate": "Deactivate", "searchPlaceholder": "Search modules...", @@ -1212,13 +1212,13 @@ "toastActivateError": "Activation failed. Please try again.", "toastDeactivateError": "Deactivation failed. Please try again.", "deactivateDialogTitle": "Deactivate Module", - "deactivateDialogBody": "Do you want to deactivate {moduleName} for this tenant? The module will be removed from the sidebar.", + "deactivateDialogBody": "Do you want to deactivate {moduleName}? The module will be removed from the sidebar.", "deactivateDialogConfirm": "Deactivate", "deactivateDialogCancel": "Cancel", - "tenantContextLabel": "Tenant Context", + "tenantContextLabel": "Organization", "backToMarketplace": "Back to Marketplace", "detailVersion": "Version {version}", - "detailStatusActive": "Activated for this tenant", + "detailStatusActive": "Activated", "detailStatusInactive": "Not activated", "accessDenied": "Access denied", "statusNoAccess": "No Access", @@ -1528,7 +1528,7 @@ "settings": { "title": "Tender Radar — Settings", "rssSectionTitle": "RSS Feeds", - "rssSectionBody": "Public, platform-wide RSS sources (e.g. service.bund.de or a subreport-elvis municipal feed) — applies equally to all tenants, not configurable per tenant.", + "rssSectionBody": "Public, platform-wide RSS sources (e.g. service.bund.de or a subreport-elvis municipal feed) — applies to everyone equally.", "rssSectionUserNote": "Add personal feeds under \"My sources\".", "accessDeniedText": "This page manages platform-wide settings and is reserved for administrators.", "digestIntervalLabel": "Digest Interval",