mirror of https://github.com/FlowiseAI/Flowise.git
276 lines
14 KiB
JavaScript
276 lines
14 KiB
JavaScript
import PropTypes from 'prop-types'
|
|
import { useState } from 'react'
|
|
import { useSelector } from 'react-redux'
|
|
|
|
// material-ui
|
|
import { Box, Typography, IconButton, Button } from '@mui/material'
|
|
import { IconArrowsMaximize, IconAlertTriangle } from '@tabler/icons-react'
|
|
|
|
// project import
|
|
import { Dropdown } from '@/ui-component/dropdown/Dropdown'
|
|
import { MultiDropdown } from '@/ui-component/dropdown/MultiDropdown'
|
|
import { AsyncDropdown } from '@/ui-component/dropdown/AsyncDropdown'
|
|
import { Input } from '@/ui-component/input/Input'
|
|
import { DataGrid } from '@/ui-component/grid/DataGrid'
|
|
import { File } from '@/ui-component/file/File'
|
|
import { SwitchInput } from '@/ui-component/switch/Switch'
|
|
import { JsonEditorInput } from '@/ui-component/json/JsonEditor'
|
|
import { TooltipWithParser } from '@/ui-component/tooltip/TooltipWithParser'
|
|
import { CodeEditor } from '@/ui-component/editor/CodeEditor'
|
|
import ExpandTextDialog from '@/ui-component/dialog/ExpandTextDialog'
|
|
import ManageScrapedLinksDialog from '@/ui-component/dialog/ManageScrapedLinksDialog'
|
|
import CredentialInputHandler from '@/views/canvas/CredentialInputHandler'
|
|
|
|
// const
|
|
import { FLOWISE_CREDENTIAL_ID } from '@/store/constant'
|
|
|
|
// ===========================|| DocStoreInputHandler ||=========================== //
|
|
|
|
const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
|
|
const customization = useSelector((state) => state.customization)
|
|
|
|
const [showExpandDialog, setShowExpandDialog] = useState(false)
|
|
const [expandDialogProps, setExpandDialogProps] = useState({})
|
|
const [showManageScrapedLinksDialog, setShowManageScrapedLinksDialog] = useState(false)
|
|
const [manageScrapedLinksDialogProps, setManageScrapedLinksDialogProps] = useState({})
|
|
|
|
const onExpandDialogClicked = (value, inputParam) => {
|
|
const dialogProps = {
|
|
value,
|
|
inputParam,
|
|
disabled,
|
|
confirmButtonName: 'Save',
|
|
cancelButtonName: 'Cancel'
|
|
}
|
|
setExpandDialogProps(dialogProps)
|
|
setShowExpandDialog(true)
|
|
}
|
|
|
|
const onManageLinksDialogClicked = (url, selectedLinks, relativeLinksMethod, limit) => {
|
|
const dialogProps = {
|
|
url,
|
|
relativeLinksMethod,
|
|
limit,
|
|
selectedLinks,
|
|
confirmButtonName: 'Save',
|
|
cancelButtonName: 'Cancel'
|
|
}
|
|
setManageScrapedLinksDialogProps(dialogProps)
|
|
setShowManageScrapedLinksDialog(true)
|
|
}
|
|
|
|
const onManageLinksDialogSave = (url, links) => {
|
|
setShowManageScrapedLinksDialog(false)
|
|
data.inputs.url = url
|
|
data.inputs.selectedLinks = links
|
|
}
|
|
|
|
const onExpandDialogSave = (newValue, inputParamName) => {
|
|
setShowExpandDialog(false)
|
|
data.inputs[inputParamName] = newValue
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
{inputParam && (
|
|
<>
|
|
<Box sx={{ p: 2 }}>
|
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
|
<Typography>
|
|
{inputParam.label}
|
|
{!inputParam.optional && <span style={{ color: 'red' }}> *</span>}
|
|
{inputParam.description && <TooltipWithParser style={{ marginLeft: 10 }} title={inputParam.description} />}
|
|
</Typography>
|
|
<div style={{ flexGrow: 1 }}></div>
|
|
{((inputParam.type === 'string' && inputParam.rows) || inputParam.type === 'code') && (
|
|
<IconButton
|
|
size='small'
|
|
sx={{
|
|
height: 25,
|
|
width: 25
|
|
}}
|
|
title='Expand'
|
|
color='primary'
|
|
onClick={() =>
|
|
onExpandDialogClicked(data.inputs[inputParam.name] ?? inputParam.default ?? '', inputParam)
|
|
}
|
|
>
|
|
<IconArrowsMaximize />
|
|
</IconButton>
|
|
)}
|
|
</div>
|
|
{inputParam.warning && (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
borderRadius: 10,
|
|
background: 'rgb(254,252,191)',
|
|
padding: 10,
|
|
marginTop: 10,
|
|
marginBottom: 10
|
|
}}
|
|
>
|
|
<IconAlertTriangle size={30} color='orange' />
|
|
<span style={{ color: 'rgb(116,66,16)', marginLeft: 10 }}>{inputParam.warning}</span>
|
|
</div>
|
|
)}
|
|
{inputParam.type === 'credential' && (
|
|
<CredentialInputHandler
|
|
disabled={disabled}
|
|
data={data}
|
|
inputParam={inputParam}
|
|
onSelect={(newValue) => {
|
|
data.credential = newValue
|
|
data.inputs[FLOWISE_CREDENTIAL_ID] = newValue // in case data.credential is not updated
|
|
}}
|
|
/>
|
|
)}
|
|
|
|
{inputParam.type === 'file' && (
|
|
<File
|
|
disabled={disabled}
|
|
fileType={inputParam.fileType || '*'}
|
|
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? 'Choose a file to upload'}
|
|
/>
|
|
)}
|
|
{inputParam.type === 'boolean' && (
|
|
<SwitchInput
|
|
disabled={disabled}
|
|
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? false}
|
|
/>
|
|
)}
|
|
{inputParam.type === 'datagrid' && (
|
|
<DataGrid
|
|
disabled={disabled}
|
|
columns={inputParam.datagrid}
|
|
hideFooter={true}
|
|
rows={data.inputs[inputParam.name] ?? JSON.stringify(inputParam.default) ?? []}
|
|
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
/>
|
|
)}
|
|
{inputParam.type === 'code' && (
|
|
<>
|
|
<div style={{ height: '5px' }}></div>
|
|
<div style={{ height: inputParam.rows ? '100px' : '200px' }}>
|
|
<CodeEditor
|
|
disabled={disabled}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? ''}
|
|
height={inputParam.rows ? '100px' : '200px'}
|
|
theme={customization.isDarkMode ? 'dark' : 'light'}
|
|
lang={'js'}
|
|
placeholder={inputParam.placeholder}
|
|
onValueChange={(code) => (data.inputs[inputParam.name] = code)}
|
|
basicSetup={{ highlightActiveLine: false, highlightActiveLineGutter: false }}
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
{(inputParam.type === 'string' || inputParam.type === 'password' || inputParam.type === 'number') && (
|
|
<Input
|
|
key={data.inputs[inputParam.name]}
|
|
disabled={disabled}
|
|
inputParam={inputParam}
|
|
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? ''}
|
|
nodeId={data.id}
|
|
/>
|
|
)}
|
|
{inputParam.type === 'json' && (
|
|
<JsonEditorInput
|
|
disabled={disabled}
|
|
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? ''}
|
|
isDarkMode={customization.isDarkMode}
|
|
/>
|
|
)}
|
|
{inputParam.type === 'options' && (
|
|
<Dropdown
|
|
disabled={disabled}
|
|
name={inputParam.name}
|
|
options={inputParam.options}
|
|
onSelect={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? 'choose an option'}
|
|
/>
|
|
)}
|
|
{inputParam.type === 'multiOptions' && (
|
|
<MultiDropdown
|
|
disabled={disabled}
|
|
name={inputParam.name}
|
|
options={inputParam.options}
|
|
onSelect={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? 'choose an option'}
|
|
/>
|
|
)}
|
|
{inputParam.type === 'asyncOptions' && (
|
|
<>
|
|
{data.inputParams.length === 1 && <div style={{ marginTop: 10 }} />}
|
|
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
|
<AsyncDropdown
|
|
disabled={disabled}
|
|
name={inputParam.name}
|
|
nodeData={data}
|
|
value={data.inputs[inputParam.name] ?? inputParam.default ?? 'choose an option'}
|
|
onSelect={(newValue) => (data.inputs[inputParam.name] = newValue)}
|
|
onCreateNew={() => addAsyncOption(inputParam.name)}
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
{(data.name === 'cheerioWebScraper' ||
|
|
data.name === 'puppeteerWebScraper' ||
|
|
data.name === 'playwrightWebScraper') &&
|
|
inputParam.name === 'url' && (
|
|
<>
|
|
<Button
|
|
style={{
|
|
display: 'flex',
|
|
flexDirection: 'row',
|
|
width: '100%'
|
|
}}
|
|
disabled={disabled}
|
|
sx={{ borderRadius: '12px', width: '100%', mt: 1 }}
|
|
variant='outlined'
|
|
onClick={() =>
|
|
onManageLinksDialogClicked(
|
|
data.inputs[inputParam.name] ?? inputParam.default ?? '',
|
|
data.inputs.selectedLinks,
|
|
data.inputs['relativeLinksMethod'] ?? 'webCrawl',
|
|
parseInt(data.inputs['limit']) ?? 0
|
|
)
|
|
}
|
|
>
|
|
Manage Links
|
|
</Button>
|
|
<ManageScrapedLinksDialog
|
|
show={showManageScrapedLinksDialog}
|
|
dialogProps={manageScrapedLinksDialogProps}
|
|
onCancel={() => setShowManageScrapedLinksDialog(false)}
|
|
onSave={onManageLinksDialogSave}
|
|
/>
|
|
</>
|
|
)}
|
|
</Box>
|
|
</>
|
|
)}
|
|
<ExpandTextDialog
|
|
show={showExpandDialog}
|
|
dialogProps={expandDialogProps}
|
|
onCancel={() => setShowExpandDialog(false)}
|
|
onConfirm={(newValue, inputParamName) => onExpandDialogSave(newValue, inputParamName)}
|
|
></ExpandTextDialog>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
DocStoreInputHandler.propTypes = {
|
|
inputParam: PropTypes.object,
|
|
data: PropTypes.object,
|
|
disabled: PropTypes.bool
|
|
}
|
|
|
|
export default DocStoreInputHandler
|