Merge branch 'python_custom_node_component' into ChatWidgetAPI
This commit is contained in:
commit
397c665536
102 changed files with 6034 additions and 671 deletions
|
|
@ -27,6 +27,7 @@ import {
|
|||
classNames,
|
||||
getRandomKeyByssmm,
|
||||
groupByFamily,
|
||||
groupByFamilyCustom,
|
||||
} from "../../../../utils/utils";
|
||||
|
||||
export default function ParameterComponent({
|
||||
|
|
@ -49,7 +50,9 @@ export default function ParameterComponent({
|
|||
const infoHtml = useRef(null);
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const [position, setPosition] = useState(0);
|
||||
const { setTabsState, tabId, save } = useContext(TabsContext);
|
||||
const { setTabsState, tabId, save, flows } = useContext(TabsContext);
|
||||
|
||||
const flow = flows.find((f) => f.id === tabId).data?.nodes ?? null;
|
||||
|
||||
// Update component position
|
||||
useEffect(() => {
|
||||
|
|
@ -80,9 +83,11 @@ export default function ParameterComponent({
|
|||
[tabId]: {
|
||||
...prev[tabId],
|
||||
isPending: true,
|
||||
formKeysData: prev[tabId].formKeysData,
|
||||
},
|
||||
};
|
||||
});
|
||||
renderTooltips();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -98,57 +103,76 @@ export default function ParameterComponent({
|
|||
);
|
||||
}, [info]);
|
||||
|
||||
useEffect(() => {
|
||||
const groupedObj = groupByFamily(myData, tooltipTitle, left, data.type);
|
||||
function renderTooltips() {
|
||||
let groupedObj = groupByFamily(myData, tooltipTitle, left, data.type, flow);
|
||||
|
||||
refNumberComponents.current = groupedObj[0]?.type?.length;
|
||||
if (groupedObj?.length === 0 && flow && flow.length > 0) {
|
||||
groupedObj = groupByFamilyCustom(
|
||||
myData,
|
||||
tooltipTitle,
|
||||
left,
|
||||
data.type,
|
||||
flow
|
||||
);
|
||||
}
|
||||
|
||||
refHtml.current = groupedObj.map((item, i) => {
|
||||
const Icon: any = nodeIconsLucide[item.family];
|
||||
if (groupedObj) {
|
||||
refNumberComponents.current = groupedObj[0]?.type?.length;
|
||||
|
||||
return (
|
||||
<span
|
||||
key={getRandomKeyByssmm() + item.family + i}
|
||||
className={classNames(
|
||||
i > 0 ? "mt-2 flex items-center" : "flex items-center"
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="h-5 w-5"
|
||||
style={{
|
||||
color: nodeColors[item.family],
|
||||
}}
|
||||
refHtml.current = groupedObj.map((item, i) => {
|
||||
const Icon: any = nodeIconsLucide[item.family];
|
||||
|
||||
return (
|
||||
<span
|
||||
key={getRandomKeyByssmm() + item.family + i}
|
||||
className={classNames(
|
||||
i > 0 ? "mt-2 flex items-center" : "flex items-center"
|
||||
)}
|
||||
>
|
||||
<Icon
|
||||
<div
|
||||
className="h-5 w-5"
|
||||
strokeWidth={1.5}
|
||||
style={{
|
||||
color: nodeColors[item.family] ?? nodeColors.unknown,
|
||||
color: nodeColors[item.family],
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="ps-2 text-xs text-foreground">
|
||||
{nodeNames[item.family] ?? ""}{" "}
|
||||
<span className="text-xs">
|
||||
{" "}
|
||||
{item.type === "" ? "" : " - "}
|
||||
{item.type.split(", ").length > 2
|
||||
? item.type.split(", ").map((el, i) => (
|
||||
<React.Fragment key={el + i}>
|
||||
<span>
|
||||
{i === item.type.split(", ").length - 1
|
||||
? el
|
||||
: (el += `, `)}
|
||||
</span>
|
||||
</React.Fragment>
|
||||
))
|
||||
: item.type}
|
||||
>
|
||||
<Icon
|
||||
className="h-5 w-5"
|
||||
strokeWidth={1.5}
|
||||
style={{
|
||||
color: nodeColors[item.family] ?? nodeColors.unknown,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="ps-2 text-xs text-foreground">
|
||||
{item.family !== "custom_components"
|
||||
? nodeNames[item.family]
|
||||
: item.component ?? ""}{" "}
|
||||
<span className="text-xs">
|
||||
{" "}
|
||||
{item.type === "" ? "" : " - "}
|
||||
{item.type.split(", ").length > 2
|
||||
? item.type.split(", ").map((el, i) => (
|
||||
<React.Fragment key={el + i}>
|
||||
<span>
|
||||
{i === item.type.split(", ").length - 1
|
||||
? el
|
||||
: (el += `, `)}
|
||||
</span>
|
||||
</React.Fragment>
|
||||
))
|
||||
: item.type}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
});
|
||||
}, [tooltipTitle]);
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
renderTooltips();
|
||||
}, [tooltipTitle, flow]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
|
|
@ -280,6 +304,7 @@ export default function ParameterComponent({
|
|||
) : left === true && type === "code" ? (
|
||||
<div className="mt-2 w-full">
|
||||
<CodeAreaComponent
|
||||
dynamic={data.node.template[name].dynamic ?? false}
|
||||
setNodeClass={(nodeClass) => {
|
||||
data.node = nodeClass;
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@ export default function GenericNode({
|
|||
"generic-node-div"
|
||||
)}
|
||||
>
|
||||
{data.node.beta && (
|
||||
<div className="beta-badge-wrapper">
|
||||
<div className="beta-badge-content">BETA</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="generic-node-div-title">
|
||||
<div className="generic-node-title-arrangement">
|
||||
<IconComponent
|
||||
|
|
@ -127,7 +132,7 @@ export default function GenericNode({
|
|||
</span>
|
||||
) : (
|
||||
<div className="max-h-96 overflow-auto">
|
||||
{validationStatus.params
|
||||
{typeof validationStatus.params === "string"
|
||||
? validationStatus.params
|
||||
.split("\n")
|
||||
.map((line, index) => <div key={index}>{line}</div>)
|
||||
|
|
@ -178,6 +183,14 @@ export default function GenericNode({
|
|||
{data.node.template[t].show &&
|
||||
!data.node.template[t].advanced ? (
|
||||
<ParameterComponent
|
||||
key={
|
||||
(data.node.template[t].input_types?.join(";") ??
|
||||
data.node.template[t].type) +
|
||||
"|" +
|
||||
t +
|
||||
"|" +
|
||||
data.id
|
||||
}
|
||||
data={data}
|
||||
setData={setData}
|
||||
color={
|
||||
|
|
@ -225,6 +238,7 @@ export default function GenericNode({
|
|||
{" "}
|
||||
</div>
|
||||
<ParameterComponent
|
||||
key={[data.type, data.id, ...data.node.base_classes].join("|")}
|
||||
data={data}
|
||||
setData={setData}
|
||||
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React, { ChangeEvent, useState } from "react";
|
||||
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
|
||||
import { Input } from "../../components/ui/input";
|
||||
import { Label } from "../../components/ui/label";
|
||||
import { Textarea } from "../../components/ui/textarea";
|
||||
import { readFlowsFromDatabase } from "../../controllers/API";
|
||||
|
||||
type InputProps = {
|
||||
name: string | null;
|
||||
|
|
@ -9,6 +10,8 @@ type InputProps = {
|
|||
maxLength?: number;
|
||||
flows: Array<{ id: string; name: string; description: string }>;
|
||||
tabId: string;
|
||||
invalidName: boolean;
|
||||
setInvalidName: (invalidName: boolean) => void;
|
||||
setName: (name: string) => void;
|
||||
setDescription: (description: string) => void;
|
||||
updateFlow: (flow: { id: string; name: string }) => void;
|
||||
|
|
@ -16,6 +19,8 @@ type InputProps = {
|
|||
|
||||
export const EditFlowSettings: React.FC<InputProps> = ({
|
||||
name,
|
||||
invalidName,
|
||||
setInvalidName,
|
||||
description,
|
||||
maxLength = 50,
|
||||
flows,
|
||||
|
|
@ -25,6 +30,14 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
|||
updateFlow,
|
||||
}) => {
|
||||
const [isMaxLength, setIsMaxLength] = useState(false);
|
||||
const nameLists = useRef([]);
|
||||
useEffect(() => {
|
||||
readFlowsFromDatabase().then((flows) => {
|
||||
flows.forEach((flow) => {
|
||||
nameLists.current.push(flow.name);
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleNameChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
const { value } = event.target;
|
||||
|
|
@ -33,7 +46,11 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
|||
} else {
|
||||
setIsMaxLength(false);
|
||||
}
|
||||
|
||||
if (!nameLists.current.includes(value)) {
|
||||
setInvalidName(false);
|
||||
} else {
|
||||
setInvalidName(true);
|
||||
}
|
||||
setName(value);
|
||||
};
|
||||
|
||||
|
|
@ -55,6 +72,9 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
|||
{isMaxLength && (
|
||||
<span className="edit-flow-span">Character limit reached</span>
|
||||
)}
|
||||
{invalidName && (
|
||||
<span className="edit-flow-span">Name already in use</span>
|
||||
)}
|
||||
</div>
|
||||
<Input
|
||||
className="nopan nodrag noundo nocopy mt-2 font-normal"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import CodeAreaModal from "../../modals/codeAreaModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
import { CodeAreaComponentType } from "../../types/components";
|
||||
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
|
|
@ -10,8 +10,9 @@ export default function CodeAreaComponent({
|
|||
disabled,
|
||||
editNode = false,
|
||||
nodeClass,
|
||||
dynamic,
|
||||
setNodeClass,
|
||||
}: TextAreaComponentType) {
|
||||
}: CodeAreaComponentType) {
|
||||
const [myValue, setMyValue] = useState(
|
||||
typeof value == "string" ? value : JSON.stringify(value)
|
||||
);
|
||||
|
|
@ -29,6 +30,7 @@ export default function CodeAreaComponent({
|
|||
return (
|
||||
<div className={disabled ? "pointer-events-none w-full " : " w-full"}>
|
||||
<CodeAreaModal
|
||||
dynamic={dynamic}
|
||||
value={myValue}
|
||||
nodeClass={nodeClass}
|
||||
setNodeClass={setNodeClass}
|
||||
|
|
|
|||
|
|
@ -491,3 +491,14 @@ export const NOUNS: string[] = [
|
|||
*
|
||||
*/
|
||||
export const USER_PROJECTS_HEADER = "My Collection";
|
||||
|
||||
/**
|
||||
* URLs excluded from error retries.
|
||||
* @constant
|
||||
*
|
||||
*/
|
||||
export const URL_EXCLUDED_FROM_ERROR_RETRIES = [
|
||||
"/api/v1/validate/code",
|
||||
"/api/v1/custom_component",
|
||||
"/api/v1/validate/prompt",
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import axios, { AxiosError, AxiosInstance } from "axios";
|
||||
import { useContext, useEffect, useRef } from "react";
|
||||
import { URL_EXCLUDED_FROM_ERROR_RETRIES } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
|
||||
// Create a new Axios instance
|
||||
|
|
@ -15,6 +16,9 @@ function ApiInterceptor() {
|
|||
const interceptor = api.interceptors.response.use(
|
||||
(response) => response,
|
||||
async (error: AxiosError) => {
|
||||
if (URL_EXCLUDED_FROM_ERROR_RETRIES.includes(error.config?.url)) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
let retryCount = 0;
|
||||
|
||||
while (retryCount < 4) {
|
||||
|
|
@ -31,7 +35,7 @@ function ApiInterceptor() {
|
|||
"Refresh the page",
|
||||
"Use a new flow tab",
|
||||
"Check if the backend is up",
|
||||
"Endpoint: " + error.config.url,
|
||||
"Endpoint: " + error.config?.url,
|
||||
],
|
||||
});
|
||||
return Promise.reject(error);
|
||||
|
|
|
|||
|
|
@ -339,3 +339,10 @@ export async function uploadFile(
|
|||
formData.append("file", file);
|
||||
return await api.post(`/api/v1/upload/${id}`, formData);
|
||||
}
|
||||
|
||||
export async function postCustomComponent(
|
||||
code: string,
|
||||
apiClass: APIClassType
|
||||
): Promise<AxiosResponse<APIClassType>> {
|
||||
return await api.post(`/api/v1/custom_component`, { code });
|
||||
}
|
||||
|
|
|
|||
22
src/frontend/src/icons/GradientSparkles/index.tsx
Normal file
22
src/frontend/src/icons/GradientSparkles/index.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { Infinity } from "lucide-react";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
const GradientSparkles = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return (
|
||||
<>
|
||||
<svg width="0" height="0" style={{ position: "absolute" }}>
|
||||
<defs>
|
||||
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop className="gradient-start" offset="0%" />
|
||||
<stop className="gradient-end" offset="100%" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<Infinity stroke="url(#grad1)" ref={ref} {...props} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default GradientSparkles;
|
||||
|
|
@ -261,6 +261,13 @@ const EditNodeModal = forwardRef(
|
|||
) : myData.node.template[n].type === "code" ? (
|
||||
<div className="mx-auto">
|
||||
<CodeAreaComponent
|
||||
dynamic={
|
||||
data.node.template[n].dynamic ?? false
|
||||
}
|
||||
setNodeClass={(nodeClass) => {
|
||||
data.node = nodeClass;
|
||||
}}
|
||||
nodeClass={data.node}
|
||||
disabled={disabled}
|
||||
editNode={true}
|
||||
value={myData.node.template[n].value ?? ""}
|
||||
|
|
|
|||
|
|
@ -160,6 +160,11 @@ export default function ModalField({
|
|||
) : 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) => {
|
||||
|
|
|
|||
|
|
@ -112,8 +112,9 @@ function BaseModal({
|
|||
<div className={`mt-2 flex flex-col ${height} w-full `}>
|
||||
{ContentChild}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row-reverse">{ContentFooter}</div>
|
||||
{ContentFooter && (
|
||||
<div className="flex flex-row-reverse">{ContentFooter}</div>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,14 +3,16 @@ import "ace-builds/src-noconflict/ext-language_tools";
|
|||
import "ace-builds/src-noconflict/mode-python";
|
||||
import "ace-builds/src-noconflict/theme-github";
|
||||
import "ace-builds/src-noconflict/theme-twilight";
|
||||
import { ReactNode, useContext, useState } from "react";
|
||||
// import "ace-builds/webpack-resolver";
|
||||
import { ReactNode, useContext, useEffect, useState } from "react";
|
||||
import AceEditor from "react-ace";
|
||||
import IconComponent from "../../components/genericIconComponent";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { CODE_PROMPT_DIALOG_SUBTITLE } from "../../constants/constants";
|
||||
import { alertContext } from "../../contexts/alertContext";
|
||||
import { darkContext } from "../../contexts/darkContext";
|
||||
import { postValidateCode } from "../../controllers/API";
|
||||
import { typesContext } from "../../contexts/typesContext";
|
||||
import { postCustomComponent, postValidateCode } from "../../controllers/API";
|
||||
import { APIClassType } from "../../types/api";
|
||||
import BaseModal from "../baseModal";
|
||||
|
||||
|
|
@ -20,18 +22,34 @@ export default function CodeAreaModal({
|
|||
nodeClass,
|
||||
setNodeClass,
|
||||
children,
|
||||
dynamic,
|
||||
}: {
|
||||
setValue: (value: string) => void;
|
||||
value: string;
|
||||
nodeClass: APIClassType;
|
||||
nodeClass?: APIClassType;
|
||||
children: ReactNode;
|
||||
setNodeClass: (Class: APIClassType) => void;
|
||||
setNodeClass?: (Class: APIClassType) => void;
|
||||
dynamic?: boolean;
|
||||
}) {
|
||||
const [code, setCode] = useState(value);
|
||||
const { dark } = useContext(darkContext);
|
||||
const { reactFlowInstance } = useContext(typesContext);
|
||||
const [height, setHeight] = useState(null);
|
||||
const { setErrorData, setSuccessData } = useContext(alertContext);
|
||||
const [error, setError] = useState<{
|
||||
detail: { error: string; traceback: string };
|
||||
}>(null);
|
||||
|
||||
function handleClick() {
|
||||
useEffect(() => {
|
||||
// if nodeClass.template has more fields other than code and dynamic is true
|
||||
// do not run handleClick
|
||||
if (dynamic && Object.keys(nodeClass.template).length > 2) {
|
||||
return;
|
||||
}
|
||||
processCode();
|
||||
}, []);
|
||||
|
||||
function processNonDynamicField() {
|
||||
postValidateCode(code)
|
||||
.then((apiReturn) => {
|
||||
if (apiReturn.data) {
|
||||
|
|
@ -41,8 +59,9 @@ export default function CodeAreaModal({
|
|||
setSuccessData({
|
||||
title: "Code is ready to run",
|
||||
});
|
||||
setValue(code);
|
||||
setOpen(false);
|
||||
setValue(code);
|
||||
// setValue(code);
|
||||
} else {
|
||||
if (funcErrors.length !== 0) {
|
||||
setErrorData({
|
||||
|
|
@ -70,6 +89,50 @@ export default function CodeAreaModal({
|
|||
});
|
||||
}
|
||||
|
||||
function processDynamicField() {
|
||||
postCustomComponent(code, nodeClass)
|
||||
.then((apiReturn) => {
|
||||
const { data } = apiReturn;
|
||||
if (data) {
|
||||
setNodeClass(data);
|
||||
setValue(code);
|
||||
setError({ detail: { error: undefined, traceback: undefined } });
|
||||
setOpen(false);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
setError(err.response.data);
|
||||
});
|
||||
}
|
||||
|
||||
function processCode() {
|
||||
if (!dynamic) {
|
||||
processNonDynamicField();
|
||||
} else {
|
||||
processDynamicField();
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick() {
|
||||
processCode();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// Function to be executed after the state changes
|
||||
const delayedFunction = setTimeout(() => {
|
||||
if (error?.detail.error !== undefined) {
|
||||
//trigger to update the height, does not really apply any height
|
||||
setHeight("90%");
|
||||
}
|
||||
//600 to happen after the transition of 500ms
|
||||
}, 600);
|
||||
|
||||
// Cleanup function to clear the timeout if the component unmounts or the state changes again
|
||||
return () => {
|
||||
clearTimeout(delayedFunction);
|
||||
};
|
||||
}, [error, setHeight]);
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
|
|
@ -89,6 +152,7 @@ export default function CodeAreaModal({
|
|||
<AceEditor
|
||||
value={code}
|
||||
mode="python"
|
||||
height={height ?? "100%"}
|
||||
highlightActiveLine={true}
|
||||
showPrintMargin={false}
|
||||
fontSize={14}
|
||||
|
|
@ -99,9 +163,26 @@ export default function CodeAreaModal({
|
|||
onChange={(value) => {
|
||||
setCode(value);
|
||||
}}
|
||||
className="h-full w-full rounded-lg border-[1px] border-border custom-scroll"
|
||||
className="h-full w-full rounded-lg border-[1px] border-gray-300 custom-scroll dark:border-gray-600"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
"w-full transition-all delay-500 " +
|
||||
(error?.detail.error !== undefined ? "h-2/6" : "h-0")
|
||||
}
|
||||
>
|
||||
<div className="mt-1 h-full w-full overflow-y-auto overflow-x-clip text-left custom-scroll">
|
||||
<h1 className="text-lg text-destructive">
|
||||
{error?.detail?.error}
|
||||
</h1>
|
||||
<div className="ml-2 w-full break-all text-sm text-status-red">
|
||||
<pre className="w-full whitespace-pre-wrap break-all">
|
||||
{error?.detail?.traceback}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-fit w-full justify-end">
|
||||
<Button className="mt-3" onClick={handleClick} type="submit">
|
||||
Check & Save
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ export default function FlowSettingsModal({
|
|||
const [description, setDescription] = useState(
|
||||
flows.find((f) => f.id === tabId).description
|
||||
);
|
||||
const [invalidName, setInvalidName] = useState(false);
|
||||
|
||||
function handleClick() {
|
||||
let savedFlow = flows.find((f) => f.id === tabId);
|
||||
savedFlow.name = name;
|
||||
|
|
@ -39,6 +41,8 @@ export default function FlowSettingsModal({
|
|||
</BaseModal.Header>
|
||||
<BaseModal.Content>
|
||||
<EditFlowSettings
|
||||
invalidName={invalidName}
|
||||
setInvalidName={setInvalidName}
|
||||
name={name}
|
||||
description={description}
|
||||
flows={flows}
|
||||
|
|
@ -50,7 +54,7 @@ export default function FlowSettingsModal({
|
|||
</BaseModal.Content>
|
||||
|
||||
<BaseModal.Footer>
|
||||
<Button onClick={handleClick} type="submit">
|
||||
<Button disabled={invalidName} onClick={handleClick} type="submit">
|
||||
Save
|
||||
</Button>
|
||||
</BaseModal.Footer>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,36 @@
|
|||
}
|
||||
}
|
||||
|
||||
@keyframes gradient-motion-start {
|
||||
0% {
|
||||
stop-color: rgb(156, 138, 236);
|
||||
}
|
||||
50% {
|
||||
stop-color: rgb(255, 130, 184);
|
||||
}
|
||||
80% {
|
||||
stop-color: rgb(255, 165, 100);
|
||||
}
|
||||
100% {
|
||||
stop-color: rgb(156, 138, 236);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gradient-motion-end {
|
||||
0% {
|
||||
stop-color: rgb(156, 138, 236);
|
||||
}
|
||||
50% {
|
||||
stop-color: rgb(255, 165, 100);
|
||||
}
|
||||
80% {
|
||||
stop-color: rgb(255, 130, 184);
|
||||
}
|
||||
100% {
|
||||
stop-color: rgb(156, 138, 236);
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.round-buttons-position {
|
||||
@apply fixed right-4;
|
||||
|
|
@ -979,6 +1009,13 @@
|
|||
@apply font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70;
|
||||
}
|
||||
|
||||
.beta-badge-wrapper {
|
||||
@apply absolute right-0 top-0 h-16 w-16 overflow-hidden rounded-tr-lg;
|
||||
}
|
||||
.beta-badge-content {
|
||||
@apply mt-2 w-24 rotate-45 bg-beta-background text-center text-xs font-semibold text-beta-foreground;
|
||||
}
|
||||
|
||||
.chat-message-highlight {
|
||||
@apply rounded-md bg-indigo-100 px-0.5 dark:bg-indigo-900;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,38 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||
monospace;
|
||||
}
|
||||
pre {
|
||||
font-family: inherit;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.react-flow__pane {
|
||||
cursor: default;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
||||
.AccordionContent {
|
||||
overflow: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
.AccordionContent[data-state='open'] {
|
||||
animation: slideDown 300ms ease-out;
|
||||
.AccordionContent[data-state="open"] {
|
||||
animation: slideDown 300ms ease-out;
|
||||
}
|
||||
.AccordionContent[data-state="closed"] {
|
||||
animation: slideUp 300ms ease-out;
|
||||
}
|
||||
|
||||
|
||||
.gradient-end {
|
||||
animation: gradient-motion-end 3s infinite forwards;
|
||||
}
|
||||
.gradient-start {
|
||||
animation: gradient-motion-start 4s infinite forwards;
|
||||
}
|
||||
.AccordionContent[data-state='closed'] {
|
||||
animation: slideUp 300ms ease-out;
|
||||
}
|
||||
|
|
@ -2,125 +2,127 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
|
||||
/* TODO: Confirm that all colors here are found in tailwind config */
|
||||
|
||||
@layer base {
|
||||
|
||||
:root {
|
||||
--background: 0 0% 100%; /* hsl(0 0% 100%) */
|
||||
--foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--muted: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
--muted-foreground: 215.4 16.3% 46.9%; /* hsl(215 16% 46%) */
|
||||
--popover: 0 0% 100%; /* hsl(0 0% 100%) */
|
||||
--popover-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--card: 0 0% 100%; /* hsl(0 0% 100%) */
|
||||
--card-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--border: 214.3 21.8% 91.4%; /* hsl(214 32% 91%) */
|
||||
--input: 214.3 21.8% 91.4%; /* hsl(214 32% 91%) */
|
||||
--primary: 222.2 27% 11.2%; /* hsl(222 27% 18%) */
|
||||
--primary-foreground: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
--secondary: 210 40% 96.1%; /* hsl(210 40% 96%) */
|
||||
--secondary-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--accent: 210 30% 96.1%; /* hsl(210 30% 96%) */
|
||||
--accent-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--destructive: 0 100% 50%; /* hsl(0 100% 50%) */
|
||||
--destructive-foreground: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
--radius: 0.5rem;
|
||||
--ring: 215 20.2% 65.1%; /* hsl(215 20% 65%) */
|
||||
--round-btn-shadow: #00000063;
|
||||
|
||||
--error-background: #fef2f2;
|
||||
--error-foreground: #991b1b;
|
||||
|
||||
--success-background: #f0fdf4;
|
||||
--success-foreground: #14532d;
|
||||
--background: 0 0% 100%; /* hsl(0 0% 100%) */
|
||||
--foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--muted: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
--muted-foreground: 215.4 16.3% 46.9%; /* hsl(215 16% 46%) */
|
||||
--popover: 0 0% 100%; /* hsl(0 0% 100%) */
|
||||
--popover-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--card: 0 0% 100%; /* hsl(0 0% 100%) */
|
||||
--card-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--border: 214.3 21.8% 91.4%; /* hsl(214 32% 91%) */
|
||||
--input: 214.3 21.8% 91.4%; /* hsl(214 32% 91%) */
|
||||
--primary: 222.2 27% 11.2%; /* hsl(222 27% 18%) */
|
||||
--primary-foreground: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
--secondary: 210 40% 96.1%; /* hsl(210 40% 96%) */
|
||||
--secondary-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--accent: 210 30% 96.1%; /* hsl(210 30% 96%) */
|
||||
--accent-foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */
|
||||
--destructive: 0 100% 50%; /* hsl(0 100% 50%) */
|
||||
--destructive-foreground: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
--radius: 0.5rem;
|
||||
--ring: 215 20.2% 65.1%; /* hsl(215 20% 65%) */
|
||||
--round-btn-shadow: #00000063;
|
||||
|
||||
--info-background: #f0f4fd;
|
||||
--info-foreground: #141653;
|
||||
--error-background: #fef2f2;
|
||||
--error-foreground: #991b1b;
|
||||
|
||||
--high-indigo: #4338ca;
|
||||
--medium-indigo: #6366f1;
|
||||
--low-indigo: #e0e7ff;
|
||||
--success-background: #f0fdf4;
|
||||
--success-foreground: #14532d;
|
||||
|
||||
--chat-bot-icon: #afe6ef;
|
||||
--chat-user-icon: #aface9;
|
||||
|
||||
/* Colors that are shared in dark and light mode */
|
||||
--blur-shared: #151923de;
|
||||
--build-trigger: #dc735b;
|
||||
--chat-trigger: #5c8be1;
|
||||
--chat-trigger-disabled: #b4c3da;
|
||||
--status-red: #ef4444;
|
||||
--status-yellow: #eab308;
|
||||
--chat-send: #059669;
|
||||
--status-green: #4ade80;
|
||||
--status-blue:#2563eb;
|
||||
--connection: #555;
|
||||
--info-background: #f0f4fd;
|
||||
--info-foreground: #141653;
|
||||
|
||||
--high-indigo: #4338ca;
|
||||
--medium-indigo: #6366f1;
|
||||
--low-indigo: #e0e7ff;
|
||||
|
||||
--beta-background: rgb(219 234 254);
|
||||
--beta-foreground: rgb(37 99 235);
|
||||
|
||||
--chat-bot-icon: #afe6ef;
|
||||
--chat-user-icon: #aface9;
|
||||
|
||||
/* Colors that are shared in dark and light mode */
|
||||
--blur-shared: #151923de;
|
||||
--build-trigger: #dc735b;
|
||||
--chat-trigger: #5c8be1;
|
||||
--chat-trigger-disabled: #b4c3da;
|
||||
--status-red: #ef4444;
|
||||
--status-yellow: #eab308;
|
||||
--chat-send: #059669;
|
||||
--status-green: #4ade80;
|
||||
--status-blue: #2563eb;
|
||||
--connection: #555;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 35% 7.5%; /* hsl(224 40% 10%) */
|
||||
--foreground: 213 31% 80%; /* hsl(213 31% 91%) */
|
||||
|
||||
--muted: 223 27% 11%; /* hsl(223 27% 11%) */
|
||||
--muted-foreground: 215.4 16.3% 56.9%; /* hsl(215 16% 56%) */
|
||||
|
||||
--popover: 224 71% 4%; /* hsl(224 71% 4%) */
|
||||
--popover-foreground: 215 20.2% 65.1%; /* hsl(215 20% 65%) */
|
||||
|
||||
--card: 224 25% 15.5%; /* hsl(224 71% 4%) */
|
||||
--card-foreground: 213 31% 80%; /* hsl(213 31% 91%) */
|
||||
|
||||
--border: 216 24% 17%; /* hsl(216 34% 17%) */
|
||||
--input: 216 24% 17%; /* hsl(216 34% 17%) */
|
||||
|
||||
--primary: 210 20% 80%; /* hsl(210 20% 80%) */
|
||||
--primary-foreground: 222.2 27.4% 1.2%; /* hsl(222 47% 1%) */
|
||||
|
||||
--secondary: 222.2 37.4% 7.2%; /* hsl(222 47% 11%) */
|
||||
--secondary-foreground: 210 40% 80%; /* hsl(210 40% 80%) */
|
||||
|
||||
--accent: 216 24% 20%; /* hsl(216 34% 17%) */
|
||||
--accent-foreground: 210 30% 98%; /* hsl(210 40% 98%) */
|
||||
|
||||
--destructive: 0 63% 31%; /* hsl(0 63% 31%) */
|
||||
--destructive-foreground: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
|
||||
--ring: 216 24% 30%; /* hsl(216 24% 30%) */
|
||||
|
||||
--radius: 0.5rem;
|
||||
|
||||
--round-btn-shadow: #00000063;
|
||||
|
||||
--success-background: #022c22;
|
||||
--success-foreground: #ecfdf5;
|
||||
|
||||
--error-foreground: #fef2f2;
|
||||
--error-background: #450a0a;
|
||||
|
||||
--info-foreground: #eff6ff;
|
||||
--info-background: #172554;
|
||||
|
||||
--high-indigo: #4338ca;
|
||||
--medium-indigo: #6366f1;
|
||||
--low-indigo: #e0e7ff;
|
||||
|
||||
/* Colors that are shared in dark and light mode */
|
||||
--blur-shared: #151923d2;
|
||||
--build-trigger: #dc735b;
|
||||
--chat-trigger: #5c8be1;
|
||||
--chat-trigger-disabled: #2d3b54;
|
||||
--status-red: #ef4444;
|
||||
--status-yellow: #eab308;
|
||||
--chat-send: #059669;
|
||||
--status-green: #4ade80;
|
||||
--status-blue: #2563eb;
|
||||
--connection: #555;
|
||||
|
||||
--beta-background: rgb(37 99 235);
|
||||
--beta-foreground: rgb(219 234 254);
|
||||
|
||||
--chat-bot-icon: #235d70;
|
||||
--chat-user-icon: #4f3d6e;
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 35% 7.5%; /* hsl(224 40% 10%) */
|
||||
--foreground: 213 31% 80%; /* hsl(213 31% 91%) */
|
||||
|
||||
--muted: 223 27% 11%; /* hsl(223 27% 11%) */
|
||||
--muted-foreground: 215.4 16.3% 56.9%; /* hsl(215 16% 56%) */
|
||||
|
||||
--popover: 224 71% 4%; /* hsl(224 71% 4%) */
|
||||
--popover-foreground: 215 20.2% 65.1%; /* hsl(215 20% 65%) */
|
||||
|
||||
--card: 224 25% 15.5%; /* hsl(224 71% 4%) */
|
||||
--card-foreground: 213 31% 80%; /* hsl(213 31% 91%) */
|
||||
|
||||
--border: 216 24% 17%; /* hsl(216 34% 17%) */
|
||||
--input: 216 24% 17%; /* hsl(216 34% 17%) */
|
||||
|
||||
--primary: 210 20% 80%; /* hsl(210 20% 80%) */
|
||||
--primary-foreground: 222.2 27.4% 1.2%; /* hsl(222 47% 1%) */
|
||||
|
||||
--secondary: 222.2 37.4% 7.2%; /* hsl(222 47% 11%) */
|
||||
--secondary-foreground: 210 40% 80%; /* hsl(210 40% 80%) */
|
||||
|
||||
--accent: 216 24% 20%; /* hsl(216 34% 17%) */
|
||||
--accent-foreground: 210 30% 98%; /* hsl(210 40% 98%) */
|
||||
|
||||
--destructive: 0 63% 31%; /* hsl(0 63% 31%) */
|
||||
--destructive-foreground: 210 40% 98%; /* hsl(210 40% 98%) */
|
||||
|
||||
--ring: 216 24% 30%; /* hsl(216 24% 30%) */
|
||||
|
||||
--radius: 0.5rem;
|
||||
|
||||
--round-btn-shadow: #00000063;
|
||||
|
||||
--success-background: #022c22;
|
||||
--success-foreground: #ecfdf5;
|
||||
|
||||
--error-foreground: #fef2f2;
|
||||
--error-background: #450a0a;
|
||||
|
||||
--info-foreground: #eff6ff;
|
||||
--info-background: #172554;
|
||||
|
||||
|
||||
--high-indigo: #4338ca;
|
||||
--medium-indigo: #6366f1;
|
||||
--low-indigo: #e0e7ff;
|
||||
|
||||
/* Colors that are shared in dark and light mode */
|
||||
--blur-shared: #151923d2;
|
||||
--build-trigger: #dc735b;
|
||||
--chat-trigger: #5c8be1;
|
||||
--chat-trigger-disabled: #2d3b54;
|
||||
--status-red: #ef4444;
|
||||
--status-yellow: #eab308;
|
||||
--chat-send: #059669;
|
||||
--status-green: #4ade80;
|
||||
--status-blue: #2563eb;
|
||||
--connection: #555;
|
||||
|
||||
--chat-bot-icon: #235d70;
|
||||
--chat-user-icon: #4f3d6e;
|
||||
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ export type APIClassType = {
|
|||
display_name: string;
|
||||
input_types?: Array<string>;
|
||||
output_types?: Array<string>;
|
||||
beta?: boolean;
|
||||
documentation: string;
|
||||
[key: string]: Array<string> | string | APITemplateType;
|
||||
[key: string]: Array<string> | string | APITemplateType | boolean;
|
||||
};
|
||||
|
||||
export type TemplateVariableType = {
|
||||
|
|
|
|||
|
|
@ -62,8 +62,9 @@ export type CodeAreaComponentType = {
|
|||
onChange: (value: string[] | string) => void;
|
||||
value: string;
|
||||
editNode?: boolean;
|
||||
nodeClass: APIClassType;
|
||||
setNodeClass: (value: APIClassType) => void;
|
||||
nodeClass?: APIClassType;
|
||||
setNodeClass?: (value: APIClassType) => void;
|
||||
dynamic?: boolean;
|
||||
};
|
||||
|
||||
export type FileComponentType = {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
Cpu,
|
||||
Download,
|
||||
DownloadCloud,
|
||||
Edit,
|
||||
Eraser,
|
||||
ExternalLink,
|
||||
File,
|
||||
|
|
@ -74,6 +75,7 @@ import { EvernoteIcon } from "../icons/Evernote";
|
|||
import { FBIcon } from "../icons/FacebookMessenger";
|
||||
import { GitBookIcon } from "../icons/GitBook";
|
||||
import { GoogleIcon } from "../icons/Google";
|
||||
import GradientSparkles from "../icons/GradientSparkles";
|
||||
import { HuggingFaceIcon } from "../icons/HuggingFace";
|
||||
import { IFixIcon } from "../icons/IFixIt";
|
||||
import { MetaIcon } from "../icons/Meta";
|
||||
|
|
@ -146,6 +148,7 @@ export const nodeColors: { [char: string]: string } = {
|
|||
str: "#049524",
|
||||
retrievers: "#e6b25a",
|
||||
unknown: "#9CA3AF",
|
||||
custom_components: "#ab11ab",
|
||||
};
|
||||
|
||||
export const nodeNames: { [char: string]: string } = {
|
||||
|
|
@ -166,6 +169,7 @@ export const nodeNames: { [char: string]: string } = {
|
|||
retrievers: "Retrievers",
|
||||
utilities: "Utilities",
|
||||
output_parsers: "Output Parsers",
|
||||
custom_components: "Custom",
|
||||
unknown: "Unknown",
|
||||
};
|
||||
|
||||
|
|
@ -224,6 +228,8 @@ export const nodeIconsLucide = {
|
|||
unknown: HelpCircle,
|
||||
WikipediaQueryRun: SvgWikipedia,
|
||||
WolframAlphaQueryRun: SvgWolfram,
|
||||
custom_components: GradientSparkles,
|
||||
custom: Edit,
|
||||
Trash2,
|
||||
X,
|
||||
XCircle,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { IVarHighlightType } from "../types/components";
|
|||
import { FlowType } from "../types/flow";
|
||||
import { TabsState } from "../types/tabs";
|
||||
import { buildTweaks } from "./reactflowUtils";
|
||||
import { nodeNames } from "./styleUtils";
|
||||
|
||||
export function classNames(...classes: Array<string>) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
|
|
@ -88,12 +89,13 @@ export function checkUpperWords(str: string) {
|
|||
export const isWrappedWithClass = (event: any, className: string | undefined) =>
|
||||
event.target.closest(`.${className}`);
|
||||
|
||||
export function groupByFamily(data, baseClasses, left, type) {
|
||||
export function groupByFamily(data, baseClasses, left, type, flow) {
|
||||
let parentOutput: string;
|
||||
let arrOfParent: string[] = [];
|
||||
let arrOfType: { family: string; type: string; component: string }[] = [];
|
||||
let arrOfLength: { length: number; type: string }[] = [];
|
||||
let lastType = "";
|
||||
|
||||
Object.keys(data).forEach((d) => {
|
||||
Object.keys(data[d]).forEach((n) => {
|
||||
try {
|
||||
|
|
@ -165,7 +167,7 @@ export function groupByFamily(data, baseClasses, left, type) {
|
|||
});
|
||||
}
|
||||
|
||||
if (left === false) {
|
||||
if (parentOutput !== "custom_components") {
|
||||
let resFil = result.filter((group) => group.family === parentOutput);
|
||||
result = resFil;
|
||||
}
|
||||
|
|
@ -203,6 +205,107 @@ export function groupByFamily(data, baseClasses, left, type) {
|
|||
}
|
||||
}
|
||||
|
||||
export function groupByFamilyCustom(data, baseClasses, left, type, flow) {
|
||||
let arrOfParentCustom: string[] = [];
|
||||
let arrOfType: { family: string; type: string; component: string }[] = [];
|
||||
|
||||
if (type === "CustomComponent") {
|
||||
const uniqueValuesSet = new Set();
|
||||
flow.forEach((element) => {
|
||||
element["data"]["node"]["base_classes"].forEach((el) => {
|
||||
if (!uniqueValuesSet.has(el)) {
|
||||
arrOfParentCustom.push(el);
|
||||
uniqueValuesSet.add(el);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (left === false) {
|
||||
arrOfParentCustom.map((n) => {
|
||||
try {
|
||||
arrOfType.push({
|
||||
family: "custom_components",
|
||||
type: n,
|
||||
component: nodeNames["custom_components"],
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
flow.forEach((element) => {
|
||||
Object.keys(element["data"]["node"]["template"]).map((el) => {
|
||||
if (
|
||||
element["data"]["node"]["template"][el].input_types &&
|
||||
element["data"]["node"]["template"][el].input_types.length > 0
|
||||
) {
|
||||
element["data"]["node"]["template"][el].input_types.map((n) => {
|
||||
try {
|
||||
arrOfType.push({
|
||||
family: "custom_components",
|
||||
type: n,
|
||||
component: nodeNames["custom_components"],
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const groupedResult = {};
|
||||
|
||||
arrOfType.forEach((item) => {
|
||||
const { family, type, component } = item;
|
||||
if (groupedResult.hasOwnProperty(family)) {
|
||||
if (!groupedResult[family].type.includes(type)) {
|
||||
groupedResult[family].type += `, ${type}`;
|
||||
}
|
||||
} else {
|
||||
groupedResult[family] = { family, type, component };
|
||||
}
|
||||
});
|
||||
|
||||
const result = Object.values(groupedResult);
|
||||
|
||||
if (left === false) {
|
||||
let resultFiltered = [];
|
||||
flow.forEach((element) => {
|
||||
Object.keys(element["data"]["node"]["template"]).map((el) => {
|
||||
if (
|
||||
element["data"]["node"]["template"][el].input_types &&
|
||||
element["data"]["node"]["template"][el].input_types.length > 0
|
||||
) {
|
||||
element["data"]["node"]["template"][el].input_types.map((n) => {
|
||||
resultFiltered.push({
|
||||
family: "custom_components",
|
||||
type: n,
|
||||
component: element["data"]["node"]["display_name"],
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (resultFiltered.length === 0) {
|
||||
Object.keys(groupedResult).forEach((el) => {
|
||||
resultFiltered.push({
|
||||
family: "custom_components",
|
||||
type: groupedResult[el].type,
|
||||
component: nodeNames["custom_components"],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return resultFiltered;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export function buildInputs(tabsState, id) {
|
||||
return tabsState &&
|
||||
tabsState[id] &&
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ module.exports = {
|
|||
"status-yellow": "var(--status-yellow)",
|
||||
"success-background": "var(--success-background)",
|
||||
"success-foreground": "var(--success-foreground)",
|
||||
"beta-background": "var(--beta-background)",
|
||||
"beta-foreground": "var(--beta-foreground)",
|
||||
"chat-bot-icon": "var(--chat-bot-icon)",
|
||||
"chat-user-icon": "var(--chat-user-icon)",
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue