From e7890dda3d78757167ca40e31cd1bad3760e312b Mon Sep 17 00:00:00 2001 From: jialin Date: Mon, 9 Feb 2026 13:23:57 +0800 Subject: [PATCH] chore: show fallback change warning --- src/components/modal-footer/index.tsx | 6 ++- src/locales/en-US/routes.ts | 4 +- src/locales/ja-JP/routes.ts | 4 +- src/locales/ru-RU/routes.ts | 4 +- src/locales/zh-CN/routes.ts | 3 +- .../components/access-control-modal/form.tsx | 5 +- .../components/add-route-modal.tsx | 31 ++++++++++- src/pages/model-routes/config/form-context.ts | 20 +++++++ src/pages/model-routes/forms/index.tsx | 52 ++++++++++--------- src/pages/model-routes/forms/targets.tsx | 17 +++++- 10 files changed, 113 insertions(+), 33 deletions(-) create mode 100644 src/pages/model-routes/config/form-context.ts diff --git a/src/components/modal-footer/index.tsx b/src/components/modal-footer/index.tsx index ae561ad0..5250590d 100644 --- a/src/components/modal-footer/index.tsx +++ b/src/components/modal-footer/index.tsx @@ -18,6 +18,9 @@ type ModalFooterProps = { extra?: React.ReactNode; form?: any; description?: React.ReactNode; + styles?: { + wrapper?: React.CSSProperties; + }; }; const Wrapper = styled.div` @@ -38,6 +41,7 @@ const ModalFooter: React.FC = ({ htmlType = 'button', style, showOkBtn = true, + styles, description, extra, showCancelBtn = true, @@ -45,7 +49,7 @@ const ModalFooter: React.FC = ({ }) => { const intl = useIntl(); return ( - +
{description}
{showCancelBtn && ( diff --git a/src/locales/en-US/routes.ts b/src/locales/en-US/routes.ts index c1c8b5f5..d235c83b 100644 --- a/src/locales/en-US/routes.ts +++ b/src/locales/en-US/routes.ts @@ -21,5 +21,7 @@ export default { 'routes.form.metadata.releaseDate': 'Release Date', 'routes.form.metadata.languages': 'Languages', 'routes.form.metadata.icons': 'Icon', - 'routes.form.metadata.uploadIcon': 'Upload Icon' + 'routes.form.metadata.uploadIcon': 'Upload Icon', + 'routes.form.fallback.warning': + 'Changes to fallback route target take effect after one minute.' }; diff --git a/src/locales/ja-JP/routes.ts b/src/locales/ja-JP/routes.ts index c1c8b5f5..d235c83b 100644 --- a/src/locales/ja-JP/routes.ts +++ b/src/locales/ja-JP/routes.ts @@ -21,5 +21,7 @@ export default { 'routes.form.metadata.releaseDate': 'Release Date', 'routes.form.metadata.languages': 'Languages', 'routes.form.metadata.icons': 'Icon', - 'routes.form.metadata.uploadIcon': 'Upload Icon' + 'routes.form.metadata.uploadIcon': 'Upload Icon', + 'routes.form.fallback.warning': + 'Changes to fallback route target take effect after one minute.' }; diff --git a/src/locales/ru-RU/routes.ts b/src/locales/ru-RU/routes.ts index c1c8b5f5..d235c83b 100644 --- a/src/locales/ru-RU/routes.ts +++ b/src/locales/ru-RU/routes.ts @@ -21,5 +21,7 @@ export default { 'routes.form.metadata.releaseDate': 'Release Date', 'routes.form.metadata.languages': 'Languages', 'routes.form.metadata.icons': 'Icon', - 'routes.form.metadata.uploadIcon': 'Upload Icon' + 'routes.form.metadata.uploadIcon': 'Upload Icon', + 'routes.form.fallback.warning': + 'Changes to fallback route target take effect after one minute.' }; diff --git a/src/locales/zh-CN/routes.ts b/src/locales/zh-CN/routes.ts index ad168308..3c824d22 100644 --- a/src/locales/zh-CN/routes.ts +++ b/src/locales/zh-CN/routes.ts @@ -21,5 +21,6 @@ export default { 'routes.form.metadata.releaseDate': '发布日期', 'routes.form.metadata.languages': '语言', 'routes.form.metadata.icons': '图标', - 'routes.form.metadata.uploadIcon': '上传图标' + 'routes.form.metadata.uploadIcon': '上传图标', + 'routes.form.fallback.warning': 'Fallback 路由目标的更改将在一分钟后生效。' }; diff --git a/src/pages/llmodels/components/access-control-modal/form.tsx b/src/pages/llmodels/components/access-control-modal/form.tsx index bee4d8e5..9784b1f4 100644 --- a/src/pages/llmodels/components/access-control-modal/form.tsx +++ b/src/pages/llmodels/components/access-control-modal/form.tsx @@ -3,6 +3,7 @@ import TooltipList from '@/components/tooltip-list'; import { PageAction } from '@/config'; import { PageActionType } from '@/config/types'; import TransferInner from '@/pages/_components/transfer'; +import { RouteItem } from '@/pages/model-routes/config/types'; import { queryUsersList } from '@/pages/users/apis'; import { DownOutlined, QuestionCircleOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; @@ -26,7 +27,7 @@ import { } from 'react'; import styled from 'styled-components'; import { queryModelAccessUserList } from '../../apis'; -import { AccessControlFormData, ListItem } from '../../config/types'; +import { AccessControlFormData } from '../../config/types'; type TransferKey = string | number | bigint; @@ -66,7 +67,7 @@ const Label = styled.div` interface AccessControlFormProps { action: PageActionType; - currentData?: ListItem | null; + currentData?: RouteItem | null; onFinish: (values: AccessControlFormData) => void; onValuesChange?: (changedValues: any, allValues: any) => void; } diff --git a/src/pages/model-routes/components/add-route-modal.tsx b/src/pages/model-routes/components/add-route-modal.tsx index 0b7160f0..19ad9242 100644 --- a/src/pages/model-routes/components/add-route-modal.tsx +++ b/src/pages/model-routes/components/add-route-modal.tsx @@ -1,8 +1,10 @@ +import AlertBlockInfo from '@/components/alert-info/block'; +import ModalFooter from '@/components/modal-footer'; import { PageActionType } from '@/config/types'; import FormDrawer from '@/pages/_components/form-drawer'; +import { useIntl } from '@umijs/max'; import React, { useRef } from 'react'; import { FormData, RouteItem as ListItem } from '../config/types'; - import ModelRouteForm from '../forms'; type AddModalProps = { @@ -21,6 +23,8 @@ const AddProvider: React.FC = ({ onOk, onCancel }) => { + const intl = useIntl(); + const [isChanged, setIsChanged] = React.useState(false); const form = useRef(null); const handleSubmit = () => { @@ -45,12 +49,37 @@ const AddProvider: React.FC = ({ onCancel={handleCancel} onSubmit={handleSubmit} width={600} + footer={ +
+ {isChanged && ( + + )} + +
+ } > { + setIsChanged(changed); + }} /> ); diff --git a/src/pages/model-routes/config/form-context.ts b/src/pages/model-routes/config/form-context.ts new file mode 100644 index 00000000..8e5738fa --- /dev/null +++ b/src/pages/model-routes/config/form-context.ts @@ -0,0 +1,20 @@ +import { PageActionType } from '@/config/types'; +import { createContext, useContext } from 'react'; + +interface FormContextProps { + onFallbackChange?: (changed: boolean) => void; + action?: PageActionType; + currentData?: any; +} + +const FormContext = createContext({}); + +export const useFormContext = () => { + const context = useContext(FormContext); + if (!context) { + throw new Error('useFormContext must be used within a FormProvider'); + } + return context; +}; + +export default FormContext; diff --git a/src/pages/model-routes/forms/index.tsx b/src/pages/model-routes/forms/index.tsx index 6d3934a7..a23f306c 100644 --- a/src/pages/model-routes/forms/index.tsx +++ b/src/pages/model-routes/forms/index.tsx @@ -14,6 +14,7 @@ import { useRef, useState } from 'react'; +import FormContext from '../config/form-context'; import { FormData, RouteItem as ListItem } from '../config/types'; import useEditTargets from '../hooks/use-edit-targets'; import Basic from './basic'; @@ -24,6 +25,7 @@ interface ProviderFormProps { action: PageActionType; currentData?: ListItem; // Used when action is EDIT onFinish: (values: FormData) => Promise; + onFallbackChange?: (changed: boolean) => void; } const TABKeysMap = { @@ -34,7 +36,7 @@ const TABKeysMap = { }; const AccessForm: React.FC = forwardRef((props, ref) => { - const { action, currentData, onFinish } = props; + const { action, currentData, onFinish, onFallbackChange } = props; const intl = useIntl(); const { getScrollElementScrollableHeight } = useWrapperContext(); const [activeKey, setActiveKey] = useState([TABKeysMap.BASIC]); @@ -175,29 +177,31 @@ const AccessForm: React.FC = forwardRef((props, ref) => { }} getScrollElementScrollableHeight={getScrollElementScrollableHeight} > -
- - - } - ]} - > - + +
+ + + } + ]} + > + +
); }); diff --git a/src/pages/model-routes/forms/targets.tsx b/src/pages/model-routes/forms/targets.tsx index d37c40d7..d33312b6 100644 --- a/src/pages/model-routes/forms/targets.tsx +++ b/src/pages/model-routes/forms/targets.tsx @@ -1,21 +1,31 @@ import MetadataList from '@/components/metadata-list'; import SealCascader from '@/components/seal-form/seal-cascader'; import SealInput from '@/components/seal-form/seal-input'; +import { PageAction } from '@/config'; import useAppUtils from '@/hooks/use-app-utils'; import { useIntl } from '@umijs/max'; import { Form } from 'antd'; import _ from 'lodash'; -import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; +import { + forwardRef, + useEffect, + useImperativeHandle, + useRef, + useState +} from 'react'; +import { useFormContext } from '../config/form-context'; import { FormData } from '../config/types'; import useTargetSourceModels from '../hooks/use-target-source-models'; const TargetsForm = forwardRef((props, ref) => { + const { onFallbackChange, action } = useFormContext(); const intl = useIntl(); const { getRuleMessage } = useAppUtils(); const { sourceModels, fetchSourceModels } = useTargetSourceModels(); const [validTriggered, setValidTriggered] = useState(false); const form = Form.useFormInstance(); const targets = Form.useWatch('targets', form) || []; + const fallbackCacheRef = useRef<{ value: any[] }>({ value: [] }); const [fallbackValues, setFallbackValues] = useState<{ value: any[] }>({ value: [] }); @@ -29,6 +39,7 @@ const TargetsForm = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ initFallbackValues: (values: { value: any[] }) => { setFallbackValues(values); + fallbackCacheRef.current = values; }, initDataList: ( list: { @@ -105,6 +116,10 @@ const TargetsForm = forwardRef((props, ref) => { setFallbackValues({ value: value }); + if (action === PageAction.EDIT) { + const isEqual = _.isEqual(fallbackCacheRef.current.value, value); + onFallbackChange?.(!isEqual); + } }; const handleOnWeightChange = (value: any, index: number) => {