feat(tagsSelectorComponent): add TagsSelector component to allow users to select tags for a flow
feat(tagsSelectorComponent): add TagComponent to render individual tags in the TagsSelector component fix(API): add tags and publicFlow parameters to saveFlowStore function to save tags and set flow visibility fix(ConfirmationModal): add size prop to allow customizing the size of the modal feat(ExtraSidebar): add TagsSelector component to the Share Flow confirmation modal to allow users to select tags for the flow feat(ExtraSidebar): add ToggleShadComponent to allow users to toggle the visibility of the shared flow fix(ExtraSidebar): pass selected tags and sharePublic value to saveFlowStore function when sharing a flow fix(ExtraSidebar): add useEffect to fetch tags from API and initialize tags state fix(ExtraSidebar): add handleTagSelection function to handle tag selection in TagsSelector component fix(ExtraSidebar): update handleShareFlow function to pass selected tags and sharePublic value to saveFlowStore function fix(ExtraSidebar): update ConfirmationModal size prop to use size prop from component props fix(ExtraSidebar): update ConfirmationModal dependency array to include sharePublic value fix(NodeToolbarComponent): pass empty array as tags parameter to saveFlowStore function when sharing a component fix(MarketCardComponent): pass tags parameter to saveFlowStore function when saving a flow from the store fix(ConfirmationModal): add size prop to ConfirmationModalType to allow customizing the size of the modal
This commit is contained in:
parent
d34b551677
commit
cf434eb7ba
8 changed files with 132 additions and 14 deletions
26
src/frontend/src/components/tagsSelectorComponent/index.tsx
Normal file
26
src/frontend/src/components/tagsSelectorComponent/index.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import TagComponent from "./tagComponent";
|
||||
|
||||
export function TagsSelector({
|
||||
tags,
|
||||
selectedTags,
|
||||
setSelectedTags,
|
||||
}: {
|
||||
tags: string[];
|
||||
selectedTags: Set<string>;
|
||||
setSelectedTags: (tag: string) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className=" flex h-full w-full flex-row flex-wrap gap-3 align-middle">
|
||||
{tags.map((tag, index) => {
|
||||
return (
|
||||
<TagComponent
|
||||
tag={tag}
|
||||
selected={selectedTags.has(tag)}
|
||||
key={index}
|
||||
handleClick={setSelectedTags}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { useState } from "react";
|
||||
import { Badge } from "../../ui/badge";
|
||||
|
||||
export default function TagComponent({
|
||||
tag,
|
||||
handleClick,
|
||||
selected,
|
||||
}: {
|
||||
tag: string;
|
||||
handleClick: (tag: string) => void;
|
||||
selected: boolean;
|
||||
}) {
|
||||
const [selectedTag, setSelectedTag] = useState(selected);
|
||||
return (
|
||||
<button
|
||||
onClick={() => {
|
||||
setSelectedTag((prev) => !prev);
|
||||
handleClick(tag);
|
||||
}}
|
||||
>
|
||||
<Badge
|
||||
size="md"
|
||||
className={selectedTag ? "shadow-md" : ""}
|
||||
variant={selectedTag ? "gray" : "secondary"}
|
||||
>
|
||||
{tag}
|
||||
</Badge>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
@ -547,14 +547,18 @@ export async function addApiKeyStore(key: string) {
|
|||
* @returns {Promise<any>} The saved flow data.
|
||||
* @throws Will throw an error if saving fails.
|
||||
*/
|
||||
export async function saveFlowStore(newFlow: {
|
||||
name?: string;
|
||||
data: ReactFlowJsonObject | null;
|
||||
description?: string;
|
||||
style?: FlowStyleType;
|
||||
is_component?: boolean;
|
||||
parent?: string;
|
||||
}): Promise<FlowType> {
|
||||
export async function saveFlowStore(
|
||||
newFlow: {
|
||||
name?: string;
|
||||
data: ReactFlowJsonObject | null;
|
||||
description?: string;
|
||||
style?: FlowStyleType;
|
||||
is_component?: boolean;
|
||||
parent?: string;
|
||||
},
|
||||
tags: string[],
|
||||
publicFlow = false
|
||||
): Promise<FlowType> {
|
||||
try {
|
||||
const response = await api.post(`${BASE_URL_API}store/components/`, {
|
||||
name: newFlow.name,
|
||||
|
|
@ -562,6 +566,8 @@ export async function saveFlowStore(newFlow: {
|
|||
description: newFlow.description,
|
||||
is_component: newFlow.is_component,
|
||||
parent: newFlow.parent,
|
||||
tags: tags,
|
||||
public: publicFlow,
|
||||
});
|
||||
|
||||
if (response.status !== 201) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ function ConfirmationModal({
|
|||
data,
|
||||
index,
|
||||
onConfirm,
|
||||
size,
|
||||
open,
|
||||
onClose,
|
||||
}: ConfirmationModalType) {
|
||||
|
|
@ -50,7 +51,7 @@ function ConfirmationModal({
|
|||
);
|
||||
|
||||
return (
|
||||
<BaseModal size="x-small" open={modalOpen} setOpen={setModalOpen}>
|
||||
<BaseModal size={size ?? "x-small"} open={modalOpen} setOpen={setModalOpen}>
|
||||
<BaseModal.Trigger asChild={asChild}>{triggerChild}</BaseModal.Trigger>
|
||||
<BaseModal.Header description={titleHeader}>
|
||||
<span className="pr-2">{title}</span>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import { useContext, useEffect, useMemo, useState } from "react";
|
|||
import { ReactFlowJsonObject } from "reactflow";
|
||||
import ShadTooltip from "../../../../components/ShadTooltipComponent";
|
||||
import IconComponent from "../../../../components/genericIconComponent";
|
||||
import { TagsSelector } from "../../../../components/tagsSelectorComponent";
|
||||
import ToggleShadComponent from "../../../../components/toggleShadComponent";
|
||||
import { Input } from "../../../../components/ui/input";
|
||||
import { Separator } from "../../../../components/ui/separator";
|
||||
import { alertContext } from "../../../../contexts/alertContext";
|
||||
|
|
@ -35,6 +37,7 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
const { setSuccessData, setErrorData } = useContext(alertContext);
|
||||
const [dataFilter, setFilterData] = useState(data);
|
||||
const [search, setSearch] = useState("");
|
||||
const [sharePublic, setSharePublic] = useState(true);
|
||||
const isPending = tabsState[tabId]?.isPending;
|
||||
function onDragStart(
|
||||
event: React.DragEvent<any>,
|
||||
|
|
@ -51,6 +54,26 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
event.dataTransfer.setData("nodedata", JSON.stringify(data));
|
||||
}
|
||||
|
||||
const [tags, setTags] = useState<string[]>([]);
|
||||
const [selectedTags, setSelectedTags] = useState<Set<string>>(new Set());
|
||||
|
||||
useEffect(() => {
|
||||
//TODO: get tags from api
|
||||
setTags(["teste1", "teste2"]);
|
||||
}, [setTags]);
|
||||
|
||||
function handleTagSelection(tag: string) {
|
||||
setSelectedTags((prev) => {
|
||||
const newSet = new Set(prev);
|
||||
if (newSet.has(tag)) {
|
||||
newSet.delete(tag);
|
||||
} else {
|
||||
newSet.add(tag);
|
||||
}
|
||||
return newSet;
|
||||
});
|
||||
}
|
||||
|
||||
// Handle showing components after use search input
|
||||
function handleSearchInput(e: string) {
|
||||
if (e === "") {
|
||||
|
|
@ -116,7 +139,7 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
},
|
||||
is_component: false,
|
||||
};
|
||||
saveFlowStore(saveFlow).then(
|
||||
saveFlowStore(saveFlow, Array.from(selectedTags), sharePublic).then(
|
||||
() => {
|
||||
setSuccessData({
|
||||
title: "Flow shared successfully",
|
||||
|
|
@ -176,6 +199,7 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
title="Share Flow"
|
||||
confirmationText="Share"
|
||||
icon="Share2"
|
||||
size="smaller"
|
||||
onConfirm={() => {
|
||||
handleShareFlow();
|
||||
}}
|
||||
|
|
@ -183,7 +207,29 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
cancelText="Cancel"
|
||||
>
|
||||
<ConfirmationModal.Content>
|
||||
<span>This flow will be available for everyone to use.</span>
|
||||
<div className="flex h-full w-full flex-col gap-7">
|
||||
<div className="flex justify-start align-middle">
|
||||
<ToggleShadComponent
|
||||
disabled={false}
|
||||
size="medium"
|
||||
setEnabled={setSharePublic}
|
||||
enabled={sharePublic}
|
||||
/>
|
||||
<div>
|
||||
{sharePublic
|
||||
? "This flow will be avaliable for everyone"
|
||||
: "This flow will be avaliable just for you"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full pt-2">
|
||||
<span className="text-sm">Add some tags to your Flow</span>
|
||||
<TagsSelector
|
||||
tags={["teste1", "teste2"]}
|
||||
selectedTags={new Set()}
|
||||
setSelectedTags={handleTagSelection}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</ConfirmationModal.Content>
|
||||
<ConfirmationModal.Trigger tolltipContent="Share" side="top">
|
||||
<div className={classNames("extra-side-bar-buttons")}>
|
||||
|
|
@ -192,7 +238,7 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
</ConfirmationModal.Trigger>
|
||||
</ConfirmationModal>
|
||||
),
|
||||
[]
|
||||
[sharePublic]
|
||||
);
|
||||
|
||||
const ExportMemo = useMemo(
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ export default function NodeToolbarComponent({
|
|||
function handleShareComponent() {
|
||||
const componentFlow = cloneDeep(data);
|
||||
saveComponent(componentFlow).then(() => {
|
||||
saveFlowStore(createFlowComponent(componentFlow)).then(
|
||||
saveFlowStore(createFlowComponent(componentFlow), []).then(
|
||||
(_) => {
|
||||
setSuccessData({
|
||||
title: "Component shared successfully",
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export const MarketCardComponent = ({ data }: { data: storeComponent }) => {
|
|||
const newFLow = cloneFLowWithParent(res, res.id, data.is_component);
|
||||
flowData.current = newFLow;
|
||||
console.log(newFLow);
|
||||
saveFlowStore(newFLow)
|
||||
saveFlowStore(newFLow, data.tags)
|
||||
.then(() => {
|
||||
setAdded(true);
|
||||
setLoading(false);
|
||||
|
|
|
|||
|
|
@ -298,6 +298,15 @@ export type ConfirmationModalType = {
|
|||
onConfirm: (index, data) => void;
|
||||
open?: boolean;
|
||||
onClose?: (close: boolean) => void;
|
||||
size?:
|
||||
| "x-small"
|
||||
| "smaller"
|
||||
| "small"
|
||||
| "medium"
|
||||
| "large"
|
||||
| "large-h-full"
|
||||
| "small-h-full"
|
||||
| "medium-h-full";
|
||||
};
|
||||
|
||||
export type UserManagementType = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue