feat: scaffolds tabs field
This commit is contained in:
@@ -8,4 +8,13 @@
|
||||
margin-right: base(.5);
|
||||
margin-bottom: base(.5);
|
||||
}
|
||||
|
||||
&__column {
|
||||
background-color: transparent;
|
||||
box-shadow: 0 0 0 1px var(--theme-elevation-200);
|
||||
}
|
||||
|
||||
&__column--active {
|
||||
background-color: var(--theme-elevation-150);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,10 @@ const ColumnSelector: React.FC<Props> = (props) => {
|
||||
alignIcon="left"
|
||||
key={field.name || i}
|
||||
icon={isEnabled ? <X /> : <Plus />}
|
||||
pillStyle={isEnabled ? 'dark' : undefined}
|
||||
className={`${baseClass}__active-column`}
|
||||
className={[
|
||||
`${baseClass}__column`,
|
||||
isEnabled && `${baseClass}__column--active`,
|
||||
].filter(Boolean).join(' ')}
|
||||
>
|
||||
{field.label || field.name}
|
||||
</Pill>
|
||||
|
||||
@@ -208,5 +208,21 @@ export const addFieldStatePromise = async ({
|
||||
locale,
|
||||
operation,
|
||||
});
|
||||
} else if (field.type === 'tabs') {
|
||||
field.tabs.forEach((tab) => {
|
||||
iterateFields({
|
||||
state,
|
||||
fields: tab.fields,
|
||||
data,
|
||||
parentPassesCondition: passesCondition,
|
||||
path,
|
||||
user,
|
||||
fieldPromises,
|
||||
fullData,
|
||||
id,
|
||||
locale,
|
||||
operation,
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -284,7 +284,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
||||
forceRender
|
||||
readOnly={readOnly}
|
||||
fieldTypes={fieldTypes}
|
||||
permissions={permissions.fields}
|
||||
permissions={permissions?.fields}
|
||||
fieldSchema={fields.map((field) => ({
|
||||
...field,
|
||||
path: `${path}.${i}${fieldAffectsData(field) ? `.${field.name}` : ''}`,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
@import '../../../../scss/styles.scss';
|
||||
|
||||
.collapsible-field {
|
||||
&__label {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.field-type:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
76
src/admin/components/forms/field-types/Tabs/index.tsx
Normal file
76
src/admin/components/forms/field-types/Tabs/index.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
import React, { useState } from 'react';
|
||||
import RenderFields from '../../RenderFields';
|
||||
import withCondition from '../../withCondition';
|
||||
import { Props } from './types';
|
||||
import { fieldAffectsData } from '../../../../../fields/config/types';
|
||||
import FieldDescription from '../../FieldDescription';
|
||||
import toKebabCase from '../../../../../utilities/toKebabCase';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const baseClass = 'tabs-field';
|
||||
|
||||
const TabsField: React.FC<Props> = (props) => {
|
||||
const {
|
||||
tabs,
|
||||
fieldTypes,
|
||||
path,
|
||||
permissions,
|
||||
admin: {
|
||||
readOnly,
|
||||
className,
|
||||
},
|
||||
} = props;
|
||||
|
||||
const [active, setActive] = useState(0);
|
||||
|
||||
const activeTab = tabs[active];
|
||||
|
||||
return (
|
||||
<div className={[
|
||||
className,
|
||||
baseClass,
|
||||
].filter(Boolean).join(' ')}
|
||||
>
|
||||
<div className={`${baseClass}__tabs`}>
|
||||
{tabs.map((tab, i) => {
|
||||
return (
|
||||
<button
|
||||
key={i}
|
||||
type="button"
|
||||
className={`${baseClass}__tab`}
|
||||
onClick={() => setActive(i)}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className={`${baseClass}__content-wrap`}>
|
||||
{activeTab && (
|
||||
<div className={[
|
||||
`${baseClass}__tab`,
|
||||
`${baseClass}__tab-${toKebabCase(activeTab.label)}`,
|
||||
].join('')}
|
||||
>
|
||||
<FieldDescription
|
||||
description={activeTab.description}
|
||||
/>
|
||||
<RenderFields
|
||||
forceRender
|
||||
readOnly={readOnly}
|
||||
permissions={permissions?.fields}
|
||||
fieldTypes={fieldTypes}
|
||||
fieldSchema={activeTab.fields.map((field) => ({
|
||||
...field,
|
||||
path: `${path ? `${path}.` : ''}${fieldAffectsData(field) ? field.name : ''}`,
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default withCondition(TabsField);
|
||||
9
src/admin/components/forms/field-types/Tabs/types.ts
Normal file
9
src/admin/components/forms/field-types/Tabs/types.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { TabsField } from '../../../../../fields/config/types';
|
||||
import { FieldTypes } from '..';
|
||||
import { FieldPermissions } from '../../../../../auth/types';
|
||||
|
||||
export type Props = Omit<TabsField, 'type'> & {
|
||||
path?: string
|
||||
fieldTypes: FieldTypes
|
||||
permissions: FieldPermissions
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import group from './Group';
|
||||
import array from './Array';
|
||||
import row from './Row';
|
||||
import collapsible from './Collapsible';
|
||||
import tabs from './Tabs';
|
||||
import upload from './Upload';
|
||||
import ui from './UI';
|
||||
|
||||
@@ -44,6 +45,7 @@ export type FieldTypes = {
|
||||
array: React.ComponentType
|
||||
row: React.ComponentType
|
||||
collapsible: React.ComponentType
|
||||
tabs: React.ComponentType
|
||||
upload: React.ComponentType
|
||||
ui: React.ComponentType
|
||||
}
|
||||
@@ -69,6 +71,7 @@ const fieldTypes: FieldTypes = {
|
||||
array,
|
||||
row,
|
||||
collapsible,
|
||||
tabs,
|
||||
upload,
|
||||
ui,
|
||||
};
|
||||
|
||||
@@ -86,6 +86,22 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
||||
);
|
||||
}
|
||||
|
||||
if (field.type === 'tabs') {
|
||||
return field.tabs.map((tab, tabIndex) => {
|
||||
return (
|
||||
<RenderFieldsToDiff
|
||||
key={tabIndex}
|
||||
fields={tab.fields}
|
||||
fieldComponents={fieldComponents}
|
||||
fieldPermissions={fieldPermissions}
|
||||
version={version}
|
||||
comparison={comparison}
|
||||
locales={locales}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// At this point, we are dealing with a `row` or similar
|
||||
if (fieldHasSubFields(field)) {
|
||||
return (
|
||||
|
||||
@@ -64,6 +64,10 @@ async function accessOperation(args: Arguments): Promise<Permissions> {
|
||||
}
|
||||
} else if (field.fields) {
|
||||
executeFieldPolicies(updatedObj, field.fields, operation);
|
||||
} else if (field.type === 'tabs') {
|
||||
field.tabs.forEach((tab) => {
|
||||
executeFieldPolicies(updatedObj, tab.fields, operation);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -269,13 +269,23 @@ function generateFieldTypes(config: SanitizedConfig, fields: Field[]): {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'row': {
|
||||
case 'row':
|
||||
case 'collapsible': {
|
||||
const topLevelFields = generateFieldTypes(config, field.fields);
|
||||
requiredTopLevelProps = requiredTopLevelProps.concat(topLevelFields.required);
|
||||
topLevelProps = topLevelProps.concat(Object.entries(topLevelFields.properties).map((prop) => prop));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'tabs': {
|
||||
field.tabs.forEach((tab) => {
|
||||
const topLevelFields = generateFieldTypes(config, tab.fields);
|
||||
requiredTopLevelProps = requiredTopLevelProps.concat(topLevelFields.required);
|
||||
topLevelProps = topLevelProps.concat(Object.entries(topLevelFields.properties).map((prop) => prop));
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case 'group': {
|
||||
fieldSchema = {
|
||||
type: 'object',
|
||||
|
||||
@@ -135,7 +135,7 @@ function initCollectionsGraphQL(payload: Payload): void {
|
||||
collection.graphQL.updateMutationInputType = new GraphQLNonNull(buildMutationInputType(
|
||||
payload,
|
||||
`${singularLabel}Update`,
|
||||
fields.filter((field) => fieldAffectsData(field) && field.name !== 'id'),
|
||||
fields.filter((field) => !(fieldAffectsData(field) && field.name === 'id')),
|
||||
`${singularLabel}Update`,
|
||||
true,
|
||||
));
|
||||
|
||||
@@ -68,6 +68,14 @@ const sanitizeFields = (fields: Field[], validRelationships: string[]): Field[]
|
||||
|
||||
if ('fields' in field && field.fields) field.fields = sanitizeFields(field.fields, validRelationships);
|
||||
|
||||
if (field.type === 'tabs') {
|
||||
field.tabs = field.tabs.map((tab) => {
|
||||
const unsanitizedTab = { ...tab };
|
||||
unsanitizedTab.fields = sanitizeFields(tab.fields, validRelationships);
|
||||
return unsanitizedTab;
|
||||
});
|
||||
}
|
||||
|
||||
if ('blocks' in field && field.blocks) {
|
||||
field.blocks = field.blocks.map((block) => {
|
||||
const unsanitizedBlock = { ...block };
|
||||
|
||||
@@ -168,20 +168,29 @@ export const radio = baseField.keys({
|
||||
export const row = baseField.keys({
|
||||
type: joi.string().valid('row').required(),
|
||||
fields: joi.array().items(joi.link('#field')),
|
||||
admin: baseAdminFields.keys({
|
||||
description: joi.forbidden(),
|
||||
readOnly: joi.forbidden(),
|
||||
hidden: joi.forbidden(),
|
||||
}),
|
||||
admin: baseAdminFields.default(),
|
||||
});
|
||||
|
||||
export const collapsible = baseField.keys({
|
||||
label: joi.string().required(),
|
||||
type: joi.string().valid('collapsible').required(),
|
||||
fields: joi.array().items(joi.link('#field')),
|
||||
admin: baseAdminFields.default(),
|
||||
});
|
||||
|
||||
export const tabs = baseField.keys({
|
||||
type: joi.string().valid('tabs').required(),
|
||||
fields: joi.forbidden(),
|
||||
tabs: joi.array().items(joi.object({
|
||||
label: joi.string().required(),
|
||||
fields: joi.array().items(joi.link('#field')).required(),
|
||||
description: joi.alternatives().try(
|
||||
joi.string(),
|
||||
componentSchema,
|
||||
),
|
||||
})).required(),
|
||||
admin: baseAdminFields.keys({
|
||||
readOnly: joi.forbidden(),
|
||||
hidden: joi.forbidden(),
|
||||
description: joi.forbidden(),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -378,6 +387,7 @@ const fieldSchema = joi.alternatives()
|
||||
array,
|
||||
row,
|
||||
collapsible,
|
||||
tabs,
|
||||
radio,
|
||||
relationship,
|
||||
checkbox,
|
||||
|
||||
@@ -179,6 +179,18 @@ export type CollapsibleField = Omit<FieldBase, 'name'> & {
|
||||
fields: Field[];
|
||||
}
|
||||
|
||||
export type TabsAdmin = Omit<Admin, 'description'>;
|
||||
|
||||
export type TabsField = Omit<FieldBase, 'admin' | 'name'> & {
|
||||
type: 'tabs';
|
||||
tabs: {
|
||||
label: string
|
||||
fields: Field[];
|
||||
description?: Description
|
||||
}[]
|
||||
admin?: TabsAdmin
|
||||
}
|
||||
|
||||
export type UIField = {
|
||||
name: string
|
||||
label?: string
|
||||
@@ -332,6 +344,7 @@ export type Field =
|
||||
| PointField
|
||||
| RowField
|
||||
| CollapsibleField
|
||||
| TabsField
|
||||
| UIField;
|
||||
|
||||
export type FieldAffectingData =
|
||||
@@ -369,6 +382,7 @@ export type NonPresentationalField = TextField
|
||||
| CodeField
|
||||
| PointField
|
||||
| RowField
|
||||
| TabsField
|
||||
| CollapsibleField;
|
||||
|
||||
export type FieldWithPath = Field & {
|
||||
|
||||
@@ -127,6 +127,22 @@ export const promise = async ({
|
||||
break;
|
||||
}
|
||||
|
||||
case 'tabs': {
|
||||
field.tabs.forEach((tab) => {
|
||||
traverseFields({
|
||||
data,
|
||||
doc,
|
||||
fields: tab.fields,
|
||||
operation,
|
||||
promises,
|
||||
req,
|
||||
siblingData: siblingData || {},
|
||||
siblingDoc: { ...siblingDoc },
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -266,6 +266,26 @@ export const promise = async ({
|
||||
break;
|
||||
}
|
||||
|
||||
case 'tabs': {
|
||||
field.tabs.forEach((tab) => {
|
||||
traverseFields({
|
||||
currentDepth,
|
||||
depth,
|
||||
doc,
|
||||
fieldPromises,
|
||||
fields: tab.fields,
|
||||
findMany,
|
||||
flattenLocales,
|
||||
overrideAccess,
|
||||
populationPromises,
|
||||
req,
|
||||
siblingDoc,
|
||||
showHiddenFields,
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -282,6 +282,29 @@ export const promise = async ({
|
||||
break;
|
||||
}
|
||||
|
||||
case 'tabs': {
|
||||
field.tabs.forEach((tab) => {
|
||||
traverseFields({
|
||||
data,
|
||||
doc,
|
||||
docWithLocales,
|
||||
errors,
|
||||
fields: tab.fields,
|
||||
id,
|
||||
mergeLocaleActions,
|
||||
operation,
|
||||
path,
|
||||
promises,
|
||||
req,
|
||||
siblingData,
|
||||
siblingDoc,
|
||||
siblingDocWithLocales,
|
||||
skipValidation: skipValidationFromHere,
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -267,6 +267,25 @@ export const promise = async ({
|
||||
break;
|
||||
}
|
||||
|
||||
case 'tabs': {
|
||||
field.tabs.forEach((tab) => {
|
||||
traverseFields({
|
||||
data,
|
||||
doc,
|
||||
fields: tab.fields,
|
||||
id,
|
||||
operation,
|
||||
overrideAccess,
|
||||
promises,
|
||||
req,
|
||||
siblingData,
|
||||
siblingDoc,
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -121,6 +121,19 @@ export const recurseNestedFields = ({
|
||||
showHiddenFields,
|
||||
});
|
||||
}
|
||||
} else if (field.type === 'tabs') {
|
||||
field.tabs.forEach((tab) => {
|
||||
recurseNestedFields({
|
||||
promises,
|
||||
data,
|
||||
fields: tab.fields,
|
||||
req,
|
||||
overrideAccess,
|
||||
depth,
|
||||
currentDepth,
|
||||
showHiddenFields,
|
||||
});
|
||||
});
|
||||
} else if (Array.isArray(data[field.name])) {
|
||||
if (field.type === 'blocks') {
|
||||
data[field.name].forEach((row, i) => {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { GraphQLJSON } from 'graphql-type-json';
|
||||
import withNullableType from './withNullableType';
|
||||
import formatName from '../utilities/formatName';
|
||||
import combineParentName from '../utilities/combineParentName';
|
||||
import { ArrayField, CodeField, DateField, EmailField, Field, fieldHasSubFields, fieldAffectsData, fieldIsPresentationalOnly, GroupField, NumberField, PointField, RadioField, RelationshipField, RichTextField, RowField, SelectField, TextareaField, TextField, UploadField, CollapsibleField } from '../../fields/config/types';
|
||||
import { ArrayField, CodeField, DateField, EmailField, Field, fieldHasSubFields, fieldAffectsData, fieldIsPresentationalOnly, GroupField, NumberField, PointField, RadioField, RelationshipField, RichTextField, RowField, SelectField, TextareaField, TextField, UploadField, CollapsibleField, TabsField } from '../../fields/config/types';
|
||||
import { toWords } from '../../utilities/formatLabels';
|
||||
import { Payload } from '../../index';
|
||||
import { SanitizedCollectionConfig } from '../../collections/config/types';
|
||||
@@ -151,6 +151,27 @@ function buildMutationInputType(payload: Payload, name: string, fields: Field[],
|
||||
|
||||
return acc;
|
||||
}, []),
|
||||
tabs: (field: TabsField) => field.tabs.reduce((acc, tab) => {
|
||||
const test = [
|
||||
...acc,
|
||||
...tab.fields.reduce((subAcc, rowField: TabsField) => {
|
||||
const getFieldSchema = fieldToSchemaMap[rowField.type];
|
||||
|
||||
if (getFieldSchema) {
|
||||
const fieldSchema = getFieldSchema(rowField);
|
||||
|
||||
return [
|
||||
...subAcc,
|
||||
fieldSchema,
|
||||
];
|
||||
}
|
||||
|
||||
return subAcc;
|
||||
}, []),
|
||||
];
|
||||
|
||||
return test;
|
||||
}, []),
|
||||
};
|
||||
|
||||
const fieldTypes = fields.reduce((schema, field: Field) => {
|
||||
@@ -160,21 +181,38 @@ function buildMutationInputType(payload: Payload, name: string, fields: Field[],
|
||||
if (getFieldSchema) {
|
||||
const fieldSchema = getFieldSchema(field);
|
||||
|
||||
if (fieldHasSubFields(field) && Array.isArray(fieldSchema)) {
|
||||
return fieldSchema.reduce((acc, subField, i) => {
|
||||
const currentSubField = field.fields[i];
|
||||
if (fieldAffectsData(currentSubField)) {
|
||||
if (Array.isArray(fieldSchema)) {
|
||||
let subFields: Field[] = [];
|
||||
|
||||
if (fieldHasSubFields(field)) {
|
||||
subFields = field.fields;
|
||||
}
|
||||
|
||||
if (field.type === 'tabs') {
|
||||
subFields = field.tabs.reduce((flattenedFields, tab) => {
|
||||
return [
|
||||
...flattenedFields,
|
||||
...tab.fields,
|
||||
];
|
||||
}, []);
|
||||
}
|
||||
|
||||
if (subFields.length > 0) {
|
||||
return fieldSchema.reduce((acc, subField, i) => {
|
||||
const currentSubField = subFields[i];
|
||||
if (fieldAffectsData(currentSubField)) {
|
||||
return {
|
||||
...acc,
|
||||
[currentSubField.name]: subField,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[currentSubField.name]: subField,
|
||||
...fieldSchema,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...acc,
|
||||
...fieldSchema,
|
||||
};
|
||||
}, schema);
|
||||
}, schema);
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldAffectsData(field)) {
|
||||
|
||||
@@ -443,6 +443,23 @@ function buildObjectType(payload: Payload, name: string, fields: Field[], parent
|
||||
|
||||
return subFieldSchema;
|
||||
}, {}),
|
||||
tabs: (field) => field.tabs.reduce((tabSchema, tab) => {
|
||||
return {
|
||||
...tabSchema,
|
||||
...tab.fields.reduce((subFieldSchema, subField) => {
|
||||
const buildSchemaType = fieldToSchemaMap[subField.type];
|
||||
|
||||
if (!fieldIsPresentationalOnly(subField) && buildSchemaType) {
|
||||
return {
|
||||
...subFieldSchema,
|
||||
[formatName(subField.name)]: buildSchemaType(subField),
|
||||
};
|
||||
}
|
||||
|
||||
return subFieldSchema;
|
||||
}, {}),
|
||||
};
|
||||
}, {}),
|
||||
};
|
||||
|
||||
const objectSchema = {
|
||||
|
||||
@@ -64,6 +64,15 @@ const buildFields = (label, fieldsToBuild) => fieldsToBuild.reduce((builtFields,
|
||||
...subFields,
|
||||
};
|
||||
}
|
||||
|
||||
if (field.type === 'tabs') {
|
||||
return field.tabs.reduce((fieldsWithTabFields, tab) => {
|
||||
return {
|
||||
...fieldsWithTabFields,
|
||||
...buildFields(label, tab.fields),
|
||||
};
|
||||
}, { ...builtFields });
|
||||
}
|
||||
}
|
||||
return builtFields;
|
||||
}, {});
|
||||
|
||||
@@ -35,7 +35,7 @@ const buildWhereInputType = (name: string, fields: Field[], parentName: string):
|
||||
if (getFieldSchema) {
|
||||
const fieldSchema = getFieldSchema(field);
|
||||
|
||||
if (fieldHasSubFields(field)) {
|
||||
if (fieldHasSubFields(field) || field.type === 'tabs') {
|
||||
return {
|
||||
...schema,
|
||||
...(fieldSchema.reduce((subFields, subField) => ({
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
NumberField, optionIsObject, PointField,
|
||||
RadioField, RelationshipField,
|
||||
RichTextField, RowField, SelectField,
|
||||
TabsField,
|
||||
TextareaField,
|
||||
TextField, UploadField,
|
||||
} from '../../fields/config/types';
|
||||
@@ -274,6 +275,38 @@ const fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
|
||||
|
||||
return rowSchema;
|
||||
}, []),
|
||||
tabs: (field: TabsField) => field.tabs.reduce((tabSchema, tab) => {
|
||||
return [
|
||||
...tabSchema,
|
||||
...tab.fields.reduce((rowSchema, subField) => {
|
||||
const getFieldSchema = fieldToSchemaMap(parentName)[subField.type];
|
||||
|
||||
if (getFieldSchema) {
|
||||
const rowFieldSchema = getFieldSchema(subField);
|
||||
|
||||
if (fieldHasSubFields(subField)) {
|
||||
return [
|
||||
...rowSchema,
|
||||
...rowFieldSchema,
|
||||
];
|
||||
}
|
||||
|
||||
if (fieldAffectsData(subField)) {
|
||||
return [
|
||||
...rowSchema,
|
||||
{
|
||||
key: subField.name,
|
||||
type: rowFieldSchema,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return rowSchema;
|
||||
}, []),
|
||||
];
|
||||
}, []),
|
||||
});
|
||||
|
||||
export default fieldToSchemaMap;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
import { Schema, SchemaDefinition, SchemaOptions } from 'mongoose';
|
||||
import { SanitizedConfig } from '../config/types';
|
||||
import { ArrayField, Block, BlockField, CheckboxField, CodeField, DateField, EmailField, Field, fieldAffectsData, GroupField, NumberField, PointField, RadioField, RelationshipField, RichTextField, RowField, SelectField, TextareaField, TextField, UploadField, fieldIsPresentationalOnly, NonPresentationalField, CollapsibleField } from '../fields/config/types';
|
||||
import { ArrayField, Block, BlockField, CheckboxField, CodeField, DateField, EmailField, Field, fieldAffectsData, GroupField, NumberField, PointField, RadioField, RelationshipField, RichTextField, RowField, SelectField, TextareaField, TextField, UploadField, fieldIsPresentationalOnly, NonPresentationalField, CollapsibleField, TabsField } from '../fields/config/types';
|
||||
import sortableFieldTypes from '../fields/sortableFieldTypes';
|
||||
|
||||
export type BuildSchemaOptions = {
|
||||
@@ -329,6 +329,23 @@ const fieldToSchemaMap = {
|
||||
}
|
||||
});
|
||||
|
||||
return newFields;
|
||||
},
|
||||
tabs: (field: TabsField, fields: SchemaDefinition, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions): SchemaDefinition => {
|
||||
const newFields = { ...fields };
|
||||
|
||||
field.tabs.forEach((tab) => {
|
||||
tab.fields.forEach((subField: Field) => {
|
||||
const fieldSchemaMap: FieldSchemaGenerator = fieldToSchemaMap[subField.type];
|
||||
|
||||
if (fieldSchemaMap && fieldAffectsData(subField)) {
|
||||
const fieldSchema = fieldSchemaMap(subField, fields, config, buildSchemaOptions);
|
||||
newFields[subField.name] = fieldSchema[subField.name];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
return newFields;
|
||||
},
|
||||
array: (field: ArrayField, fields: SchemaDefinition, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions) => {
|
||||
|
||||
Reference in New Issue
Block a user