refactor: improve store and collection card components (#3350)

* refactor: add card store component

* refactor: use StoreCardComponent for displaying store cards

* refactor: Remove unused code

* refactor: Update Collection card to fit only to the my collection case

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
anovazzi1 2024-08-14 19:02:46 -03:00 committed by GitHub
commit 981f314a73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 399 additions and 454 deletions

View file

@ -1,9 +1,10 @@
import { FlowType } from "@/types/flow";
import { storeComponent } from "../../../../types/store";
import { cn } from "../../../../utils/utils";
import ForwardedIconComponent from "../../../genericIconComponent";
import { Card, CardHeader, CardTitle } from "../../../ui/card";
export default function DragCardComponent({ data }: { data: storeComponent }) {
export default function DragCardComponent({ data }: { data: FlowType }) {
return (
<>
<Card

View file

@ -1,10 +1,11 @@
import { FlowType } from "@/types/flow";
import { useCallback } from "react";
import { createRoot } from "react-dom/client";
import useFlowsManagerStore from "../../../stores/flowsManagerStore";
import { storeComponent } from "../../../types/store";
import DragCardComponent from "../components/dragCardComponent";
const useDragStart = (data: storeComponent) => {
const useDragStart = (data: FlowType) => {
const getFlowById = useFlowsManagerStore((state) => state.getFlowById);
const onDragStart = useCallback(

View file

@ -1,17 +1,10 @@
import { usePostLikeComponent } from "@/controllers/API/queries/store";
import { useState } from "react";
import { Control } from "react-hook-form";
import { getComponent } from "../../controllers/API";
import IOModal from "../../modals/IOModal";
import DeleteConfirmationModal from "../../modals/deleteConfirmationModal";
import useAlertStore from "../../stores/alertStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { useStoreStore } from "../../stores/storeStore";
import { FlowType } from "../../types/flow";
import { storeComponent } from "../../types/store";
import cloneFLowWithParent, {
getInputsAndOutputs,
} from "../../utils/storeUtils";
import { getInputsAndOutputs } from "../../utils/storeUtils";
import { cn } from "../../utils/utils";
import IconComponent from "../genericIconComponent";
import ShadTooltip from "../shadTooltipComponent";
@ -26,57 +19,28 @@ import {
import { Checkbox } from "../ui/checkbox";
import { FormControl, FormField } from "../ui/form";
import Loading from "../ui/loading";
import useDataEffect from "./hooks/use-data-effect";
import useInstallComponent from "./hooks/use-handle-install";
import useDragStart from "./hooks/use-on-drag-start";
import { convertTestName } from "./utils/convert-test-name";
export default function CollectionCardComponent({
data,
authorized = true,
disabled = false,
button,
onClick,
onDelete,
playground,
control,
}: {
data: storeComponent;
authorized?: boolean;
data: FlowType;
disabled?: boolean;
onClick?: () => void;
button?: JSX.Element;
playground?: boolean;
onDelete?: () => void;
control?: Control<any, any>;
}) {
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const setValidApiKey = useStoreStore((state) => state.updateValidApiKey);
const isStore = false;
const [loading, setLoading] = useState(false);
const [likedByUser, setLikedByUser] = useState(data?.liked_by_user ?? false);
const [likesCount, setLikesCount] = useState(data?.liked_by_count ?? 0);
const [downloadsCount, setDownloadsCount] = useState(
data?.downloads_count ?? 0,
);
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);
const getFlowById = useFlowsManagerStore((state) => state.getFlowById);
const [openPlayground, setOpenPlayground] = useState(false);
const [loadingPlayground, setLoadingPlayground] = useState(false);
const selectedFlowsComponentsCards = useFlowsManagerStore(
(state) => state.selectedFlowsComponentsCards,
);
const name = data.is_component ? "Component" : "Flow";
async function getFlowData() {
const res = await getComponent(data.id);
const newFlow = cloneFLowWithParent(res, res.id, data.is_component, true);
return newFlow;
}
function hasPlayground(flow?: FlowType) {
if (!flow) {
return false;
@ -84,52 +48,7 @@ export default function CollectionCardComponent({
const { inputs, outputs } = getInputsAndOutputs(flow?.data?.nodes ?? []);
return inputs.length > 0 || outputs.length > 0;
}
useDataEffect(data, setLikedByUser, setLikesCount, setDownloadsCount);
const { handleInstall } = useInstallComponent(
data,
name,
isStore,
downloadsCount,
setDownloadsCount,
setLoading,
setSuccessData,
setErrorData,
);
const { mutate, isPending } = usePostLikeComponent();
const handleLikeWMutate = () => {
if (likedByUser !== undefined || likedByUser !== null) {
const temp = likedByUser;
const tempNum = likesCount;
setLikedByUser((prev) => !prev);
setLikesCount((prev) => (temp ? prev - 1 : prev + 1));
mutate(
{ componentId: data.id },
{
onSuccess: (res) => {
setLikesCount(res.data.likes_count);
setLikedByUser(res.data.liked_by_user);
},
onError: (error) => {
setLikesCount(tempNum);
setLikedByUser(temp);
if (error.response.status === 403) {
return setValidApiKey(false);
}
console.error(error);
setErrorData({
title: `Error liking ${name}.`,
list: [error.response.data.detail],
});
},
},
);
}
};
const playground = !(data.is_component ?? false);
const isSelectedCard =
selectedFlowsComponentsCards?.includes(data?.id) ?? false;
@ -165,51 +84,9 @@ export default function CollectionCardComponent({
)}
name={data.is_component ? "ToyBrick" : "Group"}
/>
<ShadTooltip content={data.name}>
<div className="w-full truncate pr-3">{data.name}</div>
</ShadTooltip>
{data?.metadata !== undefined && (
<div className="flex items-center gap-3">
{data.private && (
<ShadTooltip content="Private">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent name="Lock" className="h-4 w-4" />
</span>
</ShadTooltip>
)}
{!data.is_component && (
<ShadTooltip content="Components">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent name="ToyBrick" className="h-4 w-4" />
<span data-testid={`total-${data.name}`}>
{data?.metadata?.total ?? 0}
</span>
</span>
</ShadTooltip>
)}
<ShadTooltip content="Likes">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent name="Heart" className={cn("h-4 w-4")} />
<span data-testid={`likes-${data.name}`}>
{likesCount ?? 0}
</span>
</span>
</ShadTooltip>
<ShadTooltip content="Downloads">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent
name="DownloadCloud"
className="h-4 w-4"
/>
<span data-testid={`downloads-${data.name}`}>
{downloadsCount ?? 0}
</span>
</span>
</ShadTooltip>
</div>
)}
{control && (
<div
className="flex"
@ -238,200 +115,19 @@ export default function CollectionCardComponent({
</CardTitle>
</div>
<div className="flex gap-2">
{data.user_created && data.user_created.username && (
<span className="text-sm text-primary">
by <b>{data.user_created.username}</b>
{data.last_tested_version && (
<>
{" "}
|{" "}
<span className="text-xs">
{" "}
v{data.last_tested_version}
</span>
</>
)}
</span>
)}
<div className="flex w-full flex-1 flex-wrap gap-2"></div>
</div>
<CardDescription className="pb-2 pt-2">
<div
className={
data?.metadata !== undefined
? "truncate"
: "truncate-doubleline"
}
>
{data.description}
</div>
<div className="truncate-doubleline">{data.description}</div>
</CardDescription>
</CardHeader>
</div>
<CardFooter>
<div className="z-50 flex w-full items-center justify-between gap-2">
<div className="flex w-full flex-wrap items-end justify-end gap-2">
{playground && data?.metadata !== undefined ? (
{playground && (
<Button
disabled={loadingPlayground || !authorized}
key={data.id}
tabIndex={-1}
variant="outline"
size="sm"
className="z-50 gap-2 whitespace-nowrap"
data-testid={"playground-flow-button-" + data.id}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setLoadingPlayground(true);
const flow = getFlowById(data.id);
if (flow) {
if (!hasPlayground(flow)) {
setErrorData({
title: "Error",
list: ["This flow doesn't have a playground."],
});
setLoadingPlayground(false);
return;
}
setCurrentFlow(flow);
setOpenPlayground(true);
setLoadingPlayground(false);
} else {
getFlowData().then((res) => {
if (!hasPlayground(res)) {
setErrorData({
title: "Error",
list: ["This flow doesn't have a playground."],
});
setLoadingPlayground(false);
return;
}
setCurrentFlow(res);
setOpenPlayground(true);
setLoadingPlayground(false);
});
}
}}
>
{!loadingPlayground ? (
<IconComponent
name="BotMessageSquareIcon"
className="h-4 w-4 select-none"
/>
) : (
<Loading className="h-4 w-4 text-medium-indigo" />
)}
Playground
</Button>
) : undefined}
{data.liked_by_count != undefined && (
<div className="flex gap-0.5">
{onDelete && data?.metadata !== undefined ? (
<ShadTooltip
content={
authorized ? "Delete" : "Please review your API key."
}
>
<DeleteConfirmationModal onConfirm={onDelete}>
<Button
variant="ghost"
size="icon"
className={
"whitespace-nowrap" +
(!authorized ? " cursor-not-allowed" : "")
}
>
<IconComponent
data-testid={`delete-${convertTestName(data.name)}`}
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={isPending}
variant="ghost"
size="icon"
className={
"whitespace-nowrap" +
(!authorized ? " cursor-not-allowed" : "")
}
onClick={() => {
if (!authorized) {
return;
}
handleLikeWMutate();
}}
data-testid={`like-${data.name}`}
>
<IconComponent
name="Heart"
className={cn(
"h-5 w-5",
likedByUser
? "fill-destructive stroke-destructive"
: "",
!authorized ? "text-ring" : "",
)}
/>
</Button>
</ShadTooltip>
)}
<ShadTooltip
content={
authorized
? isStore
? "Download"
: "Install Locally"
: "Please review your API key."
}
>
<Button
disabled={loading}
variant="ghost"
size="icon"
className={
"whitespace-nowrap" +
(!authorized ? " cursor-not-allowed" : "") +
(!loading ? " p-0.5" : "")
}
onClick={() => {
if (loading || !authorized) {
return;
}
handleInstall();
}}
data-testid={`install-${data.name}`}
>
<IconComponent
name={
loading ? "Loader2" : isStore ? "Download" : "Plus"
}
className={cn(
loading ? "h-5 w-5 animate-spin" : "h-5 w-5",
!authorized ? "text-ring" : "",
)}
/>
</Button>
</ShadTooltip>
</div>
)}
{playground && data?.metadata === undefined && (
<Button
disabled={loadingPlayground || !authorized}
disabled={loadingPlayground || !hasPlayground(data)}
key={data.id}
tabIndex={-1}
variant="primary"
@ -456,18 +152,9 @@ export default function CollectionCardComponent({
setOpenPlayground(true);
setLoadingPlayground(false);
} else {
getFlowData().then((res) => {
if (!hasPlayground(res)) {
setErrorData({
title: "Error",
list: ["This flow doesn't have a playground."],
});
setLoadingPlayground(false);
return;
}
setCurrentFlow(res);
setOpenPlayground(true);
setLoadingPlayground(false);
setErrorData({
title: "Error",
list: ["Error getting flow data."],
});
}
}}

View file

@ -1,100 +0,0 @@
import useAddFlow from "@/hooks/flows/use-add-flow";
import emojiRegex from "emoji-regex";
import { useNavigate } from "react-router-dom";
import { FlowType } from "../../types/flow";
import { updateIds } from "../../utils/reactflowUtils";
import { cn } from "../../utils/utils";
import IconComponent from "../genericIconComponent";
import ShadTooltip from "../shadTooltipComponent";
import { Button } from "../ui/button";
import {
Card,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "../ui/card";
export default function CollectionCardComponent({
flow,
}: {
flow: FlowType;
authorized?: boolean;
}) {
const addFlow = useAddFlow();
const navigate = useNavigate();
const isEmoji = (str: string) => emojiRegex().test(str);
return (
<Card
className={cn(
"group relative flex h-48 w-2/6 flex-col justify-between overflow-hidden transition-all hover:shadow-md",
)}
>
<div>
<CardHeader>
<div>
<CardTitle className="flex w-full items-center justify-between gap-3 text-xl">
{flow.icon && isEmoji(flow.icon) && (
<div
className="flex items-center justify-center rounded-md p-2 align-middle"
style={{ backgroundColor: flow.icon_bg_color }}
>
<div className="h-7 w-7 pl-0.5">{flow.icon}</div>
</div>
)}
{(!flow.icon || !isEmoji(flow.icon)) && (
<div
className="flex items-center justify-center rounded-md p-2 align-middle"
style={{ backgroundColor: flow.icon_bg_color }}
>
<IconComponent
className={cn("h-7 w-7 flex-shrink-0 text-flow-icon")}
name={flow.icon || "Group"}
/>
</div>
)}
<ShadTooltip content={flow.name}>
<div className="w-full truncate">{flow.name}</div>
</ShadTooltip>
</CardTitle>
</div>
<CardDescription className="pb-2 pt-2">
<ShadTooltip
side="bottom"
styleClasses="z-50"
content={flow.description}
>
<div className="truncate-doubleline">{flow.description}</div>
</ShadTooltip>
</CardDescription>
</CardHeader>
</div>
<CardFooter>
<div className="flex w-full items-center justify-between gap-2">
<div className="flex w-full flex-wrap justify-end gap-2">
<Button
onClick={() => {
updateIds(flow.data!);
addFlow({ flow }).then((id) => {
navigate("/flow/" + id);
});
}}
tabIndex={-1}
variant="outline"
size="sm"
className="whitespace-nowrap"
>
<IconComponent
name="ExternalLink"
className="main-page-nav-button select-none"
/>
Select Flow
</Button>
</div>
</div>
</CardFooter>
</Card>
);
}

View file

@ -0,0 +1,53 @@
import useAddFlow from "@/hooks/flows/use-add-flow";
import { getComponent } from "../../../controllers/API";
import { storeComponent } from "../../../types/store";
import cloneFlowWithParent from "../../../utils/storeUtils";
const useInstallComponent = (
data: storeComponent,
name: string,
downloadsCount: number,
setDownloadsCount: (value: any) => void,
setLoading: (value: boolean) => void,
setSuccessData: (value: { title: string }) => void,
setErrorData: (value: { title: string; list: string[] }) => void,
) => {
const addFlow = useAddFlow();
const handleInstall = () => {
const temp = downloadsCount;
setDownloadsCount((old) => Number(old) + 1);
setLoading(true);
getComponent(data.id)
.then((res) => {
const newFlow = cloneFlowWithParent(res, res.id, data.is_component);
addFlow({ flow: newFlow })
.then((id) => {
setSuccessData({
title: `${name} Installed Successfully.`,
});
setLoading(false);
})
.catch((error) => {
setLoading(false);
setErrorData({
title: `Error installing the ${name}`,
list: [error.response.data.detail],
});
});
})
.catch((err) => {
setLoading(false);
setErrorData({
title: `Error installing the ${name}`,
list: [err.response.data.detail],
});
setDownloadsCount(temp);
});
};
return { handleInstall };
};
export default useInstallComponent;

View file

@ -0,0 +1,328 @@
import { usePostLikeComponent } from "@/controllers/API/queries/store";
import { useState } from "react";
import { getComponent } from "../../controllers/API";
import IOModal from "../../modals/IOModal";
import useAlertStore from "../../stores/alertStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { useStoreStore } from "../../stores/storeStore";
import { FlowType } from "../../types/flow";
import { storeComponent } from "../../types/store";
import cloneFLowWithParent, {
getInputsAndOutputs,
} from "../../utils/storeUtils";
import { cn } from "../../utils/utils";
import IconComponent from "../genericIconComponent";
import ShadTooltip from "../shadTooltipComponent";
import { Button } from "../ui/button";
import {
Card,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "../ui/card";
import Loading from "../ui/loading";
import useDataEffect from "./hooks/use-data-effect";
import useInstallComponent from "./hooks/use-handle-install";
import { convertTestName } from "./utils/convert-test-name";
export default function StoreCardComponent({
data,
authorized = true,
disabled = false,
}: {
data: storeComponent;
authorized?: boolean;
disabled?: boolean;
}) {
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const setValidApiKey = useStoreStore((state) => state.updateValidApiKey);
const [loading, setLoading] = useState(false);
const [likedByUser, setLikedByUser] = useState(data?.liked_by_user ?? false);
const [likesCount, setLikesCount] = useState(data?.liked_by_count ?? 0);
const [downloadsCount, setDownloadsCount] = useState(
data?.downloads_count ?? 0,
);
const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow);
const [openPlayground, setOpenPlayground] = useState(false);
const [loadingPlayground, setLoadingPlayground] = useState(false);
const playground =
data.last_tested_version?.includes("1.0.0") && !data.is_component;
const name = data.is_component ? "Component" : "Flow";
async function getFlowData() {
const res = await getComponent(data.id);
const newFlow = cloneFLowWithParent(res, res.id, data.is_component, true);
return newFlow;
}
function hasPlayground(flow?: FlowType) {
if (!flow) {
return false;
}
const { inputs, outputs } = getInputsAndOutputs(flow?.data?.nodes ?? []);
return inputs.length > 0 || outputs.length > 0;
}
useDataEffect(data, setLikedByUser, setLikesCount, setDownloadsCount);
const { handleInstall } = useInstallComponent(
data,
name,
downloadsCount,
setDownloadsCount,
setLoading,
setSuccessData,
setErrorData,
);
const { mutate, isPending } = usePostLikeComponent();
const handleLikeWMutate = () => {
if (likedByUser !== undefined || likedByUser !== null) {
const temp = likedByUser;
const tempNum = likesCount;
setLikedByUser((prev) => !prev);
setLikesCount((prev) => (temp ? prev - 1 : prev + 1));
mutate(
{ componentId: data.id },
{
onSuccess: (res) => {
setLikesCount(res.data.likes_count);
setLikedByUser(res.data.liked_by_user);
},
onError: (error) => {
setLikesCount(tempNum);
setLikedByUser(temp);
if (error.response.status === 403) {
return setValidApiKey(false);
}
console.error(error);
setErrorData({
title: `Error liking ${name}.`,
list: [error.response.data.detail],
});
},
},
);
}
};
return (
<>
<Card
data-testid={`card-${convertTestName(data.name)}`}
//TODO check color schema
className={cn(
"group relative flex h-[11rem] flex-col justify-between overflow-hidden",
!data.is_component &&
"hover:bg-muted/50 hover:shadow-md hover:dark:bg-[#5f5f5f0e]",
disabled ? "pointer-events-none opacity-50" : "",
)}
>
<div>
<CardHeader>
<div>
<CardTitle className="flex w-full items-start justify-between gap-3 text-xl">
<IconComponent
className={cn(
"visible flex-shrink-0",
data.is_component
? "mx-0.5 h-6 w-6 text-component-icon"
: "h-7 w-7 flex-shrink-0 text-flow-icon",
)}
name={data.is_component ? "ToyBrick" : "Group"}
/>
<ShadTooltip content={data.name}>
<div className="w-full truncate pr-3">{data.name}</div>
</ShadTooltip>
<div className="flex items-center gap-3">
{data.private && (
<ShadTooltip content="Private">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent name="Lock" className="h-4 w-4" />
</span>
</ShadTooltip>
)}
{!data.is_component && (
<ShadTooltip content="Components">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent name="ToyBrick" className="h-4 w-4" />
<span data-testid={`total-${data.name}`}>
{data?.metadata?.total ?? 0}
</span>
</span>
</ShadTooltip>
)}
<ShadTooltip content="Likes">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent name="Heart" className={cn("h-4 w-4")} />
<span data-testid={`likes-${data.name}`}>
{likesCount ?? 0}
</span>
</span>
</ShadTooltip>
<ShadTooltip content="Downloads">
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
<IconComponent name="DownloadCloud" className="h-4 w-4" />
<span data-testid={`downloads-${data.name}`}>
{downloadsCount ?? 0}
</span>
</span>
</ShadTooltip>
</div>
</CardTitle>
</div>
<div className="flex gap-2">
{data.user_created && data.user_created.username && (
<span className="text-sm text-primary">
by <b>{data.user_created.username}</b>
{data.last_tested_version && (
<>
{" "}
|{" "}
<span className="text-xs">
{" "}
v{data.last_tested_version}
</span>
</>
)}
</span>
)}
<div className="flex w-full flex-1 flex-wrap gap-2"></div>
</div>
<CardDescription className="pb-2 pt-2">
<div className="truncate-doubleline">{data.description}</div>
</CardDescription>
</CardHeader>
</div>
<CardFooter>
<div className="z-50 flex w-full items-center justify-between gap-2">
<div className="flex w-full flex-wrap items-end justify-end gap-2">
{playground && (
<Button
disabled={loadingPlayground || !authorized}
key={data.id}
tabIndex={-1}
variant="outline"
size="sm"
className="z-50 gap-2 whitespace-nowrap"
data-testid={"playground-flow-button-" + data.id}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
setLoadingPlayground(true);
getFlowData().then((res) => {
if (!hasPlayground(res)) {
setErrorData({
title: "Error",
list: ["This flow doesn't have a playground."],
});
setLoadingPlayground(false);
return;
}
setCurrentFlow(res);
setOpenPlayground(true);
setLoadingPlayground(false);
});
}}
>
{!loadingPlayground ? (
<IconComponent
name="BotMessageSquareIcon"
className="h-4 w-4 select-none"
/>
) : (
<Loading className="h-4 w-4 text-medium-indigo" />
)}
Playground
</Button>
)}
<div className="flex gap-0.5">
<ShadTooltip
content={authorized ? "Like" : "Please review your API key."}
>
<Button
disabled={isPending}
variant="ghost"
size="icon"
className={
"whitespace-nowrap" +
(!authorized ? " cursor-not-allowed" : "")
}
onClick={() => {
if (!authorized) {
return;
}
handleLikeWMutate();
}}
data-testid={`like-${data.name}`}
>
<IconComponent
name="Heart"
className={cn(
"h-5 w-5",
likedByUser
? "fill-destructive stroke-destructive"
: "",
!authorized ? "text-ring" : "",
)}
/>
</Button>
</ShadTooltip>
<ShadTooltip
content={
authorized
? "Install Locally"
: "Please review your API key."
}
>
<Button
disabled={loading}
variant="ghost"
size="icon"
className={
"whitespace-nowrap" +
(!authorized ? " cursor-not-allowed" : "") +
(!loading ? " p-0.5" : "")
}
onClick={() => {
if (loading || !authorized) {
return;
}
handleInstall();
}}
data-testid={`install-${data.name}`}
>
<IconComponent
name={loading ? "Loader2" : "Plus"}
className={cn(
loading ? "h-5 w-5 animate-spin" : "h-5 w-5",
!authorized ? "text-ring" : "",
)}
/>
</Button>
</ShadTooltip>
</div>
</div>
</div>
</CardFooter>
</Card>
{openPlayground && (
<IOModal
key={data.id}
cleanOnClose={true}
open={openPlayground}
setOpen={setOpenPlayground}
>
<></>
</IOModal>
)}
</>
);
}

View file

@ -0,0 +1,3 @@
export function convertTestName(name: string): string {
return name.replace(/ /g, "-").toLowerCase();
}

View file

@ -17,29 +17,6 @@ const CollectionCard = ({ item, type, isLoading, control }) => {
}
};
const renderButton = () => {
if (!isComponent) {
return (
<Link to={editFlowLink}>
<Button
tabIndex={-1}
variant="outline"
size="sm"
className="whitespace-nowrap"
data-testid={editFlowButtonTestId}
>
<IconComponent
name="ExternalLink"
className="main-page-nav-button select-none"
/>
Edit Flow
</Button>
</Link>
);
}
return null;
};
return (
<CollectionCardComponent
data={{
@ -48,9 +25,7 @@ const CollectionCard = ({ item, type, isLoading, control }) => {
}}
disabled={isLoading}
data-testid={editFlowButtonTestId}
button={renderButton()!}
onClick={!isComponent ? handleClick : undefined}
playground={!isComponent}
control={control}
/>
);

View file

@ -7,6 +7,7 @@ import ShadTooltip from "../../components/shadTooltipComponent";
import { SkeletonCardComponent } from "../../components/skeletonCardComponent";
import { Button } from "../../components/ui/button";
import StoreCardComponent from "@/components/storeCardComponent";
import { useGetTagsQuery } from "@/controllers/API/queries/store";
import { Link, useNavigate, useParams } from "react-router-dom";
import PaginatorComponent from "../../components/paginatorComponent";
@ -326,15 +327,11 @@ export default function StorePage(): JSX.Element {
searchData.map((item) => {
return (
<>
<CollectionCardComponent
<StoreCardComponent
key={item.id}
data={item}
authorized={validApiKey}
disabled={loading}
playground={
item.last_tested_version?.includes("1.0.0") &&
!item.is_component
}
/>
</>
);