Commit ecc45a58 by Finley Ge Committed by GitHub

chore: plugin (#7056)

* fix: workflow system tool use pluginModule

* fix: zip upload cancel && bump plugin sdk version
parent 602e4306
......@@ -13,7 +13,7 @@
"dependencies": {
"@apidevtools/swagger-parser": "^10.1.0",
"@bany/curl-to-json": "^1.2.8",
"@fastgpt-plugin/sdk-client": "0.0.1-alpha.8",
"@fastgpt-plugin/sdk-client": "0.0.1-alpha.9",
"axios": "catalog:",
"ipaddr.js": "catalog:",
"cron-parser": "^4.9.0",
......
......@@ -245,7 +245,7 @@ importers:
version: 10.1.4(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.8.9)
next-i18next:
specifier: 'catalog:'
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
prettier:
specifier: catalog:lint
version: 3.8.3
......@@ -383,8 +383,8 @@ importers:
specifier: ^1.2.8
version: 1.2.8
'@fastgpt-plugin/sdk-client':
specifier: 0.0.1-alpha.8
version: 0.0.1-alpha.8(zod@4.1.12)
specifier: 0.0.1-alpha.9
version: 0.0.1-alpha.9(zod@4.1.12)
axios:
specifier: 'catalog:'
version: 1.16.0
......@@ -692,7 +692,7 @@ importers:
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@chakra-ui/next-js':
specifier: 'catalog:'
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
'@chakra-ui/react':
specifier: 'catalog:'
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
......@@ -773,7 +773,7 @@ importers:
version: 16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
next-i18next:
specifier: 'catalog:'
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
papaparse:
specifier: ^5.4.1
version: 5.4.1
......@@ -852,7 +852,7 @@ importers:
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@chakra-ui/next-js':
specifier: 'catalog:'
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
'@chakra-ui/react':
specifier: 'catalog:'
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
......@@ -984,7 +984,7 @@ importers:
version: 16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
next-i18next:
specifier: 'catalog:'
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
nodemailer:
specifier: ^7.0.11
version: 7.0.13
......@@ -1231,7 +1231,7 @@ importers:
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@chakra-ui/next-js':
specifier: 'catalog:'
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
'@chakra-ui/react':
specifier: 'catalog:'
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
......@@ -1369,7 +1369,7 @@ importers:
version: 16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
next-i18next:
specifier: 'catalog:'
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
nprogress:
specifier: ^0.2.0
version: 0.2.0
......@@ -1572,7 +1572,7 @@ importers:
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
'@chakra-ui/next-js':
specifier: 'catalog:'
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
'@chakra-ui/react':
specifier: 'catalog:'
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
......@@ -1614,7 +1614,7 @@ importers:
version: 16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
next-i18next:
specifier: 'catalog:'
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 15.4.2(i18next@23.16.8)(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
react:
specifier: ^18
version: 18.3.1
......@@ -3590,8 +3590,8 @@ packages:
resolution: {integrity: sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==}
engines: {node: '>=18.0.0', npm: '>=9.0.0'}
'@fastgpt-plugin/sdk-client@0.0.1-alpha.8':
resolution: {integrity: sha512-YTJmErVEbQLPfeIaBcTlIvjIqyDO907cBfkfQ2mHtRI9vnrsGJGSbl+W44vzb4qBW+VxzegQyAPLimjDHw8ThQ==}
'@fastgpt-plugin/sdk-client@0.0.1-alpha.9':
resolution: {integrity: sha512-EjbVvOULgAX1EM9Q7Hj/TYQP3OmZACxLaCJktFpXz/InEFrTKwjHAo1KrnaX5dvdU5UtCeiHY3ShYHX6fpLirg==}
peerDependencies:
zod: ^4
......@@ -16608,7 +16608,7 @@ snapshots:
'@chakra-ui/system': 2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1)
react: 18.3.1
'@chakra-ui/next-js@2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)':
'@chakra-ui/next-js@2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)':
dependencies:
'@chakra-ui/react': 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@emotion/cache': 11.14.0
......@@ -17507,7 +17507,7 @@ snapshots:
'@faker-js/faker@9.9.0': {}
'@fastgpt-plugin/sdk-client@0.0.1-alpha.8(zod@4.1.12)':
'@fastgpt-plugin/sdk-client@0.0.1-alpha.9(zod@4.1.12)':
dependencies:
zod: 4.1.12
......@@ -27264,7 +27264,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
next-i18next@15.4.2(i18next@23.16.8)(next@16.2.6(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
next-i18next@15.4.2(i18next@23.16.8)(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
dependencies:
'@babel/runtime': 7.26.10
'@types/hoist-non-react-statics': 3.3.6
Subproject commit 1ebfaac6a4e6faef2c01d4b6785add3debf7285f
Subproject commit 35458b567a3b719987bdd4e9a18dc747a8b34495
......@@ -15,11 +15,17 @@ import type { GetAdminSystemToolsResponseType } from '@fastgpt/global/openapi/co
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import { AppToolSourceEnum } from '@fastgpt/global/core/app/tool/constants';
import type { UploadPkgPluginResponseType } from '@fastgpt/global/openapi/core/plugin/admin/api';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import {
getUploadedPluginSourceName as getSourceName,
removeUploadedPluginFileByRow
} from './ImportPluginModal.utils';
type UploadPkgPluginItemType = UploadPkgPluginResponseType['plugins'][number];
type UploadPkgPluginFailureType = NonNullable<UploadPkgPluginResponseType['failed']>[number];
type UploadedPluginFile = SelectFileItemType & {
rowId: string;
status: 'uploading' | 'parsing' | 'success' | 'error' | 'duplicate';
sourceName?: string;
errorMsg?: string;
......@@ -35,9 +41,6 @@ type UploadedPluginFile = SelectFileItemType & {
const isPluginDuplicated = (tools: GetAdminSystemToolsResponseType, pluginId: string) =>
tools.some((tool) => tool.id === `${AppToolSourceEnum.systemTool}-${pluginId}`);
const getSourceName = (file: Pick<UploadedPluginFile, 'name' | 'sourceName'>) =>
file.sourceName || file.name;
const safeDecodeURIComponent = (value: string) => {
try {
return decodeURIComponent(value);
......@@ -48,6 +51,8 @@ const safeDecodeURIComponent = (value: string) => {
const isZipFileName = (name: string) => name.toLowerCase().endsWith('.zip');
const buildUploadRowId = (prefix: string) => `${prefix}-${getNanoid(8)}`;
const resolveSuccessSourceFiles = ({
files,
failedSourceNameSet,
......@@ -117,6 +122,7 @@ const ImportPluginModal = ({
return {
...file,
rowId: buildUploadRowId(file.rowId),
sourceName,
status: isDuplicated ? 'duplicate' : 'success',
toolId,
......@@ -180,6 +186,7 @@ const ImportPluginModal = ({
return {
...baseFile,
rowId: buildUploadRowId(baseFile.rowId),
name: displayName,
sourceName,
status: 'error',
......@@ -249,6 +256,7 @@ const ImportPluginModal = ({
? buildUploadedPluginFile(sourceFile, parseResult, nameSuffix)
: ({
file: files[0].file,
rowId: buildUploadRowId(files[0].rowId),
icon: parseResult.icon || files[0].icon,
name:
parseI18nString(parseResult.name || '', i18n.language) || parseResult.pluginId,
......@@ -312,6 +320,7 @@ const ImportPluginModal = ({
async (files: SelectFileItemType[]) => {
const newUploadedFiles: UploadedPluginFile[] = files.map((f) => ({
...f,
rowId: buildUploadRowId('upload'),
status: 'uploading' as const
}));
setUploadedFiles((prev) => [...prev, ...newUploadedFiles]);
......@@ -352,9 +361,15 @@ const ImportPluginModal = ({
};
const handleDelete = (file: UploadedPluginFile) => {
const sourceName = getSourceName(file);
setUploadedFiles((prev) => prev.filter((f) => (f.sourceName || f.name) !== sourceName));
setSelectFiles((prev) => prev.filter((f) => f.name !== sourceName));
const { nextUploadedFiles, sourceNameToRemove } = removeUploadedPluginFileByRow(
uploadedFiles,
file
);
setUploadedFiles(nextUploadedFiles);
if (sourceNameToRemove) {
setSelectFiles((prev) => prev.filter((f) => f.name !== sourceNameToRemove));
}
};
const { runAsync: handleConfirmImport, loading: confirmLoading } = useRequest(
......@@ -440,8 +455,8 @@ const ImportPluginModal = ({
{uploadedFiles.length > 0 && (
<VStack mt={1} gap={1}>
{uploadedFiles.map((item, index) => (
<Flex key={index} w={'full'} fontSize={'12px'}>
{uploadedFiles.map((item) => (
<Flex key={item.rowId} w={'full'} fontSize={'12px'}>
<Flex w={'20%'} px={1} py={'15px'} align={'center'} gap={2}>
<Avatar src={item.icon} borderRadius={'xs'} w={'20px'} />
<Box
......
export type UploadedPluginSourceItem = {
rowId: string;
name: string;
sourceName?: string;
};
export const getUploadedPluginSourceName = (
file: Pick<UploadedPluginSourceItem, 'name' | 'sourceName'>
) => file.sourceName || file.name;
/**
* 按上传结果行删除插件,zip 拆出的多条插件记录共享 sourceName,
* 因此删除时必须使用 rowId 定位单行,只在同源记录全部删除后释放源文件。
*/
export const removeUploadedPluginFileByRow = <T extends UploadedPluginSourceItem>(
files: T[],
file: T
) => {
const sourceName = getUploadedPluginSourceName(file);
const nextUploadedFiles = files.filter((item) => item.rowId !== file.rowId);
const hasSameSourceFile = nextUploadedFiles.some(
(item) => getUploadedPluginSourceName(item) === sourceName
);
return {
nextUploadedFiles,
sourceNameToRemove: hasSameSourceFile ? undefined : sourceName
};
};
import { describe, expect, it } from 'vitest';
import { removeUploadedPluginFileByRow } from '@/pageComponents/config/ImportPluginModal.utils';
describe('ImportPluginModal utils', () => {
it('should remove only the selected plugin row from a zip upload result', () => {
const files = [
{ rowId: 'zip-row-a', name: 'tools.zip / A', sourceName: 'tools.zip' },
{ rowId: 'zip-row-b', name: 'tools.zip / B', sourceName: 'tools.zip' },
{ rowId: 'single-row', name: 'single.pkg' }
];
const result = removeUploadedPluginFileByRow(files, files[0]);
expect(result.nextUploadedFiles.map((file) => file.rowId)).toEqual(['zip-row-b', 'single-row']);
expect(result.sourceNameToRemove).toBeUndefined();
});
it('should release the source zip after deleting the last plugin row from it', () => {
const files = [
{ rowId: 'zip-row-b', name: 'tools.zip / B', sourceName: 'tools.zip' },
{ rowId: 'single-row', name: 'single.pkg' }
];
const result = removeUploadedPluginFileByRow(files, files[0]);
expect(result.nextUploadedFiles.map((file) => file.rowId)).toEqual(['single-row']);
expect(result.sourceNameToRemove).toBe('tools.zip');
});
it('should release a standalone pkg after deleting it', () => {
const files = [
{ rowId: 'zip-row-b', name: 'tools.zip / B', sourceName: 'tools.zip' },
{ rowId: 'single-row', name: 'single.pkg' }
];
const result = removeUploadedPluginFileByRow(files, files[1]);
expect(result.nextUploadedFiles.map((file) => file.rowId)).toEqual(['zip-row-b']);
expect(result.sourceNameToRemove).toBe('single.pkg');
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment