Skip to content

Commit 2a8bc31

Browse files
authored
Merge pull request #1789 from payloadcms/fix/#1775
fix: #1775 - siblingData for unnamed fields within array rows improperly formatted
2 parents 3552d6a + d6fcd19 commit 2a8bc31

File tree

9 files changed

+71
-40
lines changed

9 files changed

+71
-40
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Field, fieldAffectsData } from '../../../../fields/config/types';
2+
3+
export const createNestedFieldPath = (parentPath: string, field: Field): string => {
4+
if (parentPath) {
5+
if (fieldAffectsData(field)) {
6+
return `${parentPath}.${field.name}`;
7+
}
8+
9+
return parentPath;
10+
}
11+
12+
if (fieldAffectsData(field)) {
13+
return field.name;
14+
}
15+
16+
return '';
17+
};

src/admin/components/forms/Form/getSiblingData.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,25 @@ const getSiblingData = (fields: Fields, path: string): Data => {
88
}
99
const siblingFields = {};
1010

11-
// If this field is nested
12-
// We can provide a list of sibling fields
13-
const parentFieldPath = path.substring(0, path.lastIndexOf('.') + 1);
11+
// Determine if the last segment of the path is an array-based row
12+
const pathSegments = path.split('.');
13+
const lastSegment = pathSegments[pathSegments.length - 1];
14+
const lastSegmentIsRowIndex = !Number.isNaN(Number(lastSegment));
15+
16+
let parentFieldPath: string;
17+
18+
if (lastSegmentIsRowIndex) {
19+
// If the last segment is a row index,
20+
// the sibling data is that row's contents
21+
// so create a parent field path that will
22+
// retrieve all contents of that row index only
23+
parentFieldPath = `${path}.`;
24+
} else {
25+
// Otherwise, the last path segment is a field name
26+
// and it should be removed
27+
parentFieldPath = path.substring(0, path.lastIndexOf('.') + 1);
28+
}
29+
1430
Object.keys(fields).forEach((fieldKey) => {
1531
if (!fields[fieldKey].disableFormData && fieldKey.indexOf(parentFieldPath) === 0) {
1632
siblingFields[fieldKey.replace(parentFieldPath, '')] = fields[fieldKey].value;

src/admin/components/forms/field-types/Array/index.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ import { useDocumentInfo } from '../../../utilities/DocumentInfo';
1717
import { useOperation } from '../../../utilities/OperationProvider';
1818
import { Collapsible } from '../../../elements/Collapsible';
1919
import RenderFields from '../../RenderFields';
20-
import { fieldAffectsData } from '../../../../../fields/config/types';
2120
import { Props } from './types';
2221
import { usePreferences } from '../../../utilities/Preferences';
2322
import { ArrayAction } from '../../../elements/ArrayAction';
2423
import { scrollToID } from '../../../../utilities/scrollToID';
2524
import HiddenInput from '../HiddenInput';
2625
import { RowLabel } from '../../RowLabel';
26+
import { getTranslation } from '../../../../../utilities/getTranslation';
27+
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
2728

2829
import './index.scss';
29-
import { getTranslation } from '../../../../../utilities/getTranslation';
3030

3131
const baseClass = 'array-field';
3232

@@ -312,7 +312,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
312312
indexPath={indexPath}
313313
fieldSchema={fields.map((field) => ({
314314
...field,
315-
path: `${path}.${i}${fieldAffectsData(field) ? `.${field.name}` : ''}`,
315+
path: createNestedFieldPath(`${path}.${i}`, field),
316316
}))}
317317
/>
318318

@@ -326,10 +326,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
326326
<Banner type="error">
327327
{t('validation:requiresAtLeast', {
328328
count: minRows,
329-
label: getTranslation(minRows
330-
? labels.plural
331-
: labels.singular,
332-
i18n) || t(minRows > 1 ? 'general:row' : 'general:rows'),
329+
label: getTranslation(minRows ? labels.plural : labels.singular, i18n) || t(minRows > 1 ? 'general:row' : 'general:rows'),
333330
})}
334331
</Banner>
335332
)}

src/admin/components/forms/field-types/Blocks/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ import { useOperation } from '../../../utilities/OperationProvider';
2323
import { Collapsible } from '../../../elements/Collapsible';
2424
import { ArrayAction } from '../../../elements/ArrayAction';
2525
import RenderFields from '../../RenderFields';
26-
import { fieldAffectsData } from '../../../../../fields/config/types';
2726
import SectionTitle from './SectionTitle';
2827
import Pill from '../../../elements/Pill';
2928
import { scrollToID } from '../../../../utilities/scrollToID';
3029
import HiddenInput from '../HiddenInput';
3130
import { getTranslation } from '../../../../../utilities/getTranslation';
31+
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
3232

3333
import './index.scss';
3434

@@ -345,7 +345,7 @@ const BlocksField: React.FC<Props> = (props) => {
345345
permissions={permissions?.fields}
346346
fieldSchema={blockToRender.fields.map((field) => ({
347347
...field,
348-
path: `${path}.${i}${fieldAffectsData(field) ? `.${field.name}` : ''}`,
348+
path: createNestedFieldPath(`${path}.${i}`, field),
349349
}))}
350350
indexPath={indexPath}
351351
/>

src/admin/components/forms/field-types/Collapsible/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { usePreferences } from '../../../utilities/Preferences';
77
import { DocumentPreferences } from '../../../../../preferences/types';
88
import { useDocumentInfo } from '../../../utilities/DocumentInfo';
99
import FieldDescription from '../../FieldDescription';
10-
import { getFieldPath } from '../getFieldPath';
1110
import { RowLabel } from '../../RowLabel';
11+
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
1212

1313
import './index.scss';
1414

@@ -101,7 +101,7 @@ const CollapsibleField: React.FC<Props> = (props) => {
101101
indexPath={indexPath}
102102
fieldSchema={fields.map((field) => ({
103103
...field,
104-
path: getFieldPath(path, field),
104+
path: createNestedFieldPath(path, field),
105105
}))}
106106
/>
107107
</Collapsible>

src/admin/components/forms/field-types/Group/index.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import RenderFields from '../../RenderFields';
44
import withCondition from '../../withCondition';
55
import FieldDescription from '../../FieldDescription';
66
import { Props } from './types';
7-
import { fieldAffectsData } from '../../../../../fields/config/types';
87
import { useCollapsible } from '../../../elements/Collapsible/provider';
98
import { GroupProvider, useGroup } from './provider';
109
import { useTabs } from '../Tabs/provider';
1110
import { getTranslation } from '../../../../../utilities/getTranslation';
11+
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
1212

1313
import './index.scss';
1414

@@ -60,16 +60,16 @@ const Group: React.FC<Props> = (props) => {
6060
<GroupProvider>
6161
<div className={`${baseClass}__wrap`}>
6262
{(label || description) && (
63-
<header className={`${baseClass}__header`}>
64-
{label && (
65-
<h3 className={`${baseClass}__title`}>{getTranslation(label, i18n)}</h3>
66-
)}
67-
<FieldDescription
68-
className={`field-description-${path.replace(/\./gi, '__')}`}
69-
value={null}
70-
description={description}
71-
/>
72-
</header>
63+
<header className={`${baseClass}__header`}>
64+
{label && (
65+
<h3 className={`${baseClass}__title`}>{getTranslation(label, i18n)}</h3>
66+
)}
67+
<FieldDescription
68+
className={`field-description-${path.replace(/\./gi, '__')}`}
69+
value={null}
70+
description={description}
71+
/>
72+
</header>
7373
)}
7474
<RenderFields
7575
permissions={permissions?.fields}
@@ -78,7 +78,7 @@ const Group: React.FC<Props> = (props) => {
7878
indexPath={indexPath}
7979
fieldSchema={fields.map((subField) => ({
8080
...subField,
81-
path: `${path}${fieldAffectsData(subField) ? `.${subField.name}` : ''}`,
81+
path: createNestedFieldPath(path, subField),
8282
}))}
8383
/>
8484
</div>

src/admin/components/forms/field-types/Row/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import RenderFields from '../../RenderFields';
33
import withCondition from '../../withCondition';
44
import { Props } from './types';
5-
import { getFieldPath } from '../getFieldPath';
5+
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
66

77
import './index.scss';
88

@@ -34,7 +34,7 @@ const Row: React.FC<Props> = (props) => {
3434
indexPath={indexPath}
3535
fieldSchema={fields.map((field) => ({
3636
...field,
37-
path: getFieldPath(path, field),
37+
path: createNestedFieldPath(path, field),
3838
}))}
3939
/>
4040
);

src/admin/components/forms/field-types/Tabs/index.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
33
import RenderFields from '../../RenderFields';
44
import withCondition from '../../withCondition';
55
import { Props } from './types';
6-
import { fieldAffectsData, tabHasName } from '../../../../../fields/config/types';
6+
import { tabHasName } from '../../../../../fields/config/types';
77
import FieldDescription from '../../FieldDescription';
88
import toKebabCase from '../../../../../utilities/toKebabCase';
99
import { useCollapsible } from '../../../elements/Collapsible/provider';
@@ -12,6 +12,7 @@ import { getTranslation } from '../../../../../utilities/getTranslation';
1212
import { usePreferences } from '../../../utilities/Preferences';
1313
import { DocumentPreferences } from '../../../../../preferences/types';
1414
import { useDocumentInfo } from '../../../utilities/DocumentInfo';
15+
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
1516

1617
import './index.scss';
1718

@@ -123,10 +124,17 @@ const TabsField: React.FC<Props> = (props) => {
123124
readOnly={readOnly}
124125
permissions={tabHasName(activeTabConfig) ? permissions[activeTabConfig.name].fields : permissions}
125126
fieldTypes={fieldTypes}
126-
fieldSchema={activeTabConfig.fields.map((field) => ({
127-
...field,
128-
path: `${path ? `${path}.` : ''}${tabHasName(activeTabConfig) ? `${activeTabConfig.name}.` : ''}${fieldAffectsData(field) ? field.name : ''}`,
129-
}))}
127+
fieldSchema={activeTabConfig.fields.map((field) => {
128+
const pathSegments = [];
129+
130+
if (path) pathSegments.push(path);
131+
if (tabHasName(activeTabConfig)) pathSegments.push(activeTabConfig.name);
132+
133+
return {
134+
...field,
135+
path: createNestedFieldPath(pathSegments.join('.'), field),
136+
};
137+
})}
130138
indexPath={indexPath}
131139
/>
132140
</div>

src/admin/components/forms/field-types/getFieldPath.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)