Skip to content

Commit

Permalink
feat: add support for field grouping and annotations management (#1062)
Browse files Browse the repository at this point in the history
Co-authored-by: Rebecca Koenig <[email protected]>
  • Loading branch information
Bikappa and veu authored Apr 21, 2022
1 parent 55906c8 commit 81d52b7
Show file tree
Hide file tree
Showing 71 changed files with 6,435 additions and 204 deletions.
377 changes: 237 additions & 140 deletions README.md

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions docs/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,107 @@ migration.deleteContentType('reader');
author.editField('fullName')
.name('Name')
```
## editorLayout.TOO_MANY_TABS
When saving an editor layout with more than 5 tabs
**Example:**
```javascript
editorLayout.createFieldGroup('content', {
name: 'Content'
});
editorLayout.createFieldGroup('references', {
name: 'References'
});
editorLayout.createFieldGroup('settings', {
name: 'Settings'
});
editorLayout.createFieldGroup('seo', {
name: 'SEO'
});
editorLayout.createFieldGroup('keywords', {
name: 'Keywords'
});
editorLayout.createFieldGroup('extras', {
name: 'Extras'
});
```
## editorLayout.TAB_CONTROL_INVALID
When saving an editor layout with a tab that has `fieldset` control
**Example:**
```javascript
editorLayout.createFieldGroup('settings', {
name: 'Settings'
});
editorLayout.changeFieldGroupControl('settings', 'builtin', 'fieldset');
```
## editorLayout.FIELDSET_CONTROL_INVALID
When saving an editor layout with a field set that has `topLevelTab` control
**Example:**
```javascript
editorLayout.createFieldGroup('settings', {
name: 'Settings'
});
editorLayout.editFieldGroup('settings')
.createFieldGroup('seo')
.name('SEO');
editorLayout.changeFieldGroupControl('seo', 'builtin', 'topLevelTab');
```
## editorLayout.FIELD_GROUP_LEVEL_TOO_DEEP
When saving an editor layout with more than 2 levels deep
**Example:**
```javascript
editorLayout.createFieldGroup('settings', {
name: 'Settings'
});
editorLayout.editFieldGroup('settings')
.createFieldGroup('seo')
.name('SEO');
editorLayout.editFieldGroup('seo')
.createFieldGroup('keywords')
.name('Keywords');
```
## editorLayout.TOO_FEW_FIELD_GROUPS
When saving an editor layout with less than 2 field groups.
**Example:**
```javascript
editorLayout.createFieldGroup('content', {
name: 'Content'
});
```
## editorLayout.TOO_MANY_FIELD_SETS
When saving an editor layout with more than 15 field sets.
**Example:**
```javascript
editorLayout.createFieldGroup('content', {
name: 'Content'
});
for (let i = 0; i <= 15; i++) {
editorLayout.editFieldGroup('content')
.createFieldGroup('dummy-' + i)
.name('Dummy group ' + i)
}
```
27 changes: 27 additions & 0 deletions examples/35-create-editor-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = function (migration) {
const page = migration.createContentType('page').name('Page')
page.createField('name').name('Internal name').type('Symbol')
page.createField('title').name('Page title').type('Symbol')

// an editor layout can be created empty but not saved without adding at least one tab
const editorLayout = page.createEditorLayout()

editorLayout.createFieldGroup('content', {
name: 'Content'
})

editorLayout.changeFieldGroupControl('content', 'builtin', 'topLevelTab', {
helpText: 'Main content'
})

editorLayout.createFieldGroup('settings').name('Settings')

editorLayout.editFieldGroup('settings').createFieldGroup('seo').name('SEO')

editorLayout.changeFieldGroupControl('seo', 'builtin', 'fieldset', {
helpText: 'Search related fields',
collapsedByDefault: false
})

editorLayout.createFieldGroup('metadata').name('Metadata')
}
11 changes: 11 additions & 0 deletions examples/36-delete-editor-layout-tab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = function (migration) {
const page = migration.editContentType('page')
const editorLayout = page.editEditorLayout()
editorLayout.deleteFieldGroup('settings')

const metadata = editorLayout.editFieldGroup('metadata')
metadata.createFieldGroup('toBeDeleted', {
name: 'To be deleted'
})
editorLayout.deleteFieldGroup('toBeDeleted')
}
11 changes: 11 additions & 0 deletions examples/37-delete-editor-layout-field-set.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = function (migration) {
const page = migration.editContentType('page')
const editorLayout = page.editEditorLayout()

editorLayout.createFieldGroup('toBeDeleted', {
name: 'To be deleted'
})
editorLayout.deleteFieldGroup('toBeDeleted')

editorLayout.deleteFieldGroup('seo')
}
5 changes: 5 additions & 0 deletions examples/38-change-field-group-id-editor-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function (migration) {
const page = migration.editContentType('page')
const editorLayout = page.editEditorLayout()
editorLayout.changeFieldGroupId('metadata', 'info')
}
4 changes: 4 additions & 0 deletions examples/39-delete-editor-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = function (migration) {
const page = migration.editContentType('page')
page.deleteEditorLayout()
}
26 changes: 26 additions & 0 deletions examples/40-move-field-in-editor-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module.exports = function (migration) {
const myType = migration.createContentType('mytype').name('My type')
myType.createField('fieldA').name('Field A').type('Symbol')
myType.createField('fieldB').name('Field B').type('Symbol')
myType.createField('fieldC').name('Field C').type('Symbol')
myType.createField('fieldD').name('Field D').type('Symbol')
myType.createField('fieldE').name('Field D').type('Symbol')

// an editor layout can be created empty but not saved without adding at least one tab
const editorLayout = myType.createEditorLayout()

editorLayout.createFieldGroup('firsttab', {
name: 'First Tab'
})
editorLayout.createFieldGroup('secondtab', {
name: 'Second Tab'
})

editorLayout.editFieldGroup('secondtab').createFieldGroup('fieldset').name('Field Set')

editorLayout.moveField('fieldA').toTheTopOfFieldGroup('fieldset')
editorLayout.moveField('fieldB').beforeFieldGroup('fieldset')
editorLayout.moveField('fieldC').afterField('fieldA')
editorLayout.moveField('fieldE').beforeField('fieldC')
editorLayout.moveField('fieldE').toTheBottomOfFieldGroup()
}
10 changes: 10 additions & 0 deletions examples/41-move-field-in-existing-editor-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = function (migration) {
const myType = migration.editContentType('mytype')
const editorLayout = myType.editEditorLayout()

editorLayout.moveField('fieldA').toTheTopOfFieldGroup('firsttab')
editorLayout.moveField('fieldB').afterFieldGroup('fieldset')
editorLayout.moveField('fieldC').afterField('fieldB')
editorLayout.moveField('fieldE').beforeField('fieldC')
editorLayout.moveField('fieldE').toTheBottomOfFieldGroup()
}
9 changes: 9 additions & 0 deletions examples/42-assign-content-type-annotations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = function (migration) {
const annotatedContentType = migration.createContentType('annotated').name('Blog Post')
annotatedContentType.createField('name').name('Internal name').type('Symbol')
annotatedContentType.createField('title').name('Title').type('Symbol')
annotatedContentType.createField('body').name('Body').type('RichText')
annotatedContentType.createField('sources').name('Sources').type('Link').linkType('Entry')

annotatedContentType.setAnnotations(['Contentful:AggregateRoot'])
}
4 changes: 4 additions & 0 deletions examples/43-assign-field-annotations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = function (migration) {
const annotatedContentType = migration.editContentType('annotated')
annotatedContentType.editField('sources').setAnnotations(['Contentful:AggregateComponent'])
}
4 changes: 4 additions & 0 deletions examples/44-clear-field-annotations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = function (migration) {
const annotatedContentType = migration.editContentType('annotated')
annotatedContentType.editField('sources').clearAnnotations()
}
4 changes: 4 additions & 0 deletions examples/45-clear-content-type-annotations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = function (migration) {
const annotatedContentType = migration.editContentType('annotated')
annotatedContentType.clearAnnotations()
}
87 changes: 87 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ export interface Movement {
afterField(field: string): void
}

export interface EditorLayoutMovement {
toTheTopOfFieldGroup(groupId?: string): void
toTheBottomOfFieldGroup(groupId?: string): void
beforeField(field: string): void
afterField(field: string): void
beforeFieldGroup(groupId?: string): void
afterFieldGroup(groupId?: string): void
}

type FieldType =
| 'Symbol'
| 'Text'
Expand Down Expand Up @@ -91,6 +100,12 @@ export interface Field {

/** Sets the default value for the field. */
defaultValue(defaultValue: { [locale: string]: any }): Field

/** Set annotations associated with the field */
setAnnotations(annotationsIds: string[]): Field

/** Removes all annotaions associated with the field */
clearAnnotations(): Field
}

type LinkMimetype =
Expand Down Expand Up @@ -167,6 +182,11 @@ export interface ISidebarWidgetSettings {
[setting: string]: WidgetSettingsValue
}

export interface IFieldGroupWidgetSettings {
/** Instance settings for the field group widget as key-value pairs. */
[setting: string]: WidgetSettingsValue
}

export interface ContentType {
id: string
instanceId: string
Expand All @@ -178,6 +198,12 @@ export interface ContentType {
/** ID of the field to use as the display field for the content type. */
displayField(displayField: string): ContentType

/** Annotations associated with the content type */
setAnnotations(annotationIds: string[]): ContentType

/** Removes all annotaions associated with the field */
clearAnnotations(): ContentType

/** Creates a field with provided id. */
createField(id: string, init?: IFieldOptions): Field

Expand Down Expand Up @@ -300,6 +326,67 @@ export interface ContentType {
* Resets the sidebar of the content type to default
*/
resetSidebarToDefault(): void

/**
* Generates the default editor layout in the editor interface related to this content type.
*/
createEditorLayout(): EditorLayout

/**
* Returns the editor layout related to this content type.
*/
editEditorLayout(): EditorLayout

/**
* Removes editor layout and group controls from the editor interface of this content type.
*/
deleteEditorLayout(): void
}

export interface InitFieldGroupOptions {
name: string
}

export type FieldGroupUpdateFunction = (groupId: string, init?: InitFieldGroupOptions) => FieldGroup
export interface FieldGroup {
name: (name: string) => FieldGroup
/**
* Creates a field group nested to this one
*/
createFieldGroup: FieldGroupUpdateFunction
}

export interface EditorLayout {
/**
* Creates a field group at the top level of editor layout
* A group control is automatically generated
*/
createFieldGroup: FieldGroupUpdateFunction
/**
* Edits a field group
*/
editFieldGroup: FieldGroupUpdateFunction
/**
* Changes the identifier of a field group
*/
changeFieldGroupId: (currentId: string, newId: string) => void
/**
* Removes a field group from the editor layout
*/
deleteFieldGroup: (groupId: string) => void
/**
* Allows movements of a field in the editor layout
*/
moveField: (fieldId: string) => EditorLayoutMovement
/**
* Edits the field group control of a field group
*/
changeFieldGroupControl: (
groupId: string,
widgetNameSpace: 'builtin',
widgetId: 'fieldset' | 'topLevelTab',
settings?: IFieldGroupWidgetSettings
) => void
}

export interface IContentTypeOptions {
Expand Down
6 changes: 0 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 81d52b7

Please sign in to comment.