refactor: custom api code generator and fix chat locking when saving (#3618)
* Removed saveLoading from the chat * Fixed initialSetup that couldnt be null * Added types for get codes type * Added new types for getCodes and initialSetup on Tweaks store * Created a use custom api code to return all code * Passed the getCodes from the custom hook into initialSetup * Updated tabs array to receive object * Update every code to get correct props * Update tweaks store to handle refactored getCodes and createTabsArray * Added custom api generator component on top of the codetabscomponent
This commit is contained in:
parent
10d03360c5
commit
32d51b69e8
15 changed files with 178 additions and 128 deletions
|
|
@ -0,0 +1,3 @@
|
||||||
|
export function CustomAPIGenerator() {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
19
src/frontend/src/customization/hooks/use-custom-api-code.ts
Normal file
19
src/frontend/src/customization/hooks/use-custom-api-code.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import {
|
||||||
|
getCurlRunCode,
|
||||||
|
getCurlWebhookCode,
|
||||||
|
} from "@/modals/apiModal/utils/get-curl-code";
|
||||||
|
import getJsApiCode from "@/modals/apiModal/utils/get-js-api-code";
|
||||||
|
import getPythonApiCode from "@/modals/apiModal/utils/get-python-api-code";
|
||||||
|
import getPythonCode from "@/modals/apiModal/utils/get-python-code";
|
||||||
|
import getWidgetCode from "@/modals/apiModal/utils/get-widget-code";
|
||||||
|
|
||||||
|
export function useCustomAPICode() {
|
||||||
|
return {
|
||||||
|
getCurlRunCode,
|
||||||
|
getCurlWebhookCode,
|
||||||
|
getJsApiCode,
|
||||||
|
getPythonApiCode,
|
||||||
|
getPythonCode,
|
||||||
|
getWidgetCode,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,6 @@ type ButtonSendWrapperProps = {
|
||||||
send: () => void;
|
send: () => void;
|
||||||
lockChat: boolean;
|
lockChat: boolean;
|
||||||
noInput: boolean;
|
noInput: boolean;
|
||||||
saveLoading: boolean;
|
|
||||||
chatValue: string;
|
chatValue: string;
|
||||||
files: FilePreviewType[];
|
files: FilePreviewType[];
|
||||||
};
|
};
|
||||||
|
|
@ -17,7 +16,6 @@ const ButtonSendWrapper = ({
|
||||||
send,
|
send,
|
||||||
lockChat,
|
lockChat,
|
||||||
noInput,
|
noInput,
|
||||||
saveLoading,
|
|
||||||
chatValue,
|
chatValue,
|
||||||
files,
|
files,
|
||||||
}: ButtonSendWrapperProps) => {
|
}: ButtonSendWrapperProps) => {
|
||||||
|
|
@ -31,15 +29,11 @@ const ButtonSendWrapper = ({
|
||||||
? "text-primary"
|
? "text-primary"
|
||||||
: "bg-chat-send text-background",
|
: "bg-chat-send text-background",
|
||||||
)}
|
)}
|
||||||
disabled={lockChat || saveLoading}
|
disabled={lockChat}
|
||||||
onClick={(): void => send()}
|
onClick={(): void => send()}
|
||||||
unstyled
|
unstyled
|
||||||
>
|
>
|
||||||
<Case
|
<Case condition={lockChat || files.some((file) => file.loading)}>
|
||||||
condition={
|
|
||||||
lockChat || saveLoading || files.some((file) => file.loading)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name="Lock"
|
name="Lock"
|
||||||
className="form-modal-lock-icon"
|
className="form-modal-lock-icon"
|
||||||
|
|
@ -57,8 +51,7 @@ const ButtonSendWrapper = ({
|
||||||
|
|
||||||
<Case
|
<Case
|
||||||
condition={
|
condition={
|
||||||
!(lockChat || saveLoading || files.some((file) => file.loading)) &&
|
!(lockChat || files.some((file) => file.loading)) && !noInput
|
||||||
!noInput
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ const TextAreaWrapper = ({
|
||||||
send,
|
send,
|
||||||
lockChat,
|
lockChat,
|
||||||
noInput,
|
noInput,
|
||||||
saveLoading,
|
|
||||||
chatValue,
|
chatValue,
|
||||||
setChatValue,
|
setChatValue,
|
||||||
CHAT_INPUT_PLACEHOLDER,
|
CHAT_INPUT_PLACEHOLDER,
|
||||||
|
|
@ -30,8 +29,7 @@ const TextAreaWrapper = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const lockClass =
|
const lockClass = lockChat
|
||||||
lockChat || saveLoading
|
|
||||||
? "form-modal-lock-true bg-input"
|
? "form-modal-lock-true bg-input"
|
||||||
: noInput
|
: noInput
|
||||||
? "form-modal-no-input bg-input"
|
? "form-modal-no-input bg-input"
|
||||||
|
|
@ -45,10 +43,10 @@ const TextAreaWrapper = ({
|
||||||
const additionalClassNames = "form-modal-lockchat pl-14";
|
const additionalClassNames = "form-modal-lockchat pl-14";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!lockChat && !noInput && !saveLoading) {
|
if (!lockChat && !noInput) {
|
||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
}
|
}
|
||||||
}, [lockChat, noInput, saveLoading]);
|
}, [lockChat, noInput]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Textarea
|
<Textarea
|
||||||
|
|
@ -65,7 +63,7 @@ const TextAreaWrapper = ({
|
||||||
}}
|
}}
|
||||||
rows={1}
|
rows={1}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
disabled={lockChat || noInput || saveLoading}
|
disabled={lockChat || noInput}
|
||||||
style={{
|
style={{
|
||||||
resize: "none",
|
resize: "none",
|
||||||
bottom: `${inputRef?.current?.scrollHeight}px`,
|
bottom: `${inputRef?.current?.scrollHeight}px`,
|
||||||
|
|
@ -76,7 +74,7 @@ const TextAreaWrapper = ({
|
||||||
: "hidden"
|
: "hidden"
|
||||||
}`,
|
}`,
|
||||||
}}
|
}}
|
||||||
value={lockChat ? "Thinking..." : saveLoading ? "Saving..." : chatValue}
|
value={lockChat ? "Thinking..." : chatValue}
|
||||||
onChange={(event): void => {
|
onChange={(event): void => {
|
||||||
setChatValue(event.target.value);
|
setChatValue(event.target.value);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ export default function ChatInput({
|
||||||
setFiles,
|
setFiles,
|
||||||
isDragging,
|
isDragging,
|
||||||
}: ChatInputType): JSX.Element {
|
}: ChatInputType): JSX.Element {
|
||||||
const [repeat, setRepeat] = useState(1);
|
|
||||||
const saveLoading = useFlowsManagerStore((state) => state.saveLoading);
|
|
||||||
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
||||||
const [inputFocus, setInputFocus] = useState<boolean>(false);
|
const [inputFocus, setInputFocus] = useState<boolean>(false);
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
@ -128,7 +126,7 @@ export default function ChatInput({
|
||||||
|
|
||||||
const send = () => {
|
const send = () => {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
repeat,
|
repeat: 1,
|
||||||
files: files.map((file) => file.path ?? "").filter((file) => file !== ""),
|
files: files.map((file) => file.path ?? "").filter((file) => file !== ""),
|
||||||
});
|
});
|
||||||
setFiles([]);
|
setFiles([]);
|
||||||
|
|
@ -138,7 +136,6 @@ export default function ChatInput({
|
||||||
return (
|
return (
|
||||||
event.key === "Enter" &&
|
event.key === "Enter" &&
|
||||||
!lockChat &&
|
!lockChat &&
|
||||||
!saveLoading &&
|
|
||||||
!event.shiftKey &&
|
!event.shiftKey &&
|
||||||
!event.nativeEvent.isComposing
|
!event.nativeEvent.isComposing
|
||||||
);
|
);
|
||||||
|
|
@ -158,7 +155,6 @@ export default function ChatInput({
|
||||||
send={send}
|
send={send}
|
||||||
lockChat={lockChat}
|
lockChat={lockChat}
|
||||||
noInput={noInput}
|
noInput={noInput}
|
||||||
saveLoading={saveLoading}
|
|
||||||
chatValue={chatValue}
|
chatValue={chatValue}
|
||||||
setChatValue={setChatValue}
|
setChatValue={setChatValue}
|
||||||
CHAT_INPUT_PLACEHOLDER={CHAT_INPUT_PLACEHOLDER}
|
CHAT_INPUT_PLACEHOLDER={CHAT_INPUT_PLACEHOLDER}
|
||||||
|
|
@ -173,7 +169,6 @@ export default function ChatInput({
|
||||||
send={send}
|
send={send}
|
||||||
lockChat={lockChat}
|
lockChat={lockChat}
|
||||||
noInput={noInput}
|
noInput={noInput}
|
||||||
saveLoading={saveLoading}
|
|
||||||
chatValue={chatValue}
|
chatValue={chatValue}
|
||||||
files={files}
|
files={files}
|
||||||
/>
|
/>
|
||||||
|
|
@ -181,11 +176,11 @@ export default function ChatInput({
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={`absolute bottom-2 left-4 ${
|
className={`absolute bottom-2 left-4 ${
|
||||||
lockChat || saveLoading ? "cursor-not-allowed" : ""
|
lockChat ? "cursor-not-allowed" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<UploadFileButton
|
<UploadFileButton
|
||||||
lockChat={lockChat || saveLoading}
|
lockChat={lockChat}
|
||||||
fileInputRef={fileInputRef}
|
fileInputRef={fileInputRef}
|
||||||
handleFileChange={handleFileChange}
|
handleFileChange={handleFileChange}
|
||||||
handleButtonClick={handleButtonClick}
|
handleButtonClick={handleButtonClick}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { CustomAPIGenerator } from "@/customization/components/custom-api-generator";
|
||||||
|
import { useCustomAPICode } from "@/customization/hooks/use-custom-api-code";
|
||||||
import useAuthStore from "@/stores/authStore";
|
import useAuthStore from "@/stores/authStore";
|
||||||
import "ace-builds/src-noconflict/ext-language_tools";
|
import "ace-builds/src-noconflict/ext-language_tools";
|
||||||
import "ace-builds/src-noconflict/mode-python";
|
import "ace-builds/src-noconflict/mode-python";
|
||||||
|
|
@ -33,8 +35,10 @@ export default function ApiModal({
|
||||||
const tabs = useTweaksStore((state) => state.tabs);
|
const tabs = useTweaksStore((state) => state.tabs);
|
||||||
const initialSetup = useTweaksStore((state) => state.initialSetup);
|
const initialSetup = useTweaksStore((state) => state.initialSetup);
|
||||||
|
|
||||||
|
const getCodes = useCustomAPICode();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) initialSetup(autoLogin, flow);
|
if (open) initialSetup(autoLogin ?? false, flow, getCodes);
|
||||||
setActiveTab("0");
|
setActiveTab("0");
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
|
|
@ -50,6 +54,7 @@ export default function ApiModal({
|
||||||
/>
|
/>
|
||||||
</BaseModal.Header>
|
</BaseModal.Header>
|
||||||
<BaseModal.Content overflowHidden>
|
<BaseModal.Content overflowHidden>
|
||||||
|
<CustomAPIGenerator />
|
||||||
<CodeTabsComponent
|
<CodeTabsComponent
|
||||||
open={open}
|
open={open}
|
||||||
tabs={tabs!}
|
tabs={tabs!}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import useFlowStore from "@/stores/flowStore";
|
import useFlowStore from "@/stores/flowStore";
|
||||||
|
import { GetCodeType } from "@/types/tweaks";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get the curl code for the API
|
* Function to get the curl code for the API
|
||||||
|
|
@ -6,12 +7,12 @@ import useFlowStore from "@/stores/flowStore";
|
||||||
* @param {boolean} isAuth - If the API is authenticated
|
* @param {boolean} isAuth - If the API is authenticated
|
||||||
* @returns {string} - The curl code
|
* @returns {string} - The curl code
|
||||||
*/
|
*/
|
||||||
export function getCurlRunCode(
|
export function getCurlRunCode({
|
||||||
flowId: string,
|
flowId,
|
||||||
isAuth: boolean,
|
isAuth,
|
||||||
tweaksBuildedObject?: {},
|
tweaksBuildedObject,
|
||||||
endpointName?: string | null,
|
endpointName,
|
||||||
): string {
|
}: GetCodeType): string {
|
||||||
let tweaksString = "{}";
|
let tweaksString = "{}";
|
||||||
const inputs = useFlowStore.getState().inputs;
|
const inputs = useFlowStore.getState().inputs;
|
||||||
const outputs = useFlowStore.getState().outputs;
|
const outputs = useFlowStore.getState().outputs;
|
||||||
|
|
@ -43,11 +44,11 @@ export function getCurlRunCode(
|
||||||
* @param {string} options.endpointName - The name of the webhook endpoint.
|
* @param {string} options.endpointName - The name of the webhook endpoint.
|
||||||
* @returns {string} The cURL command.
|
* @returns {string} The cURL command.
|
||||||
*/
|
*/
|
||||||
export function getCurlWebhookCode(
|
export function getCurlWebhookCode({
|
||||||
flowId,
|
flowId,
|
||||||
isAuth,
|
isAuth,
|
||||||
endpointName?: string | null,
|
endpointName,
|
||||||
) {
|
}: GetCodeType) {
|
||||||
return `curl -X POST \\
|
return `curl -X POST \\
|
||||||
"${window.location.protocol}//${window.location.host}/api/v1/webhook/${
|
"${window.location.protocol}//${window.location.host}/api/v1/webhook/${
|
||||||
endpointName || flowId
|
endpointName || flowId
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { GetCodeType } from "@/types/tweaks";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to generate JavaScript code for interfacing with an API using the LangflowClient class.
|
* Function to generate JavaScript code for interfacing with an API using the LangflowClient class.
|
||||||
* @param {string} flowId - The id of the flow.
|
* @param {string} flowId - The id of the flow.
|
||||||
|
|
@ -6,12 +8,12 @@
|
||||||
* @param {string} [endpointName] - Optional endpoint name.
|
* @param {string} [endpointName] - Optional endpoint name.
|
||||||
* @returns {string} - The JavaScript code as a string.
|
* @returns {string} - The JavaScript code as a string.
|
||||||
*/
|
*/
|
||||||
export default function getJsApiCode(
|
export default function getJsApiCode({
|
||||||
flowId: string,
|
flowId,
|
||||||
isAuth: boolean,
|
isAuth,
|
||||||
tweaksBuildedObject: {},
|
tweaksBuildedObject,
|
||||||
endpointName?: string | null,
|
endpointName,
|
||||||
): string {
|
}: GetCodeType): string {
|
||||||
let tweaksString = "{}";
|
let tweaksString = "{}";
|
||||||
if (tweaksBuildedObject)
|
if (tweaksBuildedObject)
|
||||||
tweaksString = JSON.stringify(tweaksBuildedObject, null, 2);
|
tweaksString = JSON.stringify(tweaksBuildedObject, null, 2);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { GetCodeType } from "@/types/tweaks";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get the python code for the API
|
* Function to get the python code for the API
|
||||||
* @param {string} flowId - The id of the flow
|
* @param {string} flowId - The id of the flow
|
||||||
|
|
@ -6,12 +8,11 @@
|
||||||
* @param {string} [endpointName] - The optional endpoint name
|
* @param {string} [endpointName] - The optional endpoint name
|
||||||
* @returns {string} - The python code
|
* @returns {string} - The python code
|
||||||
*/
|
*/
|
||||||
export default function getPythonApiCode(
|
export default function getPythonApiCode({
|
||||||
flowId: string,
|
flowId,
|
||||||
isAuth: boolean,
|
tweaksBuildedObject,
|
||||||
tweaksBuildedObject?: {},
|
endpointName,
|
||||||
endpointName?: string | null,
|
}: GetCodeType): string {
|
||||||
): string {
|
|
||||||
let tweaksString = "{}";
|
let tweaksString = "{}";
|
||||||
if (tweaksBuildedObject)
|
if (tweaksBuildedObject)
|
||||||
tweaksString = JSON.stringify(tweaksBuildedObject, null, 2)
|
tweaksString = JSON.stringify(tweaksBuildedObject, null, 2)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
|
import { GetCodeType } from "@/types/tweaks";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get the python code for the API
|
* Function to get the python code for the API
|
||||||
* @param {string} flow - The current flow
|
* @param {string} flow - The current flow
|
||||||
* @param {any[]} tweaksBuildedObject - The tweaks
|
* @param {any[]} tweaksBuildedObject - The tweaks
|
||||||
* @returns {string} - The python code
|
* @returns {string} - The python code
|
||||||
*/
|
*/
|
||||||
export default function getPythonCode(
|
export default function getPythonCode({
|
||||||
flowName: string,
|
flowName,
|
||||||
tweaksBuildedObject: {},
|
tweaksBuildedObject,
|
||||||
): string {
|
}: GetCodeType): string {
|
||||||
let tweaksString = "{}";
|
let tweaksString = "{}";
|
||||||
if (tweaksBuildedObject)
|
if (tweaksBuildedObject)
|
||||||
tweaksString = JSON.stringify(tweaksBuildedObject, null, 2)
|
tweaksString = JSON.stringify(tweaksBuildedObject, null, 2)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
|
import { GetCodeType } from "@/types/tweaks";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get the widget code for the API
|
* Function to get the widget code for the API
|
||||||
* @param {string} flow - The current flow.
|
* @param {string} flow - The current flow.
|
||||||
* @returns {string} - The widget code
|
* @returns {string} - The widget code
|
||||||
*/
|
*/
|
||||||
export default function getWidgetCode(
|
export default function getWidgetCode({
|
||||||
flowId: string,
|
flowId,
|
||||||
flowName: string,
|
flowName,
|
||||||
isAuth: boolean,
|
isAuth,
|
||||||
): string {
|
}: GetCodeType): string {
|
||||||
return `<script src="https://cdn.jsdelivr.net/gh/logspace-ai/langflow-embedded-chat@v1.0.6/dist/build/static/js/bundle.min.js""></script>
|
return `<script src="https://cdn.jsdelivr.net/gh/logspace-ai/langflow-embedded-chat@v1.0.6/dist/build/static/js/bundle.min.js""></script>
|
||||||
|
|
||||||
<langflow-chat
|
<langflow-chat
|
||||||
|
|
|
||||||
|
|
@ -1,72 +1,78 @@
|
||||||
import { tabsArrayType } from "@/types/components";
|
import { tabsArrayType } from "@/types/components";
|
||||||
|
|
||||||
export function createTabsArray(
|
export function createTabsArray(
|
||||||
codes,
|
codes: { [key: string]: string },
|
||||||
includeWebhookCurl = false,
|
|
||||||
includeTweaks = false,
|
includeTweaks = false,
|
||||||
) {
|
) {
|
||||||
const tabs: tabsArrayType[] = [
|
const tabs: tabsArrayType[] = [];
|
||||||
{
|
if (codes.runCurlCode) {
|
||||||
|
tabs.push({
|
||||||
name: "Run cURL",
|
name: "Run cURL",
|
||||||
mode: "bash",
|
mode: "bash",
|
||||||
image: "https://curl.se/logo/curl-symbol-transparent.png",
|
image: "https://curl.se/logo/curl-symbol-transparent.png",
|
||||||
language: "sh",
|
language: "sh",
|
||||||
code: codes[0],
|
code: codes.runCurlCode,
|
||||||
hasTweaks: includeTweaks,
|
hasTweaks: includeTweaks,
|
||||||
},
|
});
|
||||||
{
|
}
|
||||||
|
if (codes.webhookCurlCode) {
|
||||||
|
tabs.push({
|
||||||
|
name: "Webhook cURL",
|
||||||
|
mode: "bash",
|
||||||
|
image: "https://curl.se/logo/curl-symbol-transparent.png",
|
||||||
|
language: "sh",
|
||||||
|
code: codes.webhookCurlCode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (codes.pythonApiCode) {
|
||||||
|
tabs.push({
|
||||||
name: "Python API",
|
name: "Python API",
|
||||||
mode: "python",
|
mode: "python",
|
||||||
image:
|
image:
|
||||||
"https://images.squarespace-cdn.com/content/v1/5df3d8c5d2be5962e4f87890/1628015119369-OY4TV3XJJ53ECO0W2OLQ/Python+API+Training+Logo.png?format=1000w",
|
"https://images.squarespace-cdn.com/content/v1/5df3d8c5d2be5962e4f87890/1628015119369-OY4TV3XJJ53ECO0W2OLQ/Python+API+Training+Logo.png?format=1000w",
|
||||||
language: "py",
|
language: "py",
|
||||||
code: codes[2],
|
code: codes.pythonApiCode,
|
||||||
hasTweaks: includeTweaks,
|
hasTweaks: includeTweaks,
|
||||||
},
|
});
|
||||||
{
|
}
|
||||||
|
if (codes.jsApiCode) {
|
||||||
|
tabs.push({
|
||||||
name: "JS API",
|
name: "JS API",
|
||||||
mode: "javascript",
|
mode: "javascript",
|
||||||
image: "https://cdn-icons-png.flaticon.com/512/136/136530.png",
|
image: "https://cdn-icons-png.flaticon.com/512/136/136530.png",
|
||||||
language: "js",
|
language: "js",
|
||||||
code: codes[3],
|
code: codes.jsApiCode,
|
||||||
hasTweaks: includeTweaks,
|
hasTweaks: includeTweaks,
|
||||||
},
|
});
|
||||||
{
|
}
|
||||||
|
if (codes.pythonCode) {
|
||||||
|
tabs.push({
|
||||||
name: "Python Code",
|
name: "Python Code",
|
||||||
mode: "python",
|
mode: "python",
|
||||||
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
|
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
|
||||||
language: "py",
|
language: "py",
|
||||||
code: codes[4],
|
code: codes.pythonCode,
|
||||||
hasTweaks: includeTweaks,
|
hasTweaks: includeTweaks,
|
||||||
},
|
});
|
||||||
{
|
}
|
||||||
|
if (codes.widgetCode) {
|
||||||
|
tabs.push({
|
||||||
name: "Chat Widget HTML",
|
name: "Chat Widget HTML",
|
||||||
description:
|
description:
|
||||||
"Insert this code anywhere in your <body> tag. To use with react and other libs, check our <a class='link-color' href='https://langflow.org/guidelines/widget'>documentation</a>.",
|
"Insert this code anywhere in your <body> tag. To use with react and other libs, check our <a class='link-color' href='https://langflow.org/guidelines/widget'>documentation</a>.",
|
||||||
mode: "html",
|
mode: "html",
|
||||||
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
|
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
|
||||||
language: "html",
|
language: "html",
|
||||||
code: codes[5],
|
code: codes.widgetCode,
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (includeWebhookCurl) {
|
|
||||||
tabs.splice(1, 0, {
|
|
||||||
name: "Webhook cURL",
|
|
||||||
mode: "bash",
|
|
||||||
image: "https://curl.se/logo/curl-symbol-transparent.png",
|
|
||||||
language: "sh",
|
|
||||||
code: codes[1],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeTweaks) {
|
if (includeTweaks) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
name: "Tweaks",
|
name: "Tweaks",
|
||||||
mode: "python",
|
mode: "python",
|
||||||
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
|
image: "https://cdn-icons-png.flaticon.com/512/5968/5968350.png",
|
||||||
language: "py",
|
language: "py",
|
||||||
code: codes[6],
|
code: codes.tweaksCode,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,8 @@
|
||||||
import { getChangesType } from "@/modals/apiModal/utils/get-changes-types";
|
import { getChangesType } from "@/modals/apiModal/utils/get-changes-types";
|
||||||
import {
|
|
||||||
getCurlRunCode,
|
|
||||||
getCurlWebhookCode,
|
|
||||||
} from "@/modals/apiModal/utils/get-curl-code";
|
|
||||||
import getJsApiCode from "@/modals/apiModal/utils/get-js-api-code";
|
|
||||||
import { getNodesWithDefaultValue } from "@/modals/apiModal/utils/get-nodes-with-default-value";
|
import { getNodesWithDefaultValue } from "@/modals/apiModal/utils/get-nodes-with-default-value";
|
||||||
import getPythonApiCode from "@/modals/apiModal/utils/get-python-api-code";
|
|
||||||
import getPythonCode from "@/modals/apiModal/utils/get-python-code";
|
|
||||||
import getWidgetCode from "@/modals/apiModal/utils/get-widget-code";
|
|
||||||
import { createTabsArray } from "@/modals/apiModal/utils/tabs-array";
|
import { createTabsArray } from "@/modals/apiModal/utils/tabs-array";
|
||||||
import { FlowType, NodeDataType } from "@/types/flow";
|
import { FlowType, NodeDataType } from "@/types/flow";
|
||||||
|
import { GetCodesType } from "@/types/tweaks";
|
||||||
import { customStringify } from "@/utils/reactflowUtils";
|
import { customStringify } from "@/utils/reactflowUtils";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { TweaksStoreType } from "../types/zustand/tweaks";
|
import { TweaksStoreType } from "../types/zustand/tweaks";
|
||||||
|
|
@ -51,12 +44,18 @@ export const useTweaksStore = create<TweaksStoreType>((set, get) => ({
|
||||||
},
|
},
|
||||||
autoLogin: false,
|
autoLogin: false,
|
||||||
flow: null,
|
flow: null,
|
||||||
initialSetup: (autoLogin: boolean, flow: FlowType) => {
|
getCodes: {},
|
||||||
|
initialSetup: (
|
||||||
|
autoLogin: boolean,
|
||||||
|
flow: FlowType,
|
||||||
|
getCodes: GetCodesType,
|
||||||
|
) => {
|
||||||
useFlowStore.getState().unselectAll();
|
useFlowStore.getState().unselectAll();
|
||||||
set({
|
set({
|
||||||
nodes: getNodesWithDefaultValue(flow?.data?.nodes ?? []),
|
nodes: getNodesWithDefaultValue(flow?.data?.nodes ?? []),
|
||||||
autoLogin,
|
autoLogin,
|
||||||
flow,
|
flow,
|
||||||
|
getCodes,
|
||||||
});
|
});
|
||||||
get().refreshTabs();
|
get().refreshTabs();
|
||||||
},
|
},
|
||||||
|
|
@ -90,38 +89,40 @@ export const useTweaksStore = create<TweaksStoreType>((set, get) => ({
|
||||||
tweak[node.id] = currentTweak;
|
tweak[node.id] = currentTweak;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const codesObj = {};
|
||||||
|
const getCodes = get().getCodes;
|
||||||
|
|
||||||
const pythonApiCode = getPythonApiCode(flow?.id, autoLogin, tweak);
|
const props = {
|
||||||
const runCurlCode = getCurlRunCode(
|
flowId: flow?.id,
|
||||||
flow?.id,
|
flowName: flow?.name,
|
||||||
autoLogin,
|
isAuth: autoLogin,
|
||||||
tweak,
|
tweaksBuildedObject: tweak,
|
||||||
flow?.endpoint_name,
|
endpointName: flow?.endpoint_name,
|
||||||
);
|
};
|
||||||
const jsApiCode = getJsApiCode(
|
|
||||||
flow?.id,
|
if (getCodes) {
|
||||||
autoLogin,
|
if (getCodes.getCurlRunCode) {
|
||||||
tweak,
|
codesObj["runCurlCode"] = getCodes.getCurlRunCode(props);
|
||||||
flow?.endpoint_name,
|
}
|
||||||
);
|
if (getCodes.getCurlWebhookCode && !!flow.webhook) {
|
||||||
const webhookCurlCode = getCurlWebhookCode(
|
codesObj["webhookCurlCode"] = getCodes.getCurlWebhookCode(props);
|
||||||
flow?.id,
|
}
|
||||||
autoLogin,
|
if (getCodes.getJsApiCode) {
|
||||||
flow?.endpoint_name,
|
codesObj["jsApiCode"] = getCodes.getJsApiCode(props);
|
||||||
);
|
}
|
||||||
const pythonCode = getPythonCode(flow?.name, tweak);
|
if (getCodes.getPythonApiCode) {
|
||||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
codesObj["pythonApiCode"] = getCodes.getPythonApiCode(props);
|
||||||
|
}
|
||||||
|
if (getCodes.getPythonCode) {
|
||||||
|
codesObj["pythonCode"] = getCodes.getPythonCode(props);
|
||||||
|
}
|
||||||
|
if (getCodes.getWidgetCode) {
|
||||||
|
codesObj["widgetCode"] = getCodes.getWidgetCode(props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const codesArray = [
|
|
||||||
runCurlCode,
|
|
||||||
webhookCurlCode,
|
|
||||||
pythonApiCode,
|
|
||||||
jsApiCode,
|
|
||||||
pythonCode,
|
|
||||||
widgetCode,
|
|
||||||
];
|
|
||||||
set({
|
set({
|
||||||
tabs: createTabsArray(codesArray, !!flow.webhook, nodes.length > 0),
|
tabs: createTabsArray(codesObj, nodes.length > 0),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
16
src/frontend/src/types/tweaks/index.ts
Normal file
16
src/frontend/src/types/tweaks/index.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
export type GetCodesType = {
|
||||||
|
getCurlRunCode?: (GetCodeType) => string;
|
||||||
|
getCurlWebhookCode?: (GetCodeType) => string;
|
||||||
|
getJsApiCode?: (GetCodeType) => string;
|
||||||
|
getPythonApiCode?: (GetCodeType) => string;
|
||||||
|
getPythonCode?: (GetCodeType) => string;
|
||||||
|
getWidgetCode?: (GetCodeType) => string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetCodeType = {
|
||||||
|
flowId: string;
|
||||||
|
flowName: string;
|
||||||
|
isAuth: boolean;
|
||||||
|
tweaksBuildedObject: {};
|
||||||
|
endpointName?: string | null;
|
||||||
|
};
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { FlowType, NodeType } from "@/types/flow";
|
import { FlowType, NodeType } from "@/types/flow";
|
||||||
|
import { GetCodesType } from "@/types/tweaks";
|
||||||
import { tabsArrayType } from "../../components";
|
import { tabsArrayType } from "../../components";
|
||||||
|
|
||||||
export type TweaksStoreType = {
|
export type TweaksStoreType = {
|
||||||
|
|
@ -13,9 +14,14 @@ export type TweaksStoreType = {
|
||||||
id: string,
|
id: string,
|
||||||
update: NodeType | ((oldState: NodeType) => NodeType),
|
update: NodeType | ((oldState: NodeType) => NodeType),
|
||||||
) => void;
|
) => void;
|
||||||
|
getCodes: GetCodesType;
|
||||||
getNode: (id: string) => NodeType | undefined;
|
getNode: (id: string) => NodeType | undefined;
|
||||||
tabs: tabsArrayType[];
|
tabs: tabsArrayType[];
|
||||||
initialSetup: (autoLogin: boolean, flow: FlowType) => void;
|
initialSetup: (
|
||||||
|
autoLogin: boolean,
|
||||||
|
flow: FlowType,
|
||||||
|
getCodes: GetCodesType,
|
||||||
|
) => void;
|
||||||
refreshTabs: () => void;
|
refreshTabs: () => void;
|
||||||
autoLogin: boolean;
|
autoLogin: boolean;
|
||||||
flow: FlowType | null;
|
flow: FlowType | null;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue