slice-machine-ui 1.22.2-alpha.xru-auto-save-slice-builder.2 → 1.22.2-alpha.xru-auto-save-type-builder.7
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/components/DeleteVariationModal/index.tsx +11 -12
- package/components/Forms/RenameVariationModal/RenameVariationModal.tsx +11 -12
- package/components/ScreenshotChangesModal/VariationDropZone.tsx +9 -31
- package/components/ScreenshotChangesModal/index.tsx +0 -3
- package/components/ScreenshotChangesModal/useCustomScreenshot.tsx +5 -5
- package/components/Simulator/index.tsx +3 -9
- package/lib/builders/SliceBuilder/FieldZones/index.tsx +55 -80
- package/lib/builders/SliceBuilder/Sidebar/AddVariationModal.tsx +16 -24
- package/lib/builders/SliceBuilder/Sidebar/index.tsx +40 -38
- package/lib/builders/SliceBuilder/SimulatorButton/index.tsx +26 -3
- package/lib/builders/SliceBuilder/index.tsx +96 -10
- package/lib/builders/common/Zone/index.jsx +1 -1
- package/lib/models/common/Variation.ts +100 -0
- package/out/404.html +1 -1
- package/out/_next/static/chunks/418-e2ea0df42b95b92d.js +1 -0
- package/out/_next/static/chunks/482-9277ff10845fed91.js +1 -0
- package/out/_next/static/chunks/538-07f826266d011e85.js +1 -0
- package/out/_next/static/chunks/{799-60150dd63657f0cc.js → 799-378edb0fdc3a3a5a.js} +1 -1
- package/out/_next/static/chunks/80-7b8a97d0122ff74a.js +1 -0
- package/out/_next/static/chunks/858-0b07239d5a20b65c.js +28 -0
- package/out/_next/static/chunks/{918-5bb55fb464e34768.js → 918-38d08f1e885b222d.js} +1 -1
- package/out/_next/static/chunks/958-247df4bdf5efcb92.js +1 -0
- package/out/_next/static/chunks/pages/{_app-10b1f0f39518496e.js → _app-6584070fa9ed8af3.js} +69 -66
- package/out/_next/static/chunks/pages/{changelog-68d115a14f1423d7.js → changelog-f8e0869f0551f420.js} +1 -1
- package/out/_next/static/chunks/pages/changes-47fe6af1355195e4.js +1 -0
- package/out/_next/static/chunks/pages/custom-types/{[customTypeId]-956a2fc70fe78405.js → [customTypeId]-a8658e547a11045d.js} +1 -1
- package/out/_next/static/chunks/pages/{custom-types-f87f9caaa5f7d369.js → custom-types-309e8a31d3eb6e3a.js} +1 -1
- package/out/_next/static/chunks/pages/{index-8dd208ca96259817.js → index-75046c128aa61430.js} +1 -1
- package/out/_next/static/chunks/pages/page-types/{[pageTypeId]-686d4929e736f14a.js → [pageTypeId]-a03d9eea082a69b0.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]/{simulator-897ca93c114a1435.js → simulator-55d09564cc4f522a.js} +1 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-e084a43056f481f0.js +1 -0
- package/out/_next/static/chunks/pages/slices-b1494d473dcb76ee.js +1 -0
- package/out/_next/static/km0kuIQfnqh21eAANDKkL/_buildManifest.js +1 -0
- package/out/changelog.html +1 -1
- package/out/changes.html +1 -1
- package/out/custom-types/[customTypeId].html +1 -1
- package/out/custom-types.html +1 -1
- package/out/index.html +1 -1
- package/out/labs.html +1 -1
- package/out/page-types/[pageTypeId].html +1 -1
- package/out/slices/[lib]/[sliceName]/[variation]/simulator.html +1 -1
- package/out/slices/[lib]/[sliceName]/[variation].html +1 -1
- package/out/slices.html +1 -1
- package/package.json +3 -3
- package/pages/slices/[lib]/[sliceName]/[variation]/index.tsx +11 -25
- package/pages/slices/[lib]/[sliceName]/[variation]/simulator.tsx +9 -12
- package/src/domain/slice.ts +1 -166
- package/src/features/autoSave/{AutoSaveStatus.tsx → AutoSaveStatusIndicator.tsx} +8 -6
- package/src/features/autoSave/useAutoSave.tsx +132 -77
- package/src/features/customTypes/customTypesBuilder/CustomTypeProvider.tsx +20 -17
- package/src/features/customTypes/customTypesBuilder/CustomTypesBuilderPage.tsx +3 -3
- package/src/features/slices/convertLegacySlice/ConvertLegacySliceAsNewVariationDialog.tsx +5 -5
- package/src/features/slices/sliceBuilder/actions/deleteVariation.ts +21 -10
- package/src/features/slices/sliceBuilder/actions/renameVariation.ts +22 -10
- package/src/hooks/useCurrentSlice.tsx +16 -4
- package/src/hooks/useScreenshotChangesModal.ts +0 -1
- package/src/hooks/useServerState.ts +27 -1
- package/src/layouts/WithSlice.tsx +26 -0
- package/src/modules/screenshots/actions.ts +21 -0
- package/src/modules/screenshots/sagas.ts +70 -0
- package/src/modules/selectedSlice/actions.ts +106 -0
- package/src/modules/selectedSlice/reducer.ts +175 -0
- package/src/modules/selectedSlice/sagas.ts +72 -0
- package/src/modules/selectedSlice/selectors.ts +55 -0
- package/src/modules/selectedSlice/types.ts +3 -0
- package/src/modules/simulator/index.ts +2 -0
- package/src/modules/slices/index.ts +25 -32
- package/src/modules/toaster/utils.tsx +23 -0
- package/src/modules/useSliceMachineActions.ts +152 -18
- package/src/redux/reducer.ts +2 -0
- package/src/redux/saga.ts +4 -0
- package/src/redux/type.ts +2 -0
- package/test/src/modules/selectedSlice/__fixtures__/mocks.json +171 -0
- package/test/src/modules/selectedSlice/__fixtures__/model.json +35 -0
- package/test/src/modules/selectedSlice/__testutils__/getRefreshStateCreatorPayloadData.ts +72 -0
- package/test/src/modules/selectedSlice/__testutils__/getSelectedSliceDummyData.ts +30 -0
- package/test/src/modules/selectedSlice/reducer.test.ts +170 -0
- package/test/src/modules/selectedSlice/sagas.test.ts +82 -0
- package/test/src/modules/simulator.test.ts +2 -0
- package/test/src/modules/toaster/utils.test.ts +50 -0
- package/out/_next/static/BZjIFXXV7vJrc1uzD_Ies/_buildManifest.js +0 -1
- package/out/_next/static/chunks/423-6b74bf3de145fb7c.js +0 -1
- package/out/_next/static/chunks/50-cfc2514205b86001.js +0 -1
- package/out/_next/static/chunks/543-f8766685f7f451e2.js +0 -1
- package/out/_next/static/chunks/584-11ee6995b5faaab8.js +0 -1
- package/out/_next/static/chunks/59b4e022-7a3b5554b806349f.js +0 -1
- package/out/_next/static/chunks/696-b12edad30a3617e5.js +0 -31
- package/out/_next/static/chunks/749-b2f6153434701ad6.js +0 -1
- package/out/_next/static/chunks/787-727e3aef5d2a10a8.js +0 -1
- package/out/_next/static/chunks/904-30051a26c74a94d6.js +0 -1
- package/out/_next/static/chunks/f36c6662-03bb5e9d9aa0b0aa.js +0 -1
- package/out/_next/static/chunks/pages/changes-d6dc4c8074a1d8ca.js +0 -1
- package/out/_next/static/chunks/pages/slices/[lib]/[sliceName]/[variation]-f89c7178fd60120b.js +0 -1
- package/out/_next/static/chunks/pages/slices-153cda50ad258428.js +0 -1
- package/src/features/slices/actions/uploadSliceScreenshot.ts +0 -45
- package/src/features/slices/sliceBuilder/SliceBuilderProvider.tsx +0 -115
- package/src/modules/slices/selector.ts +0 -30
- /package/out/_next/static/{BZjIFXXV7vJrc1uzD_Ies → km0kuIQfnqh21eAANDKkL}/_ssgManifest.js +0 -0
|
@@ -7,19 +7,21 @@ import {
|
|
|
7
7
|
Text,
|
|
8
8
|
} from "@prismicio/editor-ui";
|
|
9
9
|
import { useRouter } from "next/router";
|
|
10
|
-
import {
|
|
10
|
+
import type { Dispatch, FC, PropsWithChildren, SetStateAction } from "react";
|
|
11
11
|
|
|
12
|
+
import type { SliceBuilderState } from "@builders/SliceBuilder";
|
|
12
13
|
import type { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
13
14
|
import type { VariationSM } from "@lib/models/common/Slice";
|
|
14
15
|
import { deleteVariation } from "@src/features/slices/sliceBuilder/actions/deleteVariation";
|
|
15
16
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
16
|
-
import { useSliceState } from "@src/features/slices/sliceBuilder/SliceBuilderProvider";
|
|
17
17
|
|
|
18
18
|
type DeleteVariationModalProps = {
|
|
19
19
|
isOpen: boolean;
|
|
20
20
|
onClose: () => void;
|
|
21
21
|
slice: ComponentUI;
|
|
22
22
|
variation: VariationSM | undefined;
|
|
23
|
+
sliceBuilderState: SliceBuilderState;
|
|
24
|
+
setSliceBuilderState: Dispatch<SetStateAction<SliceBuilderState>>;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
export const DeleteVariationModal: FC<DeleteVariationModalProps> = ({
|
|
@@ -27,12 +29,11 @@ export const DeleteVariationModal: FC<DeleteVariationModalProps> = ({
|
|
|
27
29
|
onClose,
|
|
28
30
|
slice,
|
|
29
31
|
variation,
|
|
32
|
+
sliceBuilderState,
|
|
33
|
+
setSliceBuilderState,
|
|
30
34
|
}) => {
|
|
31
35
|
const router = useRouter();
|
|
32
|
-
const
|
|
33
|
-
const { saveSliceSuccess } = useSliceMachineActions();
|
|
34
|
-
const { setSlice } = useSliceState();
|
|
35
|
-
|
|
36
|
+
const { updateAndSaveSlice } = useSliceMachineActions();
|
|
36
37
|
return (
|
|
37
38
|
<Dialog
|
|
38
39
|
open={isOpen}
|
|
@@ -55,21 +56,19 @@ export const DeleteVariationModal: FC<DeleteVariationModalProps> = ({
|
|
|
55
56
|
onClick: () => {
|
|
56
57
|
if (!variation) return;
|
|
57
58
|
void (async () => {
|
|
58
|
-
setIsDeleting(true);
|
|
59
59
|
try {
|
|
60
|
-
|
|
60
|
+
await deleteVariation({
|
|
61
61
|
component: slice,
|
|
62
62
|
router,
|
|
63
|
-
|
|
63
|
+
setSliceBuilderState,
|
|
64
|
+
updateAndSaveSlice,
|
|
64
65
|
variation,
|
|
65
66
|
});
|
|
66
|
-
setSlice(newSlice);
|
|
67
67
|
} catch {}
|
|
68
|
-
setIsDeleting(false);
|
|
69
68
|
onClose();
|
|
70
69
|
})();
|
|
71
70
|
},
|
|
72
|
-
loading:
|
|
71
|
+
loading: sliceBuilderState.loading,
|
|
73
72
|
}}
|
|
74
73
|
cancel={{ text: "Cancel" }}
|
|
75
74
|
size="medium"
|
|
@@ -8,21 +8,23 @@ import {
|
|
|
8
8
|
Text,
|
|
9
9
|
} from "@prismicio/editor-ui";
|
|
10
10
|
import { Formik } from "formik";
|
|
11
|
-
import {
|
|
11
|
+
import type { Dispatch, FC, SetStateAction } from "react";
|
|
12
12
|
|
|
13
|
+
import type { SliceBuilderState } from "@builders/SliceBuilder";
|
|
13
14
|
import type { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
14
15
|
import type { VariationSM } from "@lib/models/common/Slice";
|
|
15
16
|
import { renameVariation } from "@src/features/slices/sliceBuilder/actions/renameVariation";
|
|
16
17
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
17
18
|
|
|
18
19
|
import * as styles from "./RenameVariationModal.css";
|
|
19
|
-
import { useSliceState } from "@src/features/slices/sliceBuilder/SliceBuilderProvider";
|
|
20
20
|
|
|
21
21
|
type RenameVariationModalProps = {
|
|
22
22
|
isOpen: boolean;
|
|
23
23
|
onClose: () => void;
|
|
24
24
|
slice: ComponentUI;
|
|
25
25
|
variation: VariationSM | undefined;
|
|
26
|
+
sliceBuilderState: SliceBuilderState;
|
|
27
|
+
setSliceBuilderState: Dispatch<SetStateAction<SliceBuilderState>>;
|
|
26
28
|
};
|
|
27
29
|
|
|
28
30
|
export const RenameVariationModal: FC<RenameVariationModalProps> = ({
|
|
@@ -30,11 +32,10 @@ export const RenameVariationModal: FC<RenameVariationModalProps> = ({
|
|
|
30
32
|
onClose,
|
|
31
33
|
slice,
|
|
32
34
|
variation,
|
|
35
|
+
sliceBuilderState,
|
|
36
|
+
setSliceBuilderState,
|
|
33
37
|
}) => {
|
|
34
|
-
const
|
|
35
|
-
const { setSlice } = useSliceState();
|
|
36
|
-
const { saveSliceSuccess } = useSliceMachineActions();
|
|
37
|
-
|
|
38
|
+
const { updateAndSaveSlice } = useSliceMachineActions();
|
|
38
39
|
return (
|
|
39
40
|
<>
|
|
40
41
|
<Dialog
|
|
@@ -55,17 +56,15 @@ export const RenameVariationModal: FC<RenameVariationModalProps> = ({
|
|
|
55
56
|
}}
|
|
56
57
|
onSubmit={async (values) => {
|
|
57
58
|
if (!variation) return;
|
|
58
|
-
setRenaming(true);
|
|
59
59
|
try {
|
|
60
|
-
|
|
60
|
+
await renameVariation({
|
|
61
61
|
component: slice,
|
|
62
|
-
|
|
62
|
+
setSliceBuilderState,
|
|
63
|
+
updateAndSaveSlice,
|
|
63
64
|
variation,
|
|
64
65
|
variationName: values.variationName.trim(),
|
|
65
66
|
});
|
|
66
|
-
setSlice(newSlice);
|
|
67
67
|
} catch {}
|
|
68
|
-
setRenaming(false);
|
|
69
68
|
onClose();
|
|
70
69
|
}}
|
|
71
70
|
>
|
|
@@ -103,7 +102,7 @@ export const RenameVariationModal: FC<RenameVariationModalProps> = ({
|
|
|
103
102
|
ok={{
|
|
104
103
|
text: "Rename",
|
|
105
104
|
onClick: () => void formik.submitForm(),
|
|
106
|
-
loading:
|
|
105
|
+
loading: sliceBuilderState.loading,
|
|
107
106
|
disabled: !formik.isValid,
|
|
108
107
|
}}
|
|
109
108
|
cancel={{ text: "Cancel" }}
|
|
@@ -14,13 +14,11 @@ import { isLoading } from "@src/modules/loading";
|
|
|
14
14
|
import { LoadingKeysEnum } from "@src/modules/loading/types";
|
|
15
15
|
import { ScreenshotPreview } from "@components/ScreenshotPreview";
|
|
16
16
|
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
17
|
-
import { uploadSliceScreenshot } from "@src/features/slices/actions/uploadSliceScreenshot";
|
|
18
17
|
|
|
19
18
|
interface DropZoneProps {
|
|
20
19
|
imageTypes?: string[];
|
|
21
20
|
variationID: string;
|
|
22
21
|
slice: ComponentUI;
|
|
23
|
-
onUploadSuccess?: (newSlice: ComponentUI) => void;
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
const DragActiveView = () => {
|
|
@@ -81,7 +79,6 @@ const DropZone: React.FC<DropZoneProps> = ({
|
|
|
81
79
|
variationID,
|
|
82
80
|
slice,
|
|
83
81
|
imageTypes = acceptedImagesTypes,
|
|
84
|
-
onUploadSuccess,
|
|
85
82
|
}) => {
|
|
86
83
|
const maybeScreenshot = slice.screenshots[variationID];
|
|
87
84
|
|
|
@@ -93,7 +90,7 @@ const DropZone: React.FC<DropZoneProps> = ({
|
|
|
93
90
|
slice,
|
|
94
91
|
]);
|
|
95
92
|
|
|
96
|
-
const {
|
|
93
|
+
const { generateSliceCustomScreenshot } = useSliceMachineActions();
|
|
97
94
|
|
|
98
95
|
const { isLoadingScreenshot } = useSelector(
|
|
99
96
|
(state: SliceMachineStoreType) => ({
|
|
@@ -105,44 +102,25 @@ const DropZone: React.FC<DropZoneProps> = ({
|
|
|
105
102
|
);
|
|
106
103
|
|
|
107
104
|
const { FileInputRenderer, fileInputProps } = useCustomScreenshot({
|
|
108
|
-
onHandleFile:
|
|
109
|
-
|
|
105
|
+
onHandleFile: (file: File, isDragActive: boolean) => {
|
|
106
|
+
generateSliceCustomScreenshot(
|
|
107
|
+
variationID,
|
|
110
108
|
slice,
|
|
111
109
|
file,
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
110
|
+
isDragActive ? "dragAndDrop" : "upload",
|
|
111
|
+
);
|
|
115
112
|
setIsHover(false);
|
|
116
|
-
|
|
117
|
-
const screenshot = newSlice?.screenshots[variationID];
|
|
118
|
-
if (screenshot) {
|
|
119
|
-
// Sync with redux store
|
|
120
|
-
saveSliceCustomScreenshotSuccess(variationID, screenshot, newSlice);
|
|
121
|
-
onUploadSuccess && onUploadSuccess(newSlice);
|
|
122
|
-
}
|
|
123
113
|
},
|
|
124
114
|
});
|
|
125
115
|
|
|
126
|
-
const handleFile =
|
|
116
|
+
const handleFile = (file: File) => {
|
|
127
117
|
if (file.size > 128000000) {
|
|
128
118
|
return openToaster(
|
|
129
119
|
"File is too big. Max file size: 128Mb.",
|
|
130
120
|
ToasterType.ERROR,
|
|
131
121
|
);
|
|
132
122
|
}
|
|
133
|
-
|
|
134
|
-
slice,
|
|
135
|
-
file,
|
|
136
|
-
method: "dragAndDrop",
|
|
137
|
-
variationId: variationID,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const screenshot = newSlice?.screenshots[variationID];
|
|
141
|
-
if (screenshot) {
|
|
142
|
-
// Sync with redux store
|
|
143
|
-
saveSliceCustomScreenshotSuccess(variationID, screenshot, newSlice);
|
|
144
|
-
onUploadSuccess && onUploadSuccess(newSlice);
|
|
145
|
-
}
|
|
123
|
+
generateSliceCustomScreenshot(variationID, slice, file, "dragAndDrop");
|
|
146
124
|
};
|
|
147
125
|
|
|
148
126
|
const supportsClipboardRead = typeof navigator.clipboard.read === "function";
|
|
@@ -171,7 +149,7 @@ const DropZone: React.FC<DropZoneProps> = ({
|
|
|
171
149
|
const maybeFile = event.dataTransfer.files?.[0];
|
|
172
150
|
if (maybeFile !== undefined) {
|
|
173
151
|
if (imageTypes.some((t) => `image/${t}` === maybeFile.type)) {
|
|
174
|
-
return
|
|
152
|
+
return handleFile(maybeFile);
|
|
175
153
|
}
|
|
176
154
|
return openToaster(
|
|
177
155
|
`Only files of type ${imageTypes.join(", ")} are accepted.`,
|
|
@@ -171,11 +171,9 @@ const variationSetter = (
|
|
|
171
171
|
const ScreenshotChangesModal = ({
|
|
172
172
|
slices,
|
|
173
173
|
defaultVariationSelector,
|
|
174
|
-
onUploadSuccess,
|
|
175
174
|
}: {
|
|
176
175
|
slices: ComponentUI[];
|
|
177
176
|
defaultVariationSelector?: SliceVariationSelector;
|
|
178
|
-
onUploadSuccess?: (newSlice: ComponentUI) => void;
|
|
179
177
|
}) => {
|
|
180
178
|
const { closeModals } = useSliceMachineActions();
|
|
181
179
|
|
|
@@ -277,7 +275,6 @@ const ScreenshotChangesModal = ({
|
|
|
277
275
|
<VariationDropZone
|
|
278
276
|
variationID={variationSelector.variationID}
|
|
279
277
|
slice={slice}
|
|
280
|
-
onUploadSuccess={onUploadSuccess}
|
|
281
278
|
/>
|
|
282
279
|
) : null;
|
|
283
280
|
})()}
|
|
@@ -6,11 +6,11 @@ import { acceptedImagesTypes } from "@lib/consts";
|
|
|
6
6
|
type HandleFileProp = {
|
|
7
7
|
inputFile: React.RefObject<HTMLInputElement>;
|
|
8
8
|
children?: React.ReactNode;
|
|
9
|
-
handleFile: (file: File | undefined, isDragActive: boolean) =>
|
|
9
|
+
handleFile: (file: File | undefined, isDragActive: boolean) => void;
|
|
10
10
|
isDragActive: boolean;
|
|
11
11
|
};
|
|
12
12
|
type CustomScreenshotProps = {
|
|
13
|
-
onHandleFile: (file: File, isDragActive: boolean) =>
|
|
13
|
+
onHandleFile: (file: File, isDragActive: boolean) => void;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
const FileInputRenderer: React.FC<HandleFileProp> = ({
|
|
@@ -43,7 +43,7 @@ const FileInputRenderer: React.FC<HandleFileProp> = ({
|
|
|
43
43
|
style={{ display: "none" }}
|
|
44
44
|
accept={acceptedImagesTypes.map((type) => `image/${type}`).join(",")}
|
|
45
45
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
46
|
-
|
|
46
|
+
handleFile(e.target.files?.[0], isDragActive);
|
|
47
47
|
}}
|
|
48
48
|
/>
|
|
49
49
|
</>
|
|
@@ -63,9 +63,9 @@ export default function useCustomScreenshot({
|
|
|
63
63
|
onHandleFile,
|
|
64
64
|
}: CustomScreenshotProps): CustomScreenshotPayload {
|
|
65
65
|
const inputFile = useRef<HTMLInputElement>(null);
|
|
66
|
-
const handleFile =
|
|
66
|
+
const handleFile = (file: File | undefined, isDragActive: boolean) => {
|
|
67
67
|
if (file) {
|
|
68
|
-
|
|
68
|
+
onHandleFile(file, isDragActive);
|
|
69
69
|
if (inputFile?.current) {
|
|
70
70
|
inputFile.current.value = "";
|
|
71
71
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
FC,
|
|
3
2
|
Suspense,
|
|
4
3
|
useCallback,
|
|
5
4
|
useEffect,
|
|
@@ -35,6 +34,7 @@ import useThrottle from "@src/hooks/useThrottle";
|
|
|
35
34
|
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
36
35
|
|
|
37
36
|
import IframeRenderer from "./components/IframeRenderer";
|
|
37
|
+
import { ComponentWithSliceProps } from "@src/layouts/WithSlice";
|
|
38
38
|
import {
|
|
39
39
|
selectIframeStatus,
|
|
40
40
|
selectIsWaitingForIFrameCheck,
|
|
@@ -44,8 +44,7 @@ import {
|
|
|
44
44
|
import FullPage from "./components/FullPage";
|
|
45
45
|
import FailedConnect from "./components/FailedConnect";
|
|
46
46
|
import SetupModal from "./components/SetupModal";
|
|
47
|
-
import { Slices
|
|
48
|
-
import { ComponentUI } from "@lib/models/common/ComponentUI";
|
|
47
|
+
import { Slices } from "@lib/models/common/Slice";
|
|
49
48
|
|
|
50
49
|
export enum UiState {
|
|
51
50
|
LOADING_SETUP = "LOADING_SETUP",
|
|
@@ -55,12 +54,7 @@ export enum UiState {
|
|
|
55
54
|
SUCCESS = "SUCCESS",
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
slice: ComponentUI;
|
|
60
|
-
variation: VariationSM;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const Simulator: FC<SimulatorProps> = ({ slice, variation }) => {
|
|
57
|
+
const Simulator: ComponentWithSliceProps = ({ slice, variation }) => {
|
|
64
58
|
const { checkSimulatorSetup, connectToSimulatorIframe, saveSliceMock } =
|
|
65
59
|
useSliceMachineActions();
|
|
66
60
|
const {
|
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
import { FC } from "react";
|
|
2
|
-
import { flushSync } from "react-dom";
|
|
3
|
-
import { DropResult } from "react-beautiful-dnd";
|
|
4
|
-
import { NestableWidget } from "@prismicio/types-internal/lib/customtypes";
|
|
5
|
-
|
|
6
1
|
import { ensureDnDDestination } from "@lib/utils";
|
|
7
2
|
import { transformKeyAccessor } from "@utils/str";
|
|
3
|
+
|
|
4
|
+
import Zone from "../../common/Zone";
|
|
5
|
+
import EditModal from "../../common/EditModal";
|
|
6
|
+
|
|
8
7
|
import * as Widgets from "@lib/models/common/widgets";
|
|
9
8
|
import sliceBuilderWidgetsArray from "@lib/models/common/widgets/sliceBuilderArray";
|
|
9
|
+
|
|
10
|
+
import { DropResult } from "react-beautiful-dnd";
|
|
10
11
|
import { List } from "@src/components/List";
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
deleteField,
|
|
16
|
-
reorderField,
|
|
17
|
-
updateField,
|
|
18
|
-
} from "@src/domain/slice";
|
|
19
|
-
import Zone from "@lib/builders/common/Zone";
|
|
20
|
-
import EditModal from "@lib/builders/common/EditModal";
|
|
21
|
-
import { AnyWidget } from "@lib/models/common/widgets/Widget";
|
|
12
|
+
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
|
|
13
|
+
import { VariationSM, WidgetsArea } from "@lib/models/common/Slice";
|
|
14
|
+
|
|
15
|
+
import { NestableWidget } from "@prismicio/types-internal/lib/customtypes";
|
|
22
16
|
|
|
23
17
|
const dataTipText = ` The non-repeatable zone
|
|
24
18
|
is for fields<br/> that should appear once, like a<br/>
|
|
@@ -28,18 +22,24 @@ const dataTipText2 = `The repeatable zone is for a group<br/>
|
|
|
28
22
|
of fields that you want to be able to repeat an<br/>
|
|
29
23
|
indeterminate number of times, like FAQs`;
|
|
30
24
|
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
type FieldZonesProps = {
|
|
26
|
+
variation: VariationSM;
|
|
27
|
+
};
|
|
33
28
|
|
|
29
|
+
const FieldZones: React.FunctionComponent<FieldZonesProps> = ({
|
|
30
|
+
variation,
|
|
31
|
+
}) => {
|
|
32
|
+
const {
|
|
33
|
+
addSliceWidget,
|
|
34
|
+
replaceSliceWidget,
|
|
35
|
+
reorderSliceWidget,
|
|
36
|
+
removeSliceWidget,
|
|
37
|
+
updateSliceWidgetMock,
|
|
38
|
+
deleteSliceWidgetMock,
|
|
39
|
+
} = useSliceMachineActions();
|
|
34
40
|
const _onDeleteItem = (widgetArea: WidgetsArea) => (key: string) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
variationId: variation.id,
|
|
38
|
-
widgetArea,
|
|
39
|
-
fieldId: key,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
setSlice(newSlice);
|
|
41
|
+
deleteSliceWidgetMock(variation.id, widgetArea, key);
|
|
42
|
+
removeSliceWidget(variation.id, widgetArea, key);
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
const _onSave =
|
|
@@ -48,23 +48,30 @@ const FieldZones: FC = () => {
|
|
|
48
48
|
apiId: previousKey,
|
|
49
49
|
newKey,
|
|
50
50
|
value,
|
|
51
|
+
mockValue,
|
|
51
52
|
}: {
|
|
52
53
|
apiId: string;
|
|
53
54
|
newKey: string;
|
|
54
55
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
56
|
value: any;
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
+
mockValue: any;
|
|
56
59
|
}) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
61
|
+
if (mockValue) {
|
|
62
|
+
updateSliceWidgetMock(
|
|
63
|
+
variation.id,
|
|
64
|
+
widgetArea,
|
|
65
|
+
previousKey,
|
|
66
|
+
newKey,
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
68
|
+
mockValue,
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
deleteSliceWidgetMock(variation.id, widgetArea, newKey);
|
|
72
|
+
}
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
74
|
+
replaceSliceWidget(variation.id, widgetArea, previousKey, newKey, value);
|
|
68
75
|
};
|
|
69
76
|
|
|
70
77
|
const _onSaveNewField =
|
|
@@ -89,56 +96,24 @@ const FieldZones: FC = () => {
|
|
|
89
96
|
);
|
|
90
97
|
}
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
newField.type === "Range" ||
|
|
97
|
-
newField.type === "IntegrationFields" ||
|
|
98
|
-
newField.type === "Separator"
|
|
99
|
-
) {
|
|
100
|
-
throw new Error(`Unsupported Field Type: ${newField.type}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
const CurrentWidget: AnyWidget = Widgets[newField.type];
|
|
105
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
106
|
-
CurrentWidget.schema.validateSync(newField, { stripUnknown: false });
|
|
107
|
-
} catch (error) {
|
|
108
|
-
throw new Error(`Model is invalid for widget "${newField.type}".`);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const newSlice = addField({
|
|
112
|
-
slice,
|
|
113
|
-
variationId: variation.id,
|
|
99
|
+
addSliceWidget(
|
|
100
|
+
variation.id,
|
|
114
101
|
widgetArea,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
setSlice(newSlice);
|
|
102
|
+
id,
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
104
|
+
widget.create(label) as NestableWidget,
|
|
105
|
+
);
|
|
120
106
|
};
|
|
121
107
|
|
|
122
108
|
const _onDragEnd = (widgetArea: WidgetsArea) => (result: DropResult) => {
|
|
123
109
|
if (ensureDnDDestination(result)) return;
|
|
124
110
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const newSlice = reorderField({
|
|
131
|
-
slice,
|
|
132
|
-
variationId: variation.id,
|
|
111
|
+
reorderSliceWidget(
|
|
112
|
+
variation.id,
|
|
133
113
|
widgetArea,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
// When removing redux and replacing it by a simple useState, react-beautiful-dnd (that is deprecated library) was making the fields flickering on reorder.
|
|
139
|
-
// The problem seems to come from the react non-synchronous way to handle our state update that didn't work well with the library.
|
|
140
|
-
// 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.
|
|
141
|
-
flushSync(() => setSlice(newSlice));
|
|
114
|
+
result.source.index,
|
|
115
|
+
result.destination?.index ?? undefined,
|
|
116
|
+
);
|
|
142
117
|
};
|
|
143
118
|
|
|
144
119
|
return (
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { Variation } from "@models/common/Variation";
|
|
2
|
+
import { VariationSM } from "@lib/models/common/Slice";
|
|
1
3
|
import React, { useEffect, useState } from "react";
|
|
2
|
-
import Select from "react-select";
|
|
3
4
|
import { Formik, Form, Field } from "formik";
|
|
4
|
-
import { Button, Box } from "@prismicio/editor-ui";
|
|
5
|
-
import { Text, Label, Input } from "theme-ui";
|
|
6
|
-
import { camelCase } from "lodash";
|
|
7
|
-
|
|
8
5
|
import SliceMachineModal from "@components/SliceMachineModal";
|
|
6
|
+
|
|
9
7
|
import Card from "@components/Card/Default";
|
|
10
|
-
import
|
|
8
|
+
import Select from "react-select";
|
|
9
|
+
|
|
10
|
+
import { Text, Box, Button, Label, Input, Flex } from "theme-ui";
|
|
11
11
|
|
|
12
12
|
const Error = ({ msg }: { msg?: string }) => (
|
|
13
13
|
<Text as="span" sx={{ fontSize: 12, color: "error", mt: "5px", ml: 2 }}>
|
|
@@ -17,14 +17,9 @@ const Error = ({ msg }: { msg?: string }) => (
|
|
|
17
17
|
);
|
|
18
18
|
const AddVariationModal: React.FunctionComponent<{
|
|
19
19
|
isOpen: boolean;
|
|
20
|
-
loading?: boolean;
|
|
21
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
21
|
onClose: () => any;
|
|
23
|
-
onSubmit: (
|
|
24
|
-
id: string,
|
|
25
|
-
name: string,
|
|
26
|
-
copiedVariation: VariationSM,
|
|
27
|
-
) => Promise<void>;
|
|
22
|
+
onSubmit: (id: string, name: string, copiedVariation: VariationSM) => void;
|
|
28
23
|
initialVariation: VariationSM;
|
|
29
24
|
variations: ReadonlyArray<VariationSM>;
|
|
30
25
|
}> = ({ isOpen, onClose, onSubmit, initialVariation, variations }) => {
|
|
@@ -36,7 +31,6 @@ const AddVariationModal: React.FunctionComponent<{
|
|
|
36
31
|
value: initialVariation.id,
|
|
37
32
|
label: initialVariation.name,
|
|
38
33
|
});
|
|
39
|
-
const [isAddingVariation, setIsAddingVariation] = useState(false);
|
|
40
34
|
|
|
41
35
|
function validateForm({
|
|
42
36
|
id,
|
|
@@ -76,7 +70,7 @@ const AddVariationModal: React.FunctionComponent<{
|
|
|
76
70
|
}
|
|
77
71
|
|
|
78
72
|
function generateId(str: string) {
|
|
79
|
-
const slug =
|
|
73
|
+
const slug = Variation.generateId(str);
|
|
80
74
|
setGeneratedId(slug);
|
|
81
75
|
}
|
|
82
76
|
|
|
@@ -116,9 +110,7 @@ const AddVariationModal: React.FunctionComponent<{
|
|
|
116
110
|
else {
|
|
117
111
|
const copiedVariation = variations.find((v) => v.id === origin.value);
|
|
118
112
|
if (copiedVariation) {
|
|
119
|
-
|
|
120
|
-
await onSubmit(generatedId, name, copiedVariation);
|
|
121
|
-
setIsAddingVariation(false);
|
|
113
|
+
onSubmit(generatedId, name, copiedVariation);
|
|
122
114
|
handleClose();
|
|
123
115
|
}
|
|
124
116
|
}
|
|
@@ -156,16 +148,16 @@ const AddVariationModal: React.FunctionComponent<{
|
|
|
156
148
|
sx={{ textAlign: "left" }}
|
|
157
149
|
HeaderContent={<Text as="h2">Add new Variation</Text>}
|
|
158
150
|
FooterContent={
|
|
159
|
-
<
|
|
160
|
-
<Button onClick={handleClose}
|
|
151
|
+
<Flex sx={{ justifyContent: "flex-end" }}>
|
|
152
|
+
<Button onClick={handleClose} mr={2} variant="secondary">
|
|
161
153
|
Cancel
|
|
162
154
|
</Button>
|
|
163
|
-
<Button
|
|
164
|
-
</
|
|
155
|
+
<Button type="submit">Submit</Button>
|
|
156
|
+
</Flex>
|
|
165
157
|
}
|
|
166
158
|
close={handleClose}
|
|
167
159
|
>
|
|
168
|
-
<Box
|
|
160
|
+
<Box sx={{ pb: 4, mt: 4 }}>
|
|
169
161
|
<Label htmlFor="name" sx={{ mb: 1 }}>
|
|
170
162
|
Variation name*
|
|
171
163
|
{errors.name ? <Error msg={errors.name} /> : ""}
|
|
@@ -187,7 +179,7 @@ const AddVariationModal: React.FunctionComponent<{
|
|
|
187
179
|
in Prismic
|
|
188
180
|
</Text>
|
|
189
181
|
</Box>
|
|
190
|
-
<Box
|
|
182
|
+
<Box sx={{ pb: 4 }}>
|
|
191
183
|
<Label htmlFor="id" sx={{ mb: 1 }}>
|
|
192
184
|
Variation ID*{errors.id ? <Error msg={errors.id} /> : ""}
|
|
193
185
|
</Label>
|
|
@@ -209,7 +201,7 @@ const AddVariationModal: React.FunctionComponent<{
|
|
|
209
201
|
</Text>
|
|
210
202
|
</Box>
|
|
211
203
|
|
|
212
|
-
<Box
|
|
204
|
+
<Box sx={{ pb: 4 }}>
|
|
213
205
|
<Label htmlFor="origin" sx={{ mb: 1 }}>
|
|
214
206
|
Duplicate from
|
|
215
207
|
</Label>
|