Skip to content

Commit c042538

Browse files
committed
add grouping block
1 parent 5c1a878 commit c042538

12 files changed

+619
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import { Client } from '@datocms/cli/lib/cma-client-node';
2+
3+
export default async function (client: Client) {
4+
console.log('Create new models/block models');
5+
6+
console.log(
7+
'Create block model "\uD83D\uDDC3\uFE0F Grouping Block" (`grouping_block`)',
8+
);
9+
await client.itemTypes.create(
10+
{
11+
id: 'TBuD6qQOSDy6i9dM3T_XEA',
12+
name: '\uD83D\uDDC3\uFE0F Grouping Block',
13+
api_key: 'grouping_block',
14+
modular_block: true,
15+
draft_saving_active: false,
16+
inverse_relationships_enabled: false,
17+
},
18+
{
19+
skip_menu_item_creation: true,
20+
schema_menu_item_id: 'XZDLSGZcSvGjkpzdfymBrg',
21+
},
22+
);
23+
24+
console.log(
25+
'Create block model "\uD83D\uDDC2\uFE0F Grouping Item Block" (`grouping_item_block`)',
26+
);
27+
await client.itemTypes.create(
28+
{
29+
id: 'BeM4dW2OQYWKc9iBZUyMeg',
30+
name: '\uD83D\uDDC2\uFE0F Grouping Item Block',
31+
api_key: 'grouping_item_block',
32+
modular_block: true,
33+
draft_saving_active: false,
34+
inverse_relationships_enabled: false,
35+
},
36+
{
37+
skip_menu_item_creation: true,
38+
schema_menu_item_id: 'HgENUoheQ_2DhBF6OFHfWg',
39+
},
40+
);
41+
42+
console.log('Creating new fields/fieldsets');
43+
44+
console.log(
45+
'Create Single-line string field "layout" (`layout`) in block model "\uD83D\uDDC3\uFE0F Grouping Block" (`grouping_block`)',
46+
);
47+
await client.fields.create('TBuD6qQOSDy6i9dM3T_XEA', {
48+
id: 'Wj5FlZbpRb23MFWVegBEoA',
49+
label: 'layout',
50+
field_type: 'string',
51+
api_key: 'layout',
52+
validators: {
53+
required: {},
54+
enum: {
55+
values: [
56+
'stack-untitled',
57+
'stack-titled',
58+
'accordion-closed',
59+
'accordion-open',
60+
'tabs',
61+
],
62+
},
63+
},
64+
appearance: {
65+
addons: [],
66+
editor: 'single_line',
67+
parameters: { heading: false, placeholder: null },
68+
},
69+
default_value: null,
70+
});
71+
72+
console.log(
73+
'Create Modular Content (Multiple blocks) field "Items" (`items`) in block model "\uD83D\uDDC3\uFE0F Grouping Block" (`grouping_block`)',
74+
);
75+
await client.fields.create('TBuD6qQOSDy6i9dM3T_XEA', {
76+
id: 'ZEgzOa7HRnqDBc-FgI0RFQ',
77+
label: 'Items',
78+
field_type: 'rich_text',
79+
api_key: 'items',
80+
validators: {
81+
rich_text_blocks: { item_types: ['BeM4dW2OQYWKc9iBZUyMeg'] },
82+
size: { min: 1 },
83+
},
84+
appearance: {
85+
addons: [],
86+
editor: 'rich_text',
87+
parameters: { start_collapsed: false },
88+
},
89+
default_value: null,
90+
});
91+
92+
console.log(
93+
'Create Single-line string field "Title" (`title`) in block model "\uD83D\uDDC2\uFE0F Grouping Item Block" (`grouping_item_block`)',
94+
);
95+
await client.fields.create('BeM4dW2OQYWKc9iBZUyMeg', {
96+
id: 'SKH6LSKZS12ZmF10nklCXg',
97+
label: 'Title',
98+
field_type: 'string',
99+
api_key: 'title',
100+
validators: { required: {} },
101+
appearance: {
102+
addons: [],
103+
editor: 'single_line',
104+
parameters: { heading: false, placeholder: null },
105+
},
106+
default_value: null,
107+
});
108+
109+
console.log(
110+
'Create Modular Content (Multiple blocks) field "Body" (`blocks`) in block model "\uD83D\uDDC2\uFE0F Grouping Item Block" (`grouping_item_block`)',
111+
);
112+
await client.fields.create('BeM4dW2OQYWKc9iBZUyMeg', {
113+
id: 'NTDc3vtCRzO5mEsE3gfmOQ',
114+
label: 'Body',
115+
field_type: 'rich_text',
116+
api_key: 'blocks',
117+
validators: {
118+
rich_text_blocks: {
119+
item_types: [
120+
'BRbU6VwTRgmG5SbwUs0rBg',
121+
'F60ZY1wFSW2qbvh99poj3g',
122+
'PAk40zGjQJCcDXXPgygUrA',
123+
'QYfZyBzIRWKxA1MinIR0aQ',
124+
'ZdBokLsWRgKKjHrKeJzdpw',
125+
'gezG9nO7SfaiWcWnp-HNqw',
126+
'0SxYNS2CR1it_5LHYWuEQg',
127+
],
128+
},
129+
size: { min: 1 },
130+
},
131+
appearance: {
132+
addons: [],
133+
editor: 'rich_text',
134+
parameters: { start_collapsed: false },
135+
},
136+
default_value: null,
137+
});
138+
139+
console.log('Update existing fields/fieldsets');
140+
141+
console.log(
142+
'Update Modular Content (Multiple blocks) field "Body" (`body_blocks`) in model "\uD83D\uDCD1 Page" (`page`)',
143+
);
144+
await client.fields.update('Q-z1nyMsQtC8Sr6w6J2oGw', {
145+
validators: {
146+
rich_text_blocks: {
147+
item_types: [
148+
'BRbU6VwTRgmG5SbwUs0rBg',
149+
'F60ZY1wFSW2qbvh99poj3g',
150+
'PAk40zGjQJCcDXXPgygUrA',
151+
'QYfZyBzIRWKxA1MinIR0aQ',
152+
'TBuD6qQOSDy6i9dM3T_XEA',
153+
'VZvVfu52RZK81WG0Dxp-FQ',
154+
'V80liDVtRC-UYgd3Sm-dXg',
155+
'ZdBokLsWRgKKjHrKeJzdpw',
156+
'gezG9nO7SfaiWcWnp-HNqw',
157+
'0SxYNS2CR1it_5LHYWuEQg',
158+
],
159+
},
160+
},
161+
});
162+
163+
console.log(
164+
'Update Modular Content (Multiple blocks) field "Body" (`body_blocks`) in model "\uD83C\uDFE0 Home" (`home_page`)',
165+
);
166+
await client.fields.update('pUj2PObgTyC-8X4lvZLMBA', {
167+
validators: {
168+
rich_text_blocks: {
169+
item_types: [
170+
'BRbU6VwTRgmG5SbwUs0rBg',
171+
'F60ZY1wFSW2qbvh99poj3g',
172+
'PAk40zGjQJCcDXXPgygUrA',
173+
'QYfZyBzIRWKxA1MinIR0aQ',
174+
'TBuD6qQOSDy6i9dM3T_XEA',
175+
'VZvVfu52RZK81WG0Dxp-FQ',
176+
'V80liDVtRC-UYgd3Sm-dXg',
177+
'ZdBokLsWRgKKjHrKeJzdpw',
178+
'gezG9nO7SfaiWcWnp-HNqw',
179+
'0SxYNS2CR1it_5LHYWuEQg',
180+
],
181+
},
182+
},
183+
});
184+
185+
console.log('Finalize models/block models');
186+
187+
console.log(
188+
'Update block model "\uD83D\uDDC3\uFE0F Grouping Block" (`grouping_block`)',
189+
);
190+
await client.itemTypes.update('TBuD6qQOSDy6i9dM3T_XEA', {
191+
presentation_title_field: { id: 'Wj5FlZbpRb23MFWVegBEoA', type: 'field' },
192+
});
193+
194+
console.log(
195+
'Update block model "\uD83D\uDDC2\uFE0F Grouping Item Block" (`grouping_item_block`)',
196+
);
197+
await client.itemTypes.update('BeM4dW2OQYWKc9iBZUyMeg', {
198+
presentation_title_field: { id: 'SKH6LSKZS12ZmF10nklCXg', type: 'field' },
199+
});
200+
}

datocms-environment.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
* @see docs/getting-started.md on how to use this file
44
* @see docs/decision-log/2023-10-24-datocms-env-file.md on why file is preferred over env vars
55
*/
6-
export const datocmsEnvironment = 'custom-file-paths';
6+
export const datocmsEnvironment = 'add-grouping-block';
77
export const datocmsBuildTriggerId = '30535';

src/blocks/Blocks.astro

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import TextBlock from './TextBlock/TextBlock.astro';
99
import TextImageBlock from './TextImageBlock/TextImageBlock.astro';
1010
import VideoBlock from './VideoBlock/VideoBlock.astro';
1111
import VideoEmbedBlock from './VideoEmbedBlock/VideoEmbedBlock.astro';
12+
import GroupingBlock from './GroupingBlock/GroupingBlock.astro';
1213
1314
const blocksByTypename = {
1415
ActionBlockRecord: ActionBlock,
@@ -20,6 +21,7 @@ const blocksByTypename = {
2021
TextImageBlockRecord: TextImageBlock,
2122
VideoBlockRecord: VideoBlock,
2223
VideoEmbedBlockRecord: VideoEmbedBlock,
24+
GroupingBlockRecord: GroupingBlock,
2325
};
2426
2527
interface Props {

src/blocks/Blocks.d.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
TextImageBlockFragment,
99
VideoBlockFragment,
1010
VideoEmbedBlockFragment,
11+
GroupingBlockFragment,
1112
} from '@lib/datocms/types';
1213

1314
export type AnyBlock =
@@ -19,4 +20,5 @@ export type AnyBlock =
1920
| TextBlockFragment
2021
| TextImageBlockFragment
2122
| VideoBlockFragment
22-
| VideoEmbedBlockFragment;
23+
| VideoEmbedBlockFragment
24+
| GroupingBlockFragment;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
import type { GroupingBlockFragment } from '@lib/datocms/types';
3+
import Blocks from '@blocks/Blocks.astro';
4+
import { Accordion, AccordionItem } from '@components/Accordion';
5+
import { Tabs, TabsTab, TabsPanel } from '@components/Tabs';
6+
import type { AnyBlock } from '@blocks/Blocks';
7+
8+
export interface Props {
9+
block: GroupingBlockFragment
10+
}
11+
12+
type GroupingItem = {
13+
title: string;
14+
blocks: AnyBlock[];
15+
};
16+
const isLayout = (layout: GroupingBlockFragment['layout']) => block.layout === layout;
17+
18+
const { block } = Astro.props;
19+
const items = block.items as GroupingItem[];
20+
---
21+
{ isLayout('stack-titled') && (
22+
items.map(item => (
23+
<section>
24+
<h2>{ item.title }</h2>
25+
<Blocks blocks={ item.blocks } />
26+
</section>
27+
))
28+
)}
29+
30+
{ isLayout('stack-untitled') && (
31+
items.map(item => (
32+
<Blocks blocks={ item.blocks } />
33+
))
34+
)}
35+
36+
{ (isLayout('accordion-open') || isLayout('accordion-closed')) && (
37+
<Accordion>
38+
{ items.map(item => (
39+
<AccordionItem
40+
name={ `block-${block.id}` }
41+
open={ isLayout('accordion-open') }
42+
>
43+
<Fragment slot="heading">{ item.title }</Fragment>
44+
<Fragment slot="body">
45+
<Blocks blocks={ item.blocks }/>
46+
</Fragment>
47+
</AccordionItem>
48+
))}
49+
</Accordion>
50+
)}
51+
52+
{ isLayout('tabs') && (
53+
<Tabs>
54+
{ items.map(item => (<>
55+
<TabsTab>{ item.title }</TabsTab>
56+
<TabsPanel>
57+
<Blocks blocks={ item.blocks }/>
58+
</TabsPanel>
59+
</>))}
60+
</Tabs>
61+
)}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#import 'src/blocks/GroupingBlock/GroupingItemBlock.fragment.graphql'
2+
3+
fragment GroupingBlock on GroupingBlockRecord {
4+
id
5+
layout
6+
items {
7+
__typename
8+
... on GroupingItemBlockRecord {
9+
...GroupingItemBlock
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)