@cooperco/cooper-component-library 0.1.68 → 0.1.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cms/0061-update-content-module-add-image-tables-testimonials.cjs +76 -0
- package/dist/cms/README.md +101 -31
- package/dist/cms/contentModule.query.ts +19 -1
- package/dist/cms/contentful/migrations/scripts/0061-update-content-module-add-image-tables-testimonials.cjs +76 -0
- package/dist/cms/contentful/queries/contentModule.query.js +19 -1
- package/dist/cms/contentful/queries/contentModule.query.ts +19 -1
- package/dist/cms/contentful/queries/testimonial.query.js +1 -0
- package/dist/cms/contentful/queries/testimonial.query.ts +1 -0
- package/dist/cms/migrations/scripts/0061-update-content-module-add-image-tables-testimonials.cjs +76 -0
- package/dist/cms/queries/contentModule.query.ts +19 -1
- package/dist/cms/queries/testimonial.query.ts +1 -0
- package/dist/cms/scripts/0061-update-content-module-add-image-tables-testimonials.cjs +76 -0
- package/dist/cms/testimonial.query.ts +1 -0
- package/dist/lib/component-lib.js +424 -421
- package/dist/lib/component-lib.umd.cjs +10 -10
- package/dist/lib/css/main.css +104 -1
- package/dist/lib/style.css +1 -1
- package/dist/types/src/components/ContentModule/ContentModule.d.ts +2 -0
- package/package.json +14 -14
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
// @ts-check
|
|
3
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
4
|
+
up: function (migration) {
|
|
5
|
+
const contentModule = migration.editContentType('contentModule')
|
|
6
|
+
|
|
7
|
+
// Add image field (appears below body copy)
|
|
8
|
+
contentModule
|
|
9
|
+
.createField('image')
|
|
10
|
+
.name('Image')
|
|
11
|
+
.type('Link')
|
|
12
|
+
.linkType('Entry')
|
|
13
|
+
.required(false)
|
|
14
|
+
.validations([{ linkContentType: ['image'] }])
|
|
15
|
+
contentModule.changeFieldControl('image', 'builtin', 'entryLinkEditor', {
|
|
16
|
+
helpText: 'Image that appears below the body copy text',
|
|
17
|
+
})
|
|
18
|
+
contentModule.moveField('image').afterField('bodyCopy')
|
|
19
|
+
|
|
20
|
+
// Update bodyCopy field to enable tables and embedded testimonials
|
|
21
|
+
contentModule.editField('bodyCopy').validations([
|
|
22
|
+
{
|
|
23
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
24
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
enabledNodeTypes: [
|
|
28
|
+
'ordered-list',
|
|
29
|
+
'unordered-list',
|
|
30
|
+
'hr',
|
|
31
|
+
'hyperlink',
|
|
32
|
+
'embedded-entry-inline',
|
|
33
|
+
'table',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
nodes: {
|
|
38
|
+
'embedded-entry-inline': [
|
|
39
|
+
{
|
|
40
|
+
linkContentType: ['testimonialModule'],
|
|
41
|
+
message: 'You can embed Testimonial entries.',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
])
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// @ts-check
|
|
50
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
51
|
+
down: async function (migration) {
|
|
52
|
+
const contentModule = migration.editContentType('contentModule')
|
|
53
|
+
|
|
54
|
+
// Remove image field
|
|
55
|
+
contentModule.deleteField('image')
|
|
56
|
+
|
|
57
|
+
// Revert bodyCopy field to original validations (without tables and testimonials)
|
|
58
|
+
contentModule.editField('bodyCopy').validations([
|
|
59
|
+
{
|
|
60
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
61
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
enabledNodeTypes: [
|
|
65
|
+
'ordered-list',
|
|
66
|
+
'unordered-list',
|
|
67
|
+
'hr',
|
|
68
|
+
'hyperlink',
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
nodes: {},
|
|
73
|
+
},
|
|
74
|
+
])
|
|
75
|
+
},
|
|
76
|
+
}
|
package/dist/cms/README.md
CHANGED
|
@@ -1,42 +1,112 @@
|
|
|
1
|
-
#
|
|
1
|
+
# GraphQL Queries
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This directory contains GraphQL queries for fetching content from Contentful CMS.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Obtain a Contentful CMA token
|
|
7
|
-
- Confirm and double check what space and environment you should be running these in
|
|
8
|
-
- Run `pnpm exec contentful-cli-migrations --environment-id <your-env-name> --space-id <space-id> --management-token <CMA-TOKEN> --initialise` on environment if not already and update `.env`
|
|
5
|
+
## Directory Structure
|
|
9
6
|
|
|
7
|
+
```
|
|
8
|
+
cms/contentful/queries/
|
|
9
|
+
├── index.ts # Barrel export file (manual updates required)
|
|
10
|
+
├── fragments.ts # Shared GraphQL fragments
|
|
11
|
+
├── *.query.ts # Individual component queries
|
|
12
|
+
└── README.md # This file
|
|
13
|
+
```
|
|
10
14
|
|
|
11
|
-
##
|
|
15
|
+
## How Queries Are Exported
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
- [Contentful Migration Reference Docs](https://github.com/contentful/contentful-migration/blob/main/README.md#reference-documentation)
|
|
15
|
-
- [Contentful Data Model](https://www.contentful.com/developers/docs/concepts/data-model/)
|
|
17
|
+
The query export system in this project is **semi-automatic**:
|
|
16
18
|
|
|
17
|
-
###
|
|
19
|
+
### The Process
|
|
18
20
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
- This should be with an up and a down function
|
|
22
|
-
- The up function updates the model
|
|
23
|
-
- The down function reversts your changes
|
|
24
|
-
- Run your migration on a test environment with the following command: `pnpm exec contentful-cli-migrations --environment-id <your-env-name> --space-id <space-id> --management-token <CMA-TOKEN>`
|
|
25
|
-
- Optional Flags:
|
|
26
|
-
- `--rollback`: Rolls back one migration.
|
|
21
|
+
1. **Individual Query Files** - Queries are defined in individual files with the pattern `*.query.ts`
|
|
22
|
+
- Example: `accordion.query.ts`, `carousel.query.ts`
|
|
27
23
|
|
|
28
|
-
|
|
24
|
+
2. **Manual Barrel Export** - Queries are re-exported through `index.ts`
|
|
25
|
+
- Uses wildcard exports: `export * from './accordion.query.js'`
|
|
26
|
+
- **Note:** Exports use `.js` extensions even though source files are `.ts` (ESM compatibility)
|
|
29
27
|
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
3. **Package-Level Export** - The barrel export is exposed via `package.json`:
|
|
29
|
+
```json
|
|
30
|
+
"./cms/contentful/graphql": {
|
|
31
|
+
"import": "./dist/cms/contentful/queries/index.js",
|
|
32
|
+
"types": "./dist/cms/contentful/queries/index.d.ts"
|
|
33
|
+
}
|
|
34
|
+
```
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
## Creating a New Query
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
|
|
38
|
+
### Steps Required
|
|
39
|
+
|
|
40
|
+
1. **Create Query File** - Add your query file: `yourComponent.query.ts`
|
|
41
|
+
|
|
42
|
+
2. **Define Query** - Follow the established pattern:
|
|
43
|
+
```typescript
|
|
44
|
+
import { gql } from 'graphql-tag'
|
|
45
|
+
import type { DocumentNode } from 'graphql'
|
|
46
|
+
import { someFragment } from './fragments.js' // If needed
|
|
47
|
+
|
|
48
|
+
export const getYourComponent: DocumentNode = gql`
|
|
49
|
+
${someFragment} // Include fragments if needed
|
|
50
|
+
query yourComponentQuery($id: String!, $preview: Boolean = false) {
|
|
51
|
+
yourComponent(id: $id, preview: $preview) {
|
|
52
|
+
__typename
|
|
53
|
+
# Add your fields here
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
`
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
3. **Update Barrel Export** - **MANUALLY ADD** export to `index.ts`:
|
|
60
|
+
```typescript
|
|
61
|
+
export * from './yourComponent.query.js'
|
|
62
|
+
```
|
|
63
|
+
- Maintain alphabetical order for consistency
|
|
64
|
+
- Use `.js` extension (not `.ts`)
|
|
65
|
+
|
|
66
|
+
### Query Naming Conventions
|
|
67
|
+
|
|
68
|
+
- **File Name:** `componentName.query.ts` (camelCase)
|
|
69
|
+
- **Export Name:** `getComponentName` (camelCase with `get` prefix)
|
|
70
|
+
- **Query Name:** `componentNameQuery` (camelCase with `Query` suffix)
|
|
71
|
+
|
|
72
|
+
### Example
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// accordion.query.ts
|
|
76
|
+
import { gql } from 'graphql-tag'
|
|
77
|
+
import type { DocumentNode } from 'graphql'
|
|
78
|
+
import { accordionItemFragment } from './fragments.js'
|
|
79
|
+
|
|
80
|
+
export const getAccordion: DocumentNode = gql`
|
|
81
|
+
${accordionItemFragment}
|
|
82
|
+
query accordionQuery($id: String!, $preview: Boolean = false) {
|
|
83
|
+
accordion(id: $id, preview: $preview) {
|
|
84
|
+
__typename
|
|
85
|
+
headline
|
|
86
|
+
accordionType
|
|
87
|
+
loadMoreButtonTitle
|
|
88
|
+
startOpen
|
|
89
|
+
accordionItemCollection {
|
|
90
|
+
items {
|
|
91
|
+
...accordionItemFragment
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
`
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Using Queries in Consumer Projects
|
|
100
|
+
|
|
101
|
+
Queries are consumed via the package export:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { getAccordion, getCarousel } from '@cooperco/cooper-component-library/cms/contentful/graphql'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Important Notes
|
|
108
|
+
|
|
109
|
+
- **Manual Export Required:** The system is NOT fully automatic - you MUST manually update `index.ts` when adding new queries
|
|
110
|
+
- **ESM Extensions:** Always use `.js` extensions in exports (even for `.ts` source files)
|
|
111
|
+
- **Preview Mode:** All queries support a `preview` parameter for Contentful preview API
|
|
112
|
+
- **Fragments:** Shared fragments are defined in `fragments.ts` and can be reused across queries
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { gql } from 'graphql-tag'
|
|
2
2
|
import type { DocumentNode } from 'graphql'
|
|
3
|
-
import { imageFragment, ctaFragment } from './fragments.js'
|
|
3
|
+
import { imageFragment, ctaFragment, videoFragment } from './fragments.js'
|
|
4
4
|
|
|
5
5
|
export const getContentModule: DocumentNode = gql`
|
|
6
6
|
${imageFragment}
|
|
7
7
|
${ctaFragment}
|
|
8
|
+
${videoFragment}
|
|
8
9
|
query contentModuleQuery($id: String!, $preview: Boolean = false) {
|
|
9
10
|
contentModule(id: $id, preview: $preview) {
|
|
10
11
|
alignment
|
|
11
12
|
logo {
|
|
12
13
|
...imageFragment
|
|
13
14
|
}
|
|
15
|
+
image {
|
|
16
|
+
...imageFragment
|
|
17
|
+
}
|
|
14
18
|
subHeadline
|
|
15
19
|
headline {
|
|
16
20
|
json
|
|
@@ -35,6 +39,20 @@ export const getContentModule: DocumentNode = gql`
|
|
|
35
39
|
sys {
|
|
36
40
|
id
|
|
37
41
|
}
|
|
42
|
+
... on TestimonialModule {
|
|
43
|
+
headline
|
|
44
|
+
quote
|
|
45
|
+
author
|
|
46
|
+
details
|
|
47
|
+
media {
|
|
48
|
+
... on Image {
|
|
49
|
+
...imageFragment
|
|
50
|
+
}
|
|
51
|
+
... on Video {
|
|
52
|
+
...videoFragment
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
38
56
|
}
|
|
39
57
|
}
|
|
40
58
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
// @ts-check
|
|
3
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
4
|
+
up: function (migration) {
|
|
5
|
+
const contentModule = migration.editContentType('contentModule')
|
|
6
|
+
|
|
7
|
+
// Add image field (appears below body copy)
|
|
8
|
+
contentModule
|
|
9
|
+
.createField('image')
|
|
10
|
+
.name('Image')
|
|
11
|
+
.type('Link')
|
|
12
|
+
.linkType('Entry')
|
|
13
|
+
.required(false)
|
|
14
|
+
.validations([{ linkContentType: ['image'] }])
|
|
15
|
+
contentModule.changeFieldControl('image', 'builtin', 'entryLinkEditor', {
|
|
16
|
+
helpText: 'Image that appears below the body copy text',
|
|
17
|
+
})
|
|
18
|
+
contentModule.moveField('image').afterField('bodyCopy')
|
|
19
|
+
|
|
20
|
+
// Update bodyCopy field to enable tables and embedded testimonials
|
|
21
|
+
contentModule.editField('bodyCopy').validations([
|
|
22
|
+
{
|
|
23
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
24
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
enabledNodeTypes: [
|
|
28
|
+
'ordered-list',
|
|
29
|
+
'unordered-list',
|
|
30
|
+
'hr',
|
|
31
|
+
'hyperlink',
|
|
32
|
+
'embedded-entry-inline',
|
|
33
|
+
'table',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
nodes: {
|
|
38
|
+
'embedded-entry-inline': [
|
|
39
|
+
{
|
|
40
|
+
linkContentType: ['testimonialModule'],
|
|
41
|
+
message: 'You can embed Testimonial entries.',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
])
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// @ts-check
|
|
50
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
51
|
+
down: async function (migration) {
|
|
52
|
+
const contentModule = migration.editContentType('contentModule')
|
|
53
|
+
|
|
54
|
+
// Remove image field
|
|
55
|
+
contentModule.deleteField('image')
|
|
56
|
+
|
|
57
|
+
// Revert bodyCopy field to original validations (without tables and testimonials)
|
|
58
|
+
contentModule.editField('bodyCopy').validations([
|
|
59
|
+
{
|
|
60
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
61
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
enabledNodeTypes: [
|
|
65
|
+
'ordered-list',
|
|
66
|
+
'unordered-list',
|
|
67
|
+
'hr',
|
|
68
|
+
'hyperlink',
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
nodes: {},
|
|
73
|
+
},
|
|
74
|
+
])
|
|
75
|
+
},
|
|
76
|
+
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { gql } from 'graphql-tag';
|
|
2
|
-
import { imageFragment, ctaFragment } from './fragments.js';
|
|
2
|
+
import { imageFragment, ctaFragment, videoFragment } from './fragments.js';
|
|
3
3
|
export const getContentModule = gql `
|
|
4
4
|
${imageFragment}
|
|
5
5
|
${ctaFragment}
|
|
6
|
+
${videoFragment}
|
|
6
7
|
query contentModuleQuery($id: String!, $preview: Boolean = false) {
|
|
7
8
|
contentModule(id: $id, preview: $preview) {
|
|
8
9
|
alignment
|
|
9
10
|
logo {
|
|
10
11
|
...imageFragment
|
|
11
12
|
}
|
|
13
|
+
image {
|
|
14
|
+
...imageFragment
|
|
15
|
+
}
|
|
12
16
|
subHeadline
|
|
13
17
|
headline {
|
|
14
18
|
json
|
|
@@ -33,6 +37,20 @@ export const getContentModule = gql `
|
|
|
33
37
|
sys {
|
|
34
38
|
id
|
|
35
39
|
}
|
|
40
|
+
... on TestimonialModule {
|
|
41
|
+
headline
|
|
42
|
+
quote
|
|
43
|
+
author
|
|
44
|
+
details
|
|
45
|
+
media {
|
|
46
|
+
... on Image {
|
|
47
|
+
...imageFragment
|
|
48
|
+
}
|
|
49
|
+
... on Video {
|
|
50
|
+
...videoFragment
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
36
54
|
}
|
|
37
55
|
}
|
|
38
56
|
}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { gql } from 'graphql-tag'
|
|
2
2
|
import type { DocumentNode } from 'graphql'
|
|
3
|
-
import { imageFragment, ctaFragment } from './fragments.js'
|
|
3
|
+
import { imageFragment, ctaFragment, videoFragment } from './fragments.js'
|
|
4
4
|
|
|
5
5
|
export const getContentModule: DocumentNode = gql`
|
|
6
6
|
${imageFragment}
|
|
7
7
|
${ctaFragment}
|
|
8
|
+
${videoFragment}
|
|
8
9
|
query contentModuleQuery($id: String!, $preview: Boolean = false) {
|
|
9
10
|
contentModule(id: $id, preview: $preview) {
|
|
10
11
|
alignment
|
|
11
12
|
logo {
|
|
12
13
|
...imageFragment
|
|
13
14
|
}
|
|
15
|
+
image {
|
|
16
|
+
...imageFragment
|
|
17
|
+
}
|
|
14
18
|
subHeadline
|
|
15
19
|
headline {
|
|
16
20
|
json
|
|
@@ -35,6 +39,20 @@ export const getContentModule: DocumentNode = gql`
|
|
|
35
39
|
sys {
|
|
36
40
|
id
|
|
37
41
|
}
|
|
42
|
+
... on TestimonialModule {
|
|
43
|
+
headline
|
|
44
|
+
quote
|
|
45
|
+
author
|
|
46
|
+
details
|
|
47
|
+
media {
|
|
48
|
+
... on Image {
|
|
49
|
+
...imageFragment
|
|
50
|
+
}
|
|
51
|
+
... on Video {
|
|
52
|
+
...videoFragment
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
38
56
|
}
|
|
39
57
|
}
|
|
40
58
|
}
|
package/dist/cms/migrations/scripts/0061-update-content-module-add-image-tables-testimonials.cjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
// @ts-check
|
|
3
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
4
|
+
up: function (migration) {
|
|
5
|
+
const contentModule = migration.editContentType('contentModule')
|
|
6
|
+
|
|
7
|
+
// Add image field (appears below body copy)
|
|
8
|
+
contentModule
|
|
9
|
+
.createField('image')
|
|
10
|
+
.name('Image')
|
|
11
|
+
.type('Link')
|
|
12
|
+
.linkType('Entry')
|
|
13
|
+
.required(false)
|
|
14
|
+
.validations([{ linkContentType: ['image'] }])
|
|
15
|
+
contentModule.changeFieldControl('image', 'builtin', 'entryLinkEditor', {
|
|
16
|
+
helpText: 'Image that appears below the body copy text',
|
|
17
|
+
})
|
|
18
|
+
contentModule.moveField('image').afterField('bodyCopy')
|
|
19
|
+
|
|
20
|
+
// Update bodyCopy field to enable tables and embedded testimonials
|
|
21
|
+
contentModule.editField('bodyCopy').validations([
|
|
22
|
+
{
|
|
23
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
24
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
enabledNodeTypes: [
|
|
28
|
+
'ordered-list',
|
|
29
|
+
'unordered-list',
|
|
30
|
+
'hr',
|
|
31
|
+
'hyperlink',
|
|
32
|
+
'embedded-entry-inline',
|
|
33
|
+
'table',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
nodes: {
|
|
38
|
+
'embedded-entry-inline': [
|
|
39
|
+
{
|
|
40
|
+
linkContentType: ['testimonialModule'],
|
|
41
|
+
message: 'You can embed Testimonial entries.',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
])
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// @ts-check
|
|
50
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
51
|
+
down: async function (migration) {
|
|
52
|
+
const contentModule = migration.editContentType('contentModule')
|
|
53
|
+
|
|
54
|
+
// Remove image field
|
|
55
|
+
contentModule.deleteField('image')
|
|
56
|
+
|
|
57
|
+
// Revert bodyCopy field to original validations (without tables and testimonials)
|
|
58
|
+
contentModule.editField('bodyCopy').validations([
|
|
59
|
+
{
|
|
60
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
61
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
enabledNodeTypes: [
|
|
65
|
+
'ordered-list',
|
|
66
|
+
'unordered-list',
|
|
67
|
+
'hr',
|
|
68
|
+
'hyperlink',
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
nodes: {},
|
|
73
|
+
},
|
|
74
|
+
])
|
|
75
|
+
},
|
|
76
|
+
}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { gql } from 'graphql-tag'
|
|
2
2
|
import type { DocumentNode } from 'graphql'
|
|
3
|
-
import { imageFragment, ctaFragment } from './fragments.js'
|
|
3
|
+
import { imageFragment, ctaFragment, videoFragment } from './fragments.js'
|
|
4
4
|
|
|
5
5
|
export const getContentModule: DocumentNode = gql`
|
|
6
6
|
${imageFragment}
|
|
7
7
|
${ctaFragment}
|
|
8
|
+
${videoFragment}
|
|
8
9
|
query contentModuleQuery($id: String!, $preview: Boolean = false) {
|
|
9
10
|
contentModule(id: $id, preview: $preview) {
|
|
10
11
|
alignment
|
|
11
12
|
logo {
|
|
12
13
|
...imageFragment
|
|
13
14
|
}
|
|
15
|
+
image {
|
|
16
|
+
...imageFragment
|
|
17
|
+
}
|
|
14
18
|
subHeadline
|
|
15
19
|
headline {
|
|
16
20
|
json
|
|
@@ -35,6 +39,20 @@ export const getContentModule: DocumentNode = gql`
|
|
|
35
39
|
sys {
|
|
36
40
|
id
|
|
37
41
|
}
|
|
42
|
+
... on TestimonialModule {
|
|
43
|
+
headline
|
|
44
|
+
quote
|
|
45
|
+
author
|
|
46
|
+
details
|
|
47
|
+
media {
|
|
48
|
+
... on Image {
|
|
49
|
+
...imageFragment
|
|
50
|
+
}
|
|
51
|
+
... on Video {
|
|
52
|
+
...videoFragment
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
38
56
|
}
|
|
39
57
|
}
|
|
40
58
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
// @ts-check
|
|
3
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
4
|
+
up: function (migration) {
|
|
5
|
+
const contentModule = migration.editContentType('contentModule')
|
|
6
|
+
|
|
7
|
+
// Add image field (appears below body copy)
|
|
8
|
+
contentModule
|
|
9
|
+
.createField('image')
|
|
10
|
+
.name('Image')
|
|
11
|
+
.type('Link')
|
|
12
|
+
.linkType('Entry')
|
|
13
|
+
.required(false)
|
|
14
|
+
.validations([{ linkContentType: ['image'] }])
|
|
15
|
+
contentModule.changeFieldControl('image', 'builtin', 'entryLinkEditor', {
|
|
16
|
+
helpText: 'Image that appears below the body copy text',
|
|
17
|
+
})
|
|
18
|
+
contentModule.moveField('image').afterField('bodyCopy')
|
|
19
|
+
|
|
20
|
+
// Update bodyCopy field to enable tables and embedded testimonials
|
|
21
|
+
contentModule.editField('bodyCopy').validations([
|
|
22
|
+
{
|
|
23
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
24
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
enabledNodeTypes: [
|
|
28
|
+
'ordered-list',
|
|
29
|
+
'unordered-list',
|
|
30
|
+
'hr',
|
|
31
|
+
'hyperlink',
|
|
32
|
+
'embedded-entry-inline',
|
|
33
|
+
'table',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
nodes: {
|
|
38
|
+
'embedded-entry-inline': [
|
|
39
|
+
{
|
|
40
|
+
linkContentType: ['testimonialModule'],
|
|
41
|
+
message: 'You can embed Testimonial entries.',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
])
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
// @ts-check
|
|
50
|
+
/** @type { import('contentful-migration').MigrationFunction } */
|
|
51
|
+
down: async function (migration) {
|
|
52
|
+
const contentModule = migration.editContentType('contentModule')
|
|
53
|
+
|
|
54
|
+
// Remove image field
|
|
55
|
+
contentModule.deleteField('image')
|
|
56
|
+
|
|
57
|
+
// Revert bodyCopy field to original validations (without tables and testimonials)
|
|
58
|
+
contentModule.editField('bodyCopy').validations([
|
|
59
|
+
{
|
|
60
|
+
enabledMarks: ['bold', 'italic', 'underline'],
|
|
61
|
+
message: 'Only bold, italic, and underline marks are allowed',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
enabledNodeTypes: [
|
|
65
|
+
'ordered-list',
|
|
66
|
+
'unordered-list',
|
|
67
|
+
'hr',
|
|
68
|
+
'hyperlink',
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
nodes: {},
|
|
73
|
+
},
|
|
74
|
+
])
|
|
75
|
+
},
|
|
76
|
+
}
|