slice-machine-ui 1.22.2 → 1.22.3-alpha.chore-introduce-css-modules.1

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.
Files changed (168) hide show
  1. package/.depcheckrc +4 -1
  2. package/.eslintignore +1 -0
  3. package/components/DeleteVariationModal/index.tsx +12 -11
  4. package/components/Forms/CreateSliceModal/CreateSliceModal.tsx +2 -5
  5. package/components/Forms/RenameCustomTypeModal/RenameCustomTypeModal.tsx +9 -5
  6. package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +12 -11
  7. package/components/ItemHeader/index.tsx +1 -0
  8. package/components/ListItem/index.tsx +5 -2
  9. package/components/ScreenshotChangesModal/VariationDropZone.tsx +31 -9
  10. package/components/ScreenshotChangesModal/index.tsx +3 -0
  11. package/components/ScreenshotChangesModal/useCustomScreenshot.tsx +5 -5
  12. package/components/Simulator/index.tsx +9 -3
  13. package/lib/builders/CustomTypeBuilder/SliceZone/SlicesTemplatesModal.tsx +2 -2
  14. package/lib/builders/CustomTypeBuilder/SliceZone/UpdateSliceZoneModal.tsx +2 -2
  15. package/lib/builders/CustomTypeBuilder/SliceZone/index.tsx +12 -20
  16. package/lib/builders/CustomTypeBuilder/TabModal/update.tsx +3 -1
  17. package/lib/builders/CustomTypeBuilder/TabZone/index.tsx +119 -52
  18. package/lib/builders/CustomTypeBuilder/index.tsx +39 -42
  19. package/lib/builders/SliceBuilder/FieldZones/index.tsx +81 -56
  20. package/lib/builders/SliceBuilder/Sidebar/AddVariationModal.tsx +24 -16
  21. package/lib/builders/SliceBuilder/Sidebar/index.tsx +44 -46
  22. package/lib/builders/SliceBuilder/SimulatorButton/index.tsx +4 -28
  23. package/lib/builders/SliceBuilder/index.tsx +10 -96
  24. package/lib/builders/common/Zone/Card/components/Hints/CodeBlock.tsx +5 -1
  25. package/lib/builders/common/Zone/Card/components/NewField.tsx +16 -15
  26. package/lib/builders/common/Zone/Card/index.jsx +2 -0
  27. package/lib/builders/common/Zone/index.jsx +3 -1
  28. package/lib/models/common/ComponentUI.ts +0 -14
  29. package/lib/models/common/CustomType/sliceZone.ts +0 -29
  30. package/lib/models/common/CustomType/tab.ts +10 -142
  31. package/lib/models/common/widgets/Group/ListItem/index.jsx +61 -23
  32. package/out/404.html +1 -1
  33. package/out/_next/static/QLcban0JdGEoFu6NgapR9/_buildManifest.js +1 -0
  34. package/out/_next/static/chunks/065a3ddb-9a38ca0d60f0bf2f.js +1 -0
  35. package/out/_next/static/chunks/183-4feb6bb3eddbc768.js +1 -0
  36. package/out/_next/static/chunks/18539003-7b2711e6c51d6fac.js +97 -0
  37. package/out/_next/static/chunks/1cc2734a-2c5b6c0367fcde86.js +1 -0
  38. package/out/_next/static/chunks/25-8fedd33ad9b6de5b.js +1 -0
  39. package/out/_next/static/chunks/286-ed90373e9a469944.js +1 -0
  40. package/out/_next/static/chunks/318-541db69860d31138.js +1 -0
  41. package/out/_next/static/chunks/{505-3f1cf09a086dcba8.js → 376-0ed5822f8afcaa7c.js} +3 -3
  42. package/out/_next/static/chunks/4c744e84-e3161d754618373f.js +1 -0
  43. package/out/_next/static/chunks/50-cfc2514205b86001.js +1 -0
  44. package/out/_next/static/chunks/543-f8766685f7f451e2.js +1 -0
  45. package/out/_next/static/chunks/59b4e022-7a3b5554b806349f.js +1 -0
  46. package/out/_next/static/chunks/696-b12edad30a3617e5.js +31 -0
  47. package/out/_next/static/chunks/727-15cf3f2fea9a37e5.js +1 -0
  48. package/out/_next/static/chunks/731-501990ebe6a71b32.js +1 -0
  49. package/out/_next/static/chunks/904-ccd8ca3368ce29fc.js +1 -0
  50. package/out/_next/static/chunks/{918-38d08f1e885b222d.js → 918-5bb55fb464e34768.js} +1 -1
  51. package/out/_next/static/chunks/f36c6662-03bb5e9d9aa0b0aa.js +1 -0
  52. package/out/_next/static/chunks/pages/_app-3bb7f58b43c87166.js +430 -0
  53. package/out/_next/static/chunks/pages/changelog-68d115a14f1423d7.js +1 -0
  54. package/out/_next/static/chunks/pages/{changes-52c9d917808d1461.js → changes-1cf9e7888029f113.js} +1 -1
  55. package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-3a37eb3373bb8823.js → [customTypeId]-3f862ad6111a1fc0.js} +1 -1
  56. package/out/_next/static/chunks/pages/{custom-types-2f5664d9492b13fb.js → custom-types-94b8f8dbf7727412.js} +1 -1
  57. package/out/_next/static/chunks/pages/{index-d8e3a2c0d712904f.js → index-64cfb8b0948ba8ef.js} +1 -1
  58. package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-733f3890c0466a05.js → [pageTypeId]-d1ffca11c42f2603.js} +1 -1
  59. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-897ca93c114a1435.js +1 -0
  60. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-73dd999915509965.js +1 -0
  61. package/out/_next/static/chunks/pages/slices-7b09cb5130c63bb3.js +1 -0
  62. package/out/_next/static/css/37153180c3b0dd66.css +1 -0
  63. package/out/_next/static/css/538ecf581b0e7c11.css +1 -0
  64. package/out/_next/static/css/{5da5d3cd7a87c3cf.css → 72465cc1225f28a2.css} +1 -1
  65. package/out/_next/static/css/{77abb01eee0e43a7.css → b22c0750c14cc089.css} +1 -1
  66. package/out/_next/static/css/f8eb526e10bc2441.css +1 -0
  67. package/out/changelog.html +1 -1
  68. package/out/changes.html +1 -1
  69. package/out/custom-types/[customTypeId].html +1 -1
  70. package/out/custom-types.html +1 -1
  71. package/out/index.html +1 -1
  72. package/out/labs.html +1 -1
  73. package/out/page-types/[pageTypeId].html +1 -1
  74. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  75. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  76. package/out/slices.html +1 -1
  77. package/package.json +21 -11
  78. package/pages/slices/[lib]/[sliceName]/[variation]/index.tsx +25 -11
  79. package/pages/slices/[lib]/[sliceName]/[variation]/simulator.tsx +12 -9
  80. package/src/apiClient.ts +7 -6
  81. package/src/components/CodeBlock/CodeBlock.tsx +1 -0
  82. package/src/components/Kbd/Kbd.module.css +10 -0
  83. package/src/components/Kbd/Kbd.module.css.d.ts +5 -0
  84. package/src/components/Kbd/Kbd.tsx +1 -1
  85. package/src/components/Window/Window.tsx +7 -1
  86. package/src/domain/__tests__/customType.test.ts +785 -0
  87. package/src/domain/customType.ts +519 -6
  88. package/src/domain/slice.ts +166 -1
  89. package/src/features/autoSave/AutoSaveStatusIndicator.tsx +43 -0
  90. package/src/features/autoSave/useAutoSave.tsx +177 -0
  91. package/src/features/customTypes/EditDropdown.tsx +3 -0
  92. package/src/features/customTypes/actions/convertCustomToPageType.ts +2 -4
  93. package/src/features/customTypes/customTypesBuilder/CustomTypeProvider.tsx +90 -0
  94. package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +46 -79
  95. package/src/features/customTypes/customTypesMessages.ts +4 -0
  96. package/src/features/slices/actions/addSlicesToSliceZone.ts +2 -7
  97. package/src/features/slices/actions/uploadSliceScreenshot.ts +45 -0
  98. package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewVariationDialog.tsx +5 -5
  99. package/src/features/slices/convertLegacySlice/ConvertLegacySliceButton.tsx +4 -10
  100. package/src/features/slices/sliceBuilder/SliceBuilderProvider.tsx +110 -0
  101. package/src/features/slices/sliceBuilder/actions/deleteVariation.ts +8 -24
  102. package/src/features/slices/sliceBuilder/actions/renameVariation.ts +8 -24
  103. package/src/features/slices/sliceCards/SharedSliceCard.tsx +1 -0
  104. package/src/hooks/useCurrentSlice.tsx +4 -16
  105. package/src/hooks/useScreenshotChangesModal.ts +1 -0
  106. package/src/hooks/useServerState.ts +1 -58
  107. package/src/modules/availableCustomTypes/index.ts +8 -3
  108. package/src/modules/simulator/index.ts +0 -2
  109. package/src/modules/slices/index.ts +32 -25
  110. package/src/modules/slices/selector.ts +30 -0
  111. package/src/modules/useSliceMachineActions.ts +20 -270
  112. package/src/redux/reducer.ts +0 -4
  113. package/src/redux/saga.ts +0 -6
  114. package/src/redux/type.ts +0 -4
  115. package/stylelint.config.js +17 -0
  116. package/test/src/modules/availableCustomTypes/index.test.ts +8 -10
  117. package/test/src/modules/simulator.test.ts +0 -2
  118. package/lib/models/common/CustomType/group.ts +0 -80
  119. package/lib/models/common/Variation.ts +0 -100
  120. package/out/_next/static/3vLhj_JZ10e4rwC2sTZNQ/_buildManifest.js +0 -1
  121. package/out/_next/static/chunks/18539003-4460ccbfe3109578.js +0 -97
  122. package/out/_next/static/chunks/482-49264466566eac99.js +0 -1
  123. package/out/_next/static/chunks/550-c80fd46fb64d1eef.js +0 -1
  124. package/out/_next/static/chunks/80-7b8a97d0122ff74a.js +0 -1
  125. package/out/_next/static/chunks/840-163f8a1040e6820d.js +0 -1
  126. package/out/_next/static/chunks/904-fe1af089657fb0cc.js +0 -1
  127. package/out/_next/static/chunks/958-3d829456f4f5632c.js +0 -1
  128. package/out/_next/static/chunks/pages/_app-f88a66f6532a8e87.js +0 -458
  129. package/out/_next/static/chunks/pages/changelog-4d0f2f1222e403fe.js +0 -1
  130. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-7b17cb59d0db03b5.js +0 -1
  131. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-ef11594ce026b650.js +0 -1
  132. package/out/_next/static/chunks/pages/slices-884a936a9a062a65.js +0 -1
  133. package/out/_next/static/css/1bbf650dfd37ce69.css +0 -1
  134. package/out/_next/static/css/7d650bca12dc4061.css +0 -1
  135. package/out/_next/static/css/cb33580e45d01b59.css +0 -1
  136. package/postcss.config.js +0 -2
  137. package/src/components/Kbd/Kbd.css.ts +0 -16
  138. package/src/domain/__tests__/CustomTypeModel.test.ts +0 -247
  139. package/src/layouts/WithSlice.tsx +0 -26
  140. package/src/modules/screenshots/actions.ts +0 -21
  141. package/src/modules/screenshots/sagas.ts +0 -70
  142. package/src/modules/selectedCustomType/actions.ts +0 -147
  143. package/src/modules/selectedCustomType/index.ts +0 -11
  144. package/src/modules/selectedCustomType/reducer.ts +0 -287
  145. package/src/modules/selectedCustomType/sagas.ts +0 -72
  146. package/src/modules/selectedCustomType/selectors.ts +0 -33
  147. package/src/modules/selectedCustomType/stateHelpers.ts +0 -42
  148. package/src/modules/selectedCustomType/types.ts +0 -9
  149. package/src/modules/selectedSlice/actions.ts +0 -106
  150. package/src/modules/selectedSlice/reducer.ts +0 -175
  151. package/src/modules/selectedSlice/sagas.ts +0 -72
  152. package/src/modules/selectedSlice/selectors.ts +0 -55
  153. package/src/modules/selectedSlice/types.ts +0 -3
  154. package/src/modules/toaster/utils.tsx +0 -23
  155. package/test/lib/models/common/CustomType/sliceZone.test.ts +0 -49
  156. package/test/pages/custom-types.test.tsx +0 -625
  157. package/test/src/modules/selectedCustomType/__fixtures__/model.json +0 -119
  158. package/test/src/modules/selectedCustomType/reducer.test.ts +0 -322
  159. package/test/src/modules/selectedCustomType/sagas.test.ts +0 -89
  160. package/test/src/modules/selectedCustomType/selectors.test.ts +0 -54
  161. package/test/src/modules/selectedSlice/__fixtures__/mocks.json +0 -171
  162. package/test/src/modules/selectedSlice/__fixtures__/model.json +0 -35
  163. package/test/src/modules/selectedSlice/__testutils__/getRefreshStateCreatorPayloadData.ts +0 -72
  164. package/test/src/modules/selectedSlice/__testutils__/getSelectedSliceDummyData.ts +0 -30
  165. package/test/src/modules/selectedSlice/reducer.test.ts +0 -170
  166. package/test/src/modules/selectedSlice/sagas.test.ts +0 -82
  167. package/test/src/modules/toaster/utils.test.ts +0 -50
  168. /package/out/_next/static/{3vLhj_JZ10e4rwC2sTZNQ → QLcban0JdGEoFu6NgapR9}/_ssgManifest.js +0 -0
@@ -1,8 +1,112 @@
1
1
  import {
2
2
  CustomType,
3
3
  DynamicSection,
4
+ DynamicSlices,
4
5
  DynamicSlicesConfig,
6
+ Group,
7
+ GroupFieldType,
8
+ NestableWidget,
9
+ SlicesFieldType,
10
+ UID,
5
11
  } from "@prismicio/types-internal/lib/customtypes";
12
+ import { removeKey } from "@prismicio/editor-support/Object";
13
+
14
+ import { CustomTypeFormat } from "@slicemachine/manager";
15
+
16
+ type DeleteSliceZoneSliceArgs = {
17
+ customType: CustomType;
18
+ sectionId: string;
19
+ sliceId: string;
20
+ };
21
+
22
+ type AddFieldArgs = {
23
+ customType: CustomType;
24
+ sectionId: string;
25
+ newField: NestableWidget | UID | Group;
26
+ newFieldId: string;
27
+ };
28
+
29
+ type DeleteFieldArgs = {
30
+ customType: CustomType;
31
+ sectionId: string;
32
+ fieldId: string;
33
+ };
34
+
35
+ type UpdateFieldArgs = {
36
+ customType: CustomType;
37
+ sectionId: string;
38
+ previousFieldId: string;
39
+ newFieldId: string;
40
+ newField: NestableWidget | UID | Group;
41
+ };
42
+
43
+ type ReorderFieldArgs = {
44
+ customType: CustomType;
45
+ sectionId: string;
46
+ sourceIndex: number;
47
+ destinationIndex: number;
48
+ };
49
+
50
+ type AddGroupField = {
51
+ customType: CustomType;
52
+ sectionId: string;
53
+ groupFieldId: string;
54
+ newField: NestableWidget;
55
+ newFieldId: string;
56
+ };
57
+
58
+ type DeleteGroupField = {
59
+ customType: CustomType;
60
+ sectionId: string;
61
+ groupFieldId: string;
62
+ fieldId: string;
63
+ };
64
+
65
+ type UpdateGroupFieldArgs = {
66
+ customType: CustomType;
67
+ sectionId: string;
68
+ groupFieldId: string;
69
+ previousFieldId: string;
70
+ newFieldId: string;
71
+ newField: NestableWidget;
72
+ };
73
+
74
+ type ReorderGroupFieldArgs = {
75
+ customType: CustomType;
76
+ sectionId: string;
77
+ groupFieldId: string;
78
+ sourceIndex: number;
79
+ destinationIndex: number;
80
+ };
81
+
82
+ type UpdateSectionArgs = {
83
+ customType: CustomType;
84
+ sectionId: string;
85
+ updatedSection: DynamicSection;
86
+ };
87
+
88
+ type UpdateFieldsArgs<T> = {
89
+ fields: Record<string, T>;
90
+ previousFieldId: string;
91
+ newFieldId: string;
92
+ newField: T;
93
+ };
94
+
95
+ type ReorderFieldsArgs<T> = {
96
+ fields: Record<string, T>;
97
+ sourceIndex: number;
98
+ destinationIndex: number;
99
+ };
100
+
101
+ type GetGroupFieldArgs = {
102
+ customType: CustomType;
103
+ sectionId: string;
104
+ groupFieldId: string;
105
+ };
106
+
107
+ export function getFormat(custom: CustomType): CustomTypeFormat {
108
+ return custom.format ?? "custom";
109
+ }
6
110
 
7
111
  export function getSectionEntries(
8
112
  customType: CustomType,
@@ -26,10 +130,10 @@ export function getSection(
26
130
  return customType.json[sectionId];
27
131
  }
28
132
 
29
- export function getSectionSliceZoneConfig(
133
+ export function getSectionSliceZoneEntry(
30
134
  customType: CustomType,
31
135
  sectionId: string,
32
- ): DynamicSlicesConfig | undefined {
136
+ ): [string, DynamicSlices] | undefined {
33
137
  const section = getSection(customType, sectionId);
34
138
 
35
139
  if (section === undefined) {
@@ -38,10 +142,23 @@ export function getSectionSliceZoneConfig(
38
142
 
39
143
  // In Slice Machine we currently only support one slice zone per section
40
144
  // so we retrieve the first one
41
- const maybeSliceZone = Object.values(section).find(
42
- (value) => value.type === "Slices",
145
+ const maybeSliceZone = Object.entries(section).find(
146
+ (entry): entry is [string, DynamicSlices] => {
147
+ const [_, value] = entry;
148
+ return value.type === SlicesFieldType;
149
+ },
43
150
  );
44
151
 
152
+ return maybeSliceZone;
153
+ }
154
+
155
+ export function getSectionSliceZoneConfig(
156
+ customType: CustomType,
157
+ sectionId: string,
158
+ ): DynamicSlicesConfig | undefined {
159
+ const maybeSliceZoneEntry = getSectionSliceZoneEntry(customType, sectionId);
160
+ const [_, maybeSliceZone] = maybeSliceZoneEntry ?? [];
161
+
45
162
  return maybeSliceZone?.config ?? undefined;
46
163
  }
47
164
 
@@ -57,7 +174,7 @@ export function findNextSectionSliceZoneKey(
57
174
  const sectionIndex = sectionsEntries.findIndex(([key]) => key === sectionId);
58
175
 
59
176
  const existingKeys = sectionsEntries.flatMap(([_, section]) =>
60
- Object.keys(section).filter((key) => section[key].type === "Slices"),
177
+ Object.keys(section).filter((key) => section[key].type === SlicesFieldType),
61
178
  );
62
179
 
63
180
  let i = sectionIndex;
@@ -97,7 +214,7 @@ export function createSectionSliceZone(
97
214
  [sectionId]: {
98
215
  ...customType.json[sectionId],
99
216
  [availableSectionSlicesKey]: {
100
- type: "Slices",
217
+ type: SlicesFieldType,
101
218
  fieldset: "Slice Zone",
102
219
  },
103
220
  },
@@ -105,6 +222,80 @@ export function createSectionSliceZone(
105
222
  };
106
223
  }
107
224
 
225
+ export function deleteSectionSliceZone(
226
+ customType: CustomType,
227
+ sectionId: string,
228
+ ): CustomType {
229
+ const section = getSection(customType, sectionId);
230
+
231
+ if (section === undefined) {
232
+ return customType;
233
+ }
234
+
235
+ const sliceZoneKey = Object.keys(section).find(
236
+ (key) => section[key].type === SlicesFieldType,
237
+ );
238
+
239
+ if (sliceZoneKey === undefined) {
240
+ return customType;
241
+ }
242
+
243
+ const newSection = removeKey(section, sliceZoneKey);
244
+
245
+ return {
246
+ ...customType,
247
+ json: {
248
+ ...customType.json,
249
+ [sectionId]: newSection,
250
+ },
251
+ };
252
+ }
253
+
254
+ export function deleteSliceZoneSlice(
255
+ args: DeleteSliceZoneSliceArgs,
256
+ ): CustomType {
257
+ const { customType, sectionId, sliceId } = args;
258
+
259
+ const section = getSection(customType, sectionId);
260
+
261
+ if (section === undefined) {
262
+ return customType;
263
+ }
264
+
265
+ const sliceZoneKey = Object.keys(section).find(
266
+ (key) => section[key].type === SlicesFieldType,
267
+ );
268
+
269
+ if (sliceZoneKey === undefined) {
270
+ return customType;
271
+ }
272
+
273
+ const sliceZone = section[sliceZoneKey];
274
+
275
+ if (sliceZone.type !== SlicesFieldType) {
276
+ return customType;
277
+ }
278
+
279
+ const newChoices = removeKey(sliceZone.config?.choices ?? {}, sliceId);
280
+
281
+ return {
282
+ ...customType,
283
+ json: {
284
+ ...customType.json,
285
+ [sectionId]: {
286
+ ...section,
287
+ [sliceZoneKey]: {
288
+ ...sliceZone,
289
+ config: {
290
+ ...sliceZone.config,
291
+ choices: newChoices,
292
+ },
293
+ },
294
+ },
295
+ },
296
+ };
297
+ }
298
+
108
299
  export function convertToPageType(customType: CustomType): CustomType {
109
300
  let newCustomType: CustomType = {
110
301
  ...customType,
@@ -120,3 +311,325 @@ export function convertToPageType(customType: CustomType): CustomType {
120
311
 
121
312
  return newCustomType;
122
313
  }
314
+
315
+ export function createSection(customType: CustomType, sectionId: string) {
316
+ return {
317
+ ...customType,
318
+ json: {
319
+ ...customType.json,
320
+ // Create the empty section
321
+ [sectionId]: {},
322
+ },
323
+ };
324
+ }
325
+
326
+ export function deleteSection(customType: CustomType, sectionId: string) {
327
+ const newJson = removeKey(customType.json, sectionId);
328
+
329
+ return {
330
+ ...customType,
331
+ json: newJson,
332
+ };
333
+ }
334
+
335
+ export function renameSection(
336
+ customType: CustomType,
337
+ sectionId: string,
338
+ newSectionId: string,
339
+ ) {
340
+ if (sectionId === newSectionId) {
341
+ return customType;
342
+ }
343
+
344
+ const newJson = Object.keys(customType.json).reduce(
345
+ (acc: CustomType["json"], key) => {
346
+ if (key === sectionId) {
347
+ // Rename the section
348
+ acc[newSectionId] = customType.json[key];
349
+ } else {
350
+ // Retain all other sections as they are
351
+ acc[key] = customType.json[key];
352
+ }
353
+ return acc;
354
+ },
355
+ {},
356
+ );
357
+
358
+ return {
359
+ ...customType,
360
+ json: newJson,
361
+ };
362
+ }
363
+
364
+ export function addField(args: AddFieldArgs): CustomType {
365
+ const { customType, sectionId, newField, newFieldId } = args;
366
+
367
+ const newCustomType = updateSection({
368
+ customType,
369
+ sectionId,
370
+ updatedSection: {
371
+ ...customType.json[sectionId],
372
+ // Add the new field to the section
373
+ [newFieldId]: newField,
374
+ },
375
+ });
376
+
377
+ return newCustomType;
378
+ }
379
+
380
+ export function deleteField(args: DeleteFieldArgs): CustomType {
381
+ const { customType, sectionId, fieldId } = args;
382
+
383
+ const updatedSection = removeKey(customType.json[sectionId], fieldId);
384
+ const newCustomType = updateSection({
385
+ customType,
386
+ sectionId,
387
+ updatedSection,
388
+ });
389
+
390
+ return newCustomType;
391
+ }
392
+
393
+ export function updateField(args: UpdateFieldArgs): CustomType {
394
+ const { customType, sectionId, previousFieldId, newFieldId, newField } = args;
395
+
396
+ const updatedSection = updateFields({
397
+ fields: customType.json[sectionId],
398
+ previousFieldId,
399
+ newFieldId,
400
+ newField,
401
+ });
402
+ const newCustomType = updateSection({
403
+ customType,
404
+ sectionId,
405
+ updatedSection,
406
+ });
407
+
408
+ return newCustomType;
409
+ }
410
+
411
+ export function reorderField(args: ReorderFieldArgs): CustomType {
412
+ const { customType, sectionId, sourceIndex, destinationIndex } = args;
413
+ const sectionJson = customType.json[sectionId];
414
+ const maybeSliceZoneEntry = getSectionSliceZoneEntry(customType, sectionId);
415
+
416
+ // Separate the fields into slices and non-slices
417
+ const sectionFields = Object.fromEntries(
418
+ Object.entries(sectionJson).filter(
419
+ ([_, value]) => value.type !== SlicesFieldType,
420
+ ),
421
+ );
422
+
423
+ const updatedSection = reorderFields({
424
+ fields: sectionFields,
425
+ sourceIndex,
426
+ destinationIndex,
427
+ });
428
+
429
+ // Merge the SlicesFieldType field back into the section, if it exists
430
+ if (maybeSliceZoneEntry !== undefined) {
431
+ const [sliceZoneKey, sliceZoneField] = maybeSliceZoneEntry;
432
+ updatedSection[sliceZoneKey] = sliceZoneField;
433
+ }
434
+
435
+ const newCustomType = updateSection({
436
+ customType,
437
+ sectionId,
438
+ updatedSection,
439
+ });
440
+
441
+ return newCustomType;
442
+ }
443
+
444
+ export function addGroupField(args: AddGroupField): CustomType {
445
+ const { customType, sectionId, groupFieldId, newField, newFieldId } = args;
446
+ const groupField = getGroupField({
447
+ customType,
448
+ sectionId,
449
+ groupFieldId,
450
+ });
451
+ const groupFields = groupField?.config?.fields;
452
+
453
+ if (!groupField) {
454
+ return customType;
455
+ }
456
+
457
+ const newGroupField = updateGroupFields(groupField, {
458
+ ...groupFields,
459
+ // Add the new field to the group fields
460
+ [newFieldId]: newField,
461
+ });
462
+ const newCustomType = updateSection({
463
+ customType,
464
+ sectionId,
465
+ updatedSection: {
466
+ ...customType.json[sectionId],
467
+ [groupFieldId]: newGroupField,
468
+ },
469
+ });
470
+
471
+ return newCustomType;
472
+ }
473
+
474
+ export function deleteGroupField(args: DeleteGroupField): CustomType {
475
+ const { customType, sectionId, groupFieldId, fieldId } = args;
476
+ const groupField = getGroupField({
477
+ customType,
478
+ sectionId,
479
+ groupFieldId,
480
+ });
481
+ const groupFields = groupField?.config?.fields;
482
+
483
+ if (!groupField || !groupFields) {
484
+ return customType;
485
+ }
486
+
487
+ const updatedFields = removeKey(groupFields, fieldId);
488
+ const newGroupField = updateGroupFields(groupField, updatedFields);
489
+ const newCustomType = updateSection({
490
+ customType,
491
+ sectionId,
492
+ updatedSection: {
493
+ ...customType.json[sectionId],
494
+ [groupFieldId]: newGroupField,
495
+ },
496
+ });
497
+
498
+ return newCustomType;
499
+ }
500
+
501
+ export function updateGroupField(args: UpdateGroupFieldArgs): CustomType {
502
+ const {
503
+ customType,
504
+ sectionId,
505
+ groupFieldId,
506
+ previousFieldId,
507
+ newFieldId,
508
+ newField,
509
+ } = args;
510
+ const groupField = getGroupField({
511
+ customType,
512
+ sectionId,
513
+ groupFieldId,
514
+ });
515
+ const groupFields = groupField?.config?.fields;
516
+
517
+ if (!groupField || !groupFields) {
518
+ return customType;
519
+ }
520
+
521
+ const updatedGroupFields = updateFields({
522
+ fields: groupFields,
523
+ previousFieldId,
524
+ newFieldId,
525
+ newField,
526
+ });
527
+ const newGroupField = updateGroupFields(groupField, updatedGroupFields);
528
+ const newCustomType = updateSection({
529
+ customType,
530
+ sectionId,
531
+ updatedSection: {
532
+ ...customType.json[sectionId],
533
+ [groupFieldId]: newGroupField,
534
+ },
535
+ });
536
+
537
+ return newCustomType;
538
+ }
539
+
540
+ export function reorderGroupField(args: ReorderGroupFieldArgs): CustomType {
541
+ const { customType, sectionId, groupFieldId, sourceIndex, destinationIndex } =
542
+ args;
543
+ const groupField = getGroupField({
544
+ customType,
545
+ sectionId,
546
+ groupFieldId,
547
+ });
548
+ const groupFields = groupField?.config?.fields;
549
+
550
+ if (!groupField || !groupFields) {
551
+ return customType;
552
+ }
553
+
554
+ const updatedGroupFields = reorderFields({
555
+ fields: groupFields,
556
+ sourceIndex,
557
+ destinationIndex,
558
+ });
559
+ const newGroupField = updateGroupFields(groupField, updatedGroupFields);
560
+ const newCustomType = updateSection({
561
+ customType,
562
+ sectionId,
563
+ updatedSection: {
564
+ ...customType.json[sectionId],
565
+ [groupFieldId]: newGroupField,
566
+ },
567
+ });
568
+
569
+ return newCustomType;
570
+ }
571
+
572
+ export function updateSection(args: UpdateSectionArgs): CustomType {
573
+ const { customType, sectionId, updatedSection } = args;
574
+
575
+ return {
576
+ ...customType,
577
+ json: {
578
+ ...customType.json,
579
+ [sectionId]: updatedSection,
580
+ },
581
+ };
582
+ }
583
+
584
+ export function updateFields<T>(args: UpdateFieldsArgs<T>): Record<string, T> {
585
+ const { fields, previousFieldId, newFieldId, newField } = args;
586
+
587
+ return Object.entries(fields).reduce(
588
+ (acc, [key, value]) => {
589
+ if (key === previousFieldId) {
590
+ // If the current key is the previous field ID, replace it with the new field.
591
+ acc[newFieldId] = newField;
592
+ } else if (key !== newFieldId) {
593
+ // Retain all other fields as they are.
594
+ acc[key] = value;
595
+ }
596
+ return acc;
597
+ },
598
+ {} as Record<string, T>,
599
+ );
600
+ }
601
+
602
+ export function reorderFields<T>(args: ReorderFieldsArgs<T>) {
603
+ const { fields, sourceIndex, destinationIndex } = args;
604
+
605
+ const fieldEntries = Object.entries(fields);
606
+ const [removedEntry] = fieldEntries.splice(sourceIndex, 1);
607
+ fieldEntries.splice(destinationIndex, 0, removedEntry);
608
+ const reorderedFields = Object.fromEntries(fieldEntries);
609
+
610
+ return reorderedFields;
611
+ }
612
+
613
+ export function getGroupField(args: GetGroupFieldArgs): Group | undefined {
614
+ const { customType, sectionId, groupFieldId } = args;
615
+ const field = customType.json[sectionId][groupFieldId];
616
+
617
+ if (field.type === GroupFieldType) {
618
+ return field;
619
+ }
620
+
621
+ return undefined;
622
+ }
623
+
624
+ export function updateGroupFields(
625
+ field: Group,
626
+ updatedGroupFields: Record<string, NestableWidget>,
627
+ ): Group {
628
+ return {
629
+ ...field,
630
+ config: {
631
+ ...field.config,
632
+ fields: updatedGroupFields,
633
+ },
634
+ };
635
+ }