From d44c338059c9b1a78ae6bcd57f1fe238a4bd0598 Mon Sep 17 00:00:00 2001
From: Archer <545436317@qq.com>
Date: Tue, 20 May 2025 13:41:56 +0800
Subject: [PATCH] perf: confirm ux (#4843)
* perf: delete tip ux
* perf: confirm ux
---
.../zh-cn/docs/development/upgrading/4910.md | 1 +
.../common/MyPopover/PopoverConfirm.tsx | 28 ++--
packages/web/styles/theme.ts | 7 +-
.../components/common/folder/SlideCard.tsx | 46 +++---
.../components/core/app/InputGuideConfig.tsx | 43 +++---
.../account/model/ModelConfigTable.tsx | 41 +++---
.../account/team/MemberTable.tsx | 132 ++++++++----------
.../account/team/OrgManage/IconButton.tsx | 3 +-
.../Flow/nodes/NodeCode.tsx | 34 ++---
.../Flow/nodes/NodePluginIO/PluginOutput.tsx | 48 ++++---
.../render/RenderDebug/NodeDebugResponse.tsx | 33 +++--
.../templates/DynamicInputs/index.tsx | 48 ++++---
.../pageComponents/chat/ChatHistorySlider.tsx | 32 ++---
.../dataset/detail/CollectionCard/Context.tsx | 2 +-
.../detail/CollectionCard/WebsiteConfig.tsx | 101 +++-----------
.../dataset/detail/DataCard.tsx | 71 +++++-----
.../dataset/detail/Info/index.tsx | 5 -
.../src/pages/dashboard/mcpServer/index.tsx | 25 ++--
18 files changed, 309 insertions(+), 391 deletions(-)
diff --git a/docSite/content/zh-cn/docs/development/upgrading/4910.md b/docSite/content/zh-cn/docs/development/upgrading/4910.md
index b0602f440..6c87dfbb4 100644
--- a/docSite/content/zh-cn/docs/development/upgrading/4910.md
+++ b/docSite/content/zh-cn/docs/development/upgrading/4910.md
@@ -15,6 +15,7 @@ weight: 790
## ⚙️ 优化
1. LLM stream调用,默认超时调大。
+2. 部分确认交互优化。
## 🐛 修复
diff --git a/packages/web/components/common/MyPopover/PopoverConfirm.tsx b/packages/web/components/common/MyPopover/PopoverConfirm.tsx
index 7d9259f82..1e4f4e434 100644
--- a/packages/web/components/common/MyPopover/PopoverConfirm.tsx
+++ b/packages/web/components/common/MyPopover/PopoverConfirm.tsx
@@ -11,15 +11,16 @@ import {
HStack,
Box,
Button,
- PopoverArrow
+ PopoverArrow,
+ Portal
} from '@chakra-ui/react';
const PopoverConfirm = ({
content,
- showCancel,
+ showCancel = true,
type,
Trigger,
- placement = 'bottom-start',
+ placement = 'auto',
offset,
onConfirm,
confirmText,
@@ -50,7 +51,7 @@ const PopoverConfirm = ({
};
if (type && map[type]) return map[type];
return map.info;
- }, [type, t]);
+ }, [type]);
const firstFieldRef = React.useRef(null);
const { onOpen, onClose, isOpen } = useDisclosure();
@@ -67,7 +68,7 @@ const PopoverConfirm = ({
onClose={onClose}
placement={placement}
offset={offset}
- closeOnBlur={false}
+ closeOnBlur={true}
trigger={'click'}
openDelay={100}
closeDelay={100}
@@ -75,6 +76,7 @@ const PopoverConfirm = ({
lazyBehavior="keepMounted"
arrowSize={10}
strategy={'fixed'}
+ computePositionOnMount={true}
>
{Trigger}
@@ -82,15 +84,25 @@ const PopoverConfirm = ({
- {content}
+
+ {content}
+
-
+
{showCancel && (
)}
-
diff --git a/packages/web/styles/theme.ts b/packages/web/styles/theme.ts
index 383a0bce2..809c8eea6 100644
--- a/packages/web/styles/theme.ts
+++ b/packages/web/styles/theme.ts
@@ -221,7 +221,8 @@ const Button = defineStyleConfig({
boxShadow: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 1px 2px 0px rgba(19, 51, 107, 0.05)',
_hover: {
color: 'red.600',
- borderColor: 'red.300'
+ borderColor: 'red.300',
+ bg: 'red.50'
},
_active: {
color: 'red.600'
@@ -281,11 +282,11 @@ const Button = defineStyleConfig({
bg: 'transparent',
transition: 'background 0.1s',
_hover: {
- bg: 'myGray.150',
+ bg: 'red.50',
color: 'red.600'
},
_active: {
- bg: 'myGray.150'
+ bg: 'red.50'
},
_disabled: {
color: 'myGray.800 !important'
diff --git a/projects/app/src/components/common/folder/SlideCard.tsx b/projects/app/src/components/common/folder/SlideCard.tsx
index 57aec6a88..6d9eea41b 100644
--- a/projects/app/src/components/common/folder/SlideCard.tsx
+++ b/projects/app/src/components/common/folder/SlideCard.tsx
@@ -5,14 +5,13 @@ import { FolderIcon } from '@fastgpt/global/common/file/image/constants';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import MyDivider from '@fastgpt/web/components/common/MyDivider';
import { useTranslation } from 'next-i18next';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
-import { type PermissionValueType } from '@fastgpt/global/support/permission/type';
import CollaboratorContextProvider, {
type MemberManagerInputPropsType
} from '../../support/permission/MemberManager/context';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import ResumeInherit from '@/components/support/permission/ResumeInheritText';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
const FolderSlideCard = ({
refreshDeps,
@@ -47,11 +46,6 @@ const FolderSlideCard = ({
const { t } = useTranslation();
const { feConfigs } = useSystemStore();
- const { ConfirmModal, openConfirm } = useConfirm({
- type: 'delete',
- content: deleteTip
- });
-
return (
@@ -93,22 +87,26 @@ const FolderSlideCard = ({
{t('common:Move')}
{managePer.permission.isOwner && (
- }
- transform={'none !important'}
- w={'100%'}
- justifyContent={'flex-start'}
- size={'sm'}
- fontSize={'mini'}
- mt={3}
- onClick={() => {
- openConfirm(onDelete)();
- }}
- >
- {t('common:delete_folder')}
-
+ }
+ transform={'none !important'}
+ w={'100%'}
+ justifyContent={'flex-start'}
+ size={'sm'}
+ fontSize={'mini'}
+ mt={3}
+ >
+ {t('common:delete_folder')}
+
+ }
+ type="delete"
+ content={deleteTip}
+ onConfirm={onDelete}
+ />
)}
>
@@ -177,8 +175,6 @@ const FolderSlideCard = ({
>
)}
-
-
);
};
diff --git a/projects/app/src/components/core/app/InputGuideConfig.tsx b/projects/app/src/components/core/app/InputGuideConfig.tsx
index 43feff3fa..0af949c53 100644
--- a/projects/app/src/components/core/app/InputGuideConfig.tsx
+++ b/projects/app/src/components/core/app/InputGuideConfig.tsx
@@ -37,7 +37,7 @@ import HighlightText from '@fastgpt/web/components/common/String/HighlightText';
import { defaultChatInputGuideConfig } from '@fastgpt/global/core/app/constants';
import ChatFunctionTip from './Tip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
const csvTemplate = `"第一列内容"
"只会将第一列内容导入,其余列会被忽略"
@@ -191,10 +191,6 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
const [searchKey, setSearchKey] = useState('');
- const { openConfirm: openConfirmDel, ConfirmModal: DelConfirmModal } = useConfirm({
- type: 'delete'
- });
-
const {
scrollDataList,
setData,
@@ -355,24 +351,26 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
>
{t('common:Delete')}
- }
- onClick={() =>
- openConfirmDel(
- () => {
- onDeleteAllData();
- setSelectedRows([]);
- },
- undefined,
- t('chat:delete_all_input_guide_confirm')
- )()
+
+ }
+ >
+ {t('chat:Delete_all')}
+
}
- >
- {t('chat:Delete_all')}
-
+ type="delete"
+ content={t('chat:delete_all_input_guide_confirm')}
+ onConfirm={() => {
+ onDeleteAllData();
+ setSelectedRows([]);
+ }}
+ />
+
{
@@ -504,7 +502,6 @@ const LexiconConfigModal = ({ appId, onClose }: { appId: string; onClose: () =>
})}
-
);
diff --git a/projects/app/src/pageComponents/account/model/ModelConfigTable.tsx b/projects/app/src/pageComponents/account/model/ModelConfigTable.tsx
index 1ddefe2bd..1ae132ab7 100644
--- a/projects/app/src/pageComponents/account/model/ModelConfigTable.tsx
+++ b/projects/app/src/pageComponents/account/model/ModelConfigTable.tsx
@@ -41,7 +41,6 @@ import {
} from '@/web/core/ai/config';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { type SystemModelItemType } from '@fastgpt/service/core/ai/type';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import MyIconButton from '@fastgpt/web/components/common/Icon/button';
import JsonEditor from '@fastgpt/web/components/common/Textarea/JsonEditor';
import { clientInitData } from '@/web/common/system/staticData';
@@ -54,6 +53,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import AIModelSelector from '@/components/Select/AIModelSelector';
import MyDivider from '@fastgpt/web/components/common/MyDivider';
import { AddModelButton } from './AddModelBox';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
const MyModal = dynamic(() => import('@fastgpt/web/components/common/MyModal'));
const ModelEditModal = dynamic(() => import('./AddModelBox').then((mod) => mod.ModelEditModal));
@@ -260,10 +260,6 @@ const ModelTable = ({ Tab }: { Tab: React.ReactNode }) => {
onSuccess: refreshModels
});
- const { ConfirmModal, openConfirm } = useConfirm({
- type: 'delete',
- content: t('account:model.delete_model_confirm')
- });
const { runAsync: deleteModel } = useRequest2(deleteSystemModel, {
onSuccess: refreshModels
});
@@ -459,10 +455,15 @@ const ModelTable = ({ Tab }: { Tab: React.ReactNode }) => {
onClick={() => onEditModel(item.model)}
/>
{item.isCustom && (
- openConfirm(() => deleteModel({ model: item.model }))()}
+
+
+
+ }
+ type="delete"
+ content={t('account:model.delete_model_confirm')}
+ onConfirm={() => deleteModel({ model: item.model })}
/>
)}
@@ -475,7 +476,6 @@ const ModelTable = ({ Tab }: { Tab: React.ReactNode }) => {
-
{!!editModelData && (
{
onSuccess();
@@ -542,18 +539,14 @@ const JsonConfigModal = ({
{t('common:Cancel')}
-
- openConfirm(() => {
- return runAsync({ config: data });
- })()
- }
- >
- {t('common:Confirm')}
-
-
-
+ {t('common:Confirm')}}
+ type="info"
+ content={t('account:model.json_config_confirm')}
+ onConfirm={() => runAsync({ config: data })}
+ />
+
);
};
diff --git a/projects/app/src/pageComponents/account/team/MemberTable.tsx b/projects/app/src/pageComponents/account/team/MemberTable.tsx
index 321fd2325..31c492de9 100644
--- a/projects/app/src/pageComponents/account/team/MemberTable.tsx
+++ b/projects/app/src/pageComponents/account/team/MemberTable.tsx
@@ -16,7 +16,6 @@ import {
} from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import { useUserStore } from '@/web/support/user/useUserStore';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import {
delRemoveMember,
getTeamMembers,
@@ -50,6 +49,8 @@ import { type PaginationResponse } from '@fastgpt/web/common/fetch/type';
import _ from 'lodash';
import MySelect from '@fastgpt/web/components/common/MySelect';
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
+import MyIconButton from '@fastgpt/web/components/common/Icon/button';
const InviteModal = dynamic(() => import('./Invite/InviteModal'));
const TeamTagModal = dynamic(() => import('@/components/support/user/team/TeamTagModal'));
@@ -121,9 +122,6 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
errorToast: t('account_team:sync_member_failed')
});
- const { ConfirmModal: ConfirmLeaveTeamModal, openConfirm: openLeaveConfirm } = useConfirm({
- content: t('account_team:confirm_leave_team')
- });
const { runAsync: onLeaveTeam } = useRequest2(delLeaveTeam, {
onSuccess() {
const defaultTeam = myTeams[0];
@@ -132,19 +130,10 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
errorToast: t('account_team:user_team_leave_team_failed')
});
- const { ConfirmModal: ConfirmRemoveMemberModal, openConfirm: openRemoveMember } = useConfirm({
- type: 'delete'
- });
const { runAsync: onRemoveMember } = useRequest2(delRemoveMember, {
onSuccess: onRefreshMembers
});
- const { ConfirmModal: ConfirmRestoreMemberModal, openConfirm: openRestoreMember } = useConfirm({
- type: 'common',
- title: t('account_team:restore_tip_title'),
- iconSrc: 'common/confirm/restoreTip',
- iconColor: 'primary.500'
- });
const { runAsync: onRestore } = useRequest2(postRestoreMember, {
onSuccess: onRefreshMembers,
successToast: t('common:Success'),
@@ -247,16 +236,22 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
)}
{!userInfo?.team.permission.isOwner && (
- }
- onClick={() => openLeaveConfirm(onLeaveTeam)()}
- >
- {t('account_team:user_team_leave_team')}
-
+ }
+ >
+ {t('account_team:user_team_leave_team')}
+
+ }
+ type="delete"
+ content={t('account_team:confirm_leave_team')}
+ onConfirm={() => onLeaveTeam()}
+ />
)}
@@ -317,62 +312,48 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
member.role !== TeamMemberRoleEnum.owner &&
member.tmbId !== userInfo?.team.tmbId &&
(member.status === TeamMemberStatusEnum.active ? (
- <>
-
+ handleEditMemberName(member.tmbId, member.memberName)}
/>
- {
- openRemoveMember(
- () => onRemoveMember(member.tmbId),
- undefined,
- t('account_team:remove_tip', {
- username: member.memberName
- })
- )();
- }}
+
+
+
+ }
+ type="delete"
+ content={t('account_team:remove_tip', {
+ username: member.memberName
+ })}
+ onConfirm={() => onRemoveMember(member.tmbId)}
/>
- >
+
) : (
member.status === TeamMemberStatusEnum.forbidden && (
- {
- openRestoreMember(
- () => onRestore(member.tmbId),
- undefined,
- t('account_team:restore_tip', {
- username: member.memberName
- })
- )();
- }}
+
+
+
+ }
+ type="info"
+ content={t('account_team:restore_tip', {
+ username: member.memberName
+ })}
+ onConfirm={() => onRestore(member.tmbId)}
/>
)
))}
@@ -381,14 +362,11 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
))}
-
-
-
{isOpenInvite && userInfo?.team?.teamId && }
{isOpenTeamTagsAsync && }
>
diff --git a/projects/app/src/pageComponents/account/team/OrgManage/IconButton.tsx b/projects/app/src/pageComponents/account/team/OrgManage/IconButton.tsx
index 3d57c6277..acaf3577d 100644
--- a/projects/app/src/pageComponents/account/team/OrgManage/IconButton.tsx
+++ b/projects/app/src/pageComponents/account/team/OrgManage/IconButton.tsx
@@ -5,7 +5,6 @@ import type { IconNameType } from '@fastgpt/web/components/common/Icon/type';
function IconButton({
name,
w = '1rem',
- h = '1rem',
...props
}: {
name: IconNameType;
@@ -14,7 +13,7 @@ function IconButton({
) => {
const { t } = useTranslation();
@@ -35,11 +36,6 @@ const NodeCode = ({ data, selected }: NodeProps) => {
const splitToolInputs = useContextSelector(WorkflowContext, (ctx) => ctx.splitToolInputs);
const onChangeNode = useContextSelector(WorkflowContext, (ctx) => ctx.onChangeNode);
- // 重置模板确认
- const { ConfirmModal: ResetTemplateConfirm, openConfirm: openResetTemplateConfirm } = useConfirm({
- content: t('workflow:code.Reset template confirm')
- });
-
// 切换语言确认
const { ConfirmModal: SwitchLangConfirm, openConfirm: openSwitchLangConfirm } = useConfirm({
content: t('workflow:code.Switch language confirm')
@@ -84,13 +80,16 @@ const NodeCode = ({ data, selected }: NodeProps) => {
{codeType.value === 'py' && (
)}
- {
+
+ {t('workflow:code.Reset template')}
+
+ }
+ showCancel
+ content={t('workflow:code.Reset template confirm')}
+ placement={'top-end'}
+ onConfirm={() =>
onChangeNode({
nodeId,
type: 'updateInput',
@@ -99,11 +98,9 @@ const NodeCode = ({ data, selected }: NodeProps) => {
...item,
value: codeType.value === 'js' ? JS_TEMPLATE : PY_TEMPLATE
}
- });
- })}
- >
- {t('workflow:code.Reset template')}
-
+ })
+ }
+ />
) => {
);
}
};
- }, [codeType, nodeId, onChangeNode, openResetTemplateConfirm, openSwitchLangConfirm, t]);
+ }, [codeType, nodeId, onChangeNode, openSwitchLangConfirm, t]);
const { isTool, commonInputs } = splitToolInputs(inputs, nodeId);
@@ -146,7 +143,6 @@ const NodeCode = ({ data, selected }: NodeProps) => {
-
);
diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodePluginIO/PluginOutput.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodePluginIO/PluginOutput.tsx
index e27b33502..45c2cdb72 100644
--- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodePluginIO/PluginOutput.tsx
+++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodePluginIO/PluginOutput.tsx
@@ -1,4 +1,4 @@
-import React, { useCallback, useMemo, useState } from 'react';
+import React, { useCallback, useState } from 'react';
import { type NodeProps } from 'reactflow';
import NodeCard from '../render/NodeCard';
import { type FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node.d';
@@ -19,9 +19,10 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import ValueTypeLabel from '../render/ValueTypeLabel';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import PluginOutputEditModal, { defaultOutput } from './PluginOutputEditModal';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
+import MyIconButton from '@fastgpt/web/components/common/Icon/button';
const customOutputConfig = {
selectValueTypeList: Object.values(WorkflowIOValueTypeEnum),
@@ -102,10 +103,7 @@ function Reference({
input: FlowNodeInputItemType;
}) {
const { t } = useTranslation();
- const { ConfirmModal, openConfirm } = useConfirm({
- type: 'delete',
- content: t('workflow:confirm_delete_field_tip')
- });
+
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const [editField, setEditField] = useState();
@@ -161,25 +159,32 @@ function Reference({
{/* value */}
- setEditField(input)}
/>
-
+
+
+ }
+ placement={'bottom'}
+ type={'delete'}
+ content={t('workflow:confirm_delete_field_tip')}
+ onConfirm={onDel}
/>
@@ -215,7 +220,6 @@ function Reference({
onSubmit={onUpdateField}
/>
)}
-
>
);
}
diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderDebug/NodeDebugResponse.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderDebug/NodeDebugResponse.tsx
index b5d03e8a1..2cc2ab2da 100644
--- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderDebug/NodeDebugResponse.tsx
+++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderDebug/NodeDebugResponse.tsx
@@ -2,7 +2,6 @@ import React, { useCallback, useMemo, useRef } from 'react';
import { Box, Button, Card, Flex } from '@chakra-ui/react';
import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { useContextSelector } from 'use-context-selector';
import { WorkflowContext } from '../../../../context';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
@@ -19,6 +18,8 @@ import {
} from '@fastgpt/global/core/workflow/runtime/utils';
import { type ChatItemType, type UserChatItemValueItemType } from '@fastgpt/global/core/chat/type';
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
+import MyIconButton from '@fastgpt/web/components/common/Icon/button';
type NodeDebugResponseProps = {
nodeId: string;
@@ -97,13 +98,6 @@ const NodeDebugResponse = ({ nodeId, debugResult }: NodeDebugResponseProps) => {
const response = debugResult?.response;
- const { openConfirm, ConfirmModal } = useConfirm({
- content: t('common:core.workflow.Confirm stop debug')
- });
- const onStop = () => {
- openConfirm(onStopNodeDebug)();
- };
-
const interactive = debugResult?.workflowInteractiveResponse;
const onNextInteractive = useCallback(
(userContent: string) => {
@@ -196,14 +190,20 @@ const NodeDebugResponse = ({ nodeId, debugResult }: NodeDebugResponseProps) => {
{t('common:core.workflow.debug.Run result')}
{workflowDebugData?.nextRunNodes.length !== 0 && (
- }
- variant={'whiteDanger'}
- onClick={onStop}
- >
- {t('common:core.workflow.Stop debug')}
-
+ }
+ variant={'whiteDanger'}
+ >
+ {t('common:core.workflow.Stop debug')}
+
+ }
+ placement={'top'}
+ content={t('common:core.workflow.Confirm stop debug')}
+ onConfirm={onStopNodeDebug}
+ />
)}
{!interactive && (
<>
@@ -266,7 +266,6 @@ const NodeDebugResponse = ({ nodeId, debugResult }: NodeDebugResponseProps) => {
)}
)}
-
>
) : null;
};
diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/DynamicInputs/index.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/DynamicInputs/index.tsx
index be510d1c6..517ad4aa7 100644
--- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/DynamicInputs/index.tsx
+++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/DynamicInputs/index.tsx
@@ -16,8 +16,8 @@ import { getInputComponentProps } from '@fastgpt/global/core/workflow/node/io/ut
import { ReferSelector, useReference } from '../Reference';
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
import ValueTypeLabel from '../../../ValueTypeLabel';
-import MyIcon from '@fastgpt/web/components/common/Icon';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
+import MyIconButton from '@fastgpt/web/components/common/Icon/button';
const FieldEditModal = dynamic(() => import('../../FieldEditModal'));
@@ -95,7 +95,7 @@ const DynamicInputs = (props: RenderInputProps) => {
)}
);
- }, [editField, dynamicInputs, item, keys, onAddField, props, t, t]);
+ }, [editField, dynamicInputs, item, keys, onAddField, props, t]);
return Render;
};
@@ -110,10 +110,7 @@ function Reference({
}) {
const { nodeId, inputs = [], item } = props;
const { t } = useTranslation();
- const { ConfirmModal, openConfirm } = useConfirm({
- type: 'delete',
- content: t('workflow:confirm_delete_field_tip')
- });
+
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const keys = useMemo(() => {
@@ -187,25 +184,31 @@ function Reference({
{/* value */}
- setEditField(inputChildren)}
/>
-
+
+
+ }
+ type={'delete'}
+ content={t('workflow:confirm_delete_field_tip')}
+ onConfirm={onDel}
/>
)}
-
>
);
}
diff --git a/projects/app/src/pageComponents/chat/ChatHistorySlider.tsx b/projects/app/src/pageComponents/chat/ChatHistorySlider.tsx
index 52fd4686b..652e6c9d2 100644
--- a/projects/app/src/pageComponents/chat/ChatHistorySlider.tsx
+++ b/projects/app/src/pageComponents/chat/ChatHistorySlider.tsx
@@ -7,7 +7,6 @@ import Avatar from '@fastgpt/web/components/common/Avatar';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'next-i18next';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { useUserStore } from '@/web/support/user/useUserStore';
import MyMenu from '@fastgpt/web/components/common/MyMenu';
import { useContextSelector } from 'use-context-selector';
@@ -16,6 +15,7 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
import { useChatStore } from '@/web/core/chat/context/useChatStore';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
type HistoryItemType = {
id: string;
@@ -73,9 +73,6 @@ const ChatHistorySlider = ({ confirmClearText }: { confirmClearText: string }) =
title: t('common:core.chat.Custom History Title'),
placeholder: t('common:core.chat.Custom History Title Description')
});
- const { openConfirm, ConfirmModal } = useConfirm({
- content: confirmClearText
- });
const canRouteToDetail = useMemo(
() => appId && userInfo?.team.permission.hasWritePer && showRouteToAppDetail,
@@ -153,19 +150,21 @@ const ChatHistorySlider = ({ confirmClearText }: { confirmClearText: string }) =
{/* Clear */}
{isPc && histories.length > 0 && (
- }
- onClick={() =>
- openConfirm(() => {
- onClearHistory();
- })()
+
+ }
+ />
+
}
+ type="delete"
+ content={confirmClearText}
+ onConfirm={() => onClearHistory()}
/>
)}
@@ -314,7 +313,6 @@ const ChatHistorySlider = ({ confirmClearText }: { confirmClearText: string }) =
)}
-
);
};
diff --git a/projects/app/src/pageComponents/dataset/detail/CollectionCard/Context.tsx b/projects/app/src/pageComponents/dataset/detail/CollectionCard/Context.tsx
index fb26518bb..8a0da33bf 100644
--- a/projects/app/src/pageComponents/dataset/detail/CollectionCard/Context.tsx
+++ b/projects/app/src/pageComponents/dataset/detail/CollectionCard/Context.tsx
@@ -3,7 +3,7 @@ import { type Dispatch, type ReactNode, type SetStateAction, useState } from 're
import { useTranslation } from 'next-i18next';
import { createContext, useContextSelector } from 'use-context-selector';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
-import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
+import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useDisclosure } from '@chakra-ui/react';
import { checkTeamWebSyncLimit } from '@/web/support/user/team/api';
import { getDatasetCollections, postWebsiteSync } from '@/web/core/dataset/api';
diff --git a/projects/app/src/pageComponents/dataset/detail/CollectionCard/WebsiteConfig.tsx b/projects/app/src/pageComponents/dataset/detail/CollectionCard/WebsiteConfig.tsx
index 812c0d4bc..96df296cf 100644
--- a/projects/app/src/pageComponents/dataset/detail/CollectionCard/WebsiteConfig.tsx
+++ b/projects/app/src/pageComponents/dataset/detail/CollectionCard/WebsiteConfig.tsx
@@ -3,22 +3,12 @@ import { useTranslation } from 'next-i18next';
import { strIsLink } from '@fastgpt/global/common/string/tools';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { useForm } from 'react-hook-form';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { getDocPath } from '@/web/common/system/doc';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useMyStep } from '@fastgpt/web/hooks/useStep';
import MyDivider from '@fastgpt/web/components/common/MyDivider';
-import React, { useRef } from 'react';
-import {
- Box,
- Link,
- Input,
- Button,
- ModalBody,
- ModalFooter,
- Textarea,
- Stack
-} from '@chakra-ui/react';
+import React from 'react';
+import { Box, Link, Input, Button, ModalBody, ModalFooter, Stack } from '@chakra-ui/react';
import {
DataChunkSplitModeEnum,
DatasetCollectionDataProcessModeEnum
@@ -33,6 +23,7 @@ import CollectionChunkForm, {
} from '../Form/CollectionChunkForm';
import { getLLMDefaultChunkSize } from '@fastgpt/global/core/dataset/training/utils';
import { type ChunkSettingsType } from '@fastgpt/global/core/dataset/type';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
export type WebsiteConfigFormType = {
websiteConfig: {
@@ -78,10 +69,6 @@ const WebsiteConfigModal = ({
const isEdit = !!websiteConfig?.url;
- const { ConfirmModal, openConfirm } = useConfirm({
- type: 'common'
- });
-
const { activeStep, goToPrevious, goToNext, MyStep } = useMyStep({
defaultStep: 0,
steps
@@ -186,73 +173,31 @@ const WebsiteConfigModal = ({
{t('common:last_step')}
- {
- openConfirm(
- () =>
- onSuccess({
- websiteConfig: websiteInfoGetValues(),
- chunkSettings: collectionChunkForm2StoreChunkData({
- ...data,
- agentModel: datasetDetail.agentModel,
- vectorModel: datasetDetail.vectorModel
- })
- }),
- undefined,
- isEdit
- ? t('common:core.dataset.website.Confirm Update Tips')
- : t('common:core.dataset.website.Confirm Create Tips')
- )();
- })}
- >
- {t('common:core.dataset.website.Start Sync')}
-
+ {t('common:core.dataset.website.Start Sync')}}
+ content={
+ isEdit
+ ? t('common:core.dataset.website.Confirm Update Tips')
+ : t('common:core.dataset.website.Confirm Create Tips')
+ }
+ onConfirm={() =>
+ form.handleSubmit((data) =>
+ onSuccess({
+ websiteConfig: websiteInfoGetValues(),
+ chunkSettings: collectionChunkForm2StoreChunkData({
+ ...data,
+ agentModel: datasetDetail.agentModel,
+ vectorModel: datasetDetail.vectorModel
+ })
+ })
+ )()
+ }
+ />
>
)}
-
);
};
export default WebsiteConfigModal;
-
-const PromptTextarea = ({
- defaultValue,
- onChange,
- onClose
-}: {
- defaultValue: string;
- onChange: (e: string) => void;
- onClose: () => void;
-}) => {
- const ref = useRef(null);
- const { t } = useTranslation();
-
- return (
-
-
-
- {Prompt_AgentQA.fixedText}
-
-
- {
- const val = ref.current?.value || Prompt_AgentQA.description;
- onChange(val);
- onClose();
- }}
- >
- {t('common:Confirm')}
-
-
-
- );
-};
diff --git a/projects/app/src/pageComponents/dataset/detail/DataCard.tsx b/projects/app/src/pageComponents/dataset/detail/DataCard.tsx
index 570cb5acf..5d1efbec7 100644
--- a/projects/app/src/pageComponents/dataset/detail/DataCard.tsx
+++ b/projects/app/src/pageComponents/dataset/detail/DataCard.tsx
@@ -7,7 +7,6 @@ import {
} from '@/web/core/dataset/api';
import { useToast } from '@fastgpt/web/hooks/useToast';
import { getErrText } from '@fastgpt/global/common/error/utils';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/router';
import MyIcon from '@fastgpt/web/components/common/Icon';
@@ -32,6 +31,7 @@ import { ImportDataSourceEnum } from '@fastgpt/global/core/dataset/constants';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import TrainingStates from './CollectionCard/TrainingStates';
import { getTextValidLength } from '@fastgpt/global/common/string/utils';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
const DataCard = () => {
const theme = useTheme();
@@ -90,28 +90,22 @@ const DataCard = () => {
const canWrite = useMemo(() => datasetDetail.permission.hasWritePer, [datasetDetail]);
- const { openConfirm, ConfirmModal } = useConfirm({
- content: t('common:dataset.Confirm to delete the data'),
- type: 'delete'
- });
- const onDeleteOneData = useMemoizedFn((dataId: string) => {
- openConfirm(async () => {
- try {
- await delOneDatasetDataById(dataId);
- setDatasetDataList((prev) => {
- return prev.filter((data) => data._id !== dataId);
- });
- toast({
- title: t('common:delete_success'),
- status: 'success'
- });
- } catch (error) {
- toast({
- title: getErrText(error),
- status: 'error'
- });
- }
- })();
+ const onDeleteOneData = useMemoizedFn(async (dataId: string) => {
+ try {
+ await delOneDatasetDataById(dataId);
+ setDatasetDataList((prev) => {
+ return prev.filter((data) => data._id !== dataId);
+ });
+ toast({
+ title: t('common:delete_success'),
+ status: 'success'
+ });
+ } catch (error) {
+ toast({
+ title: getErrText(error),
+ status: 'error'
+ });
+ }
});
return (
@@ -333,18 +327,24 @@ const DataCard = () => {
{getTextValidLength(item.q + item.a || '')}
{canWrite && (
- }
- variant={'whiteDanger'}
- size={'xsSquare'}
- onClick={(e) => {
- e.stopPropagation();
- onDeleteOneData(item._id);
- }}
- aria-label={''}
+ }
+ variant={'whiteDanger'}
+ size={'xsSquare'}
+ aria-label={''}
+ onClick={(e) => {
+ e.stopPropagation();
+ }}
+ />
+ }
+ content={t('common:dataset.Confirm to delete the data')}
+ type="delete"
+ onConfirm={() => onDeleteOneData(item._id)}
/>
)}
@@ -386,7 +386,6 @@ const DataCard = () => {
onClose={() => setErrorModalId('')}
/>
)}
-
);
};
diff --git a/projects/app/src/pageComponents/dataset/detail/Info/index.tsx b/projects/app/src/pageComponents/dataset/detail/Info/index.tsx
index 48079bbcf..9c2037256 100644
--- a/projects/app/src/pageComponents/dataset/detail/Info/index.tsx
+++ b/projects/app/src/pageComponents/dataset/detail/Info/index.tsx
@@ -55,10 +55,6 @@ const Info = ({ datasetId }: { datasetId: string }) => {
const vllmModelList = useMemo(() => getVlmModelList(), [getVlmModelList]);
const vlmModel = watch('vlmModel');
- const { ConfirmModal: ConfirmDelModal } = useConfirm({
- content: t('common:core.dataset.Delete Confirm'),
- type: 'delete'
- });
const { openConfirm: onOpenConfirmRebuild, ConfirmModal: ConfirmRebuildModal } = useConfirm({
title: t('common:action_confirm'),
content: t('dataset:confirm_to_rebuild_embedding_tip'),
@@ -414,7 +410,6 @@ const Info = ({ datasetId }: { datasetId: string }) => {
>
)}
-
{editedDataset && (
diff --git a/projects/app/src/pages/dashboard/mcpServer/index.tsx b/projects/app/src/pages/dashboard/mcpServer/index.tsx
index 612cf948c..21159963f 100644
--- a/projects/app/src/pages/dashboard/mcpServer/index.tsx
+++ b/projects/app/src/pages/dashboard/mcpServer/index.tsx
@@ -25,12 +25,11 @@ import EditMcpModal, {
} from '@/pageComponents/dashboard/mcp/EditModal';
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
import MyIconButton from '@fastgpt/web/components/common/Icon/button';
-import { useSystemStore } from '@/web/common/system/useSystemStore';
-import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import dynamic from 'next/dynamic';
import { type McpKeyType } from '@fastgpt/global/support/mcp/type';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { useUserStore } from '@/web/support/user/useUserStore';
+import PopoverConfirm from '@fastgpt/web/components/common/MyPopover/PopoverConfirm';
const UsageWay = dynamic(() => import('@/pageComponents/dashboard/mcp/usageWay'), {
ssr: false
@@ -52,10 +51,6 @@ const McpServer = () => {
const [editMcp, setEditMcp] = useState();
const [usageWay, setUsageWay] = useState();
- const { openConfirm: openDelConfirm, ConfirmModal: DelConfirmModal } = useConfirm({
- type: 'delete',
- content: t('dashboard_mcp:delete_mcp_server_confirm_tip')
- });
const { runAsync: onDeleteMcpServer } = useRequest2(deleteMcpServer, {
manual: true,
onSuccess: () => {
@@ -146,10 +141,19 @@ const McpServer = () => {
}
/>
- openDelConfirm(() => onDeleteMcpServer(mcp._id))()}
+
+
+
+ }
+ type="delete"
+ content={t('dashboard_mcp:delete_mcp_server_confirm_tip')}
+ onConfirm={() => onDeleteMcpServer(mcp._id)}
/>
@@ -164,7 +168,6 @@ const McpServer = () => {
)}
-
{!!usageWay && setUsageWay(undefined)} />}
{!!editMcp && (