add more types

This commit is contained in:
Igor Carvalho 2023-08-04 19:35:39 -03:00
commit cc26bb0c8f
23 changed files with 127 additions and 277 deletions

View file

@ -42,7 +42,7 @@ export default function GenericNode({
nodes: flow.data.nodes,
},
updateEdge: (edge) => {
flow.data.edges = edge;
flow.data!.edges = edge;
reactFlowInstance.setEdges(edge);
updateNodeInternals(data.id);
},

View file

@ -2,7 +2,7 @@ import { useEffect } from "react";
export function useOnClickOutside(ref, handler) {
useEffect(() => {
const listener = (event) => {
const listener = (event: Event) => {
// Do nothing if clicking ref's element or its children
if (!ref.current || ref.current.contains(event.target)) {
return;

View file

@ -4,6 +4,7 @@ import { Label } from "../../components/ui/label";
import { Textarea } from "../../components/ui/textarea";
import { InputProps } from "../../types/components";
import { readFlowsFromDatabase } from "../../controllers/API";
import { FlowType } from "../../types/flow";
export const EditFlowSettings: React.FC<InputProps> = ({
name,
@ -15,13 +16,12 @@ export const EditFlowSettings: React.FC<InputProps> = ({
tabId,
setName,
setDescription,
updateFlow,
}: InputProps): JSX.Element => {
const [isMaxLength, setIsMaxLength] = useState(false);
const nameLists = useRef<string[]>([]);
useEffect(() => {
readFlowsFromDatabase().then((flows) => {
flows.forEach((flow) => {
flows.forEach((flow: FlowType) => {
nameLists.current.push(flow.name);
});
});
@ -35,9 +35,9 @@ export const EditFlowSettings: React.FC<InputProps> = ({
setIsMaxLength(false);
}
if (!nameLists.current.includes(value)) {
setInvalidName(false);
setInvalidName!(false);
} else {
setInvalidName(true);
setInvalidName!(true);
}
setName(value);
};

View file

@ -42,13 +42,13 @@ export default function CodeTabsComponent({
tweaks,
}: codeTabsPropsType) {
const [isCopied, setIsCopied] = useState<Boolean>(false);
const [data, setData] = useState(flow ? flow["data"]["nodes"] : null);
const [data, setData] = useState(flow ? flow["data"]!["nodes"] : null);
const [openAccordion, setOpenAccordion] = useState<string[]>([]);
const { dark } = useContext(darkContext);
useEffect(() => {
if (flow && flow["data"]["nodes"]) {
setData(flow["data"]["nodes"]);
if (flow && flow["data"]!["nodes"]) {
setData(flow["data"]!["nodes"]);
}
}, [flow]);

View file

@ -1,4 +1,4 @@
import { createContext, useCallback, useContext, useState } from "react";
import { ReactNode, createContext, useCallback, useContext, useState } from "react";
const initialValue = {
updateSSEData: ({}) => {},

View file

@ -7,7 +7,7 @@ import {
useRef,
useState,
} from "react";
import { Node, addEdge } from "reactflow";
import { Edge, Node, ReactFlowJsonObject, addEdge } from "reactflow";
import ShortUniqueId from "short-unique-id";
import {
deleteFlowFromDatabase,
@ -18,8 +18,8 @@ import {
uploadFlowsToDatabase,
} from "../controllers/API";
import { APIClassType, APITemplateType } from "../types/api";
import { FlowType, NodeDataType, NodeType } from "../types/flow";
import { TabsContextType, TabsState } from "../types/tabs";
import { FlowType, NodeDataType, NodeType, TweaksType } from "../types/flow";
import { TabsContextType, TabsState, errorsVarType } from "../types/tabs";
import {
addVersionToDuplicates,
updateIds,
@ -78,7 +78,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
edges: any;
} | null>(null);
const [tabsState, setTabsState] = useState<TabsState>({});
const [getTweak, setTweak] = useState([]);
const [getTweak, setTweak] = useState<TweaksType[]>([]);
const newNodeId = useRef(uid());
function incrementNodeId() {
@ -133,8 +133,8 @@ export function TabsProvider({ children }: { children: ReactNode }) {
//get tabs from db
return readFlowsFromDatabase();
}
function processDBData(DbData) {
DbData.forEach((flow) => {
function processDBData(DbData: FlowType[]) {
DbData.forEach((flow: FlowType) => {
try {
if (!flow.data) {
return;
@ -147,7 +147,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
});
}
function processFlowEdges(flow) {
function processFlowEdges(flow: FlowType) {
if (!flow.data || !flow.data.edges) return;
flow.data.edges.forEach((edge) => {
edge.className = "";
@ -163,7 +163,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
node.data.node!.documentation = template["documentation"];
}
function processFlowNodes(flow) {
function processFlowNodes(flow: FlowType) {
if (!flow.data || !flow.data.nodes) return;
flow.data.nodes.forEach((node: NodeType) => {
const template = templates[node.data.type];
@ -191,7 +191,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
node: NodeType,
template: APIClassType
) {
flow.data.edges.forEach((edge) => {
flow.data!.edges.forEach((edge) => {
if (edge.source === node.id) {
edge.sourceHandle = edge.sourceHandle
?.split("|")
@ -213,7 +213,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
);
}
function updateStateWithDbData(tabsData) {
function updateStateWithDbData(tabsData: FlowType[]) {
setFlows(tabsData);
}
@ -356,7 +356,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
*/
function paste(
selectionInstance,
selectionInstance: {nodes: Node[], edges: Edge[]},
position: { x: number; y: number; paneX?: number; paneY?: number }
) {
let minimumX = Infinity;
@ -364,7 +364,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
let idsMap = {};
let nodes: Node<NodeDataType>[] = reactFlowInstance!.getNodes();
let edges = reactFlowInstance!.getEdges();
selectionInstance.nodes.forEach((n) => {
selectionInstance.nodes.forEach((n: Node) => {
if (n.position.y < minimumY) {
minimumY = n.position.y;
}
@ -406,14 +406,14 @@ export function TabsProvider({ children }: { children: ReactNode }) {
selectionInstance.edges.forEach((e) => {
let source = idsMap[e.source];
let target = idsMap[e.target];
let sourceHandleSplitted = e.sourceHandle.split("|");
let sourceHandleSplitted = e.sourceHandle!.split("|");
let sourceHandle =
sourceHandleSplitted[0] +
"|" +
source +
"|" +
sourceHandleSplitted.slice(2).join("|");
let targetHandleSplitted = e.targetHandle.split("|");
let targetHandleSplitted = e.targetHandle!.split("|");
let targetHandle =
targetHandleSplitted.slice(0, -1).join("|") + "|" + target;
let id =
@ -449,13 +449,13 @@ export function TabsProvider({ children }: { children: ReactNode }) {
newProject?: Boolean
): Promise<String | undefined> => {
if (newProject) {
let flowData = extractDataFromFlow(flow);
let flowData = extractDataFromFlow(flow!);
if (flowData.description == "") {
flowData.description = getRandomDescription();
}
// Create a new flow with a default name if no flow is provided.
const newFlow = createNewFlow(flowData, flow);
const newFlow = createNewFlow(flowData, flow!);
processFlowEdges(newFlow);
processFlowNodes(newFlow);
@ -480,13 +480,13 @@ export function TabsProvider({ children }: { children: ReactNode }) {
}
} else {
paste(
{ nodes: flow!.data.nodes, edges: flow!.data.edges },
{ nodes: flow!.data!.nodes, edges: flow!.data!.edges },
{ x: 10, y: 10 }
);
}
};
const extractDataFromFlow = (flow) => {
const extractDataFromFlow = (flow: FlowType) => {
let data = flow?.data ? flow.data : null;
const description = flow?.description ? flow.description : "";
@ -499,17 +499,17 @@ export function TabsProvider({ children }: { children: ReactNode }) {
return { data, description };
};
const updateEdges = (edges) => {
const updateEdges = (edges: Edge[]) => {
edges.forEach((edge) => {
edge.className =
(edge.targetHandle.split("|")[0] === "Text"
(edge.targetHandle!.split("|")[0] === "Text"
? "stroke-gray-800 "
: "stroke-gray-900 ") + " stroke-connection";
edge.animated = edge.targetHandle.split("|")[0] === "Text";
edge.animated = edge.targetHandle!.split("|")[0] === "Text";
});
};
const updateNodes = (nodes, edges) => {
const updateNodes = (nodes: Node[], edges: Edge[]) => {
nodes.forEach((node) => {
const template = templates[node.data.type];
if (!template) {
@ -520,7 +520,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
node.data.node.base_classes = template["base_classes"];
edges.forEach((edge) => {
if (edge.source === node.id) {
edge.sourceHandle = edge.sourceHandle
edge.sourceHandle = edge.sourceHandle!
.split("|")
.slice(0, 2)
.concat(template["base_classes"])
@ -536,14 +536,14 @@ export function TabsProvider({ children }: { children: ReactNode }) {
});
};
const createNewFlow = (flowData, flow) => ({
const createNewFlow = (flowData: { data: ReactFlowJsonObject | null; description: string; }, flow: FlowType) => ({
description: flowData.description,
name: flow?.name ?? getRandomName(),
data: flowData.data,
id: "",
});
const addFlowToLocalState = (newFlow) => {
const addFlowToLocalState = (newFlow: FlowType) => {
setFlows((prevState) => {
return [...prevState, newFlow];
});
@ -594,7 +594,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
});
}
} catch (err) {
setErrorData(err);
setErrorData(err as errorsVarType);
}
}

View file

@ -29,7 +29,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
useEffect(() => {
let delay = 1000; // Start delay of 1 second
let intervalId;
let intervalId: NodeJS.Timer;
let retryCount = 0; // Count of retry attempts
const maxRetryCount = 5; // Max retry attempts
@ -78,7 +78,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
// Start the initial interval.
intervalId = setInterval(getTypes, delay);
console.log(intervalId)
return () => {
// This will clear the interval when the component unmounts, or when the dependencies of the useEffect hook change.
clearInterval(intervalId!);

View file

@ -8,7 +8,7 @@ const api: AxiosInstance = axios.create({
baseURL: "",
});
function ApiInterceptor() {
function ApiInterceptor(): null {
const retryCounts = useRef([]);
const { setErrorData } = useContext(alertContext);
@ -55,7 +55,7 @@ function ApiInterceptor() {
}
// Function to sleep for a given duration in milliseconds
function sleep(ms) {
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

View file

@ -23,7 +23,7 @@ export async function getAll(): Promise<AxiosResponse<APIObjectType>> {
const GITHUB_API_URL = "https://api.github.com";
export async function getRepoStars(owner, repo) {
export async function getRepoStars(owner: string, repo: string) {
try {
const response = await api.get(`${GITHUB_API_URL}/repos/${owner}/${repo}`);
return response.data.stargazers_count;
@ -100,7 +100,7 @@ export async function getExamples(): Promise<FlowType[]> {
export async function saveFlowToDatabase(newFlow: {
name: string;
id: string;
data: ReactFlowJsonObject;
data: ReactFlowJsonObject | null;
description: string;
style?: FlowStyleType;
}): Promise<FlowType> {
@ -179,7 +179,7 @@ export async function downloadFlowsFromDatabase() {
}
}
export async function uploadFlowsToDatabase(flows) {
export async function uploadFlowsToDatabase(flows: FlowType[]) {
try {
const response = await api.post(`/api/v1/flows/upload/`, flows);

View file

@ -3,6 +3,7 @@ import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/theme-twilight";
import {
MutableRefObject,
ReactNode,
forwardRef,
useContext,
@ -15,7 +16,7 @@ import CodeTabsComponent from "../../components/codeTabsComponent";
import IconComponent from "../../components/genericIconComponent";
import { EXPORT_CODE_DIALOG } from "../../constants/constants";
import { TabsContext } from "../../contexts/tabsContext";
import { FlowType } from "../../types/flow/index";
import { FlowType, NodeType } from "../../types/flow/index";
import { buildTweaks } from "../../utils/reactflowUtils";
import {
getCurlCode,
@ -25,6 +26,7 @@ import {
} from "../../utils/utils";
import BaseModal from "../baseModal";
import { tweakType } from "../../types/components";
import { APITemplateType } from "../../types/api";
const ApiModal = forwardRef(
(
@ -42,7 +44,7 @@ const ApiModal = forwardRef(
const [open, setOpen] = useState(false);
const [activeTab, setActiveTab] = useState("0");
const tweak = useRef<tweakType[]>([]);
const tweaksList = useRef([]);
const tweaksList = useRef<string[]>([]);
const { setTweak, getTweak, tabsState } = useContext(TabsContext);
const pythonApiCode = getPythonApiCode(flow, tweak.current, tabsState);
const curl_code = getCurlCode(flow, tweak.current, tabsState);
@ -180,7 +182,7 @@ const ApiModal = forwardRef(
}, [flow["data"]["nodes"], open]);
function filterNodes() {
let arrNodesWithValues = [];
let arrNodesWithValues: string[] = [];
flow["data"]["nodes"].forEach((t) => {
Object.keys(t["data"]["node"]["template"])
@ -205,7 +207,7 @@ const ApiModal = forwardRef(
return self.indexOf(value) === index;
});
}
function buildTweakObject(tw, changes, template) {
function buildTweakObject(tw: string, changes: string | string[], template: APITemplateType) {
if (template.type === "float") {
changes = parseFloat(changes);
}
@ -255,7 +257,7 @@ const ApiModal = forwardRef(
setTweak(tweak.current);
}
function buildContent(value) {
function buildContent(value: string) {
const htmlContent = (
<div className="w-[200px]">
<span>{value != null && value != "" ? value : "None"}</span>
@ -264,7 +266,7 @@ const ApiModal = forwardRef(
return htmlContent;
}
function getValue(value, node, template) {
function getValue(value: string, node: NodeType, template: APITemplateType) {
let returnValue = value ?? "";
if (getTweak.length > 0) {

View file

@ -27,6 +27,7 @@ import { typesContext } from "../../contexts/typesContext";
import { NodeDataType } from "../../types/flow";
import { classNames } from "../../utils/utils";
import BaseModal from "../baseModal";
import { TabsState } from "../../types/tabs";
const EditNodeModal = forwardRef(
(
@ -310,7 +311,8 @@ const EditNodeModal = forwardRef(
className="mt-3"
onClick={() => {
setData(cloneDeep(myData)); //saves data with actual state of modal
setTabsState((prev) => {
//@ts-ignore
setTabsState((prev: TabsState) => {
return {
...prev,
[tabId]: {

View file

@ -1,180 +0,0 @@
import { useState } from "react";
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 ToggleComponent from "../../../../components/toggleComponent";
import { classNames } from "../../../../utils/utils";
export default function ModalField({
data,
title,
required,
id,
name,
type,
index,
}) {
const [enabled, setEnabled] = useState(
data.node.template[name]?.value ?? false
);
const display =
type === "str" ||
type === "int" ||
type === "prompt" ||
type === "bool" ||
type === "float" ||
type === "file" ||
type === "code";
return (
<div
className={classNames(
"flex w-full flex-row items-center justify-between",
display ? "" : "hidden",
Object.keys(data.node.template).filter(
(t) =>
t.charAt(0) !== "_" &&
data.node.template[t].advanced &&
data.node.template[t].show
).length -
1 ===
index
? "pb-4"
: ""
)}
>
{display && (
<div>
<span className="mx-2">{title}</span>
<span className="text-status-red">{required ? " *" : ""}</span>
</div>
)}
{type === "str" && !data.node.template[name].options ? (
<div className="w-1/2">
{data.node.template[name].list ? (
<InputListComponent
disabled={false}
value={
!data.node.template[name].value ||
data.node.template[name].value === ""
? [""]
: data.node.template[name].value
}
onChange={(t: string[]) => {
data.node.template[name].value = t;
}}
/>
) : data.node.template[name].multiline ? (
<TextAreaComponent
disabled={false}
value={data.node.template[name].value ?? ""}
onChange={(t: string | string[]) => {
data.node.template[name].value = t;
}}
/>
) : (
<InputComponent
disabled={false}
password={data.node.template[name].password ?? false}
value={data.node.template[name].value ?? ""}
onChange={(t) => {
data.node.template[name].value = t;
}}
/>
)}
</div>
) : type === "bool" ? (
<div className="ml-auto">
{" "}
<ToggleComponent
disabled={false}
enabled={enabled}
setEnabled={(t) => {
data.node.template[name].value = t;
setEnabled(t);
}}
size="small"
/>
</div>
) : type === "float" ? (
<div className="w-1/2">
<FloatComponent
disabled={false}
value={data.node.template[name].value ?? ""}
onChange={(t) => {
data.node.template[name].value = t;
}}
/>
</div>
) : type === "str" && data.node.template[name].options ? (
<div className="w-1/2">
<Dropdown
options={data.node.template[name].options}
onSelect={(newValue) => (data.node.template[name].value = newValue)}
value={data.node.template[name].value ?? "Choose an option"}
></Dropdown>
</div>
) : type === "int" ? (
<div className="w-1/2">
<IntComponent
disabled={false}
value={data.node.template[name].value ?? ""}
onChange={(t) => {
data.node.template[name].value = t;
}}
/>
</div>
) : type === "file" ? (
<div className="w-1/2">
<InputFileComponent
disabled={false}
value={data.node.template[name].value ?? ""}
onChange={(t: string | string[]) => {
data.node.template[name].value = t;
}}
fileTypes={data.node.template[name].fileTypes}
suffixes={data.node.template[name].suffixes}
onFileChange={(t: string) => {
data.node.template[name].file_path = t;
}}
></InputFileComponent>
</div>
) : type === "prompt" ? (
<div className="w-1/2">
<PromptAreaComponent
field_name={name}
disabled={false}
value={data.node.template[name].value ?? ""}
onChange={(t: string | string[]) => {
data.node.template[name].value = t;
}}
/>
</div>
) : type === "code" ? (
<div className="w-1/2">
<CodeAreaComponent
dynamic={data.node.template[name].dynamic ?? false}
setNodeClass={(nodeClass) => {
data.node = nodeClass;
}}
nodeClass={data.node}
disabled={false}
value={data.node.template[name].value ?? ""}
onChange={(t: string | string[]) => {
data.node.template[name].value = t;
}}
/>
</div>
) : (
<div className="hidden"></div>
)}
</div>
);
}

View file

@ -47,7 +47,6 @@ export default function FlowSettingsModal({
tabId={tabId}
setName={setName}
setDescription={setDescription}
updateFlow={updateFlow}
/>
</BaseModal.Content>

View file

@ -25,6 +25,7 @@ import { Textarea } from "../../components/ui/textarea";
import { CHAT_FORM_DIALOG_SUBTITLE } from "../../constants/constants";
import { TabsContext } from "../../contexts/tabsContext";
import { validateNodes } from "../../utils/reactflowUtils";
import { TabsState, errorsVarType } from "../../types/tabs";
export default function FormModal({
flow,
@ -354,7 +355,8 @@ export default function FormModal({
name: flow.name,
description: flow.description,
});
setTabsState((old) => {
//@ts-ignore
setTabsState((old: TabsState) => {
if (!chatKey) return old;
let newTabsState = _.cloneDeep(old);
newTabsState[id.current].formKeysData.input_keys![chatKey] = "";
@ -468,7 +470,8 @@ export default function FormModal({
tabsState[id.current].formKeysData.input_keys![i]
}
onChange={(e) => {
setTabsState((old) => {
//@ts-ignore
setTabsState((old: TabsState) => {
let newTabsState = _.cloneDeep(old);
newTabsState[id.current].formKeysData.input_keys![
i
@ -576,7 +579,8 @@ export default function FormModal({
sendMessage={sendMessage}
setChatValue={(value) => {
setChatValue(value);
setTabsState((old) => {
//@ts-ignore
setTabsState((old: TabsState) => {
let newTabsState = _.cloneDeep(old);
newTabsState[id.current].formKeysData.input_keys![
chatKey!

View file

@ -42,7 +42,7 @@ export default function GenericModal({
const [wordsHighlight, setWordsHighlight] = useState<string[]>([]);
const { setErrorData, setSuccessData, setNoticeData } =
useContext(alertContext);
const ref = useRef<HTMLDivElement>();
const ref = useRef<HTMLTextAreaElement | undefined>();
const divRef = useRef(null);
const divRefPrompt = useRef(null);
@ -208,7 +208,7 @@ export default function GenericModal({
<TextAreaContentView />
) : type !== TypeModal.PROMPT ? (
<Textarea
ref={ref}
ref={ref!}
className="form-input h-full w-full rounded-lg focus-visible:ring-1"
value={inputValue}
onChange={(e) => {

View file

@ -1,11 +1,12 @@
import _ from "lodash";
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { MouseEvent, useCallback, useContext, useEffect, useRef, useState } from "react";
import ReactFlow, {
Background,
Connection,
Controls,
Edge,
EdgeChange,
Node,
NodeChange,
NodeDragHandler,
OnEdgesDelete,
@ -30,6 +31,7 @@ import { isValidConnection } from "../../../../utils/reactflowUtils";
import { isWrappedWithClass } from "../../../../utils/utils";
import ConnectionLineComponent from "../ConnectionLineComponent";
import ExtraSidebar from "../extraSidebarComponent";
import { TabsState } from "../../../../types/tabs";
const nodeTypes = {
genericNode: GenericNode,
@ -51,7 +53,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
} = useContext(TabsContext);
const { types, reactFlowInstance, setReactFlowInstance, templates } =
useContext(typesContext);
const reactFlowWrapper = useRef(null);
const reactFlowWrapper = useRef<HTMLDivElement>(null);
const { takeSnapshot } = useContext(undoRedoContext);
@ -80,8 +82,8 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
event.preventDefault();
let bounds = reactFlowWrapper.current?.getBoundingClientRect();
paste(lastCopiedSelection, {
x: position.x - bounds.left,
y: position.y - bounds.top,
x: position.x - bounds!.left,
y: position.y - bounds!.top,
});
}
if (
@ -93,7 +95,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
}
}
};
const handleMouseMove = (event: MouseEvent) => {
const handleMouseMove = (event) => {
setPosition({ x: event.clientX, y: event.clientY });
};
@ -147,7 +149,8 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
let newX = _.cloneDeep(x);
return newX;
});
setTabsState((prev) => {
//@ts-ignore
setTabsState((prev: TabsState) => {
return {
...prev,
[tabId]: {
@ -163,7 +166,8 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
const onNodesChangeMod = useCallback(
(s: NodeChange[]) => {
onNodesChange(s);
setTabsState((prev) => {
//@ts-ignore
setTabsState((prev: TabsState) => {
return {
...prev,
[tabId]: {
@ -243,9 +247,9 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
// If data type is not "chatInput" or if there are no "chatInputNode" nodes present in the ReactFlow instance, create a new node
// Calculate the position where the node should be created
const position = reactFlowInstance?.project({
x: event.clientX - reactflowBounds.left,
y: event.clientY - reactflowBounds.top,
const position = reactFlowInstance!.project({
x: event.clientX - reactflowBounds!.left,
y: event.clientY - reactflowBounds!.top,
});
// Generate a unique node ID
@ -297,7 +301,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
}, []);
const onDelete = useCallback(
(mynodes) => {
(mynodes: Node[]) => {
takeSnapshot();
setEdges(
edges.filter(
@ -322,7 +326,6 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
[reactFlowInstance, setEdges]
);
// IS THIS RIGHT?
const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => {
if (!edgeUpdateSuccessful.current) {
setEdges((eds) => eds.filter((e) => e.id !== edge.id));
@ -335,7 +338,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
const onSelectionEnd = useCallback(() => {
setSelectionEnded(true);
}, []);
const onSelectionStart = useCallback((event) => {
const onSelectionStart = useCallback((event: MouseEvent) => {
event.preventDefault();
setSelectionEnded(false);
}, []);
@ -349,7 +352,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
}
}, [selectionEnded, lastSelection]);
const onSelectionChange = useCallback((flow): void => {
const onSelectionChange = useCallback((flow: OnSelectionChangeParams): void => {
setLastSelection(flow);
}, []);
@ -378,7 +381,6 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element {
onEdgesChange={onEdgesChangeMod}
onConnect={onConnect}
disableKeyboardA11y={true}
onLoad={setReactFlowInstance}
onInit={setReactFlowInstance}
nodeTypes={nodeTypes}
onEdgeUpdate={onEdgeUpdate}

View file

@ -1,10 +1,10 @@
import { Edge, Node, Viewport } from "reactflow";
//kind and class are just representative names to represent the actual structure of the object received by the API
export type APIObjectType = { kind: APIKindType; [key: string]: APIKindType };
export type APIObjectType = { kind?: APIKindType; [key: string]: APIKindType };
export type APIKindType = { class: APIClassType; [key: string]: APIClassType };
export type APITemplateType = {
variable: TemplateVariableType;
variable?: TemplateVariableType;
[key: string]: TemplateVariableType;
};
export type APIClassType = {

View file

@ -177,10 +177,10 @@ export type InputProps = {
maxLength?: number;
flows: Array<{ id: string; name: string; description: string }>;
tabId: string;
invalidName: boolean;
invalidName?: boolean;
setName: (name: string) => void;
setDescription: (description: string) => void;
setInvalidName: (invalidName: boolean) => void;
setInvalidName?: (invalidName: boolean) => void;
};
export type TooltipProps = {
@ -211,8 +211,24 @@ export type groupedObjType = {
type: string;
};
type test = {
[char: string]: string;
}
export type tweakType = {
[key: string]: object;
[key: string]: {
[char: string]: string;
};
};
export type apiModalTweakType = {
current: Array<{
[key: string]: {
[char: string]: string | number;
}
}>;
};
export type nodeToolbarType = {
@ -240,7 +256,7 @@ export type chatTriggerPropType = {
};
export type headerFlowsType = {
data: ReactFlowJsonObject;
data: ReactFlowJsonObject | null;
description: string;
id: string;
name: string;
@ -408,14 +424,14 @@ export type codeTabsPropsType = {
buildContent?: (value: string) => ReactNode;
getValue?: (
value: string,
node: getValueNodeType,
template: codeTabsFuncTempType
node: NodeType,
template: APITemplateType
) => string;
buildTweakObject?: (
tw: string,
changes: string | string[] | boolean,
template: codeTabsFuncTempType
) => string;
changes: string | string[] | boolean | number,
template: APITemplateType
) => string | void;
};
};

View file

@ -4,7 +4,7 @@ import { APIClassType } from "../api/index";
export type FlowType = {
name: string;
id: string;
data: ReactFlowJsonObject;
data: ReactFlowJsonObject | null;
description: string;
style?: FlowStyleType;
};

View file

@ -1,3 +1,4 @@
import { Dispatch, SetStateAction } from "react";
import { FlowType, TweaksType } from "../flow";
export type TabsContextType = {
@ -33,7 +34,7 @@ export type TabsContextType = {
) => void;
lastCopiedSelection: { nodes: any; edges: any } | null;
setLastCopiedSelection: (selection: { nodes: any; edges: any }) => void;
setTweak: (tweak: TweaksType) => void;
setTweak: Dispatch<SetStateAction<TweaksType[]>>;
getTweak: TweaksType[];
};
@ -48,3 +49,8 @@ export type TabsState = {
};
};
};
export type errorsVarType = {
title: string;
list?: Array<string>;
};

View file

@ -1,6 +1,6 @@
import { Edge, Node, ReactFlowInstance } from "reactflow";
import { AlertItemType } from "../alerts";
import { APIClassType } from "../api";
import { APIClassType, APIObjectType } from "../api";
const types: { [char: string]: string } = {};
const template: { [char: string]: APIClassType } = {};
@ -14,7 +14,7 @@ export type typesContextType = {
setTypes: (newState: {}) => void;
templates: typeof template;
setTemplates: (newState: {}) => void;
data: typeof data;
data: APIObjectType;
setData: (newState: {}) => void;
};

View file

@ -1,5 +1,5 @@
import _ from "lodash";
import { Connection, ReactFlowInstance } from "reactflow";
import { Connection, ReactFlowInstance, ReactFlowJsonObject } from "reactflow";
import { APITemplateType } from "../types/api";
import { FlowType, NodeType } from "../types/flow";
import { cleanEdgesType } from "../types/utils/reactflowUtils";
@ -93,7 +93,7 @@ export function isValidConnection(
export function removeApiKeys(flow: FlowType): FlowType {
let cleanFLow = _.cloneDeep(flow);
cleanFLow.data.nodes.forEach((node) => {
cleanFLow.data!.nodes.forEach((node) => {
for (const key in node.data.node.template) {
if (node.data.node.template[key].password) {
node.data.node.template[key].value = "";
@ -126,7 +126,7 @@ export function updateTemplate(
return clonedObject;
}
export function updateIds(newFlow, getNodeId) {
export function updateIds(newFlow: ReactFlowJsonObject, getNodeId: (type: string) => string) {
let idsMap = {};
newFlow.nodes.forEach((n: NodeType) => {
@ -141,14 +141,14 @@ export function updateIds(newFlow, getNodeId) {
newFlow.edges.forEach((e) => {
e.source = idsMap[e.source];
e.target = idsMap[e.target];
let sourceHandleSplitted = e.sourceHandle.split("|");
let sourceHandleSplitted = e.sourceHandle!.split("|");
e.sourceHandle =
sourceHandleSplitted[0] +
"|" +
e.source +
"|" +
sourceHandleSplitted.slice(2).join("|");
let targetHandleSplitted = e.targetHandle.split("|");
let targetHandleSplitted = e.targetHandle!.split("|");
e.targetHandle =
targetHandleSplitted.slice(0, -1).join("|") + "|" + e.target;
e.id =
@ -161,8 +161,8 @@ export function updateIds(newFlow, getNodeId) {
});
}
export function buildTweaks(flow) {
return flow.data.nodes.reduce((acc, node) => {
export function buildTweaks(flow: FlowType) {
return flow.data!.nodes.reduce((acc, node) => {
acc[node.data.id] = {};
return acc;
}, {});

View file

@ -89,7 +89,7 @@ export function checkUpperWords(str: string): string {
export const isWrappedWithClass = (event: any, className: string | undefined) =>
event.target.closest(`.${className}`);
export function groupByFamily(data, baseClasses: string, left: boolean, flow?: NodeType[]): groupedObjType[] {
export function groupByFamily(data: APIObjectType, baseClasses: string, left: boolean, flow?: NodeType[]): groupedObjType[] {
const baseClassesSet = new Set(baseClasses.split("\n"));
let arrOfPossibleInputs: Array<{ category: string; nodes: string[]; full: boolean; }> = [];
let arrOfPossibleOutputs: Array<{ category: string; nodes: string[]; full: boolean; }> = [];
@ -104,7 +104,7 @@ export function groupByFamily(data, baseClasses: string, left: boolean, flow?: N
"int",
]);
const checkBaseClass = (t: any) =>
const checkBaseClass = (t) =>
t.type &&
t.show &&
((!excludeTypes.has(t.type) && baseClassesSet.has(t.type)) ||
@ -234,7 +234,7 @@ export function varHighlightHTML({ name }: IVarHighlightType): string {
return html;
}
export function buildTweakObject(tweak: tweakType[]): string {
export function buildTweakObject(tweak: tweakType[]) {
tweak.forEach((el) => {
Object.keys(el).forEach((key) => {
for (let kp in el[key]) {
@ -244,7 +244,6 @@ export function buildTweakObject(tweak: tweakType[]): string {
}
});
});
const tweakString = JSON.stringify(tweak.at(-1), null, 2);
return tweakString;
}