feat: new switch plugin version

This commit is contained in:
AkaraChen 2025-01-08 15:58:05 +08:00
parent 755685a89a
commit 2fd083629d
5 changed files with 89 additions and 34 deletions

View File

@ -8,14 +8,15 @@ import type { UseMutationResult } from '@tanstack/react-query'
type Props = {
plugin: Plugin
onSave: () => void
onCancel: () => void
mutation: UseMutationResult
mutation: Pick<UseMutationResult, 'isSuccess' | 'isPending'>
mutate: () => void
confirmButtonText: ReactNode
cancelButtonText: ReactNode
modelTitle: ReactNode
description: ReactNode
cardTitleLeft: ReactNode
modalBottomLeft?: ReactNode
}
const PluginMutationModal: FC<Props> = ({
@ -27,6 +28,8 @@ const PluginMutationModal: FC<Props> = ({
modelTitle,
description,
cardTitleLeft,
mutate,
modalBottomLeft,
}: Props) => {
return (
<Modal
@ -47,20 +50,25 @@ const PluginMutationModal: FC<Props> = ({
titleLeft={cardTitleLeft}
/>
</div>
<div className='flex pt-5 justify-end items-center gap-2 self-stretch'>
{mutation.isPending && (
<Button onClick={onCancel}>
{cancelButtonText}
<div className='flex pt-5 items-center gap-2 self-stretch'>
<div>
{modalBottomLeft}
</div>
<div className='ml-auto flex gap-2'>
{!mutation.isPending && (
<Button onClick={onCancel}>
{cancelButtonText}
</Button>
)}
<Button
variant='primary'
loading={mutation.isPending}
onClick={mutate}
disabled={mutation.isPending}
>
{confirmButtonText}
</Button>
)}
<Button
variant='primary'
loading={mutation.isPending}
onClick={mutation.mutate}
disabled={mutation.isPending}
>
{confirmButtonText}
</Button>
</div>
</div>
</Modal>
)

View File

@ -3,13 +3,18 @@
import Badge from '@/app/components/base/badge'
import Tooltip from '@/app/components/base/tooltip'
import PluginVersionPicker from '@/app/components/plugins/update-plugin/plugin-version-picker'
import { RiArrowLeftRightLine } from '@remixicon/react'
import { RiArrowLeftRightLine, RiExternalLinkLine } from '@remixicon/react'
import type { ReactNode } from 'react'
import { type FC, useCallback, useState } from 'react'
import UpdateFromMarketplace from '@/app/components/plugins/update-plugin/from-market-place'
import { useBoolean } from 'ahooks'
import { useCheckInstalled } from '@/service/use-plugins'
import { useCheckInstalled, useUpdatePackageFromMarketPlace } from '@/service/use-plugins'
import cn from '@/utils/classnames'
import PluginMutationModel from '@/app/components/plugins/plugin-mutation-model'
import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
import { pluginManifestToCardPluginProps } from '@/app/components/plugins/install-plugin/utils'
import { Badge as Badge2, BadgeState } from '@/app/components/base/badge/index'
import Link from 'next/link'
import { useTranslation } from 'react-i18next'
export type SwitchPluginVersionProps = {
uniqueIdentifier: string
@ -38,21 +43,49 @@ export const SwitchPluginVersion: FC<SwitchPluginVersionProps> = (props) => {
pluginDetails.refetch()
onChange?.(target!.version)
}, [hideUpdateModal, onChange, pluginDetails, target])
const { getIconUrl } = useGetIcon()
const icon = pluginDetail?.declaration.icon ? getIconUrl(pluginDetail.declaration.icon) : undefined
const mutation = useUpdatePackageFromMarketPlace()
const install = () => {
mutation.mutate(
{
new_plugin_unique_identifier: target!.pluginUniqueIden,
original_plugin_unique_identifier: uniqueIdentifier,
},
{
onSuccess() {
handleUpdatedFromMarketplace()
},
})
}
const { t } = useTranslation()
return <Tooltip popupContent={!isShow && !isShowUpdateModal && tooltip} triggerMethod='hover'>
<div className={cn('w-fit', className)}>
{isShowUpdateModal && pluginDetail && <UpdateFromMarketplace
payload={{
originalPackageInfo: {
id: uniqueIdentifier,
payload: pluginDetail.declaration,
},
targetPackageInfo: {
id: target!.pluginUniqueIden,
version: target!.version,
},
}}
{isShowUpdateModal && pluginDetail && <PluginMutationModel
onCancel={hideUpdateModal}
onSave={handleUpdatedFromMarketplace}
plugin={pluginManifestToCardPluginProps({
...pluginDetail.declaration,
icon: icon!,
})}
mutation={mutation}
mutate={install}
confirmButtonText={t('workflow.nodes.agent.installPlugin.install')}
cancelButtonText={t('workflow.nodes.agent.installPlugin.cancel')}
modelTitle={t('workflow.nodes.agent.installPlugin.title')}
description={t('workflow.nodes.agent.installPlugin.desc')}
cardTitleLeft={<>
<Badge2 className='mx-1' size="s" state={BadgeState.Warning}>
{`${pluginDetail.version} -> ${target!.version}`}
</Badge2>
</>}
modalBottomLeft={
<Link className='flex justify-center items-center gap-1' href={'TODO: add changelog url'} target='_blank'>
<span className='text-text-accent system-xs-regular text-xs'>
{t('workflow.nodes.agent.installPlugin.changelog')}
</span>
<RiExternalLinkLine className='text-text-accent size-3' />
</Link>
}
/>}
{pluginDetail && <PluginVersionPicker
isShow={isShow}

View File

@ -26,7 +26,7 @@ const nodeDefault: NodeDefault<AgentNodeType> = {
if (!strategy) {
return {
isValid: false,
errorMessage: t('workflow.checkList.strategyNotSelected'),
errorMessage: t('workflow.nodes.agent.checkList.strategyNotSelected'),
}
}
for (const param of strategy.parameters) {

View File

@ -755,9 +755,16 @@ const translation = {
},
json: 'agent generated json',
},
},
checkList: {
strategyNotSelected: 'Strategy not selected',
checkList: {
strategyNotSelected: 'Strategy not selected',
},
installPlugin: {
title: 'Install Plugin',
desc: 'About to install the following plugin',
changelog: 'Change log',
install: 'Install',
cancel: 'Cancel',
},
},
},
tracing: {

View File

@ -758,6 +758,13 @@ const translation = {
checkList: {
strategyNotSelected: '未选择策略',
},
installPlugin: {
title: '安装插件',
desc: '即将安装以下插件',
changelog: '更新日志',
install: '安装',
cancel: '取消',
},
},
},
tracing: {