Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
235bec64
Commit
235bec64
authored
Feb 22, 2024
by
Joel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: new var input editor
parent
ee616ee6
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
250 additions
and
134 deletions
+250
-134
field.tsx
...nents/app/configuration/config-var/config-modal/field.tsx
+21
-0
index.tsx
...nents/app/configuration/config-var/config-modal/index.tsx
+76
-57
style.module.css
...pp/configuration/config-var/config-modal/style.module.css
+0
-8
index.tsx
web/app/components/app/configuration/config-var/index.tsx
+24
-6
index.tsx
...s/app/configuration/config-var/select-type-item/index.tsx
+13
-13
panel.tsx
web/app/components/workflow/nodes/start/panel.tsx
+17
-1
use-config.ts
web/app/components/workflow/nodes/start/use-config.ts
+9
-0
index.ts
web/config/index.ts
+10
-0
app-debug.en.ts
web/i18n/lang/app-debug.en.ts
+17
-12
app-debug.pt.ts
web/i18n/lang/app-debug.pt.ts
+13
-12
app-debug.uk.ts
web/i18n/lang/app-debug.uk.ts
+13
-12
app-debug.zh.ts
web/i18n/lang/app-debug.zh.ts
+17
-12
var.ts
web/utils/var.ts
+20
-1
No files found.
web/app/components/app/configuration/config-var/config-modal/field.tsx
0 → 100644
View file @
235bec64
'use client'
import
type
{
FC
}
from
'react'
import
React
from
'react'
type
Props
=
{
title
:
string
children
:
JSX
.
Element
}
const
Field
:
FC
<
Props
>
=
({
title
,
children
,
})
=>
{
return
(
<
div
>
<
div
className=
'leading-8 text-[13px] font-medium text-gray-700'
>
{
title
}
</
div
>
<
div
>
{
children
}
</
div
>
</
div
>
)
}
export
default
React
.
memo
(
Field
)
web/app/components/app/configuration/config-var/config-modal/index.tsx
View file @
235bec64
'use client'
import
type
{
FC
}
from
'react'
import
React
,
{
use
Effect
,
useState
}
from
'react'
import
React
,
{
use
Callback
,
useState
}
from
'react'
import
{
useTranslation
}
from
'react-i18next'
import
{
useContext
}
from
'use-context-selector'
import
ModalFoot
from
'../modal-foot'
import
type
{
Options
}
from
'../config-select'
import
ConfigSelect
from
'../config-select'
import
ConfigString
from
'../config-string'
import
SelectTypeItem
from
'../select-type-item'
import
s
from
'./style.module.css
'
import
Field
from
'./field
'
import
Toast
from
'@/app/components/base/toast'
import
type
{
PromptVariable
}
from
'@/models/debug'
import
{
getNewVar
}
from
'@/utils/var'
import
{
getNewVarInWorkflow
}
from
'@/utils/var'
import
ConfigContext
from
'@/context/debug-configuration'
import
{
type
InputVar
,
InputVarType
}
from
'@/app/components/workflow/types'
import
Modal
from
'@/app/components/base/modal'
import
Switch
from
'@/app/components/base/switch'
export
type
IConfigModalProps
=
{
payload
:
PromptVariable
isCreate
?:
boolean
payload
?:
InputVar
type
?:
string
isShow
:
boolean
onClose
:
()
=>
void
onConfirm
:
(
newValue
:
{
type
:
string
;
value
:
any
})
=>
void
// onConfirm: (newValue: { type: string; value: any }) => void
onConfirm
:
(
newValue
:
InputVar
)
=>
void
}
const
inputClassName
=
'w-full px-3 text-sm leading-9 text-gray-900 border-0 rounded-lg grow h-9 bg-gray-50 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200'
const
ConfigModal
:
FC
<
IConfigModalProps
>
=
({
isCreate
,
payload
,
isShow
,
onClose
,
...
...
@@ -32,45 +37,36 @@ const ConfigModal: FC<IConfigModalProps> = ({
})
=>
{
const
{
modelConfig
}
=
useContext
(
ConfigContext
)
const
{
t
}
=
useTranslation
()
const
{
type
,
name
,
key
,
options
,
max_length
}
=
payload
||
getNewVar
(
''
)
const
[
tempType
,
setTempType
]
=
useState
(
type
)
useEffect
(()
=>
{
setTempType
(
type
)
},
[
type
])
const
handleTypeChange
=
(
type
:
string
)
=>
{
return
()
=>
{
setTempType
(
type
)
}
}
const
[
tempPayload
,
setTempPayload
]
=
useState
<
InputVar
>
(
payload
||
getNewVarInWorkflow
(
''
)
as
any
)
// const { type, name, key, options, max_length } = tempPayload; name => label; variable => key
const
{
type
,
label
,
variable
,
options
,
max_length
}
=
tempPayload
const
isStringInput
=
tempType
===
'string'
||
tempType
===
'paragraph'
const
title
=
isStringInput
?
t
(
'appDebug.variableConig.maxLength'
)
:
t
(
'appDebug.variableConig.options'
)
const
isStringInput
=
type
===
InputVarType
.
textInput
||
type
===
InputVarType
.
paragraph
// string type
const
[
tempMaxLength
,
setTempMaxValue
]
=
useState
(
max_length
)
useEffect
(()
=>
{
setTempMaxValue
(
max_length
)
},
[
max_length
])
// select type
const
[
tempOptions
,
setTempOptions
]
=
useState
<
Options
>
(
options
||
[])
useEffect
(()
=>
{
setTempOptions
(
options
||
[])
},
[
options
])
const
handlePayloadChange
=
useCallback
((
key
:
string
)
=>
{
return
(
value
:
any
)
=>
{
setTempPayload
((
prev
)
=>
{
return
{
...
prev
,
[
key
]:
value
,
}
})
}
},
[])
const
handleConfirm
=
()
=>
{
if
(
isStringInput
)
{
onConfirm
({
type
:
tempType
,
value
:
tempMaxLength
})
onConfirm
(
tempPayload
)
// onConfirm({ type: type, value: tempMaxLength })
}
else
{
if
(
tempOptions
.
length
===
0
)
{
if
(
options
?
.
length
===
0
)
{
Toast
.
notify
({
type
:
'error'
,
message
:
'At least one option requied'
})
return
}
const
obj
:
Record
<
string
,
boolean
>
=
{}
let
hasRepeatedItem
=
false
tempOptions
.
forEach
((
o
)
=>
{
options
?
.
forEach
((
o
)
=>
{
if
(
obj
[
o
])
{
hasRepeatedItem
=
true
return
...
...
@@ -81,39 +77,62 @@ const ConfigModal: FC<IConfigModalProps> = ({
Toast
.
notify
({
type
:
'error'
,
message
:
'Has repeat items'
})
return
}
onConfirm
(
{
type
:
tempType
,
value
:
tempOptions
}
)
onConfirm
(
tempPayload
)
}
}
return
(
<
Modal
title=
{
t
(
'appDebug.variableConig.modalTitle'
)
}
title=
{
t
(
`appDebug.variableConig.${isCreate ? 'addModalTitle' : 'editModalTitle'}`
)
}
isShow=
{
isShow
}
onClose=
{
onClose
}
wrapperClassName=
'!z-[100]'
>
<
div
className=
'mb-8'
>
<
div
className=
'mt-2 mb-8 text-sm text-gray-500'
>
{
t
(
'appDebug.variableConig.description'
,
{
varName
:
`{{${name || key}}}`
})
}
</
div
>
<
div
className=
'mb-2'
>
<
div
className=
{
s
.
title
}
>
{
t
(
'appDebug.variableConig.fieldType'
)
}
</
div
>
<
div
className=
'flex space-x-2'
>
<
SelectTypeItem
type=
'string'
selected=
{
tempType
===
'string'
}
onClick=
{
handleTypeChange
(
'string'
)
}
/>
<
SelectTypeItem
type=
'paragraph'
selected=
{
tempType
===
'paragraph'
}
onClick=
{
handleTypeChange
(
'paragraph'
)
}
/>
<
SelectTypeItem
type=
'select'
selected=
{
tempType
===
'select'
}
onClick=
{
handleTypeChange
(
'select'
)
}
/>
</
div
>
</
div
>
<
div
className=
'space-y-2'
>
<
Field
title=
{
t
(
'appDebug.variableConig.fieldType'
)
}
>
<
div
className=
'flex space-x-2'
>
{
/* TODO handlePayloadChange(string) */
}
<
SelectTypeItem
type=
{
InputVarType
.
textInput
}
selected=
{
type
===
InputVarType
.
textInput
}
onClick=
{
()
=>
handlePayloadChange
(
'type'
)(
InputVarType
.
textInput
)
}
/>
<
SelectTypeItem
type=
{
InputVarType
.
paragraph
}
selected=
{
type
===
InputVarType
.
paragraph
}
onClick=
{
()
=>
handlePayloadChange
(
'type'
)(
InputVarType
.
paragraph
)
}
/>
<
SelectTypeItem
type=
{
InputVarType
.
select
}
selected=
{
type
===
InputVarType
.
select
}
onClick=
{
()
=>
handlePayloadChange
(
'type'
)(
InputVarType
.
select
)
}
/>
</
div
>
</
Field
>
<
Field
title=
{
t
(
'appDebug.variableConig.varName'
)
}
>
<
input
type=
'text'
className=
{
inputClassName
}
value=
{
variable
}
onChange=
{
e
=>
handlePayloadChange
(
'variable'
)(
e
.
target
.
value
)
}
/>
</
Field
>
<
Field
title=
{
t
(
'appDebug.variableConig.labelName'
)
}
>
<
input
type=
'text'
className=
{
inputClassName
}
value=
{
label
}
onChange=
{
e
=>
handlePayloadChange
(
'label'
)(
e
.
target
.
value
)
}
/>
</
Field
>
{
tempType
!==
'paragraph'
&&
(
<
div
className=
'mt-6'
>
<
div
className=
{
s
.
title
}
>
{
title
}
</
div
>
{
isStringInput
?
(
<
ConfigString
modelId=
{
modelConfig
.
model_id
}
value=
{
tempMaxLength
}
onChange=
{
setTempMaxValue
}
/>
)
:
(
<
ConfigSelect
options=
{
tempOptions
}
onChange=
{
setTempOptions
}
/>
)
}
</
div
>
)
}
{
isStringInput
&&
(
<
Field
title=
{
t
(
'appDebug.variableConig.maxLength'
)
}
>
<
ConfigString
modelId=
{
modelConfig
.
model_id
}
value=
{
max_length
}
onChange=
{
handlePayloadChange
(
'max_length'
)
}
/>
</
Field
>
)
}
{
type
===
InputVarType
.
select
&&
(
<
Field
title=
{
t
(
'appDebug.variableConig.options'
)
}
>
<
ConfigSelect
options=
{
options
!
}
onChange=
{
handlePayloadChange
(
'options'
)
}
/>
</
Field
>
)
}
<
Field
title=
{
t
(
'appDebug.variableConig.required'
)
}
>
<
Switch
defaultValue=
{
tempPayload
.
required
}
onChange=
{
handlePayloadChange
(
'required'
)
}
/>
</
Field
>
</
div
>
</
div
>
<
ModalFoot
onConfirm=
{
handleConfirm
}
...
...
web/app/components/app/configuration/config-var/config-modal/style.module.css
deleted
100644 → 0
View file @
ee616ee6
.title
{
margin-bottom
:
8px
;
font-size
:
13px
;
line-height
:
18px
;
font-weight
:
500
;
color
:
#101828
;
text-transform
:
capitalize
;
}
\ No newline at end of file
web/app/components/app/configuration/config-var/index.tsx
View file @
235bec64
...
...
@@ -25,6 +25,8 @@ import { AppType } from '@/types/app'
import
type
{
ExternalDataTool
}
from
'@/models/common'
import
{
useModalContext
}
from
'@/context/modal-context'
import
{
useEventEmitterContextContext
}
from
'@/context/event-emitter'
import
type
{
InputVar
}
from
'@/app/components/workflow/types'
import
{
InputVarType
}
from
'@/app/components/workflow/types'
export
const
ADD_EXTERNAL_DATA_TOOL
=
'ADD_EXTERNAL_DATA_TOOL'
...
...
@@ -71,6 +73,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
}
const
batchUpdatePromptVariable
=
(
key
:
string
,
updateKeys
:
string
[],
newValues
:
any
[],
isParagraph
?:
boolean
)
=>
{
console
.
log
(
key
)
const
newPromptVariables
=
promptVariables
.
map
((
item
)
=>
{
if
(
item
.
key
===
key
)
{
const
newItem
:
any
=
{
...
item
}
...
...
@@ -111,7 +114,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
})
conflictTimer
=
setTimeout
(()
=>
{
const
isKeyExists
=
promptVariables
.
some
(
item
=>
item
.
key
.
trim
()
===
newKey
.
trim
())
const
isKeyExists
=
promptVariables
.
some
(
item
=>
item
.
key
?
.
trim
()
===
newKey
.
trim
())
if
(
isKeyExists
)
{
Toast
.
notify
({
type
:
'error'
,
...
...
@@ -242,6 +245,17 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
const
[
currKey
,
setCurrKey
]
=
useState
<
string
|
null
>
(
null
)
const
currItem
=
currKey
?
promptVariables
.
find
(
item
=>
item
.
key
===
currKey
)
:
null
const
currItemToEdit
:
InputVar
|
null
=
(()
=>
{
if
(
!
currItem
)
return
null
return
{
...
currItem
,
label
:
currItem
.
name
,
variable
:
currItem
.
key
,
type
:
currItem
.
type
===
'string'
?
InputVarType
.
textInput
:
currItem
.
type
,
}
as
InputVar
})()
const
[
isShowEditModal
,
{
setTrue
:
showEditModal
,
setFalse
:
hideEditModal
}]
=
useBoolean
(
false
)
const
handleConfig
=
({
key
,
type
,
index
,
name
,
config
,
icon
,
icon_background
}:
ExternalDataToolParams
)
=>
{
...
...
@@ -297,6 +311,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
<
tr
key=
{
index
}
className=
"h-9 leading-9"
>
<
td
className=
"w-[160px] border-b border-gray-100 pl-3"
>
<
div
className=
'flex items-center space-x-1'
>
{
type
}
<
IconTypeIcon
type=
{
type
as
IInputTypeIconProps
[
'type'
]
}
className=
'text-gray-400'
/>
{
!
readonly
?
(
...
...
@@ -358,14 +373,17 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
{
isShowEditModal
&&
(
<
EditModal
payload=
{
currItem
as
PromptVariable
}
payload=
{
currItem
ToEdit
!
}
isShow=
{
isShowEditModal
}
onClose=
{
hideEditModal
}
onConfirm=
{
({
type
,
value
})
=>
{
if
(
type
===
'string'
)
batchUpdatePromptVariable
(
currKey
as
string
,
[
'type'
,
'max_length'
],
[
type
,
value
||
DEFAULT_VALUE_MAX_LEN
])
onConfirm=
{
(
item
)
=>
{
const
{
type
,
max_length
,
options
}
=
item
if
(
type
===
InputVarType
.
textInput
)
batchUpdatePromptVariable
(
currKey
as
string
,
[
'type'
,
'max_length'
],
[
'string'
,
max_length
||
DEFAULT_VALUE_MAX_LEN
])
if
(
type
===
InputVarType
.
paragraph
)
batchUpdatePromptVariable
(
currKey
as
string
,
[
'type'
,
'max_length'
],
[
InputVarType
.
paragraph
,
max_length
||
DEFAULT_VALUE_MAX_LEN
],
true
)
else
batchUpdatePromptVariable
(
currKey
as
string
,
[
'type'
,
'options'
],
[
type
,
value
||
[]],
type
===
'paragraph'
)
batchUpdatePromptVariable
(
currKey
as
string
,
[
'type'
,
'options'
],
[
type
,
options
||
[]],
false
)
hideEditModal
()
}
}
...
...
web/app/components/app/configuration/config-var/select-type-item/index.tsx
View file @
235bec64
...
...
@@ -3,18 +3,18 @@ import type { FC } from 'react'
import
React
from
'react'
import
{
useTranslation
}
from
'react-i18next'
import
cn
from
'classnames'
import
s
from
'./style.module.css'
import
{
InputVarType
}
from
'@/app/components/workflow/types'
export
type
ISelectTypeItemProps
=
{
type
:
string
type
:
InputVarType
selected
:
boolean
onClick
:
()
=>
void
}
const
Icon
=
({
type
,
selected
}:
Partial
<
ISelectTypeItemProps
>
)
=>
{
switch
(
type
)
{
case
'select'
:
case
InputVarType
.
select
:
return
selected
?
(
<
svg
width=
"17"
height=
"16"
viewBox=
"0 0 17 16"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
...
...
@@ -28,16 +28,16 @@ const Icon = ({ type, selected }: Partial<ISelectTypeItemProps>) => {
<
path
d=
"M12.8923 0.666672H7.77427C7.42285 0.666661 7.11966 0.666651 6.86995 0.687053C6.60639 0.708587 6.34424 0.756131 6.09199 0.884661C5.71567 1.07641 5.40971 1.38237 5.21796 1.75869C5.08943 2.01095 5.04188 2.27309 5.02035 2.53665C5.00206 2.76051 5.00018 3.02733 4.99999 3.33336L8.92055 3.33335C9.2463 3.33327 9.59951 3.33319 9.90523 3.35816C10.2512 3.38644 10.7084 3.4564 11.1799 3.69667C11.8071 4.01625 12.3171 4.52618 12.6367 5.15339C12.8769 5.62493 12.9469 6.08208 12.9752 6.42809C13.0001 6.73382 13.0001 7.08702 13 7.41279L13 11.3333C13.306 11.3331 13.5728 11.3313 13.7967 11.313C14.0602 11.2914 14.3224 11.2439 14.5746 11.1154C14.9509 10.9236 15.2569 10.6176 15.4487 10.2413C15.5772 9.98907 15.6247 9.72692 15.6463 9.46336C15.6667 9.21366 15.6666 8.91051 15.6666 8.5591V3.44099C15.6666 3.08959 15.6667 2.78635 15.6463 2.53665C15.6247 2.27309 15.5772 2.01095 15.4487 1.75869C15.2569 1.38237 14.9509 1.07641 14.5746 0.884661C14.3224 0.756131 14.0602 0.708587 13.7967 0.687053C13.5469 0.666651 13.2438 0.666661 12.8923 0.666672Z"
fill=
"#667085"
/>
</
svg
>
)
case
'paragraph'
:
case
InputVarType
.
paragraph
:
return
selected
?
(
<
svg
width=
"16"
height=
"16"
viewBox=
"0 0 16 16"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<
g
id=
"align-left"
>
<
g
id=
"Solid"
>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 6.66665C1.33334 6.29846 1.63182 5.99998 2.00001 5.99998H10.6667C11.0349 5.99998 11.3333 6.29846 11.3333 6.66665C11.3333 7.03484 11.0349 7.33331 10.6667 7.33331H2.00001C1.63182 7.33331 1.33334 7.03484 1.33334 6.66665Z"
fill=
"#155EEF"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 3.99998C1.33334 3.63179 1.63182 3.33331 2.00001 3.33331H13.3333C13.7015 3.33331 14 3.63179 14 3.99998C14 4.36817 13.7015 4.66665 13.3333 4.66665H2.00001C1.63182 4.66665 1.33334 4.36817 1.33334 3.99998Z"
fill=
"#155EEF"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 9.33331C1.33334 8.96512 1.63182 8.66665 2.00001 8.66665H13.3333C13.7015 8.66665 14 8.96512 14 9.33331C14 9.7015 13.7015 9.99998 13.3333 9.99998H2.00001C1.63182 9.99998 1.33334 9.7015 1.33334 9.33331Z"
fill=
"#155EEF"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6666 10.6667 12.6666H2.00001C1.63182 12.6666 1.33334 12.3682 1.33334 12Z"
fill=
"#155EEF"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 6.66665C1.33334 6.29846 1.63182 5.99998 2.00001 5.99998H10.6667C11.0349 5.99998 11.3333 6.29846 11.3333 6.66665C11.3333 7.03484 11.0349 7.33331 10.6667 7.33331H2.00001C1.63182 7.33331 1.33334 7.03484 1.33334 6.66665Z"
fill=
"#155EEF"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 3.99998C1.33334 3.63179 1.63182 3.33331 2.00001 3.33331H13.3333C13.7015 3.33331 14 3.63179 14 3.99998C14 4.36817 13.7015 4.66665 13.3333 4.66665H2.00001C1.63182 4.66665 1.33334 4.36817 1.33334 3.99998Z"
fill=
"#155EEF"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 9.33331C1.33334 8.96512 1.63182 8.66665 2.00001 8.66665H13.3333C13.7015 8.66665 14 8.96512 14 9.33331C14 9.7015 13.7015 9.99998 13.3333 9.99998H2.00001C1.63182 9.99998 1.33334 9.7015 1.33334 9.33331Z"
fill=
"#155EEF"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6666 10.6667 12.6666H2.00001C1.63182 12.6666 1.33334 12.3682 1.33334 12Z"
fill=
"#155EEF"
/>
</
g
>
</
g
>
</
svg
>
...
...
@@ -46,15 +46,15 @@ const Icon = ({ type, selected }: Partial<ISelectTypeItemProps>) => {
<
svg
width=
"16"
height=
"16"
viewBox=
"0 0 16 16"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<
g
id=
"align-left"
>
<
g
id=
"Solid"
>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 6.66666C1.33334 6.29847 1.63182 5.99999 2.00001 5.99999H10.6667C11.0349 5.99999 11.3333 6.29847 11.3333 6.66666C11.3333 7.03485 11.0349 7.33333 10.6667 7.33333H2.00001C1.63182 7.33333 1.33334 7.03485 1.33334 6.66666Z"
fill=
"#667085"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 3.99999C1.33334 3.63181 1.63182 3.33333 2.00001 3.33333H13.3333C13.7015 3.33333 14 3.63181 14 3.99999C14 4.36818 13.7015 4.66666 13.3333 4.66666H2.00001C1.63182 4.66666 1.33334 4.36818 1.33334 3.99999Z"
fill=
"#667085"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 9.33333C1.33334 8.96514 1.63182 8.66666 2.00001 8.66666H13.3333C13.7015 8.66666 14 8.96514 14 9.33333C14 9.70152 13.7015 10 13.3333 10H2.00001C1.63182 10 1.33334 9.70152 1.33334 9.33333Z"
fill=
"#667085"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6667 10.6667 12.6667H2.00001C1.63182 12.6667 1.33334 12.3682 1.33334 12Z"
fill=
"#667085"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 6.66666C1.33334 6.29847 1.63182 5.99999 2.00001 5.99999H10.6667C11.0349 5.99999 11.3333 6.29847 11.3333 6.66666C11.3333 7.03485 11.0349 7.33333 10.6667 7.33333H2.00001C1.63182 7.33333 1.33334 7.03485 1.33334 6.66666Z"
fill=
"#667085"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 3.99999C1.33334 3.63181 1.63182 3.33333 2.00001 3.33333H13.3333C13.7015 3.33333 14 3.63181 14 3.99999C14 4.36818 13.7015 4.66666 13.3333 4.66666H2.00001C1.63182 4.66666 1.33334 4.36818 1.33334 3.99999Z"
fill=
"#667085"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 9.33333C1.33334 8.96514 1.63182 8.66666 2.00001 8.66666H13.3333C13.7015 8.66666 14 8.96514 14 9.33333C14 9.70152 13.7015 10 13.3333 10H2.00001C1.63182 10 1.33334 9.70152 1.33334 9.33333Z"
fill=
"#667085"
/>
<
path
fillRule=
"evenodd"
clipRule=
"evenodd"
d=
"M1.33334 12C1.33334 11.6318 1.63182 11.3333 2.00001 11.3333H10.6667C11.0349 11.3333 11.3333 11.6318 11.3333 12C11.3333 12.3682 11.0349 12.6667 10.6667 12.6667H2.00001C1.63182 12.6667 1.33334 12.3682 1.33334 12Z"
fill=
"#667085"
/>
</
g
>
</
g
>
</
svg
>
)
case
'string'
:
case
InputVarType
.
textInput
:
default
:
return
selected
?
(
...
...
web/app/components/workflow/nodes/start/panel.tsx
View file @
235bec64
...
...
@@ -7,6 +7,7 @@ import Split from '@/app/components/workflow/nodes/_base/components/split'
import
Field
from
'@/app/components/workflow/nodes/_base/components/field'
import
OutputVars
,
{
VarItem
}
from
'@/app/components/workflow/nodes/_base/components/output-vars'
import
AddButton
from
'@/app/components/base/button/add-button'
import
ConfigVarModal
from
'@/app/components/app/configuration/config-var/config-modal'
const
i18nPrefix
=
'workflow.nodes.start'
...
...
@@ -15,6 +16,10 @@ const Panel: FC = () => {
const
readOnly
=
false
const
{
inputs
,
isShowAddVarModal
,
showAddVarModal
,
handleAddVariable
,
hideAddVarModal
,
handleVarListChange
,
}
=
useConfig
(
mockData
)
...
...
@@ -24,7 +29,7 @@ const Panel: FC = () => {
<
Field
title=
{
t
(
`${i18nPrefix}.inputField`
)
}
operations=
{
<
AddButton
onClick=
{
()
=>
{
}
}
/>
<
AddButton
onClick=
{
showAddVarModal
}
/>
}
>
<
VarList
...
...
@@ -69,6 +74,17 @@ const Panel: FC = () => {
</>
</
OutputVars
>
</
div
>
{
isShowAddVarModal
&&
(
<
ConfigVarModal
isCreate
isShow=
{
isShowAddVarModal
}
onClose=
{
hideAddVarModal
}
onConfirm=
{
(
payload
)
=>
{
handleAddVariable
(
payload
)
hideAddVarModal
()
}
}
/>
)
}
</
div
>
)
}
...
...
web/app/components/workflow/nodes/start/use-config.ts
View file @
235bec64
import
{
useCallback
,
useState
}
from
'react'
import
produce
from
'immer'
import
{
useBoolean
}
from
'ahooks'
import
type
{
StartNodeType
}
from
'./types'
import
type
{
InputVar
}
from
'@/app/components/workflow/types'
const
useConfig
=
(
initInputs
:
StartNodeType
)
=>
{
const
[
inputs
,
setInputs
]
=
useState
<
StartNodeType
>
(
initInputs
)
const
[
isShowAddVarModal
,
{
setTrue
:
showAddVarModal
,
setFalse
:
hideAddVarModal
,
}]
=
useBoolean
(
true
)
const
handleVarListChange
=
useCallback
((
newList
:
InputVar
[])
=>
{
const
newInputs
=
produce
(
inputs
,
(
draft
:
any
)
=>
{
draft
.
variables
=
newList
...
...
@@ -21,6 +27,9 @@ const useConfig = (initInputs: StartNodeType) => {
},
[
inputs
,
setInputs
])
return
{
inputs
,
isShowAddVarModal
,
showAddVarModal
,
hideAddVarModal
,
handleVarListChange
,
handleAddVariable
,
}
...
...
web/config/index.ts
View file @
235bec64
/* eslint-disable import/no-mutable-exports */
import
{
InputVarType
}
from
'@/app/components/workflow/types'
import
{
AgentStrategy
}
from
'@/types/app'
export
let
apiPrefix
=
''
...
...
@@ -115,6 +116,15 @@ export const VAR_ITEM_TEMPLATE = {
required
:
true
,
}
export
const
VAR_ITEM_TEMPLATE_IN_WORKFLOW
=
{
variable
:
''
,
label
:
''
,
type
:
InputVarType
.
textInput
,
max_length
:
DEFAULT_VALUE_MAX_LEN
,
required
:
true
,
options
:
[],
}
export
const
appDefaultIconBackground
=
'#D5F5F6'
export
const
NEED_REFRESH_APP_LIST_KEY
=
'needRefreshAppList'
...
...
web/i18n/lang/app-debug.en.ts
View file @
235bec64
...
...
@@ -266,18 +266,23 @@ const translation = {
queryNoBeEmpty
:
'Query must be set in the prompt'
,
},
variableConig
:
{
modalTitle
:
'Field settings'
,
description
:
'Setting for variable {{varName}}'
,
fieldType
:
'Field type'
,
string
:
'Short Text'
,
paragraph
:
'Paragraph'
,
select
:
'Select'
,
notSet
:
'Not set, try typing {{input}} in the prefix prompt'
,
stringTitle
:
'Form text box options'
,
maxLength
:
'Max length'
,
options
:
'Options'
,
addOption
:
'Add option'
,
apiBasedVar
:
'API-based Variable'
,
'addModalTitle'
:
'Add Input Field'
,
'editModalTitle'
:
'Edit Input Field'
,
'description'
:
'Setting for variable {{varName}}'
,
'fieldType'
:
'Field type'
,
'string'
:
'Short Text'
,
'text-input'
:
'Short Text'
,
'paragraph'
:
'Paragraph'
,
'select'
:
'Select'
,
'notSet'
:
'Not set, try typing {{input}} in the prefix prompt'
,
'stringTitle'
:
'Form text box options'
,
'maxLength'
:
'Max length'
,
'options'
:
'Options'
,
'addOption'
:
'Add option'
,
'apiBasedVar'
:
'API-based Variable'
,
'varName'
:
'Variable Name'
,
'labelName'
:
'Label Name'
,
'required'
:
'Required'
,
},
vision
:
{
name
:
'Vision'
,
...
...
web/i18n/lang/app-debug.pt.ts
View file @
235bec64
...
...
@@ -266,18 +266,19 @@ const translation = {
queryNoBeEmpty
:
'A consulta deve ser definida na solicitação'
,
},
variableConig
:
{
modalTitle
:
'Configurações do Campo'
,
description
:
'Configuração para a variável {{varName}}'
,
fieldType
:
'Tipo de Campo'
,
string
:
'Texto Curto'
,
paragraph
:
'Parágrafo'
,
select
:
'Selecionar'
,
notSet
:
'Não definido, tente digitar {{input}} na solicitação'
,
stringTitle
:
'Opções da Caixa de Texto do Formulário'
,
maxLength
:
'Comprimento Máximo'
,
options
:
'Opções'
,
addOption
:
'Adicionar opção'
,
apiBasedVar
:
'Variável Baseada em API'
,
'addModalTitle'
:
'Configurações do Campo'
,
'description'
:
'Configuração para a variável {{varName}}'
,
'fieldType'
:
'Tipo de Campo'
,
'string'
:
'Texto Curto'
,
'text-input'
:
'Texto Curto'
,
'paragraph'
:
'Parágrafo'
,
'select'
:
'Selecionar'
,
'notSet'
:
'Não definido, tente digitar {{input}} na solicitação'
,
'stringTitle'
:
'Opções da Caixa de Texto do Formulário'
,
'maxLength'
:
'Comprimento Máximo'
,
'options'
:
'Opções'
,
'addOption'
:
'Adicionar opção'
,
'apiBasedVar'
:
'Variável Baseada em API'
,
},
vision
:
{
name
:
'Visão'
,
...
...
web/i18n/lang/app-debug.uk.ts
View file @
235bec64
...
...
@@ -260,18 +260,19 @@ const translation = {
queryNoBeEmpty
:
'Запит має бути встановлений у підказці'
,
// Query must be set in the prompt
},
variableConig
:
{
modalTitle
:
'Налаштування поля'
,
// Field settings
description
:
'Налаштування для змінної {{varName}}'
,
// Setting for variable {{varName}}
fieldType
:
'Тип поля'
,
// Field type
string
:
'Короткий текст'
,
// Short Text
paragraph
:
'Абзац'
,
// Paragraph
select
:
'Вибрати'
,
// Select
notSet
:
'Не налаштовано, спробуйте ввести {{input}} у префіксну підказку'
,
// Not set, try typing {{input}} in the prefix prompt
stringTitle
:
'Опції текстового поля форми'
,
// Form text box options
maxLength
:
'Максимальна довжина'
,
// Max length
options
:
'Опції'
,
// Options
addOption
:
'Додати опцію'
,
// Add option
apiBasedVar
:
'Змінна на основі API'
,
// API-based Variable
'addModalTitle'
:
'Налаштування поля'
,
// Field settings
'description'
:
'Налаштування для змінної {{varName}}'
,
// Setting for variable {{varName}}
'fieldType'
:
'Тип поля'
,
// Field type
'string'
:
'Короткий текст'
,
// Short Text
'text-input'
:
'Короткий текст'
,
// Short Text
'paragraph'
:
'Абзац'
,
// Paragraph
'select'
:
'Вибрати'
,
// Select
'notSet'
:
'Не налаштовано, спробуйте ввести {{input}} у префіксну підказку'
,
// Not set, try typing {{input}} in the prefix prompt
'stringTitle'
:
'Опції текстового поля форми'
,
// Form text box options
'maxLength'
:
'Максимальна довжина'
,
// Max length
'options'
:
'Опції'
,
// Options
'addOption'
:
'Додати опцію'
,
// Add option
'apiBasedVar'
:
'Змінна на основі API'
,
// API-based Variable
},
vision
:
{
name
:
'Зображення'
,
// Vision
...
...
web/i18n/lang/app-debug.zh.ts
View file @
235bec64
...
...
@@ -248,6 +248,9 @@ const translation = {
action
:
'操作'
,
typeString
:
'文本'
,
typeSelect
:
'下拉选项'
,
varName
:
'变量名称'
,
labelName
:
'显示名称'
,
required
:
'必填'
,
},
varKeyError
:
{
canNoBeEmpty
:
'变量不能为空'
,
...
...
@@ -262,18 +265,20 @@ const translation = {
queryNoBeEmpty
:
'提示词中必须设置查询内容'
,
},
variableConig
:
{
modalTitle
:
'变量设置'
,
description
:
'设置变量 {{varName}}'
,
fieldType
:
'字段类型'
,
string
:
'文本'
,
paragraph
:
'段落'
,
select
:
'下拉选项'
,
notSet
:
'未设置,在 Prompt 中输入 {{input}} 试试'
,
stringTitle
:
'文本框设置'
,
maxLength
:
'最大长度'
,
options
:
'选项'
,
addOption
:
'添加选项'
,
apiBasedVar
:
'基于 API 的变量'
,
'addModalTitle'
:
'添加变量'
,
'editModalTitle'
:
'编辑变量'
,
'description'
:
'设置变量 {{varName}}'
,
'fieldType'
:
'字段类型'
,
'string'
:
'文本'
,
'text-input'
:
'文本'
,
'paragraph'
:
'段落'
,
'select'
:
'下拉选项'
,
'notSet'
:
'未设置,在 Prompt 中输入 {{input}} 试试'
,
'stringTitle'
:
'文本框设置'
,
'maxLength'
:
'最大长度'
,
'options'
:
'选项'
,
'addOption'
:
'添加选项'
,
'apiBasedVar'
:
'基于 API 的变量'
,
},
vision
:
{
name
:
'视觉'
,
...
...
web/utils/var.ts
View file @
235bec64
import
{
MAX_VAR_KEY_LENGHT
,
VAR_ITEM_TEMPLATE
,
getMaxVarNameLength
}
from
'@/config'
import
{
MAX_VAR_KEY_LENGHT
,
VAR_ITEM_TEMPLATE
,
VAR_ITEM_TEMPLATE_IN_WORKFLOW
,
getMaxVarNameLength
}
from
'@/config'
import
{
CONTEXT_PLACEHOLDER_TEXT
,
HISTORY_PLACEHOLDER_TEXT
,
PRE_PROMPT_PLACEHOLDER_TEXT
,
QUERY_PLACEHOLDER_TEXT
}
from
'@/app/components/base/prompt-editor/constants'
import
{
InputVarType
}
from
'@/app/components/workflow/types'
const
otherAllowedRegex
=
/^
[
a-zA-Z0-9_
]
+$/
...
...
@@ -21,6 +22,24 @@ export const getNewVar = (key: string, type: string) => {
}
}
export
const
getNewVarInWorkflow
=
(
key
:
string
,
type
=
InputVarType
.
textInput
)
=>
{
const
{
max_length
,
...
rest
}
=
VAR_ITEM_TEMPLATE_IN_WORKFLOW
if
(
type
!==
InputVarType
.
textInput
)
{
return
{
...
rest
,
type
,
variable
:
key
,
label
:
key
.
slice
(
0
,
getMaxVarNameLength
(
key
)),
}
}
return
{
...
VAR_ITEM_TEMPLATE_IN_WORKFLOW
,
type
,
variable
:
key
,
label
:
key
.
slice
(
0
,
getMaxVarNameLength
(
key
)),
}
}
const
checkKey
=
(
key
:
string
,
canBeEmpty
?:
boolean
)
=>
{
if
(
key
.
length
===
0
&&
!
canBeEmpty
)
return
'canNoBeEmpty'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment