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
|
// used to validate enabled collection slugs
|
||||||
const multiTenantCollectionsFound: string[] = []
|
const multiTenantCollectionsFound: string[] = []
|
||||||
|
|
||||||
@@ -157,28 +160,45 @@ export const multiTenantPlugin =
|
|||||||
|
|
||||||
if (collectionSlugs.includes(foldersSlug)) {
|
if (collectionSlugs.includes(foldersSlug)) {
|
||||||
multiTenantCollectionsFound.push(foldersSlug)
|
multiTenantCollectionsFound.push(foldersSlug)
|
||||||
const overrides = pluginConfig.collections[foldersSlug]?.tenantFieldOverrides
|
|
||||||
? pluginConfig.collections[foldersSlug]?.tenantFieldOverrides
|
|
||||||
: pluginConfig.tenantField || {}
|
|
||||||
incomingConfig.folders = incomingConfig.folders || {}
|
incomingConfig.folders = incomingConfig.folders || {}
|
||||||
incomingConfig.folders.collectionOverrides = incomingConfig.folders.collectionOverrides || []
|
incomingConfig.folders.collectionOverrides = incomingConfig.folders.collectionOverrides || []
|
||||||
incomingConfig.folders.collectionOverrides.push(({ collection }) => {
|
incomingConfig.folders.collectionOverrides.push(({ collection }) => {
|
||||||
/**
|
/**
|
||||||
* Add tenant field to enabled collections
|
* Add filter options to all relationship fields
|
||||||
*/
|
*/
|
||||||
const folderTenantField = tenantField({
|
addFilterOptionsToFields({
|
||||||
...(pluginConfig?.tenantField || {}),
|
blockReferencesWithFilters,
|
||||||
name: tenantFieldName,
|
config: incomingConfig,
|
||||||
debug: pluginConfig.debug,
|
fields: collection.fields,
|
||||||
overrides,
|
tenantEnabledCollectionSlugs: collectionSlugs,
|
||||||
|
tenantEnabledGlobalSlugs: globalCollectionSlugs,
|
||||||
|
tenantFieldName,
|
||||||
tenantsArrayFieldName,
|
tenantsArrayFieldName,
|
||||||
tenantsArrayTenantFieldName,
|
tenantsArrayTenantFieldName,
|
||||||
tenantsCollectionSlug,
|
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
|
* Add list filter to enabled collections
|
||||||
* - filters results by selected tenant
|
* - filters results by selected tenant
|
||||||
@@ -314,9 +334,10 @@ export const multiTenantPlugin =
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify enabled collections
|
* Add filter options to all relationship fields
|
||||||
*/
|
*/
|
||||||
addFilterOptionsToFields({
|
addFilterOptionsToFields({
|
||||||
|
blockReferencesWithFilters,
|
||||||
config: incomingConfig,
|
config: incomingConfig,
|
||||||
fields: collection.fields,
|
fields: collection.fields,
|
||||||
tenantEnabledCollectionSlugs: collectionSlugs,
|
tenantEnabledCollectionSlugs: collectionSlugs,
|
||||||
@@ -334,9 +355,7 @@ export const multiTenantPlugin =
|
|||||||
/**
|
/**
|
||||||
* Add tenant field to enabled collections
|
* Add tenant field to enabled collections
|
||||||
*/
|
*/
|
||||||
collection.fields.splice(
|
collection.fields.unshift(
|
||||||
0,
|
|
||||||
0,
|
|
||||||
tenantField({
|
tenantField({
|
||||||
name: tenantFieldName,
|
name: tenantFieldName,
|
||||||
debug: pluginConfig.debug,
|
debug: pluginConfig.debug,
|
||||||
@@ -349,19 +368,14 @@ export const multiTenantPlugin =
|
|||||||
)
|
)
|
||||||
|
|
||||||
const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}
|
const { useBaseFilter, useBaseListFilter } = pluginConfig.collections[collection.slug] || {}
|
||||||
|
|
||||||
if (useBaseFilter ?? useBaseListFilter ?? true) {
|
if (useBaseFilter ?? useBaseListFilter ?? true) {
|
||||||
/**
|
/**
|
||||||
* Add list filter to enabled collections
|
* Add list filter to enabled collections
|
||||||
* - filters results by selected tenant
|
* - filters results by selected tenant
|
||||||
*/
|
*/
|
||||||
if (!collection.admin) {
|
collection.admin = collection.admin || {}
|
||||||
collection.admin = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseFilter = collection.admin?.baseFilter ?? collection.admin?.baseListFilter
|
|
||||||
collection.admin.baseFilter = combineFilters({
|
collection.admin.baseFilter = combineFilters({
|
||||||
baseFilter,
|
baseFilter: collection.admin?.baseFilter ?? collection.admin?.baseListFilter,
|
||||||
customFilter: (args) =>
|
customFilter: (args) =>
|
||||||
filterDocumentsByTenants({
|
filterDocumentsByTenants({
|
||||||
filterFieldName: tenantFieldName,
|
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 { defaults } from '../defaults.js'
|
||||||
import { filterDocumentsByTenants } from '../filters/filterDocumentsByTenants.js'
|
import { filterDocumentsByTenants } from '../filters/filterDocumentsByTenants.js'
|
||||||
|
|
||||||
type AddFilterOptionsToFieldsArgs = {
|
type AddFilterOptionsToFieldsArgs = {
|
||||||
|
blockReferencesWithFilters: string[]
|
||||||
config: Config | SanitizedConfig
|
config: Config | SanitizedConfig
|
||||||
fields: Field[]
|
fields: Field[]
|
||||||
tenantEnabledCollectionSlugs: string[]
|
tenantEnabledCollectionSlugs: string[]
|
||||||
@@ -15,6 +16,7 @@ type AddFilterOptionsToFieldsArgs = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function addFilterOptionsToFields({
|
export function addFilterOptionsToFields({
|
||||||
|
blockReferencesWithFilters,
|
||||||
config,
|
config,
|
||||||
fields,
|
fields,
|
||||||
tenantEnabledCollectionSlugs,
|
tenantEnabledCollectionSlugs,
|
||||||
@@ -74,6 +76,7 @@ export function addFilterOptionsToFields({
|
|||||||
field.type === 'group'
|
field.type === 'group'
|
||||||
) {
|
) {
|
||||||
addFilterOptionsToFields({
|
addFilterOptionsToFields({
|
||||||
|
blockReferencesWithFilters,
|
||||||
config,
|
config,
|
||||||
fields: field.fields,
|
fields: field.fields,
|
||||||
tenantEnabledCollectionSlugs,
|
tenantEnabledCollectionSlugs,
|
||||||
@@ -87,14 +90,21 @@ export function addFilterOptionsToFields({
|
|||||||
|
|
||||||
if (field.type === 'blocks') {
|
if (field.type === 'blocks') {
|
||||||
;(field.blockReferences ?? field.blocks).forEach((_block) => {
|
;(field.blockReferences ?? field.blocks).forEach((_block) => {
|
||||||
const block =
|
let block: Block | undefined
|
||||||
typeof _block === 'string'
|
|
||||||
? // TODO: iterate over blocks mapped to block slug in v4, or pass through payload.blocks
|
if (typeof _block === 'string') {
|
||||||
config?.blocks?.find((b) => b.slug === _block)
|
if (blockReferencesWithFilters.includes(_block)) {
|
||||||
: _block
|
return
|
||||||
|
}
|
||||||
|
block = config?.blocks?.find((b) => b.slug === _block)
|
||||||
|
blockReferencesWithFilters.push(_block)
|
||||||
|
} else {
|
||||||
|
block = _block
|
||||||
|
}
|
||||||
|
|
||||||
if (block?.fields) {
|
if (block?.fields) {
|
||||||
addFilterOptionsToFields({
|
addFilterOptionsToFields({
|
||||||
|
blockReferencesWithFilters,
|
||||||
config,
|
config,
|
||||||
fields: block.fields,
|
fields: block.fields,
|
||||||
tenantEnabledCollectionSlugs,
|
tenantEnabledCollectionSlugs,
|
||||||
@@ -111,6 +121,7 @@ export function addFilterOptionsToFields({
|
|||||||
if (field.type === 'tabs') {
|
if (field.type === 'tabs') {
|
||||||
field.tabs.forEach((tab) => {
|
field.tabs.forEach((tab) => {
|
||||||
addFilterOptionsToFields({
|
addFilterOptionsToFields({
|
||||||
|
blockReferencesWithFilters,
|
||||||
config,
|
config,
|
||||||
fields: tab.fields,
|
fields: tab.fields,
|
||||||
tenantEnabledCollectionSlugs,
|
tenantEnabledCollectionSlugs,
|
||||||
|
|||||||
Reference in New Issue
Block a user