@@ -10,6 +10,7 @@ import type {
1010 PayloadRequest ,
1111 SanitizedFieldPermissions ,
1212 SanitizedFieldsPermissions ,
13+ TabAsField ,
1314 Validate ,
1415} from 'payload'
1516
@@ -21,7 +22,6 @@ import {
2122 fieldIsHiddenOrDisabled ,
2223 fieldIsID ,
2324 fieldIsLocalized ,
24- getFieldPaths ,
2525 tabHasName ,
2626} from 'payload/shared'
2727
@@ -42,7 +42,7 @@ export type AddFieldStatePromiseArgs = {
4242 clientFieldSchemaMap ?: ClientFieldSchemaMap
4343 collectionSlug ?: string
4444 data : Data
45- field : Field
45+ field : Field | TabAsField
4646 fieldIndex : number
4747 fieldSchemaMap : FieldSchemaMap
4848 /**
@@ -168,7 +168,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
168168 return
169169 }
170170
171- const validate : Validate = field . validate
171+ const validate : Validate = 'validate' in field ? field . validate : undefined
172172
173173 let validationResult : string | true = true
174174
@@ -235,12 +235,13 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
235235 const arrayValue = Array . isArray ( data [ field . name ] ) ? data [ field . name ] : [ ]
236236
237237 const { promises, rows } = arrayValue . reduce (
238- ( acc , row , i : number ) => {
239- const parentPath = path + '.' + i
238+ ( acc , row , rowIndex : number ) => {
239+ const rowPath = path + '.' + rowIndex
240+
240241 row . id = row ?. id || new ObjectId ( ) . toHexString ( )
241242
242243 if ( ! omitParents && ( ! filter || filter ( args ) ) ) {
243- const idKey = parentPath + '.id'
244+ const idKey = rowPath + '.id'
244245
245246 state [ idKey ] = {
246247 initialValue : row . id ,
@@ -270,7 +271,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
270271 operation,
271272 parentIndexPath : '' ,
272273 parentPassesCondition : passesCondition ,
273- parentPath,
274+ parentPath : rowPath ,
274275 parentSchemaPath : schemaPath ,
275276 permissions :
276277 fieldPermissions === true ? fieldPermissions : fieldPermissions ?. fields || { } ,
@@ -357,22 +358,23 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
357358 const blocksValue = Array . isArray ( data [ field . name ] ) ? data [ field . name ] : [ ]
358359
359360 const { promises, rowMetadata } = blocksValue . reduce (
360- ( acc , row , i : number ) => {
361+ ( acc , row , rowIndex : number ) => {
361362 const block = field . blocks . find ( ( blockType ) => blockType . slug === row . blockType )
363+
362364 if ( ! block ) {
363365 throw new Error (
364366 `Block with type "${ row . blockType } " was found in block data, but no block with that type is defined in the config for field with schema path ${ schemaPath } .` ,
365367 )
366368 }
367369
368- const parentPath = path + '.' + i
370+ const rowPath = path + '.' + rowIndex
369371
370372 if ( block ) {
371373 row . id = row ?. id || new ObjectId ( ) . toHexString ( )
372374
373375 if ( ! omitParents && ( ! filter || filter ( args ) ) ) {
374376 // Handle block `id` field
375- const idKey = parentPath + '.id'
377+ const idKey = rowPath + '.id'
376378
377379 state [ idKey ] = {
378380 initialValue : row . id ,
@@ -386,7 +388,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
386388 }
387389
388390 // Handle `blockType` field
389- const fieldKey = parentPath + '.blockType'
391+ const fieldKey = rowPath + '.blockType'
390392
391393 state [ fieldKey ] = {
392394 initialValue : row . blockType ,
@@ -400,7 +402,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
400402 }
401403
402404 // Handle `blockName` field
403- const blockNameKey = parentPath + '.blockName'
405+ const blockNameKey = rowPath + '.blockName'
404406
405407 state [ blockNameKey ] = { }
406408
@@ -434,7 +436,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
434436 operation,
435437 parentIndexPath : '' ,
436438 parentPassesCondition : passesCondition ,
437- parentPath,
439+ parentPath : rowPath ,
438440 parentSchemaPath : schemaPath + '.' + block . slug ,
439441 permissions :
440442 fieldPermissions === true
@@ -546,6 +548,7 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
546548
547549 break
548550 }
551+
549552 case 'relationship' :
550553 case 'upload' : {
551554 if ( field . filterOptions ) {
@@ -678,8 +681,8 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
678681 operation,
679682 parentIndexPath : indexPath ,
680683 parentPassesCondition : passesCondition ,
681- parentPath,
682- parentSchemaPath,
684+ parentPath : path ,
685+ parentSchemaPath : schemaPath ,
683686 permissions : parentPermissions , // TODO: Verify this is correct
684687 preferences,
685688 previousFormState,
@@ -690,74 +693,85 @@ export const addFieldStatePromise = async (args: AddFieldStatePromiseArgs): Prom
690693 skipValidation,
691694 state,
692695 } )
693- } else if ( field . type === 'tabs' ) {
694- const promises = field . tabs . map ( ( tab , tabIndex ) => {
695- const isNamedTab = tabHasName ( tab )
696-
697- const {
698- indexPath : tabIndexPath ,
699- path : tabPath ,
700- schemaPath : tabSchemaPath ,
701- } = getFieldPaths ( {
702- field : {
703- ...tab ,
704- type : 'tab' ,
705- } ,
706- index : tabIndex ,
707- parentIndexPath : indexPath ,
708- parentPath,
709- parentSchemaPath,
710- } )
711-
712- let childPermissions : SanitizedFieldsPermissions = undefined
713-
714- if ( isNamedTab ) {
715- if ( parentPermissions === true ) {
696+ } else if ( field . type === 'tab' ) {
697+ const isNamedTab = tabHasName ( field )
698+
699+ let childPermissions : SanitizedFieldsPermissions = undefined
700+
701+ if ( isNamedTab ) {
702+ if ( parentPermissions === true ) {
703+ childPermissions = true
704+ } else {
705+ const tabPermissions = parentPermissions ?. [ field . name ]
706+ if ( tabPermissions === true ) {
716707 childPermissions = true
717708 } else {
718- const tabPermissions = parentPermissions ?. [ tab . name ]
719- if ( tabPermissions === true ) {
720- childPermissions = true
721- } else {
722- childPermissions = tabPermissions ?. fields
723- }
709+ childPermissions = tabPermissions ?. fields
724710 }
725- } else {
726- childPermissions = parentPermissions
727711 }
712+ } else {
713+ childPermissions = parentPermissions
714+ }
728715
729- return iterateFields ( {
730- id,
731- addErrorPathToParent : addErrorPathToParentArg ,
732- anyParentLocalized : tab . localized || anyParentLocalized ,
733- clientFieldSchemaMap,
734- collectionSlug,
735- data : isNamedTab ? data ?. [ tab . name ] || { } : data ,
736- fields : tab . fields ,
737- fieldSchemaMap,
738- filter,
739- forceFullValue,
740- fullData,
741- includeSchema,
742- omitParents,
743- operation,
744- parentIndexPath : isNamedTab ? '' : tabIndexPath ,
745- parentPassesCondition : passesCondition ,
746- parentPath : isNamedTab ? tabPath : parentPath ,
747- parentSchemaPath : isNamedTab ? tabSchemaPath : parentSchemaPath ,
748- permissions : childPermissions ,
749- preferences,
750- previousFormState,
751- renderAllFields,
752- renderFieldFn,
753- req,
754- skipConditionChecks,
755- skipValidation,
756- state,
757- } )
716+ return iterateFields ( {
717+ id,
718+ addErrorPathToParent : addErrorPathToParentArg ,
719+ anyParentLocalized : fieldIsLocalized ( field ) || anyParentLocalized ,
720+ clientFieldSchemaMap,
721+ collectionSlug,
722+ data : isNamedTab ? data ?. [ field . name ] || { } : data ,
723+ fields : field . fields ,
724+ fieldSchemaMap,
725+ filter,
726+ forceFullValue,
727+ fullData,
728+ includeSchema,
729+ omitParents,
730+ operation,
731+ parentIndexPath : isNamedTab ? '' : indexPath ,
732+ parentPassesCondition : passesCondition ,
733+ parentPath : isNamedTab ? path : parentPath ,
734+ parentSchemaPath : schemaPath ,
735+ permissions : childPermissions ,
736+ preferences,
737+ previousFormState,
738+ renderAllFields,
739+ renderFieldFn,
740+ req,
741+ skipConditionChecks,
742+ skipValidation,
743+ state,
744+ } )
745+ } else if ( field . type === 'tabs' ) {
746+ return iterateFields ( {
747+ id,
748+ addErrorPathToParent : addErrorPathToParentArg ,
749+ anyParentLocalized : fieldIsLocalized ( field ) || anyParentLocalized ,
750+ clientFieldSchemaMap,
751+ collectionSlug,
752+ data,
753+ fields : field . tabs . map ( ( tab ) => ( { ...tab , type : 'tab' } ) ) ,
754+ fieldSchemaMap,
755+ filter,
756+ forceFullValue,
757+ fullData,
758+ includeSchema,
759+ omitParents,
760+ operation,
761+ parentIndexPath : indexPath ,
762+ parentPassesCondition : passesCondition ,
763+ parentPath : path ,
764+ parentSchemaPath : schemaPath ,
765+ permissions : parentPermissions ,
766+ preferences,
767+ previousFormState,
768+ renderAllFields,
769+ renderFieldFn,
770+ req,
771+ skipConditionChecks,
772+ skipValidation,
773+ state,
758774 } )
759-
760- await Promise . all ( promises )
761775 } else if ( field . type === 'ui' ) {
762776 if ( ! filter || filter ( args ) ) {
763777 state [ path ] = fieldState
0 commit comments