Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: improve Route module #1715

Merged
merged 17 commits into from
Apr 9, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions docs/en/latest/I18N_USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ title: i18n User Guide

The Apache APISIX Dashboard uses [@umijs/plugin-locale](https://umijs.org/plugins/plugin-locale) to solve the i18n issues, in order to make the i18n more clear and reasonable, we would recommend to obey the following rules

## Location of locale configuration
## Location of locale configuration

- Please put **the global locales** under `src/locales`.
- Please put **each page's locale file** under `src/pages/$PAGE/locales` folder.
- Please put **the Component's locale file** under `src/components/$COMPONENT/locales` folder, and we **MUST** import them manually

## How to name the key for each locale filed
## How to name the key for each locale filed

the key can be like this : [basicModule].[moduleName].[elementName].[...desc]

Expand Down Expand Up @@ -64,7 +64,6 @@ we have already defined many global keys, before you do i18n, you can refer to [

```js
'page.route.form.itemRulesExtraMessage.parameterName': '仅支持字母和数字,且只能以字母开头',
'page.route.form.itemLabel.apiName': 'API 名称',
'page.route.form.itemRulesPatternMessage.apiNameRule': '最大长度100,仅支持字母、数字、- 和 _,且只能以字母开头',
```

Expand Down Expand Up @@ -101,7 +100,7 @@ we have already defined many global keys, before you do i18n, you can refer to [
**Example:**

```js
'page.route.steps.stepTitle.defineApiRequest': '定义 API 请求',
'page.route.steps.stepTitle.defineApiRequest': '设置路由信息',
```

- **Select**
Expand Down
4 changes: 2 additions & 2 deletions web/src/components/LabelsfDrawer/LabelsDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const LabelList = (disabled: boolean, labelList: LabelList, filterList: string[]
};

const LabelsDrawer: React.FC<Props> = ({
title = 'Label Manager',
title = "",
actionName = '',
disabled = false,
dataSource = [],
Expand All @@ -135,7 +135,7 @@ const LabelsDrawer: React.FC<Props> = ({

return (
<Drawer
title={title}
title={title || formatMessage({ id: "component.label-manager" })}
placement="right"
width={512}
visible
Expand Down
5 changes: 3 additions & 2 deletions web/src/locales/en-US/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ export default {
'component.global.name': 'Name',
'component.global.updateTime': 'UpdateAt',
'component.global.form.itemExtraMessage.nameGloballyUnique': 'Name should be globally unique',
'component.global.input.placeholder.description': 'Can not more than 256 characters',
'component.global.input.placeholder.description': 'Please enter the description for this route, max 256 characters',
// User component
'component.user.loginByPassword': 'Username & Password',
'component.user.login': 'Login',

'component.document': 'Document'
'component.document': 'Document',
'component.label-manager': 'Label Manager'
};
2 changes: 2 additions & 0 deletions web/src/locales/en-US/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,6 @@ export default {
'menu.service': 'Service',
'menu.setting': 'Settings',
'menu.serverinfo': 'System Info',
'menu.advanced-feature': 'Advanced',
'menu.more': 'More'
};
5 changes: 3 additions & 2 deletions web/src/locales/zh-CN/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ export default {
'component.global.steps.stepTitle.pluginConfig': '插件配置',
'component.global.input.ruleMessage.name': '仅支持字母、数字、- 和 _,且只能以字母开头',
'component.global.form.itemExtraMessage.nameGloballyUnique': '名称需全局唯一',
'component.global.input.placeholder.description': '不超过 256 个字符',
'component.global.input.placeholder.description': '请输入路由描述(内容不超过 256 个字符',

// User component
'component.user.loginByPassword': '账号密码登录',
'component.user.login': '登录',

'component.document': '操作手册'
'component.document': '操作手册',
'component.label-manager': '标签管理器'
};
2 changes: 2 additions & 0 deletions web/src/locales/zh-CN/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ export default {
'menu.service': '服务',
'menu.setting': '系统设置',
'menu.serverinfo': '系统信息',
'menu.advanced-feature': '高级特性',
'menu.more': '更多'
};
3 changes: 1 addition & 2 deletions web/src/pages/PluginTemplate/components/Step1.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ const Step1: React.FC<Props> = ({ form, disabled }) => {

const NormalLabelComponent = () => {
const field = 'custom_normal_labels';
const title = 'Label Manager';
return (
<React.Fragment>
<Form.Item label={formatMessage({ id: 'component.global.labels' })} name={field}>
Expand Down Expand Up @@ -74,7 +73,7 @@ const Step1: React.FC<Props> = ({ form, disabled }) => {
const labels = form.getFieldValue(field) || [];
return (
<LabelsDrawer
title={title}
title={formatMessage({ id: "component.label-manager" })}
actionName={field}
dataSource={labels}
disabled={disabled || false}
Expand Down
191 changes: 126 additions & 65 deletions web/src/pages/Route/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { ReactNode } from 'react';
import React, { useRef, useEffect, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
Expand All @@ -30,9 +31,11 @@ import {
Upload,
Modal,
Divider,
Menu,
Dropdown,
} from 'antd';
import { history, useIntl } from 'umi';
import { PlusOutlined, BugOutlined, ExportOutlined, ImportOutlined } from '@ant-design/icons';
import { PlusOutlined, BugOutlined, ExportOutlined, ImportOutlined, DownOutlined } from '@ant-design/icons';
import { js_beautify } from 'js-beautify';
import yaml from 'js-yaml';
import moment from 'moment';
Expand Down Expand Up @@ -83,6 +86,7 @@ const Page: React.FC = () => {
const [id, setId] = useState('');
const [editorMode, setEditorMode] = useState<'create' | 'update'>('create');
const [paginationConfig, setPaginationConfig] = useState({ pageSize: 10, current: 1 });
const [debugDrawVisible, setDebugDrawVisible] = useState(false);

const savePageList = (page = 1, pageSize = 10) => {
history.replace(`/routes/list?page=${page}&pageSize=${pageSize}`);
Expand All @@ -97,7 +101,7 @@ const Page: React.FC = () => {
setPaginationConfig({ pageSize: Number(pageSize), current: Number(page) });
}, [window.location.search]);

const rowSelection = {
const rowSelection: any = {
selectedRowKeys,
onChange: (currentSelectKeys: string[]) => {
setSelectedRowKeys(currentSelectKeys);
Expand Down Expand Up @@ -177,6 +181,121 @@ const Page: React.FC = () => {
});
};

const ListToolbar = () => {
const tools = [
{
name: formatMessage({ id: 'page.route.pluginTemplateConfig' }),
icon: <PlusOutlined />,
onClick: () => {
history.push('/plugin-template/list')
}
}, {
name: formatMessage({ id: 'component.global.data.editor' }),
icon: <PlusOutlined />,
onClick: () => {
setVisible(true);
setEditorMode('create');
setRawData({});
}
}, {
name: formatMessage({ id: 'page.route.button.importOpenApi' }),
icon: <ImportOutlined />,
onClick: () => {
setUploadFileList([]);
setShowImportModal(true);
}
}, {
name: formatMessage({ id: 'page.route.onlineDebug' }),
icon: <BugOutlined />,
onClick: () => {
setDebugDrawVisible(true)
}
}
]

return (
<Dropdown overlay={<Menu>
{
tools.map(item => (
<Menu.Item key={item.name} onClick={item.onClick}>
{item.icon}
{item.name}
</Menu.Item>
))
}
</Menu>}>
<Button type="dashed">
<DownOutlined /> {formatMessage({ id: "menu.advanced-feature" })}
</Button>
</Dropdown>
)
}

const RecordActionDropdown: React.FC<{ record: any }> = ({ record }) => {
const tools: {
name: string;
onClick: () => void;
icon?: ReactNode;
}[] = [
{
name: formatMessage({ id: 'component.global.view' }),
onClick: () => {
setId(record.id);
setRawData(omit(record, DELETE_FIELDS));
setVisible(true);
setEditorMode('update');
}
}, {
name: formatMessage({ id: 'component.global.duplicate' }),
onClick: () => {
history.push(`/routes/${record.id}/duplicate`)
}
}, {
name: formatMessage({ id: 'component.global.delete' }),
onClick: () => {
Modal.confirm({
type: "warning",
title: formatMessage({ id: 'component.global.popconfirm.title.delete' }),
content: (
<>
{formatMessage({ id: 'component.global.name' })} - {record.name}<br />
ID - {record.id}
</>
),
onOk: () => {
remove(record.id!).then(() => {
handleTableActionSuccessResponse(
`${formatMessage({ id: 'component.global.delete' })} ${formatMessage({
id: 'menu.routes',
})} ${formatMessage({ id: 'component.status.success' })}`,
);
});
}
})
}
}
]

return (
<Dropdown overlay={
<Menu>
{
tools.map(item => (
<Menu.Item key={item.name} onClick={item.onClick}>
{item.icon && item.icon}
{item.name}
</Menu.Item>
))
}
</Menu>
}>
<Button type="dashed">
liuxiran marked this conversation as resolved.
Show resolved Hide resolved
{formatMessage({ id: "menu.more" })}
</Button>
</Dropdown>
)
}

const ListFooter: React.FC = () => {
return (
<Popconfirm
Expand Down Expand Up @@ -208,15 +327,13 @@ const Page: React.FC = () => {
);
};

const [debugDrawVisible, setDebugDrawVisible] = useState(false);

const columns: ProColumns<RouteModule.ResponseBody>[] = [
{
title: formatMessage({ id: 'component.global.name' }),
dataIndex: 'name',
},
{
title: formatMessage({ id: 'page.route.domainName' }),
title: formatMessage({ id: 'page.route.host' }),
hideInSearch: true,
render: (_, record) => {
const list = record.hosts || (record.host && [record.host]) || [];
Expand Down Expand Up @@ -409,46 +526,15 @@ const Page: React.FC = () => {
<Button type="primary" onClick={() => history.push(`/routes/${record.id}/edit`)}>
{formatMessage({ id: 'component.global.edit' })}
</Button>
<Button type="primary" onClick={() => {
setId(record.id);
setRawData(omit(record, DELETE_FIELDS));
setVisible(true);
setEditorMode('update');
}}>
{formatMessage({ id: 'component.global.view' })}
</Button>
<Button type="primary" onClick={() => history.push(`/routes/${record.id}/duplicate`)}>
{formatMessage({ id: 'component.global.duplicate' })}
</Button>
<Popconfirm
title={formatMessage({ id: 'component.global.popconfirm.title.delete' })}
onConfirm={() => {
remove(record.id!).then(() => {
handleTableActionSuccessResponse(
`${formatMessage({ id: 'component.global.delete' })} ${formatMessage({
id: 'menu.routes',
})} ${formatMessage({ id: 'component.status.success' })}`,
);
});
}}
okButtonProps={{
danger: true,
}}
okText={formatMessage({ id: 'component.global.confirm' })}
cancelText={formatMessage({ id: 'component.global.cancel' })}
>
<Button type="primary" danger>
{formatMessage({ id: 'component.global.delete' })}
</Button>
</Popconfirm>
<RecordActionDropdown record={record} />
</Space>
</>
),
},
];

return (
<PageHeaderWrapper title={formatMessage({ id: 'page.route.list' })}>
<PageHeaderWrapper title={formatMessage({ id: 'page.route.list' })} content={formatMessage({ id: 'page.route.list.description' })}>
<ProTable<RouteModule.ResponseBody>
actionRef={ref}
rowKey="id"
Expand All @@ -464,36 +550,11 @@ const Page: React.FC = () => {
resetText: formatMessage({ id: 'component.global.reset' }),
}}
toolBarRender={() => [
<Button type="primary" onClick={() => { history.push('/plugin-template/list') }}>
<PlusOutlined />
{formatMessage({ id: 'page.route.pluginTemplateConfig' })}
</Button>,
<Button type="primary" onClick={() => history.push(`/routes/create`)}>
<PlusOutlined />
{formatMessage({ id: 'component.global.create' })}
</Button>,
<Button type="primary" onClick={() => {
setVisible(true);
setEditorMode('create');
setRawData({});
}}>
<PlusOutlined />
{formatMessage({ id: 'component.global.data.editor' })}
</Button>,
<Button
type="primary"
onClick={() => {
setUploadFileList([]);
setShowImportModal(true);
}}
>
<ImportOutlined />
{formatMessage({ id: 'page.route.button.importOpenApi' })}
</Button>,
<Button type="primary" onClick={() => setDebugDrawVisible(true)}>
<BugOutlined />
{formatMessage({ id: 'page.route.onlineDebug' })}
</Button>,
<ListToolbar />
]}
rowSelection={rowSelection}
footer={() => <ListFooter />}
Expand Down Expand Up @@ -529,7 +590,7 @@ const Page: React.FC = () => {
}}
>
<Upload
fileList={uploadFileList}
fileList={uploadFileList as any}
beforeUpload={(file) => {
setUploadFileList([file]);
return false;
Expand Down
Loading