From 603f2d233d29cba65123b2d81f114e0176d896cd Mon Sep 17 00:00:00 2001 From: Daniel R Farrell Date: Thu, 12 Dec 2024 23:27:10 -0500 Subject: [PATCH 01/17] initial structure for the publish button and dropdown --- .../editor/LayersPanel/Tree/TreeNode.tsx | 16 +-- .../routes/editor/TopBar/OpenCode/index.tsx | 2 +- .../editor/TopBar/ShareProject/index.tsx | 116 ++++++++++++++++++ .../studio/src/routes/editor/TopBar/index.tsx | 2 + packages/foundation/README.md | 6 +- packages/ui/src/components/icons/index.tsx | 4 + 6 files changed, 134 insertions(+), 12 deletions(-) create mode 100644 apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx diff --git a/apps/studio/src/routes/editor/LayersPanel/Tree/TreeNode.tsx b/apps/studio/src/routes/editor/LayersPanel/Tree/TreeNode.tsx index b10994d6d..7146ef786 100644 --- a/apps/studio/src/routes/editor/LayersPanel/Tree/TreeNode.tsx +++ b/apps/studio/src/routes/editor/LayersPanel/Tree/TreeNode.tsx @@ -230,8 +230,8 @@ const TreeNode = observer( hovered && !selected ? 'text-purple-600 dark:text-purple-200 ' : selected - ? 'text-purple-100 dark:text-purple-100' - : 'text-purple-500 dark:text-purple-300', + ? 'text-purple-100 dark:text-purple-100' + : 'text-purple-500 dark:text-purple-300', )} /> ) : ( @@ -269,8 +269,8 @@ const TreeNode = observer( ? selected ? 'text-purple-100 dark:text-purple-100' : hovered - ? 'text-purple-600 dark:text-purple-200' - : 'text-purple-500 dark:text-purple-300' + ? 'text-purple-600 dark:text-purple-200' + : 'text-purple-500 dark:text-purple-300' : '', !node.data.isVisible && 'opacity-80', selected && 'mr-5', @@ -279,10 +279,10 @@ const TreeNode = observer( {component ? component : ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].includes( - node.data.tagName.toLowerCase(), - ) - ? '' - : node.data.tagName.toLowerCase()} + node.data.tagName.toLowerCase(), + ) + ? '' + : node.data.tagName.toLowerCase()} {' ' + node.data.textContent} {selected && ( diff --git a/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx b/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx index f3ecd1a2e..c7d6aa83f 100644 --- a/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx @@ -105,7 +105,7 @@ const OpenCode = observer(() => { } return ( -
+
diff --git a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx new file mode 100644 index 000000000..50fe18d84 --- /dev/null +++ b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx @@ -0,0 +1,116 @@ +import { Button } from '@onlook/ui/button'; +import { Icons } from '@onlook/ui/icons'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@onlook/ui/dropdown-menu'; +import { Tooltip, TooltipContent, TooltipTrigger } from '@onlook/ui/tooltip'; +import { useState } from 'react'; + +const ShareProject = () => { + const [isPublished, setIsPublished] = useState(false); + + const handlePublish = () => { + setIsPublished(true); + // Add actual publish logic here + }; + + const handleUnpublish = () => { + setIsPublished(false); + // Add actual unpublish logic here + }; + + const handleOpenUrl = () => { + window.open('http://localhost:3000', '_blank'); + }; + + return ( + + + + + + + + Publish Project + + + + {/* Public/Private Selector */} +
+ + +
+ + + + {isPublished && ( + <> + + + localhost:3000 + + + + )} + + + + Advanced Settings + + + + + {/* Deploy Button */} +
+ +
+
+
+ ); +}; + +export default ShareProject; diff --git a/apps/studio/src/routes/editor/TopBar/index.tsx b/apps/studio/src/routes/editor/TopBar/index.tsx index d20c5f057..3b6a1fd99 100644 --- a/apps/studio/src/routes/editor/TopBar/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/index.tsx @@ -9,6 +9,7 @@ import OpenCode from './OpenCode'; import ProjectBreadcrumb from './ProjectSelect'; import ZoomControls from './ZoomControls'; import { Hotkey } from '/common/hotkeys'; +import ShareProject from './ShareProject'; const EditorTopBar = observer( ({ @@ -93,6 +94,7 @@ const EditorTopBar = observer( handleScale={handleScale} /> +
); diff --git a/packages/foundation/README.md b/packages/foundation/README.md index 8083749c5..c5eed1575 100644 --- a/packages/foundation/README.md +++ b/packages/foundation/README.md @@ -2,6 +2,6 @@ A shared utility package for Onlook. Includes file system functionalities used in both the Onlook app and the CLI -- [x] Create new project -- [x] Setup existing project -- [x] Verify Onlook installation +- [x] Create new project +- [x] Setup existing project +- [x] Verify Onlook installation diff --git a/packages/ui/src/components/icons/index.tsx b/packages/ui/src/components/icons/index.tsx index cf93fcd56..f73fb2ae6 100644 --- a/packages/ui/src/components/icons/index.tsx +++ b/packages/ui/src/components/icons/index.tsx @@ -53,6 +53,7 @@ import { FrameIcon, GearIcon, GitHubLogoIcon, + GlobeIcon, GroupIcon, HandIcon, ImageIcon, @@ -83,6 +84,7 @@ import { ScissorsIcon, SectionIcon, ShadowIcon, + Share2Icon, SizeIcon, SquareIcon, StopIcon, @@ -957,6 +959,7 @@ export const Icons = { Frame: FrameIcon, Gear: GearIcon, GitHubLogo: GitHubLogoIcon, + Globe: GlobeIcon, Group: GroupIcon, Image: ImageIcon, Input: InputIcon, @@ -984,6 +987,7 @@ export const Icons = { Scissors: ScissorsIcon, Section: SectionIcon, Shadow: ShadowIcon, + Share: Share2Icon, Size: SizeIcon, Sun: SunIcon, Stop: StopIcon, From b8a63b82c19b3f74443270bee0fe72a53b0248cd Mon Sep 17 00:00:00 2001 From: Daniel R Farrell Date: Fri, 13 Dec 2024 17:54:36 -0500 Subject: [PATCH 02/17] UI additions and copy url button --- .../editor/TopBar/ShareProject/index.tsx | 141 +++++++++++++----- 1 file changed, 103 insertions(+), 38 deletions(-) diff --git a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx index 50fe18d84..10816b0ce 100644 --- a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx @@ -9,9 +9,11 @@ import { } from '@onlook/ui/dropdown-menu'; import { Tooltip, TooltipContent, TooltipTrigger } from '@onlook/ui/tooltip'; import { useState } from 'react'; +import { motion, AnimatePresence } from 'framer-motion'; const ShareProject = () => { const [isPublished, setIsPublished] = useState(false); + const [isCopied, setIsCopied] = useState(false); const handlePublish = () => { setIsPublished(true); @@ -27,6 +29,12 @@ const ShareProject = () => { window.open('http://localhost:3000', '_blank'); }; + const handleCopyUrl = async () => { + await navigator.clipboard.writeText('http://localhost:3000'); + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); // Reset after 2 seconds + }; + return ( @@ -44,52 +52,110 @@ const ShareProject = () => { Publish Project - + {/* Public/Private Selector */} -
- - +
+
+ + +
- - {isPublished && ( <> - - - localhost:3000 + e.preventDefault()} // Prevents menu from closing on click + > +
+ + +
)} - - - Advanced Settings + +
+ + Advanced Settings +
@@ -97,14 +163,13 @@ const ShareProject = () => { {/* Deploy Button */}
From adbfc16ba0d50602eb6feca9d6fa0b1d8a752c0f Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 15 Dec 2024 10:57:52 -0500 Subject: [PATCH 03/17] Create hosting package --- packages/foundation/README.md | 6 +++--- packages/hosting/package.json | 34 ++++++++++++++++++++++++++++++++++ packages/hosting/src/index.ts | 2 ++ packages/hosting/tsconfig.json | 8 ++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 packages/hosting/package.json create mode 100644 packages/hosting/src/index.ts create mode 100644 packages/hosting/tsconfig.json diff --git a/packages/foundation/README.md b/packages/foundation/README.md index 8083749c5..c5eed1575 100644 --- a/packages/foundation/README.md +++ b/packages/foundation/README.md @@ -2,6 +2,6 @@ A shared utility package for Onlook. Includes file system functionalities used in both the Onlook app and the CLI -- [x] Create new project -- [x] Setup existing project -- [x] Verify Onlook installation +- [x] Create new project +- [x] Setup existing project +- [x] Verify Onlook installation diff --git a/packages/hosting/package.json b/packages/hosting/package.json new file mode 100644 index 000000000..3dec3f7c6 --- /dev/null +++ b/packages/hosting/package.json @@ -0,0 +1,34 @@ +{ + "name": "@onlook/hosting", + "description": "A hosting library for Onlook", + "main": "./src/index.ts", + "type": "module", + "module": "src/index.ts", + "types": "src/index.ts", + "version": "0.0.0", + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/onlook-dev/onlook.git" + }, + "scripts": { + "clean": "rm -rf node_modules", + "lint": "eslint --fix .", + "format": "prettier --write .", + "typecheck": "tsc --noEmit" + }, + "keywords": [ + "onlook", + "hosting" + ], + "author": { + "name": "Onlook", + "email": "contact@onlook.dev" + }, + "license": "Apache-2.0", + "homepage": "https://onlook.dev", + "devDependencies": { + "@onlook/typescript": "*" + }, + "dependencies": {} +} diff --git a/packages/hosting/src/index.ts b/packages/hosting/src/index.ts new file mode 100644 index 000000000..7bfe02e85 --- /dev/null +++ b/packages/hosting/src/index.ts @@ -0,0 +1,2 @@ +export * from './coder'; +export * from './prompt'; diff --git a/packages/hosting/tsconfig.json b/packages/hosting/tsconfig.json new file mode 100644 index 000000000..6e414dd41 --- /dev/null +++ b/packages/hosting/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@onlook/typescript/base.json", + "compilerOptions": { + "baseUrl": "." + }, + "include": ["src", "test"], + "exclude": ["node_modules"] +} From 6bccfef35c610fbc89cbdc1c85529af08f68cd2a Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Sun, 15 Dec 2024 12:25:38 -0500 Subject: [PATCH 04/17] Add zonke --- bun.lockb | Bin 556656 -> 560920 bytes packages/foundation/README.md | 6 +++--- packages/hosting/package.json | 4 +++- packages/hosting/src/api/index.ts | 1 + packages/hosting/src/api/zonke.ts | 7 +++++++ packages/hosting/src/index.ts | 3 +-- 6 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 packages/hosting/src/api/index.ts create mode 100644 packages/hosting/src/api/zonke.ts diff --git a/bun.lockb b/bun.lockb index cc2482f215a59f2379a83b6e093a8ad11504fb21..7bfa8b555e87f1065c02aa295a20bc11f323bbf8 100755 GIT binary patch delta 90761 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

}63*%74AH`)6pYmMwuO#zM% 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 bzrp2N>x4#)gZRK@x>tCglWrzunEw9&lA~4= delta 88364 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 AAtP#J~FO9D<=MhJ`7dSFL3qPrxo&r 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 L4L7pP&PV?bi*l6r diff --git a/packages/foundation/README.md b/packages/foundation/README.md index c5eed1575..8083749c5 100644 --- a/packages/foundation/README.md +++ b/packages/foundation/README.md @@ -2,6 +2,6 @@ A shared utility package for Onlook. Includes file system functionalities used in both the Onlook app and the CLI -- [x] Create new project -- [x] Setup existing project -- [x] Verify Onlook installation +- [x] Create new project +- [x] Setup existing project +- [x] Verify Onlook installation diff --git a/packages/hosting/package.json b/packages/hosting/package.json index 3dec3f7c6..146e9afa1 100644 --- a/packages/hosting/package.json +++ b/packages/hosting/package.json @@ -30,5 +30,7 @@ "devDependencies": { "@onlook/typescript": "*" }, - "dependencies": {} + "dependencies": { + "@zonke-cloud/sdk": "^0.1.2" + } } diff --git a/packages/hosting/src/api/index.ts b/packages/hosting/src/api/index.ts new file mode 100644 index 000000000..ceb384e57 --- /dev/null +++ b/packages/hosting/src/api/index.ts @@ -0,0 +1 @@ +export * from './zonke'; diff --git a/packages/hosting/src/api/zonke.ts b/packages/hosting/src/api/zonke.ts new file mode 100644 index 000000000..b40a7af32 --- /dev/null +++ b/packages/hosting/src/api/zonke.ts @@ -0,0 +1,7 @@ +// Api wrapper around zonke + +export function createEnv() {} + +export function deploy() {} + +export function getEnv(envId: string) {} diff --git a/packages/hosting/src/index.ts b/packages/hosting/src/index.ts index 7bfe02e85..b1c13e734 100644 --- a/packages/hosting/src/index.ts +++ b/packages/hosting/src/index.ts @@ -1,2 +1 @@ -export * from './coder'; -export * from './prompt'; +export * from './api'; From ad3e74752f384aa10f315e703cc2cc3c84b57031 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 20:46:58 +0000 Subject: [PATCH 05/17] feat(hosting): implement zonke sdk wrapper with tests Co-Authored-By: Kiet --- bun.lockb | Bin 560920 -> 560920 bytes packages/hosting/package.json | 3 +- .../__tests__/__mocks__/@zonke-cloud/sdk.ts | 24 +++++++ .../hosting/src/api/__tests__/zonke.test.ts | 66 ++++++++++++++++++ packages/hosting/src/api/zonke.ts | 42 +++++++++-- .../hosting/src/types/zonke-cloud__sdk.d.ts | 41 +++++++++++ 6 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 packages/hosting/src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts create mode 100644 packages/hosting/src/api/__tests__/zonke.test.ts create mode 100644 packages/hosting/src/types/zonke-cloud__sdk.d.ts diff --git a/bun.lockb b/bun.lockb index 7bfa8b555e87f1065c02aa295a20bc11f323bbf8..fa64e42bb957715e65fb5cd7d8c8ef664c71b7b5 100755 GIT binary patch delta 39 vcmbO+Pie+HrG^&97N!>F7M2#)Eo_#T*csyt^bGZk+8r*jZFjiDeq#>+4U7%( delta 39 scmbO+Pie+HrG^&97N!>F7M2#)Eo_#T*qIo>pxxmT+jfUb>^JrR0Q-*&r2qf` diff --git a/packages/hosting/package.json b/packages/hosting/package.json index 146e9afa1..aebe1c4fe 100644 --- a/packages/hosting/package.json +++ b/packages/hosting/package.json @@ -15,7 +15,8 @@ "clean": "rm -rf node_modules", "lint": "eslint --fix .", "format": "prettier --write .", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "test": "bun test --preload ./src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts" }, "keywords": [ "onlook", diff --git a/packages/hosting/src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts b/packages/hosting/src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts new file mode 100644 index 000000000..fc526a452 --- /dev/null +++ b/packages/hosting/src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts @@ -0,0 +1,24 @@ +export enum SupportedFrameworks { + React = 'react', + Remix = 'remix', + NextJs = 'nextjs', +} + +export const createPreviewEnvironment = async () => ({ + environmentId: 'test-env', + endpoint: 'test.preview.test.com', + versions: [], +}); + +export const deployToPreviewEnvironment = async () => ({ + versionId: 'test-version', + message: 'Test deploy', + isLatest: true, + lastUpdated: new Date().toISOString(), +}); + +export const getPreviewEnvironment = async () => ({ + environmentId: 'test-env', + endpoint: 'test.preview.test.com', + versions: [], +}); diff --git a/packages/hosting/src/api/__tests__/zonke.test.ts b/packages/hosting/src/api/__tests__/zonke.test.ts new file mode 100644 index 000000000..40a4de270 --- /dev/null +++ b/packages/hosting/src/api/__tests__/zonke.test.ts @@ -0,0 +1,66 @@ +import { expect, test, describe, mock } from 'bun:test'; +import { createEnv, deploy, getEnv } from '../zonke'; + +// Mock the SDK functions +const mockSDK = { + createPreviewEnvironment: mock(async () => ({ + environmentId: 'test-env', + endpoint: 'test.preview.test.com', + versions: [], + })), + deployToPreviewEnvironment: mock(async () => ({ + versionId: 'test-version', + message: 'Test deploy', + isLatest: true, + lastUpdated: new Date().toISOString(), + })), + getPreviewEnvironment: mock(async () => ({ + environmentId: 'test-env', + endpoint: 'test.preview.test.com', + versions: [], + })), + SupportedFrameworks: { + React: 'react', + Remix: 'remix', + NextJs: 'nextjs', + }, +}; + +// Mock the module +mock.module('@zonke-cloud/sdk', () => mockSDK); + +describe('zonke', () => { + test('createEnv calls SDK with correct parameters', async () => { + await createEnv({ + userId: 'test-user', + hostedZone: 'test.com', + }); + + expect(mockSDK.createPreviewEnvironment).toHaveBeenCalledWith({ + userId: 'test-user', + framework: mockSDK.SupportedFrameworks.React, + awsHostedZone: 'test.com', + }); + }); + + test('deploy calls SDK with correct parameters', async () => { + await deploy({ + environmentId: 'test-env', + buildOutputDirectory: 'dist', + message: 'Test deploy', + }); + + expect(mockSDK.deployToPreviewEnvironment).toHaveBeenCalledWith({ + environmentId: 'test-env', + buildOutputDirectory: 'dist', + message: 'Test deploy', + uploadLinkExpirationOverride: 60, + }); + }); + + test('getEnv calls SDK with correct parameters', async () => { + await getEnv('test-env'); + + expect(mockSDK.getPreviewEnvironment).toHaveBeenCalledWith('test-env'); + }); +}); diff --git a/packages/hosting/src/api/zonke.ts b/packages/hosting/src/api/zonke.ts index b40a7af32..33bd4bac6 100644 --- a/packages/hosting/src/api/zonke.ts +++ b/packages/hosting/src/api/zonke.ts @@ -1,7 +1,41 @@ -// Api wrapper around zonke +import { + SupportedFrameworks, + createPreviewEnvironment, + deployToPreviewEnvironment, + getPreviewEnvironment, +} from '@zonke-cloud/sdk'; -export function createEnv() {} +export interface CreateEnvOptions { + userId?: string; + hostedZone: string; +} -export function deploy() {} +export async function createEnv(options: CreateEnvOptions) { + return createPreviewEnvironment({ + userId: options.userId, + framework: SupportedFrameworks.React, + awsHostedZone: options.hostedZone, + }); +} -export function getEnv(envId: string) {} +export interface DeployOptions { + environmentId: string; + buildOutputDirectory: string; + message?: string; +} + +export async function deploy(options: DeployOptions) { + const { environmentId, buildOutputDirectory, message } = options; + + return deployToPreviewEnvironment({ + environmentId, + buildOutputDirectory, + message, + // Default to 60 seconds for upload link expiration + uploadLinkExpirationOverride: 60, + }); +} + +export async function getEnv(envId: string) { + return getPreviewEnvironment(envId); +} diff --git a/packages/hosting/src/types/zonke-cloud__sdk.d.ts b/packages/hosting/src/types/zonke-cloud__sdk.d.ts new file mode 100644 index 000000000..ec2babf5e --- /dev/null +++ b/packages/hosting/src/types/zonke-cloud__sdk.d.ts @@ -0,0 +1,41 @@ +declare module '@zonke-cloud/sdk' { + export enum SupportedFrameworks { + React = 'react', + Remix = 'remix', + NextJs = 'nextjs', + } + + export interface PreviewEnvironment { + environmentId: string; + endpoint: string; + versions: PreviewEnvironmentVersion[]; + } + + export interface PreviewEnvironmentVersion { + versionId: string; + message?: string; + isLatest: boolean; + lastUpdated: string; + } + + export interface CreatePreviewEnvironmentPayload { + userId?: string; + framework: SupportedFrameworks; + awsHostedZone: string; + } + + export interface DeployToPreviewEnvironmentPayload { + environmentId: string; + buildOutputDirectory: string; + message?: string; + uploadLinkExpirationOverride?: number; + } + + export function createPreviewEnvironment( + payload: CreatePreviewEnvironmentPayload, + ): Promise; + export function deployToPreviewEnvironment( + payload: DeployToPreviewEnvironmentPayload, + ): Promise; + export function getPreviewEnvironment(environmentId: string): Promise; +} From 88a86974260d00049b1b36e5a3160e536ed27bb8 Mon Sep 17 00:00:00 2001 From: Daniel R Farrell Date: Sun, 15 Dec 2024 17:25:26 -0500 Subject: [PATCH 06/17] Made a center modal for creating a link. Feels nicer. Added nice UI effects --- .../editor/TopBar/ShareProject/index.tsx | 311 +++++++++--------- packages/foundation/README.md | 6 +- packages/ui/src/components/dialog.tsx | 2 +- 3 files changed, 155 insertions(+), 164 deletions(-) diff --git a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx index 10816b0ce..d0f2a7111 100644 --- a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx @@ -1,180 +1,171 @@ import { Button } from '@onlook/ui/button'; import { Icons } from '@onlook/ui/icons'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from '@onlook/ui/dropdown-menu'; -import { Tooltip, TooltipContent, TooltipTrigger } from '@onlook/ui/tooltip'; -import { useState } from 'react'; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@onlook/ui/dialog'; +import { useState, useMemo } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; +import { cn } from '@onlook/ui/utils'; const ShareProject = () => { - const [isPublished, setIsPublished] = useState(false); + const [isOpen, setIsOpen] = useState(false); + const [isLinkCreated, setIsLinkCreated] = useState(false); const [isCopied, setIsCopied] = useState(false); - - const handlePublish = () => { - setIsPublished(true); - // Add actual publish logic here - }; - - const handleUnpublish = () => { - setIsPublished(false); - // Add actual unpublish logic here - }; - - const handleOpenUrl = () => { - window.open('http://localhost:3000', '_blank'); - }; + const [hasChanges, setHasChanges] = useState(false); const handleCopyUrl = async () => { await navigator.clipboard.writeText('http://localhost:3000'); setIsCopied(true); - setTimeout(() => setIsCopied(false), 2000); // Reset after 2 seconds + setTimeout(() => setIsCopied(false), 2000); }; + const copyTextCharacters = useMemo(() => { + const text = isCopied ? 'Copied!' : 'Copy link'; + return text.split('').map((ch, index) => ({ + id: `copytext_${ch}${index}`, + label: ch === ' ' ? '\u00A0' : ch, + })); + }, [isCopied]); + return ( - - - - - - - - Publish Project - + <> + - - {/* Public/Private Selector */} -

-
- - -
-
+ + + + + {isLinkCreated ? 'Public link' : 'Share public link'} + + - {isPublished && ( - <> - e.preventDefault()} // Prevents menu from closing on click - > -
- - -
-
- - - )} + + {!isLinkCreated ? ( + +

+ Share your app with the world and update it at any time in + Onlook. +

+ +
+ ) : ( + +

+ Your app is now public – What you see is what your users see. + You can unpublish or update it at any time here. +

- -
- - Advanced Settings -
-
+
+
+
+ + https://example.dev/share/... + +
+ +
- - - {/* Deploy Button */} -
- -
- - +
+ + +
+
+
+ )} +
+
+
+ ); }; diff --git a/packages/foundation/README.md b/packages/foundation/README.md index c5eed1575..8083749c5 100644 --- a/packages/foundation/README.md +++ b/packages/foundation/README.md @@ -2,6 +2,6 @@ A shared utility package for Onlook. Includes file system functionalities used in both the Onlook app and the CLI -- [x] Create new project -- [x] Setup existing project -- [x] Verify Onlook installation +- [x] Create new project +- [x] Setup existing project +- [x] Verify Onlook installation diff --git a/packages/ui/src/components/dialog.tsx b/packages/ui/src/components/dialog.tsx index 0ce7abcf2..4e8b6ecfe 100644 --- a/packages/ui/src/components/dialog.tsx +++ b/packages/ui/src/components/dialog.tsx @@ -73,7 +73,7 @@ const DialogTitle = React.forwardRef< >(({ className, ...props }, ref) => ( )); From cdb848c46e03744f924f9010f08c28f4a5a74b0e Mon Sep 17 00:00:00 2001 From: Daniel R Farrell Date: Sun, 15 Dec 2024 17:48:48 -0500 Subject: [PATCH 07/17] very subtle style adjustment --- apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx | 2 +- apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx b/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx index c7d6aa83f..e867bab0d 100644 --- a/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/OpenCode/index.tsx @@ -105,7 +105,7 @@ const OpenCode = observer(() => { } return ( -
+
diff --git a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx index d0f2a7111..db94424f8 100644 --- a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx @@ -29,7 +29,7 @@ const ShareProject = () => { <> @@ -167,6 +181,6 @@ const ShareProject = () => { ); -}; +}); export default ShareProject; diff --git a/packages/foundation/README.md b/packages/foundation/README.md index 8083749c5..c5eed1575 100644 --- a/packages/foundation/README.md +++ b/packages/foundation/README.md @@ -2,6 +2,6 @@ A shared utility package for Onlook. Includes file system functionalities used in both the Onlook app and the CLI -- [x] Create new project -- [x] Setup existing project -- [x] Verify Onlook installation +- [x] Create new project +- [x] Setup existing project +- [x] Verify Onlook installation diff --git a/packages/hosting/package.json b/packages/hosting/package.json index aebe1c4fe..338added4 100644 --- a/packages/hosting/package.json +++ b/packages/hosting/package.json @@ -16,7 +16,7 @@ "lint": "eslint --fix .", "format": "prettier --write .", "typecheck": "tsc --noEmit", - "test": "bun test --preload ./src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts" + "test": "bun test" }, "keywords": [ "onlook", @@ -34,4 +34,4 @@ "dependencies": { "@zonke-cloud/sdk": "^0.1.2" } -} +} \ No newline at end of file diff --git a/packages/hosting/src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts b/packages/hosting/src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts deleted file mode 100644 index fc526a452..000000000 --- a/packages/hosting/src/api/__tests__/__mocks__/@zonke-cloud/sdk.ts +++ /dev/null @@ -1,24 +0,0 @@ -export enum SupportedFrameworks { - React = 'react', - Remix = 'remix', - NextJs = 'nextjs', -} - -export const createPreviewEnvironment = async () => ({ - environmentId: 'test-env', - endpoint: 'test.preview.test.com', - versions: [], -}); - -export const deployToPreviewEnvironment = async () => ({ - versionId: 'test-version', - message: 'Test deploy', - isLatest: true, - lastUpdated: new Date().toISOString(), -}); - -export const getPreviewEnvironment = async () => ({ - environmentId: 'test-env', - endpoint: 'test.preview.test.com', - versions: [], -}); diff --git a/packages/hosting/src/api/zonke.ts b/packages/hosting/src/api/zonke.ts index 33bd4bac6..9fae4a03e 100644 --- a/packages/hosting/src/api/zonke.ts +++ b/packages/hosting/src/api/zonke.ts @@ -6,15 +6,18 @@ import { } from '@zonke-cloud/sdk'; export interface CreateEnvOptions { - userId?: string; - hostedZone: string; + userId: string; + framework: 'nextjs' | 'remix' | 'react'; } export async function createEnv(options: CreateEnvOptions) { + const framework = options.framework as SupportedFrameworks; + const awsHostedZone = 'zonke.market'; + return createPreviewEnvironment({ userId: options.userId, - framework: SupportedFrameworks.React, - awsHostedZone: options.hostedZone, + framework, + awsHostedZone }); } diff --git a/packages/hosting/src/types/zonke-cloud__sdk.d.ts b/packages/hosting/src/types/zonke-cloud__sdk.d.ts deleted file mode 100644 index ec2babf5e..000000000 --- a/packages/hosting/src/types/zonke-cloud__sdk.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -declare module '@zonke-cloud/sdk' { - export enum SupportedFrameworks { - React = 'react', - Remix = 'remix', - NextJs = 'nextjs', - } - - export interface PreviewEnvironment { - environmentId: string; - endpoint: string; - versions: PreviewEnvironmentVersion[]; - } - - export interface PreviewEnvironmentVersion { - versionId: string; - message?: string; - isLatest: boolean; - lastUpdated: string; - } - - export interface CreatePreviewEnvironmentPayload { - userId?: string; - framework: SupportedFrameworks; - awsHostedZone: string; - } - - export interface DeployToPreviewEnvironmentPayload { - environmentId: string; - buildOutputDirectory: string; - message?: string; - uploadLinkExpirationOverride?: number; - } - - export function createPreviewEnvironment( - payload: CreatePreviewEnvironmentPayload, - ): Promise; - export function deployToPreviewEnvironment( - payload: DeployToPreviewEnvironmentPayload, - ): Promise; - export function getPreviewEnvironment(environmentId: string): Promise; -} diff --git a/packages/hosting/src/api/__tests__/zonke.test.ts b/packages/hosting/test/zonke.test.ts similarity index 92% rename from packages/hosting/src/api/__tests__/zonke.test.ts rename to packages/hosting/test/zonke.test.ts index 40a4de270..4935e6394 100644 --- a/packages/hosting/src/api/__tests__/zonke.test.ts +++ b/packages/hosting/test/zonke.test.ts @@ -1,5 +1,5 @@ -import { expect, test, describe, mock } from 'bun:test'; -import { createEnv, deploy, getEnv } from '../zonke'; +import { describe, expect, mock, test } from 'bun:test'; +import { createEnv, deploy, getEnv } from '../src/api/zonke'; // Mock the SDK functions const mockSDK = { @@ -33,7 +33,7 @@ describe('zonke', () => { test('createEnv calls SDK with correct parameters', async () => { await createEnv({ userId: 'test-user', - hostedZone: 'test.com', + framework: 'nextjs', }); expect(mockSDK.createPreviewEnvironment).toHaveBeenCalledWith({ From e6360ce5db1de0a5ddbd959232c49f4d31833acf Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Mon, 16 Dec 2024 15:54:00 -0500 Subject: [PATCH 09/17] Consume zonke package directly in main --- apps/studio/electron/main/events/hosting.ts | 25 +++++++ apps/studio/electron/main/events/index.ts | 2 + .../src/lib/projects/{host.ts => hosting.ts} | 7 +- apps/studio/src/lib/projects/index.ts | 2 +- bun.lockb | Bin 561368 -> 561400 bytes packages/hosting/package.json | 37 ---------- packages/hosting/src/api/index.ts | 1 - packages/hosting/src/api/zonke.ts | 44 ------------ packages/hosting/src/index.ts | 1 - packages/hosting/test/zonke.test.ts | 66 ------------------ packages/hosting/tsconfig.json | 8 --- packages/models/src/constants/index.ts | 3 + 12 files changed, 35 insertions(+), 161 deletions(-) create mode 100644 apps/studio/electron/main/events/hosting.ts rename apps/studio/src/lib/projects/{host.ts => hosting.ts} (74%) delete mode 100644 packages/hosting/package.json delete mode 100644 packages/hosting/src/api/index.ts delete mode 100644 packages/hosting/src/api/zonke.ts delete mode 100644 packages/hosting/src/index.ts delete mode 100644 packages/hosting/test/zonke.test.ts delete mode 100644 packages/hosting/tsconfig.json diff --git a/apps/studio/electron/main/events/hosting.ts b/apps/studio/electron/main/events/hosting.ts new file mode 100644 index 000000000..6ff2df183 --- /dev/null +++ b/apps/studio/electron/main/events/hosting.ts @@ -0,0 +1,25 @@ +import { MainChannels } from '@onlook/models/constants'; +import { SupportedFrameworks, createPreviewEnvironment } from '@zonke-cloud/sdk'; +import { ipcMain } from 'electron'; + +export interface CreateEnvOptions { + userId: string; + framework: 'nextjs' | 'remix' | 'react'; +} + +export function listenForHostingMessages() { + ipcMain.handle( + MainChannels.CREATE_PROJECT_HOSTING_ENV, + (e: Electron.IpcMainInvokeEvent, args) => { + const options = args as CreateEnvOptions; + const framework = options.framework as SupportedFrameworks; + const awsHostedZone = 'zonke.market'; + + return createPreviewEnvironment({ + userId: options.userId, + framework, + awsHostedZone, + }); + }, + ); +} diff --git a/apps/studio/electron/main/events/index.ts b/apps/studio/electron/main/events/index.ts index 00a84e388..0bafa9bcd 100644 --- a/apps/studio/electron/main/events/index.ts +++ b/apps/studio/electron/main/events/index.ts @@ -10,6 +10,7 @@ import { listenForAuthMessages } from './auth'; import { listenForChatMessages } from './chat'; import { listenForCodeMessages } from './code'; import { listenForCreateMessages } from './create'; +import { listenForHostingMessages } from './hosting'; import { listenForRunMessages } from './run'; import { listenForStorageMessages } from './storage'; @@ -22,6 +23,7 @@ export function listenForIpcMessages() { listenForCreateMessages(); listenForChatMessages(); listenForRunMessages(); + listenForHostingMessages(); } function listenForGeneralMessages() { diff --git a/apps/studio/src/lib/projects/host.ts b/apps/studio/src/lib/projects/hosting.ts similarity index 74% rename from apps/studio/src/lib/projects/host.ts rename to apps/studio/src/lib/projects/hosting.ts index dca4bf2a5..112250d26 100644 --- a/apps/studio/src/lib/projects/host.ts +++ b/apps/studio/src/lib/projects/hosting.ts @@ -1,6 +1,7 @@ -import { createEnv } from '@onlook/hosting'; +import { MainChannels } from '@onlook/models/constants'; import type { Project } from '@onlook/models/projects'; import { makeAutoObservable } from 'mobx'; +import { invokeMainChannel } from '../utils'; export class HostingManager { private project: Project; @@ -17,11 +18,11 @@ export class HostingManager { async create() { console.log('Creating hosting environment', this.project.id); - const env = await createEnv({ + const res = await invokeMainChannel(MainChannels.CREATE_PROJECT_HOSTING_ENV, { userId: 'testUserId', framework: 'nextjs', }); - console.log('Created hosting environment', env); + console.log('Created hosting environment', res); } async stop() { diff --git a/apps/studio/src/lib/projects/index.ts b/apps/studio/src/lib/projects/index.ts index 3da542885..24c7e01d4 100644 --- a/apps/studio/src/lib/projects/index.ts +++ b/apps/studio/src/lib/projects/index.ts @@ -4,7 +4,7 @@ import type { AppState, ProjectsCache } from '@onlook/models/settings'; import { makeAutoObservable } from 'mobx'; import { nanoid } from 'nanoid/non-secure'; import { invokeMainChannel, sendAnalytics } from '../utils'; -import { HostingManager } from './host'; +import { HostingManager } from './hosting'; import { RunManager } from './run'; export class ProjectsManager { diff --git a/bun.lockb b/bun.lockb index c12d73bc3ac5f096c042664c1bc4ef478906e91c..f9fa776d65680268b470be6e52dcca0d200fc515 100755 GIT binary patch delta 71085 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 n!+%#XXNZ zZ|s8?lpC|r=}N3JwUv5w*6iBZ*QcJ~p2wEwL#vlR+3$X<{BcUT&6RN*BmStn$`bcn zzNYe72gliIuKoB|xA0e}J%F0}WtsXe7fnC4F{xW{ycCiVFzQ`?4xI(6>d&1K*qe5m@DRH?q1q@lYz zO+yNC-y9SbJ+M<`H|iH|R)%^tF!Lv?-KN!2*EBHuq@|7R&GOUT`et^tX{TvrDpA2y zPp6+t61g-mGmzUZ(|Z)Q+cbb~+M~j?p=JjQky{$L`?fOs%d=QObl*O`y18`e-FI-; zssp>yK37u%9ok{qlq&5sjiQ9zrc0wthQrl@}-3mQWGwUas(c%k|ZR*`=W+gTM4@;PH AIRF3v diff --git a/packages/hosting/package.json b/packages/hosting/package.json deleted file mode 100644 index eaf4fd3d5..000000000 --- a/packages/hosting/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@onlook/hosting", - "description": "A hosting library for Onlook", - "main": "./src/index.ts", - "type": "module", - "module": "src/index.ts", - "types": "src/index.ts", - "version": "0.0.0", - "private": true, - "repository": { - "type": "git", - "url": "https://github.com/onlook-dev/onlook.git" - }, - "scripts": { - "clean": "rm -rf node_modules", - "lint": "eslint --fix .", - "format": "prettier --write .", - "typecheck": "tsc --noEmit", - "test": "bun test" - }, - "keywords": [ - "onlook", - "hosting" - ], - "author": { - "name": "Onlook", - "email": "contact@onlook.dev" - }, - "license": "Apache-2.0", - "homepage": "https://onlook.dev", - "devDependencies": { - "@onlook/typescript": "*" - }, - "dependencies": { - "@zonke-cloud/sdk": "^0.1.2" - } -} diff --git a/packages/hosting/src/api/index.ts b/packages/hosting/src/api/index.ts deleted file mode 100644 index ceb384e57..000000000 --- a/packages/hosting/src/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './zonke'; diff --git a/packages/hosting/src/api/zonke.ts b/packages/hosting/src/api/zonke.ts deleted file mode 100644 index 3eb41b025..000000000 --- a/packages/hosting/src/api/zonke.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { - SupportedFrameworks, - createPreviewEnvironment, - deployToPreviewEnvironment, - getPreviewEnvironment, -} from '@zonke-cloud/sdk'; - -export interface CreateEnvOptions { - userId: string; - framework: 'nextjs' | 'remix' | 'react'; -} - -export async function createEnv(options: CreateEnvOptions) { - const framework = options.framework as SupportedFrameworks; - const awsHostedZone = 'zonke.market'; - - return createPreviewEnvironment({ - userId: options.userId, - framework, - awsHostedZone, - }); -} - -export interface DeployOptions { - environmentId: string; - buildOutputDirectory: string; - message?: string; -} - -export async function deploy(options: DeployOptions) { - const { environmentId, buildOutputDirectory, message } = options; - - return deployToPreviewEnvironment({ - environmentId, - buildOutputDirectory, - message, - // Default to 60 seconds for upload link expiration - uploadLinkExpirationOverride: 60, - }); -} - -export async function getEnv(envId: string) { - return getPreviewEnvironment(envId); -} diff --git a/packages/hosting/src/index.ts b/packages/hosting/src/index.ts deleted file mode 100644 index b1c13e734..000000000 --- a/packages/hosting/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './api'; diff --git a/packages/hosting/test/zonke.test.ts b/packages/hosting/test/zonke.test.ts deleted file mode 100644 index 4935e6394..000000000 --- a/packages/hosting/test/zonke.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { describe, expect, mock, test } from 'bun:test'; -import { createEnv, deploy, getEnv } from '../src/api/zonke'; - -// Mock the SDK functions -const mockSDK = { - createPreviewEnvironment: mock(async () => ({ - environmentId: 'test-env', - endpoint: 'test.preview.test.com', - versions: [], - })), - deployToPreviewEnvironment: mock(async () => ({ - versionId: 'test-version', - message: 'Test deploy', - isLatest: true, - lastUpdated: new Date().toISOString(), - })), - getPreviewEnvironment: mock(async () => ({ - environmentId: 'test-env', - endpoint: 'test.preview.test.com', - versions: [], - })), - SupportedFrameworks: { - React: 'react', - Remix: 'remix', - NextJs: 'nextjs', - }, -}; - -// Mock the module -mock.module('@zonke-cloud/sdk', () => mockSDK); - -describe('zonke', () => { - test('createEnv calls SDK with correct parameters', async () => { - await createEnv({ - userId: 'test-user', - framework: 'nextjs', - }); - - expect(mockSDK.createPreviewEnvironment).toHaveBeenCalledWith({ - userId: 'test-user', - framework: mockSDK.SupportedFrameworks.React, - awsHostedZone: 'test.com', - }); - }); - - test('deploy calls SDK with correct parameters', async () => { - await deploy({ - environmentId: 'test-env', - buildOutputDirectory: 'dist', - message: 'Test deploy', - }); - - expect(mockSDK.deployToPreviewEnvironment).toHaveBeenCalledWith({ - environmentId: 'test-env', - buildOutputDirectory: 'dist', - message: 'Test deploy', - uploadLinkExpirationOverride: 60, - }); - }); - - test('getEnv calls SDK with correct parameters', async () => { - await getEnv('test-env'); - - expect(mockSDK.getPreviewEnvironment).toHaveBeenCalledWith('test-env'); - }); -}); diff --git a/packages/hosting/tsconfig.json b/packages/hosting/tsconfig.json deleted file mode 100644 index 6e414dd41..000000000 --- a/packages/hosting/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "@onlook/typescript/base.json", - "compilerOptions": { - "baseUrl": "." - }, - "include": ["src", "test"], - "exclude": ["node_modules"] -} diff --git a/packages/models/src/constants/index.ts b/packages/models/src/constants/index.ts index b43b9c620..38cd34601 100644 --- a/packages/models/src/constants/index.ts +++ b/packages/models/src/constants/index.ts @@ -133,6 +133,9 @@ export enum MainChannels { TERMINAL_RESIZE = 'terminal-resize', TERMINAL_KILL = 'terminal-kill', TERMINAL_GET_HISTORY = 'terminal-get-history', + + // Hosting + CREATE_PROJECT_HOSTING_ENV = 'create-project-hosting-env', } export enum Links { From 55d215c92e47826cc177cecbb1b42441239723f6 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Mon, 16 Dec 2024 16:17:25 -0500 Subject: [PATCH 10/17] Add main channel hosting manager --- apps/studio/electron/main/events/hosting.ts | 21 ++----- apps/studio/electron/main/hosting/index.ts | 66 +++++++++++++++++++++ packages/models/src/constants/index.ts | 1 + 3 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 apps/studio/electron/main/hosting/index.ts diff --git a/apps/studio/electron/main/events/hosting.ts b/apps/studio/electron/main/events/hosting.ts index 6ff2df183..d86550c13 100644 --- a/apps/studio/electron/main/events/hosting.ts +++ b/apps/studio/electron/main/events/hosting.ts @@ -1,25 +1,16 @@ import { MainChannels } from '@onlook/models/constants'; -import { SupportedFrameworks, createPreviewEnvironment } from '@zonke-cloud/sdk'; import { ipcMain } from 'electron'; - -export interface CreateEnvOptions { - userId: string; - framework: 'nextjs' | 'remix' | 'react'; -} +import hostingManager from '../hosting'; export function listenForHostingMessages() { ipcMain.handle( MainChannels.CREATE_PROJECT_HOSTING_ENV, (e: Electron.IpcMainInvokeEvent, args) => { - const options = args as CreateEnvOptions; - const framework = options.framework as SupportedFrameworks; - const awsHostedZone = 'zonke.market'; - - return createPreviewEnvironment({ - userId: options.userId, - framework, - awsHostedZone, - }); + hostingManager.createEnv(args); }, ); + + ipcMain.handle(MainChannels.GET_PROJECT_HOSTING_ENV, (e: Electron.IpcMainInvokeEvent, args) => { + hostingManager.getEnv(); + }); } diff --git a/apps/studio/electron/main/hosting/index.ts b/apps/studio/electron/main/hosting/index.ts new file mode 100644 index 000000000..d129d6edc --- /dev/null +++ b/apps/studio/electron/main/hosting/index.ts @@ -0,0 +1,66 @@ +import { SupportedFrameworks, createPreviewEnvironment } from '@zonke-cloud/sdk'; +import { PersistentStorage } from '../storage'; + +export interface CreateEnvOptions { + framework: 'nextjs' | 'remix' | 'react'; +} + +const MOCK_ENV = { + versions: [ + { + isLatest: true, + lastUpdated: '2021-11-12T00:00:00Z', + versionId: 'GXtMmG9qhkD8_QOiIP591JQSQxwMqHRv', + }, + ], + environmentId: '7366e360-a5f4-437a-9678-8bb0397067c2', + endpoint: 'y9mashx88v.preview.zonke.market', +}; + +class HostingManager { + private static instance: HostingManager; + private userId: string | null = null; + + private constructor() { + this.restoreSettings(); + } + + public static getInstance(): HostingManager { + if (!HostingManager.instance) { + HostingManager.instance = new HostingManager(); + } + return HostingManager.instance; + } + + private restoreSettings() { + const settings = PersistentStorage.USER_SETTINGS.read() || {}; + this.userId = settings.id || null; + } + + createEnv(options: CreateEnvOptions) { + // TODO: Get project info from project path to determine create params + + if (this.userId === null) { + console.error('User ID not found'); + return; + } + + return MOCK_ENV; + + const framework = options.framework as SupportedFrameworks; + const awsHostedZone = 'zonke.market'; + + return createPreviewEnvironment({ + userId: this.userId, + framework, + awsHostedZone, + }); + } + + getEnv() { + // TODO: Get project info from project path to determine create params + return MOCK_ENV; + } +} + +export default HostingManager.getInstance(); diff --git a/packages/models/src/constants/index.ts b/packages/models/src/constants/index.ts index 38cd34601..68043e56f 100644 --- a/packages/models/src/constants/index.ts +++ b/packages/models/src/constants/index.ts @@ -136,6 +136,7 @@ export enum MainChannels { // Hosting CREATE_PROJECT_HOSTING_ENV = 'create-project-hosting-env', + GET_PROJECT_HOSTING_ENV = 'get-project-hosting-env', } export enum Links { From 5d2d6a898c2c8ba8a6f9e70c70c710a8c31c03e3 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Mon, 16 Dec 2024 16:50:22 -0500 Subject: [PATCH 11/17] Save progress --- apps/studio/electron/main/events/hosting.ts | 11 +++++++---- apps/studio/electron/main/hosting/index.ts | 9 ++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/studio/electron/main/events/hosting.ts b/apps/studio/electron/main/events/hosting.ts index d86550c13..a9bd74e02 100644 --- a/apps/studio/electron/main/events/hosting.ts +++ b/apps/studio/electron/main/events/hosting.ts @@ -6,11 +6,14 @@ export function listenForHostingMessages() { ipcMain.handle( MainChannels.CREATE_PROJECT_HOSTING_ENV, (e: Electron.IpcMainInvokeEvent, args) => { - hostingManager.createEnv(args); + return hostingManager.createEnv(args); }, ); - ipcMain.handle(MainChannels.GET_PROJECT_HOSTING_ENV, (e: Electron.IpcMainInvokeEvent, args) => { - hostingManager.getEnv(); - }); + ipcMain.handle( + MainChannels.GET_PROJECT_HOSTING_ENV, + (e: Electron.IpcMainInvokeEvent, args) => { + return hostingManager.getEnv(); + }, + ); } diff --git a/apps/studio/electron/main/hosting/index.ts b/apps/studio/electron/main/hosting/index.ts index d129d6edc..1f42e7e13 100644 --- a/apps/studio/electron/main/hosting/index.ts +++ b/apps/studio/electron/main/hosting/index.ts @@ -39,14 +39,17 @@ class HostingManager { createEnv(options: CreateEnvOptions) { // TODO: Get project info from project path to determine create params - + console.log('createEnv', { + ZONKE_API_KEY: process.env.ZONKE_API_KEY, + ZONKE_API_TOKEN: process.env.ZONKE_API_TOKEN, + ZONKE_API_ENDPOINT: process.env.ZONKE_API_ENDPOINT, + }); + return MOCK_ENV; if (this.userId === null) { console.error('User ID not found'); return; } - return MOCK_ENV; - const framework = options.framework as SupportedFrameworks; const awsHostedZone = 'zonke.market'; From ceab1c533b4f45c413a7af75aa1c4bccc202c2b3 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Mon, 16 Dec 2024 21:31:09 -0500 Subject: [PATCH 12/17] Working create api --- apps/studio/.env.example | 20 +++++------ apps/studio/electron/main/events/hosting.ts | 9 ++--- apps/studio/electron/main/hosting/index.ts | 39 ++++++++++++--------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/apps/studio/.env.example b/apps/studio/.env.example index f5c00d14e..90ee6e9ad 100644 --- a/apps/studio/.env.example +++ b/apps/studio/.env.example @@ -1,10 +1,10 @@ -SUPABASE_API_URL= -SUPABASE_ANON_KEY= -MIXPANEL_TOKEN= -ANTHROPIC_API_KEY= -OPENAI_API_KEY= -LANGFUSE_SECRET_KEY= -LANGFUSE_PUBLIC_KEY= -ZONKE_API_ENDPOINT= -ZONKE_API_KEY= -ZONKE_API_TOKEN= +VITE_SUPABASE_API_URL= +VITE_SUPABASE_ANON_KEY= +VITE_MIXPANEL_TOKEN= +VITE_ANTHROPIC_API_KEY= +VITE_OPENAI_API_KEY= +VITE_LANGFUSE_SECRET_KEY= +VITE_LANGFUSE_PUBLIC_KEY= +VITE_ZONKE_API_ENDPOINT= +VITE_ZONKE_API_KEY= +VITE_ZONKE_API_TOKEN= diff --git a/apps/studio/electron/main/events/hosting.ts b/apps/studio/electron/main/events/hosting.ts index a9bd74e02..cdf2c6b56 100644 --- a/apps/studio/electron/main/events/hosting.ts +++ b/apps/studio/electron/main/events/hosting.ts @@ -10,10 +10,7 @@ export function listenForHostingMessages() { }, ); - ipcMain.handle( - MainChannels.GET_PROJECT_HOSTING_ENV, - (e: Electron.IpcMainInvokeEvent, args) => { - return hostingManager.getEnv(); - }, - ); + ipcMain.handle(MainChannels.GET_PROJECT_HOSTING_ENV, (e: Electron.IpcMainInvokeEvent, args) => { + return hostingManager.getEnv(); + }); } diff --git a/apps/studio/electron/main/hosting/index.ts b/apps/studio/electron/main/hosting/index.ts index 1f42e7e13..33b956fc4 100644 --- a/apps/studio/electron/main/hosting/index.ts +++ b/apps/studio/electron/main/hosting/index.ts @@ -1,4 +1,4 @@ -import { SupportedFrameworks, createPreviewEnvironment } from '@zonke-cloud/sdk'; +import { PreviewEnvironmentClient, SupportedFrameworks } from '@zonke-cloud/sdk'; import { PersistentStorage } from '../storage'; export interface CreateEnvOptions { @@ -6,23 +6,34 @@ export interface CreateEnvOptions { } const MOCK_ENV = { - versions: [ - { - isLatest: true, - lastUpdated: '2021-11-12T00:00:00Z', - versionId: 'GXtMmG9qhkD8_QOiIP591JQSQxwMqHRv', - }, - ], - environmentId: '7366e360-a5f4-437a-9678-8bb0397067c2', - endpoint: 'y9mashx88v.preview.zonke.market', + endpoint: 'o95ewhbkzx.preview.zonke.market', + environmentId: '850540f8-a168-43a6-9772-6a1727d73b93', + versions: [], }; class HostingManager { + private zonke: PreviewEnvironmentClient; private static instance: HostingManager; private userId: string | null = null; private constructor() { this.restoreSettings(); + this.zonke = this.initZonkeClient(); + } + + initZonkeClient() { + if ( + !import.meta.env.VITE_ZONKE_API_KEY || + !import.meta.env.VITE_ZONKE_API_TOKEN || + !import.meta.env.VITE_ZONKE_API_ENDPOINT + ) { + throw new Error('Zonke API key, token, and endpoint must be set'); + } + return new PreviewEnvironmentClient({ + apiKey: import.meta.env.VITE_ZONKE_API_KEY, + apiToken: import.meta.env.VITE_ZONKE_API_TOKEN, + apiEndpoint: import.meta.env.VITE_ZONKE_API_ENDPOINT, + }); } public static getInstance(): HostingManager { @@ -39,12 +50,6 @@ class HostingManager { createEnv(options: CreateEnvOptions) { // TODO: Get project info from project path to determine create params - console.log('createEnv', { - ZONKE_API_KEY: process.env.ZONKE_API_KEY, - ZONKE_API_TOKEN: process.env.ZONKE_API_TOKEN, - ZONKE_API_ENDPOINT: process.env.ZONKE_API_ENDPOINT, - }); - return MOCK_ENV; if (this.userId === null) { console.error('User ID not found'); return; @@ -53,7 +58,7 @@ class HostingManager { const framework = options.framework as SupportedFrameworks; const awsHostedZone = 'zonke.market'; - return createPreviewEnvironment({ + return this.zonke.createPreviewEnvironment({ userId: this.userId, framework, awsHostedZone, From c1dec7386c43f46e062ac2f78435c8155e286959 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Tue, 17 Dec 2024 10:50:42 -0500 Subject: [PATCH 13/17] Add build script --- apps/studio/electron/main/events/hosting.ts | 8 +++ apps/studio/electron/main/hosting/index.ts | 19 ++++++- apps/studio/src/lib/projects/hosting.ts | 57 ++++++++++++++++--- apps/studio/src/lib/projects/index.ts | 12 +++- apps/studio/src/lib/projects/run.ts | 4 +- .../editor/TopBar/ShareProject/index.tsx | 21 ++++--- .../routes/projects/ProjectSettingsModal.tsx | 25 ++++++-- .../ProjectsTab/Create/Load/SetUrl.tsx | 33 +++++++++-- .../projects/ProjectsTab/Create/index.tsx | 13 ++++- packages/models/src/constants/index.ts | 1 + packages/models/src/projects/index.ts | 5 +- 11 files changed, 165 insertions(+), 33 deletions(-) diff --git a/apps/studio/electron/main/events/hosting.ts b/apps/studio/electron/main/events/hosting.ts index cdf2c6b56..6795a2bda 100644 --- a/apps/studio/electron/main/events/hosting.ts +++ b/apps/studio/electron/main/events/hosting.ts @@ -13,4 +13,12 @@ export function listenForHostingMessages() { ipcMain.handle(MainChannels.GET_PROJECT_HOSTING_ENV, (e: Electron.IpcMainInvokeEvent, args) => { return hostingManager.getEnv(); }); + + ipcMain.handle( + MainChannels.PUBLISH_PROJECT_HOSTING_ENV, + (e: Electron.IpcMainInvokeEvent, args) => { + const { envId, folderPath, buildScript } = args; + return hostingManager.publishEnv(envId, folderPath, buildScript); + }, + ); } diff --git a/apps/studio/electron/main/hosting/index.ts b/apps/studio/electron/main/hosting/index.ts index 33b956fc4..ad2a1fa71 100644 --- a/apps/studio/electron/main/hosting/index.ts +++ b/apps/studio/electron/main/hosting/index.ts @@ -49,7 +49,6 @@ class HostingManager { } createEnv(options: CreateEnvOptions) { - // TODO: Get project info from project path to determine create params if (this.userId === null) { console.error('User ID not found'); return; @@ -69,6 +68,24 @@ class HostingManager { // TODO: Get project info from project path to determine create params return MOCK_ENV; } + + publishEnv(envId: string, folderPath: string, buildScript: string) { + console.log('Publishing environment', { + envId, + folderPath, + buildScript, + }); + // TODO: Run build script + // Get S3 link + // Publish build to S3 + // Return status + + // return this.zonke.publishPreviewEnvironment({ + // environmentId: envId, + // folderPath, + // buildScript, + // }); + } } export default HostingManager.getInstance(); diff --git a/apps/studio/src/lib/projects/hosting.ts b/apps/studio/src/lib/projects/hosting.ts index 112250d26..166742fa4 100644 --- a/apps/studio/src/lib/projects/hosting.ts +++ b/apps/studio/src/lib/projects/hosting.ts @@ -1,10 +1,12 @@ import { MainChannels } from '@onlook/models/constants'; import type { Project } from '@onlook/models/projects'; +import type { PreviewEnvironment } from '@zonke-cloud/sdk'; import { makeAutoObservable } from 'mobx'; import { invokeMainChannel } from '../utils'; export class HostingManager { private project: Project; + env: PreviewEnvironment | null = null; constructor(project: Project) { makeAutoObservable(this); @@ -13,20 +15,61 @@ export class HostingManager { } async restoreState() { - // Create hosting env for project + this.env = await this.getEnv(); } async create() { - console.log('Creating hosting environment', this.project.id); - const res = await invokeMainChannel(MainChannels.CREATE_PROJECT_HOSTING_ENV, { - userId: 'testUserId', - framework: 'nextjs', + const res: PreviewEnvironment | null = await invokeMainChannel( + MainChannels.CREATE_PROJECT_HOSTING_ENV, + { + userId: 'testUserId', + framework: 'nextjs', + }, + ); + if (!res) { + console.error('Failed to create hosting environment'); + return; + } + this.env = res; + } + + async getEnv() { + const res = await invokeMainChannel(MainChannels.GET_PROJECT_HOSTING_ENV, { + projectId: this.project.id, + }); + return res as PreviewEnvironment; + } + + async publish() { + const folderPath = this.project.folderPath; + const buildScript: string = this.project.commands?.build || 'npm run build'; + const envId = this.env?.environmentId; + + if (!folderPath || !buildScript || !envId) { + console.error('Failed to publish hosting environment'); + return; + } + + const res = await invokeMainChannel(MainChannels.PUBLISH_PROJECT_HOSTING_ENV, { + folderPath, + buildScript, + envId, }); - console.log('Created hosting environment', res); + if (!res) { + console.error('Failed to publish hosting environment'); + return; + } + console.log('Published hosting environment', res); } async stop() { - console.log('Stopping hosting environment', this.project.id); + // if (!this.env) { + // console.error('No hosting environment to stop'); + // return; + // } + // await invokeMainChannel(MainChannels.STOP_PROJECT_HOSTING_ENV, { + // envId: this.env.environmentId, + // }); } async restart() {} diff --git a/apps/studio/src/lib/projects/index.ts b/apps/studio/src/lib/projects/index.ts index 24c7e01d4..3bffa0a2c 100644 --- a/apps/studio/src/lib/projects/index.ts +++ b/apps/studio/src/lib/projects/index.ts @@ -35,7 +35,15 @@ export class ProjectsManager { } } - createProject(name: string, url: string, folderPath: string, runCommand: string): Project { + createProject( + name: string, + url: string, + folderPath: string, + commands: { + run: string; + build: string; + }, + ): Project { const newProject: Project = { id: nanoid(), name, @@ -43,7 +51,7 @@ export class ProjectsManager { folderPath, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), - runCommand, + commands, }; const updatedProjects = [...this.projectList, newProject]; diff --git a/apps/studio/src/lib/projects/run.ts b/apps/studio/src/lib/projects/run.ts index 94515cf24..203933a66 100644 --- a/apps/studio/src/lib/projects/run.ts +++ b/apps/studio/src/lib/projects/run.ts @@ -26,7 +26,7 @@ export class RunManager { return await invokeMainChannel(MainChannels.RUN_START, { id: this.project.id, folderPath: this.project.folderPath, - command: this.project.runCommand || 'npm run dev', + command: this.project.commands.run || 'npm run dev', }); } @@ -41,7 +41,7 @@ export class RunManager { return await invokeMainChannel(MainChannels.RUN_RESTART, { id: this.project.id, folderPath: this.project.folderPath, - command: this.project.runCommand || 'npm run dev', + command: this.project.commands.run || 'npm run dev', }); } diff --git a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx index d142607be..9f7538bbf 100644 --- a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx @@ -10,13 +10,15 @@ import { useMemo, useState } from 'react'; const ShareProject = observer(() => { const projectsManager = useProjectsManager(); const hosting = projectsManager.hosting; + const env = hosting?.env; + const endpoint = `https://${env?.endpoint}`; + const [isOpen, setIsOpen] = useState(false); - const [isLinkCreated, setIsLinkCreated] = useState(false); const [isCopied, setIsCopied] = useState(false); const [hasChanges, setHasChanges] = useState(false); const handleCopyUrl = async () => { - await navigator.clipboard.writeText('http://localhost:3000'); + await navigator.clipboard.writeText(endpoint); setIsCopied(true); setTimeout(() => setIsCopied(false), 2000); }; @@ -35,8 +37,7 @@ const ShareProject = observer(() => { return; } - const env = await hosting.create(); - setIsLinkCreated(true); + hosting.create(); }; return ( @@ -54,12 +55,12 @@ const ShareProject = observer(() => { - {isLinkCreated ? 'Public link' : 'Share public link'} + {env ? 'Public link' : 'Share public link'} - {!isLinkCreated ? ( + {!env ? ( {
- - https://example.dev/share/... - +
+
+ + diff --git a/apps/studio/src/routes/projects/ProjectsTab/Create/Load/SetUrl.tsx b/apps/studio/src/routes/projects/ProjectsTab/Create/Load/SetUrl.tsx index a17acc3e0..6689db43b 100644 --- a/apps/studio/src/routes/projects/ProjectsTab/Create/Load/SetUrl.tsx +++ b/apps/studio/src/routes/projects/ProjectsTab/Create/Load/SetUrl.tsx @@ -11,7 +11,8 @@ import type { StepComponent } from '../withStepProps'; const LoadSetUrl: StepComponent = ({ props, variant }) => { const { projectData, setProjectData, prevStep, nextStep } = props; const [projectUrl, setProjectUrl] = useState(projectData.url || ''); - const [runCommand, setRunCommand] = useState(projectData.runCommand || ''); + const [runCommand, setRunCommand] = useState(projectData.commands?.run || ''); + const [buildCommand, setBuildCommand] = useState(projectData.commands?.build || ''); const [error, setError] = useState(null); function handleUrlInput(e: React.FormEvent) { @@ -32,7 +33,21 @@ const LoadSetUrl: StepComponent = ({ props, variant }) => { setRunCommand(e.currentTarget.value); setProjectData({ ...projectData, - runCommand: e.currentTarget.value, + commands: { + ...projectData.commands, + run: e.currentTarget.value, + }, + }); + } + + function handleBuildCommandInput(e: React.FormEvent) { + setBuildCommand(e.currentTarget.value); + setProjectData({ + ...projectData, + commands: { + ...projectData.commands, + build: e.currentTarget.value, + }, }); } @@ -75,6 +90,14 @@ const LoadSetUrl: StepComponent = ({ props, variant }) => { placeholder="npm run dev" onInput={handleRunCommandInput} /> + +

{error || ''}

); @@ -88,8 +111,10 @@ const LoadSetUrl: StepComponent = ({ props, variant }) => { disabled={ !projectData.url || projectData.url.length === 0 || - !projectData.runCommand || - projectData.runCommand.length === 0 + !projectData.commands?.run || + projectData.commands?.run.length === 0 || + !projectData.commands?.build || + projectData.commands?.build.length === 0 } type="button" onClick={nextStep} diff --git a/apps/studio/src/routes/projects/ProjectsTab/Create/index.tsx b/apps/studio/src/routes/projects/ProjectsTab/Create/index.tsx index 009087509..55cf24cec 100644 --- a/apps/studio/src/routes/projects/ProjectsTab/Create/index.tsx +++ b/apps/studio/src/routes/projects/ProjectsTab/Create/index.tsx @@ -32,7 +32,10 @@ const variants = { const DEFAULT_PROJECT_DATA = { url: 'http://localhost:3000', - runCommand: 'npm run dev', + commands: { + run: 'npm run dev', + build: 'npm run build', + }, hasCopied: false, }; @@ -109,7 +112,8 @@ const CreateProject = ({ !projectData.name || !projectData.url || !projectData.folderPath || - !projectData.runCommand + !projectData.commands?.run || + !projectData.commands?.build ) { throw new Error('Project data is missing.'); } @@ -118,7 +122,10 @@ const CreateProject = ({ projectData.name, projectData.url, projectData.folderPath, - projectData.runCommand, + { + run: projectData.commands.run, + build: projectData.commands.build, + }, ); projectsManager.project = newProject; diff --git a/packages/models/src/constants/index.ts b/packages/models/src/constants/index.ts index 68043e56f..380649600 100644 --- a/packages/models/src/constants/index.ts +++ b/packages/models/src/constants/index.ts @@ -137,6 +137,7 @@ export enum MainChannels { // Hosting CREATE_PROJECT_HOSTING_ENV = 'create-project-hosting-env', GET_PROJECT_HOSTING_ENV = 'get-project-hosting-env', + PUBLISH_PROJECT_HOSTING_ENV = 'publish-project-hosting-env', } export enum Links { diff --git a/packages/models/src/projects/index.ts b/packages/models/src/projects/index.ts index 5693f9baa..77cb97d0e 100644 --- a/packages/models/src/projects/index.ts +++ b/packages/models/src/projects/index.ts @@ -34,7 +34,10 @@ export const ProjectSchema = z.object({ createdAt: z.string(), // ISO 8601 updatedAt: z.string(), // ISO 8601 settings: ProjectSettingsSchema.optional(), - runCommand: z.string().optional(), + commands: z.object({ + build: z.string().optional(), + run: z.string().optional(), + }), }); export type Project = z.infer; From f96bdbb60fe92992adf52105b1a2cdf2b91aceb6 Mon Sep 17 00:00:00 2001 From: Kiet Ho Date: Tue, 17 Dec 2024 10:59:19 -0500 Subject: [PATCH 14/17] Starting publish --- .../routes/editor/TopBar/ShareProject/index.tsx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx index 9f7538bbf..6210e0467 100644 --- a/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx +++ b/apps/studio/src/routes/editor/TopBar/ShareProject/index.tsx @@ -15,7 +15,6 @@ const ShareProject = observer(() => { const [isOpen, setIsOpen] = useState(false); const [isCopied, setIsCopied] = useState(false); - const [hasChanges, setHasChanges] = useState(false); const handleCopyUrl = async () => { await navigator.clipboard.writeText(endpoint); @@ -40,6 +39,15 @@ const ShareProject = observer(() => { hosting.create(); }; + const publish = async () => { + if (!hosting) { + console.error('Hosting is not available'); + return; + } + + hosting.publish(); + }; + return ( <>