fix(plugin-search): issues with overriding the search collection slug consistently across hooks (#8847)
Fixes https://github.com/payloadcms/payload/issues/8842
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import type { CollectionAfterDeleteHook } from 'payload'
|
||||
import type { DeleteFromSearch } from '../../types.js'
|
||||
|
||||
export const deleteFromSearch: CollectionAfterDeleteHook = async ({
|
||||
export const deleteFromSearch: DeleteFromSearch = async ({
|
||||
doc,
|
||||
pluginConfig,
|
||||
req: { payload },
|
||||
req,
|
||||
}) => {
|
||||
const searchSlug = pluginConfig?.searchOverrides?.slug || 'search'
|
||||
try {
|
||||
const searchDocQuery = await payload.find({
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
depth: 0,
|
||||
req,
|
||||
where: {
|
||||
@@ -20,14 +22,14 @@ export const deleteFromSearch: CollectionAfterDeleteHook = async ({
|
||||
if (searchDocQuery?.docs?.[0]) {
|
||||
await payload.delete({
|
||||
id: searchDocQuery?.docs?.[0]?.id,
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
req,
|
||||
})
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error({
|
||||
err,
|
||||
msg: `Error deleting search doc.`,
|
||||
msg: `Error deleting ${searchSlug} doc.`,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
|
||||
const { id, _status: status, title } = doc || {}
|
||||
|
||||
const { beforeSync, defaultPriorities, deleteDrafts, syncDrafts } = pluginConfig
|
||||
const { beforeSync, defaultPriorities, deleteDrafts, searchOverrides, syncDrafts } = pluginConfig
|
||||
|
||||
const searchSlug = searchOverrides?.slug || 'search'
|
||||
|
||||
let dataToSave: DocToSync = {
|
||||
doc: {
|
||||
@@ -50,7 +52,7 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error(err)
|
||||
payload.logger.error(
|
||||
`Error gathering default priority for search documents related to ${collection}`,
|
||||
`Error gathering default priority for ${searchSlug} documents related to ${collection}`,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@@ -64,7 +66,7 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
if (operation === 'create') {
|
||||
if (doSync) {
|
||||
await payload.create({
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
data: {
|
||||
...dataToSave,
|
||||
priority: defaultPriority,
|
||||
@@ -78,7 +80,7 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
try {
|
||||
// find the correct doc to sync with
|
||||
const searchDocQuery = await payload.find({
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
depth: 0,
|
||||
req,
|
||||
where: {
|
||||
@@ -104,12 +106,12 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
try {
|
||||
const duplicativeDocIDs = duplicativeDocs.map(({ id }) => id)
|
||||
await payload.delete({
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
req,
|
||||
where: { id: { in: duplicativeDocIDs } },
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error(`Error deleting duplicative search documents.`)
|
||||
payload.logger.error(`Error deleting duplicative ${searchSlug} documents.`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +123,7 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
try {
|
||||
await payload.update({
|
||||
id: searchDocID,
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
data: {
|
||||
...dataToSave,
|
||||
priority: foundDoc.priority || defaultPriority,
|
||||
@@ -129,7 +131,7 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
req,
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error(`Error updating search document.`)
|
||||
payload.logger.error(`Error updating ${searchSlug} document.`)
|
||||
}
|
||||
}
|
||||
if (deleteDrafts && status === 'draft') {
|
||||
@@ -137,17 +139,17 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
try {
|
||||
await payload.delete({
|
||||
id: searchDocID,
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
req,
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error({ err, msg: `Error deleting search document.` })
|
||||
payload.logger.error({ err, msg: `Error deleting ${searchSlug} document.` })
|
||||
}
|
||||
}
|
||||
} else if (doSync) {
|
||||
try {
|
||||
await payload.create({
|
||||
collection: 'search',
|
||||
collection: searchSlug,
|
||||
data: {
|
||||
...dataToSave,
|
||||
priority: defaultPriority,
|
||||
@@ -155,17 +157,17 @@ export const syncWithSearch: SyncWithSearch = async (args) => {
|
||||
req,
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error({ err, msg: `Error creating search document.` })
|
||||
payload.logger.error({ err, msg: `Error creating ${searchSlug} document.` })
|
||||
}
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error({ err, msg: `Error finding search document.` })
|
||||
payload.logger.error({ err, msg: `Error finding ${searchSlug} document.` })
|
||||
}
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
payload.logger.error({
|
||||
err,
|
||||
msg: `Error syncing search document related to ${collection} with id: '${id}'.`,
|
||||
msg: `Error syncing ${searchSlug} document related to ${collection} with id: '${id}'.`,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@ export const generateSearchCollection = (pluginConfig: SearchPluginConfig): Coll
|
||||
type: 'ui',
|
||||
admin: {
|
||||
components: {
|
||||
Field: '@payloadcms/plugin-search/client#LinkToDoc',
|
||||
Field: {
|
||||
path: '@payloadcms/plugin-search/client#LinkToDoc',
|
||||
},
|
||||
},
|
||||
position: 'sidebar',
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useConfig } from '@payloadcms/ui'
|
||||
import { useConfig, useField } from '@payloadcms/ui'
|
||||
import { formatAdminURL } from '@payloadcms/ui/shared'
|
||||
import React from 'react'
|
||||
// TODO: fix this import to work in dev mode within the monorepo in a way that is backwards compatible with 1.x
|
||||
@@ -16,13 +16,19 @@ export const LinkToDocClient: React.FC = () => {
|
||||
serverURL,
|
||||
} = config
|
||||
|
||||
const { value } = useField<{ relationTo?: string; value?: string }>({ path: 'doc' })
|
||||
|
||||
const href = `${serverURL}${formatAdminURL({
|
||||
adminRoute,
|
||||
path: '/collections/${relationTo}/${docId}',
|
||||
path: `/collections/${value.relationTo || ''}/${value.value || ''}`,
|
||||
})}`
|
||||
|
||||
if (!value.relationTo || !value.value) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 'var(--spacing-field, 1rem)' }}>
|
||||
<div>
|
||||
<span
|
||||
className="label"
|
||||
@@ -41,7 +47,9 @@ export const LinkToDocClient: React.FC = () => {
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
<a href={href}>{href}</a>
|
||||
<a href={href} target="_blank">
|
||||
{href}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -5,9 +5,5 @@ import React from 'react'
|
||||
import { LinkToDocClient } from './index.client.js'
|
||||
|
||||
export const LinkToDoc: React.FC<UIField> = () => {
|
||||
return (
|
||||
<div>
|
||||
<LinkToDocClient />
|
||||
</div>
|
||||
)
|
||||
return <LinkToDocClient />
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Config } from 'payload'
|
||||
import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, Config } from 'payload'
|
||||
|
||||
import type { SearchPluginConfig } from './types.js'
|
||||
|
||||
@@ -6,6 +6,9 @@ import { deleteFromSearch } from './Search/hooks/deleteFromSearch.js'
|
||||
import { syncWithSearch } from './Search/hooks/syncWithSearch.js'
|
||||
import { generateSearchCollection } from './Search/index.js'
|
||||
|
||||
type CollectionAfterChangeHookArgs = Parameters<CollectionAfterChangeHook>[0]
|
||||
type CollectionAfterDeleteHookArgs = Parameters<CollectionAfterDeleteHook>[0]
|
||||
|
||||
export const searchPlugin =
|
||||
(incomingPluginConfig: SearchPluginConfig) =>
|
||||
(config: Config): Config => {
|
||||
@@ -33,7 +36,7 @@ export const searchPlugin =
|
||||
...collection.hooks,
|
||||
afterChange: [
|
||||
...(existingHooks?.afterChange || []),
|
||||
async (args: any) => {
|
||||
async (args: CollectionAfterChangeHookArgs) => {
|
||||
await syncWithSearch({
|
||||
...args,
|
||||
collection: collection.slug,
|
||||
@@ -41,7 +44,15 @@ export const searchPlugin =
|
||||
})
|
||||
},
|
||||
],
|
||||
afterDelete: [...(existingHooks?.afterDelete || []), deleteFromSearch],
|
||||
afterDelete: [
|
||||
...(existingHooks?.afterDelete || []),
|
||||
async (args: CollectionAfterDeleteHookArgs) => {
|
||||
await deleteFromSearch({
|
||||
...args,
|
||||
pluginConfig,
|
||||
})
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
CollectionAfterChangeHook,
|
||||
CollectionAfterDeleteHook,
|
||||
CollectionConfig,
|
||||
Field,
|
||||
Payload,
|
||||
@@ -45,3 +46,9 @@ export type SyncWithSearch = (
|
||||
pluginConfig: SearchPluginConfig
|
||||
} & Omit<Parameters<CollectionAfterChangeHook>[0], 'collection'>,
|
||||
) => ReturnType<CollectionAfterChangeHook>
|
||||
|
||||
export type DeleteFromSearch = (
|
||||
Args: {
|
||||
pluginConfig: SearchPluginConfig
|
||||
} & Omit<Parameters<CollectionAfterDeleteHook>[0], 'collection'>,
|
||||
) => ReturnType<CollectionAfterDeleteHook>
|
||||
|
||||
Reference in New Issue
Block a user