chore: show fallback change warning
This commit is contained in:
@@ -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<ModalFooterProps> = ({
|
||||
htmlType = 'button',
|
||||
style,
|
||||
showOkBtn = true,
|
||||
styles,
|
||||
description,
|
||||
extra,
|
||||
showCancelBtn = true,
|
||||
@@ -45,7 +49,7 @@ const ModalFooter: React.FC<ModalFooterProps> = ({
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
return (
|
||||
<Wrapper>
|
||||
<Wrapper style={{ ...styles?.wrapper }}>
|
||||
<div>{description}</div>
|
||||
<Space size={20} style={{ ...style }}>
|
||||
{showCancelBtn && (
|
||||
|
||||
@@ -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.'
|
||||
};
|
||||
|
||||
@@ -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.'
|
||||
};
|
||||
|
||||
@@ -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.'
|
||||
};
|
||||
|
||||
@@ -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 路由目标的更改将在一分钟后生效。'
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<AddModalProps> = ({
|
||||
onOk,
|
||||
onCancel
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const [isChanged, setIsChanged] = React.useState(false);
|
||||
const form = useRef<any>(null);
|
||||
|
||||
const handleSubmit = () => {
|
||||
@@ -45,12 +49,37 @@ const AddProvider: React.FC<AddModalProps> = ({
|
||||
onCancel={handleCancel}
|
||||
onSubmit={handleSubmit}
|
||||
width={600}
|
||||
footer={
|
||||
<div style={{ paddingInline: 24, paddingBottom: 8 }}>
|
||||
{isChanged && (
|
||||
<AlertBlockInfo
|
||||
type="warning"
|
||||
contentStyle={{ paddingInline: 0 }}
|
||||
message={intl.formatMessage({
|
||||
id: 'routes.form.fallback.warning'
|
||||
})}
|
||||
></AlertBlockInfo>
|
||||
)}
|
||||
<ModalFooter
|
||||
onOk={handleSubmit}
|
||||
onCancel={onCancel}
|
||||
styles={{
|
||||
wrapper: {
|
||||
paddingTop: 16
|
||||
}
|
||||
}}
|
||||
></ModalFooter>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<ModelRouteForm
|
||||
ref={form}
|
||||
action={action}
|
||||
currentData={currentData}
|
||||
onFinish={onFinish}
|
||||
onFallbackChange={(changed: boolean) => {
|
||||
setIsChanged(changed);
|
||||
}}
|
||||
/>
|
||||
</FormDrawer>
|
||||
);
|
||||
|
||||
@@ -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<FormContextProps>({});
|
||||
|
||||
export const useFormContext = () => {
|
||||
const context = useContext(FormContext);
|
||||
if (!context) {
|
||||
throw new Error('useFormContext must be used within a FormProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export default FormContext;
|
||||
@@ -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<void>;
|
||||
onFallbackChange?: (changed: boolean) => void;
|
||||
}
|
||||
|
||||
const TABKeysMap = {
|
||||
@@ -34,7 +36,7 @@ const TABKeysMap = {
|
||||
};
|
||||
|
||||
const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
const { action, currentData, onFinish } = props;
|
||||
const { action, currentData, onFinish, onFallbackChange } = props;
|
||||
const intl = useIntl();
|
||||
const { getScrollElementScrollableHeight } = useWrapperContext();
|
||||
const [activeKey, setActiveKey] = useState<string[]>([TABKeysMap.BASIC]);
|
||||
@@ -175,29 +177,31 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
}}
|
||||
getScrollElementScrollableHeight={getScrollElementScrollableHeight}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
onFinish={handleOnFinish}
|
||||
initialValues={{
|
||||
categories: [],
|
||||
meta: {}
|
||||
}}
|
||||
>
|
||||
<Basic />
|
||||
<CollapsePanel
|
||||
activeKey={activeKey}
|
||||
accordion={false}
|
||||
onChange={handleOnCollapseChange}
|
||||
items={[
|
||||
{
|
||||
key: TABKeysMap.TARGETS,
|
||||
label: intl.formatMessage({ id: 'routes.form.target.title' }),
|
||||
forceRender: true,
|
||||
children: <Targets ref={targetsRef}></Targets>
|
||||
}
|
||||
]}
|
||||
></CollapsePanel>
|
||||
</Form>
|
||||
<FormContext.Provider value={{ onFallbackChange, action, currentData }}>
|
||||
<Form
|
||||
form={form}
|
||||
onFinish={handleOnFinish}
|
||||
initialValues={{
|
||||
categories: [],
|
||||
meta: {}
|
||||
}}
|
||||
>
|
||||
<Basic />
|
||||
<CollapsePanel
|
||||
activeKey={activeKey}
|
||||
accordion={false}
|
||||
onChange={handleOnCollapseChange}
|
||||
items={[
|
||||
{
|
||||
key: TABKeysMap.TARGETS,
|
||||
label: intl.formatMessage({ id: 'routes.form.target.title' }),
|
||||
forceRender: true,
|
||||
children: <Targets ref={targetsRef}></Targets>
|
||||
}
|
||||
]}
|
||||
></CollapsePanel>
|
||||
</Form>
|
||||
</FormContext.Provider>
|
||||
</ScrollSpyTabs>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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<boolean>(false);
|
||||
const form = Form.useFormInstance<FormData>();
|
||||
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) => {
|
||||
|
||||
Reference in New Issue
Block a user