feat(plugin-multi-tenant): allow customization of selector label (#11418)
### What? Allows for custom labeling of the tenant selector shown in the sidebar. Fixes https://github.com/payloadcms/payload/issues/11262
This commit is contained in:
@@ -158,6 +158,16 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
|
||||
rowFields?: never
|
||||
tenantFieldAccess?: never
|
||||
}
|
||||
/**
|
||||
* Customize tenant selector label
|
||||
*
|
||||
* Either a string or an object where the keys are locales and the values are the string labels
|
||||
*/
|
||||
tenantSelectorLabel?:
|
||||
| Partial<{
|
||||
[key in AcceptedLanguages]?: string
|
||||
}>
|
||||
| string
|
||||
/**
|
||||
* The slug for the tenant collection
|
||||
*
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@payloadcms/eslint-config": "workspace:*",
|
||||
"@payloadcms/translations": "workspace:*",
|
||||
"@payloadcms/ui": "workspace:*",
|
||||
"payload": "workspace:*"
|
||||
},
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
import type { ReactSelectOption } from '@payloadcms/ui'
|
||||
import type { ViewTypes } from 'payload'
|
||||
|
||||
import { SelectInput } from '@payloadcms/ui'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
import { SelectInput, useTranslation } from '@payloadcms/ui'
|
||||
import React from 'react'
|
||||
|
||||
import { SELECT_ALL } from '../../constants.js'
|
||||
import { useTenantSelection } from '../../providers/TenantSelectionProvider/index.client.js'
|
||||
|
||||
export const TenantSelector = ({ viewType }: { viewType?: ViewTypes }) => {
|
||||
export const TenantSelector = ({ label, viewType }: { label: string; viewType?: ViewTypes }) => {
|
||||
const { options, selectedTenantID, setTenant } = useTenantSelection()
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleChange = React.useCallback(
|
||||
(option: ReactSelectOption | ReactSelectOption[]) => {
|
||||
@@ -33,7 +33,7 @@ export const TenantSelector = ({ viewType }: { viewType?: ViewTypes }) => {
|
||||
<div className="tenant-selector">
|
||||
<SelectInput
|
||||
isClearable={viewType === 'list'}
|
||||
label="Tenant"
|
||||
label={t(label as any)}
|
||||
name="setTenant"
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
|
||||
@@ -3,4 +3,5 @@ export const defaults = {
|
||||
tenantFieldName: 'tenant',
|
||||
tenantsArrayFieldName: 'tenants',
|
||||
tenantsArrayTenantFieldName: 'tenant',
|
||||
tenantSelectorLabel: 'Tenant',
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AcceptedLanguages } from '@payloadcms/translations'
|
||||
import type { CollectionConfig, Config } from 'payload'
|
||||
|
||||
import type { MultiTenantPluginConfig } from './types.js'
|
||||
@@ -36,6 +37,7 @@ export const multiTenantPlugin =
|
||||
pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName
|
||||
const tenantsArrayTenantFieldName =
|
||||
pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName
|
||||
let tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel
|
||||
|
||||
/**
|
||||
* Add defaults for admin properties
|
||||
@@ -63,6 +65,36 @@ export const multiTenantPlugin =
|
||||
incomingConfig.collections = []
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tenant selector localized labels
|
||||
*/
|
||||
if (pluginConfig.tenantSelectorLabel && typeof pluginConfig.tenantSelectorLabel === 'object') {
|
||||
if (!incomingConfig.i18n) {
|
||||
incomingConfig.i18n = {}
|
||||
}
|
||||
Object.entries(pluginConfig.tenantSelectorLabel).forEach(([_locale, label]) => {
|
||||
const locale = _locale as AcceptedLanguages
|
||||
if (!incomingConfig.i18n) {
|
||||
incomingConfig.i18n = {}
|
||||
}
|
||||
if (!incomingConfig.i18n.translations) {
|
||||
incomingConfig.i18n.translations = {}
|
||||
}
|
||||
if (!incomingConfig.i18n.translations[locale]) {
|
||||
incomingConfig.i18n.translations[locale] = {}
|
||||
}
|
||||
if (!('multiTenant' in incomingConfig.i18n.translations[locale])) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
incomingConfig.i18n.translations[locale].multiTenant = {}
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
incomingConfig.i18n.translations[locale].multiTenant.selectorLabel = label
|
||||
tenantSelectorLabel = 'multiTenant:selectorLabel'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tenants array field to users collection
|
||||
*/
|
||||
@@ -229,7 +261,8 @@ export const multiTenantPlugin =
|
||||
|
||||
if (pluginConfig.collections[collection.slug]?.useBaseListFilter !== false) {
|
||||
/**
|
||||
* Collection baseListFilter with selected tenant constraint (if selected)
|
||||
* Add list filter to enabled collections
|
||||
* - filters results by selected tenant
|
||||
*/
|
||||
if (!collection.admin) {
|
||||
collection.admin = {}
|
||||
@@ -295,6 +328,9 @@ export const multiTenantPlugin =
|
||||
* Add tenant selector to admin UI
|
||||
*/
|
||||
incomingConfig.admin.components.beforeNavLinks.push({
|
||||
clientProps: {
|
||||
label: tenantSelectorLabel,
|
||||
},
|
||||
path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',
|
||||
})
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { AcceptedLanguages } from '@payloadcms/translations'
|
||||
import type { ArrayField, CollectionSlug, Field, RelationshipField, User } from 'payload'
|
||||
|
||||
export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
|
||||
@@ -107,6 +108,16 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
|
||||
rowFields?: never
|
||||
tenantFieldAccess?: never
|
||||
}
|
||||
/**
|
||||
* Customize tenant selector label
|
||||
*
|
||||
* Either a string or an object where the keys are locales and the values are the string labels
|
||||
*/
|
||||
tenantSelectorLabel?:
|
||||
| Partial<{
|
||||
[key in AcceptedLanguages]?: string
|
||||
}>
|
||||
| string
|
||||
/**
|
||||
* The slug for the tenant collection
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"references": [{ "path": "../payload" }, { "path": "../ui"}]
|
||||
"references": [{ "path": "../payload" }, { "path": "../ui"}, { "path": "../translations"}]
|
||||
}
|
||||
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -1031,6 +1031,9 @@ importers:
|
||||
'@payloadcms/eslint-config':
|
||||
specifier: workspace:*
|
||||
version: link:../eslint-config
|
||||
'@payloadcms/translations':
|
||||
specifier: workspace:*
|
||||
version: link:../translations
|
||||
'@payloadcms/ui':
|
||||
specifier: workspace:*
|
||||
version: link:../ui
|
||||
|
||||
@@ -41,6 +41,7 @@ export default buildConfigWithDefaults({
|
||||
isGlobal: true,
|
||||
},
|
||||
},
|
||||
tenantSelectorLabel: 'Sites',
|
||||
}),
|
||||
],
|
||||
typescript: {
|
||||
|
||||
Reference in New Issue
Block a user