feat: threads operation through field condition function (#12132)
This PR updates the field `condition` function property to include a new `operation` argument. The `operation` arg provides a string relating to which operation the field type is currently executing within. #### Changes: - Added `operation: Operation` in the Condition type. - Updated relevant condition checks to ensure correct parameter usage.
This commit is contained in:
@@ -541,6 +541,7 @@ The `ctx` object:
|
|||||||
| Property | Description |
|
| Property | Description |
|
||||||
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| **`blockData`** | The nearest parent block's data. If the field is not inside a block, this will be `undefined`. |
|
| **`blockData`** | The nearest parent block's data. If the field is not inside a block, this will be `undefined`. |
|
||||||
|
| **`operation`** | A string relating to which operation the field type is currently executing within. |
|
||||||
| **`path`** | The full path to the field in the schema, represented as an array of string segments, including array indexes. I.e `['group', 'myArray', '1', 'textField']`. |
|
| **`path`** | The full path to the field in the schema, represented as an array of string segments, including array indexes. I.e `['group', 'myArray', '1', 'textField']`. |
|
||||||
| **`user`** | The currently authenticated user object. |
|
| **`user`** | The currently authenticated user object. |
|
||||||
|
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ export type Condition<TData extends TypeWithID = any, TSiblingData = any> = (
|
|||||||
siblingData: Partial<TSiblingData>,
|
siblingData: Partial<TSiblingData>,
|
||||||
{
|
{
|
||||||
blockData,
|
blockData,
|
||||||
|
operation,
|
||||||
path,
|
path,
|
||||||
user,
|
user,
|
||||||
}: {
|
}: {
|
||||||
@@ -276,6 +277,10 @@ export type Condition<TData extends TypeWithID = any, TSiblingData = any> = (
|
|||||||
* The data of the nearest parent block. If the field is not within a block, `blockData` will be equal to `undefined`.
|
* The data of the nearest parent block. If the field is not within a block, `blockData` will be equal to `undefined`.
|
||||||
*/
|
*/
|
||||||
blockData: Partial<TData>
|
blockData: Partial<TData>
|
||||||
|
/**
|
||||||
|
* A string relating to which operation the field type is currently executing within.
|
||||||
|
*/
|
||||||
|
operation: Operation
|
||||||
/**
|
/**
|
||||||
* The path of the field, e.g. ["group", "myArray", 1, "textField"]. The path is the schemaPath but with indexes and would be used in the context of field data, not field schemas.
|
* The path of the field, e.g. ["group", "myArray", 1, "textField"]. The path is the schemaPath but with indexes and would be used in the context of field data, not field schemas.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -109,7 +109,12 @@ export const promise = async ({
|
|||||||
|
|
||||||
const passesCondition = field.admin?.condition
|
const passesCondition = field.admin?.condition
|
||||||
? Boolean(
|
? Boolean(
|
||||||
field.admin.condition(data, siblingData, { blockData, path: pathSegments, user: req.user }),
|
field.admin.condition(data, siblingData, {
|
||||||
|
blockData,
|
||||||
|
operation,
|
||||||
|
path: pathSegments,
|
||||||
|
user: req.user,
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
: true
|
: true
|
||||||
let skipValidationFromHere = skipValidation || !passesCondition
|
let skipValidationFromHere = skipValidation || !passesCondition
|
||||||
|
|||||||
@@ -827,6 +827,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
|
|||||||
if (passesCondition && typeof tab.admin?.condition === 'function') {
|
if (passesCondition && typeof tab.admin?.condition === 'function') {
|
||||||
tabPassesCondition = tab.admin.condition(fullData, data, {
|
tabPassesCondition = tab.admin.condition(fullData, data, {
|
||||||
blockData,
|
blockData,
|
||||||
|
operation,
|
||||||
path: pathSegments,
|
path: pathSegments,
|
||||||
user: req.user,
|
user: req.user,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ export const iterateFields = async ({
|
|||||||
? Boolean(
|
? Boolean(
|
||||||
field.admin.condition(fullData || {}, data || {}, {
|
field.admin.condition(fullData || {}, data || {}, {
|
||||||
blockData,
|
blockData,
|
||||||
|
operation,
|
||||||
path: pathSegments,
|
path: pathSegments,
|
||||||
user: req.user,
|
user: req.user,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type { Config } from '../../payload-types.js'
|
|||||||
import {
|
import {
|
||||||
ensureCompilationIsDone,
|
ensureCompilationIsDone,
|
||||||
initPageConsoleErrorCatch,
|
initPageConsoleErrorCatch,
|
||||||
|
saveDocAndAssert,
|
||||||
// throttleTest,
|
// throttleTest,
|
||||||
} from '../../../helpers.js'
|
} from '../../../helpers.js'
|
||||||
import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
||||||
@@ -225,4 +226,19 @@ describe('Conditional Logic', () => {
|
|||||||
|
|
||||||
await expect(numberField).toBeVisible()
|
await expect(numberField).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should render field based on operation argument', async () => {
|
||||||
|
await page.goto(url.create)
|
||||||
|
|
||||||
|
const textField = page.locator('#field-text')
|
||||||
|
const fieldWithOperationCondition = page.locator('#field-fieldWithOperationCondition')
|
||||||
|
|
||||||
|
await textField.fill('some text')
|
||||||
|
|
||||||
|
await expect(fieldWithOperationCondition).toBeVisible()
|
||||||
|
|
||||||
|
await saveDocAndAssert(page)
|
||||||
|
|
||||||
|
await expect(fieldWithOperationCondition).toBeHidden()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -24,6 +24,19 @@ const ConditionalLogic: CollectionConfig = {
|
|||||||
condition: ({ toggleField }) => Boolean(toggleField),
|
condition: ({ toggleField }) => Boolean(toggleField),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'fieldWithOperationCondition',
|
||||||
|
type: 'text',
|
||||||
|
admin: {
|
||||||
|
condition: (data, siblingData, { operation }) => {
|
||||||
|
if (operation === 'create') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'customFieldWithField',
|
name: 'customFieldWithField',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
@@ -217,7 +230,7 @@ const ConditionalLogic: CollectionConfig = {
|
|||||||
name: 'numberField',
|
name: 'numberField',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
admin: {
|
admin: {
|
||||||
condition: (data, siblingData, { path, user }) => {
|
condition: (data, siblingData, { path }) => {
|
||||||
// Ensure path has enough depth
|
// Ensure path has enough depth
|
||||||
if (path.length < 5) {
|
if (path.length < 5) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -790,6 +790,7 @@ export interface ConditionalLogic {
|
|||||||
text: string;
|
text: string;
|
||||||
toggleField?: boolean | null;
|
toggleField?: boolean | null;
|
||||||
fieldWithCondition?: string | null;
|
fieldWithCondition?: string | null;
|
||||||
|
fieldWithOperationCondition?: string | null;
|
||||||
customFieldWithField?: string | null;
|
customFieldWithField?: string | null;
|
||||||
customFieldWithHOC?: string | null;
|
customFieldWithHOC?: string | null;
|
||||||
customClientFieldWithCondition?: string | null;
|
customClientFieldWithCondition?: string | null;
|
||||||
@@ -2364,6 +2365,7 @@ export interface ConditionalLogicSelect<T extends boolean = true> {
|
|||||||
text?: T;
|
text?: T;
|
||||||
toggleField?: T;
|
toggleField?: T;
|
||||||
fieldWithCondition?: T;
|
fieldWithCondition?: T;
|
||||||
|
fieldWithOperationCondition?: T;
|
||||||
customFieldWithField?: T;
|
customFieldWithField?: T;
|
||||||
customFieldWithHOC?: T;
|
customFieldWithHOC?: T;
|
||||||
customClientFieldWithCondition?: T;
|
customClientFieldWithCondition?: T;
|
||||||
|
|||||||
Reference in New Issue
Block a user