Merge branch 'feature/store' of github.com:logspace-ai/langflow into feature/store
This commit is contained in:
commit
7a15fb7a0d
123 changed files with 1841 additions and 2729 deletions
|
|
@ -610,7 +610,7 @@ export async function getStoreComponents(
|
|||
queryParams.push(`status=${status}`);
|
||||
}
|
||||
if (tags !== undefined && tags !== null && tags.length > 0) {
|
||||
queryParams.push(`tags=${tags.join(",")}`);
|
||||
queryParams.push(`tags=${tags.join(encodeURIComponent(","))}`);
|
||||
}
|
||||
|
||||
if (sort !== undefined && sort !== null) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Input } from "../../components/ui/input";
|
|||
import { CONTROL_NEW_API_KEY } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { AuthContext } from "../../contexts/authContext";
|
||||
import { StoreContext } from "../../contexts/storeContext";
|
||||
import { addApiKeyStore } from "../../controllers/API";
|
||||
import {
|
||||
ApiKeyInputType,
|
||||
|
|
@ -25,6 +26,7 @@ export default function StoreApiKeyModal({
|
|||
const { setSuccessData, setErrorData } = useContext(alertContext);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const { storeApiKey } = useContext(AuthContext);
|
||||
const { hasApiKey } = useContext(StoreContext);
|
||||
|
||||
function handleInput({
|
||||
target: { name, value },
|
||||
|
|
@ -86,6 +88,8 @@ export default function StoreApiKeyModal({
|
|||
<div className="flex items-center justify-between gap-2">
|
||||
<Form.Control asChild>
|
||||
<Input
|
||||
//fake api key
|
||||
value={hasApiKey ? "this is not a real api key :)" : ""}
|
||||
type="password"
|
||||
onChange={({ target: { value } }) => {
|
||||
handleInput({ target: { name: "apikey", value } });
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ export const MarketCardComponent = ({
|
|||
}
|
||||
|
||||
function handleLike() {
|
||||
setLoading(true);
|
||||
if (liked_by_user !== undefined || liked_by_user !== null) {
|
||||
const temp = liked_by_user;
|
||||
const tempNum = likes_count;
|
||||
|
|
@ -107,6 +108,7 @@ export const MarketCardComponent = ({
|
|||
console.log(data.id);
|
||||
postLikeComponent(data.id)
|
||||
.catch((error) => {
|
||||
setLoading(false);
|
||||
console.error(error);
|
||||
setLiked_by_user(temp);
|
||||
setLikes_count(tempNum);
|
||||
|
|
@ -116,6 +118,7 @@ export const MarketCardComponent = ({
|
|||
});
|
||||
})
|
||||
.then((response) => {
|
||||
setLoading(false);
|
||||
setLikes_count(response.likes_count);
|
||||
setLiked_by_user(response.liked_by_user);
|
||||
});
|
||||
|
|
@ -137,7 +140,9 @@ export const MarketCardComponent = ({
|
|||
<CardHeader>
|
||||
<div>
|
||||
<CardTitle className="flex w-full items-center justify-between gap-3 text-xl">
|
||||
<span className="w-full truncate">{data.name}</span>
|
||||
<ShadTooltip content={data.name}>
|
||||
<div className="w-full truncate">{data.name}</div>
|
||||
</ShadTooltip>
|
||||
<div className="flex gap-3">
|
||||
{!data.is_component && (
|
||||
<ShadTooltip content="Components">
|
||||
|
|
@ -192,6 +197,7 @@ export const MarketCardComponent = ({
|
|||
content={authorized ? "Like" : "Please review your API key."}
|
||||
>
|
||||
<Button
|
||||
disabled={loading || !authorized}
|
||||
variant="ghost"
|
||||
size="xs"
|
||||
className={
|
||||
|
|
@ -199,7 +205,7 @@ export const MarketCardComponent = ({
|
|||
(!authorized ? " cursor-not-allowed" : "")
|
||||
}
|
||||
onClick={() => {
|
||||
if (authorized) handleLike();
|
||||
handleLike();
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
|
|
|
|||
|
|
@ -40,26 +40,23 @@ export default function StorePage(): JSX.Element {
|
|||
const [pageIndex, setPageIndex] = useState(1);
|
||||
const [pageOrder, setPageOrder] = useState("Popular");
|
||||
const [tags, setTags] = useState<{ id: string; name: string }[]>([]);
|
||||
const [tabActive, setTabActive] = useState("Flows");
|
||||
const [tabActive, setTabActive] = useState("All");
|
||||
const [searchText, setSearchText] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
handleGetTags();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
function getAllStore() {
|
||||
handleGetComponents();
|
||||
if (hasApiKey) {
|
||||
getSavedComponents();
|
||||
}
|
||||
}, [
|
||||
searchText,
|
||||
tabActive,
|
||||
pageOrder,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
filteredCategories,
|
||||
]);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getAllStore();
|
||||
}, [tabActive, pageOrder, pageIndex, pageSize, filteredCategories]);
|
||||
|
||||
function handleGetTags() {
|
||||
setLoadingTags(true);
|
||||
|
|
@ -75,7 +72,7 @@ export default function StorePage(): JSX.Element {
|
|||
pageIndex,
|
||||
pageSize,
|
||||
tabActive === "All" ? null : tabActive === "Flows" ? false : true,
|
||||
pageOrder === "Popular" ? "-count(liked_by)" : "name",
|
||||
pageOrder === "Popular" ? "-count(downloads)" : "name",
|
||||
filteredCategories,
|
||||
null,
|
||||
null,
|
||||
|
|
@ -153,6 +150,7 @@ export default function StorePage(): JSX.Element {
|
|||
<div className="flex items-end gap-4">
|
||||
<div className="relative h-12 w-[40%]">
|
||||
<Input
|
||||
disabled={loading}
|
||||
placeholder="Search Flows and Components"
|
||||
className="absolute h-12 px-5"
|
||||
onChange={(e) => {
|
||||
|
|
@ -161,55 +159,66 @@ export default function StorePage(): JSX.Element {
|
|||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
setSearchText(inputText);
|
||||
getAllStore();
|
||||
}
|
||||
}}
|
||||
value={inputText}
|
||||
/>
|
||||
<button
|
||||
disabled={loading}
|
||||
className="absolute bottom-0 right-4 top-0 my-auto h-6 cursor-pointer stroke-1 text-muted-foreground"
|
||||
onClick={() => {
|
||||
setSearchText(inputText);
|
||||
getAllStore();
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
name={loading ? "Loader2" : "Search"}
|
||||
className={loading ? " animate-spin" : ""}
|
||||
className={
|
||||
loading ? " animate-spin cursor-not-allowed" : ""
|
||||
}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div className="ml-4 flex w-full gap-2 border-b border-border">
|
||||
<button
|
||||
disabled={loading}
|
||||
onClick={() => {
|
||||
setTabActive("All");
|
||||
}}
|
||||
className={
|
||||
tabActive === "All"
|
||||
(tabActive === "All"
|
||||
? "border-b-2 border-primary p-3"
|
||||
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary"
|
||||
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
|
||||
(loading ? " cursor-not-allowed " : "")
|
||||
}
|
||||
>
|
||||
All
|
||||
</button>
|
||||
<button
|
||||
disabled={loading}
|
||||
onClick={() => {
|
||||
setTabActive("Flows");
|
||||
}}
|
||||
className={
|
||||
tabActive === "Flows"
|
||||
(tabActive === "Flows"
|
||||
? "border-b-2 border-primary p-3"
|
||||
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary"
|
||||
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
|
||||
(loading ? " cursor-not-allowed " : "")
|
||||
}
|
||||
>
|
||||
Flows
|
||||
</button>
|
||||
<button
|
||||
disabled={loading}
|
||||
onClick={() => {
|
||||
setTabActive("Components");
|
||||
}}
|
||||
className={
|
||||
tabActive === "Components"
|
||||
(tabActive === "Components"
|
||||
? "border-b-2 border-primary p-3"
|
||||
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary"
|
||||
: " border-b-2 border-transparent p-3 text-muted-foreground hover:text-primary") +
|
||||
(loading ? " cursor-not-allowed " : "")
|
||||
}
|
||||
>
|
||||
Components
|
||||
|
|
@ -225,24 +234,28 @@ export default function StorePage(): JSX.Element {
|
|||
<div className="flex h-6 items-center gap-2 px-2">
|
||||
{!loadingTags &&
|
||||
tags.map((tag, idx) => (
|
||||
<Badge
|
||||
key={idx}
|
||||
<button
|
||||
disabled={loading}
|
||||
className={loading ? "cursor-not-allowed" : ""}
|
||||
onClick={() => {
|
||||
updateTags(tag.name);
|
||||
}}
|
||||
variant="outline"
|
||||
size="sq"
|
||||
className={cn(
|
||||
"cursor-pointer",
|
||||
filteredCategories.some(
|
||||
(category) => category === tag.name
|
||||
)
|
||||
? "bg-beta-foreground text-background hover:bg-beta-foreground"
|
||||
: ""
|
||||
)}
|
||||
>
|
||||
{tag.name}
|
||||
</Badge>
|
||||
<Badge
|
||||
key={idx}
|
||||
variant="outline"
|
||||
size="sq"
|
||||
className={cn(
|
||||
filteredCategories.some(
|
||||
(category) => category === tag.name
|
||||
)
|
||||
? "bg-beta-foreground text-background hover:bg-beta-foreground"
|
||||
: ""
|
||||
)}
|
||||
>
|
||||
{tag.name}
|
||||
</Badge>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-end justify-between">
|
||||
|
|
@ -256,12 +269,13 @@ export default function StorePage(): JSX.Element {
|
|||
</span>
|
||||
|
||||
<Select
|
||||
disabled={loading}
|
||||
onValueChange={(e) => {
|
||||
setPageOrder(e);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Sort By" />
|
||||
<SelectValue placeholder="Popular" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Popular">Most Popular</SelectItem>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue