feat(web): add tooltip for workflow variables
This commit is contained in:
		
							parent
							
								
									3e55efe0a5
								
							
						
					
					
						commit
						c2d67da7db
					
				
							
								
								
									
										
											BIN
										
									
								
								web/bun.lockb
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								web/bun.lockb
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							@ -28,6 +28,7 @@
 | 
				
			|||||||
    "@radix-ui/react-select": "^2.0.0",
 | 
					    "@radix-ui/react-select": "^2.0.0",
 | 
				
			||||||
    "@radix-ui/react-slot": "^1.0.2",
 | 
					    "@radix-ui/react-slot": "^1.0.2",
 | 
				
			||||||
    "@radix-ui/react-tabs": "^1.0.4",
 | 
					    "@radix-ui/react-tabs": "^1.0.4",
 | 
				
			||||||
 | 
					    "@radix-ui/react-tooltip": "^1.0.7",
 | 
				
			||||||
    "@tanstack/react-table": "^8.10.7",
 | 
					    "@tanstack/react-table": "^8.10.7",
 | 
				
			||||||
    "@types/jsonwebtoken": "^9.0.5",
 | 
					    "@types/jsonwebtoken": "^9.0.5",
 | 
				
			||||||
    "@types/uuid": "^9.0.7",
 | 
					    "@types/uuid": "^9.0.7",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,29 +1,29 @@
 | 
				
			|||||||
import "./globals.css";
 | 
					import "./globals.css";
 | 
				
			||||||
import { NavbarRight } from "@/components/NavbarRight";
 | 
					import { NavbarRight } from "@/components/NavbarRight";
 | 
				
			||||||
import { Button } from "@/components/ui/button";
 | 
					import { Button } from "@/components/ui/button";
 | 
				
			||||||
 | 
					import { TooltipProvider } from "@/components/ui/tooltip";
 | 
				
			||||||
import { ClerkProvider, UserButton } from "@clerk/nextjs";
 | 
					import { ClerkProvider, UserButton } from "@clerk/nextjs";
 | 
				
			||||||
import { Github } from "lucide-react";
 | 
					import { Github } from "lucide-react";
 | 
				
			||||||
import type { Metadata } from "next";
 | 
					import type { Metadata } from "next";
 | 
				
			||||||
 | 
					import meta from "next-gen/config";
 | 
				
			||||||
import PlausibleProvider from "next-plausible";
 | 
					import PlausibleProvider from "next-plausible";
 | 
				
			||||||
import { Inter } from "next/font/google";
 | 
					import { Inter } from "next/font/google";
 | 
				
			||||||
