├── src ├── assets │ ├── bg.jpg │ ├── logo.png │ ├── welcome.jpg │ ├── support-apache.png │ └── logo.svg ├── components │ ├── Exception │ │ ├── demo │ │ │ ├── 404.md │ │ │ ├── 500.md │ │ │ └── 403.md │ │ ├── index.zh-CN.md │ │ ├── index.en-US.md │ │ ├── index.d.ts │ │ ├── typeConfig.js │ │ ├── index.js │ │ └── index.less │ ├── GlobalFooter │ │ ├── index.md │ │ ├── demo │ │ │ └── basic.md │ │ ├── index.d.ts │ │ ├── index.less │ │ └── index.js │ ├── CountDown │ │ ├── index.zh-CN.md │ │ ├── index.en-US.md │ │ ├── demo │ │ │ └── simple.md │ │ └── index.d.ts │ ├── Authorized │ │ ├── demo │ │ │ ├── basic.md │ │ │ ├── secured.md │ │ │ ├── AuthorizedArray.md │ │ │ └── AuthorizedFunction.md │ │ ├── index.js │ │ ├── Authorized.js │ │ ├── renderAuthorize.js │ │ ├── AuthorizedRoute.js │ │ ├── index.d.ts │ │ ├── index.md │ │ ├── Secured.js │ │ ├── PromiseRender.js │ │ ├── CheckPermissions.js │ │ └── CheckPermissions.test.js │ ├── PageHeader │ │ ├── demo │ │ │ ├── simple.md │ │ │ ├── structure.md │ │ │ ├── image.md │ │ │ └── standard.md │ │ ├── index.md │ │ ├── index.d.ts │ │ └── index.test.js │ ├── Result │ │ ├── demo │ │ │ ├── structure.md │ │ │ ├── error.md │ │ │ └── classic.md │ │ ├── index.md │ │ ├── index.d.ts │ │ ├── index.js │ │ └── index.less │ ├── tsconfig.json │ ├── _utils │ │ ├── pathTools.js │ │ ├── pathTools.test.js │ │ └── utils.ts │ ├── Login │ │ ├── index.zh-CN.md │ │ ├── LoginSubmit.js │ │ ├── index.en-US.md │ │ ├── LoginTab.js │ │ ├── index.d.ts │ │ ├── index.less │ │ ├── LoginCode.tsx │ │ ├── map.js │ │ └── demo │ │ │ └── basic.md │ ├── SiderMenu │ │ ├── index.js │ │ ├── SilderMenu.test.js │ │ └── index.less │ └── GlobalHeader │ │ └── ImportResultModal.js ├── layouts │ ├── BlankLayout.js │ ├── PageHeaderLayout.less │ ├── PageHeaderLayout.js │ └── UserLayout.less ├── routes │ ├── System │ │ ├── Alert │ │ │ └── globalData.js │ │ ├── Resource │ │ │ ├── index.less │ │ │ └── IconModal.less │ │ ├── Scale │ │ │ └── globalData.js │ │ └── AppAuth │ │ │ ├── index.less │ │ │ ├── RelateMetadata.js │ │ │ └── SearchContent.js │ ├── Exception │ │ ├── style.less │ │ ├── 403.js │ │ ├── 404.js │ │ ├── 500.js │ │ └── triggerException.js │ ├── Document │ │ └── components │ │ │ ├── ApiContext.js │ │ │ ├── globalData.js │ │ │ └── HeadersEditor.js │ ├── Result │ │ ├── Success.test.js │ │ └── Error.js │ ├── Plugin │ │ ├── PluginRuleHandle │ │ │ └── index.js │ │ ├── Discovery │ │ │ └── discovery.less │ │ └── Common │ │ │ └── ComposeRuleHandle.js │ ├── User │ │ └── Login.less │ └── Home │ │ └── home.less ├── services │ ├── error.js │ └── user.js ├── utils │ ├── emit.js │ ├── locales.js │ ├── IntlUtils.js │ ├── resizable.js │ ├── utils.less │ ├── download.js │ └── plugin.js ├── theme.js ├── models │ ├── index.js │ ├── user.js │ ├── error.js │ ├── mcpServer.js │ └── instance.js ├── rollbar.js ├── polyfill.js ├── e2e │ ├── home.e2e.js │ └── login.e2e.js ├── index.ejs ├── router.js └── index.js ├── jsconfig.json ├── public └── favicon.ico ├── .stylelintrc.json ├── NOTICE ├── .gitpod.Dockerfile ├── .gitignore ├── DISCLAIMER ├── .github ├── release-drafter-config.yml └── workflows │ ├── release-drafter.yml │ ├── build.yml │ └── deploy.yml ├── .editorconfig ├── tsconfig.json ├── .babelrc.js ├── README.md ├── .devcontainer └── devcontainer.json ├── .gitpod.yml ├── tests ├── fix_puppeteer.sh └── run-tests.js ├── .asf.yaml ├── .webpackrc.js ├── .eslintrc.js └── .roadhogrc.mock.js /src/assets/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/shenyu-dashboard/HEAD/src/assets/bg.jpg -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true, 4 | } 5 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/shenyu-dashboard/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/shenyu-dashboard/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/welcome.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/shenyu-dashboard/HEAD/src/assets/welcome.jpg -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "warning", 3 | "extends": "stylelint-config-standard" 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/support-apache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/shenyu-dashboard/HEAD/src/assets/support-apache.png -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Apache ShenYu (incubating) 2 | Copyright 2021-2022 The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /.gitpod.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gitpod/workspace-full 2 | 3 | USER gitpod 4 | 5 | RUN bash -c ". /home/gitpod/.sdkman/bin/sdkman-init.sh && \ 6 | sdk install java 17.0.3-ms && \ 7 | sdk default java 17.0.3-ms" 8 | -------------------------------------------------------------------------------- /src/components/Exception/demo/404.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 4 | zh-CN: 404 5 | en-US: 404 6 | --- 7 | 8 | ## zh-CN 9 | 10 | 404 页面。 11 | 12 | ## en-US 13 | 14 | 404 page. 15 | 16 | ````jsx 17 | import Exception from 'ant-design-pro/lib/Exception'; 18 | 19 | ReactDOM.render( 20 | 21 | , mountNode); 22 | ```` 23 | -------------------------------------------------------------------------------- /src/components/Exception/demo/500.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | title: 4 | zh-CN: 500 5 | en-US: 500 6 | --- 7 | 8 | ## zh-CN 9 | 10 | 500 页面。 11 | 12 | ## en-US 13 | 14 | 500 page. 15 | 16 | ````jsx 17 | import Exception from 'ant-design-pro/lib/Exception'; 18 | 19 | ReactDOM.render( 20 | 21 | , mountNode); 22 | ```` 23 | -------------------------------------------------------------------------------- /src/components/GlobalFooter/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 3 | en-US: GlobalFooter 4 | zh-CN: GlobalFooter 5 | subtitle: 全局页脚 6 | cols: 1 7 | order: 7 8 | --- 9 | 10 | 页脚属于全局导航的一部分,作为对顶部导航的补充,通过传递数据控制展示内容。 11 | 12 | ## API 13 | 14 | 参数 | 说明 | 类型 | 默认值 15 | ----|------|-----|------ 16 | links | 链接数据 | array<{ title: ReactNode, href: string, blankTarget?: boolean }> | - 17 | copyright | 版权信息 | ReactNode | - 18 | -------------------------------------------------------------------------------- /src/components/CountDown/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CountDown 3 | subtitle: 倒计时 4 | cols: 1 5 | order: 3 6 | --- 7 | 8 | 倒计时组件。 9 | 10 | ## API 11 | 12 | | 参数 | 说明 | 类型 | 默认值 | 13 | |----------|------------------------------------------|-------------|-------| 14 | | format | 时间格式化显示 | Function(time) | | 15 | | target | 目标时间 | Date | - | 16 | | onEnd | 倒计时结束回调 | funtion | -| 17 | -------------------------------------------------------------------------------- /src/components/CountDown/index.en-US.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CountDown 3 | cols: 1 4 | order: 3 5 | --- 6 | 7 | Simple CountDown Component. 8 | 9 | ## API 10 | 11 | | Property | Description | Type | Default | 12 | |----------|------------------------------------------|-------------|-------| 13 | | format | Formatter of time | Function(time) | | 14 | | target | Target time | Date | - | 15 | | onEnd | Countdown to the end callback | funtion | -| 16 | -------------------------------------------------------------------------------- /src/components/CountDown/demo/simple.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 4 | zh-CN: 基本 5 | en-US: Basic 6 | --- 7 | 8 | ## zh-CN 9 | 10 | 简单的倒计时组件使用。 11 | 12 | ## en-US 13 | 14 | The simplest usage. 15 | 16 | ````jsx 17 | import CountDown from 'ant-design-pro/lib/CountDown'; 18 | 19 | const targetTime = new Date().getTime() + 3900000; 20 | 21 | ReactDOM.render( 22 | 23 | , mountNode); 24 | ```` 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | # roadhog-api-doc ignore 6 | /src/utils/request-temp.js 7 | _roadhog-api-doc 8 | 9 | # production 10 | /.vscode 11 | 12 | # misc 13 | .DS_Store 14 | npm-debug.log* 15 | yarn-error.log 16 | 17 | /coverage 18 | .idea 19 | yarn.lock 20 | pnpm-lock.yaml 21 | *bak 22 | 23 | # visual studio 24 | .history 25 | dist/* 26 | 27 | # Private individual user cursor rules 28 | .cursor/rules/_*.mdc 29 | -------------------------------------------------------------------------------- /DISCLAIMER: -------------------------------------------------------------------------------- 1 | Apache ShenYu (incubating) is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC. 2 | Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, 3 | communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. 4 | While incubation status is not necessarily a reflection of the completeness or stability of the code, 5 | it does indicate that the project has yet to be fully endorsed by the ASF. 6 | -------------------------------------------------------------------------------- /src/components/Exception/demo/403.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | title: 4 | zh-CN: 403 5 | en-US: 403 6 | --- 7 | 8 | ## zh-CN 9 | 10 | 403 页面,配合自定义操作。 11 | 12 | ## en-US 13 | 14 | 403 page with custom operations. 15 | 16 | ````jsx 17 | import Exception from 'ant-design-pro/lib/Exception'; 18 | import { Button } from 'antd'; 19 | 20 | const actions = ( 21 |
22 | 23 | 24 |
25 | ); 26 | ReactDOM.render( 27 | 28 | , mountNode); 29 | ```` 30 | -------------------------------------------------------------------------------- /src/components/Authorized/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 4 | zh-CN: 基本使用 5 | en-US: Basic use 6 | --- 7 | 8 | Basic use 9 | 10 | ```jsx 11 | import RenderAuthorized from 'ant-design-pro/lib/Authorized'; 12 | import { Alert } from 'antd'; 13 | 14 | const Authorized = RenderAuthorized('user'); 15 | const noMatch = ; 16 | 17 | ReactDOM.render( 18 |
19 | 20 | 21 | 22 |
, 23 | mountNode, 24 | ); 25 | ``` 26 | -------------------------------------------------------------------------------- /src/components/Authorized/demo/secured.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 3 3 | title: 4 | zh-CN: 注解基本使用 5 | en-US: Basic use secured 6 | --- 7 | 8 | secured demo used 9 | 10 | ```jsx 11 | import RenderAuthorized from 'ant-design-pro/lib/Authorized'; 12 | import { Alert } from 'antd'; 13 | 14 | const { Secured } = RenderAuthorized('user'); 15 | 16 | @Secured('admin') 17 | class TestSecuredString extends React.Component { 18 | render() { 19 | ; 20 | } 21 | } 22 | ReactDOM.render( 23 |
24 | 25 |
, 26 | mountNode, 27 | ); 28 | ``` 29 | -------------------------------------------------------------------------------- /src/components/PageHeader/demo/simple.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 3 3 | title: Simple 4 | --- 5 | 6 | 简单的页头。 7 | 8 | ````jsx 9 | import PageHeader from 'ant-design-pro/lib/PageHeader'; 10 | 11 | const breadcrumbList = [{ 12 | title: '一级菜单', 13 | href: '/', 14 | }, { 15 | title: '二级菜单', 16 | href: '/', 17 | }, { 18 | title: '三级菜单', 19 | }]; 20 | 21 | ReactDOM.render( 22 |
23 | 24 |
25 | , mountNode); 26 | ```` 27 | 28 | 33 | -------------------------------------------------------------------------------- /src/components/Result/demo/structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: Structure 4 | --- 5 | 6 | 结构包含 `处理结果`,`补充信息` 以及 `操作建议` 三个部分,其中 `处理结果` 由 `提示图标`,`标题` 和 `结果描述` 组成。 7 | 8 | ````jsx 9 | import Result from 'ant-design-pro/lib/Result'; 10 | 11 | ReactDOM.render( 12 | 标题} 15 | description={
结果描述
} 16 | extra="其他补充信息,自带灰底效果" 17 | actions={
操作建议,一般放置按钮组
} 18 | /> 19 | , mountNode); 20 | ```` 21 | -------------------------------------------------------------------------------- /src/components/Result/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 3 | en-US: Result 4 | zh-CN: Result 5 | subtitle: 处理结果 6 | cols: 1 7 | order: 12 8 | --- 9 | 10 | 结果页用于对用户进行的一系列任务处理结果进行反馈。 11 | 12 | ## API 13 | 14 | | 参数 | 说明 | 类型 | 默认值 | 15 | |----------|------------------------------------------|-------------|-------| 16 | | type | 类型,不同类型自带对应的图标 | Enum {'success', 'error'} | - | 17 | | title | 标题 | ReactNode | - | 18 | | description | 结果描述 | ReactNode | - | 19 | | extra | 补充信息,有默认的灰色背景 | ReactNode | - | 20 | | actions | 操作建议,推荐放置跳转链接,按钮组等 | ReactNode | - | 21 | -------------------------------------------------------------------------------- /.github/release-drafter-config.yml: -------------------------------------------------------------------------------- 1 | name-template: '$NEXT_PATCH_VERSION' 2 | tag-template: '$NEXT_PATCH_VERSION' 3 | categories: 4 | - title: 'Features' 5 | labels: 6 | - 'type: new feature' 7 | - 'type: enhancement' 8 | - title: 'Bug Fixes' 9 | labels: 10 | - 'type: bug' 11 | - 'bug' 12 | - title: 'Maintenance' 13 | label: 'type: refactor' 14 | change-template: '- $TITLE #$NUMBER' 15 | exclude-labels: 16 | - 'skip-changelog' 17 | template: | 18 | ## What’s Changed 19 | 20 | $CHANGES 21 | 22 | ## Contributors 23 | We'd like to thank all the contributors who worked on this release! 24 | 25 | $CONTRIBUTORS 26 | -------------------------------------------------------------------------------- /src/components/Authorized/demo/AuthorizedArray.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | title: 4 | zh-CN: 使用数组作为参数 5 | en-US: Use Array as a parameter 6 | --- 7 | 8 | Use Array as a parameter 9 | 10 | ```jsx 11 | import RenderAuthorized from 'ant-design-pro/lib/Authorized'; 12 | import { Alert } from 'antd'; 13 | 14 | const Authorized = RenderAuthorized('user'); 15 | const noMatch = ; 16 | 17 | ReactDOM.render( 18 | 19 | 20 | , 21 | mountNode, 22 | ); 23 | ``` 24 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - master 8 | 9 | jobs: 10 | update_release_draft: 11 | runs-on: ubuntu-latest 12 | steps: 13 | # Drafts your next Release notes as Pull Requests are merged into "master" 14 | - uses: release-drafter/release-drafter@v5 15 | with: 16 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml 17 | config-name: release-drafter-config.yml 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | paths-ignore: 9 | - "**.md" 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | node-version: [12.x, 14.x, 16.x, 18.x, 20.x] 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Use Node.js ${{ matrix.node-version }} 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - run: npm install 24 | - run: npm run lint 25 | if: matrix.node-version == '20.x' 26 | - run: npm run build --if-present 27 | -------------------------------------------------------------------------------- /src/components/Exception/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Exception 3 | subtitle: 异常 4 | cols: 1 5 | order: 5 6 | --- 7 | 8 | 异常页用于对页面特定的异常状态进行反馈。通常,它包含对错误状态的阐述,并向用户提供建议或操作,避免用户感到迷失和困惑。 9 | 10 | ## API 11 | 12 | | 参数 | 说明 | 类型 | 默认值 | 13 | |-------------|------------------------------------------|-------------|-------| 14 | | type | 页面类型,若配置,则自带对应类型默认的 `title`,`desc`,`img`,此默认设置可以被 `title`,`desc`,`img` 覆盖 | Enum {'403', '404', '500'} | - | 15 | | title | 标题 | ReactNode | - | 16 | | desc | 补充描述 | ReactNode | - | 17 | | img | 背景图片地址 | string | - | 18 | | actions | 建议操作,配置此属性时默认的『返回首页』按钮不生效 | ReactNode | - | 19 | | linkElement | 定义链接的元素 | string\|ReactElement | 'a' | 20 | -------------------------------------------------------------------------------- /src/components/Authorized/demo/AuthorizedFunction.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | title: 4 | zh-CN: 使用方法作为参数 5 | en-US: Use function as a parameter 6 | --- 7 | 8 | Use Function as a parameter 9 | 10 | ```jsx 11 | import RenderAuthorized from 'ant-design-pro/lib/Authorized'; 12 | import { Alert } from 'antd'; 13 | 14 | const Authorized = RenderAuthorized('user'); 15 | const noMatch = ; 16 | 17 | const havePermission = () => { 18 | return false; 19 | }; 20 | 21 | ReactDOM.render( 22 | 23 | 28 | , 29 | mountNode, 30 | ); 31 | ``` 32 | -------------------------------------------------------------------------------- /src/components/GlobalFooter/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 演示 4 | iframe: 400 5 | --- 6 | 7 | 基本页脚。 8 | 9 | ````jsx 10 | import GlobalFooter from 'ant-design-pro/lib/GlobalFooter'; 11 | import { Icon } from 'antd'; 12 | 13 | const links = [{ 14 | key: '帮助', 15 | title: '帮助', 16 | href: '', 17 | }, { 18 | key: 'github', 19 | title: , 20 | href: 'https://github.com/ant-design/ant-design-pro', 21 | blankTarget: true, 22 | }, { 23 | key: '条款', 24 | title: '条款', 25 | href: '', 26 | blankTarget: true, 27 | }]; 28 | 29 | const copyright =
Copyright 2017 蚂蚁金服体验技术部出品
; 30 | 31 | ReactDOM.render( 32 |
33 |
34 | 35 |
36 | , mountNode); 37 | ```` 38 | -------------------------------------------------------------------------------- /src/components/Exception/index.en-US.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Exception 3 | cols: 1 4 | order: 5 5 | --- 6 | 7 | Exceptions page is used to provide feedback on specific abnormal state. Usually, it contains an explanation of the error status, and provides users with suggestions or operations, to prevent users from feeling lost and confused. 8 | 9 | ## API 10 | 11 | Property | Description | Type | Default 12 | ---------|-------------|------|-------- 13 | type | type of exception, the corresponding default `title`, `desc`, `img` will be given if set, which can be overridden by explicit setting of `title`, `desc`, `img` | Enum {'403', '404', '500'} | - 14 | title | title | ReactNode | - 15 | desc | supplementary description | ReactNode | - 16 | img | the url of background image | string | - 17 | actions | suggested operations, a default 'Home' link will show if not set | ReactNode | - 18 | linkElement | to specify the element of link | string\|ReactElement | 'a' -------------------------------------------------------------------------------- /src/layouts/BlankLayout.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | 20 | export default (props) =>
; 21 | -------------------------------------------------------------------------------- /src/routes/System/Alert/globalData.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | export const Type = { 19 | 1: "SHENYU.SYSTEM.ALERT.EMAIL", 20 | 5: "SHENYU.SYSTEM.ALERT.DING_TALK", 21 | }; 22 | -------------------------------------------------------------------------------- /src/services/error.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import request from "../utils/request"; 19 | 20 | export async function query(code) { 21 | return request(`/api/${code}`); 22 | } 23 | -------------------------------------------------------------------------------- /src/routes/Exception/style.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | .trigger { 19 | background: 'red'; 20 | :global(.ant-btn) { 21 | margin-right: 8px; 22 | margin-bottom: 12px; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/emit.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | const EventEmitter = require("events").EventEmitter; 19 | 20 | const emit = new EventEmitter(); 21 | emit.setMaxListeners(50); 22 | export { emit }; 23 | -------------------------------------------------------------------------------- /src/routes/System/Resource/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | .headerSearch { 19 | display: flex; 20 | justify-content: space-between; 21 | margin-left: 1px; 22 | 23 | .search { 24 | margin-right: 10px; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/utils/locales.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import enUs from "../locales/en-US.json"; 19 | import zhCn from "../locales/zh-CN.json"; 20 | 21 | const locales = { 22 | "en-US": enUs, 23 | "zh-CN": zhCn, 24 | }; 25 | 26 | export default locales; 27 | -------------------------------------------------------------------------------- /src/components/Result/demo/error.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | title: Failed 4 | --- 5 | 6 | 提交失败。 7 | 8 | ````jsx 9 | import Result from 'ant-design-pro/lib/Result'; 10 | import { Button, Icon } from 'antd'; 11 | 12 | const extra = ( 13 |
14 |
15 | 您提交的内容有如下错误: 16 |
17 |
18 | 您的账户已被冻结 19 | 立即解冻 20 |
21 |
22 | 您的账户还不具备申请资格 23 | 立即升级 24 |
25 |
26 | ); 27 | 28 | const actions = ; 29 | 30 | ReactDOM.render( 31 | 38 | , mountNode); 39 | ```` 40 | -------------------------------------------------------------------------------- /src/services/user.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import request from "../utils/request"; 19 | 20 | export async function query() { 21 | return request("/api/users"); 22 | } 23 | 24 | export async function queryCurrent() { 25 | return request("/api/currentUser"); 26 | } 27 | -------------------------------------------------------------------------------- /src/layouts/PageHeaderLayout.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import '~antd/lib/style/themes/default.less'; 19 | 20 | .content { 21 | margin: 24px 24px 0; 22 | } 23 | 24 | @media screen and (max-width: @screen-sm) { 25 | .content { 26 | margin: 24px 0 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: dashboard Deploy 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | 9 | jobs: 10 | build_and_deploy_job: 11 | runs-on: ubuntu-latest 12 | name: Build and Deploy Job 13 | steps: 14 | - 15 | name: Checkout Code 16 | uses: actions/checkout@v2 17 | with: 18 | submodules: recursive 19 | - 20 | name: Setup Node 21 | uses: actions/setup-node@v2.4.0 22 | with: 23 | node-version: "20" 24 | - 25 | name: Setup Dependencies 26 | run: yarn install 27 | - 28 | name: Build Site 29 | run: npm run build 30 | - 31 | name: Deploy 32 | uses: peaceiris/actions-gh-pages@v3 33 | if: github.event_name == 'push' && github.ref == 'refs/heads/master' 34 | with: 35 | github_token: ${{ secrets.GITHUB_TOKEN }} 36 | user_name: 'github-actions[bot]' 37 | user_email: 'github-actions[bot]@users.noreply.github.com' 38 | publish_branch: dist 39 | publish_dir: ./dist 40 | 41 | -------------------------------------------------------------------------------- /src/routes/Document/components/ApiContext.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* eslint-disable no-unused-vars */ 19 | 20 | import { createContext } from "react"; 21 | 22 | export default createContext({ 23 | apiDetail: {}, 24 | apiData: {}, 25 | apiMock: {}, 26 | tagDetail: {}, 27 | }); 28 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one or more 3 | # contributor license agreements. See the NOTICE file distributed with 4 | # this work for additional information regarding copyright ownership. 5 | # The ASF licenses this file to You under the Apache License, Version 2.0 6 | # (the "License"); you may not use this file except in compliance with 7 | # the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | root = true 19 | 20 | [*] 21 | indent_style = space 22 | indent_size = 2 23 | end_of_line = lf 24 | charset = utf-8 25 | trim_trailing_whitespace = true 26 | insert_final_newline = true 27 | 28 | [*.md] 29 | trim_trailing_whitespace = false 30 | 31 | [Makefile] 32 | indent_style = tab 33 | -------------------------------------------------------------------------------- /src/components/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | { 18 | "include": [ 19 | "./src/*" 20 | ], 21 | "compilerOptions": { 22 | "strict": true, 23 | "esModuleInterop": true, 24 | "lib": [ 25 | "dom", 26 | "es2015" 27 | ], 28 | "jsx": "react-jsx" 29 | } 30 | } -------------------------------------------------------------------------------- /src/routes/Exception/403.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Link } from "dva/router"; 20 | import Exception from "components/Exception"; 21 | 22 | export default () => ( 23 | 28 | ); 29 | -------------------------------------------------------------------------------- /src/routes/Exception/404.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Link } from "dva/router"; 20 | import Exception from "components/Exception"; 21 | 22 | export default () => ( 23 | 28 | ); 29 | -------------------------------------------------------------------------------- /src/routes/Exception/500.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Link } from "dva/router"; 20 | import Exception from "components/Exception"; 21 | 22 | export default () => ( 23 | 28 | ); 29 | -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | // https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less 19 | module.exports = { 20 | "primary-color": "#1890ff", 21 | "card-actions-background": "#f5f8fa", 22 | "table-row-hover-bg": "lighten(@primary-color, 25%)", 23 | "form-item-margin-bottom": "12px", 24 | }; 25 | -------------------------------------------------------------------------------- /src/components/_utils/pathTools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | // /userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id'] 19 | export function urlToList(url) { 20 | const urllist = url.split("/").filter((i) => i); 21 | return urllist.map((urlItem, index) => { 22 | return `/${urllist.slice(0, index + 1).join("/")}`; 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /src/components/CountDown/index.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import * as React from 'react'; 19 | export interface ICountDownProps { 20 | format?: (time: number) => void; 21 | target: Date | number; 22 | onEnd?: () => void; 23 | style?: React.CSSProperties; 24 | } 25 | 26 | export default class CountDown extends React.Component {} 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | { 18 | "include": [ 19 | "./src/*" 20 | ], 21 | "compilerOptions": { 22 | "strict": true, 23 | "esModuleInterop": true, 24 | "experimentalDecorators": true, 25 | "lib": [ 26 | "dom", 27 | "es2015" 28 | ], 29 | "jsx": "react" 30 | } 31 | } -------------------------------------------------------------------------------- /src/models/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | // Use require.context to require reducers automatically 19 | // Ref: https://webpack.js.org/guides/dependency-management/#require-context 20 | const context = require.context("./", false, /\.js$/); 21 | export default context 22 | .keys() 23 | .filter((item) => item !== "./index.js") 24 | .map((key) => context(key)); 25 | -------------------------------------------------------------------------------- /src/routes/Result/Success.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { shallow } from "enzyme"; 20 | import Success from "./Success"; 21 | 22 | it("renders with Result", () => { 23 | const wrapper = shallow(); 24 | expect(wrapper.find("Result").length).toBe(1); 25 | expect(wrapper.find("Result").prop("type")).toBe("success"); 26 | }); 27 | -------------------------------------------------------------------------------- /src/components/Login/index.zh-CN.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Login 3 | subtitle: 登录 4 | cols: 1 5 | order: 15 6 | --- 7 | 8 | 支持多种登录方式切换,内置了几种常见的登录控件,可以灵活组合,也支持和自定义控件配合使用。 9 | 10 | ## API 11 | 12 | ### Login 13 | 14 | 参数 | 说明 | 类型 | 默认值 15 | ----|------|-----|------ 16 | defaultActiveKey | 默认激活 tab 面板的 key | String | - 17 | onTabChange | 切换页签时的回调 | (key) => void | - 18 | onSubmit | 点击提交时的回调 | (err, values) => void | - 19 | 20 | ### Login.Tab 21 | 22 | 参数 | 说明 | 类型 | 默认值 23 | ----|------|-----|------ 24 | key | 对应选项卡的 key | String | - 25 | tab | 选项卡头显示文字 | ReactNode | - 26 | 27 | ### Login.UserName 28 | 29 | 参数 | 说明 | 类型 | 默认值 30 | ----|------|-----|------ 31 | name | 控件标记,提交数据中同样以此为 key | String | - 32 | rules | 校验规则,同 Form getFieldDecorator(id, options) 中 [option.rules 的规则](getFieldDecorator(id, options)) | object[] | - 33 | 34 | 除上述属性以外,Login.UserName 还支持 antd.Input 的所有属性,并且自带默认的基础配置,包括 `placeholder` `size` `prefix` 等,这些基础配置均可被覆盖。 35 | 36 | ### Login.Password、Login.Mobile 同 Login.UserName 37 | 38 | ### Login.Captcha 39 | 40 | 参数 | 说明 | 类型 | 默认值 41 | ----|------|-----|------ 42 | onGetCaptcha | 点击获取校验码的回调 | () => void | - 43 | 44 | 除上述属性以外,Login.Captcha 支持的属性与 Login.UserName 相同。 45 | 46 | ### Login.Submit 47 | 48 | 支持 antd.Button 的所有属性。 49 | -------------------------------------------------------------------------------- /src/components/Result/index.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import * as React from 'react'; 19 | export interface IResultProps { 20 | type: 'success' | 'error'; 21 | title: React.ReactNode; 22 | description?: React.ReactNode; 23 | extra?: React.ReactNode; 24 | actions?: React.ReactNode; 25 | style?: React.CSSProperties; 26 | } 27 | 28 | export default class Result extends React.Component {} 29 | -------------------------------------------------------------------------------- /src/rollbar.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import Rollbar from "rollbar"; 19 | 20 | // Track error by rollbar.com 21 | if (location.host === "preview.pro.ant.design") { 22 | Rollbar.init({ 23 | accessToken: "033ca6d7c0eb4cc1831cf470c2649971", 24 | captureUncaught: true, 25 | captureUnhandledRejections: true, 26 | hostWhiteList: ["ant.design"], 27 | payload: { 28 | environment: "production", 29 | }, 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /src/components/Exception/index.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import * as React from 'react'; 19 | export interface IExceptionProps { 20 | type?: '403' | '404' | '500'; 21 | title?: React.ReactNode; 22 | desc?: React.ReactNode; 23 | img?: string; 24 | actions?: React.ReactNode; 25 | linkElement?: React.ReactNode; 26 | style?: React.CSSProperties; 27 | } 28 | 29 | export default class Exception extends React.Component {} 30 | -------------------------------------------------------------------------------- /src/components/GlobalFooter/index.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import * as React from 'react'; 19 | export interface IGlobalFooterProps { 20 | links?: Array<{ 21 | key?: string; 22 | title: React.ReactNode; 23 | href: string; 24 | blankTarget?: boolean; 25 | }>; 26 | copyright?: React.ReactNode; 27 | style?: React.CSSProperties; 28 | } 29 | 30 | export default class GlobalFooter extends React.Component {} 31 | -------------------------------------------------------------------------------- /src/routes/System/Scale/globalData.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | export const ConfigType = { 19 | 0: "SHENYU.SYSTEM.SCALE.CONFIG_TYPE.SHENYU", 20 | 1: "SHENYU.SYSTEM.SCALE.CONFIG_TYPE.K8S", 21 | 2: "SHENYU.SYSTEM.SCALE.CONFIG_TYPE.OTHERS", 22 | }; 23 | 24 | export const PolicyType = { 25 | 1: "SHENYU.SYSTEM.SCALE.POLICY_TYPE.MANUAL", 26 | 2: "SHENYU.SYSTEM.SCALE.POLICY_TYPE.PERIOD", 27 | 3: "SHENYU.SYSTEM.SCALE.POLICY_TYPE.DYNAMIC", 28 | }; 29 | -------------------------------------------------------------------------------- /.babelrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | const path = require('path'); 19 | 20 | module.exports = { 21 | plugins: [ 22 | [ 23 | 'module-resolver', 24 | { 25 | alias: { 26 | components: path.join(__dirname, './src/components'), 27 | }, 28 | }, 29 | ], 30 | [ 31 | 'import', 32 | { 33 | libraryName: 'antd', 34 | style: true, // or css 35 | }, 36 | ], 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apache ShenYu Dashboard 2 | 3 | ![build](https://github.com/apache/shenyu-dashboard/workflows/build/badge.svg) 4 | [![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/apache/shenyu-dashboard) 5 | 6 | 7 | ## Overview 8 | Apache ShenYu Dashboard is frontend of a management background for [Apache ShenYu](https://github.com/apache/shenyu). The API interface is in the [Apache Shenyu Admin](https://github.com/apache/shenyu/tree/master/shenyu-admin) module. 9 | 10 | ## Prerequisite 11 | - node v8.0+ 12 | 13 | ## How to Build 14 | 15 | ### Configuration 16 | 17 | Modify the api url for different environment, eg: `http://192.168.1.100:8000` 18 | 19 | 20 | ### Develop Environment 21 | 22 | ```shell 23 | # install dependencies in this project root path. 24 | npm install 25 | # start 26 | npm start 27 | ``` 28 | 29 | ### Production Environment 30 | 31 | ```shell 32 | # install dependencies in this project root path. 33 | npm install 34 | # build for production 35 | npm run build 36 | 37 | # copy to apache-shenyu-admin 38 | cp -rf dist/* shenyu-admin/src/main/resources/static/ 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Shenyu DevContainer", 3 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 4 | "features": { 5 | "ghcr.io/devcontainers/features/java:1": { 6 | "version": "17", 7 | "installMaven": "true", 8 | "installGradle": "false" 9 | }, 10 | "ghcr.io/devcontainers/features/node:1": { 11 | "version": "20" 12 | }, 13 | "ghcr.io/devcontainers/features/git-lfs:1.1.0": {} 14 | }, 15 | "customizations": { 16 | "vscode": { 17 | "settings": {}, 18 | // same extensions as Gitpod, should match /.gitpod.yml 19 | "extensions": [ 20 | "vscjava.vscode-java-pack", 21 | "editorconfig.editorconfig", 22 | "dbaeumer.vscode-eslint", 23 | "stylelint.vscode-stylelint", 24 | "DavidAnson.vscode-markdownlint", 25 | "ms-azuretools.vscode-docker", 26 | "cweijan.vscode-database-client2", 27 | "GitHub.vscode-pull-request-github" 28 | ] 29 | } 30 | }, 31 | "portsAttributes": { 32 | "8000": { 33 | "label": "Shenyu Admin", 34 | "onAutoForward": "notify" 35 | } 36 | }, 37 | "postCreateCommand": "java -version" 38 | } 39 | -------------------------------------------------------------------------------- /src/components/Authorized/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import Authorized from "./Authorized"; 19 | import AuthorizedRoute from "./AuthorizedRoute"; 20 | import Secured from "./Secured"; 21 | import check from "./CheckPermissions.js"; 22 | import renderAuthorize from "./renderAuthorize"; 23 | 24 | Authorized.Secured = Secured; 25 | Authorized.AuthorizedRoute = AuthorizedRoute; 26 | Authorized.check = check; 27 | 28 | export default renderAuthorize(Authorized); 29 | -------------------------------------------------------------------------------- /src/components/Authorized/Authorized.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import CheckPermissions from "./CheckPermissions"; 20 | 21 | class Authorized extends React.Component { 22 | render() { 23 | const { children, authority, noMatch = null } = this.props; 24 | const childrenRender = typeof children === "undefined" ? null : children; 25 | return CheckPermissions(authority, childrenRender, noMatch); 26 | } 27 | } 28 | 29 | export default Authorized; 30 | -------------------------------------------------------------------------------- /src/polyfill.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import "@babel/polyfill"; 19 | import "url-polyfill"; 20 | import setprototypeof from "setprototypeof"; 21 | 22 | // React depends on set/map/requestAnimationFrame 23 | // https://reactjs.org/docs/javascript-environment-requirements.html 24 | // import 'core-js/es6/set'; 25 | // import 'core-js/es6/map'; 26 | // import 'raf/polyfill'; 只兼容到IE10不需要,况且fetch的polyfill whatwg-fetch也只兼容到IE10 27 | 28 | // https://github.com/umijs/umi/issues/413 29 | Object.setPrototypeOf = setprototypeof; 30 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: 2 | file: .gitpod.Dockerfile 3 | 4 | additionalRepositories: 5 | - url: https://github.com/apache/shenyu.git 6 | checkoutLocation: backend 7 | 8 | tasks: 9 | 10 | - name: Run backend 11 | before: cd ../backend/shenyu-admin 12 | command: | 13 | gp sync-await setup-backend 14 | mvn spring-boot:run 15 | 16 | - name: Run frontend 17 | command: | 18 | gp sync-await setup-frontend && gp ports await 9095 19 | npm start 20 | openMode: split-right 21 | 22 | - name: Setup backend 23 | before: cd ../backend 24 | init: | 25 | mvn clean install -DskipTests 26 | command: | 27 | gp sync-done setup-backend 28 | exit 0 29 | 30 | - name: Setup frontend 31 | init: | 32 | npm install 33 | command: | 34 | gp sync-done setup-frontend 35 | exit 0 36 | openMode: split-right 37 | 38 | vscode: 39 | extensions: 40 | - vscjava.vscode-java-pack 41 | - editorconfig.editorconfig 42 | - dbaeumer.vscode-eslint 43 | - stylelint.vscode-stylelint 44 | - DavidAnson.vscode-markdownlint 45 | - ms-azuretools.vscode-docker 46 | - cweijan.vscode-database-client2 47 | - GitHub.vscode-pull-request-github 48 | 49 | ports: 50 | - port: 9095 51 | onOpen: ignore 52 | -------------------------------------------------------------------------------- /tests/fix_puppeteer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Licensed to the Apache Software Foundation (ASF) under one or more 5 | # contributor license agreements. See the NOTICE file distributed with 6 | # this work for additional information regarding copyright ownership. 7 | # The ASF licenses this file to You under the Apache License, Version 2.0 8 | # (the "License"); you may not use this file except in compliance with 9 | # the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | sudo apt-get update 21 | sudo apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \ 22 | libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \ 23 | libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \ 24 | libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \ 25 | ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget 26 | -------------------------------------------------------------------------------- /src/layouts/PageHeaderLayout.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Link } from "dva/router"; 20 | import PageHeader from "../components/PageHeader"; 21 | import styles from "./PageHeaderLayout.less"; 22 | 23 | export default ({ children, wrapperClassName, top, ...restProps }) => ( 24 |
25 | {top} 26 | 27 | {children ?
{children}
: null} 28 |
29 | ); 30 | -------------------------------------------------------------------------------- /src/components/Exception/typeConfig.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | const config = { 19 | 403: { 20 | img: "https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg", 21 | title: "403", 22 | desc: "抱歉,你无权访问该页面", 23 | }, 24 | 404: { 25 | img: "https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg", 26 | title: "404", 27 | desc: "抱歉,你访问的页面不存在", 28 | }, 29 | 500: { 30 | img: "https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg", 31 | title: "500", 32 | desc: "抱歉,服务器出错了", 33 | }, 34 | }; 35 | 36 | export default config; 37 | -------------------------------------------------------------------------------- /src/routes/Plugin/PluginRuleHandle/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import RequestRuleHandle from "./RequestRuleHandle"; 19 | import HystrixRuleHandle from "./HystrixRuleHandle"; 20 | import ParamPluginRuleHandle from "./ParamPluginRuleHandle"; 21 | import ResponseRuleHandle from "./ResponseRuleHandle"; 22 | import GeneralContextRuleHandle from "./GeneralContextRuleHandle"; 23 | 24 | export default { 25 | request: RequestRuleHandle, 26 | generalContext: GeneralContextRuleHandle, 27 | modifyResponse: ResponseRuleHandle, 28 | hystrix: HystrixRuleHandle, 29 | paramMapping: ParamPluginRuleHandle, 30 | }; 31 | -------------------------------------------------------------------------------- /src/e2e/home.e2e.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import puppeteer from "puppeteer"; 19 | 20 | describe("Homepage", () => { 21 | it("it should have logo text", async () => { 22 | const browser = await puppeteer.launch({ args: ["--no-sandbox"] }); 23 | const page = await browser.newPage(); 24 | await page.goto("http://localhost:8000", { waitUntil: "networkidle2" }); 25 | await page.waitForSelector("h1"); 26 | const text = await page.evaluate(() => document.body.innerHTML); 27 | expect(text).toContain("

Ant Design Pro

"); 28 | await page.close(); 29 | browser.close(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /src/components/_utils/pathTools.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { urlToList } from "./pathTools"; 19 | 20 | describe("test urlToList", () => { 21 | it("A path", () => { 22 | expect(urlToList("/userinfo")).toEqual(["/userinfo"]); 23 | }); 24 | it("Secondary path", () => { 25 | expect(urlToList("/userinfo/2144")).toEqual([ 26 | "/userinfo", 27 | "/userinfo/2144", 28 | ]); 29 | }); 30 | it("Three paths", () => { 31 | expect(urlToList("/userinfo/2144/addr")).toEqual([ 32 | "/userinfo", 33 | "/userinfo/2144", 34 | "/userinfo/2144/addr", 35 | ]); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /src/models/user.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { query as queryUsers } from "../services/user"; 19 | 20 | export default { 21 | namespace: "user", 22 | 23 | state: { 24 | list: [], 25 | currentUser: {}, 26 | }, 27 | 28 | effects: { 29 | *fetch(_, { call, put }) { 30 | const response = yield call(queryUsers); 31 | yield put({ 32 | type: "save", 33 | payload: response, 34 | }); 35 | }, 36 | }, 37 | 38 | reducers: { 39 | save(state, action) { 40 | return { 41 | ...state, 42 | list: action.payload, 43 | }; 44 | }, 45 | }, 46 | }; 47 | -------------------------------------------------------------------------------- /src/utils/IntlUtils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import intl from "react-intl-universal"; 19 | import locales from "./locales"; 20 | 21 | export function initIntl(lang) { 22 | intl.init({ 23 | currentLocale: lang, 24 | locales, 25 | // eslint-disable-next-line no-unused-vars 26 | warningHandler: (message) => {}, 27 | }); 28 | } 29 | 30 | export function getIntlContent(key, defaultValue) { 31 | return intl.get(key).defaultMessage(defaultValue); 32 | } 33 | 34 | export function getCurrentLocale(locale) { 35 | if (locale === "en-US") { 36 | return "English"; 37 | } else { 38 | return "中文"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/index.ejs: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Apache ShenYu Gateway 26 | 27 | 28 | 29 | 30 | 31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/components/Login/LoginSubmit.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import classNames from "classnames"; 20 | import { Button, Form } from "antd"; 21 | import styles from "./index.less"; 22 | 23 | const FormItem = Form.Item; 24 | 25 | const LoginSubmit = ({ className, ...rest }) => { 26 | const clsString = classNames(styles.submit, className); 27 | return ( 28 | 29 |
40 | , mountNode); 41 | ```` 42 | 43 | 69 | -------------------------------------------------------------------------------- /src/routes/System/Resource/IconModal.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | .iconCard { 19 | height: 700px; 20 | overflow-y: scroll; 21 | .iconList { 22 | display: flex; 23 | justify-content: flex-start; 24 | flex-wrap: wrap; 25 | .iconContent { 26 | display:flex; 27 | justify-content: center; 28 | height: 70px; 29 | width: 100px; 30 | align-items: center; 31 | flex-direction: column; 32 | margin: 5px; 33 | cursor: pointer; 34 | border-radius: 4px; 35 | -webkit-transition: color .3s ease-in-out,background-color .3s ease-in-out; 36 | transition: color .3s ease-in-out,background-color .3s ease-in-out; 37 | } 38 | .iconContent:hover{ 39 | color: white; 40 | background-color: #1890ff; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/components/_utils/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | // 默认 namespaceId 19 | export const defaultNamespaceId = "649330b6-c2d7-4edc-be8e-8a54df9eb385"; 20 | 21 | // 随机数字 22 | export function randomNum(m: number, n: number) { 23 | return Math.floor(Math.random() * (n - m + 1) + m); 24 | } 25 | 26 | // 随机颜色 27 | export function randomColor() { 28 | return `rgb(${randomNum(0, 255)}, ${randomNum(0, 255)}, ${randomNum( 29 | 0, 30 | 255, 31 | )})`; 32 | } 33 | 34 | export const originalCharacter = [ 35 | "1", 36 | "2", 37 | "3", 38 | "4", 39 | "5", 40 | "6", 41 | "7", 42 | "8", 43 | "9", 44 | "a", 45 | "b", 46 | "c", 47 | "d", 48 | "e", 49 | "f", 50 | "g", 51 | "h", 52 | "i", 53 | "j", 54 | "k", 55 | "l", 56 | "m", 57 | "n", 58 | "p", 59 | "q", 60 | "r", 61 | "s", 62 | "t", 63 | "u", 64 | "v", 65 | "w", 66 | "x", 67 | "y", 68 | "z", 69 | ]; 70 | -------------------------------------------------------------------------------- /src/components/Authorized/AuthorizedRoute.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Route, Redirect } from "react-router-dom"; 20 | import Authorized from "./Authorized"; 21 | 22 | class AuthorizedRoute extends React.Component { 23 | render() { 24 | const { 25 | component: Component, 26 | render, 27 | authority, 28 | redirectPath, 29 | ...rest 30 | } = this.props; 31 | return ( 32 | } 38 | /> 39 | } 40 | > 41 | 44 | Component ? : render(props) 45 | } 46 | /> 47 | 48 | ); 49 | } 50 | } 51 | 52 | export default AuthorizedRoute; 53 | -------------------------------------------------------------------------------- /src/components/Login/LoginTab.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* eslint-disable react/static-property-placement */ 19 | import React, { Component } from "react"; 20 | import PropTypes from "prop-types"; 21 | import { Tabs } from "antd"; 22 | 23 | const { TabPane } = Tabs; 24 | 25 | const generateId = (() => { 26 | let i = 0; 27 | return (prefix = "") => { 28 | i += 1; 29 | return `${prefix}${i}`; 30 | }; 31 | })(); 32 | 33 | export default class LoginTab extends Component { 34 | static __ANT_PRO_LOGIN_TAB = true; 35 | 36 | static contextTypes = { 37 | tabUtil: PropTypes.object, 38 | }; 39 | 40 | constructor(props) { 41 | super(props); 42 | this.uniqueId = generateId("login-tab-"); 43 | } 44 | 45 | componentDidMount() { 46 | const { tabUtil } = this.context; 47 | if (tabUtil) { 48 | tabUtil.addTab(this.uniqueId); 49 | } 50 | } 51 | 52 | render() { 53 | return ; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /.webpackrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | const path = require("path"); 19 | 20 | export default { 21 | es5ImcompatibleVersions: true, 22 | extraBabelIncludes:[ 23 | "node_modules", 24 | ], 25 | entry: "./src/index.js", 26 | extraBabelPlugins: [ 27 | ["import", { libraryName: "antd", libraryDirectory: "es", style: true }] 28 | ], 29 | env: { 30 | development: { 31 | extraBabelPlugins: ["dva-hmr"] 32 | } 33 | }, 34 | alias: { 35 | components: path.resolve(__dirname, "src/components/") 36 | }, 37 | ignoreMomentLocale: true, 38 | theme: "./src/theme.js", 39 | html: { 40 | template: "./src/index.ejs" 41 | }, 42 | lessLoaderOptions: { 43 | javascriptEnabled: true 44 | }, 45 | disableDynamicImport: true, 46 | publicPath: "", 47 | hash: true, 48 | proxy: { 49 | "/": { 50 | target: "http://localhost:9095", 51 | changeOrigin: true, 52 | pathRewrite: { "^/": "" } 53 | } 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /src/routes/User/Login.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import '~antd/lib/style/themes/default.less'; 19 | 20 | .main { 21 | width: 368px; 22 | margin: 0 auto; 23 | 24 | @media screen and (max-width: @screen-sm) { 25 | width: 95%; 26 | } 27 | 28 | .icon { 29 | font-size: 24px; 30 | color: rgba(0, 0, 0, 0.2); 31 | margin-left: 16px; 32 | vertical-align: middle; 33 | cursor: pointer; 34 | transition: color 0.3s; 35 | 36 | &:hover { 37 | color: @primary-color; 38 | } 39 | } 40 | 41 | .other { 42 | text-align: left; 43 | margin-top: 24px; 44 | line-height: 22px; 45 | 46 | .register { 47 | float: right; 48 | } 49 | } 50 | } 51 | 52 | .verify { 53 | width: 70%; 54 | float: left; 55 | margin-right: 10px; 56 | } 57 | 58 | .codeError { 59 | color: red; 60 | font-size: 14px; 61 | } 62 | 63 | 64 | :global { 65 | .ant-input .ant-input-lg { 66 | font-size: 240px; 67 | background-color: #fff; 68 | } 69 | } -------------------------------------------------------------------------------- /src/components/Result/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import classNames from "classnames"; 20 | import { Icon } from "antd"; 21 | import styles from "./index.less"; 22 | 23 | export default function Result({ 24 | className, 25 | type, 26 | title, 27 | description, 28 | extra, 29 | actions, 30 | ...restProps 31 | }) { 32 | const iconMap = { 33 | error: , 34 | success: , 35 | }; 36 | const clsString = classNames(styles.result, className); 37 | return ( 38 |
39 |
{iconMap[type]}
40 |
{title}
41 | {description &&
{description}
} 42 | {extra &&
{extra}
} 43 | {actions &&
{actions}
} 44 |
45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /src/components/Login/index.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import * as React from 'react'; 19 | import Button from 'antd/lib/button'; 20 | export interface LoginProps { 21 | defaultActiveKey?: string; 22 | onTabChange?: (key: string) => void; 23 | style?: React.CSSProperties; 24 | onSubmit?: (error: any, values: any) => void; 25 | } 26 | 27 | export interface TabProps { 28 | key?: string; 29 | tab?: React.ReactNode; 30 | } 31 | export class Tab extends React.Component {} 32 | 33 | export interface LoginItemProps { 34 | name?: string; 35 | rules?: any[]; 36 | style?: React.CSSProperties; 37 | onGetCaptcha?: () => void; 38 | placeholder?: string; 39 | } 40 | 41 | export class LoginItem extends React.Component {} 42 | 43 | export default class Login extends React.Component { 44 | static Tab: typeof Tab; 45 | static UserName: typeof LoginItem; 46 | static Password: typeof LoginItem; 47 | static Mobile: typeof LoginItem; 48 | static Captcha: typeof LoginItem; 49 | static Submit: typeof Button; 50 | } 51 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { routerRedux, Route, Switch } from "dva/router"; 20 | import { ConfigProvider, BackTop } from "antd"; 21 | import enUS from "antd/lib/locale-provider/en_US"; 22 | import { getRouterData } from "./common/router"; 23 | import AuthRoute from "./utils/AuthRoute"; 24 | 25 | const { ConnectedRouter } = routerRedux; 26 | 27 | function RouterConfig({ history, app }) { 28 | const routerData = getRouterData(app); 29 | const UserLayout = routerData["/user"].component; 30 | const BasicLayout = routerData["/"].component; 31 | 32 | return ( 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | ); 47 | } 48 | 49 | export default RouterConfig; 50 | -------------------------------------------------------------------------------- /src/routes/Home/home.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import "~antd/lib/style/themes/default.less"; 19 | 20 | .content { 21 | text-align: center; 22 | padding-top: 28px; 23 | padding-bottom: 20px; 24 | border-bottom: 1px solid #e8e8e8; 25 | margin-bottom: 24px; 26 | 27 | span { 28 | font-size: 32px; 29 | color: @primary-color; 30 | } 31 | } 32 | 33 | .processContent { 34 | margin-left: 30px; 35 | margin-right: 30px; 36 | } 37 | 38 | .contextHide { 39 | margin-bottom: 0; 40 | margin-right: 0; 41 | margin-left: 0; 42 | } 43 | 44 | .row { 45 | padding: 15px; 46 | } 47 | 48 | .logItem { 49 | padding: 15px !important; 50 | border: none; 51 | border-radius: 20px; 52 | opacity: 0.8; 53 | box-shadow: 3px 3px 10px rgba(76, 76, 76, 0.5); 54 | border-radius: 15px; 55 | } 56 | 57 | .card { 58 | box-shadow: 3px 5px 15px rgba(50, 50, 50, 0.5); 59 | background-color: rgba(255, 255, 255, 0.2); 60 | border-radius: 25px; 61 | } 62 | 63 | .logItem, 64 | .card { 65 | border-top: 1px solid rgba(255, 255, 255, 0.5); 66 | border-left: 1px solid rgba(255, 255, 255, 0.5); 67 | } 68 | -------------------------------------------------------------------------------- /src/utils/utils.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | .textOverflow() { 19 | overflow: hidden; 20 | text-overflow: ellipsis; 21 | word-break: break-all; 22 | white-space: nowrap; 23 | } 24 | 25 | .textOverflowMulti(@line: 3, @bg: #fff) { 26 | overflow: hidden; 27 | position: relative; 28 | line-height: 1.5em; 29 | max-height: @line * 1.5em; 30 | text-align: justify; 31 | margin-right: -1em; 32 | padding-right: 1em; 33 | &:before { 34 | background: @bg; 35 | content: '...'; 36 | padding: 0 1px; 37 | position: absolute; 38 | right: 14px; 39 | bottom: 0; 40 | } 41 | &:after { 42 | background: white; 43 | content: ''; 44 | margin-top: 0.2em; 45 | position: absolute; 46 | right: 14px; 47 | width: 1em; 48 | height: 1em; 49 | } 50 | } 51 | 52 | // mixins for clearfix 53 | // ------------------------ 54 | .clearfix() { 55 | zoom: 1; 56 | &:before, 57 | &:after { 58 | content: ' '; 59 | display: table; 60 | } 61 | &:after { 62 | clear: both; 63 | visibility: hidden; 64 | font-size: 0; 65 | height: 0; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/components/PageHeader/demo/image.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 2 3 | title: With Image 4 | --- 5 | 6 | 带图片的页头。 7 | 8 | ````jsx 9 | import PageHeader from 'ant-design-pro/lib/PageHeader'; 10 | 11 | const content = ( 12 |
13 |

段落示意:蚂蚁金服务设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。

14 | 25 |
26 | ); 27 | 28 | const extra = ( 29 |
30 | 31 |
32 | ); 33 | 34 | const breadcrumbList = [{ 35 | title: '一级菜单', 36 | href: '/', 37 | }, { 38 | title: '二级菜单', 39 | href: '/', 40 | }, { 41 | title: '三级菜单', 42 | }]; 43 | 44 | ReactDOM.render( 45 |
46 | 52 |
53 | , mountNode); 54 | ```` 55 | 56 | 76 | -------------------------------------------------------------------------------- /src/components/Login/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import '~antd/lib/style/themes/default.less'; 19 | 20 | .login { 21 | .tabs { 22 | padding: 0 2px; 23 | margin: 0 -2px; 24 | 25 | :global { 26 | .ant-tabs-tab { 27 | font-size: 16px; 28 | line-height: 24px; 29 | } 30 | 31 | .ant-input-affix-wrapper .ant-input:not(:first-child) { 32 | padding-left: 34px; 33 | } 34 | 35 | 36 | } 37 | } 38 | 39 | :global { 40 | .ant-tabs .ant-tabs-bar { 41 | border-bottom: 0; 42 | margin-bottom: 24px; 43 | text-align: center; 44 | } 45 | 46 | .ant-form-item { 47 | margin-bottom: 24px; 48 | } 49 | } 50 | 51 | .prefixIcon { 52 | font-size: @font-size-base; 53 | color: @disabled-color; 54 | } 55 | 56 | .getCaptcha { 57 | display: block; 58 | width: 100%; 59 | } 60 | 61 | .submit { 62 | width: 100%; 63 | margin-top: 24px; 64 | background-color: rgba(91, 66, 54, 0.7); 65 | border: 1px solid rgba(0, 0, 0, 0) 66 | } 67 | 68 | .submit:hover { 69 | background-color: rgba(91, 66, 54, 1); 70 | border: 1px solid black 71 | } 72 | } -------------------------------------------------------------------------------- /src/routes/System/AppAuth/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | .condition { 19 | margin-top: 8px; 20 | display: flex; 21 | 22 | ul { 23 | padding: 0 0 10px 6px; 24 | margin: 0; 25 | display: flex; 26 | justify-content: space-between; 27 | align-items: top; 28 | 29 | // max-height: 200px; 30 | // overflow: hidden; 31 | li { 32 | margin-right: 4px; 33 | 34 | .title { 35 | // font-size: 14px; 36 | } 37 | 38 | .appName { 39 | width: 65px; 40 | // height: 25px; 41 | text-align: center; 42 | // line-height: 25px; 43 | padding: 0; 44 | font-size: 12px; 45 | } 46 | 47 | .appParam { 48 | width: 150px; 49 | // height: 25px; 50 | text-align: center; 51 | // line-height: 25px; 52 | padding: 0; 53 | font-size: 12px; 54 | } 55 | } 56 | } 57 | 58 | .btn { 59 | margin-left: 10px; 60 | 61 | } 62 | } 63 | 64 | .form { 65 | :global(.ant-form-item-control) { 66 | line-height: inherit !important; 67 | } 68 | } 69 | 70 | .formInput { 71 | width: 175px; 72 | } 73 | 74 | .formBtn { 75 | margin-right: 0px !important; 76 | } 77 | -------------------------------------------------------------------------------- /src/components/Login/LoginCode.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | import React, { useCallback, useState, useRef, useImperativeHandle } from "react"; 18 | import Captcha from "react-captcha-code"; 19 | import { randomNum, originalCharacter } from "../_utils/utils"; 20 | 21 | interface childProps { 22 | ChildGetCode: Function, 23 | onRef: any, 24 | } 25 | 26 | const LoginCode: React.FC = (props) => { 27 | const { ChildGetCode } = props; 28 | const captchaRef = useRef(); 29 | const [code, setCode] = useState(""); 30 | 31 | const handleClick = useCallback(() => { 32 | let str = ""; 33 | for (let i = 0; i < 4; i++) { 34 | const temp = 35 | originalCharacter[randomNum(0, originalCharacter.length - 1)]; 36 | str = `${str}${temp}`; 37 | } 38 | setCode(str); 39 | ChildGetCode(str); 40 | }, []); 41 | 42 | useImperativeHandle(props.onRef, () => { 43 | return { 44 | handleChange: handleClick, 45 | }; 46 | }); 47 | 48 | return ( 49 | 50 | 51 | 52 | ); 53 | } 54 | 55 | export default LoginCode; 56 | -------------------------------------------------------------------------------- /src/components/Result/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import '~antd/lib/style/themes/default.less'; 19 | 20 | .result { 21 | text-align: center; 22 | width: 72%; 23 | margin: 0 auto; 24 | @media screen and (max-width: @screen-xs) { 25 | width: 100%; 26 | } 27 | 28 | .icon { 29 | font-size: 72px; 30 | line-height: 72px; 31 | margin-bottom: 24px; 32 | 33 | & > .success { 34 | color: @success-color; 35 | } 36 | 37 | & > .error { 38 | color: @error-color; 39 | } 40 | } 41 | 42 | .title { 43 | font-size: 24px; 44 | color: @heading-color; 45 | font-weight: 500; 46 | line-height: 32px; 47 | margin-bottom: 16px; 48 | } 49 | 50 | .description { 51 | font-size: 14px; 52 | line-height: 22px; 53 | color: @text-color-secondary; 54 | margin-bottom: 24px; 55 | } 56 | 57 | .extra { 58 | background: #fafafa; 59 | padding: 24px 40px; 60 | border-radius: @border-radius-sm; 61 | text-align: left; 62 | 63 | @media screen and (max-width: @screen-xs) { 64 | padding: 18px 20px; 65 | } 66 | } 67 | 68 | .actions { 69 | margin-top: 32px; 70 | 71 | button:not(:last-child) { 72 | margin-right: 8px; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/components/GlobalFooter/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import classNames from "classnames"; 20 | import supportImg from "../../assets/support-apache.png"; 21 | import asfLogo from "../../assets/asf_logo.svg"; 22 | import styles from "./index.less"; 23 | 24 | const GlobalFooter = ({ className, links, copyright }) => { 25 | const imgStyle = classNames(styles.imgStyle, className); 26 | const clsString = classNames(styles.globalFooter, className); 27 | return ( 28 |
29 | {links && ( 30 |
31 | {links.map((link) => ( 32 | 38 | {link.title} 39 | 40 | ))} 41 |
42 | )} 43 | Apache Support Logo 44 | The Apache Software Foundation 49 | {copyright &&
{copyright}
} 50 |
51 | ); 52 | }; 53 | 54 | export default GlobalFooter; 55 | -------------------------------------------------------------------------------- /src/components/Authorized/index.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import * as React from 'react'; 19 | import { RouteProps } from 'react-router'; 20 | 21 | type authorityFN = (currentAuthority?: string) => boolean; 22 | 23 | type authority = string | Array | authorityFN | Promise; 24 | 25 | export type IReactComponent

= 26 | | React.StatelessComponent

27 | | React.ComponentClass

28 | | React.ClassicComponentClass

; 29 | 30 | interface Secured { 31 | (authority: authority, error?: React.ReactNode): (target: T) => T; 32 | } 33 | 34 | export interface AuthorizedRouteProps extends RouteProps { 35 | authority: authority; 36 | } 37 | export class AuthorizedRoute extends React.Component {} 38 | 39 | interface check { 40 | ( 41 | authority: authority, 42 | target: T, 43 | Exception: S 44 | ): T | S; 45 | } 46 | 47 | interface AuthorizedProps { 48 | authority: authority; 49 | noMatch?: React.ReactNode; 50 | } 51 | 52 | export class Authorized extends React.Component { 53 | static Secured: Secured; 54 | static AuthorizedRoute: typeof AuthorizedRoute; 55 | static check: check; 56 | } 57 | 58 | declare function renderAuthorize(currentAuthority: string): typeof Authorized; 59 | 60 | export default renderAuthorize; 61 | -------------------------------------------------------------------------------- /src/layouts/UserLayout.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import '~antd/lib/style/themes/default.less'; 19 | 20 | .container { 21 | display: flex; 22 | flex-direction: column; 23 | height: 100vh; 24 | overflow: auto; 25 | // background-image: url(); 26 | background: #ffffff; 27 | } 28 | 29 | .content { 30 | padding: 32px 0; 31 | flex: 1; 32 | } 33 | 34 | @media (min-width: @screen-md-min) { 35 | .container { 36 | // background url https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg 37 | background-image: url('../assets/bg.jpg'); 38 | background-repeat: no-repeat; 39 | background-position: center; 40 | background-size: cover; 41 | } 42 | 43 | .content { 44 | padding: 100px 0 0 0; 45 | } 46 | } 47 | 48 | .top { 49 | text-align: center; 50 | } 51 | 52 | .header { 53 | height: 44px; 54 | line-height: 44px; 55 | 56 | a { 57 | text-decoration: none; 58 | } 59 | } 60 | 61 | .logo { 62 | height: 44px; 63 | vertical-align: top; 64 | margin-right: 16px; 65 | } 66 | 67 | .title { 68 | font-size: 33px; 69 | color: @heading-color; 70 | font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif; 71 | font-weight: 600; 72 | position: relative; 73 | top: 2px; 74 | } 75 | 76 | .desc { 77 | font-size: @font-size-base; 78 | color: #ffffff; 79 | margin-top: 12px; 80 | margin-bottom: 40px; 81 | } 82 | -------------------------------------------------------------------------------- /tests/run-tests.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | const { spawn } = require("child_process"); 19 | const { kill } = require("cross-port-killer"); 20 | 21 | const env = Object.create(process.env); 22 | env.BROWSER = "none"; 23 | const startServer = spawn( 24 | /^win/.test(process.platform) ? "npm.cmd" : "npm", 25 | ["start"], 26 | { 27 | env, 28 | }, 29 | ); 30 | 31 | startServer.stderr.on("data", (data) => { 32 | // eslint-disable-next-line 33 | console.log(data); 34 | }); 35 | 36 | startServer.on("exit", () => { 37 | kill(process.env.PORT || 8000); 38 | }); 39 | 40 | // eslint-disable-next-li 41 | // eslint-disable-next-line no-console 42 | console.log("Starting development server for e2e tests..."); 43 | startServer.stdout.on("data", (data) => { 44 | // eslint-disable-next-line 45 | console.log(data.toString()); 46 | if ( 47 | data.toString().indexOf("Compiled successfully") >= 0 || 48 | data.toString().indexOf("Compiled with warnings") >= 0 49 | ) { 50 | // eslint-disable-next-line 51 | console.log('Development server is started, ready to run tests.'); 52 | const testCmd = spawn( 53 | /^win/.test(process.platform) ? "npm.cmd" : "npm", 54 | ["test"], 55 | { 56 | stdio: "inherit", 57 | }, 58 | ); 59 | testCmd.on("exit", (code) => { 60 | startServer.kill(); 61 | process.exit(code); 62 | }); 63 | } 64 | }); 65 | -------------------------------------------------------------------------------- /src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Exception/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React, { createElement } from "react"; 19 | import classNames from "classnames"; 20 | import { Button } from "antd"; 21 | import config from "./typeConfig"; 22 | import styles from "./index.less"; 23 | 24 | const Exception = ({ 25 | className, 26 | linkElement = "a", 27 | type, 28 | title, 29 | desc, 30 | img, 31 | actions, 32 | ...rest 33 | }) => { 34 | const pageType = type in config ? type : "404"; 35 | const clsString = classNames(styles.exception, className); 36 | return ( 37 |

38 |
39 |
43 |
44 |
45 |

{title || config[pageType].title}

46 |
{desc || config[pageType].desc}
47 |
48 | {actions || 49 | createElement( 50 | linkElement, 51 | { 52 | to: "/", 53 | href: "/", 54 | }, 55 | , 56 | )} 57 |
58 |
59 |
60 | ); 61 | }; 62 | 63 | export default Exception; 64 | -------------------------------------------------------------------------------- /src/components/Authorized/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 3 | en-US: Authorized 4 | zh-CN: Authorized 5 | subtitle: 权限 6 | cols: 1 7 | order: 15 8 | --- 9 | 10 | 权限组件,通过比对现有权限与准入权限,决定相关元素的展示。 11 | 12 | ## API 13 | 14 | ### RenderAuthorized 15 | 16 | `RenderAuthorized: (currentAuthority: string | () => string) => Authorized` 17 | 18 | 权限组件默认 export RenderAuthorized 函数,它接收当前权限作为参数,返回一个权限对象,该对象提供以下几种使用方式。 19 | 20 | 21 | ### Authorized 22 | 23 | 最基础的权限控制。 24 | 25 | | 参数 | 说明 | 类型 | 默认值 | 26 | |----------|------------------------------------------|-------------|-------| 27 | | children | 正常渲染的元素,权限判断通过时展示 | ReactNode | - | 28 | | authority | 准入权限/权限判断 | `string | array | Promise | (currentAuthority) => boolean | Promise` | - | 29 | | noMatch | 权限异常渲染元素,权限判断不通过时展示 | ReactNode | - | 30 | 31 | ### Authorized.AuthorizedRoute 32 | 33 | | 参数 | 说明 | 类型 | 默认值 | 34 | |----------|------------------------------------------|-------------|-------| 35 | | authority | 准入权限/权限判断 | `string | array | Promise | (currentAuthority) => boolean | Promise` | - | 36 | | redirectPath | 权限异常时重定向的页面路由 | string | - | 37 | 38 | 其余参数与 `Route` 相同。 39 | 40 | ### Authorized.Secured 41 | 42 | 注解方式,`@Authorized.Secured(authority, error)` 43 | 44 | | 参数 | 说明 | 类型 | 默认值 | 45 | |----------|------------------------------------------|-------------|-------| 46 | | authority | 准入权限/权限判断 | `string | Promise | (currentAuthority) => boolean | Promise` | - | 47 | | error | 权限异常时渲染元素 | ReactNode | | 48 | 49 | ### Authorized.check 50 | 51 | 函数形式的 Authorized,用于某些不能被 HOC 包裹的组件。 `Authorized.check(authority, target, Exception)` 52 | 注意:传入一个 Promise 时,无论正确还是错误返回的都是一个 ReactClass。 53 | 54 | | 参数 | 说明 | 类型 | 默认值 | 55 | |----------|------------------------------------------|-------------|-------| 56 | | authority | 准入权限/权限判断 | `string | Promise | (currentAuthority) => boolean | Promise` | - | 57 | | target | 权限判断通过时渲染的元素 | ReactNode | - | 58 | | Exception | 权限异常时渲染元素 | ReactNode | - | 59 | -------------------------------------------------------------------------------- /src/routes/Exception/triggerException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React, { PureComponent } from "react"; 19 | import { Button, Spin, Card } from "antd"; 20 | import { connect } from "dva"; 21 | import styles from "./style.less"; 22 | 23 | @connect((state) => ({ 24 | isloading: state.error.isloading, 25 | })) 26 | export default class TriggerException extends PureComponent { 27 | constructor(props) { 28 | super(props); 29 | this.state = { 30 | isloading: false, 31 | }; 32 | } 33 | 34 | triggerError = (code) => { 35 | this.setState({ 36 | isloading: true, 37 | }); 38 | const { dispatch } = this.props; 39 | dispatch({ 40 | type: "error/query", 41 | payload: { 42 | code, 43 | }, 44 | }); 45 | }; 46 | 47 | render() { 48 | const { isloading } = this.state; 49 | return ( 50 | 51 | 52 | 55 | 58 | 61 | 64 | 65 | 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import "./polyfill"; 19 | import dva from "dva"; 20 | 21 | import { createHashHistory as createHistory } from "history"; 22 | // user BrowserHistory 23 | // import createHistory from 'history/createBrowserHistory'; 24 | import createLoading from "dva-loading"; 25 | import { initIntl } from "./utils/IntlUtils"; 26 | 27 | // import 'moment/locale/zh-cn'; 28 | // import './rollbar'; 29 | import "./index.less"; 30 | import { emit } from "./utils/emit"; 31 | 32 | const middlewares = []; 33 | // if (process.env.NODE_ENV === `development`) { 34 | // const { logger } = require(`redux-logger`); 35 | 36 | // middlewares.push(logger); 37 | // } 38 | 39 | /** get session storage */ 40 | if ( 41 | window.sessionStorage.getItem("locale") === undefined || 42 | window.sessionStorage.getItem("locale") === null 43 | ) { 44 | initIntl("en-US"); 45 | window.sessionStorage.setItem("locale", "en-US"); 46 | } else { 47 | initIntl(window.sessionStorage.getItem("locale")); 48 | } 49 | 50 | emit.on("change_language", (lang) => initIntl(lang)); 51 | 52 | // 1. Initialize 53 | const app = dva({ 54 | history: createHistory(), 55 | onAction: middlewares, 56 | }); 57 | 58 | // 2. Plugins 59 | app.use(createLoading()); 60 | 61 | // 3. Register global model 62 | app.model(require("./models/global").default); 63 | 64 | // 4. Router 65 | app.router(require("./router").default); 66 | 67 | // 5. Start 68 | app.start("#root"); 69 | 70 | export default app._store; // eslint-disable-line 71 | -------------------------------------------------------------------------------- /src/routes/Result/Error.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React, { Fragment } from "react"; 19 | import { Button, Icon, Card } from "antd"; 20 | import Result from "components/Result"; 21 | import PageHeaderLayout from "../../layouts/PageHeaderLayout"; 22 | 23 | const extra = ( 24 | <> 25 |
33 | 您提交的内容有如下错误: 34 |
35 |
36 | 40 | 您的账户已被冻结 41 | 42 | 立即解冻 43 | 44 |
45 |
46 | 50 | 您的账户还不具备申请资格 51 | 52 | 立即升级 53 | 54 |
55 | 56 | ); 57 | 58 | const actions = ; 59 | 60 | export default () => ( 61 | 62 | 63 | 71 | 72 | 73 | ); 74 | -------------------------------------------------------------------------------- /src/routes/Plugin/Discovery/discovery.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | 20 | .main { 21 | width: 100%; 22 | height: 100%; 23 | padding: 24px; 24 | display: flex; 25 | flex-direction: column; 26 | } 27 | 28 | .header { 29 | display: flex; 30 | flex-direction: column; 31 | 32 | .titleBar { 33 | width: 100%; 34 | display: flex; 35 | justify-content: space-between; 36 | align-items: end; 37 | flex: 1 1 0; 38 | 39 | .left { 40 | display: flex; 41 | align-items: end; 42 | } 43 | } 44 | } 45 | 46 | 47 | .header-bar { 48 | margin: 20px 0; 49 | display: flex; 50 | justify-content: space-between; 51 | align-items: center; 52 | line-height: 40px; 53 | padding: 0 20px; 54 | border-radius: 5px; 55 | box-shadow: 1px 2px 2px rgba(191, 189, 189, 0.5); 56 | height: 40px; 57 | background: #fff; 58 | } 59 | 60 | .formItem { 61 | display: flex; 62 | justify-content: space-around; 63 | } 64 | 65 | 66 | .editable-cell { 67 | position: relative; 68 | } 69 | 70 | .editable-cell-value-wrap { 71 | padding: 5px 12px; 72 | cursor: pointer; 73 | } 74 | 75 | .editable-row:hover .editable-cell-value-wrap { 76 | border: 1px solid #d9d9d9; 77 | border-radius: 4px; 78 | padding: 4px 11px; 79 | } 80 | 81 | 82 | .discoveryCard { 83 | :global { 84 | .ant-card-body { 85 | padding: 10px 86 | } 87 | 88 | .ant-card-actions { 89 | background-color: white; 90 | } 91 | } 92 | border-radius: 5px ; 93 | box-shadow: 1px 2px 2px rgba(191, 189, 189, 0.5) 94 | } 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/e2e/login.e2e.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import puppeteer from "puppeteer"; 19 | 20 | describe("Login", () => { 21 | let browser; 22 | let page; 23 | 24 | beforeAll(async () => { 25 | browser = await puppeteer.launch({ args: ["--no-sandbox"] }); 26 | }); 27 | 28 | beforeEach(async () => { 29 | page = await browser.newPage(); 30 | await page.goto("http://localhost:8000/#/user/login", { 31 | waitUntil: "networkidle2", 32 | }); 33 | await page.evaluate(() => 34 | window.localStorage.setItem("antd-pro-authority", "guest"), 35 | ); 36 | }); 37 | 38 | afterEach(() => page.close()); 39 | 40 | it("should login with failure", async () => { 41 | await page.waitForSelector("#userName", { 42 | timeout: 2000, 43 | }); 44 | await page.type("#userName", "mockuser"); 45 | await page.type("#password", "wrong_password"); 46 | await page.click('button[type="submit"]'); 47 | await page.waitForSelector(".ant-alert-error"); // should display error 48 | }); 49 | 50 | it("should login successfully", async () => { 51 | await page.waitForSelector("#userName", { 52 | timeout: 2000, 53 | }); 54 | await page.type("#userName", "admin"); 55 | await page.type("#password", "888888"); 56 | await page.click('button[type="submit"]'); 57 | await page.waitForSelector(".ant-layout-sider h1"); // should display error 58 | const text = await page.evaluate(() => document.body.innerHTML); 59 | expect(text).toContain("

Ant Design Pro

"); 60 | }); 61 | 62 | afterAll(() => browser.close()); 63 | }); 64 | -------------------------------------------------------------------------------- /src/components/Result/demo/classic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | title: Classic 4 | --- 5 | 6 | 典型结果页面。 7 | 8 | ````jsx 9 | import Result from 'ant-design-pro/lib/Result'; 10 | import { Button, Row, Col, Icon, Steps } from 'antd'; 11 | 12 | const { Step } = Steps; 13 | 14 | const desc1 = ( 15 |
16 |
17 | 曲丽丽 18 | 19 |
20 |
2016-12-12 12:32
21 |
22 | ); 23 | 24 | const desc2 = ( 25 |
26 |
27 | 周毛毛 28 | 29 |
30 | 31 |
32 | ); 33 | 34 | const extra = ( 35 |
36 |
37 | 项目名称 38 |
39 | 40 | 41 | 项目 ID: 42 | 23421 43 | 44 | 45 | 负责人: 46 | 曲丽丽 47 | 48 | 49 | 生效时间: 50 | 2016-12-12 ~ 2017-12-12 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | ); 61 | 62 | const actions = ( 63 |
64 | 65 | 66 | 67 |
68 | ); 69 | 70 | ReactDOM.render( 71 | 79 | , mountNode); 80 | ```` 81 | -------------------------------------------------------------------------------- /src/routes/Plugin/Common/ComposeRuleHandle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React, { Component } from "react"; 19 | import PluginRuleHandle from "../PluginRuleHandle"; 20 | import CommonRuleHandle from "./CommonRuleHandle"; 21 | 22 | export default class ComposeRuleHandle extends Component { 23 | // eslint-disable-next-line react/no-unused-class-component-methods 24 | getData = (formValues) => { 25 | return this.handleCustomComponentRef.getData(formValues); 26 | }; 27 | 28 | render() { 29 | const { pluginName, form, pluginHandleList, handle, multiRuleHandle } = 30 | this.props; 31 | const CustomRuleHandle = PluginRuleHandle[pluginName]; 32 | return ( 33 | <> 34 | { 36 | this.handleCustomComponentRef = handleComponentRef; 37 | this.props.onRef(this); 38 | }} 39 | pluginName={pluginName} 40 | onAddPluginHandle={this.handleAddHandle} 41 | onDeletePluginHandle={this.handleDeleteHandle} 42 | form={form} 43 | pluginHandleList={pluginHandleList} 44 | handle={handle} 45 | multiRuleHandle={multiRuleHandle} 46 | /> 47 | 56 | 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/routes/System/AppAuth/RelateMetadata.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React, { Component } from "react"; 19 | import { Modal, Form } from "antd"; 20 | // import styles from "./index.less"; 21 | import TableTransferComponent from "./TableTransfer"; 22 | import { getIntlContent } from "../../../utils/IntlUtils"; 23 | 24 | class RelateMetadata extends Component { 25 | constructor(props) { 26 | super(props); 27 | this.state = { 28 | authPathDTOList: [], 29 | id: this.props.id, 30 | }; 31 | } 32 | 33 | // 获取穿梭框中右侧数据以便更新 34 | getUpdateMetas = (data) => { 35 | this.setState({ 36 | authPathDTOList: data, 37 | }); 38 | }; 39 | 40 | handleSubmit = () => { 41 | const { handleOk } = this.props; 42 | // 需要传值更新 43 | handleOk(this.state); 44 | }; 45 | 46 | render() { 47 | let { authName, handleCancel, auth, dataList } = this.props; 48 | return ( 49 | 59 | {/* 放置穿梭框组件 */} 60 | this.getUpdateMetas(data)} 65 | /> 66 | 67 | ); 68 | } 69 | } 70 | 71 | export default Form.create()(RelateMetadata); 72 | -------------------------------------------------------------------------------- /src/utils/download.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import fetch from "dva/fetch"; 19 | 20 | /** 21 | * Requests a URL, for downloading. 22 | * 23 | * @param {string} url The URL we want to request 24 | * @param {object} [options] The options we want to pass to "fetch" 25 | * @return {object} An object containing either "data" or "err" 26 | */ 27 | export default async function download(url, options) { 28 | const defaultOptions = { 29 | method: "GET", 30 | }; 31 | 32 | const newOptions = { ...defaultOptions, ...options }; 33 | 34 | // add token 35 | let token = window.sessionStorage.getItem("token"); 36 | if (token) { 37 | if (!newOptions.headers) { 38 | newOptions.headers = {}; 39 | } 40 | newOptions.headers = { ...newOptions.headers, "X-Access-Token": token }; 41 | } 42 | try { 43 | const response = await fetch(url, newOptions); 44 | const disposition = response.headers.get("Content-Disposition"); 45 | const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; 46 | const matches = filenameRegex.exec(disposition); 47 | let filename = "download"; 48 | if (matches != null && matches[1]) { 49 | filename = matches[1].replace(/['"]/g, ""); 50 | } 51 | 52 | const blob = await response.blob(); 53 | 54 | const a = document.createElement("a"); 55 | a.href = URL.createObjectURL(blob); // use blob obj to create URL 56 | a.download = filename; // use the file name from backend 57 | document.body.appendChild(a); 58 | a.click(); 59 | document.body.removeChild(a); 60 | } catch (error) { 61 | throw new Error(`下载文件失败:${error}`); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/components/PageHeader/index.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { getBreadcrumb } from "./index"; 19 | import { urlToList } from "../_utils/pathTools"; 20 | 21 | const routerData = { 22 | "/dashboard/analysis": { 23 | name: "分析页", 24 | }, 25 | "/userinfo": { 26 | name: "用户列表", 27 | }, 28 | "/userinfo/:id": { 29 | name: "用户信息", 30 | }, 31 | "/userinfo/:id/addr": { 32 | name: "收货订单", 33 | }, 34 | }; 35 | describe("test getBreadcrumb", () => { 36 | it("Simple url", () => { 37 | expect(getBreadcrumb(routerData, "/dashboard/analysis").name).toEqual( 38 | "分析页", 39 | ); 40 | }); 41 | it("Parameters url", () => { 42 | expect(getBreadcrumb(routerData, "/userinfo/2144").name).toEqual( 43 | "用户信息", 44 | ); 45 | }); 46 | it("The middle parameter url", () => { 47 | expect(getBreadcrumb(routerData, "/userinfo/2144/addr").name).toEqual( 48 | "收货订单", 49 | ); 50 | }); 51 | it("Loop through the parameters", () => { 52 | const urlNameList = urlToList("/userinfo/2144/addr").map((url) => { 53 | return getBreadcrumb(routerData, url).name; 54 | }); 55 | expect(urlNameList).toEqual(["用户列表", "用户信息", "收货订单"]); 56 | }); 57 | 58 | it("a path", () => { 59 | const urlNameList = urlToList("/userinfo").map((url) => { 60 | return getBreadcrumb(routerData, url).name; 61 | }); 62 | expect(urlNameList).toEqual(["用户列表"]); 63 | }); 64 | it("Secondary path", () => { 65 | const urlNameList = urlToList("/userinfo/2144").map((url) => { 66 | return getBreadcrumb(routerData, url).name; 67 | }); 68 | expect(urlNameList).toEqual(["用户列表", "用户信息"]); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /src/models/mcpServer.js: -------------------------------------------------------------------------------- 1 | import { message } from "antd"; 2 | import { 3 | fetchMcpServer, 4 | addMcpServer, 5 | updateMcpServer, 6 | deleteMcpServer, 7 | } from "../services/api"; 8 | import { getIntlContent } from "../utils/IntlUtils"; 9 | 10 | export default { 11 | namespace: "mcpServer", 12 | 13 | state: { 14 | list: [], 15 | total: 0, 16 | currentPage: 1, 17 | pageSize: 12, 18 | }, 19 | 20 | effects: { 21 | *fetch({ payload }, { call, put }) { 22 | const response = yield call(fetchMcpServer, payload); 23 | if (response) { 24 | yield put({ 25 | type: "saveList", 26 | payload: { 27 | list: response.data, 28 | total: response.total, 29 | currentPage: payload.currentPage, 30 | pageSize: payload.pageSize, 31 | }, 32 | }); 33 | } 34 | }, 35 | *add({ payload, callback }, { call, put }) { 36 | const response = yield call(addMcpServer, payload); 37 | if (response) { 38 | message.success(getIntlContent("SHENYU.COMMON.RESPONSE.ADD.SUCCESS")); 39 | yield put({ type: "reload" }); 40 | } 41 | if (callback) callback(); 42 | }, 43 | *update({ payload, callback }, { call, put }) { 44 | const response = yield call(updateMcpServer, payload); 45 | if (response) { 46 | message.success( 47 | getIntlContent("SHENYU.COMMON.RESPONSE.UPDATE.SUCCESS"), 48 | ); 49 | yield put({ type: "reload" }); 50 | } 51 | if (callback) callback(); 52 | }, 53 | *delete({ payload, callback }, { call, put }) { 54 | const response = yield call(deleteMcpServer, payload); 55 | if (response) { 56 | message.success( 57 | getIntlContent("SHENYU.COMMON.RESPONSE.DELETE.SUCCESS"), 58 | ); 59 | yield put({ type: "reload" }); 60 | } 61 | if (callback) callback(); 62 | }, 63 | *reload(_, { put, select }) { 64 | const { currentPage, pageSize } = yield select( 65 | (state) => state.mcpServer, 66 | ); 67 | yield put({ 68 | type: "fetch", 69 | payload: { currentPage, pageSize }, 70 | }); 71 | }, 72 | }, 73 | 74 | reducers: { 75 | saveList(state, { payload }) { 76 | return { 77 | ...state, 78 | list: payload.list, 79 | total: payload.total, 80 | currentPage: payload.currentPage, 81 | pageSize: payload.pageSize, 82 | }; 83 | }, 84 | }, 85 | }; 86 | -------------------------------------------------------------------------------- /src/routes/System/AppAuth/SearchContent.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Form, Input, Button } from "antd"; 20 | import { getIntlContent } from "../../../utils/IntlUtils"; 21 | import AuthButton from "../../../utils/AuthButton"; 22 | import styles from "./index.less"; 23 | 24 | class InlineSearch extends React.Component { 25 | handleSubmit = (e) => { 26 | e.preventDefault(); 27 | const searchCont = this.props.form.getFieldsValue(); 28 | this.props.onClick(searchCont); 29 | }; 30 | 31 | render() { 32 | const { getFieldDecorator } = this.props.form; 33 | return ( 34 |
39 | 40 | {getFieldDecorator("appKey", { 41 | initialValue: null, 42 | })( 43 | , 47 | )} 48 | 49 | 50 | {getFieldDecorator("phone", { 51 | initialValue: null, 52 | })( 53 | , 58 | )} 59 | 60 | 61 | 62 | 65 | 66 | 67 |
68 | ); 69 | } 70 | } 71 | const SearchContent = Form.create({})(InlineSearch); 72 | export default SearchContent; 73 | -------------------------------------------------------------------------------- /src/components/SiderMenu/SilderMenu.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { urlToList } from "../_utils/pathTools"; 19 | import { getFlatMenuKeys, getMenuMatchKeys } from "./SiderMenu"; 20 | 21 | const menu = [ 22 | { 23 | path: "/dashboard", 24 | children: [ 25 | { 26 | path: "/dashboard/name", 27 | }, 28 | ], 29 | }, 30 | { 31 | path: "/userinfo", 32 | children: [ 33 | { 34 | path: "/userinfo/:id", 35 | children: [ 36 | { 37 | path: "/userinfo/:id/info", 38 | }, 39 | ], 40 | }, 41 | ], 42 | }, 43 | ]; 44 | 45 | const flatMenuKeys = getFlatMenuKeys(menu); 46 | 47 | describe("test convert nested menu to flat menu", () => { 48 | it("simple menu", () => { 49 | expect(flatMenuKeys).toEqual([ 50 | "/dashboard", 51 | "/dashboard/name", 52 | "/userinfo", 53 | "/userinfo/:id", 54 | "/userinfo/:id/info", 55 | ]); 56 | }); 57 | }); 58 | 59 | describe("test menu match", () => { 60 | it("simple path", () => { 61 | expect(getMenuMatchKeys(flatMenuKeys, urlToList("/dashboard"))).toEqual([ 62 | "/dashboard", 63 | ]); 64 | }); 65 | 66 | it("error path", () => { 67 | expect(getMenuMatchKeys(flatMenuKeys, urlToList("/dashboardname"))).toEqual( 68 | [], 69 | ); 70 | }); 71 | 72 | it("Secondary path", () => { 73 | expect( 74 | getMenuMatchKeys(flatMenuKeys, urlToList("/dashboard/name")), 75 | ).toEqual(["/dashboard", "/dashboard/name"]); 76 | }); 77 | 78 | it("Parameter path", () => { 79 | expect(getMenuMatchKeys(flatMenuKeys, urlToList("/userinfo/2144"))).toEqual( 80 | ["/userinfo", "/userinfo/:id"], 81 | ); 82 | }); 83 | 84 | it("three parameter path", () => { 85 | expect( 86 | getMenuMatchKeys(flatMenuKeys, urlToList("/userinfo/2144/info")), 87 | ).toEqual(["/userinfo", "/userinfo/:id", "/userinfo/:id/info"]); 88 | }); 89 | }); 90 | -------------------------------------------------------------------------------- /src/components/Exception/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import '~antd/lib/style/themes/default.less'; 19 | 20 | .exception { 21 | display: flex; 22 | align-items: center; 23 | height: 100%; 24 | 25 | .imgBlock { 26 | flex: 0 0 62.5%; 27 | width: 62.5%; 28 | padding-right: 152px; 29 | zoom: 1; 30 | &:before, 31 | &:after { 32 | content: ' '; 33 | display: table; 34 | } 35 | &:after { 36 | clear: both; 37 | visibility: hidden; 38 | font-size: 0; 39 | height: 0; 40 | } 41 | } 42 | 43 | .imgEle { 44 | height: 360px; 45 | width: 100%; 46 | max-width: 430px; 47 | float: right; 48 | background-repeat: no-repeat; 49 | background-position: 50% 50%; 50 | background-size: contain; 51 | } 52 | 53 | .content { 54 | flex: auto; 55 | 56 | h1 { 57 | color: #434e59; 58 | font-size: 72px; 59 | font-weight: 600; 60 | line-height: 72px; 61 | margin-bottom: 24px; 62 | } 63 | 64 | .desc { 65 | color: @text-color-secondary; 66 | font-size: 20px; 67 | line-height: 28px; 68 | margin-bottom: 16px; 69 | } 70 | 71 | .actions { 72 | button:not(:last-child) { 73 | margin-right: 8px; 74 | } 75 | } 76 | } 77 | } 78 | 79 | @media screen and (max-width: @screen-xl) { 80 | .exception { 81 | .imgBlock { 82 | padding-right: 88px; 83 | } 84 | } 85 | } 86 | 87 | @media screen and (max-width: @screen-sm) { 88 | .exception { 89 | display: block; 90 | text-align: center; 91 | .imgBlock { 92 | padding-right: 0; 93 | margin: 0 auto 24px; 94 | } 95 | } 96 | } 97 | 98 | @media screen and (max-width: @screen-xs) { 99 | .exception { 100 | .imgBlock { 101 | margin-bottom: -24px; 102 | overflow: hidden; 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/components/PageHeader/demo/standard.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 1 3 | title: Standard 4 | --- 5 | 6 | 标准页头。 7 | 8 | ````jsx 9 | import PageHeader from 'ant-design-pro/lib/PageHeader'; 10 | import DescriptionList from 'ant-design-pro/lib/DescriptionList'; 11 | import { Button, Menu, Dropdown, Icon, Row, Col } from 'antd'; 12 | 13 | const { Description } = DescriptionList; 14 | const ButtonGroup = Button.Group; 15 | 16 | const description = ( 17 | 18 | 曲丽丽 19 | XX 服务 20 | 2017-07-07 21 | 12421 22 | 23 | ); 24 | 25 | const menu = ( 26 | 27 | 选项一 28 | 选项二 29 | 选项三 30 | 31 | ); 32 | 33 | const action = ( 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | ); 45 | 46 | const extra = ( 47 | 48 | 49 |
状态
50 |
待审批
51 | 52 | 53 |
订单金额
54 |
¥ 568.08
55 | 56 |
57 | ); 58 | 59 | const breadcrumbList = [{ 60 | title: '一级菜单', 61 | href: '/', 62 | }, { 63 | title: '二级菜单', 64 | href: '/', 65 | }, { 66 | title: '三级菜单', 67 | }]; 68 | 69 | const tabList = [{ 70 | key: 'detail', 71 | tab: '详情', 72 | }, { 73 | key: 'rule', 74 | tab: '规则', 75 | }]; 76 | 77 | function onTabChange(key) { 78 | console.log(key); 79 | } 80 | 81 | ReactDOM.render( 82 |
83 | } 86 | action={action} 87 | content={description} 88 | extraContent={extra} 89 | breadcrumbList={breadcrumbList} 90 | tabList={tabList} 91 | tabActiveKey="detail" 92 | onTabChange={onTabChange} 93 | /> 94 |
95 | , mountNode); 96 | ```` 97 | 98 | 103 | -------------------------------------------------------------------------------- /src/components/Authorized/Secured.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import Exception from "../Exception/index"; 20 | import CheckPermissions from "./CheckPermissions"; 21 | /** 22 | * 默认不能访问任何页面 23 | * default is "NULL" 24 | */ 25 | const Exception403 = () => ( 26 | 27 | ); 28 | 29 | // Determine whether the incoming component has been instantiated 30 | // AuthorizedRoute is already instantiated 31 | // Authorized render is already instantiated, children is no instantiated 32 | // Secured is not instantiated 33 | const checkIsInstantiation = (target) => { 34 | if (!React.isValidElement(target)) { 35 | return target; 36 | } 37 | return () => target; 38 | }; 39 | 40 | /** 41 | * 用于判断是否拥有权限访问此view权限 42 | * authority 支持传入 string ,funtion:()=>boolean|Promise 43 | * e.g. 'user' 只有user用户能访问 44 | * e.g. 'user,admin' user和 admin 都能访问 45 | * e.g. ()=>boolean 返回true能访问,返回false不能访问 46 | * e.g. Promise then 能访问 catch不能访问 47 | * e.g. authority support incoming string, funtion: () => boolean | Promise 48 | * e.g. 'user' only user user can access 49 | * e.g. 'user, admin' user and admin can access 50 | * e.g. () => boolean true to be able to visit, return false can not be accessed 51 | * e.g. Promise then can not access the visit to catch 52 | * @param {string | function | Promise} authority 53 | * @param {ReactNode} error 非必需参数 54 | */ 55 | const authorize = (authority, error) => { 56 | /** 57 | * conversion into a class 58 | * 防止传入字符串时找不到staticContext造成报错 59 | * String parameters can cause staticContext not found error 60 | */ 61 | let classError = false; 62 | if (error) { 63 | classError = () => error; 64 | } 65 | if (!authority) { 66 | throw new Error("authority is required"); 67 | } 68 | return function decideAuthority(target) { 69 | const component = CheckPermissions( 70 | authority, 71 | target, 72 | classError || Exception403, 73 | ); 74 | return checkIsInstantiation(component); 75 | }; 76 | }; 77 | 78 | export default authorize; 79 | -------------------------------------------------------------------------------- /src/components/Authorized/PromiseRender.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Spin } from "antd"; 20 | 21 | export default class PromiseRender extends React.PureComponent { 22 | constructor(props) { 23 | super(props); 24 | this.state = { 25 | component: null, 26 | prevPropsPromise: null, 27 | }; 28 | } 29 | 30 | componentDidMount() { 31 | this.setRenderComponent(this.props); 32 | } 33 | 34 | static getDerivedStateFromProps(nextProps, prevState) { 35 | if (nextProps.promise !== prevState.prevPropsPromise) { 36 | return { 37 | prevPropsPromise: nextProps.promise, 38 | }; 39 | } 40 | return null; 41 | } 42 | 43 | componentDidUpdate(prevProps) { 44 | if (this.props.promise !== prevProps.promise) { 45 | this.setRenderComponent(this.props); 46 | } 47 | } 48 | 49 | // set render Component : ok or error 50 | setRenderComponent(props) { 51 | const ok = this.checkIsInstantiation(props.ok); 52 | const error = this.checkIsInstantiation(props.error); 53 | props.promise 54 | .then(() => { 55 | this.setState({ 56 | component: ok, 57 | }); 58 | }) 59 | .catch(() => { 60 | this.setState({ 61 | component: error, 62 | }); 63 | }); 64 | } 65 | 66 | // Determine whether the incoming component has been instantiated 67 | // AuthorizedRoute is already instantiated 68 | // Authorized render is already instantiated, children is no instantiated 69 | // Secured is not instantiated 70 | checkIsInstantiation = (target) => { 71 | if (!React.isValidElement(target)) { 72 | return target; 73 | } 74 | return () => target; 75 | }; 76 | 77 | render() { 78 | const { component: Component } = this.state; 79 | return Component ? ( 80 | 81 | ) : ( 82 |
91 | 92 |
93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/components/SiderMenu/index.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import "~antd/lib/style/themes/default.less"; 19 | @ease-in-out-circ: cubic-bezier(0.78, 0.14, 0.15, 0.86); 20 | 21 | .logo { 22 | height: 64px; 23 | position: relative; 24 | padding-left: (@menu-collapsed-width - 32px) / 2; 25 | transition: all 0.3s; 26 | background: #002140; 27 | overflow: hidden; 28 | display: flex; 29 | flex-direction: row; 30 | align-items: center; 31 | 32 | .icon { 33 | width: 32px; 34 | height: 32px; 35 | } 36 | 37 | .TitleLogo { 38 | width: 184px; 39 | height: 184px; 40 | } 41 | 42 | .systemTitle { 43 | color: #ffffff; 44 | font-family: "Myriad Pro", "Helvetica Neue", Arial, Helvetica, sans-serif; 45 | font-weight: 600; 46 | 47 | .title { 48 | font-size: 18px; 49 | line-height: 18px; 50 | } 51 | 52 | .subTitle { 53 | font-size: 14px; 54 | line-height: 17px; 55 | } 56 | } 57 | } 58 | 59 | .sider { 60 | min-height: 100vh; 61 | box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35); 62 | position: relative; 63 | z-index: 10; 64 | 65 | &.ligth { 66 | background-color: white; 67 | 68 | .logo { 69 | background: white; 70 | 71 | h1 { 72 | color: #002140; 73 | } 74 | } 75 | } 76 | } 77 | 78 | .changeMode { 79 | margin: 10px 0px 0px 20px !important; 80 | } 81 | 82 | .icon { 83 | width: 14px; 84 | margin-right: 10px; 85 | } 86 | 87 | :global { 88 | .drawer .drawer-content { 89 | background: #001529; 90 | } 91 | 92 | .ant-menu-inline-collapsed { 93 | 94 | &>.ant-menu-item .sider-menu-item-img+span, 95 | &>.ant-menu-item-group>.ant-menu-item-group-list>.ant-menu-item .sider-menu-item-img+span, 96 | &>.ant-menu-submenu>.ant-menu-submenu-title .sider-menu-item-img+span { 97 | max-width: 0; 98 | display: inline-block; 99 | opacity: 0; 100 | } 101 | } 102 | 103 | .ant-menu-item .sider-menu-item-img+span, 104 | .ant-menu-submenu-title .sider-menu-item-img+span { 105 | transition: opacity 0.3s @ease-in-out, width 0.3s @ease-in-out; 106 | opacity: 1; 107 | } 108 | } -------------------------------------------------------------------------------- /src/utils/plugin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { refreshAuthMenus } from "./AuthRoute"; 20 | import AddModal from "../routes/System/Plugin/AddModal"; 21 | 22 | export function getUpdateModal({ 23 | pluginId, 24 | dispatch, 25 | fetchValue, 26 | callback, 27 | updatedCallback, 28 | canceledCallback, 29 | }) { 30 | dispatch({ 31 | type: "plugin/fetchItem", 32 | payload: { 33 | id: pluginId, 34 | }, 35 | callback: (plugin) => { 36 | dispatch({ 37 | type: "plugin/fetchByPluginId", 38 | payload: { 39 | pluginId: plugin.id, 40 | type: "3", 41 | }, 42 | callback: (pluginConfigList) => { 43 | callback( 44 | { 49 | const { name, enabled, id, role, config, sort, file } = values; 50 | dispatch({ 51 | type: "plugin/update", 52 | payload: { 53 | config, 54 | role, 55 | name, 56 | enabled, 57 | id, 58 | sort, 59 | file, 60 | }, 61 | fetchValue, 62 | callback: () => { 63 | if (updatedCallback) { 64 | updatedCallback(values); 65 | } 66 | refreshAuthMenus({ dispatch }); 67 | }, 68 | }); 69 | }} 70 | handleCancel={canceledCallback} 71 | />, 72 | ); 73 | }, 74 | }); 75 | }, 76 | }); 77 | } 78 | 79 | export function updatePluginsEnabled({ 80 | list, 81 | enabled, 82 | dispatch, 83 | fetchValue, 84 | callback, 85 | }) { 86 | dispatch({ 87 | type: "plugin/updateEn", 88 | payload: { 89 | list, 90 | enabled, 91 | }, 92 | fetchValue, 93 | callback: () => { 94 | if (callback) { 95 | callback(); 96 | } 97 | refreshAuthMenus({ dispatch }); 98 | }, 99 | }); 100 | } 101 | -------------------------------------------------------------------------------- /src/components/Login/map.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import { Input, Icon } from "antd"; 20 | import styles from "./index.less"; 21 | import { getIntlContent } from "../../utils/IntlUtils"; 22 | 23 | const map = { 24 | VerifyCode: { 25 | component: Input, 26 | props: { 27 | size: "large", 28 | allowClear: true, 29 | prefix: , 30 | }, 31 | rules: [ 32 | { 33 | required: true, 34 | message: getIntlContent("SHENYU.SYSTEM.VERIFICATION.CODE"), 35 | }, 36 | ], 37 | }, 38 | UserName: { 39 | component: Input, 40 | props: { 41 | size: "large", 42 | allowClear: true, 43 | prefix: , 44 | placeholder: "admin", 45 | }, 46 | rules: [ 47 | { 48 | required: true, 49 | message: getIntlContent("SHENYU.SYSTEM.USER.NAME"), 50 | }, 51 | ], 52 | }, 53 | Password: { 54 | component: Input.Password, 55 | props: { 56 | size: "large", 57 | allowClear: true, 58 | prefix: , 59 | placeholder: "888888", 60 | }, 61 | rules: [ 62 | { 63 | required: true, 64 | message: getIntlContent("SHENYU.SYSTEM.USER.PASSWORD"), 65 | }, 66 | ], 67 | }, 68 | Mobile: { 69 | component: Input, 70 | props: { 71 | size: "large", 72 | allowClear: true, 73 | prefix: , 74 | placeholder: "mobile number", 75 | }, 76 | rules: [ 77 | { 78 | required: true, 79 | message: "Please enter mobile number!", 80 | }, 81 | { 82 | pattern: /^1\d{10}$/, 83 | message: "Wrong mobile number format!", 84 | }, 85 | ], 86 | }, 87 | Captcha: { 88 | component: Input, 89 | props: { 90 | size: "large", 91 | allowClear: true, 92 | prefix: , 93 | placeholder: "captcha", 94 | }, 95 | rules: [ 96 | { 97 | required: true, 98 | message: "Please enter Captcha!", 99 | }, 100 | ], 101 | }, 102 | }; 103 | 104 | export default map; 105 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | module.exports = { 19 | parser: 'babel-eslint', 20 | extends: [ 21 | 'airbnb', 22 | 'prettier' 23 | ], 24 | plugins: [ 25 | 'prettier', 26 | ], 27 | env: { 28 | browser: true, 29 | node: true, 30 | es6: true, 31 | mocha: true, 32 | jest: true, 33 | jasmine: true, 34 | }, 35 | rules: { 36 | 'react/jsx-boolean-value': [0], 37 | 'one-var': [0], 38 | 'prefer-destructuring': [0], 39 | 'react/destructuring-assignment':[0], 40 | 'comma-dangle': [0], 41 | 'react/no-array-index-key':[0], 42 | 'no-param-reassign': [0], 43 | 'prefer-const': [0], 44 | 'linebreak-style': [0], 45 | 'generator-star-spacing': [0], 46 | 'consistent-return': [0], 47 | 'react/forbid-prop-types': [0], 48 | 'react/jsx-filename-extension': [1, { extensions: ['.js'] }], 49 | 'global-require': [1], 50 | 'import/prefer-default-export': [0], 51 | 'react/jsx-no-bind': [0], 52 | 'react/prop-types': [0], 53 | 'react/prefer-stateless-function': [0], 54 | 'react/jsx-one-expression-per-line': [0], 55 | 'react/jsx-wrap-multilines': [ 56 | 'error', 57 | { 58 | declaration: 'parens-new-line', 59 | assignment: 'parens-new-line', 60 | return: 'parens-new-line', 61 | arrow: 'parens-new-line', 62 | condition: 'parens-new-line', 63 | logical: 'parens-new-line', 64 | prop: 'ignore', 65 | }, 66 | ], 67 | 'react/jsx-props-no-spreading': 'off', 68 | 'react/function-component-definition': 'off', 69 | 'no-else-return': [0], 70 | 'no-restricted-syntax': [0], 71 | 'import/no-extraneous-dependencies': [0], 72 | 'no-use-before-define': [0], 73 | 'jsx-a11y/no-static-element-interactions': [0], 74 | 'jsx-a11y/no-noninteractive-element-interactions': [0], 75 | 'jsx-a11y/click-events-have-key-events': [0], 76 | 'jsx-a11y/anchor-is-valid': [0], 77 | 'no-nested-ternary': [0], 78 | 'arrow-body-style': [0], 79 | 'import/extensions': [0], 80 | 'no-bitwise': [0], 81 | 'no-cond-assign': [0], 82 | 'import/no-unresolved': [0], 83 | 'object-curly-newline': [0], 84 | 'function-paren-newline': [0], 85 | 'no-restricted-globals': [0], 86 | 'require-yield': [1], 87 | 'prettier/prettier': 'error', 88 | }, 89 | parserOptions: { 90 | ecmaFeatures: { 91 | experimentalObjectRestSpread: true, 92 | }, 93 | }, 94 | settings: { 95 | polyfills: ['fetch', 'promises'], 96 | }, 97 | }; 98 | -------------------------------------------------------------------------------- /src/routes/Document/components/HeadersEditor.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { Col, Input, Row, Button, Icon, Typography } from "antd"; 19 | import React, { Fragment, useEffect, useState } from "react"; 20 | 21 | const { Text } = Typography; 22 | 23 | function HeadersEditor(props) { 24 | const { value: propsValue, onChange, buttonText } = props; 25 | const jsonObj = JSON.parse(propsValue || "[]"); 26 | const [value, setValue] = useState(jsonObj); 27 | 28 | useEffect(() => { 29 | setValue(jsonObj); 30 | }, [propsValue]); 31 | 32 | const onChangeItem = (e, key, index) => { 33 | changeValue( 34 | value.map((item) => 35 | item.index === index ? { ...item, [key]: e } : item, 36 | ), 37 | ); 38 | }; 39 | 40 | const onDeleteItem = (key) => { 41 | changeValue(value.filter((item) => item.key !== key)); 42 | }; 43 | 44 | const onAddItem = () => { 45 | changeValue([...value, { index: value.length, key: "", value: "" }]); 46 | }; 47 | 48 | const changeValue = (newValue) => { 49 | setValue(newValue); 50 | onChange(JSON.stringify(newValue)); 51 | }; 52 | 53 | return ( 54 | 55 | {value.map((item) => ( 56 | 57 | 58 | onChangeItem(e.target.value, "key", item.index)} 63 | /> 64 | 65 | 66 | 71 | onChangeItem(e.target.value, "value", item.index) 72 | } 73 | /> 74 | 75 | 76 | {!item.required && ( 77 | 78 | onDeleteItem(item.key)} 82 | /> 83 | 84 | )} 85 | 86 | 87 | ))} 88 | 89 | 90 | 93 | 94 | 95 | ); 96 | } 97 | 98 | export default HeadersEditor; 99 | -------------------------------------------------------------------------------- /src/models/instance.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { 19 | getInstancesByNamespace, 20 | findInstance, 21 | findInstanceAnalysis, 22 | } from "../services/api"; 23 | 24 | export default { 25 | namespace: "instance", 26 | 27 | state: { 28 | instanceList: [], 29 | total: 0, 30 | pieData: [], 31 | lineList: [], 32 | }, 33 | 34 | effects: { 35 | *fetch(params, { call, put }) { 36 | const { payload } = params; 37 | const json = yield call(getInstancesByNamespace, payload); 38 | if (json.code === 200) { 39 | let { page, dataList } = json.data; 40 | dataList = dataList.map((item) => { 41 | item.key = item.id; 42 | return item; 43 | }); 44 | yield put({ 45 | type: "saveInstances", 46 | payload: { 47 | total: page.totalCount, 48 | dataList, 49 | }, 50 | }); 51 | } 52 | }, 53 | *fetchAnalysis(params, { call, put }) { 54 | const { payload } = params; 55 | const json = yield call(findInstanceAnalysis, payload); 56 | 57 | if (json.code === 200) { 58 | let { pieData, lineData } = json.data; 59 | yield put({ 60 | type: "saveInstancesAnalysis", 61 | payload: { 62 | pieData, 63 | lineData, 64 | }, 65 | }); 66 | } 67 | }, 68 | *fetchItem(params, { call }) { 69 | const { payload, callback } = params; 70 | const json = yield call(findInstance, payload); 71 | if (json.code === 200) { 72 | const instance = json.data; 73 | callback(instance); 74 | } 75 | }, 76 | *reload(params, { put }) { 77 | const { fetchValue } = params; 78 | const { name, currentPage, instanceType, instanceIp, pageSize } = 79 | fetchValue; 80 | const payload = { 81 | name, 82 | instanceType, 83 | instanceIp, 84 | currentPage, 85 | pageSize, 86 | }; 87 | yield put({ type: "fetch", payload }); 88 | }, 89 | }, 90 | 91 | reducers: { 92 | saveInstances(state, { payload }) { 93 | return { 94 | ...state, 95 | instanceList: payload.dataList, 96 | total: payload.total, 97 | }; 98 | }, 99 | saveInstancesAnalysis(state, { payload }) { 100 | return { 101 | ...state, 102 | pieData: payload.pieData, 103 | lineData: payload.lineData, 104 | }; 105 | }, 106 | }, 107 | }; 108 | -------------------------------------------------------------------------------- /src/components/GlobalHeader/ImportResultModal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React, { Component } from "react"; 19 | import { Modal, Form, Tooltip } from "antd"; 20 | import { connect } from "dva"; 21 | import { getIntlContent } from "../../utils/IntlUtils"; 22 | 23 | const keyMap = { 24 | metaImportSuccessCount: "metaImportSuccessCount", 25 | metaImportFailMessage: "metaImportFailMessage", 26 | authImportSuccessCount: "authImportSuccessCount", 27 | authImportFailMessage: "authImportFailMessage", 28 | pluginImportSuccessCount: "pluginImportSuccessCount", 29 | pluginImportFailMessage: "pluginImportFailMessage", 30 | proxySelectorImportSuccessCount: "proxySelectorImportSuccessCount", 31 | proxySelectorImportFailMessage: "proxySelectorImportFailMessage", 32 | discoveryImportSuccessCount: "discoveryImportSuccessCount", 33 | discoveryImportFailMessage: "discoveryImportFailMessage", 34 | discoveryUpstreamImportSuccessCount: "discoveryUpstreamImportSuccessCount", 35 | discoveryUpstreamImportFailMessage: "discoveryUpstreamImportFailMessage", 36 | dictImportSuccessCount: "dictImportSuccessCount", 37 | dictImportFailMessage: "dictImportFailMessage", 38 | }; 39 | 40 | @connect(({ global }) => ({ 41 | platform: global.platform, 42 | })) 43 | class ImportResultModal extends Component { 44 | // eslint-disable-next-line react/no-unused-class-component-methods 45 | handleSubmit = (e) => { 46 | const { form, handleOk } = this.props; 47 | e.preventDefault(); 48 | form.validateFieldsAndScroll((err, values) => { 49 | if (!err) { 50 | let { file } = values; 51 | handleOk({ file }); 52 | } 53 | }); 54 | }; 55 | 56 | handleRes = (json, key) => { 57 | // return data; 58 | const data = json[key]; 59 | const maxLength = 50; // set the max show length 60 | if (data && data.length > maxLength) { 61 | return ( 62 | {`${data.substring(0, maxLength)}...`} 63 | ); 64 | } 65 | return {data}; 66 | }; 67 | 68 | formatKey = (key) => { 69 | return keyMap[key] || key; 70 | }; 71 | 72 | renderContent = (json) => { 73 | return Object.keys(keyMap).map((key) => ( 74 |

75 | {this.formatKey(key)}: {this.handleRes(json, key)} 76 |

77 | )); 78 | }; 79 | 80 | render() { 81 | let { onOk, onCancel, json } = this.props; 82 | 83 | return ( 84 | 90 |
91 |           {this.renderContent(json)}
92 |         
93 |
94 | ); 95 | } 96 | } 97 | 98 | export default Form.create()(ImportResultModal); 99 | -------------------------------------------------------------------------------- /src/components/Authorized/CheckPermissions.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import React from "react"; 19 | import PromiseRender from "./PromiseRender"; 20 | import { CURRENT } from "./renderAuthorize"; 21 | 22 | function isPromise(obj) { 23 | return ( 24 | !!obj && 25 | (typeof obj === "object" || typeof obj === "function") && 26 | typeof obj.then === "function" 27 | ); 28 | } 29 | 30 | /** 31 | * 通用权限检查方法 32 | * Common check permissions method 33 | * @param { 权限判定 Permission judgment type string |array | Promise | Function } authority 34 | * @param { 你的权限 Your permission description type:string} currentAuthority 35 | * @param { 通过的组件 Passing components } target 36 | * @param { 未通过的组件 no pass components } Exception 37 | */ 38 | const checkPermissions = (authority, currentAuthority, target, Exception) => { 39 | // 没有判定权限.默认查看所有 40 | // Retirement authority, return target; 41 | if (!authority) { 42 | return target; 43 | } 44 | // 数组处理 45 | if (Array.isArray(authority)) { 46 | if (authority.indexOf(currentAuthority) >= 0) { 47 | return target; 48 | } 49 | if (Array.isArray(currentAuthority)) { 50 | for (let i = 0; i < currentAuthority.length; i += 1) { 51 | const element = currentAuthority[i]; 52 | if (authority.indexOf(element) >= 0) { 53 | return target; 54 | } 55 | } 56 | } 57 | return Exception; 58 | } 59 | 60 | // string 处理 61 | if (typeof authority === "string") { 62 | if (authority === currentAuthority) { 63 | return target; 64 | } 65 | if (Array.isArray(currentAuthority)) { 66 | for (let i = 0; i < currentAuthority.length; i += 1) { 67 | const element = currentAuthority[i]; 68 | if (authority.indexOf(element) >= 0) { 69 | return target; 70 | } 71 | } 72 | } 73 | return Exception; 74 | } 75 | 76 | // Promise 处理 77 | if (isPromise(authority)) { 78 | return ; 79 | } 80 | 81 | // Function 处理 82 | if (typeof authority === "function") { 83 | // eslint-disable-next-line no-useless-catch 84 | try { 85 | const bool = authority(currentAuthority); 86 | // 函数执行后返回值是 Promise 87 | if (isPromise(bool)) { 88 | return ; 89 | } 90 | if (bool) { 91 | return target; 92 | } 93 | return Exception; 94 | } catch (error) { 95 | throw error; 96 | } 97 | } 98 | throw new Error("unsupported parameters"); 99 | }; 100 | 101 | export { checkPermissions }; 102 | 103 | const check = (authority, target, Exception) => { 104 | return checkPermissions(authority, CURRENT, target, Exception); 105 | }; 106 | 107 | export default check; 108 | -------------------------------------------------------------------------------- /src/components/Login/demo/basic.md: -------------------------------------------------------------------------------- 1 | --- 2 | order: 0 3 | title: 4 | zh-CN: 标准登录 5 | en-US: Standard Login 6 | --- 7 | 8 | Support login with account and mobile number. 9 | 10 | ````jsx 11 | import Login from 'ant-design-pro/lib/Login'; 12 | import { Alert, Checkbox } from 'antd'; 13 | 14 | const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login; 15 | 16 | class LoginDemo extends React.Component { 17 | state = { 18 | notice: '', 19 | type: 'tab2', 20 | autoLogin: true, 21 | } 22 | onSubmit = (err, values) => { 23 | console.log('value collected ->', { ...values, autoLogin: this.state.autoLogin }); 24 | if (this.state.type === 'tab1') { 25 | this.setState({ 26 | notice: '', 27 | }, () => { 28 | if (!err && (values.username !== 'admin' || values.password !== '888888')) { 29 | setTimeout(() => { 30 | this.setState({ 31 | notice: 'The combination of username and password is incorrect!', 32 | }); 33 | }, 500); 34 | } 35 | }); 36 | } 37 | } 38 | onTabChange = (key) => { 39 | this.setState({ 40 | type: key, 41 | }); 42 | } 43 | changeAutoLogin = (e) => { 44 | this.setState({ 45 | autoLogin: e.target.checked, 46 | }); 47 | } 48 | render() { 49 | return ( 50 | 55 | 56 | { 57 | this.state.notice && 58 | 59 | } 60 | 61 | 62 | 63 | 64 | 65 | console.log('Get captcha!')} name="captcha" /> 66 | 67 |
68 | Keep me logged in 69 | Forgot password 70 |
71 | Login 72 |
73 | Other login methods 74 | 75 | 76 | 77 | Register 78 |
79 |
80 | ); 81 | } 82 | } 83 | 84 | ReactDOM.render(, mountNode); 85 | ```` 86 | 87 | 116 | -------------------------------------------------------------------------------- /.roadhogrc.mock.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import mockjs from 'mockjs'; 19 | import { getNotices } from './mock/notices'; 20 | 21 | import { getUsers } from './mock/user'; 22 | import { getPlatform } from './mock/platform' 23 | import { getPlugin } from './mock/plugin' 24 | import { format, delay } from 'roadhog-api-doc'; 25 | 26 | // 是否禁用代理 27 | const noProxy = process.env.NO_PROXY === 'true'; 28 | 29 | // 代码中会兼容本地 service mock 以及部署站点的静态数据 30 | const proxy = { 31 | 'GET /platform': { 32 | $body: getPlatform, 33 | }, 34 | 'GET /dashboardUser': { 35 | $params: { 36 | userName: 'ADMIN', 37 | currentPage: 1, 38 | pageSize: 10, 39 | }, 40 | $body: getUsers(), 41 | }, 42 | 43 | 'GET /dashboardUser/1': { 44 | "code": 200, 45 | "message": "detail dashboard user success", 46 | "data": { 47 | "id": "1", 48 | "userName": "admin", 49 | "password": "123456", 50 | "role": 1, 51 | "enabled": false, 52 | "dateCreated": "2018-06-23 15:12:22", 53 | "dateUpdated": "2018-06-23 15:12:23" 54 | } 55 | }, 56 | 'POST /dashboardUser': { 57 | $body: { 58 | code: 200 59 | }, 60 | }, 61 | 'PUT /dashboardUser/1': { 62 | $body: { 63 | code: 200 64 | }, 65 | }, 66 | 'POST /dashboardUser/delete': { 67 | $body: { 68 | code: 200 69 | }, 70 | }, 71 | 72 | 'GET /plugin': { 73 | $body: getPlugin, 74 | }, 75 | 76 | 'GET /plugin/1': { 77 | "code": 200, 78 | "message": "detail dashboard user success", 79 | "data": { 80 | "id": "1", 81 | "name": "admin", 82 | "enabled": false, 83 | } 84 | }, 85 | 'POST /plugin': { 86 | $body: { 87 | code: 200 88 | }, 89 | }, 90 | 'PUT /plugin/1': { 91 | $body: { 92 | code: 200 93 | }, 94 | }, 95 | 'POST /plugin/delete': { 96 | $body: { 97 | code: 200 98 | }, 99 | }, 100 | 'GET /api/notices': getNotices, 101 | 'GET /api/500': (req, res) => { 102 | res.status(500).send({ 103 | timestamp: 1513932555104, 104 | status: 500, 105 | error: 'error', 106 | message: 'error', 107 | path: '/base/category/list', 108 | }); 109 | }, 110 | 'GET /api/404': (req, res) => { 111 | res.status(404).send({ 112 | timestamp: 1513932643431, 113 | status: 404, 114 | error: 'Not Found', 115 | message: 'No message available', 116 | path: '/base/category/list/2121212', 117 | }); 118 | }, 119 | 'GET /api/403': (req, res) => { 120 | res.status(403).send({ 121 | timestamp: 1513932555104, 122 | status: 403, 123 | error: 'Unauthorized', 124 | message: 'Unauthorized', 125 | path: '/base/category/list', 126 | }); 127 | } 128 | }; 129 | 130 | export default (noProxy ? {} : delay(proxy, 1000)); 131 | -------------------------------------------------------------------------------- /src/components/Authorized/CheckPermissions.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import { checkPermissions } from "./CheckPermissions.js"; 19 | 20 | const target = "ok"; 21 | const error = "error"; 22 | 23 | describe("test CheckPermissions", () => { 24 | it("Correct string permission authentication", () => { 25 | expect(checkPermissions("user", "user", target, error)).toEqual("ok"); 26 | }); 27 | it("Correct string permission authentication", () => { 28 | expect(checkPermissions("user", "NULL", target, error)).toEqual("error"); 29 | }); 30 | it("authority is undefined , return ok", () => { 31 | expect(checkPermissions(null, "NULL", target, error)).toEqual("ok"); 32 | }); 33 | it("currentAuthority is undefined , return error", () => { 34 | expect(checkPermissions("admin", null, target, error)).toEqual("error"); 35 | }); 36 | it("Wrong string permission authentication", () => { 37 | expect(checkPermissions("admin", "user", target, error)).toEqual("error"); 38 | }); 39 | it("Correct Array permission authentication", () => { 40 | expect(checkPermissions(["user", "admin"], "user", target, error)).toEqual( 41 | "ok", 42 | ); 43 | }); 44 | it("Wrong Array permission authentication,currentAuthority error", () => { 45 | expect( 46 | checkPermissions(["user", "admin"], "user,admin", target, error), 47 | ).toEqual("error"); 48 | }); 49 | it("Wrong Array permission authentication", () => { 50 | expect(checkPermissions(["user", "admin"], "guest", target, error)).toEqual( 51 | "error", 52 | ); 53 | }); 54 | it("Wrong Function permission authentication", () => { 55 | expect(checkPermissions(() => false, "guest", target, error)).toEqual( 56 | "error", 57 | ); 58 | }); 59 | it("Correct Function permission authentication", () => { 60 | expect(checkPermissions(() => true, "guest", target, error)).toEqual("ok"); 61 | }); 62 | it("authority is string, currentAuthority is array, return ok", () => { 63 | expect(checkPermissions("user", ["user"], target, error)).toEqual("ok"); 64 | }); 65 | it("authority is string, currentAuthority is array, return ok", () => { 66 | expect(checkPermissions("user", ["user", "admin"], target, error)).toEqual( 67 | "ok", 68 | ); 69 | }); 70 | it("authority is array, currentAuthority is array, return ok", () => { 71 | expect( 72 | checkPermissions(["user", "admin"], ["user", "admin"], target, error), 73 | ).toEqual("ok"); 74 | }); 75 | it("Wrong Function permission authentication", () => { 76 | expect(checkPermissions(() => false, ["user"], target, error)).toEqual( 77 | "error", 78 | ); 79 | }); 80 | it("Correct Function permission authentication", () => { 81 | expect(checkPermissions(() => true, ["user"], target, error)).toEqual("ok"); 82 | }); 83 | it("authority is undefined , return ok", () => { 84 | expect(checkPermissions(null, ["user"], target, error)).toEqual("ok"); 85 | }); 86 | }); 87 | --------------------------------------------------------------------------------