mirror of
https://github.com/langgenius/dify.git
synced 2026-04-26 10:16:40 +08:00
167 lines
5.6 KiB
TypeScript
167 lines
5.6 KiB
TypeScript
'use client'
|
|
import React from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { useBoolean } from 'ahooks'
|
|
import {
|
|
RiAddLine,
|
|
RiBookOpenLine,
|
|
RiWebhookLine,
|
|
} from '@remixicon/react'
|
|
import { useDocLink } from '@/context/i18n'
|
|
import SubscriptionCard from './subscription-card'
|
|
import SubscriptionAddModal from './subscription-add-modal'
|
|
import AddTypeDropdown from './add-type-dropdown'
|
|
import ActionButton from '@/app/components/base/action-button'
|
|
import Button from '@/app/components/base/button'
|
|
import Tooltip from '@/app/components/base/tooltip'
|
|
import { useTriggerSubscriptions } from '@/service/use-triggers'
|
|
import type { PluginDetail } from '@/app/components/plugins/types'
|
|
import cn from '@/utils/classnames'
|
|
|
|
type Props = {
|
|
detail: PluginDetail
|
|
}
|
|
|
|
type SubscriptionAddType = 'api-key' | 'oauth' | 'manual'
|
|
|
|
export const SubscriptionList = ({ detail }: Props) => {
|
|
const { t } = useTranslation()
|
|
const docLink = useDocLink()
|
|
const showTopBorder = detail.declaration.tool || detail.declaration.endpoint
|
|
|
|
// Fetch subscriptions
|
|
const { data: subscriptions, isLoading, refetch } = useTriggerSubscriptions(`${detail.plugin_id}/${detail.declaration.name}`)
|
|
|
|
// Modal states
|
|
const [isShowAddModal, {
|
|
setTrue: showAddModal,
|
|
setFalse: hideAddModal,
|
|
}] = useBoolean(false)
|
|
|
|
const [selectedAddType, setSelectedAddType] = React.useState<SubscriptionAddType | null>(null)
|
|
|
|
// Dropdown state for add button
|
|
const [isShowAddDropdown, {
|
|
setTrue: showAddDropdown,
|
|
setFalse: hideAddDropdown,
|
|
}] = useBoolean(false)
|
|
|
|
const handleAddTypeSelect = (type: SubscriptionAddType) => {
|
|
setSelectedAddType(type)
|
|
hideAddDropdown()
|
|
showAddModal()
|
|
}
|
|
|
|
const handleModalClose = () => {
|
|
hideAddModal()
|
|
setSelectedAddType(null)
|
|
}
|
|
|
|
const handleRefreshList = () => {
|
|
refetch()
|
|
}
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className={cn('border-divider-subtle px-4 py-2', showTopBorder && 'border-t')}>
|
|
<div className='flex items-center justify-center py-8'>
|
|
<div className='text-text-tertiary'>{t('common.dataLoading')}</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const hasSubscriptions = subscriptions && subscriptions.length > 0
|
|
|
|
return (
|
|
<div className={cn('border-divider-subtle px-4 py-2', showTopBorder && 'border-t')}>
|
|
{!hasSubscriptions ? (
|
|
<div className='relative w-full'>
|
|
<Button
|
|
variant='primary'
|
|
size='medium'
|
|
className='w-full'
|
|
onClick={showAddDropdown}
|
|
>
|
|
<RiAddLine className='mr-2 h-4 w-4' />
|
|
{t('pluginTrigger.subscription.empty.button')}
|
|
</Button>
|
|
{isShowAddDropdown && (
|
|
<AddTypeDropdown
|
|
onSelect={handleAddTypeSelect}
|
|
onClose={hideAddDropdown}
|
|
position='bottom'
|
|
/>
|
|
)}
|
|
</div>
|
|
) : (
|
|
// List state with header and secondary add button
|
|
<>
|
|
<div className='system-sm-semibold-uppercase mb-3 flex items-center justify-between'>
|
|
<div className='flex items-center gap-1'>
|
|
<span className='system-sm-semibold text-text-secondary'>
|
|
{t('pluginTrigger.subscription.listNum', { num: subscriptions?.length || 0 })}
|
|
</span>
|
|
<Tooltip
|
|
position='right'
|
|
popupClassName='w-[240px] p-4 rounded-xl bg-components-panel-bg-blur border-[0.5px] border-components-panel-border'
|
|
popupContent={
|
|
<div className='flex flex-col gap-2'>
|
|
<div className='flex h-8 w-8 items-center justify-center rounded-lg border-[0.5px] border-components-panel-border-subtle bg-background-default-subtle'>
|
|
<RiWebhookLine className='h-4 w-4 text-text-tertiary' />
|
|
</div>
|
|
<div className='system-xs-regular text-text-tertiary'>
|
|
{t('pluginTrigger.subscription.list.tooltip')}
|
|
</div>
|
|
<a
|
|
href={docLink('/plugins/schema-definition/trigger')}
|
|
target='_blank'
|
|
rel='noopener noreferrer'
|
|
>
|
|
<div className='system-xs-regular inline-flex cursor-pointer items-center gap-1 text-text-accent'>
|
|
<RiBookOpenLine className='h-3 w-3' />
|
|
{t('pluginTrigger.subscription.list.tooltip.viewDocument')}
|
|
</div>
|
|
</a>
|
|
</div>
|
|
}
|
|
/>
|
|
</div>
|
|
<div className='relative'>
|
|
<ActionButton onClick={showAddDropdown}>
|
|
<RiAddLine className='h-4 w-4' />
|
|
</ActionButton>
|
|
{isShowAddDropdown && (
|
|
<AddTypeDropdown
|
|
onSelect={handleAddTypeSelect}
|
|
onClose={hideAddDropdown}
|
|
position='right'
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className='flex flex-col gap-1'>
|
|
{subscriptions?.map(subscription => (
|
|
<SubscriptionCard
|
|
key={subscription.id}
|
|
data={subscription}
|
|
onRefresh={handleRefreshList}
|
|
/>
|
|
))}
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{isShowAddModal && selectedAddType && (
|
|
<SubscriptionAddModal
|
|
type={selectedAddType}
|
|
pluginDetail={detail}
|
|
onClose={handleModalClose}
|
|
onSuccess={handleRefreshList}
|
|
/>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|