mirror of https://github.com/langgenius/dify.git
feat: add humanInputEmailDeliveryEnabled to provider context and update related components for email delivery handling
This commit is contained in:
parent
88c2483192
commit
61c7fdc614
|
|
@ -35,6 +35,7 @@ export const baseProviderContextValue: ProviderContextState = {
|
|||
refreshLicenseLimit: noop,
|
||||
isAllowTransferWorkspace: false,
|
||||
isAllowPublishAsCustomKnowledgePipelineTemplate: false,
|
||||
humanInputEmailDeliveryEnabled: false,
|
||||
}
|
||||
|
||||
export const createMockProviderContextValue = (overrides: Partial<ProviderContextState> = {}): ProviderContextState => {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ const defaultProviderContext = {
|
|||
refreshLicenseLimit: noop,
|
||||
isAllowTransferWorkspace: false,
|
||||
isAllowPublishAsCustomKnowledgePipelineTemplate: false,
|
||||
humanInputEmailDeliveryEnabled: false,
|
||||
}
|
||||
|
||||
const defaultModalContext: ModalContextState = {
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ export type CurrentPlanInfoBackend = {
|
|||
knowledge_pipeline: {
|
||||
publish_enabled: boolean
|
||||
}
|
||||
human_input_email_delivery_enabled: boolean
|
||||
}
|
||||
|
||||
export type SubscriptionItem = {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import {
|
|||
import { getKeyboardKeyCodeBySystem, getKeyboardKeyNameBySystem } from '@/app/components/workflow/utils'
|
||||
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
|
||||
import { useModalContextSelector } from '@/context/modal-context'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import { useProviderContextSelector } from '@/context/provider-context'
|
||||
import { useDatasetApiAccessUrl } from '@/hooks/use-api-access-url'
|
||||
import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now'
|
||||
import { useInvalidDatasetList } from '@/service/knowledge/use-dataset'
|
||||
|
|
@ -65,7 +65,7 @@ const Popup = () => {
|
|||
const { mutateAsync: publishWorkflow } = usePublishWorkflow()
|
||||
const { notify } = useToastContext()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const { isAllowPublishAsCustomKnowledgePipelineTemplate } = useProviderContext()
|
||||
const isAllowPublishAsCustomKnowledgePipelineTemplate = useProviderContextSelector(s => s.isAllowPublishAsCustomKnowledgePipelineTemplate)
|
||||
const setShowPricingModal = useModalContextSelector(s => s.setShowPricingModal)
|
||||
const apiReferenceUrl = useDatasetApiAccessUrl()
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ const Popup = () => {
|
|||
if (confirmVisible)
|
||||
hideConfirm()
|
||||
}
|
||||
}, [handleCheckBeforePublish, publishWorkflow, pipelineId, notify, t, workflowStore, mutateDatasetRes, invalidPublishedPipelineInfo, showConfirm, publishedAt, confirmVisible, hidePublishing, showPublishing, hideConfirm, publishing])
|
||||
}, [publishing, handleCheckBeforePublish, publishedAt, confirmVisible, showPublishing, publishWorkflow, pipelineId, datasetId, showConfirm, notify, t, workflowStore, mutateDatasetRes, invalidPublishedPipelineInfo, invalidDatasetList, hidePublishing, hideConfirm])
|
||||
|
||||
useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.shift.p`, (e) => {
|
||||
e.preventDefault()
|
||||
|
|
@ -204,15 +204,7 @@ const Popup = () => {
|
|||
hidePublishingAsCustomizedPipeline()
|
||||
hidePublishAsKnowledgePipelineModal()
|
||||
}
|
||||
}, [
|
||||
pipelineId,
|
||||
publishAsCustomizedPipeline,
|
||||
showPublishingAsCustomizedPipeline,
|
||||
hidePublishingAsCustomizedPipeline,
|
||||
hidePublishAsKnowledgePipelineModal,
|
||||
notify,
|
||||
t,
|
||||
])
|
||||
}, [showPublishingAsCustomizedPipeline, publishAsCustomizedPipeline, pipelineId, notify, t, invalidCustomizedTemplateList, hidePublishingAsCustomizedPipeline, hidePublishAsKnowledgePipelineModal])
|
||||
|
||||
const handleClickPublishAsKnowledgePipeline = useCallback(() => {
|
||||
if (!isAllowPublishAsCustomKnowledgePipelineTemplate)
|
||||
|
|
|
|||
|
|
@ -98,7 +98,9 @@ const DeliveryMethodItem: FC<DeliveryMethodItemProps> = ({
|
|||
</div>
|
||||
)}
|
||||
<div className="system-xs-medium capitalize text-text-secondary">{method.type}</div>
|
||||
{method.type === DeliveryMethodType.Email && (method.config as EmailConfig)?.debug_mode && <Badge size="s" className="!px-1 !py-0.5">DEBUG</Badge>}
|
||||
{method.type === DeliveryMethodType.Email
|
||||
&& (method.config as EmailConfig)?.debug_mode
|
||||
&& <Badge size="s" className="!px-1 !py-0.5">DEBUG</Badge>}
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
{!readonly && (
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ import {
|
|||
RiMailSendFill,
|
||||
RiRobot2Fill,
|
||||
} from '@remixicon/react'
|
||||
import * as React from 'react'
|
||||
import { useCallback, useRef, useState } from 'react'
|
||||
import { memo, useCallback, useMemo, useRef, useState } from 'react'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import { v4 as uuid4 } from 'uuid'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
|
|
@ -21,23 +20,26 @@ import {
|
|||
PortalToFollowElemTrigger,
|
||||
} from '@/app/components/base/portal-to-follow-elem'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import { useProviderContextSelector } from '@/context/provider-context'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { DeliveryMethodType } from '../../types'
|
||||
|
||||
const i18nPrefix = 'nodes.humanInput'
|
||||
|
||||
type Props = {
|
||||
type MethodSelectorProps = {
|
||||
data: DeliveryMethod[]
|
||||
onAdd: (method: DeliveryMethod) => void
|
||||
}
|
||||
|
||||
const MethodSelector: FC<Props> = ({
|
||||
const MethodSelector: FC<MethodSelectorProps> = ({
|
||||
data,
|
||||
onAdd,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [open, doSetOpen] = useState(false)
|
||||
const humanInputEmailDeliveryEnabled = useProviderContextSelector(s => s.humanInputEmailDeliveryEnabled)
|
||||
const openRef = useRef(open)
|
||||
|
||||
const setOpen = useCallback((v: boolean) => {
|
||||
doSetOpen(v)
|
||||
openRef.current = v
|
||||
|
|
@ -47,6 +49,13 @@ const MethodSelector: FC<Props> = ({
|
|||
setOpen(!openRef.current)
|
||||
}, [setOpen])
|
||||
|
||||
const emailDeliveryInfo = useMemo(() => {
|
||||
return {
|
||||
noPermission: !humanInputEmailDeliveryEnabled,
|
||||
added: data.some(method => method.type === DeliveryMethodType.Email),
|
||||
}
|
||||
}, [data, humanInputEmailDeliveryEnabled])
|
||||
|
||||
return (
|
||||
<PortalToFollowElem
|
||||
open={open}
|
||||
|
|
@ -91,9 +100,12 @@ const MethodSelector: FC<Props> = ({
|
|||
)}
|
||||
</div>
|
||||
<div
|
||||
className={cn('relative flex cursor-pointer items-center gap-1 rounded-lg p-1 pl-3 hover:bg-state-base-hover', data.some(method => method.type === DeliveryMethodType.Email) && 'cursor-not-allowed bg-transparent hover:bg-transparent')}
|
||||
className={cn(
|
||||
'relative flex cursor-pointer items-center gap-1 rounded-lg p-1 pl-3 hover:bg-state-base-hover',
|
||||
(emailDeliveryInfo.noPermission || emailDeliveryInfo.added) && 'cursor-not-allowed bg-transparent hover:bg-transparent',
|
||||
)}
|
||||
onClick={() => {
|
||||
if (data.some(method => method.type === DeliveryMethodType.Email))
|
||||
if (emailDeliveryInfo.noPermission || emailDeliveryInfo.added)
|
||||
return
|
||||
onAdd({
|
||||
id: uuid4(),
|
||||
|
|
@ -102,16 +114,24 @@ const MethodSelector: FC<Props> = ({
|
|||
})
|
||||
}}
|
||||
>
|
||||
<div className={cn('rounded-[4px] border border-divider-regular bg-components-icon-bg-blue-solid p-1', data.some(method => method.type === DeliveryMethodType.Email) && 'opacity-50')}>
|
||||
<div
|
||||
className={cn(
|
||||
'rounded-[4px] border border-divider-regular bg-components-icon-bg-blue-solid p-1',
|
||||
(emailDeliveryInfo.noPermission || emailDeliveryInfo.added) && 'opacity-50',
|
||||
)}
|
||||
>
|
||||
<RiMailSendFill className="h-4 w-4 text-text-primary-on-surface" />
|
||||
</div>
|
||||
<div className={cn('p-1', data.some(method => method.type === DeliveryMethodType.Email) && 'opacity-50')}>
|
||||
<div className={cn('p-1', (emailDeliveryInfo.noPermission || emailDeliveryInfo.added) && 'opacity-50')}>
|
||||
<div className="system-sm-medium mb-0.5 truncate text-text-primary">{t(`${i18nPrefix}.deliveryMethod.types.email.title`, { ns: 'workflow' })}</div>
|
||||
<div className="system-xs-regular truncate text-text-tertiary">{t(`${i18nPrefix}.deliveryMethod.types.email.description`, { ns: 'workflow' })}</div>
|
||||
</div>
|
||||
{data.some(method => method.type === DeliveryMethodType.Email) && (
|
||||
{emailDeliveryInfo.added && (
|
||||
<div className="system-xs-regular absolute right-[12px] top-[13px] text-text-tertiary">{t(`${i18nPrefix}.deliveryMethod.added`, { ns: 'workflow' })}</div>
|
||||
)}
|
||||
{emailDeliveryInfo.noPermission && (
|
||||
<div className="system-xs-regular absolute right-[12px] top-[13px] text-text-tertiary">Upgrade</div>
|
||||
)}
|
||||
</div>
|
||||
{/* Slack */}
|
||||
<div
|
||||
|
|
@ -181,4 +201,4 @@ const MethodSelector: FC<Props> = ({
|
|||
</PortalToFollowElem>
|
||||
)
|
||||
}
|
||||
export default React.memo(MethodSelector)
|
||||
export default memo(MethodSelector)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ export type ProviderContextState = {
|
|||
refreshLicenseLimit: () => void
|
||||
isAllowTransferWorkspace: boolean
|
||||
isAllowPublishAsCustomKnowledgePipelineTemplate: boolean
|
||||
humanInputEmailDeliveryEnabled: boolean
|
||||
}
|
||||
|
||||
export const baseProviderContextValue: ProviderContextState = {
|
||||
|
|
@ -96,6 +97,7 @@ export const baseProviderContextValue: ProviderContextState = {
|
|||
refreshLicenseLimit: noop,
|
||||
isAllowTransferWorkspace: false,
|
||||
isAllowPublishAsCustomKnowledgePipelineTemplate: false,
|
||||
humanInputEmailDeliveryEnabled: false,
|
||||
}
|
||||
|
||||
const ProviderContext = createContext<ProviderContextState>(baseProviderContextValue)
|
||||
|
|
@ -137,6 +139,7 @@ export const ProviderContextProvider = ({
|
|||
const { data: educationAccountInfo, isLoading: isLoadingEducationAccountInfo, isFetching: isFetchingEducationAccountInfo, isFetchedAfterMount: isEducationDataFetchedAfterMount } = useEducationStatus(!enableEducationPlan)
|
||||
const [isAllowTransferWorkspace, setIsAllowTransferWorkspace] = useState(false)
|
||||
const [isAllowPublishAsCustomKnowledgePipelineTemplate, setIsAllowPublishAsCustomKnowledgePipelineTemplate] = useState(false)
|
||||
const [humanInputEmailDeliveryEnabled, setHumanInputEmailDeliveryEnabled] = useState(false)
|
||||
|
||||
const refreshModelProviders = () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['common', 'model-providers'] })
|
||||
|
|
@ -173,6 +176,8 @@ export const ProviderContextProvider = ({
|
|||
setIsAllowTransferWorkspace(data.is_allow_transfer_workspace)
|
||||
if (data.knowledge_pipeline?.publish_enabled)
|
||||
setIsAllowPublishAsCustomKnowledgePipelineTemplate(data.knowledge_pipeline?.publish_enabled)
|
||||
if (data.human_input_email_delivery_enabled)
|
||||
setHumanInputEmailDeliveryEnabled(data.human_input_email_delivery_enabled)
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Failed to fetch plan info:', error)
|
||||
|
|
@ -250,6 +255,7 @@ export const ProviderContextProvider = ({
|
|||
refreshLicenseLimit: fetchPlan,
|
||||
isAllowTransferWorkspace,
|
||||
isAllowPublishAsCustomKnowledgePipelineTemplate,
|
||||
humanInputEmailDeliveryEnabled,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
Loading…
Reference in New Issue