mirror of
https://github.com/langgenius/dify.git
synced 2026-04-25 01:26:57 +08:00
fix: update plugin handle
This commit is contained in:
parent
2560d3edae
commit
56f573ecfb
@ -1,6 +1,5 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context'
|
|
||||||
import { useAppContext } from '@/context/app-context'
|
import { useAppContext } from '@/context/app-context'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
import Toast from '@/app/components/base/toast'
|
import Toast from '@/app/components/base/toast'
|
||||||
@ -14,19 +13,25 @@ import {
|
|||||||
useRemoveProviderCredentials,
|
useRemoveProviderCredentials,
|
||||||
useUpdateProviderCredentials,
|
useUpdateProviderCredentials,
|
||||||
} from '@/service/use-tools'
|
} from '@/service/use-tools'
|
||||||
|
import type { PluginDetail } from '@/app/components/plugins/types'
|
||||||
|
|
||||||
const ActionList = () => {
|
type Props = {
|
||||||
|
detail: PluginDetail
|
||||||
|
}
|
||||||
|
|
||||||
|
const ActionList = ({
|
||||||
|
detail,
|
||||||
|
}: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { isCurrentWorkspaceManager } = useAppContext()
|
const { isCurrentWorkspaceManager } = useAppContext()
|
||||||
const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail)
|
const { data: provider } = useBuiltinProviderInfo(`${detail.plugin_id}/${detail.name}`)
|
||||||
const { data: provider } = useBuiltinProviderInfo(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`)
|
|
||||||
const invalidateProviderInfo = useInvalidateBuiltinProviderInfo()
|
const invalidateProviderInfo = useInvalidateBuiltinProviderInfo()
|
||||||
const { data } = useBuiltinTools(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`)
|
const { data } = useBuiltinTools(`${detail.plugin_id}/${detail.name}`)
|
||||||
|
|
||||||
const [showSettingAuth, setShowSettingAuth] = useState(false)
|
const [showSettingAuth, setShowSettingAuth] = useState(false)
|
||||||
|
|
||||||
const handleCredentialSettingUpdate = () => {
|
const handleCredentialSettingUpdate = () => {
|
||||||
invalidateProviderInfo(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`)
|
invalidateProviderInfo(`${detail.plugin_id}/${detail.name}`)
|
||||||
Toast.notify({
|
Toast.notify({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
message: t('common.api.actionSuccess'),
|
message: t('common.api.actionSuccess'),
|
||||||
@ -74,7 +79,7 @@ const ActionList = () => {
|
|||||||
<div className='flex flex-col gap-2'>
|
<div className='flex flex-col gap-2'>
|
||||||
{data.map(tool => (
|
{data.map(tool => (
|
||||||
<ToolItem
|
<ToolItem
|
||||||
key={`${currentPluginDetail.plugin_id}${tool.name}`}
|
key={`${detail.plugin_id}${tool.name}`}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
collection={provider}
|
collection={provider}
|
||||||
tool={tool}
|
tool={tool}
|
||||||
|
|||||||
@ -13,23 +13,23 @@ import { toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-for
|
|||||||
import ActionButton from '@/app/components/base/action-button'
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
import Tooltip from '@/app/components/base/tooltip'
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
import Toast from '@/app/components/base/toast'
|
import Toast from '@/app/components/base/toast'
|
||||||
import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context'
|
|
||||||
import {
|
import {
|
||||||
useCreateEndpoint,
|
useCreateEndpoint,
|
||||||
useEndpointList,
|
useEndpointList,
|
||||||
useInvalidateEndpointList,
|
useInvalidateEndpointList,
|
||||||
} from '@/service/use-endpoints'
|
} from '@/service/use-endpoints'
|
||||||
|
import type { PluginDetail } from '@/app/components/plugins/types'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
showTopBorder?: boolean
|
detail: PluginDetail
|
||||||
}
|
}
|
||||||
const EndpointList = ({ showTopBorder }: Props) => {
|
const EndpointList = ({ detail }: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const pluginDetail = usePluginPageContext(v => v.currentPluginDetail)
|
const pluginUniqueID = detail.plugin_unique_identifier
|
||||||
const pluginUniqueID = pluginDetail.plugin_unique_identifier
|
const declaration = detail.declaration.endpoint
|
||||||
const declaration = pluginDetail.declaration.endpoint
|
const showTopBorder = detail.declaration.tool
|
||||||
const { data } = useEndpointList(pluginDetail.plugin_id)
|
const { data } = useEndpointList(detail.plugin_id)
|
||||||
const invalidateEndpointList = useInvalidateEndpointList()
|
const invalidateEndpointList = useInvalidateEndpointList()
|
||||||
|
|
||||||
const [isShowEndpointModal, {
|
const [isShowEndpointModal, {
|
||||||
@ -43,7 +43,7 @@ const EndpointList = ({ showTopBorder }: Props) => {
|
|||||||
|
|
||||||
const { mutate: createEndpoint } = useCreateEndpoint({
|
const { mutate: createEndpoint } = useCreateEndpoint({
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
await invalidateEndpointList(pluginDetail.plugin_id)
|
await invalidateEndpointList(detail.plugin_id)
|
||||||
hideEndpointModal()
|
hideEndpointModal()
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: () => {
|
||||||
@ -101,7 +101,7 @@ const EndpointList = ({ showTopBorder }: Props) => {
|
|||||||
<EndpointCard
|
<EndpointCard
|
||||||
key={index}
|
key={index}
|
||||||
data={item}
|
data={item}
|
||||||
handleChange={() => invalidateEndpointList(pluginDetail.plugin_id)}
|
handleChange={() => invalidateEndpointList(detail.plugin_id)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -7,19 +7,21 @@ import ActionList from './action-list'
|
|||||||
import ModelList from './model-list'
|
import ModelList from './model-list'
|
||||||
import Drawer from '@/app/components/base/drawer'
|
import Drawer from '@/app/components/base/drawer'
|
||||||
import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context'
|
import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context'
|
||||||
|
import type { PluginDetail } from '@/app/components/plugins/types'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
detail?: PluginDetail
|
||||||
onUpdate: () => void
|
onUpdate: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const PluginDetailPanel: FC<Props> = ({
|
const PluginDetailPanel: FC<Props> = ({
|
||||||
|
detail,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
}) => {
|
}) => {
|
||||||
const pluginDetail = usePluginPageContext(v => v.currentPluginDetail)
|
const setCurrentPluginID = usePluginPageContext(v => v.setCurrentPluginID)
|
||||||
const setCurrentPluginDetail = usePluginPageContext(v => v.setCurrentPluginDetail)
|
|
||||||
|
|
||||||
const handleHide = () => setCurrentPluginDetail(undefined)
|
const handleHide = () => setCurrentPluginID(undefined)
|
||||||
|
|
||||||
const handleUpdate = (isDelete = false) => {
|
const handleUpdate = (isDelete = false) => {
|
||||||
if (isDelete)
|
if (isDelete)
|
||||||
@ -27,12 +29,12 @@ const PluginDetailPanel: FC<Props> = ({
|
|||||||
onUpdate()
|
onUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pluginDetail)
|
if (!detail)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
isOpen={!!pluginDetail}
|
isOpen={!!detail}
|
||||||
clickOutsideNotOpen={false}
|
clickOutsideNotOpen={false}
|
||||||
onClose={handleHide}
|
onClose={handleHide}
|
||||||
footer={null}
|
footer={null}
|
||||||
@ -40,17 +42,17 @@ const PluginDetailPanel: FC<Props> = ({
|
|||||||
positionCenter={false}
|
positionCenter={false}
|
||||||
panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')}
|
panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')}
|
||||||
>
|
>
|
||||||
{pluginDetail && (
|
{detail && (
|
||||||
<>
|
<>
|
||||||
<DetailHeader
|
<DetailHeader
|
||||||
detail={pluginDetail}
|
detail={detail}
|
||||||
onHide={handleHide}
|
onHide={handleHide}
|
||||||
onUpdate={handleUpdate}
|
onUpdate={handleUpdate}
|
||||||
/>
|
/>
|
||||||
<div className='grow overflow-y-auto'>
|
<div className='grow overflow-y-auto'>
|
||||||
{!!pluginDetail.declaration.tool && <ActionList />}
|
{!!detail.declaration.tool && <ActionList detail={detail} />}
|
||||||
{!!pluginDetail.declaration.endpoint && <EndpointList showTopBorder={!!pluginDetail.declaration.tool} />}
|
{!!detail.declaration.endpoint && <EndpointList detail={detail} />}
|
||||||
{!!pluginDetail.declaration.model && <ModelList />}
|
{!!detail.declaration.model && <ModelList detail={detail} />}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,14 +1,19 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context'
|
|
||||||
import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
|
import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
|
||||||
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
|
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
|
||||||
import { useModelProviderModelList } from '@/service/use-models'
|
import { useModelProviderModelList } from '@/service/use-models'
|
||||||
|
import type { PluginDetail } from '@/app/components/plugins/types'
|
||||||
|
|
||||||
const ModelList = () => {
|
type Props = {
|
||||||
|
detail: PluginDetail
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModelList = ({
|
||||||
|
detail,
|
||||||
|
}: Props) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail)
|
const { data: res } = useModelProviderModelList(`${detail.plugin_id}/${detail.name}`)
|
||||||
const { data: res } = useModelProviderModelList(`${currentPluginDetail.plugin_id}/${currentPluginDetail.name}`)
|
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -37,8 +37,8 @@ const PluginItem: FC<Props> = ({
|
|||||||
const locale = useLanguage()
|
const locale = useLanguage()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { categoriesMap } = useCategories()
|
const { categoriesMap } = useCategories()
|
||||||
const currentPluginDetail = usePluginPageContext(v => v.currentPluginDetail)
|
const currentPluginID = usePluginPageContext(v => v.currentPluginID)
|
||||||
const setCurrentPluginDetail = usePluginPageContext(v => v.setCurrentPluginDetail)
|
const setCurrentPluginID = usePluginPageContext(v => v.setCurrentPluginID)
|
||||||
const invalidateInstalledPluginList = useInvalidateInstalledPluginList()
|
const invalidateInstalledPluginList = useInvalidateInstalledPluginList()
|
||||||
const { refreshModelProviders } = useProviderContext()
|
const { refreshModelProviders } = useProviderContext()
|
||||||
|
|
||||||
@ -66,13 +66,13 @@ const PluginItem: FC<Props> = ({
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
'p-1 rounded-xl border-[1.5px] border-background-section-burn',
|
'p-1 rounded-xl border-[1.5px] border-background-section-burn',
|
||||||
currentPluginDetail?.plugin_id === plugin_id && 'border-components-option-card-option-selected-border',
|
currentPluginID === plugin_id && 'border-components-option-card-option-selected-border',
|
||||||
source === PluginSource.debugging
|
source === PluginSource.debugging
|
||||||
? 'bg-[repeating-linear-gradient(-45deg,rgba(16,24,40,0.04),rgba(16,24,40,0.04)_5px,rgba(0,0,0,0.02)_5px,rgba(0,0,0,0.02)_10px)]'
|
? 'bg-[repeating-linear-gradient(-45deg,rgba(16,24,40,0.04),rgba(16,24,40,0.04)_5px,rgba(0,0,0,0.02)_5px,rgba(0,0,0,0.02)_10px)]'
|
||||||
: 'bg-background-section-burn',
|
: 'bg-background-section-burn',
|
||||||
)}
|
)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCurrentPluginDetail(plugin)
|
setCurrentPluginID(plugin.plugin_id)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}>
|
<div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}>
|
||||||
|
|||||||
@ -11,15 +11,14 @@ import {
|
|||||||
useContextSelector,
|
useContextSelector,
|
||||||
} from 'use-context-selector'
|
} from 'use-context-selector'
|
||||||
import { useSelector as useAppContextSelector } from '@/context/app-context'
|
import { useSelector as useAppContextSelector } from '@/context/app-context'
|
||||||
import type { PluginDetail } from '../types'
|
|
||||||
import type { FilterState } from './filter-management'
|
import type { FilterState } from './filter-management'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useTabSearchParams } from '@/hooks/use-tab-searchparams'
|
import { useTabSearchParams } from '@/hooks/use-tab-searchparams'
|
||||||
|
|
||||||
export type PluginPageContextValue = {
|
export type PluginPageContextValue = {
|
||||||
containerRef: React.RefObject<HTMLDivElement>
|
containerRef: React.RefObject<HTMLDivElement>
|
||||||
currentPluginDetail: PluginDetail | undefined
|
currentPluginID: string | undefined
|
||||||
setCurrentPluginDetail: (plugin: PluginDetail) => void
|
setCurrentPluginID: (pluginID?: string) => void
|
||||||
filters: FilterState
|
filters: FilterState
|
||||||
setFilters: (filter: FilterState) => void
|
setFilters: (filter: FilterState) => void
|
||||||
activeTab: string
|
activeTab: string
|
||||||
@ -29,8 +28,8 @@ export type PluginPageContextValue = {
|
|||||||
|
|
||||||
export const PluginPageContext = createContext<PluginPageContextValue>({
|
export const PluginPageContext = createContext<PluginPageContextValue>({
|
||||||
containerRef: { current: null },
|
containerRef: { current: null },
|
||||||
currentPluginDetail: undefined,
|
currentPluginID: undefined,
|
||||||
setCurrentPluginDetail: () => { },
|
setCurrentPluginID: () => { },
|
||||||
filters: {
|
filters: {
|
||||||
categories: [],
|
categories: [],
|
||||||
tags: [],
|
tags: [],
|
||||||
@ -60,7 +59,7 @@ export const PluginPageContextProvider = ({
|
|||||||
tags: [],
|
tags: [],
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
})
|
})
|
||||||
const [currentPluginDetail, setCurrentPluginDetail] = useState<PluginDetail | undefined>()
|
const [currentPluginID, setCurrentPluginID] = useState<string | undefined>()
|
||||||
|
|
||||||
const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures)
|
const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures)
|
||||||
const options = useMemo(() => {
|
const options = useMemo(() => {
|
||||||
@ -81,8 +80,8 @@ export const PluginPageContextProvider = ({
|
|||||||
<PluginPageContext.Provider
|
<PluginPageContext.Provider
|
||||||
value={{
|
value={{
|
||||||
containerRef,
|
containerRef,
|
||||||
currentPluginDetail,
|
currentPluginID,
|
||||||
setCurrentPluginDetail,
|
setCurrentPluginID,
|
||||||
filters,
|
filters,
|
||||||
setFilters,
|
setFilters,
|
||||||
activeTab,
|
activeTab,
|
||||||
|
|||||||
@ -14,6 +14,7 @@ const PluginsPanel = () => {
|
|||||||
const [filters, setFilters] = usePluginPageContext(v => [v.filters, v.setFilters]) as [FilterState, (filter: FilterState) => void]
|
const [filters, setFilters] = usePluginPageContext(v => [v.filters, v.setFilters]) as [FilterState, (filter: FilterState) => void]
|
||||||
const { data: pluginList, isLoading: isPluginListLoading } = useInstalledPluginList()
|
const { data: pluginList, isLoading: isPluginListLoading } = useInstalledPluginList()
|
||||||
const invalidateInstalledPluginList = useInvalidateInstalledPluginList()
|
const invalidateInstalledPluginList = useInvalidateInstalledPluginList()
|
||||||
|
const currentPluginID = usePluginPageContext(v => v.currentPluginID)
|
||||||
|
|
||||||
const { run: handleFilterChange } = useDebounceFn((filters: FilterState) => {
|
const { run: handleFilterChange } = useDebounceFn((filters: FilterState) => {
|
||||||
setFilters(filters)
|
setFilters(filters)
|
||||||
@ -31,6 +32,11 @@ const PluginsPanel = () => {
|
|||||||
return filteredList
|
return filteredList
|
||||||
}, [pluginList, filters])
|
}, [pluginList, filters])
|
||||||
|
|
||||||
|
const currentPluginDetail = useMemo(() => {
|
||||||
|
const detail = pluginList?.plugins.find(plugin => plugin.plugin_id === currentPluginID)
|
||||||
|
return detail
|
||||||
|
}, [currentPluginID, pluginList?.plugins])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'>
|
<div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'>
|
||||||
@ -40,7 +46,7 @@ const PluginsPanel = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{isPluginListLoading ? <Loading type='app' /> : (filteredList?.length ?? 0) > 0 ? (
|
{isPluginListLoading ? <Loading type='app' /> : (filteredList?.length ?? 0) > 0 ? (
|
||||||
<div className='flex px-12 items-start content-start gap-2 flex-grow self-stretch flex-wrap'>
|
<div className='flex px-12 items-start content-start gap-2 grow self-stretch flex-wrap'>
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
<List pluginList={filteredList || []} />
|
<List pluginList={filteredList || []} />
|
||||||
</div>
|
</div>
|
||||||
@ -48,7 +54,7 @@ const PluginsPanel = () => {
|
|||||||
) : (
|
) : (
|
||||||
<Empty />
|
<Empty />
|
||||||
)}
|
)}
|
||||||
<PluginDetailPanel onUpdate={() => invalidateInstalledPluginList()}/>
|
<PluginDetailPanel detail={currentPluginDetail} onUpdate={() => invalidateInstalledPluginList()}/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user