slice-machine-ui 1.22.2-alpha.xru-auto-save-type-builder.5 → 1.22.2-beta.10

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 (100) hide show
  1. package/components/Forms/CreateSliceModal/CreateSliceModal.tsx +5 -2
  2. package/components/Forms/RenameCustomTypeModal/RenameCustomTypeModal.tsx +4 -8
  3. package/components/ItemHeader/index.tsx +0 -1
  4. package/components/ListItem/index.tsx +2 -5
  5. package/lib/builders/CustomTypeBuilder/SliceZone/SlicesTemplatesModal.tsx +2 -2
  6. package/lib/builders/CustomTypeBuilder/SliceZone/UpdateSliceZoneModal.tsx +2 -2
  7. package/lib/builders/CustomTypeBuilder/SliceZone/index.tsx +20 -12
  8. package/lib/builders/CustomTypeBuilder/TabModal/update.tsx +1 -3
  9. package/lib/builders/CustomTypeBuilder/TabZone/index.tsx +52 -119
  10. package/lib/builders/CustomTypeBuilder/index.tsx +42 -39
  11. package/lib/builders/SliceBuilder/FieldZones/index.tsx +1 -1
  12. package/lib/builders/common/Zone/Card/components/Hints/CodeBlock.tsx +1 -5
  13. package/lib/builders/common/Zone/Card/components/NewField.tsx +15 -16
  14. package/lib/builders/common/Zone/Card/index.jsx +0 -2
  15. package/lib/builders/common/Zone/index.jsx +0 -2
  16. package/lib/models/common/CustomType/group.ts +80 -0
  17. package/lib/models/common/CustomType/sliceZone.ts +29 -0
  18. package/lib/models/common/CustomType/tab.ts +142 -10
  19. package/lib/models/common/widgets/Group/ListItem/index.jsx +23 -61
  20. package/out/404.html +1 -1
  21. package/out/_next/static/bgAW-O9SejtbtaQ7v0wB1/_buildManifest.js +1 -0
  22. package/out/_next/static/chunks/482-34cee2a2071c235f.js +1 -0
  23. package/out/_next/static/chunks/{376-0ed5822f8afcaa7c.js → 505-3f1cf09a086dcba8.js} +3 -3
  24. package/out/_next/static/chunks/550-c80fd46fb64d1eef.js +1 -0
  25. package/out/_next/static/chunks/{840-1477d9612100adfa.js → 840-163f8a1040e6820d.js} +1 -1
  26. package/out/_next/static/chunks/904-519dbf0f7e8c6243.js +1 -0
  27. package/out/_next/static/chunks/{958-247df4bdf5efcb92.js → 958-8aca174b80cb0c35.js} +1 -1
  28. package/out/_next/static/chunks/pages/_app-36b2c828e330d9c7.js +458 -0
  29. package/out/_next/static/chunks/pages/changelog-4d0f2f1222e403fe.js +1 -0
  30. package/out/_next/static/chunks/pages/changes-52c9d917808d1461.js +1 -0
  31. package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-91d6869a1ab2fc71.js → [customTypeId]-3a37eb3373bb8823.js} +1 -1
  32. package/out/_next/static/chunks/pages/{custom-types-309e8a31d3eb6e3a.js → custom-types-2f5664d9492b13fb.js} +1 -1
  33. package/out/_next/static/chunks/pages/{index-75046c128aa61430.js → index-d8e3a2c0d712904f.js} +1 -1
  34. package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-b77ea575830be083.js → [pageTypeId]-733f3890c0466a05.js} +1 -1
  35. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-7b17cb59d0db03b5.js +1 -0
  36. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-ef11594ce026b650.js +1 -0
  37. package/out/_next/static/chunks/pages/slices-884a936a9a062a65.js +1 -0
  38. package/out/changelog.html +1 -1
  39. package/out/changes.html +1 -1
  40. package/out/custom-types/[customTypeId].html +1 -1
  41. package/out/custom-types.html +1 -1
  42. package/out/index.html +1 -1
  43. package/out/labs.html +1 -1
  44. package/out/page-types/[pageTypeId].html +1 -1
  45. package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
  46. package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
  47. package/out/slices.html +1 -1
  48. package/package.json +3 -3
  49. package/src/apiClient.ts +6 -7
  50. package/src/components/CodeBlock/CodeBlock.tsx +0 -1
  51. package/src/components/Window/Window.tsx +1 -7
  52. package/src/domain/__tests__/CustomTypeModel.test.ts +247 -0
  53. package/src/domain/customType.ts +6 -521
  54. package/src/features/customTypes/actions/convertCustomToPageType.ts +4 -2
  55. package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +79 -45
  56. package/src/features/customTypes/customTypesMessages.ts +0 -2
  57. package/src/features/slices/actions/addSlicesToSliceZone.ts +7 -2
  58. package/src/features/slices/convertLegacySlice/ConvertLegacySliceButton.tsx +10 -4
  59. package/src/features/slices/sliceCards/SharedSliceCard.tsx +0 -1
  60. package/src/hooks/useServerState.ts +42 -11
  61. package/src/modules/availableCustomTypes/index.ts +3 -8
  62. package/src/modules/selectedCustomType/actions.ts +147 -0
  63. package/src/modules/selectedCustomType/index.ts +11 -0
  64. package/src/modules/selectedCustomType/reducer.ts +287 -0
  65. package/src/modules/selectedCustomType/sagas.ts +72 -0
  66. package/src/modules/selectedCustomType/selectors.ts +33 -0
  67. package/src/modules/selectedCustomType/stateHelpers.ts +42 -0
  68. package/src/modules/selectedCustomType/types.ts +9 -0
  69. package/src/modules/useSliceMachineActions.ts +118 -2
  70. package/src/redux/reducer.ts +2 -0
  71. package/src/redux/saga.ts +2 -0
  72. package/src/redux/type.ts +2 -0
  73. package/test/lib/models/common/CustomType/sliceZone.test.ts +49 -0
  74. package/test/pages/custom-types.test.tsx +625 -0
  75. package/test/src/modules/availableCustomTypes/index.test.ts +10 -8
  76. package/test/src/modules/selectedCustomType/__fixtures__/model.json +119 -0
  77. package/test/src/modules/selectedCustomType/reducer.test.ts +322 -0
  78. package/test/src/modules/selectedCustomType/sagas.test.ts +89 -0
  79. package/test/src/modules/selectedCustomType/selectors.test.ts +54 -0
  80. package/out/_next/static/0hBs80pK3uqpdlNRzU2Kl/_buildManifest.js +0 -1
  81. package/out/_next/static/chunks/065a3ddb-9a38ca0d60f0bf2f.js +0 -1
  82. package/out/_next/static/chunks/183-4feb6bb3eddbc768.js +0 -1
  83. package/out/_next/static/chunks/1cc2734a-2c5b6c0367fcde86.js +0 -1
  84. package/out/_next/static/chunks/482-b4e411334d37ef04.js +0 -1
  85. package/out/_next/static/chunks/4c744e84-e3161d754618373f.js +0 -1
  86. package/out/_next/static/chunks/538-3ed77c7286e59f2b.js +0 -1
  87. package/out/_next/static/chunks/694-560372a8511e7b74.js +0 -1
  88. package/out/_next/static/chunks/799-378edb0fdc3a3a5a.js +0 -1
  89. package/out/_next/static/chunks/858-0b07239d5a20b65c.js +0 -28
  90. package/out/_next/static/chunks/pages/_app-1b83d5a87c892b88.js +0 -431
  91. package/out/_next/static/chunks/pages/changelog-f8e0869f0551f420.js +0 -1
  92. package/out/_next/static/chunks/pages/changes-47fe6af1355195e4.js +0 -1
  93. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/simulator-55d09564cc4f522a.js +0 -1
  94. package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-e084a43056f481f0.js +0 -1
  95. package/out/_next/static/chunks/pages/slices-b1494d473dcb76ee.js +0 -1
  96. package/src/domain/__tests__/customType.test.ts +0 -785
  97. package/src/features/autoSave/AutoSaveStatus.tsx +0 -41
  98. package/src/features/autoSave/useAutoSave.tsx +0 -114
  99. package/src/features/customTypes/customTypesBuilder/CustomTypeProvider.tsx +0 -93
  100. /package/out/_next/static/{0hBs80pK3uqpdlNRzU2Kl → bgAW-O9SejtbtaQ7v0wB1}/_ssgManifest.js +0 -0
@@ -15,7 +15,10 @@ import { InputBox } from "../components/InputBox";
15
15
 
16
16
  type CreateSliceModalProps = {
17
17
  onClose: () => void;
18
- onSuccess: (newSlice: SharedSlice, libraryName: string) => void;
18
+ onSuccess: (
19
+ newSlice: SharedSlice,
20
+ libraryName: string,
21
+ ) => Promise<void> | void;
19
22
  localLibraries: readonly LibraryUI[];
20
23
  remoteSlices: ReadonlyArray<SliceSM>;
21
24
  };
@@ -46,7 +49,7 @@ export const CreateSliceModal: FC<CreateSliceModalProps> = ({
46
49
  // Update Redux store
47
50
  createSliceSuccess(serverState.libraries);
48
51
 
49
- onSuccess(newSlice, libraryName);
52
+ await onSuccess(newSlice, libraryName);
50
53
  },
51
54
  });
52
55
  };
@@ -6,14 +6,13 @@ import { InputBox } from "../components/InputBox";
6
6
  import { useSelector } from "react-redux";
7
7
  import { SliceMachineStoreType } from "@src/redux/type";
8
8
  import { FormikErrors } from "formik";
9
-
10
9
  import { selectAllCustomTypeLabels } from "@src/modules/availableCustomTypes";
