feat: default tab labels from name (#3129)
This commit is contained in:
@@ -25,14 +25,14 @@ _Tabs field type used to separate Hero fields from Page Layout_
|
|||||||
|
|
||||||
#### Tab-specific Config
|
#### Tab-specific Config
|
||||||
|
|
||||||
Each tab has its own required `label` and `fields` array. You can also optionally pass a `description` to render within each individual tab.
|
Each tab must have either a `name` or `label` and the required `fields` array. You can also optionally pass a `description` to render within each individual tab.
|
||||||
|
|
||||||
| Option | Description |
|
| Option | Description |
|
||||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| ---------------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| **`name`** | An optional property name to be used when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
| **`name`** | Groups field data into an object when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||||
| **`label`** \* | The label to render on the tab itself. |
|
| **`label`** | The label to render on the tab itself. Required when name is undefined, defaults to name converted to words. |
|
||||||
| **`fields`** \* | The fields to render within this tab. |
|
| **`fields`** \* | The fields to render within this tab. |
|
||||||
| **`description`** | Optionally render a description within this tab to describe the contents of the tab itself. |
|
| **`description`** | Optionally render a description within this tab to describe the contents of the tab itself. |
|
||||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). (`name` must be present) |
|
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). (`name` must be present) |
|
||||||
|
|
||||||
_\* An asterisk denotes that a property is required._
|
_\* An asterisk denotes that a property is required._
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { formatLabels, toWords } from '../../utilities/formatLabels';
|
import { formatLabels, toWords } from '../../utilities/formatLabels';
|
||||||
import { MissingFieldType, InvalidFieldRelationship, InvalidFieldName } from '../../errors';
|
import { InvalidFieldName, InvalidFieldRelationship, MissingFieldType } from '../../errors';
|
||||||
import { baseBlockFields } from '../baseFields/baseBlockFields';
|
import { baseBlockFields } from '../baseFields/baseBlockFields';
|
||||||
import validations from '../validations';
|
import validations from '../validations';
|
||||||
import { baseIDField } from '../baseFields/baseIDField';
|
import { baseIDField } from '../baseFields/baseIDField';
|
||||||
import { Field, fieldAffectsData } from './types';
|
import { Field, fieldAffectsData, tabHasName } from './types';
|
||||||
import withCondition from '../../admin/components/forms/withCondition';
|
import withCondition from '../../admin/components/forms/withCondition';
|
||||||
|
|
||||||
const sanitizeFields = (fields: Field[], validRelationships: string[]): Field[] => {
|
const sanitizeFields = (fields: Field[], validRelationships: string[]): Field[] => {
|
||||||
@@ -87,6 +87,9 @@ const sanitizeFields = (fields: Field[], validRelationships: string[]): Field[]
|
|||||||
if (field.type === 'tabs') {
|
if (field.type === 'tabs') {
|
||||||
field.tabs = field.tabs.map((tab) => {
|
field.tabs = field.tabs.map((tab) => {
|
||||||
const unsanitizedTab = { ...tab };
|
const unsanitizedTab = { ...tab };
|
||||||
|
if (tabHasName(tab) && typeof tab.label === 'undefined') {
|
||||||
|
unsanitizedTab.label = toWords(tab.name);
|
||||||
|
}
|
||||||
unsanitizedTab.fields = sanitizeFields(tab.fields, validRelationships);
|
unsanitizedTab.fields = sanitizeFields(tab.fields, validRelationships);
|
||||||
return unsanitizedTab;
|
return unsanitizedTab;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -224,13 +224,14 @@ export const collapsible = baseField.keys({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const tab = baseField.keys({
|
const tab = baseField.keys({
|
||||||
name: joi.string().when('localized', { is: joi.exist(), then: joi.required() }),
|
name: joi.string()
|
||||||
|
.when('localized', { is: joi.exist(), then: joi.required() }),
|
||||||
localized: joi.boolean(),
|
localized: joi.boolean(),
|
||||||
interfaceName: joi.string().when('name', { not: joi.exist(), then: joi.forbidden() }),
|
interfaceName: joi.string().when('name', { not: joi.exist(), then: joi.forbidden() }),
|
||||||
label: joi.alternatives().try(
|
label: joi.alternatives().try(
|
||||||
joi.string(),
|
joi.string(),
|
||||||
joi.object().pattern(joi.string(), [joi.string()]),
|
joi.object().pattern(joi.string(), [joi.string()]),
|
||||||
).required(),
|
).when('name', { is: joi.not(), then: joi.required() }),
|
||||||
fields: joi.array().items(joi.link('#field')).required(),
|
fields: joi.array().items(joi.link('#field')).required(),
|
||||||
description: joi.alternatives().try(
|
description: joi.alternatives().try(
|
||||||
joi.string(),
|
joi.string(),
|
||||||
|
|||||||
@@ -135,7 +135,6 @@ const TabsFields: CollectionConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'namedTabWithDefaultValue',
|
name: 'namedTabWithDefaultValue',
|
||||||
label: 'Tab with Default Value',
|
|
||||||
description: 'This tab has a name, which should namespace the contained fields.',
|
description: 'This tab has a name, which should namespace the contained fields.',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -159,7 +158,6 @@ const TabsFields: CollectionConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'accessControlTab',
|
name: 'accessControlTab',
|
||||||
label: 'Access Control Tab',
|
|
||||||
access: {
|
access: {
|
||||||
read: () => false,
|
read: () => false,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user