feat(plugin-multi-tenant): allow tenant field overrides (#13316)

Allows user to override more of the tenant field config. Now you can
override most of the field config with:

### At the root level
```ts
/**
 * Field configuration for the field added to all tenant enabled collections
 */
tenantField?: RootTenantFieldConfigOverrides
```

### At the collection level
Setting collection level overrides will replace the root level overrides
shown above.

```ts
collections: {
  [key in CollectionSlug]?: {
    // ... rest of the types
    /**
     * Overrides for the tenant field, will override the entire tenantField configuration
     */
    tenantFieldOverrides?: CollectionTenantFieldConfigOverrides
  }
}
```
This commit is contained in:
Jarrod Flesch
2025-08-12 11:33:29 -04:00
committed by GitHub
parent 306b7f6943
commit 995f96bc70
52 changed files with 478 additions and 303 deletions

View File

@@ -54,8 +54,15 @@ The plugin accepts an object with the following properties:
```ts ```ts
type MultiTenantPluginConfig<ConfigTypes = unknown> = { type MultiTenantPluginConfig<ConfigTypes = unknown> = {
/** /**
* After a tenant is deleted, the plugin will attempt * Base path for your application
* to clean up related documents *
* https://nextjs.org/docs/app/api-reference/config/next-config-js/basePath
*
* @default undefined
*/
basePath?: string
/**
* After a tenant is deleted, the plugin will attempt to clean up related documents
* - removing documents with the tenant ID * - removing documents with the tenant ID
* - removing the tenant from users * - removing the tenant from users
* *
@@ -68,15 +75,18 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
collections: { collections: {
[key in CollectionSlug]?: { [key in CollectionSlug]?: {
/** /**
* Set to `true` if you want the collection to * Set to `true` if you want the collection to behave as a global
* behave as a global
* *
* @default false * @default false
*/ */
isGlobal?: boolean isGlobal?: boolean
/** /**
* Set to `false` if you want to manually apply * Overrides for the tenant field, will override the entire tenantField configuration
* the baseFilter */
tenantFieldOverrides?: CollectionTenantFieldConfigOverrides
/**
* Set to `false` if you want to manually apply the baseListFilter
* Set to `false` if you want to manually apply the baseFilter
* *
* @default true * @default true
*/ */
@@ -94,8 +104,7 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
*/ */
useBaseListFilter?: boolean useBaseListFilter?: boolean
/** /**
* Set to `false` if you want to handle collection access * Set to `false` if you want to handle collection access manually without the multi-tenant constraints applied
* manually without the multi-tenant constraints applied
* *
* @default true * @default true
*/ */
@@ -104,8 +113,7 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
} }
/** /**
* Enables debug mode * Enables debug mode
* - Makes the tenant field visible in the * - Makes the tenant field visible in the admin UI within applicable collections
* admin UI within applicable collections
* *
* @default false * @default false
*/ */
@@ -117,27 +125,41 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
*/ */
enabled?: boolean enabled?: boolean
/** /**
* Field configuration for the field added * Localization for the plugin
* to all tenant enabled collections
*/ */
tenantField?: { i18n?: {
access?: RelationshipField['access'] translations: {
/** [key in AcceptedLanguages]?: {
* The name of the field added to all tenant /**
* enabled collections * @default 'You are about to change ownership from <0>{{fromTenant}}</0> to <0>{{toTenant}}</0>'
* */
* @default 'tenant' 'confirm-modal-tenant-switch--body'?: string
*/ /**
name?: string * `tenantLabel` defaults to the value of the `nav-tenantSelector-label` translation
*
* @default 'Confirm {{tenantLabel}} change'
*/
'confirm-modal-tenant-switch--heading'?: string
/**
* @default 'Assigned Tenant'
*/
'field-assignedTenant-label'?: string
/**
* @default 'Tenant'
*/
'nav-tenantSelector-label'?: string
}
}
} }
/** /**
* Field configuration for the field added * Field configuration for the field added to all tenant enabled collections
* to the users collection */
tenantField?: RootTenantFieldConfigOverrides
/**
* Field configuration for the field added to the users collection
* *
* If `includeDefaultField` is `false`, you must * If `includeDefaultField` is `false`, you must include the field on your users collection manually
* include the field on your users collection manually * This is useful if you want to customize the field or place the field in a specific location
* This is useful if you want to customize the field
* or place the field in a specific location
*/ */
tenantsArrayField?: tenantsArrayField?:
| { | {
@@ -158,8 +180,7 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
*/ */
arrayTenantFieldName?: string arrayTenantFieldName?: string
/** /**
* When `includeDefaultField` is `true`, the field will * When `includeDefaultField` is `true`, the field will be added to the users collection automatically
* be added to the users collection automatically
*/ */
includeDefaultField?: true includeDefaultField?: true
/** /**
@@ -176,8 +197,7 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
arrayFieldName?: string arrayFieldName?: string
arrayTenantFieldName?: string arrayTenantFieldName?: string
/** /**
* When `includeDefaultField` is `false`, you must * When `includeDefaultField` is `false`, you must include the field on your users collection manually
* include the field on your users collection manually
*/ */
includeDefaultField?: false includeDefaultField?: false
rowFields?: never rowFields?: never
@@ -186,8 +206,9 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
/** /**
* Customize tenant selector label * Customize tenant selector label
* *
* Either a string or an object where the keys are i18n * Either a string or an object where the keys are i18n codes and the values are the string labels
* codes and the values are the string labels *
* @deprecated Use `i18n.translations` instead.
*/ */
tenantSelectorLabel?: tenantSelectorLabel?:
| Partial<{ | Partial<{
@@ -201,27 +222,25 @@ type MultiTenantPluginConfig<ConfigTypes = unknown> = {
*/ */
tenantsSlug?: string tenantsSlug?: string
/** /**
* Function that determines if a user has access * Function that determines if a user has access to _all_ tenants
* to _all_ tenants
* *
* Useful for super-admin type users * Useful for super-admin type users
*/ */
userHasAccessToAllTenants?: ( userHasAccessToAllTenants?: (
user: ConfigTypes extends { user: unknown } ? ConfigTypes['user'] : User, user: ConfigTypes extends { user: unknown }
? ConfigTypes['user']
: TypedUser,
) => boolean ) => boolean
/** /**
* Opt out of adding access constraints to * Opt out of adding access constraints to the tenants collection
* the tenants collection
*/ */
useTenantsCollectionAccess?: boolean useTenantsCollectionAccess?: boolean
/** /**
* Opt out including the baseFilter to filter * Opt out including the baseListFilter to filter tenants by selected tenant
* tenants by selected tenant
*/ */
useTenantsListFilter?: boolean useTenantsListFilter?: boolean
/** /**
* Opt out including the baseFilter to filter * Opt out including the baseListFilter to filter users by selected tenant
* users by selected tenant
*/ */
useUsersTenantFilter?: boolean useUsersTenantFilter?: boolean
} }

View File

@@ -92,7 +92,9 @@ export const TenantSelector = ({ label, viewType }: { label: string; viewType?:
<div className="tenant-selector"> <div className="tenant-selector">
<SelectInput <SelectInput
isClearable={viewType === 'list'} isClearable={viewType === 'list'}
label={getTranslation(label, i18n)} label={
label ? getTranslation(label, i18n) : t('plugin-multi-tenant:nav-tenantSelector-label')
}
name="setTenant" name="setTenant"
onChange={onChange} onChange={onChange}
options={options} options={options}
@@ -110,7 +112,7 @@ export const TenantSelector = ({ label, viewType }: { label: string; viewType?:
}} }}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error // @ts-expect-error
i18nKey="plugin-multi-tenant:confirm-tenant-switch--body" i18nKey="plugin-multi-tenant:confirm-modal-tenant-switch--body"
t={t} t={t}
variables={{ variables={{
fromTenant: selectedValue?.label, fromTenant: selectedValue?.label,
@@ -118,8 +120,10 @@ export const TenantSelector = ({ label, viewType }: { label: string; viewType?:
}} }}
/> />
} }
heading={t('plugin-multi-tenant:confirm-tenant-switch--heading', { heading={t('plugin-multi-tenant:confirm-modal-tenant-switch--heading', {
tenantLabel: getTranslation(label, i18n), tenantLabel: label
? getTranslation(label, i18n)
: t('plugin-multi-tenant:nav-tenantSelector-label'),
})} })}
modalSlug={confirmSwitchTenantSlug} modalSlug={confirmSwitchTenantSlug}
onConfirm={() => { onConfirm={() => {

View File

@@ -1,2 +1 @@
export { tenantField } from '../fields/tenantField/index.js'
export { tenantsArrayField } from '../fields/tenantsArrayField/index.js' export { tenantsArrayField } from '../fields/tenantsArrayField/index.js'

View File

@@ -1,65 +1,83 @@
import { type RelationshipField } from 'payload' import type { RelationshipFieldSingleValidation, SingleRelationshipField } from 'payload'
import { APIError } from 'payload' import { APIError } from 'payload'
import type { RootTenantFieldConfigOverrides } from '../../types.js'
import { defaults } from '../../defaults.js' import { defaults } from '../../defaults.js'
import { getCollectionIDType } from '../../utilities/getCollectionIDType.js' import { getCollectionIDType } from '../../utilities/getCollectionIDType.js'
import { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js' import { getTenantFromCookie } from '../../utilities/getTenantFromCookie.js'
type Args = { type Args = {
access?: RelationshipField['access']
debug?: boolean debug?: boolean
name: string name: string
overrides?: RootTenantFieldConfigOverrides
tenantsCollectionSlug: string tenantsCollectionSlug: string
unique: boolean unique: boolean
} }
export const tenantField = ({ export const tenantField = ({
name = defaults.tenantFieldName, name = defaults.tenantFieldName,
access = undefined,
debug, debug,
overrides: _overrides = {},
tenantsCollectionSlug = defaults.tenantCollectionSlug, tenantsCollectionSlug = defaults.tenantCollectionSlug,
unique, unique,
}: Args): RelationshipField => ({ }: Args): SingleRelationshipField => {
name, const { validate, ...overrides } = _overrides || {}
type: 'relationship', return {
access, ...(overrides || {}),
admin: { name,
allowCreate: false, type: 'relationship',
allowEdit: false, access: overrides?.access || {},
components: { admin: {
Field: { allowCreate: false,
clientProps: { allowEdit: false,
debug, disableListColumn: true,
unique, disableListFilter: true,
...(overrides?.admin || {}),
components: {
...(overrides?.admin?.components || {}),
Field: {
path: '@payloadcms/plugin-multi-tenant/client#TenantField',
...(typeof overrides?.admin?.components?.Field !== 'string'
? overrides?.admin?.components?.Field || {}
: {}),
clientProps: {
...(typeof overrides?.admin?.components?.Field !== 'string'
? (overrides?.admin?.components?.Field || {})?.clientProps
: {}),
debug,
unique,
},
}, },
path: '@payloadcms/plugin-multi-tenant/client#TenantField',
}, },
}, },
disableListColumn: true, hasMany: false,
disableListFilter: true, hooks: {
}, ...(overrides.hooks || []),
hasMany: false, beforeChange: [
hooks: { ({ req, value }) => {
beforeChange: [ const idType = getCollectionIDType({
({ req, value }) => { collectionSlug: tenantsCollectionSlug,
const idType = getCollectionIDType({ payload: req.payload,
collectionSlug: tenantsCollectionSlug, })
payload: req.payload, if (!value) {
}) const tenantFromCookie = getTenantFromCookie(req.headers, idType)
if (!value) { if (tenantFromCookie) {
const tenantFromCookie = getTenantFromCookie(req.headers, idType) return tenantFromCookie
if (tenantFromCookie) { }
return tenantFromCookie throw new APIError('You must select a tenant', 400, null, true)
} }
throw new APIError('You must select a tenant', 400, null, true)
}
return idType === 'number' ? parseFloat(value) : value return idType === 'number' ? parseFloat(value) : value
}, },
], ...(overrides?.hooks?.beforeChange || []),
}, ],
index: true, },
// @ts-expect-error translations are not typed for this plugin index: true,
label: ({ t }) => t('plugin-multi-tenant:field-assignedTentant-label'), validate: (validate as RelationshipFieldSingleValidation) || undefined,
relationTo: tenantsCollectionSlug, // @ts-expect-error translations are not typed for this plugin
unique, label: overrides?.label || (({ t }) => t('plugin-multi-tenant:field-assignedTenant-label')),
}) relationTo: tenantsCollectionSlug,
unique,
}
}

View File

@@ -40,7 +40,6 @@ export const multiTenantPlugin =
pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName pluginConfig?.tenantsArrayField?.arrayFieldName || defaults.tenantsArrayFieldName
const tenantsArrayTenantFieldName = const tenantsArrayTenantFieldName =
pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName pluginConfig?.tenantsArrayField?.arrayTenantFieldName || defaults.tenantsArrayTenantFieldName
const tenantSelectorLabel = pluginConfig.tenantSelectorLabel || defaults.tenantSelectorLabel
const basePath = pluginConfig.basePath || defaults.basePath const basePath = pluginConfig.basePath || defaults.basePath
/** /**
@@ -69,37 +68,6 @@ export const multiTenantPlugin =
incomingConfig.collections = [] incomingConfig.collections = []
} }
/**
* Add tenant selector localized labels
*/
if (typeof tenantSelectorLabel === 'object') {
if (!incomingConfig.i18n) {
incomingConfig.i18n = {}
}
Object.entries(tenantSelectorLabel).forEach(([_locale, label]) => {
const locale = _locale as AcceptedLanguages
if (!incomingConfig.i18n) {
incomingConfig.i18n = {}
}
if (!incomingConfig.i18n.translations) {
incomingConfig.i18n.translations = {}
}
if (!(locale in incomingConfig.i18n.translations)) {
incomingConfig.i18n.translations[locale] = {}
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
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
})
}
/** /**
* Add tenants array field to users collection * Add tenants array field to users collection
*/ */
@@ -284,6 +252,10 @@ export const multiTenantPlugin =
tenantsCollectionSlug, tenantsCollectionSlug,
}) })
const overrides = pluginConfig.collections[collection.slug]?.tenantFieldOverrides
? pluginConfig.collections[collection.slug]?.tenantFieldOverrides
: pluginConfig.tenantField || {}
/** /**
* Add tenant field to enabled collections * Add tenant field to enabled collections
*/ */
@@ -291,9 +263,9 @@ export const multiTenantPlugin =
0, 0,
0, 0,
tenantField({ tenantField({
...(pluginConfig?.tenantField || {}),
name: tenantFieldName, name: tenantFieldName,
debug: pluginConfig.debug, debug: pluginConfig.debug,
overrides,
tenantsCollectionSlug, tenantsCollectionSlug,
unique: isGlobal, unique: isGlobal,
}), }),
@@ -382,7 +354,7 @@ export const multiTenantPlugin =
*/ */
incomingConfig.admin.components.beforeNavLinks.push({ incomingConfig.admin.components.beforeNavLinks.push({
clientProps: { clientProps: {
label: tenantSelectorLabel, label: pluginConfig.tenantSelectorLabel || undefined,
}, },
path: '@payloadcms/plugin-multi-tenant/client#TenantSelector', path: '@payloadcms/plugin-multi-tenant/client#TenantSelector',
}) })
@@ -390,22 +362,30 @@ export const multiTenantPlugin =
/** /**
* Merge plugin translations * Merge plugin translations
*/ */
if (!incomingConfig.i18n) {
const simplifiedTranslations = Object.entries(translations).reduce( incomingConfig.i18n = {}
(acc, [key, value]) => {
acc[key] = value.translations
return acc
},
{} as Record<string, PluginDefaultTranslationsObject>,
)
incomingConfig.i18n = {
...incomingConfig.i18n,
translations: deepMergeSimple(
simplifiedTranslations,
incomingConfig.i18n?.translations ?? {},
),
} }
Object.entries(translations).forEach(([locale, pluginI18nObject]) => {
const typedLocale = locale as AcceptedLanguages
if (!incomingConfig.i18n!.translations) {
incomingConfig.i18n!.translations = {}
}
if (!(typedLocale in incomingConfig.i18n!.translations)) {
incomingConfig.i18n!.translations[typedLocale] = {}
}
if (!('plugin-multi-tenant' in incomingConfig.i18n!.translations[typedLocale]!)) {
;(incomingConfig.i18n!.translations[typedLocale] as PluginDefaultTranslationsObject)[
'plugin-multi-tenant'
] = {} as PluginDefaultTranslationsObject['plugin-multi-tenant']
}
;(incomingConfig.i18n!.translations[typedLocale] as PluginDefaultTranslationsObject)[
'plugin-multi-tenant'
] = {
...pluginI18nObject.translations['plugin-multi-tenant'],
...(pluginConfig.i18n?.translations?.[typedLocale] || {}),
}
})
return incomingConfig return incomingConfig
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const arTranslations: PluginDefaultTranslationsObject = { export const arTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'أنت على وشك تغيير الملكية من <0>{{fromTenant}}</0> إلى <0>{{toTenant}}</0>', 'أنت على وشك تغيير الملكية من <0>{{fromTenant}}</0> إلى <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'تأكيد تغيير {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'تأكيد تغيير {{tenantLabel}}',
'field-assignedTentant-label': 'المستأجر المعين', 'field-assignedTenant-label': 'المستأجر المعين',
'nav-tenantSelector-label': 'المستأجر',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const azTranslations: PluginDefaultTranslationsObject = { export const azTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Siz <0>{{fromTenant}}</0> mülkiyyətini <0>{{toTenant}}</0> mülkiyyəti dəyişdirəcəksiniz.', 'Siz <0>{{fromTenant}}</0>-dən <0>{{toTenant}}</0>-a mülkiyyəti dəyişməyə hazırlaşırsınız',
'confirm-tenant-switch--heading': '{{tenantLabel}} dəyişikliyini təsdiqləyin', 'confirm-modal-tenant-switch--heading': '{{tenantLabel}} dəyişikliyini təsdiqləyin',
'field-assignedTentant-label': 'Təyin edilmiş İcarəçi', 'field-assignedTenant-label': 'Təyin edilmiş İcarəçi',
'nav-tenantSelector-label': 'Kirayəçi',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const bgTranslations: PluginDefaultTranslationsObject = { export const bgTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Предстои да промените собствеността от <0>{{fromTenant}}</0> на <0>{{toTenant}}</0>', 'Предстои да промените собствеността от <0>{{fromTenant}}</0> на <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Потвърдете промяната на {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Потвърждаване на промяна в {{tenantLabel}}',
'field-assignedTentant-label': 'Назначен наемател', 'field-assignedTenant-label': 'Назначен наемател',
'nav-tenantSelector-label': 'Потребител',
}, },
} }

View File

@@ -0,0 +1,16 @@
import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.js'
export const bnBdTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': {
'confirm-modal-tenant-switch--body':
'আপনি <0>{{fromTenant}}</0> থেকে <0>{{toTenant}}</0> তে মালিকানা পরিবর্তন করতে চলেছেন।',
'confirm-modal-tenant-switch--heading': '{{tenantLabel}} পরিবর্তন নিশ্চিত করুন',
'field-assignedTenant-label': 'নির্ধারিত টেনেন্ট',
'nav-tenantSelector-label': 'ভাড়াটিয়া',
},
}
export const bnBd: PluginLanguage = {
dateFNSKey: 'bn-BD',
translations: bnBdTranslations,
}

View File

@@ -0,0 +1,16 @@
import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.js'
export const bnInTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': {
'confirm-modal-tenant-switch--body':
'আপনি স্বত্বাধিকার পরিবর্তন করতে চলেছেন <0>{{fromTenant}}</0> থেকে <0>{{toTenant}}</0> এ।',
'confirm-modal-tenant-switch--heading': '{{tenantLabel}} পরিবর্তন নিশ্চিত করুন',
'field-assignedTenant-label': 'নির্ধারিত টেনেন্ট',
'nav-tenantSelector-label': 'ভাড়াটিয়া',
},
}
export const bnIn: PluginLanguage = {
dateFNSKey: 'bn-IN',
translations: bnInTranslations,
}

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const caTranslations: PluginDefaultTranslationsObject = { export const caTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Estàs a punt de canviar la propietat de <0>{{fromTenant}}</0> a <0>{{toTenant}}</0>', 'Està a punt de canviar la propietat de <0>{{fromTenant}}</0> a <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Confirmeu el canvi de {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Confirmeu el canvi de {{tenantLabel}}',
'field-assignedTentant-label': 'Llogater Assignat', 'field-assignedTenant-label': 'Llogater Assignat',
'nav-tenantSelector-label': 'Inquilí',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const csTranslations: PluginDefaultTranslationsObject = { export const csTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Chystáte se změnit vlastnictví z <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>', 'Chystáte se změnit vlastnictví z <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Potvrďte změnu {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Potvrďte změnu {{tenantLabel}}',
'field-assignedTentant-label': 'Přiřazený nájemce', 'field-assignedTenant-label': 'Přiřazený nájemce',
'nav-tenantSelector-label': 'Nájemce',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const daTranslations: PluginDefaultTranslationsObject = { export const daTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Du er ved at ændre ejerskab fra <0>{{fromTenant}}</0> til <0>{{toTenant}}</0>', 'Du er ved at skifte ejerskab fra <0>{{fromTenant}}</0> til <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Bekræft {{tenantLabel}} ændring', 'confirm-modal-tenant-switch--heading': 'Bekræft ændring af {{tenantLabel}}',
'field-assignedTentant-label': 'Tildelt Lejer', 'field-assignedTenant-label': 'Tildelt Lejer',
'nav-tenantSelector-label': 'Lejer',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const deTranslations: PluginDefaultTranslationsObject = { export const deTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Sie sind dabei, den Besitz von <0>{{fromTenant}}</0> auf <0>{{toTenant}}</0> zu übertragen.', 'Sie sind dabei, den Besitz von <0>{{fromTenant}}</0> zu <0>{{toTenant}}</0> zu ändern.',
'confirm-tenant-switch--heading': 'Bestätigen Sie die Änderung von {{tenantLabel}}.', 'confirm-modal-tenant-switch--heading': 'Bestätigung der Änderung von {{tenantLabel}}',
'field-assignedTentant-label': 'Zugewiesener Mandant', 'field-assignedTenant-label': 'Zugewiesener Mandant',
'nav-tenantSelector-label': 'Mieter',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginLanguage } from '../types.js'
export const enTranslations = { export const enTranslations = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'You are about to change ownership from <0>{{fromTenant}}</0> to <0>{{toTenant}}</0>', 'You are about to change ownership from <0>{{fromTenant}}</0> to <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Confirm {{tenantLabel}} change', 'confirm-modal-tenant-switch--heading': 'Confirm {{tenantLabel}} change',
'field-assignedTentant-label': 'Assigned Tenant', 'field-assignedTenant-label': 'Assigned Tenant',
'nav-tenantSelector-label': 'Tenant',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const esTranslations: PluginDefaultTranslationsObject = { export const esTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Está a punto de cambiar la propiedad de <0>{{fromTenant}}</0> a <0>{{toTenant}}</0>', 'Está a punto de cambiar la propiedad de <0>{{fromTenant}}</0> a <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Confirme el cambio de {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Confirme el cambio de {{tenantLabel}}',
'field-assignedTentant-label': 'Inquilino Asignado', 'field-assignedTenant-label': 'Inquilino Asignado',
'nav-tenantSelector-label': 'Inquilino',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const etTranslations: PluginDefaultTranslationsObject = { export const etTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Te olete tegemas omandiõiguse muudatust <0>{{fromTenant}}</0>lt <0>{{toTenant}}</0>le.', 'Te olete just muutmas omandiõigust <0>{{fromTenant}}</0> -lt <0>{{toTenant}}</0> -le.',
'confirm-tenant-switch--heading': 'Kinnita {{tenantLabel}} muutus', 'confirm-modal-tenant-switch--heading': 'Kinnita {{tenantLabel}} muutus',
'field-assignedTentant-label': 'Määratud üürnik', 'field-assignedTenant-label': 'Määratud üürnik',
'nav-tenantSelector-label': 'Üürnik',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const faTranslations: PluginDefaultTranslationsObject = { export const faTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'شما در حال تغییر مالکیت از <0>{{fromTenant}}</0> به <0>{{toTenant}}</0> هستید', 'شما در حال تغییر مالکیت از <0>{{fromTenant}}</0> به <0>{{toTenant}}</0> هستید.',
'confirm-tenant-switch--heading': ایید تغییر {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': أیید تغییر {{tenantLabel}}',
'field-assignedTentant-label': 'مستاجر اختصاص یافته', 'field-assignedTenant-label': 'مستاجر اختصاص یافته',
'nav-tenantSelector-label': 'مستاجر',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const frTranslations: PluginDefaultTranslationsObject = { export const frTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Vous êtes sur le point de changer la propriété de <0>{{fromTenant}}</0> à <0>{{toTenant}}</0>', 'Vous êtes sur le point de changer la propriété de <0>{{fromTenant}}</0> à <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Confirmer le changement de {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Confirmer le changement de {{tenantLabel}}',
'field-assignedTentant-label': 'Locataire Attribué', 'field-assignedTenant-label': 'Locataire Attribué',
'nav-tenantSelector-label': 'Locataire',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const heTranslations: PluginDefaultTranslationsObject = { export const heTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'אתה עומד לשנות בעלות מ- <0>{{fromTenant}}</0> ל- <0>{{toTenant}}</0>', 'אתה עומד לשנות בעלות מ- <0>{{fromTenant}}</0> ל- <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'אשר שינוי {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'אשר שינוי {{tenantLabel}}',
'field-assignedTentant-label': 'דייר מוקצה', 'field-assignedTenant-label': 'דייר מוקצה',
'nav-tenantSelector-label': 'דייר',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const hrTranslations: PluginDefaultTranslationsObject = { export const hrTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Upravo ćete promijeniti vlasništvo sa <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>', 'Na rubu ste promjene vlasništva iz <0>{{fromTenant}}</0> u <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Potvrdi promjenu {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Potvrdite promjenu {{tenantLabel}}',
'field-assignedTentant-label': 'Dodijeljeni stanar', 'field-assignedTenant-label': 'Dodijeljeni stanar',
'nav-tenantSelector-label': 'Podstanar',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const huTranslations: PluginDefaultTranslationsObject = { export const huTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Ön azon van, hogy megváltoztassa a tulajdonjogot <0>{{fromTenant}}</0>-ről <0>{{toTenant}}</0>-re.', 'Közel áll ahhoz, hogy megváltoztassa a tulajdongot <0>{{fromTenant}}</0> -ból <0>{{toTenant}}</0> -ba.',
'confirm-tenant-switch--heading': 'Erősítse meg a(z) {{tenantLabel}} változtatást', 'confirm-modal-tenant-switch--heading': 'Erősítse meg a {{tenantLabel}} változást',
'field-assignedTentant-label': 'Kijelölt Bérlő', 'field-assignedTenant-label': 'Kijelölt Bérlő',
'nav-tenantSelector-label': 'Bérlő',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const hyTranslations: PluginDefaultTranslationsObject = { export const hyTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Դուք պատրաստ եք փոխել գերեցդիմատնին ընկերությունը <0>{{fromTenant}}</0>-ից <0>{{toTenant}}</0>-ին', 'Դուք պատրաստվում եք փոխել սեփականությունը <0>{{fromTenant}}</0>-ից <0>{{toTenant}}</0>-ին:',
'confirm-tenant-switch--heading': 'Հաստատեք {{tenantLabel}} փոփոխությունը', 'confirm-modal-tenant-switch--heading': 'Հաստատեք {{tenantLabel}}֊ի փոփոխությունը',
'field-assignedTentant-label': 'Հանձնարարված վարձակալ', 'field-assignedTenant-label': 'Հանձնարարված վարձակալ',
'nav-tenantSelector-label': 'Տենանտ',
}, },
} }

View File

@@ -0,0 +1,16 @@
import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.js'
export const idTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': {
'confirm-modal-tenant-switch--body':
'Anda akan mengubah kepemilikan dari <0>{{fromTenant}}</0> ke <0>{{toTenant}}</0>',
'confirm-modal-tenant-switch--heading': 'Konfirmasi perubahan {{tenantLabel}}',
'field-assignedTenant-label': 'Penyewa yang Ditugaskan',
'nav-tenantSelector-label': 'Penyewa',
},
}
export const id: PluginLanguage = {
dateFNSKey: 'id',
translations: idTranslations,
}

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const itTranslations: PluginDefaultTranslationsObject = { export const itTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Stai per cambiare proprietà da <0>{{fromTenant}}</0> a <0>{{toTenant}}</0>', 'Stai per cambiare il possesso da <0>{{fromTenant}}</0> a <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Conferma il cambiamento di {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Conferma il cambiamento di {{tenantLabel}}',
'field-assignedTentant-label': 'Inquilino Assegnato', 'field-assignedTenant-label': 'Inquilino Assegnato',
'nav-tenantSelector-label': 'Inquilino',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const jaTranslations: PluginDefaultTranslationsObject = { export const jaTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'あなたは所有権を<0>{{fromTenant}}</0>から<0>{{toTenant}}</0>へ変更しようとしています', 'あなたは<0>{{fromTenant}}</0>から<0>{{toTenant}}</0>への所有権を変更しようとしています',
'confirm-tenant-switch--heading': '{{tenantLabel}}の変更を確認してください', 'confirm-modal-tenant-switch--heading': '{{tenantLabel}}の変更を確認します',
'field-assignedTentant-label': '割り当てられたテナント', 'field-assignedTenant-label': '割り当てられたテナント',
'nav-tenantSelector-label': 'テナント',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const koTranslations: PluginDefaultTranslationsObject = { export const koTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'<0>{{fromTenant}}</0>에서 <0>{{toTenant}}</0>로 소유권을 변경하려고 합니다.', '<0>{{fromTenant}}</0>에서 <0>{{toTenant}}</0>로 소유권을 변경하려고 합니다.',
'confirm-tenant-switch--heading': '{{tenantLabel}} 변경 확인하세요', 'confirm-modal-tenant-switch--heading': '{{tenantLabel}} 변경 확인',
'field-assignedTentant-label': '지정된 세입자', 'field-assignedTenant-label': '지정된 세입자',
'nav-tenantSelector-label': '세입자',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const ltTranslations: PluginDefaultTranslationsObject = { export const ltTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Jūs ketinate pakeisti nuosavybės teisę iš <0>{{fromTenant}}</0> į <0>{{toTenant}}</0>', 'Jūs ketinate pakeisti nuosavybę iš <0>{{fromTenant}}</0> į <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Patvirtinkite {{tenantLabel}} pakeitimą', 'confirm-modal-tenant-switch--heading': 'Patvirtinkite {{tenantLabel}} pakeitimą',
'field-assignedTentant-label': 'Paskirtas nuomininkas', 'field-assignedTenant-label': 'Paskirtas nuomininkas',
'nav-tenantSelector-label': 'Nuomininkas',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const lvTranslations: PluginDefaultTranslationsObject = { export const lvTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Jūs gatavojaties mainīt īpašumtiesības no <0>{{fromTenant}}</0> uz <0>{{toTenant}}</0>', 'Jūs gatavojaties mainīt īpašumtiesības no <0>{{fromTenant}}</0> uz <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Apstipriniet {{tenantLabel}} izmaiņu', 'confirm-modal-tenant-switch--heading': 'Apstipriniet {{tenantLabel}} izmaiņu',
'field-assignedTentant-label': 'Piešķirts īrnieks', 'field-assignedTenant-label': 'Piešķirts nomnieks',
'nav-tenantSelector-label': 'Nomnieks',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const myTranslations: PluginDefaultTranslationsObject = { export const myTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Anda akan mengubah pemilikan dari <0>{{fromTenant}}</0> ke <0>{{toTenant}}</0>', 'Anda akan menukar pemilikan dari <0>{{fromTenant}}</0> kepada <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Sahkan perubahan {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Sahkan perubahan {{tenantLabel}}',
'field-assignedTentant-label': 'ခွဲစိုက်ထားသော အငှားယူသူ', 'field-assignedTenant-label': 'ခွဲစိုက်ထားသော အငှားယူသူ',
'nav-tenantSelector-label': 'Penyewa',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const nbTranslations: PluginDefaultTranslationsObject = { export const nbTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Du er i ferd med å endre eierskap fra <0>{{fromTenant}}</0> til <0>{{toTenant}}</0>', 'Du er i ferd med å endre eierskap fra <0>{{fromTenant}}</0> til <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Bekreft {{tenantLabel}} endring', 'confirm-modal-tenant-switch--heading': 'Bekreft endring av {{tenantLabel}}',
'field-assignedTentant-label': 'Tildelt leietaker', 'field-assignedTenant-label': 'Tildelt leietaker',
'nav-tenantSelector-label': 'Leietaker',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const nlTranslations: PluginDefaultTranslationsObject = { export const nlTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'U staat op het punt het eigendom te wijzigen van <0>{{fromTenant}}</0> naar <0>{{toTenant}}</0>', 'U staat op het punt om eigenaarschap te wijzigen van <0>{{fromTenant}}</0> naar <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Bevestig wijziging van {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Bevestig wijziging van {{tenantLabel}}',
'field-assignedTentant-label': 'Toegewezen Huurder', 'field-assignedTenant-label': 'Toegewezen Huurder',
'nav-tenantSelector-label': 'Huurder',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const plTranslations: PluginDefaultTranslationsObject = { export const plTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Za chwilę nastąpi zmiana właściciela z <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>', 'Za chwilę nastąpi zmiana właściciela z <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Potwierdź zmianę {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Potwierdź zmianę {{tenantLabel}}',
'field-assignedTentant-label': 'Przypisany Najemca', 'field-assignedTenant-label': 'Przypisany Najemca',
'nav-tenantSelector-label': 'Najemca',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const ptTranslations: PluginDefaultTranslationsObject = { export const ptTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Você está prestes a alterar a propriedade de <0>{{fromTenant}}</0> para <0>{{toTenant}}</0>', 'Está prestes a mudar a propriedade de <0>{{fromTenant}}</0> para <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Confirme a alteração de {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Confirme a alteração do {{tenantLabel}}',
'field-assignedTentant-label': 'Inquilino Atribuído', 'field-assignedTenant-label': 'Inquilino Atribuído',
'nav-tenantSelector-label': 'Inquilino',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const roTranslations: PluginDefaultTranslationsObject = { export const roTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Sunteți pe punctul de a schimba proprietatea de la <0>{{fromTenant}}</0> la <0>{{toTenant}}</0>', 'Sunteți pe cale să schimbați proprietatea de la <0>{{fromTenant}}</0> la <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Confirmați schimbarea {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Confirmați modificarea {{tenantLabel}}',
'field-assignedTentant-label': 'Locatar Atribuit', 'field-assignedTenant-label': 'Locatar Atribuit',
'nav-tenantSelector-label': 'Locatar',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const rsTranslations: PluginDefaultTranslationsObject = { export const rsTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Upravo ćete promeniti vlasništvo sa <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>', 'Na putu ste da promenite vlasništvo od <0>{{fromTenant}}</0> do <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Potvrdi promena {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Potvrdite promenu {{tenantLabel}}',
'field-assignedTentant-label': 'Dodeljen stanar', 'field-assignedTenant-label': 'Dodeljen stanar',
'nav-tenantSelector-label': 'Podstanar',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const rsLatinTranslations: PluginDefaultTranslationsObject = { export const rsLatinTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Uskoro ćete promeniti vlasništvo sa <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>', 'Uskoro ćete promeniti vlasništvo sa <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Potvrdite promenu {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Potvrdite promenu {{tenantLabel}}',
'field-assignedTentant-label': 'Dodeljen stanar', 'field-assignedTenant-label': 'Dodeljen stanar',
'nav-tenantSelector-label': 'Podstanar',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const ruTranslations: PluginDefaultTranslationsObject = { export const ruTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Вы собираетесь изменить владельца с <0>{{fromTenant}}</0> на <0>{{toTenant}}</0>', 'Вы собираетесь изменить владельца с <0>{{fromTenant}}</0> на <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Подтвердите изменение {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Подтвердите изменение {{tenantLabel}}',
'field-assignedTentant-label': 'Назначенный Арендатор', 'field-assignedTenant-label': 'Назначенный Арендатор',
'nav-tenantSelector-label': 'Арендатор',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const skTranslations: PluginDefaultTranslationsObject = { export const skTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Chystáte sa zmeniť vlastníctvo z <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>', 'Chystáte sa zmeniť vlastníctvo z <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Potvrďte zmenu {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Potvrďte zmenu {{tenantLabel}}',
'field-assignedTentant-label': 'Pridelený nájomca', 'field-assignedTenant-label': 'Pridelený nájomca',
'nav-tenantSelector-label': 'Nájomca',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const slTranslations: PluginDefaultTranslationsObject = { export const slTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Ravno ste pred spremembo lastništva iz <0>{{fromTenant}}</0> na <0>{{toTenant}}</0>', 'Pravkar ste na točki, da spremenite lastništvo iz <0>{{fromTenant}}</0> v <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Potrdi spremembo {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Potrdite spremembo {{tenantLabel}}',
'field-assignedTentant-label': 'Dodeljen najemnik', 'field-assignedTenant-label': 'Dodeljen najemnik',
'nav-tenantSelector-label': 'Najemnik',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const svTranslations: PluginDefaultTranslationsObject = { export const svTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Du är på väg att ändra ägare från <0>{{fromTenant}}</0> till <0>{{toTenant}}</0>', 'Du är på väg att ändra ägande från <0>{{fromTenant}}</0> till <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Bekräfta ändring av {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Bekräfta ändring av {{tenantLabel}}',
'field-assignedTentant-label': 'Tilldelad hyresgäst', 'field-assignedTenant-label': 'Tilldelad hyresgäst',
'nav-tenantSelector-label': 'Hyresgäst',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const thTranslations: PluginDefaultTranslationsObject = { export const thTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'คุณกำลังจะเปลี่ยนความเป็นเจ้าของจาก <0>{{fromTenant}}</0> เป็น <0>{{toTenant}}</0>', 'คุณกำลังจะเปลี่ยนสิทธิ์การเป็นเจ้าของจาก <0>{{fromTenant}}</0> ไปยัง <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'ยืนยันการเปลี่ยนแปลง {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'ยืนยันการเปลี่ยนแปลง {{tenantLabel}}',
'field-assignedTentant-label': 'ผู้เช่าที่ได้รับการกำหนด', 'field-assignedTenant-label': 'ผู้เช่าที่ได้รับการกำหนด',
'nav-tenantSelector-label': 'ผู้เช่า',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const trTranslations: PluginDefaultTranslationsObject = { export const trTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
"Sahipliği <0>{{fromTenant}}</0>'den <0>{{toTenant}}</0>'e değiştirmek üzeresiniz.", "<0>{{fromTenant}}</0>'den <0>{{toTenant}}</0>'ye sahipliği değiştirmek üzeresiniz.",
'confirm-tenant-switch--heading': '{{tenantLabel}} değişikliğini onayla', 'confirm-modal-tenant-switch--heading': '{{tenantLabel}} değişikliğini onayla',
'field-assignedTentant-label': 'Atanan Kiracı', 'field-assignedTenant-label': 'Atanan Kiracı',
'nav-tenantSelector-label': 'Kiracı',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const ukTranslations: PluginDefaultTranslationsObject = { export const ukTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Ви збираєтесь змінити власність з <0>{{fromTenant}}</0> на <0>{{toTenant}}</0>', 'Ви збираєтеся змінити власність з <0>{{fromTenant}}</0> на <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Підтвердіть зміну {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Підтвердіть зміну {{tenantLabel}}',
'field-assignedTentant-label': 'Призначений орендар', 'field-assignedTenant-label': 'Призначений орендар',
'nav-tenantSelector-label': 'Орендар',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const viTranslations: PluginDefaultTranslationsObject = { export const viTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'Bạn đang chuẩn bị chuyển quyền sở hữu từ <0>{{fromTenant}}</0> sang <0>{{toTenant}}</0>', 'Bạn sắp chuyển quyền sở hữu từ <0>{{fromTenant}}</0> đến <0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': 'Xác nhận thay đổi {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': 'Xác nhận thay đổi {{tenantLabel}}',
'field-assignedTentant-label': 'Người thuê đã được chỉ định', 'field-assignedTenant-label': 'Người thuê đã được chỉ định',
'nav-tenantSelector-label': 'Người thuê',
}, },
} }

View File

@@ -2,9 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const zhTranslations: PluginDefaultTranslationsObject = { export const zhTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': '您即将将所有权从<0>{{fromTenant}}</0>更改为<0>{{toTenant}}</0>', 'confirm-modal-tenant-switch--body':
'confirm-tenant-switch--heading': '确认更改{{tenantLabel}}', '您即将从<0>{{fromTenant}}</0>更改为<0>{{toTenant}}</0>的所有权',
'field-assignedTentant-label': '指定租户', 'confirm-modal-tenant-switch--heading': '确认更改{{tenantLabel}}',
'field-assignedTenant-label': '指定租户',
'nav-tenantSelector-label': '租户',
}, },
} }

View File

@@ -2,10 +2,11 @@ import type { PluginDefaultTranslationsObject, PluginLanguage } from '../types.j
export const zhTwTranslations: PluginDefaultTranslationsObject = { export const zhTwTranslations: PluginDefaultTranslationsObject = {
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': 'confirm-modal-tenant-switch--body':
'您即將變更擁有者,從 <0>{{fromTenant}}</0> 切換為 <0>{{toTenant}}</0>', '您即將<0>{{fromTenant}}</0>變更所有權至<0>{{toTenant}}</0>',
'confirm-tenant-switch--heading': '確認變更 {{tenantLabel}}', 'confirm-modal-tenant-switch--heading': '確認變更 {{tenantLabel}}',
'field-assignedTentant-label': '指派的租用戶', 'field-assignedTenant-label': '指派的租用戶',
'nav-tenantSelector-label': '租戶',
}, },
} }

View File

@@ -4,9 +4,10 @@ import type { enTranslations } from './languages/en.js'
export type PluginLanguage = Language<{ export type PluginLanguage = Language<{
'plugin-multi-tenant': { 'plugin-multi-tenant': {
'confirm-tenant-switch--body': string 'confirm-modal-tenant-switch--body': string
'confirm-tenant-switch--heading': string 'confirm-modal-tenant-switch--heading': string
'field-assignedTentant-label': string 'field-assignedTenant-label': string
'nav-tenantSelector-label': string
} }
}> }>

View File

@@ -1,5 +1,12 @@
import type { AcceptedLanguages } from '@payloadcms/translations' import type { AcceptedLanguages } from '@payloadcms/translations'
import type { ArrayField, CollectionSlug, Field, RelationshipField, TypedUser } from 'payload' import type {
ArrayField,
CollectionSlug,
Field,
RelationshipField,
SingleRelationshipField,
TypedUser,
} from 'payload'
export type MultiTenantPluginConfig<ConfigTypes = unknown> = { export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
/** /**
@@ -30,6 +37,11 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
*/ */
isGlobal?: boolean isGlobal?: boolean
/** /**
* Overrides for the tenant field, will override the entire tenantField configuration
*/
tenantFieldOverrides?: CollectionTenantFieldConfigOverrides
/**
* Set to `false` if you want to manually apply the baseListFilter
* Set to `false` if you want to manually apply the baseFilter * Set to `false` if you want to manually apply the baseFilter
* *
* @default true * @default true
@@ -68,18 +80,37 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
* @default true * @default true
*/ */
enabled?: boolean enabled?: boolean
/**
* Localization for the plugin
*/
i18n?: {
translations: {
[key in AcceptedLanguages]?: {
/**
* @default 'You are about to change ownership from <0>{{fromTenant}}</0> to <0>{{toTenant}}</0>'
*/
'confirm-modal-tenant-switch--body'?: string
/**
* `tenantLabel` defaults to the value of the `nav-tenantSelector-label` translation
*
* @default 'Confirm {{tenantLabel}} change'
*/
'confirm-modal-tenant-switch--heading'?: string
/**
* @default 'Assigned Tenant'
*/
'field-assignedTenant-label'?: string
/**
* @default 'Tenant'
*/
'nav-tenantSelector-label'?: string
}
}
}
/** /**
* Field configuration for the field added to all tenant enabled collections * Field configuration for the field added to all tenant enabled collections
*/ */
tenantField?: { tenantField?: RootTenantFieldConfigOverrides
access?: RelationshipField['access']
/**
* The name of the field added to all tenant enabled collections
*
* @default 'tenant'
*/
name?: string
}
/** /**
* Field configuration for the field added to the users collection * Field configuration for the field added to the users collection
* *
@@ -132,6 +163,8 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
* Customize tenant selector label * Customize tenant selector label
* *
* Either a string or an object where the keys are i18n codes and the values are the string labels * Either a string or an object where the keys are i18n codes and the values are the string labels
*
* @deprecated Use `i18n.translations` instead.
*/ */
tenantSelectorLabel?: tenantSelectorLabel?:
| Partial<{ | Partial<{
@@ -166,6 +199,30 @@ export type MultiTenantPluginConfig<ConfigTypes = unknown> = {
useUsersTenantFilter?: boolean useUsersTenantFilter?: boolean
} }
export type RootTenantFieldConfigOverrides = Partial<
Omit<
SingleRelationshipField,
| '_sanitized'
| 'hasMany'
| 'hidden'
| 'index'
| 'localized'
| 'max'
| 'maxRows'
| 'min'
| 'minRows'
| 'relationTo'
| 'required'
| 'type'
| 'unique'
| 'virtual'
>
>
export type CollectionTenantFieldConfigOverrides = Partial<
Omit<RootTenantFieldConfigOverrides, 'name'>
>
export type Tenant<IDType = number | string> = { export type Tenant<IDType = number | string> = {
id: IDType id: IDType
name: string name: string

View File

@@ -124,7 +124,7 @@ export function convertTextNode(node: SlateNode): SerializedTextNode {
format: convertNodeToFormat(node), format: convertNodeToFormat(node),
mode: 'normal', mode: 'normal',
style: '', style: '',
text: node.text ?? "", text: node.text ?? '',
version: 1, version: 1,
} }
} }

View File

@@ -25,14 +25,14 @@ export const zhTwTranslations: DefaultTranslationsObject = {
failedToUnlock: '解除鎖定失敗', failedToUnlock: '解除鎖定失敗',
forceUnlock: '強制解除鎖定', forceUnlock: '強制解除鎖定',
forgotPassword: '忘記密碼', forgotPassword: '忘記密碼',
forgotPasswordEmailInstructions: forgotPasswordEmailInstructions: '請輸入您的電子郵件。您將會收到一封包含密碼重設指示的郵件。',
'請輸入您的電子郵件。您將會收到一封包含密碼重設指示的郵件。',
forgotPasswordQuestion: '忘記密碼?', forgotPasswordQuestion: '忘記密碼?',
forgotPasswordUsernameInstructions: forgotPasswordUsernameInstructions:
'請輸入您的使用者名稱。重設密碼的指示將會寄送至該帳號所綁定的電子郵件。', '請輸入您的使用者名稱。重設密碼的指示將會寄送至該帳號所綁定的電子郵件。',
generate: '產生', generate: '產生',
generateNewAPIKey: '產生新的 API 金鑰', generateNewAPIKey: '產生新的 API 金鑰',
generatingNewAPIKeyWillInvalidate: '產生新的 API 金鑰將會使原本的金鑰<1>失效</1>。確定要繼續嗎?', generatingNewAPIKeyWillInvalidate:
'產生新的 API 金鑰將會使原本的金鑰<1>失效</1>。確定要繼續嗎?',
lockUntil: '鎖定至', lockUntil: '鎖定至',
logBackIn: '重新登入', logBackIn: '重新登入',
loggedIn: '若要使用其他使用者登入,請先<0>登出</0>。', loggedIn: '若要使用其他使用者登入,請先<0>登出</0>。',
@@ -187,8 +187,10 @@ export const zhTwTranslations: DefaultTranslationsObject = {
moveFolder: '移動資料夾', moveFolder: '移動資料夾',
moveItemsToFolderConfirmation: moveItemsToFolderConfirmation:
'您即將移動 <1>{{count}} 個 {{label}}</1> 到 <2>{{toFolder}}</2>。確定要繼續?', '您即將移動 <1>{{count}} 個 {{label}}</1> 到 <2>{{toFolder}}</2>。確定要繼續?',
moveItemsToRootConfirmation: '您即將移動 <1>{{count}} 個 {{label}}</1> 到根資料夾。確定要繼續?', moveItemsToRootConfirmation:
moveItemToFolderConfirmation: '您即將移動 <1>{{title}}</1> 到 <2>{{toFolder}}</2>。確定要繼續?', '您即將移動 <1>{{count}} 個 {{label}}</1> 到根資料夾。確定要繼續?',
moveItemToFolderConfirmation:
'您即將移動 <1>{{title}}</1> 到 <2>{{toFolder}}</2>。確定要繼續?',
moveItemToRootConfirmation: '您即將移動 <1>{{title}}</1> 到根資料夾。確定要繼續?', moveItemToRootConfirmation: '您即將移動 <1>{{title}}</1> 到根資料夾。確定要繼續?',
movingFromFolder: '正在從 {{fromFolder}} 移動 {{title}}', movingFromFolder: '正在從 {{fromFolder}} 移動 {{title}}',
newFolder: '新增資料夾', newFolder: '新增資料夾',
@@ -390,8 +392,7 @@ export const zhTwTranslations: DefaultTranslationsObject = {
success: '成功', success: '成功',
successfullyCreated: '已成功建立 {{label}}。', successfullyCreated: '已成功建立 {{label}}。',
successfullyDuplicated: '已成功複製 {{label}}。', successfullyDuplicated: '已成功複製 {{label}}。',
successfullyReindexed: successfullyReindexed: '已成功重新索引 {{collections}} 中 {{total}} 筆文件中的 {{count}} 筆。',
'已成功重新索引 {{collections}} 中 {{total}} 筆文件中的 {{count}} 筆。',
takeOver: '接手編輯', takeOver: '接手編輯',
thisLanguage: '中文(繁體)', thisLanguage: '中文(繁體)',
time: '時間', time: '時間',

View File

@@ -44,7 +44,15 @@ export default buildConfigWithDefaults({
isGlobal: true, isGlobal: true,
}, },
}, },
tenantSelectorLabel: { en: 'Site', es: 'Site in es' }, i18n: {
translations: {
en: {
'field-assignedTenant-label': 'Currently Assigned Site',
'nav-tenantSelector-label': 'Filter By Site',
'confirm-modal-tenant-switch--heading': 'Confirm Site Change',
},
},
},
}), }),
], ],
typescript: { typescript: {