diff --git a/packages/ui/src/utilities/buildFormState.ts b/packages/ui/src/utilities/buildFormState.ts index 149a50a2ea..0b4a341280 100644 --- a/packages/ui/src/utilities/buildFormState.ts +++ b/packages/ui/src/utilities/buildFormState.ts @@ -204,6 +204,12 @@ export const buildFormState = async ( ? fieldOrEntityConfig.fields : [fieldOrEntityConfig] + // Ensure data.id is present during form state requests, where the data + // is passed from the client as an argument, without the ID + if (!data.id && id) { + data.id = id + } + const formStateResult = await fieldSchemasToFormState({ id, clientFieldSchemaMap: clientSchemaMap, diff --git a/test/fields/collections/ConditionalLogic/e2e.spec.ts b/test/fields/collections/ConditionalLogic/e2e.spec.ts index b2d94a9690..d2added145 100644 --- a/test/fields/collections/ConditionalLogic/e2e.spec.ts +++ b/test/fields/collections/ConditionalLogic/e2e.spec.ts @@ -15,6 +15,7 @@ import { // throttleTest, } from '../../../helpers.js' import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js' +import { assertNetworkRequests } from '../../../helpers/e2e/assertNetworkRequests.js' import { initPayloadE2ENoConfig } from '../../../helpers/initPayloadE2ENoConfig.js' import { reInitializeDB } from '../../../helpers/reInitializeDB.js' import { RESTClient } from '../../../helpers/rest.js' @@ -99,6 +100,53 @@ describe('Conditional Logic', () => { expect(true).toBe(true) }) + test('ensure conditions receive document ID during form state request', async () => { + await page.goto(url.create) + + const fieldOnlyVisibleIfNoID = page.locator('#field-fieldWithDocIDCondition') + + await expect(fieldOnlyVisibleIfNoID).toBeVisible() + + const textField = page.locator('#field-text') + await assertNetworkRequests( + page, + '/admin/collections/conditional-logic', + async () => { + await textField.fill('some text') + }, + { + minimumNumberOfRequests: 1, + }, + ) + + await assertNetworkRequests( + page, + '/api/conditional-logic', + async () => { + await saveDocAndAssert(page) + }, + { + minimumNumberOfRequests: 1, + }, + ) + + await expect(fieldOnlyVisibleIfNoID).toBeHidden() + + // Fill text and wait for form state request to come back + await assertNetworkRequests( + page, + '/admin/collections/conditional-logic', + async () => { + await textField.fill('updated text') + }, + { + minimumNumberOfRequests: 1, + }, + ) + + await expect(fieldOnlyVisibleIfNoID).toBeHidden() + }) + test('should conditionally render custom field that renders a Payload field', async () => { await page.goto(url.create) diff --git a/test/fields/collections/ConditionalLogic/index.ts b/test/fields/collections/ConditionalLogic/index.ts index 96af0df38c..d33aa547b4 100644 --- a/test/fields/collections/ConditionalLogic/index.ts +++ b/test/fields/collections/ConditionalLogic/index.ts @@ -17,6 +17,13 @@ const ConditionalLogic: CollectionConfig = { name: 'toggleField', type: 'checkbox', }, + { + name: 'fieldWithDocIDCondition', + type: 'text', + admin: { + condition: ({ id }) => !id, + }, + }, { name: 'fieldWithCondition', type: 'text', diff --git a/test/fields/payload-types.ts b/test/fields/payload-types.ts index ea9f013b6e..9a2b3ff50e 100644 --- a/test/fields/payload-types.ts +++ b/test/fields/payload-types.ts @@ -149,7 +149,7 @@ export interface Config { 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; }; db: { - defaultIDType: string; + defaultIDType: number; }; globals: {}; globalsSelect: {}; @@ -215,7 +215,7 @@ export interface LocalizedTextReference2 { * via the `definition` "users". */ export interface User { - id: string; + id: number; canViewConditionalField?: boolean | null; updatedAt: string; createdAt: string; @@ -240,7 +240,7 @@ export interface User { * via the `definition` "select-versions-fields". */ export interface SelectVersionsField { - id: string; + id: number; hasMany?: ('a' | 'b' | 'c' | 'd')[] | null; array?: | { @@ -265,7 +265,7 @@ export interface SelectVersionsField { * via the `definition` "array-fields". */ export interface ArrayField { - id: string; + id: number; title?: string | null; items: { text: string; @@ -369,7 +369,7 @@ export interface ArrayField { * via the `definition` "block-fields". */ export interface BlockField { - id: string; + id: number; blocks: (ContentBlock | NoBlockname | NumberBlock | SubBlocksBlock | TabsBlock)[]; duplicate: (ContentBlock | NoBlockname | NumberBlock | SubBlocksBlock | TabsBlock)[]; collapsedByDefaultBlocks: ( @@ -500,7 +500,7 @@ export interface BlockField { | null; relationshipBlocks?: | { - relationship?: (string | null) | TextField; + relationship?: (number | null) | TextField; id?: string | null; blockName?: string | null; blockType: 'relationships'; @@ -697,7 +697,7 @@ export interface LocalizedTabsBlock { * via the `definition` "text-fields". */ export interface TextField { - id: string; + id: number; text: string; hiddenTextField?: string | null; /** @@ -749,7 +749,7 @@ export interface TextField { * via the `definition` "checkbox-fields". */ export interface CheckboxField { - id: string; + id: number; checkbox: boolean; checkboxNotRequired?: boolean | null; updatedAt: string; @@ -760,7 +760,7 @@ export interface CheckboxField { * via the `definition` "code-fields". */ export interface CodeField { - id: string; + id: number; javascript?: string | null; typescript?: string | null; json?: string | null; @@ -775,7 +775,7 @@ export interface CodeField { * via the `definition` "collapsible-fields". */ export interface CollapsibleField { - id: string; + id: number; text: string; group: { textWithinGroup?: string | null; @@ -808,9 +808,10 @@ export interface CollapsibleField { * via the `definition` "conditional-logic". */ export interface ConditionalLogic { - id: string; + id: number; text: string; toggleField?: boolean | null; + fieldWithDocIDCondition?: string | null; fieldWithCondition?: string | null; fieldWithOperationCondition?: string | null; customFieldWithField?: string | null; @@ -921,7 +922,7 @@ export interface CustomRowId { * via the `definition` "date-fields". */ export interface DateField { - id: string; + id: number; default: string; timeOnly?: string | null; timeOnlyWithMiliseconds?: string | null; @@ -966,7 +967,7 @@ export interface DateField { * via the `definition` "email-fields". */ export interface EmailField { - id: string; + id: number; email: string; localizedEmail?: string | null; emailWithAutocomplete?: string | null; @@ -991,7 +992,7 @@ export interface EmailField { * via the `definition` "radio-fields". */ export interface RadioField { - id: string; + id: number; radio?: ('one' | 'two' | 'three') | null; radioWithJsxLabelOption?: ('one' | 'two' | 'three') | null; updatedAt: string; @@ -1002,7 +1003,7 @@ export interface RadioField { * via the `definition` "group-fields". */ export interface GroupField { - id: string; + id: number; /** * This is a group. */ @@ -1084,22 +1085,22 @@ export interface GroupField { select?: ('one' | 'two')[] | null; }; localizedGroupRel?: { - email?: (string | null) | EmailField; + email?: (number | null) | EmailField; }; localizedGroupManyRel?: { - email?: (string | EmailField)[] | null; + email?: (number | EmailField)[] | null; }; localizedGroupPolyRel?: { email?: { relationTo: 'email-fields'; - value: string | EmailField; + value: number | EmailField; } | null; }; localizedGroupPolyHasManyRel?: { email?: | { relationTo: 'email-fields'; - value: string | EmailField; + value: number | EmailField; }[] | null; }; @@ -1153,30 +1154,30 @@ export interface RowField { * via the `definition` "indexed-fields". */ export interface IndexedField { - id: string; + id: number; text: string; uniqueText?: string | null; - uniqueRelationship?: (string | null) | TextField; - uniqueHasManyRelationship?: (string | TextField)[] | null; - uniqueHasManyRelationship_2?: (string | TextField)[] | null; + uniqueRelationship?: (number | null) | TextField; + uniqueHasManyRelationship?: (number | TextField)[] | null; + uniqueHasManyRelationship_2?: (number | TextField)[] | null; uniquePolymorphicRelationship?: { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | null; uniquePolymorphicRelationship_2?: { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | null; uniqueHasManyPolymorphicRelationship?: | { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; }[] | null; uniqueHasManyPolymorphicRelationship_2?: | { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; }[] | null; uniqueRequiredText: string; @@ -1212,7 +1213,7 @@ export interface IndexedField { * via the `definition` "json-fields". */ export interface JsonField { - id: string; + id: number; json?: { array?: { object?: { @@ -1253,7 +1254,7 @@ export interface JsonField { * via the `definition` "number-fields". */ export interface NumberField { - id: string; + id: number; number?: number | null; min?: number | null; max?: number | null; @@ -1288,7 +1289,7 @@ export interface NumberField { * via the `definition` "point-fields". */ export interface PointField { - id: string; + id: number; /** * @minItems 2 * @maxItems 2 @@ -1319,83 +1320,83 @@ export interface PointField { * via the `definition` "relationship-fields". */ export interface RelationshipField { - id: string; + id: number; text?: string | null; relationship: | { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | { relationTo: 'array-fields'; - value: string | ArrayField; + value: number | ArrayField; }; relationHasManyPolymorphic?: | ( | { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | { relationTo: 'array-fields'; - value: string | ArrayField; + value: number | ArrayField; } )[] | null; - relationToSelf?: (string | null) | RelationshipField; - relationToSelfSelectOnly?: (string | null) | RelationshipField; - relationWithAllowCreateToFalse?: (string | null) | User; - relationWithAllowEditToFalse?: (string | null) | User; - relationWithDynamicDefault?: (string | null) | User; + relationToSelf?: (number | null) | RelationshipField; + relationToSelfSelectOnly?: (number | null) | RelationshipField; + relationWithAllowCreateToFalse?: (number | null) | User; + relationWithAllowEditToFalse?: (number | null) | User; + relationWithDynamicDefault?: (number | null) | User; relationHasManyWithDynamicDefault?: { relationTo: 'users'; - value: string | User; + value: number | User; } | null; - relationshipWithMin?: (string | TextField)[] | null; - relationshipWithMax?: (string | TextField)[] | null; - relationshipHasMany?: (string | TextField)[] | null; + relationshipWithMin?: (number | TextField)[] | null; + relationshipWithMax?: (number | TextField)[] | null; + relationshipHasMany?: (number | TextField)[] | null; array?: | { - relationship?: (string | null) | TextField; + relationship?: (number | null) | TextField; id?: string | null; }[] | null; relationshipWithMinRows?: | { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; }[] | null; relationToRow?: (string | null) | RowField; relationToRowMany?: (string | RowField)[] | null; - relationshipDrawer?: (string | null) | TextField; - relationshipDrawerReadOnly?: (string | null) | TextField; + relationshipDrawer?: (number | null) | TextField; + relationshipDrawerReadOnly?: (number | null) | TextField; polymorphicRelationshipDrawer?: | ({ relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | null) | ({ relationTo: 'array-fields'; - value: string | ArrayField; + value: number | ArrayField; } | null); - relationshipDrawerHasMany?: (string | TextField)[] | null; + relationshipDrawerHasMany?: (number | TextField)[] | null; relationshipDrawerHasManyPolymorphic?: | ( | { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | { relationTo: 'array-fields'; - value: string | ArrayField; + value: number | ArrayField; } )[] | null; - relationshipDrawerWithAllowCreateFalse?: (string | null) | TextField; + relationshipDrawerWithAllowCreateFalse?: (number | null) | TextField; relationshipDrawerWithFilterOptions?: { relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | null; updatedAt: string; createdAt: string; @@ -1405,7 +1406,7 @@ export interface RelationshipField { * via the `definition` "select-fields". */ export interface SelectField { - id: string; + id: number; select?: ('one' | 'two' | 'three') | null; selectReadOnly?: ('one' | 'two' | 'three') | null; selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null; @@ -1435,7 +1436,7 @@ export interface SelectField { * via the `definition` "tabs-fields-2". */ export interface TabsFields2 { - id: string; + id: number; tabsInArray?: | { text?: string | null; @@ -1453,7 +1454,7 @@ export interface TabsFields2 { * via the `definition` "tabs-fields". */ export interface TabsField { - id: string; + id: number; /** * This should not collapse despite there being many tabs pushing the main fields open. */ @@ -1555,9 +1556,9 @@ export interface TabWithName { * via the `definition` "uploads". */ export interface Upload { - id: string; + id: number; text?: string | null; - media?: (string | null) | Upload; + media?: (number | null) | Upload; updatedAt: string; createdAt: string; url?: string | null; @@ -1575,9 +1576,9 @@ export interface Upload { * via the `definition` "uploads2". */ export interface Uploads2 { - id: string; + id: number; text?: string | null; - media?: (string | null) | Uploads2; + media?: (number | null) | Uploads2; updatedAt: string; createdAt: string; url?: string | null; @@ -1595,8 +1596,8 @@ export interface Uploads2 { * via the `definition` "uploads3". */ export interface Uploads3 { - id: string; - media?: (string | null) | Uploads3; + id: number; + media?: (number | null) | Uploads3; updatedAt: string; createdAt: string; url?: string | null; @@ -1614,9 +1615,9 @@ export interface Uploads3 { * via the `definition` "uploads-multi". */ export interface UploadsMulti { - id: string; + id: number; text?: string | null; - media?: (string | Upload)[] | null; + media?: (number | Upload)[] | null; updatedAt: string; createdAt: string; } @@ -1625,16 +1626,16 @@ export interface UploadsMulti { * via the `definition` "uploads-poly". */ export interface UploadsPoly { - id: string; + id: number; text?: string | null; media?: | ({ relationTo: 'uploads'; - value: string | Upload; + value: number | Upload; } | null) | ({ relationTo: 'uploads2'; - value: string | Uploads2; + value: number | Uploads2; } | null); updatedAt: string; createdAt: string; @@ -1644,17 +1645,17 @@ export interface UploadsPoly { * via the `definition` "uploads-multi-poly". */ export interface UploadsMultiPoly { - id: string; + id: number; text?: string | null; media?: | ( | { relationTo: 'uploads'; - value: string | Upload; + value: number | Upload; } | { relationTo: 'uploads2'; - value: string | Uploads2; + value: number | Uploads2; } )[] | null; @@ -1666,11 +1667,11 @@ export interface UploadsMultiPoly { * via the `definition` "uploads-restricted". */ export interface UploadsRestricted { - id: string; + id: number; text?: string | null; - uploadWithoutRestriction?: (string | null) | Upload; - uploadWithAllowCreateFalse?: (string | null) | Upload; - uploadMultipleWithAllowCreateFalse?: (string | Upload)[] | null; + uploadWithoutRestriction?: (number | null) | Upload; + uploadWithAllowCreateFalse?: (number | null) | Upload; + uploadMultipleWithAllowCreateFalse?: (number | Upload)[] | null; updatedAt: string; createdAt: string; } @@ -1679,7 +1680,7 @@ export interface UploadsRestricted { * via the `definition` "ui-fields". */ export interface UiField { - id: string; + id: number; text: string; updatedAt: string; createdAt: string; @@ -1689,39 +1690,39 @@ export interface UiField { * via the `definition` "payload-locked-documents". */ export interface PayloadLockedDocument { - id: string; + id: number; document?: | ({ relationTo: 'users'; - value: string | User; + value: number | User; } | null) | ({ relationTo: 'select-versions-fields'; - value: string | SelectVersionsField; + value: number | SelectVersionsField; } | null) | ({ relationTo: 'array-fields'; - value: string | ArrayField; + value: number | ArrayField; } | null) | ({ relationTo: 'block-fields'; - value: string | BlockField; + value: number | BlockField; } | null) | ({ relationTo: 'checkbox-fields'; - value: string | CheckboxField; + value: number | CheckboxField; } | null) | ({ relationTo: 'code-fields'; - value: string | CodeField; + value: number | CodeField; } | null) | ({ relationTo: 'collapsible-fields'; - value: string | CollapsibleField; + value: number | CollapsibleField; } | null) | ({ relationTo: 'conditional-logic'; - value: string | ConditionalLogic; + value: number | ConditionalLogic; } | null) | ({ relationTo: 'custom-id'; @@ -1729,27 +1730,27 @@ export interface PayloadLockedDocument { } | null) | ({ relationTo: 'custom-tab-id'; - value: string | CustomTabId; + value: number | CustomTabId; } | null) | ({ relationTo: 'custom-row-id'; - value: string | CustomRowId; + value: number | CustomRowId; } | null) | ({ relationTo: 'date-fields'; - value: string | DateField; + value: number | DateField; } | null) | ({ relationTo: 'email-fields'; - value: string | EmailField; + value: number | EmailField; } | null) | ({ relationTo: 'radio-fields'; - value: string | RadioField; + value: number | RadioField; } | null) | ({ relationTo: 'group-fields'; - value: string | GroupField; + value: number | GroupField; } | null) | ({ relationTo: 'row-fields'; @@ -1757,76 +1758,76 @@ export interface PayloadLockedDocument { } | null) | ({ relationTo: 'indexed-fields'; - value: string | IndexedField; + value: number | IndexedField; } | null) | ({ relationTo: 'json-fields'; - value: string | JsonField; + value: number | JsonField; } | null) | ({ relationTo: 'number-fields'; - value: string | NumberField; + value: number | NumberField; } | null) | ({ relationTo: 'point-fields'; - value: string | PointField; + value: number | PointField; } | null) | ({ relationTo: 'relationship-fields'; - value: string | RelationshipField; + value: number | RelationshipField; } | null) | ({ relationTo: 'select-fields'; - value: string | SelectField; + value: number | SelectField; } | null) | ({ relationTo: 'tabs-fields-2'; - value: string | TabsFields2; + value: number | TabsFields2; } | null) | ({ relationTo: 'tabs-fields'; - value: string | TabsField; + value: number | TabsField; } | null) | ({ relationTo: 'text-fields'; - value: string | TextField; + value: number | TextField; } | null) | ({ relationTo: 'uploads'; - value: string | Upload; + value: number | Upload; } | null) | ({ relationTo: 'uploads2'; - value: string | Uploads2; + value: number | Uploads2; } | null) | ({ relationTo: 'uploads3'; - value: string | Uploads3; + value: number | Uploads3; } | null) | ({ relationTo: 'uploads-multi'; - value: string | UploadsMulti; + value: number | UploadsMulti; } | null) | ({ relationTo: 'uploads-poly'; - value: string | UploadsPoly; + value: number | UploadsPoly; } | null) | ({ relationTo: 'uploads-multi-poly'; - value: string | UploadsMultiPoly; + value: number | UploadsMultiPoly; } | null) | ({ relationTo: 'uploads-restricted'; - value: string | UploadsRestricted; + value: number | UploadsRestricted; } | null) | ({ relationTo: 'ui-fields'; - value: string | UiField; + value: number | UiField; } | null); globalSlug?: string | null; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; updatedAt: string; createdAt: string; @@ -1836,10 +1837,10 @@ export interface PayloadLockedDocument { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: string; + id: number; user: { relationTo: 'users'; - value: string | User; + value: number | User; }; key?: string | null; value?: @@ -1859,7 +1860,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: string; + id: number; name?: string | null; batch?: number | null; updatedAt: string; @@ -2452,6 +2453,7 @@ export interface CollapsibleFieldsSelect { export interface ConditionalLogicSelect { text?: T; toggleField?: T; + fieldWithDocIDCondition?: T; fieldWithCondition?: T; fieldWithOperationCondition?: T; customFieldWithField?: T;