diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx
new file mode 100644
index 0000000000..5ec0e4fbe2
--- /dev/null
+++ b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx
@@ -0,0 +1,152 @@
+import React, { useMemo } from 'react'
+import { useTranslation } from 'react-i18next'
+import { useContext } from 'use-context-selector'
+import { useBoolean } from 'ahooks'
+import {
+ RiBugLine,
+ RiCloseLine,
+ RiHardDrive3Line,
+ RiVerifiedBadgeLine,
+} from '@remixicon/react'
+import type { PluginDetail } from '../types'
+import { PluginSource } from '../types'
+import Description from '../card/base/description'
+import Icon from '../card/base/card-icon'
+import Title from '../card/base/title'
+import OrgInfo from '../card/base/org-info'
+import OperationDropdown from './operation-dropdown'
+import PluginInfo from '@/app/components/plugins/plugin-page/plugin-info'
+import ActionButton from '@/app/components/base/action-button'
+import Button from '@/app/components/base/button'
+import Badge from '@/app/components/base/badge'
+import Confirm from '@/app/components/base/confirm'
+import Tooltip from '@/app/components/base/tooltip'
+import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin'
+import { Github } from '@/app/components/base/icons/src/public/common'
+import I18n from '@/context/i18n'
+import cn from '@/utils/classnames'
+
+const i18nPrefix = 'plugin.action'
+
+type Props = {
+ detail: PluginDetail
+ onHide: () => void
+ onDelete: () => void
+}
+
+const DetailHeader = ({
+ detail,
+ onHide,
+ onDelete,
+}: Props) => {
+ const { t } = useTranslation()
+ const { locale } = useContext(I18n)
+
+ const hasNewVersion = useMemo(() => {
+ if (!detail)
+ return false
+ return false
+ // return pluginDetail.latest_version !== pluginDetail.version
+ }, [detail])
+
+ const handleUpdate = () => {}
+
+ const [isShowPluginInfo, {
+ setTrue: showPluginInfo,
+ setFalse: hidePluginInfo,
+ }] = useBoolean(false)
+
+ const [isShowDeleteConfirm, {
+ setTrue: showDeleteConfirm,
+ setFalse: hideDeleteConfirm,
+ }] = useBoolean(false)
+
+ const usedInApps = 3
+
+ return (
+
+
+
+
+
+
+ {detail.declaration.verified && }
+
+ {hasNewVersion && (
+
+ )}
+
+
+
+
+
·
+ {detail.source === PluginSource.marketplace && (
+
+
+
+ )}
+ {detail.source === PluginSource.github && (
+
+
+
+ )}
+ {detail.source === PluginSource.local && (
+
+
+
+ )}
+ {detail.source === PluginSource.debugging && (
+
+
+
+ )}
+
+
+
+
+
+
+ {isShowPluginInfo && (
+
+ )}
+ {isShowDeleteConfirm && (
+
+ {t(`${i18nPrefix}.deleteContentLeft`)}{detail.declaration.label[locale]}{t(`${i18nPrefix}.deleteContentRight`)}
+ {usedInApps > 0 && t(`${i18nPrefix}.usedInApps`, { num: usedInApps })}
+
+ }
+ onCancel={hideDeleteConfirm}
+ onConfirm={onDelete}
+ />
+ )}
+
+ )
+}
+
+export default DetailHeader
diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx
index aab5a93f66..0fd9570137 100644
--- a/web/app/components/plugins/plugin-detail-panel/index.tsx
+++ b/web/app/components/plugins/plugin-detail-panel/index.tsx
@@ -1,33 +1,14 @@
'use client'
-import React, { useMemo } from 'react'
+import React from 'react'
import type { FC } from 'react'
-import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
-import {
- RiBugLine,
- RiCloseLine,
- RiHardDrive3Line,
- RiVerifiedBadgeLine,
-} from '@remixicon/react'
import type { PluginDetail } from '../types'
-import { PluginSource } from '../types'
-import Description from '../card/base/description'
-import Icon from '../card/base/card-icon'
-import Title from '../card/base/title'
-import OrgInfo from '../card/base/org-info'
-import OperationDropdown from './operation-dropdown'
+import DetailHeader from './detail-header'
import EndpointList from './endpoint-list'
import ActionList from './action-list'
import ModelList from './model-list'
-import Badge from '@/app/components/base/badge'
-import Tooltip from '@/app/components/base/tooltip'
-import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin'
-import { Github } from '@/app/components/base/icons/src/public/common'
-import Button from '@/app/components/base/button'
-import ActionButton from '@/app/components/base/action-button'
import Drawer from '@/app/components/base/drawer'
// import Loading from '@/app/components/base/loading'
-import I18n from '@/context/i18n'
import cn from '@/utils/classnames'
type Props = {
@@ -40,16 +21,8 @@ const PluginDetailPanel: FC = ({
onHide,
}) => {
const { t } = useTranslation()
- const { locale } = useContext(I18n)
- const hasNewVersion = useMemo(() => {
- if (!pluginDetail)
- return false
- return false // TODO
- // return pluginDetail.latest_version !== pluginDetail.version
- }, [pluginDetail])
-
- const handleUpdate = () => {}
+ const handleDelete = () => {}
if (!pluginDetail)
return null
@@ -67,63 +40,11 @@ const PluginDetailPanel: FC = ({
{/* {loading && } */}
{pluginDetail && (
<>
-
-
-
-
-
-
- {pluginDetail.declaration.verified && }
-
- {hasNewVersion && (
-
- )}
-
-
-
-
-
·
- {pluginDetail.source === PluginSource.marketplace && (
-
-
-
- )}
- {pluginDetail.source === PluginSource.github && (
-
-
-
- )}
- {pluginDetail.source === PluginSource.local && (
-
-
-
- )}
- {pluginDetail.source === PluginSource.debugging && (
-
-
-
- )}
-
-
-
-
-
-
-
+
diff --git a/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx b/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx
index c9be924a65..e8186d1958 100644
--- a/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx
+++ b/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx
@@ -13,9 +13,14 @@ import {
import cn from '@/utils/classnames'
type Props = {
+ onInfo: () => void
+ onRemove: () => void
}
-const OperationDropdown: FC
= () => {
+const OperationDropdown: FC = ({
+ onInfo,
+ onRemove,
+}) => {
const { t } = useTranslation()
const [open, doSetOpen] = useState(false)
const openRef = useRef(open)
@@ -45,14 +50,16 @@ const OperationDropdown: FC = () => {
-
{t('plugin.detailPanel.operation.info')}
+
{t('plugin.detailPanel.operation.info')}
+ {/* ##plugin TODO## check update */}
{t('plugin.detailPanel.operation.checkUpdate')}
+ {/* ##plugin TODO## router action */}
{t('plugin.detailPanel.operation.viewDetail')}
-
{t('plugin.detailPanel.operation.remove')}
+
{t('plugin.detailPanel.operation.remove')}