import { createPortal } from 'react-dom'
import { useNavigate } from 'react-router-dom'
import { useState, useEffect } from 'react'
import { useDispatch } from 'react-redux'
import PropTypes from 'prop-types'
import { Tabs, Tab, Dialog, DialogContent, DialogTitle, Box } from '@mui/material'
import { CopyBlock, atomOneDark } from 'react-code-blocks'
// Project import
import { Dropdown } from 'ui-component/dropdown/Dropdown'
// Const
import { baseURL } from 'store/constant'
import { SET_CHATFLOW } from 'store/actions'
// Images
import pythonSVG from 'assets/images/python.svg'
import javascriptSVG from 'assets/images/javascript.svg'
import cURLSVG from 'assets/images/cURL.svg'
import EmbedSVG from 'assets/images/embed.svg'
// API
import apiKeyApi from 'api/apikey'
import chatflowsApi from 'api/chatflows'
import configApi from 'api/config'
// Hooks
import useApi from 'hooks/useApi'
import { CheckboxInput } from 'ui-component/checkbox/Checkbox'
import { TableViewOnly } from 'ui-component/table/Table'
function TabPanel(props) {
const { children, value, index, ...other } = props
return (
{value === index && {children}}
)
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.number.isRequired,
value: PropTypes.number.isRequired
}
function a11yProps(index) {
return {
id: `attachment-tab-${index}`,
'aria-controls': `attachment-tabpanel-${index}`
}
}
const unshiftFiles = (configData) => {
const filesConfig = configData.find((config) => config.name === 'files')
if (filesConfig) {
configData = configData.filter((config) => config.name !== 'files')
configData.unshift(filesConfig)
}
return configData
}
const getConfigExamplesForJS = (configData, bodyType) => {
let finalStr = ''
configData = unshiftFiles(configData)
const loop = Math.min(configData.length, 4)
for (let i = 0; i < loop; i += 1) {
const config = configData[i]
let exampleVal = `"example"`
if (config.type === 'string') exampleVal = `"example"`
else if (config.type === 'boolean') exampleVal = `true`
else if (config.type === 'number') exampleVal = `1`
else if (config.name === 'files') exampleVal = `input.files[0]`
finalStr += bodyType === 'json' ? `\n "${config.name}": ${exampleVal},` : `formData.append("${config.name}", ${exampleVal})\n`
if (i === loop - 1 && bodyType !== 'json') `formData.append("question", "Hey, how are you?")\n`
}
return finalStr
}
const getConfigExamplesForPython = (configData, bodyType) => {
let finalStr = ''
configData = unshiftFiles(configData)
const loop = Math.min(configData.length, 4)
for (let i = 0; i < loop; i += 1) {
const config = configData[i]
let exampleVal = `"example"`
if (config.type === 'string') exampleVal = `"example"`
else if (config.type === 'boolean') exampleVal = `true`
else if (config.type === 'number') exampleVal = `1`
else if (config.name === 'files') exampleVal = `('example${config.type}', open('example${config.type}', 'rb'))`
finalStr += bodyType === 'json' ? `\n "${config.name}": ${exampleVal},` : `\n "${config.name}": ${exampleVal},`
if (i === loop - 1 && bodyType !== 'json') finalStr += `\n "question": "Hey, how are you?"\n`
}
return finalStr
}
const getConfigExamplesForCurl = (configData, bodyType) => {
let finalStr = ''
configData = unshiftFiles(configData)
const loop = Math.min(configData.length, 4)
for (let i = 0; i < loop; i += 1) {
const config = configData[i]
let exampleVal = `example`
if (config.type === 'string') exampleVal = bodyType === 'json' ? `"example"` : `example`
else if (config.type === 'boolean') exampleVal = `true`
else if (config.type === 'number') exampleVal = `1`
else if (config.name === 'files') exampleVal = `@/home/user1/Desktop/example${config.type}`
finalStr += bodyType === 'json' ? `"${config.name}": ${exampleVal}` : `\n -F "${config.name}=${exampleVal}"`
if (i === loop - 1) finalStr += bodyType === 'json' ? ` }` : ` \\\n -F "question=Hey, how are you?"`
else finalStr += bodyType === 'json' ? `, ` : ` \\`
}
return finalStr
}
const embedCode = (chatflowid) => {
return ``
}
const embedCodeCustomization = (chatflowid) => {
return ``
}
const APICodeDialog = ({ show, dialogProps, onCancel }) => {
const portalElement = document.getElementById('portal')
const navigate = useNavigate()
const dispatch = useDispatch()
const codes = ['Embed', 'Python', 'JavaScript', 'cURL']
const [value, setValue] = useState(0)
const [keyOptions, setKeyOptions] = useState([])
const [apiKeys, setAPIKeys] = useState([])
const [chatflowApiKeyId, setChatflowApiKeyId] = useState('')
const [selectedApiKey, setSelectedApiKey] = useState({})
const [checkboxVal, setCheckbox] = useState(false)
const [embedChatCheckboxVal, setEmbedChatCheckbox] = useState(false)
const getAllAPIKeysApi = useApi(apiKeyApi.getAllAPIKeys)
const updateChatflowApi = useApi(chatflowsApi.updateChatflow)
const getConfigApi = useApi(configApi.getConfig)
const onCheckBoxChanged = (newVal) => {
setCheckbox(newVal)
if (newVal) {
getConfigApi.request(dialogProps.chatflowid)
}
}
const onCheckBoxEmbedChatChanged = (newVal) => {
setEmbedChatCheckbox(newVal)
}
const onApiKeySelected = (keyValue) => {
if (keyValue === 'addnewkey') {
navigate('/apikey')
return
}
setChatflowApiKeyId(keyValue)
setSelectedApiKey(apiKeys.find((key) => key.id === keyValue))
const updateBody = {
apikeyid: keyValue
}
updateChatflowApi.request(dialogProps.chatflowid, updateBody)
}
useEffect(() => {
if (updateChatflowApi.data) {
dispatch({ type: SET_CHATFLOW, chatflow: updateChatflowApi.data })
}
}, [updateChatflowApi.data, dispatch])
const handleChange = (event, newValue) => {
setValue(newValue)
}
const getCode = (codeLang) => {
if (codeLang === 'Python') {
return `import requests
API_URL = "${baseURL}/api/v1/prediction/${dialogProps.chatflowid}"
def query(payload):
response = requests.post(API_URL, json=payload)
return response.json()
output = query({
"question": "Hey, how are you?",
})
`
} else if (codeLang === 'JavaScript') {
return `async function query(data) {
const response = await fetch(
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
{
method: "POST",
body: data
}
);
const result = await response.json();
return result;
}
query({"question": "Hey, how are you?"}).then((response) => {
console.log(response);
});
`
} else if (codeLang === 'cURL') {
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
-X POST \\
-d '{"question": "Hey, how are you?"}'`
} else if (codeLang === 'Embed') {
return embedCode(dialogProps.chatflowid)
}
return ''
}
const getCodeWithAuthorization = (codeLang) => {
if (codeLang === 'Python') {
return `import requests
API_URL = "${baseURL}/api/v1/prediction/${dialogProps.chatflowid}"
headers = {"Authorization": "Bearer ${selectedApiKey?.apiKey}"}
def query(payload):
response = requests.post(API_URL, headers=headers, json=payload)
return response.json()
output = query({
"question": "Hey, how are you?",
})
`
} else if (codeLang === 'JavaScript') {
return `async function query(data) {
const response = await fetch(
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
{
headers: { Authorization: "Bearer ${selectedApiKey?.apiKey}" },
method: "POST",
body: data
}
);
const result = await response.json();
return result;
}
query({"question": "Hey, how are you?"}).then((response) => {
console.log(response);
});
`
} else if (codeLang === 'cURL') {
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
-X POST \\
-d '{"question": "Hey, how are you?"}' \\
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
} else if (codeLang === 'Embed') {
return embedCode(dialogProps.chatflowid)
}
return ''
}
const getLang = (codeLang) => {
if (codeLang === 'Python') {
return 'python'
} else if (codeLang === 'JavaScript' || codeLang === 'Embed') {
return 'javascript'
} else if (codeLang === 'cURL') {
return 'bash'
}
return 'python'
}
const getSVG = (codeLang) => {
if (codeLang === 'Python') {
return pythonSVG
} else if (codeLang === 'JavaScript') {
return javascriptSVG
} else if (codeLang === 'Embed') {
return EmbedSVG
} else if (codeLang === 'cURL') {
return cURLSVG
}
return pythonSVG
}
// ----------------------------CONFIG FORM DATA --------------------------//
const getConfigCodeWithFormData = (codeLang, configData) => {
if (codeLang === 'Python') {
return `import requests
API_URL = "${baseURL}/api/v1/prediction/${dialogProps.chatflowid}"
# use form data to upload files
form_data = {${getConfigExamplesForPython(configData, 'formData')}}
def query(form_data):
response = requests.post(API_URL, files=form_data)
return response.json()
output = query(form_data)
`
} else if (codeLang === 'JavaScript') {
return `// use FormData to upload files
let formData = new FormData();
${getConfigExamplesForJS(configData, 'formData')}
async function query(formData) {
const response = await fetch(
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
{
method: "POST",
body: formData
}
);
const result = await response.json();
return result;
}
query(formData).then((response) => {
console.log(response);
});
`
} else if (codeLang === 'cURL') {
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
-X POST \\${getConfigExamplesForCurl(configData, 'formData')}`
}
return ''
}
// ----------------------------CONFIG FORM DATA with AUTH--------------------------//
const getConfigCodeWithFormDataWithAuth = (codeLang, configData) => {
if (codeLang === 'Python') {
return `import requests
API_URL = "${baseURL}/api/v1/prediction/${dialogProps.chatflowid}"
headers = {"Authorization": "Bearer ${selectedApiKey?.apiKey}"}
# use form data to upload files
form_data = {${getConfigExamplesForPython(configData, 'formData')}}
def query(form_data):
response = requests.post(API_URL, headers=headers, files=form_data)
return response.json()
output = query(form_data)
`
} else if (codeLang === 'JavaScript') {
return `// use FormData to upload files
let formData = new FormData();
${getConfigExamplesForJS(configData, 'formData')}
async function query(formData) {
const response = await fetch(
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
{
headers: { Authorization: "Bearer ${selectedApiKey?.apiKey}" },
method: "POST",
body: formData
}
);
const result = await response.json();
return result;
}
query(formData).then((response) => {
console.log(response);
});
`
} else if (codeLang === 'cURL') {
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
-X POST \\${getConfigExamplesForCurl(configData, 'formData')} \\
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
}
return ''
}
// ----------------------------CONFIG JSON--------------------------//
const getConfigCode = (codeLang, configData) => {
if (codeLang === 'Python') {
return `import requests
API_URL = "${baseURL}/api/v1/prediction/${dialogProps.chatflowid}"
def query(payload):
response = requests.post(API_URL, json=payload)
return response.json()
output = query({
"question": "Hey, how are you?",
"overrideConfig": {${getConfigExamplesForPython(configData, 'json')}
}
})
`
} else if (codeLang === 'JavaScript') {
return `async function query(data) {
const response = await fetch(
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
{
method: "POST",
body: data
}
);
const result = await response.json();
return result;
}
query({
"question": "Hey, how are you?",
"overrideConfig": {${getConfigExamplesForJS(configData, 'json')}
}
}).then((response) => {
console.log(response);
});
`
} else if (codeLang === 'cURL') {
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
-X POST \\
-d '{"question": "Hey, how are you?", "overrideConfig": {${getConfigExamplesForCurl(configData, 'json')}}'`
}
return ''
}
// ----------------------------CONFIG JSON with AUTH--------------------------//
const getConfigCodeWithAuthorization = (codeLang, configData) => {
if (codeLang === 'Python') {
return `import requests
API_URL = "${baseURL}/api/v1/prediction/${dialogProps.chatflowid}"
headers = {"Authorization": "Bearer ${selectedApiKey?.apiKey}"}
def query(payload):
response = requests.post(API_URL, headers=headers, json=payload)
return response.json()
output = query({
"question": "Hey, how are you?",
"overrideConfig": {${getConfigExamplesForPython(configData, 'json')}
}
})
`
} else if (codeLang === 'JavaScript') {
return `async function query(data) {
const response = await fetch(
"${baseURL}/api/v1/prediction/${dialogProps.chatflowid}",
{
headers: { Authorization: "Bearer ${selectedApiKey?.apiKey}" },
method: "POST",
body: data
}
);
const result = await response.json();
return result;
}
query({
"question": "Hey, how are you?",
"overrideConfig": {${getConfigExamplesForJS(configData, 'json')}
}
}).then((response) => {
console.log(response);
});
`
} else if (codeLang === 'cURL') {
return `curl ${baseURL}/api/v1/prediction/${dialogProps.chatflowid} \\
-X POST \\
-d '{"question": "Hey, how are you?", "overrideConfig": {${getConfigExamplesForCurl(configData, 'json')}}' \\
-H "Authorization: Bearer ${selectedApiKey?.apiKey}"`
}
return ''
}
useEffect(() => {
if (getAllAPIKeysApi.data) {
const options = [
{
label: 'No Authorization',
name: ''
}
]
for (const key of getAllAPIKeysApi.data) {
options.push({
label: key.keyName,
name: key.id
})
}
options.push({
label: '- Add New Key -',
name: 'addnewkey'
})
setKeyOptions(options)
setAPIKeys(getAllAPIKeysApi.data)
if (dialogProps.chatflowApiKeyId) {
setChatflowApiKeyId(dialogProps.chatflowApiKeyId)
setSelectedApiKey(getAllAPIKeysApi.data.find((key) => key.id === dialogProps.chatflowApiKeyId))
}
}
}, [dialogProps, getAllAPIKeysApi.data])
useEffect(() => {
if (show) {
getAllAPIKeysApi.request()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [show])
const component = show ? (
) : null
return createPortal(component, portalElement)
}
APICodeDialog.propTypes = {
show: PropTypes.bool,
dialogProps: PropTypes.object,
onCancel: PropTypes.func
}
export default APICodeDialog