fix(plugin-multi-tenant): updates tenant selector upon tenant creation (#12936)

### What?
Updates the tenant selector displayed in the sidebar when a new tenant
is created.

### Why?
Currently when using the multi-tenant plugin and creating a new tenant
doc, the tenant selector dropdown does not display the new tenant as an
option until the page gets refreshed.

### How?
Extends the `WatchTenantCollection` helper to check if the tenant `id`
from the current doc exists, if the tenant is new it manually calls
`updateTenants`. The `updateTenants` function previously only adjusted
the title on existing tenants, this has been updated to add a new tenant
as an option when it doesn't exist.

#### Reported by client
This commit is contained in:
Jessica Rynkar
2025-06-27 11:26:05 +01:00
committed by GitHub
parent a1822d21d0
commit c76d83985d
2 changed files with 33 additions and 4 deletions

View File

@@ -16,6 +16,7 @@ import { useTenantSelection } from '../../providers/TenantSelectionProvider/inde
export const WatchTenantCollection = () => { export const WatchTenantCollection = () => {
const { id, collectionSlug } = useDocumentInfo() const { id, collectionSlug } = useDocumentInfo()
const { title } = useDocumentTitle() const { title } = useDocumentTitle()
const addedNewTenant = React.useRef(false)
const { getEntityConfig } = useConfig() const { getEntityConfig } = useConfig()
const [useAsTitleName] = React.useState( const [useAsTitleName] = React.useState(
@@ -23,7 +24,7 @@ export const WatchTenantCollection = () => {
) )
const titleField = useFormFields(([fields]) => (useAsTitleName ? fields[useAsTitleName] : {})) const titleField = useFormFields(([fields]) => (useAsTitleName ? fields[useAsTitleName] : {}))
const { updateTenants } = useTenantSelection() const { options, updateTenants } = useTenantSelection()
const syncTenantTitle = useEffectEvent(() => { const syncTenantTitle = useEffectEvent(() => {
if (id) { if (id) {
@@ -31,6 +32,20 @@ export const WatchTenantCollection = () => {
} }
}) })
React.useEffect(() => {
if (!id || !title || addedNewTenant.current) {
return
}
// Track tenant creation and add it to the tenant selector
const exists = options.some((opt) => opt.value === id)
if (!exists) {
addedNewTenant.current = true
updateTenants({ id, label: title })
}
// eslint-disable-next-line react-compiler/react-compiler
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id])
React.useEffect(() => { React.useEffect(() => {
// only update the tenant selector when the document saves // only update the tenant selector when the document saves
// → aka when initial value changes // → aka when initial value changes

View File

@@ -104,15 +104,29 @@ export const TenantSelectionProviderClient = ({
const updateTenants = React.useCallback<ContextType['updateTenants']>(({ id, label }) => { const updateTenants = React.useCallback<ContextType['updateTenants']>(({ id, label }) => {
setTenantOptions((prev) => { setTenantOptions((prev) => {
return prev.map((currentTenant) => { const stringID = String(id)
if (id === currentTenant.value) { let exists = false
const updated = prev.map((currentTenant) => {
if (stringID === String(currentTenant.value)) {
exists = true
return { return {
label, label,
value: id, value: stringID,
} }
} }
return currentTenant return currentTenant
}) })
if (!exists) {
updated.push({ label, value: stringID })
}
// Sort alphabetically by label (or value as fallback)
return updated.sort((a, b) => {
const aKey = typeof a.label === 'string' ? a.label : String(a.value)
const bKey = typeof b.label === 'string' ? b.label : String(b.value)
return aKey.localeCompare(bKey)
})
}) })
}, []) }, [])