From 9ba19c386fcd7e16d8605b420714ee8b7948f61e Mon Sep 17 00:00:00 2001 From: Fayorg Date: Fri, 3 May 2024 15:18:40 +0200 Subject: [PATCH] add: databases WIP --- .../databases/database-new-form.tsx | 148 ++++++++++++++++-- components/ui/label.tsx | 26 +++ lib/deploy/database.ts | 16 ++ lib/deploy/databases/database.ts | 73 --------- lib/deploy/databases/index.ts | 0 lib/deploy/databases/vitess-database.ts | 18 --- package-lock.json | 24 +++ package.json | 1 + public/redis.svg | 2 + public/vitess.png | Bin 0 -> 7418 bytes 10 files changed, 207 insertions(+), 101 deletions(-) create mode 100644 components/ui/label.tsx create mode 100644 lib/deploy/database.ts delete mode 100644 lib/deploy/databases/database.ts delete mode 100644 lib/deploy/databases/index.ts delete mode 100644 lib/deploy/databases/vitess-database.ts create mode 100644 public/redis.svg create mode 100644 public/vitess.png diff --git a/app/(deploy)/[workspace]/databases/database-new-form.tsx b/app/(deploy)/[workspace]/databases/database-new-form.tsx index df00c5f..b9a0c4b 100644 --- a/app/(deploy)/[workspace]/databases/database-new-form.tsx +++ b/app/(deploy)/[workspace]/databases/database-new-form.tsx @@ -1,18 +1,40 @@ 'use client'; import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; import { Progress } from '@/components/ui/progress'; import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet'; import { useWorkspace } from '@/hooks/useWorkspace'; +import { deployDatabase } from '@/lib/deploy/database'; import { cn } from '@/lib/utils'; import { Plus } from 'lucide-react'; +import Image from 'next/image'; import { useState } from 'react'; interface DatabaseNewSteps { display: string; } +interface IDatabaseProvider { + id: string; + display: string; + image: { + alt: string; + src: string; + }; +} + +export interface IDatabaseConfig { + name: string; + provider: IDatabaseProvider; + user: { + username: string; + password: string; + }; +} + const steps: DatabaseNewSteps[] = [ { display: 'Database Type', @@ -20,15 +42,49 @@ const steps: DatabaseNewSteps[] = [ { display: 'Configuration', }, + { + display: 'Name & User', + }, { display: 'Review & Deploy', }, ]; +const databaseProviders: IDatabaseProvider[] = [ + { + id: 'vitess', + display: 'Vitess', + image: { + alt: 'Vitess', + src: '/vitess.png', + }, + }, + { + id: 'redis', + display: 'Redis', + image: { + alt: 'Redis', + src: '/redis.svg', + }, + }, +]; + export default function DatabaseNewForm() { const [open, setOpen] = useState(false); const [currentSteps, setCurrentSteps] = useState(1); + // TODO: Generate all data, but leave the user the choice to modify + const defaultDatabaseConfig: IDatabaseConfig = { + name: 'my-new-cool-db', + provider: databaseProviders[0], + user: { + username: 'my-new-super-user', + password: 'a-super-strong-generated-password', + }, + }; + + const [databaseConfig, setDatabaseConfig] = useState(defaultDatabaseConfig); + const { id } = useWorkspace(); return ( @@ -59,15 +115,80 @@ export default function DatabaseNewForm() { {currentSteps == 1 && (
- {/* -
- - -
-
*/} + { + setDatabaseConfig((prev) => ({ ...prev, provider: databaseProviders.filter((provider) => provider.id == id)[0] })); + }} + > + {databaseProviders.map((provider) => ( +
+ + +
+ ))} +
+
+ )} + + {currentSteps == 2 && ( +
+

WIP for now 1CPU 2048Mb RAM

+

Storage 1 GB

+
+ )} + + {currentSteps == 3 && ( +
+ + { + setDatabaseConfig((prev) => ({ ...prev, name: e.target.value })); + }} + /> + + + { + setDatabaseConfig((prev) => ({ ...prev, user: { ...prev.user, username: e.target.value } })); + }} + /> + + + { + setDatabaseConfig((prev) => ({ ...prev, user: { ...prev.user, password: e.target.value } })); + }} + /> +
+
+ )} + + {currentSteps == 4 && ( +
+

Review your new database information :

+

Type : {databaseConfig.provider.display}

+

Name : {databaseConfig.name}

+

Username : {databaseConfig.user.username}

+

Password : {databaseConfig.user.password}

)} @@ -82,7 +203,14 @@ export default function DatabaseNewForm() { Back {currentSteps == steps.length ? ( - ) : ( diff --git a/components/ui/label.tsx b/components/ui/label.tsx new file mode 100644 index 0000000..5341821 --- /dev/null +++ b/components/ui/label.tsx @@ -0,0 +1,26 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +) + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, ...props }, ref) => ( + +)) +Label.displayName = LabelPrimitive.Root.displayName + +export { Label } diff --git a/lib/deploy/database.ts b/lib/deploy/database.ts new file mode 100644 index 0000000..35977bb --- /dev/null +++ b/lib/deploy/database.ts @@ -0,0 +1,16 @@ +"use server"; + +import { IDatabaseConfig } from "@/app/(deploy)/[workspace]/databases/database-new-form"; + +export async function deployDatabase(config: IDatabaseConfig) { + + return fetch("http://127.0.0.1:8080/databases", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(config), + }).then((res) => res.json()).catch((err) => { + console.error(err); + }); +} \ No newline at end of file diff --git a/lib/deploy/databases/database.ts b/lib/deploy/databases/database.ts deleted file mode 100644 index 8bcbc91..0000000 --- a/lib/deploy/databases/database.ts +++ /dev/null @@ -1,73 +0,0 @@ -import prisma from "@/lib/prisma"; -import { Database, DatabaseProvider } from "@prisma/client"; - -type DatabaseType = DatabaseProvider; - -export class CreateDatabase { - - private workspaceId: string; - private id: string; - public name: string; - public type: DatabaseType; - - public username: string; - private password: string; - private host: string | undefined; - private port: number | undefined; - - constructor(workspaceId: string, name: string, type: DatabaseType) { - this.id = "new-database-uuid"; // TODO: Generate UUID - this.username = "root"; // TODO: Generate random username - this.password = "toor"; // TODO: Generate random password - - this.workspaceId = workspaceId; - this.name = name; - this.type = type; - } - - // Deploying the database to the cluster - public async deploy(): Promise { - throw new Error("Not implemented"); - } - - // Saving the newly created database to the database - protected async save(): Promise { - // Checking if the connection details are provided - if(!this.host || !this.port) throw new MissingConnectionDetails(); - - const database = await prisma.database.create({ - data: { - id: this.id, - provider: this.type, - name: this.name, - workspaceId: this.workspaceId, - username: this.username, - password: this.password, - - host: this.host, - port: this.port - } - }); - - return database; - } - -} - -class DatabaseError extends Error { - constructor(message: string) { - super(message); - } -} - -export class SavingDatabaseError extends DatabaseError { - constructor() { - super("Error saving the database"); - } -} - -export class MissingConnectionDetails extends DatabaseError { - constructor() { - super("Missing connection details"); - } -} \ No newline at end of file diff --git a/lib/deploy/databases/index.ts b/lib/deploy/databases/index.ts deleted file mode 100644 index e69de29..0000000 diff --git a/lib/deploy/databases/vitess-database.ts b/lib/deploy/databases/vitess-database.ts deleted file mode 100644 index ae3b6fc..0000000 --- a/lib/deploy/databases/vitess-database.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Database } from "@prisma/client"; -import { CreateDatabase, SavingDatabaseError } from "./database"; - -export class CreateVitessDatabase extends CreateDatabase { - constructor(workspaceId: string, name: string) { - super(workspaceId, name, "VITESS"); - } - - public async deploy(): Promise { - try { - // Saving the database to the database - const database = await this.save(); - return database; - } catch (error) { - throw new SavingDatabaseError(); - } - } -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0db9b76..08bfdc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-radio-group": "^1.1.3", @@ -915,6 +916,29 @@ } } }, + "node_modules/@radix-ui/react-label": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", + "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popover": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz", diff --git a/package.json b/package.json index dc95fe5..ea01fd5 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-radio-group": "^1.1.3", diff --git a/public/redis.svg b/public/redis.svg new file mode 100644 index 0000000..ed31220 --- /dev/null +++ b/public/redis.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/public/vitess.png b/public/vitess.png new file mode 100644 index 0000000000000000000000000000000000000000..8ab29124af199d7b6b5d069d19923b93e04ed352 GIT binary patch literal 7418 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