mirror of https://github.com/langgenius/dify.git
feat: enhance email configuration and body input components with support for dynamic node variables
This commit is contained in:
parent
c5721184e9
commit
2b28074f4c
|
|
@ -1,4 +1,5 @@
|
|||
import type { ValueSelector } from '../../workflow/types'
|
||||
import { uniqBy } from 'es-toolkit/compat'
|
||||
import { SupportUploadFileTypes } from '../../workflow/types'
|
||||
|
||||
export const CONTEXT_PLACEHOLDER_TEXT = '{{#context#}}'
|
||||
|
|
@ -57,7 +58,8 @@ export const getInputVars = (text: string): ValueSelector[] => {
|
|||
|
||||
return valueSelector
|
||||
})
|
||||
return inputVars
|
||||
const uniqueInputVars = uniqBy(inputVars, item => item.join('.'))
|
||||
return uniqueInputVars
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import type { EmailConfig } from '../../types'
|
||||
import type {
|
||||
Node,
|
||||
NodeOutPutVar,
|
||||
} from '@/app/components/workflow/types'
|
||||
import { RiBugLine, RiCloseLine } from '@remixicon/react'
|
||||
import { noop } from 'es-toolkit/compat'
|
||||
import { memo, useCallback, useState } from 'react'
|
||||
|
|
@ -20,6 +24,8 @@ type EmailConfigureModalProps = {
|
|||
onClose: () => void
|
||||
onConfirm: (data: EmailConfig) => void
|
||||
config?: EmailConfig
|
||||
nodesOutputVars?: NodeOutPutVar[]
|
||||
availableNodes?: Node[]
|
||||
}
|
||||
|
||||
const EmailConfigureModal = ({
|
||||
|
|
@ -27,6 +33,8 @@ const EmailConfigureModal = ({
|
|||
onClose,
|
||||
onConfirm,
|
||||
config,
|
||||
nodesOutputVars = [],
|
||||
availableNodes = [],
|
||||
}: EmailConfigureModalProps) => {
|
||||
const { t } = useTranslation()
|
||||
const email = useAppContextWithSelector(s => s.userProfile.email)
|
||||
|
|
@ -110,6 +118,8 @@ const EmailConfigureModal = ({
|
|||
<MailBodyInput
|
||||
value={body}
|
||||
onChange={setBody}
|
||||
nodesOutputVars={nodesOutputVars}
|
||||
availableNodes={availableNodes}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,30 @@
|
|||
import type {
|
||||
Node,
|
||||
NodeOutPutVar,
|
||||
} from '@/app/components/workflow/types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import PromptEditor from '@/app/components/base/prompt-editor'
|
||||
import Placeholder from '@/app/components/workflow/nodes/tool/components/mixed-variable-text-input/placeholder'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
type MailBodyInputProps = {
|
||||
readOnly?: boolean
|
||||
nodesOutputVars?: NodeOutPutVar[]
|
||||
availableNodes?: Node[]
|
||||
value?: string
|
||||
onChange?: (text: string) => void
|
||||
}
|
||||
|
||||
const MailBodyInput = ({
|
||||
readOnly = false,
|
||||
nodesOutputVars,
|
||||
availableNodes = [],
|
||||
value = '',
|
||||
onChange,
|
||||
}: MailBodyInputProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<PromptEditor
|
||||
wrapperClassName={cn(
|
||||
|
|
@ -27,6 +39,23 @@ const MailBodyInput = ({
|
|||
show: true,
|
||||
selectable: true,
|
||||
}}
|
||||
workflowVariableBlock={{
|
||||
show: true,
|
||||
variables: nodesOutputVars || [],
|
||||
workflowNodesMap: availableNodes.reduce((acc, node) => {
|
||||
acc[node.id] = {
|
||||
title: node.data.title,
|
||||
type: node.data.type,
|
||||
}
|
||||
if (node.data.type === BlockEnum.Start) {
|
||||
acc.sys = {
|
||||
title: t('blocks.start', { ns: 'workflow' }),
|
||||
type: BlockEnum.Start,
|
||||
}
|
||||
}
|
||||
return acc
|
||||
}, {} as Record<string, Pick<Node['data'], 'title' | 'type'>>),
|
||||
}}
|
||||
placeholder={<Placeholder hideBadge />}
|
||||
onChange={onChange}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ const DeliveryMethodItem: FC<DeliveryMethodItemProps> = ({
|
|||
<Tooltip
|
||||
popupContent={emailSenderTooltipContent}
|
||||
asChild={false}
|
||||
needsDelay={false}
|
||||
>
|
||||
<ActionButton onClick={() => setShowTestEmailModal(true)}>
|
||||
<RiSendPlane2Line className="h-4 w-4" />
|
||||
|
|
@ -118,6 +119,7 @@ const DeliveryMethodItem: FC<DeliveryMethodItemProps> = ({
|
|||
<Tooltip
|
||||
popupContent={t('common.configure', { ns: 'workflow' })}
|
||||
asChild={false}
|
||||
needsDelay={false}
|
||||
>
|
||||
<ActionButton onClick={() => setShowEmailModal(true)}>
|
||||
<RiEqualizer2Line className="h-4 w-4" />
|
||||
|
|
@ -129,6 +131,7 @@ const DeliveryMethodItem: FC<DeliveryMethodItemProps> = ({
|
|||
<Tooltip
|
||||
popupContent={t('operation.remove', { ns: 'common' })}
|
||||
asChild={false}
|
||||
needsDelay={false}
|
||||
>
|
||||
<div
|
||||
onMouseEnter={() => setIsHovering(true)}
|
||||
|
|
@ -168,6 +171,8 @@ const DeliveryMethodItem: FC<DeliveryMethodItemProps> = ({
|
|||
<EmailConfigureModal
|
||||
isShow={showEmailModal}
|
||||
config={method.config as EmailConfig}
|
||||
nodesOutputVars={nodesOutputVars}
|
||||
availableNodes={availableNodes}
|
||||
onClose={() => setShowEmailModal(false)}
|
||||
onConfirm={(data) => {
|
||||
handleConfigChange(data)
|
||||
|
|
|
|||
|
|
@ -117,6 +117,15 @@ const MethodSelector: FC<MethodSelectorProps> = ({
|
|||
id: uuid4(),
|
||||
type: DeliveryMethodType.Email,
|
||||
enabled: false,
|
||||
config: {
|
||||
body: '{{#url#}}',
|
||||
recipients: {
|
||||
whole_workspace: false,
|
||||
items: [],
|
||||
},
|
||||
subject: '',
|
||||
debug_mode: false,
|
||||
},
|
||||
})
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ const EmailSenderModal = ({
|
|||
const accounts = members?.accounts || []
|
||||
|
||||
const generatedInputs = useMemo(() => {
|
||||
const valueSelectors = doGetInputVars(formContent || '')
|
||||
const valueSelectors = doGetInputVars((formContent || '') + (config?.body || ''))
|
||||
const variables = unionBy(valueSelectors, item => item.join('.')).map((item) => {
|
||||
const varInfo = getNodeInfoById(availableNodes, item[0])?.data
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ const EmailSenderModal = ({
|
|||
}
|
||||
})
|
||||
return varInputs
|
||||
}, [availableNodes, formContent, nodesOutputVars])
|
||||
}, [availableNodes, config?.body, formContent, nodesOutputVars])
|
||||
|
||||
const [inputs, setInputs] = useState<Record<string, any>>({})
|
||||
const [collapsed, setCollapsed] = useState(true)
|
||||
|
|
|
|||
|
|
@ -3395,16 +3395,6 @@
|
|||
"count": 5
|
||||
}
|
||||
},
|
||||
"app/components/workflow/nodes/human-input/components/delivery-method/email-configure-modal.tsx": {
|
||||
"ts/no-explicit-any": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"app/components/workflow/nodes/human-input/components/delivery-method/method-item.tsx": {
|
||||
"ts/no-explicit-any": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"app/components/workflow/nodes/human-input/components/delivery-method/recipient/email-input.tsx": {
|
||||
"ts/no-explicit-any": {
|
||||
"count": 2
|
||||
|
|
|
|||
Loading…
Reference in New Issue