10
+
11
11
  import { CustomType } from "@prismicio/types-internal/lib/customtypes";
12
12
  import { CustomTypeFormat } from "@slicemachine/manager";
13
13
  import { CUSTOM_TYPES_MESSAGES } from "@src/features/customTypes/customTypesMessages";
14
14
 
15
15
  import { renameCustomType } from "@src/features/customTypes/actions/renameCustomType";
16
- import { useCustomTypeState } from "@src/features/customTypes/customTypesBuilder/CustomTypeProvider";
17
16
 
18
17
  interface RenameCustomTypeModalProps {
19
18
  isChangesLocal: boolean;
@@ -30,18 +29,15 @@ export const RenameCustomTypeModal: React.FC<RenameCustomTypeModalProps> = ({
30
29
  }) => {
31
30
  const customTypeName = customType?.label ?? "";
32
31
  const customTypeId = customType?.id ?? "";
33
- const { renameAvailableCustomTypeSuccess } = useSliceMachineActions();
34
- const { setCustomType } = useCustomTypeState();
32
+ const { renameAvailableCustomTypeSuccess, renameSelectedCustomType } =
33
+ useSliceMachineActions();
35
34
 
36
35
  const [isRenaming, setIsRenaming] = useState(false);
37
36
 
38
37
  const handleOnSubmit = async (values: { customTypeName: string }) => {
39
38
  setIsRenaming(true);
40
39
  if (isChangesLocal) {
41
- setCustomType({
42
- ...customType,
43
- label: values.customTypeName,
44
- });
40
+ renameSelectedCustomType(values.customTypeName);
45
41
  } else {
46
42
  await renameCustomType({
47
43
  model: customType,
@@ -22,7 +22,6 @@ const ItemHeader: React.FC<{
22
22
  />
23
23
  <Text
24
24
  as="p"
25
- data-cy="item-header-text"
26
25
  sx={{
27
26
  py: 0,
28
27
  px: 1,
@@ -34,7 +34,6 @@ interface ListItemProps<F extends TabField, S extends AnyObjectSchema> {
34
34
  CustomEditElements?: JSX.Element[];
35
35
  widget: Widget<F, S>;
36
36
  draggableId: string;
37
- dataCy: string;
38
37
  isRepeatableCustomType?: boolean;
39
38
  children: React.ReactNode;
40
39
  }
@@ -51,7 +50,6 @@ function ListItem<F extends TabField, S extends AnyObjectSchema>({
51
50
  CustomEditElements,
52
51
  widget,
53
52
  draggableId,
54
- dataCy,
55
53
  isRepeatableCustomType,
56
54
  children,
57
55
  }: ListItemProps<F, S>): JSX.Element {
@@ -68,7 +66,6 @@ function ListItem<F extends TabField, S extends AnyObjectSchema>({
68
66
  {(provided) => (
69
67
  <Fragment>
70
68
  <Li
71
- data-cy={dataCy}
72
69
  ref={provided.innerRef}
73
70
  {...provided.draggableProps}
74
71
  Component={Box}
@@ -120,7 +117,7 @@ function ListItem<F extends TabField, S extends AnyObjectSchema>({
120
117
  <SliceMachineIconButton
121
118
  size={22}
122
119
  Icon={AiOutlineEdit}
123
- label="Edit field"
120
+ label="Edit slice field"
124
121
  sx={{ cursor: "pointer", color: theme.colors?.icons }}
125
122
  onClick={() =>
126
123
  enterEditMode(
@@ -137,7 +134,7 @@ function ListItem<F extends TabField, S extends AnyObjectSchema>({
137
134
  <Menu>
138
135
  <MenuButton
139
136
  className="sliceMenuButton"
140
- data-cy="field-menu-button"
137
+ data-cy="slice-menu-button"
141
138
  style={{
142
139
  padding: "0",
143
140
  cursor: "pointer",
@@ -18,7 +18,7 @@ import { sliceTemplatesComingSoon } from "./sliceTemplatesComingSoon";
18
18
  interface UpdateSliceModalProps {
19
19
  formId: string;
20
20
  close: () => void;
21
- onSuccess: (slices: SharedSlice[]) => void;
21
+ onSuccess: (slices: SharedSlice[]) => Promise<void>;
22
22
  availableSlicesTemplates: SliceTemplate[];
23
23
  localLibraries: readonly LibraryUI[];
24
24
  }
@@ -69,7 +69,7 @@ export const SlicesTemplatesModal: FC<UpdateSliceModalProps> = ({
69
69
  ) as Promise<SharedSlice>[],
70
70
  );
71
71
 
72
- onSuccess(slices);
72
+ await onSuccess(slices);
73
73
  },
74
74
  });
75
75
  }}
@@ -9,7 +9,7 @@ import UpdateSliceZoneModalList from "./UpdateSliceZoneModalList";
9
9
  interface UpdateSliceModalProps {
10
10
  formId: string;
11
11
  close: () => void;
12
- onSubmit: (slices: SharedSlice[]) => void;
12
+ onSubmit: (slices: SharedSlice[]) => Promise<void>;
13
13
  availableSlices: ReadonlyArray<ComponentUI>;
14
14
  }
15
15
 
@@ -37,7 +37,7 @@ const UpdateSliceZoneModal: React.FC<UpdateSliceModalProps> = ({
37
37
  availableSlices.find((s) => s.model.id === sliceKey)?.model,
38
38
  )
39
39
  .filter((slice) => slice !== undefined) as SharedSlice[];
40
- onSubmit(slices);
40
+ void onSubmit(slices);
41
41
  }}
42
42
  initialValues={{
43
43
  sliceKeys: [],
@@ -31,9 +31,9 @@ import {
31
31
  } from "@src/modules/slices";
32
32
  import type { SliceMachineStoreType } from "@src/redux/type";
33
33
  import { useSlicesTemplates } from "@src/features/slicesTemplates/useSlicesTemplates";
34
+ import useSliceMachineActions from "@src/modules/useSliceMachineActions";
34
35
  import { addSlicesToSliceZone } from "@src/features/slices/actions/addSlicesToSliceZone";
35
36
  import { ToastMessageWithPath } from "@components/ToasterContainer";
36
- import { useCustomTypeState } from "@src/features/customTypes/customTypesBuilder/CustomTypeProvider";
37
37
 
38
38
  import { DeleteSliceZoneModal } from "./DeleteSliceZoneModal";
39
39
  import UpdateSliceZoneModal from "./UpdateSliceZoneModal";
@@ -121,8 +121,8 @@ const SliceZone: React.FC<SliceZoneProps> = ({
121
121
  slices: getFrontendSlices(store),
122
122
  }),
123
123
  );
124
- const { setCustomType } = useCustomTypeState();
125
-
124
+ const { initCustomTypeStore, saveCustomTypeSuccess } =
125
+ useSliceMachineActions();
126
126
  const localLibraries: readonly LibraryUI[] = libraries.filter(
127
127
  (library) => library.isLocal,
128
128
  );
@@ -197,6 +197,14 @@ const SliceZone: React.FC<SliceZoneProps> = ({
197
197
  setIsSlicesTemplatesModalOpen(false);
198
198
  };
199
199
 
200
+ const onAddSlicesToSliceZone = (newCustomType: CustomTypeSM) => {
201
+ // Reset selected custom type store to update slice zone and saving status
202
+ initCustomTypeStore(newCustomType, newCustomType);
203
+
204
+ // Update available custom type store with new custom type
205
+ saveCustomTypeSuccess(CustomTypes.fromSM(newCustomType));
206
+ };
207
+
200
208
  return (
201
209
  <>
202
210
  {query.newPageType === undefined ? (
@@ -291,13 +299,13 @@ const SliceZone: React.FC<SliceZoneProps> = ({
291
299
  <UpdateSliceZoneModal
292
300
  formId={`tab-slicezone-form-${tabId}`}
293
301
  availableSlices={availableSlicesToAdd}
294
- onSubmit={(slices: SharedSlice[]) => {
295
- const newCustomType = addSlicesToSliceZone({
302
+ onSubmit={async (slices: SharedSlice[]) => {
303
+ const newCustomType = await addSlicesToSliceZone({
296
304
  customType,
297
305
  tabId,
298
306
  slices,
299
307
  });
300
- setCustomType(CustomTypes.fromSM(newCustomType));
308
+ onAddSlicesToSliceZone(newCustomType);
301
309
  closeUpdateSliceZoneModal();
302
310
  redirectToEditMode();
303
311
  toast.success("Slice(s) added to slice zone");
@@ -310,13 +318,13 @@ const SliceZone: React.FC<SliceZoneProps> = ({
310
318
  formId={`tab-slicezone-form-${tabId}`}
311
319
  availableSlicesTemplates={availableSlicesTemplates}
312
320
  localLibraries={localLibraries}
313
- onSuccess={(slices: SharedSlice[]) => {
314
- const newCustomType = addSlicesToSliceZone({
321
+ onSuccess={async (slices: SharedSlice[]) => {
322
+ const newCustomType = await addSlicesToSliceZone({
315
323
  customType,
316
324
  tabId,
317
325
  slices,
318
326
  });
319
- setCustomType(CustomTypes.fromSM(newCustomType));
327
+ onAddSlicesToSliceZone(newCustomType);
320
328
  closeSlicesTemplatesModal();
321
329
  redirectToEditMode();
322
330
  toast.success(
@@ -342,13 +350,13 @@ const SliceZone: React.FC<SliceZoneProps> = ({
342
350
  )}
343
351
  {localLibraries?.length !== 0 && isCreateSliceModalOpen && (
344
352
  <CreateSliceModal
345
- onSuccess={(newSlice: SharedSlice) => {
346
- const newCustomType = addSlicesToSliceZone({
353
+ onSuccess={async (newSlice: SharedSlice) => {
354
+ const newCustomType = await addSlicesToSliceZone({
347
355
  customType,
348
356
  tabId,
349
357
  slices: [newSlice],
350
358
  });
351
- setCustomType(CustomTypes.fromSM(newCustomType));
359
+ onAddSlicesToSliceZone(newCustomType);
352
360
  closeCreateSliceModal();
353
361
  redirectToEditMode();
354
362
  toast.success(
@@ -10,13 +10,11 @@ const UpdateCustomTypeForm = ({
10
10
  onSubmit,
11
11
  close,
12
12
  tabIds,
13
- initialTabKey,
14
13
  }: {
15
14
  isOpen: boolean;
16
15
  onSubmit: (values: { id: string }) => void;
17
16
  close: () => void;
18
17
  tabIds: ReadonlyArray<string>;
19
- initialTabKey: string;
20
18
  }) => {
21
19
  return (
22
20
  <ModalFormCard
@@ -31,7 +29,7 @@ const UpdateCustomTypeForm = ({
31
29
  close();
32
30
  }}
33
31
  initialValues={{
34
- id: initialTabKey,
32
+ id: "",
35
33
  }}
36
34
  validate={({ id }) => {
37
35
  if (!id) {
@@ -1,74 +1,67 @@
1
1
  import { Box, ErrorBoundary, ProgressCircle } from "@prismicio/editor-ui";
2
2
  import { FC, Suspense } from "react";
3
- import { flushSync } from "react-dom";
4
3
  import type { DropResult } from "react-beautiful-dnd";
4
+ import { useSelector } from "react-redux";
5
5
  import type { AnyObjectSchema } from "yup";
6
6
  import { useRouter } from "next/router";
7
7
 
8
8
  import ctBuilderArray from "@lib/models/common/widgets/ctBuilderArray";
9
- import {
10
- TabSM,
11
- type TabField,
12
- type TabFields,
13
- CustomTypes,
14
- TabFieldsModel,
9
+ import type {
10
+ CustomTypeSM,
11
+ TabField,
12
+ TabFields,
15
13
  } from "@lib/models/common/CustomType";
16
- import type { AnyWidget } from "@lib/models/common/widgets/Widget";
14
+ import type { SlicesSM } from "@lib/models/common/Slices";
17
15
  import { ensureDnDDestination, ensureWidgetTypeExistence } from "@lib/utils";
18
16
  import { List } from "@src/components/List";
17
+ import useSliceMachineActions from "@src/modules/useSliceMachineActions";
18
+ import type { SliceMachineStoreType } from "@src/redux/type";
19
19
  import { telemetry } from "@src/apiClient";
20
20
  import { transformKeyAccessor } from "@utils/str";
21
- import { useCustomTypeState } from "@src/features/customTypes/customTypesBuilder/CustomTypeProvider";
22
- import {
23
- createSectionSliceZone,
24
- deleteSectionSliceZone,
25
- deleteSliceZoneSlice,
26
- addField,
27
- deleteField,
28
- reorderField,
29
- updateField,
30
- } from "@src/domain/customType";
31
21
 
32
22
  import * as Widgets from "../../../../lib/models/common/widgets/withGroup";
23
+ import { selectCurrentPoolOfFields } from "../../../../src/modules/selectedCustomType";
24
+ import type { Widget } from "../../../models/common/widgets/Widget";
33
25
  import EditModal from "../../common/EditModal";
34
26
  import Zone from "../../common/Zone";
35
27
  import SliceZone from "../SliceZone";
36
- import {
37
- Group,
38
- NestableWidget,
39
- UID,
40
- } from "@prismicio/types-internal/lib/customtypes";
41
28
 
42
29
  interface TabZoneProps {
30
+ customType: CustomTypeSM;
43
31
  tabId: string;
32
+ sliceZone?: SlicesSM | null | undefined;
33
+ fields: TabFields;
44
34
  }
45
35
 
46
- type PoolOfFields = ReadonlyArray<{ key: string; value: TabField }>;
47
-
48
- const TabZone: FC<TabZoneProps> = ({ tabId }) => {
49
- const { customType, setCustomType } = useCustomTypeState();
50
- const customTypeSM = CustomTypes.toSM(customType);
51
- const sliceZone = customTypeSM.tabs.find((tab) => tab.key === tabId)
52
- ?.sliceZone;
53
- const fields: TabFields =
54
- customTypeSM.tabs.find((tab) => tab.key === tabId)?.value ?? [];
36
+ const TabZone: FC<TabZoneProps> = ({
37
+ customType,
38
+ tabId,
39
+ fields,
40
+ sliceZone,
41
+ }) => {
42
+ const {
43
+ deleteCustomTypeField,
44
+ addCustomTypeField,
45
+ reorderCustomTypeField,
46
+ replaceCustomTypeField,
47
+ createSliceZone,
48
+ deleteSliceZone,
49
+ deleteCustomTypeSharedSlice,
50
+ } = useSliceMachineActions();
55
51
 
56
52
  const { query } = useRouter();
57
- const poolOfFields = customTypeSM.tabs.reduce<PoolOfFields>(
58
- (acc: PoolOfFields, curr: TabSM) => {
59
- return [...acc, ...curr.value];
60
- },
61
- [],
62
- );
63
53
 
64
- const onDeleteItem = (fieldId: string) => {
65
- const newCustomType = deleteField({
66
- customType,
67
- fieldId,
68
- sectionId: tabId,
69
- });
54
+ const { poolOfFields } = useSelector((store: SliceMachineStoreType) => ({
55
+ poolOfFields: selectCurrentPoolOfFields(store),
56
+ }));
70
57
 
71
- setCustomType(newCustomType);
58
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
59
+ if (!poolOfFields) {
60
+ return null;
61
+ }
62
+
63
+ const onDeleteItem = (fieldId: string) => {
64
+ deleteCustomTypeField(tabId, fieldId);
72
65
  };
73
66
 
74
67
  const onSaveNewField = ({
@@ -87,67 +80,27 @@ const TabZone: FC<TabZoneProps> = ({ tabId }) => {
87
80
  // @ts-expect-error We have to create a widget map or a service instead of using export name
88
81
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
89
82
  const widget: Widget<TabField, AnyObjectSchema> = Widgets[widgetTypeName];
90
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment
91
- const field: TabField = widget.create(label);
92
-
93
- if (
94
- field.type === "Range" ||
95
- field.type === "IntegrationFields" ||
96
- field.type === "Separator"
97
- ) {
98
- throw new Error(`Unsupported Field Type: ${field.type}`);
99
- }
100
-
101
- const CurrentWidget: AnyWidget = Widgets[field.type];
102
-
103
- try {
104
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
105
- CurrentWidget.schema.validateSync(field, { stripUnknown: false });
106
- } catch (error) {
107
- throw new Error(`Add field: Model is invalid for field "${field.type}".`);
108
- }
109
-
110
- const newField: NestableWidget | UID | Group = TabFieldsModel.fromSM(field);
111
- const newCustomType = addField({
112
- customType,
113
- newField,
114
- newFieldId: id,
115
- sectionId: tabId,
116
- });
117
-
118
- setCustomType(newCustomType);
119
-
120
83
  void telemetry.track({
121
84
  event: "custom-type:field-added",
122
85
  id,
123
86
  name: customType.id,
124
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
125
87
  type: widget.TYPE_NAME,
126
88
  zone: "static",
127
89
  });
90
+ addCustomTypeField(tabId, id, widget.create(label));
128
91
  };
129
92
 
130
93
  const onDragEnd = (result: DropResult) => {
131
94
  if (ensureDnDDestination(result)) {
132
95
  return;
133
96
  }
134
-
135
- const { source, destination } = result;
136
- if (!destination) {
137
- return;
138
- }
139
-
140
- const newCustomType = reorderField({
141
- customType,
142
- sourceIndex: source.index,
143
- destinationIndex: destination.index,
144
- sectionId: tabId,
145
- });
146
-
147
- // When removing redux and replacing it by a simple useState, react-beautiful-dnd (that is deprecated library) was making the fields flickering on reorder.
148
- // The problem seems to come from the react non-synchronous way to handle our state update that didn't work well with the library.
149
- // It's a hack and since it's used on an old pure JavaScript code with a deprecated library it will be removed when updating the UI of the fields.
150
- flushSync(() => setCustomType(newCustomType));
97
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
98
+ reorderCustomTypeField(
99
+ tabId,
100
+ result.source.index,
101
+ // @ts-expect-error We have to change the typeGuard above to cast properly the "result" property
102
+ result.destination.index,
103
+ );
151
104
  };
152
105
 
153
106
  const onSave = ({
@@ -164,39 +117,19 @@ const TabZone: FC<TabZoneProps> = ({ tabId }) => {
164
117
  if (ensureWidgetTypeExistence(Widgets, value.type)) {
165
118
  return;
166
119
  }
167
-
168
- const newField: NestableWidget | UID | Group = TabFieldsModel.fromSM(value);
169
- const newCustomType = updateField({
170
- customType,
171
- previousFieldId: previousKey,
172
- newFieldId: newKey,
173
- newField,
174
- sectionId: tabId,
175
- });
176
-
177
- setCustomType(newCustomType);
120
+ replaceCustomTypeField(tabId, previousKey, newKey, value);
178
121
  };
179
122
 
180
123
  const onCreateSliceZone = () => {
181
- const newCustomType = createSectionSliceZone(customType, tabId);
182
-
183
- setCustomType(newCustomType);
124
+ createSliceZone(tabId);
184
125
  };
185
126
 
186
127
  const onDeleteSliceZone = () => {
187
- const newCustomType = deleteSectionSliceZone(customType, tabId);
188
-
189
- setCustomType(newCustomType);
128
+ deleteSliceZone(tabId);
190
129
  };
191
130
 
192
131
  const onRemoveSharedSlice = (sliceId: string) => {
193
- const newCustomType = deleteSliceZoneSlice({
194
- customType,
195
- sectionId: tabId,
196
- sliceId,
197
- });
198
-
199
- setCustomType(newCustomType);
132
+ deleteCustomTypeSharedSlice(tabId, sliceId);
200
133
  };
201
134
 
202
135
  return (
@@ -236,13 +169,13 @@ const TabZone: FC<TabZoneProps> = ({ tabId }) => {
236
169
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument
237
170
  `data${transformKeyAccessor(key)}`
238
171
  }
239
- dataCy="static-zone-content"
172
+ dataCy="ct-static-zone"
240
173
  isRepeatableCustomType={customType.repeatable}
241
174
  />
242
175
  ) : undefined}
243
176
 
244
177
  <SliceZone
245
- customType={customTypeSM}
178
+ customType={customType}
246
179
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
247
180
  tabId={tabId}
248
181
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment