feat: introduce trigger functionality (#27644)
Signed-off-by: lyzno1 <yuanyouhuilyz@gmail.com> Co-authored-by: Stream <Stream_2@qq.com> Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com> Co-authored-by: zhsama <torvalds@linux.do> Co-authored-by: Harry <xh001x@hotmail.com> Co-authored-by: lyzno1 <yuanyouhuilyz@gmail.com> Co-authored-by: yessenia <yessenia.contact@gmail.com> Co-authored-by: hjlarry <hjlarry@163.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: WTW0313 <twwu@dify.ai> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -13,7 +13,7 @@ import CopyFeedback from '@/app/components/base/copy-feedback'
|
||||
import Confirm from '@/app/components/base/confirm'
|
||||
import type { AppDetailResponse } from '@/models/app'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import type { AppSSO } from '@/types/app'
|
||||
import { AppModeEnum, type AppSSO } from '@/types/app'
|
||||
import Indicator from '@/app/components/header/indicator'
|
||||
import MCPServerModal from '@/app/components/tools/mcp/mcp-server-modal'
|
||||
import { useAppWorkflow } from '@/service/use-workflow'
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import cn from '@/utils/classnames'
|
||||
import { fetchAppDetail } from '@/service/apps'
|
||||
import { useDocLink } from '@/context/i18n'
|
||||
|
||||
export type IAppCardProps = {
|
||||
appInfo: AppDetailResponse & Partial<AppSSO>
|
||||
@@ -35,6 +36,7 @@ function MCPServiceCard({
|
||||
appInfo,
|
||||
}: IAppCardProps) {
|
||||
const { t } = useTranslation()
|
||||
const docLink = useDocLink()
|
||||
const appId = appInfo.id
|
||||
const { mutateAsync: updateMCPServer } = useUpdateMCPServer()
|
||||
const { mutateAsync: refreshMCPServerCode, isPending: genLoading } = useRefreshMCPServerCode()
|
||||
@@ -43,7 +45,7 @@ function MCPServiceCard({
|
||||
const [showConfirmDelete, setShowConfirmDelete] = useState(false)
|
||||
const [showMCPServerModal, setShowMCPServerModal] = useState(false)
|
||||
|
||||
const isAdvancedApp = appInfo?.mode === 'advanced-chat' || appInfo?.mode === 'workflow'
|
||||
const isAdvancedApp = appInfo?.mode === AppModeEnum.ADVANCED_CHAT || appInfo?.mode === AppModeEnum.WORKFLOW
|
||||
const isBasicApp = !isAdvancedApp
|
||||
const { data: currentWorkflow } = useAppWorkflow(isAdvancedApp ? appId : '')
|
||||
const [basicAppConfig, setBasicAppConfig] = useState<any>({})
|
||||
@@ -69,11 +71,16 @@ function MCPServiceCard({
|
||||
const { data: detail } = useMCPServerDetail(appId)
|
||||
const { id, status, server_code } = detail ?? {}
|
||||
|
||||
const isWorkflowApp = appInfo.mode === AppModeEnum.WORKFLOW
|
||||
const appUnpublished = isAdvancedApp ? !currentWorkflow?.graph : !basicAppConfig.updated_at
|
||||
const serverPublished = !!id
|
||||
const serverActivated = status === 'active'
|
||||
const serverURL = serverPublished ? `${appInfo.api_base_url.replace('/v1', '')}/mcp/server/${server_code}/mcp` : '***********'
|
||||
const toggleDisabled = !isCurrentWorkspaceEditor || appUnpublished
|
||||
const hasStartNode = currentWorkflow?.graph?.nodes?.some(node => node.data.type === BlockEnum.Start)
|
||||
const missingStartNode = isWorkflowApp && !hasStartNode
|
||||
const hasInsufficientPermissions = !isCurrentWorkspaceEditor
|
||||
const toggleDisabled = hasInsufficientPermissions || appUnpublished || missingStartNode
|
||||
const isMinimalState = appUnpublished || missingStartNode
|
||||
|
||||
const [activated, setActivated] = useState(serverActivated)
|
||||
|
||||
@@ -136,12 +143,12 @@ function MCPServiceCard({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={cn('w-full max-w-full rounded-xl border-l-[0.5px] border-t border-effects-highlight')}>
|
||||
<div className={cn('w-full max-w-full rounded-xl border-l-[0.5px] border-t border-effects-highlight', isMinimalState && 'h-12')}>
|
||||
<div className='rounded-xl bg-background-default'>
|
||||
<div className='flex w-full flex-col items-start justify-center gap-3 self-stretch border-b-[0.5px] border-divider-subtle p-3'>
|
||||
<div className={cn('flex w-full flex-col items-start justify-center gap-3 self-stretch p-3', isMinimalState ? 'border-0' : 'border-b-[0.5px] border-divider-subtle')}>
|
||||
<div className='flex w-full items-center gap-3 self-stretch'>
|
||||
<div className='flex grow items-center'>
|
||||
<div className='mr-3 shrink-0 rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-indigo-indigo-500 p-1 shadow-md'>
|
||||
<div className='mr-2 shrink-0 rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-blue-brand-blue-brand-500 p-1 shadow-md'>
|
||||
<Mcp className='h-4 w-4 text-text-primary-on-surface' />
|
||||
</div>
|
||||
<div className="group w-full">
|
||||
@@ -159,61 +166,86 @@ function MCPServiceCard({
|
||||
</div>
|
||||
</div>
|
||||
<Tooltip
|
||||
popupContent={appUnpublished ? t('tools.mcp.server.publishTip') : ''}
|
||||
popupContent={
|
||||
toggleDisabled ? (
|
||||
appUnpublished ? (
|
||||
t('tools.mcp.server.publishTip')
|
||||
) : missingStartNode ? (
|
||||
<>
|
||||
<div className="mb-1 text-xs font-normal text-text-secondary">
|
||||
{t('appOverview.overview.appInfo.enableTooltip.description')}
|
||||
</div>
|
||||
<div
|
||||
className="cursor-pointer text-xs font-normal text-text-accent hover:underline"
|
||||
onClick={() => window.open(docLink('/guides/workflow/node/user-input'), '_blank')}
|
||||
>
|
||||
{t('appOverview.overview.appInfo.enableTooltip.learnMore')}
|
||||
</div>
|
||||
</>
|
||||
) : ''
|
||||
) : ''
|
||||
}
|
||||
position="right"
|
||||
popupClassName="w-58 max-w-60 rounded-xl bg-components-panel-bg px-3.5 py-3 shadow-lg"
|
||||
offset={24}
|
||||
>
|
||||
<div>
|
||||
<Switch defaultValue={activated} onChange={onChangeStatus} disabled={toggleDisabled} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className='flex flex-col items-start justify-center self-stretch'>
|
||||
<div className="system-xs-medium pb-1 text-text-tertiary">
|
||||
{t('tools.mcp.server.url')}
|
||||
</div>
|
||||
<div className="inline-flex h-9 w-full items-center gap-0.5 rounded-lg bg-components-input-bg-normal p-1 pl-2">
|
||||
<div className="flex h-4 min-w-0 flex-1 items-start justify-start gap-2 px-1">
|
||||
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-xs font-medium text-text-secondary">
|
||||
{serverURL}
|
||||
</div>
|
||||
{!isMinimalState && (
|
||||
<div className='flex flex-col items-start justify-center self-stretch'>
|
||||
<div className="system-xs-medium pb-1 text-text-tertiary">
|
||||
{t('tools.mcp.server.url')}
|
||||
</div>
|
||||
{serverPublished && (
|
||||
<>
|
||||
<CopyFeedback
|
||||
content={serverURL}
|
||||
className={'!size-6'}
|
||||
/>
|
||||
<Divider type="vertical" className="!mx-0.5 !h-3.5 shrink-0" />
|
||||
{isCurrentWorkspaceManager && (
|
||||
<Tooltip
|
||||
popupContent={t('appOverview.overview.appInfo.regenerate') || ''}
|
||||
>
|
||||
<div
|
||||
className="cursor-pointer rounded-md p-1 hover:bg-state-base-hover"
|
||||
onClick={() => setShowConfirmDelete(true)}
|
||||
<div className="inline-flex h-9 w-full items-center gap-0.5 rounded-lg bg-components-input-bg-normal p-1 pl-2">
|
||||
<div className="flex h-4 min-w-0 flex-1 items-start justify-start gap-2 px-1">
|
||||
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-xs font-medium text-text-secondary">
|
||||
{serverURL}
|
||||
</div>
|
||||
</div>
|
||||
{serverPublished && (
|
||||
<>
|
||||
<CopyFeedback
|
||||
content={serverURL}
|
||||
className={'!size-6'}
|
||||
/>
|
||||
<Divider type="vertical" className="!mx-0.5 !h-3.5 shrink-0" />
|
||||
{isCurrentWorkspaceManager && (
|
||||
<Tooltip
|
||||
popupContent={t('appOverview.overview.appInfo.regenerate') || ''}
|
||||
>
|
||||
<RiLoopLeftLine className={cn('h-4 w-4 text-text-tertiary hover:text-text-secondary', genLoading && 'animate-spin')}/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<div
|
||||
className="cursor-pointer rounded-md p-1 hover:bg-state-base-hover"
|
||||
onClick={() => setShowConfirmDelete(true)}
|
||||
>
|
||||
<RiLoopLeftLine className={cn('h-4 w-4 text-text-tertiary hover:text-text-secondary', genLoading && 'animate-spin')}/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className='flex items-center gap-1 self-stretch p-3'>
|
||||
<Button
|
||||
disabled={toggleDisabled}
|
||||
size='small'
|
||||
variant='ghost'
|
||||
onClick={() => setShowMCPServerModal(true)}
|
||||
>
|
||||
{!isMinimalState && (
|
||||
<div className='flex items-center gap-1 self-stretch p-3'>
|
||||
<Button
|
||||
disabled={toggleDisabled}
|
||||
size='small'
|
||||
variant='ghost'
|
||||
onClick={() => setShowMCPServerModal(true)}
|
||||
>
|
||||
|
||||
<div className="flex items-center justify-center gap-[1px]">
|
||||
<RiEditLine className="h-3.5 w-3.5" />
|
||||
<div className="system-xs-medium px-[3px] text-text-tertiary">{serverPublished ? t('tools.mcp.server.edit') : t('tools.mcp.server.addDescription')}</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex items-center justify-center gap-[1px]">
|
||||
<RiEditLine className="h-3.5 w-3.5" />
|
||||
<div className="system-xs-medium px-[3px] text-text-tertiary">{serverPublished ? t('tools.mcp.server.edit') : t('tools.mcp.server.addDescription')}</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{showMCPServerModal && (
|
||||
|
||||
Reference in New Issue
Block a user