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:
Paul
2024-10-24 18:29:39 -06:00
committed by GitHub
parent e72e81c3da
commit 2df8f94a75
7 changed files with 60 additions and 32 deletions

View File

@@ -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.`,
})
}

View File

@@ -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}'.`,
})
}

View File

@@ -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',
},

View File

@@ -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>
)

View File

@@ -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 />
}

View File

@@ -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,
})
},
],
},
}
}

View File

@@ -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>