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:
@@ -16,6 +16,7 @@ import { useTenantSelection } from '../../providers/TenantSelectionProvider/inde
|
||||
export const WatchTenantCollection = () => {
|
||||
const { id, collectionSlug } = useDocumentInfo()
|
||||
const { title } = useDocumentTitle()
|
||||
const addedNewTenant = React.useRef(false)
|
||||
|
||||
const { getEntityConfig } = useConfig()
|
||||
const [useAsTitleName] = React.useState(
|
||||
@@ -23,7 +24,7 @@ export const WatchTenantCollection = () => {
|
||||
)
|
||||
const titleField = useFormFields(([fields]) => (useAsTitleName ? fields[useAsTitleName] : {}))
|
||||
|
||||
const { updateTenants } = useTenantSelection()
|
||||
const { options, updateTenants } = useTenantSelection()
|
||||
|
||||
const syncTenantTitle = useEffectEvent(() => {
|
||||
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(() => {
|
||||
// only update the tenant selector when the document saves
|
||||
// → aka when initial value changes
|
||||
|
||||
@@ -104,15 +104,29 @@ export const TenantSelectionProviderClient = ({
|
||||
|
||||
const updateTenants = React.useCallback<ContextType['updateTenants']>(({ id, label }) => {
|
||||
setTenantOptions((prev) => {
|
||||
return prev.map((currentTenant) => {
|
||||
if (id === currentTenant.value) {
|
||||
const stringID = String(id)
|
||||
let exists = false
|
||||
const updated = prev.map((currentTenant) => {
|
||||
if (stringID === String(currentTenant.value)) {
|
||||
exists = true
|
||||
return {
|
||||
label,
|
||||
value: id,
|
||||
value: stringID,
|
||||
}
|
||||
}
|
||||
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)
|
||||
})
|
||||
})
|
||||
}, [])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user