feat(plugin-search)!: make search collection fields override into a function that provides defaultFields inline with other plugins (#7095)

searchPlugin's searchOverrides for the collection now takes in a fields
function instead of array similar to other plugins and patterns we use
to allow you to map over existing fields as well if needed.

```ts
// before
searchPlugin({
  searchOverrides: {
    slug: 'search-results',
    fields: [
      {
        name: 'excerpt',
        type: 'textarea',
        admin: {
          position: 'sidebar',
        },
      },
    ]
  },
}),

// current
searchPlugin({
  searchOverrides: {
    slug: 'search-results',
    fields: ({ defaultFields }) => [
      ...defaultFields,
      {
        name: 'excerpt',
        type: 'textarea',
        admin: {
          position: 'sidebar',
        },
      },
    ]
  },
}),
```
This commit is contained in:
Paul
2024-07-10 11:22:12 -04:00
committed by GitHub
parent 8ea87afd24
commit 2bc8666bff
4 changed files with 97 additions and 65 deletions

View File

@@ -104,6 +104,8 @@ The `defaultPriorities` property is used to set a fallback `priority` on search
This plugin automatically creates the `search` collection, but you can override anything on this collection via the `searchOverrides` property. It accepts anything from the [Payload Collection Config](https://payloadcms.com/docs/configuration/collections) and merges it in with the default `search` collection config provided by the plugin.
Note that the `fields` property is a function that receives an object with a `defaultFields` key. This is an array of fields that are automatically added to the `search` collection. You can modify this array or add new fields to it.
```ts
// payload.config.ts
{
@@ -111,6 +113,16 @@ This plugin automatically creates the `search` collection, but you can override
searchPlugin({
searchOverrides: {
slug: 'search-results',
fields: ({ defaultFields }) => [
...defaultFields,
{
name: 'excerpt',
type: 'textarea',
admin: {
position: 'sidebar',
},
},
],
},
}),
}

View File

@@ -1,4 +1,4 @@
import type { CollectionConfig } from 'payload'
import type { CollectionConfig, Field } from 'payload'
import deepMerge from 'deepmerge'
@@ -7,63 +7,75 @@ import type { SearchPluginConfig } from '../types.js'
import { LinkToDoc } from './ui/index.js'
// all settings can be overridden by the config
export const generateSearchCollection = (pluginConfig: SearchPluginConfig): CollectionConfig =>
deepMerge(
export const generateSearchCollection = (pluginConfig: SearchPluginConfig): CollectionConfig => {
const defaultFields: Field[] = [
{
slug: 'search',
access: {
create: (): boolean => false,
read: (): boolean => true,
},
name: 'title',
type: 'text',
admin: {
defaultColumns: ['title'],
description:
'This is a collection of automatically created search results. These results are used by the global site search and will be updated automatically as documents in the CMS are created or updated.',
enableRichTextRelationship: false,
useAsTitle: 'title',
},
fields: [
{
name: 'title',
type: 'text',
admin: {
readOnly: true,
},
},
{
name: 'priority',
type: 'number',
admin: {
position: 'sidebar',
},
},
{
name: 'doc',
type: 'relationship',
admin: {
position: 'sidebar',
readOnly: true,
},
index: true,
maxDepth: 0,
relationTo: pluginConfig?.collections || [],
required: true,
},
{
name: 'docUrl',
type: 'ui',
admin: {
components: {
Field: LinkToDoc,
},
position: 'sidebar',
},
},
],
labels: {
plural: 'Search Results',
singular: 'Search Result',
readOnly: true,
},
},
pluginConfig?.searchOverrides || {},
)
{
name: 'priority',
type: 'number',
admin: {
position: 'sidebar',
},
},
{
name: 'doc',
type: 'relationship',
admin: {
position: 'sidebar',
readOnly: true,
},
index: true,
maxDepth: 0,
relationTo: pluginConfig?.collections || [],
required: true,
},
{
name: 'docUrl',
type: 'ui',
admin: {
components: {
Field: LinkToDoc,
},
position: 'sidebar',
},
},
]
const newConfig: CollectionConfig = {
...(pluginConfig?.searchOverrides || {}),
slug: pluginConfig?.searchOverrides?.slug || 'search',
access: {
create: (): boolean => false,
read: (): boolean => true,
...(pluginConfig?.searchOverrides?.access || {}),
},
admin: {
defaultColumns: ['title'],
description:
'This is a collection of automatically created search results. These results are used by the global site search and will be updated automatically as documents in the CMS are created or updated.',
enableRichTextRelationship: false,
useAsTitle: 'title',
...(pluginConfig?.searchOverrides?.admin || {}),
},
fields:
pluginConfig?.searchOverrides?.fields &&
typeof pluginConfig?.searchOverrides?.fields === 'function'
? pluginConfig?.searchOverrides.fields({ defaultFields })
: defaultFields,
hooks: {
...(pluginConfig?.searchOverrides?.hooks || {}),
},
labels: {
plural: 'Search Results',
singular: 'Search Result',
},
}
return newConfig
}

View File

@@ -1,4 +1,10 @@
import type { CollectionAfterChangeHook, CollectionConfig, Payload, PayloadRequest } from 'payload'
import type {
CollectionAfterChangeHook,
CollectionConfig,
Field,
Payload,
PayloadRequest,
} from 'payload'
export type DocToSync = {
[key: string]: any
@@ -18,6 +24,8 @@ export type BeforeSync = (args: {
searchDoc: DocToSync
}) => DocToSync | Promise<DocToSync>
export type FieldsOverride = (args: { defaultFields: Field[] }) => Field[]
export type SearchPluginConfig = {
beforeSync?: BeforeSync
collections?: string[]
@@ -25,15 +33,15 @@ export type SearchPluginConfig = {
[collection: string]: ((doc: any) => Promise<number> | number) | number
}
deleteDrafts?: boolean
searchOverrides?: Partial<CollectionConfig>
searchOverrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>
syncDrafts?: boolean
}
// Extend the `CollectionAfterChangeHook` with more function args
// Convert the `collection` arg from `SanitizedCollectionConfig` to a string
export type SyncWithSearch = (
Args: Omit<Parameters<CollectionAfterChangeHook>[0], 'collection'> & {
Args: {
collection: string
pluginConfig: SearchPluginConfig
},
} & Omit<Parameters<CollectionAfterChangeHook>[0], 'collection'>,
) => ReturnType<CollectionAfterChangeHook>

View File

@@ -41,14 +41,14 @@ export default buildConfigWithDefaults({
posts: ({ title }) => (title === 'Hello, world!' ? 30 : 20),
},
searchOverrides: {
fields: [
fields: ({ defaultFields }) => [
...defaultFields,
{
name: 'excerpt',
type: 'text',
type: 'textarea',
admin: {
readOnly: true,
position: 'sidebar',
},
label: 'Excerpt',
},
],
},