diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.tsx index d07960b5f7..7d749fd8bf 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.tsx @@ -284,19 +284,18 @@ export const CommonCreateModal = ({ onClose, createType, builder }: Props) => { subscriptionBuilderId: subscriptionBuilder.id, name: subscriptionNameValue, parameters: autoCommonParametersFormValues.values, - // properties: formValues.values, }, { onSuccess: () => { Toast.notify({ type: 'success', - message: 'Subscription created successfully', + message: t('pluginTrigger.subscription.createSuccess'), }) onClose() refresh?.() }, onError: async (error: any) => { - const errorMessage = await parsePluginErrorMessage(error) || t('pluginTrigger.modal.errors.createFailed') + const errorMessage = await parsePluginErrorMessage(error) || t('pluginTrigger.subscription.createFailed') Toast.notify({ type: 'error', message: errorMessage, diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx index 3c3f3f9c16..9896234c61 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/index.tsx @@ -1,4 +1,4 @@ -import { ActionButton } from '@/app/components/base/action-button' +import { ActionButton, ActionButtonState } from '@/app/components/base/action-button' import Badge from '@/app/components/base/badge' import { Button } from '@/app/components/base/button' import type { Option } from '@/app/components/base/select/custom' @@ -15,6 +15,7 @@ import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { SupportedCreationMethods } from '../../../types' import { usePluginStore } from '../store' +import { useSubscriptionList } from '../use-subscription-list' import { CommonCreateModal } from './common-modal' import { OAuthClientSettingsModal } from './oauth-client' @@ -29,10 +30,14 @@ type Props = { shape?: 'square' | 'circle' } +const MAX_COUNT = 10 + export const DEFAULT_METHOD = 'default' export const CreateSubscriptionButton = ({ buttonType = CreateButtonType.FULL_BUTTON, shape = 'square' }: Props) => { const { t } = useTranslation() + const { subscriptions } = useSubscriptionList() + const subscriptionCount = subscriptions?.length || 0 const [selectedCreateInfo, setSelectedCreateInfo] = useState<{ type: SupportedCreationMethods, builder?: TriggerSubscriptionBuilder } | null>(null) const detail = usePluginStore(state => state.detail) @@ -74,12 +79,16 @@ export const CreateSubscriptionButton = ({ buttonType = CreateButtonType.FULL_BU tag: !showCustomBadge ? null : {t('plugin.auth.custom')} , - extra: , + extra: + + + + , show: supportedMethods.includes(SupportedCreationMethods.OAUTH), }, { value: SupportedCreationMethods.APIKEY, - label: t('pluginTrigger.subscription.addType.options.apiKey.title'), + label: t('pluginTrigger.subscription.addType.options.apikey.title'), show: supportedMethods.includes(SupportedCreationMethods.APIKEY), }, { @@ -124,7 +133,12 @@ export const CreateSubscriptionButton = ({ buttonType = CreateButtonType.FULL_BU } const onClickCreate = (e: React.MouseEvent) => { - if (methodType === DEFAULT_METHOD) + if (subscriptionCount >= MAX_COUNT) { + e.stopPropagation() + return + } + + if (methodType === DEFAULT_METHOD || (methodType === SupportedCreationMethods.OAUTH && supportedMethods.length === 1)) return e.stopPropagation() @@ -141,7 +155,7 @@ export const CreateSubscriptionButton = ({ buttonType = CreateButtonType.FULL_BU value={methodType} onChange={value => onChooseCreateType(value as any)} containerProps={{ - open: methodType === DEFAULT_METHOD ? undefined : false, + open: (methodType === DEFAULT_METHOD || (methodType === SupportedCreationMethods.OAUTH && supportedMethods.length === 1)) ? undefined : false, placement: 'bottom-start', offset: 4, triggerPopupSameWidth: buttonType === CreateButtonType.FULL_BUTTON, @@ -157,32 +171,44 @@ export const CreateSubscriptionButton = ({ buttonType = CreateButtonType.FULL_BU - - {buttonTextMap[methodType]} - {methodType === SupportedCreationMethods.OAUTH && oauthConfig?.custom_enabled && oauthConfig?.custom_configured && - {t('plugin.auth.custom')} - } + + + {buttonTextMap[methodType]} + {methodType === SupportedCreationMethods.OAUTH && oauthConfig?.custom_enabled && oauthConfig?.custom_configured && + {t('plugin.auth.custom')} + } + {methodType === SupportedCreationMethods.OAUTH - && - - + && + + + + + + + } ) : ( - - - + = MAX_COUNT ? t('pluginTrigger.subscription.maxCount', { num: MAX_COUNT }) : t(`pluginTrigger.subscription.addType.options.${methodType.toLowerCase()}.description`)} + disabled={!(supportedMethods?.length === 1 || subscriptionCount >= MAX_COUNT)}> + = MAX_COUNT ? ActionButtonState.Disabled : ActionButtonState.Default} + > + + + ) }} CustomOption={option => ( diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/type-dropdown.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/type-dropdown.tsx index 151d840107..9e360095dc 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/create/type-dropdown.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/create/type-dropdown.tsx @@ -44,7 +44,7 @@ export const CreateTypeDropdown = ({ onSelect, onClose, position = 'bottom', cla }, { key: SupportedCreationMethods.APIKEY, - title: t('pluginTrigger.subscription.addType.options.apiKey.title'), + title: t('pluginTrigger.subscription.addType.options.apikey.title'), show: supportedMethods.includes(SupportedCreationMethods.APIKEY), }, { diff --git a/web/app/components/plugins/plugin-detail-panel/subscription-list/delete-confirm.tsx b/web/app/components/plugins/plugin-detail-panel/subscription-list/delete-confirm.tsx index ced7dd7994..95455b6e5c 100644 --- a/web/app/components/plugins/plugin-detail-panel/subscription-list/delete-confirm.tsx +++ b/web/app/components/plugins/plugin-detail-panel/subscription-list/delete-confirm.tsx @@ -37,7 +37,7 @@ export const DeleteConfirm = (props: Props) => { onSuccess: () => { Toast.notify({ type: 'success', - message: t(`${tPrefix}.title`, { name: currentName }), + message: t(`${tPrefix}.success`, { name: currentName }), className: 'z-[10000001]', }) refresh?.() @@ -46,7 +46,7 @@ export const DeleteConfirm = (props: Props) => { onError: (error: any) => { Toast.notify({ type: 'error', - message: error?.message || 'Failed to delete subscription', + message: error?.message || t(`${tPrefix}.error`, { name: currentName }), className: 'z-[10000001]', }) }, diff --git a/web/i18n/en-US/plugin-trigger.ts b/web/i18n/en-US/plugin-trigger.ts index 7078e6c054..e8eebca6db 100644 --- a/web/i18n/en-US/plugin-trigger.ts +++ b/web/i18n/en-US/plugin-trigger.ts @@ -12,6 +12,9 @@ const translation = { apiKey: 'New subscription with API Key', manual: 'Paste URL to create a new subscription', }, + createSuccess: 'Subscription created successfully', + createFailed: 'Failed to create subscription', + maxCount: 'Max {{num}} subscriptions', list: { title: 'Subscriptions', addButton: 'Add', @@ -28,6 +31,8 @@ const translation = { delete: 'Delete', deleteConfirm: { title: 'Delete {{name}}?', + success: 'Subscription {{name}} deleted successfully', + error: 'Failed to delete subscription {{name}}', content: 'Once deleted, this subscription cannot be recovered. Please confirm.', contentWithApps: 'The current subscription is referenced by {{count}} applications. Deleting it will cause the configured applications to stop receiving subscription events.', confirm: 'Confirm Delete', @@ -49,13 +54,14 @@ const translation = { title: 'Add subscription', description: 'Choose how you want to create your trigger subscription', options: { - apiKey: { + apikey: { title: 'Via API Key', description: 'Automatically create subscription using API credentials', }, oauth: { title: 'Via OAuth', description: 'Authorize with third-party platform to create subscription', + clientSettings: 'OAuth Client Settings', }, manual: { title: 'Manual Setup', @@ -164,12 +170,6 @@ const translation = { parameters: '{{count}} parameters', }, }, - provider: { - github: 'GitHub', - gitlab: 'GitLab', - notion: 'Notion', - webhook: 'Webhook', - }, } export default translation diff --git a/web/i18n/zh-Hans/plugin-trigger.ts b/web/i18n/zh-Hans/plugin-trigger.ts index 8c5a309feb..34e1c8bac9 100644 --- a/web/i18n/zh-Hans/plugin-trigger.ts +++ b/web/i18n/zh-Hans/plugin-trigger.ts @@ -12,6 +12,9 @@ const translation = { apiKey: '通过 API Key 新建订阅', manual: '粘贴 URL 以创建新订阅', }, + createSuccess: '订阅创建成功', + createFailed: '订阅创建失败', + maxCount: '最多 {{num}} 个订阅', list: { title: '订阅列表', addButton: '添加', @@ -27,7 +30,9 @@ const translation = { actions: { delete: '删除', deleteConfirm: { - title: '删除 {{name}} ?', + title: '删除 {{name}}?', + success: '订阅 {{name}} 删除成功', + error: '订阅 {{name}} 删除失败', content: '删除后,该订阅将无法恢复,请确认。', contentWithApps: '该订阅正在被 {{count}} 个应用使用,删除它将导致这些应用停止接收订阅事件。', confirm: '确认删除', @@ -49,13 +54,14 @@ const translation = { title: '添加订阅', description: '选择创建触发器订阅的方式', options: { - apiKey: { + apikey: { title: '通过 API Key', - description: '使用API凭据自动创建订阅', + description: '使用 API 凭据自动创建订阅', }, oauth: { title: '通过 OAuth', description: '与第三方平台授权以创建订阅', + clientSettings: 'OAuth 客户端设置', }, manual: { title: '手动设置', @@ -164,12 +170,6 @@ const translation = { parameters: '{{count}}个参数', }, }, - provider: { - github: 'GitHub', - gitlab: 'GitLab', - notion: 'Notion', - webhook: 'Webhook', - }, } export default translation