Sync with Langflow Store

This commit is contained in:
Lucas Oliveira 2023-11-18 18:06:33 -03:00
commit a81abb4c2d
4 changed files with 353 additions and 250 deletions

View file

@ -3,6 +3,7 @@ import { alertContext } from "../../contexts/alertContext";
import { FlowsContext } from "../../contexts/flowsContext";
import { StoreContext } from "../../contexts/storeContext";
import { getComponent, postLikeComponent } from "../../controllers/API";
import DeleteConfirmationModal from "../../modals/DeleteConfirmationModal";
import { storeComponent } from "../../types/store";
import cloneFLowWithParent from "../../utils/storeUtils";
import { cn } from "../../utils/utils";
@ -166,13 +167,17 @@ export default function CollectionCardComponent({
</div>
)}
{onDelete && (
<button onClick={onDelete}>
{onDelete && !data.metadata && (
<DeleteConfirmationModal
onConfirm={() => {
onDelete();
}}
>
<IconComponent
name="Trash2"
className="h-5 w-5 text-primary opacity-0 transition-all hover:text-destructive group-hover:opacity-100"
/>
</button>
</DeleteConfirmationModal>
)}
</CardTitle>
</div>
@ -207,8 +212,40 @@ export default function CollectionCardComponent({
</div>
{data.liked_by_count != undefined && (
<div className="flex gap-0.5">
{onDelete && data.metadata ? (
<ShadTooltip
content={authorized ? "Like" : "Please review your API key."}
content={
authorized ? "Delete" : "Please review your API key."
}
>
<DeleteConfirmationModal
onConfirm={() => {
onDelete();
}}
>
<Button
variant="ghost"
size="xs"
className={
"whitespace-nowrap" +
(!authorized ? " cursor-not-allowed" : "")
}
>
<IconComponent
name="Trash2"
className={cn(
"h-5 w-5",
!authorized ? " text-ring" : ""
)}
/>
</Button>
</DeleteConfirmationModal>
</ShadTooltip>
) : (
<ShadTooltip
content={
authorized ? "Like" : "Please review your API key."
}
>
<Button
disabled={loadingLike}
@ -237,6 +274,7 @@ export default function CollectionCardComponent({
/>
</Button>
</ShadTooltip>
)}
<ShadTooltip
content={
authorized

View file

@ -0,0 +1,26 @@
import Header from "../headerComponent";
import { Separator } from "../ui/separator";
export default function PageLayout({
title,
description,
children,
}: {
title: string;
description: string;
children: React.ReactNode;
}) {
return (
<div className="flex h-screen w-full flex-col">
<Header />
<div className="flex h-full w-full flex-col justify-between overflow-auto bg-background px-16">
<div className="flex w-full flex-col justify-between space-y-0.5 py-8 pb-2">
<h2 className="text-2xl font-bold tracking-tight">{title}</h2>
<p className="text-muted-foreground">{description}</p>
</div>
<Separator className="my-6 flex" />
{children}
</div>
</div>
);
}

View file

@ -0,0 +1,56 @@
import { DialogClose } from "@radix-ui/react-dialog";
import { Trash2 } from "lucide-react";
import { Button } from "../../components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
export default function DeleteConfirmationModal({
children,
onConfirm,
description,
}: {
children: JSX.Element;
onConfirm: () => void;
description?: string;
}) {
return (
<Dialog>
<DialogTrigger>{children}</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>
<div className="flex">
Delete <Trash2 className="ml-3 h-4 w-4" strokeWidth={1.5} />
</div>
</DialogTitle>
<DialogDescription>
Are you sure you want to delete this {description ?? "component"}?
<br></br>
This action cannot be undone.
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose>
<Button className="mr-3">Cancel</Button>
<Button
type="submit"
onClick={() => {
onConfirm();
}}
>
Delete
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

View file

@ -4,10 +4,9 @@ import PaginatorComponent from "../../components/PaginatorComponent";
import ShadTooltip from "../../components/ShadTooltipComponent";
import CollectionCardComponent from "../../components/cardComponent";
import IconComponent from "../../components/genericIconComponent";
import Header from "../../components/headerComponent";
import PageLayout from "../../components/pageLayout";
import { SkeletonCardComponent } from "../../components/skeletonCardComponent";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import { Input } from "../../components/ui/input";
import {
Select,
@ -21,7 +20,6 @@ import { alertContext } from "../../contexts/alertContext";
import { AuthContext } from "../../contexts/authContext";
import { StoreContext } from "../../contexts/storeContext";
import { getStoreComponents, getStoreTags } from "../../controllers/API";
import StoreApiKeyModal from "../../modals/StoreApiKeyModal";
import { storeComponent } from "../../types/store";
import { cn } from "../../utils/utils";
export default function StorePage(): JSX.Element {
@ -197,18 +195,10 @@ export default function StorePage(): JSX.Element {
};
return (
<>
<Header />
<div className="flex h-full w-full flex-col justify-between overflow-auto bg-background px-16">
<div>
<div className="flex w-full justify-between py-8 pb-2">
<span className="flex items-center justify-center gap-2 text-2xl font-semibold">
<IconComponent name="Store" className="w-6" />
Langflow Store
</span>
<div className="flex gap-2">
{StoreApiKeyModal && (
<PageLayout
title="Langflow Store"
description="Search flows and components from the community."
/* button={{StoreApiKeyModal && (
<StoreApiKeyModal disabled={loading}>
<Button
disabled={loading}
@ -222,12 +212,9 @@ export default function StorePage(): JSX.Element {
API Key
</Button>
</StoreApiKeyModal>
)}
</div>
</div>
<span className="flex w-[70%] pb-8 text-muted-foreground">
Search flows and components from the community.
</span>
)}} */
>
<div className="flex h-full w-full flex-col justify-between">
<div className="flex w-full flex-col gap-4 p-0">
<div className="flex items-end gap-4">
<div className="relative h-12 w-[40%]">
@ -254,9 +241,7 @@ export default function StorePage(): JSX.Element {
>
<IconComponent
name={loading ? "Loader2" : "Search"}
className={
loading ? " animate-spin cursor-not-allowed" : ""
}
className={loading ? " animate-spin cursor-not-allowed" : ""}
/>
</button>
</div>
@ -365,8 +350,7 @@ export default function StorePage(): JSX.Element {
<span className="px-0.5 text-sm text-muted-foreground">
{(!loading || searchData.length !== 0) && (
<>
{totalRowsCount}{" "}
{totalRowsCount !== 1 ? "results" : "result"}
{totalRowsCount} {totalRowsCount !== 1 ? "results" : "result"}
</>
)}
</span>
@ -425,9 +409,8 @@ export default function StorePage(): JSX.Element {
</div>
)}
</div>
</div>
{!loading && searchData.length > 0 && (
<div className="relative my-6">
<div className="relative py-6">
<PaginatorComponent
storeComponent={true}
pageIndex={pageIndex}
@ -441,6 +424,6 @@ export default function StorePage(): JSX.Element {
</div>
)}
</div>
</>
</PageLayout>
);
}