mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-05 03:28:59 +09:00
When setting up a Resource variable, you want to see what data comes back instantly, seeing inspector comes in quite handy ## Code Review - [ ] hi @istarkov , I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [ ] made a self-review - [ ] added inline comments where things may be not obvious (the "why", not "what") ## Before merging - [ ] tested locally and on preview environment (preview dev login: 5de6) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env.example` and the `builder/env-check.js` if mandatory
149 lines
3.4 KiB
TypeScript
149 lines
3.4 KiB
TypeScript
import { useState } from "react";
|
|
import { useNavigate, useRevalidator } from "@remix-run/react";
|
|
import {
|
|
Box,
|
|
Button,
|
|
Flex,
|
|
Label,
|
|
Text,
|
|
theme,
|
|
InputField,
|
|
DialogContent,
|
|
DialogTitle,
|
|
DialogClose,
|
|
Dialog,
|
|
DialogActions,
|
|
} from "@webstudio-is/design-system";
|
|
import { Title, Project } from "@webstudio-is/project";
|
|
import { builderPath } from "~/shared/router-utils";
|
|
import { trpcClient } from "./trpc/trpc-client";
|
|
|
|
const useCloneProject = ({
|
|
projectId,
|
|
onOpenChange,
|
|
}: {
|
|
projectId: Project["id"];
|
|
onOpenChange: (isOpen: boolean) => void;
|
|
}) => {
|
|
const revalidator = useRevalidator();
|
|
const navigate = useNavigate();
|
|
const { send, state } = trpcClient.project.clone.useMutation();
|
|
const [errors, setErrors] = useState<string>();
|
|
|
|
const handleSubmit = ({ title }: { title: string }) => {
|
|
const parsed = Title.safeParse(title);
|
|
const errors =
|
|
"error" in parsed
|
|
? parsed.error.issues.map((issue) => issue.message).join("\n")
|
|
: undefined;
|
|
|
|
setErrors(errors);
|
|
|
|
if (parsed.success) {
|
|
send({ projectId, title }, (data) => {
|
|
revalidator.revalidate();
|
|
if (data?.id) {
|
|
navigate(builderPath({ projectId: data.id }));
|
|
onOpenChange(false);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
return {
|
|
handleSubmit,
|
|
errors,
|
|
state,
|
|
};
|
|
};
|
|
|
|
const CloneProjectView = ({
|
|
isOpen,
|
|
title,
|
|
errors,
|
|
state,
|
|
onOpenChange,
|
|
onSubmit,
|
|
}: {
|
|
isOpen: boolean;
|
|
title: string;
|
|
errors?: string;
|
|
state: "idle" | "loading" | "submitting";
|
|
onOpenChange: (isOpen: boolean) => void;
|
|
onSubmit: ({ title }: { title: string }) => void;
|
|
}) => {
|
|
return (
|
|
<Dialog open={isOpen} onOpenChange={onOpenChange}>
|
|
<DialogContent>
|
|
<form
|
|
onSubmit={(event) => {
|
|
event.preventDefault();
|
|
const formData = new FormData(
|
|
event.currentTarget as HTMLFormElement
|
|
);
|
|
const title = String(formData.get("title") ?? "");
|
|
onSubmit({ title });
|
|
}}
|
|
>
|
|
<Flex
|
|
direction="column"
|
|
css={{
|
|
px: theme.spacing["9"],
|
|
paddingTop: theme.spacing["5"],
|
|
}}
|
|
gap="1"
|
|
>
|
|
<Label>Project Title</Label>
|
|
<InputField
|
|
name="title"
|
|
defaultValue={title}
|
|
color={errors ? "error" : undefined}
|
|
/>
|
|
<Box css={{ minHeight: theme.spacing["10"] }}>
|
|
{errors && <Text color="destructive">{errors}</Text>}
|
|
</Box>
|
|
</Flex>
|
|
<DialogActions>
|
|
<Button
|
|
type="submit"
|
|
state={state === "idle" ? undefined : "pending"}
|
|
>
|
|
Clone
|
|
</Button>
|
|
<DialogClose asChild>
|
|
<Button color="ghost">Cancel</Button>
|
|
</DialogClose>
|
|
</DialogActions>
|
|
</form>
|
|
<DialogTitle>Clone Project</DialogTitle>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
};
|
|
|
|
export const CloneProjectDialog = ({
|
|
isOpen,
|
|
project: { id, title },
|
|
onOpenChange,
|
|
}: {
|
|
isOpen: boolean;
|
|
project: Project;
|
|
onOpenChange: (isOpen: boolean) => void;
|
|
}) => {
|
|
const { handleSubmit, errors, state } = useCloneProject({
|
|
projectId: id,
|
|
onOpenChange,
|
|
});
|
|
|
|
return (
|
|
<CloneProjectView
|
|
title={title}
|
|
onSubmit={handleSubmit}
|
|
errors={errors}
|
|
state={state}
|
|
isOpen={isOpen}
|
|
onOpenChange={onOpenChange}
|
|
/>
|
|
);
|
|
};
|