Skip to content

Commit

Permalink
feat(auto-save): Auto-save on slice builder
Browse files Browse the repository at this point in the history
  • Loading branch information
xrutayisire committed Jan 10, 2024
1 parent 5ff0f6e commit 6320e1d
Show file tree
Hide file tree
Showing 47 changed files with 693 additions and 1,834 deletions.
23 changes: 12 additions & 11 deletions packages/slice-machine/components/DeleteVariationModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,32 @@ import {
Text,
} from "@prismicio/editor-ui";
import { useRouter } from "next/router";
import type { Dispatch, FC, PropsWithChildren, SetStateAction } from "react";
import { useState, type FC, type PropsWithChildren } from "react";

import type { SliceBuilderState } from "@builders/SliceBuilder";
import type { ComponentUI } from "@lib/models/common/ComponentUI";
import type { VariationSM } from "@lib/models/common/Slice";
import { deleteVariation } from "@src/features/slices/sliceBuilder/actions/deleteVariation";
import useSliceMachineActions from "@src/modules/useSliceMachineActions";
import { useSliceState } from "@src/features/slices/sliceBuilder/SliceBuilderProvider";

type DeleteVariationModalProps = {
isOpen: boolean;
onClose: () => void;
slice: ComponentUI;
variation: VariationSM | undefined;
sliceBuilderState: SliceBuilderState;
setSliceBuilderState: Dispatch<SetStateAction<SliceBuilderState>>;
};

export const DeleteVariationModal: FC<DeleteVariationModalProps> = ({
isOpen,
onClose,
slice,
variation,
sliceBuilderState,
setSliceBuilderState,
}) => {
const router = useRouter();
const { updateAndSaveSlice } = useSliceMachineActions();
const [isDeleting, setIsDeleting] = useState(false);
const { saveSliceSuccess } = useSliceMachineActions();
const { setSlice } = useSliceState();

return (
<Dialog
open={isOpen}
Expand All @@ -56,19 +55,21 @@ export const DeleteVariationModal: FC<DeleteVariationModalProps> = ({
onClick: () => {
if (!variation) return;
void (async () => {
setIsDeleting(true);
try {
await deleteVariation({
const newSlice = await deleteVariation({
component: slice,
router,
setSliceBuilderState,
updateAndSaveSlice,
saveSliceSuccess,
variation,
});
setSlice(newSlice);
} catch {}
setIsDeleting(false);
onClose();
})();
},
loading: sliceBuilderState.loading,
loading: isDeleting,
}}
cancel={{ text: "Cancel" }}
size="medium"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,33 @@ import {
Text,
} from "@prismicio/editor-ui";
import { Formik } from "formik";
import type { Dispatch, FC, SetStateAction } from "react";
import { useState, type FC } from "react";

import type { SliceBuilderState } from "@builders/SliceBuilder";
import type { ComponentUI } from "@lib/models/common/ComponentUI";
import type { VariationSM } from "@lib/models/common/Slice";
import { renameVariation } from "@src/features/slices/sliceBuilder/actions/renameVariation";
import useSliceMachineActions from "@src/modules/useSliceMachineActions";

import * as styles from "./RenameVariationModal.css";
import { useSliceState } from "@src/features/slices/sliceBuilder/SliceBuilderProvider";

type RenameVariationModalProps = {
isOpen: boolean;
onClose: () => void;
slice: ComponentUI;
variation: VariationSM | undefined;
sliceBuilderState: SliceBuilderState;
setSliceBuilderState: Dispatch<SetStateAction<SliceBuilderState>>;
};

export const RenameVariationModal: FC<RenameVariationModalProps> = ({
isOpen,
onClose,
slice,
variation,
sliceBuilderState,
setSliceBuilderState,
}) => {
const { updateAndSaveSlice } = useSliceMachineActions();
const [isRenaming, setRenaming] = useState(false);
const { setSlice } = useSliceState();
const { saveSliceSuccess } = useSliceMachineActions();

return (
<>
<Dialog
Expand All @@ -56,15 +55,17 @@ export const RenameVariationModal: FC<RenameVariationModalProps> = ({
}}
onSubmit={async (values) => {
if (!variation) return;
setRenaming(true);
try {
await renameVariation({
const newSlice = await renameVariation({
component: slice,
setSliceBuilderState,
updateAndSaveSlice,
saveSliceSuccess,
variation,
variationName: values.variationName.trim(),
});
setSlice(newSlice);
} catch {}
setRenaming(false);
onClose();
}}
>
Expand Down Expand Up @@ -102,7 +103,7 @@ export const RenameVariationModal: FC<RenameVariationModalProps> = ({
ok={{
text: "Rename",
onClick: () => void formik.submitForm(),
loading: sliceBuilderState.loading,
loading: isRenaming,
disabled: !formik.isValid,
}}
cancel={{ text: "Cancel" }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import { isLoading } from "@src/modules/loading";
import { LoadingKeysEnum } from "@src/modules/loading/types";
import { ScreenshotPreview } from "@components/ScreenshotPreview";
import { ComponentUI } from "@lib/models/common/ComponentUI";
import { uploadSliceScreenshot } from "@src/features/slices/actions/uploadSliceScreenshot";

interface DropZoneProps {
imageTypes?: string[];
variationID: string;
slice: ComponentUI;
onUploadSuccess?: (newSlice: ComponentUI) => void;
}

const DragActiveView = () => {
Expand Down Expand Up @@ -79,6 +81,7 @@ const DropZone: React.FC<DropZoneProps> = ({
variationID,
slice,
imageTypes = acceptedImagesTypes,
onUploadSuccess,
}) => {
const maybeScreenshot = slice.screenshots[variationID];

Expand All @@ -90,7 +93,7 @@ const DropZone: React.FC<DropZoneProps> = ({
slice,
]);

const { generateSliceCustomScreenshot } = useSliceMachineActions();
const { saveSliceCustomScreenshotSuccess } = useSliceMachineActions();

const { isLoadingScreenshot } = useSelector(
(state: SliceMachineStoreType) => ({
Expand All @@ -102,25 +105,44 @@ const DropZone: React.FC<DropZoneProps> = ({
);

const { FileInputRenderer, fileInputProps } = useCustomScreenshot({
onHandleFile: (file: File, isDragActive: boolean) => {
generateSliceCustomScreenshot(
variationID,
onHandleFile: async (file: File, isDragActive: boolean) => {
const newSlice = await uploadSliceScreenshot({
slice,
file,
isDragActive ? "dragAndDrop" : "upload",
);
method: isDragActive ? "dragAndDrop" : "upload",
variationId: variationID,
});
setIsHover(false);

const screenshot = newSlice?.screenshots[variationID];
if (screenshot) {
// Sync with redux store
saveSliceCustomScreenshotSuccess(variationID, screenshot, newSlice);
onUploadSuccess && onUploadSuccess(newSlice);
}
},
});

const handleFile = (file: File) => {
const handleFile = async (file: File) => {
if (file.size > 128000000) {
return openToaster(
"File is too big. Max file size: 128Mb.",
ToasterType.ERROR,
);
}
generateSliceCustomScreenshot(variationID, slice, file, "dragAndDrop");
const newSlice = await uploadSliceScreenshot({
slice,
file,
method: "dragAndDrop",
variationId: variationID,
});

const screenshot = newSlice?.screenshots[variationID];
if (screenshot) {
// Sync with redux store
saveSliceCustomScreenshotSuccess(variationID, screenshot, newSlice);
onUploadSuccess && onUploadSuccess(newSlice);
}
};

const supportsClipboardRead = typeof navigator.clipboard.read === "function";
Expand Down Expand Up @@ -149,7 +171,7 @@ const DropZone: React.FC<DropZoneProps> = ({
const maybeFile = event.dataTransfer.files?.[0];
if (maybeFile !== undefined) {
if (imageTypes.some((t) => `image/${t}` === maybeFile.type)) {
return handleFile(maybeFile);
return void handleFile(maybeFile);
}
return openToaster(
`Only files of type ${imageTypes.join(", ")} are accepted.`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,11 @@ const variationSetter = (
const ScreenshotChangesModal = ({
slices,
defaultVariationSelector,
onUploadSuccess,
}: {
slices: ComponentUI[];
defaultVariationSelector?: SliceVariationSelector;
onUploadSuccess?: (newSlice: ComponentUI) => void;
}) => {
const { closeModals } = useSliceMachineActions();

Expand Down Expand Up @@ -275,6 +277,7 @@ const ScreenshotChangesModal = ({
<VariationDropZone
variationID={variationSelector.variationID}
slice={slice}
onUploadSuccess={onUploadSuccess}
/>
) : null;
})()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { acceptedImagesTypes } from "@lib/consts";
type HandleFileProp = {
inputFile: React.RefObject<HTMLInputElement>;
children?: React.ReactNode;
handleFile: (file: File | undefined, isDragActive: boolean) => void;
handleFile: (file: File | undefined, isDragActive: boolean) => Promise<void>;
isDragActive: boolean;
};
type CustomScreenshotProps = {
onHandleFile: (file: File, isDragActive: boolean) => void;
onHandleFile: (file: File, isDragActive: boolean) => Promise<void>;
};

const FileInputRenderer: React.FC<HandleFileProp> = ({
Expand Down Expand Up @@ -43,7 +43,7 @@ const FileInputRenderer: React.FC<HandleFileProp> = ({
style={{ display: "none" }}
accept={acceptedImagesTypes.map((type) => `image/${type}`).join(",")}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
handleFile(e.target.files?.[0], isDragActive);
void handleFile(e.target.files?.[0], isDragActive);
}}
/>
</>
Expand All @@ -63,9 +63,9 @@ export default function useCustomScreenshot({
onHandleFile,
}: CustomScreenshotProps): CustomScreenshotPayload {
const inputFile = useRef<HTMLInputElement>(null);
const handleFile = (file: File | undefined, isDragActive: boolean) => {
const handleFile = async (file: File | undefined, isDragActive: boolean) => {
if (file) {
onHandleFile(file, isDragActive);
await onHandleFile(file, isDragActive);
if (inputFile?.current) {
inputFile.current.value = "";
}
Expand Down
12 changes: 9 additions & 3 deletions packages/slice-machine/components/Simulator/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
FC,
Suspense,
useCallback,
useEffect,
Expand Down Expand Up @@ -34,7 +35,6 @@ import useThrottle from "@src/hooks/useThrottle";
import useSliceMachineActions from "@src/modules/useSliceMachineActions";

import IframeRenderer from "./components/IframeRenderer";
import { ComponentWithSliceProps } from "@src/layouts/WithSlice";
import {
selectIframeStatus,
selectIsWaitingForIFrameCheck,
Expand All @@ -44,7 +44,8 @@ import {
import FullPage from "./components/FullPage";
import FailedConnect from "./components/FailedConnect";
import SetupModal from "./components/SetupModal";
import { Slices } from "@lib/models/common/Slice";
import { Slices, VariationSM } from "@lib/models/common/Slice";
import { ComponentUI } from "@lib/models/common/ComponentUI";

export enum UiState {
LOADING_SETUP = "LOADING_SETUP",
Expand All @@ -54,7 +55,12 @@ export enum UiState {
SUCCESS = "SUCCESS",
}

const Simulator: ComponentWithSliceProps = ({ slice, variation }) => {
type SimulatorProps = {
slice: ComponentUI;
variation: VariationSM;
};

const Simulator: FC<SimulatorProps> = ({ slice, variation }) => {
const { checkSimulatorSetup, connectToSimulatorIframe, saveSliceMock } =
useSliceMachineActions();
const {
Expand Down
Loading

0 comments on commit 6320e1d

Please sign in to comment.