Files
payloadcms/packages/payload/src/queues/localAPI.ts
Jacob Fletcher 1502e09581 fix(ui): automatically subscribes custom fields to conditional logic (#9928)
Currently, custom components do not respect `admin.condition` unless
manually wrapped with the `withCondition` HOC, like all default fields
currently do. This should not be a requirement of component authors.
Instead, we can automatically detect custom client and server fields and
wrap them with the underlying `WatchCondition` component which will
subscribe to the `passesCondition` property within client-side form
state.

For my future self: there are potentially multiple instances where
fields subscribe to conditions duplicately, such as when rendering a
default Payload field within a custom field component. This was always a
problem and it is non-breaking, but needs to be reevaluated and removed
in the future for performance. Only the default fields that Payload
renders client-side need to subscribe to field conditions in this way.
When importing a Payload field into your custom field component, for
example, it should not include the HOC, because custom components now
watch conditions themselves.
2024-12-13 14:12:37 -05:00

104 lines
3.2 KiB
TypeScript

import type { BaseJob, RunningJobFromTask } from './config/types/workflowTypes.js'
import {
createLocalReq,
type Payload,
type PayloadRequest,
type RunningJob,
type TypedJobs,
type Where,
} from '../index.js'
import { runJobs } from './operations/runJobs/index.js'
export const getJobsLocalAPI = (payload: Payload) => ({
queue: async <
// eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents
TTaskOrWorkflowSlug extends keyof TypedJobs['tasks'] | keyof TypedJobs['workflows'],
>(
args:
| {
input: TypedJobs['tasks'][TTaskOrWorkflowSlug]['input']
queue?: string
req?: PayloadRequest
// TTaskOrWorkflowlug with keyof TypedJobs['workflows'] removed:
task: TTaskOrWorkflowSlug extends keyof TypedJobs['tasks'] ? TTaskOrWorkflowSlug : never
waitUntil?: Date
workflow?: never
}
| {
input: TypedJobs['workflows'][TTaskOrWorkflowSlug]['input']
queue?: string
req?: PayloadRequest
task?: never
waitUntil?: Date
workflow: TTaskOrWorkflowSlug extends keyof TypedJobs['workflows']
? TTaskOrWorkflowSlug
: never
},
): Promise<
TTaskOrWorkflowSlug extends keyof TypedJobs['workflows']
? RunningJob<TTaskOrWorkflowSlug>
: RunningJobFromTask<TTaskOrWorkflowSlug>
> => {
let queue: string
// If user specifies queue, use that
if (args.queue) {
queue = args.queue
} else if (args.workflow) {
// Otherwise, if there is a workflow specified, and it has a default queue to use,
// use that
const workflow = payload.config.jobs?.workflows?.find(({ slug }) => slug === args.workflow)
if (workflow?.queue) {
queue = workflow.queue
}
}
return (await payload.create({
collection: 'payload-jobs',
data: {
input: args.input,
queue,
taskSlug: 'task' in args ? args.task : undefined,
waitUntil: args.waitUntil?.toISOString() ?? undefined,
workflowSlug: 'workflow' in args ? args.workflow : undefined,
} as BaseJob,
req: args.req,
})) as TTaskOrWorkflowSlug extends keyof TypedJobs['workflows']
? RunningJob<TTaskOrWorkflowSlug>
: RunningJobFromTask<TTaskOrWorkflowSlug> // Type assertion is still needed here
},
run: async (args?: {
limit?: number
overrideAccess?: boolean
queue?: string
req?: PayloadRequest
where?: Where
}): Promise<ReturnType<typeof runJobs>> => {
const newReq: PayloadRequest = args?.req ?? (await createLocalReq({}, payload))
const result = await runJobs({
limit: args?.limit,
overrideAccess: args?.overrideAccess !== false,
queue: args?.queue,
req: newReq,
where: args?.where,
})
return result
},
runByID: async (args: {
id: number | string
overrideAccess?: boolean
req?: PayloadRequest
}): Promise<ReturnType<typeof runJobs>> => {
const newReq: PayloadRequest = args?.req ?? (await createLocalReq({}, payload))
const result = await runJobs({
id: args.id,
overrideAccess: args?.overrideAccess !== false,
req: newReq,
})
return result
},
})