Fixed errors on code and made MarketCard default
This commit is contained in:
parent
dff58ee29e
commit
f7903043fe
10 changed files with 308 additions and 368 deletions
|
|
@ -1,6 +1,17 @@
|
|||
import { cardComponentPropsType } from "../../types/components";
|
||||
import { useContext, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { FlowsContext } from "../../contexts/flowsContext";
|
||||
import { StoreContext } from "../../contexts/storeContext";
|
||||
import { getComponent, postLikeComponent } from "../../controllers/API";
|
||||
import { storeComponent } from "../../types/store";
|
||||
import cloneFLowWithParent from "../../utils/storeUtils";
|
||||
import { gradients } from "../../utils/styleUtils";
|
||||
import { classNames } from "../../utils/utils";
|
||||
import ShadTooltip from "../ShadTooltipComponent";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
import { Badge } from "../ui/badge";
|
||||
import { Button } from "../ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardDescription,
|
||||
|
|
@ -9,47 +20,288 @@ import {
|
|||
CardTitle,
|
||||
} from "../ui/card";
|
||||
|
||||
export const CardComponent = ({
|
||||
export default function CollectionCardComponent({
|
||||
data,
|
||||
onDelete,
|
||||
authorized = true,
|
||||
disabled = false,
|
||||
button,
|
||||
}: cardComponentPropsType): JSX.Element => {
|
||||
return (
|
||||
<Card className="group">
|
||||
<CardHeader>
|
||||
<CardTitle className="card-component-title-display">
|
||||
<span
|
||||
className={
|
||||
"card-component-image " +
|
||||
gradients[parseInt(data.id.slice(0, 12), 16) % gradients.length]
|
||||
}
|
||||
></span>
|
||||
<span className="card-component-title-size">{data.name}</span>
|
||||
{onDelete && (
|
||||
<button className="card-component-delete-button" onClick={onDelete}>
|
||||
<IconComponent
|
||||
name="Trash2"
|
||||
className="card-component-delete-icon"
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
</CardTitle>
|
||||
<CardDescription className="card-component-desc">
|
||||
<div className="card-component-desc-text">
|
||||
{data.description}
|
||||
{/* {flow.description} */}
|
||||
</div>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
onDelete,
|
||||
}: {
|
||||
data: storeComponent;
|
||||
authorized?: boolean;
|
||||
disabled?: boolean;
|
||||
button?: JSX.Element;
|
||||
onDelete?: () => void;
|
||||
}) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { addFlow } = useContext(FlowsContext);
|
||||
const [loadingLike, setLoadingLike] = useState(false);
|
||||
const { setSuccessData, setErrorData } = useContext(alertContext);
|
||||
const { setValidApiKey } = useContext(StoreContext);
|
||||
const [liked_by_user, setLiked_by_user] = useState(data.liked_by_user);
|
||||
const [likes_count, setLikes_count] = useState(data.liked_by_count ?? 0);
|
||||
|
||||
{button && (
|
||||
<CardFooter>
|
||||
<div className="card-component-footer-arrangement">
|
||||
<div className="card-component-footer"></div>
|
||||
{button}
|
||||
</div>
|
||||
</CardFooter>
|
||||
const name = data.is_component ? "Component" : "Flow";
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
function handleInstall() {
|
||||
setLoading(true);
|
||||
getComponent(data.id).then((res) => {
|
||||
const newFlow = cloneFLowWithParent(res, res.id, data.is_component);
|
||||
addFlow(true, newFlow).then((id) => {
|
||||
setSuccessData({ title: `${name} Installed` });
|
||||
setLoading(false);
|
||||
if (!data.is_component) navigate("/flow/" + id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleLike() {
|
||||
setLoadingLike(true);
|
||||
if (liked_by_user !== undefined || liked_by_user !== null) {
|
||||
const temp = liked_by_user;
|
||||
const tempNum = likes_count;
|
||||
setLiked_by_user((prev) => !prev);
|
||||
if (!temp) {
|
||||
setLikes_count((prev) => prev + 1);
|
||||
} else {
|
||||
setLikes_count((prev) => prev - 1);
|
||||
}
|
||||
console.log(data.id);
|
||||
postLikeComponent(data.id)
|
||||
.then((response) => {
|
||||
setLoadingLike(false);
|
||||
setLikes_count(response.likes_count);
|
||||
setLiked_by_user(response.liked_by_user);
|
||||
})
|
||||
.catch((error) => {
|
||||
setLoadingLike(false);
|
||||
setLikes_count(tempNum);
|
||||
setLiked_by_user(temp);
|
||||
if (error.response.status === 403 || error.response.status === 401) {
|
||||
setValidApiKey(false);
|
||||
} else {
|
||||
console.error(error);
|
||||
setErrorData({
|
||||
title: `Error liking ${name}.`,
|
||||
list: [error["response"]["data"]["detail"]],
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const totalComponentsMetadata = () => {
|
||||
return data?.metadata ? data.metadata["total"] : 0;
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={classNames(
|
||||
"group relative flex flex-col justify-between overflow-hidden transition-all hover:shadow-md",
|
||||
disabled ? "pointer-events-none opacity-50" : ""
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<CardHeader>
|
||||
<div>
|
||||
<CardTitle className="flex w-full items-center justify-between gap-3 text-xl">
|
||||
<div
|
||||
className={classNames(
|
||||
"flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-primary",
|
||||
gradients[
|
||||
parseInt(data.id.slice(0, 12), 16) % gradients.length
|
||||
]
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
data.is_component ? "h-7 w-7 rounded-full bg-muted" : "",
|
||||
"flex items-center justify-center"
|
||||
)}
|
||||
>
|
||||
{data.is_component ? (
|
||||
<svg className="h-5 w-5" viewBox="0 0 24 24">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id={data.id}
|
||||
x1="0%"
|
||||
y1="0%"
|
||||
x2="100%"
|
||||
y2="100%"
|
||||
className={
|
||||
gradients[
|
||||
parseInt(data.id.slice(0, 12), 16) %
|
||||
gradients.length
|
||||
]
|
||||
}
|
||||
>
|
||||
<stop
|
||||
offset="0%"
|
||||
stopColor="var(--tw-gradient-from)"
|
||||
/>
|
||||
<stop
|
||||
offset="100%"
|
||||
stopColor="var(--tw-gradient-to)"
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<IconComponent
|
||||
className={classNames(
|
||||
"h-4 w-4",
|
||||
gradients[
|
||||
parseInt(data.id.slice(0, 12), 16) %
|
||||
gradients.length
|
||||
]
|
||||
)}
|
||||
stroke={`url(#${data.id})`}
|
||||
name="ToyBrick"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
<IconComponent
|
||||
className="h-4 w-4 text-background"
|
||||
name="Network"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ShadTooltip content={data.name}>
|
||||
<div className="w-full truncate">{data.name}</div>
|
||||
</ShadTooltip>
|
||||
{data?.metadata && (
|
||||
<div className="flex gap-3">
|
||||
{!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" />
|
||||
{totalComponentsMetadata()}
|
||||
</span>
|
||||
</ShadTooltip>
|
||||
)}
|
||||
<ShadTooltip content="Likes">
|
||||
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||
<IconComponent
|
||||
name="Heart"
|
||||
className={classNames("h-4 w-4 ")}
|
||||
/>
|
||||
{likes_count ?? 0}
|
||||
</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" />
|
||||
{data.downloads_count}
|
||||
</span>
|
||||
</ShadTooltip>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{onDelete && (
|
||||
<button onClick={onDelete}>
|
||||
<IconComponent
|
||||
name="Trash2"
|
||||
className="h-5 w-5 text-primary opacity-0 transition-all hover:text-destructive group-hover:opacity-100"
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
</CardTitle>
|
||||
</div>
|
||||
{data.user_created && data.user_created.username && (
|
||||
<span className="text-xs text-primary">
|
||||
by <b>{data.user_created.username}</b>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<CardDescription className="pb-2 pt-2">
|
||||
<div className="truncate-doubleline">{data.description}</div>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</div>
|
||||
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-center justify-between gap-2">
|
||||
<div className="flex w-full flex-wrap items-end justify-between gap-2">
|
||||
<div className="flex w-full flex-1 flex-wrap gap-2">
|
||||
{data.tags &&
|
||||
data.tags.length > 0 &&
|
||||
data.tags.map((tag, index) => (
|
||||
<Badge
|
||||
key={index}
|
||||
variant="outline"
|
||||
size="xq"
|
||||
className="text-muted-foreground"
|
||||
>
|
||||
{tag.name}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
{data.liked_by_count && (
|
||||
<div className="flex gap-0.5">
|
||||
<ShadTooltip
|
||||
content={authorized ? "Like" : "Please review your API key."}
|
||||
>
|
||||
<Button
|
||||
disabled={loadingLike || !authorized}
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
className={
|
||||
"whitespace-nowrap" +
|
||||
(!authorized ? " cursor-not-allowed" : "")
|
||||
}
|
||||
onClick={() => {
|
||||
handleLike();
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
name="Heart"
|
||||
className={classNames(
|
||||
"h-6 w-6 p-0.5",
|
||||
liked_by_user
|
||||
? "fill-destructive stroke-destructive"
|
||||
: "",
|
||||
!authorized ? " text-ring" : ""
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</ShadTooltip>
|
||||
<ShadTooltip
|
||||
content={
|
||||
authorized
|
||||
? "Install Locally"
|
||||
: "Please review your API key."
|
||||
}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
className={
|
||||
"whitespace-nowrap" +
|
||||
(!authorized ? " cursor-not-allowed" : "")
|
||||
}
|
||||
onClick={() => {
|
||||
if (loading || !authorized) {
|
||||
return;
|
||||
}
|
||||
handleInstall();
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
name={loading ? "Loader2" : "Plus"}
|
||||
className={classNames(
|
||||
loading ? "h-5 w-5 animate-spin" : "h-6 w-6 p-0.5",
|
||||
!authorized ? " text-ring" : ""
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</ShadTooltip>
|
||||
</div>
|
||||
)}
|
||||
{button && button}
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import {
|
|||
sourceHandleType,
|
||||
targetHandleType,
|
||||
} from "../types/flow";
|
||||
import { FlowsContextType, TabsState } from "../types/tabs";
|
||||
import { FlowsContextType, FlowsState } from "../types/tabs";
|
||||
import {
|
||||
addVersionToDuplicates,
|
||||
checkOldEdgesHandles,
|
||||
|
|
@ -73,7 +73,7 @@ const FlowsContextInitialValue: FlowsContextType = {
|
|||
lastCopiedSelection: null,
|
||||
setLastCopiedSelection: (selection: any) => {},
|
||||
tabsState: {},
|
||||
setTabsState: (state: TabsState) => {},
|
||||
setTabsState: (state: FlowsState) => {},
|
||||
getNodeId: (nodeType: string) => "",
|
||||
setTweak: (tweak: any) => {},
|
||||
getTweak: [],
|
||||
|
|
@ -107,7 +107,7 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
|||
nodes: any;
|
||||
edges: any;
|
||||
} | null>(null);
|
||||
const [tabsState, setTabsState] = useState<TabsState>({});
|
||||
const [tabsState, setTabsState] = useState<FlowsState>({});
|
||||
const [getTweak, setTweak] = useState<tweakType>([]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -698,7 +698,7 @@ export function FlowsProvider({ children }: { children: ReactNode }) {
|
|||
` (${increment})`;
|
||||
}
|
||||
}
|
||||
return addFlow(true, createFlowComponent(component));
|
||||
return addFlow(true, createFlowComponent(component, version));
|
||||
}
|
||||
|
||||
function deleteComponent(id: string, key: string) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useContext } from "react";
|
||||
import { CardComponent } from "../../../../components/cardComponent";
|
||||
import CollectionCardComponent from "../../../../components/cardComponent";
|
||||
import CardsWrapComponent from "../../../../components/cardsWrapComponent";
|
||||
import { alertContext } from "../../../../contexts/alertContext";
|
||||
import { FlowsContext } from "../../../../contexts/flowsContext";
|
||||
|
|
@ -31,7 +31,7 @@ export default function ComponentsComponent() {
|
|||
{flows
|
||||
.filter((flow) => flow.is_component)
|
||||
.map((flow, idx) => (
|
||||
<CardComponent
|
||||
<CollectionCardComponent
|
||||
key={idx}
|
||||
data={flow}
|
||||
onDelete={() => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useContext } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { CardComponent } from "../../../../components/cardComponent";
|
||||
import CollectionCardComponent from "../../../../components/cardComponent";
|
||||
import CardsWrapComponent from "../../../../components/cardsWrapComponent";
|
||||
import IconComponent from "../../../../components/genericIconComponent";
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
|
|
@ -34,7 +34,7 @@ export default function FlowsComponent() {
|
|||
.filter((flow) => !flow.is_component)
|
||||
.reverse()
|
||||
.map((flow, idx) => (
|
||||
<CardComponent
|
||||
<CollectionCardComponent
|
||||
key={idx}
|
||||
data={flow}
|
||||
button={
|
||||
|
|
|
|||
|
|
@ -1,286 +0,0 @@
|
|||
import { useContext, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import ShadTooltip from "../../../components/ShadTooltipComponent";
|
||||
import IconComponent from "../../../components/genericIconComponent";
|
||||
import { Badge } from "../../../components/ui/badge";
|
||||
import { Button } from "../../../components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "../../../components/ui/card";
|
||||
import { alertContext } from "../../../contexts/alertContext";
|
||||
import { FlowsContext } from "../../../contexts/flowsContext";
|
||||
import { StoreContext } from "../../../contexts/storeContext";
|
||||
import { getComponent, postLikeComponent } from "../../../controllers/API";
|
||||
import { storeComponent } from "../../../types/store";
|
||||
import cloneFLowWithParent from "../../../utils/storeUtils";
|
||||
import { gradients } from "../../../utils/styleUtils";
|
||||
import { classNames } from "../../../utils/utils";
|
||||
|
||||
export const MarketCardComponent = ({
|
||||
data,
|
||||
authorized = true,
|
||||
disabled = false,
|
||||
}: {
|
||||
data: storeComponent;
|
||||
authorized?: boolean;
|
||||
disabled?: boolean;
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { addFlow } = useContext(FlowsContext);
|
||||
const [loadingLike, setLoadingLike] = useState(false);
|
||||
const { setSuccessData, setErrorData } = useContext(alertContext);
|
||||
const { setValidApiKey } = useContext(StoreContext);
|
||||
const [liked_by_user, setLiked_by_user] = useState(data.liked_by_user);
|
||||
const [likes_count, setLikes_count] = useState(data.liked_by_count ?? 0);
|
||||
|
||||
const name = data.is_component ? "Component" : "Flow";
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
function handleInstall() {
|
||||
setLoading(true);
|
||||
getComponent(data.id).then((res) => {
|
||||
const newFlow = cloneFLowWithParent(res, res.id, data.is_component);
|
||||
addFlow(true, newFlow).then((id) => {
|
||||
setSuccessData({ title: `${name} Installed` });
|
||||
setLoading(false);
|
||||
if (!data.is_component) navigate("/flow/" + id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleLike() {
|
||||
setLoadingLike(true);
|
||||
if (liked_by_user !== undefined || liked_by_user !== null) {
|
||||
const temp = liked_by_user;
|
||||
const tempNum = likes_count;
|
||||
setLiked_by_user((prev) => !prev);
|
||||
if (!temp) {
|
||||
setLikes_count((prev) => prev + 1);
|
||||
} else {
|
||||
setLikes_count((prev) => prev - 1);
|
||||
}
|
||||
console.log(data.id);
|
||||
postLikeComponent(data.id)
|
||||
.then((response) => {
|
||||
setLoadingLike(false);
|
||||
setLikes_count(response.likes_count);
|
||||
setLiked_by_user(response.liked_by_user);
|
||||
})
|
||||
.catch((error) => {
|
||||
setLoadingLike(false);
|
||||
setLikes_count(tempNum);
|
||||
setLiked_by_user(temp);
|
||||
if (error.response.status === 403 || error.response.status === 401) {
|
||||
setValidApiKey(false);
|
||||
} else {
|
||||
console.error(error);
|
||||
setErrorData({
|
||||
title: `Error liking ${name}.`,
|
||||
list: [error["response"]["data"]["detail"]],
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const totalComponentsMetadata = () => {
|
||||
return data?.metadata ? data.metadata["total"] : 0;
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
className={classNames(
|
||||
"group relative flex flex-col justify-between overflow-hidden transition-all hover:shadow-md",
|
||||
disabled ? "pointer-events-none opacity-50" : ""
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<CardHeader>
|
||||
<div>
|
||||
<CardTitle className="flex w-full items-center justify-between gap-3 text-xl">
|
||||
<div
|
||||
className={classNames(
|
||||
"flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-primary",
|
||||
gradients[
|
||||
parseInt(data.id.slice(0, 12), 16) % gradients.length
|
||||
]
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
data.is_component ? "h-7 w-7 rounded-full bg-muted" : "",
|
||||
"flex items-center justify-center"
|
||||
)}
|
||||
>
|
||||
{data.is_component ? (
|
||||
<svg className="h-5 w-5" viewBox="0 0 24 24">
|
||||
<defs>
|
||||
<linearGradient
|
||||
id={data.id}
|
||||
x1="0%"
|
||||
y1="0%"
|
||||
x2="100%"
|
||||
y2="100%"
|
||||
className={
|
||||
gradients[
|
||||
parseInt(data.id.slice(0, 12), 16) %
|
||||
gradients.length
|
||||
]
|
||||
}
|
||||
>
|
||||
<stop
|
||||
offset="0%"
|
||||
stopColor="var(--tw-gradient-from)"
|
||||
/>
|
||||
<stop
|
||||
offset="100%"
|
||||
stopColor="var(--tw-gradient-to)"
|
||||
/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<IconComponent
|
||||
className={classNames(
|
||||
"h-4 w-4",
|
||||
gradients[
|
||||
parseInt(data.id.slice(0, 12), 16) %
|
||||
gradients.length
|
||||
]
|
||||
)}
|
||||
stroke={`url(#${data.id})`}
|
||||
name="ToyBrick"
|
||||
/>
|
||||
</svg>
|
||||
) : (
|
||||
<IconComponent
|
||||
className="h-4 w-4 text-background"
|
||||
name="Network"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ShadTooltip content={data.name}>
|
||||
<div className="w-full truncate">{data.name}</div>
|
||||
</ShadTooltip>
|
||||
<div className="flex gap-3">
|
||||
{!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" />
|
||||
{totalComponentsMetadata()}
|
||||
</span>
|
||||
</ShadTooltip>
|
||||
)}
|
||||
<ShadTooltip content="Likes">
|
||||
<span className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||
<IconComponent
|
||||
name="Heart"
|
||||
className={classNames("h-4 w-4 ")}
|
||||
/>
|
||||
{likes_count ?? 0}
|
||||
</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" />
|
||||
{data.downloads_count}
|
||||
</span>
|
||||
</ShadTooltip>
|
||||
</div>
|
||||
</CardTitle>
|
||||
</div>
|
||||
{data.user_created.username && (
|
||||
<span className="text-xs text-primary">
|
||||
by <b>{data.user_created.username}</b>
|
||||
</span>
|
||||
)}
|
||||
|
||||
<CardDescription className="pb-2 pt-2">
|
||||
<div className="truncate-doubleline">{data.description}</div>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</div>
|
||||
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-center justify-between gap-2">
|
||||
<div className="flex w-full flex-wrap items-end justify-between gap-2">
|
||||
<div className="flex w-full flex-1 flex-wrap gap-2">
|
||||
{data.tags.length > 0 &&
|
||||
data.tags.map((tag, index) => (
|
||||
<Badge
|
||||
key={index}
|
||||
variant="outline"
|
||||
size="xq"
|
||||
className="text-muted-foreground"
|
||||
>
|
||||
{tag.name}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex gap-0.5">
|
||||
<ShadTooltip
|
||||
content={authorized ? "Like" : "Please review your API key."}
|
||||
>
|
||||
<Button
|
||||
disabled={loadingLike || !authorized}
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
className={
|
||||
"whitespace-nowrap" +
|
||||
(!authorized ? " cursor-not-allowed" : "")
|
||||
}
|
||||
onClick={() => {
|
||||
handleLike();
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
name="Heart"
|
||||
className={classNames(
|
||||
"h-6 w-6 p-0.5",
|
||||
liked_by_user
|
||||
? "fill-destructive stroke-destructive"
|
||||
: "",
|
||||
!authorized ? " text-ring" : ""
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</ShadTooltip>
|
||||
<ShadTooltip
|
||||
content={
|
||||
authorized ? "Install Locally" : "Please review your API key."
|
||||
}
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
className={
|
||||
"whitespace-nowrap" +
|
||||
(!authorized ? " cursor-not-allowed" : "")
|
||||
}
|
||||
onClick={() => {
|
||||
if (loading || !authorized) {
|
||||
return;
|
||||
}
|
||||
handleInstall();
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
name={loading ? "Loader2" : "Plus"}
|
||||
className={classNames(
|
||||
loading ? "h-5 w-5 animate-spin" : "h-6 w-6 p-0.5",
|
||||
!authorized ? " text-ring" : ""
|
||||
)}
|
||||
/>
|
||||
</Button>
|
||||
</ShadTooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
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 { SkeletonCardComponent } from "../../components/skeletonCardComponent";
|
||||
|
|
@ -21,7 +22,6 @@ import { getStoreComponents, getStoreTags } from "../../controllers/API";
|
|||
import StoreApiKeyModal from "../../modals/StoreApiKeyModal";
|
||||
import { storeComponent } from "../../types/store";
|
||||
import { cn } from "../../utils/utils";
|
||||
import { MarketCardComponent } from "./components/market-card";
|
||||
export default function StorePage(): JSX.Element {
|
||||
const { validApiKey, setValidApiKey, hasApiKey, loadingApiKey } =
|
||||
useContext(StoreContext);
|
||||
|
|
@ -326,7 +326,7 @@ export default function StorePage(): JSX.Element {
|
|||
searchData.map((item) => {
|
||||
return (
|
||||
<>
|
||||
<MarketCardComponent
|
||||
<CollectionCardComponent
|
||||
key={item.id}
|
||||
data={item}
|
||||
authorized={validApiKey}
|
||||
|
|
|
|||
|
|
@ -353,34 +353,6 @@
|
|||
@apply alert-font-size text-success-foreground word-break-break-word;
|
||||
}
|
||||
|
||||
.card-component-title-display {
|
||||
@apply round-button-div flex-max-width;
|
||||
}
|
||||
.card-component-image {
|
||||
@apply flex h-7 w-7 items-center justify-center rounded-full text-2xl;
|
||||
}
|
||||
.card-component-title-size {
|
||||
@apply w-full flex-1 truncate-doubleline word-break-break-word;
|
||||
}
|
||||
.card-component-delete-button {
|
||||
@apply flex self-start;
|
||||
}
|
||||
.card-component-delete-icon {
|
||||
@apply h-4 w-4 text-primary opacity-0 transition-all group-hover:opacity-100;
|
||||
}
|
||||
.card-component-desc {
|
||||
@apply pb-2 pt-2;
|
||||
}
|
||||
.card-component-desc-text {
|
||||
@apply truncate-doubleline;
|
||||
}
|
||||
.card-component-footer-arrangement {
|
||||
@apply flex-max-width items-end justify-between gap-2;
|
||||
}
|
||||
.card-component-footer {
|
||||
@apply flex flex-wrap gap-2;
|
||||
}
|
||||
|
||||
.unused-side-bar-aside {
|
||||
@apply flex flex-shrink-0 flex-col overflow-hidden border-r transition-all duration-500;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export type FlowType = {
|
|||
data: ReactFlowJsonObject | null;
|
||||
description: string;
|
||||
style?: FlowStyleType;
|
||||
is_component?: boolean;
|
||||
is_component: boolean;
|
||||
parent?: string;
|
||||
date_created?: string;
|
||||
last_tested_version?: string;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
export type storeComponent = {
|
||||
id: string;
|
||||
is_component: boolean;
|
||||
tags: { id: string; name: string }[];
|
||||
tags?: { id: string; name: string }[];
|
||||
metadata?: {};
|
||||
downloads_count: number;
|
||||
downloads_count?: number;
|
||||
name: string;
|
||||
description: string;
|
||||
liked_by_count: number;
|
||||
liked_by_count?: number;
|
||||
liked_by_user?: boolean;
|
||||
user_created: { username: string };
|
||||
user_created?: { username: string };
|
||||
};
|
||||
|
||||
export type StoreComponentResponse = {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {
|
|||
ReactFlowJsonObject,
|
||||
XYPosition,
|
||||
} from "reactflow";
|
||||
import ShortUniqueId from "short-unique-id";
|
||||
import { specialCharsRegex } from "../constants/constants";
|
||||
import { APITemplateType, TemplateVariableType } from "../types/api";
|
||||
import {
|
||||
|
|
@ -519,6 +520,7 @@ export function generateFlow(
|
|||
|
||||
const newFlow: FlowType = {
|
||||
data: newFlowData,
|
||||
is_component: false,
|
||||
name: name,
|
||||
description: "",
|
||||
//generating local id instead of using the id from the server, can change in the future
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue