mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 23:01:09 +03:00
add datagrid field type
This commit is contained in:
+45
-44
@@ -1,7 +1,8 @@
|
|||||||
import { getBaseClasses, INode, INodeData, INodeParams } from '../../../src'
|
import { convertSchemaToZod, getBaseClasses, INode, INodeData, INodeParams } from '../../../src'
|
||||||
import { BaseOutputParser } from 'langchain/schema/output_parser'
|
import { BaseOutputParser } from 'langchain/schema/output_parser'
|
||||||
import { StructuredOutputParser as LangchainStructuredOutputParser } from 'langchain/output_parsers'
|
import { StructuredOutputParser as LangchainStructuredOutputParser } from 'langchain/output_parsers'
|
||||||
import { CATEGORY } from '../OutputParserHelpers'
|
import { CATEGORY } from '../OutputParserHelpers'
|
||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
class StructuredOutputParser implements INode {
|
class StructuredOutputParser implements INode {
|
||||||
label: string
|
label: string
|
||||||
@@ -24,65 +25,65 @@ class StructuredOutputParser implements INode {
|
|||||||
this.icon = 'structure.png'
|
this.icon = 'structure.png'
|
||||||
this.category = CATEGORY
|
this.category = CATEGORY
|
||||||
this.baseClasses = [this.type, ...getBaseClasses(BaseOutputParser)]
|
this.baseClasses = [this.type, ...getBaseClasses(BaseOutputParser)]
|
||||||
//TODO: To extend the structureType to ZodSchema
|
|
||||||
this.inputs = [
|
this.inputs = [
|
||||||
{
|
|
||||||
label: 'Structure Type',
|
|
||||||
name: 'structureType',
|
|
||||||
type: 'options',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: 'Names And Descriptions',
|
|
||||||
name: 'fromNamesAndDescriptions'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
default: 'fromNamesAndDescriptions'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Structure',
|
|
||||||
name: 'structure',
|
|
||||||
type: 'string',
|
|
||||||
rows: 4,
|
|
||||||
placeholder:
|
|
||||||
'{' +
|
|
||||||
' answer: "answer to the question",\n' +
|
|
||||||
' source: "source used to answer the question, should be a website.",\n' +
|
|
||||||
'}'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Autofix',
|
label: 'Autofix',
|
||||||
name: 'autofixParser',
|
name: 'autofixParser',
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: true,
|
optional: true,
|
||||||
description: 'In the event that the first call fails, will make another call to the model to fix any errors.'
|
description: 'In the event that the first call fails, will make another call to the model to fix any errors.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'JSON Structure',
|
||||||
|
name: 'jsonStructure',
|
||||||
|
type: 'datagrid',
|
||||||
|
description: 'JSON structure for LLM to return',
|
||||||
|
datagrid: [
|
||||||
|
{ field: 'property', headerName: 'Property', editable: true },
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
headerName: 'Type',
|
||||||
|
type: 'singleSelect',
|
||||||
|
valueOptions: ['string', 'number', 'boolean'],
|
||||||
|
editable: true
|
||||||
|
},
|
||||||
|
{ field: 'description', headerName: 'Description', editable: true, flex: 1 }
|
||||||
|
],
|
||||||
|
default: [
|
||||||
|
{
|
||||||
|
property: 'answer',
|
||||||
|
type: 'string',
|
||||||
|
description: `answer to the user's question`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
property: 'source',
|
||||||
|
type: 'string',
|
||||||
|
description: `sources used to answer the question, should be websites`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
additionalParams: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(nodeData: INodeData): Promise<any> {
|
async init(nodeData: INodeData): Promise<any> {
|
||||||
const structureType = nodeData.inputs?.structureType as string
|
const jsonStructure = nodeData.inputs?.jsonStructure as string
|
||||||
const structure = nodeData.inputs?.structure as string
|
|
||||||
const autoFix = nodeData.inputs?.autofixParser as boolean
|
const autoFix = nodeData.inputs?.autofixParser as boolean
|
||||||
|
|
||||||
let parsedStructure: any | undefined = undefined
|
try {
|
||||||
if (structure && structureType === 'fromNamesAndDescriptions') {
|
const structuredOutputParser = LangchainStructuredOutputParser.fromZodSchema(z.object(convertSchemaToZod(jsonStructure)))
|
||||||
try {
|
|
||||||
parsedStructure = JSON.parse(structure)
|
|
||||||
|
|
||||||
// NOTE: When we change Flowise to return a json response, the following has to be changed to: JsonStructuredOutputParser
|
// NOTE: When we change Flowise to return a json response, the following has to be changed to: JsonStructuredOutputParser
|
||||||
let structuredOutputParser = LangchainStructuredOutputParser.fromNamesAndDescriptions(parsedStructure)
|
Object.defineProperty(structuredOutputParser, 'autoFix', {
|
||||||
Object.defineProperty(structuredOutputParser, 'autoFix', {
|
enumerable: true,
|
||||||
enumerable: true,
|
configurable: true,
|
||||||
configurable: true,
|
writable: true,
|
||||||
writable: true,
|
value: autoFix
|
||||||
value: autoFix
|
})
|
||||||
})
|
return structuredOutputParser
|
||||||
return structuredOutputParser
|
} catch (exception) {
|
||||||
} catch (exception) {
|
throw new Error('Invalid JSON in StructuredOutputParser: ' + exception)
|
||||||
throw new Error('Invalid JSON in StructuredOutputParser: ' + exception)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw new Error('Error creating OutputParser.')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ICommonObject, IDatabaseEntity, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../src/Interface'
|
import { ICommonObject, IDatabaseEntity, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../src/Interface'
|
||||||
import { getBaseClasses } from '../../../src/utils'
|
import { convertSchemaToZod, getBaseClasses } from '../../../src/utils'
|
||||||
import { DynamicStructuredTool } from './core'
|
import { DynamicStructuredTool } from './core'
|
||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { DataSource } from 'typeorm'
|
import { DataSource } from 'typeorm'
|
||||||
@@ -87,26 +87,4 @@ class CustomTool_Tools implements INode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const convertSchemaToZod = (schema: string) => {
|
|
||||||
try {
|
|
||||||
const parsedSchema = JSON.parse(schema)
|
|
||||||
const zodObj: any = {}
|
|
||||||
for (const sch of parsedSchema) {
|
|
||||||
if (sch.type === 'string') {
|
|
||||||
if (sch.required) z.string({ required_error: `${sch.property} required` }).describe(sch.description)
|
|
||||||
zodObj[sch.property] = z.string().describe(sch.description)
|
|
||||||
} else if (sch.type === 'number') {
|
|
||||||
if (sch.required) z.number({ required_error: `${sch.property} required` }).describe(sch.description)
|
|
||||||
zodObj[sch.property] = z.number().describe(sch.description)
|
|
||||||
} else if (sch.type === 'boolean') {
|
|
||||||
if (sch.required) z.boolean({ required_error: `${sch.property} required` }).describe(sch.description)
|
|
||||||
zodObj[sch.property] = z.boolean().describe(sch.description)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return zodObj
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { nodeClass: CustomTool_Tools }
|
module.exports = { nodeClass: CustomTool_Tools }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export type NodeParamsType =
|
|||||||
| 'asyncOptions'
|
| 'asyncOptions'
|
||||||
| 'options'
|
| 'options'
|
||||||
| 'multiOptions'
|
| 'multiOptions'
|
||||||
|
| 'datagrid'
|
||||||
| 'string'
|
| 'string'
|
||||||
| 'number'
|
| 'number'
|
||||||
| 'boolean'
|
| 'boolean'
|
||||||
@@ -60,6 +61,7 @@ export interface INodeParams {
|
|||||||
description?: string
|
description?: string
|
||||||
warning?: string
|
warning?: string
|
||||||
options?: Array<INodeOptionsValue>
|
options?: Array<INodeOptionsValue>
|
||||||
|
datagrid?: Array<ICommonObject>
|
||||||
credentialNames?: Array<string>
|
credentialNames?: Array<string>
|
||||||
optional?: boolean | INodeDisplay
|
optional?: boolean | INodeDisplay
|
||||||
step?: number
|
step?: number
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { load } from 'cheerio'
|
|||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import { JSDOM } from 'jsdom'
|
import { JSDOM } from 'jsdom'
|
||||||
|
import { z } from 'zod'
|
||||||
import { DataSource } from 'typeorm'
|
import { DataSource } from 'typeorm'
|
||||||
import { ICommonObject, IDatabaseEntity, IMessage, INodeData } from './Interface'
|
import { ICommonObject, IDatabaseEntity, IMessage, INodeData } from './Interface'
|
||||||
import { AES, enc } from 'crypto-js'
|
import { AES, enc } from 'crypto-js'
|
||||||
@@ -546,3 +547,30 @@ export const convertChatHistoryToText = (chatHistory: IMessage[] = []): string =
|
|||||||
})
|
})
|
||||||
.join('\n')
|
.join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert schema to zod schema
|
||||||
|
* @param {string} schema
|
||||||
|
* @returns {ICommonObject}
|
||||||
|
*/
|
||||||
|
export const convertSchemaToZod = (schema: string) => {
|
||||||
|
try {
|
||||||
|
const parsedSchema = JSON.parse(schema)
|
||||||
|
const zodObj: ICommonObject = {}
|
||||||
|
for (const sch of parsedSchema) {
|
||||||
|
if (sch.type === 'string') {
|
||||||
|
if (sch.required) z.string({ required_error: `${sch.property} required` }).describe(sch.description)
|
||||||
|
zodObj[sch.property] = z.string().describe(sch.description)
|
||||||
|
} else if (sch.type === 'number') {
|
||||||
|
if (sch.required) z.number({ required_error: `${sch.property} required` }).describe(sch.description)
|
||||||
|
zodObj[sch.property] = z.number().describe(sch.description)
|
||||||
|
} else if (sch.type === 'boolean') {
|
||||||
|
if (sch.required) z.boolean({ required_error: `${sch.property} required` }).describe(sch.description)
|
||||||
|
zodObj[sch.property] = z.boolean().describe(sch.description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return zodObj
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { useState, useCallback } from 'react'
|
||||||
|
import { DataGrid as MUIDataGrid, GridActionsCellItem } from '@mui/x-data-grid'
|
||||||
|
import { IconPlus } from '@tabler/icons'
|
||||||
|
import { Button } from '@mui/material'
|
||||||
|
import DeleteIcon from '@mui/icons-material/Delete'
|
||||||
|
import { cloneDeep } from 'lodash'
|
||||||
|
import { formatDataGridRows } from 'utils/genericHelper'
|
||||||
|
|
||||||
|
export const DataGrid = ({ columns, rows, style, disabled = false, hideFooter = false, onChange }) => {
|
||||||
|
const [rowValues, setRowValues] = useState(formatDataGridRows(rows) ?? [])
|
||||||
|
|
||||||
|
const deleteItem = useCallback(
|
||||||
|
(id) => () => {
|
||||||
|
let updatedRows = []
|
||||||
|
setRowValues((prevRows) => {
|
||||||
|
let allRows = [...cloneDeep(prevRows)]
|
||||||
|
allRows = allRows.filter((row) => row.id !== id)
|
||||||
|
updatedRows = allRows
|
||||||
|
return allRows
|
||||||
|
})
|
||||||
|
onChange(JSON.stringify(updatedRows))
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
const addCols = (columns) => {
|
||||||
|
return [
|
||||||
|
...columns,
|
||||||
|
{
|
||||||
|
field: 'actions',
|
||||||
|
type: 'actions',
|
||||||
|
width: 80,
|
||||||
|
getActions: (params) => [
|
||||||
|
<GridActionsCellItem key={'Delete'} icon={<DeleteIcon />} label='Delete' onClick={deleteItem(params.id)} />
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const colValues = addCols(columns)
|
||||||
|
|
||||||
|
const handleProcessRowUpdate = (newRow) => {
|
||||||
|
let updatedRows = []
|
||||||
|
setRowValues((prevRows) => {
|
||||||
|
let allRows = [...cloneDeep(prevRows)]
|
||||||
|
const indexToUpdate = allRows.findIndex((row) => row.id === newRow.id)
|
||||||
|
if (indexToUpdate >= 0) {
|
||||||
|
allRows[indexToUpdate] = { ...newRow }
|
||||||
|
}
|
||||||
|
updatedRows = allRows
|
||||||
|
return allRows
|
||||||
|
})
|
||||||
|
onChange(JSON.stringify(updatedRows))
|
||||||
|
return newRow
|
||||||
|
}
|
||||||
|
|
||||||
|
const getEmptyJsonObj = () => {
|
||||||
|
const obj = {}
|
||||||
|
for (let i = 0; i < colValues.length; i += 1) {
|
||||||
|
obj[colValues[i]?.field] = ''
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
const addNewRow = () => {
|
||||||
|
setRowValues((prevRows) => {
|
||||||
|
let allRows = [...cloneDeep(prevRows)]
|
||||||
|
const lastRowId = allRows.length ? allRows[allRows.length - 1].id + 1 : 1
|
||||||
|
allRows.push({
|
||||||
|
...getEmptyJsonObj(),
|
||||||
|
id: lastRowId
|
||||||
|
})
|
||||||
|
return allRows
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{rowValues && colValues && (
|
||||||
|
<div style={{ marginTop: 10, height: 210, width: '100%', ...style }}>
|
||||||
|
<MUIDataGrid
|
||||||
|
processRowUpdate={handleProcessRowUpdate}
|
||||||
|
isCellEditable={() => {
|
||||||
|
return !disabled
|
||||||
|
}}
|
||||||
|
hideFooter={hideFooter}
|
||||||
|
onProcessRowUpdateError={(error) => console.error(error)}
|
||||||
|
rows={rowValues}
|
||||||
|
columns={colValues}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{!disabled && (
|
||||||
|
<Button sx={{ mt: 1 }} variant='outlined' onClick={addNewRow} startIcon={<IconPlus />}>
|
||||||
|
Add Item
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
DataGrid.propTypes = {
|
||||||
|
rows: PropTypes.array,
|
||||||
|
columns: PropTypes.array,
|
||||||
|
style: PropTypes.any,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
hideFooter: PropTypes.bool,
|
||||||
|
onChange: PropTypes.func
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ export const initNode = (nodeData, newNodeId) => {
|
|||||||
'asyncOptions',
|
'asyncOptions',
|
||||||
'options',
|
'options',
|
||||||
'multiOptions',
|
'multiOptions',
|
||||||
|
'datagrid',
|
||||||
'string',
|
'string',
|
||||||
'number',
|
'number',
|
||||||
'boolean',
|
'boolean',
|
||||||
@@ -422,3 +423,17 @@ export const isValidURL = (url) => {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const formatDataGridRows = (rows) => {
|
||||||
|
try {
|
||||||
|
const parsedRows = typeof rows === 'string' ? JSON.parse(rows) : rows
|
||||||
|
return parsedRows.map((sch, index) => {
|
||||||
|
return {
|
||||||
|
...sch,
|
||||||
|
id: index
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { Dropdown } from 'ui-component/dropdown/Dropdown'
|
|||||||
import { MultiDropdown } from 'ui-component/dropdown/MultiDropdown'
|
import { MultiDropdown } from 'ui-component/dropdown/MultiDropdown'
|
||||||
import { AsyncDropdown } from 'ui-component/dropdown/AsyncDropdown'
|
import { AsyncDropdown } from 'ui-component/dropdown/AsyncDropdown'
|
||||||
import { Input } from 'ui-component/input/Input'
|
import { Input } from 'ui-component/input/Input'
|
||||||
|
import { DataGrid } from 'ui-component/grid/DataGrid'
|
||||||
import { File } from 'ui-component/file/File'
|
import { File } from 'ui-component/file/File'
|
||||||
import { SwitchInput } from 'ui-component/switch/Switch'
|
import { SwitchInput } from 'ui-component/switch/Switch'
|
||||||
import { flowContext } from 'store/context/ReactFlowContext'
|
import { flowContext } from 'store/context/ReactFlowContext'
|
||||||
@@ -258,6 +259,15 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA
|
|||||||
value={data.inputs[inputParam.name] ?? inputParam.default ?? false}
|
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 === 'string' || inputParam.type === 'password' || inputParam.type === 'number') && (
|
{(inputParam.type === 'string' || inputParam.type === 'password' || inputParam.type === 'number') && (
|
||||||
<Input
|
<Input
|
||||||
key={data.inputs[inputParam.name]}
|
key={data.inputs[inputParam.name]}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import useApi from 'hooks/useApi'
|
|||||||
|
|
||||||
// utils
|
// utils
|
||||||
import useNotifier from 'utils/useNotifier'
|
import useNotifier from 'utils/useNotifier'
|
||||||
import { generateRandomGradient } from 'utils/genericHelper'
|
import { generateRandomGradient, formatDataGridRows } from 'utils/genericHelper'
|
||||||
import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
|
import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
|
||||||
|
|
||||||
const exampleAPIFunc = `/*
|
const exampleAPIFunc = `/*
|
||||||
@@ -142,20 +142,6 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
|
|||||||
[deleteItem]
|
[deleteItem]
|
||||||
)
|
)
|
||||||
|
|
||||||
const formatSchema = (schema) => {
|
|
||||||
try {
|
|
||||||
const parsedSchema = JSON.parse(schema)
|
|
||||||
return parsedSchema.map((sch, index) => {
|
|
||||||
return {
|
|
||||||
...sch,
|
|
||||||
id: index
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
|
if (show) dispatch({ type: SHOW_CANVAS_DIALOG })
|
||||||
else dispatch({ type: HIDE_CANVAS_DIALOG })
|
else dispatch({ type: HIDE_CANVAS_DIALOG })
|
||||||
@@ -167,7 +153,7 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
|
|||||||
setToolId(getSpecificToolApi.data.id)
|
setToolId(getSpecificToolApi.data.id)
|
||||||
setToolName(getSpecificToolApi.data.name)
|
setToolName(getSpecificToolApi.data.name)
|
||||||
setToolDesc(getSpecificToolApi.data.description)
|
setToolDesc(getSpecificToolApi.data.description)
|
||||||
setToolSchema(formatSchema(getSpecificToolApi.data.schema))
|
setToolSchema(formatDataGridRows(getSpecificToolApi.data.schema))
|
||||||
if (getSpecificToolApi.data.func) setToolFunc(getSpecificToolApi.data.func)
|
if (getSpecificToolApi.data.func) setToolFunc(getSpecificToolApi.data.func)
|
||||||
else setToolFunc('')
|
else setToolFunc('')
|
||||||
}
|
}
|
||||||
@@ -180,7 +166,7 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
|
|||||||
setToolName(dialogProps.data.name)
|
setToolName(dialogProps.data.name)
|
||||||
setToolDesc(dialogProps.data.description)
|
setToolDesc(dialogProps.data.description)
|
||||||
setToolIcon(dialogProps.data.iconSrc)
|
setToolIcon(dialogProps.data.iconSrc)
|
||||||
setToolSchema(formatSchema(dialogProps.data.schema))
|
setToolSchema(formatDataGridRows(dialogProps.data.schema))
|
||||||
if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
|
if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
|
||||||
else setToolFunc('')
|
else setToolFunc('')
|
||||||
} else if (dialogProps.type === 'EDIT' && dialogProps.toolId) {
|
} else if (dialogProps.type === 'EDIT' && dialogProps.toolId) {
|
||||||
@@ -191,7 +177,7 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
|
|||||||
setToolName(dialogProps.data.name)
|
setToolName(dialogProps.data.name)
|
||||||
setToolDesc(dialogProps.data.description)
|
setToolDesc(dialogProps.data.description)
|
||||||
setToolIcon(dialogProps.data.iconSrc)
|
setToolIcon(dialogProps.data.iconSrc)
|
||||||
setToolSchema(formatSchema(dialogProps.data.schema))
|
setToolSchema(formatDataGridRows(dialogProps.data.schema))
|
||||||
if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
|
if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
|
||||||
else setToolFunc('')
|
else setToolFunc('')
|
||||||
} else if (dialogProps.type === 'TEMPLATE' && dialogProps.data) {
|
} else if (dialogProps.type === 'TEMPLATE' && dialogProps.data) {
|
||||||
@@ -199,7 +185,7 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
|
|||||||
setToolName(dialogProps.data.name)
|
setToolName(dialogProps.data.name)
|
||||||
setToolDesc(dialogProps.data.description)
|
setToolDesc(dialogProps.data.description)
|
||||||
setToolIcon(dialogProps.data.iconSrc)
|
setToolIcon(dialogProps.data.iconSrc)
|
||||||
setToolSchema(formatSchema(dialogProps.data.schema))
|
setToolSchema(formatDataGridRows(dialogProps.data.schema))
|
||||||
if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
|
if (dialogProps.data.func) setToolFunc(dialogProps.data.func)
|
||||||
else setToolFunc('')
|
else setToolFunc('')
|
||||||
} else if (dialogProps.type === 'ADD') {
|
} else if (dialogProps.type === 'ADD') {
|
||||||
|
|||||||
Reference in New Issue
Block a user