fix(plugin-multi-tenant): prevent duplicate filters on referenced blocks (#13607)
Fixes https://github.com/payloadcms/payload/issues/13601 When using block references, tenant filter options were being applied n+1 every time a block reference was used.
This commit is contained in:
@@ -143,6 +143,9 @@ export const multiTenantPlugin =
|
||||
[[], []],
|
||||
)
|
||||
|
||||
// used to track and not duplicate filterOptions on referenced blocks
|
||||
const blockReferencesWithFilters: string[] = []
|
||||
|
||||
// used to validate enabled collection slugs
|
||||
const multiTenantCollectionsFound: string[] = []
|
||||
|
||||
@@ -157,28 +160,45 @@ export const multiTenantPlugin =
|
||||
|
||||
if (collectionSlugs.includes(foldersSlug)) {
|
||||
multiTenantCollectionsFound.push(foldersSlug)
|
||||
const overrides = pluginConfig.collections[foldersSlug]?.tenantFieldOverrides
|
||||
? pluginConfig.collections[foldersSlug]?.tenantFieldOverrides
|
||||
: pluginConfig.tenantField || {}
|
||||
incomingConfig.folders = incomingConfig.folders || {}
|
||||
incomingConfig.folders.collectionOverrides = incomingConfig.folders.collectionOverrides || []
|
||||
incomingConfig.folders.collectionOverrides.push(({ collection }) => {
|
||||
/**
|
||||
* Add tenant field to enabled collections
|
||||
* Add filter options to all relationship fields
|
||||
*/
|
||||
const folderTenantField = tenantField({
|
||||
...(pluginConfig?.tenantField || {}),
|
||||
name: tenantFieldName,
|
||||
debug: pluginConfig.debug,
|
||||
overrides,
|
||||
addFilterOptionsToFields({
|
||||
blockReferencesWithFilters,
|
||||
config: incomingConfig,
|
||||
fields: collection.fields,
|
||||
tenantEnabledCollectionSlugs: collectionSlugs,
|
||||
tenantEnabledGlobalSlugs: globalCollectionSlugs,
|
||||
tenantFieldName,
|
||||
tenantsArrayFieldName,
|
||||
tenantsArrayTenantFieldName,
|
||||
tenantsCollectionSlug,
|
||||
unique: false,
|
||||
})
|
||||
collection.fields.unshift(folderTenantField)
|
||||
|
||||
if (pluginConfig.collections[foldersSlug]?.useBaseListFilter !== false) {
|
||||
const overrides = pluginConfig.collections[collection.slug]?.tenantFieldOverrides
|
||||
? pluginConfig.collections[collection.slug]?.tenantFieldOverrides
|
||||
: pluginConfig.tenantField || {}
|
||||
|
||||
/**
|
||||
* Add tenant field to enabled collections
|
||||
*/
|
||||
collection.fields.unshift(
|
||||
tenantField({
|
||||
name: tenantFieldName,
|
||||
debug: pluginConfig.debug,
|
||||
overrides,
|
||||
tenantsArrayFieldName,
|
||||
tenantsArrayTenantFieldName,
|
||||
tenantsCollectionSlug,
|
||||
unique: false,
|
||||
}),
|
||||
)
|
||||
|
||||
const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}
|
||||
if (useBaseFilter ?? useBaseListFilter ?? true) {
|
||||
/**
|
||||
* Add list filter to enabled collections
|
||||
* - filters results by selected tenant
|
||||
@@ -314,9 +334,10 @@ export const multiTenantPlugin =
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify enabled collections
|
||||
* Add filter options to all relationship fields
|
||||
*/
|
||||
addFilterOptionsToFields({
|
||||
blockReferencesWithFilters,
|
||||
config: incomingConfig,
|
||||
fields: collection.fields,
|
||||
tenantEnabledCollectionSlugs: collectionSlugs,
|
||||
@@ -334,9 +355,7 @@ export const multiTenantPlugin =
|
||||
/**
|
||||
* Add tenant field to enabled collections
|
||||
*/
|
||||
collection.fields.splice(
|
||||
0,
|
||||
0,
|
||||
collection.fields.unshift(
|
||||
tenantField({
|
||||
name: tenantFieldName,
|
||||
debug: pluginConfig.debug,
|
||||
@@ -349,19 +368,14 @@ export const multiTenantPlugin =
|
||||
)
|
||||
|
||||
const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}
|
||||
|
||||
if (useBaseFilter ?? useBaseListFilter ?? true) {
|
||||
/**
|
||||
* Add list filter to enabled collections
|
||||
* - filters results by selected tenant
|
||||
*/
|
||||
if (!collection.admin) {
|
||||
collection.admin = {}
|
||||
}
|
||||
|
||||
const baseFilter = collection.admin?.baseFilter ?? collection.admin?.baseListFilter
|
||||
collection.admin = collection.admin || {}
|
||||
collection.admin.baseFilter = combineFilters({
|
||||
baseFilter,
|
||||
baseFilter: collection.admin?.baseFilter ?? collection.admin?.baseListFilter,
|
||||
customFilter: (args) =>
|
||||
filterDocumentsByTenants({
|
||||
filterFieldName: tenantFieldName,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { Config, Field, RelationshipField, SanitizedConfig } from 'payload'
|
||||
import type { Block, Config, Field, RelationshipField, SanitizedConfig } from 'payload'
|
||||
|
||||
import { defaults } from '../defaults.js'
|
||||
import { filterDocumentsByTenants } from '../filters/filterDocumentsByTenants.js'
|
||||
|
||||
type AddFilterOptionsToFieldsArgs = {
|
||||
blockReferencesWithFilters: string[]
|
||||
config: Config | SanitizedConfig
|
||||
fields: Field[]
|
||||
tenantEnabledCollectionSlugs: string[]
|
||||
@@ -15,6 +16,7 @@ type AddFilterOptionsToFieldsArgs = {
|
||||
}
|
||||
|
||||
export function addFilterOptionsToFields({
|
||||
blockReferencesWithFilters,
|
||||
config,
|
||||
fields,
|
||||
tenantEnabledCollectionSlugs,
|
||||
@@ -74,6 +76,7 @@ export function addFilterOptionsToFields({
|
||||
field.type === 'group'
|
||||
) {
|
||||
addFilterOptionsToFields({
|
||||
blockReferencesWithFilters,
|
||||
config,
|
||||
fields: field.fields,
|
||||
tenantEnabledCollectionSlugs,
|
||||
@@ -87,14 +90,21 @@ export function addFilterOptionsToFields({
|
||||
|
||||
if (field.type === 'blocks') {
|
||||
;(field.blockReferences ?? field.blocks).forEach((_block) => {
|
||||
const block =
|
||||
typeof _block === 'string'
|
||||
? // TODO: iterate over blocks mapped to block slug in v4, or pass through payload.blocks
|
||||
config?.blocks?.find((b) => b.slug === _block)
|
||||
: _block
|
||||
let block: Block | undefined
|
||||
|
||||
if (typeof _block === 'string') {
|
||||
if (blockReferencesWithFilters.includes(_block)) {
|
||||
return
|
||||
}
|
||||
block = config?.blocks?.find((b) => b.slug === _block)
|
||||
blockReferencesWithFilters.push(_block)
|
||||
} else {
|
||||
block = _block
|
||||
}
|
||||
|
||||
if (block?.fields) {
|
||||
addFilterOptionsToFields({
|
||||
blockReferencesWithFilters,
|
||||
config,
|
||||
fields: block.fields,
|
||||
tenantEnabledCollectionSlugs,
|
||||
@@ -111,6 +121,7 @@ export function addFilterOptionsToFields({
|
||||
if (field.type === 'tabs') {
|
||||
field.tabs.forEach((tab) => {
|
||||
addFilterOptionsToFields({
|
||||
blockReferencesWithFilters,
|
||||
config,
|
||||
fields: tab.fields,
|
||||
tenantEnabledCollectionSlugs,
|
||||
|
||||
Reference in New Issue
Block a user