Enabling prompt modal close without variables (#915)
This commit is contained in:
commit
b5cb175c58
10 changed files with 3578 additions and 2037 deletions
|
|
@ -53,6 +53,16 @@ def post_validate_prompt(prompt_request: ValidatePromptRequest):
|
|||
|
||||
def get_old_custom_fields(prompt_request):
|
||||
try:
|
||||
if (
|
||||
len(prompt_request.frontend_node.custom_fields) == 1
|
||||
and prompt_request.name == ""
|
||||
):
|
||||
# If there is only one custom field and the name is empty string
|
||||
# then we are dealing with the first prompt request after the node was created
|
||||
prompt_request.name = list(
|
||||
prompt_request.frontend_node.custom_fields.keys()
|
||||
)[0]
|
||||
|
||||
old_custom_fields = prompt_request.frontend_node.custom_fields[
|
||||
prompt_request.name
|
||||
].copy()
|
||||
|
|
|
|||
5361
src/frontend/package-lock.json
generated
5361
src/frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -321,11 +321,16 @@ export default function ParameterComponent({
|
|||
field_name={name}
|
||||
setNodeClass={(nodeClass) => {
|
||||
data.node = nodeClass;
|
||||
const clone = cloneDeep(data);
|
||||
clone.node = nodeClass;
|
||||
setData(clone);
|
||||
}}
|
||||
nodeClass={data.node}
|
||||
disabled={disabled}
|
||||
value={data.node.template[name].value ?? ""}
|
||||
onChange={handleOnNewValue}
|
||||
onChange={(e) => {
|
||||
handleOnNewValue(e);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useEffect } from "react";
|
|||
import { TypeModal } from "../../constants/enums";
|
||||
import { postValidatePrompt } from "../../controllers/API";
|
||||
import GenericModal from "../../modals/genericModal";
|
||||
import { TextAreaComponentType } from "../../types/components";
|
||||
import { PromptAreaComponentType } from "../../types/components";
|
||||
import IconComponent from "../genericIconComponent";
|
||||
|
||||
export default function PromptAreaComponent({
|
||||
|
|
@ -14,7 +14,7 @@ export default function PromptAreaComponent({
|
|||
onChange,
|
||||
disabled,
|
||||
editNode = false,
|
||||
}: TextAreaComponentType) {
|
||||
}: PromptAreaComponentType) {
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
onChange("");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Infinity } from "lucide-react";
|
||||
import { InfinityIcon } from "lucide-react";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
const GradientSparkles = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
|
|
@ -13,7 +13,7 @@ const GradientSparkles = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
|||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<Infinity stroke="url(#grad1)" ref={ref} {...props} />
|
||||
<InfinityIcon stroke="url(#grad1)" ref={ref} {...props} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import { ReactNode, forwardRef, useContext, useEffect, useState } from "react";
|
||||
import {
|
||||
ReactNode,
|
||||
forwardRef,
|
||||
useContext,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import CodeAreaComponent from "../../components/codeAreaComponent";
|
||||
import Dropdown from "../../components/dropdownComponent";
|
||||
import FloatComponent from "../../components/floatComponent";
|
||||
|
|
@ -44,40 +51,44 @@ const EditNodeModal = forwardRef(
|
|||
ref
|
||||
) => {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [myData, setMyData] = useState(data);
|
||||
const { setTabsState, tabId } = useContext(TabsContext);
|
||||
const { reactFlowInstance } = useContext(typesContext);
|
||||
const myData = useRef(data);
|
||||
|
||||
let disabled =
|
||||
reactFlowInstance?.getEdges().some((e) => e.targetHandle === data.id) ??
|
||||
false;
|
||||
|
||||
function changeAdvanced(n) {
|
||||
setMyData((old) => {
|
||||
let newData = cloneDeep(old);
|
||||
newData.node.template[n].advanced = !newData.node.template[n].advanced;
|
||||
return newData;
|
||||
});
|
||||
let newData = cloneDeep(data);
|
||||
newData.node.template[n].advanced = !newData.node.template[n].advanced;
|
||||
myData.current = newData;
|
||||
}
|
||||
|
||||
const handleOnNewValue = (newValue: any, name) => {
|
||||
setMyData((old) => {
|
||||
let newData = cloneDeep(old);
|
||||
newData.node.template[name].value = newValue;
|
||||
return newData;
|
||||
});
|
||||
let newData = cloneDeep(data);
|
||||
newData.node.template[name].value = newValue;
|
||||
myData.current = newData;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setMyData(data); // reset data to what it is on node when opening modal
|
||||
myData.current = data;
|
||||
}, [modalOpen]);
|
||||
|
||||
return (
|
||||
<BaseModal size="large-h-full" open={modalOpen} setOpen={setModalOpen}>
|
||||
<BaseModal
|
||||
size="large-h-full"
|
||||
open={modalOpen}
|
||||
setOpen={setModalOpen}
|
||||
onChangeOpenModal={(open) => {
|
||||
let newData = cloneDeep(data);
|
||||
myData.current = newData;
|
||||
}}
|
||||
>
|
||||
<BaseModal.Trigger>{children}</BaseModal.Trigger>
|
||||
<BaseModal.Header description={myData.node?.description}>
|
||||
<span className="pr-2">{myData.type}</span>
|
||||
<Badge variant="secondary">ID: {myData.id}</Badge>
|
||||
<BaseModal.Header description={myData.current.node?.description}>
|
||||
<span className="pr-2">{myData.current.type}</span>
|
||||
<Badge variant="secondary">ID: {myData.current.id}</Badge>
|
||||
</BaseModal.Header>
|
||||
<BaseModal.Content>
|
||||
<div className="flex pb-2">
|
||||
|
|
@ -110,50 +121,57 @@ const EditNodeModal = forwardRef(
|
|||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody className="p-0">
|
||||
{Object.keys(myData.node.template)
|
||||
{Object.keys(myData.current.node.template)
|
||||
.filter(
|
||||
(t) =>
|
||||
t.charAt(0) !== "_" &&
|
||||
myData.node.template[t].show &&
|
||||
(myData.node.template[t].type === "str" ||
|
||||
myData.node.template[t].type === "bool" ||
|
||||
myData.node.template[t].type === "float" ||
|
||||
myData.node.template[t].type === "code" ||
|
||||
myData.node.template[t].type === "prompt" ||
|
||||
myData.node.template[t].type === "file" ||
|
||||
myData.node.template[t].type === "int")
|
||||
myData.current.node.template[t].show &&
|
||||
(myData.current.node.template[t].type === "str" ||
|
||||
myData.current.node.template[t].type === "bool" ||
|
||||
myData.current.node.template[t].type ===
|
||||
"float" ||
|
||||
myData.current.node.template[t].type === "code" ||
|
||||
myData.current.node.template[t].type ===
|
||||
"prompt" ||
|
||||
myData.current.node.template[t].type === "file" ||
|
||||
myData.current.node.template[t].type === "int")
|
||||
)
|
||||
.map((n, i) => (
|
||||
<TableRow key={i} className="h-10">
|
||||
<TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
|
||||
{myData.node.template[n].name
|
||||
? myData.node.template[n].name
|
||||
: myData.node.template[n].display_name}
|
||||
{myData.current.node.template[n].name
|
||||
? myData.current.node.template[n].name
|
||||
: myData.current.node.template[n].display_name}
|
||||
</TableCell>
|
||||
<TableCell className="w-[300px] p-0 text-center text-xs text-foreground ">
|
||||
{myData.node.template[n].type === "str" &&
|
||||
!myData.node.template[n].options ? (
|
||||
{myData.current.node.template[n].type === "str" &&
|
||||
!myData.current.node.template[n].options ? (
|
||||
<div className="mx-auto">
|
||||
{myData.node.template[n].list ? (
|
||||
{myData.current.node.template[n].list ? (
|
||||
<InputListComponent
|
||||
editNode={true}
|
||||
disabled={disabled}
|
||||
value={
|
||||
!myData.node.template[n].value ||
|
||||
myData.node.template[n].value === ""
|
||||
!myData.current.node.template[n]
|
||||
.value ||
|
||||
myData.current.node.template[n]
|
||||
.value === ""
|
||||
? [""]
|
||||
: myData.node.template[n].value
|
||||
: myData.current.node.template[n]
|
||||
.value
|
||||
}
|
||||
onChange={(t: string[]) => {
|
||||
handleOnNewValue(t, n);
|
||||
}}
|
||||
/>
|
||||
) : myData.node.template[n].multiline ? (
|
||||
) : myData.current.node.template[n]
|
||||
.multiline ? (
|
||||
<TextAreaComponent
|
||||
disabled={disabled}
|
||||
editNode={true}
|
||||
value={
|
||||
myData.node.template[n].value ?? ""
|
||||
myData.current.node.template[n].value ??
|
||||
""
|
||||
}
|
||||
onChange={(t: string) => {
|
||||
handleOnNewValue(t, n);
|
||||
|
|
@ -164,11 +182,12 @@ const EditNodeModal = forwardRef(
|
|||
editNode={true}
|
||||
disabled={disabled}
|
||||
password={
|
||||
myData.node.template[n].password ??
|
||||
false
|
||||
myData.current.node.template[n]
|
||||
.password ?? false
|
||||
}
|
||||
value={
|
||||
myData.node.template[n].value ?? ""
|
||||
myData.current.node.template[n].value ??
|
||||
""
|
||||
}
|
||||
onChange={(t) => {
|
||||
handleOnNewValue(t, n);
|
||||
|
|
@ -176,89 +195,114 @@ const EditNodeModal = forwardRef(
|
|||
/>
|
||||
)}
|
||||
</div>
|
||||
) : myData.node.template[n].type === "bool" ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"bool" ? (
|
||||
<div className="ml-auto">
|
||||
{" "}
|
||||
<ToggleShadComponent
|
||||
disabled={disabled}
|
||||
enabled={myData.node.template[n].value}
|
||||
enabled={
|
||||
myData.current.node.template[n].value
|
||||
}
|
||||
setEnabled={(t) => {
|
||||
handleOnNewValue(t, n);
|
||||
}}
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
) : myData.node.template[n].type === "float" ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"float" ? (
|
||||
<div className="mx-auto">
|
||||
<FloatComponent
|
||||
disabled={disabled}
|
||||
editNode={true}
|
||||
value={myData.node.template[n].value ?? ""}
|
||||
value={
|
||||
myData.current.node.template[n].value ??
|
||||
""
|
||||
}
|
||||
onChange={(t) => {
|
||||
handleOnNewValue(t, n);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : myData.node.template[n].type === "str" &&
|
||||
myData.node.template[n].options ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"str" &&
|
||||
myData.current.node.template[n].options ? (
|
||||
<div className="mx-auto">
|
||||
<Dropdown
|
||||
numberOfOptions={nodeLength}
|
||||
editNode={true}
|
||||
options={myData.node.template[n].options}
|
||||
options={
|
||||
myData.current.node.template[n].options
|
||||
}
|
||||
onSelect={(t) => handleOnNewValue(t, n)}
|
||||
value={
|
||||
myData.node.template[n].value ??
|
||||
myData.current.node.template[n].value ??
|
||||
"Choose an option"
|
||||
}
|
||||
></Dropdown>
|
||||
</div>
|
||||
) : myData.node.template[n].type === "int" ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"int" ? (
|
||||
<div className="mx-auto">
|
||||
<IntComponent
|
||||
disabled={disabled}
|
||||
editNode={true}
|
||||
value={myData.node.template[n].value ?? ""}
|
||||
value={
|
||||
myData.current.node.template[n].value ??
|
||||
""
|
||||
}
|
||||
onChange={(t) => {
|
||||
handleOnNewValue(t, n);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : myData.node.template[n].type === "file" ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"file" ? (
|
||||
<div className="mx-auto">
|
||||
<InputFileComponent
|
||||
editNode={true}
|
||||
disabled={disabled}
|
||||
value={myData.node.template[n].value ?? ""}
|
||||
value={
|
||||
myData.current.node.template[n].value ??
|
||||
""
|
||||
}
|
||||
onChange={(t: string) => {
|
||||
handleOnNewValue(t, n);
|
||||
}}
|
||||
fileTypes={
|
||||
myData.node.template[n].fileTypes
|
||||
myData.current.node.template[n].fileTypes
|
||||
}
|
||||
suffixes={
|
||||
myData.current.node.template[n].suffixes
|
||||
}
|
||||
suffixes={myData.node.template[n].suffixes}
|
||||
onFileChange={(t: string) => {
|
||||
data.node.template[n].file_path = t;
|
||||
}}
|
||||
></InputFileComponent>
|
||||
</div>
|
||||
) : myData.node.template[n].type === "prompt" ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"prompt" ? (
|
||||
<div className="mx-auto">
|
||||
<PromptAreaComponent
|
||||
field_name={n}
|
||||
editNode={true}
|
||||
disabled={disabled}
|
||||
nodeClass={myData.node}
|
||||
nodeClass={myData.current.node}
|
||||
setNodeClass={(nodeClass) => {
|
||||
myData.node = nodeClass;
|
||||
myData.current.node = nodeClass;
|
||||
}}
|
||||
value={myData.node.template[n].value ?? ""}
|
||||
value={
|
||||
myData.current.node.template[n].value ??
|
||||
""
|
||||
}
|
||||
onChange={(t: string) => {
|
||||
handleOnNewValue(t, n);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : myData.node.template[n].type === "code" ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"code" ? (
|
||||
<div className="mx-auto">
|
||||
<CodeAreaComponent
|
||||
dynamic={
|
||||
|
|
@ -270,13 +314,17 @@ const EditNodeModal = forwardRef(
|
|||
nodeClass={data.node}
|
||||
disabled={disabled}
|
||||
editNode={true}
|
||||
value={myData.node.template[n].value ?? ""}
|
||||
value={
|
||||
myData.current.node.template[n].value ??
|
||||
""
|
||||
}
|
||||
onChange={(t: string) => {
|
||||
handleOnNewValue(t, n);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
) : myData.node.template[n].type === "Any" ? (
|
||||
) : myData.current.node.template[n].type ===
|
||||
"Any" ? (
|
||||
"-"
|
||||
) : (
|
||||
<div className="hidden"></div>
|
||||
|
|
@ -285,7 +333,9 @@ const EditNodeModal = forwardRef(
|
|||
<TableCell className="p-0 text-right">
|
||||
<div className="items-center text-center">
|
||||
<ToggleShadComponent
|
||||
enabled={!myData.node.template[n].advanced}
|
||||
enabled={
|
||||
!myData.current.node.template[n].advanced
|
||||
}
|
||||
setEnabled={(e) => changeAdvanced(n)}
|
||||
disabled={disabled}
|
||||
size="small"
|
||||
|
|
@ -306,7 +356,7 @@ const EditNodeModal = forwardRef(
|
|||
<Button
|
||||
className="mt-3"
|
||||
onClick={() => {
|
||||
setData(cloneDeep(myData)); //saves data with actual state of modal
|
||||
setData(cloneDeep(myData.current)); //saves data with actual state of modal
|
||||
setTabsState((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ReactNode } from "react";
|
||||
import { ReactNode, useEffect } from "react";
|
||||
|
||||
import React from "react";
|
||||
import {
|
||||
|
|
@ -48,6 +48,7 @@ interface BaseModalProps {
|
|||
setOpen?: (open: boolean) => void;
|
||||
disable?: boolean;
|
||||
size?: "smaller" | "small" | "medium" | "large" | "large-h-full";
|
||||
onChangeOpenModal?: (open: boolean) => void;
|
||||
}
|
||||
function BaseModal({
|
||||
open,
|
||||
|
|
@ -55,6 +56,7 @@ function BaseModal({
|
|||
disable = false,
|
||||
children,
|
||||
size = "large",
|
||||
onChangeOpenModal,
|
||||
}: BaseModalProps) {
|
||||
const headerChild = React.Children.toArray(children).find(
|
||||
(child) => (child as React.ReactElement).type === Header
|
||||
|
|
@ -98,6 +100,12 @@ function BaseModal({
|
|||
break;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (onChangeOpenModal) {
|
||||
onChangeOpenModal(open);
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
//UPDATE COLORS AND STYLE CLASSSES
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
|
|
|
|||
|
|
@ -130,24 +130,35 @@ export default function GenericModal({
|
|||
: "code-nohighlight";
|
||||
}
|
||||
|
||||
function validatePrompt(closeModal: boolean) {
|
||||
postValidatePrompt(field_name, inputValue, nodeClass)
|
||||
function validatePrompt(closeModal: boolean): void {
|
||||
//nodeClass is always null on tweaks
|
||||
|
||||
postValidatePrompt(field_name, inputValue, nodeClass!)
|
||||
.then((apiReturn) => {
|
||||
if (apiReturn.data) {
|
||||
setValue(inputValue);
|
||||
apiReturn.data.frontend_node["template"]["template"]["value"] =
|
||||
inputValue;
|
||||
setNodeClass!(apiReturn?.data?.frontend_node);
|
||||
|
||||
let inputVariables = apiReturn.data.input_variables ?? [];
|
||||
if (inputVariables && inputVariables.length === 0) {
|
||||
setIsEdit(true);
|
||||
setNoticeData({
|
||||
title: "Your template does not have any variables.",
|
||||
});
|
||||
setModalOpen(closeModal);
|
||||
} else {
|
||||
setIsEdit(false);
|
||||
setSuccessData({
|
||||
title: "Prompt is ready",
|
||||
});
|
||||
setNodeClass(apiReturn.data?.frontend_node);
|
||||
setModalOpen(closeModal);
|
||||
setValue(inputValue);
|
||||
if (
|
||||
JSON.stringify(apiReturn.data?.frontend_node) !==
|
||||
JSON.stringify({})
|
||||
) {
|
||||
setModalOpen(closeModal);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setIsEdit(true);
|
||||
|
|
@ -157,7 +168,6 @@ export default function GenericModal({
|
|||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
setIsEdit(true);
|
||||
return setErrorData({
|
||||
title: "There is something wrong with this prompt, please review it",
|
||||
|
|
@ -169,7 +179,11 @@ export default function GenericModal({
|
|||
const [modalOpen, setModalOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<BaseModal open={modalOpen} setOpen={setModalOpen}>
|
||||
<BaseModal
|
||||
onChangeOpenModal={(open) => {}}
|
||||
open={modalOpen}
|
||||
setOpen={setModalOpen}
|
||||
>
|
||||
<BaseModal.Trigger>{children}</BaseModal.Trigger>
|
||||
<BaseModal.Header
|
||||
description={(() => {
|
||||
|
|
@ -295,9 +309,7 @@ export default function GenericModal({
|
|||
setModalOpen(false);
|
||||
break;
|
||||
case TypeModal.PROMPT:
|
||||
!inputValue || inputValue === ""
|
||||
? setModalOpen(false)
|
||||
: validatePrompt(false);
|
||||
validatePrompt(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -57,6 +57,16 @@ export type TextAreaComponentType = {
|
|||
editNode?: boolean;
|
||||
};
|
||||
|
||||
export type PromptAreaComponentType = {
|
||||
field_name?: string;
|
||||
nodeClass?: APIClassType;
|
||||
setNodeClass?: (value: APIClassType) => void;
|
||||
disabled: boolean;
|
||||
onChange: (value: string[] | string) => void;
|
||||
value: string;
|
||||
editNode?: boolean;
|
||||
};
|
||||
|
||||
export type CodeAreaComponentType = {
|
||||
disabled: boolean;
|
||||
onChange: (value: string[] | string) => void;
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ export function handleKeyDown(
|
|||
inputValue: string | string[] | null,
|
||||
block: string
|
||||
) {
|
||||
console.log(e, inputValue, block);
|
||||
//condition to fix bug control+backspace on Windows/Linux
|
||||
if (
|
||||
(typeof inputValue === "string" &&
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue