mirror of
https://github.com/langgenius/dify.git
synced 2026-01-08 07:14:14 +00:00
feat: change subscription field
This commit is contained in:
@@ -196,7 +196,7 @@ const BaseField = ({
|
||||
)
|
||||
}
|
||||
{
|
||||
formItemType === FormTypeEnum.select && multiple && (
|
||||
formItemType === FormTypeEnum.checkbox /* && multiple */ && (
|
||||
<CheckboxList
|
||||
title={name}
|
||||
value={value}
|
||||
|
||||
@@ -52,6 +52,7 @@ export type FormSchema = {
|
||||
required: boolean
|
||||
multiple?: boolean
|
||||
default?: any
|
||||
description?: string | TypeWithI18N | Record<Locale, string>
|
||||
tooltip?: string | TypeWithI18N | Record<Locale, string>
|
||||
show_on?: FormShowOnObject[]
|
||||
url?: string
|
||||
|
||||
@@ -55,8 +55,8 @@ const Modal = ({
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'max-h-[80%] w-[480px] overflow-y-auto rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xs',
|
||||
size === 'sm' && 'w-[480px',
|
||||
'max-h-[80%] overflow-y-auto rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xs',
|
||||
size === 'sm' && 'w-[480px]',
|
||||
size === 'md' && 'w-[640px]',
|
||||
)}
|
||||
onClick={e => e.stopPropagation()}
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
useVerifyTriggerSubscriptionBuilder,
|
||||
} from '@/service/use-triggers'
|
||||
import { RiLoader2Line } from '@remixicon/react'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import LogViewer from '../log-viewer'
|
||||
import { usePluginStore, usePluginSubscriptionStore } from '../store'
|
||||
@@ -67,55 +67,65 @@ export const CommonCreateModal = ({ onClose, createType, builder }: Props) => {
|
||||
|
||||
const [subscriptionBuilder, setSubscriptionBuilder] = useState<TriggerSubscriptionBuilder | undefined>(builder)
|
||||
const [verificationError, setVerificationError] = useState<string>('')
|
||||
const isInitializedRef = useRef(false)
|
||||
|
||||
const { mutate: verifyCredentials, isPending: isVerifyingCredentials } = useVerifyTriggerSubscriptionBuilder()
|
||||
const { mutate: createBuilder /* isPending: isCreatingBuilder */ } = useCreateTriggerSubscriptionBuilder()
|
||||
const { mutateAsync: createBuilder /* isPending: isCreatingBuilder */ } = useCreateTriggerSubscriptionBuilder()
|
||||
const { mutate: buildSubscription, isPending: isBuilding } = useBuildTriggerSubscription()
|
||||
|
||||
const propertiesSchema = detail?.declaration.trigger.subscription_schema.properties_schema || [] // manual
|
||||
const manualPropertiesSchema = detail?.declaration.trigger.subscription_schema || [] // manual
|
||||
const manualPropertiesFormRef = React.useRef<FormRefObject>(null)
|
||||
|
||||
const subscriptionFormRef = React.useRef<FormRefObject>(null)
|
||||
const propertiesFormRef = React.useRef<FormRefObject>(null)
|
||||
const parametersSchema = detail?.declaration.trigger?.subscription_schema?.parameters_schema || [] // apikey and oauth
|
||||
const parametersFormRef = React.useRef<FormRefObject>(null)
|
||||
const credentialsSchema = detail?.declaration.trigger?.credentials_schema || []
|
||||
const credentialsFormRef = React.useRef<FormRefObject>(null)
|
||||
|
||||
const autoCommonParametersSchema = detail?.declaration.trigger?.subscription_constructor?.parameters || [] // apikey and oauth
|
||||
const autoCommonParametersFormRef = React.useRef<FormRefObject>(null)
|
||||
|
||||
const apiKeyCredentialsSchema = detail?.declaration.trigger?.subscription_constructor?.credentials_schema || []
|
||||
const apiKeyCredentialsFormRef = React.useRef<FormRefObject>(null)
|
||||
|
||||
const { data: logData } = useTriggerSubscriptionBuilderLogs(
|
||||
detail?.provider || '',
|
||||
subscriptionBuilder?.id || '',
|
||||
{
|
||||
enabled: createType === SupportedCreationMethods.MANUAL && !!subscriptionBuilder?.id,
|
||||
enabled: createType === SupportedCreationMethods.MANUAL,
|
||||
refetchInterval: 3000,
|
||||
},
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (!subscriptionBuilder) {
|
||||
createBuilder(
|
||||
{
|
||||
const initializeBuilder = async () => {
|
||||
isInitializedRef.current = true
|
||||
try {
|
||||
const response = await createBuilder({
|
||||
provider: detail?.provider || '',
|
||||
credential_type: CREDENTIAL_TYPE_MAP[createType],
|
||||
},
|
||||
{
|
||||
onSuccess: (response) => {
|
||||
const builder = response.subscription_builder
|
||||
setSubscriptionBuilder(builder)
|
||||
},
|
||||
onError: (error) => {
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: t('pluginTrigger.modal.errors.createFailed'),
|
||||
})
|
||||
console.error('Failed to create subscription builder:', error)
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
setSubscriptionBuilder(response.subscription_builder)
|
||||
}
|
||||
catch (error) {
|
||||
console.error('createBuilder error:', error)
|
||||
Toast.notify({
|
||||
type: 'error',
|
||||
message: t('pluginTrigger.modal.errors.createFailed'),
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [createBuilder, detail?.provider, subscriptionBuilder, t])
|
||||
if (!isInitializedRef.current && !subscriptionBuilder && detail?.provider)
|
||||
initializeBuilder()
|
||||
}, [subscriptionBuilder, detail?.provider, createType, createBuilder, t])
|
||||
|
||||
useEffect(() => {
|
||||
if (subscriptionBuilder?.endpoint && subscriptionFormRef.current) {
|
||||
const form = subscriptionFormRef.current.getForm()
|
||||
if (form)
|
||||
form.setFieldValue('callback_url', subscriptionBuilder.endpoint)
|
||||
}
|
||||
}, [subscriptionBuilder?.endpoint])
|
||||
|
||||
const handleVerify = () => {
|
||||
const credentialsFormValues = credentialsFormRef.current?.getFormValues({}) || { values: {}, isCheckValidated: false }
|
||||
const credentials = credentialsFormValues.values
|
||||
const apiKeyCredentialsFormValues = apiKeyCredentialsFormRef.current?.getFormValues({}) || { values: {}, isCheckValidated: false }
|
||||
const credentials = apiKeyCredentialsFormValues.values
|
||||
|
||||
if (!Object.keys(credentials).length) {
|
||||
Toast.notify({
|
||||
@@ -149,24 +159,24 @@ export const CommonCreateModal = ({ onClose, createType, builder }: Props) => {
|
||||
}
|
||||
|
||||
const handleCreate = () => {
|
||||
const parameterForm = parametersFormRef.current?.getFormValues({}) || { values: {}, isCheckValidated: false }
|
||||
const subscriptionForm = subscriptionFormRef.current?.getFormValues({})
|
||||
const autoCommonParametersFormValues = autoCommonParametersFormRef.current?.getFormValues({}) || { values: {}, isCheckValidated: false }
|
||||
const subscriptionFormValues = subscriptionFormRef.current?.getFormValues({}) || { values: {}, isCheckValidated: false }
|
||||
// console.log('parameterForm', parameterForm)
|
||||
|
||||
if (!subscriptionForm?.isCheckValidated || !parameterForm?.isCheckValidated)
|
||||
if (!subscriptionFormValues?.isCheckValidated || !autoCommonParametersFormValues?.isCheckValidated)
|
||||
return
|
||||
|
||||
if (!subscriptionBuilder)
|
||||
return
|
||||
|
||||
const subscriptionNameValue = subscriptionForm.values.subscription_name as string
|
||||
const subscriptionNameValue = subscriptionFormValues?.values.subscription_name as string
|
||||
|
||||
buildSubscription(
|
||||
{
|
||||
provider: detail?.provider || '',
|
||||
subscriptionBuilderId: subscriptionBuilder.id,
|
||||
name: subscriptionNameValue,
|
||||
parameters: { ...parameterForm.values, events: ['*'] },
|
||||
parameters: autoCommonParametersFormValues.values,
|
||||
// properties: formValues.values,
|
||||
},
|
||||
{
|
||||
@@ -210,11 +220,11 @@ export const CommonCreateModal = ({ onClose, createType, builder }: Props) => {
|
||||
{createType === SupportedCreationMethods.APIKEY && <MultiSteps currentStep={currentStep} />}
|
||||
{currentStep === ApiKeyStep.Verify && (
|
||||
<>
|
||||
{credentialsSchema.length > 0 && (
|
||||
{apiKeyCredentialsSchema.length > 0 && (
|
||||
<div className='mb-4'>
|
||||
<BaseForm
|
||||
formSchemas={credentialsSchema}
|
||||
ref={credentialsFormRef}
|
||||
formSchemas={apiKeyCredentialsSchema}
|
||||
ref={apiKeyCredentialsFormRef}
|
||||
labelClassName='system-sm-medium mb-2 block text-text-primary'
|
||||
preventDefaultSubmit={true}
|
||||
formClassName='space-y-4'
|
||||
@@ -264,9 +274,9 @@ export const CommonCreateModal = ({ onClose, createType, builder }: Props) => {
|
||||
{/* <div className='system-xs-regular mb-6 mt-[-1rem] text-text-tertiary'>
|
||||
{t('pluginTrigger.modal.form.callbackUrl.description')}
|
||||
</div> */}
|
||||
{createType !== SupportedCreationMethods.MANUAL && parametersSchema.length > 0 && (
|
||||
{createType !== SupportedCreationMethods.MANUAL && autoCommonParametersSchema.length > 0 && (
|
||||
<BaseForm
|
||||
formSchemas={parametersSchema.map((schema: { type: FormTypeEnum; name: any }) => ({
|
||||
formSchemas={autoCommonParametersSchema.map(schema => ({
|
||||
...schema,
|
||||
dynamicSelectParams: schema.type === FormTypeEnum.dynamicSelect ? {
|
||||
plugin_id: detail?.plugin_id || '',
|
||||
@@ -276,17 +286,17 @@ export const CommonCreateModal = ({ onClose, createType, builder }: Props) => {
|
||||
credential_id: subscriptionBuilder?.id || '',
|
||||
} : undefined,
|
||||
}))}
|
||||
ref={parametersFormRef}
|
||||
ref={autoCommonParametersFormRef}
|
||||
labelClassName='system-sm-medium mb-2 block text-text-primary'
|
||||
formClassName='space-y-4'
|
||||
/>
|
||||
)}
|
||||
{createType === SupportedCreationMethods.MANUAL && <>
|
||||
{propertiesSchema.length > 0 && (
|
||||
{manualPropertiesSchema.length > 0 && (
|
||||
<div className='mb-6'>
|
||||
<BaseForm
|
||||
formSchemas={propertiesSchema}
|
||||
ref={propertiesFormRef}
|
||||
formSchemas={manualPropertiesSchema}
|
||||
ref={manualPropertiesFormRef}
|
||||
labelClassName='system-sm-medium mb-2 block text-text-primary'
|
||||
formClassName='space-y-4'
|
||||
/>
|
||||
|
||||
@@ -1,29 +1,16 @@
|
||||
import { create } from 'zustand'
|
||||
import type { PluginDetail } from '../../types'
|
||||
|
||||
export type SubscriptionListDetail = {
|
||||
plugin_id: string
|
||||
// name: string
|
||||
provider: string
|
||||
declaration: {
|
||||
tool?: any
|
||||
endpoint?: any
|
||||
trigger?: any
|
||||
name?: string
|
||||
meta?: {
|
||||
version?: string
|
||||
}
|
||||
}
|
||||
version?: string
|
||||
}
|
||||
type SimpleDetail = Pick<PluginDetail, 'plugin_id' | 'declaration'> & { provider: string }
|
||||
|
||||
type Shape = {
|
||||
detail: SubscriptionListDetail | undefined
|
||||
setDetail: (detail: SubscriptionListDetail) => void
|
||||
detail: SimpleDetail | undefined
|
||||
setDetail: (detail: SimpleDetail) => void
|
||||
}
|
||||
|
||||
export const usePluginStore = create<Shape>(set => ({
|
||||
detail: undefined,
|
||||
setDetail: (detail: SubscriptionListDetail) => set({ detail }),
|
||||
setDetail: (detail: SimpleDetail) => set({ detail }),
|
||||
}))
|
||||
|
||||
type ShapeSubscription = {
|
||||
|
||||
@@ -83,7 +83,7 @@ export const TriggerEventsList = () => {
|
||||
const locale = useContextSelector(I18n, state => state.locale)
|
||||
const language = getLanguage(locale)
|
||||
const detail = usePluginStore(state => state.detail)
|
||||
const triggers = detail?.declaration.trigger?.triggers || []
|
||||
const events = detail?.declaration.trigger?.events || []
|
||||
const providerKey = useMemo(() => {
|
||||
if (!detail?.plugin_id || !detail?.declaration?.name)
|
||||
return ''
|
||||
@@ -98,7 +98,7 @@ export const TriggerEventsList = () => {
|
||||
|
||||
const tools = (providerInfo.events || []).map((trigger: any) => toTool(trigger, providerInfo.author))
|
||||
|
||||
const metaVersion = detail.declaration.meta?.version || detail.version || '1.0'
|
||||
const metaVersion = detail.declaration.meta?.version || detail.declaration.version || '1.0'
|
||||
|
||||
return {
|
||||
id: providerInfo.plugin_id || providerInfo.name,
|
||||
@@ -118,19 +118,19 @@ export const TriggerEventsList = () => {
|
||||
}
|
||||
}, [detail, providerInfo])
|
||||
|
||||
if (!triggers.length)
|
||||
if (!events.length)
|
||||
return null
|
||||
|
||||
return (
|
||||
<div className='px-4 pb-4 pt-2'>
|
||||
<div className='mb-1 py-1'>
|
||||
<div className='system-sm-semibold-uppercase mb-1 flex h-6 items-center justify-between text-text-secondary'>
|
||||
{t('pluginTrigger.events.actionNum', { num: triggers.length, event: t(`pluginTrigger.events.${triggers.length > 1 ? 'events' : 'event'}`) })}
|
||||
{t('pluginTrigger.events.actionNum', { num: events.length, event: t(`pluginTrigger.events.${events.length > 1 ? 'events' : 'event'}`) })}
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col gap-2'>
|
||||
{collection
|
||||
? triggers.map((triggerEvent: Trigger) => {
|
||||
? events.map((triggerEvent: Trigger) => {
|
||||
const triggerName = triggerEvent.identity?.name || ''
|
||||
const tool = collection.tools.find(item => item.name === triggerName)
|
||||
|| toTool(triggerEvent, collection.author)
|
||||
@@ -146,7 +146,7 @@ export const TriggerEventsList = () => {
|
||||
/>
|
||||
)
|
||||
})
|
||||
: triggers.map((triggerEvent: Trigger) => (
|
||||
: events.map((triggerEvent: Trigger) => (
|
||||
<div
|
||||
key={`${detail?.plugin_id}${triggerEvent.identity?.name || ''}`}
|
||||
className='bg-components-panel-item-bg rounded-xl border-[0.5px] border-components-panel-border-subtle px-4 py-3 shadow-xs'
|
||||
|
||||
@@ -89,11 +89,14 @@ export type PluginDeclaration = {
|
||||
}
|
||||
|
||||
export type PluginTriggerDefinition = {
|
||||
events: Trigger[]
|
||||
identity: Identity
|
||||
credentials_schema: CredentialsSchema[]
|
||||
oauth_schema: OauthSchema
|
||||
subscription_schema: SubscriptionSchema
|
||||
triggers: Trigger[]
|
||||
subscription_constructor: {
|
||||
credentials_schema: CredentialsSchema[]
|
||||
oauth_schema: OauthSchema
|
||||
parameters: ParametersSchema[]
|
||||
}
|
||||
subscription_schema: ParametersSchema[]
|
||||
}
|
||||
|
||||
export type CredentialsSchema = {
|
||||
@@ -115,11 +118,6 @@ export type OauthSchema = {
|
||||
credentials_schema: CredentialsSchema[]
|
||||
}
|
||||
|
||||
export type SubscriptionSchema = {
|
||||
parameters_schema: ParametersSchema[]
|
||||
properties_schema: PropertiesSchema[]
|
||||
}
|
||||
|
||||
export type ParametersSchema = {
|
||||
name: string
|
||||
label: Record<Locale, string>
|
||||
|
||||
Reference in New Issue
Block a user