import { Toaster } from "sonner";
 | 
					import { Toaster } from "sonner";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const inter = Inter({ subsets: ["latin"] });
 | 
					const inter = Inter({ subsets: ["latin"] });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import meta from 'next-gen/config';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const metadata: Metadata = {
 | 
					export const metadata: Metadata = {
 | 
				
			||||||
  title: meta['og:title'],
 | 
					  title: meta["og:title"],
 | 
				
			||||||
  description: meta['og:description'],
 | 
					  description: meta["og:description"],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  category: 'technology',
 | 
					  category: "technology",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  openGraph: {
 | 
					  openGraph: {
 | 
				
			||||||
    type: 'website',
 | 
					    type: "website",
 | 
				
			||||||
    title: meta['og:title'],
 | 
					    title: meta["og:title"],
 | 
				
			||||||
    description: meta['og:description'],
 | 
					    description: meta["og:description"],
 | 
				
			||||||
    locale: 'en_US',
 | 
					    locale: "en_US",
 | 
				
			||||||
    images: '/og.jpg',
 | 
					    images: "/og.jpg",
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -35,44 +35,51 @@ export default function RootLayout({
 | 
				
			|||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <html lang="en">
 | 
					    <html lang="en">
 | 
				
			||||||
      <ClerkProvider>
 | 
					      <ClerkProvider>
 | 
				
			||||||
        <head>
 | 
					        <TooltipProvider>
 | 
				
			||||||
          {process.env.PLAUSIBLE_DOMAIN && (
 | 
					          <head>
 | 
				
			||||||
            <PlausibleProvider domain={process.env.PLAUSIBLE_DOMAIN} />
 | 
					            {process.env.PLAUSIBLE_DOMAIN && (
 | 
				
			||||||
          )}
 | 
					              <PlausibleProvider domain={process.env.PLAUSIBLE_DOMAIN} />
 | 
				
			||||||
        </head>
 | 
					            )}
 | 
				
			||||||
        <body className={inter.className}>
 | 
					          </head>
 | 
				
			||||||
          <main className="w-full flex min-h-[100dvh] flex-col items-center justify-start">
 | 
					          <body className={inter.className}>
 | 
				
			||||||
          <div className="z-[-1] fixed h-full w-full bg-white"><div className="absolute h-full w-full bg-[radial-gradient(#e5e7eb_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div></div>
 | 
					            <main className="w-full flex min-h-[100dvh] flex-col items-center justify-start">
 | 
				
			||||||
            <div className="w-full h-18 flex items-center justify-between gap-4 p-4 border-b border-gray-200">
 | 
					              <div className="z-[-1] fixed h-full w-full bg-white">
 | 
				
			||||||
              <div className="flex flex-row items-center gap-4">
 | 
					                <div className="absolute h-full w-full bg-[radial-gradient(#e5e7eb_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]" />
 | 
				
			||||||
                <a className="font-bold text-md md:text-lg hover:underline" href="/">
 | 
					 | 
				
			||||||
                  {meta.name}
 | 
					 | 
				
			||||||
                </a>
 | 
					 | 
				
			||||||
                <NavbarRight />
 | 
					 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
              <div className="flex flex-row items-center gap-2">
 | 
					              <div className="w-full h-18 flex items-center justify-between gap-4 p-4 border-b border-gray-200">
 | 
				
			||||||
                <UserButton />
 | 
					                <div className="flex flex-row items-center gap-4">
 | 
				
			||||||
                <Button
 | 
					 | 
				
			||||||
                  asChild
 | 
					 | 
				
			||||||
                  variant={"outline"}
 | 
					 | 
				
			||||||
                  className="rounded-full aspect-square p-2"
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                  <a
 | 
					                  <a
 | 
				
			||||||
                    target="_blank"
 | 
					                    className="font-bold text-md md:text-lg hover:underline"
 | 
				
			||||||
                    href="https://github.com/BennyKok/comfyui-deploy"
 | 
					                    href="/"
 | 
				
			||||||
                  >
 | 
					                  >
 | 
				
			||||||
                    <Github />
 | 
					                    {meta.name}
 | 
				
			||||||
                  </a>
 | 
					                  </a>
 | 
				
			||||||
                </Button>
 | 
					                  <NavbarRight />
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div className="flex flex-row items-center gap-2">
 | 
				
			||||||
 | 
					                  <UserButton />
 | 
				
			||||||
 | 
					                  <Button
 | 
				
			||||||
 | 
					                    asChild
 | 
				
			||||||
 | 
					                    variant="outline"
 | 
				
			||||||
 | 
					                    className="rounded-full aspect-square p-2"
 | 
				
			||||||
 | 
					                  >
 | 
				
			||||||
 | 
					                    <a
 | 
				
			||||||
 | 
					                      target="_blank"
 | 
				
			||||||
 | 
					                      href="https://github.com/BennyKok/comfyui-deploy"
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
 | 
					                      <Github />
 | 
				
			||||||
 | 
					                    </a>
 | 
				
			||||||
 | 
					                  </Button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                {/* <div></div> */}
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
              {/* <div></div> */}
 | 
					              <div className="md:px-10 px-6 w-full min-h-[calc(100dvh-73px)]">
 | 
				
			||||||
            </div>
 | 
					                {children}
 | 
				
			||||||
            <div className="md:px-10 px-6 w-full min-h-[calc(100dvh-73px)]">
 | 
					              </div>
 | 
				
			||||||
              {children}
 | 
					              <Toaster richColors />
 | 
				
			||||||
            </div>
 | 
					            </main>
 | 
				
			||||||
            <Toaster richColors />
 | 
					          </body>
 | 
				
			||||||
          </main>
 | 
					        </TooltipProvider>
 | 
				
			||||||
        </body>
 | 
					 | 
				
			||||||
      </ClerkProvider>
 | 
					      </ClerkProvider>
 | 
				
			||||||
    </html>
 | 
					    </html>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,6 @@ export default async function Page({
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <VersionDetails workflow={workflow} />
 | 
					            <VersionDetails workflow={workflow} />
 | 
				
			||||||
 | 
					 | 
				
			||||||
            <MachinesWSMain machines={machines} />
 | 
					            <MachinesWSMain machines={machines} />
 | 
				
			||||||
          </CardContent>
 | 
					          </CardContent>
 | 
				
			||||||
        </Card>
 | 
					        </Card>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,14 @@
 | 
				
			|||||||
import { CopyButton } from "@/components/CopyButton";
 | 
					import { CopyButton } from "@/components/CopyButton";
 | 
				
			||||||
import { getHighlighter, StringLiteralUnion  } from 'shikiji'
 | 
					import type { StringLiteralUnion } from "shikiji";
 | 
				
			||||||
 | 
					import { getHighlighter } from "shikiji";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function CodeBlock(props: { code: string; lang: StringLiteralUnion<string> }) {
 | 
					export async function CodeBlock(props: {
 | 
				
			||||||
 | 
					  code: string;
 | 
				
			||||||
 | 
					  lang: StringLiteralUnion<string>;
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
  const highlighter = await getHighlighter({
 | 
					  const highlighter = await getHighlighter({
 | 
				
			||||||
    themes: ["one-dark-pro"],
 | 
					    themes: ["one-dark-pro"],
 | 
				
			||||||
    langs: [props.lang]
 | 
					    langs: [props.lang],
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,11 @@ import {
 | 
				
			|||||||
  SelectTrigger,
 | 
					  SelectTrigger,
 | 
				
			||||||
  SelectValue,
 | 
					  SelectValue,
 | 
				
			||||||
} from "@/components/ui/select";
 | 
					} from "@/components/ui/select";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  Tooltip,
 | 
				
			||||||
 | 
					  TooltipContent,
 | 
				
			||||||
 | 
					  TooltipTrigger,
 | 
				
			||||||
 | 
					} from "@/components/ui/tooltip";
 | 
				
			||||||
import { createRun } from "@/server/createRun";
 | 
					import { createRun } from "@/server/createRun";
 | 
				
			||||||
import { createDeployments } from "@/server/curdDeploments";
 | 
					import { createDeployments } from "@/server/curdDeploments";
 | 
				
			||||||
import type { getMachines } from "@/server/curdMachine";
 | 
					import type { getMachines } from "@/server/curdMachine";
 | 
				
			||||||
@ -75,11 +80,11 @@ export function MachineSelect({
 | 
				
			|||||||
      }}
 | 
					      }}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <SelectTrigger className="w-[180px]">
 | 
					      <SelectTrigger className="w-[180px]">
 | 
				
			||||||
        <SelectValue placeholder="Select a version" />
 | 
					        <SelectValue placeholder="Select a machine" />
 | 
				
			||||||
      </SelectTrigger>
 | 
					      </SelectTrigger>
 | 
				
			||||||
      <SelectContent>
 | 
					      <SelectContent>
 | 
				
			||||||
        <SelectGroup>
 | 
					        <SelectGroup>
 | 
				
			||||||
          <SelectLabel>Versions</SelectLabel>
 | 
					          <SelectLabel>Machines</SelectLabel>
 | 
				
			||||||
          {machines?.map((x) => (
 | 
					          {machines?.map((x) => (
 | 
				
			||||||
            <SelectItem key={x.id} value={x.id ?? ""}>
 | 
					            <SelectItem key={x.id} value={x.id ?? ""}>
 | 
				
			||||||
              {x.name}
 | 
					              {x.name}
 | 
				
			||||||
@ -203,7 +208,7 @@ export function CreateDeploymentButton({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const customInputNodes: Record<string, string> = {
 | 
					const customInputNodes: Record<string, string> = {
 | 
				
			||||||
  ComfyUIDeployExternalText: "string",
 | 
					  ComfyUIDeployExternalText: "string",
 | 
				
			||||||
  ComfyUIDeployExternalImage: "string - image url",
 | 
					  ComfyUIDeployExternalImage: "string - (public image url)",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function VersionDetails({
 | 
					export function VersionDetails({
 | 
				
			||||||
@ -223,7 +228,7 @@ export function VersionDetails({
 | 
				
			|||||||
      Workflow Details
 | 
					      Workflow Details
 | 
				
			||||||
      <div className="border rounded-lg p-2">
 | 
					      <div className="border rounded-lg p-2">
 | 
				
			||||||
        {workflow_version?.workflow_api && (
 | 
					        {workflow_version?.workflow_api && (
 | 
				
			||||||
          <div>
 | 
					          <div className="flex flex-col gap-2">
 | 
				
			||||||
            {Object.entries(workflow_version.workflow_api).map(
 | 
					            {Object.entries(workflow_version.workflow_api).map(
 | 
				
			||||||
              ([key, value]) => {
 | 
					              ([key, value]) => {
 | 
				
			||||||
                if (!value.class_type) return <> </>;
 | 
					                if (!value.class_type) return <> </>;
 | 
				
			||||||
@ -232,10 +237,24 @@ export function VersionDetails({
 | 
				
			|||||||
                  const input_id = value.inputs.input_id;
 | 
					                  const input_id = value.inputs.input_id;
 | 
				
			||||||
                  const defaultValue = value.inputs.default_value;
 | 
					                  const defaultValue = value.inputs.default_value;
 | 
				
			||||||
                  return (
 | 
					                  return (
 | 
				
			||||||
                    <>
 | 
					                    <div key={input_id}>
 | 
				
			||||||
                      <Badge variant="secondary">{input_id}</Badge> {nodeType}{" "}
 | 
					                      <Tooltip>
 | 
				
			||||||
                      {defaultValue}
 | 
					                        <TooltipTrigger>
 | 
				
			||||||
                    </>
 | 
					                          <Badge variant="secondary">
 | 
				
			||||||
 | 
					                            <div>
 | 
				
			||||||
 | 
					                              {input_id}
 | 
				
			||||||
 | 
					                              {" : "}
 | 
				
			||||||
 | 
					                              {nodeType}
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                          </Badge>
 | 
				
			||||||
 | 
					                          {/* {nodeType}{" "} */}
 | 
				
			||||||
 | 
					                          {/* <Button variant="outline">Hover</Button> */}
 | 
				
			||||||
 | 
					                        </TooltipTrigger>
 | 
				
			||||||
 | 
					                        <TooltipContent>
 | 
				
			||||||
 | 
					                          Default Value: {defaultValue}
 | 
				
			||||||
 | 
					                        </TooltipContent>
 | 
				
			||||||
 | 
					                      </Tooltip>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
                  );
 | 
					                  );
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return <></>;
 | 
					                return <></>;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										29
									
								
								web/src/components/ui/tooltip.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								web/src/components/ui/tooltip.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					"use client";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { cn } from "@/lib/utils";
 | 
				
			||||||
 | 
					import * as TooltipPrimitive from "@radix-ui/react-tooltip";
 | 
				
			||||||
 | 
					import * as React from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TooltipProvider = TooltipPrimitive.Provider;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Tooltip = TooltipPrimitive.Root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TooltipTrigger = TooltipPrimitive.Trigger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TooltipContent = React.forwardRef<
 | 
				
			||||||
 | 
					  React.ElementRef<typeof TooltipPrimitive.Content>,
 | 
				
			||||||
 | 
					  React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
 | 
				
			||||||
 | 
					>(({ className, sideOffset = 4, ...props }, ref) => (
 | 
				
			||||||
 | 
					  <TooltipPrimitive.Content
 | 
				
			||||||
 | 
					    ref={ref}
 | 
				
			||||||
 | 
					    sideOffset={sideOffset}
 | 
				
			||||||
 | 
					    className={cn(
 | 
				
			||||||
 | 
					      "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
 | 
				
			||||||
 | 
					      className
 | 
				
			||||||
 | 
					    )}
 | 
				
			||||||
 | 
					    {...props}
 | 
				
			||||||
 | 
					  />
 | 
				
			||||||
 | 
					));
 | 
				
			||||||
 | 
					TooltipContent.displayName = TooltipPrimitive.Content.displayName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user