feat: able to remove share page deployment
This commit is contained in:
parent
b6be0bd462
commit
f8ac6fb251
35
web/src/components/ButtonActionLoader.tsx
Normal file
35
web/src/components/ButtonActionLoader.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { LoadingIcon } from "@/components/LoadingIcon";
|
||||||
|
import { callServerPromise } from "@/components/callServerPromise";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export function ButtonAction({
|
||||||
|
action,
|
||||||
|
children,
|
||||||
|
...rest
|
||||||
|
}: {
|
||||||
|
action: () => Promise<any>;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
const [pending, setPending] = useState(false);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={async () => {
|
||||||
|
if (pending) return;
|
||||||
|
|
||||||
|
setPending(true);
|
||||||
|
await callServerPromise(action());
|
||||||
|
setPending(false);
|
||||||
|
|
||||||
|
router.refresh();
|
||||||
|
}}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{children} {pending && <LoadingIcon />}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import { ButtonAction } from "@/components/ButtonActionLoader";
|
||||||
import { CodeBlock } from "@/components/CodeBlock";
|
import { CodeBlock } from "@/components/CodeBlock";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
@ -13,6 +14,7 @@ import { TableCell, TableRow } from "@/components/ui/table";
|
|||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { getInputsFromWorkflow } from "@/lib/getInputsFromWorkflow";
|
import { getInputsFromWorkflow } from "@/lib/getInputsFromWorkflow";
|
||||||
import { getRelativeTime } from "@/lib/getRelativeTime";
|
import { getRelativeTime } from "@/lib/getRelativeTime";
|
||||||
|
import { removePublicShareDeployment } from "@/server/curdDeploments";
|
||||||
import type { findAllDeployments } from "@/server/findAllRuns";
|
import type { findAllDeployments } from "@/server/findAllRuns";
|
||||||
import { ExternalLink } from "lucide-react";
|
import { ExternalLink } from "lucide-react";
|
||||||
import { headers } from "next/headers";
|
import { headers } from "next/headers";
|
||||||
@ -136,7 +138,14 @@ export function DeploymentDisplay({
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full text-right">
|
<div className="w-full justify-end flex gap-2 py-1">
|
||||||
|
<Button asChild className="gap-2" variant="outline" type="submit">
|
||||||
|
<ButtonAction
|
||||||
|
action={removePublicShareDeployment.bind(null, deployment.id)}
|
||||||
|
>
|
||||||
|
Remove
|
||||||
|
</ButtonAction>
|
||||||
|
</Button>
|
||||||
<Button asChild className="gap-2">
|
<Button asChild className="gap-2">
|
||||||
<Link href={`/share/${deployment.id}`} target="_blank">
|
<Link href={`/share/${deployment.id}`} target="_blank">
|
||||||
View Share Page <ExternalLink size={14} />
|
View Share Page <ExternalLink size={14} />
|
||||||
|
@ -6,8 +6,16 @@ import { cn } from "@/lib/utils";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useMediaQuery } from "usehooks-ts";
|
||||||
|
|
||||||
export function NavbarMenu({ className }: { className?: string }) {
|
export function NavbarMenu({ className }: { className?: string }) {
|
||||||
|
const _isDesktop = useMediaQuery("(min-width: 1024px)");
|
||||||
|
const [isDesktop, setIsDesktop] = useState(true);
|
||||||
|
useEffect(() => {
|
||||||
|
setIsDesktop(_isDesktop);
|
||||||
|
}, [_isDesktop]);
|
||||||
|
|
||||||
const pathnames = usePathname();
|
const pathnames = usePathname();
|
||||||
const pathname = `/${pathnames.split("/")[1]}`;
|
const pathname = `/${pathnames.split("/")[1]}`;
|
||||||
|
|
||||||
@ -31,42 +39,43 @@ export function NavbarMenu({ className }: { className?: string }) {
|
|||||||
return (
|
return (
|
||||||
<div className={cn("mr-2", className)}>
|
<div className={cn("mr-2", className)}>
|
||||||
{/* <div className="w-full h-full absolute inset-x-0 top-0 flex items-center justify-center pointer-events-none"> */}
|
{/* <div className="w-full h-full absolute inset-x-0 top-0 flex items-center justify-center pointer-events-none"> */}
|
||||||
<Tabs
|
{isDesktop && (
|
||||||
defaultValue={pathname}
|
<Tabs
|
||||||
className="w-[300px] hidden lg:flex pointer-events-auto"
|
defaultValue={pathname}
|
||||||
// onValueChange={(value) => {
|
className="w-[300px] flex pointer-events-auto"
|
||||||
|
>
|
||||||
// }}
|
<TabsList className="grid w-full grid-cols-3">
|
||||||
>
|
{pages.map((page) => (
|
||||||
<TabsList className="grid w-full grid-cols-3">
|
<TabsTrigger
|
||||||
{pages.map((page) => (
|
key={page.name}
|
||||||
<TabsTrigger
|
value={page.path}
|
||||||
key={page.name}
|
onClick={() => {
|
||||||
value={page.path}
|
router.push(page.path);
|
||||||
onClick={() => {
|
}}
|
||||||
router.push(page.path);
|
>
|
||||||
}}
|
{page.name}
|
||||||
>
|
</TabsTrigger>
|
||||||
{page.name}
|
))}
|
||||||
</TabsTrigger>
|
</TabsList>
|
||||||
))}
|
</Tabs>
|
||||||
</TabsList>
|
)}
|
||||||
</Tabs>
|
|
||||||
{/* </div> */}
|
{/* </div> */}
|
||||||
|
|
||||||
<ScrollArea>
|
{!isDesktop && (
|
||||||
<div className="w-full flex lg:hidden flex-col h-full">
|
<ScrollArea>
|
||||||
{pages.map((page) => (
|
<div className="w-full flex flex-col h-full">
|
||||||
<Link
|
{pages.map((page) => (
|
||||||
key={page.name}
|
<Link
|
||||||
href={page.path}
|
key={page.name}
|
||||||
className="p-2 hover:bg-gray-100/20 hover:underline"
|
href={page.path}
|
||||||
>
|
className="p-2 hover:bg-gray-100/20 hover:underline"
|
||||||
{page.name}
|
>
|
||||||
</Link>
|
{page.name}
|
||||||
))}
|
</Link>
|
||||||
</div>
|
))}
|
||||||
</ScrollArea>
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import { db } from "@/db/db";
|
import { db } from "@/db/db";
|
||||||
import type { DeploymentType } from "@/db/schema";
|
import type { DeploymentType } from "@/db/schema";
|
||||||
import { deploymentsTable, workflowTable } from "@/db/schema";
|
import { deploymentsTable, workflowTable } from "@/db/schema";
|
||||||
|
import { withServerPromise } from "@/server/withServerPromise";
|
||||||
import { auth } from "@clerk/nextjs";
|
import { auth } from "@clerk/nextjs";
|
||||||
import { and, eq, isNull } from "drizzle-orm";
|
import { and, eq, isNull } from "drizzle-orm";
|
||||||
import { revalidatePath } from "next/cache";
|
import { revalidatePath } from "next/cache";
|
||||||
@ -104,3 +105,17 @@ export async function findSharedDeployment(workflow_id: string) {
|
|||||||
|
|
||||||
return deploymentData;
|
return deploymentData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const removePublicShareDeployment = withServerPromise(
|
||||||
|
async (deployment_id: string) => {
|
||||||
|
// throw new Error("Not implemented");
|
||||||
|
await db
|
||||||
|
.delete(deploymentsTable)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(deploymentsTable.environment, "public-share"),
|
||||||
|
eq(deploymentsTable.id, deployment_id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user