Browse Source

chore: 更新tableList的antd&procomponent&umi的用法 (#10936)

* chore: 更新tableList的antd, procomponent,umi的用法

* chore: route component path   TableList -> table-list
pull/10966/head
hms181231 3 years ago
committed by GitHub
parent
commit
795119ebc7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      config/routes.ts
  2. 75
      src/pages/table-list/components/CreateForm.tsx
  3. 384
      src/pages/table-list/components/UpdateForm.tsx
  4. 222
      src/pages/table-list/index.tsx

2
config/routes.ts

@ -142,7 +142,7 @@ export default [
name: 'table-list', name: 'table-list',
icon: 'smile', icon: 'smile',
path: '/list/table-list', path: '/list/table-list',
component: './list/table-list', component: './table-list',
}, },
{ {
name: 'basic-list', name: 'basic-list',

75
src/pages/table-list/components/CreateForm.tsx

@ -0,0 +1,75 @@
import { addRule } from '@/services/ant-design-pro/api';
import { PlusOutlined } from '@ant-design/icons';
import { ActionType, ModalForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
import { Button, message } from 'antd';
import { FC } from 'react';
interface CreateFormProps {
reload?: ActionType['reload'];
}
const CreateForm: FC<CreateFormProps> = (props) => {
const { reload } = props;
const [messageApi, contextHolder] = message.useMessage();
/**
* @en-US International configuration
* @zh-CN
* */
const intl = useIntl();
const { run, loading } = useRequest(addRule, {
manual: true,
onSuccess: () => {
messageApi.success('Added successfully');
reload?.();
},
onError: () => {
messageApi.error('Adding failed, please try again!');
},
});
return (
<>
{contextHolder}
<ModalForm
title={intl.formatMessage({
id: 'pages.searchTable.createForm.newRule',
defaultMessage: 'New rule',
})}
trigger={
<Button type="primary" icon={<PlusOutlined />}>
<FormattedMessage id="pages.searchTable.new" defaultMessage="New" />
</Button>
}
width="400px"
modalProps={{ okButtonProps: { loading } }}
onFinish={async (value) => {
await run({ data: value as API.RuleListItem });
return true;
}}
>
<ProFormText
rules={[
{
required: true,
message: (
<FormattedMessage
id="pages.searchTable.ruleName"
defaultMessage="Rule name is required"
/>
),
},
]}
width="md"
name="name"
/>
<ProFormTextArea width="md" name="desc" />
</ModalForm>
</>
);
};
export default CreateForm;

384
src/pages/table-list/components/UpdateForm.tsx

@ -1,3 +1,4 @@
import { updateRule } from '@/services/ant-design-pro/api';
import { import {
ProFormDateTimePicker, ProFormDateTimePicker,
ProFormRadio, ProFormRadio,
@ -6,9 +7,9 @@ import {
ProFormTextArea, ProFormTextArea,
StepsForm, StepsForm,
} from '@ant-design/pro-components'; } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max'; import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
import { Modal } from 'antd'; import { message, Modal } from 'antd';
import React from 'react'; import React, { cloneElement, useCallback, useState } from 'react';
export type FormValueType = { export type FormValueType = {
target?: string; target?: string;
@ -19,190 +20,227 @@ export type FormValueType = {
} & Partial<API.RuleListItem>; } & Partial<API.RuleListItem>;
export type UpdateFormProps = { export type UpdateFormProps = {
onCancel: (flag?: boolean, formVals?: FormValueType) => void; trigger?: JSX.Element;
onSubmit: (values: FormValueType) => Promise<void>; onOk?: () => void;
updateModalOpen: boolean;
values: Partial<API.RuleListItem>; values: Partial<API.RuleListItem>;
}; };
const UpdateForm: React.FC<UpdateFormProps> = (props) => { const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const { onOk, values, trigger } = props;
const intl = useIntl(); const intl = useIntl();
const [open, setOpen] = useState(false);
const [messageApi, contextHolder] = message.useMessage();
const { run } = useRequest(updateRule, {
manual: true,
onSuccess: () => {
messageApi.success('Configuration is successful');
onOk?.();
},
onError: () => {
messageApi.error('Configuration failed, please try again!');
},
});
const onCancel = useCallback(() => {
setOpen(false);
}, []);
const onOpen = useCallback(() => {
setOpen(true);
}, []);
const onFinish = useCallback(
async (values?: any) => {
await run({ data: values });
onCancel();
},
[onCancel, run],
);
return ( return (
<StepsForm <>
stepsProps={{ {contextHolder}
size: 'small', {trigger
}} ? cloneElement(trigger, {
stepsFormRender={(dom, submitter) => { onClick: onOpen,
return ( })
<Modal : null}
width={640} <StepsForm
bodyStyle={{ padding: '32px 40px 48px' }} stepsProps={{
destroyOnClose size: 'small',
title={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleConfig',
defaultMessage: '规则配置',
})}
open={props.updateModalOpen}
footer={submitter}
onCancel={() => {
props.onCancel();
}}
>
{dom}
</Modal>
);
}}
onFinish={props.onSubmit}
>
<StepsForm.StepForm
initialValues={{
name: props.values.name,
desc: props.values.desc,
}} }}
title={intl.formatMessage({ stepsFormRender={(dom, submitter) => {
id: 'pages.searchTable.updateForm.basicConfig', return (
defaultMessage: '基本信息', <Modal
})} width={640}
> bodyStyle={{ padding: '32px 40px 48px' }}
<ProFormText destroyOnClose
name="name" title={intl.formatMessage({
label={intl.formatMessage({ id: 'pages.searchTable.updateForm.ruleConfig',
id: 'pages.searchTable.updateForm.ruleName.nameLabel', defaultMessage: '规则配置',
defaultMessage: '规则名称', })}
})} open={open}
width="md" footer={submitter}
rules={[ onCancel={onCancel}
{ >
required: true, {dom}
message: ( </Modal>
<FormattedMessage );
id="pages.searchTable.updateForm.ruleName.nameRules"
defaultMessage="请输入规则名称!"
/>
),
},
]}
/>
<ProFormTextArea
name="desc"
width="md"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleDesc.descLabel',
defaultMessage: '规则描述',
})}
placeholder={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleDesc.descPlaceholder',
defaultMessage: '请输入至少五个字符',
})}
rules={[
{
required: true,
message: (
<FormattedMessage
id="pages.searchTable.updateForm.ruleDesc.descRules"
defaultMessage="请输入至少五个字符的规则描述!"
/>
),
min: 5,
},
]}
/>
</StepsForm.StepForm>
<StepsForm.StepForm
initialValues={{
target: '0',
template: '0',
}} }}
title={intl.formatMessage({ onFinish={onFinish}
id: 'pages.searchTable.updateForm.ruleProps.title',
defaultMessage: '配置规则属性',
})}
> >
<ProFormSelect <StepsForm.StepForm
name="target" initialValues={values}
width="md" title={intl.formatMessage({
label={intl.formatMessage({ id: 'pages.searchTable.updateForm.basicConfig',
id: 'pages.searchTable.updateForm.object', defaultMessage: '基本信息',
defaultMessage: '监控对象',
})} })}
valueEnum={{ >
0: '表一', <ProFormText
1: '表二', name="name"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleName.nameLabel',
defaultMessage: '规则名称',
})}
width="md"
rules={[
{
required: true,
message: (
<FormattedMessage
id="pages.searchTable.updateForm.ruleName.nameRules"
defaultMessage="请输入规则名称!"
/>
),
},
]}
/>
<ProFormTextArea
name="desc"
width="md"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleDesc.descLabel',
defaultMessage: '规则描述',
})}
placeholder={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleDesc.descPlaceholder',
defaultMessage: '请输入至少五个字符',
})}
rules={[
{
required: true,
message: (
<FormattedMessage
id="pages.searchTable.updateForm.ruleDesc.descRules"
defaultMessage="请输入至少五个字符的规则描述!"
/>
),
min: 5,
},
]}
/>
</StepsForm.StepForm>
<StepsForm.StepForm
initialValues={{
target: '0',
template: '0',
}} }}
/> title={intl.formatMessage({
<ProFormSelect id: 'pages.searchTable.updateForm.ruleProps.title',
name="template" defaultMessage: '配置规则属性',
width="md"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleProps.templateLabel',
defaultMessage: '规则模板',
})} })}
valueEnum={{ >
0: '规则模板一', <ProFormSelect
1: '规则模板二', name="target"
width="md"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.object',
defaultMessage: '监控对象',
})}
valueEnum={{
0: '表一',
1: '表二',
}}
/>
<ProFormSelect
name="template"
width="md"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleProps.templateLabel',
defaultMessage: '规则模板',
})}
valueEnum={{
0: '规则模板一',
1: '规则模板二',
}}
/>
<ProFormRadio.Group
name="type"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleProps.typeLabel',
defaultMessage: '规则类型',
})}
options={[
{
value: '0',
label: '强',
},
{
value: '1',
label: '弱',
},
]}
/>
</StepsForm.StepForm>
<StepsForm.StepForm
initialValues={{
type: '1',
frequency: 'month',
}} }}
/> title={intl.formatMessage({
<ProFormRadio.Group id: 'pages.searchTable.updateForm.schedulingPeriod.title',
name="type" defaultMessage: '设定调度周期',
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.ruleProps.typeLabel',
defaultMessage: '规则类型',
})} })}
options={[ >
{ <ProFormDateTimePicker
value: '0', name="time"
label: '强', width="md"
}, label={intl.formatMessage({
{ id: 'pages.searchTable.updateForm.schedulingPeriod.timeLabel',
value: '1', defaultMessage: '开始时间',
label: '弱', })}
}, rules={[
]} {
/> required: true,
</StepsForm.StepForm> message: (
<StepsForm.StepForm <FormattedMessage
initialValues={{ id="pages.searchTable.updateForm.schedulingPeriod.timeRules"
type: '1', defaultMessage="请选择开始时间!"
frequency: 'month', />
}} ),
title={intl.formatMessage({ },
id: 'pages.searchTable.updateForm.schedulingPeriod.title', ]}
defaultMessage: '设定调度周期', />
})} <ProFormSelect
> name="frequency"
<ProFormDateTimePicker label={intl.formatMessage({
name="time" id: 'pages.searchTable.updateForm.object',
width="md" defaultMessage: '监控对象',
label={intl.formatMessage({ })}
id: 'pages.searchTable.updateForm.schedulingPeriod.timeLabel', width="md"
defaultMessage: '开始时间', valueEnum={{
})} month: '月',
rules={[ week: '周',
{ }}
required: true, />
message: ( </StepsForm.StepForm>
<FormattedMessage </StepsForm>
id="pages.searchTable.updateForm.schedulingPeriod.timeRules" </>
defaultMessage="请选择开始时间!"
/>
),
},
]}
/>
<ProFormSelect
name="frequency"
label={intl.formatMessage({
id: 'pages.searchTable.updateForm.object',
defaultMessage: '监控对象',
})}
width="md"
valueEnum={{
month: '月',
week: '周',
}}
/>
</StepsForm.StepForm>
</StepsForm>
); );
}; };

222
src/pages/table-list/index.tsx

@ -1,103 +1,21 @@
import { addRule, removeRule, rule, updateRule } from '@/services/ant-design-pro/api'; import { removeRule, rule } from '@/services/ant-design-pro/api';
import { PlusOutlined } from '@ant-design/icons';
import type { ActionType, ProColumns, ProDescriptionsItemProps } from '@ant-design/pro-components'; import type { ActionType, ProColumns, ProDescriptionsItemProps } from '@ant-design/pro-components';
import { import {
FooterToolbar, FooterToolbar,
ModalForm,
PageContainer, PageContainer,
ProDescriptions, ProDescriptions,
ProFormText,
ProFormTextArea,
ProTable, ProTable,
} from '@ant-design/pro-components'; } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max'; import { FormattedMessage, useIntl, useRequest } from '@umijs/max';
import { Button, Drawer, Input, message } from 'antd'; import { Button, Drawer, Input, message } from 'antd';
import React, { useRef, useState } from 'react'; import React, { useCallback, useRef, useState } from 'react';
import type { FormValueType } from './components/UpdateForm'; import CreateForm from './components/CreateForm';
import UpdateForm from './components/UpdateForm'; import UpdateForm from './components/UpdateForm';
/**
* @en-US Add node
* @zh-CN
* @param fields
*/
const handleAdd = async (fields: API.RuleListItem) => {
const hide = message.loading('正在添加');
try {
await addRule({ ...fields });
hide();
message.success('Added successfully');
return true;
} catch (error) {
hide();
message.error('Adding failed, please try again!');
return false;
}
};
/**
* @en-US Update node
* @zh-CN
*
* @param fields
*/
const handleUpdate = async (fields: FormValueType) => {
const hide = message.loading('Configuring');
try {
await updateRule({
name: fields.name,
desc: fields.desc,
key: fields.key,
});
hide();
message.success('Configuration is successful');
return true;
} catch (error) {
hide();
message.error('Configuration failed, please try again!');
return false;
}
};
/**
* Delete node
* @zh-CN
*
* @param selectedRows
*/
const handleRemove = async (selectedRows: API.RuleListItem[]) => {
const hide = message.loading('正在删除');
if (!selectedRows) return true;
try {
await removeRule({
key: selectedRows.map((row) => row.key),
});
hide();
message.success('Deleted successfully and will refresh soon');
return true;
} catch (error) {
hide();
message.error('Delete failed, please try again');
return false;
}
};
const TableList: React.FC = () => { const TableList: React.FC = () => {
/** const actionRef = useRef<ActionType>();
* @en-US Pop-up window of new window
* @zh-CN
* */
const [createModalOpen, handleModalOpen] = useState<boolean>(false);
/**
* @en-US The pop-up window of the distribution update window
* @zh-CN
* */
const [updateModalOpen, handleUpdateModalOpen] = useState<boolean>(false);
const [showDetail, setShowDetail] = useState<boolean>(false); const [showDetail, setShowDetail] = useState<boolean>(false);
const actionRef = useRef<ActionType>();
const [currentRow, setCurrentRow] = useState<API.RuleListItem>(); const [currentRow, setCurrentRow] = useState<API.RuleListItem>();
const [selectedRowsState, setSelectedRows] = useState<API.RuleListItem[]>([]); const [selectedRowsState, setSelectedRows] = useState<API.RuleListItem[]>([]);
@ -107,6 +25,21 @@ const TableList: React.FC = () => {
* */ * */
const intl = useIntl(); const intl = useIntl();
const [messageApi, contextHolder] = message.useMessage();
const { run: delRun, loading } = useRequest(removeRule, {
manual: true,
onSuccess: () => {
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
messageApi.success('Deleted successfully and will refresh soon');
},
onError: () => {
messageApi.error('Delete failed, please try again');
},
});
const columns: ProColumns<API.RuleListItem>[] = [ const columns: ProColumns<API.RuleListItem>[] = [
{ {
title: ( title: (
@ -222,15 +155,16 @@ const TableList: React.FC = () => {
dataIndex: 'option', dataIndex: 'option',
valueType: 'option', valueType: 'option',
render: (_, record) => [ render: (_, record) => [
<a <UpdateForm
trigger={
<a>
<FormattedMessage id="pages.searchTable.config" defaultMessage="Configuration" />
</a>
}
key="config" key="config"
onClick={() => { onOk={actionRef.current?.reload}
handleUpdateModalOpen(true); values={record}
setCurrentRow(record); />,
}}
>
<FormattedMessage id="pages.searchTable.config" defaultMessage="Configuration" />
</a>,
<a key="subscribeAlert" href="https://procomponents.ant.design/"> <a key="subscribeAlert" href="https://procomponents.ant.design/">
<FormattedMessage <FormattedMessage
id="pages.searchTable.subscribeAlert" id="pages.searchTable.subscribeAlert"
@ -241,8 +175,32 @@ const TableList: React.FC = () => {
}, },
]; ];
/**
* Delete node
* @zh-CN
*
* @param selectedRows
*/
const handleRemove = useCallback(
async (selectedRows: API.RuleListItem[]) => {
if (!selectedRows?.length) {
messageApi.warning('请选择删除项');
return;
}
await delRun({
data: {
key: selectedRows.map((row) => row.key),
},
});
},
[delRun],
);
return ( return (
<PageContainer> <PageContainer>
{contextHolder}
<ProTable<API.RuleListItem, API.PageParams> <ProTable<API.RuleListItem, API.PageParams>
headerTitle={intl.formatMessage({ headerTitle={intl.formatMessage({
id: 'pages.searchTable.title', id: 'pages.searchTable.title',
@ -253,17 +211,7 @@ const TableList: React.FC = () => {
search={{ search={{
labelWidth: 120, labelWidth: 120,
}} }}
toolBarRender={() => [ toolBarRender={() => [<CreateForm key="create" reload={actionRef.current?.reload} />]}
<Button
type="primary"
key="primary"
onClick={() => {
handleModalOpen(true);
}}
>
<PlusOutlined /> <FormattedMessage id="pages.searchTable.new" defaultMessage="New" />
</Button>,
]}
request={rule} request={rule}
columns={columns} columns={columns}
rowSelection={{ rowSelection={{
@ -292,10 +240,9 @@ const TableList: React.FC = () => {
} }
> >
<Button <Button
onClick={async () => { loading={loading}
await handleRemove(selectedRowsState); onClick={() => {
setSelectedRows([]); handleRemove(selectedRowsState);
actionRef.current?.reloadAndRest?.();
}} }}
> >
<FormattedMessage <FormattedMessage
@ -311,61 +258,6 @@ const TableList: React.FC = () => {
</Button> </Button>
</FooterToolbar> </FooterToolbar>
)} )}
<ModalForm
title={intl.formatMessage({
id: 'pages.searchTable.createForm.newRule',
defaultMessage: 'New rule',
})}
width="400px"
open={createModalOpen}
onOpenChange={handleModalOpen}
onFinish={async (value) => {
const success = await handleAdd(value as API.RuleListItem);
if (success) {
handleModalOpen(false);
if (actionRef.current) {
actionRef.current.reload();
}
}
}}
>
<ProFormText
rules={[
{
required: true,
message: (
<FormattedMessage
id="pages.searchTable.ruleName"
defaultMessage="Rule name is required"
/>
),
},
]}
width="md"
name="name"
/>
<ProFormTextArea width="md" name="desc" />
</ModalForm>
<UpdateForm
onSubmit={async (value) => {
const success = await handleUpdate(value);
if (success) {
handleUpdateModalOpen(false);
setCurrentRow(undefined);
if (actionRef.current) {
actionRef.current.reload();
}
}
}}
onCancel={() => {
handleUpdateModalOpen(false);
if (!showDetail) {
setCurrentRow(undefined);
}
}}
updateModalOpen={updateModalOpen}
values={currentRow || {}}
/>
<Drawer <Drawer
width={600} width={600}

Loading…
Cancel
Save