Merge branch 'zustand/io/migration' into state_theories
This commit is contained in:
commit
481df3de8f
67 changed files with 798 additions and 599 deletions
|
|
@ -16,6 +16,7 @@ import PromptAreaComponent from "../../../../components/promptComponent";
|
|||
import TextAreaComponent from "../../../../components/textAreaComponent";
|
||||
import ToggleShadComponent from "../../../../components/toggleShadComponent";
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
import { RefreshButton } from "../../../../components/ui/refreshButton";
|
||||
import {
|
||||
INPUT_HANDLER_HOVER,
|
||||
LANGFLOW_SUPPORTED_TYPES,
|
||||
|
|
@ -68,7 +69,7 @@ export default function ParameterComponent({
|
|||
const nodes = useFlowStore((state) => state.nodes);
|
||||
const edges = useFlowStore((state) => state.edges);
|
||||
const setNode = useFlowStore((state) => state.setNode);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const flow = currentFlow?.data?.nodes ?? null;
|
||||
|
||||
const groupedEdge = useRef(null);
|
||||
|
|
@ -85,7 +86,12 @@ export default function ParameterComponent({
|
|||
|
||||
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
|
||||
|
||||
const handleUpdateValues = async (name: string, data: NodeDataType) => {
|
||||
const handleUpdateValues = async (
|
||||
name: string,
|
||||
data: NodeDataType,
|
||||
delayAnimation: boolean = true
|
||||
) => {
|
||||
setIsLoading(true);
|
||||
const code = data.node?.template["code"]?.value;
|
||||
if (!code) {
|
||||
console.error("Code not found in the template");
|
||||
|
|
@ -95,13 +101,48 @@ export default function ParameterComponent({
|
|||
try {
|
||||
const res = await postCustomComponentUpdate(code, name);
|
||||
if (res.status === 200 && data.node?.template) {
|
||||
data.node!.template[name] = res.data.template[name];
|
||||
setNode(data.id, (oldNode) => {
|
||||
let newNode = cloneDeep(oldNode);
|
||||
|
||||
newNode.data = {
|
||||
...newNode.data,
|
||||
};
|
||||
|
||||
newNode.data.node.template[name] = res.data.template[name];
|
||||
|
||||
return newNode;
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
setErrorData(err as { title: string; list?: Array<string> });
|
||||
}
|
||||
|
||||
renderTooltips();
|
||||
if (delayAnimation) {
|
||||
try {
|
||||
// Wait for at least 500 milliseconds
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
// Continue with the request
|
||||
// If the request takes longer than 500 milliseconds, it will not wait an additional 500 milliseconds
|
||||
} catch (error) {
|
||||
console.error("Error occurred while waiting for refresh:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
} else setIsLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
function fetchData() {
|
||||
if (
|
||||
data.node?.template[name]?.refresh &&
|
||||
Object.keys(data.node?.template[name]?.options ?? {}).length === 0
|
||||
) {
|
||||
handleUpdateValues(name, data, false);
|
||||
}
|
||||
}
|
||||
fetchData();
|
||||
}, []);
|
||||
const handleOnNewValue = (
|
||||
newValue: string | string[] | boolean | Object[]
|
||||
): void => {
|
||||
|
|
@ -314,16 +355,25 @@ export default function ParameterComponent({
|
|||
<div
|
||||
className={
|
||||
"w-full truncate text-sm" +
|
||||
(left ? "" : " text-end") +
|
||||
(left ? "" : " flex items-center justify-end gap-2") +
|
||||
(info !== "" ? " flex items-center" : "")
|
||||
}
|
||||
>
|
||||
{!left && data.node?.frozen && (
|
||||
<div>
|
||||
<IconComponent className="h-5 w-5 text-ice" name={"Snowflake"} />
|
||||
</div>
|
||||
)}
|
||||
{proxy ? (
|
||||
<ShadTooltip content={<span>{proxy.id}</span>}>
|
||||
<span>{title}</span>
|
||||
<span className={!left && data.node?.frozen ? " text-ice" : ""}>
|
||||
{title}
|
||||
</span>
|
||||
</ShadTooltip>
|
||||
) : (
|
||||
title
|
||||
<span className={!left && data.node?.frozen ? " text-ice" : ""}>
|
||||
{title}
|
||||
</span>
|
||||
)}
|
||||
<span className={(info === "" ? "" : "ml-1 ") + " text-status-red"}>
|
||||
{required ? " *" : ""}
|
||||
|
|
@ -390,16 +440,31 @@ export default function ParameterComponent({
|
|||
!data.node?.template[name].options ? (
|
||||
<div className="mt-2 w-full">
|
||||
{data.node?.template[name].list ? (
|
||||
<InputListComponent
|
||||
disabled={disabled}
|
||||
value={
|
||||
!data.node.template[name].value ||
|
||||
data.node.template[name].value === ""
|
||||
? [""]
|
||||
: data.node.template[name].value
|
||||
}
|
||||
onChange={handleOnNewValue}
|
||||
/>
|
||||
<div className="w-5/6 flex-grow">
|
||||
<InputListComponent
|
||||
disabled={disabled}
|
||||
value={
|
||||
!data.node.template[name].value ||
|
||||
data.node.template[name].value === ""
|
||||
? [""]
|
||||
: data.node.template[name].value
|
||||
}
|
||||
onChange={handleOnNewValue}
|
||||
/>
|
||||
{data.node?.template[name].refresh && (
|
||||
<div className="w-1/6">
|
||||
<RefreshButton
|
||||
isLoading={isLoading}
|
||||
disabled={disabled}
|
||||
name={name}
|
||||
data={data}
|
||||
className="extra-side-bar-buttons ml-2 mt-1"
|
||||
handleUpdateValues={handleUpdateValues}
|
||||
id={"refresh-button-" + name}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : data.node?.template[name].multiline ? (
|
||||
<TextAreaComponent
|
||||
disabled={disabled}
|
||||
|
|
@ -420,14 +485,17 @@ export default function ParameterComponent({
|
|||
/>
|
||||
</div>
|
||||
{data.node?.template[name].refresh && (
|
||||
<button
|
||||
className="extra-side-bar-buttons ml-2 mt-1 w-1/6"
|
||||
onClick={() => {
|
||||
handleUpdateValues(name, data);
|
||||
}}
|
||||
>
|
||||
<IconComponent name="RefreshCcw" />
|
||||
</button>
|
||||
<div className="w-1/6">
|
||||
<RefreshButton
|
||||
isLoading={isLoading}
|
||||
disabled={disabled}
|
||||
name={name}
|
||||
data={data}
|
||||
className="extra-side-bar-buttons ml-2 mt-1"
|
||||
handleUpdateValues={handleUpdateValues}
|
||||
id={"refresh-button-" + name}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -454,11 +522,14 @@ export default function ParameterComponent({
|
|||
</div>
|
||||
) : left === true &&
|
||||
type === "str" &&
|
||||
data.node?.template[name].options ? (
|
||||
(data.node?.template[name].options ||
|
||||
data.node?.template[name]?.refresh) ? (
|
||||
// TODO: Improve CSS
|
||||
<div className="mt-2 flex w-full items-center">
|
||||
<div className="w-5/6 flex-grow">
|
||||
<Dropdown
|
||||
disabled={disabled}
|
||||
isLoading={isLoading}
|
||||
options={data.node.template[name].options}
|
||||
onSelect={handleOnNewValue}
|
||||
value={data.node.template[name].value ?? "Choose an option"}
|
||||
|
|
@ -466,14 +537,17 @@ export default function ParameterComponent({
|
|||
/>
|
||||
</div>
|
||||
{data.node?.template[name].refresh && (
|
||||
<button
|
||||
className="extra-side-bar-buttons ml-2 mt-1 w-1/6"
|
||||
onClick={() => {
|
||||
handleUpdateValues(name, data);
|
||||
}}
|
||||
>
|
||||
<IconComponent name="RefreshCcw" />
|
||||
</button>
|
||||
<div className="w-1/6">
|
||||
<RefreshButton
|
||||
isLoading={isLoading}
|
||||
disabled={disabled}
|
||||
name={name}
|
||||
data={data}
|
||||
className="extra-side-bar-buttons ml-2 mt-1"
|
||||
handleUpdateValues={handleUpdateValues}
|
||||
id={"refresh-button-" + name}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : left === true && type === "code" ? (
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ export default function GenericNode({
|
|||
if (duration === undefined) {
|
||||
return "";
|
||||
} else {
|
||||
return `Duration: ${duration}`;
|
||||
return `${duration}`;
|
||||
}
|
||||
};
|
||||
const durationString = getDurationString(validationStatus?.data.duration);
|
||||
|
|
@ -758,15 +758,6 @@ export default function GenericNode({
|
|||
showNode={showNode}
|
||||
/>
|
||||
)}
|
||||
<div>
|
||||
{lastRunTime && (
|
||||
<div className="flex justify-center text-muted-foreground">
|
||||
{lastRunTime.split("\n").map((line, index) => (
|
||||
<div key={index}>{line}</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import { classNames } from "../../utils/utils";
|
|||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
export default function Dropdown({
|
||||
disabled,
|
||||
isLoading,
|
||||
value,
|
||||
options,
|
||||
onSelect,
|
||||
|
|
@ -27,6 +29,7 @@ export default function Dropdown({
|
|||
<>
|
||||
<Listbox
|
||||
value={internalValue}
|
||||
disabled={disabled}
|
||||
onChange={(value) => {
|
||||
setInternalValue(value);
|
||||
onSelect(value);
|
||||
|
|
@ -129,11 +132,17 @@ export default function Dropdown({
|
|||
</>
|
||||
) : (
|
||||
<>
|
||||
<div>
|
||||
<span className="text-sm italic">
|
||||
No parameters are available for display.
|
||||
</span>
|
||||
</div>
|
||||
{(!isLoading && (
|
||||
<div>
|
||||
<span className="text-sm italic">
|
||||
No parameters are available for display.
|
||||
</span>
|
||||
</div>
|
||||
)) || (
|
||||
<div>
|
||||
<span className="text-sm italic">Loading...</span>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { forwardRef } from "react";
|
||||
import dynamicIconImports from "lucide-react/dynamicIconImports";
|
||||
import { Suspense, forwardRef, lazy } from "react";
|
||||
import { IconComponentProps } from "../../types/components";
|
||||
import { nodeIconsLucide } from "../../utils/styleUtils";
|
||||
|
||||
|
|
@ -14,7 +15,13 @@ const ForwardedIconComponent = forwardRef(
|
|||
}: IconComponentProps,
|
||||
ref
|
||||
) => {
|
||||
const TargetIcon = nodeIconsLucide[name] ?? nodeIconsLucide["unknown"];
|
||||
let TargetIcon = nodeIconsLucide[name];
|
||||
if (!TargetIcon) {
|
||||
// check if name exists in dynamicIconImports
|
||||
if (!dynamicIconImports[name]) {
|
||||
TargetIcon = nodeIconsLucide["unknown"];
|
||||
} else TargetIcon = lazy(dynamicIconImports[name]);
|
||||
}
|
||||
|
||||
const style = {
|
||||
strokeWidth: strokeWidth ?? 1.5,
|
||||
|
|
@ -22,13 +29,21 @@ const ForwardedIconComponent = forwardRef(
|
|||
...(iconColor && { color: iconColor, stroke: stroke }),
|
||||
};
|
||||
|
||||
if (!TargetIcon) {
|
||||
return null; // Render nothing until the icon is loaded
|
||||
}
|
||||
const fallback = (
|
||||
<div style={{ background: "#ddd", width: 24, height: 24 }} />
|
||||
);
|
||||
return (
|
||||
<TargetIcon
|
||||
className={className}
|
||||
style={style}
|
||||
ref={ref}
|
||||
data-testid={id ? `${id}-${name}` : `icon-${name}`}
|
||||
/>
|
||||
<Suspense fallback={fallback}>
|
||||
<TargetIcon
|
||||
className={className}
|
||||
style={style}
|
||||
ref={ref}
|
||||
data-testid={id ? `${id}-${name}` : `icon-${name}`}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import * as React from "react";
|
|||
import { cn } from "../../utils/utils";
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
|
||||
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
|
|
|||
55
src/frontend/src/components/ui/refreshButton.tsx
Normal file
55
src/frontend/src/components/ui/refreshButton.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { NodeDataType } from "../../types/flow";
|
||||
import { cn } from "../../utils/utils";
|
||||
import { Button } from "./button";
|
||||
|
||||
function RefreshButton({
|
||||
isLoading,
|
||||
disabled,
|
||||
name,
|
||||
data,
|
||||
handleUpdateValues,
|
||||
className,
|
||||
id,
|
||||
}: {
|
||||
isLoading: boolean;
|
||||
disabled: boolean;
|
||||
name: string;
|
||||
data: NodeDataType;
|
||||
className?: string;
|
||||
handleUpdateValues: (name: string, data: NodeDataType) => void;
|
||||
id: string;
|
||||
}) {
|
||||
const handleClick = async () => {
|
||||
if (disabled) return;
|
||||
handleUpdateValues(name, data);
|
||||
};
|
||||
|
||||
const classNames = cn(className, disabled ? "cursor-not-allowed" : "");
|
||||
|
||||
// icon class name should take into account the disabled state and the loading state
|
||||
const disabledIconTextClass = disabled ? "text-muted-foreground" : "";
|
||||
const iconClassName = cn(
|
||||
"h-4 w-4",
|
||||
isLoading ? "animate-spin" : "animate-wiggle",
|
||||
disabledIconTextClass
|
||||
);
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="primary"
|
||||
disabled={disabled}
|
||||
className={classNames}
|
||||
onClick={handleClick}
|
||||
id={id}
|
||||
>
|
||||
<IconComponent
|
||||
name={isLoading ? "Loader2" : "RefreshCcw"}
|
||||
className={iconClassName}
|
||||
id={id + "-icon"}
|
||||
/>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
export { RefreshButton };
|
||||
|
|
@ -31,6 +31,7 @@ import {
|
|||
getNodeId,
|
||||
isValidConnection,
|
||||
reconnectEdges,
|
||||
scapeJSONParse,
|
||||
validateSelection,
|
||||
} from "../../../../utils/reactflowUtils";
|
||||
import { getRandomName, isWrappedWithClass } from "../../../../utils/utils";
|
||||
|
|
@ -108,7 +109,7 @@ export default function Page({
|
|||
...old.data,
|
||||
node: {
|
||||
...old.data.node,
|
||||
pinned: old.data?.node?.pinned ? false : true,
|
||||
frozen: old.data?.node?.frozen ? false : true,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
|
@ -320,6 +321,8 @@ export default function Page({
|
|||
(oldEdge: Edge, newConnection: Connection) => {
|
||||
if (isValidConnection(newConnection, nodes, edges)) {
|
||||
edgeUpdateSuccessful.current = true;
|
||||
oldEdge.data.targetHandle = scapeJSONParse(newConnection.targetHandle!);
|
||||
oldEdge.data.sourceHandle = scapeJSONParse(newConnection.sourceHandle!);
|
||||
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
||||
}
|
||||
},
|
||||
|
|
@ -488,4 +491,4 @@ export default function Page({
|
|||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import {
|
|||
} from "../../../../utils/utils";
|
||||
import DisclosureComponent from "../DisclosureComponent";
|
||||
import SidebarDraggableComponent from "./sideBarDraggableComponent";
|
||||
import { sortKeys } from "./utils";
|
||||
|
||||
export default function ExtraSidebar(): JSX.Element {
|
||||
const data = useTypesStore((state) => state.data);
|
||||
|
|
@ -320,19 +321,7 @@ export default function ExtraSidebar(): JSX.Element {
|
|||
|
||||
<div className="side-bar-components-div-arrangement">
|
||||
{Object.keys(dataFilter)
|
||||
.sort((a, b) => {
|
||||
if (a.toLowerCase() === "saved_components") {
|
||||
return -1;
|
||||
} else if (b.toLowerCase() === "saved_components") {
|
||||
return 1;
|
||||
} else if (a.toLowerCase() === "custom_components") {
|
||||
return -2;
|
||||
} else if (b.toLowerCase() === "custom_components") {
|
||||
return 2;
|
||||
} else {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
})
|
||||
.sort(sortKeys)
|
||||
.map((SBSectionName: keyof APIObjectType, index) =>
|
||||
Object.keys(dataFilter[SBSectionName]).length > 0 ? (
|
||||
<DisclosureComponent
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
export function sortKeys(a: string, b: string) {
|
||||
// Define the order of specific keys
|
||||
const order = [
|
||||
"saved_components",
|
||||
"inputs",
|
||||
"outputs",
|
||||
"data",
|
||||
"utilities",
|
||||
"models",
|
||||
];
|
||||
const indexA = order.indexOf(a.toLowerCase());
|
||||
const indexB = order.indexOf(b.toLowerCase());
|
||||
|
||||
// Check if both keys are in the predefined order
|
||||
if (indexA !== -1 && indexB !== -1) {
|
||||
return indexA - indexB;
|
||||
}
|
||||
|
||||
// If only 'a' is in the predefined order, it should come first
|
||||
if (indexA !== -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If only 'b' is in the predefined order, it should come first
|
||||
if (indexB !== -1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If neither 'a' nor 'b' are in the predefined order, sort them alphabetically
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ export default function NodeToolbarComponent({
|
|||
const isMinimal = numberOfHandles <= 1;
|
||||
const isGroup = data.node?.flow ? true : false;
|
||||
|
||||
const pinned = data.node?.pinned ?? false;
|
||||
const frozen = data.node?.frozen ?? false;
|
||||
const paste = useFlowStore((state) => state.paste);
|
||||
const nodes = useFlowStore((state) => state.nodes);
|
||||
const edges = useFlowStore((state) => state.edges);
|
||||
|
|
@ -267,7 +267,7 @@ export default function NodeToolbarComponent({
|
|||
</button>
|
||||
</ShadTooltip>
|
||||
|
||||
<ShadTooltip content="Pin" side="top">
|
||||
<ShadTooltip content="Freeze" side="top">
|
||||
<button
|
||||
className={classNames(
|
||||
"relative -ml-px inline-flex items-center bg-background px-2 py-2 text-foreground shadow-md ring-1 ring-inset ring-ring transition-all duration-500 ease-in-out hover:bg-muted focus:z-10"
|
||||
|
|
@ -280,17 +280,18 @@ export default function NodeToolbarComponent({
|
|||
...old.data,
|
||||
node: {
|
||||
...old.data.node,
|
||||
pinned: old.data?.node?.pinned ? false : true,
|
||||
frozen: old.data?.node?.frozen ? false : true,
|
||||
},
|
||||
},
|
||||
}));
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
name="Pin"
|
||||
name="Snowflake"
|
||||
className={cn(
|
||||
"h-4 w-4 transition-all",
|
||||
pinned ? "animate-wiggle fill-current" : ""
|
||||
// TODO UPDATE THIS COLOR TO BE A VARIABLE
|
||||
frozen ? "animate-wiggle text-ice" : ""
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import {
|
|||
FLOW_BUILD_SUCCESS_ALERT,
|
||||
MISSED_ERROR_ALERT,
|
||||
} from "../constants/alerts_constants";
|
||||
import { RUN_TIMESTAMP_PREFIX } from "../constants/constants";
|
||||
import { BuildStatus } from "../constants/enums";
|
||||
import { getFlowPool } from "../controllers/API";
|
||||
import { VertexBuildTypeAPI } from "../types/api";
|
||||
|
|
@ -188,10 +187,12 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
typeof change === "function"
|
||||
? change(get().nodes.find((node) => node.id === id)!)
|
||||
: change;
|
||||
|
||||
get().setNodes((oldNodes) =>
|
||||
oldNodes.map((node) => {
|
||||
if (node.id === id) {
|
||||
if ((node.data as NodeDataType).node?.frozen) {
|
||||
(newChange.data as NodeDataType).node!.frozen = false;
|
||||
}
|
||||
return newChange;
|
||||
}
|
||||
return node;
|
||||
|
|
@ -572,9 +573,7 @@ const useFlowStore = create<FlowStoreType>((set, get) => ({
|
|||
};
|
||||
if (status == BuildStatus.BUILT) {
|
||||
const timestamp_string = new Date(Date.now()).toLocaleString();
|
||||
newFlowBuildStatus[
|
||||
id
|
||||
].timestamp = `${RUN_TIMESTAMP_PREFIX} ${timestamp_string}`;
|
||||
newFlowBuildStatus[id].timestamp = timestamp_string;
|
||||
}
|
||||
console.log("updateBuildStatus", newFlowBuildStatus);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@
|
|||
@apply border-none ring ring-[#FF9090];
|
||||
}
|
||||
.built-invalid-status-dark {
|
||||
@apply border-none ring ring-[#751C1C]
|
||||
@apply border-none ring ring-[#751C1C];
|
||||
}
|
||||
.building-status {
|
||||
@apply border-none ring;
|
||||
|
|
@ -431,7 +431,9 @@
|
|||
.code-area-external-link:hover {
|
||||
@apply hover:text-accent-foreground;
|
||||
}
|
||||
|
||||
.dropdown-component-disabled {
|
||||
@apply pointer-events-none cursor-not-allowed;
|
||||
}
|
||||
.dropdown-component-outline {
|
||||
@apply input-edit-node relative pr-8;
|
||||
}
|
||||
|
|
@ -441,11 +443,17 @@
|
|||
.dropdown-component-display {
|
||||
@apply block w-full truncate bg-background;
|
||||
}
|
||||
.dropdown-component-display-disabled {
|
||||
@apply text-muted-foreground;
|
||||
}
|
||||
.dropdown-component-arrow {
|
||||
@apply pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2;
|
||||
}
|
||||
.dropdown-component-arrow-color {
|
||||
@apply extra-side-bar-save-disable h-5 w-5;
|
||||
@apply h-5 w-5 text-accent-foreground;
|
||||
}
|
||||
.dropdown-component-arrow-color-disable {
|
||||
@apply h-5 w-5 text-muted-foreground;
|
||||
}
|
||||
.dropdown-component-options {
|
||||
@apply z-10 mt-1 max-h-60 overflow-auto rounded-md bg-background py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm;
|
||||
|
|
@ -902,7 +910,7 @@
|
|||
@apply flex-max-width px-2 py-6 pl-4 pr-9;
|
||||
}
|
||||
.form-modal-chatbot-icon {
|
||||
@apply flex flex-col mb-3 ml-3 mr-6 mt-1;
|
||||
@apply mb-3 ml-3 mr-6 mt-1 flex flex-col;
|
||||
}
|
||||
.form-modal-chat-image {
|
||||
@apply flex flex-col items-center gap-1;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
--radius: 0.5rem;
|
||||
--ring: 215 20.2% 65.1%; /* hsl(215 20% 65%) */
|
||||
--round-btn-shadow: #00000063;
|
||||
--ice: #31a3cc;
|
||||
|
||||
--error-background: #fef2f2;
|
||||
--error-foreground: #991b1b;
|
||||
|
|
@ -67,6 +68,7 @@
|
|||
.dark {
|
||||
--background: 224 35% 7.5%; /* hsl(224 40% 10%) */
|
||||
--foreground: 213 31% 80%; /* hsl(213 31% 91%) */
|
||||
--ice: #60A5FA;
|
||||
|
||||
--muted: 223 27% 11%; /* hsl(223 27% 11%) */
|
||||
--muted-foreground: 215.4 16.3% 56.9%; /* hsl(215 16% 56%) */
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export type APIClassType = {
|
|||
documentation: string;
|
||||
error?: string;
|
||||
official?: boolean;
|
||||
pinned?: boolean;
|
||||
frozen?: boolean;
|
||||
flow?: FlowType;
|
||||
[key: string]:
|
||||
| Array<string>
|
||||
|
|
@ -54,6 +54,7 @@ export type TemplateVariableType = {
|
|||
input_types?: Array<string>;
|
||||
display_name?: string;
|
||||
name?: string;
|
||||
refresh?: boolean;
|
||||
[key: string]: any;
|
||||
};
|
||||
export type sendAllProps = {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ export type ToggleComponentType = {
|
|||
editNode?: boolean;
|
||||
};
|
||||
export type DropDownComponentType = {
|
||||
disabled?: boolean;
|
||||
isLoading?: boolean;
|
||||
value: string;
|
||||
options: string[];
|
||||
onSelect: (value: string) => void;
|
||||
|
|
|
|||
|
|
@ -126,7 +126,8 @@ export async function buildVertices({
|
|||
|
||||
if (validateNodes) {
|
||||
try {
|
||||
validateNodes(verticesIds);
|
||||
const nodes = useFlowStore.getState().nodes;
|
||||
validateNodes(nodes.map((node) => node.id));
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {
|
|||
Bot,
|
||||
Boxes,
|
||||
Braces,
|
||||
Cable,
|
||||
Check,
|
||||
CheckCircle2,
|
||||
ChevronDown,
|
||||
|
|
@ -46,6 +45,7 @@ import {
|
|||
FileUp,
|
||||
Fingerprint,
|
||||
FlaskConical,
|
||||
FolderOpen,
|
||||
FolderPlus,
|
||||
FormInput,
|
||||
Forward,
|
||||
|
|
@ -99,6 +99,7 @@ import {
|
|||
Share2,
|
||||
Shield,
|
||||
Sliders,
|
||||
Snowflake,
|
||||
Sparkles,
|
||||
Square,
|
||||
Store,
|
||||
|
|
@ -204,6 +205,9 @@ export const gradients = [
|
|||
];
|
||||
|
||||
export const nodeColors: { [char: string]: string } = {
|
||||
inputs: "#9AAE42",
|
||||
outputs: "#AA2411",
|
||||
data: "#6344BE",
|
||||
prompts: "#4367BF",
|
||||
models: "#AA2411",
|
||||
model_specs: "#6344BE",
|
||||
|
|
@ -224,16 +228,19 @@ export const nodeColors: { [char: string]: string } = {
|
|||
toolkits: "#DB2C2C",
|
||||
wrappers: "#E6277A",
|
||||
utilities: "#31A3CC",
|
||||
langchain_utilities: "#31A3CC",
|
||||
output_parsers: "#E6A627",
|
||||
str: "#31a3cc",
|
||||
Text: "#31a3cc",
|
||||
retrievers: "#e6b25a",
|
||||
unknown: "#9CA3AF",
|
||||
custom_components: "#ab11ab",
|
||||
io: "#e6b25a",
|
||||
};
|
||||
|
||||
export const nodeNames: { [char: string]: string } = {
|
||||
inputs: "Inputs",
|
||||
outputs: "Outputs",
|
||||
data: "Data",
|
||||
prompts: "Prompts",
|
||||
models: "Language Models",
|
||||
model_specs: "Model Specs",
|
||||
|
|
@ -252,13 +259,16 @@ export const nodeNames: { [char: string]: string } = {
|
|||
textsplitters: "Text Splitters",
|
||||
retrievers: "Retrievers",
|
||||
utilities: "Utilities",
|
||||
langchain_utilities: "Langchain Utilities",
|
||||
output_parsers: "Output Parsers",
|
||||
custom_components: "Custom",
|
||||
io: "I/O",
|
||||
unknown: "Other",
|
||||
};
|
||||
|
||||
export const nodeIconsLucide: iconsType = {
|
||||
inputs: Download,
|
||||
outputs: Upload,
|
||||
data: FolderOpen,
|
||||
AzureChatOpenAi: AzureIcon,
|
||||
Ollama: OllamaIcon,
|
||||
ChatOllama: OllamaIcon,
|
||||
|
|
@ -341,6 +351,7 @@ export const nodeIconsLucide: iconsType = {
|
|||
textsplitters: Scissors,
|
||||
wrappers: Gift,
|
||||
utilities: Wand2,
|
||||
langchain_utilities: Wand2,
|
||||
WolframAlphaAPIWrapper: SvgWolfram,
|
||||
output_parsers: Compass,
|
||||
retrievers: FileSearch,
|
||||
|
|
@ -383,6 +394,7 @@ export const nodeIconsLucide: iconsType = {
|
|||
Clipboard,
|
||||
Code2,
|
||||
Variable,
|
||||
Snowflake,
|
||||
Store,
|
||||
Download,
|
||||
Eraser,
|
||||
|
|
@ -446,7 +458,6 @@ export const nodeIconsLucide: iconsType = {
|
|||
TerminalSquare,
|
||||
TextCursorInput,
|
||||
Repeat,
|
||||
io: Cable,
|
||||
Sliders,
|
||||
ScreenShare,
|
||||
Code,
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ module.exports = {
|
|||
"beta-foreground": "var(--beta-foreground)",
|
||||
"chat-bot-icon": "var(--chat-bot-icon)",
|
||||
"chat-user-icon": "var(--chat-user-icon)",
|
||||
"ice": "var(--ice)",
|
||||
|
||||
white: "var(--white)",
|
||||
border: "hsl(var(--border))",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue