@@ -6,7 +6,7 @@ import isEmpty from 'lodash/isEmpty'
66* and strip it out from the key to clean things up and make it easier for the backend
77*/
88const gatherSelected = ( selected , block = null ) => {
9- return Object . assign ( { } , ... Object . keys ( selected ) . map ( key => {
9+ return Object . keys ( selected ) . map ( key => {
1010 if ( block ) {
1111 if ( isBlockField ( key , block . id ) ) {
1212 return {
@@ -19,7 +19,7 @@ const gatherSelected = (selected, block = null) => {
1919 }
2020 }
2121 return null
22- } ) . filter ( x => x ) )
22+ } ) . filter ( x => x )
2323}
2424
2525export const isBlockField = ( name , id ) => {
@@ -31,83 +31,85 @@ export const stripOutBlockNamespace = (name, id) => {
3131 return nameWithoutBlock . match ( / ] / gi) . length > 1 ? nameWithoutBlock . replace ( ']' , '' ) : nameWithoutBlock . slice ( 0 , - 1 )
3232}
3333
34- export const buildBlock = ( block , rootState , isRepeater = false ) => {
35- const repeaterIds = Object . keys ( rootState . repeaters . repeaters ) ;
36- const repeaters = Object . assign ( { } , ...repeaterIds . filter ( repeaterKey => {
37- return repeaterKey . startsWith ( 'blocks-' + block . id + '|' )
34+ export const buildBlock = ( block , rootState , isRepeater = false , subRepeaters = null , childKey ) => {
35+ const parentRepeaters = subRepeaters || rootState . repeaters . repeaters ;
36+ subRepeaters = { } ;
37+ const repeaterIds = Object . keys ( parentRepeaters ) ;
38+ const prefix = 'blocks-' + block . id + '|' ;
39+ const repeaters = repeaterIds . filter ( repeaterKey => {
40+ return repeaterKey . startsWith ( prefix )
3841 } )
39- . map ( repeaterKey => {
40- return {
41- [ repeaterKey . replace ( 'blocks-' + block . id + '|' , '' ) ] : rootState . repeaters . repeaters [ repeaterKey ] . map ( repeaterItem => {
42- return buildBlock ( repeaterItem , rootState , true )
42+ . reduce ( ( acc , repeaterKey ) => {
43+ if ( repeaterKey . split ( '|' ) . length > 2 ) {
44+ subRepeaters [ repeaterKey . replace ( prefix , '' ) ] = parentRepeaters [ repeaterKey ] ;
45+ } else {
46+ acc [ repeaterKey . replace ( prefix , '' ) ] = parentRepeaters [ repeaterKey ] . map ( repeaterItem => {
47+ return buildBlock ( repeaterItem , rootState , true , subRepeaters )
4348 } )
4449 }
45- } ) )
50+
51+ return acc
52+ } , { } )
4653
4754 const blockIds = Object . keys ( rootState . blocks . blocks ) ;
48- const blocks = Object . assign ( { } , ...blockIds . filter ( blockKey => {
49- return blockKey . startsWith ( 'blocks-' + block . id )
50- } ) . map ( blockKey => {
55+ const blocks = blockIds . filter ( blockKey => {
56+ return blockKey . startsWith ( prefix )
57+ } ) . reduce ( ( acc , blockKey ) => {
58+ acc . push ( ...rootState . blocks . blocks [ blockKey ] . map ( repeaterItem => {
59+ if ( isRepeater ) {
60+ repeaterItem = { ...repeaterItem , name : repeaterItem . name . replace ( prefix , '' ) }
61+ }
62+ return buildBlock ( repeaterItem , rootState , false , null , blockKey . replace ( prefix , '' ) )
63+ } ) ) ;
64+ return acc ;
65+ } , [ ] )
66+
67+ // retrieve all fields for this block and clean up field names
68+ const content = rootState . form . fields . filter ( ( field ) => {
69+ return isBlockField ( field . name , block . id )
70+ } ) . map ( ( field ) => {
5171 return {
52- [ blockKey . replace ( 'blocks-' + block . id + '|' , '' ) ] : rootState . blocks . blocks [ blockKey ] . map ( repeaterItem => {
53- return buildBlock ( repeaterItem , rootState )
54- } )
72+ name : stripOutBlockNamespace ( field . name , block . id ) ,
73+ value : field . value
5574 }
56- } ) )
75+ } ) . reduce ( ( content , field ) => {
76+ content [ field . name ] = field . value
77+ return content
78+ } , { } ) ;
5779
58- return {
80+ const base = {
5981 id : block . id ,
60- type : block . type ,
61- is_repeater : isRepeater ,
6282 editor_name : block . name ,
63- // retrieve all fields for this block and clean up field names
64- content : rootState . form . fields . filter ( ( field ) => {
65- return isBlockField ( field . name , block . id )
66- } ) . map ( ( field ) => {
67- return {
68- name : stripOutBlockNamespace ( field . name , block . id ) ,
69- value : field . value
70- }
71- } ) . reduce ( ( content , field ) => {
72- content [ field . name ] = field . value
73- return content
74- } , { } ) ,
7583 medias : gatherSelected ( rootState . mediaLibrary . selected , block ) ,
7684 browsers : gatherSelected ( rootState . browser . selected , block ) ,
7785 // gather repeater blocks from the repeater store module
78- blocks : { ...repeaters , ...blocks }
86+ blocks,
87+ repeaters,
7988 }
89+ return isRepeater
90+ ? { ...content , ...base , is_repeater : true , repeater_target_id : block . repeater_target_id }
91+ : { ...base , type : block . type , content, child_key : childKey }
8092}
8193
8294export const isBlockEmpty = ( blockData ) => {
8395 return isEmpty ( blockData . content ) && isEmpty ( blockData . browsers ) && isEmpty ( blockData . medias ) && isEmpty ( blockData . blocks )
8496}
8597
86- export const gatherRepeaters = ( rootState ) => {
87- return Object . assign ( { } , ...Object . keys ( rootState . repeaters . repeaters ) . filter ( repeaterKey => {
98+
99+ const buildRepeaters = ( repeaters , rootState ) => {
100+ return Object . keys ( repeaters ) . filter ( repeaterKey => {
88101 // we start by filtering out repeater blocks
89102 return ! repeaterKey . startsWith ( 'blocks-' )
90- } ) . map ( repeater => {
91- return {
92- [ repeater ] : rootState . repeaters . repeaters [ repeater ] . map ( repeaterItem => {
93- // and for each repeater we build a block for each item
94- const repeaterBlock = buildBlock ( repeaterItem , rootState )
95-
96- // we want to inline fields in the repeater object
97- // and we don't need the type of component used
98- const fields = repeaterBlock . content
99- delete repeaterBlock . content
100- delete repeaterBlock . type
101-
102- // and lastly we want to keep the id to update existing items
103- fields . id = repeaterItem . id
104- // If the repeater has a target id we are referencing an existing item.
105- fields . repeater_target_id = repeaterItem . repeater_target_id ?? null
106-
107- return Object . assign ( repeaterBlock , fields )
108- } )
109- }
110- } ) )
103+ } ) . reduce ( ( acc , repeater ) => {
104+ acc [ repeater ] = repeaters [ repeater ] . map ( repeaterItem => {
105+ // and for each repeater we build a block for each item
106+ return buildBlock ( repeaterItem , rootState , true )
107+ } )
108+ return acc ;
109+ } , { } )
110+ }
111+ export const gatherRepeaters = ( rootState ) => {
112+ return buildRepeaters ( rootState . repeaters . repeaters , rootState )
111113}
112114
113115export const gatherBlocks = ( rootState ) => {
@@ -124,7 +126,7 @@ export const gatherBlocks = (rootState) => {
124126}
125127
126128export const getFormFields = ( rootState ) => {
127- const fields = rootState . form . fields . filter ( ( field ) => {
129+ return rootState . form . fields . filter ( ( field ) => {
128130 // we start by filtering out blocks related form fields
129131 return ! field . name . startsWith ( 'blocks[' ) && ! field . name . startsWith ( 'mediaMeta[' )
130132 } ) . reduce ( ( fields , field ) => {
@@ -133,12 +135,10 @@ export const getFormFields = (rootState) => {
133135 fields [ field . name ] = field . value
134136 return fields
135137 } , { } )
136-
137- return fields
138138}
139139
140140export const getModalFormFields = ( rootState ) => {
141- const fields = rootState . form . modalFields . filter ( ( field ) => {
141+ return rootState . form . modalFields . filter ( ( field ) => {
142142 // we start by filtering out blocks related form fields
143143 return ! field . name . startsWith ( 'blocks[' ) && ! field . name . startsWith ( 'mediaMeta[' )
144144 } ) . reduce ( ( fields , field ) => {
@@ -147,8 +147,6 @@ export const getModalFormFields = (rootState) => {
147147 fields [ field . name ] = field . value
148148 return fields
149149 } , { } )
150-
151- return fields
152150}
153151
154152export const getFormData = ( rootState ) => {
@@ -159,7 +157,7 @@ export const getFormData = (rootState) => {
159157 // - publication properties
160158 // - selected medias and browsers
161159 // - created blocks and repeaters
162- const data = Object . assign ( fields , {
160+ return Object . assign ( fields , {
163161 cmsSaveType : rootState . form . type ,
164162 published : rootState . publication . published ,
165163 public : rootState . publication . visibility === 'public' ,
@@ -172,6 +170,4 @@ export const getFormData = (rootState) => {
172170 blocks : gatherBlocks ( rootState ) ,
173171 repeaters : gatherRepeaters ( rootState )
174172 } )
175-
176- return data
177173}
0 commit comments