fix: #1775 - siblingData for unnamed fields within array rows improperly formatted

This commit is contained in:
James
2023-01-02 13:31:34 -05:00
parent 3552d6a340
commit d6fcd19bd1
9 changed files with 71 additions and 40 deletions

View File

@@ -0,0 +1,17 @@
import { Field, fieldAffectsData } from '../../../../fields/config/types';
export const createNestedFieldPath = (parentPath: string, field: Field): string => {
if (parentPath) {
if (fieldAffectsData(field)) {
return `${parentPath}.${field.name}`;
}
return parentPath;
}
if (fieldAffectsData(field)) {
return field.name;
}
return '';
};

View File

@@ -8,9 +8,25 @@ const getSiblingData = (fields: Fields, path: string): Data => {
}
const siblingFields = {};
// If this field is nested
// We can provide a list of sibling fields
const parentFieldPath = path.substring(0, path.lastIndexOf('.') + 1);
// Determine if the last segment of the path is an array-based row
const pathSegments = path.split('.');
const lastSegment = pathSegments[pathSegments.length - 1];
const lastSegmentIsRowIndex = !Number.isNaN(Number(lastSegment));
let parentFieldPath: string;
if (lastSegmentIsRowIndex) {
// If the last segment is a row index,
// the sibling data is that row's contents
// so create a parent field path that will
// retrieve all contents of that row index only
parentFieldPath = `${path}.`;
} else {
// Otherwise, the last path segment is a field name
// and it should be removed
parentFieldPath = path.substring(0, path.lastIndexOf('.') + 1);
}
Object.keys(fields).forEach((fieldKey) => {
if (!fields[fieldKey].disableFormData && fieldKey.indexOf(parentFieldPath) === 0) {
siblingFields[fieldKey.replace(parentFieldPath, '')] = fields[fieldKey].value;

View File

@@ -17,16 +17,16 @@ import { useDocumentInfo } from '../../../utilities/DocumentInfo';
import { useOperation } from '../../../utilities/OperationProvider';
import { Collapsible } from '../../../elements/Collapsible';
import RenderFields from '../../RenderFields';
import { fieldAffectsData } from '../../../../../fields/config/types';
import { Props } from './types';
import { usePreferences } from '../../../utilities/Preferences';
import { ArrayAction } from '../../../elements/ArrayAction';
import { scrollToID } from '../../../../utilities/scrollToID';
import HiddenInput from '../HiddenInput';
import { RowLabel } from '../../RowLabel';
import { getTranslation } from '../../../../../utilities/getTranslation';
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
import './index.scss';
import { getTranslation } from '../../../../../utilities/getTranslation';
const baseClass = 'array-field';
@@ -312,7 +312,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
indexPath={indexPath}
fieldSchema={fields.map((field) => ({
...field,
path: `${path}.${i}${fieldAffectsData(field) ? `.${field.name}` : ''}`,
path: createNestedFieldPath(`${path}.${i}`, field),
}))}
/>
@@ -326,10 +326,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
<Banner type="error">
{t('validation:requiresAtLeast', {
count: minRows,
label: getTranslation(minRows
? labels.plural
: labels.singular,
i18n) || t(minRows > 1 ? 'general:row' : 'general:rows'),
label: getTranslation(minRows ? labels.plural : labels.singular, i18n) || t(minRows > 1 ? 'general:row' : 'general:rows'),
})}
</Banner>
)}

View File

@@ -23,12 +23,12 @@ import { useOperation } from '../../../utilities/OperationProvider';
import { Collapsible } from '../../../elements/Collapsible';
import { ArrayAction } from '../../../elements/ArrayAction';
import RenderFields from '../../RenderFields';
import { fieldAffectsData } from '../../../../../fields/config/types';
import SectionTitle from './SectionTitle';
import Pill from '../../../elements/Pill';
import { scrollToID } from '../../../../utilities/scrollToID';
import HiddenInput from '../HiddenInput';
import { getTranslation } from '../../../../../utilities/getTranslation';
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
import './index.scss';
@@ -345,7 +345,7 @@ const BlocksField: React.FC<Props> = (props) => {
permissions={permissions?.fields}
fieldSchema={blockToRender.fields.map((field) => ({
...field,
path: `${path}.${i}${fieldAffectsData(field) ? `.${field.name}` : ''}`,
path: createNestedFieldPath(`${path}.${i}`, field),
}))}
indexPath={indexPath}
/>

View File

@@ -7,8 +7,8 @@ import { usePreferences } from '../../../utilities/Preferences';
import { DocumentPreferences } from '../../../../../preferences/types';
import { useDocumentInfo } from '../../../utilities/DocumentInfo';
import FieldDescription from '../../FieldDescription';
import { getFieldPath } from '../getFieldPath';
import { RowLabel } from '../../RowLabel';
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
import './index.scss';
@@ -101,7 +101,7 @@ const CollapsibleField: React.FC<Props> = (props) => {
indexPath={indexPath}
fieldSchema={fields.map((field) => ({
...field,
path: getFieldPath(path, field),
path: createNestedFieldPath(path, field),
}))}
/>
</Collapsible>

View File

@@ -4,11 +4,11 @@ import RenderFields from '../../RenderFields';
import withCondition from '../../withCondition';
import FieldDescription from '../../FieldDescription';
import { Props } from './types';
import { fieldAffectsData } from '../../../../../fields/config/types';
import { useCollapsible } from '../../../elements/Collapsible/provider';
import { GroupProvider, useGroup } from './provider';
import { useTabs } from '../Tabs/provider';
import { getTranslation } from '../../../../../utilities/getTranslation';
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
import './index.scss';
@@ -60,16 +60,16 @@ const Group: React.FC<Props> = (props) => {
<GroupProvider>
<div className={`${baseClass}__wrap`}>
{(label || description) && (
<header className={`${baseClass}__header`}>
{label && (
<h3 className={`${baseClass}__title`}>{getTranslation(label, i18n)}</h3>
)}
<FieldDescription
className={`field-description-${path.replace(/\./gi, '__')}`}
value={null}
description={description}
/>
</header>
<header className={`${baseClass}__header`}>
{label && (
<h3 className={`${baseClass}__title`}>{getTranslation(label, i18n)}</h3>
)}
<FieldDescription
className={`field-description-${path.replace(/\./gi, '__')}`}
value={null}
description={description}
/>
</header>
)}
<RenderFields
permissions={permissions?.fields}
@@ -78,7 +78,7 @@ const Group: React.FC<Props> = (props) => {
indexPath={indexPath}
fieldSchema={fields.map((subField) => ({
...subField,
path: `${path}${fieldAffectsData(subField) ? `.${subField.name}` : ''}`,
path: createNestedFieldPath(path, subField),
}))}
/>
</div>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import RenderFields from '../../RenderFields';
import withCondition from '../../withCondition';
import { Props } from './types';
import { getFieldPath } from '../getFieldPath';
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
import './index.scss';
@@ -34,7 +34,7 @@ const Row: React.FC<Props> = (props) => {
indexPath={indexPath}
fieldSchema={fields.map((field) => ({
...field,
path: getFieldPath(path, field),
path: createNestedFieldPath(path, field),
}))}
/>
);

View File

@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import RenderFields from '../../RenderFields';
import withCondition from '../../withCondition';
import { Props } from './types';
import { fieldAffectsData, tabHasName } from '../../../../../fields/config/types';
import { tabHasName } from '../../../../../fields/config/types';
import FieldDescription from '../../FieldDescription';
import toKebabCase from '../../../../../utilities/toKebabCase';
import { useCollapsible } from '../../../elements/Collapsible/provider';
@@ -12,6 +12,7 @@ import { getTranslation } from '../../../../../utilities/getTranslation';
import { usePreferences } from '../../../utilities/Preferences';
import { DocumentPreferences } from '../../../../../preferences/types';
import { useDocumentInfo } from '../../../utilities/DocumentInfo';
import { createNestedFieldPath } from '../../Form/createNestedFieldPath';
import './index.scss';
@@ -123,10 +124,17 @@ const TabsField: React.FC<Props> = (props) => {
readOnly={readOnly}
permissions={tabHasName(activeTabConfig) ? permissions[activeTabConfig.name].fields : permissions}
fieldTypes={fieldTypes}
fieldSchema={activeTabConfig.fields.map((field) => ({
...field,
path: `${path ? `${path}.` : ''}${tabHasName(activeTabConfig) ? `${activeTabConfig.name}.` : ''}${fieldAffectsData(field) ? field.name : ''}`,
}))}
fieldSchema={activeTabConfig.fields.map((field) => {
const pathSegments = [];
if (path) pathSegments.push(path);
if (tabHasName(activeTabConfig)) pathSegments.push(activeTabConfig.name);
return {
...field,
path: createNestedFieldPath(pathSegments.join('.'), field),
};
})}
indexPath={indexPath}
/>
</div>

View File

@@ -1,7 +0,0 @@
import { Field, fieldAffectsData } from '../../../../fields/config/types';
export const getFieldPath = (path: string, field: Field): string => {
// prevents duplicate . on nesting non-named fields
const dot = path && path.slice(-1) === '.' ? '' : '.';
return `${path ? `${path}${dot}` : ''}${fieldAffectsData(field) ? field.name : ''}`;
};