From 47a3f3aaabc1712e82f424f5a0fa14953168edfb Mon Sep 17 00:00:00 2001 From: Ivan Starkov Date: Thu, 7 Sep 2023 21:52:13 +0300 Subject: [PATCH] Add export dialog to publish (#2269) ## Description image image ## Steps for reproduction 1. click button 2. expect xyz ## Code Review - [ ] hi @kof, 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 --- .../builder/features/topbar/add-domain.tsx | 43 +++-- .../app/builder/features/topbar/publish.tsx | 153 +++++++++++++++++- packages/icons/icons/custom-code.svg | 5 + .../icons/src/__generated__/custom-code.tsx | 15 ++ packages/icons/src/__generated__/index.ts | 1 + .../src/__generated__/svg/custom-code.ts | 1 + packages/icons/src/__generated__/svg/index.ts | 1 + 7 files changed, 200 insertions(+), 19 deletions(-) create mode 100644 packages/icons/icons/custom-code.svg create mode 100644 packages/icons/src/__generated__/custom-code.tsx create mode 100644 packages/icons/src/__generated__/svg/custom-code.ts diff --git a/apps/builder/app/builder/features/topbar/add-domain.tsx b/apps/builder/app/builder/features/topbar/add-domain.tsx index ca2e79a939..44fcc63c9c 100644 --- a/apps/builder/app/builder/features/topbar/add-domain.tsx +++ b/apps/builder/app/builder/features/topbar/add-domain.tsx @@ -6,6 +6,7 @@ import { Separator, theme, Text, + Grid, } from "@webstudio-is/design-system"; import type { DomainRouter } from "@webstudio-is/domain/index.server"; import { validateDomain } from "@webstudio-is/domain"; @@ -13,12 +14,14 @@ import type { Project } from "@webstudio-is/project"; import { useId, useState } from "react"; import { createTrpcFetchProxy } from "~/shared/remix/trpc-remix-proxy"; import { builderDomainsPath } from "~/shared/router-utils"; +import { CustomCodeIcon } from "@webstudio-is/icons"; const trpc = createTrpcFetchProxy(builderDomainsPath); type DomainsAddProps = { projectId: Project["id"]; onCreate: (domain: string) => void; + onExportClick: () => void; refreshDomainResult: ( input: { projectId: Project["id"] }, onSuccess: () => void @@ -33,6 +36,7 @@ export const AddDomain = ({ refreshDomainResult, domainState, isPublishing, + onExportClick, }: DomainsAddProps) => { const id = useId(); const { @@ -131,23 +135,32 @@ export const AddDomain = ({ )} - + handleCreate(); + }} + > + {isOpen ? "Add domain" : "Add a new domain"} + + + + {isOpen && } diff --git a/apps/builder/app/builder/features/topbar/publish.tsx b/apps/builder/app/builder/features/topbar/publish.tsx index 85c82b4efd..332d733ecf 100644 --- a/apps/builder/app/builder/features/topbar/publish.tsx +++ b/apps/builder/app/builder/features/topbar/publish.tsx @@ -18,6 +18,7 @@ import { ScrollArea, Box, rawTheme, + styled, } from "@webstudio-is/design-system"; import { useIsPublishDialogOpen } from "../../shared/nano-states"; import { validateProjectDomain, type Project } from "@webstudio-is/project"; @@ -36,6 +37,7 @@ import { CheckCircleIcon, ExternalLinkIcon, AlertIcon, + CopyIcon, } from "@webstudio-is/icons"; import { createTrpcFetchProxy } from "~/shared/remix/trpc-remix-proxy"; import { builderDomainsPath } from "~/shared/router-utils"; @@ -338,7 +340,10 @@ const ErrorText = ({ children }: { children: string }) => ( ); -const Content = (props: { projectId: Project["id"] }) => { +const Content = (props: { + projectId: Project["id"]; + onExportClick: () => void; +}) => { const [newDomains, setNewDomains] = useState(new Set()); const { data: domainsResult, @@ -446,6 +451,7 @@ const Content = (props: { projectId: Project["id"] }) => { }); }} isPublishing={isPublishing} + onExportClick={props.onExportClick} /> {projectData?.success === true ? ( @@ -466,12 +472,129 @@ const Content = (props: { projectId: Project["id"] }) => { ); }; +/** + * @todo change colors on theme colors when tokens will be ready + * https://discord.com/channels/955905230107738152/1149380442315825212/1149408306671128666 + **/ +const StyledLink = styled("a", { + color: "#006ADC", // @todo theme.colors.foregroundLink, + "&:visited": { + color: "#793AAF", // @todo theme.colors.foregroundLinkVisited, + }, +}); + +const ExportContent = () => { + const npxCommand = "npx @webstudio-is/cli"; + const npxVercelCommand = "npx vercel"; + return ( + + + + Step 1 + + + Download and install node v18+ from{" "} + + nodejs.org + {" "} + or with{" "} + + a package manager + + . + + + + + + + Step 2 + + + Run this command in your Terminal to install Webstudio CLI and sync + your project. + + + + + + + + + + + + + + + Step 3 + + + Use the{" "} + + Vercel CLI + {" "} + to publish your project on Vercel. + + + + + + + + + + + + + ); +}; + type PublishProps = { projectId: Project["id"]; }; + export const PublishButton = ({ projectId }: PublishProps) => { const [isOpen, setIsOpen] = useIsPublishDialogOpen(); const [authPermit] = useAuthPermit(); + const [dialogContentType, setDialogContentType] = useState< + "publish" | "export" + >("publish"); const isPublishEnabled = authPermit === "own" || authPermit === "admin"; @@ -479,8 +602,19 @@ export const PublishButton = ({ projectId }: PublishProps) => { ? undefined : "Only owner or admin can publish projects"; + const handleExportClick = () => { + setDialogContentType("export"); + }; + + const handleOpenChange = (isOpen: boolean) => { + if (isOpen === false) { + setDialogContentType("publish"); + } + setIsOpen(isOpen); + }; + return ( - + @@ -500,8 +634,19 @@ export const PublishButton = ({ projectId }: PublishProps) => { marginRight: theme.spacing[3], }} > - Publish - + {dialogContentType === "export" && ( + <> + Export + + + )} + + {dialogContentType === "publish" && ( + <> + Publish + + + )} ); diff --git a/packages/icons/icons/custom-code.svg b/packages/icons/icons/custom-code.svg new file mode 100644 index 0000000000..c4c5d104db --- /dev/null +++ b/packages/icons/icons/custom-code.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/icons/src/__generated__/custom-code.tsx b/packages/icons/src/__generated__/custom-code.tsx new file mode 100644 index 0000000000..49d0d80a5c --- /dev/null +++ b/packages/icons/src/__generated__/custom-code.tsx @@ -0,0 +1,15 @@ +// Generated from icons/custom-code.svg + +import { forwardRef } from "react"; +import type { IconProps } from "../types"; + +// prettier-ignore +export const CustomCodeIcon = forwardRef( + ({ color = "currentColor", size = 16, ...props }, forwardedRef) => { + return ( + + ); + } +); + +CustomCodeIcon.displayName = "CustomCodeIcon"; diff --git a/packages/icons/src/__generated__/index.ts b/packages/icons/src/__generated__/index.ts index f65ad80fbc..e35d580917 100644 --- a/packages/icons/src/__generated__/index.ts +++ b/packages/icons/src/__generated__/index.ts @@ -64,6 +64,7 @@ export * from "./collapsible"; export * from "./commit"; export * from "./content"; export * from "./copy"; +export * from "./custom-code"; export * from "./dash-border"; export * from "./dash"; export * from "./dashed-border"; diff --git a/packages/icons/src/__generated__/svg/custom-code.ts b/packages/icons/src/__generated__/svg/custom-code.ts new file mode 100644 index 0000000000..185f10e4c2 --- /dev/null +++ b/packages/icons/src/__generated__/svg/custom-code.ts @@ -0,0 +1 @@ +export const CustomCodeIcon = ``; diff --git a/packages/icons/src/__generated__/svg/index.ts b/packages/icons/src/__generated__/svg/index.ts index 4aadb409ae..cf7305479a 100644 --- a/packages/icons/src/__generated__/svg/index.ts +++ b/packages/icons/src/__generated__/svg/index.ts @@ -64,6 +64,7 @@ export { CollapsibleIcon } from "./collapsible"; export { CommitIcon } from "./commit"; export { ContentIcon } from "./content"; export { CopyIcon } from "./copy"; +export { CustomCodeIcon } from "./custom-code"; export { DashBorderIcon } from "./dash-border"; export { DashIcon } from "./dash"; export { DashedBorderIcon } from "./dashed-border";