Merge branch 'dev' into 335-implement-docarray-vectorstore
This commit is contained in:
commit
12c23408e0
16 changed files with 138 additions and 223 deletions
|
|
@ -18,59 +18,10 @@ def get_number_of_workers(workers=None):
|
||||||
return workers
|
return workers
|
||||||
|
|
||||||
|
|
||||||
def update_settings(config: str):
|
def update_settings(config: str, dev: bool = False):
|
||||||
"""Update the settings from a config file."""
|
"""Update the settings from a config file."""
|
||||||
if config:
|
if config:
|
||||||
settings.update_from_yaml(config)
|
settings.update_from_yaml(config, dev=dev)
|
||||||
|
|
||||||
|
|
||||||
@app.command()
|
|
||||||
def serve(
|
|
||||||
host: str = typer.Option("127.0.0.1", help="Host to bind the server to."),
|
|
||||||
workers: int = typer.Option(1, help="Number of worker processes."),
|
|
||||||
timeout: int = typer.Option(60, help="Worker timeout in seconds."),
|
|
||||||
port: int = typer.Option(7860, help="Port to listen on."),
|
|
||||||
config: str = typer.Option("config.yaml", help="Path to the configuration file."),
|
|
||||||
log_level: str = typer.Option("info", help="Logging level."),
|
|
||||||
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."),
|
|
||||||
jcloud: bool = typer.Option(False, help="Deploy on Jina AI Cloud"),
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Run the Langflow server.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if jcloud:
|
|
||||||
return serve_on_jcloud()
|
|
||||||
|
|
||||||
configure(log_level=log_level, log_file=log_file)
|
|
||||||
update_settings(config)
|
|
||||||
app = create_app()
|
|
||||||
# get the directory of the current file
|
|
||||||
path = Path(__file__).parent
|
|
||||||
static_files_dir = path / "frontend"
|
|
||||||
app.mount(
|
|
||||||
"/",
|
|
||||||
StaticFiles(directory=static_files_dir, html=True),
|
|
||||||
name="static",
|
|
||||||
)
|
|
||||||
options = {
|
|
||||||
"bind": f"{host}:{port}",
|
|
||||||
"workers": get_number_of_workers(workers),
|
|
||||||
"worker_class": "uvicorn.workers.UvicornWorker",
|
|
||||||
"timeout": timeout,
|
|
||||||
}
|
|
||||||
|
|
||||||
if platform.system() in ["Darwin", "Windows"]:
|
|
||||||
# Run using uvicorn on MacOS and Windows
|
|
||||||
# Windows doesn't support gunicorn
|
|
||||||
# MacOS requires an env variable to be set to use gunicorn
|
|
||||||
import uvicorn
|
|
||||||
|
|
||||||
uvicorn.run(app, host=host, port=port, log_level=log_level)
|
|
||||||
else:
|
|
||||||
from langflow.server import LangflowApplication
|
|
||||||
|
|
||||||
LangflowApplication(app, options).run()
|
|
||||||
|
|
||||||
|
|
||||||
def serve_on_jcloud():
|
def serve_on_jcloud():
|
||||||
|
|
@ -119,6 +70,56 @@ def serve_on_jcloud():
|
||||||
click.secho("https://github.com/jina-ai/langchain-serve", fg="blue")
|
click.secho("https://github.com/jina-ai/langchain-serve", fg="blue")
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def serve(
|
||||||
|
host: str = typer.Option("127.0.0.1", help="Host to bind the server to."),
|
||||||
|
workers: int = typer.Option(1, help="Number of worker processes."),
|
||||||
|
timeout: int = typer.Option(60, help="Worker timeout in seconds."),
|
||||||
|
port: int = typer.Option(7860, help="Port to listen on."),
|
||||||
|
config: str = typer.Option("config.yaml", help="Path to the configuration file."),
|
||||||
|
log_level: str = typer.Option("info", help="Logging level."),
|
||||||
|
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."),
|
||||||
|
jcloud: bool = typer.Option(False, help="Deploy on Jina AI Cloud"),
|
||||||
|
dev: bool = typer.Option(False, help="Run in development mode (may contain bugs)"),
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Run the Langflow server.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if jcloud:
|
||||||
|
return serve_on_jcloud()
|
||||||
|
|
||||||
|
configure(log_level=log_level, log_file=log_file)
|
||||||
|
update_settings(config, dev=dev)
|
||||||
|
app = create_app()
|
||||||
|
# get the directory of the current file
|
||||||
|
path = Path(__file__).parent
|
||||||
|
static_files_dir = path / "frontend"
|
||||||
|
app.mount(
|
||||||
|
"/",
|
||||||
|
StaticFiles(directory=static_files_dir, html=True),
|
||||||
|
name="static",
|
||||||
|
)
|
||||||
|
options = {
|
||||||
|
"bind": f"{host}:{port}",
|
||||||
|
"workers": get_number_of_workers(workers),
|
||||||
|
"worker_class": "uvicorn.workers.UvicornWorker",
|
||||||
|
"timeout": timeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
if platform.system() in ["Darwin", "Windows"]:
|
||||||
|
# Run using uvicorn on MacOS and Windows
|
||||||
|
# Windows doesn't support gunicorn
|
||||||
|
# MacOS requires an env variable to be set to use gunicorn
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
uvicorn.run(app, host=host, port=port, log_level=log_level)
|
||||||
|
else:
|
||||||
|
from langflow.server import LangflowApplication
|
||||||
|
|
||||||
|
LangflowApplication(app, options).run()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
app()
|
app()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ chains:
|
||||||
- MidJourneyPromptChain
|
- MidJourneyPromptChain
|
||||||
- TimeTravelGuideChain
|
- TimeTravelGuideChain
|
||||||
- SQLDatabaseChain
|
- SQLDatabaseChain
|
||||||
dev: false
|
|
||||||
documentloaders:
|
documentloaders:
|
||||||
- AirbyteJSONLoader
|
- AirbyteJSONLoader
|
||||||
- CoNLLULoader
|
- CoNLLULoader
|
||||||
|
|
@ -109,9 +108,6 @@ utilities:
|
||||||
- SQLDatabase
|
- SQLDatabase
|
||||||
vectorstores:
|
vectorstores:
|
||||||
- Chroma
|
- Chroma
|
||||||
- DocArrayHnswSearch
|
|
||||||
- DocArrayInMemorySearch
|
|
||||||
- Qdrant
|
|
||||||
wrappers:
|
wrappers:
|
||||||
- RequestsWrapper # Wait more tests
|
- RequestsWrapper # Wait more tests
|
||||||
# - ChatPromptTemplate
|
# - ChatPromptTemplate
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class Settings(BaseSettings):
|
||||||
values[key] = []
|
values[key] = []
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def update_from_yaml(self, file_path: str):
|
def update_from_yaml(self, file_path: str, dev: bool = False):
|
||||||
new_settings = load_settings_from_yaml(file_path)
|
new_settings = load_settings_from_yaml(file_path)
|
||||||
self.chains = new_settings.chains or []
|
self.chains = new_settings.chains or []
|
||||||
self.agents = new_settings.agents or []
|
self.agents = new_settings.agents or []
|
||||||
|
|
@ -44,7 +44,7 @@ class Settings(BaseSettings):
|
||||||
self.toolkits = new_settings.toolkits or []
|
self.toolkits = new_settings.toolkits or []
|
||||||
self.textsplitters = new_settings.textsplitters or []
|
self.textsplitters = new_settings.textsplitters or []
|
||||||
self.utilities = new_settings.utilities or []
|
self.utilities = new_settings.utilities or []
|
||||||
self.dev = new_settings.dev or False
|
self.dev = dev
|
||||||
|
|
||||||
|
|
||||||
def save_settings_to_yaml(settings: Settings, file_path: str):
|
def save_settings_to_yaml(settings: Settings, file_path: str):
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ export default function FloatComponent({
|
||||||
onChange("");
|
onChange("");
|
||||||
}
|
}
|
||||||
}, [disabled, onChange]);
|
}, [disabled, onChange]);
|
||||||
const {setDisableCopyPaste} = useContext(TabsContext)
|
|
||||||
return (
|
return (
|
||||||
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
|
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
|
||||||
<input
|
<input
|
||||||
|
|
@ -29,12 +28,7 @@ export default function FloatComponent({
|
||||||
setMyValue(e.target.value);
|
setMyValue(e.target.value);
|
||||||
onChange(e.target.value);
|
onChange(e.target.value);
|
||||||
}}
|
}}
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false)
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ export default function InputComponent({
|
||||||
}: InputComponentType) {
|
}: InputComponentType) {
|
||||||
const [myValue, setMyValue] = useState(value ?? "");
|
const [myValue, setMyValue] = useState(value ?? "");
|
||||||
const [pwdVisible, setPwdVisible] = useState(false);
|
const [pwdVisible, setPwdVisible] = useState(false);
|
||||||
const {setDisableCopyPaste} = useContext(TabsContext)
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
setMyValue("");
|
setMyValue("");
|
||||||
|
|
@ -28,12 +27,7 @@ export default function InputComponent({
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
value={myValue}
|
value={myValue}
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false)
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true)
|
|
||||||
}}
|
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"block w-full pr-12 form-input dark:bg-gray-900 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm",
|
"block w-full pr-12 form-input dark:bg-gray-900 dark:border-gray-600 rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm",
|
||||||
disabled ? " bg-gray-200 dark:bg-gray-700" : "",
|
disabled ? " bg-gray-200 dark:bg-gray-700" : "",
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ export default function InputListComponent({
|
||||||
onChange([""]);
|
onChange([""]);
|
||||||
}
|
}
|
||||||
}, [disabled, onChange]);
|
}, [disabled, onChange]);
|
||||||
const {setDisableCopyPaste} = useContext(TabsContext)
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
|
|
@ -43,12 +42,6 @@ export default function InputListComponent({
|
||||||
});
|
});
|
||||||
onChange(inputList);
|
onChange(inputList);
|
||||||
}}
|
}}
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false)
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{idx === inputList.length - 1 ? (
|
{idx === inputList.length - 1 ? (
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ export default function IntComponent({
|
||||||
onChange("");
|
onChange("");
|
||||||
}
|
}
|
||||||
}, [disabled, onChange]);
|
}, [disabled, onChange]);
|
||||||
const {setDisableCopyPaste} =useContext(TabsContext)
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
|
|
@ -45,12 +44,7 @@ export default function IntComponent({
|
||||||
setMyValue(e.target.value);
|
setMyValue(e.target.value);
|
||||||
onChange(e.target.value);
|
onChange(e.target.value);
|
||||||
}}
|
}}
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false)
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ export default function ChatInput({
|
||||||
}
|
}
|
||||||
}, [chatValue]);
|
}, [chatValue]);
|
||||||
|
|
||||||
const { setDisableCopyPaste } = useContext(TabsContext);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<textarea
|
<textarea
|
||||||
|
|
@ -27,12 +25,6 @@ export default function ChatInput({
|
||||||
sendMessage();
|
sendMessage();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false)
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true)
|
|
||||||
}}
|
|
||||||
rows={1}
|
rows={1}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
disabled={lockChat}
|
disabled={lockChat}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import { sendAllProps } from "../../types/api";
|
||||||
import { ChatMessageType, ChatType } from "../../types/chat";
|
import { ChatMessageType, ChatType } from "../../types/chat";
|
||||||
import ChatInput from "./chatInput";
|
import ChatInput from "./chatInput";
|
||||||
|
|
||||||
import _ from "lodash";
|
import _, { set } from "lodash";
|
||||||
|
|
||||||
export default function ChatModal({
|
export default function ChatModal({
|
||||||
flow,
|
flow,
|
||||||
|
|
@ -100,9 +100,9 @@ export default function ChatModal({
|
||||||
function handleOnClose(event: CloseEvent) {
|
function handleOnClose(event: CloseEvent) {
|
||||||
if (isOpen.current) {
|
if (isOpen.current) {
|
||||||
setErrorData({ title: event.reason });
|
setErrorData({ title: event.reason });
|
||||||
setLockChat(false);
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
connectWS();
|
connectWS();
|
||||||
|
setLockChat(false);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,6 +235,13 @@ export default function ChatModal({
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if((ws.current.readyState=== ws.current.CLOSED || ws.current.readyState=== ws.current.CLOSING)){
|
||||||
|
connectWS();
|
||||||
|
setLockChat(false);
|
||||||
|
}
|
||||||
|
},[lockChat]);
|
||||||
|
|
||||||
async function sendAll(data: sendAllProps) {
|
async function sendAll(data: sendAllProps) {
|
||||||
try {
|
try {
|
||||||
if (ws) {
|
if (ws) {
|
||||||
|
|
@ -339,6 +346,7 @@ export default function ChatModal({
|
||||||
function clearChat() {
|
function clearChat() {
|
||||||
setChatHistory([]);
|
setChatHistory([]);
|
||||||
ws.current.send(JSON.stringify({ clear_history: true }));
|
ws.current.send(JSON.stringify({ clear_history: true }));
|
||||||
|
if(lockChat) setLockChat(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setModalOpen(x: boolean) {
|
function setModalOpen(x: boolean) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ export default function CodeAreaModal({
|
||||||
const [code, setCode] = useState(value);
|
const [code, setCode] = useState(value);
|
||||||
const { dark } = useContext(darkContext);
|
const { dark } = useContext(darkContext);
|
||||||
const { setErrorData, setSuccessData } = useContext(alertContext);
|
const { setErrorData, setSuccessData } = useContext(alertContext);
|
||||||
const { setDisableCopyPaste } = useContext(TabsContext);
|
|
||||||
const { closePopUp } = useContext(PopUpContext);
|
const { closePopUp } = useContext(PopUpContext);
|
||||||
const ref = useRef();
|
const ref = useRef();
|
||||||
function setModalOpen(x: boolean) {
|
function setModalOpen(x: boolean) {
|
||||||
|
|
@ -111,12 +110,6 @@ export default function CodeAreaModal({
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
setCode(value);
|
setCode(value);
|
||||||
}}
|
}}
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false)
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true)
|
|
||||||
}}
|
|
||||||
className="h-full w-full rounded-lg"
|
className="h-full w-full rounded-lg"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export default function ExportModal() {
|
||||||
const { closePopUp } = useContext(PopUpContext);
|
const { closePopUp } = useContext(PopUpContext);
|
||||||
const ref = useRef();
|
const ref = useRef();
|
||||||
const { setErrorData } = useContext(alertContext);
|
const { setErrorData } = useContext(alertContext);
|
||||||
const { flows, tabIndex, updateFlow, downloadFlow,setDisableCopyPaste } = useContext(TabsContext);
|
const { flows, tabIndex, updateFlow, downloadFlow } = useContext(TabsContext);
|
||||||
function setModalOpen(x: boolean) {
|
function setModalOpen(x: boolean) {
|
||||||
setOpen(x);
|
setOpen(x);
|
||||||
if (x === false) {
|
if (x === false) {
|
||||||
|
|
@ -113,12 +113,6 @@ export default function ExportModal() {
|
||||||
placeholder="File name"
|
placeholder="File name"
|
||||||
id="name"
|
id="name"
|
||||||
className="focus:border focus:border-blue block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500 text-gray-900 dark:text-gray-100"
|
className="focus:border focus:border-blue block w-full px-3 py-2 border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500 text-gray-900 dark:text-gray-100"
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false);
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
|
|
@ -133,12 +127,6 @@ export default function ExportModal() {
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false);
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true);
|
|
||||||
}}
|
|
||||||
name="description"
|
name="description"
|
||||||
id="description"
|
id="description"
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
|
|
@ -163,12 +151,7 @@ export default function ExportModal() {
|
||||||
id="checkbox"
|
id="checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="h-4 w-4 text-blue-600 border-gray-300 rounded dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
className="h-4 w-4 text-blue-600 border-gray-300 rounded dark:bg-gray-800 dark:border-gray-600 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||||
onBlur={() => {
|
|
||||||
setDisableCopyPaste(false);
|
|
||||||
}}
|
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<span className="ml-2 font-medium text-gray-700 dark:text-white">
|
<span className="ml-2 font-medium text-gray-700 dark:text-white">
|
||||||
Save with my API keys
|
Save with my API keys
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export default function ButtonBox({
|
||||||
}) {
|
}) {
|
||||||
let bigCircle: string;
|
let bigCircle: string;
|
||||||
let smallCircle: string;
|
let smallCircle: string;
|
||||||
let minTitleFontSize: number;
|
let titleFontSize: string;
|
||||||
let descriptionFontSize: string;
|
let descriptionFontSize: string;
|
||||||
let padding: string;
|
let padding: string;
|
||||||
let marginTop: string;
|
let marginTop: string;
|
||||||
|
|
@ -32,88 +32,48 @@ export default function ButtonBox({
|
||||||
let width: string;
|
let width: string;
|
||||||
let textHeight: number;
|
let textHeight: number;
|
||||||
let textWidth: number;
|
let textWidth: number;
|
||||||
const [truncate, setTruncate] = useState<boolean>(false);
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case "small":
|
case "small":
|
||||||
bigCircle = "h-12 w-12";
|
bigCircle = "h-12 w-12";
|
||||||
smallCircle = "h-8 w-8";
|
smallCircle = "h-8 w-8";
|
||||||
minTitleFontSize =9;
|
titleFontSize = "text-sm";
|
||||||
descriptionFontSize = "text-xs";
|
descriptionFontSize = "text-xs";
|
||||||
padding = "p-2 py-3";
|
padding = "p-2 py-3";
|
||||||
marginTop = "mt-2";
|
marginTop = "mt-2";
|
||||||
height = "h-36";
|
height = "h-36";
|
||||||
textHeight = 70;
|
width = "w-32";
|
||||||
textWidth = 40;
|
break;
|
||||||
width = "w-32";
|
case "medium":
|
||||||
break;
|
bigCircle = "h-16 w-16";
|
||||||
case "medium":
|
smallCircle = "h-12 w-12";
|
||||||
bigCircle = "h-16 w-16";
|
titleFontSize = "text-base";
|
||||||
smallCircle = "h-12 w-12";
|
descriptionFontSize = "text-sm";
|
||||||
minTitleFontSize = 11;
|
padding = "p-4 py-5";
|
||||||
descriptionFontSize = "text-sm";
|
marginTop = "mt-3";
|
||||||
padding = "p-4 py-5";
|
height = "h-44";
|
||||||
marginTop = "mt-3";
|
width = "w-36";
|
||||||
textHeight = 112;
|
break;
|
||||||
textWidth = 162;
|
case "big":
|
||||||
height = "h-44";
|
bigCircle = "h-20 w-20";
|
||||||
width = "w-36";
|
smallCircle = "h-16 w-16";
|
||||||
break;
|
titleFontSize = "text-lg";
|
||||||
case "big":
|
descriptionFontSize = "text-sm";
|
||||||
bigCircle = "h-20 w-20";
|
padding = "p-8 py-10";
|
||||||
smallCircle = "h-16 w-16";
|
marginTop = "mt-6";
|
||||||
minTitleFontSize = 12;
|
height = "h-56";
|
||||||
descriptionFontSize = "text-sm";
|
width = "w-44";
|
||||||
padding = "p-8 py-10";
|
break;
|
||||||
marginTop = "mt-6";
|
default:
|
||||||
height = "h-56";
|
bigCircle = "h-20 w-20";
|
||||||
width = "w-44";
|
smallCircle = "h-16 w-16";
|
||||||
break;
|
titleFontSize = "text-lg";
|
||||||
default:
|
descriptionFontSize = "text-sm";
|
||||||
bigCircle = "h-20 w-20";
|
padding = "p-8 py-10";
|
||||||
smallCircle = "h-16 w-16";
|
marginTop = "mt-6";
|
||||||
minTitleFontSize = 12;
|
height = "h-56";
|
||||||
descriptionFontSize = "text-sm";
|
width = "w-44";
|
||||||
padding = "p-8 py-10";
|
break;
|
||||||
marginTop = "mt-6";
|
|
||||||
height = "h-56";
|
|
||||||
width = "w-44";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [fontSize, setFontSize] = useState<number>(16); // Initial font size value
|
|
||||||
|
|
||||||
const titleRef = useRef<HTMLHeadingElement>(null);
|
|
||||||
const parentDivRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const textElement = titleRef.current;
|
|
||||||
const parentDivElement = parentDivRef.current;
|
|
||||||
|
|
||||||
if (!textElement || !parentDivElement) return;
|
|
||||||
|
|
||||||
const parentDivHeight = parentDivElement.offsetHeight;
|
|
||||||
const parentDivWidth = parentDivElement.offsetWidth;
|
|
||||||
let textElementHeight = textElement.scrollHeight;
|
|
||||||
let textElementWidth = textElement.scrollWidth;
|
|
||||||
|
|
||||||
if (textElementHeight > parentDivHeight || textElementWidth > parentDivWidth && fontSize > minTitleFontSize) {
|
|
||||||
let newFontSize = fontSize;
|
|
||||||
|
|
||||||
while (textElementHeight > parentDivHeight || textElementWidth > parentDivWidth) {
|
|
||||||
newFontSize -= 1;
|
|
||||||
textElement.style.fontSize = `${newFontSize}px`;
|
|
||||||
textElementHeight = textElement.scrollHeight;
|
|
||||||
textElementWidth = textElement.scrollWidth;
|
|
||||||
}
|
|
||||||
if(newFontSize <= minTitleFontSize){
|
|
||||||
setTruncate(true);
|
|
||||||
setFontSize(minTitleFontSize);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
setFontSize(newFontSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [title, size, fontSize]);
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -136,15 +96,17 @@ export default function ButtonBox({
|
||||||
<div className={textColor}>{icon}</div>
|
<div className={textColor}>{icon}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref={parentDivRef} className="w-full h-1/2 mt-auto">
|
<div className="w-full mt-auto mb-auto">
|
||||||
<div
|
<h3
|
||||||
ref={titleRef}
|
className={classNames(
|
||||||
className={classNames(truncate?"truncate":"",
|
"w-full font-semibold break-words text-white dark:text-white/80 truncate-multiline",
|
||||||
" font-semibold text-white h-full dark:text-white/80",
|
titleFontSize,
|
||||||
)} >
|
marginTop
|
||||||
{title}
|
)}
|
||||||
</div>
|
>
|
||||||
</div>
|
{title}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -177,10 +177,10 @@ export default function ImportModal() {
|
||||||
!loadingExamples &&
|
!loadingExamples &&
|
||||||
examples.map((example, index) => {
|
examples.map((example, index) => {
|
||||||
return (
|
return (
|
||||||
<div id="index">
|
<div key={index}>
|
||||||
{" "}
|
{" "}
|
||||||
<ButtonBox
|
<ButtonBox
|
||||||
size="big"
|
size="small"
|
||||||
bgColor="bg-emerald-500 dark:bg-emerald-500/75"
|
bgColor="bg-emerald-500 dark:bg-emerald-500/75"
|
||||||
description={
|
description={
|
||||||
example.description ?? "Prebuilt Examples"
|
example.description ?? "Prebuilt Examples"
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export default function TabComponent({
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { removeFlow, updateFlow, flows, setDisableCopyPaste } = useContext(TabsContext);
|
const { removeFlow, updateFlow, flows } = useContext(TabsContext);
|
||||||
const [isRename, setIsRename] = useState(false);
|
const [isRename, setIsRename] = useState(false);
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
return (
|
return (
|
||||||
|
|
@ -40,14 +40,10 @@ export default function TabComponent({
|
||||||
<div className="bg-white dark:text-white dark:bg-gray-700/60 flex select-none justify-between w-44 items-center border border-b-0 border-gray-300 dark:border-gray-600 px-4 py-1 rounded-t-xl -ml-px">
|
<div className="bg-white dark:text-white dark:bg-gray-700/60 flex select-none justify-between w-44 items-center border border-b-0 border-gray-300 dark:border-gray-600 px-4 py-1 rounded-t-xl -ml-px">
|
||||||
{isRename ? (
|
{isRename ? (
|
||||||
<input
|
<input
|
||||||
onFocus={() => {
|
|
||||||
setDisableCopyPaste(true);
|
|
||||||
}}
|
|
||||||
autoFocus
|
autoFocus
|
||||||
className="bg-transparent focus:border-none active:outline hover:outline focus:outline outline-gray-300 rounded-md w-28"
|
className="bg-transparent focus:border-none active:outline hover:outline focus:outline outline-gray-300 rounded-md w-28"
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
setIsRename(false);
|
setIsRename(false);
|
||||||
setDisableCopyPaste(false);
|
|
||||||
if (value !== "") {
|
if (value !== "") {
|
||||||
let newFlow = _.cloneDeep(flow);
|
let newFlow = _.cloneDeep(flow);
|
||||||
newFlow.name = value;
|
newFlow.name = value;
|
||||||
|
|
|
||||||
|
|
@ -155,10 +155,6 @@ export default function FlowPage({ flow }: { flow: FlowType }) {
|
||||||
params.targetHandle.split("|")[0] === "Text"
|
params.targetHandle.split("|")[0] === "Text"
|
||||||
? { stroke: "#333333", strokeWidth: 2 }
|
? { stroke: "#333333", strokeWidth: 2 }
|
||||||
: { stroke: "#222222" },
|
: { stroke: "#222222" },
|
||||||
className:
|
|
||||||
params.targetHandle.split("|")[0] === "Text"
|
|
||||||
? ""
|
|
||||||
: "animate-pulse",
|
|
||||||
animated: params.targetHandle.split("|")[0] === "Text",
|
animated: params.targetHandle.split("|")[0] === "Text",
|
||||||
},
|
},
|
||||||
eds
|
eds
|
||||||
|
|
@ -306,8 +302,10 @@ export default function FlowPage({ flow }: { flow: FlowType }) {
|
||||||
setLastSelection(flow);
|
setLastSelection(flow);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const {setDisableCopyPaste} = useContext(TabsContext)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
<div className="w-full h-full" ref={reactFlowWrapper} >
|
||||||
{Object.keys(templates).length > 0 && Object.keys(types).length > 0 ? (
|
{Object.keys(templates).length > 0 && Object.keys(types).length > 0 ? (
|
||||||
<>
|
<>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
|
|
@ -316,6 +314,9 @@ export default function FlowPage({ flow }: { flow: FlowType }) {
|
||||||
updateFlow({ ...flow, data: reactFlowInstance.toObject() });
|
updateFlow({ ...flow, data: reactFlowInstance.toObject() });
|
||||||
}}
|
}}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
|
onPaneClick={() => {setDisableCopyPaste(false);}}
|
||||||
|
onNodeClick={() => {setDisableCopyPaste(true);}}
|
||||||
|
onPaneMouseLeave={() => {setDisableCopyPaste(true);}}
|
||||||
onNodesChange={onNodesChange}
|
onNodesChange={onNodesChange}
|
||||||
onEdgesChange={onEdgesChangeMod}
|
onEdgesChange={onEdgesChangeMod}
|
||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,14 @@ module.exports = {
|
||||||
display: "none",
|
display: "none",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
".truncate-multiline": {
|
||||||
|
"display": "-webkit-box",
|
||||||
|
"-webkit-line-clamp": "3", /* Change this number to the number of lines you want to show */
|
||||||
|
"-webkit-box-orient": "vertical",
|
||||||
|
"overflow": "hidden",
|
||||||
|
"text-overflow": "ellipsis",
|
||||||
|
},
|
||||||
|
|
||||||
".arrow-hide": {
|
".arrow-hide": {
|
||||||
"&::-webkit-inner-spin-button": {
|
"&::-webkit-inner-spin-button": {
|
||||||
"-webkit-appearance": "none",
|
"-webkit-appearance": "none",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue