Modal refactor (#647)
This PR is about the transition from PopupContext to the Radix native way of handling popups, as well as applying a BaseModal to all of the modals to improve modularity.
This commit is contained in:
commit
2d9081403f
40 changed files with 2764 additions and 4019 deletions
3504
src/frontend/package-lock.json
generated
3504
src/frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,4 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||
import { Handle, Position, useUpdateNodeInternals } from "reactflow";
|
||||
import ShadTooltip from "../../../../components/ShadTooltipComponent";
|
||||
|
|
@ -13,14 +14,10 @@ import PromptAreaComponent from "../../../../components/promptComponent";
|
|||
import TextAreaComponent from "../../../../components/textAreaComponent";
|
||||
import ToggleShadComponent from "../../../../components/toggleShadComponent";
|
||||
import { MAX_LENGTH_TO_SCROLL_TOOLTIP } from "../../../../constants/constants";
|
||||
import { PopUpContext } from "../../../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||
import { typesContext } from "../../../../contexts/typesContext";
|
||||
import { ParameterComponentType } from "../../../../types/components";
|
||||
import {
|
||||
cleanEdges,
|
||||
isValidConnection,
|
||||
} from "../../../../utils/reactflowUtils";
|
||||
import { isValidConnection } from "../../../../utils/reactflowUtils";
|
||||
import {
|
||||
nodeColors,
|
||||
nodeIconsLucide,
|
||||
|
|
@ -36,6 +33,7 @@ export default function ParameterComponent({
|
|||
left,
|
||||
id,
|
||||
data,
|
||||
setData,
|
||||
tooltipTitle,
|
||||
title,
|
||||
color,
|
||||
|
|
@ -51,7 +49,6 @@ export default function ParameterComponent({
|
|||
const infoHtml = useRef(null);
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const [position, setPosition] = useState(0);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
const { setTabsState, tabId, save } = useContext(TabsContext);
|
||||
|
||||
// Update component position
|
||||
|
|
@ -66,15 +63,16 @@ export default function ParameterComponent({
|
|||
updateNodeInternals(data.id);
|
||||
}, [data.id, position, updateNodeInternals]);
|
||||
|
||||
useEffect(() => {}, [closePopUp, data.node.template]);
|
||||
|
||||
const { reactFlowInstance } = useContext(typesContext);
|
||||
let disabled =
|
||||
reactFlowInstance?.getEdges().some((e) => e.targetHandle === id) ?? false;
|
||||
const [myData, setMyData] = useState(useContext(typesContext).data);
|
||||
|
||||
const { data: myData } = useContext(typesContext);
|
||||
|
||||
const handleOnNewValue = (newValue: any) => {
|
||||
data.node.template[name].value = newValue;
|
||||
let newData = cloneDeep(data);
|
||||
newData.node.template[name].value = newValue;
|
||||
setData(newData);
|
||||
// Set state to pending
|
||||
setTabsState((prev) => {
|
||||
return {
|
||||
|
|
@ -244,7 +242,6 @@ export default function ParameterComponent({
|
|||
) : (
|
||||
<InputComponent
|
||||
disabled={disabled}
|
||||
disableCopyPaste={true}
|
||||
password={data.node.template[name].password ?? false}
|
||||
value={data.node.template[name].value ?? ""}
|
||||
onChange={handleOnNewValue}
|
||||
|
|
@ -266,7 +263,6 @@ export default function ParameterComponent({
|
|||
<div className="mt-2 w-full">
|
||||
<FloatComponent
|
||||
disabled={disabled}
|
||||
disableCopyPaste={true}
|
||||
value={data.node.template[name].value ?? ""}
|
||||
onChange={handleOnNewValue}
|
||||
/>
|
||||
|
|
@ -311,7 +307,6 @@ export default function ParameterComponent({
|
|||
<div className="mt-2 w-full">
|
||||
<IntComponent
|
||||
disabled={disabled}
|
||||
disableCopyPaste={true}
|
||||
value={data.node.template[name].value ?? ""}
|
||||
onChange={handleOnNewValue}
|
||||
/>
|
||||
|
|
@ -322,15 +317,6 @@ export default function ParameterComponent({
|
|||
field_name={name}
|
||||
setNodeClass={(nodeClass) => {
|
||||
data.node = nodeClass;
|
||||
if (reactFlowInstance) {
|
||||
cleanEdges({
|
||||
flow: {
|
||||
edges: reactFlowInstance.getEdges(),
|
||||
nodes: reactFlowInstance.getNodes(),
|
||||
},
|
||||
updateEdge: (edge) => reactFlowInstance.setEdges(edge),
|
||||
});
|
||||
}
|
||||
}}
|
||||
nodeClass={data.node}
|
||||
disabled={disabled}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,33 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import { useContext, useEffect, useRef, useState } from "react";
|
||||
import { NodeToolbar } from "reactflow";
|
||||
import { NodeToolbar, useUpdateNodeInternals } from "reactflow";
|
||||
import ShadTooltip from "../../components/ShadTooltipComponent";
|
||||
import Tooltip from "../../components/TooltipComponent";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { useSSE } from "../../contexts/SSEContext";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import NodeModal from "../../modals/NodeModal";
|
||||
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
import { cleanEdges } from "../../utils/reactflowUtils";
|
||||
import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils";
|
||||
import { classNames, toTitleCase } from "../../utils/utils";
|
||||
import ParameterComponent from "./components/parameterComponent";
|
||||
|
||||
export default function GenericNode({
|
||||
data,
|
||||
data: olddata,
|
||||
selected,
|
||||
}: {
|
||||
data: NodeDataType;
|
||||
selected: boolean;
|
||||
}) {
|
||||
const [data, setData] = useState(olddata);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const { updateFlow, flows, tabId } = useContext(TabsContext);
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const showError = useRef(true);
|
||||
const { types, deleteNode } = useContext(typesContext);
|
||||
|
||||
const { closePopUp, openPopUp } = useContext(PopUpContext);
|
||||
const { types, deleteNode, reactFlowInstance } = useContext(typesContext);
|
||||
// any to avoid type conflict
|
||||
const Icon: any =
|
||||
nodeIconsLucide[data.type] || nodeIconsLucide[types[data.type]];
|
||||
|
|
@ -33,7 +35,26 @@ export default function GenericNode({
|
|||
const [validationStatus, setValidationStatus] = useState(null);
|
||||
// State for outline color
|
||||
const { sseData, isBuilding } = useSSE();
|
||||
const refHtml = useRef(null);
|
||||
useEffect(() => {
|
||||
olddata.node = data.node;
|
||||
let myFlow = flows.find((flow) => flow.id === tabId);
|
||||
if (reactFlowInstance && myFlow) {
|
||||
let flow = cloneDeep(myFlow);
|
||||
flow.data = reactFlowInstance.toObject();
|
||||
cleanEdges({
|
||||
flow: {
|
||||
edges: flow.data.edges,
|
||||
nodes: flow.data.nodes,
|
||||
},
|
||||
updateEdge: (edge) => {
|
||||
flow.data.edges = edge;
|
||||
reactFlowInstance.setEdges(edge);
|
||||
updateNodeInternals(data.id);
|
||||
},
|
||||
});
|
||||
updateFlow(flow);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
// New useEffect to watch for changes in sseData and update validation status
|
||||
useEffect(() => {
|
||||
|
|
@ -58,13 +79,12 @@ export default function GenericNode({
|
|||
deleteNode(data.id);
|
||||
return;
|
||||
}
|
||||
useEffect(() => {}, [closePopUp, data.node.template]);
|
||||
return (
|
||||
<>
|
||||
<NodeToolbar>
|
||||
<NodeToolbarComponent
|
||||
data={data}
|
||||
openPopUp={openPopUp}
|
||||
setData={setData}
|
||||
deleteNode={deleteNode}
|
||||
></NodeToolbarComponent>
|
||||
</NodeToolbar>
|
||||
|
|
@ -90,15 +110,6 @@ export default function GenericNode({
|
|||
</ShadTooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div className="round-button-div">
|
||||
<button
|
||||
className="relative"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
openPopUp(<NodeModal data={data} />);
|
||||
}}
|
||||
></button>
|
||||
</div>
|
||||
<div className="round-button-div">
|
||||
<div>
|
||||
<Tooltip
|
||||
|
|
@ -168,6 +179,7 @@ export default function GenericNode({
|
|||
!data.node.template[t].advanced ? (
|
||||
<ParameterComponent
|
||||
data={data}
|
||||
setData={setData}
|
||||
color={
|
||||
nodeColors[types[data.node.template[t].type]] ??
|
||||
nodeColors[data.node.template[t].type] ??
|
||||
|
|
@ -214,6 +226,7 @@ export default function GenericNode({
|
|||
</div>
|
||||
<ParameterComponent
|
||||
data={data}
|
||||
setData={setData}
|
||||
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
||||
title={
|
||||
data.node.output_types && data.node.output_types.length > 0
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ type InputProps = {
|
|||
name: string | null;
|
||||
description: string | null;
|
||||
maxLength?: number;
|
||||
flows: Array<{ id: string; name: string }>;
|
||||
flows: Array<{ id: string; name: string; description: string }>;
|
||||
tabId: string;
|
||||
setName: (name: string) => void;
|
||||
setDescription: (description: string) => void;
|
||||
|
|
@ -37,7 +37,13 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
|||
setName(value);
|
||||
};
|
||||
|
||||
const [desc, setDesc] = useState(
|
||||
flows.find((f) => f.id === tabId).description
|
||||
);
|
||||
|
||||
const handleDescriptionChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
flows.find((f) => f.id === tabId).description = event.target.value;
|
||||
setDesc(flows.find((f) => f.id === tabId).description);
|
||||
setDescription(event.target.value);
|
||||
};
|
||||
|
||||
|
|
@ -51,7 +57,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
|||
)}
|
||||
</div>
|
||||
<Input
|
||||
className="mt-2 font-normal"
|
||||
className="nopan nodrag noundo nocopy mt-2 font-normal"
|
||||
onChange={handleNameChange}
|
||||
type="text"
|
||||
name="name"
|
||||
|
|
@ -62,12 +68,15 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
|||
/>
|
||||
</Label>
|
||||
<Label>
|
||||
<span className="font-medium">Description (optional)</span>
|
||||
<div className="edit-flow-arrangement mt-3">
|
||||
<span className="font-medium ">Description (optional)</span>
|
||||
</div>
|
||||
|
||||
<Textarea
|
||||
name="description"
|
||||
id="description"
|
||||
onChange={handleDescriptionChange}
|
||||
value={description ?? ""}
|
||||
value={desc}
|
||||
placeholder="Flow description"
|
||||
className="mt-2 max-h-[100px] font-normal"
|
||||
rows={3}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { useEffect, useState } from "react";
|
||||
import CodeAreaModal from "../../modals/codeAreaModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
|
||||
|
|
@ -16,7 +15,6 @@ export default function CodeAreaComponent({
|
|||
const [myValue, setMyValue] = useState(
|
||||
typeof value == "string" ? value : JSON.stringify(value)
|
||||
);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
|
|
@ -30,45 +28,26 @@ export default function CodeAreaComponent({
|
|||
|
||||
return (
|
||||
<div className={disabled ? "pointer-events-none w-full " : " w-full"}>
|
||||
<div className="flex w-full items-center">
|
||||
<span
|
||||
onClick={() => {
|
||||
openPopUp(
|
||||
<CodeAreaModal
|
||||
value={myValue}
|
||||
nodeClass={nodeClass}
|
||||
setNodeClass={setNodeClass}
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node input-dialog"
|
||||
: (disabled ? " input-disable input-ring " : "") +
|
||||
" input-primary text-muted-foreground "
|
||||
}
|
||||
>
|
||||
{myValue !== "" ? myValue : "Type something..."}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
openPopUp(
|
||||
<CodeAreaModal
|
||||
setNodeClass={setNodeClass}
|
||||
value={myValue}
|
||||
nodeClass={nodeClass}
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
>
|
||||
<CodeAreaModal
|
||||
value={myValue}
|
||||
nodeClass={nodeClass}
|
||||
setNodeClass={setNodeClass}
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
>
|
||||
<div className="flex w-full items-center">
|
||||
<span
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node input-dialog"
|
||||
: (disabled ? " input-disable input-ring " : "") +
|
||||
" input-primary text-muted-foreground "
|
||||
}
|
||||
>
|
||||
{myValue !== "" ? myValue : "Type something..."}
|
||||
</span>
|
||||
{!editNode && (
|
||||
<IconComponent
|
||||
name="ExternalLink"
|
||||
|
|
@ -78,8 +57,8 @@ export default function CodeAreaComponent({
|
|||
}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CodeAreaModal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
667
src/frontend/src/components/codeTabsComponent/index.tsx
Normal file
667
src/frontend/src/components/codeTabsComponent/index.tsx
Normal file
|
|
@ -0,0 +1,667 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import { oneDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
||||
import AccordionComponent from "../../components/AccordionComponent";
|
||||
import ShadTooltip from "../../components/ShadTooltipComponent";
|
||||
import CodeAreaComponent from "../../components/codeAreaComponent";
|
||||
import Dropdown from "../../components/dropdownComponent";
|
||||
import FloatComponent from "../../components/floatComponent";
|
||||
import InputComponent from "../../components/inputComponent";
|
||||
import InputFileComponent from "../../components/inputFileComponent";
|
||||
import InputListComponent from "../../components/inputListComponent";
|
||||
import IntComponent from "../../components/intComponent";
|
||||
import PromptAreaComponent from "../../components/promptComponent";
|
||||
import TextAreaComponent from "../../components/textAreaComponent";
|
||||
import ToggleShadComponent from "../../components/toggleShadComponent";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "../../components/ui/table";
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "../../components/ui/tabs";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { FlowType } from "../../types/flow/index";
|
||||
import { classNames } from "../../utils/utils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
export default function CodeTabsComponent({
|
||||
flow,
|
||||
tabs,
|
||||
activeTab,
|
||||
setActiveTab,
|
||||
isMessage,
|
||||
tweaks,
|
||||
}: {
|
||||
flow?: FlowType;
|
||||
tabs: any;
|
||||
activeTab: string;
|
||||
setActiveTab: any;
|
||||
isMessage?: boolean;
|
||||
tweaks?: {
|
||||
tweak?: any;
|
||||
tweaksList?: any;
|
||||
buildContent?: any;
|
||||
getValue?: any;
|
||||
buildTweakObject?: any;
|
||||
};
|
||||
}) {
|
||||
const [isCopied, setIsCopied] = useState<Boolean>(false);
|
||||
const [data, setData] = useState(flow ? flow["data"]["nodes"] : null);
|
||||
const [openAccordion, setOpenAccordion] = useState([]);
|
||||
const { dark } = useContext(darkContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (flow && flow["data"]["nodes"]) {
|
||||
setData(flow["data"]["nodes"]);
|
||||
}
|
||||
}, [flow]);
|
||||
|
||||
const copyToClipboard = () => {
|
||||
if (!navigator.clipboard || !navigator.clipboard.writeText) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(tabs[activeTab].code).then(() => {
|
||||
setIsCopied(true);
|
||||
|
||||
setTimeout(() => {
|
||||
setIsCopied(false);
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
const downloadAsFile = () => {
|
||||
const fileExtension = tabs[activeTab].language || ".txt";
|
||||
const suggestedFileName = `${"generated-code."}${fileExtension}`;
|
||||
const fileName = window.prompt("Enter the file name.", suggestedFileName);
|
||||
|
||||
if (!fileName) {
|
||||
// user pressed cancel on prompt
|
||||
return;
|
||||
}
|
||||
|
||||
const blob = new Blob([tabs[activeTab].code], { type: "text/plain" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.download = fileName;
|
||||
link.href = url;
|
||||
link.style.display = "none";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
function openAccordions() {
|
||||
let accordionsToOpen = [];
|
||||
tweaks.tweak.current.forEach((el) => {
|
||||
Object.keys(el).forEach((key) => {
|
||||
if (Object.keys(el[key]).length > 0) {
|
||||
accordionsToOpen.push(key);
|
||||
setOpenAccordion(accordionsToOpen);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (accordionsToOpen.length == 0) {
|
||||
setOpenAccordion([]);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Tabs
|
||||
value={activeTab}
|
||||
className={
|
||||
"api-modal-tabs " +
|
||||
(isMessage ? "dark " : "") +
|
||||
(dark && isMessage ? "bg-background" : "")
|
||||
}
|
||||
onValueChange={(value) => {
|
||||
setActiveTab(value);
|
||||
if (value === "3") {
|
||||
openAccordions();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="api-modal-tablist-div">
|
||||
<TabsList>
|
||||
{tabs.map((tab, index) => (
|
||||
<TabsTrigger
|
||||
className={
|
||||
isMessage ? "data-[state=active]:bg-primary-foreground" : ""
|
||||
}
|
||||
key={index}
|
||||
value={index.toString()}
|
||||
>
|
||||
{tab.name}
|
||||
</TabsTrigger>
|
||||
))}
|
||||
</TabsList>
|
||||
{Number(activeTab) < 3 && (
|
||||
<div className="float-right mx-1 flex gap-2">
|
||||
<button
|
||||
className="flex items-center gap-1.5 rounded bg-none p-1 text-xs text-gray-500 dark:text-gray-300"
|
||||
onClick={copyToClipboard}
|
||||
>
|
||||
{isCopied ? (
|
||||
<IconComponent name="Check" className="h-4 w-4" />
|
||||
) : (
|
||||
<IconComponent name="Clipboard" className="h-4 w-4" />
|
||||
)}
|
||||
{isCopied ? "Copied!" : "Copy code"}
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center gap-1.5 rounded bg-none p-1 text-xs text-gray-500 dark:text-gray-300"
|
||||
onClick={downloadAsFile}
|
||||
>
|
||||
<IconComponent name="Download" className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{tabs.map((tab, index) => (
|
||||
<TabsContent
|
||||
value={index.toString()}
|
||||
className="api-modal-tabs-content"
|
||||
key={index} // Remember to add a unique key prop
|
||||
>
|
||||
{index < 3 ? (
|
||||
<SyntaxHighlighter
|
||||
className="mt-0 h-full w-full overflow-auto custom-scroll"
|
||||
language={tab.mode}
|
||||
style={oneDark}
|
||||
>
|
||||
{tab.code}
|
||||
</SyntaxHighlighter>
|
||||
) : index === 3 ? (
|
||||
<>
|
||||
<div className="api-modal-according-display">
|
||||
<div
|
||||
className={classNames(
|
||||
"h-[70vh] w-full rounded-lg bg-muted",
|
||||
1 == 1
|
||||
? "overflow-scroll overflow-x-hidden custom-scroll"
|
||||
: "overflow-hidden"
|
||||
)}
|
||||
>
|
||||
{data.map((t: any, index) => (
|
||||
<div className="px-3" key={index}>
|
||||
{tweaks.tweaksList.current.includes(t["data"]["id"]) && (
|
||||
<AccordionComponent
|
||||
trigger={t["data"]["id"]}
|
||||
open={openAccordion}
|
||||
keyValue={t["data"]["id"]}
|
||||
>
|
||||
<div className="api-modal-table-arrangement">
|
||||
<Table className="table-fixed bg-muted outline-1">
|
||||
<TableHeader className="h-10 border-input text-xs font-medium text-ring">
|
||||
<TableRow className="dark:border-b-muted">
|
||||
<TableHead className="h-7 text-center">
|
||||
PARAM
|
||||
</TableHead>
|
||||
<TableHead className="h-7 p-0 text-center">
|
||||
VALUE
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody className="p-0">
|
||||
{Object.keys(t["data"]["node"]["template"])
|
||||
.filter(
|
||||
(n) =>
|
||||
n.charAt(0) !== "_" &&
|
||||
t.data.node.template[n].show &&
|
||||
(t.data.node.template[n].type === "str" ||
|
||||
t.data.node.template[n].type ===
|
||||
"bool" ||
|
||||
t.data.node.template[n].type ===
|
||||
"float" ||
|
||||
t.data.node.template[n].type ===
|
||||
"code" ||
|
||||
t.data.node.template[n].type ===
|
||||
"prompt" ||
|
||||
t.data.node.template[n].type ===
|
||||
"file" ||
|
||||
t.data.node.template[n].type === "int")
|
||||
)
|
||||
.map((n, i) => {
|
||||
return (
|
||||
<TableRow
|
||||
key={i}
|
||||
className="h-10 dark:border-b-muted"
|
||||
>
|
||||
<TableCell className="p-0 text-center text-sm text-foreground">
|
||||
{n}
|
||||
</TableCell>
|
||||
<TableCell className="p-0 text-xs text-foreground">
|
||||
<div className="m-auto w-[250px]">
|
||||
{t.data.node.template[n].type ===
|
||||
"str" &&
|
||||
!t.data.node.template[n].options ? (
|
||||
<div className="mx-auto">
|
||||
{t.data.node.template[n]
|
||||
.list ? (
|
||||
<InputListComponent
|
||||
editNode={true}
|
||||
disabled={false}
|
||||
value={
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? [""]
|
||||
: t.data.node.template[
|
||||
n
|
||||
].value
|
||||
}
|
||||
onChange={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : t.data.node.template[n]
|
||||
.multiline ? (
|
||||
<ShadTooltip
|
||||
content={tweaks.buildContent(
|
||||
t.data.node.template[n]
|
||||
.value
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<TextAreaComponent
|
||||
disabled={false}
|
||||
editNode={true}
|
||||
value={
|
||||
!t.data.node.template[
|
||||
n
|
||||
].value ||
|
||||
t.data.node.template[
|
||||
n
|
||||
].value === ""
|
||||
? ""
|
||||
: t.data.node
|
||||
.template[n]
|
||||
.value
|
||||
}
|
||||
onChange={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node
|
||||
.template[n]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
) : (
|
||||
<InputComponent
|
||||
editNode={true}
|
||||
disabled={false}
|
||||
password={
|
||||
t.data.node.template[n]
|
||||
.password ?? false
|
||||
}
|
||||
value={
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[
|
||||
n
|
||||
].value
|
||||
}
|
||||
onChange={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
) : t.data.node.template[n].type ===
|
||||
"bool" ? (
|
||||
<div className="ml-auto">
|
||||
{" "}
|
||||
<ToggleShadComponent
|
||||
enabled={
|
||||
t.data.node.template[n]
|
||||
.value
|
||||
}
|
||||
setEnabled={(e) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = e;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
e,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
size="small"
|
||||
disabled={false}
|
||||
/>
|
||||
</div>
|
||||
) : t.data.node.template[n].type ===
|
||||
"file" ? (
|
||||
<ShadTooltip
|
||||
content={tweaks.buildContent(
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[n]
|
||||
.value
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto">
|
||||
<InputFileComponent
|
||||
editNode={true}
|
||||
disabled={false}
|
||||
value={
|
||||
t.data.node.template[n]
|
||||
.value ?? ""
|
||||
}
|
||||
onChange={(k: any) => {}}
|
||||
fileTypes={
|
||||
t.data.node.template[n]
|
||||
.fileTypes
|
||||
}
|
||||
suffixes={
|
||||
t.data.node.template[n]
|
||||
.suffixes
|
||||
}
|
||||
onFileChange={(
|
||||
k: any
|
||||
) => {}}
|
||||
></InputFileComponent>
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
) : t.data.node.template[n].type ===
|
||||
"float" ? (
|
||||
<div className="mx-auto">
|
||||
<FloatComponent
|
||||
disabled={false}
|
||||
editNode={true}
|
||||
value={
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[n]
|
||||
.value
|
||||
}
|
||||
onChange={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : t.data.node.template[n].type ===
|
||||
"str" &&
|
||||
t.data.node.template[n]
|
||||
.options ? (
|
||||
<div className="mx-auto">
|
||||
<Dropdown
|
||||
editNode={true}
|
||||
apiModal={true}
|
||||
options={
|
||||
t.data.node.template[n]
|
||||
.options
|
||||
}
|
||||
onSelect={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
value={
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[n]
|
||||
.value
|
||||
}
|
||||
></Dropdown>
|
||||
</div>
|
||||
) : t.data.node.template[n].type ===
|
||||
"int" ? (
|
||||
<div className="mx-auto">
|
||||
<IntComponent
|
||||
disabled={false}
|
||||
editNode={true}
|
||||
value={
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[n]
|
||||
.value
|
||||
}
|
||||
onChange={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : t.data.node.template[n].type ===
|
||||
"prompt" ? (
|
||||
<ShadTooltip
|
||||
content={tweaks.buildContent(
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[n]
|
||||
.value
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto">
|
||||
<PromptAreaComponent
|
||||
editNode={true}
|
||||
disabled={false}
|
||||
value={
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[
|
||||
n
|
||||
].value
|
||||
}
|
||||
onChange={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
) : t.data.node.template[n].type ===
|
||||
"code" ? (
|
||||
<ShadTooltip
|
||||
content={tweaks.buildContent(
|
||||
tweaks.getValue(
|
||||
t.data.node.template[n]
|
||||
.value,
|
||||
t.data,
|
||||
t.data.node.template[n]
|
||||
)
|
||||
)}
|
||||
>
|
||||
<div className="mx-auto">
|
||||
<CodeAreaComponent
|
||||
disabled={false}
|
||||
editNode={true}
|
||||
value={
|
||||
!t.data.node.template[n]
|
||||
.value ||
|
||||
t.data.node.template[n]
|
||||
.value === ""
|
||||
? ""
|
||||
: t.data.node.template[
|
||||
n
|
||||
].value
|
||||
}
|
||||
onChange={(k) => {
|
||||
setData((old) => {
|
||||
let newInputList =
|
||||
cloneDeep(old);
|
||||
newInputList[
|
||||
index
|
||||
].data.node.template[
|
||||
n
|
||||
].value = k;
|
||||
return newInputList;
|
||||
});
|
||||
tweaks.buildTweakObject(
|
||||
t["data"]["id"],
|
||||
k,
|
||||
t.data.node.template[n]
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</ShadTooltip>
|
||||
) : t.data.node.template[n].type ===
|
||||
"Any" ? (
|
||||
"-"
|
||||
) : (
|
||||
<div className="hidden"></div>
|
||||
)}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</AccordionComponent>
|
||||
)}
|
||||
|
||||
{tweaks.tweaksList.current.length === 0 && (
|
||||
<>
|
||||
<div className="pt-3">
|
||||
No tweaks are available for this flow.
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import { Listbox, Transition } from "@headlessui/react";
|
||||
import { Fragment, useContext, useEffect, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import { DropDownComponentType } from "../../types/components";
|
||||
import { classNames } from "../../utils/utils";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
|
@ -13,15 +12,13 @@ export default function Dropdown({
|
|||
numberOfOptions = 0,
|
||||
apiModal = false,
|
||||
}: DropDownComponentType) {
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
||||
let [internalValue, setInternalValue] = useState(
|
||||
value === "" || !value ? "Choose an option" : value
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setInternalValue(value === "" || !value ? "Choose an option" : value);
|
||||
}, [closePopUp]);
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,12 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { useEffect } from "react";
|
||||
import { FloatComponentType } from "../../types/components";
|
||||
|
||||
export default function FloatComponent({
|
||||
value,
|
||||
onChange,
|
||||
disableCopyPaste = false,
|
||||
disabled,
|
||||
editNode = false,
|
||||
}: FloatComponentType) {
|
||||
const [myValue, setMyValue] = useState(value ?? "");
|
||||
const { setDisableCopyPaste } = useContext(TabsContext);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
||||
const step = 0.1;
|
||||
const min = 0;
|
||||
const max = 1;
|
||||
|
|
@ -21,24 +14,13 @@ export default function FloatComponent({
|
|||
// Clear component state
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
onChange("");
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
|
||||
useEffect(() => {
|
||||
setMyValue(value);
|
||||
}, [closePopUp]);
|
||||
|
||||
return (
|
||||
<div className={"w-full " + (disabled ? "float-component-pointer" : "")}>
|
||||
<input
|
||||
onFocus={() => {
|
||||
if (disableCopyPaste) setDisableCopyPaste(true);
|
||||
}}
|
||||
onBlur={() => {
|
||||
if (disableCopyPaste) setDisableCopyPaste(false);
|
||||
}}
|
||||
type="number"
|
||||
step={step}
|
||||
min={min}
|
||||
|
|
@ -51,17 +33,17 @@ export default function FloatComponent({
|
|||
}
|
||||
}}
|
||||
max={max}
|
||||
value={myValue}
|
||||
value={value ?? ""}
|
||||
className={
|
||||
editNode
|
||||
"nopan nodrag noundo nocopy " +
|
||||
(editNode
|
||||
? "input-edit-node"
|
||||
: "input-primary" + (disabled ? " input-disable " : "")
|
||||
: "input-primary" + (disabled ? " input-disable " : ""))
|
||||
}
|
||||
placeholder={
|
||||
editNode ? "Number 0 to 1" : "Type a number from zero to one"
|
||||
}
|
||||
onChange={(e) => {
|
||||
setMyValue(e.target.value);
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { useContext } from "react";
|
||||
import { PopUpContext } from "../../../../contexts/popUpContext";
|
||||
import { useContext, useState } from "react";
|
||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||
import {
|
||||
DropdownMenu,
|
||||
|
|
@ -17,10 +16,10 @@ import IconComponent from "../../../genericIconComponent";
|
|||
import { Button } from "../../../ui/button";
|
||||
|
||||
export const MenuBar = ({ flows, tabId }) => {
|
||||
const { updateFlow, setTabId, addFlow } = useContext(TabsContext);
|
||||
const { addFlow } = useContext(TabsContext);
|
||||
const { setErrorData } = useContext(alertContext);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
const { undo, redo } = useContext(undoRedoContext);
|
||||
const [openSettings, setOpenSettings] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
|
@ -62,9 +61,10 @@ export const MenuBar = ({ flows, tabId }) => {
|
|||
<IconComponent name="Plus" className="header-menu-options" />
|
||||
New
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
openPopUp(<FlowSettingsModal />);
|
||||
setOpenSettings(true);
|
||||
}}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
|
|
@ -74,6 +74,7 @@ export const MenuBar = ({ flows, tabId }) => {
|
|||
/>
|
||||
Settings
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
undo();
|
||||
|
|
@ -94,6 +95,10 @@ export const MenuBar = ({ flows, tabId }) => {
|
|||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<FlowSettingsModal
|
||||
open={openSettings}
|
||||
setOpen={setOpenSettings}
|
||||
></FlowSettingsModal>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,56 +1,37 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { useEffect, useState } from "react";
|
||||
import { InputComponentType } from "../../types/components";
|
||||
import { classNames } from "../../utils/utils";
|
||||
|
||||
export default function InputComponent({
|
||||
value,
|
||||
onChange,
|
||||
disableCopyPaste = false,
|
||||
disabled,
|
||||
password,
|
||||
editNode = false,
|
||||
}: InputComponentType) {
|
||||
const [myValue, setMyValue] = useState(value ?? "");
|
||||
const [pwdVisible, setPwdVisible] = useState(false);
|
||||
const { setDisableCopyPaste } = useContext(TabsContext);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
||||
// Clear component state
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
onChange("");
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
|
||||
useEffect(() => {
|
||||
setMyValue(value ?? "");
|
||||
}, [closePopUp]);
|
||||
|
||||
return (
|
||||
<div className={disabled ? "input-component-div" : "relative"}>
|
||||
<input
|
||||
value={myValue}
|
||||
onFocus={() => {
|
||||
if (disableCopyPaste) setDisableCopyPaste(true);
|
||||
}}
|
||||
onBlur={() => {
|
||||
if (disableCopyPaste) setDisableCopyPaste(false);
|
||||
}}
|
||||
value={value}
|
||||
className={classNames(
|
||||
disabled ? " input-disable " : "",
|
||||
password && !pwdVisible && myValue !== ""
|
||||
? " text-clip password "
|
||||
: "",
|
||||
password && !pwdVisible && value !== "" ? " text-clip password " : "",
|
||||
editNode ? " input-edit-node " : " input-primary ",
|
||||
password && editNode ? "pr-8" : "",
|
||||
password && !editNode ? "pr-10" : ""
|
||||
password && !editNode ? "pr-10" : "",
|
||||
"nopan nodrag noundo nocopy"
|
||||
)}
|
||||
placeholder={password && editNode ? "Key" : "Type something..."}
|
||||
onChange={(e) => {
|
||||
setMyValue(e.target.value);
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { InputListComponentType } from "../../types/components";
|
||||
|
||||
import _ from "lodash";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
export default function InputListComponent({
|
||||
|
|
@ -10,21 +9,12 @@ export default function InputListComponent({
|
|||
onChange,
|
||||
disabled,
|
||||
editNode = false,
|
||||
onAddInput,
|
||||
}: InputListComponentType) {
|
||||
const [inputList, setInputList] = useState(value ?? [""]);
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setInputList([""]);
|
||||
onChange([""]);
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
|
||||
useEffect(() => {
|
||||
setInputList(value);
|
||||
}, [closePopUp]);
|
||||
}, [disabled]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -33,36 +23,31 @@ export default function InputListComponent({
|
|||
"flex flex-col gap-3"
|
||||
}
|
||||
>
|
||||
{inputList.map((i, idx) => {
|
||||
{value.map((i, idx) => {
|
||||
return (
|
||||
<div key={idx} className="flex w-full gap-3">
|
||||
<input
|
||||
type="text"
|
||||
value={i}
|
||||
className={
|
||||
editNode
|
||||
"nopan nodrag noundo nocopy " +
|
||||
(editNode
|
||||
? "input-edit-node "
|
||||
: "input-primary " + (disabled ? "input-disable" : "")
|
||||
: "input-primary " + (disabled ? "input-disable" : ""))
|
||||
}
|
||||
placeholder="Type something..."
|
||||
onChange={(e) => {
|
||||
setInputList((old) => {
|
||||
let newInputList = _.cloneDeep(old);
|
||||
newInputList[idx] = e.target.value;
|
||||
return newInputList;
|
||||
});
|
||||
onChange(inputList);
|
||||
let newInputList = _.cloneDeep(value);
|
||||
newInputList[idx] = e.target.value;
|
||||
onChange(newInputList);
|
||||
}}
|
||||
/>
|
||||
{idx === inputList.length - 1 ? (
|
||||
{idx === value.length - 1 ? (
|
||||
<button
|
||||
onClick={() => {
|
||||
setInputList((old) => {
|
||||
let newInputList = _.cloneDeep(old);
|
||||
newInputList.push("");
|
||||
return newInputList;
|
||||
});
|
||||
onChange(inputList);
|
||||
let newInputList = _.cloneDeep(value);
|
||||
newInputList.push("");
|
||||
onChange(newInputList);
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
|
|
@ -73,12 +58,9 @@ export default function InputListComponent({
|
|||
) : (
|
||||
<button
|
||||
onClick={() => {
|
||||
setInputList((old) => {
|
||||
let newInputList = _.cloneDeep(old);
|
||||
newInputList.splice(idx, 1);
|
||||
return newInputList;
|
||||
});
|
||||
onChange(inputList);
|
||||
let newInputList = _.cloneDeep(value);
|
||||
newInputList.splice(idx, 1);
|
||||
onChange(newInputList);
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
|
|
|
|||
|
|
@ -1,32 +1,21 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import { useEffect } from "react";
|
||||
import { FloatComponentType } from "../../types/components";
|
||||
|
||||
export default function IntComponent({
|
||||
value,
|
||||
onChange,
|
||||
disableCopyPaste = false,
|
||||
disabled,
|
||||
editNode = false,
|
||||
}: FloatComponentType) {
|
||||
const [myValue, setMyValue] = useState(value ?? "");
|
||||
const { setDisableCopyPaste } = useContext(TabsContext);
|
||||
const min = 0;
|
||||
const { closePopUp } = useContext(PopUpContext);
|
||||
|
||||
// Clear component state
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
onChange("");
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
|
||||
useEffect(() => {
|
||||
setMyValue(value);
|
||||
}, [closePopUp]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
|
|
@ -35,12 +24,6 @@ export default function IntComponent({
|
|||
}
|
||||
>
|
||||
<input
|
||||
onFocus={() => {
|
||||
if (disableCopyPaste) setDisableCopyPaste(true);
|
||||
}}
|
||||
onBlur={() => {
|
||||
if (disableCopyPaste) setDisableCopyPaste(false);
|
||||
}}
|
||||
onKeyDown={(event) => {
|
||||
if (
|
||||
event.key !== "Backspace" &&
|
||||
|
|
@ -67,15 +50,15 @@ export default function IntComponent({
|
|||
e.target.value = min.toString();
|
||||
}
|
||||
}}
|
||||
value={myValue}
|
||||
value={value ?? ""}
|
||||
className={
|
||||
editNode
|
||||
"nopan nodrag noundo nocopy " +
|
||||
(editNode
|
||||
? " input-edit-node "
|
||||
: " input-primary " + (disabled ? " input-disable" : "")
|
||||
: " input-primary " + (disabled ? " input-disable" : ""))
|
||||
}
|
||||
placeholder={editNode ? "Integer number" : "Type an integer number"}
|
||||
onChange={(e) => {
|
||||
setMyValue(e.target.value);
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import { TypeModal } from "../../constants/enums";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { postValidatePrompt } from "../../controllers/API";
|
||||
import GenericModal from "../../modals/genericModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
|
|
@ -17,18 +15,13 @@ export default function PromptAreaComponent({
|
|||
disabled,
|
||||
editNode = false,
|
||||
}: TextAreaComponentType) {
|
||||
const [myValue, setMyValue] = useState(value);
|
||||
const { openPopUp } = useContext(PopUpContext);
|
||||
const { reactFlowInstance } = useContext(typesContext);
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
onChange("");
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
}, [disabled]);
|
||||
|
||||
useEffect(() => {
|
||||
setMyValue(value);
|
||||
if (value !== "" && !editNode) {
|
||||
postValidatePrompt(field_name, value, nodeClass).then((apiReturn) => {
|
||||
if (apiReturn.data) {
|
||||
|
|
@ -37,56 +30,32 @@ export default function PromptAreaComponent({
|
|||
}
|
||||
});
|
||||
}
|
||||
}, [value, reactFlowInstance]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={disabled ? "pointer-events-none w-full " : " w-full"}>
|
||||
<div className="flex w-full items-center">
|
||||
<span
|
||||
onClick={() => {
|
||||
openPopUp(
|
||||
<GenericModal
|
||||
type={TypeModal.PROMPT}
|
||||
value={myValue}
|
||||
buttonText="Check & Save"
|
||||
modalTitle="Edit Prompt"
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
nodeClass={nodeClass}
|
||||
setNodeClass={setNodeClass}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node input-dialog"
|
||||
: (disabled ? " input-disable text-ring " : "") +
|
||||
" input-primary text-muted-foreground "
|
||||
}
|
||||
>
|
||||
{myValue !== "" ? myValue : "Type your prompt here"}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => {
|
||||
openPopUp(
|
||||
<GenericModal
|
||||
field_name={field_name}
|
||||
type={TypeModal.PROMPT}
|
||||
value={myValue}
|
||||
buttonText="Check & Save"
|
||||
modalTitle="Edit Prompt"
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
nodeClass={nodeClass}
|
||||
setNodeClass={setNodeClass}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
>
|
||||
<GenericModal
|
||||
type={TypeModal.PROMPT}
|
||||
value={value}
|
||||
buttonText="Check & Save"
|
||||
modalTitle="Edit Prompt"
|
||||
setValue={(t: string) => {
|
||||
onChange(t);
|
||||
}}
|
||||
nodeClass={nodeClass}
|
||||
setNodeClass={setNodeClass}
|
||||
>
|
||||
<div className="flex w-full items-center">
|
||||
<span
|
||||
className={
|
||||
editNode
|
||||
? "input-edit-node input-dialog"
|
||||
: (disabled ? " input-disable text-ring " : "") +
|
||||
" input-primary text-muted-foreground "
|
||||
}
|
||||
>
|
||||
{value !== "" ? value : "Type your prompt here..."}
|
||||
</span>
|
||||
{!editNode && (
|
||||
<IconComponent
|
||||
name="ExternalLink"
|
||||
|
|
@ -96,8 +65,8 @@ export default function PromptAreaComponent({
|
|||
}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { useContext, useEffect, useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { TypeModal } from "../../constants/enums";
|
||||
import { PopUpContext } from "../../contexts/popUpContext";
|
||||
import { TabsContext } from "../../contexts/tabsContext";
|
||||
import GenericModal from "../../modals/genericModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
|
@ -12,71 +10,50 @@ export default function TextAreaComponent({
|
|||
disabled,
|
||||
editNode = false,
|
||||
}: TextAreaComponentType) {
|
||||
const [myValue, setMyValue] = useState(value);
|
||||
const { openPopUp, closePopUp } = useContext(PopUpContext);
|
||||
const { setDisableCopyPaste } = useContext(TabsContext);
|
||||
|
||||
// Clear text area
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
setMyValue("");
|
||||
onChange("");
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
|
||||
useEffect(() => {
|
||||
setMyValue(value);
|
||||
}, [closePopUp]);
|
||||
}, [disabled]);
|
||||
|
||||
return (
|
||||
<div className={disabled ? "pointer-events-none w-full " : " w-full"}>
|
||||
<div className="flex w-full items-center">
|
||||
<input
|
||||
value={myValue}
|
||||
onFocus={() => {
|
||||
setDisableCopyPaste(true);
|
||||
}}
|
||||
onBlur={() => {
|
||||
setDisableCopyPaste(false);
|
||||
}}
|
||||
value={value}
|
||||
className={
|
||||
editNode
|
||||
(editNode
|
||||
? " input-edit-node "
|
||||
: " input-primary " + (disabled ? " input-disable" : "")
|
||||
: " input-primary " + (disabled ? " input-disable" : "")) +
|
||||
" nopan nodrag noundo nocopy w-full"
|
||||
}
|
||||
placeholder={"Type something..."}
|
||||
onChange={(e) => {
|
||||
setMyValue(e.target.value);
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
openPopUp(
|
||||
<GenericModal
|
||||
type={TypeModal.TEXT}
|
||||
buttonText="Finishing Editing"
|
||||
modalTitle="Edit Text"
|
||||
value={myValue}
|
||||
setValue={(t: string) => {
|
||||
setMyValue(t);
|
||||
onChange(t);
|
||||
}}
|
||||
<div>
|
||||
<GenericModal
|
||||
type={TypeModal.TEXT}
|
||||
buttonText="Finishing Editing"
|
||||
modalTitle="Edit Text"
|
||||
value={value}
|
||||
setValue={(t: string) => {
|
||||
onChange(t);
|
||||
}}
|
||||
>
|
||||
{!editNode && (
|
||||
<IconComponent
|
||||
name="ExternalLink"
|
||||
className={
|
||||
"icons-parameters-comp" +
|
||||
(disabled ? " text-ring" : " hover:text-accent-foreground")
|
||||
}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
>
|
||||
{!editNode && (
|
||||
<IconComponent
|
||||
name="ExternalLink"
|
||||
className={
|
||||
"icons-parameters-comp" +
|
||||
(disabled ? " text-ring" : " hover:text-accent-foreground")
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</GenericModal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export default function ToggleShadComponent({
|
|||
scaleX = 1;
|
||||
scaleY = 1;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={disabled ? "pointer-events-none cursor-not-allowed " : ""}>
|
||||
<Switch
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const DialogContent = React.forwardRef<
|
|||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed z-50 grid w-full gap-3 rounded-b-lg border bg-background p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
|
||||
"noundo nocopy fixed z-50 flex w-full flex-col gap-3 rounded-b-lg border bg-background p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
"nopan nodrag noundo nocopy flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ export default function RenameLabel(props) {
|
|||
ref={inputRef}
|
||||
onInput={resizeInput}
|
||||
className={cn(
|
||||
"rounded-md bg-transparent px-2 outline-ring hover:outline focus:border-none focus:outline active:outline",
|
||||
"nopan nodrag noundo nocopy rounded-md bg-transparent px-2 outline-ring hover:outline focus:border-none focus:outline active:outline",
|
||||
props.className
|
||||
)}
|
||||
onBlur={() => {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ const TabsList = React.forwardRef<
|
|||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
|
||||
"inline-flex h-10 items-center justify-center rounded-md p-1 text-muted-foreground",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ const TabsContextInitialValue: TabsContextType = {
|
|||
uploadFlow: () => {},
|
||||
hardReset: () => {},
|
||||
saveFlow: async (flow: FlowType) => {},
|
||||
disableCopyPaste: false,
|
||||
setDisableCopyPaste: (state: boolean) => {},
|
||||
lastCopiedSelection: null,
|
||||
setLastCopiedSelection: (selection: any) => {},
|
||||
tabsState: {},
|
||||
|
|
@ -585,16 +583,12 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
}
|
||||
}
|
||||
|
||||
const [disableCopyPaste, setDisableCopyPaste] = useState(false);
|
||||
|
||||
return (
|
||||
<TabsContext.Provider
|
||||
value={{
|
||||
saveFlow,
|
||||
lastCopiedSelection,
|
||||
setLastCopiedSelection,
|
||||
disableCopyPaste,
|
||||
setDisableCopyPaste,
|
||||
hardReset,
|
||||
tabId,
|
||||
setTabId,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue